Mickey Mania emulator comparison

Ask anything your want about Megadrive/Genesis programming.

Moderator: BigEvilCorporation

Nemesis
Very interested
Posts: 773
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Sat Mar 28, 2009 2:42 pm

Ok, so I think I've finished messing around with my sprite test rom for the time being. Here's the ROM:
http://nemesis.hacking-cult.org/MegaDri ... estRom.bin

And here's the source:
http://nemesis.hacking-cult.org/MegaDri ... estRom.zip

I've ended up with a set of 9 tests, which I've engineered to be as evil as possible. Here's a short description of each test:
1. Max sprites per line. This test checks that the correct number of sprites are being displayed on a given line. The first result verifies that the last visible sprite is displayed correctly. The second result verifies that the first discarded sprite is not displayed.
2. Max sprite dots - basic. This test checks that new sprites are being displayed up until the sprite dot count for the line is reached, and that new sprites stop being displayed once the maximum number of sprite dots for the line have been exceeded.
3. Max sprite dots - complex. More thorough than the basic test. Verifies that sprite dot overflow cuts off a sprite partway through when the sprite dot count is reached, and that sprite masks contribute to the dot count, amoung other things.
4. Sprite masking. Verifies that basic sprite masking is working when the sprite mask is not the first sprite on the line.
5. Sprite masking in slot 1. Verifies that sprite masks are ignored when they appear before any other sprites on a line.
6. Sprite masking in slot 1 on dot overflow. Verifies that sprite masks at the beginning of a line become effective when a sprite dot overflow occurs on the previous line.
7/8. Verifies that the emulator is not implementing the non-existant sprite masking mode 2.
9. Max sprites per frame. Verifies that the "sprite limits" for the frame are being followed. Actually, most emulators fail this test. Per-frame sprite limits actually determine the number of entries which are read from the sprite table. Under H32 mode, only the first 64 entries of the table are read. Under H40 mode, only the first 80 entries of the table are read. All sprite entries after these maximums are ignored. If you try and, for example, jump to sprite entry 65 under H32 mode, that sprite entry will not be processed and the sprite list will terminate, even if you jump to it directly from the first sprite.


Here's what you get on the real system:
ImageImage

Here's what you get on Kega:
ImageImage
Kega is the only emulator which passes the complex sprite dot overflow test.

Here's what you get on Gens:
ImageImage
That isn't a pass for the sprite masking on dot overflow. Note the red line at the bottom. This test is conditional on the above test passing, which it doesn't.

Here's what you get on Regen:
ImageImage
Regen is the only emulator which passes the per-frame sprite limits in H32 mode.

Here's what I currently get on my emulator:
ImageImage
Looks like I've got some work to do. Note that I followed the sprite masking mode 2 info, which causes test 8 to fail.

And just for the fun of it, here's Genecyst:
ImageImage
Could be worse.

So yeah, hopefully this test ROM will help everyone to verify their sprite overflow/masking code.

Nemesis
Very interested
Posts: 773
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Sat Mar 28, 2009 3:04 pm

As for Mickey Mania, I think you guys are right, something that Mickey Mania is doing mid-frame (haven't looked at the code at all) is affecting the total number of dots available for sprites, causing a sprite dot overflow when it would normally not occur.

I halted the game in my emulator, and dumped the complete static VDP state out to a test ROM I ran on the real system, and the masking did NOT work. I also tried the rather unscientific method of yanking out the game cart at the appropriate time, and once the game locked, the sprite masking also no longer worked correctly. That says it's an active process the game code is running which is keeping the sprites masked. I also applied those codes you gave Tasco, and it had no noticeable effect, that is, the sprites were still masked. If the game is disabling the display for large blocks of time during hblank as you guys say, it sounds like that's the likely culprit.

I don't have time to run tests on that right at this moment, but that would mean that in order to emulate this game properly, we'll need to get solid info on the exact impact disabling the display mid-frame has on the ability of the system to render sprites. This is only being displayed incorrectly in Kega because it's more accurate than other emulators in how it deals with sprite masking and overflow.

Eke
Very interested
Posts: 856
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Sat Mar 28, 2009 5:04 pm

Ok, so I think I've finished messing around with my sprite test rom for the time being. Here's the ROM:
http://nemesis.hacking-cult.org/MegaDri ... estRom.bin

And here's the source:
http://nemesis.hacking-cult.org/MegaDri ... estRom.zip

I've ended up with a set of 9 tests, which I've engineered to be as evil as possible. Here's a short description of each test:
1. Max sprites per line. This test checks that the correct number of sprites are being displayed on a given line. The first result verifies that the last visible sprite is displayed correctly. The second result verifies that the first discarded sprite is not displayed.
2. Max sprite dots - basic. This test checks that new sprites are being displayed up until the sprite dot count for the line is reached, and that new sprites stop being displayed once the maximum number of sprite dots for the line have been exceeded.
3. Max sprite dots - complex. More thorough than the basic test. Verifies that sprite dot overflow cuts off a sprite partway through when the sprite dot count is reached, and that sprite masks contribute to the dot count, amoung other things.
4. Sprite masking. Verifies that basic sprite masking is working when the sprite mask is not the first sprite on the line.
5. Sprite masking in slot 1. Verifies that sprite masks are ignored when they appear before any other sprites on a line.
6. Sprite masking in slot 1 on dot overflow. Verifies that sprite masks at the beginning of a line become effective when a sprite dot overflow occurs on the previous line.
7/8. Verifies that the emulator is not implementing the non-existant sprite masking mode 2.
9. Max sprites per frame. Verifies that the "sprite limits" for the frame are being followed. Actually, most emulators fail this test. Per-frame sprite limits actually determine the number of entries which are read from the sprite table. Under H32 mode, only the first 64 entries of the table are read. Under H40 mode, only the first 80 entries of the table are read. All sprite entries after these maximums are ignored. If you try and, for example, jump to sprite entry 65 under H32 mode, that sprite entry will not be processed and the sprite list will terminate, even if you jump to it directly from the first sprite.
Thanks a lot, I hope it's the beginning of a long serie for VDP test programs ;-)

Here's what I originally got in genesis plus:

Image
Image


If I make the change for Mickeymania to "work":

Image
Image


If I try to fix test 6 and add previous line dot overflow detection (note that I also need to take masked sprites width in account for dot overflow instead of simply exiting the sprites rendering function):

Image

Note that even with that (and as expected since no dot overflow occurs *on emulator*), Mickeymani 3D level is still wrong, the only way to get it right being to "cheat" and fail test 5

looks like we have to choose between accuracy and visual correctness :?
It's very probable the "mask S1 on dot overflow" is not used by any games though :roll:

Snake
Very interested
Posts: 203
Joined: Sat Sep 13, 2008 1:01 am

Post by Snake » Sat Mar 28, 2009 6:54 pm

That looks like a very nice test ROM :)

As I said earlier, I knew Kega would fail that one particular test, but...
Nemesis wrote:If you try and, for example, jump to sprite entry 65 under H32 mode, that sprite entry will not be processed and the sprite list will terminate, even if you jump to it directly from the first sprite.
I never thought to try that.
Nemesis wrote:I also applied those codes you gave Tasco, and it had no noticeable effect, that is, the sprites were still masked
Exactly what I expected to see, and proves that Mickey Mania does NOT use Sprite Masking. Thanks :)
Eke wrote:It's very probable the "mask S1 on dot overflow" is not used by any games though
No it isn't, in fact a lot of this stuff isn't. But still, your fix for MickeyMania is not accurate. I'll try to work out exactly what's going on, unless Nemesis or TascoDLX beat me to it. But until then, my philosophy is "if it can't be fixed correctly, don't fix it at all." :)

mickagame
Very interested
Posts: 219
Joined: Sat Jun 07, 2008 7:37 am

Post by mickagame » Sat Mar 28, 2009 7:33 pm

Thank you Nemesis for your work :-)
Last edited by mickagame on Sat Mar 28, 2009 8:40 pm, edited 1 time in total.

ob1
Very interested
Posts: 407
Joined: Wed Dec 06, 2006 9:01 am
Location: Aix-en-Provence, France

Post by ob1 » Sat Mar 28, 2009 8:38 pm

Nemesis wrote:Ok, so I think I've finished messing around with my sprite test rom for the time being. Here's the ROM:
http://nemesis.hacking-cult.org/MegaDri ... estRom.bin

And here's the source:
http://nemesis.hacking-cult.org/MegaDri ... estRom.zip
:shock:

Great piece of work Nemesis. It's amazing !

TascoDLX
Very interested
Posts: 256
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX » Sat Mar 28, 2009 10:41 pm

Here are some codes to try in Mickey Mania:

01ABE6:0068 (PCZT-CAHG) will push the DMA all the way into the active display period. You should be able to set that value down to around 0x0035 before the timing gets iffy. (Of course, those numbers are from tests in Fusion.)

01B104:9301 (AG2T-DHAE) will shorten the DMA length accordingly.

*or*

01AC34:4E71 (RG0A-C6VY) and 01AC36:4E71 (RG0A-C6V0) together will eliminate the transfer completely.

TascoDLX
Very interested
Posts: 256
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX » Sun Mar 29, 2009 1:38 pm

TascoDLX wrote:01AC34:4E71 (RG0A-C6VY) and 01AC36:4E71 (RG0A-C6V0) together will eliminate the transfer completely.
Or will crash the system? WTF? Something to do with the DMA registers? Fusion doesn't care. (Note: As a matter of full disclosure, I got these results from the CD not the cart. It's nearly the same exact code, though.)

[EDIT: Tested that with the cart. Same thing.]

Anyway, you can replace those codes with 01AC2E:6008 (BC0A-CA3R) and 01AC60:6002 (AL0A-CA5A). And that does eliminate the masking. Good. Moving right along.
TascoDLX wrote:01ABE6:0068 (PCZT-CAHG) will push the DMA all the way into the active display period.
Weird results on this one. Aside from flickering garbage, *all* of the sprites on the bottom third of the ground area are masked, but everything above that appears normal. Good luck emulating that. :P
TascoDLX wrote:01B104:9301 (AG2T-DHAE) will shorten the DMA length accordingly.
Didn't get a chance to try this but I expect it will make a difference. Also, you can add 01AC20:8174 (RW0A-CDBA) to keep the display on during the transfer.
Last edited by TascoDLX on Mon Apr 13, 2009 11:50 pm, edited 1 time in total.

Eke
Very interested
Posts: 856
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Mon Apr 06, 2009 9:22 am

I don't have time to run tests on that right at this moment, but that would mean that in order to emulate this game properly, we'll need to get solid info on the exact impact disabling the display mid-frame has on the ability of the system to render sprites. This is only being displayed incorrectly in Kega because it's more accurate than other emulators in how it deals with sprite masking and overflow.
It seems that doing the following:

Code: Select all

pixelcount += xpos ? width : (width * 2);
when updating the sprite pixels count fixes MickeyMania and does not break your Test ROM

I don't know if it's correct though, but way easier to emulate than display ON/OFF unknown side effects :wink:

Could you add a test to check if putting 5 sprites with x=0 and width=32 at the start of the line would trigger sprite pixel overflow ?

TascoDLX
Very interested
Posts: 256
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX » Mon Apr 06, 2009 7:28 pm

Eke wrote:Could you add a test to check if putting 5 sprites with x=0 and width=32 at the start of the line would trigger sprite pixel overflow ?
No point in doing that, unless you just want to check if an emulator is using your hack. But, in normal situations, that will never trigger pixel overflow... unless 160 pixels have already been drawn on the line. In the case of Mickey Mania, the x position is irrelevant -- the sprites in that area are just not displayed.

In fact, in Mickey Mania, any sprite that is displayed in the affected area -- roughly line 105 and beyond -- almost certainly has higher priority (i.e., occurs earlier in the list) than the "masking" sprites.

Now that I'm thinking about it, here are some more MM codes to try. Unfortunately I have no time to try them myself.

019EEA:00F1 (8GSA-CAHL) moves the first group of "masking" sprites down 8 pixels. [The original value is 00E9.]
019F02:0105 (A0ST-CCAC) does the same for the second group. [The original value is 00FD.]

019EE6:0003 (ARSA-CAHG) puts 4 (instead of 5) "masking" sprites in the first group. [Setting to 0000 will put 1 sprite.]
019EFE:0003 (ARSA-CAH8) does the same for the second group.

019EE4:6016 (C4SA-CA9E) removes the first group.
019EFC:6016 (C4SA-CA96) removes the second group.

Eke
Very interested
Posts: 856
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Mon Apr 06, 2009 8:10 pm

No point in doing that, unless you just want to check if an emulator is using your hack. But, in normal situations, that will never trigger pixel overflow... unless 160 pixels have already been drawn on the line. In the case of Mickey Mania, the x position is irrelevant -- the sprites in that area are just not displayed.
yeah, I know

but I thought that those sprites were masked because of the dot overflow/ limit, right ?

and since there were only 5 sprites with 32 pixels width (and that following sprites should "theorically" not been masked), my point was to know if possibly, sprite width was added differently on real hardware when xpos=0 (or maybe for any sprites outside display area, who knows), regarding the total pixel width and dot overflow/limit per line...

:?:

I know this does not seems logical AT ALL but it wouldn't be the first undocumented or weird feature/bug

or has this been already tested ?

TascoDLX
Very interested
Posts: 256
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX » Tue Apr 07, 2009 1:08 am

It has been tested and that does not appear to be the case.

It only seems to work the way it does because of the display-off DMA transfer. Eliminating this transfer causes the sprites to show through. With the transfer in place, the 'normal rules' do not apply. Note that Fusion works correctly under the 'normal rules' (aside from one inconsequential bug).

The only way it could be dot overflow is if the display-off DMA transfer is somehow cutting the limit in half (at least). However, the xpos of the sprites certainly does not make a difference. Not sure about the size or ypos.

Another MM code to try...

019EE2:0000 (ACSA-CAHC) changes all the "masking" sprites to 8x8. [Original value is 0F00 (32x32). Set it to 0300 for 8x32 (and you can figure out the rest).]

If I can get my hands on a Mickey Mania cart before this mystery is solved, I'll do some testing.

Eke
Very interested
Posts: 856
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Tue Apr 07, 2009 8:41 am

It has been tested and that does not appear to be the case.
oh,
ok then, forget about that :oops:

TascoDLX
Very interested
Posts: 256
Joined: Tue Feb 06, 2007 8:18 pm

Post by TascoDLX » Mon Apr 13, 2009 9:38 pm

OK, I got the cart and some test results.

First off, the special masking that Mickey Mania uses only happens when the display is turned off for the midscreen transfer.

In the sprite table, the ypos and size of the "masking" sprites are irrelevant. The only item I'd expect to be relevant is the link. That would indicate that the number of "masking" sprites is what's important. I'm guessing the VDP only has a chance to parse so many sprites for a line before it must start on the next line.

The transfer seems to occur at just the right time (and duration) for the special masking to work right. Here's a clue. Reducing the transfer to 11 words has no noticable effect on the sprites. Reduce it to 10 and short lines of the moose start to flicker (note: the moose is the first set of sprites after the "masking" sprites). Keep reducing it and starts to show more and more. Reduce it all the way down to 1 and the bottom of the moose shows almost completely (when not limited by normal masking) with perhaps a little flickering at times. But, the other sprites remain masked, though you might see some occassional flickering if you're really looking hard.

As I mentioned in a previous post, if you move the transfer from its usually starting time on the line, things get weird. Portions of sprite lines on the bottom half of the ground area start to flicker or disappear. Actually, as you move it further away, more seem to disappear from the left side before the right. Very strange.

As a point of interest, the codes 01B104:930A (BL2T-DHAE) and 01ABE6:0098 (XCZT-CAHG) together cause flickering (from the transfer) on the left-hand side of the screen. But, curiously, it flickers between the usual tiles and tiles from the right-hand side of the screen (I'd say 2 columns worth). I guess the VDP misses a fetch and instead uses the nametable data it last fetched (from the right-hand side).

That's all for now.

BTW, for my testing, I used these codes:

0003A2:6016 (C2BT-AA7C) brings you straight to the Press Start screen.
000384:000A (BJBT-AAEE) sets the starting level to Moose Chase.

And, in case anyone wants:

00037C:0001 (AEBT-AAD6) enables level select.

mickagame
Very interested
Posts: 219
Joined: Sat Jun 07, 2008 7:37 am

Post by mickagame » Wed Apr 15, 2009 6:35 pm

I think a possibility :

Display is enabled just before active area. During active area VDP has not many free time.
The VDP needs some clock to parse sprite datas.
So with the first sprite at x=0, vdp has perhaps not enough free time to parse the sixth sprite before the end of active area ...

Post Reply