from ..assembler import ASM from .. import utils def addBank3F(rom): # Bank3F is used to initialize the tile data in VRAM:1 at the start of the rom. # The normal rom does not use this tile data to maintain GB compatibility. rom.patch(0, 0x0150, ASM(""" cp $11 ; is running on Game Boy Color? jr nz, notGBC ldh a, [$4d] and $80 ; do we need to switch the CPU speed? jr nz, speedSwitchDone ; switch to GBC speed ld a, $30 ldh [$00], a ld a, $01 ldh [$4d], a xor a ldh [$ff], a stop db $00 speedSwitchDone: xor a ldh [$70], a ld a, $01 ; isGBC = true jr Init notGBC: xor a ; isGBC = false Init: """), ASM(""" ; Check if we are a color gameboy, we require a color version now. cp $11 jr nz, notGBC ; Switch to bank $3F to run our custom initializer ld a, $3F ld [$2100], a call $4000 ; Switch back to bank 0 after loading our own initializer ld a, $01 ld [$2100], a ; set a to 1 to indicate GBC ld a, $01 jr Init notGBC: xor a Init: """), fill_nop=True) rom.patch(0x3F, 0x0000, None, ASM(""" ; switch speed ld a, $30 ldh [$00], a ld a, $01 ldh [$4d], a xor a ldh [$ff], a stop db $00 ; Switch VRAM bank ld a, $01 ldh [$4F], a call $28CF ; display off ; Use the GBC DMA to transfer our tile data ld a, $68 ldh [$51], a ld a, $00 ldh [$52], a ld a, $80 ldh [$53], a ld a, $00 ldh [$54], a ld a, $7F ldh [$55], a waitTillTransferDone: ldh a, [$55] and $80 jr z, waitTillTransferDone ld a, $70 ldh [$51], a ld a, $00 ldh [$52], a ld a, $88 ldh [$53], a ld a, $00 ldh [$54], a ld a, $7F ldh [$55], a waitTillTransferDone2: ldh a, [$55] and $80 jr z, waitTillTransferDone2 ld a, $68 ldh [$51], a ld a, $00 ldh [$52], a ld a, $90 ldh [$53], a ld a, $00 ldh [$54], a ld a, $7F ldh [$55], a waitTillTransferDone3: ldh a, [$55] and $80 jr z, waitTillTransferDone3 ; Switch VRAM bank back ld a, $00 ldh [$4F], a ; Switch the display back on, else the later code hangs ld a, $80 ldh [$40], a speedSwitchDone: xor a ldh [$70], a ; Check if we are running on a bad emulator ldh [$02], a ldh a, [$02] and $7c cp $7c jr nz, badEmu ; Enable the timer to run 32 times per second xor a ldh [$06], a ld a, $04 ldh [$07], a ; Set SB to $FF to indicate we have no data from hardware ld a, $FF ldh [$01], a ret badEmu: xor a ldh [$40], a ; switch display off ; Load some palette ld a, $80 ldh [$68], a xor a ldh [$69], a ldh [$69], a ldh [$69], a ldh [$69], a ; Load a different gfx tile for the first gfx cpl ld hl, $8000 ld c, $10 .loop: ldi [hl], a dec c jr nz, .loop ld a, $01 ld [$9800], a ld [$9820], a ld [$9840], a ld [$9860], a ld [$9880], a ld [$9801], a ld [$9841], a ld [$9881], a ld [$9822], a ld [$9862], a ld [$9824], a ld [$9844], a ld [$9864], a ld [$9884], a ld [$9805], a ld [$9845], a ld [$9826], a ld [$9846], a ld [$9866], a ld [$9886], a ld [$9808], a ld [$9828], a ld [$9848], a ld [$9868], a ld [$9888], a ld [$9809], a ld [$9889], a ld [$982A], a ld [$984A], a ld [$986A], a ld [$9900], a ld [$9920], a ld [$9940], a ld [$9960], a ld [$9980], a ld [$9901], a ld [$9941], a ld [$9981], a ld [$9903], a ld [$9923], a ld [$9943], a ld [$9963], a ld [$9983], a ld [$9904], a ld [$9925], a ld [$9906], a ld [$9907], a ld [$9927], a ld [$9947], a ld [$9967], a ld [$9987], a ld [$9909], a ld [$9929], a ld [$9949], a ld [$9969], a ld [$9989], a ld [$998A], a ld [$990B], a ld [$992B], a ld [$994B], a ld [$996B], a ld [$998B], a ; lcd on ld a, $91 ldh [$40], a blockBadEmu: di jr blockBadEmu """)) # Copy all normal item graphics rom.banks[0x3F][0x2800:0x2B00] = rom.banks[0x2C][0x0800:0x0B00] # main items rom.banks[0x3F][0x2B00:0x2C00] = rom.banks[0x2C][0x0C00:0x0D00] # overworld key items rom.banks[0x3F][0x2C00:0x2D00] = rom.banks[0x32][0x3D00:0x3E00] # dungeon key items # Create ruppee for palettes 0-3 rom.banks[0x3F][0x2B80:0x2BA0] = rom.banks[0x3F][0x2A60:0x2A80] for n in range(0x2B80, 0x2BA0, 2): rom.banks[0x3F][n+1] ^= rom.banks[0x3F][n] # Create capacity upgrade arrows rom.banks[0x3F][0x2A30:0x2A40] = utils.createTileData(""" 33 3113 311113 33311333 3113 3333 """) rom.banks[0x3F][0x2A20:0x2A30] = rom.banks[0x3F][0x2A30:0x2A40] for n in range(0x2A20, 0x2A40, 2): rom.banks[0x3F][n] |= rom.banks[0x3F][n + 1] # Add the slime key and mushroom which are not in the above sets rom.banks[0x3F][0x2CC0:0x2D00] = rom.banks[0x2C][0x28C0:0x2900] # Add tunic sprites as well. rom.banks[0x3F][0x2C80:0x2CA0] = rom.banks[0x35][0x0F00:0x0F20] # Add the bowwow sprites rom.banks[0x3F][0x2D00:0x2E00] = rom.banks[0x2E][0x2400:0x2500] # Zol sprites, so we can have zol anywhere from a chest rom.banks[0x3F][0x2E00:0x2E60] = rom.banks[0x2E][0x1120:0x1180] # Patch gel(zol) entity to load sprites from the 2nd bank rom.patch(0x06, 0x3C09, "5202522254025422" "5200522054005420", "600A602A620A622A" "6008602862086228") rom.patch(0x07, 0x329B, "FFFFFFFF" "FFFFFFFF" "54005420" "52005220" "56005600", "FFFFFFFF" "FFFFFFFF" "62086228" "60086028" "64086408") rom.patch(0x06, 0x3BFA, "56025622", "640A642A"); # Cucco rom.banks[0x3F][0x2E80:0x2F00] = rom.banks[0x32][0x2500:0x2580] # Patch the cucco graphics to load from 2nd vram bank rom.patch(0x05, 0x0514, "5001" "5201" "5401" "5601" "5221" "5021" "5621" "5421", "6809" "6A09" "6C09" "6E09" "6A29" "6829" "6E29" "6C29") # Song symbols rom.banks[0x3F][0x2F00:0x2F60] = utils.createTileData(""" ... . .222 .2.2222 .22.222. .22222.3 .2..22.3 .33...3 .33.3.3 ..233.3 .22.2333 .222.233 .222... ... """ + """ .. .22 .223 ..222 .33.22 .3..22 .33.33 ..23. ..233. .22.333 .22..233 .. .23 .. """ + """ ... .222. .2.332 .23.32 .233.2 .222222 .2222222 .2..22.2 .2.3.222 .22...22 .2333.. .23333 .....""", " .23") # Ghost rom.banks[0x3F][0x2F60:0x2FE0] = rom.banks[0x32][0x1800:0x1880] # Instruments rom.banks[0x3F][0x3000:0x3200] = rom.banks[0x31][0x1000:0x1200] # Patch the egg song event to use the 2nd vram sprites rom.patch(0x19, 0x0BAC, "5006520654065606" "58065A065C065E06" "6006620664066606" "68066A066C066E06", "800E820E840E860E" "880E8A0E8C0E8E0E" "900E920E940E960E" "980E9A0E9C0E9E0E" ) # Rooster rom.banks[0x3F][0x3200:0x3300] = rom.banks[0x32][0x1D00:0x1E00] rom.patch(0x19, 0x19BC, "42234023" "46234423" "40034203" "44034603" "4C034C23" "4E034E23" "48034823" "4A034A23", "A22BA02B" "A62BA42B" "A00BA20B" "A40BA60B" "AC0BAC2B" "AE0BAE2B" "A80BA82B" "AA0BAA2B") # Replace some main item graphics with the rooster rom.banks[0x2C][0x0900:0x0940] = utils.createTileData(utils.tileDataToString(rom.banks[0x32][0x1D00:0x1D40]), " 321") # Trade sequence items rom.banks[0x3F][0x3300:0x3640] = rom.banks[0x2C][0x0400:0x0740]