summaryrefslogtreecommitdiff
path: root/home
diff options
context:
space:
mode:
authorehw <Knuckles500@gmail.com>2018-06-07 21:28:30 -0400
committerGitHub <noreply@github.com>2018-06-07 21:28:30 -0400
commit04dbd44cb88d311081114054aaba1294db27c136 (patch)
tree720b24fb7861bc589c087b2afd39d74d7aeb0e6d /home
parentb537cfe42b69681a7f07f47eebdb097d58708840 (diff)
parent7990b32450b833c249734e15a51de4df541bc109 (diff)
Merge pull request #10 from pret/master
Merge master
Diffstat (limited to 'home')
-rw-r--r--home/copy2.asm17
-rw-r--r--home/fade.asm95
-rw-r--r--home/init.asm14
-rw-r--r--home/joypad.asm10
-rw-r--r--home/menu.asm456
-rw-r--r--home/print_text.asm51
-rw-r--r--home/rtc.asm20
-rw-r--r--home/serial.asm299
-rw-r--r--home/text.asm366
-rw-r--r--home/time.asm138
-rw-r--r--home/unknown.asm15
-rw-r--r--home/vcopy.asm2
-rw-r--r--home/window.asm23
13 files changed, 1457 insertions, 49 deletions
diff --git a/home/copy2.asm b/home/copy2.asm
index 5d3afe2..7cc4696 100644
--- a/home/copy2.asm
+++ b/home/copy2.asm
@@ -1,6 +1,21 @@
INCLUDE "constants.asm"
-SECTION "Video Copy functions", ROM0[$0D2A]
+SECTION "Video Copy functions", ROM0[$0D02]
+
+Function0d02::
+ jpab Function14000
+
+LoadFont:: ; 00:0d0a
+ jpab LoadFontGraphics
+
+LoadFontsBattleExtra::
+ jpab LoadPokemonMenuGraphics
+
+LoadFontExtra:: ; 00:0d1a
+ jpab LoadFontExtraGraphicsWithCursor
+
+LoadFontExtra2::
+ jpab LoadHexadecimalFontOrHUDGraphics
FarCopyData: ; d2a (0:d2a)
; Identical to FarCopyBytes except for tail call optimization
diff --git a/home/fade.asm b/home/fade.asm
new file mode 100644
index 0000000..e39bd83
--- /dev/null
+++ b/home/fade.asm
@@ -0,0 +1,95 @@
+include "constants.asm"
+
+if DEBUG
+SECTION "DMG Palette Fade Effect", ROM0 [$0343]
+else
+SECTION "DMG Palette Fade Effect", ROM0 [$0307]
+endc
+
+Function0343:: ; 0343
+ ld a, [wTimeOfDayPal]
+ ld b, a
+ ld hl, IncGradGBPalTable_11 ; $39f
+ ld a, l
+ sub b
+ ld l, a
+ jr nc, .okay
+ dec h
+.okay
+ ld a, [hli]
+ ld [rBGP], a
+ ld a, [hli]
+ ld [rOBP0], a
+ ld a, [hli]
+ ld [rOBP1], a
+ ret
+
+RotateFourPalettesRight::
+ ld hl, IncGradGBPalTable_08 ; $396
+ ld b, $4
+ jr RotatePalettesRight
+
+RotateThreePalettesRight::
+ ld hl, IncGradGBPalTable_13 ; $3a5
+ ld b, $3
+RotatePalettesRight:: ; 0366
+; Rotate palettes to the right and fill with loaded colors from the left
+; If we're already at the leftmost color, fill with the leftmost color
+.loop
+ ld a, [hli]
+ ld [rBGP], a
+ ld a, [hli]
+ ld [rOBP0], a
+ ld a, [hli]
+ ld [rOBP1], a
+ ld c, $8
+ call DelayFrames
+ dec b
+ jr nz, .loop
+ ret
+
+RotateFourPalettesLeft::
+ ld hl, IncGradGBPalTable_12 - 1 ; $3a1
+ ld b, $4
+ jr RotatePalettesLeft
+
+RotateThreePalettesLeft::
+ ld hl, IncGradGBPalTable_15 - 1 ; $3aa
+ ld b, $3
+RotatePalettesLeft:: ; 0384
+; Rotate palettes to the left and fill with loaded colors from the right
+; If we're already at the rightmost color, fill with the rightmost color
+.loop
+ ld a, [hld]
+ ld [rOBP1], a
+ ld a, [hld]
+ ld [rOBP0], a
+ ld a, [hld]
+ ld [rBGP], a
+ ld c, $8
+ call DelayFrames
+ dec b
+ jr nz, .loop
+ ret
+
+; IncGradGBPalTable_00:: db %11111111, %11111111, %11111111
+; IncGradGBPalTable_01:: db %11111110, %11111110, %11111110
+; IncGradGBPalTable_02:: db %11111001, %11111001, %11111001
+; IncGradGBPalTable_03:: db %11100100, %11100100, %11100100
+
+; IncGradGBPalTable_04:: db %11100100, %11100100, %11100100
+; IncGradGBPalTable_05:: db %10010000, %10010000, %10010000
+; IncGradGBPalTable_06:: db %01000000, %01000000, %01000000
+
+; IncGradGBPalTable_07:: db %00000000, %00000000, %00000000
+; bgp obp1 obp2
+IncGradGBPalTable_08:: db %11111111, %11111111, %11111111
+IncGradGBPalTable_09:: db %11111110, %11111110, %11111000
+IncGradGBPalTable_10:: db %11111001, %11100100, %11100100
+IncGradGBPalTable_11:: db %11100100, %11010000, %11100000
+
+IncGradGBPalTable_12:: db %11100100, %11010000, %11100000
+IncGradGBPalTable_13:: db %10010000, %10000000, %10010000
+IncGradGBPalTable_14:: db %01000000, %01000000, %01000000
+
+IncGradGBPalTable_15:: db %00000000, %00000000, %00000000
diff --git a/home/init.asm b/home/init.asm
index d8ae530..5df55b8 100644
--- a/home/init.asm
+++ b/home/init.asm
@@ -21,8 +21,20 @@ else
endc
endc
+SECTION "Init", ROM0[$51C]
-SECTION "Init", ROM0[$52F]
+Reset: ; 51c (0:051c)
+ call DisableAudio
+ call ClearPalettes
+ ei
+
+ ld hl, wJoypadFlags
+ set 7, [hl]
+
+ ld c, 32
+ call DelayFrames
+
+ jr Init
Init: ; 052f
di
diff --git a/home/joypad.asm b/home/joypad.asm
index 5a4e549..faa7cf0 100644
--- a/home/joypad.asm
+++ b/home/joypad.asm
@@ -1,6 +1,14 @@
INCLUDE "constants.asm"
-SECTION "Joypad functions", ROM0[$07FE]
+SECTION "Joypad functions", ROM0[$07F8]
+
+ClearJoypad::
+ xor a
+; Pressed this frame (delta)
+ ldh [hJoyDown], a
+; Currently pressed
+ ldh [hJoyState], a
+ ret
Joypad:: ; 7fe (0:7fe)
; Read the joypad register and translate it to something more
diff --git a/home/menu.asm b/home/menu.asm
index e8b4eeb..64d3f9a 100644
--- a/home/menu.asm
+++ b/home/menu.asm
@@ -1,51 +1,425 @@
include "constants.asm"
-if DEBUG
-SECTION "Print Letter Delay", ROM0[$33a3]
-else
-SECTION "Print Letter Delay", ROM0[$3367]
-endc
-
-PrintLetterDelay:: ; 33a3 (0:33a3)
- ld a, [wce5f]
- bit 4, a
- ret nz
- ld a, [wTextBoxFlags]
+SECTION "Menu Functions", ROM0 [$1d49]
+
+LoadMenuHeader:: ; 00:1d49
+ call CopyMenuHeader
+ call PushWindow
+ ret
+
+CopyMenuHeader:: ; 00:1d50
+ ld de, wMenuDataHeader
+ ld bc, $10
+ jp CopyBytes
+
+MenuTextBox:: ; 00:1d59
+ push hl
+ ld hl, .Data
+ call LoadMenuHeader
+ pop hl
+ jp PrintText
+
+; unused
+ ret
+
+.Data: ; 00:1d65
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 0, 12, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
+ dw VRAM_Begin
+ db 0 ; default option
+
+MenuTextBoxBackup::
+ call MenuTextBox
+ call CloseWindow
+ ret
+
+LoadStandardMenuHeader::
+ ld hl, .Data
+ call LoadMenuHeader
+ ret
+
+.Data: ; 00:1d7b
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
+ dw 0
+ db 1 ; default option
+
+Call_ExitMenu::
+ call ExitMenu
+ ret
+
+VerticalMenu:: ; 00:1d87
+ xor a
+ ldh [hBGMapMode], a
+ call MenuBox
+ call UpdateSprites
+ call PlaceVerticalMenuItems
+ call WaitBGMap
+ call CopyMenuData
+ ld a, [wMenuData2]
+ bit 7, a
+ jr z, .asm_1daa
+ call InitVerticalMenuCursor
+ call Function1a7c
bit 1, a
+ jr z, .asm_1dac
+.asm_1daa: ; 00:1daa
+ scf
+ ret
+
+.asm_1dac: ; 00:1dac
+ and a
+ ret
+
+GetMenu2::
+ call LoadMenuHeader
+ call VerticalMenu
+ call CloseWindow
+ ld a, [wMenuCursorY]
+ ret
+
+CopyNameFromMenu::
+ push hl
+ push bc
+ push af
+ ld hl, wMenuDataPointer
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ inc hl
+ inc hl
+ pop af
+ call GetNthString
+ ld d, h
+ ld e, l
+ call CopyStringToCD31
+ pop bc
+ pop hl
+ ret
+
+YesNoBox::
+ lb bc, 14, 7
+ jr asm_1ddc
+
+PlaceGenericTwoOptionBox::
+ call LoadMenuHeader
+ jr asm_1df9
+
+asm_1ddc: ; 00:1ddc
+ push bc
+ ld hl, YesNoMenuHeader
+ call CopyMenuHeader
+ pop bc
+ ld a, b
+ ld [wMenuBorderLeftCoord], a
+ add 5
+ ld [wMenuBorderRightCoord], a
+ ld a, c
+ ld [wMenuBorderTopCoord], a
+ add 4
+ ld [wMenuBorderBottomCoord], a
+ call PushWindow
+asm_1df9: ; 00:1df9
+ call VerticalMenu
+ push af
+ ld c, 15
+ call DelayFrames
+ call CloseWindow
+ pop af
+ jr c, .asm_1e11
+ ld a, [wMenuCursorY]
+ cp $2
+ jr z, .asm_1e11
+ and a
+ ret
+
+.asm_1e11: ; 00:1e11
+ ld a, $2
+ ld [wMenuCursorY], a
+ scf
+ ret
+
+YesNoMenuHeader:: ; 00:1e18
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 10, 5, 15, 9
+ dw .MenuData
+ db 1 ; default option
+
+.MenuData:
+ db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags
+ db 2
+ db "はい@"
+ db "いいえ@"
+
+OffsetMenuHeader::
+ call _OffsetMenuHeader
+ call PushWindow
+ ret
+
+_OffsetMenuHeader:: ; 00:1e30
+ push de
+ call CopyMenuHeader
+ pop de
+ ld a, [wMenuBorderLeftCoord]
+ ld h, a
+ ld a, [wMenuBorderRightCoord]
+ sub h
+.asm_1e3d: ; 00:1e3d
+ ld h, a
+ ld a, d
+ ld [wMenuBorderLeftCoord], a
+ add h
+ ld [wMenuBorderRightCoord], a
+ ld a, [wMenuBorderTopCoord]
+ ld l, a
+ ld a, [wMenuBorderBottomCoord]
+ sub l
+ ld l, a
+ ld a, e
+ ld [wMenuBorderTopCoord], a
+ add l
+ ld [wMenuBorderBottomCoord], a
+ ret
+
+OpenMenu:: ; 00:1e58
+ call CopyMenuData
+ call GetMenuIndexSet
+ push de
+ ld a, [wMenuCursorBuffer]
+ push af
+ call Function1e8a
+ pop af
+ ld [wMenuCursorBuffer], a
+ call AutomaticGetMenuBottomCoord
+ call PushWindow
+ call MenuBox
+ pop de
+ call GetMenuIndexSet
+ push de
+ call RunMenuItemPrintingFunction
+ ld a, $1
+ ldh [hBGMapMode], a
+ call UpdateSprites
+ call GetMenuIndexSet
+ pop de
+ call Function1f27
+ ret
+
+Function1e8a:: ; 00:1e8a
+ xor a
+ ldh [hBGMapMode], a
+ xor a
+ call OpenSRAM
+ call Function1cae
+ ld a, l
+ ld [wWindowStackPointer], a
+ ld a, h
+ ld [wWindowStackPointer + 1], a
+ call Function1c7a
+ ld d, h
+ ld e, l
+ call Function1c60
+ call CloseSRAM
+ ld hl, wWindowStackSize
+ dec [hl]
+ ret
+
+AutomaticGetMenuBottomCoord:: ; 00:1eac
+ ld a, [wMenuBorderLeftCoord]
+ ld c, a
+ ld a, [wMenuBorderRightCoord]
+ sub c
+ ld c, a
+ ld a, [wMenuDataItems]
+ add a
+ inc a
+ ld b, a
+ ld a, [wMenuBorderTopCoord]
+ add b
+ ld [wMenuBorderBottomCoord], a
+ ret
+
+GetMenuIndexSet:: ; 00:1ec3
+ ld hl, wMenuDataIndicesPointer
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wWhichIndexSet]
+ and a
+ jr z, .asm_1ed9
+ ld b, a
+ ld c, -1
+.asm_1ed2: ; 00:1ed2
+ ld a, [hli]
+ cp c
+ jr nz, .asm_1ed2
+ dec b
+ jr nz, .asm_1ed2
+.asm_1ed9: ; 00:1ed9
+ ld d, h
+ ld e, l
+ inc hl
+ ld c, $ff
+.asm_1ede: ; 00:1ede
+ inc c
+ ld a, [hli]
+ cp $ff
+ jr nz, .asm_1ede
+ ld a, c
+ ld [wMenuDataItems], a
+ ret
+
+Function1ee9:: ; 1ee9
+ call MenuBoxCoord2Tile
+ call Function1c86
+ ld a, [wMenuDataItems]
+ add a
+ cp b
+ jr nc, .asm_1ef9
+ ld b, a
+ dec c
+ ret
+
+.asm_1ef9: ; 00:1ef9
+ ld a, b
+ srl a
+ dec a
+ ld [wMenuDataItems], a
+ dec c
+ ret
+
+RunMenuItemPrintingFunction:: ; 00:1f02
+ call MenuBoxCoord2Tile
+ ld bc, 2 * SCREEN_WIDTH + 2
+ add hl, bc
+.asm_1f09: ; 00:1f09
+ inc de
+ ld a, [de]
+ cp -1
ret z
+ ld [wMenuSelection], a
+ push de
push hl
+ ld d, h
+ ld e, l
+ ld hl, wMenuDataDisplayFunctionPointer
+ call ._hl_
+ pop hl
+ ld de, 2 * SCREEN_WIDTH
+ add hl, de
+ pop de
+ jr .asm_1f09
+
+._hl_:
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+Function1f27:: ; 00:1f27
+; Combines Crystal functions "InitMenuCursorAndButtonPermissions" and "GetStaticMenuJoypad"
push de
- push bc
- ld a, [wTextBoxFlags]
+ call InitVerticalMenuCursor
+ ld hl, wMenuJoypadFilter
+ ld a, [wMenuData2]
+ bit 3, a
+ jr z, .asm_1f37
+ set 3, [hl]
+.asm_1f37: ; 00:1f37
+ bit 2, a
+ jr z, .asm_1f3f
+ ld a, [hl]
+ or D_LEFT | D_RIGHT
+ ld [hl], a
+.asm_1f3f: ; 00:1f3f
+ call Function1a7c
+ pop de
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]
+ jr nz, .asm_1f66
+ bit 1, a
+ jr nz, .asm_1f7e
+ bit 3, a
+ jr nz, .asm_1f7e
+ bit 4, a
+ jr nz, .asm_1f58
+ bit 5, a
+ jr nz, .asm_1f5f
+ ret
+
+.asm_1f58: ; 00:1f58
+ ld a, D_RIGHT
+ ld [wMenuJoypad], a
+ jr .asm_1f6b
+
+.asm_1f5f: ; 00:1f5f
+ ld a, D_LEFT
+ ld [wMenuJoypad], a
+ jr .asm_1f6b
+
+.asm_1f66: ; 00:1f66
+ ld a, A_BUTTON
+ ld [wMenuJoypad], a
+.asm_1f6b: ; 00:1f6b
+ ld a, [wMenuCursorY]
+ ld l, a
+ ld h, $0
+ add hl, de
+ ld a, [hl]
+ ld [wMenuSelection], a
+ ld a, [wMenuCursorY]
+ ld [wMenuCursorBuffer], a
and a
- jr nz, .checkButtons
-.done
- pop bc
- pop de
+ ret
+
+.asm_1f7e: ; 00:1f7e
+ ld a, B_BUTTON
+ ld [wMenuJoypad], a
+ ld a, -1
+ ld [wMenuSelection], a
+ scf
+ ret
+
+PlaceMenuStrings::
+ push de
+ ld hl, wMenuDataPointerTableAddr
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wMenuSelection]
+ call GetNthString
+ ld d, h
+ ld e, l
pop hl
+ call PlaceString
+ ret
+
+ClearWindowData:: ; 00:1f9e
+ ld hl, wWindowStackPointer
+ call .bytefill
+ ld hl, wMenuDataHeader
+ call .bytefill
+ ld hl, wMenuData2
+ call .bytefill
+ ld hl, wMenuData3
+ call .bytefill
+
+ xor a
+ call OpenSRAM
+
+ xor a
+ ld hl, sWindowStackTop + 1
+ ld [hld], a
+ ld [hld], a
+ ld a, l
+ ld [wWindowStackPointer], a
+ ld a, h
+ ld [wWindowStackPointer + 1], a
+
+ call CloseSRAM
+ ret
+
+.bytefill: ; 00:1fcc
+ ld bc, 16
+ xor a
+ call ByteFill
ret
-; 0x33e3 \ No newline at end of file
diff --git a/home/print_text.asm b/home/print_text.asm
new file mode 100644
index 0000000..e8b4eeb
--- /dev/null
+++ b/home/print_text.asm
@@ -0,0 +1,51 @@
+include "constants.asm"
+
+if DEBUG
+SECTION "Print Letter Delay", ROM0[$33a3]
+else
+SECTION "Print Letter Delay", 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 \ No newline at end of file
diff --git a/home/rtc.asm b/home/rtc.asm
new file mode 100644
index 0000000..6179278
--- /dev/null
+++ b/home/rtc.asm
@@ -0,0 +1,20 @@
+include "constants.asm"
+
+if DEBUG
+SECTION "Time Of Day Palettes", ROM0 [$032B]
+else
+SECTION "Time Of Day Palettes", ROM0 [$02EF]
+endc
+
+UpdateTimeOfDayPalettes: ; 32b (0:032b)
+ ld a, [wVramState]
+ bit 0, a
+ ret z
+TimeOfDayPals::
+ callab _TimeOfDayPals ; Func_8c2e3
+ ret
+
+UpdateTimePals:: ; 33a
+ callab _UpdateTimePals ; Func_8c335
+ ret
+
diff --git a/home/serial.asm b/home/serial.asm
index 48d6832..d51e5a6 100644
--- a/home/serial.asm
+++ b/home/serial.asm
@@ -16,7 +16,7 @@ Serial::
ldh a, [hSerialSend]
ld [rSB], a
ldh a, [hLinkPlayerNumber]
- cp 2
+ cp USING_INTERNAL_CLOCK
jr z, .done
ld a, 1 << rSC_ON
ld [rSC], a
@@ -26,7 +26,7 @@ Serial::
ld a, [rSB]
ldh [hSerialReceive], a
ldh [hLinkPlayerNumber], a
- cp 2
+ cp USING_INTERNAL_CLOCK
jr z, .master
xor a
ld [rSB], a
@@ -43,7 +43,7 @@ Serial::
xor a
ld [rSB], a
.done
- ld a, 1
+ ld a, TRUE
ldh [hSerialReceived], a
ld a, SERIAL_NO_DATA_BYTE
ldh [hSerialSend], a
@@ -52,3 +52,296 @@ Serial::
pop bc
pop af
reti
+
+Serial_ExchangeBytes:: ; 64c
+ ld a, $1
+ ldh [hSerialIgnoringInitialData], a
+.loop
+ ld a, [hl]
+ ldh [hSerialSend], a
+ call Serial_ExchangeByte
+ push bc
+ ld b, a
+ inc hl
+ ld a, $30
+.wait
+ dec a
+ jr nz, .wait
+ ldh a, [hSerialIgnoringInitialData]
+ and a
+ ld a, b
+ pop bc
+ jr z, .load
+ dec hl
+ cp SERIAL_PREAMBLE_BYTE
+ jr nz, .loop
+ xor a
+ ldh [hSerialIgnoringInitialData], a
+ jr .loop
+
+.load
+ ld [de], a
+ inc de
+ dec bc
+ ld a, b
+ or c
+ jr nz, .loop
+ ret
+
+Serial_ExchangeByte:: ; 677 (0:0677)
+.loop
+ xor a
+ ldh [hSerialReceived], a
+ ldh a, [hLinkPlayerNumber]
+ cp USING_INTERNAL_CLOCK
+ jr nz, .not_player_2
+ ld a, (1 << rSC_ON) | 1
+ ldh [rSC], a
+.not_player_2
+.loop2
+ ldh a, [hSerialReceived]
+ and a
+ jr nz, .reset_ffca
+ ldh a, [hLinkPlayerNumber]
+ cp $1
+ jr nz, .not_player_1_or_wLinkTimeoutFrames_zero
+ call CheckwLinkTimeoutFramesNonzero
+ jr z, .not_player_1_or_wLinkTimeoutFrames_zero
+ call .delay_15_cycles
+ push hl
+ ld hl, wLinkTimeoutFrames + 1
+ inc [hl]
+ jr nz, .no_rollover_up
+ dec hl
+ inc [hl]
+
+.no_rollover_up
+ pop hl
+ call CheckwLinkTimeoutFramesNonzero
+ jr nz, .loop2
+ jp SerialDisconnected
+
+.not_player_1_or_wLinkTimeoutFrames_zero
+ ldh a, [rIE]
+ and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK)
+ cp 1 << SERIAL
+ jr nz, .loop2
+ ld a, [wcb58]
+ dec a
+ ld [wcb58], a
+ jr nz, .loop2
+ ld a, [wcb58 + 1]
+ dec a
+ ld [wcb58 + 1], a
+ jr nz, .loop2
+ ldh a, [hLinkPlayerNumber]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .reset_ffca
+
+ ld a, 255
+.delay_255_cycles
+ dec a
+ jr nz, .delay_255_cycles
+
+.reset_ffca
+ xor a
+ ldh [hSerialReceived], a
+ ldh a, [rIE]
+ and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK)
+ sub 1 << SERIAL
+ jr nz, .rIE_not_equal_8
+
+ ; LOW($5000)
+ ld [wcb58], a
+ ld a, HIGH($5000)
+ ld [wcb58 + 1], a
+
+.rIE_not_equal_8
+ ldh a, [hSerialReceive]
+ cp SERIAL_NO_DATA_BYTE
+ ret nz
+ call CheckwLinkTimeoutFramesNonzero
+ jr z, .linkTimeoutFrames_zero
+ push hl
+ ld hl, wLinkTimeoutFrames + 1
+ ld a, [hl]
+ dec a
+ ld [hld], a
+ inc a
+ jr nz, .no_rollover
+ dec [hl]
+
+.no_rollover
+ pop hl
+ call CheckwLinkTimeoutFramesNonzero
+ jr z, SerialDisconnected
+
+.linkTimeoutFrames_zero
+ ldh a, [rIE]
+ and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK)
+ cp 1 << SERIAL
+ ld a, SERIAL_NO_DATA_BYTE
+ ret z
+ ld a, [hl]
+ ldh [hSerialSend], a
+ call DelayFrame
+ jp .loop
+
+.delay_15_cycles: ; 70e (0:070e)
+ ld a, 15
+.delay_cycles
+ dec a
+ jr nz, .delay_cycles
+ ret
+
+CheckwLinkTimeoutFramesNonzero: ; 714 (0:0714)
+ push hl
+ ld hl, wLinkTimeoutFrames
+ ld a, [hli]
+ or [hl]
+ pop hl
+ ret
+
+SerialDisconnected: ; 71c (0:071c)
+ dec a
+ ld [wLinkTimeoutFrames], a
+ ld [wLinkTimeoutFrames + 1], a
+ ret
+
+; This is used to exchange the button press and selected menu item on the link menu.
+; The data is sent thrice and read twice to increase reliability.
+Serial_ExchangeLinkMenuSelection::
+ ld hl, wPlayerLinkAction
+ ld de, wOtherPlayerLinkMode
+ ld c, 2
+ ld a, TRUE
+ ldh [hSerialIgnoringInitialData], a
+.asm_0730
+ call DelayFrame
+ ld a, [hl]
+ ldh [hSerialSend], a
+ call Serial_ExchangeByte
+ ld b, a
+ inc hl
+ ldh a, [hSerialIgnoringInitialData]
+ and a
+ ld a, FALSE
+ ldh [hSerialIgnoringInitialData], a
+ jr nz, .asm_0730
+ ld a, b
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .asm_0730
+ ret
+
+Serial_PrintWaitingTextAndSyncAndExchangeNybble::
+ call BackUpTilesToBuffer
+ callab PlaceWaitingText
+ call WaitLinkTransfer
+ jp ReloadTilesFromBuffer
+
+WaitLinkTransfer:: ; 75c (0:075c)
+ ld a, $ff
+ ld [wOtherPlayerLinkAction], a
+.loop
+ call LinkTransfer
+ call DelayFrame
+ call CheckwLinkTimeoutFramesNonzero
+ jr z, .check
+ push hl
+ ld hl, wLinkTimeoutFrames + 1
+ dec [hl]
+ jr nz, .skip
+ dec hl
+ dec [hl]
+ jr nz, .skip
+ ; We might be disconnected
+ pop hl
+ xor a
+ jp SerialDisconnected
+
+.skip
+ pop hl
+.check
+ ld a, [wOtherPlayerLinkAction]
+ inc a
+ jr z, .loop
+
+ ld b, 10
+.receive
+ call DelayFrame
+ call LinkTransfer
+ dec b
+ jr nz, .receive
+
+ ld b, 10
+.acknowledge
+ call DelayFrame
+ call LinkDataReceived
+ dec b
+ jr nz, .acknowledge
+
+ ld a, [wOtherPlayerLinkAction]
+ ld [wOtherPlayerLinkMode], a
+ ret
+
+LinkTransfer:: ; 7a0 (0:07a0)
+ push bc
+ ld b, $60
+ ld a, [wLinkMode]
+ cp $2
+ jr c, .asm_07ac
+ ld b, $70
+
+.asm_07ac
+ call .Receive
+ ld a, [wPlayerLinkAction]
+ add b
+ ldh [hSerialSend], a
+ ldh a, [hLinkPlayerNumber]
+ cp USING_INTERNAL_CLOCK
+ jr nz, .player_1
+ ld a, (1 << rSC_ON) | 1
+ ldh [rSC], a
+
+.player_1
+ call .Receive
+ pop bc
+ ret
+
+.Receive: ; 7c4 (0:07c4)
+ ldh a, [hSerialReceive]
+ ld [wOtherPlayerLinkMode], a
+ and $f0
+ cp b
+ ret nz
+ xor a
+ ldh [hSerialReceive], a
+ ld a, [wOtherPlayerLinkMode]
+ and $f
+ ld [wOtherPlayerLinkAction], a
+ ret
+
+LinkDataReceived:: ; 7d9 (0:07d9)
+; Let the other system know that the data has been received.
+ xor a
+ ldh [hSerialSend], a
+ ldh a, [hLinkPlayerNumber]
+ cp USING_INTERNAL_CLOCK
+ ret nz
+ ld a, (1 << rSC_ON) | 1
+ ldh [rSC], a
+ ret
+
+Unreferenced_Function7e6::
+ ld a, [wLinkMode]
+ and a
+ ret nz
+ ld a, USING_INTERNAL_CLOCK
+ ldh [rSB], a
+ xor a
+ ldh [hSerialReceive], a
+ ld a, (1 << rSC_ON)
+ ldh [rSC], a
+ ret
diff --git a/home/text.asm b/home/text.asm
index 83bbd42..b3cd75c 100644
--- a/home/text.asm
+++ b/home/text.asm
@@ -1,6 +1,370 @@
INCLUDE "constants.asm"
-SECTION "Text Commands", ROM0[$107e]
+SECTION "Text Printing Functions", ROM0[$0e18]
+
+ClearBox:: ; 00:0e18
+; Fill a c*b box at hl with blank tiles.
+ ld a, " "
+ ; fallthrough
+
+FillBoxWithByte::
+ ld de, SCREEN_WIDTH
+.asm_0e1d: ; 00:0e1d
+ push hl
+ push bc
+.asm_0e1f: ; 00:0e1f
+ ld [hli], a
+ dec c
+ jr nz, .asm_0e1f
+ pop bc
+ pop hl
+ add hl, de
+ dec b
+ jr nz, .asm_0e1d
+ ret
+
+ClearTileMap:: ; 00:0e2a
+; Fill wTileMap with blank tiles.
+
+ hlcoord 0, 0
+ ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
+ ld a, " "
+ call ByteFill
+ ldh a, [rLCDC]
+ bit 7, a
+ ret z
+ jp WaitBGMap
+
+DrawTextBox:: ; 00:0e3d
+
+ ; Top
+ push hl
+ ld a, "┌"
+ ld [hli], a
+ inc a ; "─"
+ call .PlaceChars
+ inc a ; "┐"
+ ld [hl], a
+ pop hl
+
+ ; Middle
+ ld de, SCREEN_WIDTH
+ add hl, de
+.row
+ push hl
+ ld a, "│"
+ ld [hli], a
+ ld a, " "
+ call .PlaceChars
+ ld [hl], "│"
+ pop hl
+
+ ld de, SCREEN_WIDTH
+ add hl, de
+ dec b
+ jr nz, .row
+
+ ; Bottom
+ ld a, "└"
+ ld [hli], a
+ ld a, "─"
+ call .PlaceChars
+ ld [hl], "┘"
+
+ ret
+; e6a
+
+.PlaceChars: ; e6a
+; Place char a c times.
+ ld d, c
+.loop
+ ld [hli], a
+ dec d
+ jr nz, .loop
+ ret
+; e70
+
+PrintText::
+ push hl
+ hlcoord TEXTBOX_X, TEXTBOX_Y
+ ld b, TEXTBOX_INNERH
+ ld c, TEXTBOX_INNERW
+ call DrawTextBox
+ call UpdateSprites
+ call WaitBGMap
+ pop hl
+PrintTextBoxText::
+ bccoord TEXTBOX_INNERX, TEXTBOX_INNERY
+ call TextCommandProcessor
+ ret
+
+SpeechTextBox::
+; Standard textbox.
+ hlcoord TEXTBOX_X, TEXTBOX_Y
+ ld b, TEXTBOX_INNERH
+ ld c, TEXTBOX_INNERW
+ jp DrawTextBox
+
+PlaceString:: ; 00:0e93
+ push hl
+PlaceNextChar:: ; 00:0e94
+ ld a, [de]
+ cp "@"
+ jr nz, CheckDict
+ ld b, h
+ ld c, l
+ pop hl
+ ret
+
+CheckDict:: ; 00:0e9d
+dict: MACRO
+if \1 == 0
+ and a
+else
+ cp \1
+endc
+ jp z, \2
+ENDM
+
+ cp "<NEXT>"
+ jr nz, .asm_0eaa
+ pop hl
+ ld bc, 2 * SCREEN_WIDTH
+ add hl, bc
+ push hl
+ jp NextChar
+
+.asm_0eaa: ; 00:0eaa
+ cp "<LINE>"
+ jr nz, .asm_0eb6
+ pop hl
+ hlcoord 1, 16
+ push hl
+ jp NextChar
+
+.asm_0eb6: ; 00:0eb6
+ dict 0, NullChar
+ dict "<SCROLL>", _ContTextNoPause
+ dict "<_CONT>", _ContText
+ dict "<PARA>", Paragraph
+ dict "<MOM>", PrintMomsName
+ dict "<PLAYER>", PrintPlayerName
+ dict "<RIVAL>", PrintRivalName
+ dict "#", PlacePOKe
+ dict "<PC>", PCChar
+ dict "<ROCKET>", RocketChar
+ dict "<TM>", TMChar
+ dict "<TRAINER>", TrainerChar
+ dict "<CONT>", ContText
+ dict "<……>", SixDotsChar
+ dict "<DONE>", DoneText
+ dict "<PROMPT>", PromptText
+ dict "<GA>", GaCharacter
+ dict "<DEXEND>", PlaceDexEnd
+ dict "<TARGET>", PlaceMoveTargetsName
+ dict "<USER>", PlaceMoveUsersName
+
+ cp "゚"
+ jr z, .diacritic
+ cp "゙"
+ jr nz, .not_diacritic
+.diacritic: ; 00:0f21
+ push hl
+ ld bc, -SCREEN_WIDTH
+ add hl, bc
+ ld [hl], a
+ pop hl
+ jr NextChar
+
+.not_diacritic: ; 00:0f2a
+ cp FIRST_REGULAR_TEXT_CHAR
+ jr nc, .place
+ cp "パ"
+ jr nc, .handakuten
+ cp FIRST_HIRAGANA_DAKUTEN_CHAR
+ jr nc, .hiragana_dakuten
+ add "カ" - "ガ"
+ jr .katakana_dakuten
+
+.hiragana_dakuten: ; 00:0f3a
+ add "か" - "が"
+.katakana_dakuten: ; 00:0f3c
+ push af
+ ld a, "゙"
+ push hl
+ ld bc, -SCREEN_WIDTH
+ add hl, bc
+ ld [hl], a
+ pop hl
+ pop af
+ jr .place
+
+.handakuten: ; 00:0f49
+ cp "ぱ"
+ jr nc, .hiragana_handakuten
+ add "ハ" - "パ"
+ jr .katakana_handakuten
+
+.hiragana_handakuten: ; 00:0f51
+ add "は" - "ぱ"
+.katakana_handakuten: ; 00:0f53
+ push af
+ ld a, "゚"
+ push hl
+ ld bc, -SCREEN_WIDTH
+ add hl, bc
+ ld [hl], a
+ pop hl
+ pop af
+.place: ; 00:0f5e
+ ld [hli], a
+ call PrintLetterDelay
+NextChar:: ; 00:0f62
+ inc de
+ jp PlaceNextChar
+
+NullChar:: ; 00:0f66
+ ld b, h
+ ld c, l
+ pop hl
+ ld de, .Text
+ dec de
+ ret
+
+.Text:
+ deciram hTextErrno, 1, 2
+ text "エラー"
+ done
+
+print_name: MACRO
+ push de
+ ld de, \1
+ jr PlaceCommandCharacter
+ENDM
+
+PrintMomsName:: print_name wMomsName
+PrintPlayerName:: print_name wPlayerName
+PrintRivalName:: print_name wRivalsName
+
+TrainerChar:: print_name TrainerCharText
+TMChar:: print_name TMCharText
+PCChar:: print_name PCCharText
+RocketChar:: print_name RocketCharText
+PlacePOKe:: print_name POKeCharText
+SixDotsChar:: print_name SixDotsCharText
+GaCharacter:: print_name GaCharacterTExt
+
+PlaceMoveTargetsName:: ; 00:0fb3
+ ldh a, [hBattleTurn]
+ xor $1
+ jr asm_0fbb
+
+PlaceMoveUsersName:: ; 00:0fb9
+ ldh a, [hBattleTurn]
+asm_0fbb: ; 00:0fbb
+ push de
+ and a
+ jr nz, .asm_0fc4
+ ld de, wEnemyMonNickname
+ jr PlaceCommandCharacter
+
+.asm_0fc4: ; 00:0fc4
+ ld de, EnemyText
+ call PlaceString
+ ld h, b
+ ld l, c
+ ld de, wBattleMonNickname
+PlaceCommandCharacter: ; 00:0fcf
+ call PlaceString
+ ld h, b
+ ld l, c
+ pop de
+ inc de
+ jp PlaceNextChar
+
+TMCharText:: db "わざマシン@"
+TrainerCharText:: db "トレーナー@"
+PCCharText:: db "パソコン@"
+RocketCharText:: db "ロケットだん@"
+POKeCharText:: db "ポケモン@"
+SixDotsCharText:: db "……@"
+EnemyText:: db "てきの @"
+GaCharacterTExt:: db "が @"
+
+ContText:: ; 00:1001
+ push de
+ ld b, h
+ ld c, l
+ ld hl, .Text
+ call TextCommandProcessor
+ ld h, b
+ ld l, c
+ pop de
+ inc de
+ jp PlaceNextChar
+
+.Text:
+ text "<_CONT>@"
+ db "@"
+
+PlaceDexEnd:: ; 00:1015
+ ld [hl], "。"
+ pop hl
+ ret
+
+PromptText:: ; 00:1019
+ ld a, [wLinkMode]
+ cp $3
+ jp z, Function1026
+ ld a, "▼"
+ ldcoord_a 18, 17
+Function1026:: ; 00:1026
+ call ProtectedWaitBGMap
+ call ButtonSound
+ ld a, "─"
+ ldcoord_a 18, 17
+DoneText:: ; 00:1031
+ pop hl
+ ld de, .Text
+ dec de
+ ret
+
+.Text:: ; 00:1037
+ db "@"
+
+Paragraph:: ; 00:1038
+ push de
+ ld a, "▼"
+ ldcoord_a 18, 17
+ call ProtectedWaitBGMap
+ call ButtonSound
+ hlcoord 1, 13
+ lb bc, 4, 18
+ call ClearBox
+ ld a, "─"
+ ldcoord_a 18, 17
+ ld c, 20
+ call DelayFrames
+ pop de
+ hlcoord 1, 14
+ jp NextChar
+
+_ContText:: ; 00:105e
+ ld a, "▼"
+ ldcoord_a 18, 17
+ call ProtectedWaitBGMap
+ push de
+ call ButtonSound
+ pop de
+ ld a, "─"
+ ldcoord_a 18, 17
+_ContTextNoPause:: ; 00:1070
+ push de
+ call ScrollTextUpOneLine
+ call ScrollTextUpOneLine
+ hlcoord 1, 16
+ pop de
+ jp NextChar
ScrollTextUpOneLine:: ; 107e (0:107e)
; move both rows of text in the normal text box up one row
diff --git a/home/time.asm b/home/time.asm
new file mode 100644
index 0000000..3eba96c
--- /dev/null
+++ b/home/time.asm
@@ -0,0 +1,138 @@
+include "constants.asm"
+
+SECTION "RTC and Time Functions", ROM0 [$042B]
+
+LatchClock: ; 42b (0:042b)
+ ld a, 0
+ ld [MBC3LatchClock], a
+ ld a, 1
+ ld [MBC3LatchClock], a
+ ret
+
+UpdateTime:: ; 436 (0:0436)
+ ldh a, [hRTCStatusFlags]
+ bit 0, a
+ ret nz
+ ld a, SRAM_ENABLE
+ ld [MBC3SRamEnable], a
+ call LatchClock
+ ld a, RTC_S
+ ld [MBC3SRamBank], a
+ ld a, [MBC3RTC]
+ and $7f
+ ldh [hRTCSeconds], a
+ ld a, RTC_M
+ ld [MBC3SRamBank], a
+ ld a, [MBC3RTC]
+ and $7f
+ ldh [hRTCMinutes], a
+ ld a, RTC_H
+ ld [MBC3SRamBank], a
+ ld a, [MBC3RTC]
+ and $1f
+ ldh [hRTCHours], a
+ call CloseSRAM
+ ld a, [wce63]
+ bit 1, a
+ jr z, .asm_0478
+ ld a, [wd153]
+ bit 7, a
+ jr nz, .asm_048a
+.asm_0478
+ ldh a, [hRTCHours]
+ ld b, a
+ ld hl, .Data_049c
+.asm_047e
+ ld a, [hli]
+ cp b
+ jr nc, .asm_0485
+ inc hl
+ jr .asm_047e
+
+.asm_0485
+ ld a, [hl]
+ ld [wTimeOfDay], a
+ ret
+
+.asm_048a
+ ldh a, [hRTCSeconds]
+ ld b, a
+ ld hl, .Data_04a4
+.asm_0490
+ ld a, [hli]
+ cp b
+ jr nc, .asm_0497
+ inc hl
+ jr .asm_0490
+
+.asm_0497
+ ld a, [hl]
+ ld [wTimeOfDay], a
+ ret
+
+.Data_049c:
+ db $06, $01
+ db $09, $03
+ db $0f, $00
+ db $18, $01
+
+.Data_04a4:
+ db $1e, $00
+ db $23, $01
+ db $32, $02
+ db $3b, $03
+
+Function04ac::
+ ld hl, hRTCStatusFlags
+ set 0, [hl]
+ call Function04ea
+ ld a, SRAM_ENABLE
+ ld [MBC3SRamEnable], a
+ call LatchClock
+
+ ld a, RTC_S
+ ld [MBC3SRamBank], a
+ ld a, 0
+ ld [MBC3RTC], a
+
+ ld a, RTC_M
+ ld [MBC3SRamBank], a
+ ld a, [wStartMinute]
+ ld [MBC3RTC], a
+
+ ld a, RTC_H
+ ld [MBC3SRamBank], a
+ ld a, [wStartHour]
+ ld [MBC3RTC], a
+
+ ld a, [wStartDay]
+ ldh [hRTCDays], a
+
+ call CloseSRAM
+ ld hl, hRTCStatusFlags
+ res 0, [hl]
+ ret
+
+Function04ea:: ; 4ea (0:04ea)
+ ld a, SRAM_ENABLE
+ ld [MBC3SRamEnable], a
+ call LatchClock
+ ld a, RTC_DH
+ ld [MBC3SRamBank], a
+ ld a, [MBC3RTC]
+ set 6, a
+ ld [MBC3RTC], a
+ call CloseSRAM
+ ret
+
+Function0502:: ; 0502
+ ld a, SRAM_ENABLE
+ ld [MBC3SRamEnable], a
+ call LatchClock
+ ld a, RTC_DH
+ ld [MBC3SRamBank], a
+ ld a, [MBC3RTC]
+ res 6, a
+ ld [MBC3RTC], a
+ call CloseSRAM
+ ret
diff --git a/home/unknown.asm b/home/unknown.asm
index 5b9a6e1..e2cc5cd 100644
--- a/home/unknown.asm
+++ b/home/unknown.asm
@@ -121,3 +121,18 @@ _20F1:: ; 20f1
ld [de], a
inc de
ret
+
+SECTION "Unknown_094c", ROM0 [$094C]
+
+Function094c::
+ ldh a, [hROMBank]
+ push af
+ ld a, BANK(Functionfe255)
+ call Bankswitch
+
+ call Functionfe255
+
+ pop af
+ call Bankswitch
+
+ jp Function4031
diff --git a/home/vcopy.asm b/home/vcopy.asm
index a453da5..8e916f2 100644
--- a/home/vcopy.asm
+++ b/home/vcopy.asm
@@ -545,7 +545,7 @@ EnableSprites:: ; 1531 (0:1531)
ret
; 0x1538
-Function_1538: ; 1538 (0:1538)
+Function1538: ; 1538 (0:1538)
ld a, [$d14f]
bit 0, a
ret z
diff --git a/home/window.asm b/home/window.asm
new file mode 100644
index 0000000..1815e89
--- /dev/null
+++ b/home/window.asm
@@ -0,0 +1,23 @@
+include "constants.asm"
+
+SECTION "Window Functions", ROM0[$1fd4]
+
+RefreshScreen::
+ call ClearWindowData
+ ldh a, [hROMBank]
+ push af
+ ld a, BANK(ReanchorBGMap_NoOAMUpdate) ; and BANK(LoadFonts_NoOAMUpdate)
+ call Bankswitch
+
+ call ReanchorBGMap_NoOAMUpdate
+ call LoadFonts_NoOAMUpdate
+
+ pop af
+ call Bankswitch
+ ret
+
+Function1fea::
+ call Function3171
+ call ClearWindowData
+ call Function202c
+ ret