Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The hack doesn't work on real hardware #1

Closed
viciious opened this issue Sep 5, 2022 · 19 comments
Closed

The hack doesn't work on real hardware #1

viciious opened this issue Sep 5, 2022 · 19 comments
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@viciious
Copy link

viciious commented Sep 5, 2022

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
@HeroponRikiBestest
Copy link

HeroponRikiBestest commented Sep 5, 2022

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.

@viciious viciious changed the title Getting the ROM to work on real hw The hack doesn't work on real hardware Sep 5, 2022
@jvisser
Copy link
Owner

jvisser commented Sep 5, 2022

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):

  • Inspecting the object files for alignment issues by printing the addresses of related symbols
  • Modify the Gens emulator to detect alignment issues on the SH2 (this is not emulated by any emulator atm I think)
    • There were none (but maybe I missed a case)
  • Installing a custom exception handler for all vectors for both SH2's that display a (different) colored screen
    • Made test roms to verify the handler worked by using a trapa instruction (this worked on hardware)
    • When running the game it resulted in a black screen at crash time
  • Setting a different background color on the genesis side and 32x side between steps of the map routines
    • Resulted in a crash and black screen (no colored display)
  • Break out of the code at different points during map loading (to the point of it not communicating with the 32X at all)
    • We suspected this was the cause due to a persistent crash when starting gameplay on alacron_cinco's 32x but it seems to crash at different points for different people
    • Resulted in a crash and black screen
  • Removed/disabled all the 32X code and run it on my standalone mega drive
    • This ran the game correctly although without a visible background ofc
  • Cache issues (these are emulated correctly on Ares)
    • There were some issues with mutable data used by both cpu's (palette). But this just resulted in a wrong or no palette set but should be solved.
  • Disabling all sound routines in all combinations
  • Halt the Z80 while RV=0 (this is enabled in the current source)
  • Padding the ROM file to 2MB (to your suggestion)
    • Same issues
  • Wait for RV to become the desired state after an RV change request
    • Resulted in a crash and black screen
    • This is not in the current source but maybe it should be

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.

@viciious
Copy link
Author

viciious commented Sep 6, 2022

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

@jvisser
Copy link
Owner

jvisser commented Sep 10, 2022

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:

  1. Replacing the Z80 driver completely with the following program jr -2 to run in an infinite loop
    Still locks up.
  2. Disabled the 32x communication program on the mega drive side in file 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).
  3. Tested the above by running in mega drive mode by patching the reset vector to point to init in file md/boot.s. Then it runs on real hardware with a 32x attached (it will be disabled ofc).
  4. Modified the SH2 program's entry point to immediately run in an infinite loop.
    Still crashes.
  5. Modified the SH2 program's to run 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 crashes
  6. Removing all writes to the 32X communication registers from the Mega Drive program
    Still crashes

Seems that just having the 32X enabled causes a crash...

@jvisser jvisser added bug Something isn't working help wanted Extra attention is needed labels Sep 11, 2022
@jvisser
Copy link
Owner

jvisser commented Nov 6, 2022

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.

@viciious
Copy link
Author

viciious commented Nov 6, 2022

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 ;)

@jvisser
Copy link
Owner

jvisser commented Nov 10, 2022

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.

@jvisser
Copy link
Owner

jvisser commented Dec 29, 2023

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.

@jvisser
Copy link
Owner

jvisser commented Dec 30, 2023

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

@viciious
Copy link
Author

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.

@jvisser
Copy link
Owner

jvisser commented Dec 30, 2023

Cool thanks for testing!

I actually do set the shift register here:

MARS_VDP_SHIFTREG = horizontal_scroll;
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?

@viciious
Copy link
Author

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.

@jvisser
Copy link
Owner

jvisser commented Dec 30, 2023

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.

@viciious
Copy link
Author

viciious commented Dec 31, 2023

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 :)

@NXGMT
Copy link

NXGMT commented Dec 31, 2023

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.

@jvisser
Copy link
Owner

jvisser commented Dec 31, 2023

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.

@viciious
Copy link
Author

I suppose the original issue is now fixed. Thanks for your hard work!

@SONICR2K
Copy link

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!

@Gabriel-Goldsztajn
Copy link

Do you expect this to work with Pyron's color enhancement and/or the MSU-MD patches?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

6 participants