Any writes I do to cartridge RAM on my test game assembled with RGBDS are silently ignored. I wanted to move the stack pointer to cartridge RAM to have more room in high ram to use as a scratchpad, but the game won't recognize that the cartridge ram is available even after enabling it. (My routines for detecting the type of game boy and initializing cartridge ram are identical between my game assembled with RGBDS and my game assembled with VASM, yet only the one asssembled in VASM seems to work with regards to cartridge RAM. I double-checked to make sure that both ROMs use the same cartridge header, and reviewed the code and found it to be the same on both.
Code (RGBDS syntax):
;both games call this before doing "LD SP,$BFFF" but it only works on the second one! DetectHardware:: cp $11 ld a,0 jr nz,.skip push af push bc ;B contains the GBA/no GBA state at boot. call EnableFastCPU ;speed up the cpu for gbc and gba pop bc pop af inc a ;ld a,1 dec b ;if B was 1, it now equals zero. jr nz,.skip ;B wasn't 1. add $FE ;ld a,255 .skip: LD [isGameBoyColor],a ; store hardware type. xor a ;LD A,0 jr GBCart_RamBank GBCart_RamBank:: ;Turn on ram bank 0-3 push af ld b,$0A call GBCart_RamBankAlt ;IF YOU CALL GBCART_RAMBANKOFF THE RAM IS DISABLED INSTEAD. pop af ld [$4000],a ;SELECT CARTRIDGE RAM BANK NUMBER 0-3 ret GBCart_RamBankOff:: ;Turn off ram bank (NOT EXECUTED AT STARTUP) ld b,$00 GBCart_RamBankAlt: ld a,$01 ld [$6000],a ;WRITE 1 TO [$6000] TO TELL THE GAME BOY CPU THE CARTRIDGE HAS RAM ld a,b ld [$0000],a ;LD [$0000],$0A ENABLES THE EXTRA RAM BANK ;LD [$0000],$00 DISABLES IT ret
The same code (VASM syntax): The only difference is that this version runs in-line (The stack pointer was initialized to FFFF before executing this routine in both cases, so that shouldn't matter.)
DetectHardware: cp &11 ld a,0 jr nz,isntGBA push af push bc ;B contains the GBA/no GBA state at boot. call EnableFastCPU ;speed up the cpu for gbc and gba pop bc pop af inc a ;ld a,1 dec b ;if B was 1, it now equals zero. jr nz,isntGBA ;B wasn't 1. add &FE ;ld a,255 isntGBA: LD (isGameBoyColor),a ; store hardware type. xor a ;LD A,0 call GBCart_RamBank ; above code runs in-line, execution will set SP to $BFFF after this and continue initializing the game. The code below is somewhere else that the program counter won't reach without a jump or call. GBCart_RamBank: ;Turn on ram bank 0-3 ;THIS EXTRA RAM IS LOCATED FROM &A000-&BFFF ;USAGE: LD A,#DESIRED RAM BANK ; CALL GBCART_RAMBANK push af ld b,&0a call GBCart_RamBankAlt ;IF YOU CALL GBCART_RAMBANKOFF THE RAM IS DISABLED INSTEAD. pop af ld (&4000),a ;SELECT CARTRIDGE RAM BANK NUMBER 0-3 ; THIS RAM IS BATTERY BACKED, AND IF THE GAME IS SHUT OFF ; WHILE LOADED THE RAM CAN BE CORRUPTED. ; IF YOU'RE JUST USING IT AS A SCRATCHPAD IT DOESN'T MATTER! ret GBCart_RamBankOff: ;Turn off ram bank ld b,0 GBCart_RamBankAlt: ld a,&01 ld (&6000),a ;WRITE 1 TO (&6000) TO TELL THE GAME BOY CPU THE CARTRIDGE HAS EXTRA RAM ld a,b ld (&0000),a ;LD (&0000),&0A ENABLES THE EXTRA RAM BANK ;LD (&0000),&00 DISABLES IT ret
I can tell the RGBDS-assembled ROM isn't writing to cartridge ram because doing a function call after relocating the stack pointer to $BFFF doesn't put the return address into cartridge ram like it should. Then when it tries to return, execution returns to $FFFF and eventually crashes.
I seriously have no idea why this isn't working anymore. Just because I switched to a new assembler shouldn't change how bankswitching works (I believe I translated the syntax correctly).