ekeeke / Genesis-Plus-GX

An enhanced port of Genesis Plus - accurate & portable Sega 8/16 bit emulator
Other
716 stars 202 forks source link

Emulation of 68K bus access refresh delays #407

Open ekeeke opened 2 years ago

ekeeke commented 2 years ago

As verified on real hardware (cf. https://gendev.spritesmind.net/forum/viewtopic.php?f=2&t=2323), there are periodical refresh access slots on 68K bus which can delay access from 68K CPU:

These delays are actually not emulated in Genesis Plus GX and are the cause of graphical issues or crashes in the following games (the code of these games is somehow bugged / unsafe and is causing some race conditions with hardware or concurrently running software that were by luck not occurring on real hardware because of the tight timings but are exposed in emulator as it is running the code a little bit faster than real hardware):

Tippek commented 2 years ago

Primitive fix for Super Airwolf and Pac-man 2: https://github.com/ekeeke/Genesis-Plus-GX/blob/master/core/m68k/m68kcpu.c#L305 if((m68k.cycles-refresh_cycles)>=(128*7)) { m68k.cycles += 2*7; refresh_cycles = m68k.cycles; } with unsigned int refresh_cycles

for Megadrive 2 7, but for SCD probably 2 4. based on https://plutiedev.com/mirror/kabuto-hardware-notes#bus-system +2 cycles every 128

ekeeke commented 2 years ago

Yes, that's more or less the same way I initially tried to implement it but unfortunately this is not enough to fix Clue graphics issues without the aforementioned hack.

The two other games only need CPU execution to be shifted a little every lines/frames but Clue requires very accurate timings as the race condition window is very tight: the bug occurs if the CPU is running too fast but also if it is too slow. I think it only works correctly if the fixed ROM delays are accurately emulated (i.e only in case of access to cartridge/expansion area within the refresh cycle window) and if RAM delays are also accurately emulated (this one is more complex from what I observed on real hw as it seems to be a variable delay, between 0 and 3 cycles, depending how CPU access to RAM is aligned with the RAM refresh slot).

Tippek commented 2 years ago

I did noticed CPU still very fast in GPGX even with this refresh delay. http://gendev.spritesmind.net/forum/viewtopic.php?f=8&p=37391#p37391 - this tests on my MD1 Japan, so I guess it also need refresh delay for RAM (I guess about 3 cycles every 120 cycles), but don't sure its helps, because GPGX CPU very fast as I did said.

Is it fix correct? https://github.com/ekeeke/Genesis-Plus-GX/blob/master/core/vdp_ctrl.c#L2258 because it's not equal x*7

ekeeke commented 2 years ago

Is it fix correct? https://github.com/ekeeke/Genesis-Plus-GX/blob/master/core/vdp_ctrl.c#L2258 because it's not equal x*7

This is part of the hack mentionned in initial post to get Clue/Microcosm games working: indeed, these 2 games appear to have a big VRAM update (done with CPU writes instead of DMA as it should have been) interrupted by VINT, which screws the code register by updating VDP registers and make all the further writes to VRAM invalid when the interrupted routine continues its processing. Adding 2 M-cycles (less than one cpu cycle) on every invalid access was the minimal value I found to work in order to get sufficient delay but it is indeed not accurate at all (and does not happen on real hardware), as said above, this is hack (that I would like to get ride of by implementing accurate refresh delays).

Silanda commented 2 years ago

FWIW, Tippek's fix seems to alleviate a hitherto unreported issue with graphic corruption before the bonus stages in the PAL version of Art of Fighting, so it might be another game affected by this. Interestingly, neither the US version or the PAL version run in NTSC mode exhibit the problem.

Running with the CPU speed at 125% also stops the glitching.

ekeeke commented 9 months ago

Basic emulation of periodic 68K cartridge/expansion bus refresh delay added in https://github.com/ekeeke/Genesis-Plus-GX/commit/47761b9b8fd35eabd7b3ff3dc5ab0f54f1d95133

Implementation is a little different from Tippek's original proposition as it gave one-cycle error for many instructions when running this test ROM: https://gendev.spritesmind.net/forum/viewtopic.php?f=8&t=3321 but otherwise it's very similar.

This also gives very close results to real hardware when running Sik's 68K benchmark test ROM (real hardware shows 88AD / 88AE) image

Those two test ROMs are attached below for future references. test_inst_speed.zip 68kbench.zip

As expected, this fixes https://github.com/libretro/Genesis-Plus-GX/issues/205

https://bitbucket.org/eke/genesis-plus-gx/issues/444/crashes-in-pacman-2-new-adventures-pac-jr was actually fixed by https://github.com/ekeeke/Genesis-Plus-GX/commit/405c54555ece6b6f6b7b61afa721b4432af9c283

FIFO access delay timing hacks (previously required by Microcosm and Clue to compensate lack of 68k bus refresh delays emulation) were reverted in https://github.com/ekeeke/Genesis-Plus-GX/commit/c04a9426b7c78942c3b20a16a802b066101660d4

Without the hacks, Microcosm still boots fine and Clue also in most cases, although the latter can still occasionally display corrupted tiles depending on when or how START button is pressed to access title screen (from experiment, it seems that holding START until title screen appears is always fine but repetitively smashing the START button can cause graphical issues to occur). It seems that additional RAM refresh delays are required to be safe so I leave this issue opened until this is properly implemented.