shithub: pokecrystal

Download patch

ref: 9f53825ce2701f94470a98b3decd8013fbeba91a
parent: 7a3a4f913b32784480dc297e8a4794934ec87b06
author: yenatch <[email protected]>
date: Sat Sep 7 19:38:19 EDT 2013

move common asm from engine/ to common/

engine/ was getting really bloated and common asm wasnt what it was made for

--- /dev/null
+++ b/common/copy.asm
@@ -1,0 +1,431 @@
+; Functions to copy data from ROM.
+
+
+Functiondc9: ; dc9
+	ld a, [rLCDC]
+	bit 7, a
+	jp z, Copy2bpp
+
+	ld a, [hROMBank]
+	push af
+	ld a, BANK(Function104284)
+	rst Bankswitch
+	call Function104284
+	pop af
+	rst Bankswitch
+
+	ret
+; ddc
+
+Functionddc: ; ddc
+	ld a, [rLCDC]
+	bit 7, a
+	jp z, Copy1bpp
+
+	ld a, [hROMBank]
+	push af
+	ld a, BANK(Function1042b2)
+	rst Bankswitch
+	call Function1042b2
+	pop af
+	rst Bankswitch
+
+	ret
+; def
+
+Functiondef: ; def
+	ld [hBuffer], a
+	ld a, [hROMBank]
+	push af
+	ld a, [hBuffer]
+	rst Bankswitch
+	call FarCopyBytesDouble
+	pop af
+	rst Bankswitch
+	ret
+; dfd
+
+Functiondfd: ; dfd
+	dec c
+	ld a, [hBGMapMode]
+	push af
+	xor a
+	ld [hBGMapMode], a
+	ld a, [hROMBank]
+	push af
+	ld a, b
+	rst Bankswitch
+
+.asm_e09
+	ld a, d
+	ld [rHDMA1], a
+	ld a, e
+	and $f0
+	ld [rHDMA2], a
+	ld a, h
+	and $1f
+	ld [rHDMA3], a
+	ld a, l
+	and $f0
+	ld [rHDMA4], a
+	ld a, c
+	cp $8
+	jr c, .asm_e3c
+	sub $8
+	ld c, a
+	ld a, $f
+	ld [hDMATransfer], a
+	call DelayFrame
+	ld a, l
+	add $0
+	ld l, a
+	ld a, h
+	adc $1
+	ld h, a
+	ld a, e
+	add $0
+	ld e, a
+	ld a, d
+	adc $1
+	ld d, a
+	jr .asm_e09
+
+.asm_e3c
+	ld a, c
+	and $7f
+	ld [hDMATransfer], a
+	call DelayFrame
+	pop af
+	rst Bankswitch
+
+	pop af
+	ld [hBGMapMode], a
+	ret
+; e4a
+
+
+
+Functione4a: ; e4a
+	ld a, $5
+	ld hl, $4135
+	rst FarCall
+	ret
+; e51
+
+
+
+Functione51: ; e51
+	ld a, $3e
+	ld hl, $7449
+	rst FarCall
+	ret
+; e58
+
+Functione58: ; e58
+	ld a, $3e
+	ld hl, $74be
+	rst FarCall
+	ret
+; e5f
+
+
+
+Functione5f: ; e5f
+	ld a, $3e
+	ld hl, $748a
+	rst FarCall
+	ld a, $3e
+	ld hl, $74b0
+	rst FarCall
+	ret
+; e6c
+
+Functione6c: ; e6c
+	ld a, $3e
+	ld hl, $74b0
+	rst FarCall
+	ret
+; e73
+
+Functione73: ; e73
+	push de
+	ld a, $0
+	call GetSRAMBank
+	push bc
+	ld de, $a000
+	ld a, b
+	call FarDecompress
+	pop bc
+	pop hl
+	ld de, $a000
+	call Request2bpp
+	call CloseSRAM
+	ret
+; e8d
+
+
+
+FarCopyBytes: ; e8d
+; copy bc bytes from a:hl to de
+
+	ld [hBuffer], a
+	ld a, [hROMBank]
+	push af
+	ld a, [hBuffer]
+	rst Bankswitch
+
+	call CopyBytes
+
+	pop af
+	rst Bankswitch
+	ret
+; 0xe9b
+
+
+FarCopyBytesDouble: ; e9b
+; Copy bc bytes from a:hl to bc*2 bytes at de,
+; doubling each byte in the process.
+
+	ld [hBuffer], a
+	ld a, [hROMBank]
+	push af
+	ld a, [hBuffer]
+	rst Bankswitch
+
+; switcheroo, de <> hl
+	ld a, h
+	ld h, d
+	ld d, a
+	ld a, l
+	ld l, e
+	ld e, a
+
+	inc b
+	inc c
+	jr .dec
+
+.loop
+	ld a, [de]
+	inc de
+	ld [hli], a
+	ld [hli], a
+.dec
+	dec c
+	jr nz, .loop
+	dec b
+	jr nz, .loop
+
+	pop af
+	rst Bankswitch
+	ret
+; 0xeba
+
+
+Request2bpp: ; eba
+	ld a, [hBGMapMode]
+	push af
+	xor a
+	ld [hBGMapMode], a
+
+	ld a, [hROMBank]
+	push af
+	ld a, b
+	rst Bankswitch
+
+	ld a, [$ffd3]
+	push af
+
+	ld a, $8
+	ld [$ffd3], a
+	ld a, [InLinkBattle]
+	cp $4
+	jr nz, .asm_edc
+	ld a, [$ffe9]
+	and a
+	jr nz, .asm_edc
+	ld a, $6
+	ld [$ffd3], a
+
+.asm_edc
+	ld a, e
+	ld [Requested2bppSource], a
+	ld a, d
+	ld [Requested2bppSource + 1], a
+	ld a, l
+	ld [Requested2bppDest], a
+	ld a, h
+	ld [Requested2bppDest + 1], a
+
+.asm_eec
+	ld a, c
+	ld hl, $ffd3
+	cp [hl]
+	jr nc, .asm_f08
+
+	ld [Requested2bpp], a
+.wait
+	call DelayFrame
+	ld a, [Requested2bpp]
+	and a
+	jr nz, .wait
+
+	pop af
+	ld [$ffd3], a
+
+	pop af
+	rst Bankswitch
+
+	pop af
+	ld [hBGMapMode], a
+	ret
+
+.asm_f08
+	ld a, [$ffd3]
+	ld [Requested2bpp], a
+.asm_f0d
+	call DelayFrame
+	ld a, [Requested2bpp]
+	and a
+	jr nz, .asm_f0d
+	ld a, c
+	ld hl, $ffd3
+	sub [hl]
+	ld c, a
+	jr .asm_eec
+; f1e
+
+
+Request1bpp: ; f1e
+	ld a, [hBGMapMode]
+	push af
+	xor a
+	ld [hBGMapMode], a
+
+	ld a, [hROMBank]
+	push af
+	ld a, b
+	rst Bankswitch
+
+	ld a, [$ffd3]
+	push af
+
+	ld a, $8
+	ld [$ffd3], a
+	ld a, [InLinkBattle]
+	cp $4
+	jr nz, .asm_f40
+	ld a, [$ffe9]
+	and a
+	jr nz, .asm_f40
+	ld a, $6
+	ld [$ffd3], a
+
+.asm_f40
+	ld a, e
+	ld [Requested1bppSource], a
+	ld a, d
+	ld [Requested1bppSource + 1], a
+	ld a, l
+	ld [Requested1bppDest], a
+	ld a, h
+	ld [Requested1bppDest + 1], a
+.asm_f50
+	ld a, c
+	ld hl, $ffd3
+	cp [hl]
+	jr nc, .asm_f6c
+
+	ld [Requested1bpp], a
+.wait
+	call DelayFrame
+	ld a, [Requested1bpp]
+	and a
+	jr nz, .wait
+
+	pop af
+	ld [$ffd3], a
+
+	pop af
+	rst Bankswitch
+
+	pop af
+	ld [hBGMapMode], a
+	ret
+
+.asm_f6c
+	ld a, [$ffd3]
+	ld [Requested1bpp], a
+.asm_f71
+	call DelayFrame
+	ld a, [Requested1bpp]
+	and a
+	jr nz, .asm_f71
+	ld a, c
+	ld hl, $ffd3
+	sub [hl]
+	ld c, a
+	jr .asm_f50
+; f82
+
+
+Get2bpp: ; f82
+	ld a, [rLCDC]
+	bit 7, a
+	jp nz, Request2bpp
+
+Copy2bpp: ; f89
+; copy c 2bpp tiles from b:de to hl
+
+	push hl
+	ld h, d
+	ld l, e
+	pop de
+
+; bank
+	ld a, b
+
+; bc = c * $10
+	push af
+	swap c
+	ld a, $f
+	and c
+	ld b, a
+	ld a, $f0
+	and c
+	ld c, a
+	pop af
+
+	jp FarCopyBytes
+; f9d
+
+
+Get1bpp: ; f9d
+	ld a, [rLCDC]
+	bit 7, a
+	jp nz, Request1bpp
+
+Copy1bpp: ; fa4
+; copy c 1bpp tiles from b:de to hl
+
+	push de
+	ld d, h
+	ld e, l
+
+; bank
+	ld a, b
+
+; bc = c * $10 / 2
+	push af
+	ld h, 0
+	ld l, c
+	add hl, hl
+	add hl, hl
+	add hl, hl
+	ld b, h
+	ld c, l
+	pop af
+
+	pop hl
+	jp FarCopyBytesDouble
+; fb6
+
--- /dev/null
+++ b/common/decompress.asm
@@ -1,0 +1,367 @@
+FarDecompress: ; b40
+; Decompress graphics data at a:hl to de
+
+; put a away for a sec
+	ld [$c2c4], a
+; save bank
+	ld a, [hROMBank]
+	push af
+; bankswitch
+	ld a, [$c2c4]
+	rst Bankswitch
+	
+; what we came here for
+	call Decompress
+	
+; restore bank
+	pop af
+	rst Bankswitch
+	ret
+; b50
+
+
+Decompress: ; b50
+; Pokemon Crystal uses an lz variant for compression.
+
+; This is mainly used for graphics, but the intro's
+; tilemaps also use this compression.
+
+; This function decompresses lz-compressed data at hl to de.
+
+
+; Basic rundown:
+
+;	A typical control command consists of:
+;		-the command (bits 5-7)
+;		-the count (bits 0-4)
+;		-and any additional params
+
+;	$ff is used as a terminator.
+
+
+;	Commands:
+
+;		0: literal
+;			literal data for some number of bytes
+;		1: iterate
+;			one byte repeated for some number of bytes
+;		2: alternate
+;			two bytes alternated for some number of bytes
+;		3: zero (whitespace)
+;			0x00 repeated for some number of bytes
+
+;	Repeater control commands have a signed parameter used to determine the start point.
+;	Wraparound is simulated:
+;		Positive values are added to the start address of the decompressed data
+;		and negative values are subtracted from the current position.
+
+;		4: repeat
+;			repeat some number of bytes from decompressed data
+;		5: flipped
+;			repeat some number of flipped bytes from decompressed data
+;			ex: $ad = %10101101 -> %10110101 = $b5
+;		6: reverse
+;			repeat some number of bytes in reverse from decompressed data
+
+;	If the value in the count needs to be larger than 5 bits,
+;	control code 7 can be used to expand the count to 10 bits.
+
+;		A new control command is read in bits 2-4.
+;		The new 10-bit count is split:
+;			bits 0-1 contain the top 2 bits
+;			another byte is added containing the latter 8
+
+;		So, the structure of the control command becomes:
+;			111xxxyy yyyyyyyy
+;			 |  |  |    |
+;            |  | our new count
+;            | the control command for this count
+;            7 (this command)
+
+; For more information, refer to the code below and in extras/gfx.py .
+
+; save starting output address
+	ld a, e
+	ld [$c2c2], a
+	ld a, d
+	ld [$c2c3], a
+	
+.loop
+; get next byte
+	ld a, [hl]
+; done?
+	cp $ff ; end
+	ret z
+
+; get control code
+	and %11100000
+	
+; 10-bit param?
+	cp $e0 ; LZ_HI
+	jr nz, .normal
+	
+	
+; 10-bit param:
+
+; get next 3 bits (%00011100)
+	ld a, [hl]
+	add a
+	add a ; << 3
+	add a
+	
+; this is our new control code
+	and %11100000
+	push af
+	
+; get param hi
+	ld a, [hli]
+	and %00000011
+	ld b, a
+	
+; get param lo
+	ld a, [hli]
+	ld c, a
+	
+; read at least 1 byte
+	inc bc
+	jr .readers
+	
+	
+.normal
+; push control code
+	push af
+; get param
+	ld a, [hli]
+	and %00011111
+	ld c, a
+	ld b, $0
+; read at least 1 byte
+	inc c
+	
+.readers
+; let's get started
+
+; inc loop counts since we bail as soon as they hit 0
+	inc b
+	inc c
+	
+; get control code
+	pop af
+; command type
+	bit 7, a ; 80, a0, c0
+	jr nz, .repeatertype
+	
+; literals
+	cp $20 ; LZ_ITER
+	jr z, .iter
+	cp $40 ; LZ_ALT
+	jr z, .alt
+	cp $60 ; LZ_ZERO
+	jr z, .zero
+	; else $00
+	
+; 00 ; LZ_LIT
+; literal data for bc bytes
+.loop1
+; done?
+	dec c
+	jr nz, .next1
+	dec b
+	jp z, .loop
+	
+.next1
+	ld a, [hli]
+	ld [de], a
+	inc de
+	jr .loop1
+	
+	
+; 20 ; LZ_ITER
+; write byte for bc bytes
+.iter
+	ld a, [hli]
+	
+.iterloop
+	dec c
+	jr nz, .iternext
+	dec b
+	jp z, .loop
+	
+.iternext
+	ld [de], a
+	inc de
+	jr .iterloop
+	
+	
+; 40 ; LZ_ALT
+; alternate two bytes for bc bytes
+
+; next pair
+.alt
+; done?
+	dec c
+	jr nz, .alt0
+	dec b
+	jp z, .altclose0
+	
+; alternate for bc
+.alt0
+	ld a, [hli]
+	ld [de], a
+	inc de
+	dec c
+	jr nz, .alt1
+; done?
+	dec b
+	jp z, .altclose1
+.alt1
+	ld a, [hld]
+	ld [de], a
+	inc de
+	jr .alt
+	
+; skip past the bytes we were alternating
+.altclose0
+	inc hl
+.altclose1
+	inc hl
+	jr .loop
+	
+	
+; 60 ; LZ_ZERO
+; write 00 for bc bytes
+.zero
+	xor a
+	
+.zeroloop
+	dec c
+	jr nz, .zeronext
+	dec b
+	jp z, .loop
+	
+.zeronext
+	ld [de], a
+	inc de
+	jr .zeroloop
+	
+	
+; repeats
+; 80, a0, c0
+; repeat decompressed data from output
+.repeatertype
+	push hl
+	push af
+; get next byte
+	ld a, [hli]
+; absolute?
+	bit 7, a
+	jr z, .absolute
+	
+; relative
+; a = -a
+	and %01111111 ; forget the bit we just looked at
+	cpl
+; add de (current output address)
+	add e
+	ld l, a
+	ld a, $ff ; -1
+	adc d
+	ld h, a
+	jr .repeaters
+	
+.absolute
+; get next byte (lo)
+	ld l, [hl]
+; last byte (hi)
+	ld h, a
+; add starting output address
+	ld a, [$c2c2]
+	add l
+	ld l, a
+	ld a, [$c2c3]
+	adc h
+	ld h, a
+	
+.repeaters
+	pop af
+	cp $80 ; LZ_REPEAT
+	jr z, .repeat
+	cp $a0 ; LZ_FLIP
+	jr z, .flip
+	cp $c0 ; LZ_REVERSE
+	jr z, .reverse
+	
+; e0 -> 80
+	
+; 80 ; LZ_REPEAT
+; repeat some decompressed data
+.repeat
+; done?
+	dec c
+	jr nz, .repeatnext
+	dec b
+	jr z, .cleanup
+	
+.repeatnext
+	ld a, [hli]
+	ld [de], a
+	inc de
+	jr .repeat
+	
+	
+; a0 ; LZ_FLIP
+; repeat some decompressed data w/ flipped bit order
+.flip
+	dec c
+	jr nz, .flipnext
+	dec b
+	jp z, .cleanup
+	
+.flipnext
+	ld a, [hli]
+	push bc
+	ld bc, $0008
+	
+.fliploop
+	rra
+	rl b
+	dec c
+	jr nz, .fliploop
+	ld a, b
+	pop bc
+	ld [de], a
+	inc de
+	jr .flip
+	
+	
+; c0 ; LZ_REVERSE
+; repeat some decompressed data in reverse
+.reverse
+	dec c
+	jr nz, .reversenext
+	
+	dec b
+	jp z, .cleanup
+	
+.reversenext
+	ld a, [hld]
+	ld [de], a
+	inc de
+	jr .reverse
+	
+	
+.cleanup
+; get type of repeat we just used
+	pop hl
+; was it relative or absolute?
+	bit 7, [hl]
+	jr nz, .next
+
+; skip two bytes for absolute
+	inc hl
+; skip one byte for relative
+.next
+	inc hl
+	jp .loop
+; c2f
+
--- /dev/null
+++ b/common/delay.asm
@@ -1,0 +1,23 @@
+DelayFrame: ; 45a
+; Wait for one frame
+	ld a, 1
+	ld [VBlankOccurred], a
+
+; Wait for the next VBlank, halting to conserve battery
+.halt
+	halt ; rgbasm adds a nop after this instruction by default
+	ld a, [VBlankOccurred]
+	and a
+	jr nz, .halt
+	ret
+; 468
+
+
+DelayFrames: ; 468
+; Wait c frames
+	call DelayFrame
+	dec c
+	jr nz, DelayFrames
+	ret
+; 46f
+
--- /dev/null
+++ b/common/fade.asm
@@ -1,0 +1,134 @@
+; Functions to fade the screen in and out.
+
+
+Function48c: ; 48c
+	ld a, [TimeOfDayPal]
+	ld b, a
+	ld hl, IncGradGBPalTable_11
+	ld a, l
+	sub b
+	ld l, a
+	jr nc, .asm_499
+	dec h
+
+.asm_499
+	ld a, [hli]
+	ld [rBGP], a
+	ld a, [hli]
+	ld [rOBP0], a
+	ld a, [hli]
+	ld [rOBP1], a
+	ret
+; 4a3
+
+
+Function4a3: ; 4a3
+	ld a, [hCGB]
+	and a
+	jr z, .asm_4af
+	ld hl, IncGradGBPalTable_00
+	ld b, 4
+	jr FadeOut
+
+.asm_4af
+	ld hl, IncGradGBPalTable_08
+	ld b, 4
+	jr FadeOut
+; 4b6
+
+Function4b6: ; 4b6
+	ld a, [hCGB]
+	and a
+	jr z, .asm_4c2
+	ld hl, IncGradGBPalTable_05
+	ld b, 3
+	jr FadeOut
+
+.asm_4c2
+	ld hl, IncGradGBPalTable_13
+	ld b, 3
+; 4c7
+
+FadeOut: ; 4c7
+	push de
+	ld a, [hli]
+	call DmgToCgbBGPals
+	ld a, [hli]
+	ld e, a
+	ld a, [hli]
+	ld d, a
+	call DmgToCgbObjPals
+	ld c, 8
+	call DelayFrames
+	pop de
+	dec b
+	jr nz, FadeOut
+	ret
+; 4dd
+
+Function4dd: ; 4dd
+	ld a, [hCGB]
+	and a
+	jr z, .asm_4e9
+	ld hl, IncGradGBPalTable_04 - 1
+	ld b, 4
+	jr FadeIn
+
+.asm_4e9
+	ld hl, IncGradGBPalTable_12 - 1
+	ld b, 4
+	jr FadeIn
+; 4f0
+
+Function4f0: ; 4f0
+	ld a, [hCGB]
+	and a
+	jr z, .asm_4fc
+	ld hl, IncGradGBPalTable_07 - 1
+	ld b, 3
+	jr FadeIn
+
+.asm_4fc
+	ld hl, IncGradGBPalTable_15 - 1
+	ld b, 3
+	; fallthrough
+; 501
+
+FadeIn: ; 501
+	push de
+	ld a, [hld]
+	ld d, a
+	ld a, [hld]
+	ld e, a
+	call DmgToCgbObjPals
+	ld a, [hld]
+	call DmgToCgbBGPals
+	ld c, 8
+	call DelayFrames
+	pop de
+	dec b
+	jr nz, FadeIn
+	ret
+; 517
+
+
+; 517
+IncGradGBPalTable_00: db %11111111, %11111111, %11111111
+IncGradGBPalTable_01: db %11111110, %11111110, %11111110
+IncGradGBPalTable_02: db %11111001, %11111001, %11111001
+IncGradGBPalTable_03: db %11100100, %11100100, %11100100
+IncGradGBPalTable_04: db %11100100, %11100100, %11100100
+IncGradGBPalTable_05: db %10010000, %10010000, %10010000
+IncGradGBPalTable_06: db %01000000, %01000000, %01000000
+IncGradGBPalTable_07: db %00000000, %00000000, %00000000
+;                           bgp       obp1       obp2
+IncGradGBPalTable_08: db %11111111, %11111111, %11111111
+IncGradGBPalTable_09: db %11111110, %11111110, %11111000
+IncGradGBPalTable_10: db %11111001, %11100100, %11100100
+IncGradGBPalTable_11: db %11100100, %11010000, %11100000
+IncGradGBPalTable_12: db %11100100, %11010000, %11100000
+IncGradGBPalTable_13: db %10010000, %10000000, %10010000
+IncGradGBPalTable_14: db %01000000, %01000000, %01000000
+IncGradGBPalTable_15: db %00000000, %00000000, %00000000
+; 547
+
--- /dev/null
+++ b/common/farcall.asm
@@ -1,0 +1,55 @@
+FarCall_de: ; 2d54
+; Call a:de.
+; Preserves other registers.
+
+	ld [hBuffer], a
+	ld a, [hROMBank]
+	push af
+	ld a, [hBuffer]
+	rst Bankswitch
+	call .de
+	jr ReturnFarCall
+
+.de
+	push de
+	ret
+; 2d63
+
+
+FarCall_hl: ; 2d63
+; Call a:hl.
+; Preserves other registers.
+
+	ld [hBuffer], a
+	ld a, [hROMBank]
+	push af
+	ld a, [hBuffer]
+	rst Bankswitch
+	call Function2d82
+; 2d6e
+
+ReturnFarCall: ; 2d6e
+; We want to retain the contents of f.
+; To do this, we can pop to bc instead of af.
+	
+	ld a, b
+	ld [$cfb9], a
+	ld a, c
+	ld [$cfba], a
+	
+; Restore the working bank.
+	pop bc
+	ld a, b
+	rst Bankswitch
+	
+	ld a, [$cfb9]
+	ld b, a
+	ld a, [$cfba]
+	ld c, a
+	ret
+; 2d82
+
+Function2d82: ; 2d82
+	jp [hl]
+; 2d83
+
--- /dev/null
+++ b/common/game_time.asm
@@ -1,0 +1,132 @@
+ResetGameTime: ; 208a
+	xor a
+	ld [GameTimeCap], a
+	ld [GameTimeHours], a
+	ld [GameTimeHours + 1], a
+	ld [GameTimeMinutes], a
+	ld [GameTimeSeconds], a
+	ld [GameTimeFrames], a
+	ret
+; 209e
+
+
+GameTimer: ; 209e
+
+	nop
+
+	ld a, [rSVBK]
+	push af
+	ld a, 1
+	ld [rSVBK], a
+
+	call UpdateGameTimer
+
+	pop af
+	ld [rSVBK], a
+	ret
+; 20ad
+
+
+UpdateGameTimer: ; 20ad
+; Increment the game timer by one frame.
+; The game timer is capped at 999:59:59.00.
+
+
+; Don't update if game logic is paused.
+	ld a, [$c2cd]
+	and a
+	ret nz
+
+; Is the timer paused?
+	ld hl, GameTimerPause
+	bit 0, [hl]
+	ret z
+
+; Is the timer already capped?
+	ld hl, GameTimeCap
+	bit 0, [hl]
+	ret nz
+
+
+; +1 frame
+	ld hl, GameTimeFrames
+	ld a, [hl]
+	inc a
+
+	cp 60 ; frames/second
+	jr nc, .second
+
+	ld [hl], a
+	ret
+
+
+.second
+	xor a
+	ld [hl], a
+
+; +1 second
+	ld hl, GameTimeSeconds
+	ld a, [hl]
+	inc a
+
+	cp 60 ; seconds/minute
+	jr nc, .minute
+
+	ld [hl], a
+	ret
+
+
+.minute
+	xor a
+	ld [hl], a
+
+; +1 minute
+	ld hl, GameTimeMinutes
+	ld a, [hl]
+	inc a
+
+	cp 60 ; minutes/hour
+	jr nc, .hour
+
+	ld [hl], a
+	ret
+
+
+.hour
+	xor a
+	ld [hl], a
+
+; +1 hour
+	ld a, [GameTimeHours]
+	ld h, a
+	ld a, [GameTimeHours + 1]
+	ld l, a
+	inc hl
+
+
+; Cap the timer after 1000 hours.
+	ld a, h
+	cp 1000 / $100
+	jr c, .ok
+
+	ld a, l
+	cp 1000 % $100
+	jr c, .ok
+
+	ld hl, GameTimeCap
+	set 0, [hl]
+
+	ld a, 59 ; 999:59:59.00
+	ld [GameTimeMinutes], a
+	ld [GameTimeSeconds], a
+	ret
+
+
+.ok
+	ld a, h
+	ld [GameTimeHours], a
+	ld a, l
+	ld [GameTimeHours + 1], a
+	ret
+; 210f
+
--- /dev/null
+++ b/common/init.asm
@@ -1,0 +1,225 @@
+Reset: ; 150
+	di
+	call CleanSoundRestart
+	xor a
+	ld [$ffde], a
+	call ClearPalettes
+	xor a
+	ld [rIF], a
+	ld a, 1 ; VBlank int
+	ld [rIE], a
+	ei
+
+	ld hl, $cfbe
+	set 7, [hl]
+
+	ld c, 32
+	call DelayFrames
+
+	jr Init
+; 16e
+
+
+_Start: ; 16e
+	cp $11
+	jr z, .asm_175
+	xor a
+	jr .asm_177
+
+.asm_175
+	ld a, $1
+
+.asm_177
+	ld [hCGB], a
+	ld a, $1
+	ld [$ffea], a
+; 17d
+
+
+Init: ; 17d
+
+	di
+
+	xor a
+	ld [rIF], a
+	ld [rIE], a
+	ld [rRP], a
+	ld [rSCX], a
+	ld [rSCY], a
+	ld [rSB], a
+	ld [rSC], a
+	ld [rWX], a
+	ld [rWY], a
+	ld [rBGP], a
+	ld [rOBP0], a
+	ld [rOBP1], a
+	ld [rTMA], a
+	ld [rTAC], a
+	ld [$d000], a
+
+	ld a, %100 ; Start timer at 4096Hz
+	ld [rTAC], a
+
+.wait
+	ld a, [rLY]
+	cp 145
+	jr nz, .wait
+
+	xor a
+	ld [rLCDC], a
+
+; Clear WRAM bank 0
+	ld hl, $c000
+	ld bc, $d000 - $c000
+.asm_1b1
+	ld [hl], 0
+	inc hl
+	dec bc
+	ld a, b
+	or c
+	jr nz, .asm_1b1
+
+	ld sp, Stack
+
+; Clear HRAM
+	ld a, [hCGB]
+	push af
+	ld a, [$ffea]
+	push af
+	xor a
+	ld hl, $ff80
+	ld bc, $ffff - $ff80
+	call ByteFill
+	pop af
+	ld [$ffea], a
+	pop af
+	ld [hCGB], a
+
+	call ClearWRAM
+	ld a, 1
+	ld [rSVBK], a
+	call ClearVRAM
+	call ClearSprites
+	call Function270
+
+
+	ld a, BANK(LoadPushOAM)
+	rst Bankswitch
+
+	call LoadPushOAM
+
+	xor a
+	ld [$ffde], a
+	ld [hSCX], a
+	ld [hSCY], a
+	ld [rJOYP], a
+
+	ld a, $8 ; HBlank int enable
+	ld [rSTAT], a
+
+	ld a, $90
+	ld [hWY], a
+	ld [rWY], a
+
+	ld a, 7
+	ld [hWX], a
+	ld [rWX], a
+
+	ld a, %11100011
+	; LCD on
+	; Win tilemap 1
+	; Win on
+	; BG/Win tiledata 0
+	; BG Tilemap 0
+	; OBJ 8x8
+	; OBJ on
+	; BG on
+	ld [rLCDC], a
+
+	ld a, $ff
+	ld [$ffcb], a
+
+	callba Function9890
+
+	ld a, $9c
+	ld [$ffd7], a
+
+	xor a
+	ld [hBGMapAddress], a
+
+	callba StartClock
+
+	xor a
+	ld [MBC3LatchClock], a
+	ld [MBC3SRamEnable], a
+
+	ld a, [hCGB]
+	and a
+	jr z, .asm_22b
+	call Function2ff7
+.asm_22b
+
+	xor a
+	ld [rIF], a
+	ld a, %1111 ; VBlank, LCDStat, Timer, Serial interrupts
+	ld [rIE], a
+	ei
+
+	call DelayFrame
+
+	ld a, $30
+	call Predef
+
+	call CleanSoundRestart
+	xor a
+	ld [CurMusic], a
+	jp GameInit
+; 245
+
+
+ClearVRAM: ; 245
+; Wipe VRAM banks 0 and 1
+
+	ld a, 1
+	ld [rVBK], a
+	call .clear
+
+	xor a
+	ld [rVBK], a
+.clear
+	ld hl, VTiles0
+	ld bc, $2000
+	xor a
+	call ByteFill
+	ret
+; 25a
+
+ClearWRAM: ; 25a
+; Wipe swappable WRAM banks (1-7)
+
+	ld a, 1
+.asm_25c
+	push af
+	ld [rSVBK], a
+	xor a
+	ld hl, $d000
+	ld bc, $1000
+	call ByteFill
+	pop af
+	inc a
+	cp 8
+	jr nc, .asm_25c
+	ret
+; 270
+
+Function270: ; 270
+	ld a, $0
+	call GetSRAMBank
+	ld hl, $a000
+	ld bc, $0020
+	xor a
+	call ByteFill
+	call CloseSRAM
+	ret
+; 283
+
--- /dev/null
+++ b/common/joypad.asm
@@ -1,0 +1,491 @@
+JoypadInt: ; 92e
+; Replaced by Joypad, called from VBlank instead of the useless
+; joypad interrupt.
+
+; This is a placeholder in case the interrupt is somehow enabled.
+	reti
+; 92f
+
+ClearJoypadPublic: ; 92f
+	xor a
+; Pressed this frame (delta)
+	ld [hJoyPressed], a
+; Currently pressed
+	ld [hJoyDown], a
+	ret
+; 935
+
+Joypad: ; 935
+; Read the joypad register and translate it to something more
+; workable for use in-game. There are 8 buttons, so we can use
+; one byte to contain all player input.
+
+; Updates:
+
+; hJoypadReleased: released this frame (delta)
+; hJoypadPressed: pressed this frame (delta)
+; hJoypadDown: currently pressed
+; hJoypadSum: pressed so far
+
+; Any of these three bits can be used to disable input.
+	ld a, [$cfbe]
+	and %11010000
+	ret nz
+	
+; If we're saving, input is disabled.
+	ld a, [$c2cd]
+	and a
+	ret nz
+	
+; We can only get four inputs at a time.
+; We take d-pad first for no particular reason.
+	ld a, D_PAD
+	ld [rJOYP], a
+; Read twice to give the request time to take.
+	ld a, [rJOYP]
+	ld a, [rJOYP]
+	
+; The Joypad register output is in the lo nybble (inversed).
+; We make the hi nybble of our new container d-pad input.
+	cpl
+	and $f
+	swap a
+	
+; We'll keep this in b for now.
+	ld b, a
+	
+; Buttons make 8 total inputs (A, B, Select, Start).
+; We can fit this into one byte.
+	ld a, BUTTONS
+	ld [rJOYP], a
+; Wait for input to stabilize.
+	ld a, [rJOYP]
+	ld a, [rJOYP]
+	ld a, [rJOYP]
+	ld a, [rJOYP]
+	ld a, [rJOYP]
+	ld a, [rJOYP]
+; Buttons take the lo nybble.
+	cpl
+	and $f
+	or b
+	ld b, a
+	
+; Reset the joypad register since we're done with it.
+	ld a, $30
+	ld [rJOYP], a
+	
+; To get the delta we xor the last frame's input with the new one.
+	ld a, [hJoypadDown] ; last frame
+	ld e, a
+	xor b
+	ld d, a
+; Released this frame:
+	and e
+	ld [hJoypadReleased], a
+; Pressed this frame:
+	ld a, d
+	and b
+	ld [hJoypadPressed], a
+	
+; Add any new presses to the list of collective presses:
+	ld c, a
+	ld a, [hJoypadSum]
+	or c
+	ld [hJoypadSum], a
+	
+; Currently pressed:
+	ld a, b
+	ld [hJoypadDown], a
+	
+; Now that we have the input, we can do stuff with it.
+
+; For example, soft reset:
+	and BUTTON_A | BUTTON_B | SELECT | START
+	cp  BUTTON_A | BUTTON_B | SELECT | START
+	jp z, Reset
+	
+	ret
+; 984
+
+
+GetJoypadPublic: ; 984
+; Update mirror joypad input from hJoypadDown (real input)
+
+; hJoyReleased: released this frame (delta)
+; hJoyPressed: pressed this frame (delta)
+; hJoyDown: currently pressed
+
+; bit 0 A
+;     1 B
+;     2 SELECT
+;     3 START
+;     4 RIGHT
+;     5 LEFT
+;     6 UP
+;     7 DOWN
+
+	push af
+	push hl
+	push de
+	push bc
+	
+; The player input can be automated using an input stream.
+; See more below.
+	ld a, [InputType]
+	cp a, AUTO_INPUT
+	jr z, .auto
+
+; To get deltas, take this and last frame's input.
+	ld a, [hJoypadDown] ; real input
+	ld b, a
+	ld a, [hJoyDown] ; last frame mirror
+	ld e, a
+	
+; Released this frame:
+	xor b
+	ld d, a
+	and e
+	ld [hJoyReleased], a
+	
+; Pressed this frame:
+	ld a, d
+	and b
+	ld [hJoyPressed], a
+	
+; It looks like the collective presses got commented out here.
+	ld c, a
+	
+; Currently pressed:
+	ld a, b
+	ld [hJoyDown], a ; frame input
+	
+.quit
+	pop bc
+	pop de
+	pop hl
+	pop af
+	ret	
+
+.auto
+; Use a predetermined input stream (used in the catching tutorial).
+
+; Stream format: [input][duration]
+; A value of $ff will immediately end the stream.
+
+; Read from the input stream.
+	ld a, [hROMBank]
+	push af
+	ld a, [AutoInputBank]
+	rst Bankswitch
+	
+	ld hl, AutoInputAddress
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	
+; We only update when the input duration has expired.
+	ld a, [AutoInputLength]
+	and a
+	jr z, .updateauto
+	
+; Until then, don't change anything.
+	dec a
+	ld [AutoInputLength], a
+	pop af
+	rst Bankswitch
+	jr .quit
+	
+	
+.updateauto
+; An input of $ff will end the stream.
+	ld a, [hli]
+	cp a, $ff
+	jr z, .stopauto
+	ld b, a
+	
+; A duration of $ff will end the stream indefinitely.
+	ld a, [hli]
+	ld [AutoInputLength], a
+	cp a, $ff
+	jr nz, .next
+	
+; The current input is overwritten.
+	dec hl
+	dec hl
+	ld b, NO_INPUT
+	jr .finishauto
+	
+.next
+; On to the next input...
+	ld a, l
+	ld [AutoInputAddress], a
+	ld a, h
+	ld [AutoInputAddress+1], a
+	jr .finishauto
+	
+.stopauto
+	call StopAutoInput
+	ld b, NO_INPUT
+	
+.finishauto
+	pop af
+	rst Bankswitch
+	ld a, b
+	ld [hJoyPressed], a ; pressed
+	ld [hJoyDown], a ; input
+	jr .quit
+; 9ee
+
+
+StartAutoInput: ; 9ee
+; Start reading automated input stream at a:hl.
+	
+	ld [AutoInputBank], a
+	ld a, l
+	ld [AutoInputAddress], a
+	ld a, h
+	ld [AutoInputAddress+1], a
+; Start reading the stream immediately.
+	xor a
+	ld [AutoInputLength], a
+; Reset input mirrors.
+	xor a
+	ld [hJoyPressed], a ; pressed this frame
+	ld [hJoyReleased], a ; released this frame
+	ld [hJoyDown], a ; currently pressed
+	
+	ld a, AUTO_INPUT
+	ld [InputType], a
+	ret
+; a0a
+
+
+StopAutoInput: ; a0a
+; Clear variables related to automated input.
+	xor a
+	ld [AutoInputBank], a
+	ld [AutoInputAddress], a
+	ld [AutoInputAddress+1], a
+	ld [AutoInputLength], a
+; Back to normal input.
+	ld [InputType], a
+	ret
+; a1b
+
+
+Functiona1b: ; a1b
+
+	call DelayFrame
+
+	push bc
+	call Functiona57
+	pop bc
+
+	ld a, [hJoyDown]
+	cp D_UP | SELECT | BUTTON_B
+	jr z, .asm_a34
+
+	ld a, [$ffa9]
+	and START | BUTTON_A
+	jr nz, .asm_a34
+
+	dec c
+	jr nz, Functiona1b
+
+	and a
+	ret
+
+.asm_a34
+	scf
+	ret
+; a36
+
+
+Functiona36: ; a36
+	call DelayFrame
+	call GetJoypadPublic
+	ld a, [hJoyPressed]
+	and BUTTON_A | BUTTON_B
+	ret nz
+	call RTC
+	jr Functiona36
+; a46
+
+Functiona46: ; a46
+	ld a, [hOAMUpdate]
+	push af
+	ld a, 1
+	ld [hOAMUpdate], a
+	call WaitBGMap
+	call Functiona36
+	pop af
+	ld [hOAMUpdate], a
+	ret
+; a57
+
+Functiona57: ; a57
+	call GetJoypadPublic
+	ld a, [$ffaa]
+	and a
+	ld a, [hJoyPressed]
+	jr z, .asm_a63
+	ld a, [hJoyDown]
+.asm_a63
+	ld [$ffa9], a
+	ld a, [hJoyPressed]
+	and a
+	jr z, .asm_a70
+	ld a, 15
+	ld [TextDelayFrames], a
+	ret
+
+.asm_a70
+	ld a, [TextDelayFrames]
+	and a
+	jr z, .asm_a7a
+	xor a
+	ld [$ffa9], a
+	ret
+
+.asm_a7a
+	ld a, 5
+	ld [TextDelayFrames], a
+	ret
+; a80
+
+Functiona80: ; a80
+	ld a, [$ffaf]
+	push af
+	ld a, [$ffb0]
+	push af
+	xor a
+	ld [$ffaf], a
+	ld a, $6
+	ld [$ffb0], a
+.asm_a8d
+	push hl
+	ld hl, $c606
+	call Functionb06
+	pop hl
+	call Functiona57
+	ld a, [$ffa9]
+	and $3
+	jr z, .asm_a8d
+	pop af
+	ld [$ffb0], a
+	pop af
+	ld [$ffaf], a
+	ret
+; aa5
+
+Functionaa5: ; aa5
+	call Functiona57
+	ld a, [$ffa9]
+	and BUTTON_A | BUTTON_B
+	jr z, Functionaa5
+	ret
+; aaf
+
+Functionaaf: ; aaf
+	ld a, [InLinkBattle]
+	and a
+	jr nz, .asm_ac1
+	call Functionac6
+	push de
+	ld de, SFX_READ_TEXT_2
+	call StartSFX
+	pop de
+	ret
+
+.asm_ac1
+	ld c, 65
+	jp DelayFrames
+; ac6
+
+Functionac6: ; ac6
+	ld a, [hOAMUpdate]
+	push af
+	ld a, $1
+	ld [hOAMUpdate], a
+	ld a, [InputType]
+	or a
+	jr z, .asm_ad9
+	callba Function1de28a
+.asm_ad9
+	call Functionaf5
+	call Functiona57
+	ld a, [hJoyPressed]
+	and $3
+	jr nz, .asm_af1
+	call RTC
+	ld a, $1
+	ld [hBGMapMode], a
+	call DelayFrame
+	jr .asm_ad9
+
+.asm_af1
+	pop af
+	ld [hOAMUpdate], a
+	ret
+; af5
+
+Functionaf5: ; af5
+	ld a, [$ff9b]
+	and $10
+	jr z, .asm_aff
+	ld a, $ee
+	jr .asm_b02
+
+.asm_aff
+	ld a, [$c605]
+
+.asm_b02
+	ld [$c606], a
+	ret
+; b06
+
+Functionb06: ; b06
+	push bc
+	ld a, [hl]
+	ld b, a
+	ld a, $ee
+	cp b
+	pop bc
+	jr nz, .asm_b27
+	ld a, [$ffaf]
+	dec a
+	ld [$ffaf], a
+	ret nz
+	ld a, [$ffb0]
+	dec a
+	ld [$ffb0], a
+	ret nz
+	ld a, $7a
+	ld [hl], a
+	ld a, $ff
+	ld [$ffaf], a
+	ld a, $6
+	ld [$ffb0], a
+	ret
+
+.asm_b27
+	ld a, [$ffaf]
+	and a
+	ret z
+	dec a
+	ld [$ffaf], a
+	ret nz
+	dec a
+	ld [$ffaf], a
+	ld a, [$ffb0]
+	dec a
+	ld [$ffb0], a
+	ret nz
+	ld a, $6
+	ld [$ffb0], a
+	ld a, $ee
+	ld [hl], a
+	ret
+; b40
+
--- /dev/null
+++ b/common/lcd.asm
@@ -1,0 +1,81 @@
+; LCD handling
+
+
+Function547: ; 547
+	ld a, [hLCDStatCustom]
+	cp rSCX & $ff
+	ret nz
+	ld c, a
+	ld a, [LYOverrides]
+	ld [$ff00+c], a
+	ret
+; 552
+
+
+LCD: ; 552
+	push af
+	ld a, [hLCDStatCustom]
+	and a
+	jr z, .done
+
+; At this point it's assumed we're in WRAM bank 5!
+	push bc
+	ld a, [rLY]
+	ld c, a
+	ld b, LYOverrides >> 8
+	ld a, [bc]
+	ld b, a
+	ld a, [hLCDStatCustom]
+	ld c, a
+	ld a, b
+	ld [$ff00+c], a
+	pop bc
+
+.done
+	pop af
+	reti
+; 568
+
+
+DisableLCD: ; 568
+; Turn the LCD off
+
+; Don't need to do anything if the LCD is already off
+	ld a, [rLCDC]
+	bit 7, a ; lcd enable
+	ret z
+
+	xor a
+	ld [rIF], a
+	ld a, [rIE]
+	ld b, a
+	
+; Disable VBlank
+	res 0, a ; vblank
+	ld [rIE], a
+
+.wait
+; Wait until VBlank would normally happen
+	ld a, [rLY]
+	cp 145
+	jr nz, .wait
+
+	ld a, [rLCDC]
+	and %01111111 ; lcd enable off
+	ld [rLCDC], a
+
+	xor a
+	ld [rIF], a
+	ld a, b
+	ld [rIE], a
+	ret
+; 58a
+
+
+EnableLCD: ; 58a
+	ld a, [rLCDC]
+	set 7, a ; lcd enable
+	ld [rLCDC], a
+	ret
+; 591
+
--- /dev/null
+++ b/common/map_objects.asm
@@ -1,0 +1,683 @@
+; Functions handling map objects.
+
+
+GetSpritePalette: ; 17ff
+	push hl
+	push de
+	push bc
+	ld c, a
+	callba _GetSpritePalette
+	ld a, c
+	pop bc
+	pop de
+	pop hl
+	ret
+; 180e
+
+
+Function180e: ; 180e
+	push hl
+	push bc
+	ld hl, $d156
+	ld c, $1f
+	ld b, a
+	ld a, [hConnectionStripLength]
+	cp $0
+	jr z, .asm_182b
+	ld a, b
+.asm_181d
+	cp [hl]
+	jr z, .asm_1830
+	inc hl
+	inc hl
+	dec c
+	jr nz, .asm_181d
+	ld a, [$d155]
+	scf
+	jr .asm_1833
+
+.asm_182b
+	ld a, [$d155]
+	jr .asm_1833
+
+.asm_1830
+	inc hl
+	xor a
+	ld a, [hl]
+
+.asm_1833
+	pop bc
+	pop hl
+	ret
+; 1836
+
+Function1836: ; 1836
+	push de
+	push hl
+
+	ld b, a
+	ld a, [hROMBank]
+	push af
+	ld a, BANK(Function142a7)
+	rst Bankswitch
+
+	ld a, b
+	call Function142a7
+	ld c, a
+
+	pop de
+	ld a, d
+	rst Bankswitch
+
+	pop hl
+	pop de
+	ret
+; 184a
+
+
+
+Function184a: ; 184a
+	ld a, [StandingTile]
+	call GetTileCollision
+	ld b, a
+	ret
+; 1852
+
+Function1852: ; 1852
+	ld a, [StandingTile]
+	call GetTileCollision
+	sub 1
+	ret z
+	and a
+	ret
+; 185d
+
+
+GetTileCollision: ; 185d
+; Get the collision type of tile a.
+
+	push de
+	push hl
+
+	ld hl, TileCollisionTable
+	ld e, a
+	ld d, 0
+	add hl, de
+
+	ld a, [hROMBank]
+	push af
+	ld a, BANK(TileCollisionTable)
+	rst Bankswitch
+	ld e, [hl]
+	pop af
+	rst Bankswitch
+
+	ld a, e
+	and $f ; lo nybble only
+
+	pop hl
+	pop de
+	ret
+; 1875
+
+
+Function1875: ; 1875
+	ld d, a
+	and $f0
+	cp $10
+	jr z, .asm_1882
+	cp $20
+	jr z, .asm_1888
+	scf
+	ret
+
+.asm_1882
+	ld a, d
+	and 7
+	ret z
+	scf
+	ret
+
+.asm_1888
+	ld a, d
+	and 7
+	ret z
+	scf
+	ret
+; 188e
+
+Function188e: ; 188e
+	cp $14
+	ret z
+	cp $1c
+	ret
+; 1894
+
+CheckCutTreeTile: ; 1894
+	cp $12
+	ret z
+	cp $1a
+	ret
+; 189a
+
+CheckHeadbuttTreeTile: ; 189a
+	cp $15
+	ret z
+	cp $1d
+	ret
+; 18a0
+
+CheckCounterTile: ; 18a0
+	cp $90
+	ret z
+	cp $98
+	ret
+; 18a6
+
+CheckPitTile: ; 18a6
+	cp $60
+	ret z
+	cp $68
+	ret
+; 18ac
+
+CheckIceTile: ; 18ac
+	cp $23
+	ret z
+	cp $2b
+	ret z
+	scf
+	ret
+; 18b4
+
+CheckWhirlpoolTile: ; 18b4
+	nop
+	cp $24
+	ret z
+	cp $2c
+	ret z
+	scf
+	ret
+; 18bd
+
+CheckWaterfallTile: ; 18bd
+	cp $33
+	ret z
+	cp $3b
+	ret
+; 18c3
+
+CheckStandingOnEntrance: ; 18c3
+	ld a, [StandingTile]
+	cp $71 ; door
+	ret z
+	cp $79
+	ret z
+	cp $7a ; stairs
+	ret z
+	cp $7b ; cave
+	ret
+; 18d2
+
+
+GetMapObject: ; 18d2
+; Return the location of map object a in bc.
+	ld hl, MapObjects
+	ld bc, $10
+	call AddNTimes
+	ld b, h
+	ld c, l
+	ret
+; 18de
+
+
+Function18de: ; 18de
+	ld [hConnectionStripLength], a
+	call GetMapObject
+	ld hl, $0000
+	add hl, bc
+	ld a, [hl]
+	cp $ff
+	jr z, .asm_18f3
+	ld [hConnectedMapWidth], a
+	call Function1ae5
+	and a
+	ret
+
+.asm_18f3
+	scf
+	ret
+; 18f5
+
+Function18f5: ; 18f5
+	ld hl, $0006
+	add hl, bc
+	ld a, [hl]
+	cp $ff
+	jr nz, .asm_1921
+	ld hl, $0007
+	add hl, bc
+	ld a, [hl]
+	cp $ff
+	jr z, .asm_191c
+	ld hl, .data_191e
+	ld a, [TimeOfDay]
+	add l
+	ld l, a
+	jr nc, .asm_1912
+	inc h
+
+.asm_1912
+	ld a, [hl]
+	ld hl, $0007
+	add hl, bc
+	and [hl]
+	jr nz, .asm_191c
+	scf
+	ret
+
+.asm_191c
+	and a
+	ret
+
+.data_191e
+	db $1
+	db $2
+	db $4
+
+.asm_1921
+	ld hl, $0006
+	add hl, bc
+	ld d, [hl]
+	ld hl, $0007
+	add hl, bc
+	ld e, [hl]
+	ld hl, hHours
+	ld a, d
+	cp e
+	jr z, .asm_1949
+	jr c, .asm_193f
+	ld a, [hl]
+	cp d
+	jr nc, .asm_1949
+	cp e
+	jr c, .asm_1949
+	jr z, .asm_1949
+	jr .asm_194b
+
+.asm_193f
+	ld a, e
+	cp [hl]
+	jr c, .asm_194b
+	ld a, [hl]
+	cp d
+	jr nc, .asm_1949
+	jr .asm_194b
+
+.asm_1949
+	and a
+	ret
+
+.asm_194b
+	scf
+	ret
+; 194d
+
+Function194d: ; 194d
+	ld [hConnectionStripLength], a
+	call GetMapObject
+	call $40e7
+	ret
+; 1956
+
+
+
+Function1956: ; 1956
+	ld [hConnectionStripLength], a
+	call Function271e
+	ld a, [hConnectionStripLength]
+	call GetMapObject
+	ld a, $2
+	ld hl, $40e7
+	rst FarCall
+	ret
+; 1967
+
+Function1967: ; 1967
+	ld [hConnectionStripLength], a
+	call GetMapObject
+	ld hl, $0000
+	add hl, bc
+	ld a, [hl]
+	cp $ff
+	ret z
+	ld [hl], $ff
+	push af
+	call Function1985
+	pop af
+	call Function1ae5
+	callba Function4357
+	ret
+; 1985
+
+Function1985: ; 1985
+	ld hl, $d4cd
+	cp [hl]
+	jr z, .asm_1990
+	ld hl, $d4ce
+	cp [hl]
+	ret nz
+
+.asm_1990
+	callba Function581f
+	ld a, $ff
+	ld [$d4cd], a
+	ld [$d4ce], a
+	ret
+; 199f
+
+Function199f: ; 199f
+	call Function1967
+	call Function2712
+	ret
+; 19a6
+
+Function19a6: ; 19a6
+	push hl
+	call GetMapObject
+	ld d, b
+	ld e, c
+	ld a, $ff
+	ld [de], a
+	inc de
+	pop hl
+	ld bc, $000f
+	call CopyBytes
+	ret
+; 19b8
+
+Function19b8: ; 19b8
+	call GetMapObject
+	ld hl, $0000
+	add hl, bc
+	ld a, [hl]
+	push af
+	ld [hl], $ff
+	inc hl
+	ld bc, $000f
+	xor a
+	call ByteFill
+	pop af
+	cp $ff
+	ret z
+	cp $d
+	ret nc
+	ld b, a
+	ld a, [$d4cd]
+	cp b
+	jr nz, .asm_19de
+	ld a, $ff
+	ld [$d4cd], a
+
+.asm_19de
+	ld a, b
+	call Function1ae5
+	callba Function4357
+	ret
+; 19e9
+
+
+
+Function19e9: ; 19e9
+	ld [$c2e2], a
+	ld a, [hROMBank]
+	ld [$c2e3], a
+	ld a, l
+	ld [$c2e4], a
+	ld a, h
+	ld [$c2e5], a
+	ld a, [$c2e2]
+	call Function18de
+	ret c
+	ld hl, $0003
+	add hl, bc
+	ld [hl], $14
+	ld hl, $0009
+	add hl, bc
+	ld [hl], $0
+	ld hl, VramState
+	set 7, [hl]
+	and a
+	ret
+; 1a13
+
+
+
+Function1a13: ; 1a13
+	push bc
+	push de
+	ld hl, $d4d6
+	ld de, $0028
+	ld c, $d
+.asm_1a1d
+	ld a, [hl]
+	and a
+	jr z, .asm_1a28
+	add hl, de
+	dec c
+	jr nz, .asm_1a1d
+	xor a
+	jr .asm_1a2c
+
+.asm_1a28
+	ld a, $d
+	sub c
+	scf
+
+.asm_1a2c
+	pop de
+	pop bc
+	ret
+; 1a2f
+
+
+
+Function1a2f: ; 1a2f
+	ld hl, $0003
+	add hl, bc
+	ld a, [hl]
+	cp $25
+	jr c, .asm_1a39
+	xor a
+
+.asm_1a39
+	ld hl, Data4273
+	ld e, a
+	ld d, 0
+	add hl, de
+	add hl, de
+	add hl, de
+	add hl, de
+	add hl, de
+	add hl, de
+	ld a, [hl]
+	ret
+; 1a47
+
+Function1a47: ; 1a47
+	push bc
+	push de
+	ld e, a
+	ld d, 0
+	ld hl, Data4273 + 1
+	add hl, de
+	add hl, de
+	add hl, de
+	add hl, de
+	add hl, de
+	add hl, de
+	ld a, BANK(Data4273)
+	call GetFarByte
+	add a
+	add a
+	and $c
+	pop de
+	pop bc
+	ret
+; 1a61
+
+
+Function1a61: ; 1a61
+	ld l, a
+	ld a, [hROMBank]
+	push af
+	ld a, BANK(Data4273)
+	rst Bankswitch
+	ld a, l
+	push bc
+
+	call Function1a71
+
+	pop bc
+	pop af
+	rst Bankswitch
+
+	ret
+; 1a71
+
+Function1a71: ; 1a71
+	ld hl, $0003
+	add hl, de
+	ld [hl], a
+	push de
+	ld e, a
+	ld d, 0
+	ld hl, Data4273 + 1
+	add hl, de
+	add hl, de
+	add hl, de
+	add hl, de
+	add hl, de
+	add hl, de
+	ld b, h
+	ld c, l
+	pop de
+	ld a, [bc]
+	inc bc
+	rlca
+	rlca
+	and $c
+	ld hl, $0008
+	add hl, de
+	ld [hl], a
+	ld a, [bc]
+	inc bc
+	ld hl, $000b
+	add hl, de
+	ld [hl], a
+	ld a, [bc]
+	inc bc
+	ld hl, $0004
+	add hl, de
+	ld [hl], a
+	ld a, [bc]
+	inc bc
+	ld hl, $0005
+	add hl, de
+	ld [hl], a
+	ld a, [bc]
+	inc bc
+	ld hl, $0006
+	add hl, de
+	ld [hl], a
+	ret
+; 1aae
+
+Function1aae: ; 1aae
+	ld a, [hROMBank]
+	push af
+	ld a, [hli]
+	rst Bankswitch
+
+	ld a, [hli]
+	ld d, [hl]
+	ld hl, $001b
+	add hl, bc
+	add [hl]
+	ld e, a
+	ld a, d
+	adc $0
+	ld d, a
+	inc [hl]
+	ld a, [de]
+	ld h, a
+	pop af
+	rst Bankswitch
+
+	ld a, h
+	ret
+; 1ac6
+
+Function1ac6: ; 1ac6
+	ld hl, VramState
+	set 0, [hl]
+	ret
+; 1acc
+
+Function1acc: ; 1acc
+	ld hl, VramState
+	res 0, [hl]
+	ret
+; 1ad2
+
+
+Function1ad2: ; 1ad2
+	ld a, [VramState]
+	bit 0, a
+	ret z
+	callba Function55e0
+	callba Function5920
+	ret
+; 1ae5
+
+
+Function1ae5: ; 1ae5
+	ld bc, $0028
+	ld hl, $d4d6
+	call AddNTimes
+	ld b, h
+	ld c, l
+	ret
+; 1af1
+
+Function1af1: ; 1af1
+	ld hl, $0000
+	add hl, bc
+	ld a, [hl]
+	and a
+	ret
+; 1af8
+
+Function1af8: ; 1af8
+	push af
+	ld hl, $0008
+	add hl, bc
+	ld a, [hl]
+	and $f3
+	ld e, a
+	pop af
+	and $c
+	or e
+	ld [hl], a
+	ret
+; 1b07
+
+
+GetSpriteDirection: ; 1b07
+	ld hl, $0008
+	add hl, bc
+	ld a, [hl]
+	and $c
+	ret
+; 1b0f
+
--- /dev/null
+++ b/common/menu.asm
@@ -1,0 +1,603 @@
+; Functions used in displaying and handling menus.
+
+
+LoadMenuDataHeader: ; 0x1d35
+	call Function1d3c
+	call Function1c00
+	ret
+
+Function1d3c: ; 0x1d3c
+	ld de, $cf81
+	ld bc, $0010
+	call CopyBytes
+	ld a, [hROMBank]
+	ld [$cf8a], a
+	ret
+; 0x1d4b
+
+Function1d4b: ; 1d4b
+	ld [$cf88], a
+	ret
+; 1d4f
+
+
+Function1d4f: ; 1d4f
+	push hl
+	call Function1d58
+	pop hl
+	jp PrintText
+; 1d57
+
+Function1d57: ; 1d57
+	ret
+; 1d58
+
+Function1d58: ; 1d58
+	ld hl, MenuDataHeader_0x1d5f
+	call LoadMenuDataHeader
+	ret
+; 1d5f
+
+MenuDataHeader_0x1d5f: ; 1d5f
+	db $40 ; tile backup
+	db 12, 0 ; start coords
+	db 17, 19 ; end coords
+	dw VTiles0
+	db 0 ; default option
+; 1d67
+
+Function1d67: ; 1d67
+	call Function1d4f
+	call Function1c17
+	ret
+; 1d6e
+
+Function1d6e: ; 1d6e
+	ld hl, MenuDataHeader_0x1d75
+	call LoadMenuDataHeader
+	ret
+; 1d75
+
+MenuDataHeader_0x1d75: ; 1d75
+	db $40 ; tile backup
+	db 0, 0 ; start coords
+	db 17, 19 ; end coords
+	dw $0000
+	db 1 ; default option
+; 1d7d
+
+Function1d7d: ; 1d7d
+	call Function1c07
+	ret
+; 1d81
+
+Function1d81: ; 0x1d81
+	xor a
+	ld [hBGMapMode], a
+	call Function1cbb
+	call Function1ad2
+	call Function1c89
+	call Function321c
+	call Function1c66
+	ld a, [$cf91]
+	bit 7, a
+	jr z, .asm_1da7 ; 0x1d98 $d
+	call Function1c10
+	call Function1bc9
+	call Function1ff8
+	bit 1, a
+	jr z, .asm_1da9 ; 0x1da5 $2
+.asm_1da7
+	scf
+	ret
+.asm_1da9
+	and a
+	ret
+; 0x1dab
+
+Function1dab: ; 1dab
+	call LoadMenuDataHeader
+	call Function1d81
+	call Function1c17
+	ld a, [$cfa9]
+	ret
+; 1db8
+
+Function1db8: ; 0x1db8
+	push hl
+	push bc
+	push af
+	ld hl, $cf86
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	inc hl
+	inc hl
+	pop af
+	call GetNthString
+	ld d, h
+	ld e, l
+	call CopyName1
+	pop bc
+	pop hl
+	ret
+; 0x1dcf
+
+
+Function1dcf: ; 1dcf
+	ld bc, $0e07
+
+Function1dd2: ; 1dd2
+	jr Function1dd9
+
+Function1dd4: ; 1dd4
+	call LoadMenuDataHeader
+	jr Function1dfe
+
+Function1dd9: ; 1dd9
+	push bc
+	ld hl, MenuDataHeader_0x1e1d
+	call Function1d3c
+	pop bc
+	ld a, b
+	cp $e
+	jr nz, .asm_1de9
+	ld a, $e
+	ld b, a
+
+.asm_1de9
+	ld a, b
+	ld [$cf83], a
+	add $5
+	ld [$cf85], a
+	ld a, c
+	ld [$cf82], a
+	add $4
+	ld [$cf84], a
+	call Function1c00
+
+Function1dfe: ; 1dfe
+	call Function1d81
+	push af
+	ld c, $f
+	call DelayFrames
+	call Function1c17
+	pop af
+	jr c, .asm_1e16
+	ld a, [$cfa9]
+	cp $2
+	jr z, .asm_1e16
+	and a
+	ret
+
+.asm_1e16
+	ld a, $2
+	ld [$cfa9], a
+	scf
+	ret
+; 1e1d
+
+MenuDataHeader_0x1e1d: ; 1e1d
+	db $40 ; tile backup
+	db 5, 10 ; start coords
+	db 9, 15 ; end coords
+	dw MenuData2_0x1e25
+	db 1 ; default option
+; 1e25
+
+MenuData2_0x1e25: ; 1e25
+	db $c0 ; flags
+	db 2
+	db "YES@"
+	db "NO@"
+; 1e2e
+
+Function1e2e: ; 1e2e
+	call Function1e35
+	call Function1c00
+	ret
+; 1e35
+
+Function1e35: ; 1e35
+	push de
+	call Function1d3c
+	pop de
+	ld a, [$cf83]
+	ld h, a
+	ld a, [$cf85]
+	sub h
+	ld h, a
+	ld a, d
+	ld [$cf83], a
+	add h
+	ld [$cf85], a
+	ld a, [$cf82]
+	ld l, a
+	ld a, [$cf84]
+	sub l
+	ld l, a
+	ld a, e
+	ld [$cf82], a
+	add l
+	ld [$cf84], a
+	ret
+; 1e5d
+
+Function1e5d: ; 1e5d
+	call MenuFunc_1e7f
+	call MenuWriteText
+	call Function1eff
+	call Function1f23
+	call Function1bdd
+	call Function1ff8
+	ret
+; 1e70
+
+SetUpMenu: ; 1e70
+	call MenuFunc_1e7f ; ???
+	call MenuWriteText
+	call Function1eff ; set up selection pointer
+	ld hl, $cfa5
+	set 7, [hl]
+	ret
+
+MenuFunc_1e7f: ; 0x1e7f
+	call Function1c66
+	call Function1ebd
+	call Function1ea6
+	call Function1cbb
+	ret
+
+MenuWriteText: ; 0x1e8c
+	xor a
+	ld [hBGMapMode], a
+	call Function1ebd ; sort out the text 
+	call Function1eda ; actually write it
+	call Function2e31
+	ld a, [hOAMUpdate]
+	push af
+	ld a, $1
+	ld [hOAMUpdate], a
+	call Function321c
+	pop af
+	ld [hOAMUpdate], a
+	ret
+; 0x1ea6
+
+Function1ea6: ; 1ea6
+	ld a, [$cf83]
+	ld c, a
+	ld a, [$cf85]
+	sub c
+	ld c, a
+	ld a, [$cf92]
+	add a
+	inc a
+	ld b, a
+	ld a, [$cf82]
+	add b
+	ld [$cf84], a
+	ret
+; 1ebd
+
+Function1ebd: ; 1ebd
+	ld hl, $cf93
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	ld a, [$cf76]
+	and a
+	jr z, .asm_1ed3
+	ld b, a
+	ld c, $ff
+.asm_1ecc
+	ld a, [hli]
+	cp c
+	jr nz, .asm_1ecc
+	dec b
+	jr nz, .asm_1ecc
+
+.asm_1ed3
+	ld d, h
+	ld e, l
+	ld a, [hl]
+	ld [$cf92], a
+	ret
+; 1eda
+
+Function1eda: ; 1eda
+	call Function1cfd
+	ld bc, $002a
+	add hl, bc
+.asm_1ee1
+	inc de
+	ld a, [de]
+	cp $ff
+	ret z
+	ld [MenuSelection], a
+	push de
+	push hl
+	ld d, h
+	ld e, l
+	ld hl, $cf95
+	call Function1efb
+	pop hl
+	ld de, $0028
+	add hl, de
+	pop de
+	jr .asm_1ee1
+; 1efb
+
+Function1efb: ; 1efb
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	jp [hl]
+; 1eff
+
+Function1eff: ; 1eff
+	call Function1c10
+	ld hl, $cfa8
+	ld a, [$cf91]
+	bit 3, a
+	jr z, .asm_1f0e
+	set 3, [hl]
+
+.asm_1f0e
+	ld a, [$cf91]
+	bit 2, a
+	jr z, .asm_1f19
+	set 5, [hl]
+	set 4, [hl]
+
+.asm_1f19
+	ret
+; 1f1a
+
+
+Function1f1a: ; 1f1a
+	call Function1bd3
+	ld hl, $cfa8
+	and [hl]
+	jr Function1f2a
+; 1f23
+
+Function1f23: ; 1f23
+	xor a
+	ld [$cf73], a
+	call Function1bc9
+; 1f2a
+
+Function1f2a: ; 1f2a
+	bit 0, a
+	jr nz, .asm_1f52
+	bit 1, a
+	jr nz, .asm_1f6d
+	bit 3, a
+	jr nz, .asm_1f6d
+	bit 4, a
+	jr nz, .asm_1f44
+	bit 5, a
+	jr nz, .asm_1f4b
+	xor a
+	ld [$cf73], a
+	jr .asm_1f57
+
+.asm_1f44
+	ld a, $10
+	ld [$cf73], a
+	jr .asm_1f57
+
+.asm_1f4b
+	ld a, $20
+	ld [$cf73], a
+	jr .asm_1f57
+
+.asm_1f52
+	ld a, $1
+	ld [$cf73], a
+
+.asm_1f57
+	call Function1ebd
+	ld a, [$cfa9]
+	ld l, a
+	ld h, $0
+	add hl, de
+	ld a, [hl]
+	ld [MenuSelection], a
+	ld a, [$cfa9]
+	ld [$cf88], a
+	and a
+	ret
+
+.asm_1f6d
+	ld a, $2
+	ld [$cf73], a
+	ld a, $ff
+	ld [MenuSelection], a
+	scf
+	ret
+; 1f79
+
+Function1f79: ; 1f79
+	push de
+	ld hl, $cf97
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	ld a, [MenuSelection]
+	call GetNthString
+	ld d, h
+	ld e, l
+	pop hl
+	call PlaceString
+	ret
+; 1f8d
+
+Function1f8d: ; 1f8d
+	push de
+	ld a, [MenuSelection]
+	call Function1fb1
+	inc hl
+	inc hl
+	ld a, [hli]
+	ld d, [hl]
+	ld e, a
+	pop hl
+	call PlaceString
+	ret
+; 1f9e
+
+Function1f9e: ; 1f9e
+	call Function1fb1
+	inc hl
+	inc hl
+	ld a, [hli]
+	ld d, [hl]
+	ld e, a
+	ret
+; 1fa7
+
+Function1fa7: ; 1fa7
+	ld a, [MenuSelection]
+	call Function1fb1
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	jp [hl]
+; 1fb1
+
+Function1fb1: ; 1fb1
+	ld e, a
+	ld d, $0
+	ld hl, $cf97
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	add hl, de
+	add hl, de
+	add hl, de
+	add hl, de
+	ret
+; 1fbf
+
+Function1fbf: ; 1fbf
+	ld hl, $cf71
+	call Function1ff0
+	ld hl, $cf81
+	call Function1ff0
+	ld hl, $cf91
+	call Function1ff0
+	ld hl, $cfa1
+	call Function1ff0
+	ld a, [rSVBK]
+	push af
+	ld a, $7
+	ld [rSVBK], a
+	xor a
+	ld hl, $dfff
+	ld [hld], a
+	ld [hld], a
+	ld a, l
+	ld [$cf71], a
+	ld a, h
+	ld [$cf72], a
+	pop af
+	ld [rSVBK], a
+	ret
+; 1ff0
+
+Function1ff0: ; 1ff0
+	ld bc, $0010
+	xor a
+	call ByteFill
+	ret
+; 1ff8
+
+Function1ff8: ; 1ff8
+	push af
+	and $3
+	jr z, .asm_2007
+	ld hl, $cf81
+	bit 3, [hl]
+	jr nz, .asm_2007
+	call PlayClickSFX
+
+.asm_2007
+	pop af
+	ret
+; 2009
+
+
+PlayClickSFX: ; 2009 
+	push de
+	ld de, SFX_READ_TEXT_2
+	call StartSFX
+	pop de
+	ret
+; 0x2012
+
+Function2012: ; 2012
+	call Function1d4f
+	call Functiona46
+	call Function1c07
+	ret
+; 201c
+
+Function201c: ; 201c
+	ld [hBuffer], a
+	ld a, [hROMBank]
+	push af
+	ld a, [hBuffer]
+	rst Bankswitch
+
+	call PlaceString
+	pop af
+	rst Bankswitch
+
+	ret
+; 202a
+
+Function202a: ; 202a
+	ld a, [hROMBank]
+	ld [$cf94], a
+	ld a, $9
+	ld hl, $400e
+	rst FarCall
+	ld a, [$cf88]
+	ret
+; 2039
+
+Function2039: ; 2039
+	ld a, [hROMBank]
+	ld [$cf94], a
+	ld a, $9
+	ld hl, $4022
+	rst FarCall
+	ld a, [$cf88]
+	ret
+; 2048
+
+Function2048: ; 2048
+	ld a, [hROMBank]
+	ld [$cf94], a
+	ld a, $9
+	ld hl, $403c
+	rst FarCall
+	ld a, [$cf88]
+	ret
+; 2057
+
+Function2057: ; 2057
+	ld a, [hROMBank]
+	push af
+	ld a, $21
+	rst Bankswitch
+
+	call $42db
+	pop af
+	rst Bankswitch
+
+	ret
+; 2063
+
--- /dev/null
+++ b/common/palettes.asm
@@ -1,0 +1,347 @@
+; Functions dealing with palettes.
+
+
+UpdatePalsIfCGB: ; c2f
+; update bgp data from BGPals
+; update obp data from OBPals
+; return carry if successful
+
+; check cgb
+	ld a, [hCGB]
+	and a
+	ret z
+
+
+UpdateCGBPals: ; c33
+; return carry if successful
+; any pals to update?
+	ld a, [hCGBPalUpdate]
+	and a
+	ret z
+
+
+ForceUpdateCGBPals: ; c37
+
+	ld a, [rSVBK]
+	push af
+	ld a, 5 ; BANK(BGPals)
+	ld [rSVBK], a
+
+	ld hl, BGPals ; 5:d080
+
+; copy 8 pals to bgpd
+	ld a, %10000000 ; auto increment, index 0
+	ld [rBGPI], a
+	ld c, rBGPD % $100
+	ld b, 4 ; NUM_PALS / 2
+.bgp
+	rept $10
+	ld a, [hli]
+	ld [$ff00+c], a
+	endr
+
+	dec b
+	jr nz, .bgp
+	
+; hl is now 5:d0c0 OBPals
+	
+; copy 8 pals to obpd
+	ld a, %10000000 ; auto increment, index 0
+	ld [rOBPI], a
+	ld c, rOBPD - rJOYP
+	ld b, 4 ; NUM_PALS / 2
+.obp
+	rept $10
+	ld a, [hli]
+	ld [$ff00+c], a
+	endr
+
+	dec b
+	jr nz, .obp
+	
+	pop af
+	ld [rSVBK], a
+
+; clear pal update queue
+	xor a
+	ld [hCGBPalUpdate], a
+
+	scf
+	ret
+; c9f
+
+
+DmgToCgbBGPals: ; c9f
+; exists to forego reinserting cgb-converted image data
+
+; input: a -> bgp
+
+	ld [rBGP], a
+	push af
+
+	ld a, [hCGB]
+	and a
+	jr z, .end
+
+	push hl
+	push de
+	push bc
+	ld a, [rSVBK]
+	push af
+
+	ld a, 5
+	ld [rSVBK], a
+
+; copy & reorder bg pal buffer
+	ld hl, BGPals ; to
+	ld de, Unkn1Pals ; from
+; order
+	ld a, [rBGP]
+	ld b, a
+; all pals
+	ld c, 8
+	call CopyPals
+; request pal update
+	ld a, 1
+	ld [hCGBPalUpdate], a
+
+	pop af
+	ld [rSVBK], a
+	pop bc
+	pop de
+	pop hl
+.end
+	pop af
+	ret
+; ccb
+
+
+DmgToCgbObjPals: ; ccb
+; exists to forego reinserting cgb-converted image data
+
+; input: d -> obp1
+;        e -> obp2
+
+	ld a, e
+	ld [rOBP0], a
+	ld a, d
+	ld [rOBP1], a
+	
+	ld a, [hCGB]
+	and a
+	ret z
+
+	push hl
+	push de
+	push bc
+	ld a, [rSVBK]
+	push af
+
+	ld a, 5
+	ld [rSVBK], a
+
+; copy & reorder obj pal buffer
+	ld hl, OBPals ; to
+	ld de, Unkn2Pals ; from
+; order
+	ld a, [rOBP0]
+	ld b, a
+; all pals
+	ld c, 8
+	call CopyPals
+; request pal update
+	ld a, 1
+	ld [hCGBPalUpdate], a
+
+	pop af
+	ld [rSVBK], a
+	pop bc
+	pop de
+	pop hl
+	ret
+; cf8
+
+
+Functioncf8: ; cf8
+	ld [rOBP0], a
+	push af
+	ld a, [hCGB]
+	and a
+	jr z, .asm_d22
+	push hl
+	push de
+	push bc
+	ld a, [rSVBK]
+	push af
+	ld a, $5
+	ld [rSVBK], a
+	ld hl, $d0c0
+	ld de, MartPointer
+	ld a, [rOBP0]
+	ld b, a
+	ld c, $1
+	call CopyPals
+	ld a, $1
+	ld [hCGBPalUpdate], a
+	pop af
+	ld [rSVBK], a
+	pop bc
+	pop de
+	pop hl
+
+.asm_d22
+	pop af
+	ret
+; d24
+
+Functiond24: ; d24
+	ld [rOBP1], a
+	push af
+	ld a, [hCGB]
+	and a
+	jr z, .asm_d4e
+	push hl
+	push de
+	push bc
+	ld a, [rSVBK]
+	push af
+	ld a, $5
+	ld [rSVBK], a
+	ld hl, $d0c8
+	ld de, $d048
+	ld a, [rOBP1]
+	ld b, a
+	ld c, $1
+	call CopyPals
+	ld a, $1
+	ld [hCGBPalUpdate], a
+	pop af
+	ld [rSVBK], a
+	pop bc
+	pop de
+	pop hl
+
+.asm_d4e
+	pop af
+	ret
+; d50
+
+
+
+CopyPals: ; d50
+; copy c palettes in order b from de to hl
+
+	push bc
+	ld c, 4 ; NUM_PAL_COLORS
+.loop
+	push de
+	push hl
+	
+; get pal color
+	ld a, b
+	and %11 ; color
+; 2 bytes per color
+	add a
+	ld l, a
+	ld h, 0
+	add hl, de
+	ld e, [hl]
+	inc hl
+	ld d, [hl]
+	
+; dest
+	pop hl
+; write color
+	ld [hl], e
+	inc hl
+	ld [hl], d
+	inc hl
+; next pal color
+	srl b
+	srl b
+; source
+	pop de
+; done pal?
+	dec c
+	jr nz, .loop
+	
+; de += 8 (next pal)
+	ld a, 8 ; NUM_PAL_COLORS * 2 ; bytes per pal
+	add e
+	jr nc, .ok
+	inc d
+.ok
+	ld e, a
+	
+; how many more pals?
+	pop bc
+	dec c
+	jr nz, CopyPals
+	ret
+; d79
+
+
+Functiond79: ; d79
+	ld a, [hCGB]
+	and a
+	ret z
+	ld a, 1
+	ld [rVBK], a
+	ld hl, VTiles0
+	ld bc, $2000
+	xor a
+	call ByteFill
+	ld a, 0
+	ld [rVBK], a
+	ret
+; d90
+
+
+Functiond90: ; d90
+	ret
+; d91
+
+
+Functiond91: ; d91
+	ld a, [hCGB]
+	and a
+	ret z
+	ld a, [rSVBK]
+	push af
+	ld a, 5 ; BANK(BGPals)
+	ld [rSVBK], a
+	ld hl, BGPals
+	ld bc, $40 + $10
+	xor a
+	call ByteFill
+	pop af
+	ld [rSVBK], a
+	ld a, 1
+	ld [hCGBPalUpdate], a
+	call DelayFrame
+	ret
+; db1
+
+
+Functiondb1: ; db1
+	ld a, [hROMBank]
+	push af
+	ld a, BANK(Function4c000)
+	rst Bankswitch
+	call Function4c000
+	pop af
+	rst Bankswitch
+	ret
+; dbd
+
+Functiondbd: ; dbd
+	ld a, [hROMBank]
+	push af
+	ld a, BANK(Function4c03f)
+	rst Bankswitch
+	call Function4c03f
+	pop af
+	rst Bankswitch
+	ret
+; dc9
+
--- /dev/null
+++ b/common/rtc.asm
@@ -1,0 +1,25 @@
+RTC: ; 46f
+; update time and time-sensitive palettes
+
+; rtc enabled?
+	ld a, [$c2ce]
+	cp 0
+	ret z
+	
+	call UpdateTime
+	
+; obj update on?
+	ld a, [VramState]
+	bit 0, a ; obj update
+	ret z
+
+TimeOfDayPals: ; 47e
+	callab _TimeOfDayPals
+	ret
+; 485
+
+UpdateTimePals: ; 485
+	callab _UpdateTimePals
+	ret
+; 48c
+
--- /dev/null
+++ b/common/serial.asm
@@ -1,0 +1,408 @@
+Serial: ; 6ef
+; The serial interrupt.
+
+	push af
+	push bc
+	push de
+	push hl
+
+	ld a, [$ffc9]
+	and a
+	jr nz, .asm_71c
+
+	ld a, [$c2d4]
+	bit 0, a
+	jr nz, .asm_721
+
+	ld a, [$ffcb]
+	inc a
+	jr z, .asm_726
+
+	ld a, [rSB]
+	ld [hSerialReceive], a
+
+	ld a, [hSerialSend]
+	ld [rSB], a
+
+	ld a, [$ffcb]
+	cp $2
+	jr z, .asm_752
+
+	ld a, 0 << rSC_ON
+	ld [rSC], a
+	ld a, 1 << rSC_ON
+	ld [rSC], a
+	jr .asm_752
+
+.asm_71c
+	call Function3e80
+	jr .asm_75a
+
+.asm_721
+	call Function2057
+	jr .asm_75a
+
+.asm_726
+	ld a, [rSB]
+	cp $1
+	jr z, .asm_730
+	cp $2
+	jr nz, .asm_752
+
+.asm_730
+	ld [hSerialReceive], a
+	ld [$ffcb], a
+	cp $2
+	jr z, .asm_74f
+
+	xor a
+	ld [rSB], a
+	ld a, $3
+	ld [rDIV], a
+
+.asm_73f
+	ld a, [rDIV]
+	bit 7, a
+	jr nz, .asm_73f
+
+	ld a, 0 << rSC_ON
+	ld [rSC], a
+	ld a, 1 << rSC_ON
+	ld [rSC], a
+	jr .asm_752
+
+.asm_74f
+	xor a
+	ld [rSB], a
+
+.asm_752
+	ld a, $1
+	ld [$ffca], a
+	ld a, $fe
+	ld [hSerialSend], a
+
+.asm_75a
+	pop hl
+	pop de
+	pop bc
+	pop af
+	reti
+; 75f
+
+Function75f: ; 75f
+	ld a, $1
+	ld [$ffcc], a
+.asm_763
+	ld a, [hl]
+	ld [hSerialSend], a
+	call Function78a
+	push bc
+	ld b, a
+	inc hl
+	ld a, $30
+.asm_76e
+	dec a
+	jr nz, .asm_76e
+	ld a, [$ffcc]
+	and a
+	ld a, b
+	pop bc
+	jr z, .asm_782
+	dec hl
+	cp $fd
+	jr nz, .asm_763
+	xor a
+	ld [$ffcc], a
+	jr .asm_763
+
+.asm_782
+	ld [de], a
+	inc de
+	dec bc
+	ld a, b
+	or c
+	jr nz, .asm_763
+	ret
+; 78a
+
+Function78a: ; 78a
+	xor a
+	ld [$ffca], a
+	ld a, [$ffcb]
+	cp $2
+	jr nz, .asm_79b
+	ld a, $1
+	ld [rSC], a
+	ld a, $81
+	ld [rSC], a
+
+.asm_79b
+	ld a, [$ffca]
+	and a
+	jr nz, .asm_7e5
+	ld a, [$ffcb]
+	cp $1
+	jr nz, .asm_7c0
+	call Function82b
+	jr z, .asm_7c0
+	call .asm_825
+	push hl
+	ld hl, $cf5c
+	inc [hl]
+	jr nz, .asm_7b7
+	dec hl
+	inc [hl]
+
+.asm_7b7
+	pop hl
+	call Function82b
+	jr nz, .asm_79b
+	jp Function833
+
+.asm_7c0
+	ld a, [rIE]
+	and $f
+	cp $8
+	jr nz, .asm_79b
+	ld a, [$cf5d]
+	dec a
+	ld [$cf5d], a
+	jr nz, .asm_79b
+	ld a, [$cf5e]
+	dec a
+	ld [$cf5e], a
+	jr nz, .asm_79b
+	ld a, [$ffcb]
+	cp $1
+	jr z, .asm_7e5
+	ld a, $ff
+.asm_7e2
+	dec a
+	jr nz, .asm_7e2
+
+.asm_7e5
+	xor a
+	ld [$ffca], a
+	ld a, [rIE]
+	and $f
+	sub $8
+	jr nz, .asm_7f8
+	ld [$cf5d], a
+	ld a, $50
+	ld [$cf5e], a
+
+.asm_7f8
+	ld a, [hSerialReceive]
+	cp $fe
+	ret nz
+	call Function82b
+	jr z, .asm_813
+	push hl
+	ld hl, $cf5c
+	ld a, [hl]
+	dec a
+	ld [hld], a
+	inc a
+	jr nz, .asm_80d
+	dec [hl]
+
+.asm_80d
+	pop hl
+	call Function82b
+	jr z, Function833
+
+.asm_813
+	ld a, [rIE]
+	and $f
+	cp $8
+	ld a, $fe
+	ret z
+	ld a, [hl]
+	ld [hSerialSend], a
+	call DelayFrame
+	jp Function78a
+
+.asm_825
+	ld a, $f
+.asm_827
+	dec a
+	jr nz, .asm_827
+	ret
+; 82b
+
+Function82b: ; 82b
+	push hl
+	ld hl, $cf5b
+	ld a, [hli]
+	or [hl]
+	pop hl
+	ret
+; 833
+
+Function833: ; 833
+	dec a
+	ld [$cf5b], a
+	ld [$cf5c], a
+	ret
+; 83b
+
+Function83b: ; 83b
+	ld hl, $cf56
+	ld de, $cf51
+	ld c, $2
+	ld a, $1
+	ld [$ffcc], a
+.asm_847
+	call DelayFrame
+	ld a, [hl]
+	ld [hSerialSend], a
+	call Function78a
+	ld b, a
+	inc hl
+	ld a, [$ffcc]
+	and a
+	ld a, $0
+	ld [$ffcc], a
+	jr nz, .asm_847
+	ld a, b
+	ld [de], a
+	inc de
+	dec c
+	jr nz, .asm_847
+	ret
+; 862
+
+Function862: ; 862
+	call Function309d
+	callab Function4000
+	call Function87d
+	jp Function30b4
+; 871
+
+
+Function871: ; 871
+	call Function309d
+	callab Function4000
+	jp Function87d
+; 87d
+
+
+
+Function87d: ; 87d
+	ld a, $ff
+	ld [$cf52], a
+.asm_882
+	call Function8c1
+	call DelayFrame
+	call Function82b
+	jr z, .asm_89e
+	push hl
+	ld hl, $cf5c
+	dec [hl]
+	jr nz, .asm_89d
+	dec hl
+	dec [hl]
+	jr nz, .asm_89d
+	pop hl
+	xor a
+	jp Function833
+
+.asm_89d
+	pop hl
+
+.asm_89e
+	ld a, [$cf52]
+	inc a
+	jr z, .asm_882
+	ld b, $a
+.asm_8a6
+	call DelayFrame
+	call Function8c1
+	dec b
+	jr nz, .asm_8a6
+	ld b, $a
+.asm_8b1
+	call DelayFrame
+	call Function908
+	dec b
+	jr nz, .asm_8b1
+	ld a, [$cf52]
+	ld [$cf51], a
+	ret
+; 8c1
+
+Function8c1: ; 8c1
+	push bc
+	ld b, $60
+	ld a, [InLinkBattle]
+	cp $1
+	jr z, .asm_8d7
+	ld b, $60
+	jr c, .asm_8d7
+	cp $2
+	ld b, $70
+	jr z, .asm_8d7
+	ld b, $80
+
+.asm_8d7
+	call Function8f3
+	ld a, [$cf56]
+	add b
+	ld [hSerialSend], a
+	ld a, [$ffcb]
+	cp $2
+	jr nz, .asm_8ee
+	ld a, $1
+	ld [rSC], a
+	ld a, $81
+	ld [rSC], a
+
+.asm_8ee
+	call Function8f3
+	pop bc
+	ret
+; 8f3
+
+Function8f3: ; 8f3
+	ld a, [hSerialReceive]
+	ld [$cf51], a
+	and $f0
+	cp b
+	ret nz
+	xor a
+	ld [hSerialReceive], a
+	ld a, [$cf51]
+	and $f
+	ld [$cf52], a
+	ret
+; 908
+
+Function908: ; 908
+	xor a
+	ld [hSerialSend], a
+	ld a, [$ffcb]
+	cp $2
+	ret nz
+	ld a, $1
+	ld [rSC], a
+	ld a, $81
+	ld [rSC], a
+	ret
+; 919
+
+Function919: ; 919
+	ld a, [InLinkBattle]
+	and a
+	ret nz
+	ld a, $2
+	ld [rSB], a
+	xor a
+	ld [hSerialReceive], a
+	ld a, $0
+	ld [rSC], a
+	ld a, $80
+	ld [rSC], a
+	ret
+; 92e
+
+
--- /dev/null
+++ b/common/sine.asm
@@ -1,0 +1,22 @@
+Cosine: ; 1b0f
+; Return d * cos(a) in hl
+	add $10 ; 90 degrees
+
+Sine: ; 1b11
+; Return d * sin(a) in hl
+; a is a signed 6-bit value.
+
+	ld e, a
+
+	ld a, [hROMBank]
+	push af
+	ld a, BANK(_Sine)
+	rst Bankswitch
+
+	call _Sine
+
+	pop af
+	rst Bankswitch
+	ret
+; 1b1e
+
--- /dev/null
+++ b/common/text.asm
@@ -1,0 +1,1230 @@
+ClearBox: ; fb6
+; Fill a c*b box at hl with blank tiles.
+
+	ld a, " "
+.y
+	push bc
+	push hl
+.x
+	ld [hli], a
+	dec c
+	jr nz, .x
+	pop hl
+	ld bc, 20 ; screen width
+	add hl, bc
+	pop bc
+	dec b
+	jr nz, .y
+	ret
+; fc8
+
+
+ClearTileMap: ; fc8
+; Fill TileMap with blank tiles.
+
+	ld hl, TileMap
+	ld a, " "
+	ld bc, 360 ; screen dimensions 20*18
+	call ByteFill
+	
+; We aren't done if the LCD is on.
+	ld a, [rLCDC]
+	bit 7, a
+	ret z
+	jp WaitBGMap
+; fdb
+
+
+Functionfdb: ; fdb
+	ld a, $7
+	ld hl, AttrMap
+	ld bc, $0168
+	call ByteFill
+	jr ClearTileMap
+; fe8
+
+
+
+TextBox: ; fe8
+; Draw a text box width c height b at hl
+; Dimensions do not include the border.
+	push bc
+	push hl
+	call TextBoxBorder
+	pop hl
+	pop bc
+	jr TextBoxPalette
+; ff1
+
+
+TextBoxBorder: ; ff1
+
+; Top
+	push hl
+	ld a, "┌"
+	ld [hli], a
+	inc a ; "─"
+	call NPlaceChar
+	inc a ; "┐"
+	ld [hl], a
+
+; Middle
+	pop hl
+	ld de, 20 ; screen width
+	add hl, de
+.PlaceRow
+	push hl
+	ld a, "│"
+	ld [hli], a
+	ld a, " "
+	call NPlaceChar
+	ld [hl], "│"
+	pop hl
+	ld de, 20 ; screen width
+	add hl, de
+	dec b
+	jr nz, .PlaceRow
+
+; Bottom
+	ld a, "└"
+	ld [hli], a
+	ld a, "─"
+	call NPlaceChar
+	ld [hl], "┘"
+
+	ret
+; 101e
+
+
+NPlaceChar: ; 101e
+; Place char a c times
+	ld d,c
+.loop
+	ld [hli],a
+	dec d
+	jr nz, .loop
+	ret
+; 1024
+
+
+TextBoxPalette: ; 1024
+; Fill text box width c height b at hl with pal 7
+	ld de, AttrMap - TileMap
+	add hl, de
+	inc b
+	inc b
+	inc c
+	inc c
+	ld a, 7 ; pal
+.gotoy
+	push bc
+	push hl
+.gotox
+	ld [hli], a
+	dec c
+	jr nz, .gotox
+	pop hl
+	ld de, 20 ; screen width
+	add hl, de
+	pop bc
+	dec b
+	jr nz, .gotoy
+	ret
+; 103e
+
+
+SpeechTextBox: ; 103e
+; Standard textbox.
+	hlcoord 0, 12
+	ld b, 4 ; height
+	ld c, 18 ; screen width - 2 (border)
+	jp TextBox
+; 1048
+
+UnknownText_0x1048: ; 1048
+	db $0, "ゲームフりーク!", $57
+; 1052
+
+Function1052: ; 1052
+	ld hl, .text_1056
+	ret
+.text_1056
+	db "@"
+; 1057
+
+
+PrintText: ; 1057
+	call Function106c
+Function105a: ; 105a
+	push hl
+	hlcoord 1, 14
+	ld bc, 18 + 3<<8
+	call ClearBox
+	pop hl
+
+PrintTextBoxText: ; 1065
+	bccoord 1, 14
+	call Function13e5
+	ret
+; 106c
+
+
+Function106c: ; 106c
+	push hl
+	call SpeechTextBox
+	call Function1ad2
+	call Function321c
+	pop hl
+	ret
+; 1078
+
+
+
+PlaceString: ; 1078
+	push hl
+
+PlaceNextChar: ; 1079
+	ld a, [de]
+	cp "@"
+	jr nz, CheckDict
+	ld b, h
+	ld c, l
+	pop hl
+	ret
+	pop de
+
+NextChar: ; 1083
+	inc de
+	jp PlaceNextChar
+
+CheckDict: ; 1087
+	cp $15
+	jp z, Function117b
+	cp $4f
+	jp z, Char4F
+	cp $4e
+	jp z, Function12a7
+	cp $16
+	jp z, Function12b9
+	and a
+	jp z, Function1383
+	cp $4c
+	jp z, $1337
+	cp $4b
+	jp z, Char4B
+	cp $51 ; Player name
+	jp z, Function12f2
+	cp $49
+	jp z, Function1186
+	cp $52 ; Mother name
+	jp z, Function118d
+	cp $53
+	jp z, Function1194
+	cp $35
+	jp z, Function11e8
+	cp $36
+	jp z, Function11ef
+	cp $37
+	jp z, Function11f6
+	cp $38
+	jp z, Function119b
+	cp $39
+	jp z, Function11a2
+	cp $54
+	jp z, Function11c5
+	cp $5b
+	jp z, Function11b7
+	cp $5e
+	jp z, Function11be
+	cp $5c
+	jp z, Function11b0
+	cp $5d
+	jp z, Function11a9
+	cp $23
+	jp z, Function11cc
+	cp $22
+	jp z, Function12b0
+	cp $55
+	jp z, Char55
+	cp $56
+	jp z, Function11d3
+	cp $57
+	jp z, $137c
+	cp $58
+	jp z, Function135a
+	cp $4a
+	jp z, Function11da
+	cp $24
+	jp z, Function11e1
+	cp $25
+	jp z, NextChar
+	cp $1f
+	jr nz, .asm_1122
+	ld a, $7f
+.asm_1122
+	cp $5f
+	jp z, Char5F
+	cp $59
+	jp z, Function11fd
+	cp $5a
+	jp z, Char5D
+	cp $3f
+	jp z, $121b
+	cp $14
+	jp z, $1252
+	cp $e4
+	jr z, .asm_1174 ; 0x113d $35
+	cp $e5
+	jr z, .asm_1174 ; 0x1141 $31
+	jr .asm_114c ; 0x1143 $7
+	ld b, a
+	call Function13c6
+	jp NextChar
+.asm_114c
+	cp $60
+	jr nc, .asm_1174 ; 0x114e $24
+	cp $40
+	jr nc, .asm_1165 ; 0x1152 $11
+	cp $20
+	jr nc, .asm_115c ; 0x1156 $4
+	add $80
+	jr .asm_115e ; 0x115a $2
+.asm_115c
+	add $90
+.asm_115e
+	ld b, $e5
+	call Function13c6
+	jr .asm_1174 ; 0x1163 $f
+.asm_1165
+	cp $44
+	jr nc, .asm_116d ; 0x1167 $4
+	add $59
+	jr .asm_116f ; 0x116b $2
+.asm_116d
+	add $86
+.asm_116f
+	ld b, $e4
+	call Function13c6
+.asm_1174
+	ld [hli], a
+	call PrintLetterDelay
+	jp NextChar
+; 0x117b
+
+
+Function117b: ; 117b
+	ld c, l
+	ld b, h
+	ld a, $5f
+	ld hl, $7036
+	rst FarCall
+	jp PlaceNextChar
+; 1186
+
+Function1186: ; 1186
+	push de
+	ld de, MomsName
+	jp $126a
+; 118d
+
+Function118d: ; 118d
+	push de
+	ld de, PlayerName
+	jp $126a
+; 1194
+
+Function1194: ; 1194
+	push de
+	ld de, RivalName
+	jp $126a
+; 119b
+
+Function119b: ; 119b
+	push de
+	ld de, RedsName
+	jp $126a
+; 11a2
+
+Function11a2: ; 11a2
+	push de
+	ld de, GreensName
+	jp $126a
+; 11a9
+
+Function11a9: ; 11a9
+	push de
+	ld de, Char5DText
+	jp $126a
+; 11b0
+
+Function11b0: ; 11b0
+	push de
+	ld de, Char5CText
+	jp $126a
+; 11b7
+
+Function11b7: ; 11b7
+	push de
+	ld de, Char5BText
+	jp $126a
+; 11be
+
+Function11be: ; 11be
+	push de
+	ld de, Char5EText
+	jp $126a
+; 11c5
+
+Function11c5: ; 11c5
+	push de
+	ld de, Char54Text
+	jp $126a
+; 11cc
+
+Function11cc: ; 11cc
+	push de
+	ld de, Char23Text
+	jp $126a
+; 11d3
+
+Function11d3: ; 11d3
+	push de
+	ld de, $1292
+	jp $126a
+; 11da
+
+Function11da: ; 11da
+	push de
+	ld de, Char4AText
+	jp $126a
+; 11e1
+
+Function11e1: ; 11e1
+	push de
+	ld de, Char24Text
+	jp $126a
+; 11e8
+
+Function11e8: ; 11e8
+	push de
+	ld de, Char37Text
+	jp $126a
+; 11ef
+
+Function11ef: ; 11ef
+	push de
+	ld de, Char37Text
+	jp $126a
+; 11f6
+
+Function11f6: ; 11f6
+	push de
+	ld de, Char37Text
+	jp $126a
+; 11fd
+
+
+Function11fd: ; 11fd
+	ld a, [hBattleTurn]
+	xor $1
+	jr Function1205
+; 1203
+
+Char5D: ; 1203
+	ld a, [hBattleTurn]
+; 1205
+
+Function1205: ; 1205
+	push de
+	and a
+	jr nz, .asm_120e ; 0x1207 $5
+	ld de, BattleMonNick
+	jr .asm_126a ; 0x120c $5c
+.asm_120e
+	ld de, Char5AText ; Enemy
+	call PlaceString
+	ld h, b
+	ld l, c
+	ld de, EnemyMonNick
+	jr .asm_126a ; 0x1219 $4f
+	push de
+	ld a, [InLinkBattle]
+	and a
+	jr nz, .linkbattle
+	ld a, [TrainerClass]
+	cp $9
+	jr z, .asm_1248 ; 0x1227 $1f
+	cp $2a
+	jr z, .asm_1248 ; 0x122b $1b
+	ld de, $c656
+	call PlaceString
+	ld h, b
+	ld l, c
+	ld de, String12a2
+	call PlaceString
+	push bc
+	ld hl, $5939
+	ld a, $e
+	rst FarCall
+	pop hl
+	ld de, StringBuffer1
+	jr .asm_126a ; 0x1246 $22
+.asm_1248
+	ld de, RivalName
+	jr .asm_126a ; 0x124b $1d
+.linkbattle
+	ld de, $c656
+	jr .asm_126a ; 0x1250 $18
+	push de
+	ld de, PlayerName
+	call PlaceString
+	ld h, b
+	ld l, c
+	ld a, [PlayerGender]
+	bit 0, a
+	ld de, String12a5
+	jr z, .asm_126a ; 0x1263 $5
+	ld de, String12a6
+	jr .asm_126a ; 0x1268 $0
+.asm_126a
+	call PlaceString
+	ld h, b
+	ld l, c
+	pop de
+	jp NextChar
+; 0x1273
+
+Char5CText: ; 1273
+	db "TM@"
+Char5DText: ; 1276
+	db "TRAINER@"
+Char5BText: ; 127e
+	db "PC@"
+Char5EText: ; 1281
+	db "ROCKET@"
+Char54Text: ; 1288
+	db "POKé@"
+Char23Text: ; 128d
+	db "こうげき@"
+Char56Text:; 1292
+	db "……@"
+Char5AText: ; 1295
+	db "Enemy @"
+Char4AText: ; 129c
+	db $e1, $e2, "@" ; PK MN
+Char24Text: ; 129f
+	db $70, $71, "@" ; PO KE
+String12a2: ; 12a2
+	db " @"
+Char35Text:
+Char36Text:
+Char37Text: ; 12a4
+	db "@"
+String12a5: ; 12a5
+	db "@"
+String12a6: ; 12a6
+	db "@"
+; 12a7
+
+Function12a7: ; 12a7
+	pop hl
+	ld bc, $0028
+	add hl, bc
+	push hl
+	jp NextChar
+; 12b0
+
+Function12b0: ; 12b0
+	pop hl
+	ld bc, $0014
+	add hl, bc
+	push hl
+	jp NextChar
+; 12b9
+
+Function12b9: ; 12b9
+	pop hl
+	push de
+	ld bc, $3b60
+	add hl, bc
+	ld de, $ffec
+	ld c, $1
+.asm_12c4
+	ld a, h
+	and a
+	jr nz, .asm_12cd
+	ld a, l
+	cp $14
+	jr c, .asm_12d1
+
+.asm_12cd
+	add hl, de
+	inc c
+	jr .asm_12c4
+
+.asm_12d1
+	ld hl, TileMap
+	ld de, $0014
+	ld a, c
+.asm_12d8
+	and a
+	jr z, .asm_12df
+	add hl, de
+	dec a
+	jr .asm_12d8
+
+.asm_12df
+	pop de
+	inc de
+	ld a, [de]
+	ld c, a
+	ld b, $0
+	add hl, bc
+	push hl
+	jp NextChar
+; 12ea
+
+
+Char4F: ; 12ea
+	pop hl
+	hlcoord 1, 16
+	push hl
+	jp NextChar
+; 0x12f2
+
+Function12f2: ; 12f2
+	push de
+	ld a, [InLinkBattle]
+	cp $3
+	jr z, .asm_1301
+	cp $4
+	jr z, .asm_1301
+	call Function13c7
+
+.asm_1301
+	call Function13b6
+	call Functionaaf
+	ld hl, $c5b9
+	ld bc, $0312
+	call ClearBox
+	call Function13cd
+	ld c, $14
+	call DelayFrames
+	ld hl, $c5b9
+	pop de
+	jp NextChar
+; 131f
+
+
+Char4B: ; 131f
+	ld a, [InLinkBattle]
+	or a
+	jr nz, .asm_1328
+	call Function13c7
+
+.asm_1328
+	call Function13b6
+
+	push de
+	call Functionaaf
+	pop de
+
+	ld a, [InLinkBattle]
+	or a
+	call z, Function13cd
+
+	push de
+	call Function138c
+	call Function138c
+	hlcoord 1, 16
+	pop de
+	jp NextChar
+; 1345
+
+
+Char55: ; 1345
+	push de
+	ld de, Text_1354
+	ld b, h
+	ld c, l
+	call PlaceString
+	ld h, b
+	ld l, c
+	pop de
+	jp NextChar
+; 1354
+
+Text_1354: ; 1354
+	db $4b, "@"
+; 1356
+
+
+Char5F: ; 1356
+; ends a Pokédex entry
+	ld [hl], "."
+	pop hl
+	ret
+; 135a
+
+Function135a: ; 135a
+	ld a, [InLinkBattle]
+	cp $3
+	jr z, .asm_1368
+	cp $4
+	jr z, .asm_1368
+	call Function13c7
+
+.asm_1368
+	call Function13b6
+	call Functionaaf
+	ld a, [InLinkBattle]
+	cp $3
+	jr z, .asm_137c
+	cp $4
+	jr z, .asm_137c
+	call Function13cd
+
+.asm_137c
+	pop hl
+	ld de, .string_1382
+	dec de
+	ret
+
+.string_1382
+	db "@"
+; 1383
+
+Function1383: ; 1383
+	ld a, $e6
+	ld [hli], a
+	call PrintLetterDelay
+	jp NextChar
+; 138c
+
+Function138c: ; 138c
+	ld hl, $c5b9
+	ld de, $c5a5
+	ld a, $3
+.asm_1394
+	push af
+	ld c, $12
+.asm_1397
+	ld a, [hli]
+	ld [de], a
+	inc de
+	dec c
+	jr nz, .asm_1397
+	inc de
+	inc de
+	inc hl
+	inc hl
+	pop af
+	dec a
+	jr nz, .asm_1394
+	ld hl, $c5e1
+	ld a, $7f
+	ld bc, $0012
+	call ByteFill
+	ld c, $5
+	call DelayFrames
+	ret
+; 13b6
+
+Function13b6: ; 13b6
+	push bc
+	ld a, [hOAMUpdate]
+	push af
+	ld a, $1
+	ld [hOAMUpdate], a
+	call WaitBGMap
+	pop af
+	ld [hOAMUpdate], a
+	pop bc
+	ret
+; 13c6
+
+Function13c6: ; 13c6
+	ret
+; 13c7
+
+Function13c7: ; 13c7
+	ld a, $ee
+	ld [$c606], a
+	ret
+; 13cd
+
+Function13cd: ; 13cd
+	ld a, [$c605]
+	ld [$c606], a
+	ret
+; 13d4
+
+Function13d4: ; 13d4
+	ld b, a
+	ld a, [hROMBank]
+	push af
+	ld a, b
+	rst Bankswitch
+
+	call PlaceString
+	pop af
+	rst Bankswitch
+
+	ret
+; 13e0
+
+Function13e0: ; 13e0
+	ld hl, $13e4
+	ret
+
+.string_13e4
+	db "@"
+; 13e5
+
+
+Function13e5: ; 13e5
+	ld a, [$cfcf]
+	push af
+	set 1, a
+	ld [$cfcf], a
+	call Function13f6
+	pop af
+	ld [$cfcf], a
+	ret
+; 13f6
+
+Function13f6: ; 13f6
+.asm_13f6
+	ld a, [hli]
+	cp "@"
+	ret z
+	call Function13ff
+	jr .asm_13f6
+; 13ff
+
+Function13ff: ; 13ff
+	push hl
+	push bc
+	ld c, a
+	ld b, 0
+	ld hl, TextCommands
+	add hl, bc
+	add hl, bc
+	ld e, [hl]
+	inc hl
+	ld d, [hl]
+	pop bc
+	pop hl
+	
+; jp de
+	push de
+	ret
+; 1410
+
+TextCommands: ; 1410
+	dw Text_00
+	dw Text_01
+	dw Text_02
+	dw Text_03
+	dw Text_04
+	dw Text_05
+	dw Text_06
+	dw Text_07
+	dw Text_08
+	dw Text_09
+	dw Text_0A
+	dw Text_PlaySound ; $0b
+	dw Text_0C
+	dw Text_0D
+	dw Text_PlaySound ; $0e
+	dw Text_PlaySound ; $0f
+	dw Text_PlaySound ; $10
+	dw Text_PlaySound ; $11
+	dw Text_PlaySound ; $12
+	dw Text_PlaySound ; $13
+	dw Text_14
+	dw Text_15
+	dw Text_16
+; 143e
+
+Text_00: ; 143e
+; TX
+; write text until "@"
+; [$00]["...@"]
+
+	ld d, h
+	ld e, l
+	ld h, b
+	ld l, c
+	call PlaceString
+	ld h, d
+	ld l, e
+	inc hl
+	ret
+; 1449
+
+Text_01: ; 1449
+; TX_RAM
+; write text from a ram address
+; little endian
+; [$01][addr]
+
+	ld a, [hli]
+	ld e, a
+	ld a, [hli]
+	ld d, a
+	push hl
+	ld h, b
+	ld l, c
+	call PlaceString
+	pop hl
+	ret
+; 1455
+
+Text_16: ; 1455
+; TX_FAR
+; write text from a different bank
+; little endian
+; [$16][addr][bank]
+
+	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
+
+	push hl
+	ld h, d
+	ld l, e
+	call Function13f6
+	pop hl
+
+	pop af
+	ld [hROMBank], a
+	ld [MBC3RomBank], a
+	ret
+; 1470
+
+Text_02: ; 1470
+; TX_NUM
+; write bcdnumber from address, typically ram
+; little endian
+; [$02][addr][flags]
+; flags: see PrintBCDNumber
+
+	ld a, [hli]
+	ld e, a
+	ld a, [hli]
+	ld d, a
+	ld a, [hli]
+	push hl
+	ld h, b
+	ld l, c
+	ld c, a
+	call PrintBCDNumber
+	ld b, h
+	ld c, l
+	pop hl
+	ret
+; 1480
+
+Text_03: ; 1480
+; TX_MOVE
+; move to a new tile
+; little endian
+; [$03][tileaddr]
+
+	ld a, [hli]
+	ld [$d0e6], a
+	ld c, a
+	ld a, [hli]
+	ld [$d0e7], a
+	ld b, a
+	ret
+; 148b
+
+Text_04: ; 148b
+; TX_BOX
+; draw a box
+; little endian
+; [$04][tileaddr][height][width]
+
+	ld a, [hli]
+	ld e, a
+	ld a, [hli]
+	ld d, a
+	ld a, [hli]
+	ld b, a
+	ld a, [hli]
+	ld c, a
+	push hl
+	ld h, d
+	ld l, e
+	call TextBox
+	pop hl
+	ret
+; 149b
+
+Text_05: ; 149b
+; TX_LOW
+; write text at (1,16)
+; [$05]
+
+	bccoord 1, 16
+	ret
+; 149f
+
+Text_06:: ; 149f
+; TX_WAITBUTTON
+; wait for button press
+; show arrow
+; [06]
+
+	ld a, [InLinkBattle]
+	cp $3
+	jp z, Text_0D
+	cp $4
+	jp z, Text_0D
+	push hl
+	call Function13c7
+	push bc
+	call Functionaaf
+	pop bc
+	call Function13cd
+	pop hl
+	ret
+; 14ba
+
+Text_07: ; 14ba
+	push hl
+	call Function13cd
+	call Function138c
+	call Function138c
+	pop hl
+	bccoord 1, 16
+	ret
+; 14c9
+
+Text_08: ; 14c9
+; TX_ASM
+
+; rom only?
+	bit 7, h
+	jr nz, .asm_14ce
+	jp [hl]
+
+.asm_14ce
+	ld a, "@"
+	ld [hl], a
+	ret
+; 14d2
+
+Text_09: ; 14d2
+	ld a, [hli]
+	ld e, a
+	ld a, [hli]
+	ld d, a
+	ld a, [hli]
+	push hl
+	ld h, b
+	ld l, c
+	ld b, a
+	and $f
+	ld c, a
+	ld a, b
+	and $f0
+	swap a
+	set 6, a
+	ld b, a
+	call PrintNum
+	ld b, h
+	ld c, l
+	pop hl
+	ret
+; 14ed
+
+Text_0A: ; 14ed
+	push hl
+	push bc
+	call GetJoypadPublic
+	ld a, [hJoyDown]
+	and BUTTON_A | BUTTON_B
+	jr nz, .asm_14fd
+	ld c, 30
+	call DelayFrames
+
+.asm_14fd
+	pop bc
+	pop hl
+	ret
+; 1500
+
+Text_PlaySound:: ; 1500
+; chars:
+;   $0b, $0e, $0f, $10, $11, $12, $13
+; see TextSFX
+
+	push bc
+	dec hl
+	ld a, [hli]
+	ld b, a
+	push hl
+	ld hl, TextSFX
+.asm_1508
+	ld a, [hli]
+	cp $ff
+	jr z, .asm_151f
+	cp b
+	jr z, .asm_1514
+	inc hl
+	inc hl
+	jr .asm_1508
+
+.asm_1514
+	push de
+	ld e, [hl]
+	inc hl
+	ld d, [hl]
+	call StartSFX
+	call WaitSFX
+	pop de
+
+.asm_151f
+	pop hl
+	pop bc
+	ret
+; 1522
+
+Function1522: ; 1522
+	push de
+	ld e, [hl]
+	inc hl
+	ld d, [hl]
+	call Function37ce
+	pop de
+	pop hl
+	pop bc
+	ret
+; 152d
+
+TextSFX: ; 152d
+	dbw $0b, SFX_DEX_FANFARE_50_79
+	dbw $12, SFX_FANFARE
+	dbw $0e, SFX_DEX_FANFARE_20_49
+	dbw $0f, SFX_ITEM
+	dbw $10, SFX_CAUGHT_MON
+	dbw $11, SFX_DEX_FANFARE_80_109
+	dbw $13, SFX_SLOT_MACHINE_START
+	db $ff ; end
+; 1543
+
+Text_0C: ; 1543
+	ld a, [hli]
+	ld d, a
+	push hl
+	ld h, b
+	ld l, c
+.asm_1548
+	push de
+	ld a, "…"
+	ld [hli], a
+	call GetJoypadPublic
+	ld a, [hJoyDown]
+	and BUTTON_A | BUTTON_B
+	jr nz, .asm_155a
+	ld c, 10
+	call DelayFrames
+.asm_155a
+	pop de
+	dec d
+	jr nz, .asm_1548
+	ld b, h
+	ld c, l
+	pop hl
+	ret
+; 1562
+
+Text_0D: ; 1562
+; wait for key down
+; display arrow
+	push hl
+	push bc
+	call Functionaaf
+	pop bc
+	pop hl
+	ret
+; 156a
+
+Text_14: ; 156a
+; TX_PREDEF
+; [$14][id]
+
+	ld a, [hli]
+	push hl
+	ld e, a
+	ld d, 0
+	ld hl, $4000
+	add hl, de
+	add hl, de
+	ld a, $9
+	call GetFarHalfword
+	ld d, h
+	ld e, l
+	ld h, b
+	ld l, c
+	call PlaceString
+	pop hl
+	ret
+; 1582
+
+Text_15: ; 1582
+; TX_DAY
+
+	call GetWeekday
+	push hl
+	push bc
+	ld c, a
+	ld b, 0
+	ld hl, .Days
+	add hl, bc
+	add hl, bc
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	ld d, h
+	ld e, l
+	pop hl
+	call PlaceString
+	ld h, b
+	ld l, c
+	ld de, .Day
+	call PlaceString
+	pop hl
+	ret
+; 15a2
+
+.Days ; 15a2
+	dw .Sun
+	dw .Mon
+	dw .Tues
+	dw .Wednes
+	dw .Thurs
+	dw .Fri
+	dw .Satur
+
+.Sun    db "SUN@"
+.Mon    db "MON@"
+.Tues   db "TUES@"
+.Wednes db "WEDNES@"
+.Thurs  db "THURS@"
+.Fri    db "FRI@"
+.Satur  db "SATUR@"
+.Day    db "DAY@"
+; 15d8
+
--- /dev/null
+++ b/common/time.asm
@@ -1,0 +1,311 @@
+; Functions relating to the timer interrupt and the real-time-clock.
+
+
+AskTimer: ; 591
+	push af
+	ld a, [$ffe9]
+	and a
+	jr z, .asm_59a
+	call Timer
+
+.asm_59a
+	pop af
+	reti
+; 59c
+
+
+LatchClock: ; 59c
+; latch clock counter data
+	ld a, 0
+	ld [MBC3LatchClock], a
+	ld a, 1
+	ld [MBC3LatchClock], a
+	ret
+; 5a7
+
+
+UpdateTime: ; 5a7
+	call GetClock
+	call FixDays
+	call FixTime
+	callba GetTimeOfDay
+	ret
+; 5b7
+
+
+GetClock: ; 5b7
+; store clock data in hRTCDayHi-hRTCSeconds
+
+; enable clock r/w
+	ld a, SRAM_ENABLE
+	ld [MBC3SRamEnable], a
+
+; clock data is 'backwards' in hram
+
+	call LatchClock
+	ld hl, MBC3SRamBank
+	ld de, MBC3RTC
+
+	ld [hl], RTC_S
+	ld a, [de]
+	and $3f
+	ld [hRTCSeconds], a
+
+	ld [hl], RTC_M
+	ld a, [de]
+	and $3f
+	ld [hRTCMinutes], a
+
+	ld [hl], RTC_H
+	ld a, [de]
+	and $1f
+	ld [hRTCHours], a
+
+	ld [hl], RTC_DL
+	ld a, [de]
+	ld [hRTCDayLo], a
+
+	ld [hl], RTC_DH
+	ld a, [de]
+	ld [hRTCDayHi], a
+
+; unlatch clock / disable clock r/w
+	call CloseSRAM
+	ret
+; 5e8
+
+
+FixDays: ; 5e8
+; fix day count
+; mod by 140
+
+; check if day count > 255 (bit 8 set)
+	ld a, [hRTCDayHi] ; DH
+	bit 0, a
+	jr z, .daylo
+; reset dh (bit 8)
+	res 0, a
+	ld [hRTCDayHi], a ; DH
+	
+; mod 140
+; mod twice since bit 8 (DH) was set
+	ld a, [hRTCDayLo] ; DL
+.modh
+	sub 140
+	jr nc, .modh
+.modl
+	sub 140
+	jr nc, .modl
+	add 140
+	
+; update dl
+	ld [hRTCDayLo], a ; DL
+
+; unknown output
+	ld a, $40 ; %1000000
+	jr .set
+
+.daylo
+; quit if fewer than 140 days have passed
+	ld a, [hRTCDayLo] ; DL
+	cp 140
+	jr c, .quit
+	
+; mod 140
+.mod
+	sub 140
+	jr nc, .mod
+	add 140
+	
+; update dl
+	ld [hRTCDayLo], a ; DL
+	
+; unknown output
+	ld a, $20 ; %100000
+	
+.set
+; update clock with modded day value
+	push af
+	call SetClock
+	pop af
+	scf
+	ret
+	
+.quit
+	xor a
+	ret
+; 61d
+
+
+FixTime: ; 61d
+; add ingame time (set at newgame) to current time
+;				  day     hr    min    sec
+; store time in CurDay, hHours, hMinutes, hSeconds
+
+; second
+	ld a, [hRTCSeconds] ; S
+	ld c, a
+	ld a, [StartSecond]
+	add c
+	sub 60
+	jr nc, .updatesec
+	add 60
+.updatesec
+	ld [hSeconds], a
+	
+; minute
+	ccf ; carry is set, so turn it off
+	ld a, [hRTCMinutes] ; M
+	ld c, a
+	ld a, [StartMinute]
+	adc c
+	sub 60
+	jr nc, .updatemin
+	add 60
+.updatemin
+	ld [hMinutes], a
+	
+; hour
+	ccf ; carry is set, so turn it off
+	ld a, [hRTCHours] ; H
+	ld c, a
+	ld a, [StartHour]
+	adc c
+	sub 24
+	jr nc, .updatehr
+	add 24
+.updatehr
+	ld [hHours], a
+	
+; day
+	ccf ; carry is set, so turn it off
+	ld a, [hRTCDayLo] ; DL
+	ld c, a
+	ld a, [StartDay]
+	adc c
+	ld [CurDay], a
+	ret
+; 658
+
+Function658: ; 658
+	xor a
+	ld [StringBuffer2], a
+	ld a, $0
+	ld [$d089], a
+	jr .asm_677
+
+	call UpdateTime
+	ld a, [hHours]
+	ld [$d087], a
+	ld a, [hMinutes]
+	ld [$d088], a
+	ld a, [hSeconds]
+	ld [$d089], a
+	jr .asm_677
+
+.asm_677
+	ld a, $5
+	ld hl, $40ed
+	rst FarCall
+	ret
+; 67e
+
+
+
+Function67e: ; 67e
+	call Function685
+	call SetClock
+	ret
+; 685
+
+Function685: ; 685
+	xor a
+	ld [hRTCSeconds], a
+	ld [hRTCMinutes], a
+	ld [hRTCHours], a
+	ld [hRTCDayLo], a
+	ld [hRTCDayHi], a
+	ret
+; 691
+
+
+SetClock: ; 691
+; set clock data from hram
+
+; enable clock r/w
+	ld a, SRAM_ENABLE
+	ld [MBC3SRamEnable], a
+	
+; set clock data
+; stored 'backwards' in hram
+
+	call LatchClock
+	ld hl, MBC3SRamBank
+	ld de, MBC3RTC
+	
+; seems to be a halt check that got partially commented out
+; this block is totally pointless
+	ld [hl], RTC_DH
+	ld a, [de]
+	bit 6, a ; halt
+	ld [de], a
+	
+; seconds
+	ld [hl], RTC_S
+	ld a, [hRTCSeconds]
+	ld [de], a
+; minutes
+	ld [hl], RTC_M
+	ld a, [hRTCMinutes]
+	ld [de], a
+; hours
+	ld [hl], RTC_H
+	ld a, [hRTCHours]
+	ld [de], a
+; day lo
+	ld [hl], RTC_DL
+	ld a, [hRTCDayLo]
+	ld [de], a
+; day hi
+	ld [hl], RTC_DH
+	ld a, [hRTCDayHi]
+	res 6, a ; make sure timer is active
+	ld [de], a
+	
+; cleanup
+	call CloseSRAM ; unlatch clock, disable clock r/w
+	ret
+; 6c4
+
+
+Function6c4: ; 6c4
+	xor a
+	push af
+	ld a, $0
+	call GetSRAMBank
+	pop af
+	ld [$ac60], a
+	call CloseSRAM
+	ret
+; 6d3
+
+Function6d3: ; 6d3
+	ld hl, $ac60
+	push af
+	ld a, $0
+	call GetSRAMBank
+	pop af
+	or [hl]
+	ld [hl], a
+	call CloseSRAM
+	ret
+; 6e3
+
+Function6e3: ; 6e3
+	ld a, $0
+	call GetSRAMBank
+	ld a, [$ac60]
+	call CloseSRAM
+	ret
+; 6ef
+
--- /dev/null
+++ b/common/vblank.asm
@@ -1,0 +1,541 @@
+; VBlank is the interrupt responsible for updating VRAM.
+
+; In Pokemon Crystal, VBlank has been hijacked to act as the
+; main loop. After time-sensitive graphics operations have been
+; performed, joypad input and sound functions are executed.
+
+; This prevents the display and audio output from lagging.
+
+
+VBlank: ; 283
+	push af
+	push bc
+	push de
+	push hl
+	
+; get vblank type
+	ld a, [$ff9e]
+	and $7
+	
+; get fn pointer
+	ld e, a
+	ld d, $0
+	ld hl, .VBlanks
+	add hl, de
+	add hl, de
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	
+; down to business
+	call _hl_
+	
+; since this is called once per frame
+	call GameTimer
+	
+	pop hl
+	pop de
+	pop bc
+	pop af
+	reti
+; 2a1
+
+.VBlanks ; 2a1
+	dw VBlank0 ; 0
+	dw VBlank1 ; 1
+	dw VBlank2 ; 2
+	dw VBlank3 ; 3
+	dw VBlank4 ; 4
+	dw VBlank5 ; 5
+	dw VBlank6 ; 6
+	dw VBlank0 ; 7
+; 2b1
+
+
+VBlank0: ; 2b1
+; normal operation
+
+; rng
+; scx, scy, wy, wx
+; bg map buffer
+; palettes
+; dma transfer
+; bg map
+; tiles
+; oam
+; joypad
+; sound
+
+; inc frame counter
+	ld hl, $ff9b
+	inc [hl]
+	
+; advance rng
+	ld a, [rDIV]
+	ld b, a
+	ld a, [hRandomAdd]
+	adc b
+	ld [hRandomAdd], a
+	
+	ld a, [rDIV]
+	ld b, a
+	ld a, [hRandomSub]
+	sbc b
+	ld [hRandomSub], a
+	
+; save bank
+	ld a, [hROMBank] ; current bank
+	ld [$ff8a], a
+	
+; scroll x
+	ld a, [hSCX]
+	ld [rSCX], a
+; scroll y
+	ld a, [hSCY]
+	ld [rSCY], a
+; window y
+	ld a, [hWY]
+	ld [rWY], a
+; window x + 7
+	ld a, [hWX]
+	ld [rWX], a
+	
+; some time management is in order
+; only have time for one of these during vblank
+	
+; bg map buffer has priority
+	call UpdateBGMapBuffer
+	jr c, .doneframeaction
+	
+; then pals
+	call UpdatePalsIfCGB
+	jr c, .doneframeaction
+	
+; dma transfer
+	call DMATransfer
+	jr c, .doneframeaction
+	
+; bg map
+	call UpdateBGMap
+	
+; these have their own timing checks
+	call Serve2bppRequest
+	call Serve1bppRequest
+	call AnimateTileset
+	
+.doneframeaction
+; oam update off?
+	ld a, [hOAMUpdate]
+	and a
+	jr nz, .vblankoccurred
+	
+; update oam by dma transfer
+	call hPushOAM
+;	@PushOAM:
+;		ld a, Sprites >> 8
+;		ld [rDMA], a
+;		ld a, $28
+;	.loop
+;		dec a
+;		jr nz, .loop
+;		ret
+
+
+; vblank-sensitive operations are done
+	
+.vblankoccurred
+; tell other fns vblank happened
+	xor a
+	ld [VBlankOccurred], a
+	
+; dec OverworldDelay until 0
+	ld a, [OverworldDelay]
+	and a
+	jr z, .textdelay
+	dec a
+	ld [OverworldDelay], a
+	
+.textdelay
+; dec text delay counter until 0
+	ld a, [TextDelayFrames]
+	and a
+	jr z, .joypad
+	dec a
+	ld [TextDelayFrames], a
+	
+.joypad
+	call Joypad
+	
+; update sound
+	ld a, BANK(UpdateSound)
+	rst Bankswitch ; bankswitch
+	call UpdateSound
+	ld a, [$ff8a]
+	rst Bankswitch ; restore bank
+	
+; 
+	ld a, [hSeconds]
+	ld [$ffe3], a
+	
+	ret
+; 325
+
+
+VBlank2: ; 325
+; sound only
+
+; save bank
+	ld a, [hROMBank]
+	ld [$ff8a], a
+	
+; update sound
+	ld a, BANK(UpdateSound)
+	rst Bankswitch ; bankswitch
+	call UpdateSound
+	
+; restore bank
+	ld a, [$ff8a]
+	rst Bankswitch
+	
+; tell other fns vblank happened
+	xor a
+	ld [VBlankOccurred], a
+	ret
+; 337
+
+
+VBlank1: ; 337
+; scx, scy
+; palettes
+; bg map
+; tiles
+; oam
+; sound / lcd stat
+
+; save bank
+	ld a, [hROMBank]
+	ld [$ff8a], a
+	
+; scroll x
+	ld a, [hSCX]
+	ld [rSCX], a
+	
+; scroll y
+	ld a, [hSCY]
+	ld [rSCY], a
+	
+; time-sensitive fns
+	call UpdatePals
+	jr c, .vblankoccurred
+	
+; these have their own timing checks
+	call UpdateBGMap
+	call Serve2bppRequest@VBlank
+; update oam by dma transfer
+	call hPushOAM
+;	@PushOAM:
+;		ld a, Sprites >> 8
+;		ld [rDMA], a
+;		ld a, $28
+;	.loop
+;		dec a
+;		jr nz, .loop
+;		ret
+	
+.vblankoccurred
+; tell other fns vblank happened
+	xor a
+	ld [VBlankOccurred], a
+	
+; get requested ints
+	ld a, [rIF]
+	ld b, a
+; discard requested ints
+	xor a
+	ld [rIF], a
+; enable lcd stat
+	ld a, %10 ; lcd stat
+	ld [rIE], a
+; rerequest serial int if applicable (still disabled)
+; request lcd stat
+	ld a, b
+	and %1000 ; serial
+	or %10 ; lcd stat
+	ld [rIF], a
+	
+	ei
+; update sound
+	ld a, BANK(UpdateSound)
+	rst Bankswitch ; bankswitch
+	call UpdateSound
+; restore bank
+	ld a, [$ff8a]
+	rst Bankswitch
+	di
+	
+; get requested ints
+	ld a, [rIF]
+	ld b, a
+; discard requested ints
+	xor a
+	ld [rIF], a
+; enable ints besides joypad
+	ld a, %1111 ; serial timer lcdstat vblank
+	ld [rIE], a
+; rerequest ints
+	ld a, b
+	ld [rIF], a
+	ret
+; 37f
+
+
+UpdatePals: ; 37f
+; update pals for either dmg or cgb
+
+; check cgb
+	ld a, [hCGB]
+	and a
+	jp nz, UpdateCGBPals
+	
+; update gb pals
+	ld a, [$cfc7]
+	ld [rBGP], a
+	
+	ld a, [$cfc8]
+	ld [rOBP0], a
+	
+	ld a, [$cfc9]
+	ld [rOBP1], a
+	
+	and a
+	ret
+; 396
+
+
+VBlank3: ; 396
+; scx, scy
+; palettes
+; bg map
+; tiles
+; oam
+; sound / lcd stat
+
+; save bank
+	ld a, [hROMBank]
+	ld [$ff8a], a
+	
+; scroll x
+	ld a, [hSCX]
+	ld [rSCX], a
+; scroll y
+	ld a, [hSCY]
+	ld [rSCY], a
+	
+; any pals to update?
+	ld a, [hCGBPalUpdate]
+	and a
+	call nz, ForceUpdateCGBPals
+	jr c, .vblankoccurred
+; else
+	call UpdateBGMap
+	call Serve2bppRequest@VBlank
+	
+; update oam by dma transfer
+	call hPushOAM
+;	@PushOAM:
+;		ld a, Sprites >> 8
+;		ld [rDMA], a
+;		ld a, $28
+;	.loop
+;		dec a
+;		jr nz, .loop
+;		ret
+	
+.vblankoccurred
+; tell other fns vblank happened
+	xor a
+	ld [VBlankOccurred], a
+	
+; save int flag
+	ld a, [rIF]
+	push af
+; reset ints
+	xor a
+	ld [rIF], a
+; force lcdstat int during sound update
+	ld a, %10 ; lcd stat
+	ld [rIE], a
+	ld [rIF], a
+	
+	ei
+; update sound
+	ld a, BANK(UpdateSound)
+	rst Bankswitch ; bankswitch
+	call UpdateSound
+; restore bank
+	ld a, [$ff8a]
+	rst Bankswitch
+	di
+	
+; request lcdstat
+	ld a, [rIF]
+	ld b, a
+; and any other ints
+	pop af
+	or b
+	ld b, a
+; reset ints
+	xor a
+	ld [rIF], a
+; enable ints besides joypad
+	ld a, %1111 ; serial timer lcdstat vblank
+	ld [rIE], a
+; request ints
+	ld a, b
+	ld [rIF], a
+	ret
+; 3df
+
+
+VBlank4: ; 3df
+; bg map
+; tiles
+; oam
+; joypad
+; serial
+; sound
+
+; save bank
+	ld a, [hROMBank]
+	ld [$ff8a], a
+	
+	call UpdateBGMap
+	call Serve2bppRequest
+	
+; update oam by dma transfer
+	call hPushOAM
+;	@PushOAM:
+;		ld a, Sprites >> 8
+;		ld [rDMA], a
+;		ld a, $28
+;	.loop
+;		dec a
+;		jr nz, .loop
+;		ret
+	
+; update joypad
+	call Joypad
+	
+; tell other fns vblank happened
+	xor a
+	ld [VBlankOccurred], a
+	
+; handshake
+	call AskSerial
+	
+; update sound
+	ld a, BANK(UpdateSound)
+	rst Bankswitch ; bankswitch
+	call UpdateSound
+; restore bank
+	ld a, [$ff8a]
+	rst Bankswitch
+	ret
+; 400
+
+
+VBlank5: ; 400
+; scx
+; palettes
+; bg map
+; tiles
+; joypad
+; 
+
+; save bank
+	ld a, [hROMBank]
+	ld [$ff8a], a
+	
+; scroll x
+	ld a, [hSCX]
+	ld [rSCX], a
+	
+; if we can update pals, skip this part
+	call UpdatePalsIfCGB
+	jr c, .vblankoccurred
+	
+	call UpdateBGMap
+	call Serve2bppRequest
+	
+.vblankoccurred
+; tell other fns vblank happened
+	xor a
+	ld [VBlankOccurred], a
+	
+; joypad
+	call Joypad
+	
+; discard requested ints
+	xor a
+	ld [rIF], a
+; enable lcd stat
+	ld a, %10 ; lcd stat
+	ld [rIE], a
+; request lcd stat
+	ld [rIF], a
+	
+	ei
+; update sound
+	ld a, BANK(UpdateSound)
+	rst Bankswitch ; bankswitch
+	call UpdateSound
+; restore bank
+	ld a, [$ff8a]
+	rst Bankswitch
+	di
+	
+; discard requested ints
+	xor a
+	ld [rIF], a
+; enable ints besides joypad
+	ld a, %1111 ; serial timer lcdstat vblank
+	ld [rIE], a
+	ret
+; 436
+
+
+VBlank6: ; 436
+; palettes
+; tiles
+; dma transfer
+; sound
+
+; save bank
+	ld a, [hROMBank]
+	ld [$ff8a], a
+	
+; inc frame counter
+	ld hl, $ff9b
+	inc [hl]
+	
+	call UpdateCGBPals
+	jr c, .vblankoccurred
+	
+	call Serve2bppRequest
+	call Serve1bppRequest
+	call DMATransfer
+	
+.vblankoccurred
+; tell other fns vblank happened
+	xor a
+	ld [VBlankOccurred], a
+	
+; update sound
+	ld a, BANK(UpdateSound)
+	rst Bankswitch ; bankswitch
+	call UpdateSound
+; restore bank
+	ld a, [$ff8a]
+	rst Bankswitch
+	ret
+; 45a
--- /dev/null
+++ b/common/video.asm
@@ -1,0 +1,487 @@
+; Functions dealing with VRAM.
+
+DMATransfer: ; 15d8
+; Return carry if the transfer is completed.
+
+	ld a, [hDMATransfer]
+	and a
+	ret z
+
+; Start transfer
+	ld [rHDMA5], a
+
+; Execution is halted until the transfer is complete.
+
+	xor a
+	ld [hDMATransfer], a
+	scf
+	ret
+; 15e3
+
+
+UpdateBGMapBuffer: ; 15e3
+; Copy [$ffdc] 16x8 tiles from BGMapBuffer
+; to bg map addresses in BGMapBufferPtrs.
+
+; [$ffdc] must be even since this is done in pairs.
+
+; Return carry on success.
+
+	ld a, [hBGMapUpdate]
+	and a
+	ret z
+
+	ld a, [rVBK]
+	push af
+	ld [hSPBuffer], sp
+
+	ld hl, BGMapBufferPtrs
+	ld sp, hl
+
+; We can now pop the addresses of affected spots on the BG Map
+
+	ld hl, BGMapPalBuffer
+	ld de, BGMapBuffer
+
+
+.next
+; Copy a pair of 16x8 blocks (one 16x16 block)
+
+rept 2
+; Get our BG Map address
+	pop bc
+
+; Palettes
+	ld a, 1
+	ld [rVBK], a
+
+	ld a, [hli]
+	ld [bc], a
+	inc c
+	ld a, [hli]
+	ld [bc], a
+	dec c
+
+; Tiles
+	ld a, 0
+	ld [rVBK], a
+
+	ld a, [de]
+	inc de
+	ld [bc], a
+	inc c
+	ld a, [de]
+	inc de
+	ld [bc], a
+endr
+
+; We've done 2 16x8 blocks
+	ld a, [$ffdc]
+	dec a
+	dec a
+	ld [$ffdc], a
+
+	jr nz, .next
+
+
+	ld a, [hSPBuffer]
+	ld l, a
+	ld a, [hSPBuffer + 1]
+	ld h, a
+	ld sp, hl
+
+	pop af
+	ld [rVBK], a
+
+	xor a
+	ld [hBGMapUpdate], a
+	scf
+	ret
+; 163a
+
+
+WaitTop: ; 163a
+; Wait until the top third of the BG Map is being updated.
+
+	ld a, [hBGMapMode]
+	and a
+	ret z
+
+	ld a, [hBGMapThird]
+	and a
+	jr z, .done
+
+	call DelayFrame
+	jr WaitTop
+
+.done
+	xor a
+	ld [hBGMapMode], a
+	ret
+; 164c
+
+
+UpdateBGMap: ; 164c
+; Update the BG Map, in thirds, from TileMap and AttrMap.
+
+	ld a, [hBGMapMode]
+	and a
+	ret z
+
+; BG Map 0
+	dec a ; 1
+	jr z, .Tiles
+	dec a ; 2
+	jr z, .Attr
+
+; BG Map 1
+	dec a
+
+	ld a, [hBGMapAddress]
+	ld l, a
+	ld a, [hBGMapAddress + 1]
+	ld h, a
+	push hl
+
+	xor a
+	ld [hBGMapAddress], a
+	ld a, VBGMap1 >> 8
+	ld [hBGMapAddress + 1], a
+
+	ld a, [hBGMapMode]
+	push af
+	cp 3
+	call z, .Tiles
+	pop af
+	cp 4
+	call z, .Attr
+
+	pop hl
+	ld a, l
+	ld [hBGMapAddress], a
+	ld a, h
+	ld [hBGMapAddress + 1], a
+	ret
+
+
+.Attr
+	ld a, 1
+	ld [rVBK], a
+
+	ld hl, AttrMap
+	call .update
+
+	ld a, 0
+	ld [rVBK], a
+	ret
+
+
+.Tiles
+	ld hl, TileMap
+
+
+.update
+	ld [hSPBuffer], sp
+	
+; Which third?
+	ld a, [hBGMapThird]
+	and a ; 0
+	jr z, .top
+	dec a ; 1
+	jr z, .middle
+	; 2
+
+
+THIRD_HEIGHT EQU SCREEN_HEIGHT / 3
+
+
+.bottom
+	ld de, 2 * THIRD_HEIGHT * SCREEN_WIDTH
+	add hl, de
+	ld sp, hl
+
+	ld a, [hBGMapAddress + 1]
+	ld h, a
+	ld a, [hBGMapAddress]
+	ld l, a
+
+	ld de, 2 * THIRD_HEIGHT * BG_MAP_WIDTH
+	add hl, de
+
+; Next time: top third
+	xor a
+	jr .start
+
+
+.middle
+	ld de, THIRD_HEIGHT * SCREEN_WIDTH
+	add hl, de
+	ld sp, hl
+
+	ld a, [hBGMapAddress + 1]
+	ld h, a
+	ld a, [hBGMapAddress]
+	ld l, a
+
+	ld de, THIRD_HEIGHT * BG_MAP_WIDTH
+	add hl, de
+
+; Next time: bottom third
+	ld a, 2
+	jr .start
+
+
+.top
+	ld sp, hl
+
+	ld a, [hBGMapAddress + 1]
+	ld h, a
+	ld a, [hBGMapAddress]
+	ld l, a
+
+; Next time: middle third
+	ld a, 1
+
+
+.start
+; Which third to update next time
+	ld [hBGMapThird], a
+
+; Rows of tiles in a third
+	ld a, SCREEN_HEIGHT / 3
+
+; Discrepancy between TileMap and BGMap
+	ld bc, BG_MAP_WIDTH - (SCREEN_WIDTH - 1)
+
+
+.row
+; Copy a row of 20 tiles
+rept SCREEN_WIDTH / 2 - 1
+	pop de
+	ld [hl], e
+	inc l
+	ld [hl], d
+	inc l
+endr
+	pop de
+	ld [hl], e
+	inc l
+	ld [hl], d
+
+	add hl, bc
+	dec a
+	jr nz, .row
+
+
+	ld a, [hSPBuffer]
+	ld l, a
+	ld a, [hSPBuffer + 1]
+	ld h, a
+	ld sp, hl
+	ret
+; 170a
+
+
+Serve1bppRequest: ; 170a
+; Only call during the first fifth of VBlank
+
+	ld a, [Requested1bpp]
+	and a
+	ret z
+
+; Back out if we're too far into VBlank
+	ld a, [rLY]
+	cp 144
+	ret c
+	cp 146
+	ret nc
+
+; Copy [Requested1bpp] 1bpp tiles from [Requested1bppSource] to [Requested1bppDest]
+
+	ld [hSPBuffer], sp
+
+; Source
+	ld hl, Requested1bppSource
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	ld sp, hl
+	
+; Destination
+	ld hl, Requested1bppDest
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	
+; # tiles to copy
+	ld a, [Requested1bpp]
+	ld b, a
+
+	xor a
+	ld [Requested1bpp], a
+
+.next
+
+rept 3
+	pop de
+	ld [hl], e
+	inc l
+	ld [hl], e
+	inc l
+	ld [hl], d
+	inc l
+	ld [hl], d
+	inc l
+endr
+	pop de
+	ld [hl], e
+	inc l
+	ld [hl], e
+	inc l
+	ld [hl], d
+	inc l
+	ld [hl], d
+
+	inc hl
+	dec b
+	jr nz, .next
+
+
+	ld a, l
+	ld [Requested1bppDest], a
+	ld a, h
+	ld [Requested1bppDest + 1], a
+
+	ld [Requested1bppSource], sp
+
+	ld a, [hSPBuffer]
+	ld l, a
+	ld a, [hSPBuffer + 1]
+	ld h, a
+	ld sp, hl
+	ret
+; 1769
+
+
+Serve2bppRequest: ; 1769
+; Only call during the first fifth of VBlank
+
+	ld a, [Requested2bpp]
+	and a
+	ret z
+
+; Back out if we're too far into VBlank
+	ld a, [rLY]
+	cp 144
+	ret c
+	cp 146
+	ret nc
+	jr _Serve2bppRequest
+
+
+Serve2bppRequest@VBlank: ; 1778
+
+	ld a, [Requested2bpp]
+	and a
+	ret z
+
+_Serve2bppRequest: ; 177d
+; Copy [Requested2bpp] 2bpp tiles from [Requested2bppSource] to [Requested2bppDest]
+
+	ld [hSPBuffer], sp
+	
+; Source
+	ld hl, Requested2bppSource
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	ld sp, hl
+	
+; Destination
+	ld hl, Requested2bppDest
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	
+; # tiles to copy
+	ld a, [Requested2bpp]
+	ld b, a
+
+	xor a
+	ld [Requested2bpp], a
+	
+.next
+
+rept 7
+	pop de
+	ld [hl], e
+	inc l
+	ld [hl], d
+	inc l
+endr
+	pop de
+	ld [hl], e
+	inc l
+	ld [hl], d
+
+	inc hl
+	dec b
+	jr nz, .next
+
+
+	ld a, l
+	ld [Requested2bppDest], a
+	ld a, h
+	ld [Requested2bppDest + 1], a
+
+	ld [Requested2bppSource], sp
+
+	ld a, [hSPBuffer]
+	ld l, a
+	ld a, [hSPBuffer + 1]
+	ld h, a
+	ld sp, hl
+	ret
+; 17d3
+
+
+AnimateTileset: ; 17d3
+; Only call during the first fifth of VBlank
+
+	ld a, [$ffde]
+	and a
+	ret z
+	
+; Back out if we're too far into VBlank
+	ld a, [rLY]
+	cp 144
+	ret c
+	cp 151
+	ret nc
+
+	ld a, [hROMBank]
+	push af
+	ld a, BANK(_AnimateTileset)
+	rst Bankswitch
+
+	ld a, [rSVBK]
+	push af
+	ld a, 1
+	ld [rSVBK], a
+
+	ld a, [rVBK]
+	push af
+	ld a, 0
+	ld [rVBK], a
+
+	call _AnimateTileset
+
+	pop af
+	ld [rVBK], a
+	pop af
+	ld [rSVBK], a
+	pop af
+	rst Bankswitch
+	ret
+; 17ff
+
--- a/engine/copy.asm
+++ /dev/null
@@ -1,431 +1,0 @@
-; Functions to copy data from ROM.
-
-
-Functiondc9: ; dc9
-	ld a, [rLCDC]
-	bit 7, a
-	jp z, Copy2bpp
-
-	ld a, [hROMBank]
-	push af
-	ld a, BANK(Function104284)
-	rst Bankswitch
-	call Function104284
-	pop af
-	rst Bankswitch
-
-	ret
-; ddc
-
-Functionddc: ; ddc
-	ld a, [rLCDC]
-	bit 7, a
-	jp z, Copy1bpp
-
-	ld a, [hROMBank]
-	push af
-	ld a, BANK(Function1042b2)
-	rst Bankswitch
-	call Function1042b2
-	pop af
-	rst Bankswitch
-
-	ret
-; def
-
-Functiondef: ; def
-	ld [hBuffer], a
-	ld a, [hROMBank]
-	push af
-	ld a, [hBuffer]
-	rst Bankswitch
-	call FarCopyBytesDouble
-	pop af
-	rst Bankswitch
-	ret
-; dfd
-
-Functiondfd: ; dfd
-	dec c
-	ld a, [hBGMapMode]
-	push af
-	xor a
-	ld [hBGMapMode], a
-	ld a, [hROMBank]
-	push af
-	ld a, b
-	rst Bankswitch
-
-.asm_e09
-	ld a, d
-	ld [rHDMA1], a
-	ld a, e
-	and $f0
-	ld [rHDMA2], a
-	ld a, h
-	and $1f
-	ld [rHDMA3], a
-	ld a, l
-	and $f0
-	ld [rHDMA4], a
-	ld a, c
-	cp $8
-	jr c, .asm_e3c
-	sub $8
-	ld c, a
-	ld a, $f
-	ld [hDMATransfer], a
-	call DelayFrame
-	ld a, l
-	add $0
-	ld l, a
-	ld a, h
-	adc $1
-	ld h, a
-	ld a, e
-	add $0
-	ld e, a
-	ld a, d
-	adc $1
-	ld d, a
-	jr .asm_e09
-
-.asm_e3c
-	ld a, c
-	and $7f
-	ld [hDMATransfer], a
-	call DelayFrame
-	pop af
-	rst Bankswitch
-
-	pop af
-	ld [hBGMapMode], a
-	ret
-; e4a
-
-
-
-Functione4a: ; e4a
-	ld a, $5
-	ld hl, $4135
-	rst FarCall
-	ret
-; e51
-
-
-
-Functione51: ; e51
-	ld a, $3e
-	ld hl, $7449
-	rst FarCall
-	ret
-; e58
-
-Functione58: ; e58
-	ld a, $3e
-	ld hl, $74be
-	rst FarCall
-	ret
-; e5f
-
-
-
-Functione5f: ; e5f
-	ld a, $3e
-	ld hl, $748a
-	rst FarCall
-	ld a, $3e
-	ld hl, $74b0
-	rst FarCall
-	ret
-; e6c
-
-Functione6c: ; e6c
-	ld a, $3e
-	ld hl, $74b0
-	rst FarCall
-	ret
-; e73
-
-Functione73: ; e73
-	push de
-	ld a, $0
-	call GetSRAMBank
-	push bc
-	ld de, $a000
-	ld a, b
-	call FarDecompress
-	pop bc
-	pop hl
-	ld de, $a000
-	call Request2bpp
-	call CloseSRAM
-	ret
-; e8d
-
-
-
-FarCopyBytes: ; e8d
-; copy bc bytes from a:hl to de
-
-	ld [hBuffer], a
-	ld a, [hROMBank]
-	push af
-	ld a, [hBuffer]
-	rst Bankswitch
-
-	call CopyBytes
-
-	pop af
-	rst Bankswitch
-	ret
-; 0xe9b
-
-
-FarCopyBytesDouble: ; e9b
-; Copy bc bytes from a:hl to bc*2 bytes at de,
-; doubling each byte in the process.
-
-	ld [hBuffer], a
-	ld a, [hROMBank]
-	push af
-	ld a, [hBuffer]
-	rst Bankswitch
-
-; switcheroo, de <> hl
-	ld a, h
-	ld h, d
-	ld d, a
-	ld a, l
-	ld l, e
-	ld e, a
-
-	inc b
-	inc c
-	jr .dec
-
-.loop
-	ld a, [de]
-	inc de
-	ld [hli], a
-	ld [hli], a
-.dec
-	dec c
-	jr nz, .loop
-	dec b
-	jr nz, .loop
-
-	pop af
-	rst Bankswitch
-	ret
-; 0xeba
-
-
-Request2bpp: ; eba
-	ld a, [hBGMapMode]
-	push af
-	xor a
-	ld [hBGMapMode], a
-
-	ld a, [hROMBank]
-	push af
-	ld a, b
-	rst Bankswitch
-
-	ld a, [$ffd3]
-	push af
-
-	ld a, $8
-	ld [$ffd3], a
-	ld a, [InLinkBattle]
-	cp $4
-	jr nz, .asm_edc
-	ld a, [$ffe9]
-	and a
-	jr nz, .asm_edc
-	ld a, $6
-	ld [$ffd3], a
-
-.asm_edc
-	ld a, e
-	ld [Requested2bppSource], a
-	ld a, d
-	ld [Requested2bppSource + 1], a
-	ld a, l
-	ld [Requested2bppDest], a
-	ld a, h
-	ld [Requested2bppDest + 1], a
-
-.asm_eec
-	ld a, c
-	ld hl, $ffd3
-	cp [hl]
-	jr nc, .asm_f08
-
-	ld [Requested2bpp], a
-.wait
-	call DelayFrame
-	ld a, [Requested2bpp]
-	and a
-	jr nz, .wait
-
-	pop af
-	ld [$ffd3], a
-
-	pop af
-	rst Bankswitch
-
-	pop af
-	ld [hBGMapMode], a
-	ret
-
-.asm_f08
-	ld a, [$ffd3]
-	ld [Requested2bpp], a
-.asm_f0d
-	call DelayFrame
-	ld a, [Requested2bpp]
-	and a
-	jr nz, .asm_f0d
-	ld a, c
-	ld hl, $ffd3
-	sub [hl]
-	ld c, a
-	jr .asm_eec
-; f1e
-
-
-Request1bpp: ; f1e
-	ld a, [hBGMapMode]
-	push af
-	xor a
-	ld [hBGMapMode], a
-
-	ld a, [hROMBank]
-	push af
-	ld a, b
-	rst Bankswitch
-
-	ld a, [$ffd3]
-	push af
-
-	ld a, $8
-	ld [$ffd3], a
-	ld a, [InLinkBattle]
-	cp $4
-	jr nz, .asm_f40
-	ld a, [$ffe9]
-	and a
-	jr nz, .asm_f40
-	ld a, $6
-	ld [$ffd3], a
-
-.asm_f40
-	ld a, e
-	ld [Requested1bppSource], a
-	ld a, d
-	ld [Requested1bppSource + 1], a
-	ld a, l
-	ld [Requested1bppDest], a
-	ld a, h
-	ld [Requested1bppDest + 1], a
-.asm_f50
-	ld a, c
-	ld hl, $ffd3
-	cp [hl]
-	jr nc, .asm_f6c
-
-	ld [Requested1bpp], a
-.wait
-	call DelayFrame
-	ld a, [Requested1bpp]
-	and a
-	jr nz, .wait
-
-	pop af
-	ld [$ffd3], a
-
-	pop af
-	rst Bankswitch
-
-	pop af
-	ld [hBGMapMode], a
-	ret
-
-.asm_f6c
-	ld a, [$ffd3]
-	ld [Requested1bpp], a
-.asm_f71
-	call DelayFrame
-	ld a, [Requested1bpp]
-	and a
-	jr nz, .asm_f71
-	ld a, c
-	ld hl, $ffd3
-	sub [hl]
-	ld c, a
-	jr .asm_f50
-; f82
-
-
-Get2bpp: ; f82
-	ld a, [rLCDC]
-	bit 7, a
-	jp nz, Request2bpp
-
-Copy2bpp: ; f89
-; copy c 2bpp tiles from b:de to hl
-
-	push hl
-	ld h, d
-	ld l, e
-	pop de
-
-; bank
-	ld a, b
-
-; bc = c * $10
-	push af
-	swap c
-	ld a, $f
-	and c
-	ld b, a
-	ld a, $f0
-	and c
-	ld c, a
-	pop af
-
-	jp FarCopyBytes
-; f9d
-
-
-Get1bpp: ; f9d
-	ld a, [rLCDC]
-	bit 7, a
-	jp nz, Request1bpp
-
-Copy1bpp: ; fa4
-; copy c 1bpp tiles from b:de to hl
-
-	push de
-	ld d, h
-	ld e, l
-
-; bank
-	ld a, b
-
-; bc = c * $10 / 2
-	push af
-	ld h, 0
-	ld l, c
-	add hl, hl
-	add hl, hl
-	add hl, hl
-	ld b, h
-	ld c, l
-	pop af
-
-	pop hl
-	jp FarCopyBytesDouble
-; fb6
-
--- a/engine/decompress.asm
+++ /dev/null
@@ -1,367 +1,0 @@
-FarDecompress: ; b40
-; Decompress graphics data at a:hl to de
-
-; put a away for a sec
-	ld [$c2c4], a
-; save bank
-	ld a, [hROMBank]
-	push af
-; bankswitch
-	ld a, [$c2c4]
-	rst Bankswitch
-	
-; what we came here for
-	call Decompress
-	
-; restore bank
-	pop af
-	rst Bankswitch
-	ret
-; b50
-
-
-Decompress: ; b50
-; Pokemon Crystal uses an lz variant for compression.
-
-; This is mainly used for graphics, but the intro's
-; tilemaps also use this compression.
-
-; This function decompresses lz-compressed data at hl to de.
-
-
-; Basic rundown:
-
-;	A typical control command consists of:
-;		-the command (bits 5-7)
-;		-the count (bits 0-4)
-;		-and any additional params
-
-;	$ff is used as a terminator.
-
-
-;	Commands:
-
-;		0: literal
-;			literal data for some number of bytes
-;		1: iterate
-;			one byte repeated for some number of bytes
-;		2: alternate
-;			two bytes alternated for some number of bytes
-;		3: zero (whitespace)
-;			0x00 repeated for some number of bytes
-
-;	Repeater control commands have a signed parameter used to determine the start point.
-;	Wraparound is simulated:
-;		Positive values are added to the start address of the decompressed data
-;		and negative values are subtracted from the current position.
-
-;		4: repeat
-;			repeat some number of bytes from decompressed data
-;		5: flipped
-;			repeat some number of flipped bytes from decompressed data
-;			ex: $ad = %10101101 -> %10110101 = $b5
-;		6: reverse
-;			repeat some number of bytes in reverse from decompressed data
-
-;	If the value in the count needs to be larger than 5 bits,
-;	control code 7 can be used to expand the count to 10 bits.
-
-;		A new control command is read in bits 2-4.
-;		The new 10-bit count is split:
-;			bits 0-1 contain the top 2 bits
-;			another byte is added containing the latter 8
-
-;		So, the structure of the control command becomes:
-;			111xxxyy yyyyyyyy
-;			 |  |  |    |
-;            |  | our new count
-;            | the control command for this count
-;            7 (this command)
-
-; For more information, refer to the code below and in extras/gfx.py .
-
-; save starting output address
-	ld a, e
-	ld [$c2c2], a
-	ld a, d
-	ld [$c2c3], a
-	
-.loop
-; get next byte
-	ld a, [hl]
-; done?
-	cp $ff ; end
-	ret z
-
-; get control code
-	and %11100000
-	
-; 10-bit param?
-	cp $e0 ; LZ_HI
-	jr nz, .normal
-	
-	
-; 10-bit param:
-
-; get next 3 bits (%00011100)
-	ld a, [hl]
-	add a
-	add a ; << 3
-	add a
-	
-; this is our new control code
-	and %11100000
-	push af
-	
-; get param hi
-	ld a, [hli]
-	and %00000011
-	ld b, a
-	
-; get param lo
-	ld a, [hli]
-	ld c, a
-	
-; read at least 1 byte
-	inc bc
-	jr .readers
-	
-	
-.normal
-; push control code
-	push af
-; get param
-	ld a, [hli]
-	and %00011111
-	ld c, a
-	ld b, $0
-; read at least 1 byte
-	inc c
-	
-.readers
-; let's get started
-
-; inc loop counts since we bail as soon as they hit 0
-	inc b
-	inc c
-	
-; get control code
-	pop af
-; command type
-	bit 7, a ; 80, a0, c0
-	jr nz, .repeatertype
-	
-; literals
-	cp $20 ; LZ_ITER
-	jr z, .iter
-	cp $40 ; LZ_ALT
-	jr z, .alt
-	cp $60 ; LZ_ZERO
-	jr z, .zero
-	; else $00
-	
-; 00 ; LZ_LIT
-; literal data for bc bytes
-.loop1
-; done?
-	dec c
-	jr nz, .next1
-	dec b
-	jp z, .loop
-	
-.next1
-	ld a, [hli]
-	ld [de], a
-	inc de
-	jr .loop1
-	
-	
-; 20 ; LZ_ITER
-; write byte for bc bytes
-.iter
-	ld a, [hli]
-	
-.iterloop
-	dec c
-	jr nz, .iternext
-	dec b
-	jp z, .loop
-	
-.iternext
-	ld [de], a
-	inc de
-	jr .iterloop
-	
-	
-; 40 ; LZ_ALT
-; alternate two bytes for bc bytes
-
-; next pair
-.alt
-; done?
-	dec c
-	jr nz, .alt0
-	dec b
-	jp z, .altclose0
-	
-; alternate for bc
-.alt0
-	ld a, [hli]
-	ld [de], a
-	inc de
-	dec c
-	jr nz, .alt1
-; done?
-	dec b
-	jp z, .altclose1
-.alt1
-	ld a, [hld]
-	ld [de], a
-	inc de
-	jr .alt
-	
-; skip past the bytes we were alternating
-.altclose0
-	inc hl
-.altclose1
-	inc hl
-	jr .loop
-	
-	
-; 60 ; LZ_ZERO
-; write 00 for bc bytes
-.zero
-	xor a
-	
-.zeroloop
-	dec c
-	jr nz, .zeronext
-	dec b
-	jp z, .loop
-	
-.zeronext
-	ld [de], a
-	inc de
-	jr .zeroloop
-	
-	
-; repeats
-; 80, a0, c0
-; repeat decompressed data from output
-.repeatertype
-	push hl
-	push af
-; get next byte
-	ld a, [hli]
-; absolute?
-	bit 7, a
-	jr z, .absolute
-	
-; relative
-; a = -a
-	and %01111111 ; forget the bit we just looked at
-	cpl
-; add de (current output address)
-	add e
-	ld l, a
-	ld a, $ff ; -1
-	adc d
-	ld h, a
-	jr .repeaters
-	
-.absolute
-; get next byte (lo)
-	ld l, [hl]
-; last byte (hi)
-	ld h, a
-; add starting output address
-	ld a, [$c2c2]
-	add l
-	ld l, a
-	ld a, [$c2c3]
-	adc h
-	ld h, a
-	
-.repeaters
-	pop af
-	cp $80 ; LZ_REPEAT
-	jr z, .repeat
-	cp $a0 ; LZ_FLIP
-	jr z, .flip
-	cp $c0 ; LZ_REVERSE
-	jr z, .reverse
-	
-; e0 -> 80
-	
-; 80 ; LZ_REPEAT
-; repeat some decompressed data
-.repeat
-; done?
-	dec c
-	jr nz, .repeatnext
-	dec b
-	jr z, .cleanup
-	
-.repeatnext
-	ld a, [hli]
-	ld [de], a
-	inc de
-	jr .repeat
-	
-	
-; a0 ; LZ_FLIP
-; repeat some decompressed data w/ flipped bit order
-.flip
-	dec c
-	jr nz, .flipnext
-	dec b
-	jp z, .cleanup
-	
-.flipnext
-	ld a, [hli]
-	push bc
-	ld bc, $0008
-	
-.fliploop
-	rra
-	rl b
-	dec c
-	jr nz, .fliploop
-	ld a, b
-	pop bc
-	ld [de], a
-	inc de
-	jr .flip
-	
-	
-; c0 ; LZ_REVERSE
-; repeat some decompressed data in reverse
-.reverse
-	dec c
-	jr nz, .reversenext
-	
-	dec b
-	jp z, .cleanup
-	
-.reversenext
-	ld a, [hld]
-	ld [de], a
-	inc de
-	jr .reverse
-	
-	
-.cleanup
-; get type of repeat we just used
-	pop hl
-; was it relative or absolute?
-	bit 7, [hl]
-	jr nz, .next
-
-; skip two bytes for absolute
-	inc hl
-; skip one byte for relative
-.next
-	inc hl
-	jp .loop
-; c2f
-
--- a/engine/delay.asm
+++ /dev/null
@@ -1,23 +1,0 @@
-DelayFrame: ; 45a
-; Wait for one frame
-	ld a, 1
-	ld [VBlankOccurred], a
-
-; Wait for the next VBlank, halting to conserve battery
-.halt
-	halt ; rgbasm adds a nop after this instruction by default
-	ld a, [VBlankOccurred]
-	and a
-	jr nz, .halt
-	ret
-; 468
-
-
-DelayFrames: ; 468
-; Wait c frames
-	call DelayFrame
-	dec c
-	jr nz, DelayFrames
-	ret
-; 46f
-
--- a/engine/fade.asm
+++ /dev/null
@@ -1,134 +1,0 @@
-; Functions to fade the screen in and out.
-
-
-Function48c: ; 48c
-	ld a, [TimeOfDayPal]
-	ld b, a
-	ld hl, IncGradGBPalTable_11
-	ld a, l
-	sub b
-	ld l, a
-	jr nc, .asm_499
-	dec h
-
-.asm_499
-	ld a, [hli]
-	ld [rBGP], a
-	ld a, [hli]
-	ld [rOBP0], a
-	ld a, [hli]
-	ld [rOBP1], a
-	ret
-; 4a3
-
-
-Function4a3: ; 4a3
-	ld a, [hCGB]
-	and a
-	jr z, .asm_4af
-	ld hl, IncGradGBPalTable_00
-	ld b, 4
-	jr FadeOut
-
-.asm_4af
-	ld hl, IncGradGBPalTable_08
-	ld b, 4
-	jr FadeOut
-; 4b6
-
-Function4b6: ; 4b6
-	ld a, [hCGB]
-	and a
-	jr z, .asm_4c2
-	ld hl, IncGradGBPalTable_05
-	ld b, 3
-	jr FadeOut
-
-.asm_4c2
-	ld hl, IncGradGBPalTable_13
-	ld b, 3
-; 4c7
-
-FadeOut: ; 4c7
-	push de
-	ld a, [hli]
-	call DmgToCgbBGPals
-	ld a, [hli]
-	ld e, a
-	ld a, [hli]
-	ld d, a
-	call DmgToCgbObjPals
-	ld c, 8
-	call DelayFrames
-	pop de
-	dec b
-	jr nz, FadeOut
-	ret
-; 4dd
-
-Function4dd: ; 4dd
-	ld a, [hCGB]
-	and a
-	jr z, .asm_4e9
-	ld hl, IncGradGBPalTable_04 - 1
-	ld b, 4
-	jr FadeIn
-
-.asm_4e9
-	ld hl, IncGradGBPalTable_12 - 1
-	ld b, 4
-	jr FadeIn
-; 4f0
-
-Function4f0: ; 4f0
-	ld a, [hCGB]
-	and a
-	jr z, .asm_4fc
-	ld hl, IncGradGBPalTable_07 - 1
-	ld b, 3
-	jr FadeIn
-
-.asm_4fc
-	ld hl, IncGradGBPalTable_15 - 1
-	ld b, 3
-	; fallthrough
-; 501
-
-FadeIn: ; 501
-	push de
-	ld a, [hld]
-	ld d, a
-	ld a, [hld]
-	ld e, a
-	call DmgToCgbObjPals
-	ld a, [hld]
-	call DmgToCgbBGPals
-	ld c, 8
-	call DelayFrames
-	pop de
-	dec b
-	jr nz, FadeIn
-	ret
-; 517
-
-
-; 517
-IncGradGBPalTable_00: db %11111111, %11111111, %11111111
-IncGradGBPalTable_01: db %11111110, %11111110, %11111110
-IncGradGBPalTable_02: db %11111001, %11111001, %11111001
-IncGradGBPalTable_03: db %11100100, %11100100, %11100100
-IncGradGBPalTable_04: db %11100100, %11100100, %11100100
-IncGradGBPalTable_05: db %10010000, %10010000, %10010000
-IncGradGBPalTable_06: db %01000000, %01000000, %01000000
-IncGradGBPalTable_07: db %00000000, %00000000, %00000000
-;                           bgp       obp1       obp2
-IncGradGBPalTable_08: db %11111111, %11111111, %11111111
-IncGradGBPalTable_09: db %11111110, %11111110, %11111000
-IncGradGBPalTable_10: db %11111001, %11100100, %11100100
-IncGradGBPalTable_11: db %11100100, %11010000, %11100000
-IncGradGBPalTable_12: db %11100100, %11010000, %11100000
-IncGradGBPalTable_13: db %10010000, %10000000, %10010000
-IncGradGBPalTable_14: db %01000000, %01000000, %01000000
-IncGradGBPalTable_15: db %00000000, %00000000, %00000000
-; 547
-
--- a/engine/farcall.asm
+++ /dev/null
@@ -1,55 +1,0 @@
-FarCall_de: ; 2d54
-; Call a:de.
-; Preserves other registers.
-
-	ld [hBuffer], a
-	ld a, [hROMBank]
-	push af
-	ld a, [hBuffer]
-	rst Bankswitch
-	call .de
-	jr ReturnFarCall
-
-.de
-	push de
-	ret
-; 2d63
-
-
-FarCall_hl: ; 2d63
-; Call a:hl.
-; Preserves other registers.
-
-	ld [hBuffer], a
-	ld a, [hROMBank]
-	push af
-	ld a, [hBuffer]
-	rst Bankswitch
-	call Function2d82
-; 2d6e
-
-ReturnFarCall: ; 2d6e
-; We want to retain the contents of f.
-; To do this, we can pop to bc instead of af.
-	
-	ld a, b
-	ld [$cfb9], a
-	ld a, c
-	ld [$cfba], a
-	
-; Restore the working bank.
-	pop bc
-	ld a, b
-	rst Bankswitch
-	
-	ld a, [$cfb9]
-	ld b, a
-	ld a, [$cfba]
-	ld c, a
-	ret
-; 2d82
-
-Function2d82: ; 2d82
-	jp [hl]
-; 2d83
-
--- a/engine/game_time.asm
+++ /dev/null
@@ -1,132 +1,0 @@
-ResetGameTime: ; 208a
-	xor a
-	ld [GameTimeCap], a
-	ld [GameTimeHours], a
-	ld [GameTimeHours + 1], a
-	ld [GameTimeMinutes], a
-	ld [GameTimeSeconds], a
-	ld [GameTimeFrames], a
-	ret
-; 209e
-
-
-GameTimer: ; 209e
-
-	nop
-
-	ld a, [rSVBK]
-	push af
-	ld a, 1
-	ld [rSVBK], a
-
-	call UpdateGameTimer
-
-	pop af
-	ld [rSVBK], a
-	ret
-; 20ad
-
-
-UpdateGameTimer: ; 20ad
-; Increment the game timer by one frame.
-; The game timer is capped at 999:59:59.00.
-
-
-; Don't update if game logic is paused.
-	ld a, [$c2cd]
-	and a
-	ret nz
-
-; Is the timer paused?
-	ld hl, GameTimerPause
-	bit 0, [hl]
-	ret z
-
-; Is the timer already capped?
-	ld hl, GameTimeCap
-	bit 0, [hl]
-	ret nz
-
-
-; +1 frame
-	ld hl, GameTimeFrames
-	ld a, [hl]
-	inc a
-
-	cp 60 ; frames/second
-	jr nc, .second
-
-	ld [hl], a
-	ret
-
-
-.second
-	xor a
-	ld [hl], a
-
-; +1 second
-	ld hl, GameTimeSeconds
-	ld a, [hl]
-	inc a
-
-	cp 60 ; seconds/minute
-	jr nc, .minute
-
-	ld [hl], a
-	ret
-
-
-.minute
-	xor a
-	ld [hl], a
-
-; +1 minute
-	ld hl, GameTimeMinutes
-	ld a, [hl]
-	inc a
-
-	cp 60 ; minutes/hour
-	jr nc, .hour
-
-	ld [hl], a
-	ret
-
-
-.hour
-	xor a
-	ld [hl], a
-
-; +1 hour
-	ld a, [GameTimeHours]
-	ld h, a
-	ld a, [GameTimeHours + 1]
-	ld l, a
-	inc hl
-
-
-; Cap the timer after 1000 hours.
-	ld a, h
-	cp 1000 / $100
-	jr c, .ok
-
-	ld a, l
-	cp 1000 % $100
-	jr c, .ok
-
-	ld hl, GameTimeCap
-	set 0, [hl]
-
-	ld a, 59 ; 999:59:59.00
-	ld [GameTimeMinutes], a
-	ld [GameTimeSeconds], a
-	ret
-
-
-.ok
-	ld a, h
-	ld [GameTimeHours], a
-	ld a, l
-	ld [GameTimeHours + 1], a
-	ret
-; 210f
-
--- a/engine/init.asm
+++ /dev/null
@@ -1,225 +1,0 @@
-Reset: ; 150
-	di
-	call CleanSoundRestart
-	xor a
-	ld [$ffde], a
-	call ClearPalettes
-	xor a
-	ld [rIF], a
-	ld a, 1 ; VBlank int
-	ld [rIE], a
-	ei
-
-	ld hl, $cfbe
-	set 7, [hl]
-
-	ld c, 32
-	call DelayFrames
-
-	jr Init
-; 16e
-
-
-_Start: ; 16e
-	cp $11
-	jr z, .asm_175
-	xor a
-	jr .asm_177
-
-.asm_175
-	ld a, $1
-
-.asm_177
-	ld [hCGB], a
-	ld a, $1
-	ld [$ffea], a
-; 17d
-
-
-Init: ; 17d
-
-	di
-
-	xor a
-	ld [rIF], a
-	ld [rIE], a
-	ld [rRP], a
-	ld [rSCX], a
-	ld [rSCY], a
-	ld [rSB], a
-	ld [rSC], a
-	ld [rWX], a
-	ld [rWY], a
-	ld [rBGP], a
-	ld [rOBP0], a
-	ld [rOBP1], a
-	ld [rTMA], a
-	ld [rTAC], a
-	ld [$d000], a
-
-	ld a, %100 ; Start timer at 4096Hz
-	ld [rTAC], a
-
-.wait
-	ld a, [rLY]
-	cp 145
-	jr nz, .wait
-
-	xor a
-	ld [rLCDC], a
-
-; Clear WRAM bank 0
-	ld hl, $c000
-	ld bc, $d000 - $c000
-.asm_1b1
-	ld [hl], 0
-	inc hl
-	dec bc
-	ld a, b
-	or c
-	jr nz, .asm_1b1
-
-	ld sp, Stack
-
-; Clear HRAM
-	ld a, [hCGB]
-	push af
-	ld a, [$ffea]
-	push af
-	xor a
-	ld hl, $ff80
-	ld bc, $ffff - $ff80
-	call ByteFill
-	pop af
-	ld [$ffea], a
-	pop af
-	ld [hCGB], a
-
-	call ClearWRAM
-	ld a, 1
-	ld [rSVBK], a
-	call ClearVRAM
-	call ClearSprites
-	call Function270
-
-
-	ld a, BANK(LoadPushOAM)
-	rst Bankswitch
-
-	call LoadPushOAM
-
-	xor a
-	ld [$ffde], a
-	ld [hSCX], a
-	ld [hSCY], a
-	ld [rJOYP], a
-
-	ld a, $8 ; HBlank int enable
-	ld [rSTAT], a
-
-	ld a, $90
-	ld [hWY], a
-	ld [rWY], a
-
-	ld a, 7
-	ld [hWX], a
-	ld [rWX], a
-
-	ld a, %11100011
-	; LCD on
-	; Win tilemap 1
-	; Win on
-	; BG/Win tiledata 0
-	; BG Tilemap 0
-	; OBJ 8x8
-	; OBJ on
-	; BG on
-	ld [rLCDC], a
-
-	ld a, $ff
-	ld [$ffcb], a
-
-	callba Function9890
-
-	ld a, $9c
-	ld [$ffd7], a
-
-	xor a
-	ld [hBGMapAddress], a
-
-	callba StartClock
-
-	xor a
-	ld [MBC3LatchClock], a
-	ld [MBC3SRamEnable], a
-
-	ld a, [hCGB]
-	and a
-	jr z, .asm_22b
-	call Function2ff7
-.asm_22b
-
-	xor a
-	ld [rIF], a
-	ld a, %1111 ; VBlank, LCDStat, Timer, Serial interrupts
-	ld [rIE], a
-	ei
-
-	call DelayFrame
-
-	ld a, $30
-	call Predef
-
-	call CleanSoundRestart
-	xor a
-	ld [CurMusic], a
-	jp GameInit
-; 245
-
-
-ClearVRAM: ; 245
-; Wipe VRAM banks 0 and 1
-
-	ld a, 1
-	ld [rVBK], a
-	call .clear
-
-	xor a
-	ld [rVBK], a
-.clear
-	ld hl, VTiles0
-	ld bc, $2000
-	xor a
-	call ByteFill
-	ret
-; 25a
-
-ClearWRAM: ; 25a
-; Wipe swappable WRAM banks (1-7)
-
-	ld a, 1
-.asm_25c
-	push af
-	ld [rSVBK], a
-	xor a
-	ld hl, $d000
-	ld bc, $1000
-	call ByteFill
-	pop af
-	inc a
-	cp 8
-	jr nc, .asm_25c
-	ret
-; 270
-
-Function270: ; 270
-	ld a, $0
-	call GetSRAMBank
-	ld hl, $a000
-	ld bc, $0020
-	xor a
-	call ByteFill
-	call CloseSRAM
-	ret
-; 283
-
--- a/engine/joypad.asm
+++ /dev/null
@@ -1,491 +1,0 @@
-JoypadInt: ; 92e
-; Replaced by Joypad, called from VBlank instead of the useless
-; joypad interrupt.
-
-; This is a placeholder in case the interrupt is somehow enabled.
-	reti
-; 92f
-
-ClearJoypadPublic: ; 92f
-	xor a
-; Pressed this frame (delta)
-	ld [hJoyPressed], a
-; Currently pressed
-	ld [hJoyDown], a
-	ret
-; 935
-
-Joypad: ; 935
-; Read the joypad register and translate it to something more
-; workable for use in-game. There are 8 buttons, so we can use
-; one byte to contain all player input.
-
-; Updates:
-
-; hJoypadReleased: released this frame (delta)
-; hJoypadPressed: pressed this frame (delta)
-; hJoypadDown: currently pressed
-; hJoypadSum: pressed so far
-
-; Any of these three bits can be used to disable input.
-	ld a, [$cfbe]
-	and %11010000
-	ret nz
-	
-; If we're saving, input is disabled.
-	ld a, [$c2cd]
-	and a
-	ret nz
-	
-; We can only get four inputs at a time.
-; We take d-pad first for no particular reason.
-	ld a, D_PAD
-	ld [rJOYP], a
-; Read twice to give the request time to take.
-	ld a, [rJOYP]
-	ld a, [rJOYP]
-	
-; The Joypad register output is in the lo nybble (inversed).
-; We make the hi nybble of our new container d-pad input.
-	cpl
-	and $f
-	swap a
-	
-; We'll keep this in b for now.
-	ld b, a
-	
-; Buttons make 8 total inputs (A, B, Select, Start).
-; We can fit this into one byte.
-	ld a, BUTTONS
-	ld [rJOYP], a
-; Wait for input to stabilize.
-	ld a, [rJOYP]
-	ld a, [rJOYP]
-	ld a, [rJOYP]
-	ld a, [rJOYP]
-	ld a, [rJOYP]
-	ld a, [rJOYP]
-; Buttons take the lo nybble.
-	cpl
-	and $f
-	or b
-	ld b, a
-	
-; Reset the joypad register since we're done with it.
-	ld a, $30
-	ld [rJOYP], a
-	
-; To get the delta we xor the last frame's input with the new one.
-	ld a, [hJoypadDown] ; last frame
-	ld e, a
-	xor b
-	ld d, a
-; Released this frame:
-	and e
-	ld [hJoypadReleased], a
-; Pressed this frame:
-	ld a, d
-	and b
-	ld [hJoypadPressed], a
-	
-; Add any new presses to the list of collective presses:
-	ld c, a
-	ld a, [hJoypadSum]
-	or c
-	ld [hJoypadSum], a
-	
-; Currently pressed:
-	ld a, b
-	ld [hJoypadDown], a
-	
-; Now that we have the input, we can do stuff with it.
-
-; For example, soft reset:
-	and BUTTON_A | BUTTON_B | SELECT | START
-	cp  BUTTON_A | BUTTON_B | SELECT | START
-	jp z, Reset
-	
-	ret
-; 984
-
-
-GetJoypadPublic: ; 984
-; Update mirror joypad input from hJoypadDown (real input)
-
-; hJoyReleased: released this frame (delta)
-; hJoyPressed: pressed this frame (delta)
-; hJoyDown: currently pressed
-
-; bit 0 A
-;     1 B
-;     2 SELECT
-;     3 START
-;     4 RIGHT
-;     5 LEFT
-;     6 UP
-;     7 DOWN
-
-	push af
-	push hl
-	push de
-	push bc
-	
-; The player input can be automated using an input stream.
-; See more below.
-	ld a, [InputType]
-	cp a, AUTO_INPUT
-	jr z, .auto
-
-; To get deltas, take this and last frame's input.
-	ld a, [hJoypadDown] ; real input
-	ld b, a
-	ld a, [hJoyDown] ; last frame mirror
-	ld e, a
-	
-; Released this frame:
-	xor b
-	ld d, a
-	and e
-	ld [hJoyReleased], a
-	
-; Pressed this frame:
-	ld a, d
-	and b
-	ld [hJoyPressed], a
-	
-; It looks like the collective presses got commented out here.
-	ld c, a
-	
-; Currently pressed:
-	ld a, b
-	ld [hJoyDown], a ; frame input
-	
-.quit
-	pop bc
-	pop de
-	pop hl
-	pop af
-	ret	
-
-.auto
-; Use a predetermined input stream (used in the catching tutorial).
-
-; Stream format: [input][duration]
-; A value of $ff will immediately end the stream.
-
-; Read from the input stream.
-	ld a, [hROMBank]
-	push af
-	ld a, [AutoInputBank]
-	rst Bankswitch
-	
-	ld hl, AutoInputAddress
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	
-; We only update when the input duration has expired.
-	ld a, [AutoInputLength]
-	and a
-	jr z, .updateauto
-	
-; Until then, don't change anything.
-	dec a
-	ld [AutoInputLength], a
-	pop af
-	rst Bankswitch
-	jr .quit
-	
-	
-.updateauto
-; An input of $ff will end the stream.
-	ld a, [hli]
-	cp a, $ff
-	jr z, .stopauto
-	ld b, a
-	
-; A duration of $ff will end the stream indefinitely.
-	ld a, [hli]
-	ld [AutoInputLength], a
-	cp a, $ff
-	jr nz, .next
-	
-; The current input is overwritten.
-	dec hl
-	dec hl
-	ld b, NO_INPUT
-	jr .finishauto
-	
-.next
-; On to the next input...
-	ld a, l
-	ld [AutoInputAddress], a
-	ld a, h
-	ld [AutoInputAddress+1], a
-	jr .finishauto
-	
-.stopauto
-	call StopAutoInput
-	ld b, NO_INPUT
-	
-.finishauto
-	pop af
-	rst Bankswitch
-	ld a, b
-	ld [hJoyPressed], a ; pressed
-	ld [hJoyDown], a ; input
-	jr .quit
-; 9ee
-
-
-StartAutoInput: ; 9ee
-; Start reading automated input stream at a:hl.
-	
-	ld [AutoInputBank], a
-	ld a, l
-	ld [AutoInputAddress], a
-	ld a, h
-	ld [AutoInputAddress+1], a
-; Start reading the stream immediately.
-	xor a
-	ld [AutoInputLength], a
-; Reset input mirrors.
-	xor a
-	ld [hJoyPressed], a ; pressed this frame
-	ld [hJoyReleased], a ; released this frame
-	ld [hJoyDown], a ; currently pressed
-	
-	ld a, AUTO_INPUT
-	ld [InputType], a
-	ret
-; a0a
-
-
-StopAutoInput: ; a0a
-; Clear variables related to automated input.
-	xor a
-	ld [AutoInputBank], a
-	ld [AutoInputAddress], a
-	ld [AutoInputAddress+1], a
-	ld [AutoInputLength], a
-; Back to normal input.
-	ld [InputType], a
-	ret
-; a1b
-
-
-Functiona1b: ; a1b
-
-	call DelayFrame
-
-	push bc
-	call Functiona57
-	pop bc
-
-	ld a, [hJoyDown]
-	cp D_UP | SELECT | BUTTON_B
-	jr z, .asm_a34
-
-	ld a, [$ffa9]
-	and START | BUTTON_A
-	jr nz, .asm_a34
-
-	dec c
-	jr nz, Functiona1b
-
-	and a
-	ret
-
-.asm_a34
-	scf
-	ret
-; a36
-
-
-Functiona36: ; a36
-	call DelayFrame
-	call GetJoypadPublic
-	ld a, [hJoyPressed]
-	and BUTTON_A | BUTTON_B
-	ret nz
-	call RTC
-	jr Functiona36
-; a46
-
-Functiona46: ; a46
-	ld a, [hOAMUpdate]
-	push af
-	ld a, 1
-	ld [hOAMUpdate], a
-	call WaitBGMap
-	call Functiona36
-	pop af
-	ld [hOAMUpdate], a
-	ret
-; a57
-
-Functiona57: ; a57
-	call GetJoypadPublic
-	ld a, [$ffaa]
-	and a
-	ld a, [hJoyPressed]
-	jr z, .asm_a63
-	ld a, [hJoyDown]
-.asm_a63
-	ld [$ffa9], a
-	ld a, [hJoyPressed]
-	and a
-	jr z, .asm_a70
-	ld a, 15
-	ld [TextDelayFrames], a
-	ret
-
-.asm_a70
-	ld a, [TextDelayFrames]
-	and a
-	jr z, .asm_a7a
-	xor a
-	ld [$ffa9], a
-	ret
-
-.asm_a7a
-	ld a, 5
-	ld [TextDelayFrames], a
-	ret
-; a80
-
-Functiona80: ; a80
-	ld a, [$ffaf]
-	push af
-	ld a, [$ffb0]
-	push af
-	xor a
-	ld [$ffaf], a
-	ld a, $6
-	ld [$ffb0], a
-.asm_a8d
-	push hl
-	ld hl, $c606
-	call Functionb06
-	pop hl
-	call Functiona57
-	ld a, [$ffa9]
-	and $3
-	jr z, .asm_a8d
-	pop af
-	ld [$ffb0], a
-	pop af
-	ld [$ffaf], a
-	ret
-; aa5
-
-Functionaa5: ; aa5
-	call Functiona57
-	ld a, [$ffa9]
-	and BUTTON_A | BUTTON_B
-	jr z, Functionaa5
-	ret
-; aaf
-
-Functionaaf: ; aaf
-	ld a, [InLinkBattle]
-	and a
-	jr nz, .asm_ac1
-	call Functionac6
-	push de
-	ld de, SFX_READ_TEXT_2
-	call StartSFX
-	pop de
-	ret
-
-.asm_ac1
-	ld c, 65
-	jp DelayFrames
-; ac6
-
-Functionac6: ; ac6
-	ld a, [hOAMUpdate]
-	push af
-	ld a, $1
-	ld [hOAMUpdate], a
-	ld a, [InputType]
-	or a
-	jr z, .asm_ad9
-	callba Function1de28a
-.asm_ad9
-	call Functionaf5
-	call Functiona57
-	ld a, [hJoyPressed]
-	and $3
-	jr nz, .asm_af1
-	call RTC
-	ld a, $1
-	ld [hBGMapMode], a
-	call DelayFrame
-	jr .asm_ad9
-
-.asm_af1
-	pop af
-	ld [hOAMUpdate], a
-	ret
-; af5
-
-Functionaf5: ; af5
-	ld a, [$ff9b]
-	and $10
-	jr z, .asm_aff
-	ld a, $ee
-	jr .asm_b02
-
-.asm_aff
-	ld a, [$c605]
-
-.asm_b02
-	ld [$c606], a
-	ret
-; b06
-
-Functionb06: ; b06
-	push bc
-	ld a, [hl]
-	ld b, a
-	ld a, $ee
-	cp b
-	pop bc
-	jr nz, .asm_b27
-	ld a, [$ffaf]
-	dec a
-	ld [$ffaf], a
-	ret nz
-	ld a, [$ffb0]
-	dec a
-	ld [$ffb0], a
-	ret nz
-	ld a, $7a
-	ld [hl], a
-	ld a, $ff
-	ld [$ffaf], a
-	ld a, $6
-	ld [$ffb0], a
-	ret
-
-.asm_b27
-	ld a, [$ffaf]
-	and a
-	ret z
-	dec a
-	ld [$ffaf], a
-	ret nz
-	dec a
-	ld [$ffaf], a
-	ld a, [$ffb0]
-	dec a
-	ld [$ffb0], a
-	ret nz
-	ld a, $6
-	ld [$ffb0], a
-	ld a, $ee
-	ld [hl], a
-	ret
-; b40
-
--- a/engine/lcd.asm
+++ /dev/null
@@ -1,81 +1,0 @@
-; LCD handling
-
-
-Function547: ; 547
-	ld a, [hLCDStatCustom]
-	cp rSCX & $ff
-	ret nz
-	ld c, a
-	ld a, [LYOverrides]
-	ld [$ff00+c], a
-	ret
-; 552
-
-
-LCD: ; 552
-	push af
-	ld a, [hLCDStatCustom]
-	and a
-	jr z, .done
-
-; At this point it's assumed we're in WRAM bank 5!
-	push bc
-	ld a, [rLY]
-	ld c, a
-	ld b, LYOverrides >> 8
-	ld a, [bc]
-	ld b, a
-	ld a, [hLCDStatCustom]
-	ld c, a
-	ld a, b
-	ld [$ff00+c], a
-	pop bc
-
-.done
-	pop af
-	reti
-; 568
-
-
-DisableLCD: ; 568
-; Turn the LCD off
-
-; Don't need to do anything if the LCD is already off
-	ld a, [rLCDC]
-	bit 7, a ; lcd enable
-	ret z
-
-	xor a
-	ld [rIF], a
-	ld a, [rIE]
-	ld b, a
-	
-; Disable VBlank
-	res 0, a ; vblank
-	ld [rIE], a
-
-.wait
-; Wait until VBlank would normally happen
-	ld a, [rLY]
-	cp 145
-	jr nz, .wait
-
-	ld a, [rLCDC]
-	and %01111111 ; lcd enable off
-	ld [rLCDC], a
-
-	xor a
-	ld [rIF], a
-	ld a, b
-	ld [rIE], a
-	ret
-; 58a
-
-
-EnableLCD: ; 58a
-	ld a, [rLCDC]
-	set 7, a ; lcd enable
-	ld [rLCDC], a
-	ret
-; 591
-
--- a/engine/map_objects.asm
+++ /dev/null
@@ -1,683 +1,0 @@
-; Functions handling map objects.
-
-
-GetSpritePalette: ; 17ff
-	push hl
-	push de
-	push bc
-	ld c, a
-	callba _GetSpritePalette
-	ld a, c
-	pop bc
-	pop de
-	pop hl
-	ret
-; 180e
-
-
-Function180e: ; 180e
-	push hl
-	push bc
-	ld hl, $d156
-	ld c, $1f
-	ld b, a
-	ld a, [hConnectionStripLength]
-	cp $0
-	jr z, .asm_182b
-	ld a, b
-.asm_181d
-	cp [hl]
-	jr z, .asm_1830
-	inc hl
-	inc hl
-	dec c
-	jr nz, .asm_181d
-	ld a, [$d155]
-	scf
-	jr .asm_1833
-
-.asm_182b
-	ld a, [$d155]
-	jr .asm_1833
-
-.asm_1830
-	inc hl
-	xor a
-	ld a, [hl]
-
-.asm_1833
-	pop bc
-	pop hl
-	ret
-; 1836
-
-Function1836: ; 1836
-	push de
-	push hl
-
-	ld b, a
-	ld a, [hROMBank]
-	push af
-	ld a, BANK(Function142a7)
-	rst Bankswitch
-
-	ld a, b
-	call Function142a7
-	ld c, a
-
-	pop de
-	ld a, d
-	rst Bankswitch
-
-	pop hl
-	pop de
-	ret
-; 184a
-
-
-
-Function184a: ; 184a
-	ld a, [StandingTile]
-	call GetTileCollision
-	ld b, a
-	ret
-; 1852
-
-Function1852: ; 1852
-	ld a, [StandingTile]
-	call GetTileCollision
-	sub 1
-	ret z
-	and a
-	ret
-; 185d
-
-
-GetTileCollision: ; 185d
-; Get the collision type of tile a.
-
-	push de
-	push hl
-
-	ld hl, TileCollisionTable
-	ld e, a
-	ld d, 0
-	add hl, de
-
-	ld a, [hROMBank]
-	push af
-	ld a, BANK(TileCollisionTable)
-	rst Bankswitch
-	ld e, [hl]
-	pop af
-	rst Bankswitch
-
-	ld a, e
-	and $f ; lo nybble only
-
-	pop hl
-	pop de
-	ret
-; 1875
-
-
-Function1875: ; 1875
-	ld d, a
-	and $f0
-	cp $10
-	jr z, .asm_1882
-	cp $20
-	jr z, .asm_1888
-	scf
-	ret
-
-.asm_1882
-	ld a, d
-	and 7
-	ret z
-	scf
-	ret
-
-.asm_1888
-	ld a, d
-	and 7
-	ret z
-	scf
-	ret
-; 188e
-
-Function188e: ; 188e
-	cp $14
-	ret z
-	cp $1c
-	ret
-; 1894
-
-CheckCutTreeTile: ; 1894
-	cp $12
-	ret z
-	cp $1a
-	ret
-; 189a
-
-CheckHeadbuttTreeTile: ; 189a
-	cp $15
-	ret z
-	cp $1d
-	ret
-; 18a0
-
-CheckCounterTile: ; 18a0
-	cp $90
-	ret z
-	cp $98
-	ret
-; 18a6
-
-CheckPitTile: ; 18a6
-	cp $60
-	ret z
-	cp $68
-	ret
-; 18ac
-
-CheckIceTile: ; 18ac
-	cp $23
-	ret z
-	cp $2b
-	ret z
-	scf
-	ret
-; 18b4
-
-CheckWhirlpoolTile: ; 18b4
-	nop
-	cp $24
-	ret z
-	cp $2c
-	ret z
-	scf
-	ret
-; 18bd
-
-CheckWaterfallTile: ; 18bd
-	cp $33
-	ret z
-	cp $3b
-	ret
-; 18c3
-
-CheckStandingOnEntrance: ; 18c3
-	ld a, [StandingTile]
-	cp $71 ; door
-	ret z
-	cp $79
-	ret z
-	cp $7a ; stairs
-	ret z
-	cp $7b ; cave
-	ret
-; 18d2
-
-
-GetMapObject: ; 18d2
-; Return the location of map object a in bc.
-	ld hl, MapObjects
-	ld bc, $10
-	call AddNTimes
-	ld b, h
-	ld c, l
-	ret
-; 18de
-
-
-Function18de: ; 18de
-	ld [hConnectionStripLength], a
-	call GetMapObject
-	ld hl, $0000
-	add hl, bc
-	ld a, [hl]
-	cp $ff
-	jr z, .asm_18f3
-	ld [hConnectedMapWidth], a
-	call Function1ae5
-	and a
-	ret
-
-.asm_18f3
-	scf
-	ret
-; 18f5
-
-Function18f5: ; 18f5
-	ld hl, $0006
-	add hl, bc
-	ld a, [hl]
-	cp $ff
-	jr nz, .asm_1921
-	ld hl, $0007
-	add hl, bc
-	ld a, [hl]
-	cp $ff
-	jr z, .asm_191c
-	ld hl, .data_191e
-	ld a, [TimeOfDay]
-	add l
-	ld l, a
-	jr nc, .asm_1912
-	inc h
-
-.asm_1912
-	ld a, [hl]
-	ld hl, $0007
-	add hl, bc
-	and [hl]
-	jr nz, .asm_191c
-	scf
-	ret
-
-.asm_191c
-	and a
-	ret
-
-.data_191e
-	db $1
-	db $2
-	db $4
-
-.asm_1921
-	ld hl, $0006
-	add hl, bc
-	ld d, [hl]
-	ld hl, $0007
-	add hl, bc
-	ld e, [hl]
-	ld hl, hHours
-	ld a, d
-	cp e
-	jr z, .asm_1949
-	jr c, .asm_193f
-	ld a, [hl]
-	cp d
-	jr nc, .asm_1949
-	cp e
-	jr c, .asm_1949
-	jr z, .asm_1949
-	jr .asm_194b
-
-.asm_193f
-	ld a, e
-	cp [hl]
-	jr c, .asm_194b
-	ld a, [hl]
-	cp d
-	jr nc, .asm_1949
-	jr .asm_194b
-
-.asm_1949
-	and a
-	ret
-
-.asm_194b
-	scf
-	ret
-; 194d
-
-Function194d: ; 194d
-	ld [hConnectionStripLength], a
-	call GetMapObject
-	call $40e7
-	ret
-; 1956
-
-
-
-Function1956: ; 1956
-	ld [hConnectionStripLength], a
-	call Function271e
-	ld a, [hConnectionStripLength]
-	call GetMapObject
-	ld a, $2
-	ld hl, $40e7
-	rst FarCall
-	ret
-; 1967
-
-Function1967: ; 1967
-	ld [hConnectionStripLength], a
-	call GetMapObject
-	ld hl, $0000
-	add hl, bc
-	ld a, [hl]
-	cp $ff
-	ret z
-	ld [hl], $ff
-	push af
-	call Function1985
-	pop af
-	call Function1ae5
-	callba Function4357
-	ret
-; 1985
-
-Function1985: ; 1985
-	ld hl, $d4cd
-	cp [hl]
-	jr z, .asm_1990
-	ld hl, $d4ce
-	cp [hl]
-	ret nz
-
-.asm_1990
-	callba Function581f
-	ld a, $ff
-	ld [$d4cd], a
-	ld [$d4ce], a
-	ret
-; 199f
-
-Function199f: ; 199f
-	call Function1967
-	call Function2712
-	ret
-; 19a6
-
-Function19a6: ; 19a6
-	push hl
-	call GetMapObject
-	ld d, b
-	ld e, c
-	ld a, $ff
-	ld [de], a
-	inc de
-	pop hl
-	ld bc, $000f
-	call CopyBytes
-	ret
-; 19b8
-
-Function19b8: ; 19b8
-	call GetMapObject
-	ld hl, $0000
-	add hl, bc
-	ld a, [hl]
-	push af
-	ld [hl], $ff
-	inc hl
-	ld bc, $000f
-	xor a
-	call ByteFill
-	pop af
-	cp $ff
-	ret z
-	cp $d
-	ret nc
-	ld b, a
-	ld a, [$d4cd]
-	cp b
-	jr nz, .asm_19de
-	ld a, $ff
-	ld [$d4cd], a
-
-.asm_19de
-	ld a, b
-	call Function1ae5
-	callba Function4357
-	ret
-; 19e9
-
-
-
-Function19e9: ; 19e9
-	ld [$c2e2], a
-	ld a, [hROMBank]
-	ld [$c2e3], a
-	ld a, l
-	ld [$c2e4], a
-	ld a, h
-	ld [$c2e5], a
-	ld a, [$c2e2]
-	call Function18de
-	ret c
-	ld hl, $0003
-	add hl, bc
-	ld [hl], $14
-	ld hl, $0009
-	add hl, bc
-	ld [hl], $0
-	ld hl, VramState
-	set 7, [hl]
-	and a
-	ret
-; 1a13
-
-
-
-Function1a13: ; 1a13
-	push bc
-	push de
-	ld hl, $d4d6
-	ld de, $0028
-	ld c, $d
-.asm_1a1d
-	ld a, [hl]
-	and a
-	jr z, .asm_1a28
-	add hl, de
-	dec c
-	jr nz, .asm_1a1d
-	xor a
-	jr .asm_1a2c
-
-.asm_1a28
-	ld a, $d
-	sub c
-	scf
-
-.asm_1a2c
-	pop de
-	pop bc
-	ret
-; 1a2f
-
-
-
-Function1a2f: ; 1a2f
-	ld hl, $0003
-	add hl, bc
-	ld a, [hl]
-	cp $25
-	jr c, .asm_1a39
-	xor a
-
-.asm_1a39
-	ld hl, Data4273
-	ld e, a
-	ld d, 0
-	add hl, de
-	add hl, de
-	add hl, de
-	add hl, de
-	add hl, de
-	add hl, de
-	ld a, [hl]
-	ret
-; 1a47
-
-Function1a47: ; 1a47
-	push bc
-	push de
-	ld e, a
-	ld d, 0
-	ld hl, Data4273 + 1
-	add hl, de
-	add hl, de
-	add hl, de
-	add hl, de
-	add hl, de
-	add hl, de
-	ld a, BANK(Data4273)
-	call GetFarByte
-	add a
-	add a
-	and $c
-	pop de
-	pop bc
-	ret
-; 1a61
-
-
-Function1a61: ; 1a61
-	ld l, a
-	ld a, [hROMBank]
-	push af
-	ld a, BANK(Data4273)
-	rst Bankswitch
-	ld a, l
-	push bc
-
-	call Function1a71
-
-	pop bc
-	pop af
-	rst Bankswitch
-
-	ret
-; 1a71
-
-Function1a71: ; 1a71
-	ld hl, $0003
-	add hl, de
-	ld [hl], a
-	push de
-	ld e, a
-	ld d, 0
-	ld hl, Data4273 + 1
-	add hl, de
-	add hl, de
-	add hl, de
-	add hl, de
-	add hl, de
-	add hl, de
-	ld b, h
-	ld c, l
-	pop de
-	ld a, [bc]
-	inc bc
-	rlca
-	rlca
-	and $c
-	ld hl, $0008
-	add hl, de
-	ld [hl], a
-	ld a, [bc]
-	inc bc
-	ld hl, $000b
-	add hl, de
-	ld [hl], a
-	ld a, [bc]
-	inc bc
-	ld hl, $0004
-	add hl, de
-	ld [hl], a
-	ld a, [bc]
-	inc bc
-	ld hl, $0005
-	add hl, de
-	ld [hl], a
-	ld a, [bc]
-	inc bc
-	ld hl, $0006
-	add hl, de
-	ld [hl], a
-	ret
-; 1aae
-
-Function1aae: ; 1aae
-	ld a, [hROMBank]
-	push af
-	ld a, [hli]
-	rst Bankswitch
-
-	ld a, [hli]
-	ld d, [hl]
-	ld hl, $001b
-	add hl, bc
-	add [hl]
-	ld e, a
-	ld a, d
-	adc $0
-	ld d, a
-	inc [hl]
-	ld a, [de]
-	ld h, a
-	pop af
-	rst Bankswitch
-
-	ld a, h
-	ret
-; 1ac6
-
-Function1ac6: ; 1ac6
-	ld hl, VramState
-	set 0, [hl]
-	ret
-; 1acc
-
-Function1acc: ; 1acc
-	ld hl, VramState
-	res 0, [hl]
-	ret
-; 1ad2
-
-
-Function1ad2: ; 1ad2
-	ld a, [VramState]
-	bit 0, a
-	ret z
-	callba Function55e0
-	callba Function5920
-	ret
-; 1ae5
-
-
-Function1ae5: ; 1ae5
-	ld bc, $0028
-	ld hl, $d4d6
-	call AddNTimes
-	ld b, h
-	ld c, l
-	ret
-; 1af1
-
-Function1af1: ; 1af1
-	ld hl, $0000
-	add hl, bc
-	ld a, [hl]
-	and a
-	ret
-; 1af8
-
-Function1af8: ; 1af8
-	push af
-	ld hl, $0008
-	add hl, bc
-	ld a, [hl]
-	and $f3
-	ld e, a
-	pop af
-	and $c
-	or e
-	ld [hl], a
-	ret
-; 1b07
-
-
-GetSpriteDirection: ; 1b07
-	ld hl, $0008
-	add hl, bc
-	ld a, [hl]
-	and $c
-	ret
-; 1b0f
-
--- a/engine/menu.asm
+++ /dev/null
@@ -1,603 +1,0 @@
-; Functions used in displaying and handling menus.
-
-
-LoadMenuDataHeader: ; 0x1d35
-	call Function1d3c
-	call Function1c00
-	ret
-
-Function1d3c: ; 0x1d3c
-	ld de, $cf81
-	ld bc, $0010
-	call CopyBytes
-	ld a, [hROMBank]
-	ld [$cf8a], a
-	ret
-; 0x1d4b
-
-Function1d4b: ; 1d4b
-	ld [$cf88], a
-	ret
-; 1d4f
-
-
-Function1d4f: ; 1d4f
-	push hl
-	call Function1d58
-	pop hl
-	jp PrintText
-; 1d57
-
-Function1d57: ; 1d57
-	ret
-; 1d58
-
-Function1d58: ; 1d58
-	ld hl, MenuDataHeader_0x1d5f
-	call LoadMenuDataHeader
-	ret
-; 1d5f
-
-MenuDataHeader_0x1d5f: ; 1d5f
-	db $40 ; tile backup
-	db 12, 0 ; start coords
-	db 17, 19 ; end coords
-	dw VTiles0
-	db 0 ; default option
-; 1d67
-
-Function1d67: ; 1d67
-	call Function1d4f
-	call Function1c17
-	ret
-; 1d6e
-
-Function1d6e: ; 1d6e
-	ld hl, MenuDataHeader_0x1d75
-	call LoadMenuDataHeader
-	ret
-; 1d75
-
-MenuDataHeader_0x1d75: ; 1d75
-	db $40 ; tile backup
-	db 0, 0 ; start coords
-	db 17, 19 ; end coords
-	dw $0000
-	db 1 ; default option
-; 1d7d
-
-Function1d7d: ; 1d7d
-	call Function1c07
-	ret
-; 1d81
-
-Function1d81: ; 0x1d81
-	xor a
-	ld [hBGMapMode], a
-	call Function1cbb
-	call Function1ad2
-	call Function1c89
-	call Function321c
-	call Function1c66
-	ld a, [$cf91]
-	bit 7, a
-	jr z, .asm_1da7 ; 0x1d98 $d
-	call Function1c10
-	call Function1bc9
-	call Function1ff8
-	bit 1, a
-	jr z, .asm_1da9 ; 0x1da5 $2
-.asm_1da7
-	scf
-	ret
-.asm_1da9
-	and a
-	ret
-; 0x1dab
-
-Function1dab: ; 1dab
-	call LoadMenuDataHeader
-	call Function1d81
-	call Function1c17
-	ld a, [$cfa9]
-	ret
-; 1db8
-
-Function1db8: ; 0x1db8
-	push hl
-	push bc
-	push af
-	ld hl, $cf86
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	inc hl
-	inc hl
-	pop af
-	call GetNthString
-	ld d, h
-	ld e, l
-	call CopyName1
-	pop bc
-	pop hl
-	ret
-; 0x1dcf
-
-
-Function1dcf: ; 1dcf
-	ld bc, $0e07
-
-Function1dd2: ; 1dd2
-	jr Function1dd9
-
-Function1dd4: ; 1dd4
-	call LoadMenuDataHeader
-	jr Function1dfe
-
-Function1dd9: ; 1dd9
-	push bc
-	ld hl, MenuDataHeader_0x1e1d
-	call Function1d3c
-	pop bc
-	ld a, b
-	cp $e
-	jr nz, .asm_1de9
-	ld a, $e
-	ld b, a
-
-.asm_1de9
-	ld a, b
-	ld [$cf83], a
-	add $5
-	ld [$cf85], a
-	ld a, c
-	ld [$cf82], a
-	add $4
-	ld [$cf84], a
-	call Function1c00
-
-Function1dfe: ; 1dfe
-	call Function1d81
-	push af
-	ld c, $f
-	call DelayFrames
-	call Function1c17
-	pop af
-	jr c, .asm_1e16
-	ld a, [$cfa9]
-	cp $2
-	jr z, .asm_1e16
-	and a
-	ret
-
-.asm_1e16
-	ld a, $2
-	ld [$cfa9], a
-	scf
-	ret
-; 1e1d
-
-MenuDataHeader_0x1e1d: ; 1e1d
-	db $40 ; tile backup
-	db 5, 10 ; start coords
-	db 9, 15 ; end coords
-	dw MenuData2_0x1e25
-	db 1 ; default option
-; 1e25
-
-MenuData2_0x1e25: ; 1e25
-	db $c0 ; flags
-	db 2
-	db "YES@"
-	db "NO@"
-; 1e2e
-
-Function1e2e: ; 1e2e
-	call Function1e35
-	call Function1c00
-	ret
-; 1e35
-
-Function1e35: ; 1e35
-	push de
-	call Function1d3c
-	pop de
-	ld a, [$cf83]
-	ld h, a
-	ld a, [$cf85]
-	sub h
-	ld h, a
-	ld a, d
-	ld [$cf83], a
-	add h
-	ld [$cf85], a
-	ld a, [$cf82]
-	ld l, a
-	ld a, [$cf84]
-	sub l
-	ld l, a
-	ld a, e
-	ld [$cf82], a
-	add l
-	ld [$cf84], a
-	ret
-; 1e5d
-
-Function1e5d: ; 1e5d
-	call MenuFunc_1e7f
-	call MenuWriteText
-	call Function1eff
-	call Function1f23
-	call Function1bdd
-	call Function1ff8
-	ret
-; 1e70
-
-SetUpMenu: ; 1e70
-	call MenuFunc_1e7f ; ???
-	call MenuWriteText
-	call Function1eff ; set up selection pointer
-	ld hl, $cfa5
-	set 7, [hl]
-	ret
-
-MenuFunc_1e7f: ; 0x1e7f
-	call Function1c66
-	call Function1ebd
-	call Function1ea6
-	call Function1cbb
-	ret
-
-MenuWriteText: ; 0x1e8c
-	xor a
-	ld [hBGMapMode], a
-	call Function1ebd ; sort out the text 
-	call Function1eda ; actually write it
-	call Function2e31
-	ld a, [hOAMUpdate]
-	push af
-	ld a, $1
-	ld [hOAMUpdate], a
-	call Function321c
-	pop af
-	ld [hOAMUpdate], a
-	ret
-; 0x1ea6
-
-Function1ea6: ; 1ea6
-	ld a, [$cf83]
-	ld c, a
-	ld a, [$cf85]
-	sub c
-	ld c, a
-	ld a, [$cf92]
-	add a
-	inc a
-	ld b, a
-	ld a, [$cf82]
-	add b
-	ld [$cf84], a
-	ret
-; 1ebd
-
-Function1ebd: ; 1ebd
-	ld hl, $cf93
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	ld a, [$cf76]
-	and a
-	jr z, .asm_1ed3
-	ld b, a
-	ld c, $ff
-.asm_1ecc
-	ld a, [hli]
-	cp c
-	jr nz, .asm_1ecc
-	dec b
-	jr nz, .asm_1ecc
-
-.asm_1ed3
-	ld d, h
-	ld e, l
-	ld a, [hl]
-	ld [$cf92], a
-	ret
-; 1eda
-
-Function1eda: ; 1eda
-	call Function1cfd
-	ld bc, $002a
-	add hl, bc
-.asm_1ee1
-	inc de
-	ld a, [de]
-	cp $ff
-	ret z
-	ld [MenuSelection], a
-	push de
-	push hl
-	ld d, h
-	ld e, l
-	ld hl, $cf95
-	call Function1efb
-	pop hl
-	ld de, $0028
-	add hl, de
-	pop de
-	jr .asm_1ee1
-; 1efb
-
-Function1efb: ; 1efb
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	jp [hl]
-; 1eff
-
-Function1eff: ; 1eff
-	call Function1c10
-	ld hl, $cfa8
-	ld a, [$cf91]
-	bit 3, a
-	jr z, .asm_1f0e
-	set 3, [hl]
-
-.asm_1f0e
-	ld a, [$cf91]
-	bit 2, a
-	jr z, .asm_1f19
-	set 5, [hl]
-	set 4, [hl]
-
-.asm_1f19
-	ret
-; 1f1a
-
-
-Function1f1a: ; 1f1a
-	call Function1bd3
-	ld hl, $cfa8
-	and [hl]
-	jr Function1f2a
-; 1f23
-
-Function1f23: ; 1f23
-	xor a
-	ld [$cf73], a
-	call Function1bc9
-; 1f2a
-
-Function1f2a: ; 1f2a
-	bit 0, a
-	jr nz, .asm_1f52
-	bit 1, a
-	jr nz, .asm_1f6d
-	bit 3, a
-	jr nz, .asm_1f6d
-	bit 4, a
-	jr nz, .asm_1f44
-	bit 5, a
-	jr nz, .asm_1f4b
-	xor a
-	ld [$cf73], a
-	jr .asm_1f57
-
-.asm_1f44
-	ld a, $10
-	ld [$cf73], a
-	jr .asm_1f57
-
-.asm_1f4b
-	ld a, $20
-	ld [$cf73], a
-	jr .asm_1f57
-
-.asm_1f52
-	ld a, $1
-	ld [$cf73], a
-
-.asm_1f57
-	call Function1ebd
-	ld a, [$cfa9]
-	ld l, a
-	ld h, $0
-	add hl, de
-	ld a, [hl]
-	ld [MenuSelection], a
-	ld a, [$cfa9]
-	ld [$cf88], a
-	and a
-	ret
-
-.asm_1f6d
-	ld a, $2
-	ld [$cf73], a
-	ld a, $ff
-	ld [MenuSelection], a
-	scf
-	ret
-; 1f79
-
-Function1f79: ; 1f79
-	push de
-	ld hl, $cf97
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	ld a, [MenuSelection]
-	call GetNthString
-	ld d, h
-	ld e, l
-	pop hl
-	call PlaceString
-	ret
-; 1f8d
-
-Function1f8d: ; 1f8d
-	push de
-	ld a, [MenuSelection]
-	call Function1fb1
-	inc hl
-	inc hl
-	ld a, [hli]
-	ld d, [hl]
-	ld e, a
-	pop hl
-	call PlaceString
-	ret
-; 1f9e
-
-Function1f9e: ; 1f9e
-	call Function1fb1
-	inc hl
-	inc hl
-	ld a, [hli]
-	ld d, [hl]
-	ld e, a
-	ret
-; 1fa7
-
-Function1fa7: ; 1fa7
-	ld a, [MenuSelection]
-	call Function1fb1
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	jp [hl]
-; 1fb1
-
-Function1fb1: ; 1fb1
-	ld e, a
-	ld d, $0
-	ld hl, $cf97
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	add hl, de
-	add hl, de
-	add hl, de
-	add hl, de
-	ret
-; 1fbf
-
-Function1fbf: ; 1fbf
-	ld hl, $cf71
-	call Function1ff0
-	ld hl, $cf81
-	call Function1ff0
-	ld hl, $cf91
-	call Function1ff0
-	ld hl, $cfa1
-	call Function1ff0
-	ld a, [rSVBK]
-	push af
-	ld a, $7
-	ld [rSVBK], a
-	xor a
-	ld hl, $dfff
-	ld [hld], a
-	ld [hld], a
-	ld a, l
-	ld [$cf71], a
-	ld a, h
-	ld [$cf72], a
-	pop af
-	ld [rSVBK], a
-	ret
-; 1ff0
-
-Function1ff0: ; 1ff0
-	ld bc, $0010
-	xor a
-	call ByteFill
-	ret
-; 1ff8
-
-Function1ff8: ; 1ff8
-	push af
-	and $3
-	jr z, .asm_2007
-	ld hl, $cf81
-	bit 3, [hl]
-	jr nz, .asm_2007
-	call PlayClickSFX
-
-.asm_2007
-	pop af
-	ret
-; 2009
-
-
-PlayClickSFX: ; 2009 
-	push de
-	ld de, SFX_READ_TEXT_2
-	call StartSFX
-	pop de
-	ret
-; 0x2012
-
-Function2012: ; 2012
-	call Function1d4f
-	call Functiona46
-	call Function1c07
-	ret
-; 201c
-
-Function201c: ; 201c
-	ld [hBuffer], a
-	ld a, [hROMBank]
-	push af
-	ld a, [hBuffer]
-	rst Bankswitch
-
-	call PlaceString
-	pop af
-	rst Bankswitch
-
-	ret
-; 202a
-
-Function202a: ; 202a
-	ld a, [hROMBank]
-	ld [$cf94], a
-	ld a, $9
-	ld hl, $400e
-	rst FarCall
-	ld a, [$cf88]
-	ret
-; 2039
-
-Function2039: ; 2039
-	ld a, [hROMBank]
-	ld [$cf94], a
-	ld a, $9
-	ld hl, $4022
-	rst FarCall
-	ld a, [$cf88]
-	ret
-; 2048
-
-Function2048: ; 2048
-	ld a, [hROMBank]
-	ld [$cf94], a
-	ld a, $9
-	ld hl, $403c
-	rst FarCall
-	ld a, [$cf88]
-	ret
-; 2057
-
-Function2057: ; 2057
-	ld a, [hROMBank]
-	push af
-	ld a, $21
-	rst Bankswitch
-
-	call $42db
-	pop af
-	rst Bankswitch
-
-	ret
-; 2063
-
--- a/engine/palettes.asm
+++ /dev/null
@@ -1,347 +1,0 @@
-; Functions dealing with palettes.
-
-
-UpdatePalsIfCGB: ; c2f
-; update bgp data from BGPals
-; update obp data from OBPals
-; return carry if successful
-
-; check cgb
-	ld a, [hCGB]
-	and a
-	ret z
-
-
-UpdateCGBPals: ; c33
-; return carry if successful
-; any pals to update?
-	ld a, [hCGBPalUpdate]
-	and a
-	ret z
-
-
-ForceUpdateCGBPals: ; c37
-
-	ld a, [rSVBK]
-	push af
-	ld a, 5 ; BANK(BGPals)
-	ld [rSVBK], a
-
-	ld hl, BGPals ; 5:d080
-
-; copy 8 pals to bgpd
-	ld a, %10000000 ; auto increment, index 0
-	ld [rBGPI], a
-	ld c, rBGPD % $100
-	ld b, 4 ; NUM_PALS / 2
-.bgp
-	rept $10
-	ld a, [hli]
-	ld [$ff00+c], a
-	endr
-
-	dec b
-	jr nz, .bgp
-	
-; hl is now 5:d0c0 OBPals
-	
-; copy 8 pals to obpd
-	ld a, %10000000 ; auto increment, index 0
-	ld [rOBPI], a
-	ld c, rOBPD - rJOYP
-	ld b, 4 ; NUM_PALS / 2
-.obp
-	rept $10
-	ld a, [hli]
-	ld [$ff00+c], a
-	endr
-
-	dec b
-	jr nz, .obp
-	
-	pop af
-	ld [rSVBK], a
-
-; clear pal update queue
-	xor a
-	ld [hCGBPalUpdate], a
-
-	scf
-	ret
-; c9f
-
-
-DmgToCgbBGPals: ; c9f
-; exists to forego reinserting cgb-converted image data
-
-; input: a -> bgp
-
-	ld [rBGP], a
-	push af
-
-	ld a, [hCGB]
-	and a
-	jr z, .end
-
-	push hl
-	push de
-	push bc
-	ld a, [rSVBK]
-	push af
-
-	ld a, 5
-	ld [rSVBK], a
-
-; copy & reorder bg pal buffer
-	ld hl, BGPals ; to
-	ld de, Unkn1Pals ; from
-; order
-	ld a, [rBGP]
-	ld b, a
-; all pals
-	ld c, 8
-	call CopyPals
-; request pal update
-	ld a, 1
-	ld [hCGBPalUpdate], a
-
-	pop af
-	ld [rSVBK], a
-	pop bc
-	pop de
-	pop hl
-.end
-	pop af
-	ret
-; ccb
-
-
-DmgToCgbObjPals: ; ccb
-; exists to forego reinserting cgb-converted image data
-
-; input: d -> obp1
-;        e -> obp2
-
-	ld a, e
-	ld [rOBP0], a
-	ld a, d
-	ld [rOBP1], a
-	
-	ld a, [hCGB]
-	and a
-	ret z
-
-	push hl
-	push de
-	push bc
-	ld a, [rSVBK]
-	push af
-
-	ld a, 5
-	ld [rSVBK], a
-
-; copy & reorder obj pal buffer
-	ld hl, OBPals ; to
-	ld de, Unkn2Pals ; from
-; order
-	ld a, [rOBP0]
-	ld b, a
-; all pals
-	ld c, 8
-	call CopyPals
-; request pal update
-	ld a, 1
-	ld [hCGBPalUpdate], a
-
-	pop af
-	ld [rSVBK], a
-	pop bc
-	pop de
-	pop hl
-	ret
-; cf8
-
-
-Functioncf8: ; cf8
-	ld [rOBP0], a
-	push af
-	ld a, [hCGB]
-	and a
-	jr z, .asm_d22
-	push hl
-	push de
-	push bc
-	ld a, [rSVBK]
-	push af
-	ld a, $5
-	ld [rSVBK], a
-	ld hl, $d0c0
-	ld de, MartPointer
-	ld a, [rOBP0]
-	ld b, a
-	ld c, $1
-	call CopyPals
-	ld a, $1
-	ld [hCGBPalUpdate], a
-	pop af
-	ld [rSVBK], a
-	pop bc
-	pop de
-	pop hl
-
-.asm_d22
-	pop af
-	ret
-; d24
-
-Functiond24: ; d24
-	ld [rOBP1], a
-	push af
-	ld a, [hCGB]
-	and a
-	jr z, .asm_d4e
-	push hl
-	push de
-	push bc
-	ld a, [rSVBK]
-	push af
-	ld a, $5
-	ld [rSVBK], a
-	ld hl, $d0c8
-	ld de, $d048
-	ld a, [rOBP1]
-	ld b, a
-	ld c, $1
-	call CopyPals
-	ld a, $1
-	ld [hCGBPalUpdate], a
-	pop af
-	ld [rSVBK], a
-	pop bc
-	pop de
-	pop hl
-
-.asm_d4e
-	pop af
-	ret
-; d50
-
-
-
-CopyPals: ; d50
-; copy c palettes in order b from de to hl
-
-	push bc
-	ld c, 4 ; NUM_PAL_COLORS
-.loop
-	push de
-	push hl
-	
-; get pal color
-	ld a, b
-	and %11 ; color
-; 2 bytes per color
-	add a
-	ld l, a
-	ld h, 0
-	add hl, de
-	ld e, [hl]
-	inc hl
-	ld d, [hl]
-	
-; dest
-	pop hl
-; write color
-	ld [hl], e
-	inc hl
-	ld [hl], d
-	inc hl
-; next pal color
-	srl b
-	srl b
-; source
-	pop de
-; done pal?
-	dec c
-	jr nz, .loop
-	
-; de += 8 (next pal)
-	ld a, 8 ; NUM_PAL_COLORS * 2 ; bytes per pal
-	add e
-	jr nc, .ok
-	inc d
-.ok
-	ld e, a
-	
-; how many more pals?
-	pop bc
-	dec c
-	jr nz, CopyPals
-	ret
-; d79
-
-
-Functiond79: ; d79
-	ld a, [hCGB]
-	and a
-	ret z
-	ld a, 1
-	ld [rVBK], a
-	ld hl, VTiles0
-	ld bc, $2000
-	xor a
-	call ByteFill
-	ld a, 0
-	ld [rVBK], a
-	ret
-; d90
-
-
-Functiond90: ; d90
-	ret
-; d91
-
-
-Functiond91: ; d91
-	ld a, [hCGB]
-	and a
-	ret z
-	ld a, [rSVBK]
-	push af
-	ld a, 5 ; BANK(BGPals)
-	ld [rSVBK], a
-	ld hl, BGPals
-	ld bc, $40 + $10
-	xor a
-	call ByteFill
-	pop af
-	ld [rSVBK], a
-	ld a, 1
-	ld [hCGBPalUpdate], a
-	call DelayFrame
-	ret
-; db1
-
-
-Functiondb1: ; db1
-	ld a, [hROMBank]
-	push af
-	ld a, BANK(Function4c000)
-	rst Bankswitch
-	call Function4c000
-	pop af
-	rst Bankswitch
-	ret
-; dbd
-
-Functiondbd: ; dbd
-	ld a, [hROMBank]
-	push af
-	ld a, BANK(Function4c03f)
-	rst Bankswitch
-	call Function4c03f
-	pop af
-	rst Bankswitch
-	ret
-; dc9
-
--- a/engine/rtc.asm
+++ /dev/null
@@ -1,25 +1,0 @@
-RTC: ; 46f
-; update time and time-sensitive palettes
-
-; rtc enabled?
-	ld a, [$c2ce]
-	cp 0
-	ret z
-	
-	call UpdateTime
-	
-; obj update on?
-	ld a, [VramState]
-	bit 0, a ; obj update
-	ret z
-
-TimeOfDayPals: ; 47e
-	callab _TimeOfDayPals
-	ret
-; 485
-
-UpdateTimePals: ; 485
-	callab _UpdateTimePals
-	ret
-; 48c
-
--- a/engine/serial.asm
+++ /dev/null
@@ -1,408 +1,0 @@
-Serial: ; 6ef
-; The serial interrupt.
-
-	push af
-	push bc
-	push de
-	push hl
-
-	ld a, [$ffc9]
-	and a
-	jr nz, .asm_71c
-
-	ld a, [$c2d4]
-	bit 0, a
-	jr nz, .asm_721
-
-	ld a, [$ffcb]
-	inc a
-	jr z, .asm_726
-
-	ld a, [rSB]
-	ld [hSerialReceive], a
-
-	ld a, [hSerialSend]
-	ld [rSB], a
-
-	ld a, [$ffcb]
-	cp $2
-	jr z, .asm_752
-
-	ld a, 0 << rSC_ON
-	ld [rSC], a
-	ld a, 1 << rSC_ON
-	ld [rSC], a
-	jr .asm_752
-
-.asm_71c
-	call Function3e80
-	jr .asm_75a
-
-.asm_721
-	call Function2057
-	jr .asm_75a
-
-.asm_726
-	ld a, [rSB]
-	cp $1
-	jr z, .asm_730
-	cp $2
-	jr nz, .asm_752
-
-.asm_730
-	ld [hSerialReceive], a
-	ld [$ffcb], a
-	cp $2
-	jr z, .asm_74f
-
-	xor a
-	ld [rSB], a
-	ld a, $3
-	ld [rDIV], a
-
-.asm_73f
-	ld a, [rDIV]
-	bit 7, a
-	jr nz, .asm_73f
-
-	ld a, 0 << rSC_ON
-	ld [rSC], a
-	ld a, 1 << rSC_ON
-	ld [rSC], a
-	jr .asm_752
-
-.asm_74f
-	xor a
-	ld [rSB], a
-
-.asm_752
-	ld a, $1
-	ld [$ffca], a
-	ld a, $fe
-	ld [hSerialSend], a
-
-.asm_75a
-	pop hl
-	pop de
-	pop bc
-	pop af
-	reti
-; 75f
-
-Function75f: ; 75f
-	ld a, $1
-	ld [$ffcc], a
-.asm_763
-	ld a, [hl]
-	ld [hSerialSend], a
-	call Function78a
-	push bc
-	ld b, a
-	inc hl
-	ld a, $30
-.asm_76e
-	dec a
-	jr nz, .asm_76e
-	ld a, [$ffcc]
-	and a
-	ld a, b
-	pop bc
-	jr z, .asm_782
-	dec hl
-	cp $fd
-	jr nz, .asm_763
-	xor a
-	ld [$ffcc], a
-	jr .asm_763
-
-.asm_782
-	ld [de], a
-	inc de
-	dec bc
-	ld a, b
-	or c
-	jr nz, .asm_763
-	ret
-; 78a
-
-Function78a: ; 78a
-	xor a
-	ld [$ffca], a
-	ld a, [$ffcb]
-	cp $2
-	jr nz, .asm_79b
-	ld a, $1
-	ld [rSC], a
-	ld a, $81
-	ld [rSC], a
-
-.asm_79b
-	ld a, [$ffca]
-	and a
-	jr nz, .asm_7e5
-	ld a, [$ffcb]
-	cp $1
-	jr nz, .asm_7c0
-	call Function82b
-	jr z, .asm_7c0
-	call .asm_825
-	push hl
-	ld hl, $cf5c
-	inc [hl]
-	jr nz, .asm_7b7
-	dec hl
-	inc [hl]
-
-.asm_7b7
-	pop hl
-	call Function82b
-	jr nz, .asm_79b
-	jp Function833
-
-.asm_7c0
-	ld a, [rIE]
-	and $f
-	cp $8
-	jr nz, .asm_79b
-	ld a, [$cf5d]
-	dec a
-	ld [$cf5d], a
-	jr nz, .asm_79b
-	ld a, [$cf5e]
-	dec a
-	ld [$cf5e], a
-	jr nz, .asm_79b
-	ld a, [$ffcb]
-	cp $1
-	jr z, .asm_7e5
-	ld a, $ff
-.asm_7e2
-	dec a
-	jr nz, .asm_7e2
-
-.asm_7e5
-	xor a
-	ld [$ffca], a
-	ld a, [rIE]
-	and $f
-	sub $8
-	jr nz, .asm_7f8
-	ld [$cf5d], a
-	ld a, $50
-	ld [$cf5e], a
-
-.asm_7f8
-	ld a, [hSerialReceive]
-	cp $fe
-	ret nz
-	call Function82b
-	jr z, .asm_813
-	push hl
-	ld hl, $cf5c
-	ld a, [hl]
-	dec a
-	ld [hld], a
-	inc a
-	jr nz, .asm_80d
-	dec [hl]
-
-.asm_80d
-	pop hl
-	call Function82b
-	jr z, Function833
-
-.asm_813
-	ld a, [rIE]
-	and $f
-	cp $8
-	ld a, $fe
-	ret z
-	ld a, [hl]
-	ld [hSerialSend], a
-	call DelayFrame
-	jp Function78a
-
-.asm_825
-	ld a, $f
-.asm_827
-	dec a
-	jr nz, .asm_827
-	ret
-; 82b
-
-Function82b: ; 82b
-	push hl
-	ld hl, $cf5b
-	ld a, [hli]
-	or [hl]
-	pop hl
-	ret
-; 833
-
-Function833: ; 833
-	dec a
-	ld [$cf5b], a
-	ld [$cf5c], a
-	ret
-; 83b
-
-Function83b: ; 83b
-	ld hl, $cf56
-	ld de, $cf51
-	ld c, $2
-	ld a, $1
-	ld [$ffcc], a
-.asm_847
-	call DelayFrame
-	ld a, [hl]
-	ld [hSerialSend], a
-	call Function78a
-	ld b, a
-	inc hl
-	ld a, [$ffcc]
-	and a
-	ld a, $0
-	ld [$ffcc], a
-	jr nz, .asm_847
-	ld a, b
-	ld [de], a
-	inc de
-	dec c
-	jr nz, .asm_847
-	ret
-; 862
-
-Function862: ; 862
-	call Function309d
-	callab Function4000
-	call Function87d
-	jp Function30b4
-; 871
-
-
-Function871: ; 871
-	call Function309d
-	callab Function4000
-	jp Function87d
-; 87d
-
-
-
-Function87d: ; 87d
-	ld a, $ff
-	ld [$cf52], a
-.asm_882
-	call Function8c1
-	call DelayFrame
-	call Function82b
-	jr z, .asm_89e
-	push hl
-	ld hl, $cf5c
-	dec [hl]
-	jr nz, .asm_89d
-	dec hl
-	dec [hl]
-	jr nz, .asm_89d
-	pop hl
-	xor a
-	jp Function833
-
-.asm_89d
-	pop hl
-
-.asm_89e
-	ld a, [$cf52]
-	inc a
-	jr z, .asm_882
-	ld b, $a
-.asm_8a6
-	call DelayFrame
-	call Function8c1
-	dec b
-	jr nz, .asm_8a6
-	ld b, $a
-.asm_8b1
-	call DelayFrame
-	call Function908
-	dec b
-	jr nz, .asm_8b1
-	ld a, [$cf52]
-	ld [$cf51], a
-	ret
-; 8c1
-
-Function8c1: ; 8c1
-	push bc
-	ld b, $60
-	ld a, [InLinkBattle]
-	cp $1
-	jr z, .asm_8d7
-	ld b, $60
-	jr c, .asm_8d7
-	cp $2
-	ld b, $70
-	jr z, .asm_8d7
-	ld b, $80
-
-.asm_8d7
-	call Function8f3
-	ld a, [$cf56]
-	add b
-	ld [hSerialSend], a
-	ld a, [$ffcb]
-	cp $2
-	jr nz, .asm_8ee
-	ld a, $1
-	ld [rSC], a
-	ld a, $81
-	ld [rSC], a
-
-.asm_8ee
-	call Function8f3
-	pop bc
-	ret
-; 8f3
-
-Function8f3: ; 8f3
-	ld a, [hSerialReceive]
-	ld [$cf51], a
-	and $f0
-	cp b
-	ret nz
-	xor a
-	ld [hSerialReceive], a
-	ld a, [$cf51]
-	and $f
-	ld [$cf52], a
-	ret
-; 908
-
-Function908: ; 908
-	xor a
-	ld [hSerialSend], a
-	ld a, [$ffcb]
-	cp $2
-	ret nz
-	ld a, $1
-	ld [rSC], a
-	ld a, $81
-	ld [rSC], a
-	ret
-; 919
-
-Function919: ; 919
-	ld a, [InLinkBattle]
-	and a
-	ret nz
-	ld a, $2
-	ld [rSB], a
-	xor a
-	ld [hSerialReceive], a
-	ld a, $0
-	ld [rSC], a
-	ld a, $80
-	ld [rSC], a
-	ret
-; 92e
-
-
--- a/engine/sine.asm
+++ /dev/null
@@ -1,22 +1,0 @@
-Cosine: ; 1b0f
-; Return d * cos(a) in hl
-	add $10 ; 90 degrees
-
-Sine: ; 1b11
-; Return d * sin(a) in hl
-; a is a signed 6-bit value.
-
-	ld e, a
-
-	ld a, [hROMBank]
-	push af
-	ld a, BANK(_Sine)
-	rst Bankswitch
-
-	call _Sine
-
-	pop af
-	rst Bankswitch
-	ret
-; 1b1e
-
--- a/engine/text.asm
+++ /dev/null
@@ -1,1230 +1,0 @@
-ClearBox: ; fb6
-; Fill a c*b box at hl with blank tiles.
-
-	ld a, " "
-.y
-	push bc
-	push hl
-.x
-	ld [hli], a
-	dec c
-	jr nz, .x
-	pop hl
-	ld bc, 20 ; screen width
-	add hl, bc
-	pop bc
-	dec b
-	jr nz, .y
-	ret
-; fc8
-
-
-ClearTileMap: ; fc8
-; Fill TileMap with blank tiles.
-
-	ld hl, TileMap
-	ld a, " "
-	ld bc, 360 ; screen dimensions 20*18
-	call ByteFill
-	
-; We aren't done if the LCD is on.
-	ld a, [rLCDC]
-	bit 7, a
-	ret z
-	jp WaitBGMap
-; fdb
-
-
-Functionfdb: ; fdb
-	ld a, $7
-	ld hl, AttrMap
-	ld bc, $0168
-	call ByteFill
-	jr ClearTileMap
-; fe8
-
-
-
-TextBox: ; fe8
-; Draw a text box width c height b at hl
-; Dimensions do not include the border.
-	push bc
-	push hl
-	call TextBoxBorder
-	pop hl
-	pop bc
-	jr TextBoxPalette
-; ff1
-
-
-TextBoxBorder: ; ff1
-
-; Top
-	push hl
-	ld a, "┌"
-	ld [hli], a
-	inc a ; "─"
-	call NPlaceChar
-	inc a ; "┐"
-	ld [hl], a
-
-; Middle
-	pop hl
-	ld de, 20 ; screen width
-	add hl, de
-.PlaceRow
-	push hl
-	ld a, "│"
-	ld [hli], a
-	ld a, " "
-	call NPlaceChar
-	ld [hl], "│"
-	pop hl
-	ld de, 20 ; screen width
-	add hl, de
-	dec b
-	jr nz, .PlaceRow
-
-; Bottom
-	ld a, "└"
-	ld [hli], a
-	ld a, "─"
-	call NPlaceChar
-	ld [hl], "┘"
-
-	ret
-; 101e
-
-
-NPlaceChar: ; 101e
-; Place char a c times
-	ld d,c
-.loop
-	ld [hli],a
-	dec d
-	jr nz, .loop
-	ret
-; 1024
-
-
-TextBoxPalette: ; 1024
-; Fill text box width c height b at hl with pal 7
-	ld de, AttrMap - TileMap
-	add hl, de
-	inc b
-	inc b
-	inc c
-	inc c
-	ld a, 7 ; pal
-.gotoy
-	push bc
-	push hl
-.gotox
-	ld [hli], a
-	dec c
-	jr nz, .gotox
-	pop hl
-	ld de, 20 ; screen width
-	add hl, de
-	pop bc
-	dec b
-	jr nz, .gotoy
-	ret
-; 103e
-
-
-SpeechTextBox: ; 103e
-; Standard textbox.
-	hlcoord 0, 12
-	ld b, 4 ; height
-	ld c, 18 ; screen width - 2 (border)
-	jp TextBox
-; 1048
-
-UnknownText_0x1048: ; 1048
-	db $0, "ゲームフりーク!", $57
-; 1052
-
-Function1052: ; 1052
-	ld hl, .text_1056
-	ret
-.text_1056
-	db "@"
-; 1057
-
-
-PrintText: ; 1057
-	call Function106c
-Function105a: ; 105a
-	push hl
-	hlcoord 1, 14
-	ld bc, 18 + 3<<8
-	call ClearBox
-	pop hl
-
-PrintTextBoxText: ; 1065
-	bccoord 1, 14
-	call Function13e5
-	ret
-; 106c
-
-
-Function106c: ; 106c
-	push hl
-	call SpeechTextBox
-	call Function1ad2
-	call Function321c
-	pop hl
-	ret
-; 1078
-
-
-
-PlaceString: ; 1078
-	push hl
-
-PlaceNextChar: ; 1079
-	ld a, [de]
-	cp "@"
-	jr nz, CheckDict
-	ld b, h
-	ld c, l
-	pop hl
-	ret
-	pop de
-
-NextChar: ; 1083
-	inc de
-	jp PlaceNextChar
-
-CheckDict: ; 1087
-	cp $15
-	jp z, Function117b
-	cp $4f
-	jp z, Char4F
-	cp $4e
-	jp z, Function12a7
-	cp $16
-	jp z, Function12b9
-	and a
-	jp z, Function1383
-	cp $4c
-	jp z, $1337
-	cp $4b
-	jp z, Char4B
-	cp $51 ; Player name
-	jp z, Function12f2
-	cp $49
-	jp z, Function1186
-	cp $52 ; Mother name
-	jp z, Function118d
-	cp $53
-	jp z, Function1194
-	cp $35
-	jp z, Function11e8
-	cp $36
-	jp z, Function11ef
-	cp $37
-	jp z, Function11f6
-	cp $38
-	jp z, Function119b
-	cp $39
-	jp z, Function11a2
-	cp $54
-	jp z, Function11c5
-	cp $5b
-	jp z, Function11b7
-	cp $5e
-	jp z, Function11be
-	cp $5c
-	jp z, Function11b0
-	cp $5d
-	jp z, Function11a9
-	cp $23
-	jp z, Function11cc
-	cp $22
-	jp z, Function12b0
-	cp $55
-	jp z, Char55
-	cp $56
-	jp z, Function11d3
-	cp $57
-	jp z, $137c
-	cp $58
-	jp z, Function135a
-	cp $4a
-	jp z, Function11da
-	cp $24
-	jp z, Function11e1
-	cp $25
-	jp z, NextChar
-	cp $1f
-	jr nz, .asm_1122
-	ld a, $7f
-.asm_1122
-	cp $5f
-	jp z, Char5F
-	cp $59
-	jp z, Function11fd
-	cp $5a
-	jp z, Char5D
-	cp $3f
-	jp z, $121b
-	cp $14
-	jp z, $1252
-	cp $e4
-	jr z, .asm_1174 ; 0x113d $35
-	cp $e5
-	jr z, .asm_1174 ; 0x1141 $31
-	jr .asm_114c ; 0x1143 $7
-	ld b, a
-	call Function13c6
-	jp NextChar
-.asm_114c
-	cp $60
-	jr nc, .asm_1174 ; 0x114e $24
-	cp $40
-	jr nc, .asm_1165 ; 0x1152 $11
-	cp $20
-	jr nc, .asm_115c ; 0x1156 $4
-	add $80
-	jr .asm_115e ; 0x115a $2
-.asm_115c
-	add $90
-.asm_115e
-	ld b, $e5
-	call Function13c6
-	jr .asm_1174 ; 0x1163 $f
-.asm_1165
-	cp $44
-	jr nc, .asm_116d ; 0x1167 $4
-	add $59
-	jr .asm_116f ; 0x116b $2
-.asm_116d
-	add $86
-.asm_116f
-	ld b, $e4
-	call Function13c6
-.asm_1174
-	ld [hli], a
-	call PrintLetterDelay
-	jp NextChar
-; 0x117b
-
-
-Function117b: ; 117b
-	ld c, l
-	ld b, h
-	ld a, $5f
-	ld hl, $7036
-	rst FarCall
-	jp PlaceNextChar
-; 1186
-
-Function1186: ; 1186
-	push de
-	ld de, MomsName
-	jp $126a
-; 118d
-
-Function118d: ; 118d
-	push de
-	ld de, PlayerName
-	jp $126a
-; 1194
-
-Function1194: ; 1194
-	push de
-	ld de, RivalName
-	jp $126a
-; 119b
-
-Function119b: ; 119b
-	push de
-	ld de, RedsName
-	jp $126a
-; 11a2
-
-Function11a2: ; 11a2
-	push de
-	ld de, GreensName
-	jp $126a
-; 11a9
-
-Function11a9: ; 11a9
-	push de
-	ld de, Char5DText
-	jp $126a
-; 11b0
-
-Function11b0: ; 11b0
-	push de
-	ld de, Char5CText
-	jp $126a
-; 11b7
-
-Function11b7: ; 11b7
-	push de
-	ld de, Char5BText
-	jp $126a
-; 11be
-
-Function11be: ; 11be
-	push de
-	ld de, Char5EText
-	jp $126a
-; 11c5
-
-Function11c5: ; 11c5
-	push de
-	ld de, Char54Text
-	jp $126a
-; 11cc
-
-Function11cc: ; 11cc
-	push de
-	ld de, Char23Text
-	jp $126a
-; 11d3
-
-Function11d3: ; 11d3
-	push de
-	ld de, $1292
-	jp $126a
-; 11da
-
-Function11da: ; 11da
-	push de
-	ld de, Char4AText
-	jp $126a
-; 11e1
-
-Function11e1: ; 11e1
-	push de
-	ld de, Char24Text
-	jp $126a
-; 11e8
-
-Function11e8: ; 11e8
-	push de
-	ld de, Char37Text
-	jp $126a
-; 11ef
-
-Function11ef: ; 11ef
-	push de
-	ld de, Char37Text
-	jp $126a
-; 11f6
-
-Function11f6: ; 11f6
-	push de
-	ld de, Char37Text
-	jp $126a
-; 11fd
-
-
-Function11fd: ; 11fd
-	ld a, [hBattleTurn]
-	xor $1
-	jr Function1205
-; 1203
-
-Char5D: ; 1203
-	ld a, [hBattleTurn]
-; 1205
-
-Function1205: ; 1205
-	push de
-	and a
-	jr nz, .asm_120e ; 0x1207 $5
-	ld de, BattleMonNick
-	jr .asm_126a ; 0x120c $5c
-.asm_120e
-	ld de, Char5AText ; Enemy
-	call PlaceString
-	ld h, b
-	ld l, c
-	ld de, EnemyMonNick
-	jr .asm_126a ; 0x1219 $4f
-	push de
-	ld a, [InLinkBattle]
-	and a
-	jr nz, .linkbattle
-	ld a, [TrainerClass]
-	cp $9
-	jr z, .asm_1248 ; 0x1227 $1f
-	cp $2a
-	jr z, .asm_1248 ; 0x122b $1b
-	ld de, $c656
-	call PlaceString
-	ld h, b
-	ld l, c
-	ld de, String12a2
-	call PlaceString
-	push bc
-	ld hl, $5939
-	ld a, $e
-	rst FarCall
-	pop hl
-	ld de, StringBuffer1
-	jr .asm_126a ; 0x1246 $22
-.asm_1248
-	ld de, RivalName
-	jr .asm_126a ; 0x124b $1d
-.linkbattle
-	ld de, $c656
-	jr .asm_126a ; 0x1250 $18
-	push de
-	ld de, PlayerName
-	call PlaceString
-	ld h, b
-	ld l, c
-	ld a, [PlayerGender]
-	bit 0, a
-	ld de, String12a5
-	jr z, .asm_126a ; 0x1263 $5
-	ld de, String12a6
-	jr .asm_126a ; 0x1268 $0
-.asm_126a
-	call PlaceString
-	ld h, b
-	ld l, c
-	pop de
-	jp NextChar
-; 0x1273
-
-Char5CText: ; 1273
-	db "TM@"
-Char5DText: ; 1276
-	db "TRAINER@"
-Char5BText: ; 127e
-	db "PC@"
-Char5EText: ; 1281
-	db "ROCKET@"
-Char54Text: ; 1288
-	db "POKé@"
-Char23Text: ; 128d
-	db "こうげき@"
-Char56Text:; 1292
-	db "……@"
-Char5AText: ; 1295
-	db "Enemy @"
-Char4AText: ; 129c
-	db $e1, $e2, "@" ; PK MN
-Char24Text: ; 129f
-	db $70, $71, "@" ; PO KE
-String12a2: ; 12a2
-	db " @"
-Char35Text:
-Char36Text:
-Char37Text: ; 12a4
-	db "@"
-String12a5: ; 12a5
-	db "@"
-String12a6: ; 12a6
-	db "@"
-; 12a7
-
-Function12a7: ; 12a7
-	pop hl
-	ld bc, $0028
-	add hl, bc
-	push hl
-	jp NextChar
-; 12b0
-
-Function12b0: ; 12b0
-	pop hl
-	ld bc, $0014
-	add hl, bc
-	push hl
-	jp NextChar
-; 12b9
-
-Function12b9: ; 12b9
-	pop hl
-	push de
-	ld bc, $3b60
-	add hl, bc
-	ld de, $ffec
-	ld c, $1
-.asm_12c4
-	ld a, h
-	and a
-	jr nz, .asm_12cd
-	ld a, l
-	cp $14
-	jr c, .asm_12d1
-
-.asm_12cd
-	add hl, de
-	inc c
-	jr .asm_12c4
-
-.asm_12d1
-	ld hl, TileMap
-	ld de, $0014
-	ld a, c
-.asm_12d8
-	and a
-	jr z, .asm_12df
-	add hl, de
-	dec a
-	jr .asm_12d8
-
-.asm_12df
-	pop de
-	inc de
-	ld a, [de]
-	ld c, a
-	ld b, $0
-	add hl, bc
-	push hl
-	jp NextChar
-; 12ea
-
-
-Char4F: ; 12ea
-	pop hl
-	hlcoord 1, 16
-	push hl
-	jp NextChar
-; 0x12f2
-
-Function12f2: ; 12f2
-	push de
-	ld a, [InLinkBattle]
-	cp $3
-	jr z, .asm_1301
-	cp $4
-	jr z, .asm_1301
-	call Function13c7
-
-.asm_1301
-	call Function13b6
-	call Functionaaf
-	ld hl, $c5b9
-	ld bc, $0312
-	call ClearBox
-	call Function13cd
-	ld c, $14
-	call DelayFrames
-	ld hl, $c5b9
-	pop de
-	jp NextChar
-; 131f
-
-
-Char4B: ; 131f
-	ld a, [InLinkBattle]
-	or a
-	jr nz, .asm_1328
-	call Function13c7
-
-.asm_1328
-	call Function13b6
-
-	push de
-	call Functionaaf
-	pop de
-
-	ld a, [InLinkBattle]
-	or a
-	call z, Function13cd
-
-	push de
-	call Function138c
-	call Function138c
-	hlcoord 1, 16
-	pop de
-	jp NextChar
-; 1345
-
-
-Char55: ; 1345
-	push de
-	ld de, Text_1354
-	ld b, h
-	ld c, l
-	call PlaceString
-	ld h, b
-	ld l, c
-	pop de
-	jp NextChar
-; 1354
-
-Text_1354: ; 1354
-	db $4b, "@"
-; 1356
-
-
-Char5F: ; 1356
-; ends a Pokédex entry
-	ld [hl], "."
-	pop hl
-	ret
-; 135a
-
-Function135a: ; 135a
-	ld a, [InLinkBattle]
-	cp $3
-	jr z, .asm_1368
-	cp $4
-	jr z, .asm_1368
-	call Function13c7
-
-.asm_1368
-	call Function13b6
-	call Functionaaf
-	ld a, [InLinkBattle]
-	cp $3
-	jr z, .asm_137c
-	cp $4
-	jr z, .asm_137c
-	call Function13cd
-
-.asm_137c
-	pop hl
-	ld de, .string_1382
-	dec de
-	ret
-
-.string_1382
-	db "@"
-; 1383
-
-Function1383: ; 1383
-	ld a, $e6
-	ld [hli], a
-	call PrintLetterDelay
-	jp NextChar
-; 138c
-
-Function138c: ; 138c
-	ld hl, $c5b9
-	ld de, $c5a5
-	ld a, $3
-.asm_1394
-	push af
-	ld c, $12
-.asm_1397
-	ld a, [hli]
-	ld [de], a
-	inc de
-	dec c
-	jr nz, .asm_1397
-	inc de
-	inc de
-	inc hl
-	inc hl
-	pop af
-	dec a
-	jr nz, .asm_1394
-	ld hl, $c5e1
-	ld a, $7f
-	ld bc, $0012
-	call ByteFill
-	ld c, $5
-	call DelayFrames
-	ret
-; 13b6
-
-Function13b6: ; 13b6
-	push bc
-	ld a, [hOAMUpdate]
-	push af
-	ld a, $1
-	ld [hOAMUpdate], a
-	call WaitBGMap
-	pop af
-	ld [hOAMUpdate], a
-	pop bc
-	ret
-; 13c6
-
-Function13c6: ; 13c6
-	ret
-; 13c7
-
-Function13c7: ; 13c7
-	ld a, $ee
-	ld [$c606], a
-	ret
-; 13cd
-
-Function13cd: ; 13cd
-	ld a, [$c605]
-	ld [$c606], a
-	ret
-; 13d4
-
-Function13d4: ; 13d4
-	ld b, a
-	ld a, [hROMBank]
-	push af
-	ld a, b
-	rst Bankswitch
-
-	call PlaceString
-	pop af
-	rst Bankswitch
-
-	ret
-; 13e0
-
-Function13e0: ; 13e0
-	ld hl, $13e4
-	ret
-
-.string_13e4
-	db "@"
-; 13e5
-
-
-Function13e5: ; 13e5
-	ld a, [$cfcf]
-	push af
-	set 1, a
-	ld [$cfcf], a
-	call Function13f6
-	pop af
-	ld [$cfcf], a
-	ret
-; 13f6
-
-Function13f6: ; 13f6
-.asm_13f6
-	ld a, [hli]
-	cp "@"
-	ret z
-	call Function13ff
-	jr .asm_13f6
-; 13ff
-
-Function13ff: ; 13ff
-	push hl
-	push bc
-	ld c, a
-	ld b, 0
-	ld hl, TextCommands
-	add hl, bc
-	add hl, bc
-	ld e, [hl]
-	inc hl
-	ld d, [hl]
-	pop bc
-	pop hl
-	
-; jp de
-	push de
-	ret
-; 1410
-
-TextCommands: ; 1410
-	dw Text_00
-	dw Text_01
-	dw Text_02
-	dw Text_03
-	dw Text_04
-	dw Text_05
-	dw Text_06
-	dw Text_07
-	dw Text_08
-	dw Text_09
-	dw Text_0A
-	dw Text_PlaySound ; $0b
-	dw Text_0C
-	dw Text_0D
-	dw Text_PlaySound ; $0e
-	dw Text_PlaySound ; $0f
-	dw Text_PlaySound ; $10
-	dw Text_PlaySound ; $11
-	dw Text_PlaySound ; $12
-	dw Text_PlaySound ; $13
-	dw Text_14
-	dw Text_15
-	dw Text_16
-; 143e
-
-Text_00: ; 143e
-; TX
-; write text until "@"
-; [$00]["...@"]
-
-	ld d, h
-	ld e, l
-	ld h, b
-	ld l, c
-	call PlaceString
-	ld h, d
-	ld l, e
-	inc hl
-	ret
-; 1449
-
-Text_01: ; 1449
-; TX_RAM
-; write text from a ram address
-; little endian
-; [$01][addr]
-
-	ld a, [hli]
-	ld e, a
-	ld a, [hli]
-	ld d, a
-	push hl
-	ld h, b
-	ld l, c
-	call PlaceString
-	pop hl
-	ret
-; 1455
-
-Text_16: ; 1455
-; TX_FAR
-; write text from a different bank
-; little endian
-; [$16][addr][bank]
-
-	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
-
-	push hl
-	ld h, d
-	ld l, e
-	call Function13f6
-	pop hl
-
-	pop af
-	ld [hROMBank], a
-	ld [MBC3RomBank], a
-	ret
-; 1470
-
-Text_02: ; 1470
-; TX_NUM
-; write bcdnumber from address, typically ram
-; little endian
-; [$02][addr][flags]
-; flags: see PrintBCDNumber
-
-	ld a, [hli]
-	ld e, a
-	ld a, [hli]
-	ld d, a
-	ld a, [hli]
-	push hl
-	ld h, b
-	ld l, c
-	ld c, a
-	call PrintBCDNumber
-	ld b, h
-	ld c, l
-	pop hl
-	ret
-; 1480
-
-Text_03: ; 1480
-; TX_MOVE
-; move to a new tile
-; little endian
-; [$03][tileaddr]
-
-	ld a, [hli]
-	ld [$d0e6], a
-	ld c, a
-	ld a, [hli]
-	ld [$d0e7], a
-	ld b, a
-	ret
-; 148b
-
-Text_04: ; 148b
-; TX_BOX
-; draw a box
-; little endian
-; [$04][tileaddr][height][width]
-
-	ld a, [hli]
-	ld e, a
-	ld a, [hli]
-	ld d, a
-	ld a, [hli]
-	ld b, a
-	ld a, [hli]
-	ld c, a
-	push hl
-	ld h, d
-	ld l, e
-	call TextBox
-	pop hl
-	ret
-; 149b
-
-Text_05: ; 149b
-; TX_LOW
-; write text at (1,16)
-; [$05]
-
-	bccoord 1, 16
-	ret
-; 149f
-
-Text_06:: ; 149f
-; TX_WAITBUTTON
-; wait for button press
-; show arrow
-; [06]
-
-	ld a, [InLinkBattle]
-	cp $3
-	jp z, Text_0D
-	cp $4
-	jp z, Text_0D
-	push hl
-	call Function13c7
-	push bc
-	call Functionaaf
-	pop bc
-	call Function13cd
-	pop hl
-	ret
-; 14ba
-
-Text_07: ; 14ba
-	push hl
-	call Function13cd
-	call Function138c
-	call Function138c
-	pop hl
-	bccoord 1, 16
-	ret
-; 14c9
-
-Text_08: ; 14c9
-; TX_ASM
-
-; rom only?
-	bit 7, h
-	jr nz, .asm_14ce
-	jp [hl]
-
-.asm_14ce
-	ld a, "@"
-	ld [hl], a
-	ret
-; 14d2
-
-Text_09: ; 14d2
-	ld a, [hli]
-	ld e, a
-	ld a, [hli]
-	ld d, a
-	ld a, [hli]
-	push hl
-	ld h, b
-	ld l, c
-	ld b, a
-	and $f
-	ld c, a
-	ld a, b
-	and $f0
-	swap a
-	set 6, a
-	ld b, a
-	call PrintNum
-	ld b, h
-	ld c, l
-	pop hl
-	ret
-; 14ed
-
-Text_0A: ; 14ed
-	push hl
-	push bc
-	call GetJoypadPublic
-	ld a, [hJoyDown]
-	and BUTTON_A | BUTTON_B
-	jr nz, .asm_14fd
-	ld c, 30
-	call DelayFrames
-
-.asm_14fd
-	pop bc
-	pop hl
-	ret
-; 1500
-
-Text_PlaySound:: ; 1500
-; chars:
-;   $0b, $0e, $0f, $10, $11, $12, $13
-; see TextSFX
-
-	push bc
-	dec hl
-	ld a, [hli]
-	ld b, a
-	push hl
-	ld hl, TextSFX
-.asm_1508
-	ld a, [hli]
-	cp $ff
-	jr z, .asm_151f
-	cp b
-	jr z, .asm_1514
-	inc hl
-	inc hl
-	jr .asm_1508
-
-.asm_1514
-	push de
-	ld e, [hl]
-	inc hl
-	ld d, [hl]
-	call StartSFX
-	call WaitSFX
-	pop de
-
-.asm_151f
-	pop hl
-	pop bc
-	ret
-; 1522
-
-Function1522: ; 1522
-	push de
-	ld e, [hl]
-	inc hl
-	ld d, [hl]
-	call Function37ce
-	pop de
-	pop hl
-	pop bc
-	ret
-; 152d
-
-TextSFX: ; 152d
-	dbw $0b, SFX_DEX_FANFARE_50_79
-	dbw $12, SFX_FANFARE
-	dbw $0e, SFX_DEX_FANFARE_20_49
-	dbw $0f, SFX_ITEM
-	dbw $10, SFX_CAUGHT_MON
-	dbw $11, SFX_DEX_FANFARE_80_109
-	dbw $13, SFX_SLOT_MACHINE_START
-	db $ff ; end
-; 1543
-
-Text_0C: ; 1543
-	ld a, [hli]
-	ld d, a
-	push hl
-	ld h, b
-	ld l, c
-.asm_1548
-	push de
-	ld a, "…"
-	ld [hli], a
-	call GetJoypadPublic
-	ld a, [hJoyDown]
-	and BUTTON_A | BUTTON_B
-	jr nz, .asm_155a
-	ld c, 10
-	call DelayFrames
-.asm_155a
-	pop de
-	dec d
-	jr nz, .asm_1548
-	ld b, h
-	ld c, l
-	pop hl
-	ret
-; 1562
-
-Text_0D: ; 1562
-; wait for key down
-; display arrow
-	push hl
-	push bc
-	call Functionaaf
-	pop bc
-	pop hl
-	ret
-; 156a
-
-Text_14: ; 156a
-; TX_PREDEF
-; [$14][id]
-
-	ld a, [hli]
-	push hl
-	ld e, a
-	ld d, 0
-	ld hl, $4000
-	add hl, de
-	add hl, de
-	ld a, $9
-	call GetFarHalfword
-	ld d, h
-	ld e, l
-	ld h, b
-	ld l, c
-	call PlaceString
-	pop hl
-	ret
-; 1582
-
-Text_15: ; 1582
-; TX_DAY
-
-	call GetWeekday
-	push hl
-	push bc
-	ld c, a
-	ld b, 0
-	ld hl, .Days
-	add hl, bc
-	add hl, bc
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	ld d, h
-	ld e, l
-	pop hl
-	call PlaceString
-	ld h, b
-	ld l, c
-	ld de, .Day
-	call PlaceString
-	pop hl
-	ret
-; 15a2
-
-.Days ; 15a2
-	dw .Sun
-	dw .Mon
-	dw .Tues
-	dw .Wednes
-	dw .Thurs
-	dw .Fri
-	dw .Satur
-
-.Sun    db "SUN@"
-.Mon    db "MON@"
-.Tues   db "TUES@"
-.Wednes db "WEDNES@"
-.Thurs  db "THURS@"
-.Fri    db "FRI@"
-.Satur  db "SATUR@"
-.Day    db "DAY@"
-; 15d8
-
--- a/engine/time.asm
+++ /dev/null
@@ -1,311 +1,0 @@
-; Functions relating to the timer interrupt and the real-time-clock.
-
-
-AskTimer: ; 591
-	push af
-	ld a, [$ffe9]
-	and a
-	jr z, .asm_59a
-	call Timer
-
-.asm_59a
-	pop af
-	reti
-; 59c
-
-
-LatchClock: ; 59c
-; latch clock counter data
-	ld a, 0
-	ld [MBC3LatchClock], a
-	ld a, 1
-	ld [MBC3LatchClock], a
-	ret
-; 5a7
-
-
-UpdateTime: ; 5a7
-	call GetClock
-	call FixDays
-	call FixTime
-	callba GetTimeOfDay
-	ret
-; 5b7
-
-
-GetClock: ; 5b7
-; store clock data in hRTCDayHi-hRTCSeconds
-
-; enable clock r/w
-	ld a, SRAM_ENABLE
-	ld [MBC3SRamEnable], a
-
-; clock data is 'backwards' in hram
-
-	call LatchClock
-	ld hl, MBC3SRamBank
-	ld de, MBC3RTC
-
-	ld [hl], RTC_S
-	ld a, [de]
-	and $3f
-	ld [hRTCSeconds], a
-
-	ld [hl], RTC_M
-	ld a, [de]
-	and $3f
-	ld [hRTCMinutes], a
-
-	ld [hl], RTC_H
-	ld a, [de]
-	and $1f
-	ld [hRTCHours], a
-
-	ld [hl], RTC_DL
-	ld a, [de]
-	ld [hRTCDayLo], a
-
-	ld [hl], RTC_DH
-	ld a, [de]
-	ld [hRTCDayHi], a
-
-; unlatch clock / disable clock r/w
-	call CloseSRAM
-	ret
-; 5e8
-
-
-FixDays: ; 5e8
-; fix day count
-; mod by 140
-
-; check if day count > 255 (bit 8 set)
-	ld a, [hRTCDayHi] ; DH
-	bit 0, a
-	jr z, .daylo
-; reset dh (bit 8)
-	res 0, a
-	ld [hRTCDayHi], a ; DH
-	
-; mod 140
-; mod twice since bit 8 (DH) was set
-	ld a, [hRTCDayLo] ; DL
-.modh
-	sub 140
-	jr nc, .modh
-.modl
-	sub 140
-	jr nc, .modl
-	add 140
-	
-; update dl
-	ld [hRTCDayLo], a ; DL
-
-; unknown output
-	ld a, $40 ; %1000000
-	jr .set
-
-.daylo
-; quit if fewer than 140 days have passed
-	ld a, [hRTCDayLo] ; DL
-	cp 140
-	jr c, .quit
-	
-; mod 140
-.mod
-	sub 140
-	jr nc, .mod
-	add 140
-	
-; update dl
-	ld [hRTCDayLo], a ; DL
-	
-; unknown output
-	ld a, $20 ; %100000
-	
-.set
-; update clock with modded day value
-	push af
-	call SetClock
-	pop af
-	scf
-	ret
-	
-.quit
-	xor a
-	ret
-; 61d
-
-
-FixTime: ; 61d
-; add ingame time (set at newgame) to current time
-;				  day     hr    min    sec
-; store time in CurDay, hHours, hMinutes, hSeconds
-
-; second
-	ld a, [hRTCSeconds] ; S
-	ld c, a
-	ld a, [StartSecond]
-	add c
-	sub 60
-	jr nc, .updatesec
-	add 60
-.updatesec
-	ld [hSeconds], a
-	
-; minute
-	ccf ; carry is set, so turn it off
-	ld a, [hRTCMinutes] ; M
-	ld c, a
-	ld a, [StartMinute]
-	adc c
-	sub 60
-	jr nc, .updatemin
-	add 60
-.updatemin
-	ld [hMinutes], a
-	
-; hour
-	ccf ; carry is set, so turn it off
-	ld a, [hRTCHours] ; H
-	ld c, a
-	ld a, [StartHour]
-	adc c
-	sub 24
-	jr nc, .updatehr
-	add 24
-.updatehr
-	ld [hHours], a
-	
-; day
-	ccf ; carry is set, so turn it off
-	ld a, [hRTCDayLo] ; DL
-	ld c, a
-	ld a, [StartDay]
-	adc c
-	ld [CurDay], a
-	ret
-; 658
-
-Function658: ; 658
-	xor a
-	ld [StringBuffer2], a
-	ld a, $0
-	ld [$d089], a
-	jr .asm_677
-
-	call UpdateTime
-	ld a, [hHours]
-	ld [$d087], a
-	ld a, [hMinutes]
-	ld [$d088], a
-	ld a, [hSeconds]
-	ld [$d089], a
-	jr .asm_677
-
-.asm_677
-	ld a, $5
-	ld hl, $40ed
-	rst FarCall
-	ret
-; 67e
-
-
-
-Function67e: ; 67e
-	call Function685
-	call SetClock
-	ret
-; 685
-
-Function685: ; 685
-	xor a
-	ld [hRTCSeconds], a
-	ld [hRTCMinutes], a
-	ld [hRTCHours], a
-	ld [hRTCDayLo], a
-	ld [hRTCDayHi], a
-	ret
-; 691
-
-
-SetClock: ; 691
-; set clock data from hram
-
-; enable clock r/w
-	ld a, SRAM_ENABLE
-	ld [MBC3SRamEnable], a
-	
-; set clock data
-; stored 'backwards' in hram
-
-	call LatchClock
-	ld hl, MBC3SRamBank
-	ld de, MBC3RTC
-	
-; seems to be a halt check that got partially commented out
-; this block is totally pointless
-	ld [hl], RTC_DH
-	ld a, [de]
-	bit 6, a ; halt
-	ld [de], a
-	
-; seconds
-	ld [hl], RTC_S
-	ld a, [hRTCSeconds]
-	ld [de], a
-; minutes
-	ld [hl], RTC_M
-	ld a, [hRTCMinutes]
-	ld [de], a
-; hours
-	ld [hl], RTC_H
-	ld a, [hRTCHours]
-	ld [de], a
-; day lo
-	ld [hl], RTC_DL
-	ld a, [hRTCDayLo]
-	ld [de], a
-; day hi
-	ld [hl], RTC_DH
-	ld a, [hRTCDayHi]
-	res 6, a ; make sure timer is active
-	ld [de], a
-	
-; cleanup
-	call CloseSRAM ; unlatch clock, disable clock r/w
-	ret
-; 6c4
-
-
-Function6c4: ; 6c4
-	xor a
-	push af
-	ld a, $0
-	call GetSRAMBank
-	pop af
-	ld [$ac60], a
-	call CloseSRAM
-	ret
-; 6d3
-
-Function6d3: ; 6d3
-	ld hl, $ac60
-	push af
-	ld a, $0
-	call GetSRAMBank
-	pop af
-	or [hl]
-	ld [hl], a
-	call CloseSRAM
-	ret
-; 6e3
-
-Function6e3: ; 6e3
-	ld a, $0
-	call GetSRAMBank
-	ld a, [$ac60]
-	call CloseSRAM
-	ret
-; 6ef
-
--- a/engine/vblank.asm
+++ /dev/null
@@ -1,541 +1,0 @@
-; VBlank is the interrupt responsible for updating VRAM.
-
-; In Pokemon Crystal, VBlank has been hijacked to act as the
-; main loop. After time-sensitive graphics operations have been
-; performed, joypad input and sound functions are executed.
-
-; This prevents the display and audio output from lagging.
-
-
-VBlank: ; 283
-	push af
-	push bc
-	push de
-	push hl
-	
-; get vblank type
-	ld a, [$ff9e]
-	and $7
-	
-; get fn pointer
-	ld e, a
-	ld d, $0
-	ld hl, .VBlanks
-	add hl, de
-	add hl, de
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	
-; down to business
-	call _hl_
-	
-; since this is called once per frame
-	call GameTimer
-	
-	pop hl
-	pop de
-	pop bc
-	pop af
-	reti
-; 2a1
-
-.VBlanks ; 2a1
-	dw VBlank0 ; 0
-	dw VBlank1 ; 1
-	dw VBlank2 ; 2
-	dw VBlank3 ; 3
-	dw VBlank4 ; 4
-	dw VBlank5 ; 5
-	dw VBlank6 ; 6
-	dw VBlank0 ; 7
-; 2b1
-
-
-VBlank0: ; 2b1
-; normal operation
-
-; rng
-; scx, scy, wy, wx
-; bg map buffer
-; palettes
-; dma transfer
-; bg map
-; tiles
-; oam
-; joypad
-; sound
-
-; inc frame counter
-	ld hl, $ff9b
-	inc [hl]
-	
-; advance rng
-	ld a, [rDIV]
-	ld b, a
-	ld a, [hRandomAdd]
-	adc b
-	ld [hRandomAdd], a
-	
-	ld a, [rDIV]
-	ld b, a
-	ld a, [hRandomSub]
-	sbc b
-	ld [hRandomSub], a
-	
-; save bank
-	ld a, [hROMBank] ; current bank
-	ld [$ff8a], a
-	
-; scroll x
-	ld a, [hSCX]
-	ld [rSCX], a
-; scroll y
-	ld a, [hSCY]
-	ld [rSCY], a
-; window y
-	ld a, [hWY]
-	ld [rWY], a
-; window x + 7
-	ld a, [hWX]
-	ld [rWX], a
-	
-; some time management is in order
-; only have time for one of these during vblank
-	
-; bg map buffer has priority
-	call UpdateBGMapBuffer
-	jr c, .doneframeaction
-	
-; then pals
-	call UpdatePalsIfCGB
-	jr c, .doneframeaction
-	
-; dma transfer
-	call DMATransfer
-	jr c, .doneframeaction
-	
-; bg map
-	call UpdateBGMap
-	
-; these have their own timing checks
-	call Serve2bppRequest
-	call Serve1bppRequest
-	call AnimateTileset
-	
-.doneframeaction
-; oam update off?
-	ld a, [hOAMUpdate]
-	and a
-	jr nz, .vblankoccurred
-	
-; update oam by dma transfer
-	call hPushOAM
-;	@PushOAM:
-;		ld a, Sprites >> 8
-;		ld [rDMA], a
-;		ld a, $28
-;	.loop
-;		dec a
-;		jr nz, .loop
-;		ret
-
-
-; vblank-sensitive operations are done
-	
-.vblankoccurred
-; tell other fns vblank happened
-	xor a
-	ld [VBlankOccurred], a
-	
-; dec OverworldDelay until 0
-	ld a, [OverworldDelay]
-	and a
-	jr z, .textdelay
-	dec a
-	ld [OverworldDelay], a
-	
-.textdelay
-; dec text delay counter until 0
-	ld a, [TextDelayFrames]
-	and a
-	jr z, .joypad
-	dec a
-	ld [TextDelayFrames], a
-	
-.joypad
-	call Joypad
-	
-; update sound
-	ld a, BANK(UpdateSound)
-	rst Bankswitch ; bankswitch
-	call UpdateSound
-	ld a, [$ff8a]
-	rst Bankswitch ; restore bank
-	
-; 
-	ld a, [hSeconds]
-	ld [$ffe3], a
-	
-	ret
-; 325
-
-
-VBlank2: ; 325
-; sound only
-
-; save bank
-	ld a, [hROMBank]
-	ld [$ff8a], a
-	
-; update sound
-	ld a, BANK(UpdateSound)
-	rst Bankswitch ; bankswitch
-	call UpdateSound
-	
-; restore bank
-	ld a, [$ff8a]
-	rst Bankswitch
-	
-; tell other fns vblank happened
-	xor a
-	ld [VBlankOccurred], a
-	ret
-; 337
-
-
-VBlank1: ; 337
-; scx, scy
-; palettes
-; bg map
-; tiles
-; oam
-; sound / lcd stat
-
-; save bank
-	ld a, [hROMBank]
-	ld [$ff8a], a
-	
-; scroll x
-	ld a, [hSCX]
-	ld [rSCX], a
-	
-; scroll y
-	ld a, [hSCY]
-	ld [rSCY], a
-	
-; time-sensitive fns
-	call UpdatePals
-	jr c, .vblankoccurred
-	
-; these have their own timing checks
-	call UpdateBGMap
-	call Serve2bppRequest@VBlank
-; update oam by dma transfer
-	call hPushOAM
-;	@PushOAM:
-;		ld a, Sprites >> 8
-;		ld [rDMA], a
-;		ld a, $28
-;	.loop
-;		dec a
-;		jr nz, .loop
-;		ret
-	
-.vblankoccurred
-; tell other fns vblank happened
-	xor a
-	ld [VBlankOccurred], a
-	
-; get requested ints
-	ld a, [rIF]
-	ld b, a
-; discard requested ints
-	xor a
-	ld [rIF], a
-; enable lcd stat
-	ld a, %10 ; lcd stat
-	ld [rIE], a
-; rerequest serial int if applicable (still disabled)
-; request lcd stat
-	ld a, b
-	and %1000 ; serial
-	or %10 ; lcd stat
-	ld [rIF], a
-	
-	ei
-; update sound
-	ld a, BANK(UpdateSound)
-	rst Bankswitch ; bankswitch
-	call UpdateSound
-; restore bank
-	ld a, [$ff8a]
-	rst Bankswitch
-	di
-	
-; get requested ints
-	ld a, [rIF]
-	ld b, a
-; discard requested ints
-	xor a
-	ld [rIF], a
-; enable ints besides joypad
-	ld a, %1111 ; serial timer lcdstat vblank
-	ld [rIE], a
-; rerequest ints
-	ld a, b
-	ld [rIF], a
-	ret
-; 37f
-
-
-UpdatePals: ; 37f
-; update pals for either dmg or cgb
-
-; check cgb
-	ld a, [hCGB]
-	and a
-	jp nz, UpdateCGBPals
-	
-; update gb pals
-	ld a, [$cfc7]
-	ld [rBGP], a
-	
-	ld a, [$cfc8]
-	ld [rOBP0], a
-	
-	ld a, [$cfc9]
-	ld [rOBP1], a
-	
-	and a
-	ret
-; 396
-
-
-VBlank3: ; 396
-; scx, scy
-; palettes
-; bg map
-; tiles
-; oam
-; sound / lcd stat
-
-; save bank
-	ld a, [hROMBank]
-	ld [$ff8a], a
-	
-; scroll x
-	ld a, [hSCX]
-	ld [rSCX], a
-; scroll y
-	ld a, [hSCY]
-	ld [rSCY], a
-	
-; any pals to update?
-	ld a, [hCGBPalUpdate]
-	and a
-	call nz, ForceUpdateCGBPals
-	jr c, .vblankoccurred
-; else
-	call UpdateBGMap
-	call Serve2bppRequest@VBlank
-	
-; update oam by dma transfer
-	call hPushOAM
-;	@PushOAM:
-;		ld a, Sprites >> 8
-;		ld [rDMA], a
-;		ld a, $28
-;	.loop
-;		dec a
-;		jr nz, .loop
-;		ret
-	
-.vblankoccurred
-; tell other fns vblank happened
-	xor a
-	ld [VBlankOccurred], a
-	
-; save int flag
-	ld a, [rIF]
-	push af
-; reset ints
-	xor a
-	ld [rIF], a
-; force lcdstat int during sound update
-	ld a, %10 ; lcd stat
-	ld [rIE], a
-	ld [rIF], a
-	
-	ei
-; update sound
-	ld a, BANK(UpdateSound)
-	rst Bankswitch ; bankswitch
-	call UpdateSound
-; restore bank
-	ld a, [$ff8a]
-	rst Bankswitch
-	di
-	
-; request lcdstat
-	ld a, [rIF]
-	ld b, a
-; and any other ints
-	pop af
-	or b
-	ld b, a
-; reset ints
-	xor a
-	ld [rIF], a
-; enable ints besides joypad
-	ld a, %1111 ; serial timer lcdstat vblank
-	ld [rIE], a
-; request ints
-	ld a, b
-	ld [rIF], a
-	ret
-; 3df
-
-
-VBlank4: ; 3df
-; bg map
-; tiles
-; oam
-; joypad
-; serial
-; sound
-
-; save bank
-	ld a, [hROMBank]
-	ld [$ff8a], a
-	
-	call UpdateBGMap
-	call Serve2bppRequest
-	
-; update oam by dma transfer
-	call hPushOAM
-;	@PushOAM:
-;		ld a, Sprites >> 8
-;		ld [rDMA], a
-;		ld a, $28
-;	.loop
-;		dec a
-;		jr nz, .loop
-;		ret
-	
-; update joypad
-	call Joypad
-	
-; tell other fns vblank happened
-	xor a
-	ld [VBlankOccurred], a
-	
-; handshake
-	call AskSerial
-	
-; update sound
-	ld a, BANK(UpdateSound)
-	rst Bankswitch ; bankswitch
-	call UpdateSound
-; restore bank
-	ld a, [$ff8a]
-	rst Bankswitch
-	ret
-; 400
-
-
-VBlank5: ; 400
-; scx
-; palettes
-; bg map
-; tiles
-; joypad
-; 
-
-; save bank
-	ld a, [hROMBank]
-	ld [$ff8a], a
-	
-; scroll x
-	ld a, [hSCX]
-	ld [rSCX], a
-	
-; if we can update pals, skip this part
-	call UpdatePalsIfCGB
-	jr c, .vblankoccurred
-	
-	call UpdateBGMap
-	call Serve2bppRequest
-	
-.vblankoccurred
-; tell other fns vblank happened
-	xor a
-	ld [VBlankOccurred], a
-	
-; joypad
-	call Joypad
-	
-; discard requested ints
-	xor a
-	ld [rIF], a
-; enable lcd stat
-	ld a, %10 ; lcd stat
-	ld [rIE], a
-; request lcd stat
-	ld [rIF], a
-	
-	ei
-; update sound
-	ld a, BANK(UpdateSound)
-	rst Bankswitch ; bankswitch
-	call UpdateSound
-; restore bank
-	ld a, [$ff8a]
-	rst Bankswitch
-	di
-	
-; discard requested ints
-	xor a
-	ld [rIF], a
-; enable ints besides joypad
-	ld a, %1111 ; serial timer lcdstat vblank
-	ld [rIE], a
-	ret
-; 436
-
-
-VBlank6: ; 436
-; palettes
-; tiles
-; dma transfer
-; sound
-
-; save bank
-	ld a, [hROMBank]
-	ld [$ff8a], a
-	
-; inc frame counter
-	ld hl, $ff9b
-	inc [hl]
-	
-	call UpdateCGBPals
-	jr c, .vblankoccurred
-	
-	call Serve2bppRequest
-	call Serve1bppRequest
-	call DMATransfer
-	
-.vblankoccurred
-; tell other fns vblank happened
-	xor a
-	ld [VBlankOccurred], a
-	
-; update sound
-	ld a, BANK(UpdateSound)
-	rst Bankswitch ; bankswitch
-	call UpdateSound
-; restore bank
-	ld a, [$ff8a]
-	rst Bankswitch
-	ret
-; 45a
--- a/engine/video.asm
+++ /dev/null
@@ -1,487 +1,0 @@
-; Functions dealing with VRAM.
-
-DMATransfer: ; 15d8
-; Return carry if the transfer is completed.
-
-	ld a, [hDMATransfer]
-	and a
-	ret z
-
-; Start transfer
-	ld [rHDMA5], a
-
-; Execution is halted until the transfer is complete.
-
-	xor a
-	ld [hDMATransfer], a
-	scf
-	ret
-; 15e3
-
-
-UpdateBGMapBuffer: ; 15e3
-; Copy [$ffdc] 16x8 tiles from BGMapBuffer
-; to bg map addresses in BGMapBufferPtrs.
-
-; [$ffdc] must be even since this is done in pairs.
-
-; Return carry on success.
-
-	ld a, [hBGMapUpdate]
-	and a
-	ret z
-
-	ld a, [rVBK]
-	push af
-	ld [hSPBuffer], sp
-
-	ld hl, BGMapBufferPtrs
-	ld sp, hl
-
-; We can now pop the addresses of affected spots on the BG Map
-
-	ld hl, BGMapPalBuffer
-	ld de, BGMapBuffer
-
-
-.next
-; Copy a pair of 16x8 blocks (one 16x16 block)
-
-rept 2
-; Get our BG Map address
-	pop bc
-
-; Palettes
-	ld a, 1
-	ld [rVBK], a
-
-	ld a, [hli]
-	ld [bc], a
-	inc c
-	ld a, [hli]
-	ld [bc], a
-	dec c
-
-; Tiles
-	ld a, 0
-	ld [rVBK], a
-
-	ld a, [de]
-	inc de
-	ld [bc], a
-	inc c
-	ld a, [de]
-	inc de
-	ld [bc], a
-endr
-
-; We've done 2 16x8 blocks
-	ld a, [$ffdc]
-	dec a
-	dec a
-	ld [$ffdc], a
-
-	jr nz, .next
-
-
-	ld a, [hSPBuffer]
-	ld l, a
-	ld a, [hSPBuffer + 1]
-	ld h, a
-	ld sp, hl
-
-	pop af
-	ld [rVBK], a
-
-	xor a
-	ld [hBGMapUpdate], a
-	scf
-	ret
-; 163a
-
-
-WaitTop: ; 163a
-; Wait until the top third of the BG Map is being updated.
-
-	ld a, [hBGMapMode]
-	and a
-	ret z
-
-	ld a, [hBGMapThird]
-	and a
-	jr z, .done
-
-	call DelayFrame
-	jr WaitTop
-
-.done
-	xor a
-	ld [hBGMapMode], a
-	ret
-; 164c
-
-
-UpdateBGMap: ; 164c
-; Update the BG Map, in thirds, from TileMap and AttrMap.
-
-	ld a, [hBGMapMode]
-	and a
-	ret z
-
-; BG Map 0
-	dec a ; 1
-	jr z, .Tiles
-	dec a ; 2
-	jr z, .Attr
-
-; BG Map 1
-	dec a
-
-	ld a, [hBGMapAddress]
-	ld l, a
-	ld a, [hBGMapAddress + 1]
-	ld h, a
-	push hl
-
-	xor a
-	ld [hBGMapAddress], a
-	ld a, VBGMap1 >> 8
-	ld [hBGMapAddress + 1], a
-
-	ld a, [hBGMapMode]
-	push af
-	cp 3
-	call z, .Tiles
-	pop af
-	cp 4
-	call z, .Attr
-
-	pop hl
-	ld a, l
-	ld [hBGMapAddress], a
-	ld a, h
-	ld [hBGMapAddress + 1], a
-	ret
-
-
-.Attr
-	ld a, 1
-	ld [rVBK], a
-
-	ld hl, AttrMap
-	call .update
-
-	ld a, 0
-	ld [rVBK], a
-	ret
-
-
-.Tiles
-	ld hl, TileMap
-
-
-.update
-	ld [hSPBuffer], sp
-	
-; Which third?
-	ld a, [hBGMapThird]
-	and a ; 0
-	jr z, .top
-	dec a ; 1
-	jr z, .middle
-	; 2
-
-
-THIRD_HEIGHT EQU SCREEN_HEIGHT / 3
-
-
-.bottom
-	ld de, 2 * THIRD_HEIGHT * SCREEN_WIDTH
-	add hl, de
-	ld sp, hl
-
-	ld a, [hBGMapAddress + 1]
-	ld h, a
-	ld a, [hBGMapAddress]
-	ld l, a
-
-	ld de, 2 * THIRD_HEIGHT * BG_MAP_WIDTH
-	add hl, de
-
-; Next time: top third
-	xor a
-	jr .start
-
-
-.middle
-	ld de, THIRD_HEIGHT * SCREEN_WIDTH
-	add hl, de
-	ld sp, hl
-
-	ld a, [hBGMapAddress + 1]
-	ld h, a
-	ld a, [hBGMapAddress]
-	ld l, a
-
-	ld de, THIRD_HEIGHT * BG_MAP_WIDTH
-	add hl, de
-
-; Next time: bottom third
-	ld a, 2
-	jr .start
-
-
-.top
-	ld sp, hl
-
-	ld a, [hBGMapAddress + 1]
-	ld h, a
-	ld a, [hBGMapAddress]
-	ld l, a
-
-; Next time: middle third
-	ld a, 1
-
-
-.start
-; Which third to update next time
-	ld [hBGMapThird], a
-
-; Rows of tiles in a third
-	ld a, SCREEN_HEIGHT / 3
-
-; Discrepancy between TileMap and BGMap
-	ld bc, BG_MAP_WIDTH - (SCREEN_WIDTH - 1)
-
-
-.row
-; Copy a row of 20 tiles
-rept SCREEN_WIDTH / 2 - 1
-	pop de
-	ld [hl], e
-	inc l
-	ld [hl], d
-	inc l
-endr
-	pop de
-	ld [hl], e
-	inc l
-	ld [hl], d
-
-	add hl, bc
-	dec a
-	jr nz, .row
-
-
-	ld a, [hSPBuffer]
-	ld l, a
-	ld a, [hSPBuffer + 1]
-	ld h, a
-	ld sp, hl
-	ret
-; 170a
-
-
-Serve1bppRequest: ; 170a
-; Only call during the first fifth of VBlank
-
-	ld a, [Requested1bpp]
-	and a
-	ret z
-
-; Back out if we're too far into VBlank
-	ld a, [rLY]
-	cp 144
-	ret c
-	cp 146
-	ret nc
-
-; Copy [Requested1bpp] 1bpp tiles from [Requested1bppSource] to [Requested1bppDest]
-
-	ld [hSPBuffer], sp
-
-; Source
-	ld hl, Requested1bppSource
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	ld sp, hl
-	
-; Destination
-	ld hl, Requested1bppDest
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	
-; # tiles to copy
-	ld a, [Requested1bpp]
-	ld b, a
-
-	xor a
-	ld [Requested1bpp], a
-
-.next
-
-rept 3
-	pop de
-	ld [hl], e
-	inc l
-	ld [hl], e
-	inc l
-	ld [hl], d
-	inc l
-	ld [hl], d
-	inc l
-endr
-	pop de
-	ld [hl], e
-	inc l
-	ld [hl], e
-	inc l
-	ld [hl], d
-	inc l
-	ld [hl], d
-
-	inc hl
-	dec b
-	jr nz, .next
-
-
-	ld a, l
-	ld [Requested1bppDest], a
-	ld a, h
-	ld [Requested1bppDest + 1], a
-
-	ld [Requested1bppSource], sp
-
-	ld a, [hSPBuffer]
-	ld l, a
-	ld a, [hSPBuffer + 1]
-	ld h, a
-	ld sp, hl
-	ret
-; 1769
-
-
-Serve2bppRequest: ; 1769
-; Only call during the first fifth of VBlank
-
-	ld a, [Requested2bpp]
-	and a
-	ret z
-
-; Back out if we're too far into VBlank
-	ld a, [rLY]
-	cp 144
-	ret c
-	cp 146
-	ret nc
-	jr _Serve2bppRequest
-
-
-Serve2bppRequest@VBlank: ; 1778
-
-	ld a, [Requested2bpp]
-	and a
-	ret z
-
-_Serve2bppRequest: ; 177d
-; Copy [Requested2bpp] 2bpp tiles from [Requested2bppSource] to [Requested2bppDest]
-
-	ld [hSPBuffer], sp
-	
-; Source
-	ld hl, Requested2bppSource
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	ld sp, hl
-	
-; Destination
-	ld hl, Requested2bppDest
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	
-; # tiles to copy
-	ld a, [Requested2bpp]
-	ld b, a
-
-	xor a
-	ld [Requested2bpp], a
-	
-.next
-
-rept 7
-	pop de
-	ld [hl], e
-	inc l
-	ld [hl], d
-	inc l
-endr
-	pop de
-	ld [hl], e
-	inc l
-	ld [hl], d
-
-	inc hl
-	dec b
-	jr nz, .next
-
-
-	ld a, l
-	ld [Requested2bppDest], a
-	ld a, h
-	ld [Requested2bppDest + 1], a
-
-	ld [Requested2bppSource], sp
-
-	ld a, [hSPBuffer]
-	ld l, a
-	ld a, [hSPBuffer + 1]
-	ld h, a
-	ld sp, hl
-	ret
-; 17d3
-
-
-AnimateTileset: ; 17d3
-; Only call during the first fifth of VBlank
-
-	ld a, [$ffde]
-	and a
-	ret z
-	
-; Back out if we're too far into VBlank
-	ld a, [rLY]
-	cp 144
-	ret c
-	cp 151
-	ret nc
-
-	ld a, [hROMBank]
-	push af
-	ld a, BANK(_AnimateTileset)
-	rst Bankswitch
-
-	ld a, [rSVBK]
-	push af
-	ld a, 1
-	ld [rSVBK], a
-
-	ld a, [rVBK]
-	push af
-	ld a, 0
-	ld [rVBK], a
-
-	call _AnimateTileset
-
-	pop af
-	ld [rVBK], a
-	pop af
-	ld [rSVBK], a
-	pop af
-	rst Bankswitch
-	ret
-; 17ff
-
--- a/main.asm
+++ b/main.asm
@@ -14,22 +14,22 @@
 
 SECTION "start",ROM0[$150]
 
-INCLUDE "engine/init.asm"
-INCLUDE "engine/vblank.asm"
-INCLUDE "engine/delay.asm"
-INCLUDE "engine/rtc.asm"
-INCLUDE "engine/fade.asm"
-INCLUDE "engine/lcd.asm"
-INCLUDE "engine/time.asm"
-INCLUDE "engine/serial.asm"
-INCLUDE "engine/joypad.asm"
-INCLUDE "engine/decompress.asm"
-INCLUDE "engine/palettes.asm"
-INCLUDE "engine/copy.asm"
-INCLUDE "engine/text.asm"
-INCLUDE "engine/video.asm"
-INCLUDE "engine/map_objects.asm"
-INCLUDE "engine/sine.asm"
+INCLUDE "common/init.asm"
+INCLUDE "common/vblank.asm"
+INCLUDE "common/delay.asm"
+INCLUDE "common/rtc.asm"
+INCLUDE "common/fade.asm"
+INCLUDE "common/lcd.asm"
+INCLUDE "common/time.asm"
+INCLUDE "common/serial.asm"
+INCLUDE "common/joypad.asm"
+INCLUDE "common/decompress.asm"
+INCLUDE "common/palettes.asm"
+INCLUDE "common/copy.asm"
+INCLUDE "common/text.asm"
+INCLUDE "common/video.asm"
+INCLUDE "common/map_objects.asm"
+INCLUDE "common/sine.asm"
 
 Function1b1e: ; 1b1e
 	ld [$d003], a
@@ -473,7 +473,7 @@
 ; 1d35
 
 
-INCLUDE "engine/menu.asm"
+INCLUDE "common/menu.asm"
 
 
 AskSerial: ; 2063
@@ -515,7 +515,7 @@
 ; 208a
 
 
-INCLUDE "engine/game_time.asm"
+INCLUDE "common/game_time.asm"
 
 
 Function210f: ; 210f
@@ -2906,7 +2906,7 @@
 ; 2d54
 
 
-INCLUDE "engine/farcall.asm"
+INCLUDE "common/farcall.asm"
 
 
 Predef: ; 2d83