shithub: pokecrystal

Download patch

ref: 99df17d57173cb82abc668714727c5dada6aac73
parent: 1e1bbbbf8c82364dcfb8e64ad22c4ce3e9988c75
author: Rangi <remy.oukaour+rangi42@gmail.com>
date: Wed Apr 4 20:35:14 EDT 2018

Move more code from home.asm into home/

--- a/home.asm
+++ b/home.asm
@@ -37,7 +37,7 @@
 INCLUDE "home/map_objects.asm"
 INCLUDE "home/sine.asm"
 INCLUDE "home/movement.asm"
-INCLUDE "home/tilemap.asm"
+INCLUDE "home/menu_window.asm"
 INCLUDE "home/menu.asm"
 INCLUDE "home/handshake.asm"
 INCLUDE "home/game_time.asm"
@@ -87,65 +87,10 @@
 	ret
 ; 2ed3
 
-DisableSpriteUpdates:: ; 0x2ed3
-; disables overworld sprite updating?
-	xor a
-	ld [hMapAnims], a
-	ld a, [wVramState]
-	res 0, a
-	ld [wVramState], a
-	ld a, $0
-	ld [wSpriteUpdatesEnabled], a
-	ret
-; 0x2ee4
-
-EnableSpriteUpdates:: ; 2ee4
-	ld a, $1
-	ld [wSpriteUpdatesEnabled], a
-	ld a, [wVramState]
-	set 0, a
-	ld [wVramState], a
-	ld a, $1
-	ld [hMapAnims], a
-	ret
-; 2ef6
-
+INCLUDE "home/sprite_updates.asm"
 INCLUDE "home/string.asm"
+INCLUDE "home/region.asm"
 
-IsInJohto:: ; 2f17
-; Return 0 if the player is in Johto, and 1 in Kanto.
-
-	ld a, [wMapGroup]
-	ld b, a
-	ld a, [wMapNumber]
-	ld c, a
-	call GetWorldMapLocation
-
-	cp FAST_SHIP
-	jr z, .Johto
-
-	cp SPECIAL_MAP
-	jr nz, .CheckRegion
-
-	ld a, [wBackupMapGroup]
-	ld b, a
-	ld a, [wBackupMapNumber]
-	ld c, a
-	call GetWorldMapLocation
-
-.CheckRegion:
-	cp KANTO_LANDMARK
-	jr nc, .Kanto
-
-.Johto:
-	xor a
-	ret
-
-.Kanto:
-	ld a, 1
-	ret
-; 2f3e
-
 ret_2f3e:: ; 2f3e
 	ret
 ; 2f3f
@@ -166,89 +111,11 @@
 ; 2fef
 
 INCLUDE "home/double_speed.asm"
-
-ClearSprites:: ; 300b
-; Erase OAM data
-	ld hl, wVirtualOAM
-	ld b, wVirtualOAMEnd - wVirtualOAM
-	xor a
-.loop
-	ld [hli], a
-	dec b
-	jr nz, .loop
-	ret
-; 3016
-
-HideSprites:: ; 3016
-; Set all OAM y-positions to 160 to hide them offscreen
-	ld hl, wVirtualOAMSprite00YCoord
-	ld de, SPRITEOAMSTRUCT_LENGTH
-	ld b, NUM_SPRITE_OAM_STRUCTS
-	ld a, SCREEN_WIDTH_PX
-.loop
-	ld [hl], a ; y
-	add hl, de
-	dec b
-	jr nz, .loop
-	ret
-; 3026
-
+INCLUDE "home/clear_sprites.asm"
 INCLUDE "home/copy2.asm"
+INCLUDE "home/copy_tilemap.asm"
+INCLUDE "home/copy_name.asm"
 
-LoadTileMapToTempTileMap:: ; 309d
-; Load wTileMap into wTempTileMap
-	ld a, [rSVBK]
-	push af
-	ld a, BANK(wTempTileMap)
-	ld [rSVBK], a
-	hlcoord 0, 0
-	decoord 0, 0, wTempTileMap
-	ld bc, wTileMapEnd - wTileMap
-	call CopyBytes
-	pop af
-	ld [rSVBK], a
-	ret
-; 30b4
-
-Call_LoadTempTileMapToTileMap:: ; 30b4
-	xor a
-	ld [hBGMapMode], a
-	call LoadTempTileMapToTileMap
-	ld a, 1
-	ld [hBGMapMode], a
-	ret
-; 30bf
-
-LoadTempTileMapToTileMap:: ; 30bf
-; Load wTempTileMap into wTileMap
-	ld a, [rSVBK]
-	push af
-	ld a, BANK(wTempTileMap)
-	ld [rSVBK], a
-	hlcoord 0, 0, wTempTileMap
-	decoord 0, 0
-	ld bc, wTileMapEnd - wTileMap
-	call CopyBytes
-	pop af
-	ld [rSVBK], a
-	ret
-; 30d6
-
-CopyName1:: ; 30d6
-; Copies the name from de to wStringBuffer2
-	ld hl, wStringBuffer2
-
-CopyName2:: ; 30d9
-; Copies the name from de to hl
-.loop
-	ld a, [de]
-	inc de
-	ld [hli], a
-	cp "@"
-	jr nz, .loop
-	ret
-; 30e1
-
 IsInArray:: ; 30e1
 ; Find value a for every de bytes in array hl.
 ; Return index in b and carry if found.
@@ -287,133 +154,8 @@
 ; 0x30fe
 
 INCLUDE "home/math.asm"
+INCLUDE "home/print_text.asm"
 
-PrintLetterDelay:: ; 313d
-; Wait before printing the next letter.
-
-; The text speed setting in wOptions is actually a frame count:
-; 	fast: 1 frame
-; 	mid:  3 frames
-; 	slow: 5 frames
-
-; wTextBoxFlags[!0] and A or B override text speed with a one-frame delay.
-; wOptions[4] and wTextBoxFlags[!1] disable the delay.
-
-	ld a, [wOptions]
-	bit NO_TEXT_SCROLL, a
-	ret nz
-
-; non-scrolling text?
-	ld a, [wTextBoxFlags]
-	bit NO_TEXT_DELAY_F, a
-	ret z
-
-	push hl
-	push de
-	push bc
-
-	ld hl, hOAMUpdate
-	ld a, [hl]
-	push af
-
-; orginally turned oam update off...
-;	ld a, 1
-	ld [hl], a
-
-; force fast scroll?
-	ld a, [wTextBoxFlags]
-	bit FAST_TEXT_DELAY_F, a
-	jr z, .fast
-
-; text speed
-	ld a, [wOptions]
-	and %111
-	jr .updatedelay
-
-.fast
-	ld a, TEXT_DELAY_FAST
-
-.updatedelay
-	ld [wTextDelayFrames], a
-
-.checkjoypad
-	call GetJoypad
-
-; input override
-	ld a, [wDisableTextAcceleration]
-	and a
-	jr nz, .wait
-
-; Wait one frame if holding A or B.
-	ld a, [hJoyDown]
-	bit A_BUTTON_F, a
-	jr z, .checkb
-	jr .delay
-.checkb
-	bit B_BUTTON_F, a
-	jr z, .wait
-
-.delay
-	call DelayFrame
-	jr .end
-
-.wait
-	ld a, [wTextDelayFrames]
-	and a
-	jr nz, .checkjoypad
-
-.end
-	pop af
-	ld [hOAMUpdate], a
-	pop bc
-	pop de
-	pop hl
-	ret
-; 318c
-
-CopyDataUntil:: ; 318c
-; Copy [hl .. bc) to de.
-
-; In other words, the source data is
-; from hl up to but not including bc,
-; and the destination is de.
-
-	ld a, [hli]
-	ld [de], a
-	inc de
-	ld a, h
-	cp b
-	jr nz, CopyDataUntil
-	ld a, l
-	cp c
-	jr nz, CopyDataUntil
-	ret
-; 0x3198
-
-PrintNum:: ; 3198
-	homecall _PrintNum
-	ret
-; 31a4
-
-MobilePrintNum:: ; 31a4
-	homecall _MobilePrintNum
-	ret
-; 31b0
-
-FarPrintText:: ; 31b0
-	ld [hBuffer], a
-	ld a, [hROMBank]
-	push af
-	ld a, [hBuffer]
-	rst Bankswitch
-
-	call PrintText
-
-	pop af
-	rst Bankswitch
-	ret
-; 31be
-
 CallPointerAt:: ; 31be
 	ld a, [hROMBank]
 	push af
@@ -484,236 +226,8 @@
 	ret
 ; 31f3
 
-ClearBGPalettes:: ; 31f3
-	call ClearPalettes
-WaitBGMap:: ; 31f6
-; Tell VBlank to update BG Map
-	ld a, 1 ; BG Map 0 tiles
-	ld [hBGMapMode], a
-; Wait for it to do its magic
-	ld c, 4
-	call DelayFrames
-	ret
-; 3200
+INCLUDE "home/tilemap.asm"
 
-WaitBGMap2:: ; 0x3200
-	ld a, [hCGB]
-	and a
-	jr z, .bg0
-
-	ld a, 2
-	ld [hBGMapMode], a
-	ld c, 4
-	call DelayFrames
-
-.bg0
-	ld a, 1
-	ld [hBGMapMode], a
-	ld c, 4
-	call DelayFrames
-	ret
-; 0x3218
-
-IsCGB:: ; 3218
-	ld a, [hCGB]
-	and a
-	ret
-; 321c
-
-ApplyTilemap:: ; 321c
-	ld a, [hCGB]
-	and a
-	jr z, .dmg
-
-	ld a, [wSpriteUpdatesEnabled]
-	cp 0
-	jr z, .dmg
-
-	ld a, 1
-	ld [hBGMapMode], a
-	jr CopyTilemapAtOnce
-
-.dmg
-; WaitBGMap
-	ld a, 1
-	ld [hBGMapMode], a
-	ld c, 4
-	call DelayFrames
-	ret
-; 3238
-
-CGBOnly_CopyTilemapAtOnce:: ; 3238
-	ld a, [hCGB]
-	and a
-	jr z, WaitBGMap
-
-CopyTilemapAtOnce:: ; 323d
-	jr .CopyTilemapAtOnce
-; 323f
-
-; unused
-	farcall HDMATransferAttrMapAndTileMapToWRAMBank3
-	ret
-; 3246
-
-.CopyTilemapAtOnce: ; 3246
-	ld a, [hBGMapMode]
-	push af
-	xor a
-	ld [hBGMapMode], a
-
-	ld a, [hMapAnims]
-	push af
-	xor a
-	ld [hMapAnims], a
-
-.wait
-	ld a, [rLY]
-	cp $7f
-	jr c, .wait
-
-	di
-	ld a, BANK(vTiles3)
-	ld [rVBK], a
-	hlcoord 0, 0, wAttrMap
-	call .StackPointerMagic
-	ld a, BANK(vTiles0)
-	ld [rVBK], a
-	hlcoord 0, 0
-	call .StackPointerMagic
-
-.wait2
-	ld a, [rLY]
-	cp $7f
-	jr c, .wait2
-	ei
-
-	pop af
-	ld [hMapAnims], a
-	pop af
-	ld [hBGMapMode], a
-	ret
-; 327b
-
-.StackPointerMagic: ; 327b
-; Copy all tiles to vBGMap
-	ld [hSPBuffer], sp
-	ld sp, hl
-	ld a, [hBGMapAddress + 1]
-	ld h, a
-	ld l, 0
-	ld a, SCREEN_HEIGHT
-	ld [hTilesPerCycle], a
-	ld b, 1 << 1 ; not in v/hblank
-	ld c, LOW(rSTAT)
-
-.loop
-rept SCREEN_WIDTH / 2
-	pop de
-; if in v/hblank, wait until not in v/hblank
-.loop\@
-	ld a, [$ff00+c]
-	and b
-	jr nz, .loop\@
-; load BGMap0
-	ld [hl], e
-	inc l
-	ld [hl], d
-	inc l
-endr
-
-	ld de, BG_MAP_WIDTH - SCREEN_WIDTH
-	add hl, de
-	ld a, [hTilesPerCycle]
-	dec a
-	ld [hTilesPerCycle], a
-	jr nz, .loop
-
-	ld a, [hSPBuffer]
-	ld l, a
-	ld a, [hSPBuffer + 1]
-	ld h, a
-	ld sp, hl
-	ret
-; 32f9
-
-SetPalettes:: ; 32f9
-; Inits the Palettes
-; depending on the system the monochromes palettes or color palettes
-	ld a, [hCGB]
-	and a
-	jr nz, .SetPalettesForGameBoyColor
-	ld a, %11100100
-	ld [rBGP], a
-	ld a, %11010000
-	ld [rOBP0], a
-	ld [rOBP1], a
-	ret
-
-.SetPalettesForGameBoyColor:
-	push de
-	ld a, %11100100
-	call DmgToCgbBGPals
-	lb de, %11100100, %11100100
-	call DmgToCgbObjPals
-	pop de
-	ret
-; 3317
-
-ClearPalettes:: ; 3317
-; Make all palettes white
-
-; CGB: make all the palette colors white
-	ld a, [hCGB]
-	and a
-	jr nz, .cgb
-
-; DMG: just change palettes to 0 (white)
-	xor a
-	ld [rBGP], a
-	ld [rOBP0], a
-	ld [rOBP1], a
-	ret
-
-.cgb
-	ld a, [rSVBK]
-	push af
-
-	ld a, BANK(wBGPals2)
-	ld [rSVBK], a
-
-; Fill wBGPals2 and wOBPals2 with $ffff (white)
-	ld hl, wBGPals2
-	ld bc, 16 palettes
-	ld a, $ff
-	call ByteFill
-
-	pop af
-	ld [rSVBK], a
-
-; Request palette update
-	ld a, 1
-	ld [hCGBPalUpdate], a
-	ret
-; 333e
-
-GetMemSGBLayout:: ; 333e
-	ld b, SCGB_RAM
-GetSGBLayout:: ; 3340
-; load sgb packets unless dmg
-
-	ld a, [hCGB]
-	and a
-	jr nz, .sgb
-
-	ld a, [hSGB]
-	and a
-	ret z
-
-.sgb
-	predef_jump LoadSGBLayout
-; 334e
-
 SetHPPal:: ; 334e
 ; Set palette for hp bar pixel length e at hl.
 	call GetHPPal
@@ -769,634 +283,17 @@
 ; 3380
 
 INCLUDE "home/pokedex_flags.asm"
-
 INCLUDE "home/names.asm"
-
-ScrollingMenu:: ; 350c
-	call CopyMenuData
-	ld a, [hROMBank]
-	push af
-
-	ld a, BANK(_ScrollingMenu)
-	rst Bankswitch
-
-	call _InitScrollingMenu
-	call .UpdatePalettes
-	call _ScrollingMenu
-
-	pop af
-	rst Bankswitch
-
-	ld a, [wMenuJoypad]
-	ret
-; 3524
-
-.UpdatePalettes: ; 3524
-	ld hl, wVramState
-	bit 0, [hl]
-	jp nz, UpdateTimePals
-	jp SetPalettes
-; 352f
-
-InitScrollingMenu:: ; 352f
-	ld a, [wMenuBorderTopCoord]
-	dec a
-	ld b, a
-	ld a, [wMenuBorderBottomCoord]
-	sub b
-	ld d, a
-	ld a, [wMenuBorderLeftCoord]
-	dec a
-	ld c, a
-	ld a, [wMenuBorderRightCoord]
-	sub c
-	ld e, a
-	push de
-	call Coord2Tile
-	pop bc
-	jp TextBox
-; 354b
-
-JoyTextDelay_ForcehJoyDown:: ; 354b joypad
-	call DelayFrame
-
-	ld a, [hInMenu]
-	push af
-	ld a, $1
-	ld [hInMenu], a
-	call JoyTextDelay
-	pop af
-	ld [hInMenu], a
-
-	ld a, [hJoyLast]
-	and D_RIGHT + D_LEFT + D_UP + D_DOWN
-	ld c, a
-	ld a, [hJoyPressed]
-	and A_BUTTON + B_BUTTON + SELECT + START
-	or c
-	ld c, a
-	ret
-; 3567
-
-HandleStoneQueue:: ; 3567
-	ld a, [hROMBank]
-	push af
-
-	call SwitchToMapScriptsBank
-	call .WarpAction
-
-	pop bc
-	ld a, b
-	rst Bankswitch
-	ret
-; 3574
-
-.WarpAction: ; 3574
-	ld hl, OBJECT_MAP_OBJECT_INDEX
-	add hl, de
-	ld a, [hl]
-	cp $ff
-	jr z, .nope
-
-	ld l, a
-	push hl
-	call .IsObjectOnWarp
-	pop hl
-	jr nc, .nope
-	ld d, a
-	ld e, l
-	call .IsObjectInStoneTable
-	jr nc, .nope
-	call CallMapScript
-	farcall EnableScriptMode
-	scf
-	ret
-
-.nope
-	and a
-	ret
-; 3599
-
-.IsObjectOnWarp: ; 3599
-	push de
-
-	ld hl, OBJECT_NEXT_MAP_X
-	add hl, de
-	ld a, [hl]
-	ld hl, OBJECT_NEXT_MAP_Y
-	add hl, de
-	ld e, [hl]
-
-	sub 4
-	ld d, a
-	ld a, e
-	sub 4
-	ld e, a
-	call .check_on_warp
-
-	pop de
-	ret
-; 35b0
-
-.check_on_warp ; 35b0
-	ld hl, wCurrMapWarpsPointer
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	ld a, [wCurrMapWarpCount]
-	and a
-	jr z, .nope2
-
-.loop
-	push af
-	ld a, [hl]
-	cp e
-	jr nz, .not_on_warp
-	inc hl
-	ld a, [hld]
-	cp d
-	jr nz, .not_on_warp
-	jr .found_warp
-
-.not_on_warp
-	ld a, 5
-	add l
-	ld l, a
-	jr nc, .no_carry
-	inc h
-.no_carry
-
-	pop af
-	dec a
-	jr nz, .loop
-
-.nope2
-	and a
-	ret
-
-.found_warp
-	pop af
-	ld d, a
-	ld a, [wCurrMapWarpCount]
-	sub d
-	inc a
-	scf
-	ret
-; 35de
-
-.IsObjectInStoneTable: ; 35de
-	inc e
-	ld hl, CMDQUEUE_ADDR
-	add hl, bc
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-.loop2
-	ld a, [hli]
-	cp $ff
-	jr z, .nope3
-	cp d
-	jr nz, .next_inc3
-	ld a, [hli]
-	cp e
-	jr nz, .next_inc2
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	jr .yes
-
-.next_inc3
-	inc hl
-
-.next_inc2
-	inc hl
-	inc hl
-	jr .loop2
-
-.nope3
-	and a
-	ret
-
-.yes
-	scf
-	ret
-; 3600
-
+INCLUDE "home/scrolling_menu.asm"
+INCLUDE "home/stone_queue.asm"
 INCLUDE "home/trainers.asm"
-
-IsAPokemon:: ; 3741
-; Return carry if species a is not a Pokemon.
-	and a
-	jr z, .NotAPokemon
-	cp EGG
-	jr z, .Pokemon
-	cp NUM_POKEMON + 1
-	jr c, .Pokemon
-
-.NotAPokemon:
-	scf
-	ret
-
-.Pokemon:
-	and a
-	ret
-; 3750
-
-DrawBattleHPBar:: ; 3750
-; Draw an HP bar d tiles long at hl
-; Fill it up to e pixels
-
-	push hl
-	push de
-	push bc
-
-; Place 'HP:'
-	ld a, $60
-	ld [hli], a
-	ld a, $61
-	ld [hli], a
-
-; Draw a template
-	push hl
-	ld a, $62 ; empty bar
-.template
-	ld [hli], a
-	dec d
-	jr nz, .template
-	ld a, $6b ; bar end
-	add b
-	ld [hl], a
-	pop hl
-
-; Safety check # pixels
-	ld a, e
-	and a
-	jr nz, .fill
-	ld a, c
-	and a
-	jr z, .done
-	ld e, 1
-
-.fill
-; Keep drawing tiles until pixel length is reached
-	ld a, e
-	sub TILE_WIDTH
-	jr c, .lastbar
-
-	ld e, a
-	ld a, $6a ; full bar
-	ld [hli], a
-	ld a, e
-	and a
-	jr z, .done
-	jr .fill
-
-.lastbar
-	ld a, $62  ; empty bar
-	add e      ; + e
-	ld [hl], a
-
-.done
-	pop bc
-	pop de
-	pop hl
-	ret
-; 3786
-
-PrepMonFrontpic:: ; 3786
-	ld a, $1
-	ld [wBoxAlignment], a
-
-_PrepMonFrontpic:: ; 378b
-	ld a, [wCurPartySpecies]
-	call IsAPokemon
-	jr c, .not_pokemon
-
-	push hl
-	ld de, vTiles2
-	predef GetMonFrontpic
-	pop hl
-	xor a
-	ld [hGraphicStartTile], a
-	lb bc, 7, 7
-	predef PlaceGraphic
-	xor a
-	ld [wBoxAlignment], a
-	ret
-
-.not_pokemon
-	xor a
-	ld [wBoxAlignment], a
-	inc a
-	ld [wCurPartySpecies], a
-	ret
-; 37b6
-
+INCLUDE "home/mon_stats.asm"
 INCLUDE "home/cry.asm"
-
-PrintLevel:: ; 382d
-; Print wTempMonLevel at hl
-
-	ld a, [wTempMonLevel]
-	ld [hl], "<LV>"
-	inc hl
-
-; How many digits?
-	ld c, 2
-	cp 100 ; This is distinct from MAX_LEVEL.
-	jr c, Print8BitNumRightAlign
-
-; 3-digit numbers overwrite the :L.
-	dec hl
-	inc c
-	jr Print8BitNumRightAlign
-; 383d
-
-PrintLevel_Force3Digits:: ; 383d
-; Print :L and all 3 digits
-	ld [hl], "<LV>"
-	inc hl
-	ld c, 3
-; 3842
-
-Print8BitNumRightAlign:: ; 3842
-	ld [wd265], a
-	ld de, wd265
-	ld b, PRINTNUM_RIGHTALIGN | 1
-	jp PrintNum
-; 384d
-
-Unreferenced_Function384d:: ; 384d
-; GetNthMove
-	ld hl, wListMoves_MoveIndicesBuffer
-	ld c, a
-	ld b, 0
-	add hl, bc
-	ld a, [hl]
-	ret
-; 3856
-
-GetBaseData:: ; 3856
-	push bc
-	push de
-	push hl
-	ld a, [hROMBank]
-	push af
-	ld a, BANK(BaseData)
-	rst Bankswitch
-
-; Egg doesn't have BaseData
-	ld a, [wCurSpecies]
-	cp EGG
-	jr z, .egg
-
-; Get BaseData
-	dec a
-	ld bc, BASE_DATA_SIZE
-	ld hl, BaseData
-	call AddNTimes
-	ld de, wCurBaseData
-	ld bc, BASE_DATA_SIZE
-	call CopyBytes
-	jr .end
-
-.egg
-; ????
-	ld de, UnknownEggPic
-
-; Sprite dimensions
-	ld b, $55 ; 5x5
-	ld hl, wBasePicSize
-	ld [hl], b
-
-; ????
-	ld hl, wBasePadding
-	ld [hl], e
-	inc hl
-	ld [hl], d
-	inc hl
-	ld [hl], e
-	inc hl
-	ld [hl], d
-	jr .end
-
-.end
-; Replace Pokedex # with species
-	ld a, [wCurSpecies]
-	ld [wBaseDexNo], a
-
-	pop af
-	rst Bankswitch
-	pop hl
-	pop de
-	pop bc
-	ret
-; 389c
-
-GetCurNick:: ; 389c
-	ld a, [wCurPartyMon]
-	ld hl, wPartyMonNicknames
-
-GetNick:: ; 38a2
-; Get nickname a from list hl.
-
-	push hl
-	push bc
-
-	call SkipNames
-	ld de, wStringBuffer1
-
-	push de
-	ld bc, MON_NAME_LENGTH
-	call CopyBytes
-	pop de
-
-	callfar CorrectNickErrors
-
-	pop bc
-	pop hl
-	ret
-; 38bb
-
-PrintBCDNumber:: ; 38bb
-; 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
-; bit 5: if set, print currency symbol at the beginning of the string
-;        if unset, do not print the currency symbol
-; bits 0-4: 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.
-	ld b, c ; save flags in b
-	res 7, c
-	res 6, c
-	res 5, c ; c now holds the length
-	bit 5, b
-	jr z, .loop
-	bit 7, b
-	jr nz, .loop ; skip currency symbol
-	ld [hl], "¥"
-	inc hl
-.loop
-	ld a, [de]
-	swap a
-	call PrintBCDDigit ; print upper digit
-	ld a, [de]
-	call PrintBCDDigit ; print lower digit
-	inc de
-	dec c
-	jr nz, .loop
-	bit 7, b ; were any non-zero digits printed?
-	jr z, .done ; if so, we are done
-.numberEqualsZero ; if every digit of the BCD number is zero
-	bit 6, b ; left or right alignment?
-	jr nz, .skipRightAlignmentAdjustment
-	dec hl ; if the string is right-aligned, it needs to be moved back one space
-.skipRightAlignmentAdjustment
-	bit 5, b
-	jr z, .skipCurrencySymbol
-	ld [hl], "¥" ; currency symbol
-	inc hl
-.skipCurrencySymbol
-	ld [hl], "0"
-	call PrintLetterDelay
-	inc hl
-.done
-	ret
-; 0x38f2
-
-PrintBCDDigit:: ; 38f2
-	and %00001111
-	and a
-	jr z, .zeroDigit
-.nonzeroDigit
-	bit 7, b ; have any non-space characters been printed?
-	jr z, .outputDigit
-; if bit 7 is set, then no numbers have been printed yet
-	bit 5, b ; print the currency symbol?
-	jr z, .skipCurrencySymbol
-	ld [hl], "¥"
-	inc hl
-	res 5, b
-.skipCurrencySymbol
-	res 7, b ; unset 7 to indicate that a nonzero digit has been reached
-.outputDigit
-	add "0"
-	ld [hli], a
-	jp PrintLetterDelay
-
-.zeroDigit
-	bit 7, b ; either printing leading zeroes or already reached a nonzero digit?
-	jr z, .outputDigit ; if so, print a zero digit
-	bit 6, b ; left or right alignment?
-	ret nz
-	ld a, " "
-	ld [hli], a ; if right-aligned, "print" a space by advancing the pointer
-	ret
-; 0x3917
-
-GetPartyParamLocation:: ; 3917
-; Get the location of parameter a from wCurPartyMon in hl
-	push bc
-	ld hl, wPartyMons
-	ld c, a
-	ld b, 0
-	add hl, bc
-	ld a, [wCurPartyMon]
-	call GetPartyLocation
-	pop bc
-	ret
-; 3927
-
-GetPartyLocation:: ; 3927
-; Add the length of a PartyMon struct to hl a times.
-	ld bc, PARTYMON_STRUCT_LENGTH
-	jp AddNTimes
-; 392d
-
-Unreferenced_Function392d:: ; 392d
-; GetDexNumber
-; Probably used in gen 1 to convert index number to dex number
-; Not required in gen 2 because index number == dex number
-	push hl
-	ld a, b
-	dec a
-	ld b, 0
-	add hl, bc
-	ld hl, BaseData + BASE_DEX_NO
-	ld bc, BASE_DATA_SIZE
-	call AddNTimes
-	ld a, BANK(BaseData)
-	call GetFarHalfword
-	ld b, l
-	ld c, h
-	pop hl
-	ret
-; 3945
-
+INCLUDE "home/print_level.asm"
+INCLUDE "home/mon_data.asm"
+INCLUDE "home/print_bcd.asm"
+INCLUDE "home/mon_data_2.asm"
 INCLUDE "home/battle.asm"
-
-PushLYOverrides:: ; 3b0c
-
-	ld a, [hLCDCPointer]
-	and a
-	ret z
-
-	ld a, LOW(wLYOverridesBackup)
-	ld [wRequested2bppSource], a
-	ld a, HIGH(wLYOverridesBackup)
-	ld [wRequested2bppSource + 1], a
-
-	ld a, LOW(wLYOverrides)
-	ld [wRequested2bppDest], a
-	ld a, HIGH(wLYOverrides)
-	ld [wRequested2bppDest + 1], a
-
-	ld a, (wLYOverridesEnd - wLYOverrides) / 16
-	ld [wRequested2bpp], a
-	ret
-; 3b2a
-
-_InitSpriteAnimStruct:: ; 3b2a
-
-	ld [wSpriteAnimIDBuffer], a
-	ld a, [hROMBank]
-	push af
-
-	ld a, BANK(InitSpriteAnimStruct)
-	rst Bankswitch
-	ld a, [wSpriteAnimIDBuffer]
-
-	call InitSpriteAnimStruct
-
-	pop af
-	rst Bankswitch
-
-	ret
-; 3b3c
-
-ReinitSpriteAnimFrame:: ; 3b3c
-
-	ld [wSpriteAnimIDBuffer], a
-	ld a, [hROMBank]
-	push af
-
-	ld a, BANK(_ReinitSpriteAnimFrame)
-	rst Bankswitch
-	ld a, [wSpriteAnimIDBuffer]
-
-	call _ReinitSpriteAnimFrame
-
-	pop af
-	rst Bankswitch
-
-	ret
-; 3b4e
-
+INCLUDE "home/sprite_anims.asm"
 INCLUDE "home/audio.asm"
 INCLUDE "home/mobile.asm"
--- /dev/null
+++ b/home/clear_sprites.asm
@@ -1,0 +1,25 @@
+ClearSprites:: ; 300b
+; Erase OAM data
+	ld hl, wVirtualOAM
+	ld b, wVirtualOAMEnd - wVirtualOAM
+	xor a
+.loop
+	ld [hli], a
+	dec b
+	jr nz, .loop
+	ret
+; 3016
+
+HideSprites:: ; 3016
+; Set all OAM y-positions to 160 to hide them offscreen
+	ld hl, wVirtualOAMSprite00YCoord
+	ld de, SPRITEOAMSTRUCT_LENGTH
+	ld b, NUM_SPRITE_OAM_STRUCTS
+	ld a, SCREEN_WIDTH_PX
+.loop
+	ld [hl], a ; y
+	add hl, de
+	dec b
+	jr nz, .loop
+	ret
+; 3026
--- /dev/null
+++ b/home/copy_name.asm
@@ -1,0 +1,14 @@
+CopyName1:: ; 30d6
+; Copies the name from de to wStringBuffer2
+	ld hl, wStringBuffer2
+
+CopyName2:: ; 30d9
+; Copies the name from de to hl
+.loop
+	ld a, [de]
+	inc de
+	ld [hli], a
+	cp "@"
+	jr nz, .loop
+	ret
+; 30e1
--- /dev/null
+++ b/home/copy_tilemap.asm
@@ -1,0 +1,38 @@
+LoadTileMapToTempTileMap:: ; 309d
+; Load wTileMap into wTempTileMap
+	ld a, [rSVBK]
+	push af
+	ld a, BANK(wTempTileMap)
+	ld [rSVBK], a
+	hlcoord 0, 0
+	decoord 0, 0, wTempTileMap
+	ld bc, wTileMapEnd - wTileMap
+	call CopyBytes
+	pop af
+	ld [rSVBK], a
+	ret
+; 30b4
+
+Call_LoadTempTileMapToTileMap:: ; 30b4
+	xor a
+	ld [hBGMapMode], a
+	call LoadTempTileMapToTileMap
+	ld a, 1
+	ld [hBGMapMode], a
+	ret
+; 30bf
+
+LoadTempTileMapToTileMap:: ; 30bf
+; Load wTempTileMap into wTileMap
+	ld a, [rSVBK]
+	push af
+	ld a, BANK(wTempTileMap)
+	ld [rSVBK], a
+	hlcoord 0, 0, wTempTileMap
+	decoord 0, 0
+	ld bc, wTileMapEnd - wTileMap
+	call CopyBytes
+	pop af
+	ld [rSVBK], a
+	ret
+; 30d6
--- /dev/null
+++ b/home/menu_window.asm
@@ -1,0 +1,257 @@
+PushWindow:: ; 1c00
+	callfar _PushWindow
+	ret
+; 1c07
+
+ExitMenu:: ; 0x1c07
+	push af
+	callfar _ExitMenu
+	pop af
+	ret
+
+InitVerticalMenuCursor:: ; 0x1c10
+	callfar _InitVerticalMenuCursor
+	ret
+
+CloseWindow:: ; 0x1c17
+	push af
+	call ExitMenu
+	call ApplyTilemap
+	call UpdateSprites
+	pop af
+	ret
+
+RestoreTileBackup:: ; 0x1c23
+	call MenuBoxCoord2Tile
+	call .copy
+	call MenuBoxCoord2Attr
+	call .copy
+	ret
+; 0x1c30
+
+.copy ; 0x1c30
+	call GetMenuBoxDims
+	inc b
+	inc c
+
+.row
+	push bc
+	push hl
+
+.col
+	ld a, [de]
+	ld [hli], a
+	dec de
+	dec c
+	jr nz, .col ; 0x1c3b $fa
+
+	pop hl
+	ld bc, SCREEN_WIDTH
+	add hl, bc
+	pop bc
+	dec b
+	jr nz, .row ; 0x1c44 $ef
+
+	ret
+
+PopWindow:: ; 0x1c47
+	ld b, $10
+	ld de, wMenuFlags
+.loop
+	ld a, [hld]
+	ld [de], a
+	inc de
+	dec b
+	jr nz, .loop ; 0x1c50 $fa
+	ret
+
+GetMenuBoxDims:: ; 0x1c53
+	ld a, [wMenuBorderTopCoord] ; top
+	ld b, a
+	ld a, [wMenuBorderBottomCoord] ; bottom
+	sub b
+	ld b, a
+	ld a, [wMenuBorderLeftCoord] ; left
+	ld c, a
+	ld a, [wMenuBorderRightCoord] ; right
+	sub c
+	ld c, a
+	ret
+; 0x1c66
+
+CopyMenuData:: ; 1c66
+	push hl
+	push de
+	push bc
+	push af
+	ld hl, wMenuDataPointer
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	ld de, wMenuDataFlags
+	ld bc, wMenuDataEnd - wMenuDataFlags
+	call CopyBytes
+	pop af
+	pop bc
+	pop de
+	pop hl
+	ret
+; 1c7e
+
+GetWindowStackTop:: ; 1c7e
+	ld hl, wWindowStackPointer
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	inc hl
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	ret
+; 1c89
+
+PlaceVerticalMenuItems:: ; 1c89
+	call CopyMenuData
+	ld hl, wMenuDataPointer
+	ld e, [hl]
+	inc hl
+	ld d, [hl]
+	call GetMenuTextStartCoord
+	call Coord2Tile ; hl now contains the tilemap address where we will start printing text.
+	inc de
+	ld a, [de] ; Number of items
+	inc de
+	ld b, a
+.loop
+	push bc
+	call PlaceString
+	inc de
+	ld bc, 2 * SCREEN_WIDTH
+	add hl, bc
+	pop bc
+	dec b
+	jr nz, .loop
+
+	ld a, [wMenuDataFlags]
+	bit 4, a
+	ret z
+
+	call MenuBoxCoord2Tile
+	ld a, [de]
+	ld c, a
+	inc de
+	ld b, $0
+	add hl, bc
+	jp PlaceString
+; 1cbb
+
+MenuBox:: ; 1cbb
+	call MenuBoxCoord2Tile
+	call GetMenuBoxDims
+	dec b
+	dec c
+	jp TextBox
+; 1cc6
+
+GetMenuTextStartCoord:: ; 1cc6
+	ld a, [wMenuBorderTopCoord]
+	ld b, a
+	inc b
+	ld a, [wMenuBorderLeftCoord]
+	ld c, a
+	inc c
+; bit 6: if not set, leave extra room on top
+	ld a, [wMenuDataFlags]
+	bit 6, a
+	jr nz, .bit_6_set
+	inc b
+
+.bit_6_set
+; bit 7: if set, leave extra room on the left
+	ld a, [wMenuDataFlags]
+	bit 7, a
+	jr z, .bit_7_clear
+	inc c
+
+.bit_7_clear
+	ret
+; 1ce1
+
+ClearMenuBoxInterior:: ; 1ce1
+	call MenuBoxCoord2Tile
+	ld bc, SCREEN_WIDTH + 1
+	add hl, bc
+	call GetMenuBoxDims
+	dec b
+	dec c
+	call ClearBox
+	ret
+; 1cf1
+
+ClearWholeMenuBox:: ; 1cf1
+	call MenuBoxCoord2Tile
+	call GetMenuBoxDims
+	inc c
+	inc b
+	call ClearBox
+	ret
+; 1cfd
+
+
+MenuBoxCoord2Tile:: ; 1cfd
+	ld a, [wMenuBorderLeftCoord]
+	ld c, a
+	ld a, [wMenuBorderTopCoord]
+	ld b, a
+; 1d05
+
+
+Coord2Tile:: ; 1d05
+; Return the address of wTileMap(c, b) in hl.
+	xor a
+	ld h, a
+	ld l, b
+	ld a, c
+	ld b, h
+	ld c, l
+	add hl, hl
+	add hl, hl
+	add hl, bc
+	add hl, hl
+	add hl, hl
+	ld c, a
+	xor a
+	ld b, a
+	add hl, bc
+	bccoord 0, 0
+	add hl, bc
+	ret
+; 1d19
+
+MenuBoxCoord2Attr:: ; 1d19
+	ld a, [wMenuBorderLeftCoord]
+	ld c, a
+	ld a, [wMenuBorderTopCoord]
+	ld b, a
+
+Coord2Attr:: ; 1d21
+; Return the address of wAttrMap(c, b) in hl.
+	xor a
+	ld h, a
+	ld l, b
+	ld a, c
+	ld b, h
+	ld c, l
+	add hl, hl
+	add hl, hl
+	add hl, bc
+	add hl, hl
+	add hl, hl
+	ld c, a
+	xor a
+	ld b, a
+	add hl, bc
+	bccoord 0, 0, wAttrMap
+	add hl, bc
+	ret
+; 1d35
--- /dev/null
+++ b/home/mon_data.asm
@@ -1,0 +1,90 @@
+Unreferenced_GetNthMove:: ; 384d
+	ld hl, wListMoves_MoveIndicesBuffer
+	ld c, a
+	ld b, 0
+	add hl, bc
+	ld a, [hl]
+	ret
+; 3856
+
+GetBaseData:: ; 3856
+	push bc
+	push de
+	push hl
+	ld a, [hROMBank]
+	push af
+	ld a, BANK(BaseData)
+	rst Bankswitch
+
+; Egg doesn't have BaseData
+	ld a, [wCurSpecies]
+	cp EGG
+	jr z, .egg
+
+; Get BaseData
+	dec a
+	ld bc, BASE_DATA_SIZE
+	ld hl, BaseData
+	call AddNTimes
+	ld de, wCurBaseData
+	ld bc, BASE_DATA_SIZE
+	call CopyBytes
+	jr .end
+
+.egg
+; ????
+	ld de, UnknownEggPic
+
+; Sprite dimensions
+	ld b, $55 ; 5x5
+	ld hl, wBasePicSize
+	ld [hl], b
+
+; ????
+	ld hl, wBasePadding
+	ld [hl], e
+	inc hl
+	ld [hl], d
+	inc hl
+	ld [hl], e
+	inc hl
+	ld [hl], d
+	jr .end
+
+.end
+; Replace Pokedex # with species
+	ld a, [wCurSpecies]
+	ld [wBaseDexNo], a
+
+	pop af
+	rst Bankswitch
+	pop hl
+	pop de
+	pop bc
+	ret
+; 389c
+
+GetCurNick:: ; 389c
+	ld a, [wCurPartyMon]
+	ld hl, wPartyMonNicknames
+
+GetNick:: ; 38a2
+; Get nickname a from list hl.
+
+	push hl
+	push bc
+
+	call SkipNames
+	ld de, wStringBuffer1
+
+	push de
+	ld bc, MON_NAME_LENGTH
+	call CopyBytes
+	pop de
+
+	callfar CorrectNickErrors
+
+	pop bc
+	pop hl
+	ret
+; 38bb
--- /dev/null
+++ b/home/mon_data_2.asm
@@ -1,0 +1,37 @@
+GetPartyParamLocation:: ; 3917
+; Get the location of parameter a from wCurPartyMon in hl
+	push bc
+	ld hl, wPartyMons
+	ld c, a
+	ld b, 0
+	add hl, bc
+	ld a, [wCurPartyMon]
+	call GetPartyLocation
+	pop bc
+	ret
+; 3927
+
+GetPartyLocation:: ; 3927
+; Add the length of a PartyMon struct to hl a times.
+	ld bc, PARTYMON_STRUCT_LENGTH
+	jp AddNTimes
+; 392d
+
+Unreferenced_GetDexNumber:: ; 392d
+; Probably used in gen 1 to convert index number to dex number
+; Not required in gen 2 because index number == dex number
+	push hl
+	ld a, b
+	dec a
+	ld b, 0
+	add hl, bc
+	ld hl, BaseData + BASE_DEX_NO
+	ld bc, BASE_DATA_SIZE
+	call AddNTimes
+	ld a, BANK(BaseData)
+	call GetFarHalfword
+	ld b, l
+	ld c, h
+	pop hl
+	ret
+; 3945
--- /dev/null
+++ b/home/mon_stats.asm
@@ -1,0 +1,107 @@
+IsAPokemon:: ; 3741
+; Return carry if species a is not a Pokemon.
+	and a
+	jr z, .NotAPokemon
+	cp EGG
+	jr z, .Pokemon
+	cp NUM_POKEMON + 1
+	jr c, .Pokemon
+
+.NotAPokemon:
+	scf
+	ret
+
+.Pokemon:
+	and a
+	ret
+; 3750
+
+DrawBattleHPBar:: ; 3750
+; Draw an HP bar d tiles long at hl
+; Fill it up to e pixels
+
+	push hl
+	push de
+	push bc
+
+; Place 'HP:'
+	ld a, $60
+	ld [hli], a
+	ld a, $61
+	ld [hli], a
+
+; Draw a template
+	push hl
+	ld a, $62 ; empty bar
+.template
+	ld [hli], a
+	dec d
+	jr nz, .template
+	ld a, $6b ; bar end
+	add b
+	ld [hl], a
+	pop hl
+
+; Safety check # pixels
+	ld a, e
+	and a
+	jr nz, .fill
+	ld a, c
+	and a
+	jr z, .done
+	ld e, 1
+
+.fill
+; Keep drawing tiles until pixel length is reached
+	ld a, e
+	sub TILE_WIDTH
+	jr c, .lastbar
+
+	ld e, a
+	ld a, $6a ; full bar
+	ld [hli], a
+	ld a, e
+	and a
+	jr z, .done
+	jr .fill
+
+.lastbar
+	ld a, $62  ; empty bar
+	add e      ; + e
+	ld [hl], a
+
+.done
+	pop bc
+	pop de
+	pop hl
+	ret
+; 3786
+
+PrepMonFrontpic:: ; 3786
+	ld a, $1
+	ld [wBoxAlignment], a
+
+_PrepMonFrontpic:: ; 378b
+	ld a, [wCurPartySpecies]
+	call IsAPokemon
+	jr c, .not_pokemon
+
+	push hl
+	ld de, vTiles2
+	predef GetMonFrontpic
+	pop hl
+	xor a
+	ld [hGraphicStartTile], a
+	lb bc, 7, 7
+	predef PlaceGraphic
+	xor a
+	ld [wBoxAlignment], a
+	ret
+
+.not_pokemon
+	xor a
+	ld [wBoxAlignment], a
+	inc a
+	ld [wCurPartySpecies], a
+	ret
+; 37b6
--- /dev/null
+++ b/home/print_bcd.asm
@@ -1,0 +1,81 @@
+PrintBCDNumber:: ; 38bb
+; 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
+; bit 5: if set, print currency symbol at the beginning of the string
+;        if unset, do not print the currency symbol
+; bits 0-4: 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.
+	ld b, c ; save flags in b
+	res 7, c
+	res 6, c
+	res 5, c ; c now holds the length
+	bit 5, b
+	jr z, .loop
+	bit 7, b
+	jr nz, .loop ; skip currency symbol
+	ld [hl], "¥"
+	inc hl
+.loop
+	ld a, [de]
+	swap a
+	call PrintBCDDigit ; print upper digit
+	ld a, [de]
+	call PrintBCDDigit ; print lower digit
+	inc de
+	dec c
+	jr nz, .loop
+	bit 7, b ; were any non-zero digits printed?
+	jr z, .done ; if so, we are done
+.numberEqualsZero ; if every digit of the BCD number is zero
+	bit 6, b ; left or right alignment?
+	jr nz, .skipRightAlignmentAdjustment
+	dec hl ; if the string is right-aligned, it needs to be moved back one space
+.skipRightAlignmentAdjustment
+	bit 5, b
+	jr z, .skipCurrencySymbol
+	ld [hl], "¥" ; currency symbol
+	inc hl
+.skipCurrencySymbol
+	ld [hl], "0"
+	call PrintLetterDelay
+	inc hl
+.done
+	ret
+; 0x38f2
+
+PrintBCDDigit:: ; 38f2
+	and %00001111
+	and a
+	jr z, .zeroDigit
+.nonzeroDigit
+	bit 7, b ; have any non-space characters been printed?
+	jr z, .outputDigit
+; if bit 7 is set, then no numbers have been printed yet
+	bit 5, b ; print the currency symbol?
+	jr z, .skipCurrencySymbol
+	ld [hl], "¥"
+	inc hl
+	res 5, b
+.skipCurrencySymbol
+	res 7, b ; unset 7 to indicate that a nonzero digit has been reached
+.outputDigit
+	add "0"
+	ld [hli], a
+	jp PrintLetterDelay
+
+.zeroDigit
+	bit 7, b ; either printing leading zeroes or already reached a nonzero digit?
+	jr z, .outputDigit ; if so, print a zero digit
+	bit 6, b ; left or right alignment?
+	ret nz
+	ld a, " "
+	ld [hli], a ; if right-aligned, "print" a space by advancing the pointer
+	ret
+; 0x3917
--- /dev/null
+++ b/home/print_level.asm
@@ -1,0 +1,31 @@
+PrintLevel:: ; 382d
+; Print wTempMonLevel at hl
+
+	ld a, [wTempMonLevel]
+	ld [hl], "<LV>"
+	inc hl
+
+; How many digits?
+	ld c, 2
+	cp 100 ; This is distinct from MAX_LEVEL.
+	jr c, Print8BitNumRightAlign
+
+; 3-digit numbers overwrite the :L.
+	dec hl
+	inc c
+	jr Print8BitNumRightAlign
+; 383d
+
+PrintLevel_Force3Digits:: ; 383d
+; Print :L and all 3 digits
+	ld [hl], "<LV>"
+	inc hl
+	ld c, 3
+; 3842
+
+Print8BitNumRightAlign:: ; 3842
+	ld [wd265], a
+	ld de, wd265
+	ld b, PRINTNUM_RIGHTALIGN | 1
+	jp PrintNum
+; 384d
--- /dev/null
+++ b/home/print_text.asm
@@ -1,0 +1,125 @@
+PrintLetterDelay:: ; 313d
+; Wait before printing the next letter.
+
+; The text speed setting in wOptions is actually a frame count:
+; 	fast: 1 frame
+; 	mid:  3 frames
+; 	slow: 5 frames
+
+; wTextBoxFlags[!0] and A or B override text speed with a one-frame delay.
+; wOptions[4] and wTextBoxFlags[!1] disable the delay.
+
+	ld a, [wOptions]
+	bit NO_TEXT_SCROLL, a
+	ret nz
+
+; non-scrolling text?
+	ld a, [wTextBoxFlags]
+	bit NO_TEXT_DELAY_F, a
+	ret z
+
+	push hl
+	push de
+	push bc
+
+	ld hl, hOAMUpdate
+	ld a, [hl]
+	push af
+
+; orginally turned oam update off...
+;	ld a, 1
+	ld [hl], a
+
+; force fast scroll?
+	ld a, [wTextBoxFlags]
+	bit FAST_TEXT_DELAY_F, a
+	jr z, .fast
+
+; text speed
+	ld a, [wOptions]
+	and %111
+	jr .updatedelay
+
+.fast
+	ld a, TEXT_DELAY_FAST
+
+.updatedelay
+	ld [wTextDelayFrames], a
+
+.checkjoypad
+	call GetJoypad
+
+; input override
+	ld a, [wDisableTextAcceleration]
+	and a
+	jr nz, .wait
+
+; Wait one frame if holding A or B.
+	ld a, [hJoyDown]
+	bit A_BUTTON_F, a
+	jr z, .checkb
+	jr .delay
+.checkb
+	bit B_BUTTON_F, a
+	jr z, .wait
+
+.delay
+	call DelayFrame
+	jr .end
+
+.wait
+	ld a, [wTextDelayFrames]
+	and a
+	jr nz, .checkjoypad
+
+.end
+	pop af
+	ld [hOAMUpdate], a
+	pop bc
+	pop de
+	pop hl
+	ret
+; 318c
+
+CopyDataUntil:: ; 318c
+; Copy [hl .. bc) to de.
+
+; In other words, the source data is
+; from hl up to but not including bc,
+; and the destination is de.
+
+	ld a, [hli]
+	ld [de], a
+	inc de
+	ld a, h
+	cp b
+	jr nz, CopyDataUntil
+	ld a, l
+	cp c
+	jr nz, CopyDataUntil
+	ret
+; 0x3198
+
+PrintNum:: ; 3198
+	homecall _PrintNum
+	ret
+; 31a4
+
+MobilePrintNum:: ; 31a4
+	homecall _MobilePrintNum
+	ret
+; 31b0
+
+FarPrintText:: ; 31b0
+	ld [hBuffer], a
+	ld a, [hROMBank]
+	push af
+	ld a, [hBuffer]
+	rst Bankswitch
+
+	call PrintText
+
+	pop af
+	rst Bankswitch
+	ret
+; 31be
--- /dev/null
+++ b/home/region.asm
@@ -1,0 +1,33 @@
+IsInJohto:: ; 2f17
+; Return 0 if the player is in Johto, and 1 in Kanto.
+
+	ld a, [wMapGroup]
+	ld b, a
+	ld a, [wMapNumber]
+	ld c, a
+	call GetWorldMapLocation
+
+	cp FAST_SHIP
+	jr z, .Johto
+
+	cp SPECIAL_MAP
+	jr nz, .CheckRegion
+
+	ld a, [wBackupMapGroup]
+	ld b, a
+	ld a, [wBackupMapNumber]
+	ld c, a
+	call GetWorldMapLocation
+
+.CheckRegion:
+	cp KANTO_LANDMARK
+	jr nc, .Kanto
+
+.Johto:
+	xor a
+	ret
+
+.Kanto:
+	ld a, 1
+	ret
+; 2f3e
--- /dev/null
+++ b/home/scrolling_menu.asm
@@ -1,0 +1,65 @@
+ScrollingMenu:: ; 350c
+	call CopyMenuData
+	ld a, [hROMBank]
+	push af
+
+	ld a, BANK(_ScrollingMenu)
+	rst Bankswitch
+
+	call _InitScrollingMenu
+	call .UpdatePalettes
+	call _ScrollingMenu
+
+	pop af
+	rst Bankswitch
+
+	ld a, [wMenuJoypad]
+	ret
+; 3524
+
+.UpdatePalettes: ; 3524
+	ld hl, wVramState
+	bit 0, [hl]
+	jp nz, UpdateTimePals
+	jp SetPalettes
+; 352f
+
+InitScrollingMenu:: ; 352f
+	ld a, [wMenuBorderTopCoord]
+	dec a
+	ld b, a
+	ld a, [wMenuBorderBottomCoord]
+	sub b
+	ld d, a
+	ld a, [wMenuBorderLeftCoord]
+	dec a
+	ld c, a
+	ld a, [wMenuBorderRightCoord]
+	sub c
+	ld e, a
+	push de
+	call Coord2Tile
+	pop bc
+	jp TextBox
+; 354b
+
+JoyTextDelay_ForcehJoyDown:: ; 354b joypad
+	call DelayFrame
+
+	ld a, [hInMenu]
+	push af
+	ld a, $1
+	ld [hInMenu], a
+	call JoyTextDelay
+	pop af
+	ld [hInMenu], a
+
+	ld a, [hJoyLast]
+	and D_RIGHT + D_LEFT + D_UP + D_DOWN
+	ld c, a
+	ld a, [hJoyPressed]
+	and A_BUTTON + B_BUTTON + SELECT + START
+	or c
+	ld c, a
+	ret
+; 3567
--- /dev/null
+++ b/home/sprite_anims.asm
@@ -1,0 +1,53 @@
+PushLYOverrides:: ; 3b0c
+	ld a, [hLCDCPointer]
+	and a
+	ret z
+
+	ld a, LOW(wLYOverridesBackup)
+	ld [wRequested2bppSource], a
+	ld a, HIGH(wLYOverridesBackup)
+	ld [wRequested2bppSource + 1], a
+
+	ld a, LOW(wLYOverrides)
+	ld [wRequested2bppDest], a
+	ld a, HIGH(wLYOverrides)
+	ld [wRequested2bppDest + 1], a
+
+	ld a, (wLYOverridesEnd - wLYOverrides) / 16
+	ld [wRequested2bpp], a
+	ret
+; 3b2a
+
+_InitSpriteAnimStruct:: ; 3b2a
+	ld [wSpriteAnimIDBuffer], a
+	ld a, [hROMBank]
+	push af
+
+	ld a, BANK(InitSpriteAnimStruct)
+	rst Bankswitch
+	ld a, [wSpriteAnimIDBuffer]
+
+	call InitSpriteAnimStruct
+
+	pop af
+	rst Bankswitch
+
+	ret
+; 3b3c
+
+ReinitSpriteAnimFrame:: ; 3b3c
+	ld [wSpriteAnimIDBuffer], a
+	ld a, [hROMBank]
+	push af
+
+	ld a, BANK(_ReinitSpriteAnimFrame)
+	rst Bankswitch
+	ld a, [wSpriteAnimIDBuffer]
+
+	call _ReinitSpriteAnimFrame
+
+	pop af
+	rst Bankswitch
+
+	ret
+; 3b4e
--- /dev/null
+++ b/home/sprite_updates.asm
@@ -1,0 +1,21 @@
+DisableSpriteUpdates:: ; 0x2ed3
+	xor a
+	ld [hMapAnims], a
+	ld a, [wVramState]
+	res 0, a
+	ld [wVramState], a
+	ld a, $0
+	ld [wSpriteUpdatesEnabled], a
+	ret
+; 0x2ee4
+
+EnableSpriteUpdates:: ; 2ee4
+	ld a, $1
+	ld [wSpriteUpdatesEnabled], a
+	ld a, [wVramState]
+	set 0, a
+	ld [wVramState], a
+	ld a, $1
+	ld [hMapAnims], a
+	ret
+; 2ef6
--- /dev/null
+++ b/home/stone_queue.asm
@@ -1,0 +1,143 @@
+HandleStoneQueue:: ; 3567
+	ld a, [hROMBank]
+	push af
+
+	call SwitchToMapScriptsBank
+	call .WarpAction
+
+	pop bc
+	ld a, b
+	rst Bankswitch
+	ret
+; 3574
+
+.WarpAction: ; 3574
+	ld hl, OBJECT_MAP_OBJECT_INDEX
+	add hl, de
+	ld a, [hl]
+	cp $ff
+	jr z, .nope
+
+	ld l, a
+	push hl
+	call .IsObjectOnWarp
+	pop hl
+	jr nc, .nope
+	ld d, a
+	ld e, l
+	call .IsObjectInStoneTable
+	jr nc, .nope
+	call CallMapScript
+	farcall EnableScriptMode
+	scf
+	ret
+
+.nope
+	and a
+	ret
+; 3599
+
+.IsObjectOnWarp: ; 3599
+	push de
+
+	ld hl, OBJECT_NEXT_MAP_X
+	add hl, de
+	ld a, [hl]
+	ld hl, OBJECT_NEXT_MAP_Y
+	add hl, de
+	ld e, [hl]
+
+	sub 4
+	ld d, a
+	ld a, e
+	sub 4
+	ld e, a
+	call .check_on_warp
+
+	pop de
+	ret
+; 35b0
+
+.check_on_warp ; 35b0
+	ld hl, wCurrMapWarpsPointer
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	ld a, [wCurrMapWarpCount]
+	and a
+	jr z, .nope2
+
+.loop
+	push af
+	ld a, [hl]
+	cp e
+	jr nz, .not_on_warp
+	inc hl
+	ld a, [hld]
+	cp d
+	jr nz, .not_on_warp
+	jr .found_warp
+
+.not_on_warp
+	ld a, 5
+	add l
+	ld l, a
+	jr nc, .no_carry
+	inc h
+.no_carry
+
+	pop af
+	dec a
+	jr nz, .loop
+
+.nope2
+	and a
+	ret
+
+.found_warp
+	pop af
+	ld d, a
+	ld a, [wCurrMapWarpCount]
+	sub d
+	inc a
+	scf
+	ret
+; 35de
+
+.IsObjectInStoneTable: ; 35de
+	inc e
+	ld hl, CMDQUEUE_ADDR
+	add hl, bc
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+.loop2
+	ld a, [hli]
+	cp $ff
+	jr z, .nope3
+	cp d
+	jr nz, .next_inc3
+	ld a, [hli]
+	cp e
+	jr nz, .next_inc2
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	jr .yes
+
+.next_inc3
+	inc hl
+
+.next_inc2
+	inc hl
+	inc hl
+	jr .loop2
+
+.nope3
+	and a
+	ret
+
+.yes
+	scf
+	ret
+; 3600
--- a/home/tilemap.asm
+++ b/home/tilemap.asm
@@ -1,257 +1,229 @@
-PushWindow:: ; 1c00
-	callfar _PushWindow
+ClearBGPalettes:: ; 31f3
+	call ClearPalettes
+WaitBGMap:: ; 31f6
+; Tell VBlank to update BG Map
+	ld a, 1 ; BG Map 0 tiles
+	ld [hBGMapMode], a
+; Wait for it to do its magic
+	ld c, 4
+	call DelayFrames
 	ret
-; 1c07
+; 3200
 
-ExitMenu:: ; 0x1c07
-	push af
-	callfar _ExitMenu
-	pop af
-	ret
+WaitBGMap2:: ; 0x3200
+	ld a, [hCGB]
+	and a
+	jr z, .bg0
 
-InitVerticalMenuCursor:: ; 0x1c10
-	callfar _InitVerticalMenuCursor
-	ret
+	ld a, 2
+	ld [hBGMapMode], a
+	ld c, 4
+	call DelayFrames
 
-CloseWindow:: ; 0x1c17
-	push af
-	call ExitMenu
-	call ApplyTilemap
-	call UpdateSprites
-	pop af
+.bg0
+	ld a, 1
+	ld [hBGMapMode], a
+	ld c, 4
+	call DelayFrames
 	ret
+; 0x3218
 
-RestoreTileBackup:: ; 0x1c23
-	call MenuBoxCoord2Tile
-	call .copy
-	call MenuBoxCoord2Attr
-	call .copy
+IsCGB:: ; 3218
+	ld a, [hCGB]
+	and a
 	ret
-; 0x1c30
+; 321c
 
-.copy ; 0x1c30
-	call GetMenuBoxDims
-	inc b
-	inc c
+ApplyTilemap:: ; 321c
+	ld a, [hCGB]
+	and a
+	jr z, .dmg
 
-.row
-	push bc
-	push hl
+	ld a, [wSpriteUpdatesEnabled]
+	cp 0
+	jr z, .dmg
 
-.col
-	ld a, [de]
-	ld [hli], a
-	dec de
-	dec c
-	jr nz, .col ; 0x1c3b $fa
+	ld a, 1
+	ld [hBGMapMode], a
+	jr CopyTilemapAtOnce
 
-	pop hl
-	ld bc, SCREEN_WIDTH
-	add hl, bc
-	pop bc
-	dec b
-	jr nz, .row ; 0x1c44 $ef
-
+.dmg
+; WaitBGMap
+	ld a, 1
+	ld [hBGMapMode], a
+	ld c, 4
+	call DelayFrames
 	ret
+; 3238
 
-PopWindow:: ; 0x1c47
-	ld b, $10
-	ld de, wMenuFlags
-.loop
-	ld a, [hld]
-	ld [de], a
-	inc de
-	dec b
-	jr nz, .loop ; 0x1c50 $fa
-	ret
+CGBOnly_CopyTilemapAtOnce:: ; 3238
+	ld a, [hCGB]
+	and a
+	jr z, WaitBGMap
 
-GetMenuBoxDims:: ; 0x1c53
-	ld a, [wMenuBorderTopCoord] ; top
-	ld b, a
-	ld a, [wMenuBorderBottomCoord] ; bottom
-	sub b
-	ld b, a
-	ld a, [wMenuBorderLeftCoord] ; left
-	ld c, a
-	ld a, [wMenuBorderRightCoord] ; right
-	sub c
-	ld c, a
+CopyTilemapAtOnce:: ; 323d
+	jr .CopyTilemapAtOnce
+; 323f
+
+; unused
+	farcall HDMATransferAttrMapAndTileMapToWRAMBank3
 	ret
-; 0x1c66
+; 3246
 
-CopyMenuData:: ; 1c66
-	push hl
-	push de
-	push bc
+.CopyTilemapAtOnce: ; 3246
+	ld a, [hBGMapMode]
 	push af
-	ld hl, wMenuDataPointer
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	ld de, wMenuDataFlags
-	ld bc, wMenuDataEnd - wMenuDataFlags
-	call CopyBytes
-	pop af
-	pop bc
-	pop de
-	pop hl
-	ret
-; 1c7e
+	xor a
+	ld [hBGMapMode], a
 
-GetWindowStackTop:: ; 1c7e
-	ld hl, wWindowStackPointer
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	inc hl
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	ret
-; 1c89
+	ld a, [hMapAnims]
+	push af
+	xor a
+	ld [hMapAnims], a
 
-PlaceVerticalMenuItems:: ; 1c89
-	call CopyMenuData
-	ld hl, wMenuDataPointer
-	ld e, [hl]
-	inc hl
-	ld d, [hl]
-	call GetMenuTextStartCoord
-	call Coord2Tile ; hl now contains the tilemap address where we will start printing text.
-	inc de
-	ld a, [de] ; Number of items
-	inc de
-	ld b, a
-.loop
-	push bc
-	call PlaceString
-	inc de
-	ld bc, 2 * SCREEN_WIDTH
-	add hl, bc
-	pop bc
-	dec b
-	jr nz, .loop
+.wait
+	ld a, [rLY]
+	cp $7f
+	jr c, .wait
 
-	ld a, [wMenuDataFlags]
-	bit 4, a
-	ret z
+	di
+	ld a, BANK(vTiles3)
+	ld [rVBK], a
+	hlcoord 0, 0, wAttrMap
+	call .StackPointerMagic
+	ld a, BANK(vTiles0)
+	ld [rVBK], a
+	hlcoord 0, 0
+	call .StackPointerMagic
 
-	call MenuBoxCoord2Tile
-	ld a, [de]
-	ld c, a
-	inc de
-	ld b, $0
-	add hl, bc
-	jp PlaceString
-; 1cbb
+.wait2
+	ld a, [rLY]
+	cp $7f
+	jr c, .wait2
+	ei
 
-MenuBox:: ; 1cbb
-	call MenuBoxCoord2Tile
-	call GetMenuBoxDims
-	dec b
-	dec c
-	jp TextBox
-; 1cc6
+	pop af
+	ld [hMapAnims], a
+	pop af
+	ld [hBGMapMode], a
+	ret
+; 327b
 
-GetMenuTextStartCoord:: ; 1cc6
-	ld a, [wMenuBorderTopCoord]
-	ld b, a
-	inc b
-	ld a, [wMenuBorderLeftCoord]
-	ld c, a
-	inc c
-; bit 6: if not set, leave extra room on top
-	ld a, [wMenuDataFlags]
-	bit 6, a
-	jr nz, .bit_6_set
-	inc b
+.StackPointerMagic: ; 327b
+; Copy all tiles to vBGMap
+	ld [hSPBuffer], sp
+	ld sp, hl
+	ld a, [hBGMapAddress + 1]
+	ld h, a
+	ld l, 0
+	ld a, SCREEN_HEIGHT
+	ld [hTilesPerCycle], a
+	ld b, 1 << 1 ; not in v/hblank
+	ld c, LOW(rSTAT)
 
-.bit_6_set
-; bit 7: if set, leave extra room on the left
-	ld a, [wMenuDataFlags]
-	bit 7, a
-	jr z, .bit_7_clear
-	inc c
+.loop
+rept SCREEN_WIDTH / 2
+	pop de
+; if in v/hblank, wait until not in v/hblank
+.loop\@
+	ld a, [$ff00+c]
+	and b
+	jr nz, .loop\@
+; load BGMap0
+	ld [hl], e
+	inc l
+	ld [hl], d
+	inc l
+endr
 
-.bit_7_clear
+	ld de, BG_MAP_WIDTH - SCREEN_WIDTH
+	add hl, de
+	ld a, [hTilesPerCycle]
+	dec a
+	ld [hTilesPerCycle], a
+	jr nz, .loop
+
+	ld a, [hSPBuffer]
+	ld l, a
+	ld a, [hSPBuffer + 1]
+	ld h, a
+	ld sp, hl
 	ret
-; 1ce1
+; 32f9
 
-ClearMenuBoxInterior:: ; 1ce1
-	call MenuBoxCoord2Tile
-	ld bc, SCREEN_WIDTH + 1
-	add hl, bc
-	call GetMenuBoxDims
-	dec b
-	dec c
-	call ClearBox
+SetPalettes:: ; 32f9
+; Inits the Palettes
+; depending on the system the monochromes palettes or color palettes
+	ld a, [hCGB]
+	and a
+	jr nz, .SetPalettesForGameBoyColor
+	ld a, %11100100
+	ld [rBGP], a
+	ld a, %11010000
+	ld [rOBP0], a
+	ld [rOBP1], a
 	ret
-; 1cf1
 
-ClearWholeMenuBox:: ; 1cf1
-	call MenuBoxCoord2Tile
-	call GetMenuBoxDims
-	inc c
-	inc b
-	call ClearBox
+.SetPalettesForGameBoyColor:
+	push de
+	ld a, %11100100
+	call DmgToCgbBGPals
+	lb de, %11100100, %11100100
+	call DmgToCgbObjPals
+	pop de
 	ret
-; 1cfd
+; 3317
 
+ClearPalettes:: ; 3317
+; Make all palettes white
 
-MenuBoxCoord2Tile:: ; 1cfd
-	ld a, [wMenuBorderLeftCoord]
-	ld c, a
-	ld a, [wMenuBorderTopCoord]
-	ld b, a
-; 1d05
+; CGB: make all the palette colors white
+	ld a, [hCGB]
+	and a
+	jr nz, .cgb
 
-
-Coord2Tile:: ; 1d05
-; Return the address of wTileMap(c, b) in hl.
+; DMG: just change palettes to 0 (white)
 	xor a
-	ld h, a
-	ld l, b
-	ld a, c
-	ld b, h
-	ld c, l
-	add hl, hl
-	add hl, hl
-	add hl, bc
-	add hl, hl
-	add hl, hl
-	ld c, a
-	xor a
-	ld b, a
-	add hl, bc
-	bccoord 0, 0
-	add hl, bc
+	ld [rBGP], a
+	ld [rOBP0], a
+	ld [rOBP1], a
 	ret
-; 1d19
 
-MenuBoxCoord2Attr:: ; 1d19
-	ld a, [wMenuBorderLeftCoord]
-	ld c, a
-	ld a, [wMenuBorderTopCoord]
-	ld b, a
+.cgb
+	ld a, [rSVBK]
+	push af
 
-Coord2Attr:: ; 1d21
-; Return the address of wAttrMap(c, b) in hl.
-	xor a
-	ld h, a
-	ld l, b
-	ld a, c
-	ld b, h
-	ld c, l
-	add hl, hl
-	add hl, hl
-	add hl, bc
-	add hl, hl
-	add hl, hl
-	ld c, a
-	xor a
-	ld b, a
-	add hl, bc
-	bccoord 0, 0, wAttrMap
-	add hl, bc
+	ld a, BANK(wBGPals2)
+	ld [rSVBK], a
+
+; Fill wBGPals2 and wOBPals2 with $ffff (white)
+	ld hl, wBGPals2
+	ld bc, 16 palettes
+	ld a, $ff
+	call ByteFill
+
+	pop af
+	ld [rSVBK], a
+
+; Request palette update
+	ld a, 1
+	ld [hCGBPalUpdate], a
 	ret
-; 1d35
+; 333e
+
+GetMemSGBLayout:: ; 333e
+	ld b, SCGB_RAM
+GetSGBLayout:: ; 3340
+; load sgb packets unless dmg
+
+	ld a, [hCGB]
+	and a
+	jr nz, .sgb
+
+	ld a, [hSGB]
+	and a
+	ret z
+
+.sgb
+	predef_jump LoadSGBLayout
+; 334e
--- a/home/window.asm
+++ b/home/window.asm
@@ -1,5 +1,4 @@
 RefreshScreen:: ; 2dba
-
 	call ClearWindowData
 	ld a, [hROMBank]
 	push af