don't click here

Sonic 3 Z80 Sound Driver Disassembly

Discussion in 'Engineering & Reverse Engineering' started by kram1024, Mar 8, 2011.

Thread Status:
Not open for further replies.
  1. kram1024

    kram1024

    Researcher / Hacker Oldbie
    63
    1
    6
    at home, duh
    Part of the new Team Revamped; Kraminator Special Series disassemblies; Sonic 3 Sound Driver porting guides; KENS 1.5; smps studio; various non-sonic related things
    You probably saw in an updated reply a ways back that I was having trouble with esreal's sonic3 driver port related to music, so I am disassembling the sonic 3 driver and I like what I see. Expect the howto section to utilized my disassembly in both sonic1 and sonic2 and I learned some new things about z80 pointers, they are 15 bit byte swapped, not 16 bit absolute byte swapped and are relative to the bank they are in. They work like gameboy pointers in a way. The ones you have mostly worked with so far have the high 16th bit set, which I have no idea what it is for though the sonic 3 driver seems to unset it prior to reading the offset.

    Well, did you notice that every once in a while a dac sample pointer doesn't have that big set? This is why I say we have not a 16 bit absolute pointer, but a 15 bit bank relative with an unknown high bit flag.

    I am getting close to ready to release the asm form of the driver.

    In other words we had it wrong but still got done what we needed to. The music should be aligned to a location in 8000h bank space, not to a physical loation in the rom itself, yet we did that unknowingly by aligning to the rom, though now we know. Want to add new music or sounds outside a bank? simply add a new bank and align to that (the pointers may not match the lower half of the rom address but they are legit to the z80)

    Update: This thing is totally amazing, remember how the sonic 1 driver and sonic 2 driver had to be reloaded via the interrupts? I just saw Z80 interrupt code in the sonic 3 driver that does just that. And even more, the driver even uses space in the same bank it is in to copy and execute Z80 code and reset the Z80 via the Z80 which is very weird.

    You can now download all currently up-to-date versions of the Sonic 3 Driver disassembly on Mediafire via my Mediapro account:Sonic 3 Sound Driver Disassembly files
     
  2. Alriightyman

    Alriightyman

    I am back... from the dead! Tech Member
    357
    11
    18
    Somewhere in hot, death Florida
    0101001101101111011011100110100101100011 00000010: 0101001100000011 01000101011001000110100101110100011010010110111101101110
    Sounds really freaking cool.
    So, is there a limit to how many banks that can be used? I need to look into z80 coding...
     
  3. Andlabs

    Andlabs

    「いっきまーす」 Wiki Sysop
    2,175
    1
    0
    Writing my own MD/Genesis sound driver :D
    The Z80 bank pointer is the high 9 bits of the 24-bit 68000 address, so you don't have a limit as to what the Z80 can access, but a MD ROM can only safely go up to 4MB ($4xxxxx) on a Genesis (if you try to go up to 10MB ($Axxxxx), you'll get clobbered by the Sega CD and/or 32X; at 10MB is the Z80 area and I/O area and above that... you kknow the deal).

    Keep in mind Sonic 3 has SRAM, and most SRAM mappers will just hide the upper 2MB ($2xxxxx/$3xxxxx) of the cart — I'm not sure how Sonic 3 (2MB) works with S3K (total 4MB), and I know Phantasy Star IV (3MB) has a mapper that switches between ROM and SRAM...

    Because of the 9 bits, each Z80 bank is 32KB, so that's your hard limit on filesize.
     
  4. kram1024

    kram1024

    Researcher / Hacker Oldbie
    63
    1
    6
    at home, duh
    Part of the new Team Revamped; Kraminator Special Series disassemblies; Sonic 3 Sound Driver porting guides; KENS 1.5; smps studio; various non-sonic related things
    indeed it does, why else do we have various sizes of gameboy games? Isn's a gameboy CPU just simply a modified Z80?

    By the way, here is a small taste of what is around the corner:

    <div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>Bank0:00D3 loc_D3: ; ...
    Bank0:00D3 ld (byte_1B43+24BFh), a
    Bank0:00D6 nop
    Bank0:00D7 ld a, c
    Bank0:00D8 ld (byte_1B43+24C0h), a
    Bank0:00DB ret
    Bank0:00DB ; End of function sub_B5
    Bank0:00DC DacBankSetup: db DacBank0 ; 0 ; ...
    Bank0:00DC db DacBank0 ; 1
    Bank0:00DC db DacBank0 ; 2
    Bank0:00DC db DacBank0 ; 3
    Bank0:00DC db DacBank0 ; 4
    Bank0:00DC db DacBank0 ; 5
    Bank0:00DC db DacBank0 ; 6
    Bank0:00DC db DacBank0 ; 7
    Bank0:00DC db DacBank0 ; 8
    Bank0:00DC db DacBank0 ; 9
    Bank0:00DC db DacBank0 ; 10
    Bank0:00DC db DacBank0 ; 11
    Bank0:00DC db DacBank0 ; 12
    Bank0:00DC db DacBank0 ; 13
    Bank0:00DC db DacBank0 ; 14
    Bank0:00DC db DacBank0 ; 15
    Bank0:00DC db DacBank0 ; 16
    Bank0:00DC db DacBank0 ; 17
    Bank0:00DC db DacBank0 ; 18
    Bank0:00DC db DacBank0 ; 19
    Bank0:00DC db DacBank0 ; 20
    Bank0:00DC db DacBank0 ; 21
    Bank0:00DC db DacBank0 ; 22
    Bank0:00DC db DacBank0 ; 23
    Bank0:00DC db DacBank0 ; 24
    Bank0:00DC db DacBank0 ; 25
    Bank0:00DC db DacBank0 ; 26
    Bank0:00DC db DacBank1 ; 27
    Bank0:00DC db DacBank1 ; 28
    Bank0:00DC db DacBank1 ; 29
    Bank0:00DC db DacBank1 ; 30
    Bank0:00DC db DacBank1 ; 31
    Bank0:00DC db DacBank1 ; 32
    Bank0:00DC db DacBank1 ; 33
    Bank0:00DC db DacBank1 ; 34
    Bank0:00DC db DacBank1 ; 35
    Bank0:00DC db DacBank1 ; 36
    Bank0:00DC db DacBank1 ; 37
    Bank0:00DC db DacBank1 ; 38
    Bank0:00DC db DacBank1 ; 39
    Bank0:00DC db DacBank1 ; 40
    Bank0:00DC db DacBank1 ; 41
    Bank0:00DC db DacBank1 ; 42
    Bank0:00DC db DacBank2 ; 43
    Bank0:00DC db DacBank2 ; 44
    Bank0:00DC db DacBank2 ; 45
    Bank0:00DC db DacBank2 ; 46
    Bank0:00DC db DacBank2 ; 47
    Bank0:00DC db DacBank2 ; 48
    Bank0:00DC db DacBank2 ; 49
    Bank0:00DC db DacBank2 ; 50
    Bank0:00DC db DacBank2 ; 51
    Bank0:00DC db DacBank2 ; 52
    Bank0:00DC db DacBank2 ; 53
    Bank0:00DC db DacBank2 ; 54
    Bank0:00DC db DacBank2 ; 55
    Bank0:00DC db DacBank2 ; 56
    Bank0:00DC db DacBank2 ; 57
    Bank0:00DC db DacBank2 ; 58
    Bank0:00DC db DacBank2 ; 59
    Bank0:00DC db DacBank2 ; 60
    Bank0:00DC db DacBank2 ; 61
    Bank0:00DC db DacBank2 ; 62
    Bank0:00DC db DacBank2 ; 63
    Bank0:00DC db DacBank2 ; 64
    Bank0:00DC db DacBank2 ; 65
    Bank0:00DC db DacBank2 ; 66
    Bank0:00DC db DacBank2 ; 67
    Bank0:00DC db DacBank2 ; 68
    Bank0:0121 ; =============== S U B R O U T I N E =======================================
    Bank0:0121 sub_121: ; ...
    Bank0:0121 call sub_7E8
    Bank0:0124 call sub_1A2
    Bank0:0127 loc_127: ; ...
    Bank0:0127 call sub_9B1
    Bank0:012A call sub_862
    Bank0:012D call sub_8C6
    </div>
     
  5. Tiddles

    Tiddles

    Diamond Dust Tech Member
    471
    0
    0
    Leicester, England
    Get in an accident and wake up in 1973
    S3K works pretty much the same as PS4 as you describe it - SRAM is banked in over the mapped location of the S3 ROM to save and load.

    This bit me with Sonic 3 Complete. I was trying to save space in the easy-to-edit-without-retooling-the-build-process S&K half by reading all the DAC and SFX from the Sonic 3 half. This worked absolutely fine on emulators, but on my flashcarts I would often get brief audio pops and crackles whenever game data got saved. Worst of all, at the end of the game after Doomsday, the sound driver would sometimes just completely fail, frequently causing the ending music to play at utterly manic speed, followed by the game halting not long after. And I didn't notice for ages, as I normally test out of the level select rather than save screen, so the SRAM banking never happened.

    For that reason I'd suggest trying to keep sound data below the $200000 watermark, unless someone more knowledgable than I am can suggest a workaround. That said, music tracks themselves and the S3-only DAC samples play back fine from the second half, as they always did in S3K, so it doesn't necessarily apply to everything.
     
  6. Spanner

    Spanner

    The Tool Member
    Just use a file sharing service such as MediaFire or MegaUpload. You might also want to create an exported ASM file for those who do not have IDA installed.
     
  7. jman2050

    jman2050

    Teh Sonik Haker Tech Member
    634
    4
    18
    I'm not sure how viable this would be, but perhaps a check can be added in the driver to see if SRAM is currently being banked and to simply suspend itself until its done?
     
  8. kram1024

    kram1024

    Researcher / Hacker Oldbie
    63
    1
    6
    at home, duh
    Part of the new Team Revamped; Kraminator Special Series disassemblies; Sonic 3 Sound Driver porting guides; KENS 1.5; smps studio; various non-sonic related things
    I agree with you on that, and it should be very easy to do as long assuming the SRAM banker is in the sound driver itself and the 68k simply just feeds data to the sound driver in another address.

    You can now download all currently up-to-date versions of the Sonic 3 Driver disassembly on Mediafire via my Mediapro account:Sonic 3 Sound Driver Disassembly files
     
  9. nineko

    nineko

    I am the Holy Cat Tech Member
    6,298
    475
    63
    italy
    Alternatively you can send me an email and I will upload everything on my webspace. Whatever is easier for you.

    Of course this only applies if the size of your files is greater than 50kB, because for files smaller than that you can use the attachment system here on the forum, with the "browse" and "upload" buttons.
     
  10. kram1024

    kram1024

    Researcher / Hacker Oldbie
    63
    1
    6
    at home, duh
    Part of the new Team Revamped; Kraminator Special Series disassemblies; Sonic 3 Sound Driver porting guides; KENS 1.5; smps studio; various non-sonic related things
    Now I am working on a split disassembly of the driver from the work I just completed.
     
  11. Andlabs

    Andlabs

    「いっきまーす」 Wiki Sysop
    2,175
    1
    0
    Writing my own MD/Genesis sound driver :D
    Oi. Looked at the IDB:
    • The only two named functions are the two Z80 bank switch functions. The comments are 100% useless — they just describe what each opcode does. How well do you understand this driver?
    • By using signed constants by default, flags look rather weird... like with the PSG markers — that last value with the high bit set is also a volume whose value is the lower nibble...
    • Some addresses are still literal in the driver code...
    I could probably fix all of these if I could understand how you got IDA to look the way it did... + - (or just do another one :/ )  
     
  12. kram1024

    kram1024

    Researcher / Hacker Oldbie
    63
    1
    6
    at home, duh
    Part of the new Team Revamped; Kraminator Special Series disassemblies; Sonic 3 Sound Driver porting guides; KENS 1.5; smps studio; various non-sonic related things
    the high bits I spoke of earlier, are in pointers, not in the PSG samples.
     
  13. Andlabs

    Andlabs

    「いっきまーす」 Wiki Sysop
    2,175
    1
    0
    Writing my own MD/Genesis sound driver :D
    Ok I think I didn't get what I meant across:

    Code (Text):
    1. Bank0:160D&nbsp;&nbsp;&nbsp;&nbsp; PSGA7:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;db&nbsp;&nbsp; 00h,&nbsp;&nbsp;02h,&nbsp;&nbsp;02h,&nbsp;&nbsp;02h,&nbsp;&nbsp;03h,&nbsp;&nbsp;03h,&nbsp;&nbsp;03h,&nbsp;&nbsp;04h; ...
    2. Bank0:160D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; db&nbsp;&nbsp; 04h,&nbsp;&nbsp;04h,&nbsp;&nbsp;05h,&nbsp;&nbsp;05h, -7Dh <-- this value here should not be signed
    I'd still like to know how much of the sound driver you understand...
     
  14. kram1024

    kram1024

    Researcher / Hacker Oldbie
    63
    1
    6
    at home, duh
    Part of the new Team Revamped; Kraminator Special Series disassemblies; Sonic 3 Sound Driver porting guides; KENS 1.5; smps studio; various non-sonic related things
    <div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>Begin_SegaPCM:
    call Z80BankSwitch
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    ld hl, SegaPCM+8000h - SegaPCM ; Set Sega PCM location
    ld de, 5E2Fh ; Set Sega PCM size to $5E2F
    ld a, 2Ah ; '*' ; Set Sega PCM sample rate
    ld (byte_1B43+24BDh), a ; Load it!
    nop
    </div>
    you forgot that I also labeled that one and provided comments on it that set the size value for the sega PCM as well as its sample rate. Other labels were lost by accident in the garbage collection process and besides I know less about IDA itself than the driver, though I thought that most PCM samples were signed and that the psg was somewhat similar to that of a gameboy thus if the sample is a pcm then it is signed, but later found out that unsigned pcms also exist, besides I am working on a split disassembly anyway so if you have a problem with signed psg data, then in the split version it would be impossible to see it.

    both intel x86 processors and the z80 are little endian processors and the 68k is a big endian processor

    little endian:
    add <destination>,<source>

    big endian:
    add <source>,<destination>

    notice the difference.

    little endian:
    67452301
    big endian:
    01234567

    notice the difference.

    the comments may seem useless to you, but they are how I followed the flow of the driver and saw how it ticks.
    Edit: I just realized how closed minded I was with this by wrapping whitespace. It made it so that all my RAM labels were lost and thanx to Andlabs discovering these oddities, I just located a few critical sound routines because of the usage of addresses 0x1C0C, 0x1C08, 0x1C0A, and 0x1C0B
     
  15. GerbilSoft

    GerbilSoft

    RickRotate'd. Administrator
    2,971
    76
    28
    USA
    rom-properties
    Endianness has nothing to do with the dest/src syntax. GNU assembler on x86 uses src,dest; PowerPC, MIPS, and ARM assembler use dest,src1,src2.

    The second part is correct, but needs some clarification:

    If you have a 32-bit integer 0x12345678 at address $0, it's stored in memory like this on big-endian systems:

    Code (Text):
    1. 000000: 12 34 56 78
    and like this on little-endian systems:

    Code (Text):
    1. 000000: 78 56 34 12
    Historically, little-endian has been used on processors that evolved from 8-bit CPUs, whereas big-endian has been used on processors that were initially 16-bit or 32-bit. (A notable exception is the 6800 series, which is an 8-bit CPU, but handles 16-bit integers using big-endian format.)
     
  16. kram1024

    kram1024

    Researcher / Hacker Oldbie
    63
    1
    6
    at home, duh
    Part of the new Team Revamped; Kraminator Special Series disassemblies; Sonic 3 Sound Driver porting guides; KENS 1.5; smps studio; various non-sonic related things
    actually when comparing asw 68k and asw z80 it does matter what order the operands are in gerbilsoft.
     
  17. GerbilSoft

    GerbilSoft

    RickRotate'd. Administrator
    2,971
    76
    28
    USA
    rom-properties
    You completely missed the point. The order of operands is dependent on the assembly language dialect in use. It is *not* dependent on the fact that 68000 is big-endian or Z80 is little-endian. It's entirely possible to write a 68000 assembler that uses dest,src format, and a Z80 assembler that uses src,dest format.
     
  18. kram1024

    kram1024

    Researcher / Hacker Oldbie
    63
    1
    6
    at home, duh
    Part of the new Team Revamped; Kraminator Special Series disassemblies; Sonic 3 Sound Driver porting guides; KENS 1.5; smps studio; various non-sonic related things
    On another note, I have just uncovered some more things, Wiki Sysop, do you mind checking the IDB again? (download again, the link has changed)
    or to clarify, the IDB file has been updated (still might have a few bugs in it, but a lot has changed)
     
Thread Status:
Not open for further replies.