Clear Up Some RAM in Sonic 1

Discussion in 'Engineering & Reverse Engineering' started by Alex Field, Nov 29, 2019.

Tags:
  1. Alex Field

    Alex Field

    シュート! カオス・エメラルド・ザが消えようとしている! Member
    138
    78
    28
    Downunda, Mobius
    Sonic the Hedgehog 2+, Sonic the Hedgehog 3+
    So you're making a hack of Sonic 1, but you realize you don't have enough RAM!

    Well, first of all, what do you need that requires that much RAM? And second of all, I'm here to help!

    This guide will consist of several guides, all of which will free at-least some RAM. Please note this is targeted at the Hivebrain disassembly, though you shouldn't have much trouble porting it to other disassemblies such as the Github one.

    Anyway, let's get started!

    This first guide you've probably already seen on the wiki, but this version is using the code from Mercury's ReadySonic, which is optimized.

    First of all, replace all references of "map256" with "map256_u." This will replace the Kosinski compressed versions with the uncompressed version. Then, at
    Title_LoadText: replace the following lines:
    Code (Text):
    1.         lea    (Blk256_GHZ).l,a0 ; load GHZ 256x256 mappings
    2.         lea    ($FF0000).l,a1
    3.         bsr.w    KosDec
    With this:
    Code (Text):
    1.         move.l    #Blk256_GHZ,(v_256x256).l    ; store the ROM address for the chunk mappings
    Then at sub_6BD6 (or loc_712C if you've ported REV01 BG effects), replaced this:
    Code (Text):
    1.         moveq    #-1,d3
    With this:
    Code (Text):
    1.         moveq    #0,d3
    Then, between "add.w d5,d3" and "movea.l d3,a0," add this line:
    Code (Text):
    1.         add.l    ($FF0000).l,d3
    Now we need to remove the code which decompresses the chunks from Kosinski to Uncompressed. At MainLoadBlockLoad, replace these three lines:
    Code (Text):
    1.         movea.l    (a2)+,a0
    2.         lea    ($FF0000).l,a1    ; RAM address for 256x256 mappings
    3.         bsr.w    KosDec
    With this line:

    Code (Text):
    1.         move.l    (a2)+,($FF0000).l
    Now the levels should display fine, but the collision is gone! This is because the game's collision system still thinks we're using compressed chunks. To fix this, at Floor_ChkTile you'll see a similar line to the "moveq #-1," except here it's using d1. Replace the "-1" with 0.

    Finally, before the "movea.l d1,a1"'s, add this line:
    Code (Text):
    1.         add.l    ($FF0000).l,d3
    NOW, you might think we've finished, but if we look at the title-screen, the background is corrupted! To fix this, delete these four lines:
    Code (Text):
    1.         lea    ($FF0000).l,a1
    2.         lea    (Eni_Title).l,a0 ; load    title screen mappings
    3.         move.w    #0,d0
    4.         bsr.w    EniDec
    Then replace the $FF0000 right below it with Eni_Title. Then, at Eni_Title, replace "mapeni" with "mapeni_u." Also if you want, you can apply the same change to the SEGA and Japanese credits screens.

    NOTE: For the Sega screen if you're doing the above, replace the $FF0180 with Eni_SegaLogo+$180

    There you go! You've freed-up a ton of RAM (roughly $0000 to $A3FF)! You'll probably never need more RAM then this, but why stop here?

    This change was also made available on Mercury's ReadySonic, so why not add it here?

    Like above, replace all references to "map16" with "map16_u." Then, at Title_LoadText, replace the following lines:
    Code (Text):
    1.         lea    ($FFFFB000).w,a1
    2.         lea    (Blk16_GHZ).l,a0 ; load    GHZ 16x16 mappings
    3.         move.w    #0,d0
    4.         bsr.w    EniDec
    With this:
    Code (Text):
    1.         move.l    #Blk16_GHZ,($FF0004).l    ; store the ROM address for the block mappings
    Then back at sub_6BD6, replace this line:
    Code (Text):
    1.         lea    ($FFFFB000).w,a1
    With this:
    Code (Text):
    1.         movea.l    ($FF0004).l,a1
    Finally at MainLoadBlockLoad, replace the following...
    Code (Text):
    1.         movea.l    (a2)+,a0
    2.         lea    ($FFFFB000).w,a1 ; RAM address for 16x16 mappings
    3.         move.w    #0,d0
    4.         bsr.w    EniDec
    With this:
    Code (Text):
    1.         move.l    (a2)+,($FF0004).l    ; store the ROM address for the block mappings
    2.         andi.l    #$FFFFFF,($FF0004).l
    With this, you've just freed $B000 to $C7FF! Yeah, over half the RAM free now!

    There is a little bit of RAM in Sonic 1 that is referenced once, but never mentioned again. This is due to many concepts being scrapped. This is quite small, but we might as-well free-up a bit more.

    At SegaScreen, delete references to $F660 and $F662. Then at Sonic_Floor, delete references to $FFEC-$FFEF. Finally at Title_LoadText, delete the reference to $FFEB.

    Installing a Z80 Sound Driver will free-up $F000-$F5BF, though installing it will be up-to you considering there's two Sonic Z80 Drivers, Sonic 2's and Sonic 3's.

    And there you go, around $C106 RAM is now cleared and available! Enjoy! And of-course, feel free to post your ways to free RAM.
     
    Last edited: Nov 29, 2019