diff options
| author | PikalaxALT <pikalaxalt@gmail.com> | 2018-06-02 21:26:20 -0400 |
|---|---|---|
| committer | PikalaxALT <pikalaxalt@gmail.com> | 2018-06-02 21:26:20 -0400 |
| commit | 04883f4bf9fa6c0bf935f1aac95d5d48abe3bb30 (patch) | |
| tree | 3ff95e7bbb62d0decfb9e2cba9e3d54f61013706 /home | |
| parent | 956d010d59ad225bea768aec172ccb56977b1775 (diff) | |
| parent | 5fb7140613d6ea00ec1964fde18418c6257c2e27 (diff) | |
Merge branch 'master' into build_more_roms
Diffstat (limited to 'home')
| -rw-r--r-- | home/audio.asm | 247 | ||||
| -rw-r--r-- | home/bankswitch.asm | 6 | ||||
| -rw-r--r-- | home/clear_sprites.asm | 32 | ||||
| -rw-r--r-- | home/copy.asm | 149 | ||||
| -rw-r--r-- | home/copy2.asm | 28 | ||||
| -rw-r--r-- | home/copy_tilemap.asm | 24 | ||||
| -rw-r--r-- | home/delay.asm | 28 | ||||
| -rw-r--r-- | home/farcall.asm | 62 | ||||
| -rw-r--r-- | home/init.asm | 221 | ||||
| -rw-r--r-- | home/interrupts.asm | 14 | ||||
| -rwxr-xr-x | home/items.asm | 145 | ||||
| -rw-r--r-- | home/joypad.asm | 285 | ||||
| -rw-r--r-- | home/lcd.asm | 120 | ||||
| -rw-r--r-- | home/names.asm | 23 | ||||
| -rw-r--r-- | home/oam_dma.asm | 30 | ||||
| -rw-r--r-- | home/pic.asm | 40 | ||||
| -rw-r--r-- | home/pokemon.asm | 28 | ||||
| -rw-r--r-- | home/predef.asm | 72 | ||||
| -rw-r--r-- | home/print_bcd.asm | 113 | ||||
| -rw-r--r-- | home/print_hex.asm | 42 | ||||
| -rw-r--r-- | home/print_num.asm | 252 | ||||
| -rw-r--r-- | home/serial.asm | 87 | ||||
| -rw-r--r-- | home/sram.asm | 28 | ||||
| -rw-r--r-- | home/text.asm | 368 | ||||
| -rw-r--r-- | home/unknown.asm | 32 | ||||
| -rw-r--r-- | home/vblank.asm | 315 | ||||
| -rw-r--r-- | home/vcopy.asm | 616 |
27 files changed, 2761 insertions, 646 deletions
diff --git a/home/audio.asm b/home/audio.asm index ede88d4..bf3a6c5 100644 --- a/home/audio.asm +++ b/home/audio.asm @@ -7,143 +7,136 @@ SECTION "Audio interface", ROM0[$3C83] endc DisableAudio:: ; 3cbf - push hl - push de - push bc - push af - ldh a, [hROMBank] - push af - ld a, BANK(_DisableAudio) - ld [MBC3RomBank], a ; Unsafe - ldh [hROMBank], a - call _DisableAudio - pop af - ld [MBC3RomBank], a ; Unsafe - ldh [hROMBank], a - pop af - pop bc - pop de - pop hl - ret - + push hl + push de + push bc + push af + ldh a, [hROMBank] + push af + ld a, BANK(_DisableAudio) + ld [MBC3RomBank], a ; Unsafe + ldh [hROMBank], a + call _DisableAudio + pop af + ld [MBC3RomBank], a ; Unsafe + ldh [hROMBank], a + pop af + pop bc + pop de + pop hl + ret UpdateSound:: ; 3cdb - push hl - push de - push bc - push af - ldh a, [hROMBank] - push af - ld a, BANK(_UpdateSound) - ld [MBC3RomBank], a ; Unsafe - ldh [hROMBank], a - call _UpdateSound - pop af - ld [MBC3RomBank], a ; Unsafe - ldh [hROMBank], a - pop af - pop bc - pop de - pop hl - ret - + push hl + push de + push bc + push af + ldh a, [hROMBank] + push af + ld a, BANK(_UpdateSound) + ld [MBC3RomBank], a ; Unsafe + ldh [hROMBank], a + call _UpdateSound + pop af + ld [MBC3RomBank], a ; Unsafe + ldh [hROMBank], a + pop af + pop bc + pop de + pop hl + ret _LoadMusicByte:: ; 3cf7 - ld [MBC3RomBank], a ; Unsafe - ldh [hROMBank], a - ld a, [de] - push af - ld a, BANK(_UpdateSound) - ld [MBC3RomBank], a ; Unsafe - ldh [hROMBank], a - pop af - ret - + ld [MBC3RomBank], a ; Unsafe + ldh [hROMBank], a + ld a, [de] + push af + ld a, BANK(_UpdateSound) + ld [MBC3RomBank], a ; Unsafe + ldh [hROMBank], a + pop af + ret PlayMusic:: ; 3d07 - push hl - push de - push bc - push af - ldh a, [hROMBank] - push af - ld a, BANK(_PlayMusic) - ld [MBC3RomBank], a ; Unsafe - ldh [hROMBank], a - call _PlayMusic - pop af - ld [MBC3RomBank], a ; Unsafe - ldh [hROMBank], a - pop af - pop bc - pop de - pop hl - ret - + push hl + push de + push bc + push af + ldh a, [hROMBank] + push af + ld a, BANK(_PlayMusic) + ld [MBC3RomBank], a ; Unsafe + ldh [hROMBank], a + call _PlayMusic + pop af + ld [MBC3RomBank], a ; Unsafe + ldh [hROMBank], a + pop af + pop bc + pop de + pop hl + ret PlayCryHeader:: ; 3d23 - push hl - push de - push bc - push af - ldh a, [hROMBank] - push af - - ld a, BANK(CryHeaders) - ld [MBC3RomBank], a ; Unsafe - ldh [hROMBank], a - ld hl, CryHeaders -REPT 6 - add hl, de -ENDR - ld e, [hl] - inc hl - ld d, [hl] - inc hl - ld a, [hli] - ld [wCryPitch], a - ld a, [hli] - ld [wCryPitch + 1], a - ld a, [hli] - ld [wCryLength], a - ld a, [hl] - ld [wCryLength + 1], a - - ld a, BANK(_PlayCryHeader) - ld [MBC3RomBank], a ; Unsafe - ldh [hROMBank], a - call _PlayCryHeader + push hl + push de + push bc + push af + ldh a, [hROMBank] + push af + + ld a, BANK(CryHeaders) + ld [MBC3RomBank], a ; Unsafe + ldh [hROMBank], a + ld hl, CryHeaders +rept 6 + add hl, de +endr + ld e, [hl] + inc hl + ld d, [hl] + inc hl + ld a, [hli] + ld [wCryPitch], a + ld a, [hli] + ld [wCryPitch + 1], a + ld a, [hli] + ld [wCryLength], a + ld a, [hl] + ld [wCryLength + 1], a + + ld a, BANK(_PlayCryHeader) + ld [MBC3RomBank], a ; Unsafe + ldh [hROMBank], a + call _PlayCryHeader - pop af - ld [MBC3RomBank], a ; Unsafe - ldh [hROMBank], a - pop af - pop bc - pop de - pop hl - ret - - - + pop af + ld [MBC3RomBank], a ; Unsafe + ldh [hROMBank], a + pop af + pop bc + pop de + pop hl + ret PlaySFX:: ; 3d63 - push hl - push de - push bc - push af - ldh a, [hROMBank] - push af - ld a, BANK(_PlaySFX) - ld [MBC3RomBank], a ; Unsafe - ldh [hROMBank], a - call _PlaySFX - pop af - ld [MBC3RomBank], a ; Unsafe - ldh [hROMBank], a - pop af - pop bc - pop de - pop hl - ret + push hl + push de + push bc + push af + ldh a, [hROMBank] + push af + ld a, BANK(_PlaySFX) + ld [MBC3RomBank], a ; Unsafe + ldh [hROMBank], a + call _PlaySFX + pop af + ld [MBC3RomBank], a ; Unsafe + ldh [hROMBank], a + pop af + pop bc + pop de + pop hl + ret WaitPlaySFX:: ; 3d7f diff --git a/home/bankswitch.asm b/home/bankswitch.asm index 574fa64..278013c 100644 --- a/home/bankswitch.asm +++ b/home/bankswitch.asm @@ -9,6 +9,6 @@ endc ; Moved to a rst vector in final US releases (not sure about JP) ; All rst vectors are unused at this point in development Bankswitch:: ; 32c2 - ldh [hROMBank], a - ld [MBC3RomBank], a - ret + ldh [hROMBank], a + ld [MBC3RomBank], a + ret diff --git a/home/clear_sprites.asm b/home/clear_sprites.asm index 90e8f38..489b375 100644 --- a/home/clear_sprites.asm +++ b/home/clear_sprites.asm @@ -7,23 +7,23 @@ SECTION "Sprite clearing", ROM0[$32A0] endc ClearSprites:: ; 32dc - ld hl, wVirtualOAM - ld b, wVirtualOAMEnd - wVirtualOAM - xor a + ld hl, wVirtualOAM + ld b, wVirtualOAMEnd - wVirtualOAM + xor a .loop - ld [hli], a - dec b - jr nz, .loop - ret + ld [hli], a + dec b + jr nz, .loop + ret HideSprites:: ; 32e7 - ld hl, wVirtualOAM - ld de, SPRITEOAMSTRUCT_LENGTH - ld b, NUM_SPRITE_OAM_STRUCTS - ld a, $A0 + ld hl, wVirtualOAM + ld de, SPRITEOAMSTRUCT_LENGTH + ld b, NUM_SPRITE_OAM_STRUCTS + ld a, SPRITEOAMSTRUCT_LENGTH * NUM_SPRITE_OAM_STRUCTS .loop - ld [hl], a - add hl, de - dec b - jr nz, .loop - ret + ld [hl], a + add hl, de + dec b + jr nz, .loop + ret diff --git a/home/copy.asm b/home/copy.asm index 757da0d..c916cbd 100644 --- a/home/copy.asm +++ b/home/copy.asm @@ -6,72 +6,109 @@ else SECTION "Copy functions", ROM0[$32BB] endc -; Copy bc bytes from a:hl to de. FarCopyBytes:: ; 32f7 - ld [wBuffer], a - ldh a, [hROMBank] - push af - ld a, [wBuffer] - call Bankswitch - call CopyBytes - pop af - jp Bankswitch +; Copy bc bytes from a:hl to de. + ld [wBuffer], a + ldh a, [hROMBank] + push af + ld a, [wBuffer] + call Bankswitch + call CopyBytes + pop af + jp Bankswitch -; Copy bc bytes from hl to de CopyBytes:: ; 330a - ld a, b - and a - jr z, CopyBytesSmall - ld a, c - and a - jr z, .next - inc b +; Copy bc bytes from hl to de + ld a, b + and a + jr z, CopyBytesSmall + ld a, c + and a + jr z, .next + inc b .next - call CopyBytesSmall - dec b - jr nz, .next - ret + call CopyBytesSmall + dec b + jr nz, .next + ret -; Copy c bytes from hl to de CopyBytesSmall:: ; 331a - ld a, [hli] - ld [de], a - inc de - dec c - jr nz, CopyBytesSmall - ret - +; Copy c bytes from hl to de + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, CopyBytesSmall + ret GetFarByte:: ; 3321 - ld [wBuffer], a - ldh a, [hROMBank] - push af - ld a, [wBuffer] - call Bankswitch - ld a, [hl] - ld [wBuffer], a - pop af - call Bankswitch - ld a, [wBuffer] - ret - + ld [wBuffer], a + ldh a, [hROMBank] + push af + ld a, [wBuffer] + call Bankswitch + ld a, [hl] + ld [wBuffer], a + pop af + call Bankswitch + ld a, [wBuffer] + ret ByteFill:: ; 3339 - push af - ld a, b - and a - jr z, .small_fill - ld a, c - and a - jr z, .start_filling + push af + ld a, b + and a + jr z, .small_fill + ld a, c + and a + jr z, .start_filling .small_fill - inc b + inc b .start_filling - pop af + pop af .loop - ld [hli], a - dec c - jr nz, .loop - dec b - jr nz, .loop - ret + ld [hli], a + dec c + jr nz, .loop + dec b + jr nz, .loop + ret + +UncompressSpriteFromDE:: +; Decompress pic at a:de. + ld hl, wSpriteInputPtr + ld [hl], e + inc hl + ld [hl], d + jp UncompressSpriteData + +BackUpTilesToBuffer:: ; 3355 + hlcoord 0, 0 + decoord 0, 0, wTileMapBackup + ld bc, SCREEN_HEIGHT * SCREEN_WIDTH + jp CopyBytes + +ReloadTilesFromBuffer:: ; 3361 + xor a + ldh [hBGMapMode], a + hlcoord 0, 0, wTileMapBackup + decoord 0, 0 + ld bc, SCREEN_HEIGHT * SCREEN_WIDTH + call CopyBytes + ld a, 1 + ldh [hBGMapMode], a + ret + +CopyStringToCD31:: +; copies a string from [de] to [wcd31] + ld hl, wcd31 + ; fallthrough + +CopyString:: +; copies a string from [de] to [hl] + ld a, [de] + inc de + ld [hli], a + cp "@" + jr nz, CopyString + ret diff --git a/home/copy2.asm b/home/copy2.asm index 27abf08..0a0ee54 100644 --- a/home/copy2.asm +++ b/home/copy2.asm @@ -2,9 +2,9 @@ INCLUDE "constants.asm" SECTION "Video Copy functions", ROM0[$0D2A] +FarCopyData: ; d2a (0:d2a) ; Identical to FarCopyBytes except for tail call optimization ; Copy bc 2bpp bytes from a:hl to de. -FarCopyData: ; d2a (0:d2a) ld [wBuffer], a ldh a, [hROMBank] push af @@ -15,8 +15,8 @@ FarCopyData: ; d2a (0:d2a) call Bankswitch ret -; Copy and expand bc 1bpp bytes from a:hl to de. FarCopyDataDouble: ; d3e (0:d3e) +; Copy and expand bc 1bpp bytes from a:hl to de. ld [wBuffer], a ldh a, [hROMBank] push af @@ -49,10 +49,10 @@ FarCopyDataDouble: ; d3e (0:d3e) call Bankswitch ret +CopyVideoData:: ; d68 (0:d68) ; Wait for the next VBlank, then copy c 2bpp ; tiles from b:de to hl, 8 tiles at a time. ; This takes c/8 frames. -CopyVideoData:: ; d68 (0:d68) ldh a, [hBGMapMode] push af xor a ; disable auto-transfer while copying @@ -71,7 +71,7 @@ CopyVideoData:: ; d68 (0:d68) ld [wVBCopyDst + 1], a .loop ld a, c - cp $08 + cp $8 jr nc, .keepgoing ld [wVBCopySize], a call DelayFrame @@ -81,18 +81,18 @@ CopyVideoData:: ; d68 (0:d68) ldh [hBGMapMode], a ret .keepgoing - ld a, $08 + ld a, $8 ld [wVBCopySize], a call DelayFrame ld a, c - sub $08 + sub $8 ld c, a jr .loop +CopyVideoDataDouble:: ; da6 (0:da6) ; Wait for the next VBlank, then copy c 1bpp ; tiles from b:de to hl, 8 tiles at a time. ; This takes c/8 frames. -CopyVideoDataDouble:: ; da6 (0:da6) ldh a, [hBGMapMode] push af xor a @@ -111,7 +111,7 @@ CopyVideoDataDouble:: ; da6 (0:da6) ld [wVBCopyDoubleDst + 1], a .loop ld a, c - cp $08 + cp $8 jr nc, .keepgoing ld [wVBCopyDoubleSize], a call DelayFrame @@ -121,18 +121,18 @@ CopyVideoDataDouble:: ; da6 (0:da6) ldh [hBGMapMode], a ret .keepgoing - ld a, $08 + ld a, $8 ld [wVBCopyDoubleSize], a call DelayFrame ld a, c - sub $08 + sub $8 ld c, a jr .loop +CopyVideoDataOptimized:: ; de4 (0:de4) ; Copy c 2bpp tiles from b:de to hl in VRAM ; using VBlank service or direct copy in ; case LCD is off -CopyVideoDataOptimized:: ; de4 (0:de4) ldh a, [rLCDC] bit rLCDC_ENABLE, a jp nz, CopyVideoData ; copy video data during vblank while screen is on @@ -152,10 +152,10 @@ CopyVideoDataOptimized:: ; de4 (0:de4) pop af jp FarCopyData +CopyVideoDataDoubleOptimized: ; dff (0:dff) ; Copy c 1bpp tiles from b:de to hl in VRAM ; using VBlank service or direct copy in ; case LCD is off -CopyVideoDataDoubleOptimized: ; dff (0:dff) ldh a, [rLCDC] bit rLCDC_ENABLE, a jp nz, CopyVideoDataDouble @@ -164,7 +164,7 @@ CopyVideoDataDoubleOptimized: ; dff (0:dff) ld e, l ld a, b push af - ld h, $00 + ld h, 0 ld l, c add hl, hl add hl, hl @@ -174,4 +174,4 @@ CopyVideoDataDoubleOptimized: ; dff (0:dff) pop af pop hl jp FarCopyDataDouble -; 0xe18
\ No newline at end of file +; 0xe18 diff --git a/home/copy_tilemap.asm b/home/copy_tilemap.asm deleted file mode 100644 index 27c33c0..0000000 --- a/home/copy_tilemap.asm +++ /dev/null @@ -1,24 +0,0 @@ -INCLUDE "constants.asm" - -if DEBUG -SECTION "Tilemap copy/restore funcs", ROM0[$3355] -else -SECTION "Tilemap copy/restore funcs", ROM0[$3319] -endc - -BackUpTilesToBuffer:: ; 3355 - hlcoord 0, 0 - decoord 0, 0, wTileMapBackup - ld bc, SCREEN_HEIGHT * SCREEN_WIDTH - jp CopyBytes - -ReloadTilesFromBuffer:: ; 3361 - xor a - ldh [hBGMapMode], a - hlcoord 0, 0, wTileMapBackup - decoord 0, 0 - ld bc, SCREEN_HEIGHT * SCREEN_WIDTH - call CopyBytes - ld a, 1 - ldh [hBGMapMode], a - ret diff --git a/home/delay.asm b/home/delay.asm index dc3ad40..286cc0c 100644 --- a/home/delay.asm +++ b/home/delay.asm @@ -4,23 +4,19 @@ SECTION "Delay", ROM0[$0317] DelayFrame:: ; Wait for one frame - ld a, 1 - ld [wVBlankOccurred], a - -; Wait for the next VBlank, halting to conserve battery + ld a, 1 + ld [wVBlankOccurred], a .halt - halt ; rgbasm adds a nop after this instruction by default - ld a, [wVBlankOccurred] - and a - jr nz, .halt - - ret - +; Wait for the next VBlank, halting to conserve battery + halt ; rgbasm adds a nop after this instruction by default + ld a, [wVBlankOccurred] + and a + jr nz, .halt + ret DelayFrames:: ; Wait c frames - call DelayFrame - dec c - jr nz, DelayFrames - - ret + call DelayFrame + dec c + jr nz, DelayFrames + ret diff --git a/home/farcall.asm b/home/farcall.asm index 32fcce5..3fcf37f 100644 --- a/home/farcall.asm +++ b/home/farcall.asm @@ -7,36 +7,36 @@ SECTION "FarCall", ROM0[$2F6C] endc FarCall_hl:: ; 2fa8 - push af - ld a, b - ld [wFarCallBCBuffer], a - ld a, c - ld [wFarCallBCBuffer + 1], a - pop af - ld b, a - ldh a, [hROMBank] - push af - ld a, b - call Bankswitch - ld bc, .return - push bc - push hl - ld a, [wFarCallBCBuffer] - ld b, a - ld a, [wFarCallBCBuffer + 1] - ld c, a - ret + push af + ld a, b + ld [wFarCallBCBuffer], a + ld a, c + ld [wFarCallBCBuffer + 1], a + pop af + ld b, a + ldh a, [hROMBank] + push af + ld a, b + call Bankswitch + ld bc, .return + push bc + push hl + ld a, [wFarCallBCBuffer] + ld b, a + ld a, [wFarCallBCBuffer + 1] + ld c, a + ret .return - ld a, b - ld [wFarCallBCBuffer], a - ld a, c - ld [wFarCallBCBuffer + 1], a - pop bc - ld a, b - call Bankswitch - ld a, [wFarCallBCBuffer] - ld b, a - ld a, [wFarCallBCBuffer + 1] - ld c, a - ret + ld a, b + ld [wFarCallBCBuffer], a + ld a, c + ld [wFarCallBCBuffer + 1], a + pop bc + ld a, b + call Bankswitch + ld a, [wFarCallBCBuffer] + ld b, a + ld a, [wFarCallBCBuffer + 1] + ld c, a + ret diff --git a/home/init.asm b/home/init.asm index 5498b35..ef4b745 100644 --- a/home/init.asm +++ b/home/init.asm @@ -1,8 +1,8 @@ INCLUDE "constants.asm" SECTION "Entry point", ROM0[$100] - nop - jp Init + nop + jp Init SECTION "Global check value", ROM0[$14E] ; The ROM has an incorrect global check, so set it here @@ -25,121 +25,122 @@ endc SECTION "Init", ROM0[$52F] Init: ; 052f - di - xor a - ld [rIF], a - ld [rIE], 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 [wcc38], a ; Useless, since WRAM gets cleared right after - ld a, 1 << rTAC_ON | rTAC_4096_HZ - ld [rTAC], a - ld a, 1 << rLCDC_ENABLE - ld [rLCDC], a - call DisableLCD - - ld sp, wStackBottom - call ClearVRAM - ld hl, WRAM0_Begin - ld bc, WRAM1_End - WRAM0_Begin + di + xor a + ld [rIF], a + ld [rIE], 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 [wcc38], a ; Useless, since WRAM gets cleared right after + ld a, 1 << rTAC_ON | rTAC_4096_HZ + ld [rTAC], a + ld a, 1 << rLCDC_ENABLE + ld [rLCDC], a + call DisableLCD + + ld sp, wStackBottom + call ClearVRAM + ld hl, WRAM0_Begin + ld bc, WRAM1_End - WRAM0_Begin .ByteFill ; 0565 - ld [hl], 0 - inc hl - dec bc - ld a, b - or c - jr nz, .ByteFill - ld hl, HRAM_Begin - ld bc, HRAM_End - HRAM_Begin - call ByteFill - call ClearSprites - - ld a, BANK(WriteOAMDMACodeToHRAM) - call Bankswitch - call WriteOAMDMACodeToHRAM - - xor a - ldh [hMapAnims], a - ldh [hSCX], a - ldh [hSCY], a - ldh [rJOYP], a - ld a, 1 << rSTAT_HBLANK - ld [rSTAT], a - ld a, SCREEN_HEIGHT_PX - ldh [hWY], a - ld [rWY], a - ld a, 7 - ldh [hWX], a - ld [rWX], a - - ld a, $FF - ldh [hLinkPlayerNumber], a - ld h, HIGH($9800) - call BlankBGMap - ld h, HIGH($9C00) - call BlankBGMap - ld a, LCDC_DEFAULT - ld [rLCDC], a - - call DisableAudio - call _2007 - ; predef ??? - ld a, $4B ; TODO: add predefs so the line above can be uncommented - call Predef - ld a, $1F - ld [rIE], a - ld a, HIGH($9C00) - ldh [hBGMapAddress + 1], a - xor a - ldh [hBGMapAddress], a - - call DisableLCD - call ClearVRAM - ld a, LCDC_DEFAULT - ld [rLCDC], a - ei - - ld a, SRAM_ENABLE - ld [MBC3SRamEnable], a - ld a, RTC_DH - ld [MBC3SRamBank], a - xor a - ld [SRAM_Begin], a - ld a, 0 ; Useless - ld [MBC3LatchClock], a - ld [MBC3SRamEnable], a - jp GameInit + ld [hl], 0 + inc hl + dec bc + ld a, b + or c + jr nz, .ByteFill + ld hl, HRAM_Begin + ld bc, HRAM_End - HRAM_Begin + call ByteFill + call ClearSprites + + ld a, BANK(WriteOAMDMACodeToHRAM) + call Bankswitch + call WriteOAMDMACodeToHRAM + + xor a + ldh [hMapAnims], a + ldh [hSCX], a + ldh [hSCY], a + ldh [rJOYP], a + ld a, 1 << rSTAT_HBLANK + ld [rSTAT], a + ld a, SCREEN_HEIGHT_PX + ldh [hWY], a + ld [rWY], a + ld a, 7 + ldh [hWX], a + ld [rWX], a + + ld a, $ff + ldh [hLinkPlayerNumber], a + ld h, HIGH($9800) + call BlankBGMap + ld h, HIGH($9C00) + call BlankBGMap + ld a, LCDC_DEFAULT + ld [rLCDC], a + + call DisableAudio + call _2007 + ; predef ??? + ld a, $4B ; TODO: add predefs so the line above can be uncommented + call Predef + ld a, $1F + ld [rIE], a + ld a, HIGH($9C00) + ldh [hBGMapAddress + 1], a + xor a + ldh [hBGMapAddress], a + + call DisableLCD + call ClearVRAM + ld a, LCDC_DEFAULT + ld [rLCDC], a + ei + + ld a, SRAM_ENABLE + ld [MBC3SRamEnable], a + ld a, RTC_DH + ld [MBC3SRamBank], a + xor a + ld [SRAM_Begin], a + ld a, 0 ; Useless + ld [MBC3LatchClock], a + ld [MBC3SRamEnable], a + jp GameInit ClearVRAM: ; 05e6 - ld hl, VRAM_Begin - ld bc, VRAM_End - VRAM_Begin - xor a - call ByteFill - ret + ld hl, VRAM_Begin + ld bc, VRAM_End - VRAM_Begin + xor a + call ByteFill + ret BlankBGMap: - ld a, $7F - jr _FillBGMap + ld a, $7f + jr _FillBGMap FillBGMap: - ld a, l + ld a, l + ; fallthrough _FillBGMap: - ld de, $400 - ld l, e + ld de, BG_MAP_WIDTH * BG_MAP_HEIGHT + ld l, e .loop - ld [hli], a - dec e - jr nz, .loop - dec d - jr nz, .loop - ret + ld [hli], a + dec e + jr nz, .loop + dec d + jr nz, .loop + ret diff --git a/home/interrupts.asm b/home/interrupts.asm index b7800f1..f9d8ba1 100644 --- a/home/interrupts.asm +++ b/home/interrupts.asm @@ -1,28 +1,28 @@ INCLUDE "constants.asm" SECTION "VBlank interrupt vector", ROM0[$040] - jp VBlank + jp VBlank SECTION "LCD interrupt vector", ROM0[$048] - jp LCD + jp LCD SECTION "Timer interrupt vector", ROM0[$050] - jp TimerDummy + jp TimerDummy SECTION "Serial interrupt vector", ROM0[$058] - jp Serial + jp Serial SECTION "Joypad interrupt vector", ROM0[$060] - jp JoypadDummy + jp JoypadDummy SECTION "Timer dummy interrupt", ROM0[$42A] TimerDummy: ; 042a - reti + reti SECTION "Joypad dummy interrupt", ROM0[$7F7] JoypadDummy: ; 07f7 - reti + reti diff --git a/home/items.asm b/home/items.asm new file mode 100755 index 0000000..496b685 --- /dev/null +++ b/home/items.asm @@ -0,0 +1,145 @@ +INCLUDE "constants.asm"
+
+if DEBUG
+SECTION "AddItemToInventory", ROM0[$3259]
+else
+SECTION "AddItemToInventory", ROM0[$321D]
+endc
+
+AddItemToInventory:: ; 3259
+; function to add an item (in varying quantities) to the player's bag or PC box
+; INPUT:
+; HL = address of inventory (either wNumBagItems or wNumBoxItems)
+; [wcd76] = item ID
+; [wItemQuantity] = item quantity
+; sets carry flag if successful, unsets carry flag if unsuccessful
+ push bc
+ ldh a, [hROMBank]
+ push af
+ ld a, BANK(AddItemToInventory_)
+ call Bankswitch
+ push hl
+ push de
+ call AddItemToInventory_
+ pop de
+ pop hl
+ pop bc
+ ld a, b
+ call Bankswitch
+ pop bc
+ ret
+
+if DEBUG
+SECTION "GiveItem", ROM0[$366C]
+else
+SECTION "GiveItem", ROM0[$3630]
+endc
+
+GiveItem::
+; Give player quantity c of item b,
+; and copy the item's name to wcf4b.
+; Return carry on success.
+ ld a, b
+ ld [wce37], a
+ ld [wcd76], a
+ ld a, c
+ ld [wItemQuantity], a
+ ld hl, wNumBagItems
+ call AddItemToInventory
+ ret nc
+ call GetItemName
+ call CopyStringToCD31
+ scf
+ ret
+
+if DEBUG
+SECTION "GetItemName", ROM0[$376F]
+else
+SECTION "GetItemName", ROM0[$3733]
+endc
+
+GetItemName:: ; 376F
+; given an item ID at [wce37], store the name of the item into a string
+; starting at wcd26
+ push hl
+ push bc
+ ld a, [wce37]
+ cp ITEM_HM01_RED
+ jr nc, .machine
+
+ ld [wcb5b], a
+ ld a, ITEM_NAME
+ ld [wNameCategory], a
+ call GetName
+ jr .finish
+
+.machine
+ call GetMachineName
+.finish
+ ld de, wcd26 ; pointer to where item name is stored in RAM
+ pop bc
+ pop hl
+ ret
+
+if DEBUG
+SECTION "GetMachineName", ROM0[$378E]
+else
+SECTION "GetMachineName", ROM0[$3752]
+endc
+
+GetMachineName::
+; copies the name of the TM/HM in [wce37] to wcd26
+ push hl
+ push de
+ push bc
+ ld a, [wce37]
+ push af
+ cp ITEM_TM01_RED
+ jr nc, .WriteTM
+; if HM, then write "HM" and add 5 to the item ID, so we can reuse the
+; TM printing code
+ add 5
+ ld [wce37], a
+ ld hl, HiddenPrefix
+ ld bc, 6
+ jr .WriteMachinePrefix
+.WriteTM
+ ld hl, TechnicalPrefix
+ ld bc, 5
+.WriteMachinePrefix
+ ld de, wcd26
+ call CopyBytes
+; now get the machine number and convert it to text
+ ld a, [wce37]
+ sub ITEM_TM01_RED - 1
+ ld b, "0"
+.FirstDigit
+ sub 10
+ jr c, .SecondDigit
+ inc b
+ jr .FirstDigit
+.SecondDigit
+ add 10
+ push af
+ ld a, b
+ ld [de], a
+ inc de
+ pop af
+ ld b, "0"
+ add b
+ ld [de], a
+ inc de
+ ld a, "@"
+ ld [de], a
+ pop af
+ ld [wce37], a
+ pop bc
+ pop de
+ pop hl
+ ret
+
+TechnicalPrefix:
+ db "わざマシン@"
+
+HiddenPrefix:
+ db "ひでんマシン@"
diff --git a/home/joypad.asm b/home/joypad.asm new file mode 100644 index 0000000..e0740f2 --- /dev/null +++ b/home/joypad.asm @@ -0,0 +1,285 @@ +INCLUDE "constants.asm" + +SECTION "Joypad functions", ROM0[$07FE] + +Joypad:: ; 7fe (0:7fe) +; 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: + +; hJoypadUp: released this frame (delta) +; hJoypadDown: pressed this frame (delta) +; hJoypadState: currently pressed +; hJoypadSum: pressed so far + ld a, [$d4ab] + and $d0 + ret nz + ld a, 1 << 5 ; select direction keys + ldh [rJOYP], a + ldh a, [rJOYP] + ldh a, [rJOYP] + cpl + and $0f + swap a + ld b, a + ld a, 1 << 4 ; select button keys + ldh [rJOYP], a + ldh a, [rJOYP] + ldh a, [rJOYP] + ldh a, [rJOYP] + ldh a, [rJOYP] + ldh a, [rJOYP] + ldh a, [rJOYP] + cpl + and $0f + or b + ld b, a + ld a, (1 << 5 | 1 << 4) ; port reset + ldh [rJOYP], a + ldh a, [hJoypadState] + ld e, a + xor b + ld d, a + and e + ldh [hJoypadUp], a + ld a, d + and b + ldh [hJoypadDown], a + ld c, a + ldh a, [hJoypadSum] + or c + ldh [hJoypadSum], a + ld a, b + ldh [hJoypadState], a + ldh [hJoypadState2], a + ; Soft-Reset by holding A+B+SELECT+START + and (A_BUTTON | B_BUTTON | SELECT | START) + cp (A_BUTTON | B_BUTTON | SELECT | START) + jp z, Reset + ret + +GetJoypad:: ; 84a (0:84a) +; Update mirror joypad input from hJoypadState (real input) + +; hJoyReleased, hJoyDown and hJoyState are synchronized +; copies of their hJoypad* counterparts. + +; bit 0 A +; 1 B +; 2 SELECT +; 3 START +; 4 RIGHT +; 5 LEFT +; 6 UP +; 7 DOWN + push af + push hl + push de + ld hl, wJoypadFlags + set 6, [hl] ; mutex + ld hl, hJoypadDown + ld de, hJoyDown + ld a, [hli] + ld [de], a + inc de + ld a, [hli] + ld [de], a + inc de + ld a, [hl] + ld [de], a + ld hl, wJoypadFlags + res 6, [hl] + pop de + pop hl + pop af + ret + +JoyTitleScreenInput:: ; 869 (0:869) +; Check if any of the following conditions +; is met for c frames +; - B, Select and Up keys are pressed in same frame +; - A is pressed +; - START is pressed +; +; Inputs: c - number of frames to check for +; Return: carry set if condition met, else reset +.loop + call DelayFrame + push bc + call GetJoypadDebounced + pop bc + ldh a, [hJoyState] + cp (D_UP | SELECT | B_BUTTON) + jr z, .done + ldh a, [hJoySum] + and (START | A_BUTTON) + jr nz, .done + dec c + jr nz, .loop + and a + ret +.done + scf + ret + +GetJoypadDebounced:: ; 884 (0:884) +; Update hJoySum joypad input from either hJoyDown or +; hJoyState depending on hJoyDebounceSrc. +; hJoyState is only updated every 5 frames and +; the update is delayed by 15 frames after any button +; press. + call GetJoypad + ldh a, [hJoyDebounceSrc] + and a + ldh a, [hJoyDown] + jr z, .joyDownSrc +.joyStateSrc + ldh a, [hJoyState] +.joyDownSrc + ldh [hJoySum], a + ldh a, [hJoyDown] + and a + jr z, .sampleAfterPress + ld a, $0f + ld [wVBlankJoyFrameCounter], a + ret +.sampleAfterPress + ld a, [wVBlankJoyFrameCounter] + and a + jr z, .sampleRegular + xor a + ldh [hJoySum], a + ret +.sampleRegular + ld a, $05 + ld [wVBlankJoyFrameCounter], a + ret +; 0x8ad + +TextboxWaitPressAorB_BlinkCursor: ; 8ad (0:8ad) +; Show a blinking cursor in the lower right-hand +; corner of a textbox and wait until A or B is +; pressed. +; +; CAUTION: The cursor has to be shown when calling +; this function or no cursor will be shown at all. +; Waiting on button presses is unaffected by this. + ldh a, [hSpriteWidth] ; hTextBoxCursorBlinkInterval is shared with + push af ; hSpriteWidth and hSpriteHeight, so we need + ldh a, [hSpriteHeight] ; to back them up + push af + xor a + ldh [hTextBoxCursorBlinkInterval], a + ld a, $06 + ldh [hTextBoxCursorBlinkInterval + 1], a ; initially, 0x600 iterations +.loop + push hl + coord hl, (TEXTBOX_WIDTH - 2), (TEXTBOX_Y + TEXTBOX_HEIGHT - 1) + call TextboxBlinkCursor + pop hl + call GetJoypadDebounced + ldh a, [hJoySum] + and (A_BUTTON | B_BUTTON) + jr z, .loop + pop af + ldh [hSpriteHeight], a + pop af + ldh [hSpriteWidth], a + ret + +ButtonSound:: ; 8d2 (0:8d2) + ld a, [wLinkMode] + cp $03 + jr z, .link + call WaitAorB_BlinkCursor + push de + ld de, $5 + call PlaySFX + pop de + ret +.link + ld c, $41 + jp DelayFrames + +WaitAorB_BlinkCursor:: ; 8ea (0:8ea) +.loop + call BlinkCursor + call GetJoypadDebounced + ldh a, [hJoySum] + and (A_BUTTON | B_BUTTON) + ret nz + call RTC + call UpdateTimeOfDayPalettes + ld a, $01 + ldh [hBGMapMode], a + call DelayFrame + jr .loop + +BlinkCursor: ; 904 (0:904) +; Show a blinking cursor in the lower right-hand +; corner of the screen +; Will toggle between cursor and blank every +; 16 frames. + ldh a, [hVBlankCounter] + and $10 + jr z, .cursor_off + ld a, "▼" + jr .save_cursor_state +.cursor_off + ld a, " " +.save_cursor_state + ldcoord_a (SCREEN_WIDTH - 2), (SCREEN_HEIGHT - 1) + ret + +TextboxBlinkCursor:: ; 914 (0:914) +; Show a blinking cursor at the specified position +; that toggles between down arrow and horizontal textbox +; frame tile. +; hl - address of cursor +; hTextBoxCursorBlinkInterval - initial delay between toggling +; subsequent delays will be 0x6FF +; calls of this function +; CAUTION: if the cursor is not shown initially, even initial +; hTextBoxCursorBlinkInterval values will cause no cursor +; to be shown at all. + ld a, [hl] + ld b, a + ld a, "▼" + cp b + jr nz, .showCursorCountdown +.showTextboxFrameCountdown + ldh a, [hTextBoxCursorBlinkInterval] + dec a + ldh [hTextBoxCursorBlinkInterval], a + ret nz + ldh a, [hTextBoxCursorBlinkInterval + 1] + dec a + ldh [hTextBoxCursorBlinkInterval + 1], a + ret nz + ld a, "─" + ld [hl], a + ld a, $ff + ldh [hTextBoxCursorBlinkInterval], a + ld a, $06 + ldh [hTextBoxCursorBlinkInterval + 1], a ; reset to 0x6FF iterations + ret +.showCursorCountdown + ldh a, [hTextBoxCursorBlinkInterval] + and a + ret z + dec a + ldh [hTextBoxCursorBlinkInterval], a + ret nz + dec a + ldh [hTextBoxCursorBlinkInterval], a + ldh a, [hTextBoxCursorBlinkInterval + 1] + dec a + ldh [hTextBoxCursorBlinkInterval + 1], a + ret nz + ld a, $06 + ldh [hTextBoxCursorBlinkInterval + 1], a ; reset to 0x6FF iterations + ld a, "▼" + ld [hl], a + ret diff --git a/home/lcd.asm b/home/lcd.asm index 6641f05..e915806 100644 --- a/home/lcd.asm +++ b/home/lcd.asm @@ -3,78 +3,78 @@ INCLUDE "constants.asm" SECTION "LCD functions", ROM0[$3AE] LCD:: ; 03ae - push af - ldh a, [hLCDCPointer] - and a - jr z, .done - push hl - rla - jr c, .try_hide_sprites - ld a, [rLY] - ld l, a - ld h, HIGH(wLYOverrides) - ld h, [hl] - ldh a, [hLCDCPointer] - ld l, a - ld a, h - ld h, $FF - ld [hl], a - pop hl - pop af - reti + push af + ldh a, [hLCDCPointer] + and a + jr z, .done + push hl + rla + jr c, .try_hide_sprites + ld a, [rLY] + ld l, a + ld h, HIGH(wLYOverrides) + ld h, [hl] + ldh a, [hLCDCPointer] + ld l, a + ld a, h + ld h, $FF + ld [hl], a + pop hl + pop af + reti .try_hide_sprites - ld a, [rLY] - cp $80 - jr nz, .dont_hide - ld hl, rLCDC - res 1, [hl] + ld a, [rLY] + cp $80 + jr nz, .dont_hide + ld hl, rLCDC + res 1, [hl] .dont_hide - pop hl - pop af - reti + pop hl + pop af + reti - ; Seems unused? - ldh a, [hSCX] - ld [rSCX], a - ldh a, [hSCY] - ld [rSCY], a - pop hl + ; Seems unused? + ldh a, [hSCX] + ld [rSCX], a + ldh a, [hSCY] + ld [rSCY], a + pop hl .done - pop af - reti + pop af + reti ; 0:3e1 ; TODO: can this be done using `sine_table`? - db 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 3, 3, 2, 2, 1, 0, -1, -2, -2, -3, -3, -4, -4, -4, -4, -4, -3, -3, -2, -2, -1 + db 0, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4, 3, 3, 2, 2, 1, 0, -1, -2, -2, -3, -3, -4, -4, -4, -4, -4, -3, -3, -2, -2, -1 DisableLCD:: ; 0401 - ld a, [rLCDC] - bit 7, a - ret z - xor a - ld [rIF], a - ld a, [rIE] - ld b, a - res 0, a - ld [rIE], a + ld a, [rLCDC] + bit 7, a + ret z + xor a + ld [rIF], a + ld a, [rIE] + ld b, a + res 0, a + ld [rIE], a .wait - ld a, [rLY] - cp LY_VBLANK + 1 - jr nz, .wait - ld a, [rLCDC] - and $7F ; Shut LCD down - ld [rLCDC], a - xor a - ld [rIF], a - ld a, b - ld [rIE], a - ret + ld a, [rLY] + cp LY_VBLANK + 1 + jr nz, .wait + ld a, [rLCDC] + and $7f ; Shut LCD down + ld [rLCDC], a + xor a + ld [rIF], a + ld a, b + ld [rIE], a + ret EnableLCD:: ; 0423 - ld a, [rLCDC] - set 7, a - ld [rLCDC], a - ret + ld a, [rLCDC] + set 7, a + ld [rLCDC], a + ret diff --git a/home/names.asm b/home/names.asm new file mode 100644 index 0000000..7ce5767 --- /dev/null +++ b/home/names.asm @@ -0,0 +1,23 @@ +INCLUDE "constants.asm" + +if DEBUG +SECTION "GetNthString", ROM0[$3732] +else +SECTION "GetNthString", ROM0[$36F6] +endc + +GetNthString:: +; Return the address of the ath string starting from hl. + and a + ret z + push bc + ld b, a + ld c, "@" +.readChar: + ld a, [hli] + cp c + jr nz, .readChar + dec b + jr nz, .readChar + pop bc + ret diff --git a/home/oam_dma.asm b/home/oam_dma.asm index d76df89..42ecaaf 100644 --- a/home/oam_dma.asm +++ b/home/oam_dma.asm @@ -3,23 +3,23 @@ INCLUDE "constants.asm" SECTION "OAM DMA", ROMX[$4153],BANK[1] WriteOAMDMACodeToHRAM:: ; 4153 - ld c, LOW(hOAMDMA) - ld b, .OAMDMAEnd - .OAMDMA - ld hl, .OAMDMA + ld c, LOW(hOAMDMA) + ld b, .OAMDMAEnd - .OAMDMA + ld hl, .OAMDMA .loop - ld a, [hli] - ld [$ff00+c], a - inc c - dec b - jr nz, .loop - ret + ld a, [hli] + ld [$ff00+c], a + inc c + dec b + jr nz, .loop + ret .OAMDMA ; 4161 - ld a, HIGH(wVirtualOAM) - ldh [rDMA], a - ld a, $28 + ld a, HIGH(wVirtualOAM) + ldh [rDMA], a + ld a, $28 .wait - dec a - jr nz, .wait - ret + dec a + jr nz, .wait + ret .OAMDMAEnd ; 416b diff --git a/home/pic.asm b/home/pic.asm index 60dd6a3..04cf7bb 100644 --- a/home/pic.asm +++ b/home/pic.asm @@ -2,9 +2,9 @@ INCLUDE "constants.asm" SECTION "Decompression Functions", ROM0[$095E] +UncompressSpriteData:: ; 95e (0:95e) ; bankswitches and runs _UncompressSpriteData ; bank is given in a, sprite input stream is pointed to in wSpriteInputPtr -UncompressSpriteData:: ; 95e (0:95e) ld b, a ldh a, [hROMBank] push af @@ -18,11 +18,11 @@ UncompressSpriteData:: ; 95e (0:95e) call Bankswitch ret -; initializes necessary data to load a sprite and runs UncompressSpriteDataLoop _UncompressSpriteData:: ; 976 (0:976) +; initializes necessary data to load a sprite and runs UncompressSpriteDataLoop ld hl, sSpriteBuffer1 - ld c, (2*SPRITEBUFFERSIZE) % $100 - ld b, (2*SPRITEBUFFERSIZE) / $100 + ld c, (2 * SPRITEBUFFERSIZE) % $100 + ld b, (2 * SPRITEBUFFERSIZE) / $100 xor a call ByteFill ld a, $01 ; next call to ReadNextInputBit will read byte @@ -51,12 +51,12 @@ _UncompressSpriteData:: ; 976 (0:976) ld [wSpriteLoadFlags], a ; initialite bit1 to 0 and bit0 to the first input bit ; this will load two chunks of data to sSpriteBuffer1 and sSpriteBuffer2 ; bit 0 decides in which one the first chunk is placed - ; fall through + ; fallthrough +UncompressSpriteDataLoop:: ; uncompresses a chunk from the sprite input data stream (pointed to at wSpriteInputPtr) into sSpriteBuffer1 or sSpriteBuffer2 ; each chunk is a 1bpp sprite. A 2bpp sprite consist of two chunks which are merged afterwards ; note that this is an endless loop which is terminated during a call to MoveToNextBufferPosition by manipulating the stack -UncompressSpriteDataLoop:: ld hl, sSpriteBuffer1 ld a, [wSpriteLoadFlags] bit 0, a @@ -143,10 +143,10 @@ UncompressSpriteDataLoop:: jr nz, .writeZerosLoop jr .readNextInput +MoveToNextBufferPosition:: ; a34 (0:a34) ; moves output pointer to next position ; also cancels the calling function if the all output is done (by removing the return pointer from stack) ; and calls postprocessing functions according to the unpack mode -MoveToNextBufferPosition:: ; a34 (0:a34) ld a, [wSpriteHeight] ld b, a ld a, [wSpriteCurPosY] @@ -206,8 +206,8 @@ MoveToNextBufferPosition:: ; a34 (0:a34) .done jp UnpackSprite -; writes 2 bits (from a) to the output buffer (pointed to from wSpriteOutputPtr) WriteSpriteBitsToBuffer:: ; aa5 (0:aa5) +; writes 2 bits (from a) to the output buffer (pointed to from wSpriteOutputPtr) ld e, a ld a, [wSpriteOutputBitOffset] and a @@ -234,8 +234,8 @@ WriteSpriteBitsToBuffer:: ; aa5 (0:aa5) ld [hl], a ret -; reads next bit from input stream and returns it in a ReadNextInputBit:: ; acc (0:acc) +; reads next bit from input stream and returns it in a ld a, [wSpriteInputBitCounter] dec a jr nz, .curByteHasMoreBitsToRead @@ -250,8 +250,8 @@ ReadNextInputBit:: ; acc (0:acc) and $01 ret -; reads next byte from input stream and returns it in a ReadNextInputByte: ; ae7 (0:ae7) +; reads next byte from input stream and returns it in a ld a, [wSpriteInputPtr] ld l, a ld a, [wSpriteInputPtr + 1] @@ -265,8 +265,8 @@ ReadNextInputByte: ; ae7 (0:ae7) ld a, b ret -; the nth item is 2^n - 1 LengthEncodingOffsetList:: +; the nth item is 2^n - 1 dw %0000000000000001 dw %0000000000000011 dw %0000000000000111 @@ -284,8 +284,8 @@ LengthEncodingOffsetList:: dw %0111111111111111 dw %1111111111111111 -; unpacks the sprite data depending on the unpack mode UnpackSprite:: ; b1b (0:b1b) +; unpacks the sprite data depending on the unpack mode ld a, [wSpriteUnpackMode] cp $02 jp z, UnpackSpriteMode2 @@ -294,11 +294,11 @@ UnpackSprite:: ; b1b (0:b1b) ld hl, sSpriteBuffer1 call SpriteDifferentialDecode ld hl, sSpriteBuffer2 - ; fall through + ; fallthrough +SpriteDifferentialDecode:: ; decodes differential encoded sprite data ; input bit value 0 preserves the current bit value and input bit value 1 toggles it (starting from initial value 0). -SpriteDifferentialDecode:: xor a ld [wSpriteCurPosX], a ld [wSpriteCurPosY], a @@ -382,8 +382,8 @@ SpriteDifferentialDecode:: ld [wSpriteCurPosY], a ret -; decodes the nybble stored in a. Last decoded data is assumed to be in e (needed to determine if initial value is 0 or 1) DifferentialDecodeNybble:: ; bc9 (0:bc9) +; decodes the nybble stored in a. Last decoded data is assumed to be in e (needed to determine if initial value is 0 or 1) srl a ; c=a%2, a/=2 ld c, $00 jr nc, .evenNumber @@ -462,8 +462,8 @@ DecodeNybble1TableFlipped:: dn $e, $6 dn $2, $a -; combines the two loaded chunks with xor (the chunk loaded second is the destination). The source chunk is differentially decoded beforehand. XorSpriteChunks:: ; c23 (0:c23) +; combines the two loaded chunks with xor (the chunk loaded second is the destination). The source chunk is differentially decoded beforehand. xor a ld [wSpriteCurPosX], a ld [wSpriteCurPosY], a @@ -527,8 +527,8 @@ XorSpriteChunks:: ; c23 (0:c23) ld [wSpriteCurPosX], a ret -; reverses the bits in the nybble given in register a ReverseNybble:: ; c93 (0:c93) +; reverses the bits in the nybble given in register a ld de, NybbleReverseTable add e ld e, a @@ -538,8 +538,8 @@ ReverseNybble:: ; c93 (0:c93) ld a, [de] ret -; resets sprite buffer pointers to buffer 1 and 2, depending on wSpriteLoadFlags ResetSpriteBufferPointers:: ; c9d (0:c9d) +; resets sprite buffer pointers to buffer 1 and 2, depending on wSpriteLoadFlags ld a, [wSpriteLoadFlags] bit 0, a jr nz, .buffer2Selected @@ -564,8 +564,8 @@ ResetSpriteBufferPointers:: ; c9d (0:c9d) NybbleReverseTable:: db $0, $8, $4, $c, $2, $a, $6 ,$e, $1, $9, $5, $d, $3, $b, $7 ,$f -; combines the two loaded chunks with xor (the chunk loaded second is the destination). Both chunks are differentially decoded beforehand. UnpackSpriteMode2:: ; cd3 (0:cd3) +; combines the two loaded chunks with xor (the chunk loaded second is the destination). Both chunks are differentially decoded beforehand. call ResetSpriteBufferPointers ld a, [wSpriteFlipped] push af @@ -581,8 +581,8 @@ UnpackSpriteMode2:: ; cd3 (0:cd3) ld [wSpriteFlipped], a jp XorSpriteChunks -; stores hl into the output pointers StoreSpriteOutputPointer:: ; cf3 (0:cf3) +; stores hl into the output pointers ld a, l ld [wSpriteOutputPtr], a ld [wSpriteOutputPtrCached], a diff --git a/home/pokemon.asm b/home/pokemon.asm index 1f51f8e..f990393 100644 --- a/home/pokemon.asm +++ b/home/pokemon.asm @@ -5,10 +5,10 @@ SECTION "3A4B", ROM0[$3A4B] else SECTION "3A4B", ROM0[$3A0F] endc +GetMonHeader:: ; 3a4b (0:3a4b) ; copies the base stat data of a pokemon to wMonHeader ; INPUT: ; [wcb5b] = pokemon ID in dex order -GetMonHeader:: ; 3a4b (0:3a4b) push bc push de push hl @@ -29,7 +29,7 @@ GetMonHeader:: ; 3a4b (0:3a4b) jr .done .egg ld de, EggPicFront - ld b, $55 ; egg sprite dimension + ln b, 5, 5 ; egg sprite dimension ld hl, wMonHSpriteDim ld [hl], b ld hl, wMonHFrontSprite @@ -53,10 +53,10 @@ else SECTION "3AED", ROM0[$3AB1] endc +UncompressMonSprite:: ; 3aed (0:3aed) ; Uncompresses the front or back sprite of the specified mon ; assumes the corresponding mon header is already loaded ; hl contains offset to sprite pointer ($b for front or $d for back) -UncompressMonSprite:: ; 3aed (0:3aed) ld a, [wMonDexIndex] and a ret z @@ -104,12 +104,12 @@ UncompressMonSprite:: ; 3aed (0:3aed) ld a, BANK(AnnonPics) jp UncompressSpriteData -; Uncompress Pokémon Front Srite for +LoadMonFrontSprite:: ; 3b3f +; Uncompress Pokémon Front Sprite for ; mon currently loaded in wMonHeader ; to 0x9000 ; de: destination location ; returns the sprite dimension in c -LoadMonFrontSprite:: ; 3b3f push de ld hl, wMonHFrontSprite - wMonHeader call UncompressMonSprite @@ -117,13 +117,13 @@ LoadMonFrontSprite:: ; 3b3f ld a, [hl] ld c, a pop de - ; fall through - + ; fallthrough + +LoadUncompressedSpriteData:: ; 3b4c (0:3b4c) ; postprocesses uncompressed sprite chunks to a 2bpp sprite and loads it into video ram ; calculates alignment parameters to place both sprite chunks in the center of the 7*7 tile sprite buffers ; de: destination location ; a,c: sprite dimensions (in tiles of 8x8 each) -LoadUncompressedSpriteData:: ; 3b4c (0:3b4c) push de and $0f ldh [hSpriteWidth], a ; each byte contains 8 pixels (in 1bpp), so tiles=bytes for width @@ -172,15 +172,15 @@ LoadUncompressedSpriteData:: ; 3b4c (0:3b4c) call InterlaceMergeSpriteBuffers ret -; fills the sprite buffer (pointed to in hl) with zeros ZeroSpriteBuffer:: ; 3ba1 (0:3ba1) +; fills the sprite buffer (pointed to in hl) with zeros ld bc, SPRITEBUFFERSIZE xor a jp ByteFill +AlignSpriteDataCentered:: ; 3ba8 (0:3ba8) ; copies and aligns the sprite data properly inside the sprite buffer ; sprite buffers are 7*7 tiles in size, the loaded sprite is centered within this area -AlignSpriteDataCentered:: ; 3ba8 (0:3ba8) ldh a, [hSpriteOffset] ld c, a ld b, $00 @@ -206,28 +206,28 @@ AlignSpriteDataCentered:: ; 3ba8 (0:3ba8) jr nz, .columnLoop ret +InterlaceMergeSpriteBuffers:: ; 3bc6 (0:3bc6) ; combines the (7*7 tiles, 1bpp) sprite chunks in buffer 0 and 1 into a 2bpp sprite located in buffer 1 through 2 ; in the resulting sprite, the rows of the two source sprites are interlaced ; de: output address -InterlaceMergeSpriteBuffers:: ; 3bc6 (0:3bc6) ld a, $00 call OpenSRAM push de call _InterlaceMergeSpriteBuffers pop hl ld de, sSpriteBuffer1 - ld c, (2*SPRITEBUFFERSIZE)/16 ; $31, number of 16 byte chunks to be copied + ld c, (2 * SPRITEBUFFERSIZE) / 16 ; $31, number of 16 byte chunks to be copied ldh a, [hROMBank] ld b, a call CopyVideoDataOptimized call CloseSRAM ret +_InterlaceMergeSpriteBuffers:: ; 3bdf (0:3bdf) ; actual implementation of InterlaceMergeSpriteBuffers ; sprite flipping is now done during interlace merge loop ; and not as second loop after regular interlace merge ; to save time -_InterlaceMergeSpriteBuffers:: ; 3bdf (0:3bdf) ld a, [wSpriteFlipped] and a jr nz, .flipped @@ -271,7 +271,7 @@ _InterlaceMergeSpriteBuffers:: ; 3bdf (0:3bdf) ld hl, sSpriteBuffer2 + (SPRITEBUFFERSIZE - 1) ; destination: end of buffer 2 ld de, sSpriteBuffer1 + (SPRITEBUFFERSIZE - 1) ; source 2: end of buffer 1 ld bc, sSpriteBuffer0 + (SPRITEBUFFERSIZE - 1) ; source 1: end of buffer 0 - ld a, SPRITEBUFFERSIZE/2 ; $c4 + ld a, SPRITEBUFFERSIZE / 2 ; $c4 ldh [hSpriteInterlaceCounter], a .interlaceLoopFlipped ld a, [de] diff --git a/home/predef.asm b/home/predef.asm index a9ff091..e6d5019 100644 --- a/home/predef.asm +++ b/home/predef.asm @@ -7,43 +7,43 @@ SECTION "Predef", ROM0[$2FA2] endc Predef:: ; 2fde - ld [wPredefID], a - ldh a, [hROMBank] - push af - ld a, BANK(GetPredefPointer) - call Bankswitch - call GetPredefPointer - call Bankswitch - ld hl, .return - push hl - push de - jr .get_regs + ld [wPredefID], a + ldh a, [hROMBank] + push af + ld a, BANK(GetPredefPointer) + call Bankswitch + call GetPredefPointer + call Bankswitch + ld hl, .return + push hl + push de + jr .get_regs .return - ld a, h - ld [wPredefHL], a - ld a, l - ld [wPredefHL + 1], a - pop hl - ld a, h ; Could have used `pop af` instead - call Bankswitch - ld a, [wPredefHL] - ld h, a - ld a, [wPredefHL + 1] - ld l, a - ret + ld a, h + ld [wPredefHL], a + ld a, l + ld [wPredefHL + 1], a + pop hl + ld a, h ; Could have used `pop af` instead + call Bankswitch + ld a, [wPredefHL] + ld h, a + ld a, [wPredefHL + 1] + ld l, a + ret .get_regs - ld a, [wPredefHL] - ld h, a - ld a, [wPredefHL + 1] - ld l, a - ld a, [wPredefDE] - ld d, a - ld a, [wPredefDE + 1] - ld e, a - ld a, [wPredefBC] - ld b, a - ld a, [wPredefBC + 1] - ld c, a - ret + ld a, [wPredefHL] + ld h, a + ld a, [wPredefHL + 1] + ld l, a + ld a, [wPredefDE] + ld d, a + ld a, [wPredefDE + 1] + ld e, a + ld a, [wPredefBC] + ld b, a + ld a, [wPredefBC + 1] + ld c, a + ret diff --git a/home/print_bcd.asm b/home/print_bcd.asm new file mode 100644 index 0000000..4f647ff --- /dev/null +++ b/home/print_bcd.asm @@ -0,0 +1,113 @@ +INCLUDE "constants.asm" + +if DEBUG +SECTION "BCD Finalize", ROM0[$33a3] +else +SECTION "BCD Finalize", ROM0[$3367] +endc + +PrintLetterDelay:: ; 33a3 (0:33a3) + ld a, [wce5f] + bit 4, a + ret nz + ld a, [wTextBoxFlags] + bit 1, a + ret z + push hl + push de + push bc + ld a, [wTextBoxFlags] + bit 0, a + jr z, .waitOneFrame + ld a, [wce5f] + and $07 + jr .initFrameCnt +.waitOneFrame + ld a, $01 +.initFrameCnt + ld [wVBlankJoyFrameCounter], a +.checkButtons + call GetJoypad + ldh a, [hJoyState] +.checkAButton + bit 0, a ; is the A button pressed? + jr z, .checkBButton + jr .endWait +.checkBButton + bit 1, a ; is the B button pressed? + jr z, .buttonsNotPressed +.endWait + call DelayFrame + jr .done +.buttonsNotPressed ; if neither A nor B is pressed + ld a, [wVBlankJoyFrameCounter] + and a + jr nz, .checkButtons +.done + pop bc + pop de + pop hl + ret +; 0x33e3 + +if DEBUG +SECTION "BCD Functions", ROM0[$3AB2] +else +SECTION "BCD Functions", ROM0[$3A76] +endc + +; function to print a BCD (Binary-coded decimal) number +; de = address of BCD number +; hl = destination address +; c = flags and length +; bit 7: if set, do not print leading zeroes +; if unset, print leading zeroes +; bit 6: if set, left-align the string (do not pad empty digits with spaces) +; if unset, right-align the string +; bits 0-5: length of BCD number in bytes +; Note that bits 5 and 7 are modified during execution. The above reflects +; their meaning at the beginning of the functions's execution. +PrintBCDNumber:: ; 3ab2 (0:3ab2) + ld b, c ; save flags in b + res 7, c + res 6, c ; c now holds the length +.loop + ld a, [de] + swap a + call PrintBCDDigit + ld a, [de] + call PrintBCDDigit + inc de + dec c + jr nz, .loop + bit 7, b ; were any non-zero digits printed? + jr z, .done +.numberEqualsZero ; if every digit of the BCD number is zero + bit 6, b + jr nz, .skipRightAlignmentAdjustment + dec hl ; if the string is right-aligned, it needs +.skipRightAlignmentAdjustment ;to be moved back one space + ld [hl], "0" + call PrintLetterDelay + inc hl +.done + ret + +PrintBCDDigit:: ; 3ad5 (0:3ad5) + and $0f + and a + jr z, .zeroDigit + res 7, b ; unset 7 to indicate that a nonzero +.outputDigit ; digit has been reached + add "0" + ld [hli], a + jp PrintLetterDelay +.zeroDigit + bit 7, b ; either printing leading zeroes or + jr z, .outputDigit ; already reached a nonzero digit? + bit 6, b + ret nz ; left-align, don't pad with space + ld a, " " + ld [hli], a + ret +; 0x3aed
\ No newline at end of file diff --git a/home/print_hex.asm b/home/print_hex.asm new file mode 100644 index 0000000..993e210 --- /dev/null +++ b/home/print_hex.asm @@ -0,0 +1,42 @@ +INCLUDE "constants.asm" + +if DEBUG +SECTION "Print Hexadecimal functions", ROM0[$3597] +else +SECTION "Print Hexadecimal functions", ROM0[$355B] +endc + +PrintHexBytes: ; 3597 (0:3597) +.loop + push bc + call PrintHexByte + pop bc + dec c + jr nz, .loop + ret + +PrintHexByte:: ; 35a0 (0:35a0) + ld a, [de] + swap a + and $0f + call PrintHexDigit + ld [hli], a + ld a, [de] + and $0f + call PrintHexDigit + ld [hli], a + inc de + ret + +PrintHexDigit: ; 35b2 (0:35b2) + ld bc, .hexDigitTable + add c + ld c, a + ld a, $00 + adc b + ld b, a + ld a, [bc] + ret + +.hexDigitTable: + db "0123456789ABCDEF" diff --git a/home/print_num.asm b/home/print_num.asm new file mode 100644 index 0000000..3ae1c10 --- /dev/null +++ b/home/print_num.asm @@ -0,0 +1,252 @@ +INCLUDE "constants.asm" + +if DEBUG +SECTION "Number Printing Functions", ROM0[$3460] +else +SECTION "Number Printing Functions", ROM0[$3424] +endc + +PrintNumber:: ; 3460 (0:3460) +; function to print a number +; de = address of number in little-endian format +; hl = destination address +; b = flags and length +; bit 7: if set, do not print leading zeroes +; if unset, print leading zeroes +; bit 6: if set, left-align the string (do not pad empty digits with spaces) +; if unset, right-align the string +; bits 0-5: length of number in bytes +; 01 - 1 byte +; 02 - 2 bytes +; <> - 3 bytes +; c = number of digits from 2 to 7 +; For 1-digit numbers, add the value to char "0" +; instead of calling PrintNumber. +; This function works as follow +; There are three temporary registers +; - hPrintNumDividend, +; - hPrintNumDivisor, +; - hPrintNumTemp +; All are three bytes long and organized in big-endian order. +; To produce digits, PrintNumber is going to +; 1. Store Input in hPrintNumDividend +; 1a. Init hPrintNumLeadingDigit to zero (no prior leading digit) +; 2. Repeatedly call .PrintDigit for required digits 7 thru 3: +; 2a. Store divisor in hPrintNumDivisor +; 2b. Divide dividend by divisor to get digit +; 2c. hPrintNumTemp is used, because dividend < divisor might +; not be immediately visible in byte-wise division +; 2d. Update hPrintNumLeadingDigit in case digit > 0 +; 3. Perform the same operations for two digits as byte-wide operations +; as opposed to three-byte-wide operations +; 4. Check if at least one non-zero digit was printed, else print zero. +; 5. Done. + push bc + xor a + ldh [hPrintNumLeadingDigit], a + ldh [hPrintNumDividend], a + ldh [hPrintNumDividend + 1], a + ld a, b + and $0f + cp $01 + jr z, .byte + cp $02 + jr z, .word + ld a, [de] + ldh [hPrintNumDividend], a + inc de + ld a, [de] + ldh [hPrintNumDividend + 1], a + inc de + ld a, [de] + ldh [hPrintNumDividend + 2], a + jr .start +.word + ld a, [de] + ldh [hPrintNumDividend + 1], a + inc de + ld a, [de] + ldh [hPrintNumDividend + 2], a + jr .start +.byte + ld a, [de] + ldh [hPrintNumDividend + 2], a +.start + push de + ld d, b + ld a, c + ld b, a + xor a + ld c, a + ld a, b + cp $02 + jr z, .two_digits + cp $03 + jr z, .three_digits + cp $04 + jr z, .four_digits + cp $05 + jr z, .five_digits + cp $06 + jr z, .six_digits +.seven_digits + ld a, 1000000 / $10000 % $100 + ldh [hPrintNumDivisor], a + ld a, 1000000 / $100 % $100 + ldh [hPrintNumDivisor + 1], a + ld a, 1000000 % $100 + ldh [hPrintNumDivisor + 2], a + call .PrintDigit + call .AdvancePointer +.six_digits + ld a, 100000 / $10000 % $100 + ldh [hPrintNumDivisor], a + ld a, 100000 / $100 % $100 + ldh [hPrintNumDivisor + 1], a + ld a, 100000 % $100 + ldh [hPrintNumDivisor + 2], a + call .PrintDigit + call .AdvancePointer +.five_digits + xor a + ldh [hPrintNumDivisor], a + ld a, 10000 / $100 + ldh [hPrintNumDivisor + 1], a + ld a, 10000 % $100 + ldh [hPrintNumDivisor + 2], a + call .PrintDigit + call .AdvancePointer +.four_digits + xor a + ldh [hPrintNumDivisor], a + ld a, 1000 / $100 + ldh [hPrintNumDivisor + 1], a + ld a, 1000 % $100 + ldh [hPrintNumDivisor + 2], a + call .PrintDigit + call .AdvancePointer +.three_digits + xor a + ldh [hPrintNumDivisor], a + xor a + ldh [hPrintNumDivisor + 1], a + ld a, 100 + ldh [hPrintNumDivisor + 2], a + call .PrintDigit + call .AdvancePointer +.two_digits + ld c, $00 + ldh a, [hPrintNumDividend + 2] +.mod_10 + cp $0a + jr c, .modded_10 + sub $0a + inc c + jr .mod_10 +.modded_10 + ld b, a + ldh a, [hPrintNumLeadingDigit] + or c + ldh [hPrintNumLeadingDigit], a + jr nz, .LeadingNonZero + call .PrintLeadingZero + jr .PrintLeastSignificantDigit +.LeadingNonZero + ld a, "0" + add c + ld [hl], a +.PrintLeastSignificantDigit + call .AdvancePointer + ld a, "0" + add b + ld [hli], a + pop de + pop bc + ret + +.PrintDigit: ; 3525 (0:3525) + ld c, $00 +.loop + ldh a, [hPrintNumDivisor] + ld b, a + ldh a, [hPrintNumDividend] + ldh [hPrintNumTemp], a ; store high byte in case dividend < divisor + cp b ; in subsequent bytes + jr c, .DividendLessThanDivisor ; dividend < divisor --> the digit is zero + sub b + ldh [hPrintNumDividend], a + ldh a, [hPrintNumDivisor + 1] + ld b, a + ldh a, [hPrintNumDividend + 1] + ldh [hPrintNumTemp + 1], a ; store mid byte in case dividend < divisor + cp b ; in subsequent byte + jr nc, .SubtractMidNoBorrow + ldh a, [hPrintNumDividend] ; try to borrow from upper byte + or $00 + jr z, .DividendLessThanDivisorRestoreHigh ; can't borrow, because dividend < divisor + dec a + ldh [hPrintNumDividend], a + ldh a, [hPrintNumDividend + 1] +.SubtractMidNoBorrow + sub b + ldh [hPrintNumDividend + 1], a + ldh a, [hPrintNumDivisor + 2] + ld b, a + ldh a, [hPrintNumDividend + 2] + ldh [hPrintNumTemp + 2], a ; store low byte in case dividend < divisor, which + cp b ; goes unused, because the algorithm doesn't + jr nc, .SubtractLoNoBorrow ; clobber hPrintNumDividend + 2 in that case + ldh a, [hPrintNumDividend + 1] + and a + jr nz, .SubtractLoBorrow + ldh a, [hPrintNumDividend] ; if mid byte == zero, we need to borrow from high + and a + jr z, .DividendLessThanDivisorRestoreMid +.SubtractLoBorrowFromHigh + dec a + ldh [hPrintNumDividend], a + xor a +.SubtractLoBorrow + dec a + ldh [hPrintNumDividend + 1], a + ldh a, [hPrintNumDividend + 2] +.SubtractLoNoBorrow + sub b + ldh [hPrintNumDividend + 2], a + inc c + jr .loop +.DividendLessThanDivisorRestoreMid + ldh a, [hPrintNumTemp + 1] + ldh [hPrintNumDividend + 1], a +.DividendLessThanDivisorRestoreHigh + ldh a, [hPrintNumTemp] + ldh [hPrintNumDividend], a +.DividendLessThanDivisor + ldh a, [hPrintNumLeadingDigit] + or c + jr z, .PrintLeadingZero + ld a, "0" + add c + ld [hl], a + ldh [hPrintNumLeadingDigit], a + ret +.PrintLeadingZero: +; prints a leading zero unless they are turned off in the flags + bit 7, d + ret z + ld [hl], "0" + ret + +.AdvancePointer: ; 3589 (0:3589) +; increments the pointer unless leading zeroes are not being printed, +; the number is left-aligned, and no nonzero digits have been printed yet + bit 7, d ; print leading zeroes? + jr nz, .inc + bit 6, d ; left alignment or right alignment? + jr z, .inc + ldh a, [hPrintNumLeadingDigit] + and a + ret z ; don't advance if leading digit is zero +.inc + inc hl + ret diff --git a/home/serial.asm b/home/serial.asm index 61510b0..48d6832 100644 --- a/home/serial.asm +++ b/home/serial.asm @@ -3,53 +3,52 @@ INCLUDE "constants.asm" SECTION "Serial handler", ROM0[$602] Serial:: - push af - push bc - push de - push hl - ldh a, [hLinkPlayerNumber] - inc a - jr z, .init_player_number + push af + push bc + push de + push hl + ldh a, [hLinkPlayerNumber] + inc a + jr z, .init_player_number - ld a, [rSB] - ldh [hSerialReceive], a - ldh a, [hSerialSend] - ld [rSB], a - ldh a, [hLinkPlayerNumber] - cp 2 - jr z, .done - ld a, 1 << rSC_ON - ld [rSC], a - jr .done + ld a, [rSB] + ldh [hSerialReceive], a + ldh a, [hSerialSend] + ld [rSB], a + ldh a, [hLinkPlayerNumber] + cp 2 + jr z, .done + ld a, 1 << rSC_ON + ld [rSC], a + jr .done .init_player_number - ld a, [rSB] - ldh [hSerialReceive], a - ldh [hLinkPlayerNumber], a - cp 2 - jr z, .master - xor a - ld [rSB], a - ld a, 3 - ld [rDIV], a + ld a, [rSB] + ldh [hSerialReceive], a + ldh [hLinkPlayerNumber], a + cp 2 + jr z, .master + xor a + ld [rSB], a + ld a, 3 + ld [rDIV], a .wait - ld a, [rDIV] - bit 7, a - jr nz, .wait - ld a, 1 << rSC_ON - ld [rSC], a - jr .done + ld a, [rDIV] + bit 7, a + jr nz, .wait + ld a, 1 << rSC_ON + ld [rSC], a + jr .done .master - xor a - ld [rSB], a - + xor a + ld [rSB], a .done - ld a, 1 - ldh [hSerialReceived], a - ld a, SERIAL_NO_DATA_BYTE - ldh [hSerialSend], a - pop hl - pop de - pop bc - pop af - reti + ld a, 1 + ldh [hSerialReceived], a + ld a, SERIAL_NO_DATA_BYTE + ldh [hSerialSend], a + pop hl + pop de + pop bc + pop af + reti diff --git a/home/sram.asm b/home/sram.asm index 03d4411..87f2335 100644 --- a/home/sram.asm +++ b/home/sram.asm @@ -7,19 +7,19 @@ SECTION "SRAM functions", ROM0[$326B] endc OpenSRAM:: ; 32a7 - push af - ld a, 1 - ld [MBC3LatchClock], a - ld a, SRAM_ENABLE - ld [MBC3SRamEnable], a - pop af - ld [MBC3SRamBank], a - ret + push af + ld a, 1 + ld [MBC3LatchClock], a + ld a, SRAM_ENABLE + ld [MBC3SRamEnable], a + pop af + ld [MBC3SRamBank], a + ret CloseSRAM:: ; 32b7 - push af - ld a, SRAM_DISABLE - ld [MBC3LatchClock], a - ld [MBC3SRamEnable], a - pop af - ret + push af + ld a, SRAM_DISABLE + ld [MBC3LatchClock], a + ld [MBC3SRamEnable], a + pop af + ret diff --git a/home/text.asm b/home/text.asm new file mode 100644 index 0000000..83bbd42 --- /dev/null +++ b/home/text.asm @@ -0,0 +1,368 @@ +INCLUDE "constants.asm" + +SECTION "Text Commands", ROM0[$107e] + +ScrollTextUpOneLine:: ; 107e (0:107e) +; move both rows of text in the normal text box up one row +; always called twice in a row +; first time, copy the two rows of text to the "in between" rows that are usually emtpy +; second time, copy the bottom row of text into the top row of text + coord hl, TEXTBOX_X, TEXTBOX_INNERY ; top row of text + coord de, TEXTBOX_X, TEXTBOX_INNERY - 1 ; empty line above text + ld b, TEXTBOX_WIDTH * 3 +.copyText + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .copyText + coord hl, TEXTBOX_INNERX, TEXTBOX_INNERY + 2 + ld a, " " + ld b, TEXTBOX_INNERW +.clearText + ld [hli], a + dec b + jr nz, .clearText + ld b, $05 ; wait five frames +.waitFrame + call DelayFrame + dec b + jr nz, .waitFrame + ret + +ProtectedWaitBGMap:: ; 10a0 (0:10a0) + push bc + call WaitBGMap + pop bc + ret + +TextCommandProcessor:: ; 10a6 (0:10a6) +; Process a string of text commands +; at hl and write text to bc + ld a, [wTextBoxFlags] + push af + set 1, a + ld [wTextBoxFlags], a + ld a, c + ld [wTextDest], a + ld a, b + ld [wTextDest + 1], a + ; fall through + +NextTextCommand:: ; 10b7 (0:10b7) + ld a, [hli] + cp "@" ; terminator + jr nz, .doTextCommand + pop af + ld [wTextBoxFlags], a + ret +.doTextCommand + push hl + ld hl, TextCommands + push bc + add a + ld b, $00 + ld c, a + add hl, bc + pop bc + ld a, [hli] + ld h, [hl] + ld l, a + jp hl + +Text_TX_BOX:: ; 10d0 (0:10d0) +; TX_BOX +; draw a box +; little endian +; [$04][addr][height][width] + pop hl + 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 DrawTextBox + pop hl + jr NextTextCommand + +Text_TX:: ; 10e2 (0:10e2) +; TX +; write text until "@" +; [$00]["...@"] + pop hl + ld d, h + ld e, l + ld h, b + ld l, c + call PlaceString + ld h, d + ld l, e + inc hl + jr NextTextCommand + +Text_TX_RAM:: ; 10ef (0:10ef) +; text_from_ram +; write text from a ram address +; little endian +; [$01][addr] + pop hl + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + push hl + ld h, b + ld l, c + call PlaceString + pop hl + jr NextTextCommand + +Text_TX_BCD:: ; 10fd (0:10fd) +; TX_BCD +; write bcd from address, typically ram +; [$02][addr][flags] +; flags: see PrintBCDNumber + pop hl + 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 + jr NextTextCommand + +Text_TX_MOVE:: ; 110f (0:110f) +; TX_MOVE +; move to a new tile +; [$03][addr] + pop hl + ld a, [hli] + ld [wTextDest], a + ld c, a + ld a, [hli] + ld [wTextDest + 1], a + ld b, a + jp NextTextCommand + +Text_TX_LOW:: ; 111d (0:111d) +; TX_LOW +; write text at (1,16) +; [$05] + pop hl + coord bc, TEXTBOX_INNERX, TEXTBOX_INNERY + 2 + jp NextTextCommand +; 0x1124 + +Text_WAIT_BUTTON:: ; 1124 (0:1124) +; TX_WAITBUTTON +; wait for button press +; show arrow +; [06] + ld a, [wLinkMode] + cp $03 + jp z, Text_TX_LINK_WAIT_BUTTON + ld a, "▼" + ldcoord_a TEXTBOX_WIDTH - 2, TEXTBOX_Y + TEXTBOX_HEIGHT - 1 + push bc + call ButtonSound + pop bc + ld a, "─" + ldcoord_a TEXTBOX_WIDTH - 2, TEXTBOX_Y + TEXTBOX_HEIGHT - 1 + pop hl + jp NextTextCommand + +Text_TX_SCROLL:: ; 113f (0:113f) +; TX_SCROLL +; pushes text up two lines and sets the BC cursor to the border tile +; below the first character column of the text box. +; [07] + ld a, "─" + ldcoord_a TEXTBOX_WIDTH - 2, TEXTBOX_Y + TEXTBOX_HEIGHT - 1 + call ScrollTextUpOneLine + call ScrollTextUpOneLine + pop hl + coord bc, TEXTBOX_INNERX, TEXTBOX_INNERY + 2 + jp NextTextCommand + +Text_START_ASM:: ; 1151 (0:1151) +; TX_ASM +; Executes code following this command. +; Text processing is resumed upon returning. +; [08][asm...ret] + pop hl + ld de, NextTextCommand + push de + jp hl + +Text_TX_NUM:: ; 1157 (0:1157) +; TX_NUM +; [$09][addr][hi:bytes lo:digits] + pop hl + 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 $0f + ld c, a + ld a, b + and $f0 + swap a + set 6, a + ld b, a + call PrintNumber + ld b, h + ld c, l + pop hl + jp NextTextCommand +; 0x1175 + +Text_TX_EXIT: ; 1175 (0:1175) +; TX_EXIT +; [$0A] + push bc + call GetJoypad + ldh a, [hJoyState] + and (A_BUTTON | B_BUTTON) + jr nz, .done + ld c, 30 + call DelayFrames +.done + pop bc + pop hl + jp NextTextCommand +; 0x1189 + +Text_PlaySound:: ; 1189 (0:1189) +; Text_PlaySound +; [0B|0E..13] Play Sound Effects +; [14..16] Play Pokémon Cries + pop hl + push bc + dec hl + ld a, [hli] + ld b, a + push hl + ld hl, .soundTable +.loop + ld a, [hli] + cp b + jr z, .found + inc hl + inc hl + jr .loop +.found + cp $14 + jr z, .playCry + cp $15 + jr z, .playCry + cp $16 + jr z, .playCry + push de + ld e, [hl] + inc hl + ld d, [hl] + call PlaySFX + call WaitSFX + pop de + pop hl + pop bc + jp NextTextCommand +.playCry + push de + ld e, [hl] + inc hl + ld d, [hl] + call PlayCry + pop de + pop hl + pop bc + jp NextTextCommand + +.soundTable: + dbw TX_SOUND_0B, $0063 + dbw TX_SOUND_12, $006B + dbw TX_SOUND_0E, $0066 + dbw TX_SOUND_0F, $0067 + dbw TX_SOUND_10, $0068 + dbw TX_SOUND_11, $0069 + dbw TX_SOUND_13, $0027 + dbw TX_CRY_14, MON_NIDORINA ; or MON_LEAFY? + dbw TX_CRY_15, MON_PIGEOT + dbw TX_CRY_16, MON_JUGON + +Text_TX_DOTS: ; 11e1 (0:11e1) + pop hl + ld a, [hli] + ld d, a + push hl + ld h, b + ld l, c +.loop + ld a, "…" + ld [hli], a + push de + call GetJoypad + pop de + ldh a, [hJoyState] + and (A_BUTTON | B_BUTTON) + jr nz, .next + ld c, 10 + call DelayFrames +.next + dec d + jr nz, .loop + ld b, h + ld c, l + pop hl + jp NextTextCommand + +Text_TX_LINK_WAIT_BUTTON:: ; 1203 (0:1203) + push bc + call ButtonSound + pop bc + pop hl + jp NextTextCommand +; 0x120c + +TextCommands:: ; 120c + dw Text_TX + dw Text_TX_RAM + dw Text_TX_BCD + dw Text_TX_MOVE + dw Text_TX_BOX + dw Text_TX_LOW + dw Text_WAIT_BUTTON + dw Text_TX_SCROLL + dw Text_START_ASM + dw Text_TX_NUM + dw Text_TX_EXIT + dw Text_PlaySound + dw Text_TX_DOTS + dw Text_TX_LINK_WAIT_BUTTON + dw Text_PlaySound + dw Text_PlaySound + dw Text_PlaySound + dw Text_PlaySound + dw Text_PlaySound + dw Text_PlaySound + dw Text_PlaySound + dw Text_PlaySound + dw Text_PlaySound diff --git a/home/unknown.asm b/home/unknown.asm index c216f62..5b9a6e1 100644 --- a/home/unknown.asm +++ b/home/unknown.asm @@ -7,10 +7,10 @@ SECTION "Empty function", ROM0[$2F5B] endc InexplicablyEmptyFunction:: ; 2f97 -REPT 16 - nop -ENDR - ret +rept 16 + nop +endr + ret ; TODO: @@ -21,14 +21,14 @@ ENDR SECTION "Unknown functions", ROM0[$1FF4] _1FF4:: ; 1ff4 - ld a, BANK(s0_a600) - call OpenSRAM - ld hl, s0_a600 ; TODO: label this. - ld bc, 7 - xor a - call ByteFill - call CloseSRAM - ret + ld a, BANK(s0_a600) + call OpenSRAM + ld hl, s0_a600 ; TODO: label this. + ld bc, 7 + xor a + call ByteFill + call CloseSRAM + ret _2007:: ; 2007 ld a, BANK(s0_a600) @@ -65,13 +65,13 @@ if DEBUG ._209e: endc - ld hl, hHours + ld hl, hRTCHours ld de, wcbd2 call _20DC - ld hl, hMinutes + ld hl, hRTCMinutes ld de, wcbd2 + 3 call _20DC - ldh a, [hDays] + ldh a, [hRTCDays] and 7 add $71 ; Sunday ld [wcbd2 + 6], a @@ -79,7 +79,7 @@ endc ld [wcbd2 + 9], a inc a ; mobile ld [wcbd2 + 11], a - ldh a, [hSeconds] + ldh a, [hRTCSeconds] and 1 ret z ld a, $70 ; : diff --git a/home/vblank.asm b/home/vblank.asm index 334cef4..33bbd40 100644 --- a/home/vblank.asm +++ b/home/vblank.asm @@ -3,29 +3,298 @@ INCLUDE "constants.asm" SECTION "VBlank handler", ROM0[$150] VBlank:: ; 0150 - push af - push bc - push de - push hl - ldh a, [hVBlank] - and 3 - ld e, a - ld d, 0 - ld hl, .blanks - add hl, de - add hl, de - ld a, [hli] - ld h, [hl] - ld l, a - ld de, .return - push de - jp hl + push af + push bc + push de + push hl + ldh a, [hVBlank] + and 3 + ld e, a + ld d, 0 + ld hl, .blanks + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + ld de, .return + push de + jp hl .return - pop hl - pop de - pop bc - pop af - reti + pop hl + pop de + pop bc + pop af + reti .blanks - ; TODO + dw VBlank0 + dw VBlank1 + dw VBlank2 + dw VBlank3 + +VBlank0:: ; 175 (0:175) +; rng +; scx, scy, wy, wx +; bg map +; row/column redraw +; copy 2bpp +; copy 1bpp +; animate tileset +; copy far 2bpp +; enable oam sprites +; oam +; joypad +; sound / serial / lcd_stat + ldh a, [hVBlankCounter] + inc a + ldh [hVBlankCounter], a + bit 0, a + jr nz, .even_frame + ldh a, [hRTCRandom] + ld b, a + ldh a, [rLY] + adc b +.even_frame + ; advance random variables + ld b, a + ldh a, [hRandomAdd] + adc b + ldh [hRandomAdd], a + ld b, a + ldh a, [hRandomSub] + sbc b + ldh [hRandomSub], a + ldh a, [hRTCSeconds] + ldh [hRTCRandom], a + ldh a, [hROMBank] + ld [wVBlankSavedROMBank], a + ldh a, [hSCX] + ldh [rSCX], a + ldh a, [hSCY] + ldh [rSCY], a + ld a, [wDisableVBlankWYUpdate] + and a + jr nz, .ok + ldh a, [hWY] + ldh [rWY], a + ldh a, [hWX] + ldh [rWX], a +.ok + call AutoBgMapTransfer + call RedrawRowOrColumn + call VBlankCopy + call VBlankCopyDouble + call AnimateTileset + call VBlankCopyFar + call EnableSprites + call hOAMDMA + xor a + ld [wVBlankOccurred], a + ld a, [wVBlankJoyFrameCounter] + and a + jr z, .skipDec + dec a + ld [wVBlankJoyFrameCounter], a +.skipDec + call Joypad + xor a + ldh [rIF], a + ld a, (1 << SERIAL | 1 << LCD_STAT) + ldh [rIE], a + ld a, (1 << LCD_STAT) + ldh [rIF], a + ei + call UpdateSound + ld a, [wVBlankSavedROMBank] + call Bankswitch + di + xor a + ldh [rIF], a + ld a, (1 << JOYPAD | 1 << SERIAL | 1 << TIMER | 1 << LCD_STAT | 1 << VBLANK) + ldh [rIE], a + ret + +VBlank1:: ; 1f6 (0:1f6) +; Simple VBlank +; +; scx, scy +; dmg pals +; bg map +; copy 2bpp +; oam +; sound / lcd_stat +; no counters! + ldh a, [hROMBank] + ld [wVBlankSavedROMBank], a + ldh a, [hSCX] + ldh [rSCX], a + ldh a, [hSCY] + ldh [rSCY], a + ld a, [wBGP] + ldh [rBGP], a + ld a, [wOBP0] + ldh [rOBP0], a + ld a, [wOBP1] + ldh [rOBP1], a + call AutoBgMapTransfer + call VBlankCopy + ld a, [wDisableVBlankOAMUpdate] + and a + jr nz, .skip_oam + call hOAMDMA +.skip_oam + xor a + ld [wVBlankOccurred], a + xor a + ldh [rIF], a + ld a, (1 << LCD_STAT) + ldh [rIE], a + ldh [rIF], a + ei + call UpdateSound + ld a, [wVBlankSavedROMBank] + call Bankswitch + di + xor a + ldh [rIF], a + ld a, (1 << JOYPAD | 1 << SERIAL | 1 << TIMER | 1 << LCD_STAT | 1 << VBLANK) + ldh [rIE], a + ret + +VBlank2:: ; 241 (0:241) +; rng +; scx, scy, wy, wx +; joypad +; bg map +; row/column redraw +; copy 2bpp +; copy 1bpp +; copy far 2bpp +; oam +; sound + ldh a, [hVBlankCounter] + inc a + ldh [hVBlankCounter], a + bit 0, a + jr nz, .even_frame + ldh a, [rLY] +.even_frame + ; advance random variables + ld b, a + ldh a, [hRandomAdd] + adc b + ldh [hRandomAdd], a + ld b, a + ldh a, [hRandomSub] + sbc b + ldh [hRandomSub], a + call Joypad + ldh a, [hROMBank] + ld [wVBlankSavedROMBank], a + ldh a, [hSCX] + ldh [rSCX], a + ldh a, [hSCY] + ldh [rSCY], a + ld a, [wDisableVBlankWYUpdate] + and a + jr nz, .ok + ldh a, [hWY] + ldh [rWY], a + ldh a, [hWX] + ldh [rWX], a +.ok + call AutoBgMapTransfer + call RedrawRowOrColumn + call VBlankCopy + call VBlankCopyDouble + call VBlankCopyFar + call hOAMDMA + xor a + ld [wVBlankOccurred], a + ld a, [wVBlankJoyFrameCounter] + and a + jr z, .skipDec + dec a + ld [wVBlankJoyFrameCounter], a +.skipDec + call UpdateSound + ld a, [wVBlankSavedROMBank] + call Bankswitch + ret + +VBlank3:: ; 2a0 (0:2a0) +; rng +; joypad +; scx, scy, wy, wx +; bg map +; row/column redraw +; copy 2bpp +; copy 1bpp +; animate tileset +; copy far 2bpp +; enable oam sprites +; oam +; sound / lcd_stat + ldh a, [hVBlankCounter] + inc a + ldh [hVBlankCounter], a + bit 0, a + jr nz, .even_frame + ldh a, [rLY] +.even_frame + ld b, a + ldh a, [hRandomAdd] + adc b + ldh [hRandomAdd], a + ld b, a + ldh a, [hRandomSub] + sbc b + ldh [hRandomSub], a + call Joypad + ldh a, [hROMBank] + ld [wVBlankSavedROMBank], a + ldh a, [hSCX] + ldh [rSCX], a + ldh a, [hSCY] + ldh [rSCY], a + ld a, [wDisableVBlankWYUpdate] + and a + jr nz, .ok + ldh a, [hWY] + ldh [rWY], a + ldh a, [hWX] + ldh [rWX], a +.ok + call AutoBgMapTransfer + call RedrawRowOrColumn + call VBlankCopy + call VBlankCopyDouble + call AnimateTileset + call VBlankCopyFar + call EnableSprites + call hOAMDMA + xor a + ld [wVBlankOccurred], a + ld a, [wVBlankJoyFrameCounter] + and a + jr z, .skipDec + dec a + ld [wVBlankJoyFrameCounter], a +.skipDec + xor a + ldh [rIF], a + ld a, (1 << LCD_STAT) + ldh [rIE], a + ldh [rIF], a + ei + call UpdateSound + ld a, [wVBlankSavedROMBank] + call Bankswitch + di + xor a + ldh [rIF], a + ld a, (1 << JOYPAD | 1 << SERIAL | 1 << TIMER | 1 << LCD_STAT | 1 << VBLANK) + ldh [rIE], a + ret +; 0x317 diff --git a/home/vcopy.asm b/home/vcopy.asm new file mode 100644 index 0000000..a453da5 --- /dev/null +++ b/home/vcopy.asm @@ -0,0 +1,616 @@ +INCLUDE "constants.asm" +INCLUDE "vram.asm" + +SECTION "Copy Routines used by VBlank ISR", ROM0[$123a] + +RedrawRowOrColumn:: ; 123a (0:123a) +; This function redraws a BG row of height 2 or a BG column of width 2. +; One of its main uses is redrawing the row or column that will be exposed upon +; scrolling the BG when the player takes a step. Redrawing only the exposed +; row or column is more efficient than redrawing the entire screen. +; However, this function is also called repeatedly to redraw the whole screen +; when necessary. It is also used in trade animation and elevator code. +; This also implements the flashlight drawing distance effect, which takes +; multiple frames in either direction to complete + ldh a, [hRedrawRowOrColumnMode] + and a + ret z + cp $03 + jr nc, .flashlight_effect + ld b, a + xor a + ldh [hRedrawRowOrColumnMode], a + dec b + jr nz, .redrawRow +.redrawColumn + ld hl, wRedrawRowOrColumnSrcTiles + ldh a, [hRedrawRowOrColumnDest] + ld e, a + ldh a, [hRedrawRowOrColumnDest + 1] + ld d, a + ld c, SCREEN_HEIGHT +.col_loop + ld a, [hli] + ld [de], a + inc de + ld a, [hli] + ld [de], a + ld a, BG_MAP_WIDTH - 1 + add e + ld e, a + jr nc, .noCarry + inc d +.noCarry +; the following 4 lines wrap us from bottom to top if necessary + ld a, d + and HIGH(vBGMap1 - vBGMap0 - $01) + or HIGH(vBGMap0) + ld d, a + dec c + jr nz, .col_loop + xor a + ldh [hRedrawRowOrColumnMode], a + ret +.redrawRow + ld hl, wRedrawRowOrColumnSrcTiles + ldh a, [hRedrawRowOrColumnDest] + ld e, a + ldh a, [hRedrawRowOrColumnDest + 1] + ld d, a + push de + call .DrawHalf + pop de + ld a, BG_MAP_WIDTH ; width of VRAM background map + add e + ld e, a + ; fallthrough (draw lower half) + +.DrawHalf + ld c, SCREEN_WIDTH / 2 +.row_loop + ld a, [hli] + ld [de], a + inc de + ld a, [hli] + ld [de], a + ld a, e + inc a +; the following 6 lines wrap us from the right edge to the left edge if necessary + and BG_MAP_WIDTH - 1 ; mask lower address bits + ld b, a + ld a, e + and ($FF ^ (BG_MAP_WIDTH - 1)) ; mask upper address bits + or b + ld e, a + dec c + jr nz, .row_loop + ret +.flashlight_effect + dec a + dec a + dec a + ld c, a + ld b, $00 + ld hl, .flashlight_effect_table + add hl, bc + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + jp hl + +.flashlight_effect_table + dw RedrawFlashlightRow0 ; $1310 + dw RedrawFlashlightRow0 ; $1310 + dw RedrawFlashlightColumn0 ; $12C3 + dw RedrawFlashlightColumn0 ; $12C3 + dw RedrawFlashlightRow1 ; $1329 + dw RedrawFlashlightRow1 ; $1329 + dw RedrawFlashlightColumn1 ; $12DC + dw RedrawFlashlightColumn1 ; $12DC + dw RedrawFlashlightRow2 ; $1335 + dw RedrawFlashlightRow2 ; $1335 + dw RedrawFlashlightColumn2 ; $12E8 + dw RedrawFlashlightColumn2 ; $12E8 + dw RedrawFlashlightRow3 ; $134E + dw RedrawFlashlightRow3 ; $134E + dw RedrawFlashlightColumn3 ; $1301 + dw RedrawFlashlightColumn3 ; $1301 + +RedrawFlashlightColumn0:: ; 12c3 (0:12c3) + ldh a, [hSCX] + and $07 + ret nz ; wait till we moved one complete tile in X + ld a, [wRedrawFlashlightDst0] + ld e, a + ld a, [wRedrawFlashlightDst0 + 1] + ld d, a + ld a, [wRedrawFlashlightSrc0] + ld l, a + ld a, [wRedrawFlashlightSrc0 + 1] + ld h, a + call _RedrawFlashlightColumn + ret + +RedrawFlashlightColumn1:: ; 12dc (0:12dc) + ld a, [wRedrawFlashlightBlackDst0] + ld e, a + ld a, [wRedrawFlashlightBlackDst0 + 1] + ld d, a + call _RedrawFlashlightColumnBlack + ret +; 0x12e8 + +RedrawFlashlightColumn2:: ; 12e8 (0:12e8) + ldh a, [hSCX] + and $0f + ret nz ; wait till we moved two complete tiles in X + ld a, [wRedrawFlashlightDst1] + ld e, a + ld a, [wRedrawFlashlightDst1 + 1] + ld d, a + ld a, [wRedrawFlashlightSrc1] + ld l, a + ld a, [wRedrawFlashlightSrc1 + 1] + ld h, a + call _RedrawFlashlightColumn + ret + +RedrawFlashlightColumn3:: ; 1301 (0:1301) + ld a, [wRedrawFlashlightBlackDst1] + ld e, a + ld a, [wRedrawFlashlightBlackDst1 + 1] + ld d, a + call _RedrawFlashlightColumnBlack + xor a + ldh [hRedrawRowOrColumnMode], a ; end flashlight redraw + ret + +RedrawFlashlightRow0:: ; 1310 (0:1310) + ldh a, [hSCY] + and $07 + ret nz ; wait till we moved one complete tile in Y + ld a, [wRedrawFlashlightDst0] + ld e, a + ld a, [wRedrawFlashlightDst0 + 1] + ld d, a + ld a, [wRedrawFlashlightSrc0] + ld l, a + ld a, [wRedrawFlashlightSrc0 + 1] + ld h, a + call _RedrawFlashlightRow + ret + +RedrawFlashlightRow1:: ; 1329 (0:1329) + ld a, [wRedrawFlashlightBlackDst0] + ld e, a + ld a, [wRedrawFlashlightBlackDst0 + 1] + ld d, a + call _RedrawFlashlightRowBlack + ret +; 0x12e8 + +RedrawFlashlightRow2:: ; 1335 (0:1335) + ldh a, [hSCY] + and $0f + ret nz ; wait till we moved two complete tiles in Y + ld a, [wRedrawFlashlightDst1] + ld e, a + ld a, [wRedrawFlashlightDst1 + 1] + ld d, a + ld a, [wRedrawFlashlightSrc1] + ld l, a + ld a, [wRedrawFlashlightSrc1 + 1] + ld h, a + call _RedrawFlashlightRow + ret + +RedrawFlashlightRow3:: ; 134e (0:134e) + ld a, [wRedrawFlashlightBlackDst1] + ld e, a + ld a, [wRedrawFlashlightBlackDst1 + 1] + ld d, a + call _RedrawFlashlightRowBlack + xor a + ldh [hRedrawRowOrColumnMode], a ; end flashlight redraw + ret + +_RedrawFlashlightColumn:: ; 135d (0:135d) + ld a, [wRedrawFlashlightWidthHeight] + add a + ld c, a +.loop + ld a, [hli] + ld [de], a + ld a, SCREEN_WIDTH - 1 + add l + ld l, a + jr nc, .noCarryScreen + inc h +.noCarryScreen + ld a, BG_MAP_WIDTH + add e + ld e, a + jr nc, .noCarryBG + inc d +.noCarryBG +; the following 4 lines wrap us from bottom to top if necessary + ld a, d + and HIGH(vBGMap1 - vBGMap0 - $01) + or HIGH(vBGMap0) + ld d, a + dec c + jr nz, .loop + ldh a, [hRedrawRowOrColumnMode] + add $04 ; inc by 4, because flashlight redraw + ldh [hRedrawRowOrColumnMode], a ; has four directions + ret + +_RedrawFlashlightRow:: ; 1382 (0:1382) + ld a, [wRedrawFlashlightWidthHeight] + ld c, a +.loop + ld a, [hli] + ld [de], a + inc de + ld a, [hli] + ld [de], a + ld a, e + inc a +; the following 6 lines wrap us from the right edge to the left edge if necessary + and BG_MAP_WIDTH - 1 ; mask lower address bits + ld b, a + ld a, e + and ($FF ^ (BG_MAP_WIDTH - 1)) ; mask upper address bits + or b + ld e, a + dec c + jr nz, .loop + ldh a, [hRedrawRowOrColumnMode] + add $04 ; inc by 4, because flashlight redraw + ldh [hRedrawRowOrColumnMode], a ; has four directions + ret + +_RedrawFlashlightColumnBlack:: ; 139f (0:139f) + ld l, e + ld h, d + ld b, "■" + ld de, BG_MAP_WIDTH + ld a, [wRedrawFlashlightWidthHeight] + add a + ld c, a +.loop + ld [hl], b + add hl, de +; the following 4 lines wrap us from bottom to top if necessary + ld a, h + and HIGH(vBGMap1 - vBGMap0 - $01) + or HIGH(vBGMap0) + ld h, a + dec c + jr nz, .loop + ldh a, [hRedrawRowOrColumnMode] + add $04 ; inc by 4, because flashlight redraw + ldh [hRedrawRowOrColumnMode], a ; has four directions + ret + +_RedrawFlashlightRowBlack:: ; 13bd (0:13bd) + ld l, e + ld h, d + ld b, "■" + ld a, [wRedrawFlashlightWidthHeight] + ld c, a +.loop + ld [hl], b + inc hl + ld [hl], b + ld a, l + inc a +; the following 6 lines wrap us from the right edge to the left edge if necessary + and BG_MAP_WIDTH - 1 ; mask lower address bits + ld d, a + ld a, l + and ($FF ^ (BG_MAP_WIDTH - 1)) ; mask upper address bits + or d + ld l, a + dec c + jr nz, .loop + ldh a, [hRedrawRowOrColumnMode] + add $04 ; inc by 4, because flashlight redraw + ldh [hRedrawRowOrColumnMode], a ; has four directions + ret + +WaitForAutoBgMapTransfer:: ; 13dc (0:13dc) +.loop + ldh a, [hBGMapMode] + and a + ret z + ldh a, [hBGMapTransferPosition] + and a + jr z, .done + call DelayFrame + jr .loop +.done + xor a + ldh [hBGMapMode], a + ret + +; This function automatically transfers tile number data from the tile map at +; wTileMap to VRAM during V-blank. Note that it only transfers one third of the +; background per V-blank. It cycles through which third it draws. +; This transfer is turned off when walking around the map, but is turned +; on when talking to sprites, battling, using menus, etc. This is because +; the above function, RedrawRowOrColumn, is used when walking to +; improve efficiency. +AutoBgMapTransfer:: ; 13ee (0:13ee) + ldh a, [hBGMapMode] + and a + ret z + ld [hSPTemp], sp + ldh a, [hBGMapTransferPosition] + and a + jr z, .transferTopThird + dec a + jr z, .transferMiddleThird +.transferBottomThird + coord hl, 0, 12 + ld sp, hl + ldh a, [hBGMapAddress + 1] + ld h, a + ldh a, [hBGMapAddress] + ld l, a + ld de, 12 * BG_MAP_WIDTH + add hl, de + xor a + jr .doTransfer +.transferTopThird + coord hl, 0, 0 + ld sp, hl + ldh a, [hBGMapAddress + 1] + ld h, a + ldh a, [hBGMapAddress] + ld l, a + ld a, $01 + jr .doTransfer +.transferMiddleThird + coord hl, 0, 6 + ld sp, hl + ldh a, [hBGMapAddress + 1] + ld h, a + ldh a, [hBGMapAddress] + ld l, a + ld de, 6 * BG_MAP_WIDTH + add hl, de + ld a, $02 +.doTransfer + ldh [hBGMapTransferPosition], a + ld a, $06 ; 6 rows of SCREEN_WIDTH each + ; fallthrough + +TransferBgRows:: ; 1430 (0:1430) + ld bc, BG_MAP_WIDTH - SCREEN_WIDTH + 1 +.loop + + rept SCREEN_WIDTH / 2 - 1 ; two bytes per pop minus last block + 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, .loop + ldh a, [hSPTemp] + ld l, a + ldh a, [hSPTemp + 1] + ld h, a + ld sp, hl + ret + +VBlankCopyDouble:: ; 1470 (0:1470) +; Copy [wVBCopyDoubleSize] 1bpp tiles +; from wVBCopyDoubleSrc to wVBCopyDoubleDst. +; wVBCopyDoubleDst must be aligned to 0x10 bytes. + +; While we're here, convert to 2bpp. +; The process is straightforward: +; copy each byte twice. + ld a, [wVBCopyDoubleSize] + and a + ret z + ld [hSPTemp], sp + ld hl, wVBCopyDoubleSrc + ld a, [hli] + ld h, [hl] + ld l, a + ld sp, hl + ld hl, wVBCopyDoubleDst + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wVBCopyDoubleSize] + ld b, a + xor a + ld [wVBCopyDoubleSize], a +.loop + + rept 16/4 - 1 ; 16 bytes per 2bpp tile at 2 bytes per pop + pop de ; copied twice minus last block + 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, .loop + ld a, l + ld [wVBCopyDoubleDst], a + ld a, h + ld [wVBCopyDoubleDst + 1], a + ld [wVBCopyDoubleSrc], sp + ldh a, [hSPTemp] + ld l, a + ldh a, [hSPTemp + 1] + ld h, a + ld sp, hl + ret + +VBlankCopy:: ; 14c7 (0:14c7) +; Copy 16 * [wVBCopySize] bytes +; from wVBCopySrc to wVBCopyDst. +; wVBCopyDst must be aligned to 0x10 bytes. + +; Source and destination addresses are updated, +; so transfer can continue in subsequent calls. + ld a, [wVBCopySize] + and a + ret z + ld [hSPTemp], sp + ld hl, wVBCopySrc + ld a, [hli] + ld h, [hl] + ld l, a + ld sp, hl + ld hl, wVBCopyDst + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wVBCopySize] + ld b, a + xor a + ld [wVBCopySize], a +.loop + + rept 16/2 - 1 ; 16 bytes per transfer at 2 bytes per pop + pop de ; minus last block + 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, .loop + ld a, l + ld [wVBCopyDst], a + ld a, h + ld [wVBCopyDst + 1], a + ld [wVBCopySrc], sp + ldh a, [hSPTemp] + ld l, a + ldh a, [hSPTemp + 1] + ld h, a + ld sp, hl + ret + +AnimateTileset:: ; 1522 (0:1522) + ldh a, [hROMBank] + push af + ld a, BANK(AnimateTilesetImpl) + call Bankswitch + call AnimateTilesetImpl + pop af + jp Bankswitch +; 0x1531 + +EnableSprites:: ; 1531 (0:1531) + nop + ld hl, rLCDC + set rLCDC_SPRITES_ENABLE, [hl] + ret +; 0x1538 + +Function_1538: ; 1538 (0:1538) + ld a, [$d14f] + bit 0, a + ret z + bit 7, a + ret nz + bit 2, a + res 2, a + ret z + ld [$d14f], a + ld [hSPTemp], sp + ld hl, $cbd2 + ld sp, hl + ld hl, $9c20 + ld a, $01 + jp TransferBgRows + +VBlankCopyFar:: ; 1558 (0:1558) +; Copy 0x10 * [wVBCopyFarSize] bytes +; from wVBCopyFarSrcBank::wVBCopyFarSrc to wVBCopyFarDst. +; wVBCopyFarDst must be aligned to 0x10 bytes. + +; Source and destination addresses are updated, +; so transfer can continue in subsequent calls. + ld a, [wVBCopyFarSize] + and a + ret z + ld a, [wVBCopyFarSrcBank] + call Bankswitch + ld [hSPTemp], sp + ld hl, wVBCopyFarSrc + ld a, [hli] + ld h, [hl] + ld l, a + ld sp, hl + ld hl, wVBCopyFarDst + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wVBCopyFarSize] + ld b, a + xor a + ld [wVBCopyFarSize], a +.loop + rept 16/2 - 1 ; 16 bytes per transfer at 2 bytes per pop + 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, .loop + ld [wVBCopyFarSrc], sp + ld sp, hl + ld [wVBCopyFarDst], sp + ldh a, [hSPTemp] + ld l, a + ldh a, [hSPTemp + 1] + ld h, a + ld sp, hl + ret +; 0x15b5 |
