don't click here

Sonic 2 ASM68K

Discussion in 'Engineering & Reverse Engineering' started by OrionNavattan, Oct 13, 2022.

  1. Barely six months after I took my first steps into programming with the Sonic disassemblies, I am a month and a half into the process of putting together a new ASM68K-based disassembly of Sonic 2 that will target AXM68K with Z80 macros, (and once it is mature enough, ClownAssembler).

    The tools and methods required for this to happen for the most part already exist; AXM68K takes care of assembling the sound driver, and Natsumi's DualPCM_Compress should work to compress the sound driver and insert it in the ROM, simply by calling a Saxman compressor rather than a Kosinski compressor. The only thing that I can't solve on my own is automatically patching the Saxman decompressor, though that is simply due to my lack of knowledge of higher-level programming. I know just enough about C-style programming that from looking at its code, I believe that DualPCM_Compress could be modified to handle that.

    In general, my goal is to emulate the styling of Sonic 1 Hivebrain 2022, with double-intended code lines, indentation used to indicate label hierarchy, use of symbolic constants in place of raw immediate values wherever possible, splitting of the code into separate files instead of everything in one gargantuan file, macro-based sprite mappings, and SMPS2ASM music. I've changed nearly all variable and constant names and some subroutine names to match their names in Hivebrain 2022 or otherwise mimic their style (e.g., Chunk_table is now v_128x128_tlles), and a compatibility file will be included that should make it easier for code targeting Sonic 2 Git to be used. I've also changed the names of nearly all of the BINCLUDED files to ones that are more systematic and meaningful (e.g., Large wooden box from MCZ.bin > MCZ Crate.bin, Chopper blades for EHZ boss.bin > EHZ Boss Helicopter Blades.bin, etc). I plan to include documentation and comments from Sonic 2 Git (along with some from HB2022 where appropriate), as well as all of the bugfix conditionals.

    As of this moment, it is not yet buildable (but does complete the first pass), and still very much resembles the ancient pre-2007 disassemblies. Currently, the RAM Address definitions are finished, along with the various macros required for the REV02 optimization related changes and filename changes, labels for some major subroutines, and some documentation. The sound driver is currently in the form of a hexadecimal blob (a placeholder until I get around to getting the disassembled one working). Compressed music is incbined for the moment; uncompressed sounds are taken straight from the current Git disasm, and assembled using a minimal ASM68K port of SMPS2ASM that I put together (only those functions required to assemble for Sonic 2's driver are included. While the disasm is not yet buildable, everything is assembling to the correct offsets per the listing file, and the uncompressed music does appear to be assembling to the correct bytecode.

    Overall, this is admittedly something of a personal endeavor, being motivated primary by my dislike of both AS and the code styling of the Sonic 2 Git disassembly, but also by my desire to learn more about the internals of the game engine and of computer programming in general. But FWIW, if my passion project is something others might be interested in, I'll go ahead and publish it to GitHub. :>
  2. President Zippy

    President Zippy

    Zombies rule Belgium! Member
    Just do a C port like a sane person and let the '-O3' compiler flag do the rest :P

    All joking aside, this is a great idea that a lot of people could likely use when completed, and it's awesome that you went this hard on something you believe in!
  3. Hivebrain


    53.4N, 1.5W
    Good stuff. I'm glad to see you're using my disassembly as an inspiration. Funnily enough, a couple of months ago I tried converting it to use AS, which is when I discovered AS is awful and doesn't even work properly. I agree the current best plan is to switch to ClownAssembler if Clownacy continues working on it.
  4. To be fair, AS does have a couple of features that would be nice to have in ASM68K (namely functions, writing to the listing file on every pass, and dare I say it, nameless temporary symbols, which are good for short loops or skipping one or two instructions), but then you look at its broken phase/dephase function, the macro-based hack required to disable its zero-offset optimization, and its apparent inability to generate unique symbolic constants within macros. Granted, it was primarily developed for assembling programs for embedded systems and microcontrollers, but still....

    And I do have to sing my praises on your disassembly. With the emphasis on readability, it feels less like a disassembly and more like an actual source code release. (And i do have an improvement to share for it.)
  5. Brainulator


    Regular garden-variety member Member
    Nice work; I've wanted to do this myself, though frankly, what I would want to put out would differ drastically from what Sonic Retro's GitHub page offers (but maybe closer to yours?). There's just so much about the Sonic 2 disassembly I really do not like...

    I actually converted the SMPS2ASM file that flamewing made to work with ASM68K. I'd be happy to share it with you.
  6. If it includes all of the conversion functionality, I would love that. I wasn't sure how to do it because of the usage of AS' MOMPASS function (conditionals that trigger only on a specific pass of the assembler).
  7. Brainulator


    Regular garden-variety member Member
    Here you go. Some of the MOMPASS functionality was removed for simplicity's sake, though in one case, I took advantage of ASM68K being a one/two-pass assembler. I've only confirmed that Sonic 1 builds bit-perfectly with this in use; I'd haven't tried porting non-Sonic 1 songs to Sonic 1 nor have I dealt with the other games.
  8. Thank you. Had to change a few of the macros to work correctly with the ASM68K group/section functions (changing '*' to 'offset(*)') and tweaked the styling to my preference (double-indented code lines), and as I can tell, it's working (everything is assembling to the correct bytecode per the listing file).

    For the record, this is what I came up with (alas GitHub messed up my tidy indenting). Very similar, except I defined the notes, pitches, and DAC samples using a pair of macros to emulate AS' enum and enumconf functions (the former taken straight from AuroraFields' AMPS, the latter written by myself to extend the former's functionality), and used the ifarg short macro from S1 HB2022. In place of the conversion functionality, I set smpsHeaderStartSong to throw a fatal error if the source driver was anything other than 2.
  9. Brainulator


    Regular garden-variety member Member
    For my part, I actually wrote this with the Sonic Retro GitHub Sonic 1 disassembly in mind, since SMPS2ASM was being touted as a thing that the AS branch had that ASM68K's did not.
  10. Kurk


    Funky Kong Member
    I have a nearly completed asm68k port of Esrael's S2 Rev02 disassembly on my Github that you could take a look at if you want. There are still many issues that I haven't fixed because I've been busy with life. I also have a fully working port of his S2 9/14/92 disassembly and an improved version of his S2B4 disassembly, if those can be of use.

    Best of luck to you!
  11. [removed as full repository has now been published]
    Last edited: Nov 1, 2022
  12. It is now published on GitHub:

    Still in a bit of a messy state, but it currently builds bit-perfect to Revision 1, with all sound, including the compressed music, assembled, and all Kosinski files compressed at build time.
  13. I did not think I would reach this milestone this quickly. Not only have I got Sonic 2's sound driver assembling bit-perfect with Z80 macros, I managed to modify Natsumi's DualPCM_Compress to allow it to patch the Saxman decompressor (a practical miracle given my extremely limited knowledge of higher-level programming)!
    Snippet of S2 Sound Driver Compress, repository here.
    Screen Shot 2022-11-05 at 19.24.00.png
    Converted bankswitch macros:
    Screen Shot 2022-11-06 at 08.01.41.png
    Screen Shot 2022-11-06 at 08.01.58.png

    Unfortunately, the result is not bit-perfect, but that is only because there doesn't seem to yet be a standalone Saxman compressor that is both accurate to the original and excludes putting the compressed size in the header (s2p2bin seems to be the only thing that has both). Flamewing's saxcmp doesn't produce bit-perfect, but it works well enough to prove that what I have is working.

    When I started this project back in August, I did so not knowing how I would assemble the sound driver, or even IF it would be possible to assemble it. That I made it to here... I have no clue what to say for myself.
  14. Hivebrain


    53.4N, 1.5W
    To clarify, are you saying s2p2bin is an accurate saxman compressor that adds unwanted bytes to the header? If so, I could write another program to fix the header, or it might even be fixable with a macro.
  15. MainMemory


    Kate the Wolf Tech Member
    You could just take the modified compressor code from the s2p2bin source and make it into a standalone program.
  16. Clownacy


    Tech Member
    You can use the original Saxman compressor that Sega used: you just have to edit its code as described in this wiki page and then compile it, and you'll have a standalone compressor that doesn't add a header to the data. The file you'll want to edit and compile is 'LZSS.C'.

    Eh, screw it, I'll just do it: here you go.

    Attached Files:

    • Like Like x 1
    • Agree Agree x 1
    • List
  17. Taking a closer look, I think I found a solution that works a bit better: I modified the source of the standalone saxman.exe from Sonic 2 AS to take an additional argument that enables or disables the insertion of the header, allowing the same executable to be used for both the driver and the compressed music, eliminating the need for two separate compressor binaries.

    Unfortunately, I can't get GCC to build it (it fails with Undefined Reference errors, as does the unmodified source files, so it is not a syntax error or anything I introduced), so I haven't been able to actually test it.

    I feel so silly now that I've learned about CMake and how to use it.
    Last edited: Nov 7, 2022