summaryrefslogtreecommitdiff
path: root/home.asm
diff options
context:
space:
mode:
Diffstat (limited to 'home.asm')
-rw-r--r--home.asm3400
1 files changed, 3400 insertions, 0 deletions
diff --git a/home.asm b/home.asm
new file mode 100644
index 000000000..79be98470
--- /dev/null
+++ b/home.asm
@@ -0,0 +1,3400 @@
+INCLUDE "includes.asm"
+
+
+SECTION "Hardware", ROM0
+
+INCLUDE "rst.asm"
+INCLUDE "interrupts.asm"
+
+
+SECTION "Header", ROM0[$100]
+
+Start:
+ nop
+ jp _Start
+
+
+SECTION "Home", ROM0[$150]
+
+INCLUDE "home/init.asm"
+INCLUDE "home/vblank.asm"
+INCLUDE "home/delay.asm"
+INCLUDE "home/rtc.asm"
+INCLUDE "home/fade.asm"
+INCLUDE "home/lcd.asm"
+INCLUDE "home/time.asm"
+INCLUDE "home/serial.asm"
+INCLUDE "home/joypad.asm"
+INCLUDE "home/decompress.asm"
+INCLUDE "home/palettes.asm"
+INCLUDE "home/copy.asm"
+INCLUDE "home/text.asm"
+INCLUDE "home/video.asm"
+INCLUDE "home/map_objects.asm"
+INCLUDE "home/sine.asm"
+INCLUDE "home/movement.asm"
+INCLUDE "home/tilemap.asm"
+INCLUDE "home/menu.asm"
+INCLUDE "home/handshake.asm"
+INCLUDE "home/game_time.asm"
+INCLUDE "home/map.asm"
+
+
+Function2d43: ; 2d43
+; Inexplicably empty.
+; Seen in PredefPointers.
+ rept 16
+ nop
+ endr
+ ret
+; 2d54
+
+
+INCLUDE "home/farcall.asm"
+INCLUDE "home/predef.asm"
+INCLUDE "home/window.asm"
+
+
+Function2e4e: ; 2e4e
+ scf
+ ret
+; 2e50
+
+
+INCLUDE "home/flag.asm"
+
+
+Function2ebb: ; 2ebb
+ ld a, [$c2cc]
+ bit 1, a
+ ret z
+ ld a, [hJoyDown]
+ bit A_BUTTON, a
+ ret
+; 2ec6
+
+
+Function2ec6: ; 2ec6
+ xor a
+ ret
+; 2ec8
+
+Function2ec8: ; 2ec8
+ xor a
+ dec a
+ ret
+; 2ecb
+
+Function2ecb: ; 2ecb
+ push hl
+ ld hl, $c2cc
+ bit 1, [hl]
+ pop hl
+ ret
+; 2ed3
+
+
+Function2ed3: ; 0x2ed3
+; disables overworld sprite updating?
+ xor a
+ ld [$ffde], a
+ ld a, [VramState]
+ res 0, a
+ ld [VramState], a
+ ld a, $0
+ ld [$c2ce], a
+ ret
+; 0x2ee4
+
+Function2ee4: ; 2ee4
+ ld a, $1
+ ld [$c2ce], a
+ ld a, [VramState]
+ set 0, a
+ ld [VramState], a
+ ld a, $1
+ ld [$ffde], a
+ ret
+; 2ef6
+
+
+INCLUDE "home/string.asm"
+
+
+IsInJohto: ; 2f17
+; Return 0 if the player is in Johto, and 1 in Kanto.
+
+ ld a, [MapGroup]
+ ld b, a
+ ld a, [MapNumber]
+ ld c, a
+ call GetWorldMapLocation
+
+ cp FAST_SHIP
+ jr z, .Johto
+
+ cp SPECIAL_MAP
+ jr nz, .CheckRegion
+
+ ld a, [BackupMapGroup]
+ ld b, a
+ ld a, [BackupMapNumber]
+ ld c, a
+ call GetWorldMapLocation
+
+.CheckRegion
+ cp KANTO_LANDMARK
+ jr nc, .Kanto
+
+.Johto
+ xor a
+ ret
+
+.Kanto
+ ld a, 1
+ ret
+; 2f3e
+
+
+Function2f3e: ; 2f3e
+ ret
+; 2f3f
+
+
+INCLUDE "home/item.asm"
+INCLUDE "home/random.asm"
+INCLUDE "home/sram.asm"
+
+
+; Register aliases
+
+_hl_: ; 2fec
+ jp [hl]
+; 2fed
+
+_de_: ; 2fed
+ push de
+ ret
+; 2fef
+
+
+INCLUDE "home/double_speed.asm"
+
+
+ClearSprites: ; 300b
+; Erase OAM data
+ ld hl, Sprites
+ ld b, SpritesEnd - Sprites
+ 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, Sprites
+ ld de, 4 ; length of an OAM struct
+ ld b, (SpritesEnd - Sprites) / 4 ; number of OAM structs
+ ld a, 160 ; y
+.loop
+ ld [hl], a
+ add hl, de
+ dec b
+ jr nz, .loop
+ ret
+; 3026
+
+
+INCLUDE "home/copy2.asm"
+
+
+Function309d: ; 309d
+ ld a, [rSVBK]
+ push af
+ ld a, 2
+ ld [rSVBK], a
+ ld hl, TileMap
+ ld de, $d000
+ ld bc, 360
+ call CopyBytes
+ pop af
+ ld [rSVBK], a
+ ret
+; 30b4
+
+Function30b4: ; 30b4
+ xor a
+ ld [hBGMapMode], a
+ call Function30bf
+ ld a, 1
+ ld [hBGMapMode], a
+ ret
+; 30bf
+
+Function30bf: ; 30bf
+ ld a, [rSVBK]
+ push af
+ ld a, 2
+ ld [rSVBK], a
+ ld hl, $d000
+ ld de, TileMap
+ ld bc, 360
+ call CopyBytes
+ pop af
+ ld [rSVBK], a
+ ret
+; 30d6
+
+
+CopyName1: ; 30d6
+ ld hl, StringBuffer2
+
+CopyName2: ; 30d9
+.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.
+
+ ld b, 0
+ ld c, a
+.loop
+ ld a, [hl]
+ cp $ff
+ jr z, .NotInArray
+ cp c
+ jr z, .InArray
+ inc b
+ add hl, de
+ jr .loop
+
+.NotInArray
+ and a
+ ret
+
+.InArray
+ scf
+ ret
+; 30f4
+
+SkipNames: ; 0x30f4
+; skips n names where n = a
+ ld bc, $000b ; name length
+ and a
+ ret z
+.loop
+ add hl, bc
+ dec a
+ jr nz, .loop
+ ret
+; 0x30fe
+
+AddNTimes: ; 0x30fe
+; adds bc n times where n = a
+ and a
+ ret z
+.loop
+ add hl, bc
+ dec a
+ jr nz, .loop
+ ret
+; 0x3105
+
+
+INCLUDE "home/math.asm"
+
+
+PrintLetterDelay: ; 313d
+; Wait before printing the next letter.
+
+; The text speed setting in Options is actually a frame count:
+; fast: 1 frame
+; mid: 3 frames
+; slow: 5 frames
+
+; $cfcf[!0] and A or B override text speed with a one-frame delay.
+; Options[4] and $cfcf[!1] disable the delay.
+
+; delay off?
+ ld a, [Options]
+ bit 4, a
+ ret nz
+
+; non-scrolling text?
+ ld a, [$cfcf]
+ bit 1, 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, [$cfcf]
+ bit 0, a
+ jr z, .fast
+
+; text speed
+ ld a, [Options]
+ and %111
+ jr .updatedelay
+
+.fast
+ ld a, 1
+
+.updatedelay
+ ld [TextDelayFrames], a
+
+.checkjoypad
+ call GetJoypadPublic
+
+; input override
+ ld a, [$c2d7]
+ and a
+ jr nz, .wait
+
+; Wait one frame if holding A or B.
+ ld a, [hJoyDown]
+ bit 0, a ; A_BUTTON
+ jr z, .checkb
+ jr .delay
+.checkb
+ bit 1, a ; B_BUTTON
+ jr z, .wait
+
+.delay
+ call DelayFrame
+ jr .end
+
+.wait
+ ld a, [TextDelayFrames]
+ 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 .. de + bc - hl).
+
+; 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
+ ld a, [hROMBank]
+ push af
+ ld a, BANK(_PrintNum)
+ rst Bankswitch
+
+ call _PrintNum
+
+ pop af
+ rst Bankswitch
+ ret
+; 31a4
+
+
+Function31a4: ; 31a4
+ ld a, [hROMBank]
+ push af
+ ld a, BANK(Function1061ef)
+ rst Bankswitch
+
+ call Function1061ef
+
+ pop af
+ rst Bankswitch
+ 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
+ ld a, [hli]
+ rst Bankswitch
+
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+
+ call _hl_
+
+ pop hl
+ ld a, h
+ rst Bankswitch
+ ret
+; 31cd
+
+
+Function31cd: ; 31cd
+; Push pointer hl in the current bank to $d0e8.
+ ld a, [hROMBank]
+
+Function31cf: ; 31cf
+; Push pointer a:hl to $d0e8.
+ ld [$d0e8], a
+ ld a, l
+ ld [$d0e9], a
+ ld a, h
+ ld [$d0ea], a
+ ret
+; 31db
+
+
+StringCmp: ; 31db
+; Compare c bytes at de and hl.
+; Return z if they all match.
+ ld a, [de]
+ cp [hl]
+ ret nz
+ inc de
+ inc hl
+ dec c
+ jr nz, StringCmp
+ ret
+; 0x31e4
+
+
+CompareLong: ; 31e4
+; Compare bc bytes at de and hl.
+; Return carry if they all match.
+
+ ld a, [de]
+ cp [hl]
+ jr nz, .Diff
+
+ inc de
+ inc hl
+ dec bc
+
+ ld a, b
+ or c
+ jr nz, CompareLong
+
+ scf
+ ret
+
+.Diff
+ and a
+ ret
+; 31f3
+
+
+WhiteBGMap: ; 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
+
+Function3200: ; 0x3200
+ ld a, [hCGB]
+ and a
+ jr z, .asm_320e
+ ld a, 2
+ ld [hBGMapMode], a
+ ld c, 4
+ call DelayFrames
+
+.asm_320e
+ ld a, 1
+ ld [hBGMapMode], a
+ ld c, 4
+ call DelayFrames
+ ret
+; 0x3218
+
+
+Function3218: ; 3218
+ ld a, [hCGB]
+ and a
+ ret
+; 321c
+
+
+Function321c: ; 321c
+ ld a, [hCGB]
+ and a
+ jr z, .asm_322e
+
+ ld a, [$c2ce]
+ cp 0
+ jr z, .asm_322e
+
+ ld a, 1
+ ld [hBGMapMode], a
+ jr Function323d
+
+.asm_322e
+ ld a, 1
+ ld [hBGMapMode], a
+ ld c, 4
+ call DelayFrames
+ ret
+; 3238
+
+Function3238: ; 3238
+ ld a, [hCGB]
+ and a
+ jr z, WaitBGMap
+
+Function323d: ; 323d
+ jr Function3246
+; 323f
+
+Function323f: ; 323f
+ callba Function104000
+ ret
+; 3246
+
+Function3246: ; 3246
+ ld a, [hBGMapMode]
+ push af
+ xor a
+ ld [hBGMapMode], a
+ ld a, [$ffde]
+ push af
+ xor a
+ ld [$ffde], a
+.asm_3252
+ ld a, [rLY]
+ cp $7f
+ jr c, .asm_3252 ; 3256 $fa
+ di
+ ld a, $1
+ ld [rVBK], a
+ ld hl, AttrMap
+ call Function327b
+ ld a, $0
+ ld [rVBK], a
+ ld hl, TileMap
+ call Function327b
+.asm_326d
+ ld a, [rLY]
+ cp $7f
+ jr c, .asm_326d ; 3271 $fa
+ ei
+ pop af
+ ld [$ffde], a
+ pop af
+ ld [hBGMapMode], a
+ ret
+; 327b
+
+Function327b: ; 327b
+ ld [hSPBuffer], sp
+ ld sp, hl
+ ld a, [$ffd7]
+ ld h, a
+ ld l, $0
+ ld a, $12
+ ld [$ffd3], a
+ ld b, $2
+ ld c, $41
+.asm_328c
+ pop de
+
+rept 9
+.loop\@
+ ld a, [$ff00+c]
+ and b
+ jr nz, .loop\@
+ ld [hl], e
+ inc l
+ ld [hl], d
+ inc l
+ pop de
+endr
+
+.asm_32de
+ ld a, [$ff00+c]
+ and b
+ jr nz, .asm_32de
+ ld [hl], e
+ inc l
+ ld [hl], d
+ inc l
+
+ ld de, $000c
+ add hl, de
+ ld a, [$ffd3]
+ dec a
+ ld [$ffd3], a
+ jr nz, .asm_328c
+ ld a, [hSPBuffer]
+ ld l, a
+ ld a, [$ffda]
+ ld h, a
+ ld sp, hl
+ ret
+; 32f9
+
+
+
+Function32f9: ; 32f9
+ ld a, [hCGB]
+ and a
+ jr nz, .asm_3309
+ ld a, $e4
+ ld [rBGP], a
+ ld a, $d0
+ ld [rOBP0], a
+ ld [rOBP1], a
+ ret
+
+.asm_3309
+ push de
+ ld a, $e4
+ call DmgToCgbBGPals
+ ld de, $e4e4
+ 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, 5
+ ld [rSVBK], a
+
+; Fill BGPals and OBPals with $ffff (white)
+ ld hl, BGPals
+ ld bc, $80
+ ld a, $ff
+ call ByteFill
+
+ pop af
+ ld [rSVBK], a
+
+; Request palette update
+ ld a, 1
+ ld [hCGBPalUpdate], a
+ ret
+; 333e
+
+
+ClearSGB: ; 333e
+ ld b, $ff
+
+GetSGBLayout: ; 3340
+; load sgb packets unless dmg
+
+ ld a, [hCGB]
+ and a
+ jr nz, .dosgb
+
+ ld a, [hSGB]
+ and a
+ ret z
+
+.dosgb
+ ld a, $31 ; LoadSGBLayout
+ jp Predef
+; 334e
+
+
+SetHPPal: ; 334e
+; Set palette for hp bar pixel length e at hl.
+ call GetHPPal
+ ld [hl], d
+ ret
+; 3353
+
+
+GetHPPal: ; 3353
+; Get palette for hp bar pixel length e in d.
+
+ ld d, 0 ; green
+ ld a, e
+ cp 24
+ ret nc
+ inc d ; yellow
+ cp 10
+ ret nc
+ inc d ; red
+ ret
+; 335f
+
+
+CountSetBits: ; 0x335f
+; Count the number of set bits in b bytes starting from hl.
+; Return in a, c and [$d265].
+
+ ld c, 0
+.next
+ ld a, [hli]
+ ld e, a
+ ld d, 8
+
+.count
+ srl e
+ ld a, 0
+ adc c
+ ld c, a
+ dec d
+ jr nz, .count
+
+ dec b
+ jr nz, .next
+
+ ld a, c
+ ld [$d265], a
+ ret
+; 0x3376
+
+
+GetWeekday: ; 3376
+ ld a, [CurDay]
+.mod
+ sub 7
+ jr nc, .mod
+ add 7
+ ret
+; 3380
+
+
+INCLUDE "home/pokedex_flags.asm"
+
+
+NamesPointers: ; 33ab
+ dbw BANK(PokemonNames), PokemonNames
+ dbw BANK(MoveNames), MoveNames
+ dbw 0, 0
+ dbw BANK(ItemNames), ItemNames
+ dbw 0, PartyMonOT
+ dbw 0, OTPartyMonOT
+ dbw BANK(TrainerClassNames), TrainerClassNames
+ dbw $04, $4b52 ; ????
+; 33c3
+
+
+GetName: ; 33c3
+; Return name CurSpecies from name list $cf61 in StringBuffer1.
+
+ ld a, [hROMBank]
+ push af
+ push hl
+ push bc
+ push de
+
+ ld a, [$cf61]
+ cp 1 ; Pokemon names
+ jr nz, .NotPokeName
+
+ ld a, [CurSpecies]
+ ld [$d265], a
+ call GetPokemonName
+ ld hl, 11
+ add hl, de
+ ld e, l
+ ld d, h
+ jr .done
+
+.NotPokeName
+ ld a, [$cf61]
+ dec a
+ ld e, a
+ ld d, 0
+ ld hl, NamesPointers
+ add hl, de
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ rst Bankswitch
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+
+ ld a, [CurSpecies]
+ dec a
+ call GetNthString
+
+ ld de, StringBuffer1
+ ld bc, $000d
+ call CopyBytes
+
+.done
+ ld a, e
+ ld [$d102], a
+ ld a, d
+ ld [$d103], a
+
+ pop de
+ pop bc
+ pop hl
+ pop af
+ rst Bankswitch
+ ret
+; 3411
+
+
+GetNthString: ; 3411
+; Return the address of the
+; ath string starting from hl.
+
+ and a
+ ret z
+
+ push bc
+ ld b, a
+ ld c, "@"
+.readChar
+ ld a, [hli]
+ cp c
+ jr nz, .readChar
+ dec b
+ jr nz, .readChar
+ pop bc
+ ret
+; 3420
+
+
+GetBasePokemonName: ; 3420
+; Discards gender (Nidoran).
+
+ push hl
+ call GetPokemonName
+
+ ld hl, StringBuffer1
+.loop
+ ld a, [hl]
+ cp "@"
+ jr z, .quit
+ cp "♂"
+ jr z, .end
+ cp "♀"
+ jr z, .end
+ inc hl
+ jr .loop
+.end
+ ld [hl], "@"
+.quit
+ pop hl
+ ret
+
+; 343b
+
+
+GetPokemonName: ; 343b
+; Get Pokemon name $d265.
+
+ ld a, [hROMBank]
+ push af
+ push hl
+ ld a, BANK(PokemonNames)
+ rst Bankswitch
+
+; Each name is ten characters
+ ld a, [$d265]
+ dec a
+ ld d, 0
+ ld e, a
+ ld h, 0
+ ld l, a
+ add hl, hl
+ add hl, hl
+ add hl, de
+ add hl, hl
+ ld de, PokemonNames
+ add hl, de
+
+; Terminator
+ ld de, StringBuffer1
+ push de
+ ld bc, PKMN_NAME_LENGTH - 1
+ call CopyBytes
+ ld hl, StringBuffer1 + PKMN_NAME_LENGTH - 1
+ ld [hl], "@"
+ pop de
+
+ pop hl
+ pop af
+ rst Bankswitch
+ ret
+; 3468
+
+
+GetItemName: ; 3468
+; Get item name $d265.
+
+ push hl
+ push bc
+ ld a, [$d265]
+
+ cp TM_01
+ jr nc, .TM
+
+ ld [CurSpecies], a
+ ld a, 4 ; Item names
+ ld [$cf61], a
+ call GetName
+ jr .Copied
+.TM
+ call GetTMHMName
+.Copied
+ ld de, StringBuffer1
+ pop bc
+ pop hl
+ ret
+; 3487
+
+
+GetTMHMName: ; 3487
+; Get TM/HM name by item id $d265.
+
+ push hl
+ push de
+ push bc
+ ld a, [$d265]
+ push af
+
+; TM/HM prefix
+ cp HM_01
+ push af
+ jr c, .TM
+
+ ld hl, .HMText
+ ld bc, .HMTextEnd - .HMText
+ jr .asm_34a1
+
+.TM
+ ld hl, .TMText
+ ld bc, .TMTextEnd - .TMText
+
+.asm_34a1
+ ld de, StringBuffer1
+ call CopyBytes
+
+; TM/HM number
+ push de
+ ld a, [$d265]
+ ld c, a
+ callab GetTMHMNumber
+ pop de
+
+; HM numbers start from 51, not 1
+ pop af
+ ld a, c
+ jr c, .asm_34b9
+ sub NUM_TMS
+
+; Divide and mod by 10 to get the top and bottom digits respectively
+.asm_34b9
+ ld b, "0"
+.mod10
+ sub 10
+ jr c, .asm_34c2
+ inc b
+ jr .mod10
+.asm_34c2
+ add 10
+
+ push af
+ ld a, b
+ ld [de], a
+ inc de
+ pop af
+
+ ld b, "0"
+ add b
+ ld [de], a
+
+; End the string
+ inc de
+ ld a, "@"
+ ld [de], a
+
+ pop af
+ ld [$d265], a
+ pop bc
+ pop de
+ pop hl
+ ret
+
+.TMText
+ db "TM"
+.TMTextEnd
+ db "@"
+
+.HMText
+ db "HM"
+.HMTextEnd
+ db "@"
+; 34df
+
+
+IsHM: ; 34df
+ cp HM_01
+ jr c, .NotHM
+ scf
+ ret
+.NotHM
+ and a
+ ret
+; 34e7
+
+
+IsHMMove: ; 34e7
+ ld hl, .HMMoves
+ ld de, 1
+ jp IsInArray
+
+.HMMoves
+ db CUT
+ db FLY
+ db SURF
+ db STRENGTH
+ db FLASH
+ db WATERFALL
+ db WHIRLPOOL
+ db $ff
+; 34f8
+
+
+GetMoveName: ; 34f8
+ push hl
+; move name
+ ld a, $2 ; move names
+ ld [$cf61], a
+; move id
+ ld a, [$d265]
+ ld [CurSpecies], a
+
+ call GetName
+ ld de, StringBuffer1
+ pop hl
+ ret
+; 350c
+
+
+Function350c: ; 350c
+ call Function1c66
+ ld a, [hROMBank]
+ push af
+ ld a, $9
+ rst Bankswitch
+
+ call Function245af
+ call Function3524
+ call Function245cb
+ pop af
+ rst Bankswitch
+
+ ld a, [$cf73]
+ ret
+; 3524
+
+Function3524: ; 3524
+ ld hl, VramState
+ bit 0, [hl]
+ jp nz, UpdateTimePals
+ jp Function32f9
+; 352f
+
+Function352f: ; 352f
+ ld a, [$cf82]
+ dec a
+ ld b, a
+ ld a, [$cf84]
+ sub b
+ ld d, a
+ ld a, [$cf83]
+ dec a
+ ld c, a
+ ld a, [$cf85]
+ sub c
+ ld e, a
+ push de
+ call GetTileCoord
+ pop bc
+ jp TextBox
+; 354b
+
+Function354b: ; 354b
+ call DelayFrame
+ ld a, [$ffaa]
+ push af
+ ld a, $1
+ ld [$ffaa], a
+ call Functiona57
+ pop af
+ ld [$ffaa], a
+ ld a, [$ffa9]
+ and $f0
+ ld c, a
+ ld a, [hJoyPressed]
+ and $f
+ or c
+ ld c, a
+ ret
+; 3567
+
+
+Function3567: ; 3567
+ ld a, [hROMBank]
+ push af
+ call Function2c52
+ call Function3574
+ pop bc
+ ld a, b
+ rst Bankswitch
+
+ ret
+; 3574
+
+Function3574: ; 3574
+ ld hl, $0001
+ add hl, de
+ ld a, [hl]
+ cp $ff
+ jr z, .asm_3597
+ ld l, a
+ push hl
+ call Function3599
+ pop hl
+ jr nc, .asm_3597
+ ld d, a
+ ld e, l
+ call Function35de
+ jr nc, .asm_3597
+ call Function2631
+ callba Function96c56
+ scf
+ ret
+
+.asm_3597
+ and a
+ ret
+; 3599
+
+Function3599: ; 3599
+ push de
+ ld hl, $0010
+ add hl, de
+ ld a, [hl]
+ ld hl, $0011
+ add hl, de
+ ld e, [hl]
+ sub $4
+ ld d, a
+ ld a, e
+ sub $4
+ ld e, a
+ call Function35b0
+ pop de
+ ret
+; 35b0
+
+Function35b0: ; 35b0
+ ld hl, $dbfc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [$dbfb]
+ and a
+ jr z, .asm_35d3
+.asm_35bc
+ push af
+ ld a, [hl]
+ cp e
+ jr nz, .asm_35c8
+ inc hl
+ ld a, [hld]
+ cp d
+ jr nz, .asm_35c8
+ jr .asm_35d5
+
+.asm_35c8
+ ld a, $5
+ add l
+ ld l, a
+ jr nc, .asm_35cf
+ inc h
+
+.asm_35cf
+ pop af
+ dec a
+ jr nz, .asm_35bc
+
+.asm_35d3
+ and a
+ ret
+
+.asm_35d5
+ pop af
+ ld d, a
+ ld a, [$dbfb]
+ sub d
+ inc a
+ scf
+ ret
+; 35de
+
+Function35de: ; 35de
+ inc e
+ ld hl, $0001
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+.asm_35e6
+ ld a, [hli]
+ cp $ff
+ jr z, .asm_35fc
+ cp d
+ jr nz, .asm_35f7
+ ld a, [hli]
+ cp e
+ jr nz, .asm_35f8
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jr .asm_35fe
+
+.asm_35f7
+ inc hl
+
+.asm_35f8
+ inc hl
+ inc hl
+ jr .asm_35e6
+
+.asm_35fc
+ and a
+ ret
+
+.asm_35fe
+ scf
+ ret
+; 3600
+
+
+CheckTrainerBattle2: ; 3600
+
+ ld a, [hROMBank]
+ push af
+ call Function2c52
+
+ call CheckTrainerBattle
+
+ pop bc
+ ld a, b
+ rst Bankswitch
+ ret
+; 360d
+
+
+CheckTrainerBattle: ; 360d
+; Check if any trainer on the map sees the player and wants to battle.
+
+; Skip the player object.
+ ld a, 1
+ ld de, MapObjects + OBJECT_LENGTH
+
+.loop
+
+; Start a battle if the object:
+
+ push af
+ push de
+
+; Has a sprite
+ ld hl, $0001
+ add hl, de
+ ld a, [hl]
+ and a
+ jr z, .next
+
+; Is a trainer
+ ld hl, $0008
+ add hl, de
+ ld a, [hl]
+ and $f
+ cp $2
+ jr nz, .next
+
+; Is visible on the map
+ ld hl, $0000
+ add hl, de
+ ld a, [hl]
+ cp $ff
+ jr z, .next
+
+; Is facing the player...
+ call Function1ae5
+ call FacingPlayerDistance_bc
+ jr nc, .next
+
+; ...within their sight range
+ ld hl, $0009
+ add hl, de
+ ld a, [hl]
+ cp b
+ jr c, .next
+
+; And hasn't already been beaten
+ push bc
+ push de
+ ld hl, $000a
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld b, CHECK_FLAG
+ call EventFlagAction
+ ld a, c
+ pop de
+ pop bc
+ and a
+ jr z, .asm_3666
+
+.next
+ pop de
+ ld hl, OBJECT_LENGTH
+ add hl, de
+ ld d, h
+ ld e, l
+
+ pop af
+ inc a
+ cp NUM_OBJECTS
+ jr nz, .loop
+ xor a
+ ret
+
+.asm_3666
+ pop de
+ pop af
+ ld [$ffe0], a
+ ld a, b
+ ld [$d03f], a
+ ld a, c
+ ld [MartPointer], a
+ jr Function367e
+; 3674
+
+Function3674: ; 3674
+ ld a, $1
+ ld [$d03f], a
+ ld a, $ff
+ ld [MartPointer], a
+
+Function367e: ; 367e
+ call GetMapScriptHeaderBank
+ ld [EngineBuffer1], a
+ ld a, [$ffe0]
+ call GetMapObject
+ ld hl, $000a
+ add hl, bc
+ ld a, [EngineBuffer1]
+ call GetFarHalfword
+ ld de, $d041
+ ld bc, $000d
+ ld a, [EngineBuffer1]
+ call FarCopyBytes
+ xor a
+ ld [$d04d], a
+ scf
+ ret
+; 36a5
+
+
+FacingPlayerDistance_bc: ; 36a5
+
+ push de
+ call FacingPlayerDistance
+ ld b, d
+ ld c, e
+ pop de
+ ret
+; 36ad
+
+
+FacingPlayerDistance: ; 36ad
+; Return carry if the sprite at bc is facing the player,
+; and its distance in d.
+
+ ld hl, $0010 ; x
+ add hl, bc
+ ld d, [hl]
+
+ ld hl, $0011 ; y
+ add hl, bc
+ ld e, [hl]
+
+ ld a, [MapX]
+ cp d
+ jr z, .CheckY
+
+ ld a, [MapY]
+ cp e
+ jr z, .CheckX
+
+ and a
+ ret
+
+.CheckY
+ ld a, [MapY]
+ sub e
+ jr z, .NotFacing
+ jr nc, .Above
+
+; Below
+ cpl
+ inc a
+ ld d, a
+ ld e, UP << 2
+ jr .CheckFacing
+
+.Above
+ ld d, a
+ ld e, DOWN << 2
+ jr .CheckFacing
+
+.CheckX
+ ld a, [MapX]
+ sub d
+ jr z, .NotFacing
+ jr nc, .Left
+
+; Right
+ cpl
+ inc a
+ ld d, a
+ ld e, LEFT << 2
+ jr .CheckFacing
+
+.Left
+ ld d, a
+ ld e, RIGHT << 2
+
+.CheckFacing
+ call GetSpriteDirection
+ cp e
+ jr nz, .NotFacing
+ scf
+ ret
+
+.NotFacing
+ and a
+ ret
+; 36f5
+
+
+Function36f5: ; 36f5
+ push bc
+ ld hl, $0001
+ add hl, bc
+ ld a, [hl]
+ call GetMapObject
+ ld hl, $000a
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call GetMapScriptHeaderBank
+ call GetFarHalfword
+ ld d, h
+ ld e, l
+ push de
+ ld b, $2
+ call EventFlagAction
+ pop de
+ ld a, c
+ and a
+ pop bc
+ ret
+; 3718
+
+
+Function3718: ; 3718
+ ld a, [BattleType]
+ cp $1
+ jr .asm_3724
+
+ ld hl, WalkingTile
+ jr .asm_3731
+
+.asm_3724
+ ld a, [$d0ee]
+ ld hl, WalkingTile
+ and $f
+ jr z, .asm_3731
+ ld hl, $d049
+
+.asm_3731
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call GetMapScriptHeaderBank
+ call FarPrintText
+ call WaitBGMap
+ call Functiona80
+ ret
+; 3741
+
+
+
+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
+
+
+DrawHPBar: ; 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
+
+
+Function3786: ; 3786
+ ld a, $1
+ ld [$c2c6], a
+
+Function378b: ; 378b
+ ld a, [CurPartySpecies]
+ call IsAPokemon
+ jr c, .asm_37ad
+ push hl
+ ld de, VTiles2
+ ld a, $3c
+ call Predef
+ pop hl
+ xor a
+ ld [$ffad], a
+ ld bc, $0707
+ ld a, $13
+ call Predef
+ xor a
+ ld [$c2c6], a
+ ret
+
+.asm_37ad
+ xor a
+ ld [$c2c6], a
+ inc a
+ ld [CurPartySpecies], a
+ ret
+; 37b6
+
+Function37b6: ; 37b6
+ push af
+ ld a, $1
+ ld [$c2bc], a
+ pop af
+ call Function37e2
+ call WaitSFX
+ ret
+; 37c4
+
+Function37c4: ; 37c4
+ push af
+ ld a, $1
+ ld [$c2bc], a
+ pop af
+ jp Function37e2
+; 37ce
+
+Function37ce: ; 37ce
+ call Function37d5
+ call WaitSFX
+ ret
+; 37d5
+
+Function37d5: ; 37d5
+ push af
+ xor a
+ ld [$c2bc], a
+ ld [CryTracks], a
+ pop af
+ call Function37e2
+ ret
+; 37e2
+
+Function37e2: ; 37e2
+ push hl
+ push de
+ push bc
+ call Function381e
+ jr c, .asm_37ef
+ ld e, c
+ ld d, b
+ call PlayCryHeader
+
+.asm_37ef
+ pop bc
+ pop de
+ pop hl
+ ret
+; 37f3
+
+Function37f3: ; 37f3
+ call Function381e
+ ret c
+ ld a, [hROMBank]
+ push af
+ ld a, $3c
+ rst Bankswitch
+
+ ld hl, $6787
+ add hl, bc
+ add hl, bc
+ add hl, bc
+ add hl, bc
+ add hl, bc
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc hl
+ ld a, [hli]
+ ld [CryPitch], a
+ ld a, [hli]
+ ld [CryEcho], a
+ ld a, [hli]
+ ld [CryLength], a
+ ld a, [hl]
+ ld [$c2b3], a
+ pop af
+ rst Bankswitch
+
+ and a
+ ret
+; 381e
+
+Function381e: ; 381e
+ and a
+ jr z, .asm_382b
+ cp $fc
+ jr nc, .asm_382b
+ dec a
+ ld c, a
+ ld b, $0
+ and a
+ ret
+
+.asm_382b
+ scf
+ ret
+; 382d
+
+
+PrintLevel: ; 382d
+; Print TempMonLevel at hl
+
+ ld a, [TempMonLevel]
+ ld [hl], $6e ; ":L"
+ inc hl
+
+; How many digits?
+ ld c, 2
+ cp 100
+ jr c, Function3842
+
+; 3-digit numbers overwrite the :L.
+ dec hl
+ inc c
+ jr Function3842
+; 383d
+
+Function383d: ; 383d
+; Print :L and all 3 digits
+ ld [hl], $6e
+ inc hl
+ ld c, 3
+; 3842
+
+Function3842: ; 3842
+ ld [$d265], a
+ ld de, $d265
+ ld b, %01000001 ; flags
+ jp PrintNum
+; 384d
+
+
+Function384d: ; 384d
+ ld hl, $d25e
+ 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, [CurSpecies]
+ cp EGG
+ jr z, .egg
+
+; Get BaseData
+ dec a
+ ld bc, BaseData1 - BaseData0
+ ld hl, BaseData
+ call AddNTimes
+ ld de, CurBaseData
+ ld bc, BaseData1 - BaseData0
+ call CopyBytes
+ jr .end
+
+.egg
+; ????
+ ld de, $7d9c
+
+; Sprite dimensions
+ ld b, $55 ; 5x5
+ ld hl, BasePicSize
+ ld [hl], b
+
+; ????
+ ld hl, BasePadding
+ 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, [CurSpecies]
+ ld [BaseDexNo], a
+
+ pop af
+ rst Bankswitch
+ pop hl
+ pop de
+ pop bc
+ ret
+; 389c
+
+
+GetCurNick: ; 389c
+ ld a, [CurPartyMon]
+ ld hl, PartyMonNicknames
+
+GetNick: ; 38a2
+; Get nickname a from list hl.
+
+ push hl
+ push bc
+
+ call SkipNames
+ ld de, StringBuffer1
+
+ push de
+ ld bc, PKMN_NAME_LENGTH
+ call CopyBytes
+ pop de
+
+ callab CheckNickErrors
+
+ 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
+ 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 a, %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 a, "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 CurPartyMon in hl
+ push bc
+ ld hl, PartyMons
+ ld c, a
+ ld b, $00
+ add hl, bc
+ ld a, [CurPartyMon]
+ call GetPartyLocation
+ pop bc
+ ret
+; 3927
+
+GetPartyLocation: ; 3927
+; Add the length of a PartyMon struct to hl a times.
+ ld bc, PartyMon2 - PartyMon1
+ jp AddNTimes
+; 392d
+
+
+Function392d: ; 392d
+ push hl
+ ld a, b
+ dec a
+ ld b, $0
+ add hl, bc
+ ld hl, $5424
+ ld bc, $0020
+ call AddNTimes
+ ld a, $14
+ call GetFarHalfword
+ ld b, l
+ ld c, h
+ pop hl
+ ret
+; 3945
+
+
+UserPartyAttr: ; 3945
+ push af
+ ld a, [hBattleTurn]
+ and a
+ jr nz, .asm_394e
+ pop af
+ jr BattlePartyAttr
+.asm_394e
+ pop af
+ jr OTPartyAttr
+; 3951
+
+
+OpponentPartyAttr: ; 3951
+ push af
+ ld a, [hBattleTurn]
+ and a
+ jr z, .asm_395a
+ pop af
+ jr BattlePartyAttr
+.asm_395a
+ pop af
+ jr OTPartyAttr
+; 395d
+
+
+BattlePartyAttr: ; 395d
+; Get attribute a from the active BattleMon's party struct.
+ push bc
+ ld c, a
+ ld b, 0
+ ld hl, PartyMons
+ add hl, bc
+ ld a, [CurBattleMon]
+ call GetPartyLocation
+ pop bc
+ ret
+; 396d
+
+
+OTPartyAttr: ; 396d
+; Get attribute a from the active EnemyMon's party struct.
+ push bc
+ ld c, a
+ ld b, 0
+ ld hl, OTPartyMon1Species
+ add hl, bc
+ ld a, [CurOTMon]
+ call GetPartyLocation
+ pop bc
+ ret
+; 397d
+
+
+ResetDamage: ; 397d
+ xor a
+ ld [CurDamage], a
+ ld [CurDamage + 1], a
+ ret
+; 3985
+
+SetPlayerTurn: ; 3985
+ xor a
+ ld [hBattleTurn], a
+ ret
+; 3989
+
+SetEnemyTurn: ; 3989
+ ld a, 1
+ ld [hBattleTurn], a
+ ret
+; 398e
+
+
+UpdateOpponentInParty: ; 398e
+ ld a, [hBattleTurn]
+ and a
+ jr z, UpdateEnemyMonInParty
+ jr UpdateBattleMonInParty
+; 3995
+
+UpdateUserInParty: ; 3995
+ ld a, [hBattleTurn]
+ and a
+ jr z, UpdateBattleMonInParty
+ jr UpdateEnemyMonInParty
+; 399c
+
+UpdateBattleMonInParty: ; 399c
+; Update level, status, current HP
+
+ ld a, [CurBattleMon]
+
+Function399f: ; 399f
+ ld hl, PartyMon1Level
+ call GetPartyLocation
+
+ ld d, h
+ ld e, l
+ ld hl, BattleMonLevel
+ ld bc, BattleMonMaxHP - BattleMonLevel
+ jp CopyBytes
+; 39b0
+
+UpdateEnemyMonInParty: ; 39b0
+; Update level, status, current HP
+
+; No wildmons.
+ ld a, [IsInBattle]
+ dec a
+ ret z
+
+ ld a, [CurOTMon]
+ ld hl, OTPartyMon1Level
+ call GetPartyLocation
+
+ ld d, h
+ ld e, l
+ ld hl, EnemyMonLevel
+ ld bc, EnemyMonMaxHP - EnemyMonLevel
+ jp CopyBytes
+; 39c9
+
+
+RefreshBattleHuds: ; 39c9
+ call UpdateBattleHuds
+ ld c, 3
+ call DelayFrames
+ jp WaitBGMap
+; 39d4
+
+UpdateBattleHuds: ; 39d4
+ callba Function3df48
+ callba Function3e036
+ ret
+; 39e1
+
+
+GetBattleVar: ; 39e1
+; Preserves hl.
+ push hl
+ call _GetBattleVar
+ pop hl
+ ret
+; 39e7
+
+_GetBattleVar: ; 39e7
+; Get variable from pair a, depending on whose turn it is.
+; There are 21 variable pairs.
+
+ push bc
+
+ ld hl, .battlevarpairs
+ ld c, a
+ ld b, 0
+ add hl, bc
+ add hl, bc
+
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+
+; Enemy turn uses the second byte instead.
+; This lets battle variable calls be side-neutral.
+ ld a, [hBattleTurn]
+ and a
+ jr z, .getvar
+ inc hl
+
+.getvar
+; var id
+ ld a, [hl]
+ ld c, a
+ ld b, 0
+
+ ld hl, .vars
+ add hl, bc
+ add hl, bc
+
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+
+ ld a, [hl]
+
+ pop bc
+ ret
+
+
+.battlevarpairs
+ dw .substatus1, .substatus2, .substatus3, .substatus4, .substatus5
+ dw .substatus1opp, .substatus2opp, .substatus3opp, .substatus4opp, .substatus5opp
+ dw .status, .statusopp, .animation, .effect, .power, .type
+ dw .curmove, .lastcounter, .lastcounteropp, .lastmove, .lastmoveopp
+
+
+ const_def
+ const PLAYER_SUBSTATUS_1
+ const ENEMY_SUBSTATUS_1
+ const PLAYER_SUBSTATUS_2
+ const ENEMY_SUBSTATUS_2
+ const PLAYER_SUBSTATUS_3
+ const ENEMY_SUBSTATUS_3
+ const PLAYER_SUBSTATUS_4
+ const ENEMY_SUBSTATUS_4
+ const PLAYER_SUBSTATUS_5
+ const ENEMY_SUBSTATUS_5
+ const PLAYER_STATUS
+ const ENEMY_STATUS
+ const PLAYER_MOVE_ANIMATION
+ const ENEMY_MOVE_ANIMATION
+ const PLAYER_MOVE_EFFECT
+ const ENEMY_MOVE_EFFECT
+ const PLAYER_MOVE_POWER
+ const ENEMY_MOVE_POWER
+ const PLAYER_MOVE_TYPE
+ const ENEMY_MOVE_TYPE
+ const PLAYER_CUR_MOVE
+ const ENEMY_CUR_MOVE
+ const PLAYER_COUNTER_MOVE
+ const ENEMY_COUNTER_MOVE
+ const PLAYER_LAST_MOVE
+ const ENEMY_LAST_MOVE
+
+
+; player enemy
+.substatus1 db PLAYER_SUBSTATUS_1, ENEMY_SUBSTATUS_1
+.substatus1opp db ENEMY_SUBSTATUS_1, PLAYER_SUBSTATUS_1
+.substatus2 db PLAYER_SUBSTATUS_2, ENEMY_SUBSTATUS_2
+.substatus2opp db ENEMY_SUBSTATUS_2, PLAYER_SUBSTATUS_2
+.substatus3 db PLAYER_SUBSTATUS_3, ENEMY_SUBSTATUS_3
+.substatus3opp db ENEMY_SUBSTATUS_3, PLAYER_SUBSTATUS_3
+.substatus4 db PLAYER_SUBSTATUS_4, ENEMY_SUBSTATUS_4
+.substatus4opp db ENEMY_SUBSTATUS_4, PLAYER_SUBSTATUS_4
+.substatus5 db PLAYER_SUBSTATUS_5, ENEMY_SUBSTATUS_5
+.substatus5opp db ENEMY_SUBSTATUS_5, PLAYER_SUBSTATUS_5
+.status db PLAYER_STATUS, ENEMY_STATUS
+.statusopp db ENEMY_STATUS, PLAYER_STATUS
+.animation db PLAYER_MOVE_ANIMATION, ENEMY_MOVE_ANIMATION
+.effect db PLAYER_MOVE_EFFECT, ENEMY_MOVE_EFFECT
+.power db PLAYER_MOVE_POWER, ENEMY_MOVE_POWER
+.type db PLAYER_MOVE_TYPE, ENEMY_MOVE_TYPE
+.curmove db PLAYER_CUR_MOVE, ENEMY_CUR_MOVE
+.lastcounter db PLAYER_COUNTER_MOVE, ENEMY_COUNTER_MOVE
+.lastcounteropp db ENEMY_COUNTER_MOVE, PLAYER_COUNTER_MOVE
+.lastmove db PLAYER_LAST_MOVE, ENEMY_LAST_MOVE
+.lastmoveopp db ENEMY_LAST_MOVE, PLAYER_LAST_MOVE
+
+.vars
+ dw PlayerSubStatus1, EnemySubStatus1
+ dw PlayerSubStatus2, EnemySubStatus2
+ dw PlayerSubStatus3, EnemySubStatus3
+ dw PlayerSubStatus4, EnemySubStatus4
+ dw PlayerSubStatus5, EnemySubStatus5
+ dw BattleMonStatus, EnemyMonStatus
+ dw PlayerMoveAnimation, EnemyMoveAnimation
+ dw PlayerMoveEffect, EnemyMoveEffect
+ dw PlayerMovePower, EnemyMovePower
+ dw PlayerMoveType, EnemyMoveType
+ dw CurPlayerMove, CurEnemyMove
+ dw LastEnemyCounterMove, LastPlayerCounterMove
+ dw LastPlayerMove, LastEnemyMove
+; 3a90
+
+
+Function3a90: ; 3a90
+ inc hl
+ ld a, [hROMBank]
+ push af
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ ld [hROMBank], a
+ ld [MBC3RomBank], a
+ ld a, e
+ ld l, a
+ ld a, d
+ ld h, a
+ ld de, $d00c
+ ld bc, $0028
+ call CopyBytes
+ pop af
+ ld [hROMBank], a
+ ld [MBC3RomBank], a
+ ret
+; 3ab2
+
+
+MobileTextBorder: ; 3ab2
+; For mobile link battles only.
+ ld a, [InLinkBattle]
+ cp 4
+ ret c
+; Draw a cell phone icon at the top right corner of the border.
+ ld hl, $c5a3 ; TileMap(19,12)
+ ld [hl], $5e ; cell phone top
+ ld hl, $c5b7 ; TileMap(19,13)
+ ld [hl], $5f ; cell phone bottom
+ ret
+; 3ac3
+
+
+BattleTextBox: ; 3ac3
+; Open a textbox and print text at hl.
+ push hl
+ call SpeechTextBox
+ call MobileTextBorder
+ call Function1ad2
+ call Function321c
+ pop hl
+ call PrintTextBoxText
+ ret
+; 3ad5
+
+
+StdBattleTextBox: ; 3ad5
+; Open a textbox and print battle text at 20:hl.
+
+ ld a, [hROMBank]
+ push af
+
+ ld a, BANK(BattleText)
+ rst Bankswitch
+
+ call BattleTextBox
+
+ pop af
+ rst Bankswitch
+ ret
+; 3ae1
+
+
+Function3ae1: ; 3ae1
+ ld a, $32
+ rst Bankswitch
+
+ ld a, [hli]
+ ld [$d410], a
+ ld a, [hl]
+ ld [$d411], a
+ ld a, $33
+ rst Bankswitch
+
+ ret
+; 3af0
+
+Function3af0: ; 3af0
+ push hl
+ push de
+ ld hl, $d410
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld a, $32
+ rst Bankswitch
+
+ ld a, [de]
+ ld [$d417], a
+ inc de
+ ld a, $33
+ rst Bankswitch
+
+ ld [hl], d
+ dec hl
+ ld [hl], e
+ pop de
+ pop hl
+ ld a, [$d417]
+ ret
+; 3b0c
+
+Function3b0c: ; 3b0c
+ ld a, [hLCDStatCustom]
+ and a
+ ret z
+
+ ld a, $00
+ ld [Requested2bppSource], a
+ ld a, $d2
+ ld [Requested2bppSource + 1], a
+
+ ld a, $00
+ ld [Requested2bppDest], a
+ ld a, $d1
+ ld [Requested2bppDest + 1], a
+
+ ld a, $9
+ ld [Requested2bpp], a
+ ret
+; 3b2a
+
+
+
+Function3b2a: ; 3b2a
+ ld [$c3b8], a
+ ld a, [hROMBank]
+ push af
+ ld a, BANK(Function8cfd6)
+ rst Bankswitch
+
+ ld a, [$c3b8]
+ call Function8cfd6
+ pop af
+ rst Bankswitch
+
+ ret
+; 3b3c
+
+
+Function3b3c: ; 3b3c
+ ld [$c3b8], a
+ ld a, [hROMBank]
+ push af
+ ld a, BANK(Function8d120)
+ rst Bankswitch
+
+ ld a, [$c3b8]
+ call Function8d120
+ pop af
+ rst Bankswitch
+
+ ret
+; 3b4e
+
+
+SoundRestart: ; 3b4e
+
+ push hl
+ push de
+ push bc
+ push af
+
+ ld a, [hROMBank]
+ push af
+ ld a, BANK(_SoundRestart)
+ ld [hROMBank], a
+ ld [MBC3RomBank], a
+
+ call _SoundRestart
+
+ pop af
+ ld [hROMBank], a
+ ld [MBC3RomBank], a
+
+ pop af
+ pop bc
+ pop de
+ pop hl
+ ret
+; 3b6a
+
+
+UpdateSound: ; 3b6a
+
+ push hl
+ push de
+ push bc
+ push af
+
+ ld a, [hROMBank]
+ push af
+ ld a, BANK(_UpdateSound)
+ ld [hROMBank], a
+ ld [MBC3RomBank], a
+
+ call _UpdateSound
+
+ pop af
+ ld [hROMBank], a
+ ld [MBC3RomBank], a
+
+ pop af
+ pop bc
+ pop de
+ pop hl
+ ret
+; 3b86
+
+
+_LoadMusicByte: ; 3b86
+; CurMusicByte = [a:de]
+
+ ld [hROMBank], a
+ ld [MBC3RomBank], a
+
+ ld a, [de]
+ ld [CurMusicByte], a
+ ld a, BANK(LoadMusicByte)
+
+ ld [hROMBank], a
+ ld [MBC3RomBank], a
+ ret
+; 3b97
+
+
+PlayMusic: ; 3b97
+; Play music de.
+
+ push hl
+ push de
+ push bc
+ push af
+
+ ld a, [hROMBank]
+ push af
+ ld a, BANK(_PlayMusic) ; and BANK(_SoundRestart)
+ ld [hROMBank], a
+ ld [MBC3RomBank], a
+
+ ld a, e
+ and a
+ jr z, .nomusic
+
+ call _PlayMusic
+ jr .end
+
+.nomusic
+ call _SoundRestart
+
+.end
+ pop af
+ ld [hROMBank], a
+ ld [MBC3RomBank], a
+ pop af
+ pop bc
+ pop de
+ pop hl
+ ret
+; 3bbc
+
+
+PlayMusic2: ; 3bbc
+; Stop playing music, then play music de.
+
+ push hl
+ push de
+ push bc
+ push af
+
+ ld a, [hROMBank]
+ push af
+ ld a, BANK(_PlayMusic)
+ ld [hROMBank], a
+ ld [MBC3RomBank], a
+
+ push de
+ ld de, MUSIC_NONE
+ call _PlayMusic
+ call DelayFrame
+ pop de
+ call _PlayMusic
+
+ pop af
+ ld [hROMBank], a
+ ld [MBC3RomBank], a
+
+ pop af
+ pop bc
+ pop de
+ pop hl
+ ret
+
+; 3be3
+
+
+PlayCryHeader: ; 3be3
+; Play a cry given parameters in header de
+
+ push hl
+ push de
+ push bc
+ push af
+
+; Save current bank
+ ld a, [hROMBank]
+ push af
+
+; Cry headers are stuck in one bank.
+ ld a, BANK(CryHeaders)
+ ld [hROMBank], a
+ ld [MBC3RomBank], a
+
+; Each header is 6 bytes long:
+ ld hl, CryHeaders
+ add hl, de
+ add hl, de
+ add hl, de
+ add hl, de
+ add hl, de
+ add hl, de
+
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc hl
+
+ ld a, [hli]
+ ld [CryPitch], a
+ ld a, [hli]
+ ld [CryEcho], a
+ ld a, [hli]
+ ld [CryLength], a
+ ld a, [hl]
+ ld [CryLength+1], a
+
+ ld a, BANK(PlayCry)
+ ld [hROMBank], a
+ ld [MBC3RomBank], a
+
+ call PlayCry
+
+ pop af
+ ld [hROMBank], a
+ ld [MBC3RomBank], a
+
+ pop af
+ pop bc
+ pop de
+ pop hl
+ ret
+; 3c23
+
+
+PlaySFX: ; 3c23
+; Play sound effect de.
+; Sound effects are ordered by priority (lowest to highest)
+
+ push hl
+ push de
+ push bc
+ push af
+
+; Is something already playing?
+ call CheckSFX
+ jr nc, .play
+; Does it have priority?
+ ld a, [CurSFX]
+ cp e
+ jr c, .quit
+
+.play
+ ld a, [hROMBank]
+ push af
+ ld a, BANK(_PlaySFX)
+ ld [hROMBank], a
+ ld [MBC3RomBank], a ; bankswitch
+
+ ld a, e
+ ld [CurSFX], a
+ call _PlaySFX
+
+ pop af
+ ld [hROMBank], a
+ ld [MBC3RomBank], a ; bankswitch
+.quit
+ pop af
+ pop bc
+ pop de
+ pop hl
+ ret
+; 3c4e
+
+
+WaitPlaySFX: ; 3c4e
+ call WaitSFX
+ call PlaySFX
+ ret
+; 3c55
+
+
+WaitSFX: ; 3c55
+; infinite loop until sfx is done playing
+
+ push hl
+
+.loop
+ ; ch5 on?
+ ld hl, Channel5 + Channel1Flags - Channel1
+ bit 0, [hl]
+ jr nz, .loop
+ ; ch6 on?
+ ld hl, Channel6 + Channel1Flags - Channel1
+ bit 0, [hl]
+ jr nz, .loop
+ ; ch7 on?
+ ld hl, Channel7 + Channel1Flags - Channel1
+ bit 0, [hl]
+ jr nz, .loop
+ ; ch8 on?
+ ld hl, Channel8 + Channel1Flags - Channel1
+ bit 0, [hl]
+ jr nz, .loop
+
+ pop hl
+ ret
+; 3c74
+
+Function3c74: ; 3c74
+ push hl
+ ld hl, $c1cc
+ bit 0, [hl]
+ jr nz, .asm_3c94
+ ld hl, $c1fe
+ bit 0, [hl]
+ jr nz, .asm_3c94
+ ld hl, $c230
+ bit 0, [hl]
+ jr nz, .asm_3c94
+ ld hl, $c262
+ bit 0, [hl]
+ jr nz, .asm_3c94
+ pop hl
+ scf
+ ret
+
+.asm_3c94
+ pop hl
+ and a
+ ret
+; 3c97
+
+MaxVolume: ; 3c97
+ ld a, $77 ; max
+ ld [Volume], a
+ ret
+; 3c9d
+
+LowVolume: ; 3c9d
+ ld a, $33 ; 40%
+ ld [Volume], a
+ ret
+; 3ca3
+
+VolumeOff: ; 3ca3
+ xor a
+ ld [Volume], a
+ ret
+; 3ca8
+
+Function3ca8: ; 3ca8
+ ld a, $4
+ ld [MusicFade], a
+ ret
+; 3cae
+
+Function3cae: ; 3cae
+ ld a, $84
+ ld [MusicFade], a
+ ret
+; 3cb4
+
+Function3cb4: ; 3cb4
+.asm_3cb4
+ and a
+ ret z
+ dec a
+ call UpdateSound
+ jr .asm_3cb4
+; 3cbc
+
+Function3cbc: ; 3cbc
+ push hl
+ push de
+ push bc
+ push af
+ call Function3d97
+ ld a, [CurMusic]
+ cp e
+ jr z, .asm_3cda
+ ld a, $8
+ ld [MusicFade], a
+ ld a, e
+ ld [MusicFadeIDLo], a
+ ld a, d
+ ld [MusicFadeIDHi], a
+ ld a, e
+ ld [CurMusic], a
+
+.asm_3cda
+ pop af
+ pop bc
+ pop de
+ pop hl
+ ret
+; 3cdf
+
+Function3cdf: ; 3cdf
+ push hl
+ push de
+ push bc
+ push af
+ call Function3d97
+ ld a, [CurMusic]
+ cp e
+ jr z, .asm_3cfe
+ push de
+ ld de, MUSIC_NONE
+ call PlayMusic
+ call DelayFrame
+ pop de
+ ld a, e
+ ld [CurMusic], a
+ call PlayMusic
+
+.asm_3cfe
+ pop af
+ pop bc
+ pop de
+ pop hl
+ ret
+; 3d03
+
+Function3d03: ; 3d03
+ push hl
+ push de
+ push bc
+ push af
+ xor a
+ ld [$c2c1], a
+ ld de, MUSIC_BICYCLE
+ ld a, [PlayerState]
+ cp $1
+ jr z, .asm_3d18
+ call Function3d97
+.asm_3d18
+ push de
+ ld de, MUSIC_NONE
+ call PlayMusic
+ call DelayFrame
+ pop de
+ ld a, e
+ ld [CurMusic], a
+ call PlayMusic
+ pop af
+ pop bc
+ pop de
+ pop hl
+ ret
+; 3d2f
+
+Function3d2f: ; 3d2f
+ ld a, [$c2c1]
+ and a
+ jr z, Function3d47
+ xor a
+ ld [CurMusic], a
+ ld de, MUSIC_NONE
+ call PlayMusic
+ call DelayFrame
+ xor a
+ ld [$c2c1], a
+ ret
+; 3d47
+
+Function3d47: ; 3d47
+ push hl
+ push de
+ push bc
+ push af
+ ld de, MUSIC_NONE
+ call PlayMusic
+ call DelayFrame
+ ld a, [CurMusic]
+ ld e, a
+ ld d, 0
+ call PlayMusic
+ pop af
+ pop bc
+ pop de
+ pop hl
+ ret
+; 3d62
+
+Function3d62: ; 3d62
+ ld a, [PlayerState]
+ cp $4
+ jr z, .asm_3d7b
+ cp $8
+ jr z, .asm_3d7b
+ ld a, [StatusFlags2]
+ bit 2, a
+ jr nz, .asm_3d80
+.asm_3d74
+ and a
+ ret
+
+ ld de, $0013
+ scf
+ ret
+
+.asm_3d7b
+ ld de, $0021
+ scf
+ ret
+
+.asm_3d80
+ ld a, [MapGroup]
+ cp $a
+ jr nz, .asm_3d74
+ ld a, [MapNumber]
+ cp $f
+ jr z, .asm_3d92
+ cp $11
+ jr nz, .asm_3d74
+
+.asm_3d92
+ ld de, $0058
+ scf
+ ret
+; 3d97
+
+Function3d97: ; 3d97
+ call Function3d62
+ ret c
+ call Function2cbd
+ ret
+; 3d9f
+
+Function3d9f: ; 3d9f
+ ld a, $20
+ ld [$c498], a
+ ld [$c49c], a
+ ld a, $50
+ ld [$c499], a
+ ld a, $58
+ ld [$c49d], a
+ xor a
+ ld [$c49b], a
+ ld [$c49f], a
+ ld a, [$c296]
+ cp $64
+ jr nc, .asm_3dd5
+ add $1
+ daa
+ ld b, a
+ swap a
+ and $f
+ add $f6
+ ld [$c49a], a
+ ld a, b
+ and $f
+ add $f6
+ ld [$c49e], a
+ ret
+
+.asm_3dd5
+ ld a, $ff
+ ld [$c49a], a
+ ld [$c49e], a
+ ret
+; 3dde
+
+CheckSFX: ; 3dde
+; returns carry if sfx channels are active
+ ld a, [$c1cc] ; 1
+ bit 0, a
+ jr nz, .quit
+ ld a, [$c1fe] ; 2
+ bit 0, a
+ jr nz, .quit
+ ld a, [$c230] ; 3
+ bit 0, a
+ jr nz, .quit
+ ld a, [$c262] ; 4
+ bit 0, a
+ jr nz, .quit
+ and a
+ ret
+.quit
+ scf
+ ret
+; 3dfe
+
+Function3dfe: ; 3dfe
+ xor a
+ ld [$c1cc], a
+ ld [SoundInput], a
+ ld [rNR10], a
+ ld [rNR11], a
+ ld [rNR12], a
+ ld [rNR13], a
+ ld [rNR14], a
+ ret
+; 3e10
+
+
+ChannelsOff: ; 3e10
+; Quickly turn off music channels
+ xor a
+ ld [Channel1Flags], a
+ ld [$c136], a
+ ld [$c168], a
+ ld [$c19a], a
+ ld [SoundInput], a
+ ret
+; 3e21
+
+SFXChannelsOff: ; 3e21
+; Quickly turn off sound effect channels
+ xor a
+ ld [$c1cc], a
+ ld [$c1fe], a
+ ld [$c230], a
+ ld [$c262], a
+ ld [SoundInput], a
+ ret
+; 3e32
+
+Function3e32: ; 3e32
+ cp $2
+ ld [$c988], a
+ ld a, l
+ ld [$c986], a
+ ld a, h
+ ld [$c987], a
+ jr nz, .asm_3e4f
+ ld [$c982], a
+ ld a, l
+ ld [$c981], a
+ ld hl, $c983
+ ld a, c
+ ld [hli], a
+ ld a, b
+ ld [hl], a
+
+.asm_3e4f
+ ld hl, $c822
+ set 6, [hl]
+ ld a, [hROMBank]
+ push af
+ ld a, BANK(Function110030)
+ ld [$c981], a
+ rst Bankswitch
+
+ jp Function110030
+; 3e60
+
+
+Function3e60: ; 3e60
+ ld [$c986], a
+ ld a, l
+ ld [$c987], a
+ ld a, h
+ ld [$c988], a
+ pop bc
+ ld a, b
+ ld [$c981], a
+ rst Bankswitch
+
+ ld hl, $c822
+ res 6, [hl]
+ ld hl, $c987
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [$c986]
+ ret
+; 3e80
+
+
+Function3e80: ; 3e80
+ ld a, [hROMBank]
+ push af
+ ld a, BANK(Function1116c5)
+ ld [$c981], a
+ rst Bankswitch
+
+ call Function1116c5
+ pop bc
+ ld a, b
+ ld [$c981], a
+ rst Bankswitch
+
+ ret
+; 3e93
+
+
+Timer: ; 3e93
+ push af
+ push bc
+ push de
+ push hl
+
+ ld a, [$ffe9]
+ and a
+ jr z, .asm_3ed2
+
+ xor a
+ ld [rTAC], a
+
+; Turn off timer interrupt
+ ld a, [rIF]
+ and 1 << VBLANK | 1 << LCD_STAT | 1 << SERIAL | 1 << JOYPAD
+ ld [rIF], a
+
+ ld a, [$c86a]
+ or a
+ jr z, .asm_3ed2
+
+ ld a, [$c822]
+ bit 1, a
+ jr nz, .asm_3eca
+
+ ld a, [rSC]
+ and 1 << rSC_ON
+ jr nz, .asm_3eca
+
+ ld a, [hROMBank]
+ push af
+ ld a, BANK(Function1118de)
+ ld [$c981], a
+ rst Bankswitch
+
+ call Function1118de
+
+ pop bc
+ ld a, b
+ ld [$c981], a
+ rst Bankswitch
+
+.asm_3eca
+ ld a, [rTMA]
+ ld [rTIMA], a
+
+ ld a, 1 << rTAC_ON | rTAC_65536_HZ
+ ld [rTAC], a
+
+.asm_3ed2
+ pop hl
+ pop de
+ pop bc
+ pop af
+ reti
+; 3ed7
+
+Function3ed7: ; 3ed7
+ ld [$dc02], a
+ ld a, [hROMBank]
+ push af
+ ld a, BANK(Function114243)
+ rst Bankswitch
+
+ call Function114243
+ pop bc
+ ld a, b
+ rst Bankswitch
+
+ ld a, [$dc02]
+ ret
+; 3eea
+
+Function3eea: ; 3eea
+ push hl
+ push bc
+ ld de, $0939
+ add hl, de
+ inc b
+ inc b
+ inc c
+ inc c
+ call Function3f35
+ pop bc
+ pop hl
+ call Function3f47
+ ret
+; 3efd
+
+Function3efd: ; 3efd
+ push hl
+ ld hl, $c590
+ ld b, $4
+ ld c, $12
+ call Function3f0d
+ pop hl
+ call PrintTextBoxText
+ ret
+; 3f0d
+
+Function3f0d: ; 3f0d
+ push hl
+ push bc
+ ld de, $0939
+ add hl, de
+ inc b
+ inc b
+ inc c
+ inc c
+ call Function3f35
+ pop bc
+ pop hl
+ call TextBoxBorder
+ ret
+; 3f20
+
+Function3f20: ; 3f20
+ ld hl, AttrMap
+ ld b, $6
+ ld c, $14
+ call Function3f35
+ ld hl, TileMap
+ ld b, $4
+ ld c, $12
+ call Function3f47
+ ret
+; 3f35
+
+Function3f35: ; 3f35
+ ld a, $6
+ ld de, $0014
+.asm_3f3a
+ push bc
+ push hl
+.asm_3f3c
+ ld [hli], a
+ dec c
+ jr nz, .asm_3f3c
+ pop hl
+ add hl, de
+ pop bc
+ dec b
+ jr nz, .asm_3f3a
+ ret
+; 3f47
+
+Function3f47: ; 3f47
+ push bc
+ call Function3f58
+ pop bc
+.asm_3f4c
+ push bc
+ call Function3f68
+ pop bc
+ dec b
+ jr nz, .asm_3f4c
+ call Function3f60
+ ret
+; 3f58
+
+Function3f58: ; 3f58
+ ld a, $63
+ ld d, $62
+ ld e, $64
+ jr Function3f6e
+
+Function3f60: ; 3f60
+ ld a, $68
+ ld d, $67
+ ld e, $69
+ jr Function3f6e
+
+Function3f68: ; 3f68
+ ld a, $7f
+ ld d, $65
+ ld e, $66
+
+Function3f6e: ; 3f6e
+ push hl
+ ld [hl], d
+ inc hl
+.asm_3f71
+ ld [hli], a
+ dec c
+ jr nz, .asm_3f71
+ ld [hl], e
+ pop hl
+ ld de, $0014
+ add hl, de
+ ret
+; 3f7c
+
+Function3f7c: ; 3f7c
+ call Function1cfd
+ call Function1c53
+ dec b
+ dec c
+ call Function3eea
+ ret
+; 3f88
+
+Function3f88: ; 3f88
+ ld hl, $d000
+ ld b, $0
+.asm_3f8d
+ push bc
+ ld c, $8
+.asm_3f90
+ ld a, [de]
+ inc de
+ cpl
+ ld [hl], $0
+ inc hl
+ ld [hli], a
+ dec c
+ jr nz, .asm_3f90
+ pop bc
+ dec c
+ jr nz, .asm_3f8d
+ ret
+; 3f9f
+
+Function3f9f: ; 3f9f
+ ld hl, $d000
+.asm_3fa2
+ push bc
+ ld c, $8
+.asm_3fa5
+ ld a, [de]
+ inc de
+ inc de
+ cpl
+ ld [hl], $0
+ inc hl
+ ld [hli], a
+ dec c
+ jr nz, .asm_3fa5
+ pop bc
+ dec c
+ jr nz, .asm_3fa2
+ ret
+; 3fb5
+