summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTauwasser <Tauwasser@tauwasser.eu>2018-06-01 01:26:26 +0200
committerTauwasser <Tauwasser@tauwasser.eu>2018-06-01 01:26:41 +0200
commit66e714913c3ed0bcb1c8d9ee9c004960b711a8ac (patch)
treec9c4d961883f220a29abca51826e863e7bc3a2bb
parent513028a98e6225e39c53ea64e4f9c483b3abd55b (diff)
home: disassemble vblank and associated functions
Signed-off-by: Tauwasser <Tauwasser@tauwasser.eu>
-rw-r--r--home/joypad.asm51
-rw-r--r--home/vblank.asm271
-rw-r--r--home/vcopy.asm615
-rw-r--r--hram.asm74
-rw-r--r--shim.sym6
-rw-r--r--vram.asm21
-rw-r--r--wram.asm160
7 files changed, 1152 insertions, 46 deletions
diff --git a/home/joypad.asm b/home/joypad.asm
new file mode 100644
index 0000000..80371b7
--- /dev/null
+++ b/home/joypad.asm
@@ -0,0 +1,51 @@
+INCLUDE "constants.asm"
+
+SECTION "Joypad functions", ROM0[$07FE]
+
+Joypad:: ; 7fe (0:7fe)
+ 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, [hJoypadDown]
+ ld e, a
+ xor b
+ ld d, a
+ and e
+ ldh [hJoypadReleased], a
+ ld a, d
+ and b
+ ldh [hJoypadPressed], a
+ ld c, a
+ ldh a, [hJoypadSum]
+ or c
+ ldh [hJoypadSum], a
+ ld a, b
+ ldh [hJoypadDown], a
+ ldh [hJoypadDown2], a
+ and $0f
+ cp $0f
+ jp z, Reset
+ ret
+; 0x84a \ No newline at end of file
diff --git a/home/vblank.asm b/home/vblank.asm
index 334cef4..8d9fb25 100644
--- a/home/vblank.asm
+++ b/home/vblank.asm
@@ -28,4 +28,273 @@ VBlank:: ; 0150
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, [wVBlankCounter]
+ and a
+ jr z, .skipDec
+ dec a
+ ld [wVBlankCounter], 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, [wVBlankCounter]
+ and a
+ jr z, .skipDec
+ dec a
+ ld [wVBlankCounter], 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, [wVBlankCounter]
+ and a
+ jr z, .skipDec
+ dec a
+ ld [wVBlankCounter], 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 \ No newline at end of file
diff --git a/home/vcopy.asm b/home/vcopy.asm
new file mode 100644
index 0000000..bfcaa7c
--- /dev/null
+++ b/home/vcopy.asm
@@ -0,0 +1,615 @@
+INCLUDE "constants.asm"
+INCLUDE "vram.asm"
+
+SECTION "Copy Routines used by VBlank ISR", ROM0[$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
+RedrawRowOrColumn:: ; 123a (0:123a)
+ 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
+ ; fall through and 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
+ ; fall through
+
+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
+
+; 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.
+VBlankCopyDouble:: ; 1470 (0:1470)
+ 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
+
+; 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.
+VBlankCopy:: ; 14c7 (0:14c7)
+ 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
+
+; 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.
+VBlankCopyFar:: ; 1558 (0:1558)
+ 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
diff --git a/hram.asm b/hram.asm
index 2d28b47..7675963 100644
--- a/hram.asm
+++ b/hram.asm
@@ -1,11 +1,16 @@
SECTION "HRAM", HRAM[$FF80]
hOAMDMA:: ; ff80
- ds 10
+ ds 13
+hRTCHours:: db ; ff8d
+hRTCMinutes:: db ; ff8e
+hRTCSeconds:: db ; ff8f
- ds 14 ; TODO
+ ds 7 ; TODO
+hVBlankCounter:: ; ff97
+ db
hROMBank:: ; ff98
db
@@ -14,8 +19,18 @@ hROMBank:: ; ff98
hVBlank:: ; ff99
db
+ ds 3 ; TODO
+
+hJoypadReleased:: db ; ff9d
+hJoypadPressed:: db ; ff9e
+hJoypadDown:: db ; ff9f
+hJoypadSum:: db ; ffa0
+
+ ds 5; TODO
- ds 21 ; TODO
+hJoypadDown2:: db ; ffa6
+
+ ds 8 ; TODO
hSpriteWidth:: ; ffaf
hSpriteInterlaceCounter:: ; ffaf
@@ -55,22 +70,61 @@ hSCY:: db ; ffda
hWX:: db ; ffdb
hWY:: db ; ffdc
- db ; TODO
+hOverworldFlashlightEffect:: db ; ffdd
+; Influences draw distance of map around HIRO
+; Meant to go from 0x00--> to desired distance
+; or else graphical errors will occur.
+; 0x00 - regular distance
+; 0x01 - 14x14 tile block
+; 0x02 - 10x10 tile block
+; 0x03 - 6x 6 tile block
+; 0x04 - 2x 2 tile block
hBGMapMode:: ; ffde
db
- db ; TODO
+hBGMapTransferPosition:: ; ffdf
+ db
hBGMapAddress:: ; ffe0
dw
-
-
- ds 6 ; TODO
-
+ db ; TODO
+
+hSPTemp:: ; ffe3
+ dw
+
+hRedrawRowOrColumnMode:: db ; ffe5
+; Used for redrawing BG in small updates
+; instead of once completely for faster
+; scrolling on overworld etc.
+; Valid values:
+; 0x00 - no redraw
+; 0x01 - column redraw (move horizontally)
+; 0x02 - row redraw (move vertically)
+; 0x03 - flashlight row redraw 0 (move up)
+; 0x04 - flashlight row redraw 0 (move down)
+; 0x05 - flashlight column redraw 0 (move left)
+; 0x06 - flashlight column redraw 0 (move right)
+; 0x07 - flashlight row redraw 1 (move up)
+; 0x08 - flashlight row redraw 1 (move down)
+; 0x09 - flashlight column redraw 1 (move left)
+; 0x0A - flashlight column redraw 1 (move right)
+; 0x0B - flashlight row redraw 2 (move up)
+; 0x0C - flashlight row redraw 2 (move down)
+; 0x0D - flashlight column redraw 2 (move left)
+; 0x0E - flashlight column redraw 2 (move right)
+; 0x0F - flashlight row redraw 3 (move up)
+; 0x10 - flashlight row redraw 3 (move down)
+; 0x11 - flashlight column redraw 3 (move left)
+; 0x12 - flashlight column redraw 3 (move right)
+
+hRedrawRowOrColumnDest:: ds 2 ; ffe6
hMapAnims:: ; ffe8
; TODO: figure out size
-
+ ds 7
+hRandomAdd:: db ; ffef
+hRandomSub:: db ; fff0
+hRTCRandom:: db ; fff1
; TODO
diff --git a/shim.sym b/shim.sym
index 2bd959b..8fb54b0 100644
--- a/shim.sym
+++ b/shim.sym
@@ -1,4 +1,5 @@
; ROM0
+00:051C Reset
00:0884 UpdateJoypad
00:0d1a LoadFontExtra
00:0d0a LoadFont
@@ -20,6 +21,7 @@
00:20ff RunMapScript
00:232c LoadMapWarp
00:23e5 OverworldFadeIn
+00:2C05 StartMenuCheck
00:3270 Random
00:3429 AddAMulBC
@@ -69,6 +71,7 @@
10:40A6 ShowPokedexMenu
+23:4000 AnimateTilesetImpl
23:4349 OverworldFadeOut
23:60cc MenuMonIconGfx
@@ -80,6 +83,7 @@
3A:4F6C LoadMusicByte
3A:52C7 Music
+3f:40E9 InGameDebugMenu
3f:64ce MonsterTest
3f:654e PicTest
3f:6750 PicTestMenu
@@ -97,7 +101,7 @@
00:cdbe wTargetMapUnk
00:cdbf wTargetMapGroup
00:cdc0 wTargetMapId
-00:CE62 wTextBoxFlags
+00:ce62 wTextBoxFlags
00:ce67 wPlayerName
01:d165 wTMCounts
diff --git a/vram.asm b/vram.asm
new file mode 100644
index 0000000..05f3199
--- /dev/null
+++ b/vram.asm
@@ -0,0 +1,21 @@
+vChars0 EQU $8000
+vChars1 EQU $8800
+vChars2 EQU $9000
+vBGMap0 EQU $9800
+vBGMap1 EQU $9c00
+
+; Battle/Menu
+vSprites EQU vChars0
+vFont EQU vChars1
+vFrontPic EQU vChars2
+vBackPic EQU vFrontPic + 7 * 7 * $10
+
+; Overworld
+vNPCSprites EQU vChars0
+vNPCSprites2 EQU vChars1
+vTileset EQU vChars2
+
+; Title
+vTitleLogo EQU vChars1
+vTitleLogo2 EQU vFrontPic + 7 * 7 * $10
+
diff --git a/wram.asm b/wram.asm
index 001481f..34edd62 100644
--- a/wram.asm
+++ b/wram.asm
@@ -81,22 +81,49 @@ SECTION "LY overrides buffer", WRAM0[$C600]
wLYOverrides:: ; c600
ds SCREEN_HEIGHT_PX
+SECTION "CB14", WRAM0[$CB14]
+
+UNION
+wRedrawRowOrColumnSrcTiles:: ; cb14
+; the tiles of the row or column to be redrawn by RedrawRowOrColumn
+ ds SCREEN_WIDTH * 2
+NEXTU
+wRedrawFlashlightDst0:: dw ; cb14
+wRedrawFlashlightSrc0:: dw ; cb16
+wRedrawFlashlightBlackDst0:: dw ; cb18
+wRedrawFlashlightDst1:: dw ; cb1a
+wRedrawFlashlightSrc1:: dw ; cb1c
+wRedrawFlashlightBlackDst1:: dw ; cb1e
+wRedrawFlashlightWidthHeight:: db ; cb20
+; width or height of flashlight redraw region
+; in units of two tiles (people event meta tile)
+ENDU
+
SECTION "CB56", WRAM0[$CB5B]
wcb5b:: ds 1 ; multipurpose, also wName, wMonDexIndex2
wNameCategory:: ds 1
SECTION "CB62", WRAM0[$CB62]
-wVBCopySize:: ds 1
-wVBCopySrc:: ds 2
-wVBCopyDst:: ds 2
-wVBCopyDoubleSize:: ds 1
-wVBCopyDoubleSrc:: ds 2
-wVBCopyDoubleDst:: ds 2
+wVBCopySize:: ds 1 ; cb62
+wVBCopySrc:: ds 2 ; cb63
+wVBCopyDst:: ds 2 ; cb65
+wVBCopyDoubleSize:: ds 1 ; cb67
+wVBCopyDoubleSrc:: ds 2 ; cb68
+wVBCopyDoubleDst:: ds 2 ; cb6a
+
+SECTION "CB71", WRAM0[$CB71]
+
+wVBCopyFarSize:: ds 1 ; cb71
+wVBCopyFarSrc:: ds 2 ; cb72
+wVBCopyFarDst:: ds 2 ; cb74
+wVBCopyFarSrcBank:: ds 1 ; cb76
-SECTION "CC33", WRAM0[$CC33] ; Please merge when more is disassembled
+SECTION "CC32", WRAM0[$CC32] ; Please merge when more is disassembled
-wVBlankOccurred: db
+wVBlankCounter: db ; cc32
+
+wVBlankOccurred: db ; cc33
ds 4
@@ -129,6 +156,20 @@ wSpriteOutputPtrCached : ds 2 ; ccba
wSpriteDecodeTable0Ptr : ds 2 ; ccbc
wSpriteDecodeTable1Ptr : ds 2 ; ccbe
+SECTION "CCC7", WRAM0[$CCC7]
+
+wDisableVBlankOAMUpdate:: db ; ccc7
+
+SECTION "CCCA", WRAM0[$CCCA]
+
+wBGP:: db ; ccca
+wOBP0:: db ; cccb
+wOBP1:: db ; cccc
+
+SECTION "CCCE", WRAM0[$CCCE]
+
+wDisableVBlankWYUpdate:: db ; ccce
+
SECTION "CD4F", WRAM0[$CD4F]
wPredefID:: ; cd4f
@@ -159,83 +200,134 @@ wMonHeader::
wMonHIndex:: ; ce07
; In the ROM base stats data structure, this is the dex number, but it is
; overwritten with the dex number after the header is copied to WRAM.
- ds 1
+ ds 1
wMonHBaseStats:: ; ce08
wMonHBaseHP:: ; ce08
- ds 1
+ ds 1
wMonHBaseAttack:: ; ce09
- ds 1
+ ds 1
wMonHBaseDefense:: ; ce0a
- ds 1
+ ds 1
wMonHBaseSpeed:: ; ce0b
- ds 1
+ ds 1
wMonHBaseSpecialAtt:: ; ce0c
- ds 1
+ ds 1
wMonHBaseSpecialDef:: ; ce0d
- ds 1
+ ds 1
wMonHTypes:: ; ce0e
wMonHType1:: ; ce0e
- ds 1
+ ds 1
wMonHType2:: ; ce0f
- ds 1
+ ds 1
wMonHCatchRate:: ; ce10
- ds 1
+ ds 1
wMonHBaseEXP:: ; ce11
- ds 1
+ ds 1
wMonHItems:: ; ce12
wMonHItem1:: ; ce12
- ds 1
+ ds 1
wMonHItem2:: ; ce13
- ds 1
+ ds 1
wMonHGenderRatio:: ; ce14
- ds 1
+ ds 1
wMonHUnk0:: ; ce15
- ds 1
+ ds 1
wMonHUnk1:: ; ce16
- ds 1
+ ds 1
wMonHUnk2:: ; ce17
- ds 1
+ ds 1
wMonHSpriteDim:: ; ce18
- ds 1
+ ds 1
wMonHFrontSprite:: ; ce19
- ds 2
+ ds 2
wMonHBackSprite:: ; ce1b
- ds 2
+ ds 2
wMonHGrowthRate:: ; ce1d
- ds 1
+ ds 1
wMonHLearnset:: ; ce1e
; bit field
- flag_array 50 + 5
- ds 1
+ flag_array 50 + 5
+ ds 1
+
+SECTION "CE3B", WRAM0[$CE3B]
-SECTION "CE3C", WRAM0[$CE3C]
+wVBlankSavedROMBank:: ; ce3b
+ db
wBuffer:: ; ce3c
db
+wTimeOfDay:: db ; ce3d
+; based on RTC
+; Time of Day Regular Debug
+; 00 - Day 09--15h 00--30s
+; 01 - Night 15--06h 30--35s
+; 02 - Cave 35--50s
+; 03 - Morning 06--09h 50--59s
SECTION "CE5F", WRAM0[$CE5F]
wce5f:: ; ce5f ; TODO
db
+SECTION "CE63", WRAM0[$CE63]
+
+wce63:: db ; ce63
+; 76543210
+; \-- global debug enable
+
+SECTION "D152", WRAM0[$D152]
+
+wMapTimeOfDayPalette:: db ; d152
+; Applied according to wMapTimeOfDay from wMapTimeOfDayPaletteMap
+
+wd153:: db ; d153
+; 76543210
+; \-------- switch overworld palettes according to seconds not hours
+
+ ds 3 ; TODO
+wd157:: db ; d157
+; 76543210
+; \-------- disable overworld palette switch
+
+wMapTimeOfDayPaletteMap:: db ; d158
+; 76543210
+; \/\/\/\/
+; | | | \- Map Palette for TimeOfDay 0x00
+; | | \--- Map Palette for TimeOfDay 0x01
+; | \----- Map Palette for TimeOfDay 0x02
+; \------- Map Palette for TimeOfDay 0x03
+
+wMapTimeOfDay:: db ; d159
+
+SECTION "D4AB", WRAM0[$D4AB]
+
+wJoypadFlags:: db ; d4ab
+; 76543210
+; ||||\__/
+; |||| \-- unkn
+; |||\----- unkn
+; ||\------ don't wait for keypress to close text box
+; |\------- joypad sync mtx
+; \-------- joypad disabled
+
SECTION "PokeDexFlags", WRAM0[$D81A]
wPokedexOwned:: ; d81a
- flag_array NUM_POKEMON
+ flag_array NUM_POKEMON
wPokedexOwnedEnd:: ; d839
wPokedexSeen:: ; d83a
- flag_array NUM_POKEMON
+ flag_array NUM_POKEMON
wPokedexSeenEnd:: ; d859
wAnnonDex:: ds 26 ; d85a