diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/copy.asm | 431 | ||||
-rw-r--r-- | common/decompress.asm | 367 | ||||
-rw-r--r-- | common/delay.asm | 23 | ||||
-rw-r--r-- | common/fade.asm | 134 | ||||
-rw-r--r-- | common/farcall.asm | 55 | ||||
-rw-r--r-- | common/flag.asm | 113 | ||||
-rw-r--r-- | common/game_time.asm | 132 | ||||
-rw-r--r-- | common/init.asm | 225 | ||||
-rw-r--r-- | common/joypad.asm | 491 | ||||
-rw-r--r-- | common/lcd.asm | 81 | ||||
-rw-r--r-- | common/map.asm | 2369 | ||||
-rw-r--r-- | common/map_objects.asm | 683 | ||||
-rw-r--r-- | common/menu.asm | 603 | ||||
-rw-r--r-- | common/palettes.asm | 347 | ||||
-rw-r--r-- | common/rtc.asm | 25 | ||||
-rw-r--r-- | common/serial.asm | 408 | ||||
-rw-r--r-- | common/sine.asm | 22 | ||||
-rw-r--r-- | common/string.asm | 39 | ||||
-rw-r--r-- | common/text.asm | 1230 | ||||
-rw-r--r-- | common/time.asm | 311 | ||||
-rw-r--r-- | common/vblank.asm | 541 | ||||
-rw-r--r-- | common/video.asm | 487 |
22 files changed, 9117 insertions, 0 deletions
diff --git a/common/copy.asm b/common/copy.asm new file mode 100644 index 000000000..ad25c96e6 --- /dev/null +++ b/common/copy.asm @@ -0,0 +1,431 @@ +; Functions to copy data from ROM. + + +Functiondc9: ; dc9 + ld a, [rLCDC] + bit 7, a + jp z, Copy2bpp + + ld a, [hROMBank] + push af + ld a, BANK(Function104284) + rst Bankswitch + call Function104284 + pop af + rst Bankswitch + + ret +; ddc + +Functionddc: ; ddc + ld a, [rLCDC] + bit 7, a + jp z, Copy1bpp + + ld a, [hROMBank] + push af + ld a, BANK(Function1042b2) + rst Bankswitch + call Function1042b2 + pop af + rst Bankswitch + + ret +; def + +Functiondef: ; def + ld [hBuffer], a + ld a, [hROMBank] + push af + ld a, [hBuffer] + rst Bankswitch + call FarCopyBytesDouble + pop af + rst Bankswitch + ret +; dfd + +Functiondfd: ; dfd + dec c + ld a, [hBGMapMode] + push af + xor a + ld [hBGMapMode], a + ld a, [hROMBank] + push af + ld a, b + rst Bankswitch + +.asm_e09 + ld a, d + ld [rHDMA1], a + ld a, e + and $f0 + ld [rHDMA2], a + ld a, h + and $1f + ld [rHDMA3], a + ld a, l + and $f0 + ld [rHDMA4], a + ld a, c + cp $8 + jr c, .asm_e3c + sub $8 + ld c, a + ld a, $f + ld [hDMATransfer], a + call DelayFrame + ld a, l + add $0 + ld l, a + ld a, h + adc $1 + ld h, a + ld a, e + add $0 + ld e, a + ld a, d + adc $1 + ld d, a + jr .asm_e09 + +.asm_e3c + ld a, c + and $7f + ld [hDMATransfer], a + call DelayFrame + pop af + rst Bankswitch + + pop af + ld [hBGMapMode], a + ret +; e4a + + + +Functione4a: ; e4a + ld a, $5 + ld hl, $4135 + rst FarCall + ret +; e51 + + + +Functione51: ; e51 + ld a, $3e + ld hl, $7449 + rst FarCall + ret +; e58 + +Functione58: ; e58 + ld a, $3e + ld hl, $74be + rst FarCall + ret +; e5f + + + +Functione5f: ; e5f + ld a, $3e + ld hl, $748a + rst FarCall + ld a, $3e + ld hl, $74b0 + rst FarCall + ret +; e6c + +Functione6c: ; e6c + ld a, $3e + ld hl, $74b0 + rst FarCall + ret +; e73 + +Functione73: ; e73 + push de + ld a, $0 + call GetSRAMBank + push bc + ld de, $a000 + ld a, b + call FarDecompress + pop bc + pop hl + ld de, $a000 + call Request2bpp + call CloseSRAM + ret +; e8d + + + +FarCopyBytes: ; e8d +; copy bc bytes from a:hl to de + + ld [hBuffer], a + ld a, [hROMBank] + push af + ld a, [hBuffer] + rst Bankswitch + + call CopyBytes + + pop af + rst Bankswitch + ret +; 0xe9b + + +FarCopyBytesDouble: ; e9b +; Copy bc bytes from a:hl to bc*2 bytes at de, +; doubling each byte in the process. + + ld [hBuffer], a + ld a, [hROMBank] + push af + ld a, [hBuffer] + rst Bankswitch + +; switcheroo, de <> hl + ld a, h + ld h, d + ld d, a + ld a, l + ld l, e + ld e, a + + inc b + inc c + jr .dec + +.loop + ld a, [de] + inc de + ld [hli], a + ld [hli], a +.dec + dec c + jr nz, .loop + dec b + jr nz, .loop + + pop af + rst Bankswitch + ret +; 0xeba + + +Request2bpp: ; eba + ld a, [hBGMapMode] + push af + xor a + ld [hBGMapMode], a + + ld a, [hROMBank] + push af + ld a, b + rst Bankswitch + + ld a, [$ffd3] + push af + + ld a, $8 + ld [$ffd3], a + ld a, [InLinkBattle] + cp $4 + jr nz, .asm_edc + ld a, [$ffe9] + and a + jr nz, .asm_edc + ld a, $6 + ld [$ffd3], a + +.asm_edc + ld a, e + ld [Requested2bppSource], a + ld a, d + ld [Requested2bppSource + 1], a + ld a, l + ld [Requested2bppDest], a + ld a, h + ld [Requested2bppDest + 1], a + +.asm_eec + ld a, c + ld hl, $ffd3 + cp [hl] + jr nc, .asm_f08 + + ld [Requested2bpp], a +.wait + call DelayFrame + ld a, [Requested2bpp] + and a + jr nz, .wait + + pop af + ld [$ffd3], a + + pop af + rst Bankswitch + + pop af + ld [hBGMapMode], a + ret + +.asm_f08 + ld a, [$ffd3] + ld [Requested2bpp], a +.asm_f0d + call DelayFrame + ld a, [Requested2bpp] + and a + jr nz, .asm_f0d + ld a, c + ld hl, $ffd3 + sub [hl] + ld c, a + jr .asm_eec +; f1e + + +Request1bpp: ; f1e + ld a, [hBGMapMode] + push af + xor a + ld [hBGMapMode], a + + ld a, [hROMBank] + push af + ld a, b + rst Bankswitch + + ld a, [$ffd3] + push af + + ld a, $8 + ld [$ffd3], a + ld a, [InLinkBattle] + cp $4 + jr nz, .asm_f40 + ld a, [$ffe9] + and a + jr nz, .asm_f40 + ld a, $6 + ld [$ffd3], a + +.asm_f40 + ld a, e + ld [Requested1bppSource], a + ld a, d + ld [Requested1bppSource + 1], a + ld a, l + ld [Requested1bppDest], a + ld a, h + ld [Requested1bppDest + 1], a +.asm_f50 + ld a, c + ld hl, $ffd3 + cp [hl] + jr nc, .asm_f6c + + ld [Requested1bpp], a +.wait + call DelayFrame + ld a, [Requested1bpp] + and a + jr nz, .wait + + pop af + ld [$ffd3], a + + pop af + rst Bankswitch + + pop af + ld [hBGMapMode], a + ret + +.asm_f6c + ld a, [$ffd3] + ld [Requested1bpp], a +.asm_f71 + call DelayFrame + ld a, [Requested1bpp] + and a + jr nz, .asm_f71 + ld a, c + ld hl, $ffd3 + sub [hl] + ld c, a + jr .asm_f50 +; f82 + + +Get2bpp: ; f82 + ld a, [rLCDC] + bit 7, a + jp nz, Request2bpp + +Copy2bpp: ; f89 +; copy c 2bpp tiles from b:de to hl + + push hl + ld h, d + ld l, e + pop de + +; bank + ld a, b + +; bc = c * $10 + push af + swap c + ld a, $f + and c + ld b, a + ld a, $f0 + and c + ld c, a + pop af + + jp FarCopyBytes +; f9d + + +Get1bpp: ; f9d + ld a, [rLCDC] + bit 7, a + jp nz, Request1bpp + +Copy1bpp: ; fa4 +; copy c 1bpp tiles from b:de to hl + + push de + ld d, h + ld e, l + +; bank + ld a, b + +; bc = c * $10 / 2 + push af + ld h, 0 + ld l, c + add hl, hl + add hl, hl + add hl, hl + ld b, h + ld c, l + pop af + + pop hl + jp FarCopyBytesDouble +; fb6 + diff --git a/common/decompress.asm b/common/decompress.asm new file mode 100644 index 000000000..8d39cd968 --- /dev/null +++ b/common/decompress.asm @@ -0,0 +1,367 @@ +FarDecompress: ; b40 +; Decompress graphics data at a:hl to de + +; put a away for a sec + ld [$c2c4], a +; save bank + ld a, [hROMBank] + push af +; bankswitch + ld a, [$c2c4] + rst Bankswitch + +; what we came here for + call Decompress + +; restore bank + pop af + rst Bankswitch + ret +; b50 + + +Decompress: ; b50 +; Pokemon Crystal uses an lz variant for compression. + +; This is mainly used for graphics, but the intro's +; tilemaps also use this compression. + +; This function decompresses lz-compressed data at hl to de. + + +; Basic rundown: + +; A typical control command consists of: +; -the command (bits 5-7) +; -the count (bits 0-4) +; -and any additional params + +; $ff is used as a terminator. + + +; Commands: + +; 0: literal +; literal data for some number of bytes +; 1: iterate +; one byte repeated for some number of bytes +; 2: alternate +; two bytes alternated for some number of bytes +; 3: zero (whitespace) +; 0x00 repeated for some number of bytes + +; Repeater control commands have a signed parameter used to determine the start point. +; Wraparound is simulated: +; Positive values are added to the start address of the decompressed data +; and negative values are subtracted from the current position. + +; 4: repeat +; repeat some number of bytes from decompressed data +; 5: flipped +; repeat some number of flipped bytes from decompressed data +; ex: $ad = %10101101 -> %10110101 = $b5 +; 6: reverse +; repeat some number of bytes in reverse from decompressed data + +; If the value in the count needs to be larger than 5 bits, +; control code 7 can be used to expand the count to 10 bits. + +; A new control command is read in bits 2-4. +; The new 10-bit count is split: +; bits 0-1 contain the top 2 bits +; another byte is added containing the latter 8 + +; So, the structure of the control command becomes: +; 111xxxyy yyyyyyyy +; | | | | +; | | our new count +; | the control command for this count +; 7 (this command) + +; For more information, refer to the code below and in extras/gfx.py . + +; save starting output address + ld a, e + ld [$c2c2], a + ld a, d + ld [$c2c3], a + +.loop +; get next byte + ld a, [hl] +; done? + cp $ff ; end + ret z + +; get control code + and %11100000 + +; 10-bit param? + cp $e0 ; LZ_HI + jr nz, .normal + + +; 10-bit param: + +; get next 3 bits (%00011100) + ld a, [hl] + add a + add a ; << 3 + add a + +; this is our new control code + and %11100000 + push af + +; get param hi + ld a, [hli] + and %00000011 + ld b, a + +; get param lo + ld a, [hli] + ld c, a + +; read at least 1 byte + inc bc + jr .readers + + +.normal +; push control code + push af +; get param + ld a, [hli] + and %00011111 + ld c, a + ld b, $0 +; read at least 1 byte + inc c + +.readers +; let's get started + +; inc loop counts since we bail as soon as they hit 0 + inc b + inc c + +; get control code + pop af +; command type + bit 7, a ; 80, a0, c0 + jr nz, .repeatertype + +; literals + cp $20 ; LZ_ITER + jr z, .iter + cp $40 ; LZ_ALT + jr z, .alt + cp $60 ; LZ_ZERO + jr z, .zero + ; else $00 + +; 00 ; LZ_LIT +; literal data for bc bytes +.loop1 +; done? + dec c + jr nz, .next1 + dec b + jp z, .loop + +.next1 + ld a, [hli] + ld [de], a + inc de + jr .loop1 + + +; 20 ; LZ_ITER +; write byte for bc bytes +.iter + ld a, [hli] + +.iterloop + dec c + jr nz, .iternext + dec b + jp z, .loop + +.iternext + ld [de], a + inc de + jr .iterloop + + +; 40 ; LZ_ALT +; alternate two bytes for bc bytes + +; next pair +.alt +; done? + dec c + jr nz, .alt0 + dec b + jp z, .altclose0 + +; alternate for bc +.alt0 + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .alt1 +; done? + dec b + jp z, .altclose1 +.alt1 + ld a, [hld] + ld [de], a + inc de + jr .alt + +; skip past the bytes we were alternating +.altclose0 + inc hl +.altclose1 + inc hl + jr .loop + + +; 60 ; LZ_ZERO +; write 00 for bc bytes +.zero + xor a + +.zeroloop + dec c + jr nz, .zeronext + dec b + jp z, .loop + +.zeronext + ld [de], a + inc de + jr .zeroloop + + +; repeats +; 80, a0, c0 +; repeat decompressed data from output +.repeatertype + push hl + push af +; get next byte + ld a, [hli] +; absolute? + bit 7, a + jr z, .absolute + +; relative +; a = -a + and %01111111 ; forget the bit we just looked at + cpl +; add de (current output address) + add e + ld l, a + ld a, $ff ; -1 + adc d + ld h, a + jr .repeaters + +.absolute +; get next byte (lo) + ld l, [hl] +; last byte (hi) + ld h, a +; add starting output address + ld a, [$c2c2] + add l + ld l, a + ld a, [$c2c3] + adc h + ld h, a + +.repeaters + pop af + cp $80 ; LZ_REPEAT + jr z, .repeat + cp $a0 ; LZ_FLIP + jr z, .flip + cp $c0 ; LZ_REVERSE + jr z, .reverse + +; e0 -> 80 + +; 80 ; LZ_REPEAT +; repeat some decompressed data +.repeat +; done? + dec c + jr nz, .repeatnext + dec b + jr z, .cleanup + +.repeatnext + ld a, [hli] + ld [de], a + inc de + jr .repeat + + +; a0 ; LZ_FLIP +; repeat some decompressed data w/ flipped bit order +.flip + dec c + jr nz, .flipnext + dec b + jp z, .cleanup + +.flipnext + ld a, [hli] + push bc + ld bc, $0008 + +.fliploop + rra + rl b + dec c + jr nz, .fliploop + ld a, b + pop bc + ld [de], a + inc de + jr .flip + + +; c0 ; LZ_REVERSE +; repeat some decompressed data in reverse +.reverse + dec c + jr nz, .reversenext + + dec b + jp z, .cleanup + +.reversenext + ld a, [hld] + ld [de], a + inc de + jr .reverse + + +.cleanup +; get type of repeat we just used + pop hl +; was it relative or absolute? + bit 7, [hl] + jr nz, .next + +; skip two bytes for absolute + inc hl +; skip one byte for relative +.next + inc hl + jp .loop +; c2f + diff --git a/common/delay.asm b/common/delay.asm new file mode 100644 index 000000000..4e8b2147c --- /dev/null +++ b/common/delay.asm @@ -0,0 +1,23 @@ +DelayFrame: ; 45a +; Wait for one frame + ld a, 1 + ld [VBlankOccurred], a + +; Wait for the next VBlank, halting to conserve battery +.halt + halt ; rgbasm adds a nop after this instruction by default + ld a, [VBlankOccurred] + and a + jr nz, .halt + ret +; 468 + + +DelayFrames: ; 468 +; Wait c frames + call DelayFrame + dec c + jr nz, DelayFrames + ret +; 46f + diff --git a/common/fade.asm b/common/fade.asm new file mode 100644 index 000000000..d67211e29 --- /dev/null +++ b/common/fade.asm @@ -0,0 +1,134 @@ +; Functions to fade the screen in and out. + + +Function48c: ; 48c + ld a, [TimeOfDayPal] + ld b, a + ld hl, IncGradGBPalTable_11 + ld a, l + sub b + ld l, a + jr nc, .asm_499 + dec h + +.asm_499 + ld a, [hli] + ld [rBGP], a + ld a, [hli] + ld [rOBP0], a + ld a, [hli] + ld [rOBP1], a + ret +; 4a3 + + +Function4a3: ; 4a3 + ld a, [hCGB] + and a + jr z, .asm_4af + ld hl, IncGradGBPalTable_00 + ld b, 4 + jr FadeOut + +.asm_4af + ld hl, IncGradGBPalTable_08 + ld b, 4 + jr FadeOut +; 4b6 + +Function4b6: ; 4b6 + ld a, [hCGB] + and a + jr z, .asm_4c2 + ld hl, IncGradGBPalTable_05 + ld b, 3 + jr FadeOut + +.asm_4c2 + ld hl, IncGradGBPalTable_13 + ld b, 3 +; 4c7 + +FadeOut: ; 4c7 + push de + ld a, [hli] + call DmgToCgbBGPals + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + call DmgToCgbObjPals + ld c, 8 + call DelayFrames + pop de + dec b + jr nz, FadeOut + ret +; 4dd + +Function4dd: ; 4dd + ld a, [hCGB] + and a + jr z, .asm_4e9 + ld hl, IncGradGBPalTable_04 - 1 + ld b, 4 + jr FadeIn + +.asm_4e9 + ld hl, IncGradGBPalTable_12 - 1 + ld b, 4 + jr FadeIn +; 4f0 + +Function4f0: ; 4f0 + ld a, [hCGB] + and a + jr z, .asm_4fc + ld hl, IncGradGBPalTable_07 - 1 + ld b, 3 + jr FadeIn + +.asm_4fc + ld hl, IncGradGBPalTable_15 - 1 + ld b, 3 + ; fallthrough +; 501 + +FadeIn: ; 501 + push de + ld a, [hld] + ld d, a + ld a, [hld] + ld e, a + call DmgToCgbObjPals + ld a, [hld] + call DmgToCgbBGPals + ld c, 8 + call DelayFrames + pop de + dec b + jr nz, FadeIn + ret +; 517 + + +; 517 +IncGradGBPalTable_00: db %11111111, %11111111, %11111111 +IncGradGBPalTable_01: db %11111110, %11111110, %11111110 +IncGradGBPalTable_02: db %11111001, %11111001, %11111001 +IncGradGBPalTable_03: db %11100100, %11100100, %11100100 +IncGradGBPalTable_04: db %11100100, %11100100, %11100100 +IncGradGBPalTable_05: db %10010000, %10010000, %10010000 +IncGradGBPalTable_06: db %01000000, %01000000, %01000000 +IncGradGBPalTable_07: db %00000000, %00000000, %00000000 +; bgp obp1 obp2 +IncGradGBPalTable_08: db %11111111, %11111111, %11111111 +IncGradGBPalTable_09: db %11111110, %11111110, %11111000 +IncGradGBPalTable_10: db %11111001, %11100100, %11100100 +IncGradGBPalTable_11: db %11100100, %11010000, %11100000 +IncGradGBPalTable_12: db %11100100, %11010000, %11100000 +IncGradGBPalTable_13: db %10010000, %10000000, %10010000 +IncGradGBPalTable_14: db %01000000, %01000000, %01000000 +IncGradGBPalTable_15: db %00000000, %00000000, %00000000 +; 547 + diff --git a/common/farcall.asm b/common/farcall.asm new file mode 100644 index 000000000..bdee3bf38 --- /dev/null +++ b/common/farcall.asm @@ -0,0 +1,55 @@ +FarCall_de: ; 2d54 +; Call a:de. +; Preserves other registers. + + ld [hBuffer], a + ld a, [hROMBank] + push af + ld a, [hBuffer] + rst Bankswitch + call .de + jr ReturnFarCall + +.de + push de + ret +; 2d63 + + +FarCall_hl: ; 2d63 +; Call a:hl. +; Preserves other registers. + + ld [hBuffer], a + ld a, [hROMBank] + push af + ld a, [hBuffer] + rst Bankswitch + call Function2d82 +; 2d6e + +ReturnFarCall: ; 2d6e +; We want to retain the contents of f. +; To do this, we can pop to bc instead of af. + + ld a, b + ld [$cfb9], a + ld a, c + ld [$cfba], a + +; Restore the working bank. + pop bc + ld a, b + rst Bankswitch + + ld a, [$cfb9] + ld b, a + ld a, [$cfba] + ld c, a + ret +; 2d82 + +Function2d82: ; 2d82 + jp [hl] +; 2d83 + diff --git a/common/flag.asm b/common/flag.asm new file mode 100644 index 000000000..e99248a3e --- /dev/null +++ b/common/flag.asm @@ -0,0 +1,113 @@ +Function2e50: ; 2e50 + xor a + ld hl, EventFlags + ld [hli], a + ret +; 2e56 + +Function2e56: ; 2e56 + xor a + ld hl, BikeFlags + ld [hli], a + ld [hl], a + ret +; 2e5d + +Function2e5d: ; 2e5d + ld a, [$d19a] + cp $2 + jr z, .asm_2e69 + cp $1 + jr z, .asm_2e69 + ret + +.asm_2e69 + ld hl, StatusFlags + res 2, [hl] + ret +; 2e6f + + +EventFlagAction: ; 0x2e6f + ld hl, EventFlags + call FlagAction + ret + +FlagAction: ; 0x2e76 +; Perform action b on bit de in flag array hl. + +; inputs: +; b: function +; 0 clear bit +; 1 set bit +; 2 check bit +; de: bit number +; hl: index within bit table + + ; get index within the byte + ld a, e + and 7 + + ; shift de right by three bits (get the index within memory) + srl d + rr e + srl d + rr e + srl d + rr e + add hl, de + + ; implement a decoder + ld c, 1 + rrca + jr nc, .one + rlc c +.one + rrca + jr nc, .two + rlc c + rlc c +.two + rrca + jr nc, .three + swap c +.three + + ; check b's value: 0, 1, 2 + ld a, b + cp 1 + jr c, .clearbit ; 0 + jr z, .setbit ; 1 + + ; check bit + ld a, [hl] + and c + ld c, a + ret + +.setbit + ; set bit + ld a, [hl] + or c + ld [hl], a + ret + +.clearbit + ; clear bit + ld a, c + cpl + and [hl] + ld [hl], a + ret +; 0x2ead + + +Function2ead: ; 2ead + ld de, ENGINE_POKEDEX + ld b, CHECK_FLAG + callba EngineFlagAction + ld a, c + and a + ret +; 2ebb + diff --git a/common/game_time.asm b/common/game_time.asm new file mode 100644 index 000000000..ee52488f4 --- /dev/null +++ b/common/game_time.asm @@ -0,0 +1,132 @@ +ResetGameTime: ; 208a + xor a + ld [GameTimeCap], a + ld [GameTimeHours], a + ld [GameTimeHours + 1], a + ld [GameTimeMinutes], a + ld [GameTimeSeconds], a + ld [GameTimeFrames], a + ret +; 209e + + +GameTimer: ; 209e + + nop + + ld a, [rSVBK] + push af + ld a, 1 + ld [rSVBK], a + + call UpdateGameTimer + + pop af + ld [rSVBK], a + ret +; 20ad + + +UpdateGameTimer: ; 20ad +; Increment the game timer by one frame. +; The game timer is capped at 999:59:59.00. + + +; Don't update if game logic is paused. + ld a, [$c2cd] + and a + ret nz + +; Is the timer paused? + ld hl, GameTimerPause + bit 0, [hl] + ret z + +; Is the timer already capped? + ld hl, GameTimeCap + bit 0, [hl] + ret nz + + +; +1 frame + ld hl, GameTimeFrames + ld a, [hl] + inc a + + cp 60 ; frames/second + jr nc, .second + + ld [hl], a + ret + + +.second + xor a + ld [hl], a + +; +1 second + ld hl, GameTimeSeconds + ld a, [hl] + inc a + + cp 60 ; seconds/minute + jr nc, .minute + + ld [hl], a + ret + + +.minute + xor a + ld [hl], a + +; +1 minute + ld hl, GameTimeMinutes + ld a, [hl] + inc a + + cp 60 ; minutes/hour + jr nc, .hour + + ld [hl], a + ret + + +.hour + xor a + ld [hl], a + +; +1 hour + ld a, [GameTimeHours] + ld h, a + ld a, [GameTimeHours + 1] + ld l, a + inc hl + + +; Cap the timer after 1000 hours. + ld a, h + cp 1000 / $100 + jr c, .ok + + ld a, l + cp 1000 % $100 + jr c, .ok + + ld hl, GameTimeCap + set 0, [hl] + + ld a, 59 ; 999:59:59.00 + ld [GameTimeMinutes], a + ld [GameTimeSeconds], a + ret + + +.ok + ld a, h + ld [GameTimeHours], a + ld a, l + ld [GameTimeHours + 1], a + ret +; 210f + diff --git a/common/init.asm b/common/init.asm new file mode 100644 index 000000000..3104c416d --- /dev/null +++ b/common/init.asm @@ -0,0 +1,225 @@ +Reset: ; 150 + di + call CleanSoundRestart + xor a + ld [$ffde], a + call ClearPalettes + xor a + ld [rIF], a + ld a, 1 ; VBlank int + ld [rIE], a + ei + + ld hl, $cfbe + set 7, [hl] + + ld c, 32 + call DelayFrames + + jr Init +; 16e + + +_Start: ; 16e + cp $11 + jr z, .asm_175 + xor a + jr .asm_177 + +.asm_175 + ld a, $1 + +.asm_177 + ld [hCGB], a + ld a, $1 + ld [$ffea], a +; 17d + + +Init: ; 17d + + di + + xor a + ld [rIF], a + ld [rIE], a + ld [rRP], a + ld [rSCX], a + ld [rSCY], a + ld [rSB], a + ld [rSC], a + ld [rWX], a + ld [rWY], a + ld [rBGP], a + ld [rOBP0], a + ld [rOBP1], a + ld [rTMA], a + ld [rTAC], a + ld [$d000], a + + ld a, %100 ; Start timer at 4096Hz + ld [rTAC], a + +.wait + ld a, [rLY] + cp 145 + jr nz, .wait + + xor a + ld [rLCDC], a + +; Clear WRAM bank 0 + ld hl, $c000 + ld bc, $d000 - $c000 +.asm_1b1 + ld [hl], 0 + inc hl + dec bc + ld a, b + or c + jr nz, .asm_1b1 + + ld sp, Stack + +; Clear HRAM + ld a, [hCGB] + push af + ld a, [$ffea] + push af + xor a + ld hl, $ff80 + ld bc, $ffff - $ff80 + call ByteFill + pop af + ld [$ffea], a + pop af + ld [hCGB], a + + call ClearWRAM + ld a, 1 + ld [rSVBK], a + call ClearVRAM + call ClearSprites + call Function270 + + + ld a, BANK(LoadPushOAM) + rst Bankswitch + + call LoadPushOAM + + xor a + ld [$ffde], a + ld [hSCX], a + ld [hSCY], a + ld [rJOYP], a + + ld a, $8 ; HBlank int enable + ld [rSTAT], a + + ld a, $90 + ld [hWY], a + ld [rWY], a + + ld a, 7 + ld [hWX], a + ld [rWX], a + + ld a, %11100011 + ; LCD on + ; Win tilemap 1 + ; Win on + ; BG/Win tiledata 0 + ; BG Tilemap 0 + ; OBJ 8x8 + ; OBJ on + ; BG on + ld [rLCDC], a + + ld a, $ff + ld [$ffcb], a + + callba Function9890 + + ld a, $9c + ld [$ffd7], a + + xor a + ld [hBGMapAddress], a + + callba StartClock + + xor a + ld [MBC3LatchClock], a + ld [MBC3SRamEnable], a + + ld a, [hCGB] + and a + jr z, .asm_22b + call Function2ff7 +.asm_22b + + xor a + ld [rIF], a + ld a, %1111 ; VBlank, LCDStat, Timer, Serial interrupts + ld [rIE], a + ei + + call DelayFrame + + ld a, $30 + call Predef + + call CleanSoundRestart + xor a + ld [CurMusic], a + jp GameInit +; 245 + + +ClearVRAM: ; 245 +; Wipe VRAM banks 0 and 1 + + ld a, 1 + ld [rVBK], a + call .clear + + xor a + ld [rVBK], a +.clear + ld hl, VTiles0 + ld bc, $2000 + xor a + call ByteFill + ret +; 25a + +ClearWRAM: ; 25a +; Wipe swappable WRAM banks (1-7) + + ld a, 1 +.asm_25c + push af + ld [rSVBK], a + xor a + ld hl, $d000 + ld bc, $1000 + call ByteFill + pop af + inc a + cp 8 + jr nc, .asm_25c + ret +; 270 + +Function270: ; 270 + ld a, $0 + call GetSRAMBank + ld hl, $a000 + ld bc, $0020 + xor a + call ByteFill + call CloseSRAM + ret +; 283 + diff --git a/common/joypad.asm b/common/joypad.asm new file mode 100644 index 000000000..198e1c47b --- /dev/null +++ b/common/joypad.asm @@ -0,0 +1,491 @@ +JoypadInt: ; 92e +; Replaced by Joypad, called from VBlank instead of the useless +; joypad interrupt. + +; This is a placeholder in case the interrupt is somehow enabled. + reti +; 92f + +ClearJoypadPublic: ; 92f + xor a +; Pressed this frame (delta) + ld [hJoyPressed], a +; Currently pressed + ld [hJoyDown], a + ret +; 935 + +Joypad: ; 935 +; Read the joypad register and translate it to something more +; workable for use in-game. There are 8 buttons, so we can use +; one byte to contain all player input. + +; Updates: + +; hJoypadReleased: released this frame (delta) +; hJoypadPressed: pressed this frame (delta) +; hJoypadDown: currently pressed +; hJoypadSum: pressed so far + +; Any of these three bits can be used to disable input. + ld a, [$cfbe] + and %11010000 + ret nz + +; If we're saving, input is disabled. + ld a, [$c2cd] + and a + ret nz + +; We can only get four inputs at a time. +; We take d-pad first for no particular reason. + ld a, D_PAD + ld [rJOYP], a +; Read twice to give the request time to take. + ld a, [rJOYP] + ld a, [rJOYP] + +; The Joypad register output is in the lo nybble (inversed). +; We make the hi nybble of our new container d-pad input. + cpl + and $f + swap a + +; We'll keep this in b for now. + ld b, a + +; Buttons make 8 total inputs (A, B, Select, Start). +; We can fit this into one byte. + ld a, BUTTONS + ld [rJOYP], a +; Wait for input to stabilize. + ld a, [rJOYP] + ld a, [rJOYP] + ld a, [rJOYP] + ld a, [rJOYP] + ld a, [rJOYP] + ld a, [rJOYP] +; Buttons take the lo nybble. + cpl + and $f + or b + ld b, a + +; Reset the joypad register since we're done with it. + ld a, $30 + ld [rJOYP], a + +; To get the delta we xor the last frame's input with the new one. + ld a, [hJoypadDown] ; last frame + ld e, a + xor b + ld d, a +; Released this frame: + and e + ld [hJoypadReleased], a +; Pressed this frame: + ld a, d + and b + ld [hJoypadPressed], a + +; Add any new presses to the list of collective presses: + ld c, a + ld a, [hJoypadSum] + or c + ld [hJoypadSum], a + +; Currently pressed: + ld a, b + ld [hJoypadDown], a + +; Now that we have the input, we can do stuff with it. + +; For example, soft reset: + and A_BUTTON | B_BUTTON | SELECT | START + cp A_BUTTON | B_BUTTON | SELECT | START + jp z, Reset + + ret +; 984 + + +GetJoypadPublic: ; 984 +; Update mirror joypad input from hJoypadDown (real input) + +; hJoyReleased: released this frame (delta) +; hJoyPressed: pressed this frame (delta) +; hJoyDown: currently pressed + +; bit 0 A +; 1 B +; 2 SELECT +; 3 START +; 4 RIGHT +; 5 LEFT +; 6 UP +; 7 DOWN + + push af + push hl + push de + push bc + +; The player input can be automated using an input stream. +; See more below. + ld a, [InputType] + cp a, AUTO_INPUT + jr z, .auto + +; To get deltas, take this and last frame's input. + ld a, [hJoypadDown] ; real input + ld b, a + ld a, [hJoyDown] ; last frame mirror + ld e, a + +; Released this frame: + xor b + ld d, a + and e + ld [hJoyReleased], a + +; Pressed this frame: + ld a, d + and b + ld [hJoyPressed], a + +; It looks like the collective presses got commented out here. + ld c, a + +; Currently pressed: + ld a, b + ld [hJoyDown], a ; frame input + +.quit + pop bc + pop de + pop hl + pop af + ret + +.auto +; Use a predetermined input stream (used in the catching tutorial). + +; Stream format: [input][duration] +; A value of $ff will immediately end the stream. + +; Read from the input stream. + ld a, [hROMBank] + push af + ld a, [AutoInputBank] + rst Bankswitch + + ld hl, AutoInputAddress + ld a, [hli] + ld h, [hl] + ld l, a + +; We only update when the input duration has expired. + ld a, [AutoInputLength] + and a + jr z, .updateauto + +; Until then, don't change anything. + dec a + ld [AutoInputLength], a + pop af + rst Bankswitch + jr .quit + + +.updateauto +; An input of $ff will end the stream. + ld a, [hli] + cp a, $ff + jr z, .stopauto + ld b, a + +; A duration of $ff will end the stream indefinitely. + ld a, [hli] + ld [AutoInputLength], a + cp a, $ff + jr nz, .next + +; The current input is overwritten. + dec hl + dec hl + ld b, NO_INPUT + jr .finishauto + +.next +; On to the next input... + ld a, l + ld [AutoInputAddress], a + ld a, h + ld [AutoInputAddress+1], a + jr .finishauto + +.stopauto + call StopAutoInput + ld b, NO_INPUT + +.finishauto + pop af + rst Bankswitch + ld a, b + ld [hJoyPressed], a ; pressed + ld [hJoyDown], a ; input + jr .quit +; 9ee + + +StartAutoInput: ; 9ee +; Start reading automated input stream at a:hl. + + ld [AutoInputBank], a + ld a, l + ld [AutoInputAddress], a + ld a, h + ld [AutoInputAddress+1], a +; Start reading the stream immediately. + xor a + ld [AutoInputLength], a +; Reset input mirrors. + xor a + ld [hJoyPressed], a ; pressed this frame + ld [hJoyReleased], a ; released this frame + ld [hJoyDown], a ; currently pressed + + ld a, AUTO_INPUT + ld [InputType], a + ret +; a0a + + +StopAutoInput: ; a0a +; Clear variables related to automated input. + xor a + ld [AutoInputBank], a + ld [AutoInputAddress], a + ld [AutoInputAddress+1], a + ld [AutoInputLength], a +; Back to normal input. + ld [InputType], a + ret +; a1b + + +Functiona1b: ; a1b + + call DelayFrame + + push bc + call Functiona57 + pop bc + + ld a, [hJoyDown] + cp D_UP | SELECT | B_BUTTON + jr z, .asm_a34 + + ld a, [$ffa9] + and START | A_BUTTON + jr nz, .asm_a34 + + dec c + jr nz, Functiona1b + + and a + ret + +.asm_a34 + scf + ret +; a36 + + +Functiona36: ; a36 + call DelayFrame + call GetJoypadPublic + ld a, [hJoyPressed] + and A_BUTTON | B_BUTTON + ret nz + call RTC + jr Functiona36 +; a46 + +Functiona46: ; a46 + ld a, [hOAMUpdate] + push af + ld a, 1 + ld [hOAMUpdate], a + call WaitBGMap + call Functiona36 + pop af + ld [hOAMUpdate], a + ret +; a57 + +Functiona57: ; a57 + call GetJoypadPublic + ld a, [$ffaa] + and a + ld a, [hJoyPressed] + jr z, .asm_a63 + ld a, [hJoyDown] +.asm_a63 + ld [$ffa9], a + ld a, [hJoyPressed] + and a + jr z, .asm_a70 + ld a, 15 + ld [TextDelayFrames], a + ret + +.asm_a70 + ld a, [TextDelayFrames] + and a + jr z, .asm_a7a + xor a + ld [$ffa9], a + ret + +.asm_a7a + ld a, 5 + ld [TextDelayFrames], a + ret +; a80 + +Functiona80: ; a80 + ld a, [$ffaf] + push af + ld a, [$ffb0] + push af + xor a + ld [$ffaf], a + ld a, $6 + ld [$ffb0], a +.asm_a8d + push hl + ld hl, $c606 + call Functionb06 + pop hl + call Functiona57 + ld a, [$ffa9] + and $3 + jr z, .asm_a8d + pop af + ld [$ffb0], a + pop af + ld [$ffaf], a + ret +; aa5 + +Functionaa5: ; aa5 + call Functiona57 + ld a, [$ffa9] + and A_BUTTON | B_BUTTON + jr z, Functionaa5 + ret +; aaf + +Functionaaf: ; aaf + ld a, [InLinkBattle] + and a + jr nz, .asm_ac1 + call Functionac6 + push de + ld de, SFX_READ_TEXT_2 + call StartSFX + pop de + ret + +.asm_ac1 + ld c, 65 + jp DelayFrames +; ac6 + +Functionac6: ; ac6 + ld a, [hOAMUpdate] + push af + ld a, $1 + ld [hOAMUpdate], a + ld a, [InputType] + or a + jr z, .asm_ad9 + callba Function1de28a +.asm_ad9 + call Functionaf5 + call Functiona57 + ld a, [hJoyPressed] + and $3 + jr nz, .asm_af1 + call RTC + ld a, $1 + ld [hBGMapMode], a + call DelayFrame + jr .asm_ad9 + +.asm_af1 + pop af + ld [hOAMUpdate], a + ret +; af5 + +Functionaf5: ; af5 + ld a, [$ff9b] + and $10 + jr z, .asm_aff + ld a, $ee + jr .asm_b02 + +.asm_aff + ld a, [$c605] + +.asm_b02 + ld [$c606], a + ret +; b06 + +Functionb06: ; b06 + push bc + ld a, [hl] + ld b, a + ld a, $ee + cp b + pop bc + jr nz, .asm_b27 + ld a, [$ffaf] + dec a + ld [$ffaf], a + ret nz + ld a, [$ffb0] + dec a + ld [$ffb0], a + ret nz + ld a, $7a + ld [hl], a + ld a, $ff + ld [$ffaf], a + ld a, $6 + ld [$ffb0], a + ret + +.asm_b27 + ld a, [$ffaf] + and a + ret z + dec a + ld [$ffaf], a + ret nz + dec a + ld [$ffaf], a + ld a, [$ffb0] + dec a + ld [$ffb0], a + ret nz + ld a, $6 + ld [$ffb0], a + ld a, $ee + ld [hl], a + ret +; b40 + diff --git a/common/lcd.asm b/common/lcd.asm new file mode 100644 index 000000000..9c86eaa5c --- /dev/null +++ b/common/lcd.asm @@ -0,0 +1,81 @@ +; LCD handling + + +Function547: ; 547 + ld a, [hLCDStatCustom] + cp rSCX & $ff + ret nz + ld c, a + ld a, [LYOverrides] + ld [$ff00+c], a + ret +; 552 + + +LCD: ; 552 + push af + ld a, [hLCDStatCustom] + and a + jr z, .done + +; At this point it's assumed we're in WRAM bank 5! + push bc + ld a, [rLY] + ld c, a + ld b, LYOverrides >> 8 + ld a, [bc] + ld b, a + ld a, [hLCDStatCustom] + ld c, a + ld a, b + ld [$ff00+c], a + pop bc + +.done + pop af + reti +; 568 + + +DisableLCD: ; 568 +; Turn the LCD off + +; Don't need to do anything if the LCD is already off + ld a, [rLCDC] + bit 7, a ; lcd enable + ret z + + xor a + ld [rIF], a + ld a, [rIE] + ld b, a + +; Disable VBlank + res 0, a ; vblank + ld [rIE], a + +.wait +; Wait until VBlank would normally happen + ld a, [rLY] + cp 145 + jr nz, .wait + + ld a, [rLCDC] + and %01111111 ; lcd enable off + ld [rLCDC], a + + xor a + ld [rIF], a + ld a, b + ld [rIE], a + ret +; 58a + + +EnableLCD: ; 58a + ld a, [rLCDC] + set 7, a ; lcd enable + ld [rLCDC], a + ret +; 591 + diff --git a/common/map.asm b/common/map.asm new file mode 100644 index 000000000..d4cfe1be9 --- /dev/null +++ b/common/map.asm @@ -0,0 +1,2369 @@ +; Functions dealing with rendering and interacting with maps. + +Function210f: ; 210f + ld hl, $c7e8 + ld bc, $0018 + ld a, $0 + call ByteFill + ret +; 211b + +Function211b: ; 211b + push hl + ld hl, $dbf7 + ld a, [hli] + ld h, [hl] + ld l, a + or h + ld a, [hl] + jr nz, .asm_2128 + ld a, $ff + +.asm_2128 + pop hl + ret +; 212a + +Function212a: ; 212a + ld a, [MapGroup] + ld b, a + ld a, [MapNumber] + ld c, a + xor a + ld [$dbf7], a + ld [$dbf8], a + call Function2147 + ret c + ld a, e + ld [$dbf7], a + ld a, d + ld [$dbf8], a + xor a + ret +; 2147 + +Function2147: ; 2147 + push bc + ld a, [hROMBank] + push af + ld a, $13 + rst Bankswitch + + ld hl, $501e +.asm_2151 + push hl + ld a, [hli] + cp $ff + jr z, .asm_2167 + cp b + jr nz, .asm_2160 + ld a, [hli] + cp c + jr nz, .asm_2160 + jr .asm_216a + +.asm_2160 + pop hl + ld de, $0004 + add hl, de + jr .asm_2151 + +.asm_2167 + scf + jr .asm_216d + +.asm_216a + ld e, [hl] + inc hl + ld d, [hl] + +.asm_216d + pop hl + pop bc + ld a, b + rst Bankswitch + + pop bc + ret +; 2173 + +Function2173: ; 2173 + call Function217a + call Functiondb1 + ret +; 217a + +Function217a: ; 217a + ld a, [hROMBank] + push af + ld a, [TilesetBlocksBank] + rst Bankswitch + + call Function2198 + ld a, $60 + ld hl, TileMap + ld bc, $0168 + call ByteFill + ld a, $13 + rst Bankswitch + + call $515b + pop af + rst Bankswitch + + ret +; 2198 + +Function2198: ; 2198 + ld a, [$d194] + ld e, a + ld a, [$d195] + ld d, a + ld hl, EnemyMoveAnimation + ld b, $5 + +.asm_21a5 + push de + push hl + ld c, $6 + +.asm_21a9 + push de + push hl + ld a, [de] + and a + jr nz, .asm_21b2 + ld a, [$d19d] + +.asm_21b2 + ld e, l + ld d, h + add a + ld l, a + ld h, $0 + add hl, hl + add hl, hl + add hl, hl + ld a, [TilesetBlocksAddress] + add l + ld l, a + ld a, [TilesetBlocksAddress + 1] + adc h + ld h, a + +rept 3 + 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 + + ld a, e + add 20 + ld e, a + jr nc, .next\@ + inc d +.next\@ +endr + + 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 + + pop hl + ld de, $0004 + add hl, de + pop de + inc de + dec c + jp nz, .asm_21a9 + pop hl + ld de, $0060 + add hl, de + pop de + ld a, [$d19f] + add $6 + add e + ld e, a + jr nc, .asm_2225 + inc d + +.asm_2225 + dec b + jp nz, .asm_21a5 + ret +; 222a + +Function222a: ; 222a + ld a, $fa + ld [$ff9f], a + callba Function15363 + xor a + ld [$ff9f], a + ret +; 2238 + +Function2238: ; 2238 + call Function2252 + ret nc + push bc + callba Function149af + pop bc + ret nc + call Function22a7 + scf + ret +; 224a + + + +Function224a: ; 224a + call Function2252 + ret nc + call Function22a7 + ret +; 2252 + +Function2252: ; 2252 + callba Function1499a + ret nc + + ld a, [hROMBank] + push af + + call Function2c52 + call Function2266 + + pop de + ld a, d + rst Bankswitch + ret +; 2266 + +Function2266: ; 2266 + ld a, [MapY] + sub $4 + ld e, a + ld a, [MapX] + sub $4 + ld d, a + ld a, [$dbfb] + and a + ret z + ld c, a + ld hl, $dbfc + ld a, [hli] + ld h, [hl] + ld l, a +.asm_227e + push hl + ld a, [hli] + cp e + jr nz, .asm_2289 + ld a, [hli] + cp d + jr nz, .asm_2289 + jr .asm_2296 + +.asm_2289 + pop hl + ld a, $5 + add l + ld l, a + jr nc, .asm_2291 + inc h + +.asm_2291 + dec c + jr nz, .asm_227e + xor a + ret + +.asm_2296 + pop hl + call Function22a3 + ret nc + ld a, [$dbfb] + inc a + sub c + ld c, a + scf + ret +; 22a3 + +Function22a3: ; 22a3 + inc hl + inc hl + scf + ret +; 22a7 + +Function22a7: ; 22a7 + ld a, [hROMBank] + push af + + call Function2c52 + call Function22b4 + + pop af + rst Bankswitch + scf + ret +; 22b4 + +Function22b4: ; 22b4 + push bc + ld hl, $dbfc + ld a, [hli] + ld h, [hl] + ld l, a + ld a, c + dec a + ld bc, $0005 + call AddNTimes + ld bc, $0002 + add hl, bc + ld a, [hli] + cp $ff + jr nz, .asm_22d0 + ld hl, $dcac + ld a, [hli] + +.asm_22d0 + pop bc + ld [$d146], a + ld a, [hli] + ld [$d147], a + ld a, [hli] + ld [$d148], a + ld a, c + ld [$d149], a + ld a, [MapGroup] + ld [$d14a], a + ld a, [MapNumber] + ld [$d14b], a + scf + ret +; 22ee + + + +CheckOutdoorMap: ; 22ee + cp ROUTE + ret z + cp TOWN + ret +; 22f4 + +CheckIndoorMap: ; 22f4 + cp INDOOR + ret z + cp CAVE + ret z + cp DUNGEON + ret z + cp GATE + ret +; 2300 + +Function2300: ; 2300 + cp INDOOR + ret z + cp GATE + ret z + cp $5 + ret +; 2309 + + +Function2309: ; 2309 + call Function2326 + call Function2c52 + call Function234f + xor a + call Function2336 + ret +; 2317 + +Function2317: ; 2317 + call Function2326 + call Function2c52 + call Function234f + ld a, $1 + call Function2336 + ret +; 2326 + +Function2326: ; 2326 + call Function2c3d + call Function2c1c + call GetSecondaryMapHeaderPointer + call Function235c + call Function2368 + ret +; 2336 + +Function2336: ; 2336 + push af + ld hl, $d1a6 + ld a, [hli] + ld h, [hl] + ld l, a + inc hl + inc hl + call Function23da + call Function23f1 + call Function2408 + pop af + and a + ret nz + call Function241f + ret +; 234f + +Function234f: ; 234f + ld hl, $d1a4 + ld a, [hli] + ld h, [hl] + ld l, a + call Function23ac + call Function23c3 + ret +; 235c + +Function235c: ; 235c + ld de, $d19d + ld c, $c +.asm_2361 + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .asm_2361 + ret +; 2368 + +Function2368: ; 2368 + ld a, $ff + ld [NorthConnectedMapGroup], a + ld [SouthConnectedMapGroup], a + ld [WestConnectedMapGroup], a + ld [EastConnectedMapGroup], a + + ld a, [$d1a8] + ld b, a + + bit 3, b + jr z, .asm_2384 + ld de, NorthMapConnection + call GetMapConnection + +.asm_2384 + bit 2, b + jr z, .asm_238e + ld de, SouthMapConnection + call GetMapConnection + +.asm_238e + bit 1, b + jr z, .asm_2398 + ld de, WestMapConnection + call GetMapConnection + +.asm_2398 + bit 0, b + jr z, .asm_23a2 + ld de, EastMapConnection + call GetMapConnection + +.asm_23a2 + ret +; 23a3 + + +GetMapConnection: ; 23a3 +; Load map connection struct at hl into de. + ld c, SouthMapConnection - NorthMapConnection +.loop + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .loop + ret +; 23ac + + +Function23ac: ; 23ac + ld a, [hli] + ld c, a + ld [$dc07], a + ld a, l + ld [$dc08], a + ld a, h + ld [$dc09], a + ld a, c + and a + ret z + ld bc, $0004 + call AddNTimes + ret +; 23c3 + +Function23c3: ; 23c3 + ld a, [hli] + ld c, a + ld [$dc0a], a + ld a, l + ld [$dc0b], a + ld a, h + ld [$dc0c], a + ld a, c + and a + ret z + ld bc, $0003 + call AddNTimes + ret +; 23da + +Function23da: ; 23da + ld a, [hli] + ld c, a + ld [$dbfb], a + ld a, l + ld [$dbfc], a + ld a, h + ld [$dbfd], a + ld a, c + and a + ret z + ld bc, $0005 + call AddNTimes + ret +; 23f1 + +Function23f1: ; 23f1 + ld a, [hli] + ld c, a + ld [$dbfe], a + ld a, l + ld [$dbff], a + ld a, h + ld [$dc00], a + ld a, c + and a + ret z + ld bc, $0008 + call AddNTimes + ret +; 2408 + +Function2408: ; 2408 + ld a, [hli] + ld c, a + ld [$dc01], a + ld a, l + ld [$dc02], a + ld a, h + ld [$dc03], a + ld a, c + and a + ret z + ld bc, $0005 + call AddNTimes + ret +; 241f + +Function241f: ; 241f + push hl + call Function2471 + pop de + ld hl, $d72e + ld a, [de] + inc de + ld [$dc04], a + ld a, e + ld [$dc05], a + ld a, d + ld [$dc06], a + ld a, [$dc04] + call Function2457 + ld a, [$dc04] + ld c, a + ld a, $10 + sub c + jr z, .asm_2454 + ld bc, $0001 + add hl, bc + ld bc, $0010 +.asm_244a + ld [hl], $0 + inc hl + ld [hl], $ff + dec hl + add hl, bc + dec a + jr nz, .asm_244a + +.asm_2454 + ld h, d + ld l, e + ret +; 2457 + +Function2457: ; 2457 + and a + ret z + ld c, a +.asm_245a + push bc + push hl + ld a, $ff + ld [hli], a + ld b, $d +.asm_2461 + ld a, [de] + inc de + ld [hli], a + dec b + jr nz, .asm_2461 + pop hl + ld bc, $0010 + add hl, bc + pop bc + dec c + jr nz, .asm_245a + ret +; 2471 + +Function2471: ; 2471 + ld hl, $d4fe + ld bc, $01e0 + xor a + call ByteFill + ld hl, $d4fe + ld de, $0028 + ld c, $c + xor a +.asm_2484 + ld [hl], a + add hl, de + dec c + jr nz, .asm_2484 + ret +; 248a + +Function248a: ; 248a + call GetMapEventBank + rst Bankswitch + + ld hl, $d1a6 + ld a, [hli] + ld h, [hl] + ld l, a + inc hl + inc hl + inc hl + ld a, [WarpNumber] + dec a + ld c, a + ld b, $0 + ld a, $5 + call AddNTimes + ld a, [hli] + ld [YCoord], a + ld a, [hli] + ld [XCoord], a + ld a, [hli] + cp $ff + jr nz, .asm_24b3 + call Function24ba + +.asm_24b3 + ld a, $41 + ld hl, $486d + rst FarCall + ret +; 24ba + +Function24ba: ; 24ba + ld a, [$d149] + ld [$dcac], a + ld a, [$d14a] + ld [BackupMapGroup], a + ld a, [$d14b] + ld [BackupMapNumber], a + ret +; 24cd + +Function24cd: ; 24cd + ld hl, OverworldMap + ld bc, $0514 + ld a, $0 + call ByteFill + call Function24e4 + call FillMapConnections + ld a, $1 + call Function263b + ret +; 24e4 + + + +Function24e4: ; 24e4 + ld a, [hROMBank] + push af + ld hl, OverworldMap + ld a, [$d19f] + ld [hConnectedMapWidth], a + add $6 + ld [hConnectionStripLength], a + ld c, a + ld b, $0 + add hl, bc + add hl, bc + add hl, bc + ld c, $3 + add hl, bc + ld a, [$d1a0] + rst Bankswitch + + ld a, [$d1a1] + ld e, a + ld a, [$d1a2] + ld d, a + ld a, [$d19e] + ld b, a +.asm_250c + push hl + ld a, [hConnectedMapWidth] + ld c, a +.asm_2510 + ld a, [de] + inc de + ld [hli], a + dec c + jr nz, .asm_2510 + pop hl + ld a, [hConnectionStripLength] + add l + ld l, a + jr nc, .asm_251e + inc h + +.asm_251e + dec b + jr nz, .asm_250c + pop af + rst Bankswitch + + ret +; 2524 + + + +FillMapConnections: ; 2524 + +; North + ld a, [NorthConnectedMapGroup] + cp $ff + jr z, .South + ld b, a + ld a, [NorthConnectedMapNumber] + ld c, a + call GetAnyMapBlockdataBank + + ld a, [NorthConnectionStripPointer] + ld l, a + ld a, [NorthConnectionStripPointer + 1] + ld h, a + ld a, [NorthConnectionStripLocation] + ld e, a + ld a, [NorthConnectionStripLocation + 1] + ld d, a + ld a, [NorthConnectionStripLength] + ld [hConnectionStripLength], a + ld a, [NorthConnectedMapWidth] + ld [hConnectedMapWidth], a + call FillNorthConnectionStrip + +.South + ld a, [SouthConnectedMapGroup] + cp $ff + jr z, .West + ld b, a + ld a, [SouthConnectedMapNumber] + ld c, a + call GetAnyMapBlockdataBank + + ld a, [SouthConnectionStripPointer] + ld l, a + ld a, [SouthConnectionStripPointer + 1] + ld h, a + ld a, [SouthConnectionStripLocation] + ld e, a + ld a, [SouthConnectionStripLocation + 1] + ld d, a + ld a, [SouthConnectionStripLength] + ld [hConnectionStripLength], a + ld a, [SouthConnectedMapWidth] + ld [hConnectedMapWidth], a + call FillSouthConnectionStrip + +.West + ld a, [WestConnectedMapGroup] + cp $ff + jr z, .East + ld b, a + ld a, [WestConnectedMapNumber] + ld c, a + call GetAnyMapBlockdataBank + + ld a, [WestConnectionStripPointer] + ld l, a + ld a, [WestConnectionStripPointer + 1] + ld h, a + ld a, [WestConnectionStripLocation] + ld e, a + ld a, [WestConnectionStripLocation + 1] + ld d, a + ld a, [WestConnectionStripLength] + ld b, a + ld a, [WestConnectedMapWidth] + ld [hConnectionStripLength], a + call FillWestConnectionStrip + +.East + ld a, [EastConnectedMapGroup] + cp $ff + jr z, .Done + ld b, a + ld a, [EastConnectedMapNumber] + ld c, a + call GetAnyMapBlockdataBank + + ld a, [EastConnectionStripPointer] + ld l, a + ld a, [EastConnectionStripPointer + 1] + ld h, a + ld a, [EastConnectionStripLocation] + ld e, a + ld a, [EastConnectionStripLocation + 1] + ld d, a + ld a, [EastConnectionStripLength] + ld b, a + ld a, [EastConnectedMapWidth] + ld [hConnectionStripLength], a + call FillEastConnectionStrip + +.Done + ret +; 25d3 + + +FillNorthConnectionStrip: +FillSouthConnectionStrip: ; 25d3 + + ld c, 3 +.y + push de + + push hl + ld a, [hConnectionStripLength] + ld b, a +.x + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .x + pop hl + + ld a, [hConnectedMapWidth] + ld e, a + ld d, 0 + add hl, de + pop de + + ld a, [$d19f] + add 6 + add e + ld e, a + jr nc, .asm_25f2 + inc d +.asm_25f2 + dec c + jr nz, .y + ret +; 25f6 + + +FillWestConnectionStrip: +FillEastConnectionStrip: ; 25f6 + +.asm_25f6 + ld a, [$d19f] + add 6 + ld [hConnectedMapWidth], a + + push de + + push hl + ld a, [hli] + ld [de], a + inc de + ld a, [hli] + ld [de], a + inc de + ld a, [hli] + ld [de], a + inc de + pop hl + + ld a, [hConnectionStripLength] + ld e, a + ld d, 0 + add hl, de + pop de + + ld a, [hConnectedMapWidth] + add e + ld e, a + jr nc, .asm_2617 + inc d +.asm_2617 + dec b + jr nz, .asm_25f6 + ret +; 261b + +Function261b: ; 261b + ld [$d432], a + ret +; 261f + + +CallScript: ; 261f +; Call a script at a:hl. + + ld [ScriptBank], a + ld a, l + ld [ScriptPos], a + ld a, h + ld [ScriptPos + 1], a + + ld a, $ff + ld [ScriptRunning], a + + scf + ret +; 2631 + +Function2631: ; 2631 + ld a, [ScriptRunning] + and a + ret nz + call GetMapEventBank + jr CallScript +; 263b + +Function263b: ; 263b + ld b, a + ld a, [hROMBank] + push af + call Function2c52 + call Function2653 + jr nc, .done + + call GetMapEventBank + ld b, a + ld d, h + ld e, l + call Function2674 + +.done + pop af + rst Bankswitch + ret +; 2653 + +Function2653: ; 2653 + ld a, [$dc0a] + ld c, a + and a + ret z + ld hl, $dc0b + ld a, [hli] + ld h, [hl] + ld l, a + or h + ret z + ld de, $0003 +.asm_2664 + ld a, [hl] + cp b + jr z, .asm_266e + add hl, de + dec c + jr nz, .asm_2664 + xor a + ret + +.asm_266e + inc hl + ld a, [hli] + ld h, [hl] + ld l, a + scf + ret +; 2674 + +Function2674: ; 2674 + callba Unknown_0x974f3 + ld a, [ScriptMode] + push af + ld hl, ScriptFlags + ld a, [hl] + push af + set 1, [hl] + callba Function96c56 + callba ScriptEvents + pop af + ld [ScriptFlags], a + pop af + ld [ScriptMode], a + ret +; 269a + +Function269a: ; 269a + ld a, [hROMBank] + push af + ld a, b + rst Bankswitch + + push hl + call SpeechTextBox + call Function2e31 + ld a, 1 + ld [hOAMUpdate], a + call Function321c + pop hl + call PrintTextBoxText + xor a + ld [hOAMUpdate], a + pop af + rst Bankswitch + + ret +; 26b7 + +Function26b7: ; 26b7 +; Call a:de. + + ld [hBuffer], a + ld a, [hROMBank] + push af + ld a, [hBuffer] + rst Bankswitch + + call .de + + pop af + rst Bankswitch + ret + +.de + push de + ret +; 26c7 + +Function26c7: ; 26c7 + ld a, [hROMBank] + push af + ld a, b + rst Bankswitch + + ld a, c + call Function19e9 + + pop hl + ld a, h + rst Bankswitch + ret +; 26d4 + + +GetScriptByte: ; 0x26d4 +; Return byte at ScriptBank:ScriptPos in a. + + push hl + push bc + ld a, [hROMBank] + push af + ld a, [ScriptBank] + rst Bankswitch + + ld hl, ScriptPos + ld c, [hl] + inc hl + ld b, [hl] + + ld a, [bc] + + inc bc + ld [hl], b + dec hl + ld [hl], c + + ld b, a + pop af + rst Bankswitch + ld a, b + pop bc + pop hl + ret +; 0x26ef + + +ObjectEvent: ; 0x26ef + jumptextfaceplayer ObjectEventText +; 0x26f2 + +ObjectEventText: + TX_FAR _ObjectEventText + db "@" +; 0x26f7 + + +BGEvent: ; 26f7 + jumptext BGEventText +; 26fa + +BGEventText: ; 26fa + text_jump UnknownText_0x1c46fc, BANK(UnknownText_0x1c46fc) + db "@" +; 26ff + + +CoordinatesEvent: ; 26ff + jumptext CoordinatesEventText +; 2702 + +CoordinatesEventText: ; 2702 + text_jump UnknownText_0x1c4706, BANK(UnknownText_0x1c4706) + db "@" +; 2707 + + +Function2707: ; 2707 + ld a, [hConnectionStripLength] + ld e, a + ld d, $0 + ld hl, $d81e + add hl, de + ld a, [hl] + ret +; 2712 + +Function2712: ; 2712 + ld a, [hConnectionStripLength] + ld e, a + ld d, $0 + ld hl, $d81e + add hl, de + ld [hl], $ff + ret +; 271e + +Function271e: ; 271e + ld a, [hConnectionStripLength] + ld e, a + ld d, $0 + ld hl, $d81e + add hl, de + ld [hl], $0 + ret +; 272a + + +Function272a: ; 272a + ld hl, TileMap + ld de, BGMapBuffer + call Function27b7 + ld c, $28 + call Functiondbd + ld a, [$d152] + ld e, a + ld a, [$d153] + ld d, a + call Function27d3 + ld a, $1 + ld [hBGMapUpdate], a + ret +; 2748 + +Function2748: ; 2748 + ld hl, $c5e0 + ld de, BGMapBuffer + call Function27b7 + ld c, $28 + call Functiondbd + ld a, [$d152] + ld l, a + ld a, [$d153] + ld h, a + ld bc, $0200 + add hl, bc + ld a, h + and $3 + or $98 + ld e, l + ld d, a + call Function27d3 + ld a, $1 + ld [hBGMapUpdate], a + ret +; 2771 + +Function2771: ; 2771 + ld hl, TileMap + ld de, BGMapBuffer + call Function27c0 + ld c, $24 + call Functiondbd + ld a, [$d152] + ld e, a + ld a, [$d153] + ld d, a + call Function27f8 + ld a, $1 + ld [hBGMapUpdate], a + ret +; 278f + +Function278f: ; 278f + ld hl, $c4b2 + ld de, BGMapBuffer + call Function27c0 + ld c, $24 + call Functiondbd + ld a, [$d152] + ld e, a + and $e0 + ld b, a + ld a, e + add $12 + and $1f + or b + ld e, a + ld a, [$d153] + ld d, a + call Function27f8 + ld a, $1 + ld [hBGMapUpdate], a + ret +; 27b7 + +Function27b7: ; 27b7 + ld c, $28 +.asm_27b9 + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .asm_27b9 + ret +; 27c0 + +Function27c0: ; 27c0 + ld c, $12 +.asm_27c2 + ld a, [hli] + ld [de], a + inc de + ld a, [hl] + ld [de], a + inc de + ld a, $13 + add l + ld l, a + jr nc, .asm_27cf + inc h + +.asm_27cf + dec c + jr nz, .asm_27c2 + ret +; 27d3 + +Function27d3: ; 27d3 + ld hl, BGMapBufferPtrs + push de + call .asm_27df + pop de + ld a, $20 + add e + ld e, a + +.asm_27df + ld c, $a +.asm_27e1 + ld a, e + ld [hli], a + ld a, d + ld [hli], a + ld a, e + inc a + inc a + and $1f + ld b, a + ld a, e + and $e0 + or b + ld e, a + dec c + jr nz, .asm_27e1 + ld a, $14 + ld [$ffdc], a + ret +; 27f8 + +Function27f8: ; 27f8 + ld hl, BGMapBufferPtrs + ld c, $12 +.asm_27fd + ld a, e + ld [hli], a + ld a, d + ld [hli], a + ld a, $20 + add e + ld e, a + jr nc, .asm_280e + inc d + ld a, d + and $3 + or $98 + ld d, a + +.asm_280e + dec c + jr nz, .asm_27fd + ld a, $12 + ld [$ffdc], a + ret +; 2816 + +Function2816: ; 2816 + ld hl, BGMapBuffer + ld bc, $0078 + xor a + call ByteFill + ret +; 2821 + +Function2821: ; 2821 + ld hl, TilesetAddress + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [TilesetBank] + ld e, a + ld a, [rSVBK] + push af + ld a, $6 + ld [rSVBK], a + ld a, e + ld de, $d000 + call FarDecompress + ld hl, $d000 + ld de, VTiles2 + ld bc, $0600 + call CopyBytes + ld a, [rVBK] + push af + ld a, $1 + ld [rVBK], a + ld hl, $d600 + ld de, VTiles2 + ld bc, $0600 + call CopyBytes + pop af + ld [rVBK], a + pop af + ld [rSVBK], a + ld a, [$d199] + cp $1 + jr z, .asm_286f + cp $2 + jr z, .asm_286f + cp $4 + jr z, .asm_286f + jr .asm_2875 + +.asm_286f + ld a, $7 + ld hl, $4000 + rst FarCall + +.asm_2875 + xor a + ld [hTileAnimFrame], a + ret +; 2879 + +Function2879: ; 2879 + ld hl, $d194 + ld a, [hli] + ld h, [hl] + ld l, a + ld de, $dcb9 + ld c, $5 + ld b, $6 +.asm_2886 + push bc + push hl +.asm_2888 + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .asm_2888 + pop hl + ld a, [$d19f] + add $6 + ld c, a + ld b, $0 + add hl, bc + pop bc + dec c + jr nz, .asm_2886 + ret +; 289d + +Function289d: ; 289d + ld hl, $d194 + ld a, [hli] + ld h, [hl] + ld l, a + ld de, $dcb9 + ld a, [$d19f] + add $6 + ld [hConnectionStripLength], a + ld a, [$d151] + and a + jr z, .asm_28cb + cp $1 + jr z, .asm_28c0 + cp $2 + jr z, .asm_28d4 + cp $3 + jr z, .asm_28da + ret + +.asm_28c0 + ld de, $dcbf + ld a, [hConnectionStripLength] + ld c, a + ld b, $0 + add hl, bc + jr .asm_28ce + +.asm_28cb + ld de, $dcb9 + +.asm_28ce + ld b, $6 + ld c, $4 + jr .asm_28f7 + +.asm_28d4 + ld de, $dcba + inc hl + jr .asm_28dd + +.asm_28da + ld de, $dcb9 + +.asm_28dd + ld b, $5 + ld c, $5 + jr .asm_28f7 + + ld hl, $d194 + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [$d19f] + add $6 + ld [hConnectionStripLength], a + ld de, $dcb9 + ld b, $6 + ld c, $5 + +.asm_28f7 + push bc + push hl + push de +.asm_28fa + ld a, [de] + inc de + ld [hli], a + dec b + jr nz, .asm_28fa + pop de + ld a, e + add $6 + ld e, a + jr nc, .asm_2908 + inc d + +.asm_2908 + pop hl + ld a, [hConnectionStripLength] + ld c, a + ld b, $0 + add hl, bc + pop bc + dec c + jr nz, .asm_28f7 + ret +; 2914 + +Function2914: ; 2914 + xor a + ld [TilePermissions], a + call Function296c + call Function294d + ld a, [MapX] + ld d, a + ld a, [MapY] + ld e, a + call Function2a3c + ld [StandingTile], a + call Function29ff + ret nz + ld a, [StandingTile] + and 7 + ld hl, .data_2945 + add l + ld l, a + ld a, 0 + adc h + ld h, a + ld a, [hl] + ld hl, TilePermissions + or [hl] + ld [hl], a + ret +; 2945 + +.data_2945 ; 2945 + db 1, 2, 4, 8, 9, 10, 5, 6 +; 294d + +Function294d: ; 294d + ld a, [MapX] + ld d, a + ld a, [MapY] + ld e, a + push de + inc e + call Function2a3c + ld [TileDown], a + call Function298b + pop de + dec e + call Function2a3c + ld [TileUp], a + call Function29a8 + ret +; 296c + +Function296c: ; 296c + ld a, [MapX] + ld d, a + ld a, [MapY] + ld e, a + push de + dec d + call Function2a3c + ld [TileLeft], a + call Function29e2 + pop de + inc d + call Function2a3c + ld [TileRight], a + call Function29c5 + ret +; 298b + +Function298b: ; 298b + call Function29ff + ret nz + ld a, [TileDown] + and $7 + cp $2 + jr z, .asm_299f + cp $6 + jr z, .asm_299f + cp $7 + ret nz + +.asm_299f + ld a, [TilePermissions] + or $8 + ld [TilePermissions], a + ret +; 29a8 + +Function29a8: ; 29a8 + call Function29ff + ret nz + ld a, [TileUp] + and $7 + cp $3 + jr z, .asm_29bc + cp $4 + jr z, .asm_29bc + cp $5 + ret nz + +.asm_29bc + ld a, [TilePermissions] + or $4 + ld [TilePermissions], a + ret +; 29c5 + +Function29c5: ; 29c5 + call Function29ff + ret nz + ld a, [TileRight] + and $7 + cp $1 + jr z, .asm_29d9 + cp $5 + jr z, .asm_29d9 + cp $7 + ret nz + +.asm_29d9 + ld a, [TilePermissions] + or $1 + ld [TilePermissions], a + ret +; 29e2 + +Function29e2: ; 29e2 + call Function29ff + ret nz + ld a, [TileLeft] + and $7 + cp $0 + jr z, .asm_29f6 + cp $4 + jr z, .asm_29f6 + cp $6 + ret nz + +.asm_29f6 + ld a, [TilePermissions] + or $2 + ld [TilePermissions], a + ret +; 29ff + +Function29ff: ; 29ff + and $f0 + cp $b0 + ret z + cp $c0 + ret +; 2a07 + + +GetFacingTileCoord: ; 2a07 +; Return map coordinates in (d, e) and tile id in a +; of the tile the player is facing. + + ld a, [PlayerDirection] + and %1100 + srl a + srl a + ld l, a + ld h, 0 + add hl, hl + add hl, hl + ld de, .Directions + add hl, de + + ld d, [hl] + inc hl + ld e, [hl] + inc hl + + ld a, [hli] + ld h, [hl] + ld l, a + + ld a, [MapX] + add d + ld d, a + ld a, [MapY] + add e + ld e, a + ld a, [hl] + ret + +.Directions + ; x, y + db 0, 1 + dw TileDown + db 0, -1 + dw TileUp + db -1, 0 + dw TileLeft + db 1, 0 + dw TileRight +; 2a3c + + +Function2a3c: ; 2a3c + call Function2a66 + ld a, [hl] + and a + jr z, .asm_2a63 + ld l, a + ld h, $0 + add hl, hl + add hl, hl + ld a, [TilesetCollisionAddress] + ld c, a + ld a, [$d1e1] + ld b, a + add hl, bc + rr d + jr nc, .asm_2a56 + inc hl + +.asm_2a56 + rr e + jr nc, .asm_2a5c + inc hl + inc hl + +.asm_2a5c + ld a, [TilesetCollisionBank] + call GetFarByte + ret + +.asm_2a63 + ld a, $ff + ret +; 2a66 + +Function2a66: ; 2a66 + ld a, [$d19f] + add $6 + ld c, a + ld b, $0 + ld hl, $c801 + add hl, bc + ld a, e + srl a + jr z, .asm_2a84 + and a +.asm_2a78 + srl a + jr nc, .asm_2a7d + add hl, bc + +.asm_2a7d + sla c + rl b + and a + jr nz, .asm_2a78 + +.asm_2a84 + ld c, d + srl c + ld b, $0 + add hl, bc + ret +; 2a8b + + +CheckFacingSign: ; 2a8b + call GetFacingTileCoord + ld b, a + ld a, d + sub 4 + ld d, a + ld a, e + sub 4 + ld e, a + ld a, [$dc01] + and a + ret z + ld c, a + ld a, [hROMBank] + push af + call Function2c52 + call Function2aaa + pop hl + ld a, h + rst Bankswitch + ret +; 2aaa + +Function2aaa: ; 2aaa + ld hl, $dc02 + ld a, [hli] + ld h, [hl] + ld l, a +.asm_2ab0 + push hl + ld a, [hli] + cp e + jr nz, .asm_2abb + ld a, [hli] + cp d + jr nz, .asm_2abb + jr .asm_2ac8 + +.asm_2abb + pop hl + ld a, 5 + add l + ld l, a + jr nc, .asm_2ac3 + inc h + +.asm_2ac3 + dec c + jr nz, .asm_2ab0 + xor a + ret + +.asm_2ac8 + pop hl + ld de, EngineBuffer1 + ld bc, 5 + call CopyBytes + scf + ret +; 2ad4 + +Function2ad4: ; 2ad4 + ld a, [$dbfe] + and a + ret z + ld c, a + ld a, [hROMBank] + push af + call Function2c52 + call Function2ae7 + pop hl + ld a, h + rst Bankswitch + ret +; 2ae7 + +Function2ae7: ; 2ae7 + ld hl, $dbff + ld a, [hli] + ld h, [hl] + ld l, a + call Function211b + ld b, a + ld a, [MapX] + sub $4 + ld d, a + ld a, [MapY] + sub $4 + ld e, a +.asm_2afd + push hl + ld a, [hli] + cp b + jr z, .asm_2b06 + cp $ff + jr nz, .asm_2b10 + +.asm_2b06 + ld a, [hli] + cp e + jr nz, .asm_2b10 + ld a, [hli] + cp d + jr nz, .asm_2b10 + jr .asm_2b1d + +.asm_2b10 + pop hl + ld a, $8 + add l + ld l, a + jr nc, .asm_2b18 + inc h + +.asm_2b18 + dec c + jr nz, .asm_2afd + xor a + ret + +.asm_2b1d + pop hl + ld de, EngineBuffer1 + ld bc, $0008 + call CopyBytes + scf + ret +; 2b29 + + +FadeToMenu: ; 2b29 + xor a + ld [hBGMapMode], a + call Function1d6e + ld a, $23 + ld hl, $4084 + rst FarCall + call ClearSprites + call Function2ed3 + ret +; 2b3c + + +Function2b3c: ; 2b3c + call WhiteBGMap + call Function2bae + call Function1ad2 + call Function1d7d + call Functiond90 + jr Function2b5c +; 2b4d + +Function2b4d: ; 2b4d + call WhiteBGMap + call Function1d7d + call Function2bae + call Function1ad2 + call Functiond90 +; 2b5c + +Function2b5c: ; 2b5c + ld b, $9 + call GetSGBLayout + ld a, $12 + ld hl, $5409 + rst FarCall + call Function3200 + ld a, $23 + ld hl, $4079 + rst FarCall + call Function2ee4 + ret +; 2b74 + + +Function2b74: ; 0x2b74 + push af + ld a, $1 + ld [$c2ce], a + call WhiteBGMap + call ClearSprites + call Function2bae + ld hl, $c590 ; tile 0, 12 + ld bc, $0412 + call TextBox + ld hl, VramState + set 0, [hl] + call Function1ad2 + call Function3200 + ld b, $9 + call GetSGBLayout + callba Function49409 + call UpdateTimePals + call DelayFrame + ld a, $1 + ld [$ffde], a + pop af + ret +; 0x2bae + +Function2bae: ; 2bae + call DisableLCD + call ClearSprites + ld a, $5 + ld hl, $4168 + rst FarCall + call Functione51 + call Functione5f + ld a, [hROMBank] + push af + ld a, [MapGroup] + ld b, a + ld a, [MapNumber] + ld c, a + call Function2c24 + ld a, $23 + ld hl, $4001 + rst FarCall + call Function2173 + call Function2821 + ld a, $9 + call Function3cb4 + pop af + rst Bankswitch + + call EnableLCD + ret +; 2be5 + + +GetMapHeaderPointer: ; 2be5 + ld a, [MapGroup] + ld b, a + ld a, [MapNumber] + ld c, a +; 2bed + +GetAnyMapHeaderPointer: ; 0x2bed +; Prior to calling this function, you must have switched banks so that +; MapGroupPointers is visible. + +; inputs: +; b = map group, c = map number +; XXX de = ??? + +; outputs: +; hl points to the map header + push bc ; save map number for later + + ; get pointer to map group + dec b + ld c, b + ld b, $0 + ld hl, MapGroupPointers + add hl, bc + add hl, bc + + ld a, [hli] + ld h, [hl] + ld l, a + pop bc ; restore map number + + ; find the cth map header + dec c + ld b, $0 + ld a, OlivineGym_MapHeader - OlivinePokeCenter1F_MapHeader + call AddNTimes + ret +; 0x2c04 + +GetMapHeaderMember: ; 0x2c04 +; Extract data from the current map's header. + +; inputs: +; de = offset of desired data within the mapheader + +; outputs: +; bc = data from the current map's header +; (e.g., de = $0003 would return a pointer to the secondary map header) + + ld a, [MapGroup] + ld b, a + ld a, [MapNumber] + ld c, a + ; fallthrough + +GetAnyMapHeaderMember: ; 0x2c0c + ; bankswitch + ld a, [hROMBank] + push af + ld a, BANK(MapGroupPointers) + rst Bankswitch + + call GetAnyMapHeaderPointer + add hl, de + ld c, [hl] + inc hl + ld b, [hl] + + ; bankswitch back + pop af + rst Bankswitch + ret +; 0x2c1c + + +Function2c1c: ; 2c1c + ld a, [MapGroup] + ld b, a + ld a, [MapNumber] + ld c, a +; 2c24 + +Function2c24: ; 2c24 + call Function2c31 + rst Bankswitch + ret +; 2c29 + + +Function2c29: ; 2c29 + ld a, [MapGroup] + ld b, a + ld a, [MapNumber] + ld c, a +; 2c31 + +Function2c31: ; 2c31 + push hl + push de + ld de, $0000 + call GetAnyMapHeaderMember + ld a, c + pop de + pop hl + ret +; 2c3d + +Function2c3d: ; 2c3d + ld a, [hROMBank] + push af + ld a, $25 + rst Bankswitch + call GetMapHeaderPointer + ld de, $d198 + ld bc, $0005 + call CopyBytes + pop af + rst Bankswitch + ret +; 2c52 + +Function2c52: ; 2c52 + ld a, [MapEventBank] + rst Bankswitch + ret +; 2c57 + + +GetMapEventBank: ; 2c57 + ld a, [MapEventBank] + ret +; 2c5b + +GetAnyMapBlockdataBank: ; 2c5b +; Return the blockdata bank for group b map c. + push hl + push de + push bc + + push bc + ld de, 3 ; second map header pointer + call GetAnyMapHeaderMember + ld l, c + ld h, b + pop bc + + push hl + ld de, 0 ; second map header bank + call GetAnyMapHeaderMember + pop hl + + ld de, 3 ; blockdata bank + add hl, de + ld a, c + call GetFarByte + rst Bankswitch + + pop bc + pop de + pop hl + ret +; 2c7d + +GetSecondaryMapHeaderPointer: ; 0x2c7d +; returns the current map's secondary map header pointer in hl. + push bc + push de + ld de, $0003 ; secondary map header pointer (offset within header) + call GetMapHeaderMember + ld l, c + ld h, b + pop de + pop bc + ret +; 2c8a + +GetMapPermission: ; 2c8a + push hl + push de + push bc + ld de, 2 + call GetMapHeaderMember + ld a, c + pop bc + pop de + pop hl + ret +; 2c98 + +Function2c98: ; 2c98 + ret +; 2c99 + +Function2c99: ; 2c99 + push hl + push de + push bc + ld de, $0002 + call GetAnyMapHeaderMember + ld a, c + pop bc + pop de + pop hl + ret +; 2ca7 + +Function2ca7: ; 2ca7 + ld de, $0001 + call GetAnyMapHeaderMember + ld a, c + ret +; 2caf + +GetWorldMapLocation: ; 0x2caf +; given a map group/id in bc, return its location on the Pokégear map. + push hl + push de + push bc + ld de, 5 + call GetAnyMapHeaderMember + ld a, c + pop bc + pop de + pop hl + ret +; 0x2cbd + +Function2cbd: ; 2cbd + push hl + push bc + ld de, $0006 + call GetMapHeaderMember + ld a, c + cp $64 + jr z, .asm_2cee + bit 7, c + jr nz, .asm_2cda + ld a, $22 + ld hl, $7342 + rst FarCall + ld e, c + ld d, $0 +.asm_2cd7 + pop bc + pop hl + ret + +.asm_2cda + ld a, [StatusFlags2] + bit 0, a + jr z, .asm_2ce6 + ld de, $0056 + jr .asm_2cd7 + +.asm_2ce6 + ld a, c + and $7f + ld e, a + ld d, $0 + jr .asm_2cd7 + +.asm_2cee + ld a, [StatusFlags2] + bit 7, a + jr z, .asm_2cfa + ld de, $0048 + jr .asm_2cd7 + +.asm_2cfa + ld de, $0026 + jr .asm_2cd7 +; 2cff + +Function2cff: ; 2cff + call Function2d0d + and $f + ret +; 2d05 + +Function2d05: ; 2d05 + call Function2d0d + and $f0 + swap a + ret +; 2d0d + +Function2d0d: ; 2d0d + push hl + push bc + ld de, $0007 + call GetMapHeaderMember + ld a, c + pop bc + pop hl + ret +; 2d19 + +Function2d19: ; 2d19 + push de + push hl + push bc + ld de, $0008 + call GetMapHeaderMember + ld a, c + pop bc + pop hl + pop de + ret +; 2d27 + +Function2d27: ; 2d27 + push hl + push bc + ld hl, $5596 + ld bc, $000f + ld a, [$d199] + call AddNTimes + ld de, TilesetBank + ld bc, $000f + ld a, $13 + call FarCopyBytes + pop bc + pop hl + ret +; 2d43 + diff --git a/common/map_objects.asm b/common/map_objects.asm new file mode 100644 index 000000000..3ebc1b597 --- /dev/null +++ b/common/map_objects.asm @@ -0,0 +1,683 @@ +; Functions handling map objects. + + +GetSpritePalette: ; 17ff + push hl + push de + push bc + ld c, a + callba _GetSpritePalette + ld a, c + pop bc + pop de + pop hl + ret +; 180e + + +Function180e: ; 180e + push hl + push bc + ld hl, $d156 + ld c, $1f + ld b, a + ld a, [hConnectionStripLength] + cp $0 + jr z, .asm_182b + ld a, b +.asm_181d + cp [hl] + jr z, .asm_1830 + inc hl + inc hl + dec c + jr nz, .asm_181d + ld a, [$d155] + scf + jr .asm_1833 + +.asm_182b + ld a, [$d155] + jr .asm_1833 + +.asm_1830 + inc hl + xor a + ld a, [hl] + +.asm_1833 + pop bc + pop hl + ret +; 1836 + +Function1836: ; 1836 + push de + push hl + + ld b, a + ld a, [hROMBank] + push af + ld a, BANK(Function142a7) + rst Bankswitch + + ld a, b + call Function142a7 + ld c, a + + pop de + ld a, d + rst Bankswitch + + pop hl + pop de + ret +; 184a + + + +Function184a: ; 184a + ld a, [StandingTile] + call GetTileCollision + ld b, a + ret +; 1852 + +Function1852: ; 1852 + ld a, [StandingTile] + call GetTileCollision + sub 1 + ret z + and a + ret +; 185d + + +GetTileCollision: ; 185d +; Get the collision type of tile a. + + push de + push hl + + ld hl, TileCollisionTable + ld e, a + ld d, 0 + add hl, de + + ld a, [hROMBank] + push af + ld a, BANK(TileCollisionTable) + rst Bankswitch + ld e, [hl] + pop af + rst Bankswitch + + ld a, e + and $f ; lo nybble only + + pop hl + pop de + ret +; 1875 + + +Function1875: ; 1875 + ld d, a + and $f0 + cp $10 + jr z, .asm_1882 + cp $20 + jr z, .asm_1888 + scf + ret + +.asm_1882 + ld a, d + and 7 + ret z + scf + ret + +.asm_1888 + ld a, d + and 7 + ret z + scf + ret +; 188e + +Function188e: ; 188e + cp $14 + ret z + cp $1c + ret +; 1894 + +CheckCutTreeTile: ; 1894 + cp $12 + ret z + cp $1a + ret +; 189a + +CheckHeadbuttTreeTile: ; 189a + cp $15 + ret z + cp $1d + ret +; 18a0 + +CheckCounterTile: ; 18a0 + cp $90 + ret z + cp $98 + ret +; 18a6 + +CheckPitTile: ; 18a6 + cp $60 + ret z + cp $68 + ret +; 18ac + +CheckIceTile: ; 18ac + cp $23 + ret z + cp $2b + ret z + scf + ret +; 18b4 + +CheckWhirlpoolTile: ; 18b4 + nop + cp $24 + ret z + cp $2c + ret z + scf + ret +; 18bd + +CheckWaterfallTile: ; 18bd + cp $33 + ret z + cp $3b + ret +; 18c3 + +CheckStandingOnEntrance: ; 18c3 + ld a, [StandingTile] + cp $71 ; door + ret z + cp $79 + ret z + cp $7a ; stairs + ret z + cp $7b ; cave + ret +; 18d2 + + +GetMapObject: ; 18d2 +; Return the location of map object a in bc. + ld hl, MapObjects + ld bc, $10 + call AddNTimes + ld b, h + ld c, l + ret +; 18de + + +Function18de: ; 18de + ld [hConnectionStripLength], a + call GetMapObject + ld hl, $0000 + add hl, bc + ld a, [hl] + cp $ff + jr z, .asm_18f3 + ld [hConnectedMapWidth], a + call Function1ae5 + and a + ret + +.asm_18f3 + scf + ret +; 18f5 + +Function18f5: ; 18f5 + ld hl, $0006 + add hl, bc + ld a, [hl] + cp $ff + jr nz, .asm_1921 + ld hl, $0007 + add hl, bc + ld a, [hl] + cp $ff + jr z, .asm_191c + ld hl, .data_191e + ld a, [TimeOfDay] + add l + ld l, a + jr nc, .asm_1912 + inc h + +.asm_1912 + ld a, [hl] + ld hl, $0007 + add hl, bc + and [hl] + jr nz, .asm_191c + scf + ret + +.asm_191c + and a + ret + +.data_191e + db $1 + db $2 + db $4 + +.asm_1921 + ld hl, $0006 + add hl, bc + ld d, [hl] + ld hl, $0007 + add hl, bc + ld e, [hl] + ld hl, hHours + ld a, d + cp e + jr z, .asm_1949 + jr c, .asm_193f + ld a, [hl] + cp d + jr nc, .asm_1949 + cp e + jr c, .asm_1949 + jr z, .asm_1949 + jr .asm_194b + +.asm_193f + ld a, e + cp [hl] + jr c, .asm_194b + ld a, [hl] + cp d + jr nc, .asm_1949 + jr .asm_194b + +.asm_1949 + and a + ret + +.asm_194b + scf + ret +; 194d + +Function194d: ; 194d + ld [hConnectionStripLength], a + call GetMapObject + call $40e7 + ret +; 1956 + + + +Function1956: ; 1956 + ld [hConnectionStripLength], a + call Function271e + ld a, [hConnectionStripLength] + call GetMapObject + ld a, $2 + ld hl, $40e7 + rst FarCall + ret +; 1967 + +Function1967: ; 1967 + ld [hConnectionStripLength], a + call GetMapObject + ld hl, $0000 + add hl, bc + ld a, [hl] + cp $ff + ret z + ld [hl], $ff + push af + call Function1985 + pop af + call Function1ae5 + callba Function4357 + ret +; 1985 + +Function1985: ; 1985 + ld hl, $d4cd + cp [hl] + jr z, .asm_1990 + ld hl, $d4ce + cp [hl] + ret nz + +.asm_1990 + callba Function581f + ld a, $ff + ld [$d4cd], a + ld [$d4ce], a + ret +; 199f + +Function199f: ; 199f + call Function1967 + call Function2712 + ret +; 19a6 + +Function19a6: ; 19a6 + push hl + call GetMapObject + ld d, b + ld e, c + ld a, $ff + ld [de], a + inc de + pop hl + ld bc, $000f + call CopyBytes + ret +; 19b8 + +Function19b8: ; 19b8 + call GetMapObject + ld hl, $0000 + add hl, bc + ld a, [hl] + push af + ld [hl], $ff + inc hl + ld bc, $000f + xor a + call ByteFill + pop af + cp $ff + ret z + cp $d + ret nc + ld b, a + ld a, [$d4cd] + cp b + jr nz, .asm_19de + ld a, $ff + ld [$d4cd], a + +.asm_19de + ld a, b + call Function1ae5 + callba Function4357 + ret +; 19e9 + + + +Function19e9: ; 19e9 + ld [$c2e2], a + ld a, [hROMBank] + ld [$c2e3], a + ld a, l + ld [$c2e4], a + ld a, h + ld [$c2e5], a + ld a, [$c2e2] + call Function18de + ret c + ld hl, $0003 + add hl, bc + ld [hl], $14 + ld hl, $0009 + add hl, bc + ld [hl], $0 + ld hl, VramState + set 7, [hl] + and a + ret +; 1a13 + + + +Function1a13: ; 1a13 + push bc + push de + ld hl, $d4d6 + ld de, $0028 + ld c, $d +.asm_1a1d + ld a, [hl] + and a + jr z, .asm_1a28 + add hl, de + dec c + jr nz, .asm_1a1d + xor a + jr .asm_1a2c + +.asm_1a28 + ld a, $d + sub c + scf + +.asm_1a2c + pop de + pop bc + ret +; 1a2f + + + +Function1a2f: ; 1a2f + ld hl, $0003 + add hl, bc + ld a, [hl] + cp $25 + jr c, .asm_1a39 + xor a + +.asm_1a39 + ld hl, Data4273 + ld e, a + ld d, 0 + add hl, de + add hl, de + add hl, de + add hl, de + add hl, de + add hl, de + ld a, [hl] + ret +; 1a47 + +Function1a47: ; 1a47 + push bc + push de + ld e, a + ld d, 0 + ld hl, Data4273 + 1 + add hl, de + add hl, de + add hl, de + add hl, de + add hl, de + add hl, de + ld a, BANK(Data4273) + call GetFarByte + add a + add a + and $c + pop de + pop bc + ret +; 1a61 + + +Function1a61: ; 1a61 + ld l, a + ld a, [hROMBank] + push af + ld a, BANK(Data4273) + rst Bankswitch + ld a, l + push bc + + call Function1a71 + + pop bc + pop af + rst Bankswitch + + ret +; 1a71 + +Function1a71: ; 1a71 + ld hl, $0003 + add hl, de + ld [hl], a + push de + ld e, a + ld d, 0 + ld hl, Data4273 + 1 + add hl, de + add hl, de + add hl, de + add hl, de + add hl, de + add hl, de + ld b, h + ld c, l + pop de + ld a, [bc] + inc bc + rlca + rlca + and $c + ld hl, $0008 + add hl, de + ld [hl], a + ld a, [bc] + inc bc + ld hl, $000b + add hl, de + ld [hl], a + ld a, [bc] + inc bc + ld hl, $0004 + add hl, de + ld [hl], a + ld a, [bc] + inc bc + ld hl, $0005 + add hl, de + ld [hl], a + ld a, [bc] + inc bc + ld hl, $0006 + add hl, de + ld [hl], a + ret +; 1aae + +Function1aae: ; 1aae + ld a, [hROMBank] + push af + ld a, [hli] + rst Bankswitch + + ld a, [hli] + ld d, [hl] + ld hl, $001b + add hl, bc + add [hl] + ld e, a + ld a, d + adc $0 + ld d, a + inc [hl] + ld a, [de] + ld h, a + pop af + rst Bankswitch + + ld a, h + ret +; 1ac6 + +Function1ac6: ; 1ac6 + ld hl, VramState + set 0, [hl] + ret +; 1acc + +Function1acc: ; 1acc + ld hl, VramState + res 0, [hl] + ret +; 1ad2 + + +Function1ad2: ; 1ad2 + ld a, [VramState] + bit 0, a + ret z + callba Function55e0 + callba Function5920 + ret +; 1ae5 + + +Function1ae5: ; 1ae5 + ld bc, $0028 + ld hl, $d4d6 + call AddNTimes + ld b, h + ld c, l + ret +; 1af1 + +Function1af1: ; 1af1 + ld hl, $0000 + add hl, bc + ld a, [hl] + and a + ret +; 1af8 + +Function1af8: ; 1af8 + push af + ld hl, $0008 + add hl, bc + ld a, [hl] + and $f3 + ld e, a + pop af + and $c + or e + ld [hl], a + ret +; 1b07 + + +GetSpriteDirection: ; 1b07 + ld hl, $0008 + add hl, bc + ld a, [hl] + and $c + ret +; 1b0f + diff --git a/common/menu.asm b/common/menu.asm new file mode 100644 index 000000000..c761a927c --- /dev/null +++ b/common/menu.asm @@ -0,0 +1,603 @@ +; Functions used in displaying and handling menus. + + +LoadMenuDataHeader: ; 0x1d35 + call Function1d3c + call Function1c00 + ret + +Function1d3c: ; 0x1d3c + ld de, $cf81 + ld bc, $0010 + call CopyBytes + ld a, [hROMBank] + ld [$cf8a], a + ret +; 0x1d4b + +Function1d4b: ; 1d4b + ld [$cf88], a + ret +; 1d4f + + +Function1d4f: ; 1d4f + push hl + call Function1d58 + pop hl + jp PrintText +; 1d57 + +Function1d57: ; 1d57 + ret +; 1d58 + +Function1d58: ; 1d58 + ld hl, MenuDataHeader_0x1d5f + call LoadMenuDataHeader + ret +; 1d5f + +MenuDataHeader_0x1d5f: ; 1d5f + db $40 ; tile backup + db 12, 0 ; start coords + db 17, 19 ; end coords + dw VTiles0 + db 0 ; default option +; 1d67 + +Function1d67: ; 1d67 + call Function1d4f + call Function1c17 + ret +; 1d6e + +Function1d6e: ; 1d6e + ld hl, MenuDataHeader_0x1d75 + call LoadMenuDataHeader + ret +; 1d75 + +MenuDataHeader_0x1d75: ; 1d75 + db $40 ; tile backup + db 0, 0 ; start coords + db 17, 19 ; end coords + dw $0000 + db 1 ; default option +; 1d7d + +Function1d7d: ; 1d7d + call Function1c07 + ret +; 1d81 + +Function1d81: ; 0x1d81 + xor a + ld [hBGMapMode], a + call Function1cbb + call Function1ad2 + call Function1c89 + call Function321c + call Function1c66 + ld a, [$cf91] + bit 7, a + jr z, .asm_1da7 ; 0x1d98 $d + call Function1c10 + call Function1bc9 + call Function1ff8 + bit 1, a + jr z, .asm_1da9 ; 0x1da5 $2 +.asm_1da7 + scf + ret +.asm_1da9 + and a + ret +; 0x1dab + +Function1dab: ; 1dab + call LoadMenuDataHeader + call Function1d81 + call Function1c17 + ld a, [$cfa9] + ret +; 1db8 + +Function1db8: ; 0x1db8 + push hl + push bc + push af + ld hl, $cf86 + ld a, [hli] + ld h, [hl] + ld l, a + inc hl + inc hl + pop af + call GetNthString + ld d, h + ld e, l + call CopyName1 + pop bc + pop hl + ret +; 0x1dcf + + +Function1dcf: ; 1dcf + ld bc, $0e07 + +Function1dd2: ; 1dd2 + jr Function1dd9 + +Function1dd4: ; 1dd4 + call LoadMenuDataHeader + jr Function1dfe + +Function1dd9: ; 1dd9 + push bc + ld hl, MenuDataHeader_0x1e1d + call Function1d3c + pop bc + ld a, b + cp $e + jr nz, .asm_1de9 + ld a, $e + ld b, a + +.asm_1de9 + ld a, b + ld [$cf83], a + add $5 + ld [$cf85], a + ld a, c + ld [$cf82], a + add $4 + ld [$cf84], a + call Function1c00 + +Function1dfe: ; 1dfe + call Function1d81 + push af + ld c, $f + call DelayFrames + call Function1c17 + pop af + jr c, .asm_1e16 + ld a, [$cfa9] + cp $2 + jr z, .asm_1e16 + and a + ret + +.asm_1e16 + ld a, $2 + ld [$cfa9], a + scf + ret +; 1e1d + +MenuDataHeader_0x1e1d: ; 1e1d + db $40 ; tile backup + db 5, 10 ; start coords + db 9, 15 ; end coords + dw MenuData2_0x1e25 + db 1 ; default option +; 1e25 + +MenuData2_0x1e25: ; 1e25 + db $c0 ; flags + db 2 + db "YES@" + db "NO@" +; 1e2e + +Function1e2e: ; 1e2e + call Function1e35 + call Function1c00 + ret +; 1e35 + +Function1e35: ; 1e35 + push de + call Function1d3c + pop de + ld a, [$cf83] + ld h, a + ld a, [$cf85] + sub h + ld h, a + ld a, d + ld [$cf83], a + add h + ld [$cf85], a + ld a, [$cf82] + ld l, a + ld a, [$cf84] + sub l + ld l, a + ld a, e + ld [$cf82], a + add l + ld [$cf84], a + ret +; 1e5d + +Function1e5d: ; 1e5d + call MenuFunc_1e7f + call MenuWriteText + call Function1eff + call Function1f23 + call Function1bdd + call Function1ff8 + ret +; 1e70 + +SetUpMenu: ; 1e70 + call MenuFunc_1e7f ; ??? + call MenuWriteText + call Function1eff ; set up selection pointer + ld hl, $cfa5 + set 7, [hl] + ret + +MenuFunc_1e7f: ; 0x1e7f + call Function1c66 + call Function1ebd + call Function1ea6 + call Function1cbb + ret + +MenuWriteText: ; 0x1e8c + xor a + ld [hBGMapMode], a + call Function1ebd ; sort out the text + call Function1eda ; actually write it + call Function2e31 + ld a, [hOAMUpdate] + push af + ld a, $1 + ld [hOAMUpdate], a + call Function321c + pop af + ld [hOAMUpdate], a + ret +; 0x1ea6 + +Function1ea6: ; 1ea6 + ld a, [$cf83] + ld c, a + ld a, [$cf85] + sub c + ld c, a + ld a, [$cf92] + add a + inc a + ld b, a + ld a, [$cf82] + add b + ld [$cf84], a + ret +; 1ebd + +Function1ebd: ; 1ebd + ld hl, $cf93 + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [$cf76] + and a + jr z, .asm_1ed3 + ld b, a + ld c, $ff +.asm_1ecc + ld a, [hli] + cp c + jr nz, .asm_1ecc + dec b + jr nz, .asm_1ecc + +.asm_1ed3 + ld d, h + ld e, l + ld a, [hl] + ld [$cf92], a + ret +; 1eda + +Function1eda: ; 1eda + call Function1cfd + ld bc, $002a + add hl, bc +.asm_1ee1 + inc de + ld a, [de] + cp $ff + ret z + ld [MenuSelection], a + push de + push hl + ld d, h + ld e, l + ld hl, $cf95 + call Function1efb + pop hl + ld de, $0028 + add hl, de + pop de + jr .asm_1ee1 +; 1efb + +Function1efb: ; 1efb + ld a, [hli] + ld h, [hl] + ld l, a + jp [hl] +; 1eff + +Function1eff: ; 1eff + call Function1c10 + ld hl, $cfa8 + ld a, [$cf91] + bit 3, a + jr z, .asm_1f0e + set 3, [hl] + +.asm_1f0e + ld a, [$cf91] + bit 2, a + jr z, .asm_1f19 + set 5, [hl] + set 4, [hl] + +.asm_1f19 + ret +; 1f1a + + +Function1f1a: ; 1f1a + call Function1bd3 + ld hl, $cfa8 + and [hl] + jr Function1f2a +; 1f23 + +Function1f23: ; 1f23 + xor a + ld [$cf73], a + call Function1bc9 +; 1f2a + +Function1f2a: ; 1f2a + bit 0, a + jr nz, .asm_1f52 + bit 1, a + jr nz, .asm_1f6d + bit 3, a + jr nz, .asm_1f6d + bit 4, a + jr nz, .asm_1f44 + bit 5, a + jr nz, .asm_1f4b + xor a + ld [$cf73], a + jr .asm_1f57 + +.asm_1f44 + ld a, $10 + ld [$cf73], a + jr .asm_1f57 + +.asm_1f4b + ld a, $20 + ld [$cf73], a + jr .asm_1f57 + +.asm_1f52 + ld a, $1 + ld [$cf73], a + +.asm_1f57 + call Function1ebd + ld a, [$cfa9] + ld l, a + ld h, $0 + add hl, de + ld a, [hl] + ld [MenuSelection], a + ld a, [$cfa9] + ld [$cf88], a + and a + ret + +.asm_1f6d + ld a, $2 + ld [$cf73], a + ld a, $ff + ld [MenuSelection], a + scf + ret +; 1f79 + +Function1f79: ; 1f79 + push de + ld hl, $cf97 + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [MenuSelection] + call GetNthString + ld d, h + ld e, l + pop hl + call PlaceString + ret +; 1f8d + +Function1f8d: ; 1f8d + push de + ld a, [MenuSelection] + call Function1fb1 + inc hl + inc hl + ld a, [hli] + ld d, [hl] + ld e, a + pop hl + call PlaceString + ret +; 1f9e + +Function1f9e: ; 1f9e + call Function1fb1 + inc hl + inc hl + ld a, [hli] + ld d, [hl] + ld e, a + ret +; 1fa7 + +Function1fa7: ; 1fa7 + ld a, [MenuSelection] + call Function1fb1 + ld a, [hli] + ld h, [hl] + ld l, a + jp [hl] +; 1fb1 + +Function1fb1: ; 1fb1 + ld e, a + ld d, $0 + ld hl, $cf97 + ld a, [hli] + ld h, [hl] + ld l, a + add hl, de + add hl, de + add hl, de + add hl, de + ret +; 1fbf + +Function1fbf: ; 1fbf + ld hl, $cf71 + call Function1ff0 + ld hl, $cf81 + call Function1ff0 + ld hl, $cf91 + call Function1ff0 + ld hl, $cfa1 + call Function1ff0 + ld a, [rSVBK] + push af + ld a, $7 + ld [rSVBK], a + xor a + ld hl, $dfff + ld [hld], a + ld [hld], a + ld a, l + ld [$cf71], a + ld a, h + ld [$cf72], a + pop af + ld [rSVBK], a + ret +; 1ff0 + +Function1ff0: ; 1ff0 + ld bc, $0010 + xor a + call ByteFill + ret +; 1ff8 + +Function1ff8: ; 1ff8 + push af + and $3 + jr z, .asm_2007 + ld hl, $cf81 + bit 3, [hl] + jr nz, .asm_2007 + call PlayClickSFX + +.asm_2007 + pop af + ret +; 2009 + + +PlayClickSFX: ; 2009 + push de + ld de, SFX_READ_TEXT_2 + call StartSFX + pop de + ret +; 0x2012 + +Function2012: ; 2012 + call Function1d4f + call Functiona46 + call Function1c07 + ret +; 201c + +Function201c: ; 201c + ld [hBuffer], a + ld a, [hROMBank] + push af + ld a, [hBuffer] + rst Bankswitch + + call PlaceString + pop af + rst Bankswitch + + ret +; 202a + +Function202a: ; 202a + ld a, [hROMBank] + ld [$cf94], a + ld a, $9 + ld hl, $400e + rst FarCall + ld a, [$cf88] + ret +; 2039 + +Function2039: ; 2039 + ld a, [hROMBank] + ld [$cf94], a + ld a, $9 + ld hl, $4022 + rst FarCall + ld a, [$cf88] + ret +; 2048 + +Function2048: ; 2048 + ld a, [hROMBank] + ld [$cf94], a + ld a, $9 + ld hl, $403c + rst FarCall + ld a, [$cf88] + ret +; 2057 + +Function2057: ; 2057 + ld a, [hROMBank] + push af + ld a, $21 + rst Bankswitch + + call $42db + pop af + rst Bankswitch + + ret +; 2063 + diff --git a/common/palettes.asm b/common/palettes.asm new file mode 100644 index 000000000..accaa96b5 --- /dev/null +++ b/common/palettes.asm @@ -0,0 +1,347 @@ +; Functions dealing with palettes. + + +UpdatePalsIfCGB: ; c2f +; update bgp data from BGPals +; update obp data from OBPals +; return carry if successful + +; check cgb + ld a, [hCGB] + and a + ret z + + +UpdateCGBPals: ; c33 +; return carry if successful +; any pals to update? + ld a, [hCGBPalUpdate] + and a + ret z + + +ForceUpdateCGBPals: ; c37 + + ld a, [rSVBK] + push af + ld a, 5 ; BANK(BGPals) + ld [rSVBK], a + + ld hl, BGPals ; 5:d080 + +; copy 8 pals to bgpd + ld a, %10000000 ; auto increment, index 0 + ld [rBGPI], a + ld c, rBGPD % $100 + ld b, 4 ; NUM_PALS / 2 +.bgp + rept $10 + ld a, [hli] + ld [$ff00+c], a + endr + + dec b + jr nz, .bgp + +; hl is now 5:d0c0 OBPals + +; copy 8 pals to obpd + ld a, %10000000 ; auto increment, index 0 + ld [rOBPI], a + ld c, rOBPD - rJOYP + ld b, 4 ; NUM_PALS / 2 +.obp + rept $10 + ld a, [hli] + ld [$ff00+c], a + endr + + dec b + jr nz, .obp + + pop af + ld [rSVBK], a + +; clear pal update queue + xor a + ld [hCGBPalUpdate], a + + scf + ret +; c9f + + +DmgToCgbBGPals: ; c9f +; exists to forego reinserting cgb-converted image data + +; input: a -> bgp + + ld [rBGP], a + push af + + ld a, [hCGB] + and a + jr z, .end + + push hl + push de + push bc + ld a, [rSVBK] + push af + + ld a, 5 + ld [rSVBK], a + +; copy & reorder bg pal buffer + ld hl, BGPals ; to + ld de, Unkn1Pals ; from +; order + ld a, [rBGP] + ld b, a +; all pals + ld c, 8 + call CopyPals +; request pal update + ld a, 1 + ld [hCGBPalUpdate], a + + pop af + ld [rSVBK], a + pop bc + pop de + pop hl +.end + pop af + ret +; ccb + + +DmgToCgbObjPals: ; ccb +; exists to forego reinserting cgb-converted image data + +; input: d -> obp1 +; e -> obp2 + + ld a, e + ld [rOBP0], a + ld a, d + ld [rOBP1], a + + ld a, [hCGB] + and a + ret z + + push hl + push de + push bc + ld a, [rSVBK] + push af + + ld a, 5 + ld [rSVBK], a + +; copy & reorder obj pal buffer + ld hl, OBPals ; to + ld de, Unkn2Pals ; from +; order + ld a, [rOBP0] + ld b, a +; all pals + ld c, 8 + call CopyPals +; request pal update + ld a, 1 + ld [hCGBPalUpdate], a + + pop af + ld [rSVBK], a + pop bc + pop de + pop hl + ret +; cf8 + + +Functioncf8: ; cf8 + ld [rOBP0], a + push af + ld a, [hCGB] + and a + jr z, .asm_d22 + push hl + push de + push bc + ld a, [rSVBK] + push af + ld a, $5 + ld [rSVBK], a + ld hl, $d0c0 + ld de, MartPointer + ld a, [rOBP0] + ld b, a + ld c, $1 + call CopyPals + ld a, $1 + ld [hCGBPalUpdate], a + pop af + ld [rSVBK], a + pop bc + pop de + pop hl + +.asm_d22 + pop af + ret +; d24 + +Functiond24: ; d24 + ld [rOBP1], a + push af + ld a, [hCGB] + and a + jr z, .asm_d4e + push hl + push de + push bc + ld a, [rSVBK] + push af + ld a, $5 + ld [rSVBK], a + ld hl, $d0c8 + ld de, $d048 + ld a, [rOBP1] + ld b, a + ld c, $1 + call CopyPals + ld a, $1 + ld [hCGBPalUpdate], a + pop af + ld [rSVBK], a + pop bc + pop de + pop hl + +.asm_d4e + pop af + ret +; d50 + + + +CopyPals: ; d50 +; copy c palettes in order b from de to hl + + push bc + ld c, 4 ; NUM_PAL_COLORS +.loop + push de + push hl + +; get pal color + ld a, b + and %11 ; color +; 2 bytes per color + add a + ld l, a + ld h, 0 + add hl, de + ld e, [hl] + inc hl + ld d, [hl] + +; dest + pop hl +; write color + ld [hl], e + inc hl + ld [hl], d + inc hl +; next pal color + srl b + srl b +; source + pop de +; done pal? + dec c + jr nz, .loop + +; de += 8 (next pal) + ld a, 8 ; NUM_PAL_COLORS * 2 ; bytes per pal + add e + jr nc, .ok + inc d +.ok + ld e, a + +; how many more pals? + pop bc + dec c + jr nz, CopyPals + ret +; d79 + + +Functiond79: ; d79 + ld a, [hCGB] + and a + ret z + ld a, 1 + ld [rVBK], a + ld hl, VTiles0 + ld bc, $2000 + xor a + call ByteFill + ld a, 0 + ld [rVBK], a + ret +; d90 + + +Functiond90: ; d90 + ret +; d91 + + +Functiond91: ; d91 + ld a, [hCGB] + and a + ret z + ld a, [rSVBK] + push af + ld a, 5 ; BANK(BGPals) + ld [rSVBK], a + ld hl, BGPals + ld bc, $40 + $10 + xor a + call ByteFill + pop af + ld [rSVBK], a + ld a, 1 + ld [hCGBPalUpdate], a + call DelayFrame + ret +; db1 + + +Functiondb1: ; db1 + ld a, [hROMBank] + push af + ld a, BANK(Function4c000) + rst Bankswitch + call Function4c000 + pop af + rst Bankswitch + ret +; dbd + +Functiondbd: ; dbd + ld a, [hROMBank] + push af + ld a, BANK(Function4c03f) + rst Bankswitch + call Function4c03f + pop af + rst Bankswitch + ret +; dc9 + diff --git a/common/rtc.asm b/common/rtc.asm new file mode 100644 index 000000000..91428d03b --- /dev/null +++ b/common/rtc.asm @@ -0,0 +1,25 @@ +RTC: ; 46f +; update time and time-sensitive palettes + +; rtc enabled? + ld a, [$c2ce] + cp 0 + ret z + + call UpdateTime + +; obj update on? + ld a, [VramState] + bit 0, a ; obj update + ret z + +TimeOfDayPals: ; 47e + callab _TimeOfDayPals + ret +; 485 + +UpdateTimePals: ; 485 + callab _UpdateTimePals + ret +; 48c + diff --git a/common/serial.asm b/common/serial.asm new file mode 100644 index 000000000..fca9d82c3 --- /dev/null +++ b/common/serial.asm @@ -0,0 +1,408 @@ +Serial: ; 6ef +; The serial interrupt. + + push af + push bc + push de + push hl + + ld a, [$ffc9] + and a + jr nz, .asm_71c + + ld a, [$c2d4] + bit 0, a + jr nz, .asm_721 + + ld a, [$ffcb] + inc a + jr z, .asm_726 + + ld a, [rSB] + ld [hSerialReceive], a + + ld a, [hSerialSend] + ld [rSB], a + + ld a, [$ffcb] + cp $2 + jr z, .asm_752 + + ld a, 0 << rSC_ON + ld [rSC], a + ld a, 1 << rSC_ON + ld [rSC], a + jr .asm_752 + +.asm_71c + call Function3e80 + jr .asm_75a + +.asm_721 + call Function2057 + jr .asm_75a + +.asm_726 + ld a, [rSB] + cp $1 + jr z, .asm_730 + cp $2 + jr nz, .asm_752 + +.asm_730 + ld [hSerialReceive], a + ld [$ffcb], a + cp $2 + jr z, .asm_74f + + xor a + ld [rSB], a + ld a, $3 + ld [rDIV], a + +.asm_73f + ld a, [rDIV] + bit 7, a + jr nz, .asm_73f + + ld a, 0 << rSC_ON + ld [rSC], a + ld a, 1 << rSC_ON + ld [rSC], a + jr .asm_752 + +.asm_74f + xor a + ld [rSB], a + +.asm_752 + ld a, $1 + ld [$ffca], a + ld a, $fe + ld [hSerialSend], a + +.asm_75a + pop hl + pop de + pop bc + pop af + reti +; 75f + +Function75f: ; 75f + ld a, $1 + ld [$ffcc], a +.asm_763 + ld a, [hl] + ld [hSerialSend], a + call Function78a + push bc + ld b, a + inc hl + ld a, $30 +.asm_76e + dec a + jr nz, .asm_76e + ld a, [$ffcc] + and a + ld a, b + pop bc + jr z, .asm_782 + dec hl + cp $fd + jr nz, .asm_763 + xor a + ld [$ffcc], a + jr .asm_763 + +.asm_782 + ld [de], a + inc de + dec bc + ld a, b + or c + jr nz, .asm_763 + ret +; 78a + +Function78a: ; 78a + xor a + ld [$ffca], a + ld a, [$ffcb] + cp $2 + jr nz, .asm_79b + ld a, $1 + ld [rSC], a + ld a, $81 + ld [rSC], a + +.asm_79b + ld a, [$ffca] + and a + jr nz, .asm_7e5 + ld a, [$ffcb] + cp $1 + jr nz, .asm_7c0 + call Function82b + jr z, .asm_7c0 + call .asm_825 + push hl + ld hl, $cf5c + inc [hl] + jr nz, .asm_7b7 + dec hl + inc [hl] + +.asm_7b7 + pop hl + call Function82b + jr nz, .asm_79b + jp Function833 + +.asm_7c0 + ld a, [rIE] + and $f + cp $8 + jr nz, .asm_79b + ld a, [$cf5d] + dec a + ld [$cf5d], a + jr nz, .asm_79b + ld a, [$cf5e] + dec a + ld [$cf5e], a + jr nz, .asm_79b + ld a, [$ffcb] + cp $1 + jr z, .asm_7e5 + ld a, $ff +.asm_7e2 + dec a + jr nz, .asm_7e2 + +.asm_7e5 + xor a + ld [$ffca], a + ld a, [rIE] + and $f + sub $8 + jr nz, .asm_7f8 + ld [$cf5d], a + ld a, $50 + ld [$cf5e], a + +.asm_7f8 + ld a, [hSerialReceive] + cp $fe + ret nz + call Function82b + jr z, .asm_813 + push hl + ld hl, $cf5c + ld a, [hl] + dec a + ld [hld], a + inc a + jr nz, .asm_80d + dec [hl] + +.asm_80d + pop hl + call Function82b + jr z, Function833 + +.asm_813 + ld a, [rIE] + and $f + cp $8 + ld a, $fe + ret z + ld a, [hl] + ld [hSerialSend], a + call DelayFrame + jp Function78a + +.asm_825 + ld a, $f +.asm_827 + dec a + jr nz, .asm_827 + ret +; 82b + +Function82b: ; 82b + push hl + ld hl, $cf5b + ld a, [hli] + or [hl] + pop hl + ret +; 833 + +Function833: ; 833 + dec a + ld [$cf5b], a + ld [$cf5c], a + ret +; 83b + +Function83b: ; 83b + ld hl, $cf56 + ld de, $cf51 + ld c, $2 + ld a, $1 + ld [$ffcc], a +.asm_847 + call DelayFrame + ld a, [hl] + ld [hSerialSend], a + call Function78a + ld b, a + inc hl + ld a, [$ffcc] + and a + ld a, $0 + ld [$ffcc], a + jr nz, .asm_847 + ld a, b + ld [de], a + inc de + dec c + jr nz, .asm_847 + ret +; 862 + +Function862: ; 862 + call Function309d + callab Function4000 + call Function87d + jp Function30b4 +; 871 + + +Function871: ; 871 + call Function309d + callab Function4000 + jp Function87d +; 87d + + + +Function87d: ; 87d + ld a, $ff + ld [$cf52], a +.asm_882 + call Function8c1 + call DelayFrame + call Function82b + jr z, .asm_89e + push hl + ld hl, $cf5c + dec [hl] + jr nz, .asm_89d + dec hl + dec [hl] + jr nz, .asm_89d + pop hl + xor a + jp Function833 + +.asm_89d + pop hl + +.asm_89e + ld a, [$cf52] + inc a + jr z, .asm_882 + ld b, $a +.asm_8a6 + call DelayFrame + call Function8c1 + dec b + jr nz, .asm_8a6 + ld b, $a +.asm_8b1 + call DelayFrame + call Function908 + dec b + jr nz, .asm_8b1 + ld a, [$cf52] + ld [$cf51], a + ret +; 8c1 + +Function8c1: ; 8c1 + push bc + ld b, $60 + ld a, [InLinkBattle] + cp $1 + jr z, .asm_8d7 + ld b, $60 + jr c, .asm_8d7 + cp $2 + ld b, $70 + jr z, .asm_8d7 + ld b, $80 + +.asm_8d7 + call Function8f3 + ld a, [$cf56] + add b + ld [hSerialSend], a + ld a, [$ffcb] + cp $2 + jr nz, .asm_8ee + ld a, $1 + ld [rSC], a + ld a, $81 + ld [rSC], a + +.asm_8ee + call Function8f3 + pop bc + ret +; 8f3 + +Function8f3: ; 8f3 + ld a, [hSerialReceive] + ld [$cf51], a + and $f0 + cp b + ret nz + xor a + ld [hSerialReceive], a + ld a, [$cf51] + and $f + ld [$cf52], a + ret +; 908 + +Function908: ; 908 + xor a + ld [hSerialSend], a + ld a, [$ffcb] + cp $2 + ret nz + ld a, $1 + ld [rSC], a + ld a, $81 + ld [rSC], a + ret +; 919 + +Function919: ; 919 + ld a, [InLinkBattle] + and a + ret nz + ld a, $2 + ld [rSB], a + xor a + ld [hSerialReceive], a + ld a, $0 + ld [rSC], a + ld a, $80 + ld [rSC], a + ret +; 92e + + diff --git a/common/sine.asm b/common/sine.asm new file mode 100644 index 000000000..09d06ca89 --- /dev/null +++ b/common/sine.asm @@ -0,0 +1,22 @@ +Cosine: ; 1b0f +; Return d * cos(a) in hl + add $10 ; 90 degrees + +Sine: ; 1b11 +; Return d * sin(a) in hl +; a is a signed 6-bit value. + + ld e, a + + ld a, [hROMBank] + push af + ld a, BANK(_Sine) + rst Bankswitch + + call _Sine + + pop af + rst Bankswitch + ret +; 1b1e + diff --git a/common/string.asm b/common/string.asm new file mode 100644 index 000000000..a871b4d2a --- /dev/null +++ b/common/string.asm @@ -0,0 +1,39 @@ +InitString: ; 2ef6 +; Init a string of length c. + push hl + jr _InitString +; 2ef9 + +InitName: ; 2ef9 +; Intended for names, so this function is limited to ten characters. + push hl + ld c, 10 +; 2efc + +_InitString: ; 2efc +; if the string pointed to by hl is empty (defined as "zero or more spaces +; followed by a null"), then initialize it to the string pointed to by de. + push bc +.loop + ld a, [hli] + cp "@" + jr z, .blank + cp " " + jr nz, .notblank + dec c + jr nz, .loop +.blank + pop bc + ld l, e + ld h, d + pop de + ld b, 0 + inc c + call CopyBytes + ret +.notblank + pop bc + pop hl + ret +; 2f17 + diff --git a/common/text.asm b/common/text.asm new file mode 100644 index 000000000..e010de6d4 --- /dev/null +++ b/common/text.asm @@ -0,0 +1,1230 @@ +ClearBox: ; fb6 +; Fill a c*b box at hl with blank tiles. + + ld a, " " +.y + push bc + push hl +.x + ld [hli], a + dec c + jr nz, .x + pop hl + ld bc, 20 ; screen width + add hl, bc + pop bc + dec b + jr nz, .y + ret +; fc8 + + +ClearTileMap: ; fc8 +; Fill TileMap with blank tiles. + + ld hl, TileMap + ld a, " " + ld bc, 360 ; screen dimensions 20*18 + call ByteFill + +; We aren't done if the LCD is on. + ld a, [rLCDC] + bit 7, a + ret z + jp WaitBGMap +; fdb + + +Functionfdb: ; fdb + ld a, $7 + ld hl, AttrMap + ld bc, $0168 + call ByteFill + jr ClearTileMap +; fe8 + + + +TextBox: ; fe8 +; Draw a text box width c height b at hl +; Dimensions do not include the border. + push bc + push hl + call TextBoxBorder + pop hl + pop bc + jr TextBoxPalette +; ff1 + + +TextBoxBorder: ; ff1 + +; Top + push hl + ld a, "┌" + ld [hli], a + inc a ; "─" + call NPlaceChar + inc a ; "┐" + ld [hl], a + +; Middle + pop hl + ld de, 20 ; screen width + add hl, de +.PlaceRow + push hl + ld a, "│" + ld [hli], a + ld a, " " + call NPlaceChar + ld [hl], "│" + pop hl + ld de, 20 ; screen width + add hl, de + dec b + jr nz, .PlaceRow + +; Bottom + ld a, "└" + ld [hli], a + ld a, "─" + call NPlaceChar + ld [hl], "┘" + + ret +; 101e + + +NPlaceChar: ; 101e +; Place char a c times + ld d,c +.loop + ld [hli],a + dec d + jr nz, .loop + ret +; 1024 + + +TextBoxPalette: ; 1024 +; Fill text box width c height b at hl with pal 7 + ld de, AttrMap - TileMap + add hl, de + inc b + inc b + inc c + inc c + ld a, 7 ; pal +.gotoy + push bc + push hl +.gotox + ld [hli], a + dec c + jr nz, .gotox + pop hl + ld de, 20 ; screen width + add hl, de + pop bc + dec b + jr nz, .gotoy + ret +; 103e + + +SpeechTextBox: ; 103e +; Standard textbox. + hlcoord 0, 12 + ld b, 4 ; height + ld c, 18 ; screen width - 2 (border) + jp TextBox +; 1048 + +UnknownText_0x1048: ; 1048 + db $0, "ゲームフりーク!", $57 +; 1052 + +Function1052: ; 1052 + ld hl, .text_1056 + ret +.text_1056 + db "@" +; 1057 + + +PrintText: ; 1057 + call Function106c +Function105a: ; 105a + push hl + hlcoord 1, 14 + ld bc, 18 + 3<<8 + call ClearBox + pop hl + +PrintTextBoxText: ; 1065 + bccoord 1, 14 + call Function13e5 + ret +; 106c + + +Function106c: ; 106c + push hl + call SpeechTextBox + call Function1ad2 + call Function321c + pop hl + ret +; 1078 + + + +PlaceString: ; 1078 + push hl + +PlaceNextChar: ; 1079 + ld a, [de] + cp "@" + jr nz, CheckDict + ld b, h + ld c, l + pop hl + ret + pop de + +NextChar: ; 1083 + inc de + jp PlaceNextChar + +CheckDict: ; 1087 + cp $15 + jp z, Function117b + cp $4f + jp z, Char4F + cp $4e + jp z, Function12a7 + cp $16 + jp z, Function12b9 + and a + jp z, Function1383 + cp $4c + jp z, $1337 + cp $4b + jp z, Char4B + cp $51 ; Player name + jp z, Function12f2 + cp $49 + jp z, Function1186 + cp $52 ; Mother name + jp z, Function118d + cp $53 + jp z, Function1194 + cp $35 + jp z, Function11e8 + cp $36 + jp z, Function11ef + cp $37 + jp z, Function11f6 + cp $38 + jp z, Function119b + cp $39 + jp z, Function11a2 + cp $54 + jp z, Function11c5 + cp $5b + jp z, Function11b7 + cp $5e + jp z, Function11be + cp $5c + jp z, Function11b0 + cp $5d + jp z, Function11a9 + cp $23 + jp z, Function11cc + cp $22 + jp z, Function12b0 + cp $55 + jp z, Char55 + cp $56 + jp z, Function11d3 + cp $57 + jp z, $137c + cp $58 + jp z, Function135a + cp $4a + jp z, Function11da + cp $24 + jp z, Function11e1 + cp $25 + jp z, NextChar + cp $1f + jr nz, .asm_1122 + ld a, $7f +.asm_1122 + cp $5f + jp z, Char5F + cp $59 + jp z, Function11fd + cp $5a + jp z, Char5D + cp $3f + jp z, $121b + cp $14 + jp z, $1252 + cp $e4 + jr z, .asm_1174 ; 0x113d $35 + cp $e5 + jr z, .asm_1174 ; 0x1141 $31 + jr .asm_114c ; 0x1143 $7 + ld b, a + call Function13c6 + jp NextChar +.asm_114c + cp $60 + jr nc, .asm_1174 ; 0x114e $24 + cp $40 + jr nc, .asm_1165 ; 0x1152 $11 + cp $20 + jr nc, .asm_115c ; 0x1156 $4 + add $80 + jr .asm_115e ; 0x115a $2 +.asm_115c + add $90 +.asm_115e + ld b, $e5 + call Function13c6 + jr .asm_1174 ; 0x1163 $f +.asm_1165 + cp $44 + jr nc, .asm_116d ; 0x1167 $4 + add $59 + jr .asm_116f ; 0x116b $2 +.asm_116d + add $86 +.asm_116f + ld b, $e4 + call Function13c6 +.asm_1174 + ld [hli], a + call PrintLetterDelay + jp NextChar +; 0x117b + + +Function117b: ; 117b + ld c, l + ld b, h + ld a, $5f + ld hl, $7036 + rst FarCall + jp PlaceNextChar +; 1186 + +Function1186: ; 1186 + push de + ld de, MomsName + jp $126a +; 118d + +Function118d: ; 118d + push de + ld de, PlayerName + jp $126a +; 1194 + +Function1194: ; 1194 + push de + ld de, RivalName + jp $126a +; 119b + +Function119b: ; 119b + push de + ld de, RedsName + jp $126a +; 11a2 + +Function11a2: ; 11a2 + push de + ld de, GreensName + jp $126a +; 11a9 + +Function11a9: ; 11a9 + push de + ld de, Char5DText + jp $126a +; 11b0 + +Function11b0: ; 11b0 + push de + ld de, Char5CText + jp $126a +; 11b7 + +Function11b7: ; 11b7 + push de + ld de, Char5BText + jp $126a +; 11be + +Function11be: ; 11be + push de + ld de, Char5EText + jp $126a +; 11c5 + +Function11c5: ; 11c5 + push de + ld de, Char54Text + jp $126a +; 11cc + +Function11cc: ; 11cc + push de + ld de, Char23Text + jp $126a +; 11d3 + +Function11d3: ; 11d3 + push de + ld de, $1292 + jp $126a +; 11da + +Function11da: ; 11da + push de + ld de, Char4AText + jp $126a +; 11e1 + +Function11e1: ; 11e1 + push de + ld de, Char24Text + jp $126a +; 11e8 + +Function11e8: ; 11e8 + push de + ld de, Char37Text + jp $126a +; 11ef + +Function11ef: ; 11ef + push de + ld de, Char37Text + jp $126a +; 11f6 + +Function11f6: ; 11f6 + push de + ld de, Char37Text + jp $126a +; 11fd + + +Function11fd: ; 11fd + ld a, [hBattleTurn] + xor $1 + jr Function1205 +; 1203 + +Char5D: ; 1203 + ld a, [hBattleTurn] +; 1205 + +Function1205: ; 1205 + push de + and a + jr nz, .asm_120e ; 0x1207 $5 + ld de, BattleMonNick + jr .asm_126a ; 0x120c $5c +.asm_120e + ld de, Char5AText ; Enemy + call PlaceString + ld h, b + ld l, c + ld de, EnemyMonNick + jr .asm_126a ; 0x1219 $4f + push de + ld a, [InLinkBattle] + and a + jr nz, .linkbattle + ld a, [TrainerClass] + cp $9 + jr z, .asm_1248 ; 0x1227 $1f + cp $2a + jr z, .asm_1248 ; 0x122b $1b + ld de, $c656 + call PlaceString + ld h, b + ld l, c + ld de, String12a2 + call PlaceString + push bc + ld hl, $5939 + ld a, $e + rst FarCall + pop hl + ld de, StringBuffer1 + jr .asm_126a ; 0x1246 $22 +.asm_1248 + ld de, RivalName + jr .asm_126a ; 0x124b $1d +.linkbattle + ld de, $c656 + jr .asm_126a ; 0x1250 $18 + push de + ld de, PlayerName + call PlaceString + ld h, b + ld l, c + ld a, [PlayerGender] + bit 0, a + ld de, String12a5 + jr z, .asm_126a ; 0x1263 $5 + ld de, String12a6 + jr .asm_126a ; 0x1268 $0 +.asm_126a + call PlaceString + ld h, b + ld l, c + pop de + jp NextChar +; 0x1273 + +Char5CText: ; 1273 + db "TM@" +Char5DText: ; 1276 + db "TRAINER@" +Char5BText: ; 127e + db "PC@" +Char5EText: ; 1281 + db "ROCKET@" +Char54Text: ; 1288 + db "POKé@" +Char23Text: ; 128d + db "こうげき@" +Char56Text:; 1292 + db "……@" +Char5AText: ; 1295 + db "Enemy @" +Char4AText: ; 129c + db $e1, $e2, "@" ; PK MN +Char24Text: ; 129f + db $70, $71, "@" ; PO KE +String12a2: ; 12a2 + db " @" +Char35Text: +Char36Text: +Char37Text: ; 12a4 + db "@" +String12a5: ; 12a5 + db "@" +String12a6: ; 12a6 + db "@" +; 12a7 + +Function12a7: ; 12a7 + pop hl + ld bc, $0028 + add hl, bc + push hl + jp NextChar +; 12b0 + +Function12b0: ; 12b0 + pop hl + ld bc, $0014 + add hl, bc + push hl + jp NextChar +; 12b9 + +Function12b9: ; 12b9 + pop hl + push de + ld bc, $3b60 + add hl, bc + ld de, $ffec + ld c, $1 +.asm_12c4 + ld a, h + and a + jr nz, .asm_12cd + ld a, l + cp $14 + jr c, .asm_12d1 + +.asm_12cd + add hl, de + inc c + jr .asm_12c4 + +.asm_12d1 + ld hl, TileMap + ld de, $0014 + ld a, c +.asm_12d8 + and a + jr z, .asm_12df + add hl, de + dec a + jr .asm_12d8 + +.asm_12df + pop de + inc de + ld a, [de] + ld c, a + ld b, $0 + add hl, bc + push hl + jp NextChar +; 12ea + + +Char4F: ; 12ea + pop hl + hlcoord 1, 16 + push hl + jp NextChar +; 0x12f2 + +Function12f2: ; 12f2 + push de + ld a, [InLinkBattle] + cp $3 + jr z, .asm_1301 + cp $4 + jr z, .asm_1301 + call Function13c7 + +.asm_1301 + call Function13b6 + call Functionaaf + ld hl, $c5b9 + ld bc, $0312 + call ClearBox + call Function13cd + ld c, $14 + call DelayFrames + ld hl, $c5b9 + pop de + jp NextChar +; 131f + + +Char4B: ; 131f + ld a, [InLinkBattle] + or a + jr nz, .asm_1328 + call Function13c7 + +.asm_1328 + call Function13b6 + + push de + call Functionaaf + pop de + + ld a, [InLinkBattle] + or a + call z, Function13cd + + push de + call Function138c + call Function138c + hlcoord 1, 16 + pop de + jp NextChar +; 1345 + + +Char55: ; 1345 + push de + ld de, Text_1354 + ld b, h + ld c, l + call PlaceString + ld h, b + ld l, c + pop de + jp NextChar +; 1354 + +Text_1354: ; 1354 + db $4b, "@" +; 1356 + + +Char5F: ; 1356 +; ends a Pokédex entry + ld [hl], "." + pop hl + ret +; 135a + +Function135a: ; 135a + ld a, [InLinkBattle] + cp $3 + jr z, .asm_1368 + cp $4 + jr z, .asm_1368 + call Function13c7 + +.asm_1368 + call Function13b6 + call Functionaaf + ld a, [InLinkBattle] + cp $3 + jr z, .asm_137c + cp $4 + jr z, .asm_137c + call Function13cd + +.asm_137c + pop hl + ld de, .string_1382 + dec de + ret + +.string_1382 + db "@" +; 1383 + +Function1383: ; 1383 + ld a, $e6 + ld [hli], a + call PrintLetterDelay + jp NextChar +; 138c + +Function138c: ; 138c + ld hl, $c5b9 + ld de, $c5a5 + ld a, $3 +.asm_1394 + push af + ld c, $12 +.asm_1397 + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .asm_1397 + inc de + inc de + inc hl + inc hl + pop af + dec a + jr nz, .asm_1394 + ld hl, $c5e1 + ld a, $7f + ld bc, $0012 + call ByteFill + ld c, $5 + call DelayFrames + ret +; 13b6 + +Function13b6: ; 13b6 + push bc + ld a, [hOAMUpdate] + push af + ld a, $1 + ld [hOAMUpdate], a + call WaitBGMap + pop af + ld [hOAMUpdate], a + pop bc + ret +; 13c6 + +Function13c6: ; 13c6 + ret +; 13c7 + +Function13c7: ; 13c7 + ld a, $ee + ld [$c606], a + ret +; 13cd + +Function13cd: ; 13cd + ld a, [$c605] + ld [$c606], a + ret +; 13d4 + +Function13d4: ; 13d4 + ld b, a + ld a, [hROMBank] + push af + ld a, b + rst Bankswitch + + call PlaceString + pop af + rst Bankswitch + + ret +; 13e0 + +Function13e0: ; 13e0 + ld hl, $13e4 + ret + +.string_13e4 + db "@" +; 13e5 + + +Function13e5: ; 13e5 + ld a, [$cfcf] + push af + set 1, a + ld [$cfcf], a + call Function13f6 + pop af + ld [$cfcf], a + ret +; 13f6 + +Function13f6: ; 13f6 +.asm_13f6 + ld a, [hli] + cp "@" + ret z + call Function13ff + jr .asm_13f6 +; 13ff + +Function13ff: ; 13ff + push hl + push bc + ld c, a + ld b, 0 + ld hl, TextCommands + add hl, bc + add hl, bc + ld e, [hl] + inc hl + ld d, [hl] + pop bc + pop hl + +; jp de + push de + ret +; 1410 + +TextCommands: ; 1410 + dw Text_00 + dw Text_01 + dw Text_02 + dw Text_03 + dw Text_04 + dw Text_05 + dw Text_06 + dw Text_07 + dw Text_08 + dw Text_09 + dw Text_0A + dw Text_PlaySound ; $0b + dw Text_0C + dw Text_0D + dw Text_PlaySound ; $0e + dw Text_PlaySound ; $0f + dw Text_PlaySound ; $10 + dw Text_PlaySound ; $11 + dw Text_PlaySound ; $12 + dw Text_PlaySound ; $13 + dw Text_14 + dw Text_15 + dw Text_16 +; 143e + +Text_00: ; 143e +; TX +; write text until "@" +; [$00]["...@"] + + ld d, h + ld e, l + ld h, b + ld l, c + call PlaceString + ld h, d + ld l, e + inc hl + ret +; 1449 + +Text_01: ; 1449 +; TX_RAM +; write text from a ram address +; little endian +; [$01][addr] + + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + push hl + ld h, b + ld l, c + call PlaceString + pop hl + ret +; 1455 + +Text_16: ; 1455 +; TX_FAR +; write text from a different bank +; little endian +; [$16][addr][bank] + + ld a, [hROMBank] + push af + + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + ld a, [hli] + + ld [hROMBank], a + ld [MBC3RomBank], a + + push hl + ld h, d + ld l, e + call Function13f6 + pop hl + + pop af + ld [hROMBank], a + ld [MBC3RomBank], a + ret +; 1470 + +Text_02: ; 1470 +; TX_NUM +; write bcdnumber from address, typically ram +; little endian +; [$02][addr][flags] +; flags: see PrintBCDNumber + + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + ld a, [hli] + push hl + ld h, b + ld l, c + ld c, a + call PrintBCDNumber + ld b, h + ld c, l + pop hl + ret +; 1480 + +Text_03: ; 1480 +; TX_MOVE +; move to a new tile +; little endian +; [$03][tileaddr] + + ld a, [hli] + ld [$d0e6], a + ld c, a + ld a, [hli] + ld [$d0e7], a + ld b, a + ret +; 148b + +Text_04: ; 148b +; TX_BOX +; draw a box +; little endian +; [$04][tileaddr][height][width] + + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + ld a, [hli] + ld b, a + ld a, [hli] + ld c, a + push hl + ld h, d + ld l, e + call TextBox + pop hl + ret +; 149b + +Text_05: ; 149b +; TX_LOW +; write text at (1,16) +; [$05] + + bccoord 1, 16 + ret +; 149f + +Text_06:: ; 149f +; TX_WAITBUTTON +; wait for button press +; show arrow +; [06] + + ld a, [InLinkBattle] + cp $3 + jp z, Text_0D + cp $4 + jp z, Text_0D + push hl + call Function13c7 + push bc + call Functionaaf + pop bc + call Function13cd + pop hl + ret +; 14ba + +Text_07: ; 14ba + push hl + call Function13cd + call Function138c + call Function138c + pop hl + bccoord 1, 16 + ret +; 14c9 + +Text_08: ; 14c9 +; TX_ASM + +; rom only? + bit 7, h + jr nz, .asm_14ce + jp [hl] + +.asm_14ce + ld a, "@" + ld [hl], a + ret +; 14d2 + +Text_09: ; 14d2 + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + ld a, [hli] + push hl + ld h, b + ld l, c + ld b, a + and $f + ld c, a + ld a, b + and $f0 + swap a + set 6, a + ld b, a + call PrintNum + ld b, h + ld c, l + pop hl + ret +; 14ed + +Text_0A: ; 14ed + push hl + push bc + call GetJoypadPublic + ld a, [hJoyDown] + and A_BUTTON | B_BUTTON + jr nz, .asm_14fd + ld c, 30 + call DelayFrames + +.asm_14fd + pop bc + pop hl + ret +; 1500 + +Text_PlaySound:: ; 1500 +; chars: +; $0b, $0e, $0f, $10, $11, $12, $13 +; see TextSFX + + push bc + dec hl + ld a, [hli] + ld b, a + push hl + ld hl, TextSFX +.asm_1508 + ld a, [hli] + cp $ff + jr z, .asm_151f + cp b + jr z, .asm_1514 + inc hl + inc hl + jr .asm_1508 + +.asm_1514 + push de + ld e, [hl] + inc hl + ld d, [hl] + call StartSFX + call WaitSFX + pop de + +.asm_151f + pop hl + pop bc + ret +; 1522 + +Function1522: ; 1522 + push de + ld e, [hl] + inc hl + ld d, [hl] + call Function37ce + pop de + pop hl + pop bc + ret +; 152d + +TextSFX: ; 152d + dbw $0b, SFX_DEX_FANFARE_50_79 + dbw $12, SFX_FANFARE + dbw $0e, SFX_DEX_FANFARE_20_49 + dbw $0f, SFX_ITEM + dbw $10, SFX_CAUGHT_MON + dbw $11, SFX_DEX_FANFARE_80_109 + dbw $13, SFX_SLOT_MACHINE_START + db $ff ; end +; 1543 + +Text_0C: ; 1543 + ld a, [hli] + ld d, a + push hl + ld h, b + ld l, c +.asm_1548 + push de + ld a, "…" + ld [hli], a + call GetJoypadPublic + ld a, [hJoyDown] + and A_BUTTON | B_BUTTON + jr nz, .asm_155a + ld c, 10 + call DelayFrames +.asm_155a + pop de + dec d + jr nz, .asm_1548 + ld b, h + ld c, l + pop hl + ret +; 1562 + +Text_0D: ; 1562 +; wait for key down +; display arrow + push hl + push bc + call Functionaaf + pop bc + pop hl + ret +; 156a + +Text_14: ; 156a +; TX_PREDEF +; [$14][id] + + ld a, [hli] + push hl + ld e, a + ld d, 0 + ld hl, $4000 + add hl, de + add hl, de + ld a, $9 + call GetFarHalfword + ld d, h + ld e, l + ld h, b + ld l, c + call PlaceString + pop hl + ret +; 1582 + +Text_15: ; 1582 +; TX_DAY + + call GetWeekday + push hl + push bc + ld c, a + ld b, 0 + ld hl, .Days + add hl, bc + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld d, h + ld e, l + pop hl + call PlaceString + ld h, b + ld l, c + ld de, .Day + call PlaceString + pop hl + ret +; 15a2 + +.Days ; 15a2 + dw .Sun + dw .Mon + dw .Tues + dw .Wednes + dw .Thurs + dw .Fri + dw .Satur + +.Sun db "SUN@" +.Mon db "MON@" +.Tues db "TUES@" +.Wednes db "WEDNES@" +.Thurs db "THURS@" +.Fri db "FRI@" +.Satur db "SATUR@" +.Day db "DAY@" +; 15d8 + diff --git a/common/time.asm b/common/time.asm new file mode 100644 index 000000000..fff52b173 --- /dev/null +++ b/common/time.asm @@ -0,0 +1,311 @@ +; Functions relating to the timer interrupt and the real-time-clock. + + +AskTimer: ; 591 + push af + ld a, [$ffe9] + and a + jr z, .asm_59a + call Timer + +.asm_59a + pop af + reti +; 59c + + +LatchClock: ; 59c +; latch clock counter data + ld a, 0 + ld [MBC3LatchClock], a + ld a, 1 + ld [MBC3LatchClock], a + ret +; 5a7 + + +UpdateTime: ; 5a7 + call GetClock + call FixDays + call FixTime + callba GetTimeOfDay + ret +; 5b7 + + +GetClock: ; 5b7 +; store clock data in hRTCDayHi-hRTCSeconds + +; enable clock r/w + ld a, SRAM_ENABLE + ld [MBC3SRamEnable], a + +; clock data is 'backwards' in hram + + call LatchClock + ld hl, MBC3SRamBank + ld de, MBC3RTC + + ld [hl], RTC_S + ld a, [de] + and $3f + ld [hRTCSeconds], a + + ld [hl], RTC_M + ld a, [de] + and $3f + ld [hRTCMinutes], a + + ld [hl], RTC_H + ld a, [de] + and $1f + ld [hRTCHours], a + + ld [hl], RTC_DL + ld a, [de] + ld [hRTCDayLo], a + + ld [hl], RTC_DH + ld a, [de] + ld [hRTCDayHi], a + +; unlatch clock / disable clock r/w + call CloseSRAM + ret +; 5e8 + + +FixDays: ; 5e8 +; fix day count +; mod by 140 + +; check if day count > 255 (bit 8 set) + ld a, [hRTCDayHi] ; DH + bit 0, a + jr z, .daylo +; reset dh (bit 8) + res 0, a + ld [hRTCDayHi], a ; DH + +; mod 140 +; mod twice since bit 8 (DH) was set + ld a, [hRTCDayLo] ; DL +.modh + sub 140 + jr nc, .modh +.modl + sub 140 + jr nc, .modl + add 140 + +; update dl + ld [hRTCDayLo], a ; DL + +; unknown output + ld a, $40 ; %1000000 + jr .set + +.daylo +; quit if fewer than 140 days have passed + ld a, [hRTCDayLo] ; DL + cp 140 + jr c, .quit + +; mod 140 +.mod + sub 140 + jr nc, .mod + add 140 + +; update dl + ld [hRTCDayLo], a ; DL + +; unknown output + ld a, $20 ; %100000 + +.set +; update clock with modded day value + push af + call SetClock + pop af + scf + ret + +.quit + xor a + ret +; 61d + + +FixTime: ; 61d +; add ingame time (set at newgame) to current time +; day hr min sec +; store time in CurDay, hHours, hMinutes, hSeconds + +; second + ld a, [hRTCSeconds] ; S + ld c, a + ld a, [StartSecond] + add c + sub 60 + jr nc, .updatesec + add 60 +.updatesec + ld [hSeconds], a + +; minute + ccf ; carry is set, so turn it off + ld a, [hRTCMinutes] ; M + ld c, a + ld a, [StartMinute] + adc c + sub 60 + jr nc, .updatemin + add 60 +.updatemin + ld [hMinutes], a + +; hour + ccf ; carry is set, so turn it off + ld a, [hRTCHours] ; H + ld c, a + ld a, [StartHour] + adc c + sub 24 + jr nc, .updatehr + add 24 +.updatehr + ld [hHours], a + +; day + ccf ; carry is set, so turn it off + ld a, [hRTCDayLo] ; DL + ld c, a + ld a, [StartDay] + adc c + ld [CurDay], a + ret +; 658 + +Function658: ; 658 + xor a + ld [StringBuffer2], a + ld a, $0 + ld [$d089], a + jr .asm_677 + + call UpdateTime + ld a, [hHours] + ld [$d087], a + ld a, [hMinutes] + ld [$d088], a + ld a, [hSeconds] + ld [$d089], a + jr .asm_677 + +.asm_677 + ld a, $5 + ld hl, $40ed + rst FarCall + ret +; 67e + + + +Function67e: ; 67e + call Function685 + call SetClock + ret +; 685 + +Function685: ; 685 + xor a + ld [hRTCSeconds], a + ld [hRTCMinutes], a + ld [hRTCHours], a + ld [hRTCDayLo], a + ld [hRTCDayHi], a + ret +; 691 + + +SetClock: ; 691 +; set clock data from hram + +; enable clock r/w + ld a, SRAM_ENABLE + ld [MBC3SRamEnable], a + +; set clock data +; stored 'backwards' in hram + + call LatchClock + ld hl, MBC3SRamBank + ld de, MBC3RTC + +; seems to be a halt check that got partially commented out +; this block is totally pointless + ld [hl], RTC_DH + ld a, [de] + bit 6, a ; halt + ld [de], a + +; seconds + ld [hl], RTC_S + ld a, [hRTCSeconds] + ld [de], a +; minutes + ld [hl], RTC_M + ld a, [hRTCMinutes] + ld [de], a +; hours + ld [hl], RTC_H + ld a, [hRTCHours] + ld [de], a +; day lo + ld [hl], RTC_DL + ld a, [hRTCDayLo] + ld [de], a +; day hi + ld [hl], RTC_DH + ld a, [hRTCDayHi] + res 6, a ; make sure timer is active + ld [de], a + +; cleanup + call CloseSRAM ; unlatch clock, disable clock r/w + ret +; 6c4 + + +Function6c4: ; 6c4 + xor a + push af + ld a, $0 + call GetSRAMBank + pop af + ld [$ac60], a + call CloseSRAM + ret +; 6d3 + +Function6d3: ; 6d3 + ld hl, $ac60 + push af + ld a, $0 + call GetSRAMBank + pop af + or [hl] + ld [hl], a + call CloseSRAM + ret +; 6e3 + +Function6e3: ; 6e3 + ld a, $0 + call GetSRAMBank + ld a, [$ac60] + call CloseSRAM + ret +; 6ef + diff --git a/common/vblank.asm b/common/vblank.asm new file mode 100644 index 000000000..71114964e --- /dev/null +++ b/common/vblank.asm @@ -0,0 +1,541 @@ +; VBlank is the interrupt responsible for updating VRAM. + +; In Pokemon Crystal, VBlank has been hijacked to act as the +; main loop. After time-sensitive graphics operations have been +; performed, joypad input and sound functions are executed. + +; This prevents the display and audio output from lagging. + + +VBlank: ; 283 + push af + push bc + push de + push hl + +; get vblank type + ld a, [$ff9e] + and $7 + +; get fn pointer + ld e, a + ld d, $0 + ld hl, .VBlanks + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + +; down to business + call _hl_ + +; since this is called once per frame + call GameTimer + + pop hl + pop de + pop bc + pop af + reti +; 2a1 + +.VBlanks ; 2a1 + dw VBlank0 ; 0 + dw VBlank1 ; 1 + dw VBlank2 ; 2 + dw VBlank3 ; 3 + dw VBlank4 ; 4 + dw VBlank5 ; 5 + dw VBlank6 ; 6 + dw VBlank0 ; 7 +; 2b1 + + +VBlank0: ; 2b1 +; normal operation + +; rng +; scx, scy, wy, wx +; bg map buffer +; palettes +; dma transfer +; bg map +; tiles +; oam +; joypad +; sound + +; inc frame counter + ld hl, $ff9b + inc [hl] + +; advance rng + ld a, [rDIV] + ld b, a + ld a, [hRandomAdd] + adc b + ld [hRandomAdd], a + + ld a, [rDIV] + ld b, a + ld a, [hRandomSub] + sbc b + ld [hRandomSub], a + +; save bank + ld a, [hROMBank] ; current bank + ld [$ff8a], a + +; scroll x + ld a, [hSCX] + ld [rSCX], a +; scroll y + ld a, [hSCY] + ld [rSCY], a +; window y + ld a, [hWY] + ld [rWY], a +; window x + 7 + ld a, [hWX] + ld [rWX], a + +; some time management is in order +; only have time for one of these during vblank + +; bg map buffer has priority + call UpdateBGMapBuffer + jr c, .doneframeaction + +; then pals + call UpdatePalsIfCGB + jr c, .doneframeaction + +; dma transfer + call DMATransfer + jr c, .doneframeaction + +; bg map + call UpdateBGMap + +; these have their own timing checks + call Serve2bppRequest + call Serve1bppRequest + call AnimateTileset + +.doneframeaction +; oam update off? + ld a, [hOAMUpdate] + and a + jr nz, .vblankoccurred + +; update oam by dma transfer + call hPushOAM +; @PushOAM: +; ld a, Sprites >> 8 +; ld [rDMA], a +; ld a, $28 +; .loop +; dec a +; jr nz, .loop +; ret + + +; vblank-sensitive operations are done + +.vblankoccurred +; tell other fns vblank happened + xor a + ld [VBlankOccurred], a + +; dec OverworldDelay until 0 + ld a, [OverworldDelay] + and a + jr z, .textdelay + dec a + ld [OverworldDelay], a + +.textdelay +; dec text delay counter until 0 + ld a, [TextDelayFrames] + and a + jr z, .joypad + dec a + ld [TextDelayFrames], a + +.joypad + call Joypad + +; update sound + ld a, BANK(UpdateSound) + rst Bankswitch ; bankswitch + call UpdateSound + ld a, [$ff8a] + rst Bankswitch ; restore bank + +; + ld a, [hSeconds] + ld [$ffe3], a + + ret +; 325 + + +VBlank2: ; 325 +; sound only + +; save bank + ld a, [hROMBank] + ld [$ff8a], a + +; update sound + ld a, BANK(UpdateSound) + rst Bankswitch ; bankswitch + call UpdateSound + +; restore bank + ld a, [$ff8a] + rst Bankswitch + +; tell other fns vblank happened + xor a + ld [VBlankOccurred], a + ret +; 337 + + +VBlank1: ; 337 +; scx, scy +; palettes +; bg map +; tiles +; oam +; sound / lcd stat + +; save bank + ld a, [hROMBank] + ld [$ff8a], a + +; scroll x + ld a, [hSCX] + ld [rSCX], a + +; scroll y + ld a, [hSCY] + ld [rSCY], a + +; time-sensitive fns + call UpdatePals + jr c, .vblankoccurred + +; these have their own timing checks + call UpdateBGMap + call Serve2bppRequest@VBlank +; update oam by dma transfer + call hPushOAM +; @PushOAM: +; ld a, Sprites >> 8 +; ld [rDMA], a +; ld a, $28 +; .loop +; dec a +; jr nz, .loop +; ret + +.vblankoccurred +; tell other fns vblank happened + xor a + ld [VBlankOccurred], a + +; get requested ints + ld a, [rIF] + ld b, a +; discard requested ints + xor a + ld [rIF], a +; enable lcd stat + ld a, %10 ; lcd stat + ld [rIE], a +; rerequest serial int if applicable (still disabled) +; request lcd stat + ld a, b + and %1000 ; serial + or %10 ; lcd stat + ld [rIF], a + + ei +; update sound + ld a, BANK(UpdateSound) + rst Bankswitch ; bankswitch + call UpdateSound +; restore bank + ld a, [$ff8a] + rst Bankswitch + di + +; get requested ints + ld a, [rIF] + ld b, a +; discard requested ints + xor a + ld [rIF], a +; enable ints besides joypad + ld a, %1111 ; serial timer lcdstat vblank + ld [rIE], a +; rerequest ints + ld a, b + ld [rIF], a + ret +; 37f + + +UpdatePals: ; 37f +; update pals for either dmg or cgb + +; check cgb + ld a, [hCGB] + and a + jp nz, UpdateCGBPals + +; update gb pals + ld a, [$cfc7] + ld [rBGP], a + + ld a, [$cfc8] + ld [rOBP0], a + + ld a, [$cfc9] + ld [rOBP1], a + + and a + ret +; 396 + + +VBlank3: ; 396 +; scx, scy +; palettes +; bg map +; tiles +; oam +; sound / lcd stat + +; save bank + ld a, [hROMBank] + ld [$ff8a], a + +; scroll x + ld a, [hSCX] + ld [rSCX], a +; scroll y + ld a, [hSCY] + ld [rSCY], a + +; any pals to update? + ld a, [hCGBPalUpdate] + and a + call nz, ForceUpdateCGBPals + jr c, .vblankoccurred +; else + call UpdateBGMap + call Serve2bppRequest@VBlank + +; update oam by dma transfer + call hPushOAM +; @PushOAM: +; ld a, Sprites >> 8 +; ld [rDMA], a +; ld a, $28 +; .loop +; dec a +; jr nz, .loop +; ret + +.vblankoccurred +; tell other fns vblank happened + xor a + ld [VBlankOccurred], a + +; save int flag + ld a, [rIF] + push af +; reset ints + xor a + ld [rIF], a +; force lcdstat int during sound update + ld a, %10 ; lcd stat + ld [rIE], a + ld [rIF], a + + ei +; update sound + ld a, BANK(UpdateSound) + rst Bankswitch ; bankswitch + call UpdateSound +; restore bank + ld a, [$ff8a] + rst Bankswitch + di + +; request lcdstat + ld a, [rIF] + ld b, a +; and any other ints + pop af + or b + ld b, a +; reset ints + xor a + ld [rIF], a +; enable ints besides joypad + ld a, %1111 ; serial timer lcdstat vblank + ld [rIE], a +; request ints + ld a, b + ld [rIF], a + ret +; 3df + + +VBlank4: ; 3df +; bg map +; tiles +; oam +; joypad +; serial +; sound + +; save bank + ld a, [hROMBank] + ld [$ff8a], a + + call UpdateBGMap + call Serve2bppRequest + +; update oam by dma transfer + call hPushOAM +; @PushOAM: +; ld a, Sprites >> 8 +; ld [rDMA], a +; ld a, $28 +; .loop +; dec a +; jr nz, .loop +; ret + +; update joypad + call Joypad + +; tell other fns vblank happened + xor a + ld [VBlankOccurred], a + +; handshake + call AskSerial + +; update sound + ld a, BANK(UpdateSound) + rst Bankswitch ; bankswitch + call UpdateSound +; restore bank + ld a, [$ff8a] + rst Bankswitch + ret +; 400 + + +VBlank5: ; 400 +; scx +; palettes +; bg map +; tiles +; joypad +; + +; save bank + ld a, [hROMBank] + ld [$ff8a], a + +; scroll x + ld a, [hSCX] + ld [rSCX], a + +; if we can update pals, skip this part + call UpdatePalsIfCGB + jr c, .vblankoccurred + + call UpdateBGMap + call Serve2bppRequest + +.vblankoccurred +; tell other fns vblank happened + xor a + ld [VBlankOccurred], a + +; joypad + call Joypad + +; discard requested ints + xor a + ld [rIF], a +; enable lcd stat + ld a, %10 ; lcd stat + ld [rIE], a +; request lcd stat + ld [rIF], a + + ei +; update sound + ld a, BANK(UpdateSound) + rst Bankswitch ; bankswitch + call UpdateSound +; restore bank + ld a, [$ff8a] + rst Bankswitch + di + +; discard requested ints + xor a + ld [rIF], a +; enable ints besides joypad + ld a, %1111 ; serial timer lcdstat vblank + ld [rIE], a + ret +; 436 + + +VBlank6: ; 436 +; palettes +; tiles +; dma transfer +; sound + +; save bank + ld a, [hROMBank] + ld [$ff8a], a + +; inc frame counter + ld hl, $ff9b + inc [hl] + + call UpdateCGBPals + jr c, .vblankoccurred + + call Serve2bppRequest + call Serve1bppRequest + call DMATransfer + +.vblankoccurred +; tell other fns vblank happened + xor a + ld [VBlankOccurred], a + +; update sound + ld a, BANK(UpdateSound) + rst Bankswitch ; bankswitch + call UpdateSound +; restore bank + ld a, [$ff8a] + rst Bankswitch + ret +; 45a diff --git a/common/video.asm b/common/video.asm new file mode 100644 index 000000000..0d0aa272d --- /dev/null +++ b/common/video.asm @@ -0,0 +1,487 @@ +; Functions dealing with VRAM. + +DMATransfer: ; 15d8 +; Return carry if the transfer is completed. + + ld a, [hDMATransfer] + and a + ret z + +; Start transfer + ld [rHDMA5], a + +; Execution is halted until the transfer is complete. + + xor a + ld [hDMATransfer], a + scf + ret +; 15e3 + + +UpdateBGMapBuffer: ; 15e3 +; Copy [$ffdc] 16x8 tiles from BGMapBuffer +; to bg map addresses in BGMapBufferPtrs. + +; [$ffdc] must be even since this is done in pairs. + +; Return carry on success. + + ld a, [hBGMapUpdate] + and a + ret z + + ld a, [rVBK] + push af + ld [hSPBuffer], sp + + ld hl, BGMapBufferPtrs + ld sp, hl + +; We can now pop the addresses of affected spots on the BG Map + + ld hl, BGMapPalBuffer + ld de, BGMapBuffer + + +.next +; Copy a pair of 16x8 blocks (one 16x16 block) + +rept 2 +; Get our BG Map address + pop bc + +; Palettes + ld a, 1 + ld [rVBK], a + + ld a, [hli] + ld [bc], a + inc c + ld a, [hli] + ld [bc], a + dec c + +; Tiles + ld a, 0 + ld [rVBK], a + + ld a, [de] + inc de + ld [bc], a + inc c + ld a, [de] + inc de + ld [bc], a +endr + +; We've done 2 16x8 blocks + ld a, [$ffdc] + dec a + dec a + ld [$ffdc], a + + jr nz, .next + + + ld a, [hSPBuffer] + ld l, a + ld a, [hSPBuffer + 1] + ld h, a + ld sp, hl + + pop af + ld [rVBK], a + + xor a + ld [hBGMapUpdate], a + scf + ret +; 163a + + +WaitTop: ; 163a +; Wait until the top third of the BG Map is being updated. + + ld a, [hBGMapMode] + and a + ret z + + ld a, [hBGMapThird] + and a + jr z, .done + + call DelayFrame + jr WaitTop + +.done + xor a + ld [hBGMapMode], a + ret +; 164c + + +UpdateBGMap: ; 164c +; Update the BG Map, in thirds, from TileMap and AttrMap. + + ld a, [hBGMapMode] + and a + ret z + +; BG Map 0 + dec a ; 1 + jr z, .Tiles + dec a ; 2 + jr z, .Attr + +; BG Map 1 + dec a + + ld a, [hBGMapAddress] + ld l, a + ld a, [hBGMapAddress + 1] + ld h, a + push hl + + xor a + ld [hBGMapAddress], a + ld a, VBGMap1 >> 8 + ld [hBGMapAddress + 1], a + + ld a, [hBGMapMode] + push af + cp 3 + call z, .Tiles + pop af + cp 4 + call z, .Attr + + pop hl + ld a, l + ld [hBGMapAddress], a + ld a, h + ld [hBGMapAddress + 1], a + ret + + +.Attr + ld a, 1 + ld [rVBK], a + + ld hl, AttrMap + call .update + + ld a, 0 + ld [rVBK], a + ret + + +.Tiles + ld hl, TileMap + + +.update + ld [hSPBuffer], sp + +; Which third? + ld a, [hBGMapThird] + and a ; 0 + jr z, .top + dec a ; 1 + jr z, .middle + ; 2 + + +THIRD_HEIGHT EQU SCREEN_HEIGHT / 3 + + +.bottom + ld de, 2 * THIRD_HEIGHT * SCREEN_WIDTH + add hl, de + ld sp, hl + + ld a, [hBGMapAddress + 1] + ld h, a + ld a, [hBGMapAddress] + ld l, a + + ld de, 2 * THIRD_HEIGHT * BG_MAP_WIDTH + add hl, de + +; Next time: top third + xor a + jr .start + + +.middle + ld de, THIRD_HEIGHT * SCREEN_WIDTH + add hl, de + ld sp, hl + + ld a, [hBGMapAddress + 1] + ld h, a + ld a, [hBGMapAddress] + ld l, a + + ld de, THIRD_HEIGHT * BG_MAP_WIDTH + add hl, de + +; Next time: bottom third + ld a, 2 + jr .start + + +.top + ld sp, hl + + ld a, [hBGMapAddress + 1] + ld h, a + ld a, [hBGMapAddress] + ld l, a + +; Next time: middle third + ld a, 1 + + +.start +; Which third to update next time + ld [hBGMapThird], a + +; Rows of tiles in a third + ld a, SCREEN_HEIGHT / 3 + +; Discrepancy between TileMap and BGMap + ld bc, BG_MAP_WIDTH - (SCREEN_WIDTH - 1) + + +.row +; Copy a row of 20 tiles +rept SCREEN_WIDTH / 2 - 1 + pop de + ld [hl], e + inc l + ld [hl], d + inc l +endr + pop de + ld [hl], e + inc l + ld [hl], d + + add hl, bc + dec a + jr nz, .row + + + ld a, [hSPBuffer] + ld l, a + ld a, [hSPBuffer + 1] + ld h, a + ld sp, hl + ret +; 170a + + +Serve1bppRequest: ; 170a +; Only call during the first fifth of VBlank + + ld a, [Requested1bpp] + and a + ret z + +; Back out if we're too far into VBlank + ld a, [rLY] + cp 144 + ret c + cp 146 + ret nc + +; Copy [Requested1bpp] 1bpp tiles from [Requested1bppSource] to [Requested1bppDest] + + ld [hSPBuffer], sp + +; Source + ld hl, Requested1bppSource + ld a, [hli] + ld h, [hl] + ld l, a + ld sp, hl + +; Destination + ld hl, Requested1bppDest + ld a, [hli] + ld h, [hl] + ld l, a + +; # tiles to copy + ld a, [Requested1bpp] + ld b, a + + xor a + ld [Requested1bpp], a + +.next + +rept 3 + pop de + ld [hl], e + inc l + ld [hl], e + inc l + ld [hl], d + inc l + ld [hl], d + inc l +endr + pop de + ld [hl], e + inc l + ld [hl], e + inc l + ld [hl], d + inc l + ld [hl], d + + inc hl + dec b + jr nz, .next + + + ld a, l + ld [Requested1bppDest], a + ld a, h + ld [Requested1bppDest + 1], a + + ld [Requested1bppSource], sp + + ld a, [hSPBuffer] + ld l, a + ld a, [hSPBuffer + 1] + ld h, a + ld sp, hl + ret +; 1769 + + +Serve2bppRequest: ; 1769 +; Only call during the first fifth of VBlank + + ld a, [Requested2bpp] + and a + ret z + +; Back out if we're too far into VBlank + ld a, [rLY] + cp 144 + ret c + cp 146 + ret nc + jr _Serve2bppRequest + + +Serve2bppRequest@VBlank: ; 1778 + + ld a, [Requested2bpp] + and a + ret z + +_Serve2bppRequest: ; 177d +; Copy [Requested2bpp] 2bpp tiles from [Requested2bppSource] to [Requested2bppDest] + + ld [hSPBuffer], sp + +; Source + ld hl, Requested2bppSource + ld a, [hli] + ld h, [hl] + ld l, a + ld sp, hl + +; Destination + ld hl, Requested2bppDest + ld a, [hli] + ld h, [hl] + ld l, a + +; # tiles to copy + ld a, [Requested2bpp] + ld b, a + + xor a + ld [Requested2bpp], a + +.next + +rept 7 + pop de + ld [hl], e + inc l + ld [hl], d + inc l +endr + pop de + ld [hl], e + inc l + ld [hl], d + + inc hl + dec b + jr nz, .next + + + ld a, l + ld [Requested2bppDest], a + ld a, h + ld [Requested2bppDest + 1], a + + ld [Requested2bppSource], sp + + ld a, [hSPBuffer] + ld l, a + ld a, [hSPBuffer + 1] + ld h, a + ld sp, hl + ret +; 17d3 + + +AnimateTileset: ; 17d3 +; Only call during the first fifth of VBlank + + ld a, [$ffde] + and a + ret z + +; Back out if we're too far into VBlank + ld a, [rLY] + cp 144 + ret c + cp 151 + ret nc + + ld a, [hROMBank] + push af + ld a, BANK(_AnimateTileset) + rst Bankswitch + + ld a, [rSVBK] + push af + ld a, 1 + ld [rSVBK], a + + ld a, [rVBK] + push af + ld a, 0 + ld [rVBK], a + + call _AnimateTileset + + pop af + ld [rVBK], a + pop af + ld [rSVBK], a + pop af + rst Bankswitch + ret +; 17ff + |