Closed viciious closed 10 months ago
From Luke Usher, emudev for (among other things), ares-
Okay so this romhack uses the 32x in a very weird and unusual mode. The 32X has a very different memory map than the stock megadrive, but the memory map types can be swapped between by toggling the RV bit of the 32x. When the 32X is used with megadrive memory map (RV = 1), interrupts and exceptions now point to unmapped memory so you can't use them; so this patches the game to poll for vblank instead of using the interrupt handler. This means that any unexpected interrupt or exception will completey lock up. Aditionally, there's an edge case bug described in the 32X hardware manual that this may run into: when accessing the PSG hardware from the Z80 (which this game does), if the Z80 bank register is configured to access megadrive rom (which is most likely is: in order to read the audio data), the 32X may misunderstand the bus state and corrupt registers. as well as this, it can also cause the m68k to fetch invalid data from rom
When Z80 accesses PSG, make sure that the bank settings at access time are values outside of the $000000-$3fffff and $84000-9fffff ranges. After Z80 accesses PSG, the MegaDrive internal circuitry bank automatically becomes $C000XX. However, after the Z80 access is over, the currently set bank values will output to the 68000 side, and here, there will be a period of time existing during which the signial that displays access on the 68000 side will be in an active mode. With MegaDrive, there would be no problems; however, 32X compared to 68000 has a much faster reaction. Therefore, it would react to the above state, and if bank settings are in the When Z80 accesses PSG, make sure that the bank settings at access time are values outside of the $000000-$3fffff and $84000-9fffff ranges, 32X will misunderstand that access to the adapter has occured. And soon after 68000 accesses this area, the misunderstood data could be passed to 68000. In addition, depending on the address at that time, the contents of 32X registers could be damaged. Also, please note that because this phenomenon could occur at very different frequencies depending on the MegaDrive individual differences, the problem may not occur when the software is being checked
^ ~ 32X Technical Documentation
I very much suspect Golden Axe could be hitting this. patching the rom to disable the sound driver could confirm, but I don't have a physical 32X I can test on at the moment...
the issue mostly is that the 32X hardware is much higher clocked than the megadrive hardware, and such what is not an issue for normal megadrive behavior (the time taken for the bus to become stable) is observable by the 32X hardware, so it may cause incorrect reads/writes to the busses based on unstable bus state. The result is that incorrect data may be placed on the m68k bus by the 32x, meaning even instructions may get corrupted,, and in some cases, the 32x observes writes and state gets corrupted.
.. there's also a chance that even if we test on real hardware, this particular issue will never occur on the specifc MD/32X we have. Also the 32Xs need to be tested in multiple megadrives, because this timing bug is a megadrive issue, not a 32X one. It just happens that the megadrive components are slow enough that it's not observed.
Hi @viciious, @HeroponRikiBestest
I think we tried most of the options. Most of the testing was done by alacron_cinco and some by Mr_Boo_Berry using multiple mega drives/flashcards etc. I don't own a 32X myself unfortunately.
Options already explored (still mistakes could have been made here too):
A big problem is ofc as mentioned if the 68000 crashes you cant make an exception handler to capture it due to the vector rom mapping as mention by Luke.
It seems to work in MiSTer with some issues at the character profile screens and I guess the credits screen. But I think that is an issue with the MiSTer implementation displaying a black background when the 32x is blanked instead of the mega drive background color.
As per Luke's suggestion the next logical step would be to permanently halt the Z80 and/or disable all sound subroutines. Padding to is still a requirement on certain flashcart models, please refer to this thread for more information: http://gendev.spritesmind.net/forum/viewtopic.php?t=2732
Sorry for the late reply. I already tried disabling the sound driver communication routines on the md side before. That did not work.
I padded the output file to the next MB boundary. Then I tried everything mentioned below incrementally:
jr -2
to run in an infinite loop
Still locks up.md/system/marscomm.s
by changing routines __mars_comm_init
and __mars_comm
to return directly.
Still crashes, but only when gameplay starts (either attract mode or actual gameplay). init
in file md/boot.s
. Then it runs on real hardware with a 32x attached (it will be disabled ofc).sleep
as the first instruction. If sleep works there should be no bus activity I think.
Although the 32x manual says you can't use sleep so maybe this will fail in any case.
Still crashesSeems that just having the 32X enabled causes a crash...
For reference: Here is a comment from hangemhighhilton who claims it runs on their original hardware configuration.
I've been using a Krikzz Everdrive x3, plugged into a model 1 "High Definition Graphics" Genesis with Signetics 68k cpu, model 1 Sega CD and early model 32x. Not sure if there were different models of 32x besides different region models but I know mine was manufactured quite early.
For reference: Here is a comment from hangemhighhilton who claims it runs on their original hardware configuration.
I've been using a Krikzz Everdrive x3, plugged into a model 1 "High Definition Graphics" Genesis with Signetics 68k cpu, model 1 Sega CD and early model 32x. Not sure if there were different models of 32x besides different region models but I know mine was manufactured quite early.
The guy is yet to post a video though ;)
The guy is yet to post a video though ;)
True but I have seen reports with differences in stability. I have bought a PAL 32X since and mine crashes really fast. But for some people it only crashes when actually starting the game after character select (consistently). I tested with both ED Pro and x3 with the same results.
I don't think I'm able to fix this. I lack the knowledge and frankly also time/motivation at this point. I still learned a lot of new things making this patch at least... so it was worth it to me. Maybe next year when I have some more time I will explore the 32X/SH2 properly and on real hardware for some new projects.
Btw I actually got the idea for this hack after a comment by you about the RV bit that I got indirectly (i think from Relikk) when implementing the 32X+ patch for Mortal Kombat 2.
Just an update for completeness sake.
Took a brief look at the code again. And one of the problems on my 32X was this: https://github.com/viciious/32XDK/wiki/Bugs-and-quirks#about-rom-read-when-rv1. I made some changes to prevent crashes caused by that specific issue.
But it still crashes on the 32X side with an illegal instruction at address 0 at random on the master cpu. No clue what causes this... If it was a coding error like a stackoverflow or whatever I would expect emulators to have this behavior as well but they seem to not have this issue.
Ok it was partially a programming error lol (disclaimer: I'm not a C programmer in daily life). For some reason the value read from the COMM registers on the 32X side get corrupted in some cases. I'm not sure why but I just made a workaround for that. It seems to work well now on my PAL version at least. Did not do a full playthrough though.
I need some help testing especially on the NTSC version as it has less cpu cycles per frame but also in general. Here is a patch: https://mega.nz/file/HTAEEJqI#Y_dolb-XficfAcnfxlhA0kMEzhP0pgZkK8DK_UONgEU
Tested on an NTSC console and the game worked fine, at least the first level did. One thing I noticed is that the backgrounds don't scroll smoothly. I suppose you're not using the screen shift register so the backgrounds only scroll at 2px increments.
Cool thanks for testing!
I actually do set the shift register here: https://github.com/jvisser/golden-axe-32x-edition/blob/067900fc96d134a10fae5fd9c16b6a4c89dd73be/src/mars/command/map.c#L298 It seems to work on my console although I have a really bad scart to hdmi adapter so its a blurry distorted mess on my monitor, so maybe it's just not visible enough. When I disabled the shift reg it looked like it stuttered more.
The code uses a single framebuffer which is a bit unusual I think. It really depends on finishing the rendering in the vblank window. But it only renders a single 2 pixel column for horizontal scrolling and the actual lines scrolled for vertical scrolling per frame. It prepares the pixel data in a ram buffer during active display. The ram buffer is then transferred in the vblank period. If the vblank part of the routine runs out of time it would cause the wrong framebuffer to display so I don't think that is the issue. Maybe it drops frames due to the vsyncwait being too late on NTSC? I made the vsync wait routine to skip a full frame when it is called when in vblank period, Maybe just removing that part will fix it. But then I would expect the framerate of the genesis side to drop too (depending on if there was any scrolling). The code is not very readable I admit :/.
I made a patch where the vsync wait routine does not wait for the next frame if called inside vblank period. Could be a bit flacky depending on the timing: https://mega.nz/file/jWY0lZAR#7wiRrlUzJcjfp6F1VKPxxj-glJW1e808KSxehKhZEpY
I think this is also an issue but I really couldn't notice it on my screen: https://github.com/viciious/32XDK/wiki/Bugs-and-quirks#shift-bit-precaution.
Really grateful for the 32xdk pages and wiki btw without those I would never have found these issues! But I actually only recently discovered the wiki part. Maybe it's useful to print a reference to it in the readme?
Ah, if you do use the shift register, then what happens is indeed it occasionally misses a vblank and stutters as the result.
But why did you choose the copy-from-SDRAM approach to begin with? It offers no timing advantage over writing directly to the VRAM. Also you don't need to tie your screen updates to vblanks at all since the hardware handles double-buffering for you.
I think I was just experimenting at that point to find a solution that would be fast enough to keep in sync with the mega drive (I still use the md layers in limited ways)
The md code sets the scroll values at the end of all processing iirc. So I have the remaining frame time (about half a frame on average iirc) to update the 32X display.
I first just rendered brute force the whole screen but that was too slow even on emulators. Probably also because I used word writes to vram. I was not sure dword writes were possible on hardware. I think it is never explicitly mentioned in the manual.
But you are right, I should use the double buffer.
Dword writes are possible but they don't offer very little speed advantage over word writes, if any at all.
Ah well, whatever works best in your case: if the copy-from-SDRAM works for you, that's fine :)
Excellent work on ironing out the quirks of the 32X architecture, I tested on both PAL and NTSC Model 1 Megadrives and works 95% of the time. Oddly I found the initial boot would lock up with sound still playing, but 2nd/3rd boot works no issues. Possible a random seek/write on the spinning logo section. This was with Patch 2, but played to stage 5 no issues at all. I love to see these homebrew updates to show what the 32X Tower of Power combo could have achieved, superb.
Thanks for testing. Maybe it's issues with the Z80 as described here: https://github.com/viciious/32XDK/wiki/Bugs-and-quirks#z80. These did not seem to manifest on my system though.
The patch also works with the existing MD+ patch btw which is kinda cool.
It could be that if you try the MD+ version you have less boot issues due to the Z80 not being used anymore for the music. That would verify if the Z80 is the issue.
Although it's not perfect yet I made a new release.
I suppose the original issue is now fixed. Thanks for your hard work!
Oh sweet. Glad to see development has resumed on this. I'll have to flash me a repro cart and test it on my 32X with my Gen1,Gen2, CDX and heck even MegaSG & Polymega. Hope progress continues! Hope to see all the arcade stuff and hope exclusive 32X stuff like a new 3 player mode, SegaCD OST reading from the Sega Arcade Classics CD and more!
Do you expect this to work with Pyron's color enhancement and/or the MSU-MD patches?
Congrats with the first public release!
You mention that the hack doesn't work on real hw, so here's a few ideas as to what might be the culprit: 1) the ROM has to be padded to a multiple of 512KiB (128KiB is also worth a try) - real hw is really bitchy about that 2) cache incoherence between master and slave CPUs on the 32X 3) unaligned memory access 4) the RV bit value being off