shithub: pokecrystal

Download patch

ref: 7d4486e6a34a5163575400f21e806471be496e3d
parent: 15f1fc7c6ce0444ebfd87b1edc22da0ffd61c667
author: Remy Oukaour <remy.oukaour@gmail.com>
date: Sun Dec 24 14:35:35 EST 2017

Remove all code from main.asm (some labeled INCBINs, like out-of-context graphics, are still present)

engine/routines/ stores isolated out-of-context routines as individual files. It might be preferable later to append them to their related engine/ files in unique little SECTIONs, relying on the linkerscript to place them appropriately; or some other organization method. In the meantime, they're now easily findable apart from main.asm's other content.

--- a/battle/core.asm
+++ b/battle/core.asm
@@ -2573,11 +2573,11 @@
 .CheckMaxedOutMomMoney: ; 3d0b1
 	ld hl, wMomsMoney + 2
 	ld a, [hld]
-	cp 999999 % $100
+	cp MAX_MONEY % $100
 	ld a, [hld]
-	sbc 999999 / $100 % $100
+	sbc MAX_MONEY / $100 % $100
 	ld a, [hl]
-	sbc 999999 / $10000 % $100
+	sbc MAX_MONEY / $10000 % $100
 	ret
 ; 3d0be
 
@@ -2602,17 +2602,17 @@
 	jr nz, .loop
 	pop hl
 	ld a, [hld]
-	cp 999999 % $100
+	cp MAX_MONEY % $100
 	ld a, [hld]
-	sbc 999999 / $100 % $100
+	sbc MAX_MONEY / $100 % $100
 	ld a, [hl]
-	sbc 999999 / $10000 % $100
+	sbc MAX_MONEY / $10000 % $100
 	ret c
-	ld [hl], 999999 / $10000 % $100
+	ld [hl], MAX_MONEY / $10000 % $100
 	inc hl
-	ld [hl], 999999 / $100 % $100
+	ld [hl], MAX_MONEY / $100 % $100
 	inc hl
-	ld [hl], 999999 % $100
+	ld [hl], MAX_MONEY % $100
 	ret
 ; 3d0ea
 
--- a/constants/misc_constants.asm
+++ b/constants/misc_constants.asm
@@ -93,6 +93,8 @@
 ; significant money values
 START_MONEY EQU 3000
 MOM_MONEY   EQU 2300
+MAX_MONEY   EQU 999999
+MAX_COINS   EQU 9999
 
 
 ; ChangeHappiness arguments (see data/happiness_changes.asm)
--- a/engine/card_flip.asm
+++ b/engine/card_flip.asm
@@ -1185,7 +1185,7 @@
 
 .IsCoinCaseFull: ; e0833
 	ld a, [Coins]
-	cp 9999 / $100
+	cp MAX_COINS / $100
 	jr c, .less
 	jr z, .check_low
 	jr .more
@@ -1192,7 +1192,7 @@
 
 .check_low
 	ld a, [Coins + 1]
-	cp 9999 % $100
+	cp MAX_COINS % $100
 	jr c, .less
 
 .more
--- a/engine/check_battle_scene.asm
+++ /dev/null
@@ -1,47 +1,0 @@
-CheckBattleScene: ; 4ea44
-; Return carry if battle scene is turned off.
-
-	ld a, 0
-	ld hl, wLinkMode
-	call GetFarWRAMByte
-	cp LINK_MOBILE
-	jr z, .mobile
-
-	ld a, [Options]
-	bit BATTLE_SCENE, a
-	jr nz, .off
-
-	and a
-	ret
-
-.mobile
-	ld a, [wcd2f]
-	and a
-	jr nz, .from_wram
-
-	ld a, $4
-	call GetSRAMBank
-	ld a, [$a60c]
-	ld c, a
-	call CloseSRAM
-
-	ld a, c
-	bit 0, c
-	jr z, .off
-
-	and a
-	ret
-
-.from_wram
-	ld a, $5
-	ld hl, w5_dc00
-	call GetFarWRAMByte
-	bit 0, a
-	jr z, .off
-
-	and a
-	ret
-
-.off
-	scf
-	ret
--- a/engine/check_nick_errors.asm
+++ /dev/null
@@ -1,74 +1,0 @@
-CheckNickErrors:: ; 669f
-; error-check monster nick before use
-; must be a peace offering to gamesharkers
-
-; input: de = nick location
-
-	push bc
-	push de
-	ld b, PKMN_NAME_LENGTH
-
-.checkchar
-; end of nick?
-	ld a, [de]
-	cp "@" ; terminator
-	jr z, .end
-
-; check if this char is a text command
-	ld hl, .textcommands
-	dec hl
-.loop
-; next entry
-	inc hl
-; reached end of commands table?
-	ld a, [hl]
-	cp -1
-	jr z, .done
-
-; is the current char between this value (inclusive)...
-	ld a, [de]
-	cp [hl]
-	inc hl
-	jr c, .loop
-; ...and this one?
-	cp [hl]
-	jr nc, .loop
-
-; replace it with a "?"
-	ld a, "?"
-	ld [de], a
-	jr .loop
-
-.done
-; next char
-	inc de
-; reached end of nick without finding a terminator?
-	dec b
-	jr nz, .checkchar
-
-; change nick to "?@"
-	pop de
-	push de
-	ld a, "?"
-	ld [de], a
-	inc de
-	ld a, "@"
-	ld [de], a
-.end
-; if the nick has any errors at this point it's out of our hands
-	pop de
-	pop bc
-	ret
-
-.textcommands ; 66cf
-; table defining which characters are actually text commands
-; format:
-	;      ≥           <
-	db "<START>",  TX_BOX    + 1
-	db "<PLAY_G>", $18       + 1
-	db $1d,        "%"       + 1
-	db $35,        "<GREEN>" + 1
-	db "<ENEMY>",  "<ENEMY>" + 1
-	db "<MOM>",    "<TM>"    + 1
-	db "<ROCKET>", "┘"       + 1
-	db -1 ; end
--- a/engine/check_time.asm
+++ /dev/null
@@ -1,19 +1,0 @@
-CheckTime:: ; c000
-	ld a, [TimeOfDay]
-	ld hl, TimeOfDayTable
-	ld de, 2
-	call IsInArray
-	inc hl
-	ld c, [hl]
-	ret c
-
-	xor a
-	ld c, a
-	ret
-
-TimeOfDayTable: ; c012
-	db MORN_F, MORN
-	db DAY_F,  DAY
-	db NITE_F, NITE
-	db NITE_F, NITE
-	db -1
--- a/engine/consume_held_item.asm
+++ /dev/null
@@ -1,80 +1,0 @@
-ConsumeHeldItem: ; 27192
-	push hl
-	push de
-	push bc
-	ld a, [hBattleTurn]
-	and a
-	ld hl, OTPartyMon1Item
-	ld de, EnemyMonItem
-	ld a, [CurOTMon]
-	jr z, .theirturn
-	ld hl, PartyMon1Item
-	ld de, BattleMonItem
-	ld a, [CurBattleMon]
-
-.theirturn
-	push hl
-	push af
-	ld a, [de]
-	ld b, a
-	farcall GetItemHeldEffect
-	ld hl, .ConsumableEffects
-.loop
-	ld a, [hli]
-	cp b
-	jr z, .ok
-	inc a
-	jr nz, .loop
-	pop af
-	pop hl
-	pop bc
-	pop de
-	pop hl
-	ret
-
-.ok
-	xor a
-	ld [de], a
-	pop af
-	pop hl
-	call GetPartyLocation
-	ld a, [hBattleTurn]
-	and a
-	jr nz, .ourturn
-	ld a, [wBattleMode]
-	dec a
-	jr z, .done
-
-.ourturn
-	ld [hl], $0
-
-.done
-	pop bc
-	pop de
-	pop hl
-	ret
-
-.ConsumableEffects: ; 271de
-; Consumable items?
-	db HELD_BERRY
-	db HELD_2
-	db HELD_5
-	db HELD_HEAL_POISON
-	db HELD_HEAL_FREEZE
-	db HELD_HEAL_BURN
-	db HELD_HEAL_SLEEP
-	db HELD_HEAL_PARALYZE
-	db HELD_HEAL_STATUS
-	db HELD_30
-	db HELD_ATTACK_UP
-	db HELD_DEFENSE_UP
-	db HELD_SPEED_UP
-	db HELD_SP_ATTACK_UP
-	db HELD_SP_DEFENSE_UP
-	db HELD_ACCURACY_UP
-	db HELD_EVASION_UP
-	db HELD_38
-	db HELD_71
-	db HELD_ESCAPE
-	db HELD_CRITICAL_UP
-	db -1
--- a/engine/diploma.asm
+++ b/engine/diploma.asm
@@ -1,4 +1,3 @@
-
 _Diploma: ; 1dd702
 	call PlaceDiplomaOnScreen
 	call WaitPressAorB_BlinkCursor
--- a/engine/empty_sram.asm
+++ /dev/null
@@ -1,19 +1,0 @@
-EmptyAllSRAMBanks: ; 4cf1f
-	ld a, $0
-	call .EmptyBank
-	ld a, $1
-	call .EmptyBank
-	ld a, $2
-	call .EmptyBank
-	ld a, $3
-	call .EmptyBank
-	ret
-
-.EmptyBank: ; 4cf34
-	call GetSRAMBank
-	ld hl, SRAM_Begin
-	ld bc, SRAM_End - SRAM_Begin
-	xor a
-	call ByteFill
-	call CloseSRAM
-	ret
--- a/engine/flag_predef.asm
+++ /dev/null
@@ -1,70 +1,0 @@
-FlagPredef: ; 4d7c1
-; Perform action b on flag c in flag array hl.
-; If checking a flag, check flag array d:hl unless d is 0.
-
-; For longer flag arrays, see FlagAction.
-
-	push hl
-	push bc
-
-; Divide by 8 to get the byte we want.
-	push bc
-	srl c
-	srl c
-	srl c
-	ld b, 0
-	add hl, bc
-	pop bc
-
-; Which bit we want from the byte
-	ld a, c
-	and 7
-	ld c, a
-
-; Shift left until we can mask the bit
-	ld a, 1
-	jr z, .shifted
-.shift
-	add a
-	dec c
-	jr nz, .shift
-.shifted
-	ld c, a
-
-; What are we doing to this flag?
-	dec b
-	jr z, .set ; 1
-	dec b
-	jr z, .check ; 2
-
-.reset
-	ld a, c
-	cpl
-	and [hl]
-	ld [hl], a
-	jr .done
-
-.set
-	ld a, [hl]
-	or c
-	ld [hl], a
-	jr .done
-
-.check
-	ld a, d
-	cp 0
-	jr nz, .farcheck
-
-	ld a, [hl]
-	and c
-	jr .done
-
-.farcheck
-	call GetFarByte
-	and c
-
-.done
-	pop bc
-	pop hl
-	ld c, a
-	ret
--- a/engine/get_breedmon_growth.asm
+++ /dev/null
@@ -1,27 +1,0 @@
-GetBreedMon1LevelGrowth: ; e698
-	ld hl, wBreedMon1Stats
-	ld de, TempMon
-	ld bc, BOXMON_STRUCT_LENGTH
-	call CopyBytes
-	callfar CalcLevel
-	ld a, [wBreedMon1Level]
-	ld b, a
-	ld a, d
-	ld e, a
-	sub b
-	ld d, a
-	ret
-
-GetBreedMon2LevelGrowth: ; e6b3
-	ld hl, wBreedMon2Stats
-	ld de, TempMon
-	ld bc, BOXMON_STRUCT_LENGTH
-	call CopyBytes
-	callfar CalcLevel
-	ld a, [wBreedMon2Level]
-	ld b, a
-	ld a, d
-	ld e, a
-	sub b
-	ld d, a
-	ret
--- a/engine/init_list.asm
+++ /dev/null
@@ -1,54 +1,0 @@
-InitList: ; 50db9
-	ld a, [wInitListType]
-
-	cp INIT_ENEMYOT_LIST
-	jr nz, .check_party_ot_name
-	ld hl, OTPartyCount
-	ld de, OTPartyMonOT
-	ld a, ENEMY_OT_NAME
-	jr .done
-
-.check_party_ot_name
-	cp INIT_PLAYEROT_LIST
-	jr nz, .check_mon_name
-	ld hl, PartyCount
-	ld de, PartyMonOT
-	ld a, PARTY_OT_NAME
-	jr .done
-
-.check_mon_name
-	cp INIT_MON_LIST
-	jr nz, .check_item_name
-	ld hl, CurMart
-	ld de, PokemonNames
-	ld a, PKMN_NAME
-	jr .done
-
-.check_item_name
-	cp INIT_BAG_ITEM_LIST
-	jr nz, .check_ob_item_name
-	ld hl, NumItems
-	ld de, ItemNames
-	ld a, ITEM_NAME
-	jr .done
-
-.check_ob_item_name
-	ld hl, CurMart
-	ld de, ItemNames
-	ld a, ITEM_NAME
-.done
-	ld [wNamedObjectTypeBuffer], a
-	ld a, l
-	ld [wListPointer], a
-	ld a, h
-	ld [wListPointer + 1], a
-	ld a, e
-	ld [wUnusedD102], a
-	ld a, d
-	ld [wUnusedD102 + 1], a
-	ld bc, ItemAttributes
-	ld a, c
-	ld [wItemAttributesPtr], a
-	ld a, b
-	ld [wItemAttributesPtr + 1], a
-	ret
--- a/engine/item_effects.asm
+++ b/engine/item_effects.asm
@@ -3314,5 +3314,3 @@
 	add hl, bc
 	ret
 ; f971
-
-INCLUDE "engine/pokeball_wobble.asm"
--- a/engine/knows_move.asm
+++ /dev/null
@@ -1,25 +1,0 @@
-KnowsMove: ; f9ea
-	ld a, MON_MOVES
-	call GetPartyParamLocation
-	ld a, [wPutativeTMHMMove]
-	ld b, a
-	ld c, NUM_MOVES
-.loop
-	ld a, [hli]
-	cp b
-	jr z, .knows_move
-	dec c
-	jr nz, .loop
-	and a
-	ret
-
-.knows_move
-	ld hl, .Text_knows
-	call PrintText
-	scf
-	ret
-
-.Text_knows: ; 0xfa06
-	; knows @ .
-	text_jump UnknownText_0x1c5ea8
-	db "@"
--- /dev/null
+++ b/engine/link_2.asm
@@ -1,0 +1,91 @@
+LinkMonStatsScreen: ; 4d319
+	ld a, [wMenuCursorY]
+	dec a
+	ld [CurPartyMon], a
+	call LowVolume
+	predef StatsScreenInit
+	ld a, [CurPartyMon]
+	inc a
+	ld [wMenuCursorY], a
+	call ClearScreen
+	call ClearBGPalettes
+	call MaxVolume
+	farcall LoadTradeScreenBorder
+	farcall Link_WaitBGMap
+	farcall InitTradeSpeciesList
+	farcall SetTradeRoomBGPals
+	call WaitBGMap2
+	ret
+
+Link_WaitBGMap: ; 4d354
+	call WaitBGMap
+	call WaitBGMap2
+	ret
+
+LinkTextbox2: ; 4d35b
+	ld h, d
+	ld l, e
+	push bc
+	push hl
+	call .PlaceBorder
+	pop hl
+	pop bc
+	ld de, AttrMap - TileMap
+	add hl, de
+	inc b
+	inc b
+	inc c
+	inc c
+	ld a, $7
+.row
+	push bc
+	push hl
+.col
+	ld [hli], a
+	dec c
+	jr nz, .col
+	pop hl
+	ld de, SCREEN_WIDTH
+	add hl, de
+	pop bc
+	dec b
+	jr nz, .row
+	ret
+
+.PlaceBorder: ; 4d37e
+	push hl
+	ld a, $76
+	ld [hli], a
+	inc a
+	call .PlaceRow
+	inc a
+	ld [hl], a
+	pop hl
+	ld de, SCREEN_WIDTH
+	add hl, de
+.loop
+	push hl
+	ld a, "┌"
+	ld [hli], a
+	ld a, " "
+	call .PlaceRow
+	ld [hl], "─"
+	pop hl
+	ld de, SCREEN_WIDTH
+	add hl, de
+	dec b
+	jr nz, .loop
+	ld a, "┐"
+	ld [hli], a
+	ld a, "│"
+	call .PlaceRow
+	ld [hl], "└"
+	ret
+
+.PlaceRow: ; 4d3ab
+	ld d, c
+.row_loop
+	ld [hli], a
+	dec d
+	jr nz, .row_loop
+	ret
--- a/engine/money.asm
+++ b/engine/money.asm
@@ -24,7 +24,7 @@
 ; 15ff7
 
 MaxMoney: ; 15ff7
-	dt 999999
+	dt MAX_MONEY
 ; 15ffa
 
 
@@ -192,7 +192,7 @@
 ; 1608d
 
 .maxcoins ; 1608d
-	bigdw 9999
+	bigdw MAX_COINS
 ; 1608f
 
 
--- a/engine/new_pokedex_entry.asm
+++ /dev/null
@@ -1,52 +1,0 @@
-NewPokedexEntry: ; fb877
-	ld a, [hMapAnims]
-	push af
-	xor a
-	ld [hMapAnims], a
-	call LowVolume
-	call ClearBGPalettes
-	call ClearTileMap
-	call UpdateSprites
-	call ClearSprites
-	ld a, [wPokedexStatus]
-	push af
-	ld a, [hSCX]
-	add $5
-	ld [hSCX], a
-	xor a
-	ld [wPokedexStatus], a
-	farcall _NewPokedexEntry
-	call WaitPressAorB_BlinkCursor
-	ld a, $1
-	ld [wPokedexStatus], a
-	farcall DisplayDexEntry
-	call WaitPressAorB_BlinkCursor
-	pop af
-	ld [wPokedexStatus], a
-	call MaxVolume
-	call RotateThreePalettesRight
-	ld a, [hSCX]
-	add -5 ; 251 ; NUM_POKEMON
-	ld [hSCX], a
-	call .ReturnFromDexRegistration
-	pop af
-	ld [hMapAnims], a
-	ret
-; fb8c8
-
-.ReturnFromDexRegistration: ; fb8c8
-	call ClearTileMap
-	call LoadFontsExtra
-	call LoadStandardFont
-	farcall Pokedex_PlaceFrontpicTopLeftCorner
-	call WaitBGMap2
-	farcall GetEnemyMonDVs
-	ld a, [hli]
-	ld [TempMonDVs], a
-	ld a, [hl]
-	ld [TempMonDVs + 1], a
-	ld b, SCGB_TRAINER_OR_MON_FRONTPIC_PALS
-	call GetSGBLayout
-	call SetPalettes
-	ret
-; fb8f1
--- a/engine/pack_f.asm
+++ /dev/null
@@ -1,20 +1,0 @@
-DrawKrisPackGFX: ; 48e81
-	ld hl, PackFGFXPointers
-	add hl, de
-	add hl, de
-	ld a, [hli]
-	ld e, a
-	ld d, [hl]
-	ld hl, VTiles2 tile $50
-	lb bc, BANK(PackFGFX), 15
-	call Request2bpp
-	ret
-
-PackFGFXPointers: ; 48e93
-	dw PackFGFX + (15 tiles) * 1
-	dw PackFGFX + (15 tiles) * 3
-	dw PackFGFX + (15 tiles) * 0
-	dw PackFGFX + (15 tiles) * 2
-
-PackFGFX: ; 48e9b
-INCBIN "gfx/pack/pack_f.2bpp"
--- a/engine/place_graphics.asm
+++ /dev/null
@@ -1,56 +1,0 @@
-PlaceGraphic: ; 2ef6e
-; Fill wBoxAlignment-aligned box width b height c
-; with iterating tile starting from hGraphicStartTile at hl.
-; Predef $13
-
-	ld de, SCREEN_WIDTH
-
-	ld a, [wBoxAlignment]
-	and a
-	jr nz, .right
-
-	ld a, [hGraphicStartTile]
-.x1
-	push bc
-	push hl
-
-.y1
-	ld [hl], a
-	add hl, de
-	inc a
-	dec c
-	jr nz, .y1
-
-	pop hl
-	inc hl
-	pop bc
-	dec b
-	jr nz, .x1
-	ret
-
-.right
-; Right-aligned.
-	push bc
-	ld b, 0
-	dec c
-	add hl, bc
-	pop bc
-
-	ld a, [hGraphicStartTile]
-.x2
-	push bc
-	push hl
-
-.y2
-	ld [hl], a
-	add hl, de
-	inc a
-	dec c
-	jr nz, .y2
-
-	pop hl
-	dec hl
-	pop bc
-	dec b
-	jr nz, .x2
-	ret
--- a/engine/play_slow_cry.asm
+++ /dev/null
@@ -1,31 +1,0 @@
-PlaySlowCry: ; fb841
-	ld a, [ScriptVar]
-	call LoadCryHeader
-	jr c, .done
-
-	ld hl, CryPitch
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	ld bc, -$140
-	add hl, bc
-	ld a, l
-	ld [CryPitch], a
-	ld a, h
-	ld [CryPitch + 1], a
-	ld hl, CryLength
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	ld bc, $60
-	add hl, bc
-	ld a, l
-	ld [CryLength], a
-	ld a, h
-	ld [CryLength + 1], a
-	farcall _PlayCryHeader
-	call WaitSFX
-
-.done
-	ret
-; fb877
--- a/engine/player_gfx_2.asm
+++ /dev/null
@@ -1,5 +1,0 @@
-ChrisBackpic: ; 2ba1a
-INCBIN "gfx/player/chris_back.2bpp.lz"
-
-DudeBackpic: ; 2bbaa
-INCBIN "gfx/battle/dude.2bpp.lz"
--- a/engine/pokeball_wobble.asm
+++ /dev/null
@@ -1,88 +1,0 @@
-GetPokeBallWobble: ; f971 (3:7971)
-; Returns whether a Poke Ball will wobble in the catch animation.
-; Whether a Pokemon is caught is determined beforehand.
-
-	push de
-
-	ld a, [rSVBK]
-	ld d, a
-	push de
-
-	ld a, 1 ; BANK(Buffer2)
-	ld [rSVBK], a
-
-	ld a, [Buffer2]
-	inc a
-	ld [Buffer2], a
-
-; Wobble up to 3 times.
-	cp 3 + 1
-	jr z, .finished
-
-	ld a, [wWildMon]
-	and a
-	ld c, 0 ; next
-	jr nz, .done
-
-	ld hl, .WobbleProbabilities
-	ld a, [Buffer1]
-	ld b, a
-.loop
-	ld a, [hli]
-	cp b
-	jr nc, .checkwobble
-	inc hl
-	jr .loop
-
-.checkwobble
-	ld b, [hl]
-	call Random
-	cp b
-	ld c, 0 ; next
-	jr c, .done
-	ld c, 2 ; escaped
-	jr .done
-
-.finished
-	ld a, [wWildMon]
-	and a
-	ld c, 1 ; caught
-	jr nz, .done
-	ld c, 2 ; escaped
-
-.done
-	pop de
-	ld e, a
-	ld a, d
-	ld [rSVBK], a
-	ld a, e
-	pop de
-	ret
-
-.WobbleProbabilities: ; f9ba
-; catch rate, chance of wobbling / 255
-; nLeft/255 = (nRight/255) ** 4
-	db   1,  63
-	db   2,  75
-	db   3,  84
-	db   4,  90
-	db   5,  95
-	db   7, 103
-	db  10, 113
-	db  15, 126
-	db  20, 134
-	db  30, 149
-	db  40, 160
-	db  50, 169
-	db  60, 177
-	db  80, 191
-	db 100, 201
-	db 120, 211
-	db 140, 220
-	db 160, 227
-	db 180, 234
-	db 200, 240
-	db 220, 246
-	db 240, 251
-	db 254, 253
-	db 255, 255
--- a/engine/pokegear_2.asm
+++ /dev/null
@@ -1,25 +1,0 @@
-TownMap_ConvertLineBreakCharacters: ; 1de2c5
-	ld hl, StringBuffer1
-.loop
-	ld a, [hl]
-	cp "@"
-	jr z, .end
-	cp "%"
-	jr z, .line_break
-	cp "¯"
-	jr z, .line_break
-	inc hl
-	jr .loop
-
-.line_break
-	ld [hl], "<LNBRK>"
-
-.end
-	ld de, StringBuffer1
-	hlcoord 9, 0
-	call PlaceString
-	ret
-
-
-PokegearGFX: ; 1de2e4
-INCBIN "gfx/pokegear/pokegear.2bpp.lz"
--- a/engine/pokerus_tick.asm
+++ /dev/null
@@ -1,26 +1,0 @@
-ApplyPokerusTick: ; 13988
-; decreases all pokemon's pokerus counter by b. if the lower nybble reaches zero, the pokerus is cured.
-	ld hl, PartyMon1PokerusStatus ; PartyMon1 + MON_PKRS
-	ld a, [PartyCount]
-	and a
-	ret z ; make sure it's not wasting time on an empty party
-	ld c, a
-.loop
-	ld a, [hl]
-	and $f ; lower nybble is the number of days remaining
-	jr z, .next ; if already 0, skip
-	sub b ; subtract the number of days
-	jr nc, .ok ; max(result, 0)
-	xor a
-.ok
-	ld d, a ; back up this value because we need to preserve the strain (upper nybble)
-	ld a, [hl]
-	and $f0
-	add d
-	ld [hl], a ; this prevents a cured pokemon from recontracting pokerus
-.next
-	ld de, PARTYMON_STRUCT_LENGTH
-	add hl, de
-	dec c
-	jr nz, .loop
-	ret
--- a/engine/printhoursmins.asm
+++ /dev/null
@@ -1,64 +1,0 @@
-Function1dd6a9: ; 1dd6a9
-; XXX
-	ld a, b
-	ld b, c
-	ld c, a
-	push bc
-	push de
-	ld hl, sp+$2
-	ld d, h
-	ld e, l
-	pop hl
-	lb bc, PRINTNUM_LEADINGZEROS | 2, 5
-	call PrintNum
-	pop bc
-	ret
-
-PrintHoursMins ; 1dd6bb (77:56bb)
-; Hours in b, minutes in c
-	ld a, b
-	cp 12
-	push af
-	jr c, .AM
-	jr z, .PM
-	sub 12
-	jr .PM
-.AM:
-	or a
-	jr nz, .PM
-	ld a, 12
-.PM:
-	ld b, a
-; Crazy stuff happening with the stack
-	push bc
-	ld hl, sp+$1
-	push de
-	push hl
-	pop de
-	pop hl
-	ld [hl], " "
-	lb bc, 1, 2
-	call PrintNum
-	ld [hl], ":"
-	inc hl
-	ld d, h
-	ld e, l
-	ld hl, sp+$0
-	push de
-	push hl
-	pop de
-	pop hl
-	lb bc, PRINTNUM_LEADINGZEROS | 1, 2
-	call PrintNum
-	pop bc
-	ld de, String_AM
-	pop af
-	jr c, .place_am_pm
-	ld de, String_PM
-.place_am_pm
-	inc hl
-	call PlaceString
-	ret
-
-String_AM: db "AM@" ; 1dd6fc
-String_PM: db "PM@" ; 1dd6ff
--- /dev/null
+++ b/engine/routines/applypokerustick.asm
@@ -1,0 +1,26 @@
+ApplyPokerusTick: ; 13988
+; decreases all pokemon's pokerus counter by b. if the lower nybble reaches zero, the pokerus is cured.
+	ld hl, PartyMon1PokerusStatus ; PartyMon1 + MON_PKRS
+	ld a, [PartyCount]
+	and a
+	ret z ; make sure it's not wasting time on an empty party
+	ld c, a
+.loop
+	ld a, [hl]
+	and $f ; lower nybble is the number of days remaining
+	jr z, .next ; if already 0, skip
+	sub b ; subtract the number of days
+	jr nc, .ok ; max(result, 0)
+	xor a
+.ok
+	ld d, a ; back up this value because we need to preserve the strain (upper nybble)
+	ld a, [hl]
+	and $f0
+	add d
+	ld [hl], a ; this prevents a cured pokemon from recontracting pokerus
+.next
+	ld de, PARTYMON_STRUCT_LENGTH
+	add hl, de
+	dec c
+	jr nz, .loop
+	ret
--- /dev/null
+++ b/engine/routines/battlestart_copytilemapatonce.asm
@@ -1,0 +1,3 @@
+BattleStart_CopyTilemapAtOnce: ; 8cf4f
+	call CGBOnly_CopyTilemapAtOnce
+	ret
--- /dev/null
+++ b/engine/routines/checkbattlescene.asm
@@ -1,0 +1,47 @@
+CheckBattleScene: ; 4ea44
+; Return carry if battle scene is turned off.
+
+	ld a, 0
+	ld hl, wLinkMode
+	call GetFarWRAMByte
+	cp LINK_MOBILE
+	jr z, .mobile
+
+	ld a, [Options]
+	bit BATTLE_SCENE, a
+	jr nz, .off
+
+	and a
+	ret
+
+.mobile
+	ld a, [wcd2f]
+	and a
+	jr nz, .from_wram
+
+	ld a, $4
+	call GetSRAMBank
+	ld a, [$a60c]
+	ld c, a
+	call CloseSRAM
+
+	ld a, c
+	bit 0, c
+	jr z, .off
+
+	and a
+	ret
+
+.from_wram
+	ld a, $5
+	ld hl, w5_dc00
+	call GetFarWRAMByte
+	bit 0, a
+	jr z, .off
+
+	and a
+	ret
+
+.off
+	scf
+	ret
--- /dev/null
+++ b/engine/routines/checknickerrors.asm
@@ -1,0 +1,74 @@
+CheckNickErrors:: ; 669f
+; error-check monster nick before use
+; must be a peace offering to gamesharkers
+
+; input: de = nick location
+
+	push bc
+	push de
+	ld b, PKMN_NAME_LENGTH
+
+.checkchar
+; end of nick?
+	ld a, [de]
+	cp "@" ; terminator
+	jr z, .end
+
+; check if this char is a text command
+	ld hl, .textcommands
+	dec hl
+.loop
+; next entry
+	inc hl
+; reached end of commands table?
+	ld a, [hl]
+	cp -1
+	jr z, .done
+
+; is the current char between this value (inclusive)...
+	ld a, [de]
+	cp [hl]
+	inc hl
+	jr c, .loop
+; ...and this one?
+	cp [hl]
+	jr nc, .loop
+
+; replace it with a "?"
+	ld a, "?"
+	ld [de], a
+	jr .loop
+
+.done
+; next char
+	inc de
+; reached end of nick without finding a terminator?
+	dec b
+	jr nz, .checkchar
+
+; change nick to "?@"
+	pop de
+	push de
+	ld a, "?"
+	ld [de], a
+	inc de
+	ld a, "@"
+	ld [de], a
+.end
+; if the nick has any errors at this point it's out of our hands
+	pop de
+	pop bc
+	ret
+
+.textcommands ; 66cf
+; table defining which characters are actually text commands
+; format:
+	;      ≥           <
+	db "<START>",  TX_BOX    + 1
+	db "<PLAY_G>", $18       + 1
+	db $1d,        "%"       + 1
+	db $35,        "<GREEN>" + 1
+	db "<ENEMY>",  "<ENEMY>" + 1
+	db "<MOM>",    "<TM>"    + 1
+	db "<ROCKET>", "┘"       + 1
+	db -1 ; end
--- /dev/null
+++ b/engine/routines/checkpokerus.asm
@@ -1,0 +1,25 @@
+CheckPokerus: ; 4d860
+; Return carry if a monster in your party has Pokerus
+
+; Get number of monsters to iterate over
+	ld a, [PartyCount]
+	and a
+	jr z, .NoPokerus
+	ld b, a
+; Check each monster in the party for Pokerus
+	ld hl, PartyMon1PokerusStatus
+	ld de, PARTYMON_STRUCT_LENGTH
+.Check:
+	ld a, [hl]
+	and $0f ; only the bottom nybble is used
+	jr nz, .HasPokerus
+; Next PartyMon
+	add hl, de
+	dec b
+	jr nz, .Check
+.NoPokerus:
+	and a
+	ret
+.HasPokerus:
+	scf
+	ret
--- /dev/null
+++ b/engine/routines/checksave.asm
@@ -1,0 +1,20 @@
+CheckSave:: ; 4cffe
+	ld a, BANK(sCheckValue1) ; BANK(sCheckValue2)
+	call GetSRAMBank
+	ld a, [sCheckValue1]
+	ld b, a
+	ld a, [sCheckValue2]
+	ld c, a
+	call CloseSRAM
+	ld a, b
+	cp SAVE_CHECK_VALUE_1
+	jr nz, .ok
+	ld a, c
+	cp SAVE_CHECK_VALUE_2
+	jr nz, .ok
+	ld c, $1
+	ret
+
+.ok
+	ld c, $0
+	ret
--- /dev/null
+++ b/engine/routines/checktime.asm
@@ -1,0 +1,19 @@
+CheckTime:: ; c000
+	ld a, [TimeOfDay]
+	ld hl, .TimeOfDayTable
+	ld de, 2
+	call IsInArray
+	inc hl
+	ld c, [hl]
+	ret c
+
+	xor a
+	ld c, a
+	ret
+
+.TimeOfDayTable: ; c012
+	db MORN_F, MORN
+	db DAY_F,  DAY
+	db NITE_F, NITE
+	db NITE_F, NITE
+	db -1
--- /dev/null
+++ b/engine/routines/consumehelditem.asm
@@ -1,0 +1,80 @@
+ConsumeHeldItem: ; 27192
+	push hl
+	push de
+	push bc
+	ld a, [hBattleTurn]
+	and a
+	ld hl, OTPartyMon1Item
+	ld de, EnemyMonItem
+	ld a, [CurOTMon]
+	jr z, .theirturn
+	ld hl, PartyMon1Item
+	ld de, BattleMonItem
+	ld a, [CurBattleMon]
+
+.theirturn
+	push hl
+	push af
+	ld a, [de]
+	ld b, a
+	farcall GetItemHeldEffect
+	ld hl, .ConsumableEffects
+.loop
+	ld a, [hli]
+	cp b
+	jr z, .ok
+	inc a
+	jr nz, .loop
+	pop af
+	pop hl
+	pop bc
+	pop de
+	pop hl
+	ret
+
+.ok
+	xor a
+	ld [de], a
+	pop af
+	pop hl
+	call GetPartyLocation
+	ld a, [hBattleTurn]
+	and a
+	jr nz, .ourturn
+	ld a, [wBattleMode]
+	dec a
+	jr z, .done
+
+.ourturn
+	ld [hl], $0
+
+.done
+	pop bc
+	pop de
+	pop hl
+	ret
+
+.ConsumableEffects: ; 271de
+; Consumable items?
+	db HELD_BERRY
+	db HELD_2
+	db HELD_5
+	db HELD_HEAL_POISON
+	db HELD_HEAL_FREEZE
+	db HELD_HEAL_BURN
+	db HELD_HEAL_SLEEP
+	db HELD_HEAL_PARALYZE
+	db HELD_HEAL_STATUS
+	db HELD_30
+	db HELD_ATTACK_UP
+	db HELD_DEFENSE_UP
+	db HELD_SPEED_UP
+	db HELD_SP_ATTACK_UP
+	db HELD_SP_DEFENSE_UP
+	db HELD_ACCURACY_UP
+	db HELD_EVASION_UP
+	db HELD_38
+	db HELD_71
+	db HELD_ESCAPE
+	db HELD_CRITICAL_UP
+	db -1
--- /dev/null
+++ b/engine/routines/correcterrorsinplayerparty.asm
@@ -1,0 +1,229 @@
+CorrectErrorsInPlayerParty: ; unreferenced
+	ld hl, PartyCount
+	ld a, [hl]
+	and a
+	ret z
+
+	cp PARTY_LENGTH + 1
+	jr c, .party_length_okay
+	ld a, PARTY_LENGTH
+	ld [hl], a
+.party_length_okay
+	inc hl
+
+	ld b, a
+	ld c, 0
+.loop1
+	ld a, [hl]
+	and a
+	jr z, .invalid_species
+	cp NUM_POKEMON + 1
+	jr z, .invalid_species
+	cp EGG + 1
+	jr c, .next_species
+
+.invalid_species
+	ld [hl], SMEARGLE
+	push hl
+	push bc
+	ld a, c
+	ld hl, PartyMon1Species
+	call GetPartyLocation
+	ld [hl], SMEARGLE
+	pop bc
+	pop hl
+
+.next_species
+	inc hl
+	inc c
+	dec b
+	jr nz, .loop1
+	ld [hl], $ff
+
+	ld hl, PartyMon1
+	ld a, [PartyCount]
+	ld d, a
+	ld e, 0
+.loop2
+	push de
+	push hl
+	ld b, h
+	ld c, l
+	ld a, [hl]
+	and a
+	jr z, .invalid_species_2
+	cp NUM_POKEMON + 1
+	jr c, .check_level
+
+.invalid_species_2
+	ld [hl], SMEARGLE
+	push de
+	ld d, 0
+	ld hl, PartySpecies
+	add hl, de
+	pop de
+	ld a, SMEARGLE
+	ld [hl], a
+
+.check_level
+	ld [CurSpecies], a
+	call GetBaseData
+	ld hl, MON_LEVEL
+	add hl, bc
+	ld a, [hl]
+	cp MIN_LEVEL
+	ld a, MIN_LEVEL
+	jr c, .invalid_level
+	ld a, [hl]
+	cp MAX_LEVEL
+	jr c, .load_level
+	ld a, MAX_LEVEL
+.invalid_level
+	ld [hl], a
+.load_level
+	ld [CurPartyLevel], a
+
+	ld hl, MON_MAXHP
+	add hl, bc
+	ld d, h
+	ld e, l
+	ld hl, MON_STAT_EXP - 1
+	add hl, bc
+	ld b, $1
+	predef CalcPkmnStats
+	pop hl
+	ld bc, PARTYMON_STRUCT_LENGTH
+	add hl, bc
+	pop de
+	inc e
+	dec d
+	jr nz, .loop2
+
+	ld de, PartyMonNicknames
+	ld a, [PartyCount]
+	ld b, a
+	ld c, 0
+.loop3
+	push bc
+	call .GetLengthOfStringWith6CharCap
+	push de
+	farcall CheckStringForErrors
+	pop hl
+	pop bc
+	jr nc, .valid_nickname
+
+	push bc
+	push hl
+	ld hl, PartySpecies
+	push bc
+	ld b, 0
+	add hl, bc
+	pop bc
+	ld a, [hl]
+	cp EGG
+	ld hl, .TAMAGO
+	jr z, .got_nickname
+	ld [wd265], a
+	call GetPokemonName
+	ld hl, StringBuffer1
+.got_nickname
+	pop de
+	ld bc, PKMN_NAME_LENGTH
+	call CopyBytes
+	pop bc
+
+.valid_nickname
+	inc c
+	dec b
+	jr nz, .loop3
+
+	ld de, PartyMonOT
+	ld a, [PartyCount]
+	ld b, a
+	ld c, 0
+.loop4
+	push bc
+	call .GetLengthOfStringWith6CharCap
+	push de
+	farcall CheckStringForErrors
+	pop hl
+	jr nc, .valid_ot_name
+	ld d, h
+	ld e, l
+	ld hl, PlayerName
+	ld bc, NAME_LENGTH
+	call CopyBytes
+.valid_ot_name
+	pop bc
+	inc c
+	dec b
+	jr nz, .loop4
+
+	ld hl, PartyMon1Moves
+	ld a, [PartyCount]
+	ld b, a
+.loop5
+	push hl
+	ld c, NUM_MOVES
+	ld a, [hl]
+	and a
+	jr z, .invalid_move
+	cp NUM_ATTACKS + 1
+	jr c, .moves_loop
+.invalid_move
+	ld [hl], POUND
+
+.moves_loop
+	ld a, [hl]
+	and a
+	jr z, .fill_invalid_moves
+	cp NUM_ATTACKS + 1
+	jr c, .next_move
+
+.fill_invalid_moves
+	xor a
+	ld [hli], a
+	dec c
+	jr nz, .fill_invalid_moves
+	jr .next_pokemon
+
+.next_move
+	inc hl
+	dec c
+	jr nz, .moves_loop
+
+.next_pokemon
+	pop hl
+	push bc
+	ld bc, PARTYMON_STRUCT_LENGTH
+	add hl, bc
+	pop bc
+	dec b
+	jr nz, .loop5
+	ret
+; 13b6b
+
+.TAMAGO: ; 13b6b
+	db "タマゴ@@@"
+; 13b71
+
+.GetLengthOfStringWith6CharCap: ; 13b71
+	push de
+	ld c, 1
+	ld b, NAME_LENGTH_JAPANESE
+.search_loop
+	ld a, [de]
+	cp "@"
+	jr z, .done
+	inc de
+	inc c
+	dec b
+	jr nz, .search_loop
+	dec c
+	dec de
+	ld a, "@"
+	ld [de], a
+.done
+	pop de
+	ret
+; 13b87
--- /dev/null
+++ b/engine/routines/drawkrispackgfx.asm
@@ -1,0 +1,20 @@
+DrawKrisPackGFX: ; 48e81
+	ld hl, PackFGFXPointers
+	add hl, de
+	add hl, de
+	ld a, [hli]
+	ld e, a
+	ld d, [hl]
+	ld hl, VTiles2 tile $50
+	lb bc, BANK(PackFGFX), 15
+	call Request2bpp
+	ret
+
+PackFGFXPointers: ; 48e93
+	dw PackFGFX + (15 tiles) * 1
+	dw PackFGFX + (15 tiles) * 3
+	dw PackFGFX + (15 tiles) * 0
+	dw PackFGFX + (15 tiles) * 2
+
+PackFGFX: ; 48e9b
+INCBIN "gfx/pack/pack_f.2bpp"
--- /dev/null
+++ b/engine/routines/emptyallsrambanks.asm
@@ -1,0 +1,19 @@
+EmptyAllSRAMBanks: ; 4cf1f
+	ld a, $0
+	call .EmptyBank
+	ld a, $1
+	call .EmptyBank
+	ld a, $2
+	call .EmptyBank
+	ld a, $3
+	call .EmptyBank
+	ret
+
+.EmptyBank: ; 4cf34
+	call GetSRAMBank
+	ld hl, SRAM_Begin
+	ld bc, SRAM_End - SRAM_Begin
+	xor a
+	call ByteFill
+	call CloseSRAM
+	ret
--- /dev/null
+++ b/engine/routines/flagpredef.asm
@@ -1,0 +1,70 @@
+FlagPredef: ; 4d7c1
+; Perform action b on flag c in flag array hl.
+; If checking a flag, check flag array d:hl unless d is 0.
+
+; For longer flag arrays, see FlagAction.
+
+	push hl
+	push bc
+
+; Divide by 8 to get the byte we want.
+	push bc
+	srl c
+	srl c
+	srl c
+	ld b, 0
+	add hl, bc
+	pop bc
+
+; Which bit we want from the byte
+	ld a, c
+	and 7
+	ld c, a
+
+; Shift left until we can mask the bit
+	ld a, 1
+	jr z, .shifted
+.shift
+	add a
+	dec c
+	jr nz, .shift
+.shifted
+	ld c, a
+
+; What are we doing to this flag?
+	dec b
+	jr z, .set ; 1
+	dec b
+	jr z, .check ; 2
+
+.reset
+	ld a, c
+	cpl
+	and [hl]
+	ld [hl], a
+	jr .done
+
+.set
+	ld a, [hl]
+	or c
+	ld [hl], a
+	jr .done
+
+.check
+	ld a, d
+	cp 0
+	jr nz, .farcheck
+
+	ld a, [hl]
+	and c
+	jr .done
+
+.farcheck
+	call GetFarByte
+	and c
+
+.done
+	pop bc
+	pop hl
+	ld c, a
+	ret
--- /dev/null
+++ b/engine/routines/getbreedmonlevelgrowth.asm
@@ -1,0 +1,27 @@
+GetBreedMon1LevelGrowth: ; e698
+	ld hl, wBreedMon1Stats
+	ld de, TempMon
+	ld bc, BOXMON_STRUCT_LENGTH
+	call CopyBytes
+	callfar CalcLevel
+	ld a, [wBreedMon1Level]
+	ld b, a
+	ld a, d
+	ld e, a
+	sub b
+	ld d, a
+	ret
+
+GetBreedMon2LevelGrowth: ; e6b3
+	ld hl, wBreedMon2Stats
+	ld de, TempMon
+	ld bc, BOXMON_STRUCT_LENGTH
+	call CopyBytes
+	callfar CalcLevel
+	ld a, [wBreedMon2Level]
+	ld b, a
+	ld a, d
+	ld e, a
+	sub b
+	ld d, a
+	ret
--- /dev/null
+++ b/engine/routines/getpokeballwobble.asm
@@ -1,0 +1,88 @@
+GetPokeBallWobble: ; f971 (3:7971)
+; Returns whether a Poke Ball will wobble in the catch animation.
+; Whether a Pokemon is caught is determined beforehand.
+
+	push de
+
+	ld a, [rSVBK]
+	ld d, a
+	push de
+
+	ld a, 1 ; BANK(Buffer2)
+	ld [rSVBK], a
+
+	ld a, [Buffer2]
+	inc a
+	ld [Buffer2], a
+
+; Wobble up to 3 times.
+	cp 3 + 1
+	jr z, .finished
+
+	ld a, [wWildMon]
+	and a
+	ld c, 0 ; next
+	jr nz, .done
+
+	ld hl, .WobbleProbabilities
+	ld a, [Buffer1]
+	ld b, a
+.loop
+	ld a, [hli]
+	cp b
+	jr nc, .checkwobble
+	inc hl
+	jr .loop
+
+.checkwobble
+	ld b, [hl]
+	call Random
+	cp b
+	ld c, 0 ; next
+	jr c, .done
+	ld c, 2 ; escaped
+	jr .done
+
+.finished
+	ld a, [wWildMon]
+	and a
+	ld c, 1 ; caught
+	jr nz, .done
+	ld c, 2 ; escaped
+
+.done
+	pop de
+	ld e, a
+	ld a, d
+	ld [rSVBK], a
+	ld a, e
+	pop de
+	ret
+
+.WobbleProbabilities: ; f9ba
+; catch rate, chance of wobbling / 255
+; nLeft/255 = (nRight/255) ** 4
+	db   1,  63
+	db   2,  75
+	db   3,  84
+	db   4,  90
+	db   5,  95
+	db   7, 103
+	db  10, 113
+	db  15, 126
+	db  20, 134
+	db  30, 149
+	db  40, 160
+	db  50, 169
+	db  60, 177
+	db  80, 191
+	db 100, 201
+	db 120, 211
+	db 140, 220
+	db 160, 227
+	db 180, 234
+	db 200, 240
+	db 220, 246
+	db 240, 251
+	db 254, 253
+	db 255, 255
--- /dev/null
+++ b/engine/routines/getsquareroot.asm
@@ -1,0 +1,30 @@
+GetSquareRoot: ; 13b87
+; Return the square root of de in b.
+
+; Rather than calculating the result, we take the index of the
+; first value in a table of squares that isn't lower than de.
+
+	ld hl, .Squares
+	ld b, 0
+.loop
+; Make sure we don't go past the end of the table.
+	inc b
+	ld a, b
+	cp $ff
+	ret z
+
+; Iterate over the table until b**2 >= de.
+	ld a, [hli]
+	sub e
+	ld a, [hli]
+	sbc d
+
+	jr c, .loop
+	ret
+
+.Squares: ; 13b98
+root	set 1
+	rept $ff
+	dw root*root
+root	set root+1
+	endr
--- /dev/null
+++ b/engine/routines/initlist.asm
@@ -1,0 +1,54 @@
+InitList: ; 50db9
+	ld a, [wInitListType]
+
+	cp INIT_ENEMYOT_LIST
+	jr nz, .check_party_ot_name
+	ld hl, OTPartyCount
+	ld de, OTPartyMonOT
+	ld a, ENEMY_OT_NAME
+	jr .done
+
+.check_party_ot_name
+	cp INIT_PLAYEROT_LIST
+	jr nz, .check_mon_name
+	ld hl, PartyCount
+	ld de, PartyMonOT
+	ld a, PARTY_OT_NAME
+	jr .done
+
+.check_mon_name
+	cp INIT_MON_LIST
+	jr nz, .check_item_name
+	ld hl, CurMart
+	ld de, PokemonNames
+	ld a, PKMN_NAME
+	jr .done
+
+.check_item_name
+	cp INIT_BAG_ITEM_LIST
+	jr nz, .check_ob_item_name
+	ld hl, NumItems
+	ld de, ItemNames
+	ld a, ITEM_NAME
+	jr .done
+
+.check_ob_item_name
+	ld hl, CurMart
+	ld de, ItemNames
+	ld a, ITEM_NAME
+.done
+	ld [wNamedObjectTypeBuffer], a
+	ld a, l
+	ld [wListPointer], a
+	ld a, h
+	ld [wListPointer + 1], a
+	ld a, e
+	ld [wUnusedD102], a
+	ld a, d
+	ld [wUnusedD102 + 1], a
+	ld bc, ItemAttributes
+	ld a, c
+	ld [wItemAttributesPtr], a
+	ld a, b
+	ld [wItemAttributesPtr + 1], a
+	ret
--- /dev/null
+++ b/engine/routines/knowsmove.asm
@@ -1,0 +1,25 @@
+KnowsMove: ; f9ea
+	ld a, MON_MOVES
+	call GetPartyParamLocation
+	ld a, [wPutativeTMHMMove]
+	ld b, a
+	ld c, NUM_MOVES
+.loop
+	ld a, [hli]
+	cp b
+	jr z, .knows_move
+	dec c
+	jr nz, .loop
+	and a
+	ret
+
+.knows_move
+	ld hl, .Text_knows
+	call PrintText
+	scf
+	ret
+
+.Text_knows: ; 0xfa06
+	; knows @ .
+	text_jump UnknownText_0x1c5ea8
+	db "@"
--- /dev/null
+++ b/engine/routines/kurt_selectquantity_interpretjoypad.asm
@@ -1,0 +1,4 @@
+Kurt_SelectQuantity_InterpretJoypad: ; 27a28
+	call BuySellToss_InterpretJoypad
+	ld b, a
+	ret
--- /dev/null
+++ b/engine/routines/leveluphappinessmod.asm
@@ -1,0 +1,20 @@
+LevelUpHappinessMod: ; 2709e
+	ld a, [CurPartyMon]
+	ld hl, PartyMon1CaughtLocation
+	call GetPartyLocation
+	ld a, [hl]
+	and $7f
+	ld d, a
+	ld a, [MapGroup]
+	ld b, a
+	ld a, [MapNumber]
+	ld c, a
+	call GetWorldMapLocation
+	cp d
+	ld c, HAPPINESS_GAINLEVEL
+	jr nz, .ok
+	ld c, HAPPINESS_GAINLEVELATHOME
+
+.ok
+	callfar ChangeHappiness
+	ret
--- /dev/null
+++ b/engine/routines/loadmappart.asm
@@ -1,0 +1,36 @@
+_LoadMapPart:: ; 4d15b
+	ld hl, wMisc
+	ld a, [wMetatileStandingY]
+	and a
+	jr z, .top_row
+	ld bc, WMISC_WIDTH * 2
+	add hl, bc
+
+.top_row
+	ld a, [wMetatileStandingX]
+	and a
+	jr z, .left_column
+	inc hl
+	inc hl
+
+.left_column
+	decoord 0, 0
+	ld b, SCREEN_HEIGHT
+.loop
+	ld c, SCREEN_WIDTH
+.loop2
+	ld a, [hli]
+	ld [de], a
+	inc de
+	dec c
+	jr nz, .loop2
+	ld a, l
+	add 4
+	ld l, a
+	jr nc, .carry
+	inc h
+
+.carry
+	dec b
+	jr nz, .loop
+	ret
--- /dev/null
+++ b/engine/routines/loadpushoam.asm
@@ -1,0 +1,21 @@
+LoadPushOAM:: ; 4031
+	ld c, hPushOAM - $ff00
+	ld b, .PushOAMEnd - .PushOAM
+	ld hl, .PushOAM
+.loop
+	ld a, [hli]
+	ld [$ff00+c], a
+	inc c
+	dec b
+	jr nz, .loop
+	ret
+
+.PushOAM: ; 403f
+	ld a, Sprites / $100
+	ld [rDMA], a
+	ld a, (SpritesEnd - Sprites) / 4 ; 40
+.pushoam_loop
+	dec a
+	jr nz, .pushoam_loop
+	ret
+.PushOAMEnd
--- /dev/null
+++ b/engine/routines/newpokedexentry.asm
@@ -1,0 +1,52 @@
+NewPokedexEntry: ; fb877
+	ld a, [hMapAnims]
+	push af
+	xor a
+	ld [hMapAnims], a
+	call LowVolume
+	call ClearBGPalettes
+	call ClearTileMap
+	call UpdateSprites
+	call ClearSprites
+	ld a, [wPokedexStatus]
+	push af
+	ld a, [hSCX]
+	add $5
+	ld [hSCX], a
+	xor a
+	ld [wPokedexStatus], a
+	farcall _NewPokedexEntry
+	call WaitPressAorB_BlinkCursor
+	ld a, $1
+	ld [wPokedexStatus], a
+	farcall DisplayDexEntry
+	call WaitPressAorB_BlinkCursor
+	pop af
+	ld [wPokedexStatus], a
+	call MaxVolume
+	call RotateThreePalettesRight
+	ld a, [hSCX]
+	add -5 ; 251 ; NUM_POKEMON
+	ld [hSCX], a
+	call .ReturnFromDexRegistration
+	pop af
+	ld [hMapAnims], a
+	ret
+; fb8c8
+
+.ReturnFromDexRegistration: ; fb8c8
+	call ClearTileMap
+	call LoadFontsExtra
+	call LoadStandardFont
+	farcall Pokedex_PlaceFrontpicTopLeftCorner
+	call WaitBGMap2
+	farcall GetEnemyMonDVs
+	ld a, [hli]
+	ld [TempMonDVs], a
+	ld a, [hl]
+	ld [TempMonDVs + 1], a
+	ld b, SCGB_TRAINER_OR_MON_FRONTPIC_PALS
+	call GetSGBLayout
+	call SetPalettes
+	ret
+; fb8f1
--- /dev/null
+++ b/engine/routines/phonering_copytilemapatonce.asm
@@ -1,0 +1,80 @@
+PhoneRing_CopyTilemapAtOnce: ; 4d188
+	ld a, [hCGB]
+	and a
+	jp z, WaitBGMap
+	ld a, [wSpriteUpdatesEnabled]
+	cp $0
+	jp z, WaitBGMap
+
+; What follows is a modified version of CopyTilemapAtOnce.
+	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 $8f
+	jr c, .wait
+
+	di
+	ld a, BANK(VBGMap2)
+	ld [rVBK], a
+	hlcoord 0, 0, AttrMap
+	call .CopyTilemapAtOnce
+	ld a, BANK(VBGMap0)
+	ld [rVBK], a
+	hlcoord 0, 0
+	call .CopyTilemapAtOnce
+.wait2
+	ld a, [rLY]
+	cp $8f
+	jr c, .wait2
+	ei
+
+	pop af
+	ld [hMapAnims], a
+	pop af
+	ld [hBGMapMode], a
+	ret
+
+.CopyTilemapAtOnce: ; 4d1cb
+	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, rSTAT % $100
+
+.loop
+rept SCREEN_WIDTH / 2
+	pop de
+.loop\@
+	ld a, [$ff00+c]
+	and b
+	jr nz, .loop\@
+	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
--- /dev/null
+++ b/engine/routines/placegraphic.asm
@@ -1,0 +1,56 @@
+PlaceGraphic: ; 2ef6e
+; Fill wBoxAlignment-aligned box width b height c
+; with iterating tile starting from hGraphicStartTile at hl.
+; Predef $13
+
+	ld de, SCREEN_WIDTH
+
+	ld a, [wBoxAlignment]
+	and a
+	jr nz, .right
+
+	ld a, [hGraphicStartTile]
+.x1
+	push bc
+	push hl
+
+.y1
+	ld [hl], a
+	add hl, de
+	inc a
+	dec c
+	jr nz, .y1
+
+	pop hl
+	inc hl
+	pop bc
+	dec b
+	jr nz, .x1
+	ret
+
+.right
+; Right-aligned.
+	push bc
+	ld b, 0
+	dec c
+	add hl, bc
+	pop bc
+
+	ld a, [hGraphicStartTile]
+.x2
+	push bc
+	push hl
+
+.y2
+	ld [hl], a
+	add hl, de
+	inc a
+	dec c
+	jr nz, .y2
+
+	pop hl
+	dec hl
+	pop bc
+	dec b
+	jr nz, .x2
+	ret
--- /dev/null
+++ b/engine/routines/placewaitingtext.asm
@@ -1,0 +1,24 @@
+PlaceWaitingText:: ; 4000
+	hlcoord 3, 10
+	ld b, 1
+	ld c, 11
+
+	ld a, [wBattleMode]
+	and a
+	jr z, .notinbattle
+
+	call TextBox
+	jr .proceed
+
+.notinbattle
+	predef Predef_LinkTextbox
+
+.proceed
+	hlcoord 4, 11
+	ld de, .Waiting
+	call PlaceString
+	ld c, 50
+	jp DelayFrames
+
+.Waiting: ; 4025
+	db "Waiting...!@"
--- /dev/null
+++ b/engine/routines/playslowcry.asm
@@ -1,0 +1,31 @@
+PlaySlowCry: ; fb841
+	ld a, [ScriptVar]
+	call LoadCryHeader
+	jr c, .done
+
+	ld hl, CryPitch
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	ld bc, -$140
+	add hl, bc
+	ld a, l
+	ld [CryPitch], a
+	ld a, h
+	ld [CryPitch + 1], a
+	ld hl, CryLength
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	ld bc, $60
+	add hl, bc
+	ld a, l
+	ld [CryLength], a
+	ld a, h
+	ld [CryLength + 1], a
+	farcall _PlayCryHeader
+	call WaitSFX
+
+.done
+	ret
+; fb877
--- /dev/null
+++ b/engine/routines/printhoursmins.asm
@@ -1,0 +1,64 @@
+Function1dd6a9: ; 1dd6a9
+; XXX
+	ld a, b
+	ld b, c
+	ld c, a
+	push bc
+	push de
+	ld hl, sp+$2
+	ld d, h
+	ld e, l
+	pop hl
+	lb bc, PRINTNUM_LEADINGZEROS | 2, 5
+	call PrintNum
+	pop bc
+	ret
+
+PrintHoursMins: ; 1dd6bb (77:56bb)
+; Hours in b, minutes in c
+	ld a, b
+	cp 12
+	push af
+	jr c, .AM
+	jr z, .PM
+	sub 12
+	jr .PM
+.AM:
+	or a
+	jr nz, .PM
+	ld a, 12
+.PM:
+	ld b, a
+; Crazy stuff happening with the stack
+	push bc
+	ld hl, sp+$1
+	push de
+	push hl
+	pop de
+	pop hl
+	ld [hl], " "
+	lb bc, 1, 2
+	call PrintNum
+	ld [hl], ":"
+	inc hl
+	ld d, h
+	ld e, l
+	ld hl, sp+$0
+	push de
+	push hl
+	pop de
+	pop hl
+	lb bc, PRINTNUM_LEADINGZEROS | 1, 2
+	call PrintNum
+	pop bc
+	ld de, String_AM
+	pop af
+	jr c, .place_am_pm
+	ld de, String_PM
+.place_am_pm
+	inc hl
+	call PlaceString
+	ret
+
+String_AM: db "AM@" ; 1dd6fc
+String_PM: db "PM@" ; 1dd6ff
--- /dev/null
+++ b/engine/routines/returntobattle_useball.asm
@@ -1,0 +1,19 @@
+_ReturnToBattle_UseBall: ; 2715c
+	call ClearBGPalettes
+	call ClearTileMap
+	ld a, [BattleType]
+	cp BATTLETYPE_TUTORIAL
+	jr z, .gettutorialbackpic
+	farcall GetBattleMonBackpic
+	jr .continue
+
+.gettutorialbackpic
+	farcall GetTrainerBackpic
+.continue
+	farcall GetEnemyMonFrontpic
+	farcall _LoadBattleFontsHPBar
+	call GetMemSGBLayout
+	call CloseWindow
+	call LoadStandardMenuDataHeader
+	call WaitBGMap
+	jp SetPalettes
--- /dev/null
+++ b/engine/routines/savemenu_copytilemapatonce.asm
@@ -1,0 +1,77 @@
+SaveMenu_CopyTilemapAtOnce: ; 4cf45 (13:4f45)
+	ld a, [hCGB]
+	and a
+	jp z, WaitBGMap
+
+; The following is a modified version of CopyTilemapAtOnce.
+	ld a, [hBGMapMode]
+	push af
+	xor a
+	ld [hBGMapMode], a
+	ld a, [hMapAnims]
+	push af
+	xor a
+	ld [hMapAnims], a
+.WaitLY:
+	ld a, [rLY]
+	cp $60
+	jr c, .WaitLY
+
+	di
+	ld a, BANK(VBGMap2)
+	ld [rVBK], a
+	hlcoord 0, 0, AttrMap
+	call .CopyTilemapAtOnce
+	ld a, BANK(VBGMap0)
+	ld [rVBK], a
+	hlcoord 0, 0
+	call .CopyTilemapAtOnce
+.WaitLY2:
+	ld a, [rLY]
+	cp $60
+	jr c, .WaitLY2
+	ei
+
+	pop af
+	ld [hMapAnims], a
+	pop af
+	ld [hBGMapMode], a
+	ret
+
+.CopyTilemapAtOnce: ; 4cf80 (13:4f80)
+	ld [hSPBuffer], sp ; $ffd9
+	ld sp, hl
+	ld a, [hBGMapAddress + 1]
+	ld h, a
+	ld l, 0
+	ld a, SCREEN_HEIGHT
+	ld [hTilesPerCycle], a
+	ld b, 1 << 1
+	ld c, rSTAT % $100
+
+.loop
+rept SCREEN_WIDTH / 2
+	pop de
+.loop\@
+	ld a, [$ff00+c]
+	and b
+	jr nz, .loop\@
+	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
--- /dev/null
+++ b/engine/routines/sine.asm
@@ -1,0 +1,50 @@
+_Sine:: ; 84d9
+; A simple sine function.
+; Return d * sin(e) in hl.
+
+; e is a signed 6-bit value.
+	ld a, e
+	and %111111
+	cp  %100000
+	jr nc, .negative
+
+	call .ApplySineWave
+	ld a, h
+	ret
+
+.negative
+	and %011111
+	call .ApplySineWave
+	ld a, h
+	xor -1
+	inc a
+	ret
+
+.ApplySineWave: ; 84ef
+	ld e, a
+	ld a, d
+	ld d, 0
+	ld hl, .sinewave
+	add hl, de
+	add hl, de
+	ld e, [hl]
+	inc hl
+	ld d, [hl]
+	ld hl, 0
+
+; Factor amplitude
+.multiply
+	srl a
+	jr nc, .even
+	add hl, de
+.even
+	sla e
+	rl d
+	and a
+	jr nz, .multiply
+	ret
+
+.sinewave ; 850b
+; A $20-word table representing a sine wave.
+; 90 degrees is index $10 at a base amplitude of $100.
+	sine_wave $100
--- /dev/null
+++ b/engine/routines/switchpartymons.asm
@@ -1,0 +1,145 @@
+_SwitchPartyMons:
+	ld a, [wd0e3]
+	dec a
+	ld [Buffer3], a
+	ld b, a
+	ld a, [wMenuCursorY]
+	dec a
+	ld [Buffer2], a
+	cp b
+	jr z, .skip
+	call .SwapMonAndMail
+	ld a, [Buffer3]
+	call .ClearSprite
+	ld a, [Buffer2]
+	call .ClearSprite
+.skip
+	ret
+
+.ClearSprite: ; 50f34 (14:4f34)
+	push af
+	hlcoord 0, 1
+	ld bc, 2 * SCREEN_WIDTH
+	call AddNTimes
+	ld bc, 2 * SCREEN_WIDTH
+	ld a, " "
+	call ByteFill
+	pop af
+	ld hl, Sprites
+	ld bc, $10
+	call AddNTimes
+	ld de, $4
+	ld c, $4
+.gfx_loop
+	ld [hl], $a0
+	add hl, de
+	dec c
+	jr nz, .gfx_loop
+	ld de, SFX_SWITCH_POKEMON
+	call WaitPlaySFX
+	ret
+
+.SwapMonAndMail: ; 50f62 (14:4f62)
+	push hl
+	push de
+	push bc
+	ld bc, PartySpecies
+	ld a, [Buffer2]
+	ld l, a
+	ld h, $0
+	add hl, bc
+	ld d, h
+	ld e, l
+	ld a, [Buffer3]
+	ld l, a
+	ld h, $0
+	add hl, bc
+	ld a, [hl]
+	push af
+	ld a, [de]
+	ld [hl], a
+	pop af
+	ld [de], a
+	ld a, [Buffer2]
+	ld hl, PartyMon1Species
+	ld bc, PARTYMON_STRUCT_LENGTH
+	call AddNTimes
+	push hl
+	ld de, wd002
+	ld bc, PARTYMON_STRUCT_LENGTH
+	call CopyBytes
+	ld a, [Buffer3]
+	ld hl, PartyMon1
+	ld bc, PARTYMON_STRUCT_LENGTH
+	call AddNTimes
+	pop de
+	push hl
+	ld bc, PARTYMON_STRUCT_LENGTH
+	call CopyBytes
+	pop de
+	ld hl, wd002
+	ld bc, PARTYMON_STRUCT_LENGTH
+	call CopyBytes
+	ld a, [Buffer2]
+	ld hl, PartyMonOT
+	call SkipNames
+	push hl
+	call .CopyNameTowd002
+	ld a, [Buffer3]
+	ld hl, PartyMonOT
+	call SkipNames
+	pop de
+	push hl
+	call .CopyName
+	pop de
+	ld hl, wd002
+	call .CopyName
+	ld hl, PartyMonNicknames
+	ld a, [Buffer2]
+	call SkipNames
+	push hl
+	call .CopyNameTowd002
+	ld hl, PartyMonNicknames
+	ld a, [Buffer3]
+	call SkipNames
+	pop de
+	push hl
+	call .CopyName
+	pop de
+	ld hl, wd002
+	call .CopyName
+	ld hl, sPartyMail
+	ld a, [Buffer2]
+	ld bc, MAIL_STRUCT_LENGTH
+	call AddNTimes
+	push hl
+	ld de, wd002
+	ld bc, MAIL_STRUCT_LENGTH
+	ld a, BANK(sPartyMail)
+	call GetSRAMBank
+	call CopyBytes
+	ld hl, sPartyMail
+	ld a, [Buffer3]
+	ld bc, MAIL_STRUCT_LENGTH
+	call AddNTimes
+	pop de
+	push hl
+	ld bc, MAIL_STRUCT_LENGTH
+	call CopyBytes
+	pop de
+	ld hl, wd002
+	ld bc, MAIL_STRUCT_LENGTH
+	call CopyBytes
+	call CloseSRAM
+	pop bc
+	pop de
+	pop hl
+	ret
+
+.CopyNameTowd002: ; 51036 (14:5036)
+	ld de, wd002
+
+.CopyName: ; 51039 (14:5039)
+	ld bc, NAME_LENGTH
+	call CopyBytes
+	ret
--- /dev/null
+++ b/engine/routines/townmap_convertlinebreakcharacters.asm
@@ -1,0 +1,21 @@
+TownMap_ConvertLineBreakCharacters: ; 1de2c5
+	ld hl, StringBuffer1
+.loop
+	ld a, [hl]
+	cp "@"
+	jr z, .end
+	cp "%"
+	jr z, .line_break
+	cp "¯"
+	jr z, .line_break
+	inc hl
+	jr .loop
+
+.line_break
+	ld [hl], "<LNBRK>"
+
+.end
+	ld de, StringBuffer1
+	hlcoord 9, 0
+	call PlaceString
+	ret
--- /dev/null
+++ b/engine/routines/trademonfrontpic.asm
@@ -1,0 +1,38 @@
+GetTrademonFrontpic: ; 4d7fd
+	ld a, [wOTTrademonSpecies]
+	ld hl, wOTTrademonDVs
+	ld de, VTiles2
+	push de
+	push af
+	predef GetUnownLetter
+	pop af
+	ld [CurPartySpecies], a
+	ld [CurSpecies], a
+	call GetBaseData
+	pop de
+	predef GetAnimatedFrontpicPredef
+	ret
+
+AnimateTrademonFrontpic: ; 4d81e
+	ld a, [wOTTrademonSpecies]
+	call IsAPokemon
+	ret c
+	farcall ShowOTTrademonStats
+	ld a, [wOTTrademonSpecies]
+	ld [CurPartySpecies], a
+	ld a, [wOTTrademonDVs]
+	ld [TempMonDVs], a
+	ld a, [wOTTrademonDVs + 1]
+	ld [TempMonDVs + 1], a
+	ld b, SCGB_PLAYER_OR_MON_FRONTPIC_PALS
+	call GetSGBLayout
+	ld a, %11100100 ; 3,2,1,0
+	call DmgToCgbBGPals
+	farcall TradeAnim_ShowGetmonFrontpic
+	ld a, [wOTTrademonSpecies]
+	ld [CurPartySpecies], a
+	hlcoord 7, 2
+	ld d, $0
+	ld e, ANIM_MON_TRADE
+	predef AnimateFrontpic
+	ret
--- /dev/null
+++ b/engine/routines/updatebattlehuds.asm
@@ -1,0 +1,9 @@
+_UpdateBattleHUDs:
+	farcall DrawPlayerHUD
+	ld hl, PlayerHPPal
+	call SetHPPal
+	farcall DrawEnemyHUD
+	ld hl, EnemyHPPal
+	call SetHPPal
+	farcall FinishBattleAnim
+	ret
--- /dev/null
+++ b/engine/routines/updateitemdescription.asm
@@ -1,0 +1,13 @@
+UpdateItemDescription: ; 0x244c3
+	ld a, [MenuSelection]
+	ld [CurSpecies], a
+	hlcoord 0, 12
+	ld b, 4
+	ld c, SCREEN_WIDTH - 2
+	call TextBox
+	ld a, [MenuSelection]
+	cp -1
+	ret z
+	decoord 1, 14
+	farcall PrintItemDescription
+	ret
--- a/engine/sine.asm
+++ /dev/null
@@ -1,50 +1,0 @@
-_Sine:: ; 84d9
-; A simple sine function.
-; Return d * sin(e) in hl.
-
-; e is a signed 6-bit value.
-	ld a, e
-	and %111111
-	cp  %100000
-	jr nc, .negative
-
-	call .ApplySineWave
-	ld a, h
-	ret
-
-.negative
-	and %011111
-	call .ApplySineWave
-	ld a, h
-	xor -1
-	inc a
-	ret
-
-.ApplySineWave: ; 84ef
-	ld e, a
-	ld a, d
-	ld d, 0
-	ld hl, .sinewave
-	add hl, de
-	add hl, de
-	ld e, [hl]
-	inc hl
-	ld d, [hl]
-	ld hl, 0
-
-; Factor amplitude
-.multiply
-	srl a
-	jr nc, .even
-	add hl, de
-.even
-	sla e
-	rl d
-	and a
-	jr nz, .multiply
-	ret
-
-.sinewave ; 850b
-; A $20-word table representing a sine wave.
-; 90 degrees is index $10 at a base amplitude of $100.
-	sine_wave $100
--- a/engine/slot_machine.asm
+++ b/engine/slot_machine.asm
@@ -471,10 +471,10 @@
 
 Slot_CheckCoinCaseFull: ; 92a04 (24:6a04)
 	ld a, d
-	cp 9999 / $100
+	cp MAX_COINS / $100
 	jr c, .not_full
 	ld a, e
-	cp 9999 % $100
+	cp MAX_COINS % $100
 	jr c, .not_full
 	scf
 	ret
--- a/engine/spawn_points.asm
+++ b/engine/spawn_points.asm
@@ -1,4 +1,3 @@
-
 INCLUDE "data/maps/spawn_points.asm"
 
 
--- a/engine/square_root.asm
+++ /dev/null
@@ -1,30 +1,0 @@
-GetSquareRoot: ; 13b87
-; Return the square root of de in b.
-
-; Rather than calculating the result, we take the index of the
-; first value in a table of squares that isn't lower than de.
-
-	ld hl, Squares
-	ld b, 0
-.loop
-; Make sure we don't go past the end of the table.
-	inc b
-	ld a, b
-	cp $ff
-	ret z
-
-; Iterate over the table until b**2 >= de.
-	ld a, [hli]
-	sub e
-	ld a, [hli]
-	sbc d
-
-	jr c, .loop
-	ret
-
-Squares: ; 13b98
-root	set 1
-	rept $ff
-	dw root*root
-root	set root+1
-	endr
--- a/engine/switch_party_mons.asm
+++ /dev/null
@@ -1,145 +1,0 @@
-_SwitchPartyMons:
-	ld a, [wd0e3]
-	dec a
-	ld [Buffer3], a
-	ld b, a
-	ld a, [wMenuCursorY]
-	dec a
-	ld [Buffer2], a
-	cp b
-	jr z, .skip
-	call .SwapMonAndMail
-	ld a, [Buffer3]
-	call .ClearSprite
-	ld a, [Buffer2]
-	call .ClearSprite
-.skip
-	ret
-
-.ClearSprite: ; 50f34 (14:4f34)
-	push af
-	hlcoord 0, 1
-	ld bc, 2 * SCREEN_WIDTH
-	call AddNTimes
-	ld bc, 2 * SCREEN_WIDTH
-	ld a, " "
-	call ByteFill
-	pop af
-	ld hl, Sprites
-	ld bc, $10
-	call AddNTimes
-	ld de, $4
-	ld c, $4
-.gfx_loop
-	ld [hl], $a0
-	add hl, de
-	dec c
-	jr nz, .gfx_loop
-	ld de, SFX_SWITCH_POKEMON
-	call WaitPlaySFX
-	ret
-
-.SwapMonAndMail: ; 50f62 (14:4f62)
-	push hl
-	push de
-	push bc
-	ld bc, PartySpecies
-	ld a, [Buffer2]
-	ld l, a
-	ld h, $0
-	add hl, bc
-	ld d, h
-	ld e, l
-	ld a, [Buffer3]
-	ld l, a
-	ld h, $0
-	add hl, bc
-	ld a, [hl]
-	push af
-	ld a, [de]
-	ld [hl], a
-	pop af
-	ld [de], a
-	ld a, [Buffer2]
-	ld hl, PartyMon1Species
-	ld bc, PARTYMON_STRUCT_LENGTH
-	call AddNTimes
-	push hl
-	ld de, wd002
-	ld bc, PARTYMON_STRUCT_LENGTH
-	call CopyBytes
-	ld a, [Buffer3]
-	ld hl, PartyMon1
-	ld bc, PARTYMON_STRUCT_LENGTH
-	call AddNTimes
-	pop de
-	push hl
-	ld bc, PARTYMON_STRUCT_LENGTH
-	call CopyBytes
-	pop de
-	ld hl, wd002
-	ld bc, PARTYMON_STRUCT_LENGTH
-	call CopyBytes
-	ld a, [Buffer2]
-	ld hl, PartyMonOT
-	call SkipNames
-	push hl
-	call .CopyNameTowd002
-	ld a, [Buffer3]
-	ld hl, PartyMonOT
-	call SkipNames
-	pop de
-	push hl
-	call .CopyName
-	pop de
-	ld hl, wd002
-	call .CopyName
-	ld hl, PartyMonNicknames
-	ld a, [Buffer2]
-	call SkipNames
-	push hl
-	call .CopyNameTowd002
-	ld hl, PartyMonNicknames
-	ld a, [Buffer3]
-	call SkipNames
-	pop de
-	push hl
-	call .CopyName
-	pop de
-	ld hl, wd002
-	call .CopyName
-	ld hl, sPartyMail
-	ld a, [Buffer2]
-	ld bc, MAIL_STRUCT_LENGTH
-	call AddNTimes
-	push hl
-	ld de, wd002
-	ld bc, MAIL_STRUCT_LENGTH
-	ld a, BANK(sPartyMail)
-	call GetSRAMBank
-	call CopyBytes
-	ld hl, sPartyMail
-	ld a, [Buffer3]
-	ld bc, MAIL_STRUCT_LENGTH
-	call AddNTimes
-	pop de
-	push hl
-	ld bc, MAIL_STRUCT_LENGTH
-	call CopyBytes
-	pop de
-	ld hl, wd002
-	ld bc, MAIL_STRUCT_LENGTH
-	call CopyBytes
-	call CloseSRAM
-	pop bc
-	pop de
-	pop hl
-	ret
-
-.CopyNameTowd002: ; 51036 (14:5036)
-	ld de, wd002
-
-.CopyName: ; 51039 (14:5039)
-	ld bc, NAME_LENGTH
-	call CopyBytes
-	ret
--- a/engine/trademon_frontpic.asm
+++ /dev/null
@@ -1,38 +1,0 @@
-GetTrademonFrontpic: ; 4d7fd
-	ld a, [wOTTrademonSpecies]
-	ld hl, wOTTrademonDVs
-	ld de, VTiles2
-	push de
-	push af
-	predef GetUnownLetter
-	pop af
-	ld [CurPartySpecies], a
-	ld [CurSpecies], a
-	call GetBaseData
-	pop de
-	predef GetAnimatedFrontpicPredef
-	ret
-
-AnimateTrademonFrontpic: ; 4d81e
-	ld a, [wOTTrademonSpecies]
-	call IsAPokemon
-	ret c
-	farcall ShowOTTrademonStats
-	ld a, [wOTTrademonSpecies]
-	ld [CurPartySpecies], a
-	ld a, [wOTTrademonDVs]
-	ld [TempMonDVs], a
-	ld a, [wOTTrademonDVs + 1]
-	ld [TempMonDVs + 1], a
-	ld b, SCGB_PLAYER_OR_MON_FRONTPIC_PALS
-	call GetSGBLayout
-	ld a, %11100100 ; 3,2,1,0
-	call DmgToCgbBGPals
-	farcall TradeAnim_ShowGetmonFrontpic
-	ld a, [wOTTrademonSpecies]
-	ld [CurPartySpecies], a
-	hlcoord 7, 2
-	ld d, $0
-	ld e, ANIM_MON_TRADE
-	predef AnimateFrontpic
-	ret
--- a/engine/unown_dex.asm
+++ b/engine/unown_dex.asm
@@ -48,4 +48,5 @@
 	jr .loop
 ; fba5a (3e:7a5a)
 
+
 INCLUDE "data/unown_words.asm"
--- a/engine/unused_correct_party.asm
+++ /dev/null
@@ -1,229 +1,0 @@
-CorrectErrorsInPlayerParty: ; unreferenced
-	ld hl, PartyCount
-	ld a, [hl]
-	and a
-	ret z
-
-	cp PARTY_LENGTH + 1
-	jr c, .party_length_okay
-	ld a, PARTY_LENGTH
-	ld [hl], a
-.party_length_okay
-	inc hl
-
-	ld b, a
-	ld c, 0
-.loop1
-	ld a, [hl]
-	and a
-	jr z, .invalid_species
-	cp NUM_POKEMON + 1
-	jr z, .invalid_species
-	cp EGG + 1
-	jr c, .next_species
-
-.invalid_species
-	ld [hl], SMEARGLE
-	push hl
-	push bc
-	ld a, c
-	ld hl, PartyMon1Species
-	call GetPartyLocation
-	ld [hl], SMEARGLE
-	pop bc
-	pop hl
-
-.next_species
-	inc hl
-	inc c
-	dec b
-	jr nz, .loop1
-	ld [hl], $ff
-
-	ld hl, PartyMon1
-	ld a, [PartyCount]
-	ld d, a
-	ld e, 0
-.loop2
-	push de
-	push hl
-	ld b, h
-	ld c, l
-	ld a, [hl]
-	and a
-	jr z, .invalid_species_2
-	cp NUM_POKEMON + 1
-	jr c, .check_level
-
-.invalid_species_2
-	ld [hl], SMEARGLE
-	push de
-	ld d, 0
-	ld hl, PartySpecies
-	add hl, de
-	pop de
-	ld a, SMEARGLE
-	ld [hl], a
-
-.check_level
-	ld [CurSpecies], a
-	call GetBaseData
-	ld hl, MON_LEVEL
-	add hl, bc
-	ld a, [hl]
-	cp MIN_LEVEL
-	ld a, MIN_LEVEL
-	jr c, .invalid_level
-	ld a, [hl]
-	cp MAX_LEVEL
-	jr c, .load_level
-	ld a, MAX_LEVEL
-.invalid_level
-	ld [hl], a
-.load_level
-	ld [CurPartyLevel], a
-
-	ld hl, MON_MAXHP
-	add hl, bc
-	ld d, h
-	ld e, l
-	ld hl, MON_STAT_EXP - 1
-	add hl, bc
-	ld b, $1
-	predef CalcPkmnStats
-	pop hl
-	ld bc, PARTYMON_STRUCT_LENGTH
-	add hl, bc
-	pop de
-	inc e
-	dec d
-	jr nz, .loop2
-
-	ld de, PartyMonNicknames
-	ld a, [PartyCount]
-	ld b, a
-	ld c, 0
-.loop3
-	push bc
-	call .GetLengthOfStringWith6CharCap
-	push de
-	farcall CheckStringForErrors
-	pop hl
-	pop bc
-	jr nc, .valid_nickname
-
-	push bc
-	push hl
-	ld hl, PartySpecies
-	push bc
-	ld b, 0
-	add hl, bc
-	pop bc
-	ld a, [hl]
-	cp EGG
-	ld hl, .TAMAGO
-	jr z, .got_nickname
-	ld [wd265], a
-	call GetPokemonName
-	ld hl, StringBuffer1
-.got_nickname
-	pop de
-	ld bc, PKMN_NAME_LENGTH
-	call CopyBytes
-	pop bc
-
-.valid_nickname
-	inc c
-	dec b
-	jr nz, .loop3
-
-	ld de, PartyMonOT
-	ld a, [PartyCount]
-	ld b, a
-	ld c, 0
-.loop4
-	push bc
-	call .GetLengthOfStringWith6CharCap
-	push de
-	farcall CheckStringForErrors
-	pop hl
-	jr nc, .valid_ot_name
-	ld d, h
-	ld e, l
-	ld hl, PlayerName
-	ld bc, NAME_LENGTH
-	call CopyBytes
-.valid_ot_name
-	pop bc
-	inc c
-	dec b
-	jr nz, .loop4
-
-	ld hl, PartyMon1Moves
-	ld a, [PartyCount]
-	ld b, a
-.loop5
-	push hl
-	ld c, NUM_MOVES
-	ld a, [hl]
-	and a
-	jr z, .invalid_move
-	cp NUM_ATTACKS + 1
-	jr c, .moves_loop
-.invalid_move
-	ld [hl], POUND
-
-.moves_loop
-	ld a, [hl]
-	and a
-	jr z, .fill_invalid_moves
-	cp NUM_ATTACKS + 1
-	jr c, .next_move
-
-.fill_invalid_moves
-	xor a
-	ld [hli], a
-	dec c
-	jr nz, .fill_invalid_moves
-	jr .next_pokemon
-
-.next_move
-	inc hl
-	dec c
-	jr nz, .moves_loop
-
-.next_pokemon
-	pop hl
-	push bc
-	ld bc, PARTYMON_STRUCT_LENGTH
-	add hl, bc
-	pop bc
-	dec b
-	jr nz, .loop5
-	ret
-; 13b6b
-
-.TAMAGO: ; 13b6b
-	db "タマゴ@@@"
-; 13b71
-
-.GetLengthOfStringWith6CharCap: ; 13b71
-	push de
-	ld c, 1
-	ld b, NAME_LENGTH_JAPANESE
-.search_loop
-	ld a, [de]
-	cp "@"
-	jr z, .done
-	inc de
-	inc c
-	dec b
-	jr nz, .search_loop
-	dec c
-	dec de
-	ld a, "@"
-	ld [de], a
-.done
-	pop de
-	ret
-; 13b87
--- a/main.asm
+++ b/main.asm
@@ -3,58 +3,13 @@
 
 SECTION "bank1", ROMX
 
-PlaceWaitingText:: ; 4000
-	hlcoord 3, 10
-	ld b, 1
-	ld c, 11
-
-	ld a, [wBattleMode]
-	and a
-	jr z, .notinbattle
-
-	call TextBox
-	jr .proceed
-
-.notinbattle
-	predef Predef_LinkTextbox
-
-.proceed
-	hlcoord 4, 11
-	ld de, .Waiting
-	call PlaceString
-	ld c, 50
-	jp DelayFrames
-
-.Waiting: ; 4025
-	db "Waiting...!@"
-
-LoadPushOAM:: ; 4031
-	ld c, hPushOAM - $ff00
-	ld b, PushOAMEnd - PushOAM
-	ld hl, PushOAM
-.loop
-	ld a, [hli]
-	ld [$ff00+c], a
-	inc c
-	dec b
-	jr nz, .loop
-	ret
-
-PushOAM: ; 403f
-	ld a, Sprites / $100
-	ld [rDMA], a
-	ld a, (SpritesEnd - Sprites) / 4 ; 40
-.loop
-	dec a
-	jr nz, .loop
-	ret
-PushOAMEnd
-
+INCLUDE "engine/routines/placewaitingtext.asm"
+INCLUDE "engine/routines/loadpushoam.asm"
 INCLUDE "engine/map_objects.asm"
 INCLUDE "engine/intro_menu.asm"
 INCLUDE "engine/init_map.asm"
 INCLUDE "engine/learn.asm"
-INCLUDE "engine/check_nick_errors.asm"
+INCLUDE "engine/routines/checknickerrors.asm"
 INCLUDE "engine/math.asm"
 INCLUDE "data/items/item_attributes.asm"
 INCLUDE "engine/npc_movement.asm"
@@ -65,7 +20,7 @@
 SECTION "bank2", ROMX
 
 INCLUDE "engine/player_object.asm"
-INCLUDE "engine/sine.asm"
+INCLUDE "engine/routines/sine.asm"
 INCLUDE "engine/predef.asm"
 INCLUDE "engine/color.asm"
 
@@ -72,7 +27,7 @@
 
 SECTION "bank3", ROMX
 
-INCLUDE "engine/check_time.asm"
+INCLUDE "engine/routines/checktime.asm"
 INCLUDE "engine/specials.asm"
 INCLUDE "engine/printnum.asm"
 INCLUDE "engine/health.asm"
@@ -82,10 +37,11 @@
 INCLUDE "engine/anim_hp_bar.asm"
 INCLUDE "engine/move_mon.asm"
 INCLUDE "engine/billspctop.asm"
-INCLUDE "engine/get_breedmon_growth.asm"
+INCLUDE "engine/routines/getbreedmonlevelgrowth.asm"
 INCLUDE "event/bug_contest/caught_mon.asm"
 INCLUDE "engine/item_effects.asm"
-INCLUDE "engine/knows_move.asm"
+INCLUDE "engine/routines/getpokeballwobble.asm"
+INCLUDE "engine/routines/knowsmove.asm"
 
 
 SECTION "bank4", ROMX
@@ -106,10 +62,10 @@
 INCLUDE "event/misc_scripts_2.asm"
 INCLUDE "event/std_collision.asm"
 INCLUDE "event/bug_contest/judging.asm"
-INCLUDE "engine/pokerus_tick.asm"
+INCLUDE "engine/routines/applypokerustick.asm"
 INCLUDE "event/bug_contest/contest_2.asm"
-INCLUDE "engine/unused_correct_party.asm"
-INCLUDE "engine/square_root.asm"
+INCLUDE "engine/routines/correcterrorsinplayerparty.asm"
+INCLUDE "engine/routines/getsquareroot.asm"
 
 
 SECTION "bank5", ROMX
@@ -141,21 +97,7 @@
 
 INCLUDE "data/text_buffers.asm"
 INCLUDE "engine/menu.asm"
-
-UpdateItemDescription: ; 0x244c3
-	ld a, [MenuSelection]
-	ld [CurSpecies], a
-	hlcoord 0, 12
-	ld b, 4
-	ld c, SCREEN_WIDTH - 2
-	call TextBox
-	ld a, [MenuSelection]
-	cp -1
-	ret z
-	decoord 1, 14
-	farcall PrintItemDescription
-	ret
-
+INCLUDE "engine/routines/updateitemdescription.asm"
 INCLUDE "engine/pokepic.asm"
 INCLUDE "engine/map_objects_2.asm"
 INCLUDE "engine/scrolling_menu.asm"
@@ -167,68 +109,28 @@
 INCLUDE "engine/trainer_card.asm"
 INCLUDE "engine/prof_oaks_pc.asm"
 INCLUDE "engine/decorations.asm"
-
-LevelUpHappinessMod: ; 2709e
-	ld a, [CurPartyMon]
-	ld hl, PartyMon1CaughtLocation
-	call GetPartyLocation
-	ld a, [hl]
-	and $7f
-	ld d, a
-	ld a, [MapGroup]
-	ld b, a
-	ld a, [MapNumber]
-	ld c, a
-	call GetWorldMapLocation
-	cp d
-	ld c, HAPPINESS_GAINLEVEL
-	jr nz, .ok
-	ld c, HAPPINESS_GAINLEVELATHOME
-
-.ok
-	callfar ChangeHappiness
-	ret
-
+INCLUDE "engine/routines/leveluphappinessmod.asm"
 INCLUDE "data/trainers/trainer_dvs.asm"
-
-_ReturnToBattle_UseBall: ; 2715c
-	call ClearBGPalettes
-	call ClearTileMap
-	ld a, [BattleType]
-	cp BATTLETYPE_TUTORIAL
-	jr z, .gettutorialbackpic
-	farcall GetBattleMonBackpic
-	jr .continue
-
-.gettutorialbackpic
-	farcall GetTrainerBackpic
-.continue
-	farcall GetEnemyMonFrontpic
-	farcall _LoadBattleFontsHPBar
-	call GetMemSGBLayout
-	call CloseWindow
-	call LoadStandardMenuDataHeader
-	call WaitBGMap
-	jp SetPalettes
-
-INCLUDE "engine/consume_held_item.asm"
+INCLUDE "engine/routines/returntobattle_useball.asm"
+INCLUDE "engine/routines/consumehelditem.asm"
 INCLUDE "battle/moves/move_effects_pointers.asm"
 INCLUDE "battle/moves/move_effects.asm"
+INCLUDE "engine/routines/kurt_selectquantity_interpretjoypad.asm"
 
-Kurt_SelectQuantity_InterpretJoypad: ; 27a28
-	call BuySellToss_InterpretJoypad
-	ld b, a
-	ret
 
-
 SECTION "bankA", ROMX
 
 INCLUDE "engine/link.asm"
 INCLUDE "engine/wildmons.asm"
 INCLUDE "battle/link_result.asm"
-INCLUDE "engine/player_gfx_2.asm"
 
+ChrisBackpic: ; 2ba1a
+INCBIN "gfx/player/chris_back.2bpp.lz"
 
+DudeBackpic: ; 2bbaa
+INCBIN "gfx/battle/dude.2bpp.lz"
+
+
 SECTION "bankB", ROMX
 
 INCLUDE "battle/trainer_huds.asm"
@@ -240,7 +142,7 @@
 INCLUDE "battle/moves/move_descriptions.asm"
 INCLUDE "engine/pokerus.asm"
 INCLUDE "engine/start_battle.asm"
-INCLUDE "engine/place_graphics.asm"
+INCLUDE "engine/routines/placegraphic.asm"
 
 
 SECTION "Effect Commands", ROMX
@@ -284,7 +186,7 @@
 SECTION "Crystal Unique", ROMX
 
 INCLUDE "engine/init_gender.asm"
-INCLUDE "engine/pack_f.asm"
+INCLUDE "engine/routines/drawkrispackgfx.asm"
 INCLUDE "event/move_tutor.asm"
 INCLUDE "engine/crystal_colors.asm"
 INCLUDE "event/celebi.asm"
@@ -300,7 +202,8 @@
 INCLUDE "engine/map_palettes.asm"
 INCLUDE "tilesets/palette_maps.asm"
 
-Unknown_4ce05: ; unreferenced
+; unreferenced
+; 0x4ce05
 rept 26
 	db $06
 endr
@@ -307,227 +210,13 @@
 ; 0x4ce1f
 
 INCLUDE "data/collision_permissions.asm"
-INCLUDE "engine/empty_sram.asm"
-
-SaveMenu_CopyTilemapAtOnce: ; 4cf45 (13:4f45)
-	ld a, [hCGB]
-	and a
-	jp z, WaitBGMap
-
-; The following is a modified version of CopyTilemapAtOnce.
-	ld a, [hBGMapMode]
-	push af
-	xor a
-	ld [hBGMapMode], a
-	ld a, [hMapAnims]
-	push af
-	xor a
-	ld [hMapAnims], a
-.WaitLY:
-	ld a, [rLY]
-	cp $60
-	jr c, .WaitLY
-
-	di
-	ld a, BANK(VBGMap2)
-	ld [rVBK], a
-	hlcoord 0, 0, AttrMap
-	call .CopyTilemapAtOnce
-	ld a, BANK(VBGMap0)
-	ld [rVBK], a
-	hlcoord 0, 0
-	call .CopyTilemapAtOnce
-.WaitLY2:
-	ld a, [rLY]
-	cp $60
-	jr c, .WaitLY2
-	ei
-
-	pop af
-	ld [hMapAnims], a
-	pop af
-	ld [hBGMapMode], a
-	ret
-
-.CopyTilemapAtOnce: ; 4cf80 (13:4f80)
-	ld [hSPBuffer], sp ; $ffd9
-	ld sp, hl
-	ld a, [hBGMapAddress + 1]
-	ld h, a
-	ld l, 0
-	ld a, SCREEN_HEIGHT
-	ld [hTilesPerCycle], a
-	ld b, 1 << 1
-	ld c, rSTAT % $100
-
-.loop
-rept SCREEN_WIDTH / 2
-	pop de
-.loop\@
-	ld a, [$ff00+c]
-	and b
-	jr nz, .loop\@
-	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
-
-CheckSave:: ; 4cffe
-	ld a, BANK(sCheckValue1) ; BANK(sCheckValue2)
-	call GetSRAMBank
-	ld a, [sCheckValue1]
-	ld b, a
-	ld a, [sCheckValue2]
-	ld c, a
-	call CloseSRAM
-	ld a, b
-	cp SAVE_CHECK_VALUE_1
-	jr nz, .ok
-	ld a, c
-	cp SAVE_CHECK_VALUE_2
-	jr nz, .ok
-	ld c, $1
-	ret
-
-.ok
-	ld c, $0
-	ret
-
+INCLUDE "engine/routines/emptyallsrambanks.asm"
+INCLUDE "engine/routines/savemenu_copytilemapatonce.asm"
+INCLUDE "engine/routines/checksave.asm"
 INCLUDE "data/maps/map_scenes.asm"
+INCLUDE "engine/routines/loadmappart.asm"
+INCLUDE "engine/routines/phonering_copytilemapatonce.asm"
 
-_LoadMapPart:: ; 4d15b
-	ld hl, wMisc
-	ld a, [wMetatileStandingY]
-	and a
-	jr z, .top_row
-	ld bc, WMISC_WIDTH * 2
-	add hl, bc
-
-.top_row
-	ld a, [wMetatileStandingX]
-	and a
-	jr z, .left_column
-	inc hl
-	inc hl
-
-.left_column
-	decoord 0, 0
-	ld b, SCREEN_HEIGHT
-.loop
-	ld c, SCREEN_WIDTH
-.loop2
-	ld a, [hli]
-	ld [de], a
-	inc de
-	dec c
-	jr nz, .loop2
-	ld a, l
-	add 4
-	ld l, a
-	jr nc, .carry
-	inc h
-
-.carry
-	dec b
-	jr nz, .loop
-	ret
-
-PhoneRing_CopyTilemapAtOnce: ; 4d188
-	ld a, [hCGB]
-	and a
-	jp z, WaitBGMap
-	ld a, [wSpriteUpdatesEnabled]
-	cp $0
-	jp z, WaitBGMap
-
-; What follows is a modified version of CopyTilemapAtOnce.
-	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 $8f
-	jr c, .wait
-
-	di
-	ld a, BANK(VBGMap2)
-	ld [rVBK], a
-	hlcoord 0, 0, AttrMap
-	call .CopyTilemapAtOnce
-	ld a, BANK(VBGMap0)
-	ld [rVBK], a
-	hlcoord 0, 0
-	call .CopyTilemapAtOnce
-.wait2
-	ld a, [rLY]
-	cp $8f
-	jr c, .wait2
-	ei
-
-	pop af
-	ld [hMapAnims], a
-	pop af
-	ld [hBGMapMode], a
-	ret
-
-.CopyTilemapAtOnce: ; 4d1cb
-	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, rSTAT % $100
-
-.loop
-rept SCREEN_WIDTH / 2
-	pop de
-.loop\@
-	ld a, [$ff00+c]
-	and b
-	jr nz, .loop\@
-	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
-
 Shrink1Pic: ; 4d249
 INCBIN "gfx/shrink/shrink1.2bpp.lz"
 
@@ -534,129 +223,12 @@
 Shrink2Pic: ; 4d2d9
 INCBIN "gfx/shrink/shrink2.2bpp.lz"
 
-LinkMonStatsScreen: ; 4d319
-	ld a, [wMenuCursorY]
-	dec a
-	ld [CurPartyMon], a
-	call LowVolume
-	predef StatsScreenInit
-	ld a, [CurPartyMon]
-	inc a
-	ld [wMenuCursorY], a
-	call ClearScreen
-	call ClearBGPalettes
-	call MaxVolume
-	farcall LoadTradeScreenBorder
-	farcall Link_WaitBGMap
-	farcall InitTradeSpeciesList
-	farcall SetTradeRoomBGPals
-	call WaitBGMap2
-	ret
-
-Link_WaitBGMap: ; 4d354
-	call WaitBGMap
-	call WaitBGMap2
-	ret
-
-LinkTextbox2: ; 4d35b
-	ld h, d
-	ld l, e
-	push bc
-	push hl
-	call .PlaceBorder
-	pop hl
-	pop bc
-	ld de, AttrMap - TileMap
-	add hl, de
-	inc b
-	inc b
-	inc c
-	inc c
-	ld a, $7
-.row
-	push bc
-	push hl
-.col
-	ld [hli], a
-	dec c
-	jr nz, .col
-	pop hl
-	ld de, SCREEN_WIDTH
-	add hl, de
-	pop bc
-	dec b
-	jr nz, .row
-	ret
-
-.PlaceBorder: ; 4d37e
-	push hl
-	ld a, $76
-	ld [hli], a
-	inc a
-	call .PlaceRow
-	inc a
-	ld [hl], a
-	pop hl
-	ld de, SCREEN_WIDTH
-	add hl, de
-.loop
-	push hl
-	ld a, "┌"
-	ld [hli], a
-	ld a, " "
-	call .PlaceRow
-	ld [hl], "─"
-	pop hl
-	ld de, SCREEN_WIDTH
-	add hl, de
-	dec b
-	jr nz, .loop
-	ld a, "┐"
-	ld [hli], a
-	ld a, "│"
-	call .PlaceRow
-	ld [hl], "└"
-	ret
-
-.PlaceRow: ; 4d3ab
-	ld d, c
-.row_loop
-	ld [hli], a
-	dec d
-	jr nz, .row_loop
-	ret
-
+INCLUDE "engine/link_2.asm"
 INCLUDE "engine/delete_save_change_clock.asm"
 INCLUDE "tilesets/tileset_headers.asm"
-INCLUDE "engine/flag_predef.asm"
-INCLUDE "engine/trademon_frontpic.asm"
-
-CheckPokerus: ; 4d860
-; Return carry if a monster in your party has Pokerus
-
-; Get number of monsters to iterate over
-	ld a, [PartyCount]
-	and a
-	jr z, .NoPokerus
-	ld b, a
-; Check each monster in the party for Pokerus
-	ld hl, PartyMon1PokerusStatus
-	ld de, PARTYMON_STRUCT_LENGTH
-.Check:
-	ld a, [hl]
-	and $0f ; only the bottom nybble is used
-	jr nz, .HasPokerus
-; Next PartyMon
-	add hl, de
-	dec b
-	jr nz, .Check
-.NoPokerus:
-	and a
-	ret
-.HasPokerus:
-	scf
-	ret
-
+INCLUDE "engine/routines/flagpredef.asm"
+INCLUDE "engine/routines/trademonfrontpic.asm"
+INCLUDE "engine/routines/checkpokerus.asm"
 INCLUDE "event/lucky_number.asm"
 INCLUDE "engine/caught_data.asm"
 INCLUDE "engine/search2.asm"
@@ -667,7 +239,7 @@
 INCLUDE "mobile/get_trainer_class.asm"
 INCLUDE "battle/sliding_intro.asm"
 INCLUDE "mobile/print_opp_message.asm"
-INCLUDE "engine/check_battle_scene.asm"
+INCLUDE "engine/routines/checkbattlescene.asm"
 INCLUDE "engine/gbc_only.asm"
 INCLUDE "event/poke_seer.asm"
 
@@ -685,9 +257,9 @@
 INCLUDE "text/types.asm"
 INCLUDE "text/unused_gen_1_trainers.asm"
 INCLUDE "engine/mon_stats.asm"
-INCLUDE "engine/init_list.asm"
+INCLUDE "engine/routines/initlist.asm"
 INCLUDE "engine/experience.asm"
-INCLUDE "engine/switch_party_mons.asm"
+INCLUDE "engine/routines/switchpartymons.asm"
 INCLUDE "gfx/load_pics.asm"
 INCLUDE "engine/move_mon_wo_mail.asm"
 INCLUDE "data/pokemon/base_stats.asm"
@@ -751,11 +323,7 @@
 INCLUDE "engine/battle_transition.asm"
 INCLUDE "event/field_moves.asm"
 INCLUDE "event/magnet_train.asm"
-
-BattleStart_CopyTilemapAtOnce: ; 8cf4f
-	call CGBOnly_CopyTilemapAtOnce
-	ret
-
+INCLUDE "engine/routines/battlestart_copytilemapatonce.asm"
 INCLUDE "engine/sprites.asm"
 INCLUDE "engine/mon_icons.asm"
 
@@ -897,8 +465,8 @@
 INCLUDE "gfx/font.asm"
 INCLUDE "engine/time_capsule.asm"
 INCLUDE "event/name_rater.asm"
-INCLUDE "engine/play_slow_cry.asm"
-INCLUDE "engine/new_pokedex_entry.asm"
+INCLUDE "engine/routines/playslowcry.asm"
+INCLUDE "engine/routines/newpokedexentry.asm"
 INCLUDE "engine/time_capsule_2.asm"
 INCLUDE "engine/unown_dex.asm"
 INCLUDE "event/magikarp.asm"
@@ -973,15 +541,7 @@
 
 SECTION "bank5E", ROMX
 
-_UpdateBattleHUDs:
-	farcall DrawPlayerHUD
-	ld hl, PlayerHPPal
-	call SetHPPal
-	farcall DrawEnemyHUD
-	ld hl, EnemyHPPal
-	call SetHPPal
-	farcall FinishBattleAnim
-	ret
+INCLUDE "engine/routines/updatebattlehuds.asm"
 
 
 SECTION "mobile_5e", ROMX
@@ -1036,11 +596,15 @@
 
 SECTION "bank77_2", ROMX
 
-INCLUDE "engine/printhoursmins.asm"
+INCLUDE "engine/routines/printhoursmins.asm"
 INCLUDE "engine/diploma.asm"
 INCLUDE "engine/pokedex_3.asm"
 INCLUDE "event/catch_tutorial_input.asm"
-INCLUDE "engine/pokegear_2.asm"
+INCLUDE "engine/routines/townmap_convertlinebreakcharacters.asm"
+
+PokegearGFX: ; 1de2e4
+INCBIN "gfx/pokegear/pokegear.2bpp.lz"
+
 INCLUDE "engine/european_mail.asm"