News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: First Hack - GB Tetris Score Saving  (Read 4718 times)

Capaneus

  • Jr. Member
  • **
  • Posts: 2
    • View Profile
First Hack - GB Tetris Score Saving
« on: April 11, 2014, 10:33:35 am »
Hey folks, long time lurker, first time poster.

Anyway, my absolute favorite version of Tetris is the original for the Game Boy.  It's bummed me out for years that there is a high score table that just gets blanked out every time the game gets turned off, so I descided I wanted to do something about it.  I started messing around with disassemblers and debuggers, and learning about GB's memory address scheme, and header info.  Tons of info out there, which made the first step really easy.  So I modified the cart type to include RAM, gave it 8Kb of RAM (0x03), and modified the reads/writes for the high score that were going to $D000 (B-type high scores) and $D654 (A-type high scores), to write to $A000 and $A654 respectively.  This works on some emulators as long as I seed the .sav file with zeros, however on more accurate emulators it seems the SRAM is not writeable.  I've read some stuff about enabling SRAM with MBC1 but I dont know what assembler command I have to do and what specific address I have to write to.    Then I have to somehow check the validity of the SRAM at boot, and zero it out if it appears corrupt.

Anyone out there done a hack like this?  Thanks!

FAST6191

  • Hero Member
  • *****
  • Posts: 3182
    • View Profile
Re: First Hack - GB Tetris Score Saving
« Reply #1 on: April 11, 2014, 02:26:06 pm »
Most save hacks I see were for games that have saves possibly until late beta, still it sounds like you are probably on the right path and you lucked out as the original tetris game is 32 kilobytes and you do not have to do proper memory bank handling (though this is not always so bad on the GB).

Your solutions are most of the way to reinventing commercial saves, about the only thing you have not got is a checksum of some form on the data. If it is any consolation I have had commercial games with the need to have a 00/FF filled save before they work properly, in fact one was actually a Tetris game (minna no soft tetris on the GBA seemed to stop crashing when I had a FF filled save, the original cart also dumped like that).
Alternatively if you keep the table in normal RAM you can have it copy and restore from the save section at points. If you do this for other games this can be good as you do not always know when something will read a save value, for high score tables it is fairly safe though.

On the more accurate emulator thing as you say there does appear to be a ram initialise command http://nocash.emubase.de/pandocs.htm#mbc1max2mbyteromandor32kbyteram has more -- you want to write a value to somewhere in the 0000-1FFF area (it is ROM area but the cart/emulator should interpret it as write enable). From the link "00h  Disable RAM (default)  0Ah  Enable RAM Practically any value with 0Ah in the lower 4 bits enables RAM, and any other value disables RAM.". It also mentions you want to disable it so any floating voltages/chips that are no longer pulled up during power down do not do odd things.

With the header thing you should be good and the emulators will hopefully not be second guessing you; it was not for the GB/GBC but I have seen emulators have a game database to draw from.

Capaneus

  • Jr. Member
  • **
  • Posts: 2
    • View Profile
Re: First Hack - GB Tetris Score Saving
« Reply #2 on: April 12, 2014, 10:06:18 am »
Ok, so I got the very simple asm to enable SRAM:

ld a,0A
ld (0000),a

Are there guides on how to inject new asm?  Most things I have done would be just modifying it, but I'mhaving a hard time with injecting it.  Do you have to completely disassemble, and reassemble?  Do you have to edit other lines that call explicit addresses in the ROM? 

KingMike

  • Forum Moderator
  • Hero Member
  • *****
  • Posts: 7152
  • *sigh* A changed avatar. Big deal.
    • View Profile
Re: First Hack - GB Tetris Score Saving
« Reply #3 on: April 12, 2014, 12:04:34 pm »
For GB, I use WLA DX.

This looks like a lot, but it's very simple.
To use that, create an assembly code file, a text file with you ASM code.
Code: [Select]
.ROMDMG

.MEMORYMAP          ;CPU memory map
DEFAULTSLOT 0
SLOTSIZE $4000
SLOT 0 $0000        ;fixed ROM bank
SLOT 1 $4000        ;swappable ROM bank
SLOT 2 $8000        ;actually, 8000-9FFF is VRAM and A000-BFFF is SRAM
SLOT 3 $C000        ;WRAM
.ENDME

.ROMBANKSIZE $4000
.ROMBANKS 8

.BACKGROUND "romname.gb"   ;your ROM file name here, allowing you to overwrite the original

.bank 0 slot 0      ;insert code in ROM bank 0 (0000-3FFF), assuming this ROM bank maps to CPU slot 0 (defined above as PU address 0-3FFF)

.org SomeAddress  ;will insert code at SomeAddress in the currently specified bank
  ;code goes here
You'll need to write your new code in some empty space. Then go to the original code and insert a jp/call command (as approriate to whether you end your code with a jp or ret command) to your new code.

Then to assemble, I create a BAT file.
Code: [Select]
wla-gb -o source.asm source.o
wlalink -r source.txt rom.gb
pause
Where source.asm is our source code we just created, source.o is some file our assembler will create,
source.txt is another text file we will create:
Code: [Select]
[objects]
source.o
(of course the file our assembler created)
and rom.gb is our ROM file we are hacking.

Also, once you're done saving the scores to SRAM, you probably want to disable SRAM again. That will avoid the "saves get erased when the power is turned off" problem, like NES games had.
"My watch says 30 chickens" Google, 2018