SECTION "rst 00", ROM0 [$00] di jp Entry SECTION "rst 10", ROM0 [$10] jp DelayFrame SECTION "rst 18", ROM0 [$18] jp JumpToFuncInTable SECTION "rst 20", ROM0 [$20] jp Func_486 SECTION "VBlankInt", ROM0 [$40] jp VBlank SECTION "HBlankInt", ROM0 [$48] jp LCD SECTION "TimerInt", ROM0 [$50] jp Timer SECTION "SerialInt", ROM0 [$58] jp Serial SECTION "JoypadInt", ROM0 [$60] jp Joypad SECTION "Entry", ROM0 [$100] Entry: ; 0x100 nop jp Start SECTION "Header", ROM0 [$104] ; The header is generated by rgbfix. ; The space here is allocated to prevent code from being overwritten. ds $150 - $104 SECTION "Main", ROM0 [$150] Start: ; 0x150 ld [hGameBoyColorFlag], a ld sp, hGameBoyColorFlag di xor a ld [rIF], a ld a, [rLCDC] ; LCD Control bit 7, a ; Check if LCD Display is enabled jr nz, .LCDDisplayEnabled set 7, a ld [rLCDC], a .LCDDisplayEnabled ld bc, $0002 call SGBWait1750 .waitForVBlank ld a, [rLY] ; LY register (LCDC Y-Coordinate) cp 145 ; > 144 means V-Blank jr c, .waitForVBlank ld a, $81 ld [rLCDC], a ; Enable LCD Display xor a ld [rBGP], a ; Clear Palette Data ld [rOBP0], a ld [rOBP1], a ld bc, $0002 call SGBWait1750 .waitForVBlank2 ld a, [rLY] ; LY register (LCDC Y-Coordinate) cp 145 ; > 144 means V-Blank jr c, .waitForVBlank2 xor a ld [rLCDC], a ; Disable LCD Display ld hl, wc000 ld bc, $2000 call ClearData ; Clear WRAM Bank 0 ld hl, vTilesOB ld bc, $1000 call ClearData ; Clear First half of VRAM ld a, SRAM_ENABLE ld [MBC5SRamEnable], a ; Enable RAM ld a, $1 ld [MBC5RomBank], a ; Load ROM Bank $1 ld a, $0 ld [MBC5RomBankOn], a ; Enable ROM Banking Mode ld a, $0 ld [MBC5SRamBank], a ; Set bits 5 and 6 of ROM Bank Number ld a, $1 ld [hLoadedROMBank], a ld a, $1 ld [MBC5RomBankOn], a ; Enable RAM Banking Mode ld a, $0 ld [MBC5SRamBank], a ; Load RAM Bank $0 ld sp, wStack ; Initialize stack pointer to the end of WRAM Bank $1 ld hl, hPushOAM ld bc, $007e call ClearData ; Clear High RAM (HRAM) call WriteDMACodeToHRAM call ClearOAMBuffer xor a ld [wd7fb], a ld [wd7fc], a ld [wd7fd], a ld [hHBlankRoutine], a ld [$ffb1], a ld [wd8e1], a ld [wd7fe], a ld [hSGBInit], a ld hl, hLCDC xor a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld a, $8f ld [hli], a ld a, $a6 ld [hli], a ld a, $0 ld [wd849], a ld [wd84a], a ld a, Bank(PlaySong_BankF) call SetSongBank call Func_23b ld a, [hGameBoyColorFlag] and a jr nz, .asm_222 call InitSGB rl a and $1 ld [hSGBFlag], a call SendSGBBorder ld a, [hSGBFlag] and a jr z, .asm_222 ld a, $1 ld [wd917], a .asm_222 ld a, $1 ld [rIE], a ; Only enable LCD Status interrupt ei ld a, $ff ld [wd810], a call Func_97a xor a ld [wdaa3], a ld a, BANK(Func_1ffc) ld hl, Func_1ffc call BankSwitchSimple Func_23b: ; 0x23b ld a, [hGameBoyColorFlag] cp $11 jr nz, .asm_248 ld a, $1 ld [hGameBoyColorFlag], a ld [$fffd], a ret .asm_248 xor a ld [hGameBoyColorFlag], a ld [$fffd], a ret SoftReset: di ld sp, hGameBoyColorFlag xor a ld [rIF], a ld bc, $2 call SGBWait1750 ld hl, wc000 ld bc, $2000 call ClearData ld hl, $8000 ld bc, $1000 call ClearData ld a, SRAM_ENABLE ld [MBC5SRamEnable], a ld a, $1 ld [MBC5RomBank], a ld a, $0 ld [MBC5RomBankOn], a ld a, $0 ld [MBC5SRamBank], a ld a, $1 ld [hLoadedROMBank], a ld a, $1 ld [MBC5RomBankOn], a ld a, $0 ld [MBC5SRamBank], a ld sp, wStack call WriteDMACodeToHRAM call ClearOAMBuffer xor a ld [wd7fb], a ld [wd7fc], a ld [wd7fd], a ld [hHBlankRoutine], a ld [$ffb1], a ld [wd8e1], a ld [wd7fe], a ld hl, hLCDC xor a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld a, $8f ld [hli], a ld a, $a6 ld [hli], a ld a, $0 ld [wd849], a ld [wd84a], a ld a, BANK(Func_3c000) call SetSongBank ld a, [hSGBFlag] and a jr z, .asm_02d5 ld a, $1 ld [wd917], a .asm_02d5 ld a, $1 ld [rIE], a ei ld a, $ff ld [wd810], a call Func_97a ld a, [hGameBoyColorFlag] ld [$fffd], a xor a ld [wdaa3], a ld a, $0 ld hl, Func_1ffc call BankSwitchSimple ; fallthrough VBlank: ; 0x2f2 push af push bc push de push hl call hPushOAM ; OAM DMA transfer ld a, [hLCDC] ld [rLCDC], a call Func_113a ei ld a, [rLY] cp $90 jr c, .asm_328 ld hl, hSTAT ld c, rSTAT - $ff00 ld a, [hli] ld [$ff00+c], a inc c ld a, [hli] ld [$ff00+c], a inc c ld a, [hli] ld [$ff00+c], a inc c inc c ld a, [hli] ld [$ff00+c], a inc c inc c ld a, [hli] ld [$ff00+c], a inc c ld a, [hli] ld [$ff00+c], a inc c ld a, [hli] ld [$ff00+c], a inc c ld a, [hli] ld [$ff00+c], a inc c ld a, [hli] ld [$ff00+c], a .asm_328 ld a, [hLYC] ld [hLastLYC], a ld a, [hNextLYCSub] ld [hLYCSub], a ld a, [hNextFrameHBlankSCX] ld [hHBlankSCX], a ld a, [hNextFrameHBlankSCY] ld [hHBlankSCY], a call ReadJoypad ld a, [wdaa3] and a jr nz, .asm_359 ld a, [hJoypadState] cp $f jr nz, .asm_359 ld a, [hNewlyPressedButtons] and $f jr z, .asm_359 ld hl, [sp+$8] ld [hl], $c3 inc hl ld [hl], $3 ld a, $1 ld [wdaa3], a .asm_359 ld hl, hNumFramesSinceLastVBlank ld a, [hl] inc [hl] and a jr nz, .asm_365 ld hl, hNumFramesDropped inc [hl] .asm_365 ld hl, hVBlankCount inc [hl] ld a, [wd8e1] and a call nz, Func_167b ld a, [wd849] and a jr nz, .asm_37d ld a, [wd85d] and a call nz, Func_504 .asm_37d ld a, [wd84a] and a jr z, .asm_39d xor a ld [wd84a], a ld a, $1 ld [wd849], a ld a, $bc ld [rTMA], a ld a, $0 ld [rTAC], a ld hl, rIE set 2, [hl] ld a, $4 ld [rTAC], a .asm_39d ld hl, MBC5SRamBank ld a, [wd917] and a jr nz, .asm_3b5 ld a, [wd803] rrca ld [wd803], a and $1 jr z, .asm_3b5 set 3, [hl] jr .asm_3b7 .asm_3b5 res 3, [hl] .asm_3b7 ld a, [wd4aa] and a call nz, Func_e69 pop hl pop de pop bc pop af reti Func_3c3: ld a, [rLCDC] bit 7, a jr z, .asm_03cf call Func_cb5 call Func_576 .asm_03cf ld hl, hSTAT res 6, [hl] ld hl, rIE res 1, [hl] xor a ld [MBC5SRamEnable], a ld [rSB], a ld [rSC], a ld [rIE], a ld [rNR52], a ld a, [$fffd] ld [hGameBoyColorFlag], a jp SoftReset LCD: ; 0x3ec push af push bc push de push hl ld a, [hHBlankRoutine] sla a ld c, a ld b, $0 ld hl, PointerTable_408 add hl, bc ld a, [hli] ld h, [hl] ld l, a jp [hl] Func_3ff: ; 0x3ff ld a, $1 ld [$ffb5], a pop hl pop de pop bc pop af reti PointerTable_408: ; 0x408 dw Func_fbc dw Func_fbf dw Func_fea dw Func_105d dw Func_109e dw Func_10a1 dw Func_10a4 dw Func_10a7 Timer: ; 0x418 ei push af push bc push de push hl ld a, [wd849] and a jr z, .asm_42a ld a, [wd85d] and a call nz, Func_504 .asm_42a ld a, [wd84a] and a jr z, .asm_440 xor a ld [wd84a], a ld [wd849], a ld a, $0 ld [rTAC], a ld hl, rIE res 2, [hl] .asm_440 pop hl pop de pop bc pop af reti Serial: ; 0x445 push af push bc push de push hl ld hl, Data_45d push hl ld a, [$ffb1] sla a ld c, a ld b, $0 ld hl, Data_462 add hl, bc ld c, [hl] inc hl ld b, [hl] push bc ret Data_45d: db $e1, $d1, $c1, $f1, $d9 Data_462: db $64, $16, $66, $04, $c9 Joypad: ; 0x467 reti DelayFrame: ; 0x468 ld a, [rLCDC] bit 7, a ret z ld hl, hNumFramesSinceLastVBlank xor a ld [hl], a .asm_472 ld a, [hl] and a jr z, .asm_472 ret JumpToFuncInTable: ; 0x477 ; Jumps to a function in the pointer table immediately following ; a "rst JumpTable" call. Function must be in the same Bank as the pointer table. ; input: a = index of function in table sla a pop hl push de ld e, a ld d, $0 add hl, de ld e, [hl] inc hl ld d, [hl] ld l, e ld h, d pop de jp [hl] Func_486: ; 0x486 rlca add l ld l, a jr nc, .noCarry inc h .noCarry ld a, [hli] ld h, [hl] ld l, a ret PlaySong: ; 0x490 ld a, [hLoadedROMBank] push af ld a, [wCurrentSongBank] ld [hLoadedROMBank], a ld [MBC5RomBank], a ld a, e ld [wStageSong], a ld a, [wCurrentSongBank] ld [wStageSongBank], a call PlaySong_BankF ; this function is replicated in multiple banks. pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ret PlaySoundEffect: ; 0x4af ; input: de = sound effect id? I think d specifies something special and e holds the id ld a, [wdead] and a ret nz ld a, [wSFXTimer] and a jr z, .asm_4bd ld a, d and a ret z .asm_4bd ld a, d ld [wSFXTimer], a ld d, $0 ld a, [hLoadedROMBank] push af ld a, [wCurrentSongBank] ld [hLoadedROMBank], a ld [MBC5RomBank], a call PlaySoundEffect_BankF ; this function is replicated in multiple banks pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ret Func_4d8: ; 0x4d8 push bc push de push hl ld a, [wChannel5 + 2] ld hl, wChannel6 + 2 or [hl] ld hl, wChannel7 + 2 or [hl] and $1 call z, PlaySoundEffect pop hl pop de pop bc ret PlayCry: ; 0x4ef ; Plays a Pokemon cry. ; Input: e = mon id ld a, [hLoadedROMBank] push af ld a, [wCurrentSongBank] ld [hLoadedROMBank], a ld [MBC5RomBank], a call PlayCry_BankF ; this function is replicated in multiple banks pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ret Func_504: ; 0x504 ld a, [hLoadedROMBank] push af ld a, [wCurrentSongBank] ld [hLoadedROMBank], a ld [MBC5RomBank], a call Func_3c180 pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ld a, [wd801] inc a ld [wd801], a and $3 ret nz ld a, [wSFXTimer] and a ret z dec a ld [wSFXTimer], a ret SetSongBank: ; 0x52c di ld [wCurrentSongBank], a ei ret CallInFollowingTable: ; 0x532 ; Calls a function in a table located immediately after a call to this function. ; Inputs: a = entry in the table ld e, a ld d, $0 sla e rl d sla e rl d ; multiplied a by 4 because entries in the table are 4 bytes each pop hl add hl, de ld e, [hl] inc hl ld d, [hl] inc hl ld a, [hl] ld h, d ld l, e jp BankSwitch BankSwitchSimple: ; 0x549 ; Switches to Bank in register a and jumps to hl. ld [hLoadedROMBank], a ld [MBC5RomBank], a ; Load Bank jp [hl] BankSwitch: ; 0x54f ld e, a ld a, [hLoadedROMBank] ; currently-loaded Bank cp e jr z, .doJump push af ld a, e call .loadNewBank call .doJump pop de ld a, d .loadNewBank push hl push de ld hl, rIE ld d, [hl] ld [hl], $0 ld [MBC5RomBank], a ld [hLoadedROMBank], a ld [hl], d pop de pop hl ret .doJump ld a, [hFarCallTempE] ld e, a ld a, [hFarCallTempA] jp [hl] Func_576: ; 0x576 ld a, [rLCDC] bit 7, a ret z ld a, [hLCDC] res 7, a ld [hLCDC], a .asm_581 ld a, [rLCDC] bit 7, a jr nz, .asm_581 ret Func_588: ; 0x588 ld a, [hFFC4] and a call nz, Func_597 ld a, [hLCDC] set 7, a ld [rLCDC], a ld [hLCDC], a ret Func_597: ; 0x597 ld de, rBGPI ld a, $80 ld [de], a inc de ld b, $8 .asm_5a0 ld a, [wBGP] call Func_5c2 dec b jr nz, .asm_5a0 ld de, rOBPI ld a, $80 ld [de], a inc de ld b, $4 .asm_5b2 ld a, [wOBP0] call Func_5c2 ld a, [wOBP1] call Func_5c2 dec b jr nz, .asm_5b2 ret Func_5c2: ; 0x5c2 push bc ld b, $4 .asm_5c5 push af push bc and $3 sla a ld c, a ld b, $0 ld hl, Data_5e1 add hl, bc ld a, [hli] ld [de], a ld a, [hli] ld [de], a pop bc pop af srl a srl a dec b jr nz, .asm_5c5 pop bc ret Data_5e1: dr $5e1, $5e9 Func_5e9: ld a, [rIE] res 0, a ld [rIE], a ret Func_5f0: ld a, [rIE] set 0, a ld [rIE], a ret WriteDMACodeToHRAM: ; 0x5f7 ; Initializes registers hPushOAM - hFarCallTempA ld c, $80 ld b, $a ; number of bytes to load ld hl, DMARoutine .loop ld a, [hli] ld [$ff00+c], a ; add register c to $ff00, and store register a into the resulting address inc c dec b jr nz, .loop ret DMARoutine: ; This routine is initially loaded into hPushOAM - hFarCallTempA by WriteDMACodeToHRAM. ld a, (wOAMBuffer >> 8) ld [rDMA], a ; start DMA ld a, $28 .waitLoop ; wait for DMA to finish dec a jr nz, .waitLoop ret WaitForLCD: ; 0x60f ; Wait for LCD controller to stop reading from both OAM and VRAM because ; CPU can't access OAM, VRAM, or palette data ($ff69, $ff6b) during this time. ld a, [rSTAT] ; LCDC Status register and $3 jr nz, WaitForLCD ld a, $a .delay10Cycles dec a jr nz, .delay10Cycles ret Func_61b: ; 0x61b ld a, [rLY] ; LY register (LCDC Y-Coordinate) cp $40 jr c, .asm_625 cp $80 jr c, .asm_63d .asm_625 ld a, [rLY] ; LY register (LCDC Y-Coordinate) cp $40 jr c, .asm_625 cp $80 jr nc, .asm_625 .asm_62f ld a, [rSTAT] and $3 jr nz, .asm_62f ; wait for lcd controller to finish transferring data ld a, $15 .wait dec a jr nz, .wait nop nop nop .asm_63d ret Func_63e: ; 0xc3e dec bc .asm_63f ld [hli], a dec bc bit 7, b jr z, .asm_63f ret Func_646: srl b rr c .asm_064a ld a, e ld [hli], a ld a, d ld [hli], a dec bc ld a, b or c jr nz, .asm_064a ret ClearData: ; 0x654 ; Clears bc bytes starting at hl. ; bc can be a maximum of $7fff, since it checks bit 7 of b when looping. xor a dec bc .clearLoop ld [hli], a dec bc bit 7, b jr z, .clearLoop ret LocalCopyData: ; 0x65d ld a, [hli] ld [de], a inc de dec bc ld a, c or b jr nz, LocalCopyData ret FarCopyData: ; 0x666 spooky ; Copies data from any bank to either working RAM or video RAM ; Input: hl = address of data to copy ; a = bank of data to copy ; de = destination for data ; bc = number of bytes to copy bit 7, h jr nz, .copyFromSRAM ld [hROMBankBuffer], a ld a, [hLoadedROMBank] push af ld a, [hROMBankBuffer] ld [hLoadedROMBank], a ld [MBC5RomBank], a scf jr .copyData .copyFromSRAM ld [MBC5SRamBank], a and a .copyData push af .copyLoop ld a, [hli] ld [de], a inc de dec bc ld a, c or b jr nz, .copyLoop pop af ret nc pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ret ReadByteFromBank: ; 0x68f ; Input: a = bank ; hl = address of byte to read ; Output: a = byte at a:hl push de ld d, a ld a, [hLoadedROMBank] ld e, a ld a, d ld [hLoadedROMBank], a ld [MBC5RomBank], a ld d, [hl] ld a, e ld [hLoadedROMBank], a ld [MBC5RomBank], a ld a, d pop de ret LoadVideoData: ; 0x6a4 ; Input: ; hl = address of pointer table ; a = index of item to load in pointer table ; This needs more documentation. It loads things like graphics and palettes. sla a ld c, a ld b, $0 add hl, bc ld a, [hli] ld h, [hl] ld l, a .loadItem ld a, [hli] ld c, a and [hl] cp $ff ; two consecutive $ff bytes terminate the array ret z ld a, [hli] ld b, a ; bc contains pointer to data to be loaded push hl push bc ld a, [hli] ; a contains bank of data to be loaded ld e, [hl] inc hl ld d, [hl] ; de contains destination address for data inc hl ld c, [hl] inc hl ld b, [hl] ; bc contains last word of data struct inc hl ; this is a wasted instruction pop hl call Func_6cb pop hl ld bc, $0005 add hl, bc jr .loadItem Func_6cb: ; 0x6cb srl b rr c jp c, Func_6fd ; if lowest bit of bc is set jp Func_6d5 ; This jumps to the next instruction... Strange. Func_6d5: ; 0x6d5 ld [hROMBankBuffer], a ; save bank of data to be loaded ld a, [hLoadedROMBank] push af ld a, [hROMBankBuffer] ; a contains bank of data to be loaded ld [hLoadedROMBank], a ld [MBC5RomBank], a ; switch bank to the bank of data to be loaded srl b rr c rl a and $1 ; checks bit 1 of the last word in the data struct ld [rVBK], a ; set VRAM Bank .copyByte ld a, [hli] ld [de], a inc de dec bc ld a, c or b ; does bc = 0? jr nz, .copyByte xor a ld [rVBK], a ; set VRAM Bank to Bank 0 pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ; reload the previous ROM Bank ret Func_6fd: ; 0x6fd ld [hROMBankBuffer], a ; save bank of data to be loaded ld a, [hLoadedROMBank] push af ld a, [hROMBankBuffer] ; a contains bank of data to be loaded ld [hLoadedROMBank], a ld [MBC5RomBank], a ; switch bank to the bank of data to be loaded ld a, e bit 6, a jr nz, .asm_717 ld de, rBGPI call Func_724 jr z, .asm_71d xor a .asm_717 ld de, rOBPI call Func_724 .asm_71d pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ret Func_724: ; 0x724 res 6, a ld b, a set 7, a ld [de], a inc de .copyByte ld a, [hli] ld [de], a inc b dec c ret z bit 6, b jr z, .copyByte ret LoadOrCopyVRAMData: ; 0x735 push hl ld hl, rLCDC bit 7, [hl] pop hl jp z, FarCopyData ; fall through LoadVRAMData: ; 0x73f ; This loads some data into VRAM. It waits for the LCD H-Blank to copy the data 4 bytes at a time. ; input: hl = source of data ; a = bank of data to load ; de = destination of data ; bc = number of bytes to copy bit 7, h jr nz, .asm_752 ld [hROMBankBuffer], a ld a, [hLoadedROMBank] push af ld a, [hROMBankBuffer] ld [hLoadedROMBank], a ld [MBC5RomBank], a scf jr .asm_756 .asm_752 ld [MBC5SRamBank], a and a .asm_756 push af call WaitForLCD .loop call Func_61b .waitForHBlank ld a, [rSTAT] and $3 jr nz, .waitForHBlank ld a, [hli] ld [de], a inc de ld a, [hli] ld [de], a inc de ld a, [hli] ld [de], a inc de ld a, [hli] ld [de], a inc de nop nop nop nop nop nop nop nop nop nop nop nop dec bc dec bc dec bc dec bc nop nop nop nop ld a, b or c jr nz, .loop pop af ret nc pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ret FarCopyPalettes: ; 0x790 push hl ld hl, rLCDC bit 7, [hl] pop hl jp nz, Func_7dc bit 7, h jr nz, .asm_7ad ld [hROMBankBuffer], a ld a, [hLoadedROMBank] push af ld a, [hROMBankBuffer] ld [hLoadedROMBank], a ld [MBC5RomBank], a scf jr .asm_7b1 .asm_7ad ld [MBC5SRamBank], a and a .asm_7b1 push af ld a, e bit 6, e ld de, rBGPI jr z, .asm_7bf res 6, a ld de, rOBPI .asm_7bf set 7, a ld [de], a inc de .asm_7c3 ld a, [hli] ld [de], a ld a, [hli] ld [de], a ld a, [hli] ld [de], a ld a, [hli] ld [de], a dec bc dec bc dec bc dec bc ld a, b or c jr nz, .asm_7c3 pop af ret nc pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ret Func_7dc: ; 0x7dc bit 7, h jr nz, .asm_7ef ld [hROMBankBuffer], a ld a, [hLoadedROMBank] push af ld a, [hROMBankBuffer] ld [hLoadedROMBank], a ld [MBC5RomBank], a scf jr .asm_7f3 .asm_7ef ld [MBC5SRamBank], a and a .asm_7f3 push af ld a, e bit 6, e ld de, rBGPI jr z, .asm_801 res 6, a ld de, rOBPI .asm_801 push hl ld h, d ld l, e set 7, a call PutTileInVRAM inc de pop hl call WaitForLCD .asm_80e call Func_61b .asm_811 ld a, [rSTAT] and $3 jr nz, .asm_811 ld a, [hli] ld [de], a ld a, [hli] ld [de], a ld a, [hli] ld [de], a ld a, [hli] ld [de], a nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop dec bc dec bc dec bc dec bc nop nop nop nop ld a, b or c jr nz, .asm_80e pop af ret nc pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ret PutTileInVRAM: ; 0x848 ; Puts a tile in VRAM. ; input: a = tile number ; hl = pointer to VRAM location where tile should be placed push af call WaitForLCD call Func_61b .asm_84f ld a, [rSTAT] and $3 jr nz, .asm_84f ; wait for lcd controller to finish transferring data pop af ld [hl], a ; Store tile number in VRAM background map ret Func_858: ; 0x858 push af call WaitForLCD call Func_61b .asm_85f ld a, [rSTAT] and $3 jr nz, .asm_85f ld a, $1 ld [rVBK], a pop af ld [hl], a xor a ld [rVBK], a ret Func_86f: ; 0x86f ld [hROMBankBuffer], a ld a, [hLoadedROMBank] push af ld a, [hROMBankBuffer] ld [hLoadedROMBank], a ld [MBC5RomBank], a ld a, [rLCDC] bit 7, a jr nz, .asm_8ac ld a, $1 ld [rVBK], a ld b, $4 .asm_887 push bc ld a, [de] ld [hli], a inc de ld a, [de] ld [hli], a inc de ld a, [de] ld [hli], a inc de ld a, [de] ld [hli], a inc de ld a, [de] ld [hli], a inc de ld a, [de] ld [hli], a inc de ld bc, $001a add hl, bc pop bc dec b jr nz, .asm_887 xor a ld [rVBK], a pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ret .asm_8ac ld b, $4 .asm_8ae push bc ld a, [de] call Func_858 inc hl inc de ld a, [de] call Func_858 inc hl inc de ld a, [de] call Func_858 inc hl inc de ld a, [de] call Func_858 inc hl inc de ld a, [de] call Func_858 inc hl inc de ld a, [de] call Func_858 inc de ld bc, $001b add hl, bc pop bc dec b jr nz, .asm_8ae pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ret Func_8e1: ; 0x8e1 ld [hROMBankBuffer], a ld a, [hLoadedROMBank] push af ld a, [hROMBankBuffer] ld [hLoadedROMBank], a ld [MBC5RomBank], a ld a, [rLCDC] bit 7, a jr nz, .asm_902 ld a, c ld [hli], a .asm_8f5 ld a, [de] ld [hl], a inc de dec b jr nz, .asm_8f5 pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ret .asm_902 ld a, c call PutTileInVRAM inc hl .asm_907 ld a, [de] call PutTileInVRAM inc de dec b jr nz, .asm_907 pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ret ClearOAMBuffer: ; 0x916 ; Clears the OAM buffer by loading $f0 into all of the entries. ld hl, wOAMBuffer ; 0xd000 ld b, 4 * 40 ; wOAMBuffer is 4 * 40 bytes long (40 OAM entries, 4 bytes each) ld a, $f0 ; byte to write .loop ld [hli], a dec b jr nz, .loop xor a ld [wOAMBufferSize], a ret Func_926: ; 0x926 ld a, [wOAMBufferSize] cp wOAMBufferEnd % $100 jr nc, .asm_93a ld l, a ld h, wOAMBufferEnd / $100 cpl add (wOAMBufferEnd + 1) % $100 ld b, a ld a, $f0 .asm_936 ld [hli], a dec b jr nz, .asm_936 .asm_93a xor a ld [wOAMBufferSize], a ret AdvanceFrames: ; 0x93f push bc rst AdvanceFrame pop bc dec bc ld a, c or b jr nz, AdvanceFrames ret SGBWait1750: ; 0x948 ld de, 1750 .asm_94b nop nop nop dec de ld a, d or e jr nz, .asm_94b dec bc ld a, b or c jr nz, SGBWait1750 ret GenRandom: ; 0x959 push bc push de push hl ld a, [wd811] ld c, a ld b, $0 inc a cp $37 jr nz, .asm_96e call Func_9fa xor a ld bc, $0000 .asm_96e ld [wd811], a ld hl, wd812 add hl, bc ld a, [hl] pop hl pop de pop bc ret Func_97a: ; 0x97a ld a, [wd810] ld d, a ld a, $0 ld a, [$afff] .asm_983 cp d jr c, .asm_989 sub d jr .asm_983 .asm_989 ld [wd80f], a ld [wd848], a ld e, $1 ld hl, Data_9c4 ld a, $36 .asm_996 push af ld c, [hl] inc hl ld b, $0 push hl ld hl, wd812 add hl, bc ld [hl], e ld a, [wd80f] sub e jr nc, .asm_9a8 add d .asm_9a8 ld e, a ld a, [hl] ld [wd80f], a pop hl pop af dec a jr nz, .asm_996 call Func_9fa call Func_9fa call Func_9fa ld a, $0 call GenRandom ld [$afff], a ret Data_9c4: db $14, $29, $07, $1c, $31, $0f, $24, $02, $17 db $2c, $0a, $1f, $34, $12, $27, $05, $1a, $2f db $0d, $22, $00, $15, $2a, $08, $1d, $32, $10 db $25, $03, $18, $2d, $0b, $20, $35, $13, $28 db $06, $1b, $30, $0e, $23, $01, $16, $2b, $09 db $1e, $33, $11, $26, $04, $19, $2e, $0c, $21 Func_9fa: ; 0x9fa ld a, [wd810] ld d, a ld bc, wd812 ld hl, wd831 ld e, $18 .asm_a06 ld a, [bc] sub [hl] jr nc, .asm_a0b add d .asm_a0b ld [bc], a dec e jr nz, .asm_a06 ld bc, wd82a ld hl, wd812 ld e, $1f .asm_a17 ld a, [bc] sub [hl] jr nc, .asm_a1c add d .asm_a1c ld [bc], a dec e jr nz, .asm_a17 ret Func_a21: ; 0xa21 push bc push hl ld c, a ld b, $0 ld hl, Data_a38 add hl, bc ld l, [hl] call GenRandom call Func_dd4 inc h srl h ld a, h pop hl pop bc ret Data_a38: x = 0 REPT 128 db x | ((x >> 7) & 1) x = x + 2 ENDR ReadJoypad: ; 0xab8 ; Reads the current state of the joypad and saves the state into ; some registers the game uses during gameplay. It remembers the joypad state ; from the current frame, previous frame, and two frames ago. ld a, $20 ld [rJOYP], a ld a, [rJOYP] ld a, [rJOYP] and $f swap a ld b, a ld a, $30 ld [rJOYP], a ld a, $10 ld [rJOYP], a ld a, [rJOYP] ld a, [rJOYP] ld a, [rJOYP] ld a, [rJOYP] ld a, [rJOYP] ld a, [rJOYP] and $f or b cpl ; a contains currently-pressed buttons ld [hJoypadState], a ld a, $30 ld [rJOYP], a ld a, [hJoypadState] ld hl, hPreviousJoypadState xor [hl] ; a contains buttons that are different from previous frame push af ld hl, hJoypadState and [hl] ; a contains newly-pressed buttons compared to last frame ld [hNewlyPressedButtons], a ld [hPressedButtons], a pop af ld hl, hPreviousJoypadState and [hl] ; a contains newly-pressed buttons compared to two frames ago ld [hPrevPreviousJoypadState], a ld a, [hJoypadState] and a jr z, .asm_b15 ld hl, hPreviousJoypadState cp [hl] jr nz, .asm_b15 ; button(s) is pressed, and they're identical to the buttons pressed last frame. ; this code is related to holding down a button for an extended period of time. ld hl, hJoyRepeatDelay dec [hl] jr nz, .asm_b1a ld a, [hJoypadState] ld [hPressedButtons], a ld a, [wd807] ld [hJoyRepeatDelay], a jr .asm_b1a .asm_b15 ld a, [wd806] ld [hJoyRepeatDelay], a .asm_b1a ld a, [hJoypadState] ld [hPreviousJoypadState], a ld hl, wd808 ld a, [hJoypadState] or [hl] ld [hli], a ld a, [hNewlyPressedButtons] or [hl] ld [hli], a ld a, [hPressedButtons] or [hl] ld [hli], a ret Func_b2e: ; 0xb2e ld hl, wd808 xor a ld [hli], a ld [hli], a ld [hl], a ret IsKeyPressed2: ; 0xb36 ld a, [hJoypadState] and [hl] jr z, .asm_b3e cp [hl] jr z, .asm_b48 .asm_b3e inc hl ld a, [hJoypadState] and [hl] ret z cp [hl] jr z, .asm_b48 xor a ret .asm_b48 ld a, $1 and a ret IsKeyPressed: ; 0xb4c ; Checks if a key for the specified key config is pressed. ; input: hl = pointer to key config byte pair (e.g. wKeyConfigLeftFlipper) ; output: zero flag is set if a corresponding key is pressed ; zero flag is reset if no corresponding key is pressed ld a, [hJoypadState] and [hl] jr z, .asm_b58 cp [hl] jr nz, .asm_b58 ld a, [hNewlyPressedButtons] and [hl] ret nz .asm_b58 inc hl ld a, [hJoypadState] and [hl] ret z cp [hl] jr nz, .asm_b64 ld a, [hNewlyPressedButtons] and [hl] ret .asm_b64 xor a ret Func_b66: ; 0xb66 ld a, [hGameBoyColorFlag] and a jr nz, .asm_b73 xor a ld [hBGP], a ld [hOBP0], a ld [hOBP1], a ret .asm_b73 ld de, rBGPI ld hl, wPaletteData ld b, $0 ld c, $20 .asm_b7d ld a, b ld [rBGPI], a inc b ld a, [rBGPD] ld [hli], a ld a, b ld [rBGPI], a inc b ld a, [rBGPD] ld [hli], a dec c jr nz, .asm_b7d ld b, $0 ld c, $20 .asm_b92 ld a, b ld [rOBPI], a inc b ld a, [rOBPD] ld [hli], a ld a, b ld [rOBPI], a inc b ld a, [rOBPD] ld [hli], a dec c jr nz, .asm_b92 ld de, rBGPI ld b, $2 .asm_ba8 ld a, $80 ld [de], a inc de ld c, $20 .asm_bae ld a, $ff ld [de], a ld [hli], a ld a, $7f ld [de], a ld [hli], a dec c jr nz, .asm_bae inc de dec b jr nz, .asm_ba8 ret Func_bbe: ; 0xbbe ld a, [hGameBoyColorFlag] and a jp nz, Func_c19 ld hl, hBGP ld de, wBGP ld b, $3 .asm_bcc ld a, [de] and $55 ld c, a ld a, [de] and $aa srl a and c ld [hli], a inc de dec b jr nz, .asm_bcc ld bc, $0002 call AdvanceFrames ld hl, hBGP ld de, wBGP ld b, $3 .asm_be9 ld a, [de] and $aa srl a add [hl] ld [hli], a inc de dec b jr nz, .asm_be9 ld bc, $0002 call AdvanceFrames ld hl, hBGP ld de, wBGP ld b, $3 .asm_c02 ld a, [de] and $55 ld c, a ld a, [de] and $aa srl a or c add [hl] ld [hli], a inc de dec b jr nz, .asm_c02 ld bc, $0002 call AdvanceFrames ret Func_c19: ; 0xc19 ld b, $10 .asm_c1b push bc ld de, wPaletteData ld hl, wd280 call Func_c2d call Func_d61 pop bc dec b jr nz, .asm_c1b ret Func_c2d: ; 0xc2d ld a, b cp $1 jr z, .asm_c49 ld c, $40 .asm_c34 push bc ld a, [hli] sub $42 ld c, a ld a, [hld] sbc $8 ld b, a call Func_c60 ld a, c ld [hli], a ld a, b ld [hli], a pop bc dec c jr nz, .asm_c34 ret .asm_c49 ld c, $40 .asm_c4b push bc ld a, [hli] sub $21 ld c, a ld a, [hld] sbc $4 ld b, a call Func_c60 ld a, c ld [hli], a ld a, b ld [hli], a pop bc dec c jr nz, .asm_c4b ret Func_c60: ; 0xc60 push hl ld a, [de] and $1f ld l, a ld a, c and $1f cp l jr nc, .asm_c70 ld a, c and $e0 or l ld c, a .asm_c70 ld a, [de] and $e0 ld l, a inc de ld a, [de] srl a rr l srl a rr l ld a, c and $e0 ld h, a ld a, b srl a rr h srl a rr h ld a, h cp l jr nc, .asm_ca3 ld h, $0 sla l rl h sla l rl h ld a, c and $1f or l ld c, a ld a, b and $7c or h ld b, a .asm_ca3 ld a, [de] and $7c ld l, a ld a, b and $7c cp l jr nc, .asm_cb2 ld a, b and $3 or l ld b, a .asm_cb2 inc de pop hl ret Func_cb5: ; 0xcb5 ld a, [hGameBoyColorFlag] and a jp nz, Func_cee ld hl, hBGP ld b, $3 .asm_cc0 push bc push hl ld b, $3 .asm_cc4 ld a, [hl] and $55 ld c, a ld a, [hl] and $aa srl a or c cpl inc a add [hl] ld [hli], a dec b jr nz, .asm_cc4 ld bc, $0002 call AdvanceFrames pop hl pop bc dec b jr nz, .asm_cc0 xor a ld hl, hBGP ld [hli], a ld [hli], a ld [hl], a ld bc, $0002 call AdvanceFrames ret Func_cee: ; 0xcee ld hl, wd280 ld de, rBGPI call Func_d9d ld hl, wd2c0 ld de, rOBPI call Func_d9d ld b, $10 .asm_d02 push bc ld hl, wd280 call Func_d11 call Func_d61 pop bc dec b jr nz, .asm_d02 ret Func_d11: ; 0xd11 ld b, $40 .asm_d13 ld a, [hl] and $1f add $2 ld e, a cp $1f jr c, .asm_d1f ld e, $1f .asm_d1f ld a, [hl] and $e0 or e ld [hl], a ld a, [hli] and $e0 ld e, [hl] dec hl srl e rr a srl e rr a add $10 ld e, a jr nc, .asm_d38 ld e, $f8 .asm_d38 ld d, $0 sla e rl d sla e rl d ld a, [hl] and $1f or e ld [hli], a ld a, [hl] and $7c or d ld [hl], a ld a, [hl] and $7c add $8 ld e, a cp $7c jr c, .asm_d58 ld e, $7c .asm_d58 ld a, [hl] and $3 or e ld [hli], a dec b jr nz, .asm_d13 ret Func_d61: ; 0d61 ld a, [rIE] res 0, a ld [rIE], a ld hl, wd280 ld de, rBGPI ld a, $80 ld [de], a inc de .asm_d71 ld a, [rLY] cp $90 jr c, .asm_d71 ld b, $10 .asm_d79 ld a, [hli] ld [de], a ld a, [hli] ld [de], a ld a, [hli] ld [de], a ld a, [hli] ld [de], a dec b jr nz, .asm_d79 inc de ld a, $80 ld [de], a inc de ld b, $10 .asm_d8b ld a, [hli] ld [de], a ld a, [hli] ld [de], a ld a, [hli] ld [de], a ld a, [hli] ld [de], a dec b jr nz, .asm_d8b ld a, [rIE] set 0, a ld [rIE], a ret Func_d9d: ; 0xd9d ld b, $0 ld c, e inc c call WaitForLCD .asm_da4 call Func_61b .asm_da7 ld a, [rSTAT] and $3 jr nz, .asm_da7 ; wait for lcd controller to finish transferring data ld a, b ld [de], a ld a, [$ff00+c] ld [hli], a inc b ld a, b ld [de], a ld a, [$ff00+c] ld [hli], a inc b ld a, b ld [de], a ld a, [$ff00+c] ld [hli], a inc b ld a, b ld [de], a ld a, [$ff00+c] ld [hli], a inc b nop nop nop nop nop nop nop nop nop nop nop nop nop ld a, b cp $40 jr nz, .asm_da4 ret Func_dd4: ; 0xdd4 ; Return a * l to hl ; Stupid waste of space push bc ld c, l ld b, $0 ld hl, $0000 bit 0, a jr z, .asm_de0 add hl, bc .asm_de0 sla c rl b bit 1, a jr z, .asm_de9 add hl, bc .asm_de9 sla c rl b bit 2, a jr z, .asm_df2 add hl, bc .asm_df2 sla c rl b bit 3, a jr z, .asm_dfb add hl, bc .asm_dfb sla c rl b bit 4, a jr z, .asm_e04 add hl, bc .asm_e04 sla c rl b bit 5, a jr z, .asm_e0d add hl, bc .asm_e0d sla c rl b bit 6, a jr z, .asm_e16 add hl, bc .asm_e16 sla c rl b bit 7, a jr z, .asm_e1f add hl, bc .asm_e1f pop bc ret ConvertHexByteToDecWord: ; 0xe21 ; Convert the base-16 value in register a into a Binary Coded Decimal (base-10) word. ; Example: If a = $97, de = $0151. ld b, a ld hl, PowersOfTwo ld de, $0000 .asm_e28 srl b ld a, [hli] jr nc, .asm_e34 add e daa ld e, a ld a, [hl] adc d daa ld d, a .asm_e34 inc hl ld a, b and a jr nz, .asm_e28 ret PowersOfTwo: ; 0xe3a dw $0001 dw $0002 dw $0004 dw $0008 dw $0016 dw $0032 dw $0064 dw $0128 Func_e4a: ; 0xe4a ld a, [hl] cp $64 jr z, .asm_e53 inc a ld [hl], a scf ret .asm_e53 and a ret Func_e55: ; 0xe55 cp c jr c, .asm_e5b sub c jr Func_e55 .asm_e5b and a ret Func_e5d: ; 0xe5d ld a, $1 ld [wd84a], a .asm_e62 ld a, [wd84a] and a jr nz, .asm_e62 ret Func_e69: ; 0xe69 ld a, [rLY] cp $90 jr nc, Func_e69 .asm_e6f ld a, [rSTAT] and $3 jr nz, .asm_e6f ld a, $a .asm_e77 dec a jr nz, .asm_e77 ld hl, wBottomMessageBuffer + $40 call Func_eef push hl ld hl, $9c00 call Func_ef8 pop hl call Func_eef push hl ld hl, $9c04 call Func_ef8 pop hl call Func_eef push hl ld hl, $9c08 call Func_ef8 pop hl call Func_eef push hl ld hl, $9c0c call Func_ef8 pop hl call Func_eef push hl ld hl, $9c10 call Func_ef8 pop hl ld hl, wBottomMessageBuffer + $c0 call Func_eef push hl ld hl, $9c20 call Func_ef8 pop hl call Func_eef push hl ld hl, $9c24 call Func_ef8 pop hl call Func_eef push hl ld hl, $9c28 call Func_ef8 pop hl call Func_eef push hl ld hl, $9c2c call Func_ef8 pop hl call Func_eef push hl ld hl, $9c30 call Func_ef8 pop hl ret Func_eef: ; 0xeef ld a, [hli] ld b, a ld a, [hli] ld c, a ld a, [hli] ld d, a ld a, [hli] ld e, a ret Func_ef8: ; 0xef8 ld a, [rSTAT] and $3 jr nz, Func_ef8 ld a, b ld [hli], a ld a, c ld [hli], a ld a, d ld [hli], a ld a, e ld [hli], a ld a, $a .asm_f08 dec a jr nz, .asm_f08 ret INCLUDE "home/save.asm" Func_fbc: ; 0xfbc jp Func_3ff Func_fbf: ; 0xfbf ld hl, hLastLYC ld c, [hl] ld a, [rLY] cp c jp c, Func_3ff inc c inc c cp c jp nc, Func_3ff ld a, [hLCDCMask] ld c, a ld a, [hLCDC] xor $10 and c ld c, a ld hl, rSTAT .asm_fdb ld a, [hl] and $3 jr nz, .asm_fdb ld a, [rLCDC] and $80 or c ld [rLCDC], a jp Func_3ff Func_fea: ; 0xfea ld hl, hLastLYC ld a, [hLYCSub] cp [hl] jr nz, .asm_1015 ld a, [rLY] cp [hl] jp nz, Func_3ff ld a, [hLCDC] xor $18 ld c, a ld a, [hHBlankSCX] ld b, a ld hl, rSTAT .asm_1003 ld a, [hl] and $3 jr nz, .asm_1003 ld a, [rLCDC] and $80 or c ld [rLCDC], a ld a, b ld [rSCY], a jp Func_3ff .asm_1015 ld a, [rLY] cp [hl] jr nz, .asm_1037 ld a, [hLastLYC] ld hl, hLYCSub sub [hl] add $40 ld c, a ld a, [hLYCSub] ld b, a ld hl, rSTAT .asm_1029 ld a, [hl] and $3 jr nz, .asm_1029 ld a, c ld [rSCY], a ld a, b ld [rLYC], a jp Func_3ff .asm_1037 ld hl, hLYCSub ld a, [rLY] cp [hl] jp nz, Func_3ff ld a, [hLCDC] xor $18 ld c, a ld a, [hHBlankSCX] ld b, a ld hl, rSTAT .asm_104b ld a, [hl] and $3 jr nz, .asm_104b ld a, [rLCDC] and $80 or c ld [rLCDC], a ld a, b ld [rSCY], a jp Func_3ff Func_105d: ; 0x105d ld hl, hLastLYC ld a, [rLY] cp [hl] jr z, .asm_1069 dec a cp [hl] jr nz, .asm_1080 .asm_1069 ld a, [hLYCSub] ld c, a ld a, [hHBlankSCX] ld b, a ld hl, rSTAT .asm_1072 ld a, [hl] and $3 jr nz, .asm_1072 ld a, b ld [rSCY], a ld a, c ld [rLYC], a jp Func_3ff .asm_1080 ld hl, hLYCSub ld a, [rLY] cp [hl] jr z, .asm_108d dec a cp [hl] jp nz, Func_3ff .asm_108d ld a, [hHBlankSCY] ld b, a ld hl, rSTAT .asm_1093 ld a, [hl] and $3 jr nz, .asm_1093 ld a, b ld [rSCY], a jp Func_3ff Func_109e: ; 0x109e jp Func_3ff Func_10a1: ; 0x10a1 jp Func_3ff Func_10a4: ; 0x10a4 jp Func_3ff Func_10a7: ; 0x10a7 jp Func_3ff Func_10aa: ; 0x10aa ld c, a ld a, [hli] ld b, a .loop push bc ld a, c ld c, [hl] inc hl ld b, [hl] inc hl push af ld a, [bc] ld e, a inc bc ld a, [bc] ld d, a inc bc pop af push hl call Func_10c5 pop hl pop bc dec b jr nz, .loop ret Func_10c5: ; 0x10c5 push af ld a, [rLCDC] bit 7, a jr z, .skip_wait_ly .wait_ly ld a, [rLY] cp $88 jr nc, .wait_ly .skip_wait_ly pop af ld hl, wd7fb ld l, [hl] ld h, wcb00 / $100 inc bc ld [hl], c inc h ld [hl], b inc h ld [hl], a inc h ld [hl], e inc h ld [hl], d ld e, $ff ld [hROMBankBuffer], a ld a, [hLoadedROMBank] push af ld a, [hROMBankBuffer] ld [hLoadedROMBank], a ld [MBC5RomBank], a dec bc ld a, [bc] ld hl, wd7fa add [hl] cp $30 jr c, .size_okay ld a, [bc] ld e, $0 .size_okay add $4 ld [hl], a pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, wd7fb ld l, [hl] ld h, wca00 / $100 inc l ld [hl], $0 dec l ld [hl], e ld hl, wd7fb inc [hl] ld a, [rLCDC] bit 7, a ret nz ld a, [rIE] push af res 0, a ld [rIE], a call Func_113a pop af ld [rIE], a ret Func_1129: ; 0x1129 ld a, [wd7fb] ld [wd7fc], a ret Func_1130: ; 0x1130 push hl ld a, [wd7fb] ld hl, wd7fc cp [hl] pop hl ret Func_113a: ; 0x113a ld hl, wd7fc ld a, [wd7fb] cp [hl] ret z ld l, [hl] ld h, $ca ld [hl], $ff .loop ld a, [hl] and a jr z, .done push hl inc h ld e, [hl] inc h ld d, [hl] inc h ld a, [hLoadedROMBank] push af ld a, [hl] ld [hLoadedROMBank], a ld [MBC5RomBank], a inc h ld a, [hl] inc h ld h, [hl] ld l, a call JumpToHL pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a pop hl inc l jr .loop .done ld a, l ld [wd7fc], a ld hl, wd7fb cp [hl] ret nz xor a ld [wd7fa], a ret JumpToHL: ; 0x117a jp [hl] LoadTileLists: ; 0x117b ; Loads a series of defined tile ids into VRAM ; input: de = pointer to data structure ; data structure: list of VRAM tile data with the following format ; [num tiles][destination pointer][list of tile ids] ld h, d ld l, e .loadTileSequence ld a, [hli] and a ret z ld b, a ld a, [hli] ld e, a ld a, [hli] ld d, a ; de = destination for tile data .loadTileData ld a, [hli] ld [de], a inc de dec b jr nz, .loadTileData jr .loadTileSequence LoadTileListsBank1: ; 0x118d ld a, $1 ld [rVBK], a call LoadTileLists xor a ld [rVBK], a ret Func_1198: ld h, d ld l, e .asm_119a ld a, [hli] and a ret z ld b, a ld a, [hli] ld e, a ld a, [hli] ld d, a srl b jr nc, .asm_11a8 ld a, [hli] ld c, a .asm_11a8 push hl ld h, d ld l, e ld a, c .asm_11ac ld [hli], a inc a dec b jr nz, .asm_11ac ld c, a pop hl jr .asm_119a Func_11b5: ; 11b5 (0:11b5) ld h, d ld l, e .asm_11b7 ld a, [hli] and a ret z ld b, a ld a, [hli] ld e, a ld a, [hli] ld d, a ld a, [hli] .asm_11c0 ld [de], a inc de dec b jr nz, .asm_11c0 jr .asm_11b7 Func_11c7: ld a, $1 ld [rVBK], a call Func_11b5 xor a ld [rVBK], a ret Func_11d2: ld h, d ld l, e ld a, [hLoadedROMBank] ld [$ff94], a .asm_11d8 ld a, [hli] and a ret z ld [$ff95], a ld a, [hli] ld e, a ld a, [hli] ld d, a ld a, [hli] ld c, a ld a, [hli] ld b, a ld a, [hli] ld [hLoadedROMBank], a ld [MBC5RomBank], a push hl ld h, b ld l, c ld a, [$ff95] ld b, a .asm_11f1 ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc de dec b jr nz, .asm_11f1 pop hl ld a, [$ff94] ld [hLoadedROMBank], a ld [MBC5RomBank], a jr .asm_11d8 Func_122e: ld a, $1 ld [rVBK], a ld h, d ld l, e ld a, [hLoadedROMBank] ld [$ff94], a .asm_1238 ld a, [hli] and a jr nz, .asm_1240 xor a ld [rVBK], a ret .asm_1240 ld [$ff95], a ld a, [hli] ld e, a ld a, [hli] ld d, a ld a, [hli] ld c, a ld a, [hli] ld b, a ld a, [hli] ld [hLoadedROMBank], a ld [MBC5RomBank], a push hl ld h, b ld l, c ld a, [$ff95] ld b, a .asm_1256 ld a, [hli] ld [de], a inc de dec b jr nz, .asm_1256 pop hl ld a, [$ff94] ld [hLoadedROMBank], a ld [MBC5RomBank], a jr .asm_1238 Func_1266: ld h, d ld l, e .asm_1268 ld a, [hli] and a ret z ld [$ff94], a ld a, [hli] bit 6, a ld de, rBGPI jr z, .asm_127a res 6, a ld de, rOBPI .asm_127a set 7, a ld [de], a inc de ld a, [hli] ld c, a ld a, [hli] ld b, a ld a, [hLoadedROMBank] push af ld a, [hli] ld [hLoadedROMBank], a ld [MBC5RomBank], a push hl ld h, b ld l, c ld a, [$ff94] ld b, a .asm_1291 ld a, [hli] ld [de], a ld a, [hli] ld [de], a dec b jr nz, .asm_1291 pop hl pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a jr .asm_1268 INCLUDE "home/sgb.asm" INCLUDE "home/serial.asm" Func_1a21: ; 0x1a21 call Func_1a59 call Func_1a89 jr c, .asm_1a3f .asm_1a29 call Func_1aa9 call Func_1b3d jr c, .asm_1a3f ld a, [wd86c] and a jr z, .asm_1a29 call Func_1b60 jr c, .asm_1a3f call Func_1b88 .asm_1a3f call Func_1ba7 ret Func_1a43: ; 0x1a43 xor a ld [wd86e], a call Func_1a59 call Func_1a89 jr c, .asm_1a54 ld a, $1 ld [wd86e], a .asm_1a54 call Func_1ba7 ret ret ; unused instruction? Func_1a59: ; 0x1a59 ld [wd86a], a ld a, h ld [wd869], a ld a, l ld [wd868], a ld a, $80 ld [wd866], a ld a, $c2 ld [wd867], a xor a ld [wd86b], a ld [wd86c], a ld [wd86d], a call Func_16a2 ld hl, rIE set 3, [hl] xor a ld [$ffb1], a ld a, $1 ld [wd8e1], a ret Func_1a89: ; 0x1a89 call Func_16e2 cp $f0 jr z, .asm_1a9f cp $ff jp z, Func_1bb2 ld a, [wd8c8] cp $81 jp nz, Func_1bb2 and a ret .asm_1a9f ld a, [hNewlyPressedButtons] bit 1, a jp nz, Func_1bd3 rst AdvanceFrame jr Func_1a89 Func_1aa9: ; 0x1aa9 ld a, [wd866] ld l, a ld a, [wd867] ld h, a ld de, wc000 ld b, $2 .asm_1ab6 ld c, $14 .asm_1ab8 ld a, [hli] call Func_1ae2 dec c jr nz, .asm_1ab8 ld a, l add $c ld l, a jr nc, .asm_1ac6 inc h .asm_1ac6 dec b jr nz, .asm_1ab6 ld a, l ld [wd866], a ld a, h ld [wd867], a ld a, [wd86b] inc a ld [wd86b], a cp $9 jr nz, .asm_1ae1 ld a, $1 ld [wd86c], a .asm_1ae1 ret Func_1ae2: ; 0x1ae2 push bc push hl xor $80 swap a ld c, a and $f ld b, a ld a, c and $f0 ld c, a ld a, [wd868] ld l, a ld a, [wd869] ld h, a add hl, bc ld a, [hLoadedROMBank] push af ld a, [wd86a] ld [hLoadedROMBank], a ld [MBC5RomBank], a REPT 15 ld a, [hli] ld [de], a inc e ENDR ld a, [hli] ld [de], a inc de pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a pop hl pop bc ret Func_1b3d: ; 0x1b3d ld a, [wd86c] ld [wd8dd], a ld hl, wc000 ld a, $1 call Func_1779 cp $ff jp z, Func_1bb2 cp $f0 jr z, .asm_1b56 and a ret .asm_1b56 ld a, [hNewlyPressedButtons] bit BIT_B_BUTTON, a jp nz, Func_1bd3 rst AdvanceFrame jr Func_1b3d Func_1b60: ; 0x1b60 ld a, $1 ld [wd8a8], a ld a, $13 ld [wd8a9], a call Func_1740 cp $ff jp z, Func_1bb2 cp $f0 jr z, .asm_1b7e ld bc, $001e call AdvanceFrames and a ret .asm_1b7e ld a, [hNewlyPressedButtons] bit BIT_B_BUTTON, a jp nz, Func_1bd3 rst AdvanceFrame jr Func_1b60 Func_1b88: ; 0x1b88 ld a, [wd8c7] ld b, a cp $ff jr z, Func_1bb2 and $f0 jr nz, Func_1bb2 bit 1, b jr nz, .asm_1b9d call Func_16a2 and a ret .asm_1b9d ld a, [hNewlyPressedButtons] bit BIT_B_BUTTON, a jp nz, Func_1bd3 rst AdvanceFrame jr Func_1b88 Func_1ba7: ; 0x1ba7 ld hl, rIE res 3, [hl] xor a ld [wd8e1], a and a ret Func_1bb2: ; 0x1bb2 ld hl, Data_1bcf ld a, [wd8c7] cp $ff jr z, .asm_1bc6 ld b, $3 .asm_1bbe inc hl sla a jr c, .asm_1bc6 dec b jr nz, .asm_1bbe .asm_1bc6 ld a, [hl] ld [wd86d], a call Func_16a2 scf ret Data_1bcf: dr $1bcf, $1bd3 Func_1bd3: ; 0x1bd3 lb de, $00, $01 call PlaySoundEffect ld a, $5 ld [wd86d], a call Func_16a2 scf ret Func_1be3: ; 0x1be3 ld a, $c0 ld [rRP], a ld a, $ff ld [wd8ea], a xor a ld b, a .asm_1bee inc a jr nz, .asm_1bee inc b jr nz, .asm_1bee ld hl, wd8eb ld a, [rKEY1] bit 7, a jr z, .asm_1c0c ld [hl], $e inc hl ld [hl], $12 inc hl ld [hl], $8 inc hl ld [hl], $c inc hl ld [hl], $c ret .asm_1c0c ld [hl], $6 inc hl ld [hl], $8 inc hl ld [hl], $2 inc hl ld [hl], $4 inc hl ld [hl], $5 ret Func_1c1b: ; 0x1c1b inc d ret z ld a, [$ff00+c] bit 1, a jr z, Func_1c1b ret Func_1c23: ; 0x1c23 inc d ret z ld a, [$ff00+c] bit 1, a jr nz, Func_1c23 ret Func_1c2b: ; 0x1c2b ld a, $c1 ld [$ff00+c], a .asm_1c2e dec d jr nz, .asm_1c2e ret Func_1c32: ; 0x1c32 ld a, $c0 ld [$ff00+c], a .asm_1c35 dec d jr nz, .asm_1c35 ret Func_1c39: xor a ld [hNumFramesSinceLastVBlank], a ld a, $1 ld [wd8e9], a .asm_1c41 ld b, $2 ld c, rRP % $100 ld a, [$ff00+c] and b jr z, Func_1c50 ld a, [hNumFramesSinceLastVBlank] and a jr nz, Func_1ca1 jr .asm_1c41 Func_1c50: ; 0x1c50 ld a, $1 ld [wd8e9], a ld b, $1a ld c, rRP % $100 ld d, $0 ld e, d call Func_1c23 ld a, d and a jp z, Func_1dc2 ld d, e call Func_1c1b ld a, d and a jp z, Func_1dc2 call Func_1c23 ld a, d and a jp z, Func_1dc2 call Func_1c1b ld a, d and a jp z, Func_1dc2 cp $8 jp c, Func_1dc2 cp $2a jp nc, Func_1dc2 ld a, $0 ld [wd8ea], a ld d, b call Func_1c32 ld d, b call Func_1c2b ld d, b call Func_1c32 ld d, b call Func_1c2b ld d, b call Func_1c32 ret Func_1ca1: ; 0x1ca1 ld a, $2 ld [wd8e9], a ld b, $1a ld c, rRP % $100 ld d, b ld e, $0 call Func_1c32 ld d, b call Func_1c2b ld d, b call Func_1c32 ld d, b call Func_1c2b ld d, b call Func_1c32 ld d, e call Func_1c23 ld a, d and a jp z, Func_1dc2 ld d, e call Func_1c1b ld a, d and a jp z, Func_1dc2 ld d, e call Func_1c23 ld a, d and a jp z, Func_1dc2 ld d, e call Func_1c1b ld a, d and a jp z, Func_1dc2 ld d, $1a call Func_1c32 ld a, $0 ld [wd8ea], a ret Func_1cef: xor a ld [rRP], a ld a, $ff ld [wd8ea], a ret Func_1cf8: ; 0x1cf8 xor a ld [wd8e4], a ld [wd8e5], a push hl push bc ld hl, wd8e6 ld a, $5a ld [hli], a ld [hl], b dec hl ld b, $2 ld d, $1e call Func_1c32 call Func_1d44 pop bc pop hl call Func_1ed3 call Func_1d44 ld a, [wd8e4] ld [wd8e6], a ld a, [wd8e5] ld [wd8e7], a ld hl, wd8e6 ld b, $2 call Func_1d44 ld hl, wd8ea ld b, $1 call Func_1e3b ld a, [wd8e6] ld [wd8e4], a ld a, [wd8e7] ld [wd8e5], a ret Func_1d44: ; 0x1d44 ld a, [wd8ea] cp $0 ret nz ld c, rRP % $100 ld d, $16 call Func_1c2b ld d, $16 call Func_1c32 ld a, b cpl ld b, a .asm_1d59 inc b jr z, .asm_1dae ld a, $8 ld [wd8e3], a ld a, [hli] ld e, a ld a, [wd8e4] add e ld [wd8e4], a jr nc, .asm_1d75 ld a, [wd8e5] inc a ld [wd8e5], a jr .asm_1d78 .asm_1d75 call Func_1ed3 .asm_1d78 ld a, e rlca ld e, a jr nc, .asm_1d8d ld a, [wd8eb] ld d, a call Func_1c2b ld a, [wd8ec] ld d, a call Func_1c32 jr .asm_1d9b .asm_1d8d ld a, [wd8ed] ld d, a call Func_1c2b ld a, [wd8ee] ld d, a call Func_1c32 .asm_1d9b ld a, [wd8e3] dec a ld [wd8e3], a jr z, .asm_1dac call Func_1ed4 call Func_1ed4 jr .asm_1d78 .asm_1dac jr .asm_1d59 .asm_1dae call Func_1ed3 call Func_1ed3 call Func_1ed4 ld d, $16 call Func_1c2b ld d, $16 call Func_1c32 ret Func_1dc2: ; 0x1dc2 ld a, $2 ld [wd8ea], a ret Func_1dc8: ld a, [wd8ea] or $1 ld [wd8ea], a ret Func_1dd1: ; 0x1dd1 ld a, [wd8ea] or $4 ld [wd8ea], a ret Func_1dda: ; 0x1dda xor a ld [wd8e4], a ld [wd8e5], a push hl ld hl, wd8e6 ld b, $2 call Func_1e3b ld a, [wd8e7] ld [wd8e8], a ld b, a pop hl ld a, [wd8e6] cp $5a jp nz, Func_1dd1 call Func_1e3b ld a, [wd8e4] ld d, a ld a, [wd8e5] ld e, a push de ld hl, wd8e6 ld b, $2 call Func_1e3b pop de ld hl, wd8e6 ld a, [hli] xor d ld b, a ld a, [hl] xor e or b jr z, .asm_1e22 ld a, [wd8ea] or $1 ld [wd8ea], a .asm_1e22 push de ld hl, wd8ea ld b, $1 call Func_1d44 pop de ld a, d ld [wd8e4], a ld a, e ld [wd8e5], a ld a, [wd8e8] cp $82 ret z ret Func_1e3b: ; 0x1e3b ld a, [wd8ea] cp $0 ret nz ld c, rRP % $100 ld d, $0 call Func_1c23 ld a, d or a jp z, Func_1dc2 ld d, $0 call Func_1c1b ld a, d or a jp z, Func_1dc2 ld d, $0 call Func_1c23 ld a, d or a jp z, Func_1dc2 call Func_1ed4 call Func_1ed4 push af pop af ld a, b cpl ld b, a .asm_1e6c inc b jr z, .asm_1eb9 ld a, $8 ld [wd8e3], a .asm_1e74 ld d, $0 call Func_1c1b call Func_1c23 ld a, [wd8ef] cp d jr nc, .asm_1e88 ld a, e set 0, a ld e, a jr .asm_1e8c .asm_1e88 ld a, e res 0, a ld e, a .asm_1e8c ld a, [wd8e3] dec a ld [wd8e3], a jr z, .asm_1ea0 ld a, e rlca ld e, a call Func_1ed4 call Func_1ed4 jr .asm_1e74 .asm_1ea0 ld a, e ld [hli], a ld a, [wd8e4] add e ld [wd8e4], a jr nc, .asm_1eb4 ld a, [wd8e5] inc a ld [wd8e5], a jr .asm_1eb7 .asm_1eb4 call Func_1ed3 .asm_1eb7 jr .asm_1e6c .asm_1eb9 ld d, $0 call Func_1c1b ld a, d and a jp z, Func_1dc2 ld d, $11 call Func_1c32 ret Func_1ec9: ld b, $00 jp Func_1cf8 Func_1ece: ld b, $00 jp Func_1dda Func_1ed3: ; 0x1ed3 ret Func_1ed4: ; 0x1ed4 jr z, .asm_1ed6 .asm_1ed6 jr nz, .asm_1ed8 .asm_1ed8 ret Func_1ed9: push bc push de push hl ld e, a ld d, $0 sla e rl d ld a, [hLoadedROMBank] push af ld a, BANK(Data_8f06) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, Data_8f06 jr asm_1f3b Func_1ef2: push bc push de push hl ld e, a ld d, $0 sla e rl d ld a, [hLoadedROMBank] push af ld a, BANK(Data_8f06) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, Data_8f06 jr asm_1f3b LoadOAMData2: ; 0x1f0b ; This function loads OAM data, but it adds b and c to the x and y values ; input: a = OAM data id (see OAMDataPointers2) push bc push de push hl ld e, a ld d, $0 sla e rl d ld a, [hLoadedROMBank] push af ld a, Bank(OAMDataPointers2) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, OAMDataPointers2 jr asm_1f3b LoadOAMData: ; 0x1f24 ; This function loads OAM data, but it adds b and c to the x and y values ; input: a = OAM data id (see OAMDataPointers) push bc push de push hl ld e, a ld d, $0 sla e rl d ; multiply de by 2 ld a, [hLoadedROMBank] push af ld a, Bank(OAMDataPointers) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, OAMDataPointers asm_1f3b: ; 0x1f3b add hl, de ; hl points to oam pointer in OAMDataPointers ld a, [hli] ld e, a ld a, [hl] ld d, a ; de points to OAM data ld a, [wOAMBufferSize] ld l, a ld h, (wOAMBuffer >> 8) .loadOAMDataLoop ld a, [de] cp $80 ; OAM data list terminator jr z, .doneReadingOAMData add c ld [hli], a inc de ld a, [de] add b ld [hli], a inc de ld a, [de] ld [hli], a inc de ld a, [de] ld [hli], a inc de jr .loadOAMDataLoop .doneReadingOAMData ld a, l ld [wOAMBufferSize], a pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a pop hl pop de pop bc ret Func_1f68: push bc push de push hl ld e, a ld d, $0 sla e rl d ld a, [hLoadedROMBank] push af ld a, BANK(Data_8f06) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, Data_8f06 ; all 0s jr asm_1fca Func_1f81: push bc push de push hl ld e, a ld d, $0 sla e rl d ld a, [hLoadedROMBank] push af ld a, BANK(Data_8f06) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, Data_8f06 ; all 0s jr asm_1fca Func_1f9a: push bc push de push hl ld e, a ld d, $0 sla e rl d ld a, [hLoadedROMBank] push af ld a, BANK(OAMDataPointers2) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, OAMDataPointers2 jr asm_1fca Func_1fb3: push bc push de push hl ld e, a ld d, $0 sla e rl d ld a, [hLoadedROMBank] push af ld a, BANK(OAMDataPointers) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, OAMDataPointers asm_1fca add hl, de ld a, [hli] ld e, a ld a, [hl] ld d, a ld a, [wOAMBufferSize] ld l, a ld h, $d0 .asm_1fd5 ld a, [de] cp $80 jr z, .asm_1fee add c ld [hli], a inc de ld a, [de] add b ld [hli], a inc de ld a, [de] push hl ld hl, sp+$7 add [hl] pop hl ld [hli], a inc de ld a, [de] ld [hli], a inc de jr .asm_1fd5 .asm_1fee ld a, l ld [wOAMBufferSize], a pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a pop hl pop de pop bc ret Func_1ffc: ; 0x1ffc ld a, $b ld [wd806], a ld a, $4 ld [wd807], a callba Func_3c000 ld a, $1 ld [wd85d], a ld a, $37 ld [wd470], a ld [wd471], a ld [wd472], a ld a, SCREEN_ERASE_ALL_DATA ld [wCurrentScreen], a .master_loop call Func_2034 call Func_2043 call Func_926 call Func_b2e rst AdvanceFrame jr .master_loop Func_2034: ; 0x2034 ld a, [wd804] and a jr z, .asm_203f dec a ld [wd804], a ret .asm_203f ld [wd803], a ret Func_2043: ; 0x2043 ld a, [wCurrentScreen] call CallInFollowingTable CallTable_2049: ; 0x2049 ; First two bytes is function pointer. ; Third byte is bank of function. ; Fourth byte seems to be unused. padded_dab Func_8000 ; SCREEN_ERASE_ALL_DATA padded_dab HandleEraseAllDataMenu ; SCREEN_COPYRIGHT padded_dab HandleCopyrightScreen ; SCREEN_TITLESCREEN padded_dab HandleTitlescreen ; SCREEN_PINBALL_GAME padded_dab HandlePinballGame ; SCREEN_POKEDEX padded_dab HandlePokedexScreen ; SCREEN_OPTIONS padded_dab HandleOptionsScreen ; SCREEN_HIGH_SCORES padded_dab HandleHighScoresScreen ; SCREEN_FIELD_SELECT padded_dab HandleFieldSelectScreen ; end of call table Func_206d: ; 0x206d ld a, [hLoadedROMBank] push af ld a, Bank(Func_8d17) ld [hLoadedROMBank], a ld [MBC5RomBank], a call Func_8d17 jr c, .asm_2084 pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a and a ret .asm_2084 pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a scf ret Func_208c: ; 0x208c ld a, [hLoadedROMBank] push af ld a, Bank(Func_8ee0) ld [hLoadedROMBank], a ld [MBC5RomBank], a call Func_8ee0 jr c, .asm_20a3 pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a and a ret .asm_20a3 pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a scf ret MultiplyBbyCUnsigned: ; 0x20ab ; u16 bc = (u8)b * (u8)c push af xor a ld [hSignedMathSignBuffer], a jr asm_20c6 MultiplyBbyCSigned: ; s16 bc = (s8)b * (s8)c push af ld a, b xor c ld [hSignedMathSignBuffer], a bit 7, b jr z, .asm_20be ld a, b cpl inc a ld b, a .asm_20be bit 7, c jr z, asm_20c6 ld a, c cpl inc a ld c, a asm_20c6 ; b*c == (b**2 + c**2 - (b - c)**2) / 2 push de push hl ld a, b cp c jr nc, .c_le_b ld b, c ld c, a .c_le_b ; hl = b**2 + c**2 ld h, SquaresLow / $100 ld l, c ld e, [hl] inc h ; SquaresHigh / $100 ld d, [hl] ld l, b ld a, [hl] dec h ld l, [hl] ld h, a add hl, de push af ; hl -= (b - c) ** 2 ld d, SquaresLow / $100 ld a, b sub c ld e, a ld a, [de] ld c, a inc d ; SquaresHigh / $100 ld a, [de] ld b, a ld a, l sub c ld l, a ld a, h sbc b ld h, a jr nc, .no_carry pop af ccf jr .check_sign .no_carry pop af .check_sign ; hl /= 2 rr h rr l ld b, h ld c, l ld a, [hSignedMathSignBuffer] rlca jr nc, .done ld a, c cpl add $1 ld c, a ld a, b cpl adc $0 ld b, a .done pop hl pop de pop af ret MultiplyBCByEAndRoundToMostSignificantShort: ; 0x210b ; bc = round(bc * e / 256) ; b^d = sign of output push af push hl ld a, b xor d ld [hSignedMathSignBuffer2], a bit 7, b jr z, .positive1 ld a, c cpl add $1 ld c, a ld a, b cpl adc $0 ld b, a .positive1 push bc ld b, e call MultiplyBbyCUnsigned ld l, c ld h, b ld bc, $0080 add hl, bc ld l, h ld h, $0 pop bc ld c, e call MultiplyBbyCUnsigned add hl, bc ld a, [hSignedMathSignBuffer2] rlca jr nc, .positive2 ld a, l cpl add $1 ld l, a ld a, h cpl adc $0 ld h, a .positive2 ld c, l ld b, h pop hl pop af ret Cosine: ; 0x2147 ; cos(a) add $40 ; fall through Sine: ; 0x2149 ; sin(a) push hl ld [hSignedMathSignBuffer], a and $7f ; subtract 180 degrees cp $40 jr c, .firstQuadrant ; convert angle so it's between 0 and 90 degrees cpl add $80+1 .firstQuadrant ld hl, SineTable ld e, a ld d, $0 add hl, de ld e, [hl] pop hl ld d, $0 ld a, [hSignedMathSignBuffer] sla a ret nc ld d, $ff ret ApplyGravityToBall: ; 0x2168 ; Adds a constant to the pinball's y velocity. ld a, [wd549] and a ret z ld de, $000b ; gravity added to y velocity every frame ld hl, wBallYVelocity ld a, [hli] ld h, [hl] ld l, a add hl, de ld a, l ld [wBallYVelocity], a ld a, h ld [wBallYVelocity + 1], a ret LimitBallVelocity: ; 0x2180 ; Ensures that the ball's x and y velocity are kept under a threshold. ; The ball can travel at a higher max speed when moving diagonally, since it ; limits the x and y components independently. ld hl, wBallXVelocity + 1 call _LimitBallVelocity ld hl, wBallYVelocity + 1 ; fall through _LimitBallVelocity: ; 0x2189 ld a, [hl] bit 7, a ; is it negative velocity? (left or up) jr nz, .negativeVelocity cp $8 ret c ld a, $7 ; max positive velocity ld [hl], a ret .negativeVelocity cp $f9 ret nc ld a, $f9 ; max negative velocity ld [hl], a ret MoveBallPosition: ; 0x219c ; Updates the ball's position according to its velocity ld a, [wBallXPos] ld [wPreviousBallXPos], a ld a, [wBallXPos + 1] ld [wPreviousBallXPos + 1], a ld a, [wBallYPos] ld [wPreviousBallYPos], a ld a, [wBallYPos + 1] ld [wPreviousBallYPos + 1], a ld de, wBallXVelocity + 1 ld hl, wBallXPos call AddVelocityToPosition ld de, wBallYVelocity + 1 ld hl, wBallYPos ; fall through AddVelocityToPosition: ; 0x21c3 ld a, [de] bit 7, a jr nz, .asm_21d1 cp 1+4 jr c, .asm_21da ld bc, $04ff jr .asm_21de .asm_21d1 cp -4 jr nc, .asm_21da ld bc, -$04ff jr .asm_21de .asm_21da ld b, a dec de ld a, [de] ld c, a .asm_21de ld a, [hl] add c ld [hli], a ld a, [hl] adc b ld [hl], a ret NegateAngleAndApplyCollisionForce: ; 0x21e5 cpl inc a ; fall through ApplyCollisionForce: ; 0x21e7 push hl ; bc_ret = bc * cos(a) + de * sin(x) ; de_ret = bc * cos(a) - de * sin(x) push bc push de ld [hSineOrCosineArgumentBuffer], a call Cosine ld a, e ld [hCosineResultBuffer], a ld a, d ld [hCosineResultBuffer + 1], a call MultiplyBCByEAndRoundToMostSignificantShort ld l, c ld h, b pop bc push bc ld a, [hSineOrCosineArgumentBuffer] call Sine ld a, e ld [hSineResultBuffer], a ld a, d ld [hSineResultBuffer + 1], a call MultiplyBCByEAndRoundToMostSignificantShort add hl, bc pop de pop bc push hl push de ld a, [hSineResultBuffer] ld e, a ld a, [hSineResultBuffer + 1] cpl ld d, a call MultiplyBCByEAndRoundToMostSignificantShort ld l, c ld h, b pop bc ld a, [hCosineResultBuffer] ld e, a ld a, [hCosineResultBuffer + 1] ld d, a call MultiplyBCByEAndRoundToMostSignificantShort add hl, bc ld d, h ld e, l pop bc pop hl ret ApplyTorque: ; 0x222b push hl ld hl, wd7f8 ld [hl], $ff bit 7, d jr nz, .asm_2297 ld [hl], $0 ld a, d cp $3 jr c, .asm_2254 ld a, $ff ld [wd803], a ld a, $1 ld [wd804], a ld a, [wFlipperCollision] and a jr nz, .asm_2254 push de ld de, $0008 call Func_4d8 pop de .asm_2254 srl d rr e srl d rr e ld h, d ld l, e srl d rr e ld a, [wd7eb] and a jr z, .asm_226c .asm_2268 add hl, de dec a jr nz, .asm_2268 .asm_226c ld d, h ld e, l ld a, e cpl add $1 ld e, a ld a, d cpl adc $0 ld d, a ld a, [wBallSpin] sra a ld l, a ld h, $0 bit 7, l jr z, .asm_2286 ld h, $ff .asm_2286 add hl, bc ld b, h ld c, l push bc sla c rl b sla c rl b ld a, b ld [wBallSpin], a pop bc .asm_2297 pop hl ret LoadBallVelocity: ; 0x2299 ; Loads velocity of the ball into bc and de ; bc = x velocity ; de = y velocity push hl ld hl, wBallXVelocity ld a, [hli] ld c, a ld a, [hli] ld b, a ld a, [hli] ld e, a ld a, [hl] ld d, a pop hl ret SetBallVelocity: ; 0x22a7 ; Sets the x and y velocities of the ball. ; bc = x velocity ; de = y velocity push hl ld hl, wBallXVelocity ld a, c ld [hli], a ld a, b ld [hli], a ld a, e ld [hli], a ld a, d ld [hl], a pop hl ret CheckObjectCollision: ; 0x22b5 ld a, [wBallXPos + 1] sub $4 push af and $7 ld [wSubTileBallXPos], a ; sub-tile position pop af and $f8 ld c, a ld a, [wBallYPos + 1] sub $4 push af and $7 ld [wSubTileBallYPos], a pop af and $f8 ld b, a ld l, b ; bc contains tile coords of ball position ld h, $0 sla l rl h sla l rl h ; b was multiplied by 4 (y tile position) srl c srl c srl c ; c was divided by 8 (x tile position) ld b, $0 add hl, bc ld a, l ld [wBallPositionPointerOffsetFromStageTopLeft], a ld a, h ld [wBallPositionPointerOffsetFromStageTopLeft + 1], a ld a, [wStageCollisionMapPointer] ld c, a ld a, [wStageCollisionMapPointer + 1] ld b, a add hl, bc ; hl = address of upper-left collision byte ld a, [hLoadedROMBank] push af ld a, [wStageCollisionMapBank] ld [hLoadedROMBank], a ld [MBC5RomBank], a ld bc, $001f ; number of tiles wide - 1 ld a, [hli] ld [wUpperLeftCollisionAttribute], a ld a, [hl] ld [wUpperRightCollisionAttribute], a add hl, bc ld a, [hli] ld [wLowerLeftCollisionAttribute], a ld a, [hl] ld [wLowerRightCollisionAttribute], a pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ld a, [hLoadedROMBank] push af ld a, [wStageCollisionMasksBank] ld [hLoadedROMBank], a ld [MBC5RomBank], a ld a, [wSubTileBallXPos] sla a ld c, a ld b, $0 ld hl, SubTileXPos_CollisionDataPointers add hl, bc ld e, [hl] inc hl ld d, [hl] ld a, [wSubTileBallYPos] ld c, a ld b, $10 ; number of times to loop over .asm_233d .asm_233d push bc ld a, [de] inc de add c ; add the sub tile y pos push af srl a srl a srl a ld c, a ld b, $0 ld hl, wUpperLeftCollisionAttribute add hl, bc ld a, [hl] call Func_248a jr nc, .asm_235e pop af and $7 ld c, a ld b, $0 add hl, bc jr .asm_237b .asm_235e ld c, a ld b, $0 sla c rl b sla c rl b sla c rl b ld hl, wStageCollisionMasksPointer ld a, [hli] ld h, [hl] ld l, a add hl, bc pop af and $7 ld c, a ld b, $0 add hl, bc .asm_237b ld a, [de] inc de and [hl] push af ld a, [de] inc de ld c, a ld hl, wd7c9 add hl, bc pop af ld [hl], a pop bc dec b jr nz, .asm_233d pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, wd7c9 ld de, wd7d9 ld b, $4 .asm_239a ld a, [hli] ld [de], a inc de ld a, [hli] ld [de], a inc de ld a, [hli] ld [de], a inc de ld a, [hli] ld [de], a inc de dec b jr nz, .asm_239a ld hl, wd7c9 ld de, $0000 ld b, $0 ld a, [hl] and a jr z, .asm_23c1 .asm_23b5 ld a, [hli] inc b and a jr z, .asm_23c1 ld a, b cp $11 jr nc, .asm_23ee jr .asm_23b5 .asm_23c1 ld a, [hli] inc b and a jr nz, .asm_23cd ld a, b cp $11 jr nc, .asm_23ee jr .asm_23c1 .asm_23cd push de ld d, $1 ld c, b dec c .asm_23d2 ld a, [hli] inc b inc d and a jr nz, .asm_23d2 dec d ld a, b dec a dec a and $f swap c or c ld c, a ld a, d cp e pop de jr c, .asm_23e9 ld e, a ld d, c .asm_23e9 ld a, b cp $10 jr c, .asm_23c1 .asm_23ee ld a, e ld [wd7e9], a and a ret z ld a, [hLoadedROMBank] push af ld a, Bank(CollisionForceAngles) ld [hLoadedROMBank], a ld [MBC5RomBank], a push de ld e, d ld d, $0 ld hl, CollisionForceAngles add hl, de ld a, [hl] ld [wCollisionForceAngle], a sla e rl d ld hl, CollisionYDeltas add hl, de ld a, [wBallYPos] add [hl] ld [wBallYPos], a inc hl ld a, [wBallYPos + 1] adc [hl] ld [wBallYPos + 1], a ld hl, CollisionXDeltas add hl, de ld a, [wBallXPos] add [hl] ld [wBallXPos], a inc hl ld a, [wBallXPos + 1] adc [hl] ld [wBallXPos + 1], a pop de pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ld a, d swap a and $f ld e, a ld a, d and $f sub e jr nc, .asm_2449 add $10 .asm_2449 add e add e inc a and $1e ld c, a ld b, $0 ld hl, SubTileBallPosDeltas add hl, bc ld a, [wSubTileBallXPos] add $4 add [hl] bit 3, a ld c, b jr z, .asm_2462 ld c, $2 .asm_2462 ld a, [wSubTileBallYPos] add $4 inc hl add [hl] bit 3, a jr z, .asm_246e inc c .asm_246e ld hl, wUpperLeftCollisionAttribute add hl, bc ld a, [hl] ld [wCurCollisionAttribute], a ld hl, BallPositionPointerOffsetDeltas add hl, bc ld a, [wBallPositionPointerOffsetFromStageTopLeft] add [hl] ld [wd7f6], a ld a, [wBallPositionPointerOffsetFromStageTopLeft + 1] adc $0 ld [wd7f7], a ret Func_248a: ; 0x248a push af ld a, [wCurrentStage] bit 0, a jr nz, .asm_2495 pop af and a ret .asm_2495 pop af cp $d0 ccf ret nc cp $e0 jr nc, .asm_24ab sub $d0 sla a sla a sla a ld l, a ld h, $c4 scf ret .asm_24ab push de sub $e0 ld b, a ld a, [wCurrentStage] cp $6 ; gengar stage buggy? jr nc, .asm_24e0 bit 4, b ld hl, Data_3800 ld a, [wd7af] jr z, .asm_24c8 res 4, b ld hl, Data_3980 ld a, [wd7b3] .asm_24c8 ld de, $0080 cp $7 jr c, .asm_24d5 add hl, de cp $e jr c, .asm_24d5 add hl, de .asm_24d5 ld e, b sla e sla e sla e add hl, de pop de scf ret .asm_24e0 bit 4, b ld hl, Data_3b00 ld a, [wd7af] jr z, .asm_24f2 res 4, b ld hl, Data_3c80 ld a, [wd7b3] .asm_24f2 ld de, $0080 cp $7 jr c, .asm_24ff add hl, de cp $e jr c, .asm_24ff add hl, de .asm_24ff ld e, b sla e sla e sla e add hl, de pop de scf ret BallPositionPointerOffsetDeltas: db $00, $20 db $01, $21 SubTileBallPosDeltas: db 4, 0 db 4, 1 db 3, 3 db 1, 4 db 0, 4 db -1, 4 db -3, 3 db -4, 1 db -4, 0 db -4, -1 db -3, -3 db -1, -4 db 0, -4 db 1, -4 db 3, -3 db 4, -1 SubTileXPos_CollisionDataPointers: ; 0x252e dw SubTileXPos_CollisionData0 dw SubTileXPos_CollisionData1 dw SubTileXPos_CollisionData2 dw SubTileXPos_CollisionData3 dw SubTileXPos_CollisionData4 dw SubTileXPos_CollisionData5 dw SubTileXPos_CollisionData6 dw SubTileXPos_CollisionData7 SubTileXPos_CollisionData0: ; 0x253e db $00, $10, $0B db $00, $08, $0C db $00, $04, $0D db $01, $40, $0A db $01, $01, $0E db $03, $80, $09 db $13, $80, $0F db $04, $80, $08 db $14, $80, $00 db $05, $80, $07 db $15, $80, $01 db $07, $40, $06 db $07, $01, $02 db $08, $10, $05 db $08, $08, $04 db $08, $04, $03 SubTileXPos_CollisionData1: ; 0x256e db $00, $08, $0B db $00, $04, $0C db $00, $02, $0D db $01, $20, $0A db $11, $80, $0E db $03, $40, $09 db $13, $40, $0F db $04, $40, $08 db $14, $40, $00 db $05, $40, $07 db $15, $40, $01 db $07, $20, $06 db $17, $80, $02 db $08, $08, $05 db $08, $04, $04 db $08, $02, $03 SubTileXPos_CollisionData2: ; 0x259e db $00, $04, $0B db $00, $02, $0C db $00, $01, $0D db $01, $10, $0A db $11, $40, $0E db $03, $20, $09 db $13, $20, $0F db $04, $20, $08 db $14, $20, $00 db $05, $20, $07 db $15, $20, $01 db $07, $10, $06 db $17, $40, $02 db $08, $04, $05 db $08, $02, $04 db $08, $01, $03 SubTileXPos_CollisionData3: ; 0x25ce db $00, $02, $0B db $00, $01, $0C db $10, $80, $0D db $01, $08, $0A db $11, $20, $0E db $03, $10, $09 db $13, $10, $0F db $04, $10, $08 db $14, $10, $00 db $05, $10, $07 db $15, $10, $01 db $07, $08, $06 db $17, $20, $02 db $08, $02, $05 db $08, $01, $04 db $18, $80, $03 SubTileXPos_CollisionData4: ; 0x25fe db $00, $01, $0B db $10, $80, $0C db $10, $40, $0D db $01, $04, $0A db $11, $10, $0E db $03, $08, $09 db $13, $08, $0F db $04, $08, $08 db $14, $08, $00 db $05, $08, $07 db $15, $08, $01 db $07, $04, $06 db $17, $10, $02 db $08, $01, $05 db $18, $80, $04 db $18, $40, $03 SubTileXPos_CollisionData5: ; 0x262e db $10, $80, $0B db $10, $40, $0C db $10, $20, $0D db $01, $02, $0A db $11, $08, $0E db $03, $04, $09 db $13, $04, $0F db $04, $04, $08 db $14, $04, $00 db $05, $04, $07 db $15, $04, $01 db $07, $02, $06 db $17, $08, $02 db $18, $80, $05 db $18, $40, $04 db $18, $20, $03 SubTileXPos_CollisionData6: ; 0x265e db $10, $40, $0B db $10, $20, $0C db $10, $10, $0D db $01, $01, $0A db $11, $04, $0E db $03, $02, $09 db $13, $02, $0F db $04, $02, $08 db $14, $02, $00 db $05, $02, $07 db $15, $02, $01 db $07, $01, $06 db $17, $04, $02 db $18, $40, $05 db $18, $20, $04 db $18, $10, $03 SubTileXPos_CollisionData7: ; 0x268e db $10, $20, $0B db $10, $10, $0C db $10, $08, $0D db $11, $80, $0A db $11, $02, $0E db $03, $01, $09 db $13, $01, $0F db $04, $01, $08 db $14, $01, $00 db $05, $01, $07 db $15, $01, $01 db $17, $80, $06 db $17, $02, $02 db $18, $20, $05 db $18, $10, $04 db $18, $08, $03 INCLUDE "data/sine_table.asm" CheckGameObjectCollisions: ; 0x2720 ld a, $ff ld [wTriggeredGameObject], a call CheckGameObjectCollisions_ ld a, [wTriggeredGameObject] ld [wPreviousTriggeredGameObject], a ret CheckGameObjectCollisions_: ; 0x272f ld a, [wCurrentStage] call CallInFollowingTable GameObjectCollisions_CallTable: ; 0x2735 ; STAGE_RED_FIELD_TOP padded_dab CheckRedStageTopGameObjectCollisions ; STAGE_RED_FIELD_BOTTOM padded_dab CheckRedStageBottomGameObjectCollisions padded_dab DoNothing_18061 padded_dab CheckRedStageLaunchAlleyCollision_ ; STAGE_BLUE_FIELD_TOP padded_dab CheckBlueStageTopGameObjectCollisions ; STAGE_BLUE_FIELD_BOTTOM padded_dab CheckBlueStageBottomGameObjectCollisions ; STAGE_GENGAR_BONUS padded_dab CheckGengarBonusStageGameObjectCollisions ; STAGE_GENGAR_BONUS padded_dab CheckGengarBonusStageGameObjectCollisions ; STAGE_MEWTWO_BONUS padded_dab CheckMewtwoBonusStageGameObjectCollisions ; STAGE_MEWTWO_BONUS padded_dab CheckMewtwoBonusStageGameObjectCollisions ; STAGE_MEOWTH_BONUS padded_dab CheckMeowthBonusStageGameObjectCollisions ; STAGE_MEOWTH_BONUS padded_dab CheckMeowthBonusStageGameObjectCollisions ; STAGE_DIGLETT_BONUS padded_dab CheckDiglettBonusStageGameObjectCollisions ; STAGE_DIGLETT_BONUS padded_dab CheckDiglettBonusStageGameObjectCollisions ; STAGE_SEEL_BONUS padded_dab CheckSeelBonusStageGameObjectCollisions ; STAGE_SEEL_BONUS padded_dab CheckSeelBonusStageGameObjectCollisions HandleGameObjectCollision: ; 0x2775 ; Handle collision checking for one set of game objects, such as the bumpers, Pikachu savers, etc. ; Input: hl = pointer to collision attribute list for game objects ; de = pointer to object collision struct ; carry flag = unset to skip the collision attribute list check ld a, [wTriggeredGameObject] inc a jr nz, .noTrigger ld a, [bc] bit 7, a jr nz, .noTrigger push bc push de call nc, IsCollisionInList pop hl call c, CheckGameObjectCollision ld a, [wTriggeredGameObject] ld b, a pop hl ld [hl], $0 jr nc, .noTrigger ld a, [wPreviousTriggeredGameObject] cp b jr z, .noTrigger ld a, [wTriggeredGameObjectIndex] ld [hli], a ld a, [wTriggeredGameObject] ld [hl], a scf ret .noTrigger and a ret CheckGameObjectCollision: ; 0x27a4 ; Checks if any of the given game objects are colliding with the pinball. ; Saves information about which game object was collided. ; Sets carry flag if a game object was collided. ; Input: hl = pointer to game object struct with the following format: ; [x distance][y distance] (defines bounding box for the following list of objects) ; [game object id][object x][object y] (terminate this list with $FF) xor a ld [wTriggeredGameObjectIndex], a ld a, [hli] ; x distance threshold ld d, a ld a, [hli] ; y distance threshold ld e, a ld a, [wBallXPos + 1] ld b, a ld a, [wBallYPos + 1] ld c, a .loop ld a, [wTriggeredGameObjectIndex] inc a ld [wTriggeredGameObjectIndex], a ld a, [hli] ld [wTriggeredGameObject], a cp $ff ret z ld a, [hli] sub b bit 7, a jr z, .compareXDifference cpl ; calculate absolute value of the difference inc a .compareXDifference cp d ld a, [hli] jr nc, .loop sub c bit 7, a jr z, .compareYDifference cpl ; calculate absolute value of the difference inc a .compareYDifference cp e jr nc, .loop scf ret IsCollisionInList: ; 0x27da ; Checks if the pinball's current collision attribute is in the given list. ; Input: hl = pointer to list of collision attributes, terminated by $FF. ; Output: Sets carry flag if the attribute is in the list. ; First byte in list is 0 if the list is independent of the stage's current collision state (Red stage's ; top section changes during gameply.) ld a, [hli] and a jr z, .checkList dec hl ld a, [wStageCollisionState] ld c, a ld b, $0 add hl, bc ld c, [hl] add hl, bc .checkList ld a, [wd7e9] and a ret z ld a, [wCurCollisionAttribute] ld b, a ld c, -1 ; This saves the list offset in C, but the result isn't used by any callers of this routine. .loop inc c ld a, [hli] cp $ff ret z cp b jr nz, .loop scf ret PinballCollidesWithPoints: ; 0x27fd ; Checks if pinball collides with any of the (x, y) points in the given list. ; Saves the index of the collided point. ; Input: hl = pointer to array of (x, y) points ; Output: Saves index of collided point in wd578 ld a, [wBallXPos + 1] ld b, a ld a, [wBallYPos + 1] ld c, a ld d, $0 .nextPoint ld a, [hli] and a ret z inc d ld a, [hli] sub b cp $e8 ld a, [hli] jr c, .nextPoint sub c cp $e8 jr c, .nextPoint ld a, d ld [wd578], a ret Func_281c: ; 0x281c ld a, [wCurrentStage] call CallInFollowingTable CallTable_2822: ; 0x2822 ; not collisions ; STAGE_RED_FIELD_TOP padded_dab Func_1460e ; STAGE_RED_FIELD_BOTTOM padded_dab Func_14652 padded_dab DoNothing_1806d padded_dab Func_1806e ; STAGE_BLUE_FIELD_TOP padded_dab Func_1c715 ; STAGE_BLUE_FIELD_BOTTOM padded_dab Func_1c769 ; STAGE_GENGAR_BONUS padded_dab Func_18377 ; STAGE_GENGAR_BONUS padded_dab Func_18377 ; STAGE_MEWTWO_BONUS padded_dab Func_19451 ; STAGE_MEWTWO_BONUS padded_dab Func_19451 ; STAGE_MEOWTH_BONUS padded_dab Func_2442a ; STAGE_MEOWTH_BONUS padded_dab Func_2442a ; STAGE_DIGLETT_BONUS padded_dab Func_19b88 ; STAGE_DIGLETT_BONUS padded_dab Func_19b88 ; STAGE_SEEL_BONUS padded_dab Func_25c5a ; STAGE_SEEL_BONUS padded_dab Func_25c5a Func_2862: ; 0x2862 ld a, [wd7be] and a jr nz, .asm_287c ld a, [hGameBoyColorFlag] and a jr z, .asm_287b ld a, $0 ld hl, Data_2890 ld de, $0052 ld bc, $0004 call FarCopyPalettes .asm_287b ret .asm_287c ld a, [hGameBoyColorFlag] and a jr z, .asm_288f ld a, $0 ld hl, Data_2894 ld de, $0052 ld bc, $0004 call FarCopyPalettes .asm_288f ret Data_2890: RGB 31, 31, 31 RGB 21, 21, 27 Data_2894: RGB 27, 10, 10 RGB 20, 04, 04 Data_2898: dr $2898, $28a0 CopyHLToDE: ; 0x28a0 ; Places [hl] into [de] ; Also places $0 into [de + 2] ld a, [hli] ld [de], a inc de ld a, [hli] ld [de], a inc de xor a ld [de], a ret UpdateAnimation: ; 0x28a9 ; Updates an animation struct. (See wDugtrioAnimationFrameCounter) ; Input: de = pointer to 3-byte animation struct ; hl = pointer to animation frames data ; Sets carry flag if the animation is over. ld a, [de] and a ret z ; return, if counter is zero dec a ld [de], a ret nz ; return if counter is not zero after the decrement push de inc de inc de ld a, [de] ; a = current frame index inc a ld [de], a ld c, a ld b, $0 sla c rl b add hl, bc ; hl = pointer to two-byte entry in the frames data table ld a, [hli] pop de and a scf ret z ; return if the next entry is $00 push de ld [de], a ; save the animation duration inc de ld a, [hli] ld [de], a ; save the next animation frame id pop de ret INCLUDE "text.asm" INCLUDE "home/text.asm" Func_3500: ld hl, wd464 ld a, e ld [hli], a ld a, d ld [hli], a ld a, c ld [hli], a ld a, b ld [hli], a xor a ld [hli], a ld [hl], a ld bc, wd464 callba AddBigBCD6FromQueueWithBallMultiplier ret AddBCDEToCurBufferValue: ; 0x351c ld hl, wd464 ld a, e ld [hli], a ld a, d ld [hli], a ld a, c ld [hli], a ld a, b ld [hli], a xor a ld [hli], a ld [hl], a ld bc, wd464 callba AddBigBCD6FromQueue ret Func_3538: ; 0x3538 ; Add BCD value bcde to [wd47a]. Cap at $99999999. ld hl, wd47a ld a, [hl] add e daa ld [hli], a ld a, [hl] adc d daa ld [hli], a ld a, [hl] adc c daa ld [hli], a ld a, [hl] adc b daa ld [hli], a ret nc ld hl, wd47a ld a, $99 ld [hli], a ld [hli], a ld [hli], a ld [hli], a ret Retrieve8DigitBCDValueAtwd47a: ; 0x3556 ; Retrieves a 4-byte BCD value at wd47a ld a, [wd47a] ld e, a ld a, [wd47a + 1] ld d, a ld a, [wd47a + 2] ld c, a ld a, [wd47a + 3] ld b, a ret Func_3567: ; BCD add bc to hl ld a, l add c daa ld l, a ld a, h adc b daa ld h, a ret Func_3570: ; BCD add de to hl ld a, l add e daa ld l, a ld a, h adc d daa ld h, a ret Func_3579: ; 0x3579 ; Delete 4-byte BCD value at wd47a ld hl, wd47a xor a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ret HandleTilts: ; 0x3582 call HandleLeftTilt call HandleRightTilt call HandleUpperTilt ret HandleLeftTilt: ; 0x358c ld a, [wLeftTiltReset] and a jr nz, .tiltCoolDown ld hl, wKeyConfigLeftTilt call IsKeyPressed2 jr z, .tiltCoolDown ld a, [wLeftTiltCounter] cp $3 jr z, .startCoolDown inc a ld [wLeftTiltCounter], a cp $1 jr nz, .skipSoundEffect lb de, $00, $3f call PlaySoundEffect .skipSoundEffect ld a, [wd548] ld hl, wd549 and [hl] jr z, .skipBallMovement ld a, [wBallXPos + 1] dec a ; move ball's position to the left by 1 pixel ld [wBallXPos + 1], a .skipBallMovement ld a, [wd79f] inc a ld [wd79f], a ld a, $1 ld [wLeftTiltPushing], a ret .startCoolDown ld a, $1 ld [wLeftTiltReset], a .tiltCoolDown xor a ld [wLeftTiltPushing], a ld a, [wLeftTiltCounter] and a jr z, .done dec a ld [wLeftTiltCounter], a ld a, [wd79f] dec a ld [wd79f], a ret .done ld hl, wKeyConfigLeftTilt call IsKeyPressed2 ret nz xor a ld [wLeftTiltReset], a ret HandleRightTilt: ; 0x35f3 ld a, [wRightTiltReset] and a jr nz, .tiltCoolDown ld hl, wKeyConfigRightTilt call IsKeyPressed2 jr z, .tiltCoolDown ld a, [wRightTiltCounter] cp $3 jr z, .startCoolDown inc a ld [wRightTiltCounter], a cp $1 jr nz, .skipSoundEffect lb de, $00, $3f call PlaySoundEffect .skipSoundEffect ld a, [wd548] ld hl, wd549 and [hl] jr z, .skipBallMovement ld a, [wBallXPos + 1] inc a ; move ball's position to the right by 1 pixel ld [wBallXPos + 1], a .skipBallMovement ld a, [wd79f] dec a ld [wd79f], a ld a, $1 ld [wRightTiltPushing], a ret .startCoolDown ld a, $1 ld [wRightTiltReset], a .tiltCoolDown xor a ld [wRightTiltPushing], a ld a, [wRightTiltCounter] and a jr z, .done dec a ld [wRightTiltCounter], a ld a, [wd79f] inc a ld [wd79f], a ret .done ld hl, wKeyConfigRightTilt call IsKeyPressed2 ret nz xor a ld [wRightTiltReset], a ret HandleUpperTilt: ; 0x365a ld a, [wUpperTiltReset] and a jr nz, .tiltCoolDown ld hl, wKeyConfigUpperTilt call IsKeyPressed2 jr z, .tiltCoolDown ld a, [wUpperTiltCounter] cp $4 jr z, .startCoolDown inc a ld [wUpperTiltCounter], a cp $1 jr nz, .skipSoundEffect lb de, $00, $3f call PlaySoundEffect .skipSoundEffect ld a, [wd548] ld hl, wd549 and [hl] jr z, .skipBallMovement ld a, [wBallYPos + 1] inc a ; move ball's position down by 1 pixel ld [wBallYPos + 1], a .skipBallMovement ld a, [wd7a0] dec a ld [wd7a0], a ld a, $1 ld [wUpperTiltPushing], a ret .startCoolDown ld a, $1 ld [wUpperTiltReset], a .tiltCoolDown xor a ld [wUpperTiltPushing], a ld a, [wUpperTiltCounter] and a jr z, .done dec a ld [wUpperTiltCounter], a ld a, [wd7a0] inc a ld [wd7a0], a ret .done ld hl, wKeyConfigUpperTilt call IsKeyPressed2 ret nz xor a ld [wUpperTiltReset], a ret ApplyTiltForces: ; 0x36c1 ld a, [wd548] ld hl, wd549 and [hl] ret z ld c, $0 ld a, [wUpperTiltPushing] srl a rl c ld a, [wRightTiltPushing] srl a rl c ld a, [wLeftTiltPushing] srl a rl c ld b, $0 sla c ld hl, Data_372d add hl, bc ld a, [hli] ld h, [hl] ld l, a bit 7, h ret nz ld a, [wCollisionForceAngle] ld c, a ld b, $0 sla c rl b sla c rl b add hl, bc ld a, [hLoadedROMBank] push af ld a, BANK(TiltLeftOnlyForce) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld a, [wBallXVelocity] add [hl] ld [wBallXVelocity], a inc hl ld a, [wBallXVelocity + 1] adc [hl] ld [wBallXVelocity + 1], a inc hl ld a, [wBallYVelocity] add [hl] ld [wBallYVelocity], a inc hl ld a, [wBallYVelocity + 1] adc [hl] ld [wBallYVelocity + 1], a pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ret Data_372d: dw -1 ; no tilt dw TiltLeftOnlyForce dw TiltRightOnlyForce dw -1 ; left + right (cancel) dw TiltUpOnlyForce dw TiltUpLeftForce dw TiltUpRightForce dw TiltUpOnlyForce SECTION "bank0.2", ROM0 [$3800] Data_3800: dr $3800, $3980 Data_3980: dr $3980, $3b00 Data_3b00: dr $3b00, $3c80 Data_3c80: dr $3c80, $3e00 SquaresLow: x = 0 rept 256 db (x * x) % $100 x = x + 1 endr SquaresHigh: x = 0 rept 256 db (x * x) / $100 x = x + 1 endr