don't click here

Sonic Crackers (Stadium) Hack?

Discussion in 'Engineering & Reverse Engineering' started by Retro_Stew, Mar 13, 2014.

  1. Caverns 4

    Caverns 4

    Member
    346
    0
    16
    Sonic: Retold
    What would all of this mean in the context of putting this fix into the disassembly of Crackers? I've messed with the game a bit on Regen, but the crashing has been bugging me.
     
  2. MarkeyJester

    MarkeyJester

    Time to Grow Up. Resident Jester
    2,122
    248
    43
    Japan
    Well, that doesn't actually "fix" the problem, it more avoids it. Lemmy explain why I gave the instructions to avoid rather than to 100% fix.

    The Z80 sound driver reads DAC samples through a window into 68k memory (I.e. directly from the ROM) in $8000 byte sections (mapped at offset $8000 - $FFFF). Upon start up, the sound driver sets up the YM2612, PSG, etc, and the bank window address. It does this by sending a bank slot address (that is a byte long) into a port at offset $6000 one bit at a time. It uses the "h" and "l" registers (paired together as "hl") to access the port, meaning "hl" is now set to $6000.

    After the setup is run, it goes into a DAC (DPCM) playback loop where it'll read the registers "d" and "e" (paired together as "de") as a DAC size counter, if "de" is set to $0000, then there are no bytes to decompress and flush out (I.e. no sample). What the setup doesn't do, is clear the registers "d" and "e", so "de" contains an unknown value (that unfortunately for us, isn't $0000). So it continues thinking it's playing a sample, the "hl" register pair is used as the bank window offset, but that isn't setup either, it's still set to 6000 when it set the bank address. So it tries loading byte after byte from 6000 onwards, decompressing in a loop. The problem is, around the 6001 - 7FFF region, is a space the Z80 is not allowed to access on the Mega Drive. However, the Z80 seems to have success reading the data from 6001 all the way up to somewhere around 7E00 without crashing, but of course, crashes eventually somewhere around 7E00 - 7FFF (I cannot pin point exactly which offset, but that's irrelevant, it shouldn't be accessing data around the 6001 - 7FFF region anyway). Which is why it takes a while and manages to show a bit of the SEGA logo before crashing.

    tl;dr, ensuring the "de" register pair is cleared on startup, will fix the issue (offset E5 the instruction 11 00 00 (ld de,00000h) should be placed).

    But performing that fix on a binary ROM is rather difficult, inserting instructions can be difficult without unaligning data/pointers/etc. For the 68k, you can get away with at least jumping to an unused padded section containing the inserted instructions there, and then jump back. But for the Z80 data on the 68k ROM, it's not as easy. On a disassembly, it should be pretty much a one instruction insert (provided the disassembly is fully complete, and all pointers/instructions/referrences are linked up for assembly). The fix I posted before is simply a set of instructions for the 68k, telling it to play a music track, wait a while, and then stop the track before it makes a sound, thus causing the Z80 to clear it's "de" register by itself, thus avoiding it.

    If you want to fix it in the context of a disassembly, then use the clearing "de" method, not the previous method.
     
  3. ValleyBell

    ValleyBell

    Tech Member
    243
    14
    18
    researching PC-98/X68000 sound drivers
    I'm a bit late, but here is the fix for the Z80 driver:
    At offset 0052B7, replace 21 05 1C 7E with 11 00 00 00.

    Disassembly:
    Code (Text):
    1. 00C6    3E 04       LD  A, 04h      ; start with DAC bank 04 (ROM offset 020000)
    2. 00C8    32 05 1C    LD  (1C05h), A  ; save to DAC Bank slot
    3. 00CB    21 05 1C    LD  HL, 1C05h
    4. 00CE    7E      LD  A, (HL)     ; load again
    5. 00CF    21 00 60    LD  HL, 6000h   ; load Bank Switch address
    becomes
    Code (Text):
    1. 00C6    3E 04       LD  A, 04h
    2. 00C8    32 05 1C    LD  (1C05h), A  ; save to DAC Bank slot
    3. 00CB    11 00 00    LD  DE, 0000h   ; initialize DE (remaining DAC bytes to play)
    4. 00CE    00      NOP
    5. 00CF    21 00 60    LD  HL, 6000h
    It was a bit of luck that they had some redundancies in the code. But else I would've placed the code in the unused slots of the sound priority table, I guess.
     
  4. Retro_Stew

    Retro_Stew

    French Twitch Gamer Member
    1,644
    0
    16
    France
    Twitch channel
    Thanks a lot, guys! I'll try to flash my Eprom again and make some tests.