Hey GBDev, for a while now I've been wanting to try and add SRAM saving to the original Gameboy version of Tetris, but have been reluctant to try since I've never added SRAM to a game before. I've done some reading on the Gameboy's dev side and have a few questions before I attempt to try it. I've dabbled in ASM for the SNES, but even that is at a beginner's level. Also, I'm aware that Tetris DX already has saving but it is very different to the original game (easier to get points, different algorithim, etc.).
A user at Romhacking.net, Capaneus, also wanted to add saving and has already done much of the hard debugging work locating where the high scores are read/written. He said he modified the cart type to include RAM and gave the game "8Kb of RAM (0x03)". I'm not sure what the 0x03 means?
He then modified the reads/writes for the high scores that were going to $D654 (A-Type high scores) and $D000 (B-Type High Scores) to write to $A654 and $A600 respectively.
Most GB games with RAM use MBC1 or MBC2, however two types of games on the list of cartridge types don't (8=ROM+RAM, 9=ROM+RAM+BATTERY).
Additionally, on the "Everything You Always Wanted To Know About GAMEBOY" Pan Docs document there is a blurb under "Memory Bank Controllers" that says:
"Small games of not more than 32KBytes ROM do not require a MBC chip for ROM banking. The ROM is directly mapped to memory at 0000-7FFFh. Optionally up to 8KByte of RAM could be connected at A000-BFFF, even though that could require a tiny MBC-like circuit, but no real MBC chip."
So since Tetris is a 32KByte game it can have RAM connected at A000-BFFF without the use of bank switching because of the info in the document and as shown by Capaneus putting the reads/writes for saving high scores in the A000 area. Is this correct to assume?
Capaneus then wrote that, "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."
Later he came back with "a very simple asm to enable SRAM:
ld a,0A
ld (0000),a",
but didn't know how to inject it.
However, he never posted again so I'm not sure if he ever completed it. I believe he got the info on how to enable SRAM from under Rom Types in the Pan Docs document, where it states: "Before you can read or write to a RAM bank you have to enable it by writing a 0A into 0000-1FFF area. To disable RAM bank operations write a 00 into 0000-1FFF area. Disabling a RAM bank probably protects that bank from false writes during power down of the GameBoy." Dwedit on GBDev also wrote in a non-related thread, "Looks like the sequence for reading the SRAM is:
Ram Enable: write 0A to 0000."
Some quick questions I have:
Is modifying the cart type to include 8Kb of RAM as simple as changing the cart memory info at 0147 (Cartridge type) from 00h to 09h and changing 00h to 02h at 0149 (RAM size) in a hex editor? Or is there a more complex process?
Is changing the high score reads/writes from $D000 (Type-B scores) and $D654 (Type-A scores) to $A000 and $A654 as easy as changing the values in a hex editor? Or would it require simple ASM that reads/writes to those addresses instead?
Where would the reading SRAM/enable RAM ASM need to go in the rom? Somewhere near the beginning of the boot up of the game after the Power Up Sequence (scrolling Nintendo logo)?
Also another quick Tetris question that isn't related to SRAM. The original v1.0 of the game has different A-Type music (Minuet) than v1.1 (Korobeiniki) which is what most people are familiar with and associate with Tetris as the Tetris theme. I've never cared much for the C-Type music and wonder if it would be possible to have the C-Type option play the A-Type music from v1.0 instead? Would it require something like copying the hex data from v1.0 and pasting it over C-Type's hex data in v1.1?
Thanks for the help and sorry for my lack of programming knowledge.
A user at Romhacking.net, Capaneus, also wanted to add saving and has already done much of the hard debugging work locating where the high scores are read/written. He said he modified the cart type to include RAM and gave the game "8Kb of RAM (0x03)". I'm not sure what the 0x03 means?
He then modified the reads/writes for the high scores that were going to $D654 (A-Type high scores) and $D000 (B-Type High Scores) to write to $A654 and $A600 respectively.
Most GB games with RAM use MBC1 or MBC2, however two types of games on the list of cartridge types don't (8=ROM+RAM, 9=ROM+RAM+BATTERY).
Additionally, on the "Everything You Always Wanted To Know About GAMEBOY" Pan Docs document there is a blurb under "Memory Bank Controllers" that says:
"Small games of not more than 32KBytes ROM do not require a MBC chip for ROM banking. The ROM is directly mapped to memory at 0000-7FFFh. Optionally up to 8KByte of RAM could be connected at A000-BFFF, even though that could require a tiny MBC-like circuit, but no real MBC chip."
So since Tetris is a 32KByte game it can have RAM connected at A000-BFFF without the use of bank switching because of the info in the document and as shown by Capaneus putting the reads/writes for saving high scores in the A000 area. Is this correct to assume?
Capaneus then wrote that, "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."
Later he came back with "a very simple asm to enable SRAM:
ld a,0A
ld (0000),a",
but didn't know how to inject it.
However, he never posted again so I'm not sure if he ever completed it. I believe he got the info on how to enable SRAM from under Rom Types in the Pan Docs document, where it states: "Before you can read or write to a RAM bank you have to enable it by writing a 0A into 0000-1FFF area. To disable RAM bank operations write a 00 into 0000-1FFF area. Disabling a RAM bank probably protects that bank from false writes during power down of the GameBoy." Dwedit on GBDev also wrote in a non-related thread, "Looks like the sequence for reading the SRAM is:
Ram Enable: write 0A to 0000."
Some quick questions I have:
Is modifying the cart type to include 8Kb of RAM as simple as changing the cart memory info at 0147 (Cartridge type) from 00h to 09h and changing 00h to 02h at 0149 (RAM size) in a hex editor? Or is there a more complex process?
Is changing the high score reads/writes from $D000 (Type-B scores) and $D654 (Type-A scores) to $A000 and $A654 as easy as changing the values in a hex editor? Or would it require simple ASM that reads/writes to those addresses instead?
Where would the reading SRAM/enable RAM ASM need to go in the rom? Somewhere near the beginning of the boot up of the game after the Power Up Sequence (scrolling Nintendo logo)?
Also another quick Tetris question that isn't related to SRAM. The original v1.0 of the game has different A-Type music (Minuet) than v1.1 (Korobeiniki) which is what most people are familiar with and associate with Tetris as the Tetris theme. I've never cared much for the C-Type music and wonder if it would be possible to have the C-Type option play the A-Type music from v1.0 instead? Would it require something like copying the hex data from v1.0 and pasting it over C-Type's hex data in v1.1?
Thanks for the help and sorry for my lack of programming knowledge.