summaryrefslogtreecommitdiff
path: root/engine/printer
diff options
context:
space:
mode:
authormid-kid <esteve.varela@gmail.com>2018-03-13 13:07:16 +0100
committermid-kid <esteve.varela@gmail.com>2018-03-13 13:21:40 +0100
commitbaa0dc5a963a79843b37888bcfe1d2dfe833ade9 (patch)
tree968c86105bd67a3121d8f3f20018bfc59191f4c9 /engine/printer
parent12070ca50067d3abe36a730190f88ee43f2cace9 (diff)
Organize the engine/ directory
This is an informed attempt at reorganizing the engine/ directory by creating categorized subdirectories, in order to make it easier to navigate and find things. The directories created are as follows: * engine/game: Contains all "minigames", things like the unown puzzle and slot machine. * engine/gfx: Contains all handling of graphics. From loading palettes to playing animations. * engine/link: Contains all multiplayer functionality. * engine/menu: Contains all generic/misc. menus and menu code. Other, more specialized menus are in their own subdirectories (pokedex, pokegear, party menu, etc). * engine/overworld: Contains all handling of the overworld. From loading and connecting maps to wild encounters and the scripting engine. * engine/pokegear: In the same vein as engine/pokedex, except it could use some more splitting up. * engine/pokemon: Contains everything related to manipulating pokemon data. From the pokemon storage system to evolution and mail. * engine/printer: Contains everything related to printing things as well as the printer communication. * engine/title: Contains intro sequences, title screens and credits.
Diffstat (limited to 'engine/printer')
-rwxr-xr-xengine/printer/print_party.asm364
-rwxr-xr-xengine/printer/printer.asm949
-rwxr-xr-xengine/printer/printer_serial.asm640
3 files changed, 1953 insertions, 0 deletions
diff --git a/engine/printer/print_party.asm b/engine/printer/print_party.asm
new file mode 100755
index 000000000..1095ce584
--- /dev/null
+++ b/engine/printer/print_party.asm
@@ -0,0 +1,364 @@
+PRINTPARTY_HP EQUS "\"◀\"" ; $71
+
+PrintPage1: ; 1dc1b0
+ hlcoord 0, 0
+ decoord 0, 0, wPrinterTileMapBuffer
+ ld bc, 17 * SCREEN_WIDTH
+ call CopyBytes
+ hlcoord 17, 1, wPrinterTileMapBuffer
+ ld a, $62
+ ld [hli], a
+ inc a
+ ld [hl], a
+ hlcoord 17, 2, wPrinterTileMapBuffer
+ ld a, $64
+ ld [hli], a
+ inc a
+ ld [hl], a
+ hlcoord 1, 9, wPrinterTileMapBuffer
+ ld a, " "
+ ld [hli], a
+ ld [hl], a
+ hlcoord 1, 10, wPrinterTileMapBuffer
+ ld a, $61
+ ld [hli], a
+ ld [hl], a
+ hlcoord 2, 11, wPrinterTileMapBuffer
+ lb bc, 5, 18
+ call ClearBox
+ ld a, [wd265]
+ dec a
+ call CheckCaughtMon
+ push af
+ ld a, [wd265]
+ ld b, a
+ ld c, 1 ; get page 1
+ farcall GetDexEntryPagePointer
+ pop af
+ ld a, b
+ hlcoord 1, 11, wPrinterTileMapBuffer
+ call nz, FarString
+ hlcoord 19, 0, wPrinterTileMapBuffer
+ ld [hl], $35
+ ld de, SCREEN_WIDTH
+ add hl, de
+ ld b, $f
+.column_loop
+ ld [hl], $37
+ add hl, de
+ dec b
+ jr nz, .column_loop
+ ld [hl], $3a
+ ret
+; 1dc213
+
+PrintPage2: ; 1dc213
+ hlcoord 0, 0, wPrinterTileMapBuffer
+ ld bc, 8 * SCREEN_WIDTH
+ ld a, " "
+ call ByteFill
+ hlcoord 0, 0, wPrinterTileMapBuffer
+ ld a, $36
+ ld b, 6
+ call .FillColumn
+ hlcoord 19, 0, wPrinterTileMapBuffer
+ ld a, $37
+ ld b, 6
+ call .FillColumn
+ hlcoord 0, 6, wPrinterTileMapBuffer
+ ld [hl], $38
+ inc hl
+ ld a, $39
+ ld bc, SCREEN_HEIGHT
+ call ByteFill
+ ld [hl], $3a
+ hlcoord 0, 7, wPrinterTileMapBuffer
+ ld bc, SCREEN_WIDTH
+ ld a, $32
+ call ByteFill
+ ld a, [wd265]
+ dec a
+ call CheckCaughtMon
+ push af
+ ld a, [wd265]
+ ld b, a
+ ld c, 2 ; get page 2
+ farcall GetDexEntryPagePointer
+ pop af
+ hlcoord 1, 1, wPrinterTileMapBuffer
+ ld a, b
+ call nz, FarString
+ ret
+; 1dc26a
+
+.FillColumn: ; 1dc26a
+ push de
+ ld de, SCREEN_WIDTH
+.column_loop
+ ld [hl], a
+ add hl, de
+ dec b
+ jr nz, .column_loop
+ pop de
+ ret
+; 1dc275
+
+GBPrinterStrings:
+GBPrinterString_Null: db "@"
+GBPrinterString_CheckingLink: next " CHECKING LINK...@"
+GBPrinterString_Transmitting: next " TRANSMITTING...@"
+GBPrinterString_Printing: next " PRINTING...@"
+GBPrinterString_PrinterError1:
+ db " Printer Error 1"
+ next ""
+ next "Check the Game Boy"
+ next "Printer Manual."
+ db "@"
+GBPrinterString_PrinterError2:
+ db " Printer Error 2"
+ next ""
+ next "Check the Game Boy"
+ next "Printer Manual."
+ db "@"
+GBPrinterString_PrinterError3:
+ db " Printer Error 3"
+ next ""
+ next "Check the Game Boy"
+ next "Printer Manual."
+ db "@"
+GBPrinterString_PrinterError4:
+ db " Printer Error 4"
+ next ""
+ next "Check the Game Boy"
+ next "Printer Manual."
+ db "@"
+; 1dc381
+
+PrintPartyMonPage1: ; 1dc381
+ call ClearBGPalettes
+ call ClearTileMap
+ call ClearSprites
+ xor a
+ ld [hBGMapMode], a
+ call LoadFontsBattleExtra
+
+ ld de, GBPrinterHPIcon
+ ld hl, vTiles2 tile PRINTPARTY_HP
+ lb bc, BANK(GBPrinterHPIcon), 1
+ call Request1bpp
+
+ ld de, GBPrinterLvIcon
+ ld hl, vTiles2 tile "<LV>"
+ lb bc, BANK(GBPrinterLvIcon), 1
+ call Request1bpp
+
+ ld de, StatsScreenPageTilesGFX + 14 tiles ; shiny icon
+ ld hl, vTiles2 tile "⁂"
+ lb bc, BANK(StatsScreenPageTilesGFX), 1
+ call Get2bpp
+
+ xor a
+ ld [wMonType], a
+ farcall CopyMonToTempMon
+ hlcoord 0, 7
+ ld b, 9
+ ld c, 18
+ call TextBox
+ hlcoord 8, 2
+ ld a, [wTempMonLevel]
+ call PrintLevel_Force3Digits
+ hlcoord 12, 2
+ ld [hl], PRINTPARTY_HP
+ inc hl
+ ld de, wTempMonMaxHP
+ lb bc, 2, 3
+ call PrintNum
+ ld a, [wCurPartySpecies]
+ ld [wd265], a
+ ld [wCurSpecies], a
+ ld hl, wPartyMonNicknames
+ call Function1dc50e
+ hlcoord 8, 4
+ call PlaceString
+ hlcoord 9, 6
+ ld [hl], "/"
+ call GetPokemonName
+ hlcoord 10, 6
+ call PlaceString
+ hlcoord 8, 0
+ ld [hl], "№"
+ inc hl
+ ld [hl], "."
+ inc hl
+ ld de, wd265
+ lb bc, PRINTNUM_LEADINGZEROS | 1, 3
+ call PrintNum
+ hlcoord 1, 9
+ ld de, String1dc550
+ call PlaceString
+ ld hl, wPartyMonOT
+ call Function1dc50e
+ hlcoord 4, 9
+ call PlaceString
+ hlcoord 1, 11
+ ld de, String1dc559
+ call PlaceString
+ hlcoord 4, 11
+ ld de, wTempMonID
+ lb bc, PRINTNUM_LEADINGZEROS | 2, 5
+ call PrintNum
+ hlcoord 1, 14
+ ld de, String1dc554
+ call PlaceString
+ hlcoord 7, 14
+ ld a, [wTempMonMoves + 0]
+ call Function1dc51a
+ call Function1dc52c
+ ld hl, wTempMonDVs
+ predef GetUnownLetter
+ ld hl, wBoxAlignment
+ xor a
+ ld [hl], a
+ ld a, [wCurPartySpecies]
+ cp UNOWN
+ jr z, .asm_1dc469
+ inc [hl]
+
+.asm_1dc469
+ hlcoord 0, 0
+ call _PrepMonFrontpic
+ call WaitBGMap
+ ld b, SCGB_STATS_SCREEN_HP_PALS
+ call GetSGBLayout
+ call SetPalettes
+ ret
+; 1dc47b
+
+PrintPartyMonPage2: ; 1dc47b
+ call ClearBGPalettes
+ call ClearTileMap
+ call ClearSprites
+ xor a
+ ld [hBGMapMode], a
+ call LoadFontsBattleExtra
+ xor a
+ ld [wMonType], a
+ farcall CopyMonToTempMon
+ hlcoord 0, 0
+ ld b, 15
+ ld c, 18
+ call TextBox
+ ld bc, SCREEN_WIDTH
+ decoord 0, 0
+ hlcoord 0, 1
+ call CopyBytes
+ hlcoord 7, 0
+ ld a, [wTempMonMoves + 1]
+ call Function1dc51a
+ hlcoord 7, 2
+ ld a, [wTempMonMoves + 2]
+ call Function1dc51a
+ hlcoord 7, 4
+ ld a, [wTempMonMoves + 3]
+ call Function1dc51a
+ hlcoord 7, 7
+ ld de, String1dc55d
+ call PlaceString
+ hlcoord 16, 7
+ ld de, wTempMonAttack
+ call .PrintTempMonStats
+ hlcoord 16, 9
+ ld de, wTempMonDefense
+ call .PrintTempMonStats
+ hlcoord 16, 11
+ ld de, wTempMonSpclAtk
+ call .PrintTempMonStats
+ hlcoord 16, 13
+ ld de, wTempMonSpclDef
+ call .PrintTempMonStats
+ hlcoord 16, 15
+ ld de, wTempMonSpeed
+ call .PrintTempMonStats
+ call WaitBGMap
+ ld b, SCGB_STATS_SCREEN_HP_PALS
+ call GetSGBLayout
+ call SetPalettes
+ ret
+; 1dc507
+
+.PrintTempMonStats: ; 1dc507
+ lb bc, 2, 3
+ call PrintNum
+ ret
+; 1dc50e
+
+Function1dc50e: ; 1dc50e
+ ld bc, NAME_LENGTH
+ ld a, [wCurPartyMon]
+ call AddNTimes
+ ld e, l
+ ld d, h
+ ret
+; 1dc51a
+
+Function1dc51a: ; 1dc51a
+ and a
+ jr z, .no_move
+
+ ld [wd265], a
+ call GetMoveName
+ jr .got_string
+
+.no_move
+ ld de, String1dc584
+
+.got_string
+ call PlaceString
+ ret
+; 1dc52c
+
+Function1dc52c: ; 1dc52c
+ farcall GetGender
+ ld a, " "
+ jr c, .got_gender
+ ld a, "♂"
+ jr nz, .got_gender
+ ld a, "♀"
+
+.got_gender
+ hlcoord 17, 2
+ ld [hl], a
+ ld bc, wTempMonDVs
+ farcall CheckShininess
+ ret nc
+ hlcoord 18, 2
+ ld [hl], "⁂"
+ ret
+; 1dc550
+
+String1dc550: ; 1dc550
+ db "OT/@"
+
+String1dc554: ; 1dc554
+ db "MOVE@"
+
+String1dc559: ; 1dc559
+ db "<ID>№.@"
+
+String1dc55d: ; 1dc55d
+ db "ATTACK"
+ next "DEFENSE"
+ next "SPCL.ATK"
+ next "SPCL.DEF"
+ next "SPEED"
+ db "@"
+
+String1dc584: ; 1dc584
+ db "------------@"
+; 1dc591
+
+GBPrinterHPIcon: ; 1dc591
+INCBIN "gfx/printer/hp.1bpp"
+
+GBPrinterLvIcon: ; 1dc599
+INCBIN "gfx/printer/lv.1bpp"
diff --git a/engine/printer/printer.asm b/engine/printer/printer.asm
new file mode 100755
index 000000000..0264b4f7a
--- /dev/null
+++ b/engine/printer/printer.asm
@@ -0,0 +1,949 @@
+INCLUDE "engine/printer/printer_serial.asm"
+
+SendScreenToPrinter: ; 843f0
+.loop
+ call JoyTextDelay
+ call CheckCancelPrint
+ jr c, .cancel
+ ld a, [wJumptableIndex]
+ bit 7, a
+ jr nz, .finished
+ call PrinterJumptableIteration
+ call CheckPrinterStatus
+ call PlacePrinterStatusString
+ call DelayFrame
+ jr .loop
+
+.finished
+ and a
+ ret
+
+.cancel
+ scf
+ ret
+; 84411
+
+Printer_CleanUpAfterSend: ; 84411
+ xor a
+ ld [wPrinterConnectionOpen], a
+ ld [wPrinterOpcode], a
+ ret
+; 84419
+
+Printer_PrepareTileMapForPrint: ; 84419
+ push af
+ call Printer_StartTransmission
+ pop af
+ ld [wcbfa], a
+ call Printer_CopyTileMapToBuffer
+ ret
+; 84425
+
+Printer_ExitPrinter: ; 84425
+ call ReturnToMapFromSubmenu
+ call Printer_RestartMapMusic
+ ret
+; 8442c
+
+PrintDexEntry: ; 8442c
+ ld a, [wPrinterQueueLength]
+ push af
+
+ ld hl, vTiles1
+ ld de, FontInversed
+ lb bc, BANK(FontInversed), $80
+ call Request1bpp
+
+ xor a
+ ld [hPrinter], a
+ call Printer_PlayMusic
+
+ ld a, [rIE]
+ push af
+ xor a
+ ld [rIF], a
+ ld a, $9
+ ld [rIE], a
+
+ call Printer_StartTransmission
+ ld a, $10
+ ld [wcbfa], a
+ farcall PrintPage1
+ call ClearTileMap
+ ld a, %11100100
+ call DmgToCgbBGPals
+ call DelayFrame
+
+ ld hl, hVBlank
+ ld a, [hl]
+ push af
+ ld [hl], $4
+
+ ld a, 8 ; 16 rows
+ ld [wPrinterQueueLength], a
+ call Printer_ResetJoypadRegisters
+ call SendScreenToPrinter
+ jr c, .skip_second_page ; canceled or got an error
+
+ call Printer_CleanUpAfterSend
+ ld c, 12
+ call DelayFrames
+ xor a
+ ld [hBGMapMode], a
+
+ call Printer_StartTransmission
+ ld a, $3
+ ld [wcbfa], a
+ farcall PrintPage2
+ call Printer_ResetJoypadRegisters
+ ld a, 4
+ ld [wPrinterQueueLength], a
+ call SendScreenToPrinter
+
+.skip_second_page
+ pop af
+ ld [hVBlank], a
+ call Printer_CleanUpAfterSend
+
+ xor a
+ ld [rIF], a
+ pop af
+ ld [rIE], a
+
+ call Printer_ExitPrinter
+ ld c, 8
+.low_volume_delay_frames
+ call LowVolume
+ call DelayFrame
+ dec c
+ jr nz, .low_volume_delay_frames
+
+ pop af
+ ld [wPrinterQueueLength], a
+ ret
+; 844bc
+
+PrintPCBox: ; 844bc (21:44bc)
+ ld a, [wPrinterQueueLength]
+ push af
+ ld a, 18 / 2
+ ld [wPrinterQueueLength], a
+
+ ld a, e
+ ld [wAddrOfBoxToPrint], a
+ ld a, d
+ ld [wAddrOfBoxToPrint + 1], a
+ ld a, b
+ ld [wBankOfBoxToPrint], a
+ ld a, c
+ ld [wWhichBoxToPrint], a
+
+ xor a
+ ld [hPrinter], a
+ ld [wFinishedPrintingBox], a
+ call Printer_PlayMusic
+
+ ld a, [rIE]
+ push af
+ xor a
+ ld [rIF], a
+ ld a, %1001
+ ld [rIE], a
+
+ ld hl, hVBlank
+ ld a, [hl]
+ push af
+ ld [hl], %0100
+
+ xor a
+ ld [hBGMapMode], a
+ call PrintPCBox_Page1
+ ld a, $10 ; to be loaded to wcbfa
+ call Printer_PrepareTileMapForPrint
+ call Printer_ResetRegistersAndStartDataSend
+ jr c, .cancel
+
+ call Printer_CleanUpAfterSend
+ ld c, 12
+ call DelayFrames
+ xor a
+ ld [hBGMapMode], a
+ call PrintPCBox_Page2
+ ld a, $0 ; to be loaded to wcbfa
+ call Printer_PrepareTileMapForPrint
+ call Printer_ResetRegistersAndStartDataSend
+ jr c, .cancel
+
+ call Printer_CleanUpAfterSend
+ ld c, 12
+ call DelayFrames
+
+ xor a
+ ld [hBGMapMode], a
+ call PrintPCBox_Page3
+ ld a, $0 ; to be loaded to wcbfa
+ call Printer_PrepareTileMapForPrint
+ call Printer_ResetRegistersAndStartDataSend
+ jr c, .cancel
+
+ call Printer_CleanUpAfterSend
+ ld c, 12
+ call DelayFrames
+
+ xor a
+ ld [hBGMapMode], a
+ call PrintPCBox_Page4
+ ld a, $3 ; to be loaded to wcbfa
+ call Printer_PrepareTileMapForPrint
+ call Printer_ResetRegistersAndStartDataSend
+.cancel
+ pop af
+ ld [hVBlank], a
+ call Printer_CleanUpAfterSend
+
+ xor a
+ ld [rIF], a
+ pop af
+ ld [rIE], a
+ call Printer_ExitPrinter
+
+ pop af
+ ld [wPrinterQueueLength], a
+ ret
+
+Printer_ResetRegistersAndStartDataSend: ; 84559 (21:4559)
+ call Printer_ResetJoypadRegisters
+ call SendScreenToPrinter
+ ret
+
+PrintUnownStamp: ; 84560
+ ld a, [wPrinterQueueLength]
+ push af
+ xor a
+ ld [hPrinter], a
+ call Printer_PlayMusic
+ ld a, [rIE]
+ push af
+ xor a
+ ld [rIF], a
+ ld a, $9
+ ld [rIE], a
+ ld hl, hVBlank
+ ld a, [hl]
+ push af
+ ld [hl], $4
+ xor a
+ ld [hBGMapMode], a
+ call LoadTileMapToTempTileMap
+ farcall PlaceUnownPrinterFrontpic
+ ld a, $0 ; to be loaded to wcbfa
+ call Printer_PrepareTileMapForPrint
+ call Call_LoadTempTileMapToTileMap
+ call Printer_ResetJoypadRegisters
+ ld a, 18 / 2
+ ld [wPrinterQueueLength], a
+.loop
+ call JoyTextDelay
+ call CheckCancelPrint
+ jr c, .done
+ ld a, [wJumptableIndex]
+ bit 7, a
+ jr nz, .done
+ call PrinterJumptableIteration
+ ld a, [wJumptableIndex]
+ cp $2
+ jr nc, .check_status
+ ld a, 6 / 2
+ ld [wPrinterRowIndex], a
+
+.check_status
+ call CheckPrinterStatus
+ call PlacePrinterStatusString
+ call DelayFrame
+ jr .loop
+
+.done
+ pop af
+ ld [hVBlank], a
+ call Printer_CleanUpAfterSend
+ call Call_LoadTempTileMapToTileMap
+ xor a
+ ld [rIF], a
+ pop af
+ ld [rIE], a
+ pop af
+ ld [wPrinterQueueLength], a
+ ret
+; 845d4
+
+PrintMail: ; 845d4
+ call PrintMail_
+ call Printer_ExitPrinter
+ ret
+; 845db
+
+PrintMail_: ; 845db
+ ld a, [wPrinterQueueLength]
+ push af
+ xor a
+ ld [hPrinter], a
+ call Printer_PlayMusic
+
+ ld a, [rIE]
+ push af
+ xor a
+ ld [rIF], a
+ ld a, %1001
+ ld [rIE], a
+
+ xor a
+ ld [hBGMapMode], a
+
+ ld a, $13 ; to be loaded to wcbfa
+ call Printer_PrepareTileMapForPrint
+ ld hl, hVBlank
+ ld a, [hl]
+ push af
+ ld [hl], %0100
+
+ ld a, 18 / 2
+ ld [wPrinterQueueLength], a
+ call SendScreenToPrinter
+
+ pop af
+ ld [hVBlank], a
+ call Printer_CleanUpAfterSend
+ call Printer_CopyBufferToTileMap
+
+ xor a
+ ld [rIF], a
+ pop af
+ ld [rIE], a
+
+ pop af
+ ld [wPrinterQueueLength], a
+ ret
+; 8461a
+
+PrintPartymon: ; 8461a
+ ld a, [wPrinterQueueLength]
+ push af
+ xor a
+ ld [hPrinter], a
+ call Printer_PlayMusic
+
+ ld a, [rIE]
+ push af
+ xor a
+ ld [rIF], a
+ ld a, %1001
+ ld [rIE], a
+
+ xor a
+ ld [hBGMapMode], a
+ farcall PrintPartyMonPage1
+ ld a, $10 ; to be loaded to wcbfa
+ call Printer_PrepareTileMapForPrint
+
+ ld hl, hVBlank
+ ld a, [hl]
+ push af
+ ld [hl], %0100
+
+ ld a, 16 / 2
+ ld [wPrinterQueueLength], a
+ call Printer_ResetJoypadRegisters
+ call SendScreenToPrinter
+ jr c, .cancel
+
+ call Printer_CleanUpAfterSend
+ ld c, 12
+ call DelayFrames
+
+ xor a
+ ld [hBGMapMode], a
+ farcall PrintPartyMonPage2
+ ld a, $3 ; to be loaded to wcbfa
+ call Printer_PrepareTileMapForPrint
+
+ ld a, 18 / 2
+ ld [wPrinterQueueLength], a
+ call Printer_ResetJoypadRegisters
+ call SendScreenToPrinter
+.cancel
+ pop af
+ ld [hVBlank], a
+ call Printer_CleanUpAfterSend
+
+ call Printer_CopyBufferToTileMap
+ xor a
+ ld [rIF], a
+ pop af
+ ld [rIE], a
+ call Printer_ExitPrinter
+
+ pop af
+ ld [wPrinterQueueLength], a
+ ret
+; 84688
+
+_PrintDiploma: ; 84688
+ ld a, [wPrinterQueueLength]
+ push af
+
+ farcall PlaceDiplomaOnScreen
+
+ xor a
+ ld [hPrinter], a
+ call Printer_PlayMusic
+
+ ld a, [rIE]
+ push af
+ xor a
+ ld [rIF], a
+ ld a, %1001
+ ld [rIE], a
+
+ ld hl, hVBlank
+ ld a, [hl]
+ push af
+ ld [hl], %0100
+
+ ld a, $10 ; to be loaded to wcbfa
+ call Printer_PrepareTileMapForPrint
+ call Printer_ResetJoypadRegisters
+
+ ld a, 18 / 2
+ ld [wPrinterQueueLength], a
+ call SendScreenToPrinter
+ jr c, .cancel
+ call Printer_CleanUpAfterSend
+ ld c, 12
+ call DelayFrames
+
+ call LoadTileMapToTempTileMap
+ xor a
+ ld [hBGMapMode], a
+
+ farcall PrintDiplomaPage2
+
+ ld a, $3 ; to be loaded to wcbfa
+ call Printer_PrepareTileMapForPrint
+ call Call_LoadTempTileMapToTileMap
+ call Printer_ResetJoypadRegisters
+
+ ld a, 18 / 2
+ ld [wPrinterQueueLength], a
+ call SendScreenToPrinter
+.cancel
+ pop af
+ ld [hVBlank], a
+ call Printer_CleanUpAfterSend
+
+ xor a
+ ld [rIF], a
+ pop af
+ ld [rIE], a
+ call Printer_ExitPrinter
+
+ pop af
+ ld [wPrinterQueueLength], a
+ ret
+; 846f6
+
+CheckCancelPrint: ; 846f6
+ ld a, [hJoyDown]
+ and B_BUTTON
+ jr nz, .pressed_b
+ and a
+ ret
+
+.pressed_b
+ ld a, [wca80]
+ cp $c
+ jr nz, .cancel
+.loop
+ ld a, [wPrinterOpcode]
+ and a
+ jr nz, .loop
+ ld a, $16 ; cancel
+ ld [wPrinterOpcode], a
+ ld a, $88
+ ld [rSB], a
+ ld a, $1
+ ld [rSC], a
+ ld a, $81
+ ld [rSC], a
+.loop2
+ ld a, [wPrinterOpcode]
+ and a
+ jr nz, .loop2
+
+.cancel
+ ld a, $1
+ ld [hPrinter], a
+ scf
+ ret
+; 84728
+
+Printer_CopyTileMapToBuffer: ; 84728
+ hlcoord 0, 0
+ ld de, wPrinterTileMapBuffer
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ call CopyBytes
+ ret
+; 84735
+
+Printer_CopyBufferToTileMap: ; 84735
+ ld hl, wPrinterTileMapBuffer
+ decoord 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ call CopyBytes
+ ret
+; 84742
+
+Printer_ResetJoypadRegisters: ; 84742
+ xor a
+ ld [hJoyReleased], a
+ ld [hJoyPressed], a
+ ld [hJoyDown], a
+ ld [hJoyLast], a
+ ret
+; 8474c
+
+Printer_PlayMusic: ; 8474c
+ ld de, MUSIC_PRINTER
+ call PlayMusic2
+ ret
+; 84753
+
+Printer_RestartMapMusic: ; 84753
+ call RestartMapMusic
+ ret
+; 84757
+
+CheckPrinterStatus: ; 84757
+; Check for printer errors
+; If [ca88] == -1, we're disconnected
+ ld a, [wPrinterHandshake]
+ cp -1
+ jr nz, .printer_connected
+ ld a, [wPrinterStatusFlags]
+ cp -1
+ jr z, .error_2
+.printer_connected
+; ca89 contains printer status flags
+ ld a, [wPrinterStatusFlags]
+ and %11100000
+ ret z ; no error
+
+ bit 7, a
+ jr nz, .error_1
+ bit 6, a
+ jr nz, .error_4
+ ; paper error
+ ld a, PRINTER_ERROR_3
+ jr .load_text_index
+
+.error_4
+ ; temperature error
+ ld a, PRINTER_ERROR_4
+ jr .load_text_index
+
+.error_1
+ ; printer battery low
+ ld a, PRINTER_ERROR_1
+ jr .load_text_index
+
+.error_2
+ ; connection error
+ ld a, PRINTER_ERROR_2
+.load_text_index
+ ld [wPrinterStatus], a
+ ret
+; 84785
+
+PlacePrinterStatusString: ; 84785
+; Print nonzero printer status
+ ld a, [wPrinterStatus]
+ and a
+ ret z
+ push af
+ xor a
+ ld [hBGMapMode], a
+ hlcoord 0, 5
+ lb bc, 10, 18
+ call TextBox
+ pop af
+ ld e, a
+ ld d, 0
+ ld hl, PrinterStatusStringPointers
+ add hl, de
+ add hl, de
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ hlcoord 1, 7
+ ld a, BANK(GBPrinterStrings)
+ call FarString
+ hlcoord 2, 15
+ ld de, String_PressBToCancel
+ call PlaceString
+ ld a, $1
+ ld [hBGMapMode], a
+ xor a
+ ld [wPrinterStatus], a
+ ret
+; 847bd
+
+Unreferenced_Function847bd: ; 847bd
+ ld a, [wPrinterStatus]
+ and a
+ ret z
+ push af
+ xor a
+ ld [hBGMapMode], a
+ hlcoord 2, 4
+ lb bc, 13, 16
+ call ClearBox
+ pop af
+ ld e, a
+ ld d, 0
+ ld hl, PrinterStatusStringPointers
+ add hl, de
+ add hl, de
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ hlcoord 4, 7
+ ld a, BANK(GBPrinterStrings)
+ call FarString
+ hlcoord 4, 15
+ ld de, String_PressBToCancel
+ call PlaceString
+ ld a, $1
+ ld [hBGMapMode], a
+ xor a
+ ld [wPrinterStatus], a
+ ret
+; 847f5
+
+String_PressBToCancel:
+ db "Press B to Cancel@"
+; 84807
+
+PrinterStatusStringPointers: ; 84807
+ dw GBPrinterString_Null ; @
+ dw GBPrinterString_CheckingLink ; CHECKING LINK
+ dw GBPrinterString_Transmitting ; TRANSMITTING
+ dw GBPrinterString_Printing ; PRINTING
+ dw GBPrinterString_PrinterError1 ; error 1
+ dw GBPrinterString_PrinterError2 ; error 2
+ dw GBPrinterString_PrinterError3 ; error 3
+ dw GBPrinterString_PrinterError4 ; error 4
+; 84817
+
+PrintPCBox_Page1: ; 84817 (21:4817)
+ xor a
+ ld [wWhichBoxMonToPrint], a
+ hlcoord 0, 0
+ ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
+ ld a, " "
+ call ByteFill
+ call Printer_PlaceEmptyBoxSlotString
+
+ hlcoord 0, 0
+ ld bc, 9 * SCREEN_WIDTH
+ ld a, " "
+ call ByteFill
+
+ call Printer_PlaceSideBorders
+ call Printer_PlaceTopBorder
+
+ hlcoord 4, 3
+ ld de, .String_PokemonList
+ call PlaceString
+
+ ld a, [wWhichBoxToPrint]
+ ld bc, BOX_NAME_LENGTH
+ ld hl, wBoxNames
+ call AddNTimes
+ ld d, h
+ ld e, l
+ hlcoord 6, 5
+ call PlaceString
+ ld a, 1
+ call Printer_GetBoxMonSpecies
+ hlcoord 2, 9
+ ld c, 3
+ call Printer_PrintBoxListSegment
+ ret
+; 84865 (21:4865)
+
+.String_PokemonList:
+ db "#MON LIST@"
+; 8486f
+
+PrintPCBox_Page2: ; 8486f (21:486f)
+ hlcoord 0, 0
+ ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
+ ld a, " "
+ call ByteFill
+ call Printer_PlaceEmptyBoxSlotString
+ call Printer_PlaceSideBorders
+ ld a, [wFinishedPrintingBox]
+ and a
+ ret nz
+ ld a, 4
+ call Printer_GetBoxMonSpecies
+ hlcoord 2, 0
+ ld c, 6
+ call Printer_PrintBoxListSegment
+ ret
+
+PrintPCBox_Page3: ; 84893 (21:4893)
+ hlcoord 0, 0
+ ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
+ ld a, " "
+ call ByteFill
+ call Printer_PlaceEmptyBoxSlotString
+ call Printer_PlaceSideBorders
+ ld a, [wFinishedPrintingBox]
+ and a
+ ret nz
+ ld a, 10
+ call Printer_GetBoxMonSpecies
+ hlcoord 2, 0
+ ld c, 6
+ call Printer_PrintBoxListSegment
+ ret
+
+PrintPCBox_Page4: ; 848b7 (21:48b7)
+ hlcoord 0, 0
+ ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
+ ld a, " "
+ call ByteFill
+ call Printer_PlaceEmptyBoxSlotString
+ hlcoord 1, 15
+ lb bc, 2, 18
+ call ClearBox
+ call Printer_PlaceSideBorders
+ call Printer_PlaceBottomBorders
+ ld a, [wFinishedPrintingBox]
+ and a
+ ret nz
+ ld a, 16
+ call Printer_GetBoxMonSpecies
+ hlcoord 2, 0
+ ld c, 5
+ call Printer_PrintBoxListSegment
+ ret
+
+Printer_PrintBoxListSegment: ; 848e7 (21:48e7)
+ ld a, [wBankOfBoxToPrint]
+ call GetSRAMBank
+.loop
+ ld a, c
+ and a
+ jp z, .max_length
+ dec c
+ ld a, [de]
+ cp $ff
+ jp z, .finish
+ ld [wd265], a
+ ld [wCurPartySpecies], a
+
+ push bc
+ push hl
+ push de
+
+ push hl
+ ld bc, 16
+ ld a, " "
+ call ByteFill
+ pop hl
+
+ push hl
+ call GetBasePokemonName
+ pop hl
+
+ push hl
+ call PlaceString
+ ld a, [wCurPartySpecies]
+ cp EGG
+ pop hl
+ jr z, .ok2
+
+ ld bc, MON_NAME_LENGTH
+ add hl, bc
+ call Printer_GetMonGender
+ ld bc, SCREEN_WIDTH - MON_NAME_LENGTH
+ add hl, bc
+ ld a, "/"
+ ld [hli], a
+
+ push hl
+ ld bc, 14
+ ld a, " "
+ call ByteFill
+ pop hl
+
+ push hl
+ ld a, [wAddrOfBoxToPrint]
+ ld l, a
+ ld a, [wAddrOfBoxToPrint + 1]
+ ld h, a
+ ld bc, sBoxMonNicknames - sBox
+ add hl, bc
+ ld bc, MON_NAME_LENGTH
+ ld a, [wWhichBoxMonToPrint]
+ call AddNTimes
+ ld e, l
+ ld d, h
+ pop hl
+
+ push hl
+ call PlaceString
+ pop hl
+
+ ld bc, MON_NAME_LENGTH
+ add hl, bc
+ push hl
+ ld a, [wAddrOfBoxToPrint]
+ ld l, a
+ ld a, [wAddrOfBoxToPrint + 1]
+ ld h, a
+ ld bc, 2 + MONS_PER_BOX + MON_LEVEL
+ add hl, bc
+ ld bc, BOXMON_STRUCT_LENGTH
+ ld a, [wWhichBoxMonToPrint]
+ call AddNTimes
+ ld a, [hl]
+ pop hl
+ call PrintLevel_Force3Digits
+.ok2
+ ld hl, wWhichBoxMonToPrint
+ inc [hl]
+ pop de
+ pop hl
+ ld bc, 3 * SCREEN_WIDTH
+ add hl, bc
+ pop bc
+ inc de
+ jp .loop
+
+.finish
+ ld a, $1
+ ld [wFinishedPrintingBox], a
+.max_length
+ call CloseSRAM
+ ret
+
+Printer_GetMonGender: ; 8498a (21:498a)
+ push hl
+ ld a, [wAddrOfBoxToPrint]
+ ld l, a
+ ld a, [wAddrOfBoxToPrint + 1]
+ ld h, a
+ ld bc, $2b
+ add hl, bc
+ ld bc, BOXMON_STRUCT_LENGTH
+ ld a, [wWhichBoxMonToPrint]
+ call AddNTimes
+ ld de, wTempMonDVs
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ ld a, [wWhichBoxMonToPrint]
+ ld [wCurPartyMon], a
+ ld a, TEMPMON
+ ld [wMonType], a
+ farcall GetGender
+ ld a, " "
+ jr c, .got_gender
+ ld a, "♂"
+ jr nz, .got_gender
+ ld a, "♀"
+.got_gender
+ pop hl
+ ld [hli], a
+ ret
+
+Printer_GetBoxMonSpecies: ; 849c6 (21:49c6)
+ push hl
+ ld e, a
+ ld d, $0
+ ld a, [wAddrOfBoxToPrint]
+ ld l, a
+ ld a, [wAddrOfBoxToPrint + 1]
+ ld h, a
+ add hl, de
+ ld e, l
+ ld d, h
+ pop hl
+ ret
+
+Printer_PlaceTopBorder: ; 849d7 (21:49d7)
+ hlcoord 0, 0
+ ld a, "┌"
+ ld [hli], a
+ ld a, "─"
+ ld c, SCREEN_WIDTH - 2
+.loop
+ ld [hli], a
+ dec c
+ jr nz, .loop
+ ld a, "┐"
+ ld [hl], a
+ ret
+
+Printer_PlaceSideBorders: ; 849e9 (21:49e9)
+ hlcoord 0, 0
+ ld de, SCREEN_WIDTH - 1
+ ld c, SCREEN_HEIGHT
+.loop
+ ld a, "│"
+ ld [hl], a
+ add hl, de
+ ld a, "│"
+ ld [hli], a
+ dec c
+ jr nz, .loop
+ ret
+
+Printer_PlaceBottomBorders: ; 849fc (21:49fc)
+ hlcoord 0, 17
+ ld a, "└"
+ ld [hli], a
+ ld a, "─"
+ ld c, SCREEN_WIDTH - 2
+.loop
+ ld [hli], a
+ dec c
+ jr nz, .loop
+ ld a, "┘"
+ ld [hl], a
+ ret
+
+Printer_PlaceEmptyBoxSlotString: ; 84a0e (21:4a0e)
+ hlcoord 2, 0
+ ld c, $6
+.loop
+ push bc
+ push hl
+ ld de, String84a25
+ call PlaceString
+ pop hl
+ ld bc, 3 * SCREEN_WIDTH
+ add hl, bc
+ pop bc
+ dec c
+ jr nz, .loop
+ ret
+; 84a25 (21:4a25)
+
+String84a25: ; 84a25
+ db " ------@"
+; 84a2e
diff --git a/engine/printer/printer_serial.asm b/engine/printer/printer_serial.asm
new file mode 100755
index 000000000..4e0d10851
--- /dev/null
+++ b/engine/printer/printer_serial.asm
@@ -0,0 +1,640 @@
+Printer_StartTransmission: ; 84000
+ ld hl, wGameboyPrinterRAM
+ ld bc, wGameboyPrinterRAMEnd - wGameboyPrinterRAM
+ xor a
+ call Printer_ByteFill
+ xor a
+ ld [rSB], a
+ ld [rSC], a
+ ld [wPrinterOpcode], a
+ ld hl, wPrinterConnectionOpen
+ set 0, [hl]
+ ld a, [wGBPrinter]
+ ld [wGBPrinterSettings], a
+ xor a
+ ld [wJumptableIndex], a
+ ret
+; 84022
+
+PrinterJumptableIteration: ; 84022
+ ld a, [wJumptableIndex]
+ ld e, a
+ ld d, 0
+ ld hl, .Jumptable
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+; 84031
+
+.Jumptable: ; 84031 (21:4031)
+ dw Print_InitPrinterHandshake ; 00
+ dw Printer_CheckConnectionStatus ; 01
+ dw Printer_WaitSerial ; 02
+ dw Printer_StartTransmittingTilemap ; 03
+ dw Printer_TransmissionLoop ; 04
+ dw Printer_WaitSerialAndLoopBack2 ; 05
+
+ dw Printer_EndTilemapTransmission ; 06
+ dw Printer_TransmissionLoop ; 07
+ dw Printer_WaitSerial ; 08
+ dw Printer_SignalSendHeader ; 09
+ dw Printer_TransmissionLoop ; 0a
+ dw Printer_WaitSerial ; 0b
+ dw Printer_WaitUntilFinished ; 0c
+ dw Printer_Quit ; 0d
+
+ dw Printer_NextSection_ ; 0e
+ dw Printer_WaitSerial ; 0f
+ dw Printer_SignalLoopBack ; 10
+ dw Printer_SectionOne ; 11
+ dw Printer_WaitLoopBack ; 12
+ dw Printer_WaitLoopBack_ ; 13
+
+Printer_NextSection: ; 84059 (21:4059)
+ ld hl, wJumptableIndex
+ inc [hl]
+ ret
+
+Printer_PrevSection: ; 8405e (21:405e)
+ ld hl, wJumptableIndex
+ dec [hl]
+ ret
+
+Printer_Quit: ; 84063 (21:4063)
+ xor a
+ ld [wPrinterStatusFlags], a
+ ld hl, wJumptableIndex
+ set 7, [hl]
+ ret
+
+Printer_NextSection_: ; 8406d (21:406d)
+ call Printer_NextSection
+ ret
+
+Printer_SectionOne: ; 84071 (21:4071)
+ ld a, $1
+ ld [wJumptableIndex], a
+ ret
+
+Print_InitPrinterHandshake: ; 84077 (21:4077)
+ call Printer_ResetData
+ ld hl, PrinterDataPacket1
+ call Printer_CopyPacket
+ xor a
+ ld [wPrinterSendByteCounter], a
+ ld [wPrinterSendByteCounter + 1], a
+ ld a, [wPrinterQueueLength]
+ ld [wPrinterRowIndex], a
+ call Printer_NextSection
+ call Printer_WaitHandshake
+ ld a, PRINTER_STATUS_CHECKING
+ ld [wPrinterStatus], a
+ ret
+
+Printer_StartTransmittingTilemap: ; 84099 (21:4099)
+ call Printer_ResetData
+ ; check ???
+ ld hl, wPrinterRowIndex
+ ld a, [hl]
+ and a
+ jr z, Printer_EndTilemapTransmission
+ ; send packet 3
+ ld hl, PrinterDataPacket3 ; signal start of transmission
+ call Printer_CopyPacket
+ ; prepare to send 40 tiles
+ call Printer_Convert2RowsTo2bpp
+ ld a, LOW(40 tiles)
+ ld [wPrinterSendByteCounter], a
+ ld a, HIGH(40 tiles)
+ ld [wPrinterSendByteCounter + 1], a
+ ; compute the checksum
+ call Printer_ComputeChecksum
+ call Printer_NextSection
+ call Printer_WaitHandshake
+ ld a, PRINTER_STATUS_TRANSMITTING
+ ld [wPrinterStatus], a
+ ret
+
+Printer_EndTilemapTransmission: ; 840c5 (21:40c5)
+ ; ensure that we go from here to routine 7
+ ld a, $6
+ ld [wJumptableIndex], a
+ ; send packet 4
+ ld hl, PrinterDataPacket4 ; signal no transmission
+ call Printer_CopyPacket
+ ; send no tile data
+ xor a
+ ld [wPrinterSendByteCounter], a
+ ld [wPrinterSendByteCounter + 1], a
+ call Printer_NextSection
+ call Printer_WaitHandshake
+ ret
+
+Printer_SignalSendHeader: ; 840de (21:40de)
+ call Printer_ResetData
+ ld hl, PrinterDataPacket2 ; signal request print
+ call Printer_CopyPacket
+ ; prepare to send 1 tile
+ call Printer_StageHeaderForSend
+ ld a, LOW(4)
+ ld [wPrinterSendByteCounter], a
+ ld a, HIGH(4)
+ ld [wPrinterSendByteCounter + 1], a
+ ; compute the checksum
+ call Printer_ComputeChecksum
+ call Printer_NextSection
+ call Printer_WaitHandshake
+ ld a, PRINTER_STATUS_PRINTING
+ ld [wPrinterStatus], a
+ ret
+
+Printer_SignalLoopBack: ; 84103 (21:4103)
+ call Printer_ResetData
+ ; send packet 1
+ ld hl, PrinterDataPacket1 ; signal no transmission
+ call Printer_CopyPacket
+ ; send no tile data
+ xor a
+ ld [wPrinterSendByteCounter], a
+ ld [wPrinterSendByteCounter + 1], a
+ ld a, [wPrinterQueueLength]
+ ld [wPrinterRowIndex], a
+ call Printer_NextSection
+ call Printer_WaitHandshake
+ ret
+
+Printer_WaitSerial: ; 84120 (21:4120)
+ ld hl, wPrinterSerialFrameDelay
+ inc [hl]
+ ld a, [hl]
+ cp $6
+ ret c
+ xor a
+ ld [hl], a
+ call Printer_NextSection
+ ret
+
+Printer_WaitSerialAndLoopBack2: ; 8412e (21:412e)
+ ld hl, wPrinterSerialFrameDelay
+ inc [hl]
+ ld a, [hl]
+ cp $6
+ ret c
+ xor a
+ ld [hl], a
+ ld hl, wPrinterRowIndex
+ dec [hl]
+ call Printer_PrevSection
+ call Printer_PrevSection
+ ret
+
+Printer_CheckConnectionStatus: ; 84143 (21:4143)
+ ld a, [wPrinterOpcode]
+ and a
+ ret nz
+ ld a, [wPrinterHandshake]
+ cp $ff
+ jr nz, .printer_connected
+ ld a, [wPrinterStatusFlags]
+ cp $ff
+ jr z, .printer_error
+
+.printer_connected
+ ld a, [wPrinterHandshake]
+ cp $81
+ jr nz, .printer_error
+ ld a, [wPrinterStatusFlags]
+ cp $0
+ jr nz, .printer_error
+ ld hl, wPrinterConnectionOpen
+ set 1, [hl]
+ ld a, $5
+ ld [wHandshakeFrameDelay], a
+ call Printer_NextSection
+ ret
+
+.printer_error
+ ld a, $ff
+ ld [wPrinterHandshake], a
+ ld [wPrinterStatusFlags], a
+ ld a, $e
+ ld [wJumptableIndex], a
+ ret
+
+Printer_TransmissionLoop: ; 84180 (21:4180)
+ ld a, [wPrinterOpcode]
+ and a
+ ret nz
+ ld a, [wPrinterStatusFlags]
+ and $f0
+ jr nz, .enter_wait_loop
+ ld a, [wPrinterStatusFlags]
+ and $1
+ jr nz, .cycle_back
+ call Printer_NextSection
+ ret
+
+.cycle_back
+ call Printer_PrevSection
+ ret
+
+.enter_wait_loop
+ ld a, $12 ; Printer_WaitLoopBack
+ ld [wJumptableIndex], a
+ ret
+
+Printer_WaitUntilFinished: ; 841a1 (21:41a1)
+ ld a, [wPrinterOpcode]
+ and a
+ ret nz
+ ld a, [wPrinterStatusFlags]
+ and $f3
+ ret nz
+ call Printer_NextSection
+ ret
+
+Printer_WaitLoopBack: ; 841b0 (21:41b0)
+ call Printer_NextSection
+Printer_WaitLoopBack_: ; 841b3 (21:41b3)
+ ld a, [wPrinterOpcode]
+ and a
+ ret nz
+ ld a, [wPrinterStatusFlags]
+ and $f0
+ ret nz
+ xor a
+ ld [wJumptableIndex], a
+ ret
+
+Printer_WaitHandshake: ; 841c3 (21:41c3)
+.loop
+ ld a, [wPrinterOpcode]
+ and a
+ jr nz, .loop
+ xor a
+ ld [wPrinterSendByteOffset], a
+ ld [wPrinterSendByteOffset + 1], a
+ ld a, $1
+ ld [wPrinterOpcode], a
+ ld a, $88
+ ld [rSB], a
+ ld a, $1
+ ld [rSC], a
+ ld a, $81
+ ld [rSC], a
+ ret
+
+Printer_CopyPacket: ; 841e2 (21:41e2)
+ ld a, [hli]
+ ld [wPrinterData], a
+ ld a, [hli]
+ ld [wPrinterData + 1], a
+ ld a, [hli]
+ ld [wPrinterData + 2], a
+ ld a, [hli]
+ ld [wPrinterData + 3], a
+ ld a, [hli]
+ ld [wPrinterChecksum], a
+ ld a, [hl]
+ ld [wPrinterChecksum + 1], a
+ ret
+
+Printer_ResetData: ; 841fb (21:41fb)
+ xor a
+ ld hl, wPrinterData
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld hl, wPrinterChecksum
+ ld [hli], a
+ ld [hl], a
+ xor a
+ ld [wPrinterSendByteCounter], a
+ ld [wPrinterSendByteCounter + 1], a
+ ld hl, wGameboyPrinterRAM
+ ld bc, wGameboyPrinter2bppSourceEnd - wGameboyPrinter2bppSource
+ call Printer_ByteFill
+ ret
+
+Printer_ComputeChecksum: ; 84219 (21:4219)
+ ld hl, 0
+ ld bc, 4
+ ld de, wPrinterData
+ call .ComputeChecksum
+ ld a, [wPrinterSendByteCounter]
+ ld c, a
+ ld a, [wPrinterSendByteCounter + 1]
+ ld b, a
+ ld de, wGameboyPrinterRAM
+ call .ComputeChecksum
+ ld a, l
+ ld [wPrinterChecksum], a
+ ld a, h
+ ld [wPrinterChecksum + 1], a
+ ret
+
+.ComputeChecksum: ; 8423c (21:423c)
+.loop
+ ld a, [de]
+ inc de
+ add l
+ jr nc, .no_overflow
+ inc h
+.no_overflow
+ ld l, a
+ dec bc
+ ld a, c
+ or b
+ jr nz, .loop
+ ret
+
+Printer_StageHeaderForSend: ; 84249 (21:4249)
+ ld a, $1
+ ld [wGameboyPrinter2bppSource + 0], a
+ ld a, [wcbfa]
+ ld [wGameboyPrinter2bppSource + 1], a
+ ld a, %11100100
+ ld [wGameboyPrinter2bppSource + 2], a
+ ld a, [wGBPrinterSettings]
+ ld [wGameboyPrinter2bppSource + 3], a
+ ret
+
+Printer_Convert2RowsTo2bpp: ; 84260 (21:4260)
+ ; de = wPrinterTileMapBuffer + 2 * SCREEN_WIDTH * ([wPrinterQueueLength] - [wPrinterRowIndex])
+ ld a, [wPrinterRowIndex]
+ xor $ff
+ ld d, a
+ ld a, [wPrinterQueueLength]
+ inc a
+ add d
+ ld hl, wPrinterTileMapBuffer
+ ld de, 2 * SCREEN_WIDTH
+.loop1
+ and a
+ jr z, .okay1
+ add hl, de
+ dec a
+ jr .loop1
+.okay1
+ ld e, l
+ ld d, h
+ ld hl, wGameboyPrinter2bppSource
+ ld c, 2 * SCREEN_WIDTH
+.loop2
+ ld a, [de]
+ inc de
+ push bc
+ push de
+ push hl
+ ; convert tile index to vram address
+ swap a
+ ld d, a
+ and $f0
+ ld e, a
+ ld a, d
+ and $f
+ ld d, a
+ and $8
+ ld a, d
+ jr nz, .vtiles_8xxx
+ or $90
+ jr .got_vtile_addr
+
+.vtiles_8xxx
+ or $80
+.got_vtile_addr
+ ld d, a
+ ; copy 1 vtile to hl
+ lb bc, BANK(Printer_Convert2RowsTo2bpp), 1
+ call Request2bpp
+ pop hl
+ ld de, 1 tiles
+ add hl, de
+ pop de
+ pop bc
+ dec c
+ jr nz, .loop2
+ ret
+
+Printer_ByteFill: ; 842ab
+ push de
+ ld e, a
+.loop
+ ld [hl], e
+ inc hl
+ dec bc
+ ld a, c
+ or b
+ jr nz, .loop
+ ld a, e
+ pop de
+ ret
+; 842b7
+
+PrinterDataPacket1:
+ db 1, 0, $00, 0
+ dw 1
+PrinterDataPacket2:
+ db 2, 0, $04, 0
+ dw 0
+PrinterDataPacket3:
+ db 4, 0, $80, 2
+ dw 0
+PrinterDataPacket4:
+ db 4, 0, $00, 0
+ dw 4
+PrinterDataPacket5: ; unused
+ db 8, 0, $00, 0
+ dw 8
+PrinterDataPacket6: ; unused
+ db 15, 0, $00, 0
+ dw 15
+; 842db
+
+_PrinterReceive:: ; 842db
+ ld a, [wPrinterOpcode]
+ add a
+ ld e, a
+ ld d, 0
+ ld hl, .Jumptable
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+; 842ea
+
+.Jumptable: ; 842ea (21:42ea)
+ dw Printer_DoNothing ; 00
+
+ dw Printer_Send0x33 ; 01
+ dw Printer_SendPrinterData1 ; 02
+ dw Printer_SendPrinterData2 ; 03
+ dw Printer_SendPrinterData3 ; 04
+ dw Printer_SendPrinterData4 ; 05
+ dw Printer_SendNextByte ; 06
+ dw Printer_SendwPrinterChecksumLo ; 07
+ dw Printer_SendwPrinterChecksumHi ; 08
+ dw Printer_Send0x00 ; 09
+ dw Printer_ReceiveTowPrinterHandshakeAndSend0x00 ; 0a
+ dw Printer_ReceiveTowPrinterStatusFlagsAndExitSendLoop ; 0b
+
+ dw Printer_Send0x33 ; 0c triggered by AskSerial
+ dw Printer_Send0x0f ; 0d
+ dw Printer_Send0x00_ ; 0e
+ dw Printer_Send0x00_ ; 0f
+ dw Printer_Send0x00_ ; 10
+ dw Printer_Send0x0f ; 11
+ dw Printer_Send0x00_ ; 12
+ dw Printer_Send0x00 ; 13
+ dw Printer_ReceiveTowPrinterHandshakeAndSend0x00 ; 14
+ dw Printer_ReceiveTowPrinterStatusFlagsAndExitSendLoop_ ; 15
+
+ dw Printer_Send0x33 ; 16 triggered by pressing B
+ dw Printer_Send0x08 ; 17
+ dw Printer_Send0x00_ ; 18
+ dw Printer_Send0x00_ ; 19
+ dw Printer_Send0x00_ ; 1a
+ dw Printer_Send0x08 ; 1b
+ dw Printer_Send0x00_ ; 1c
+ dw Printer_Send0x00 ; 1d
+ dw Printer_ReceiveTowPrinterHandshakeAndSend0x00 ; 1e
+ dw Printer_ReceiveTowPrinterStatusFlagsAndExitSendLoop ; 1f
+
+Printer_NextInstruction: ; 8432a (21:432a)
+ ld hl, wPrinterOpcode
+ inc [hl]
+ ret
+
+Printer_DoNothing: ; 8432f (21:432f)
+ ret
+
+Printer_Send0x33: ; 84330 (21:4330)
+ ld a, $33
+ call Printer_SerialSend
+ call Printer_NextInstruction
+ ret
+
+Printer_SendPrinterData1: ; 84339 (21:4339)
+ ld a, [wPrinterData]
+ call Printer_SerialSend
+ call Printer_NextInstruction
+ ret
+
+Printer_SendPrinterData2: ; 84343 (21:4343)
+ ld a, [wPrinterData + 1]
+ call Printer_SerialSend
+ call Printer_NextInstruction
+ ret
+
+Printer_SendPrinterData3: ; 8434d (21:434d)
+ ld a, [wPrinterData + 2]
+ call Printer_SerialSend
+ call Printer_NextInstruction
+ ret
+
+Printer_SendPrinterData4: ; 84357 (21:4357)
+ ld a, [wPrinterData + 3]
+ call Printer_SerialSend
+ call Printer_NextInstruction
+ ret
+
+Printer_SendNextByte: ; 84361 (21:4361)
+ ; decrement 16-bit counter
+ ld hl, wPrinterSendByteCounter
+ ld a, [hli]
+ ld d, [hl]
+ ld e, a
+ or d
+ jr z, .done
+ dec de
+ ld [hl], d
+ dec hl
+ ld [hl], e
+
+ ld a, [wPrinterSendByteOffset]
+ ld e, a
+ ld a, [wPrinterSendByteOffset + 1]
+ ld d, a
+ ld hl, wGameboyPrinterRAM
+ add hl, de
+ inc de
+ ld a, e
+ ld [wPrinterSendByteOffset], a
+ ld a, d
+ ld [wPrinterSendByteOffset + 1], a
+ ld a, [hl]
+ call Printer_SerialSend
+ ret
+
+.done
+ call Printer_NextInstruction
+Printer_SendwPrinterChecksumLo: ; 8438b (21:438b)
+ ld a, [wPrinterChecksum]
+ call Printer_SerialSend
+ call Printer_NextInstruction
+ ret
+
+Printer_SendwPrinterChecksumHi: ; 84395 (21:4395)
+ ld a, [wPrinterChecksum + 1]
+ call Printer_SerialSend
+ call Printer_NextInstruction
+ ret
+
+Printer_Send0x00: ; 8439f (21:439f)
+ ld a, $0
+ call Printer_SerialSend
+ call Printer_NextInstruction
+ ret
+
+Printer_ReceiveTowPrinterHandshakeAndSend0x00: ; 843a8 (21:43a8)
+ ld a, [rSB]
+ ld [wPrinterHandshake], a
+ ld a, $0
+ call Printer_SerialSend
+ call Printer_NextInstruction
+ ret
+
+Printer_ReceiveTowPrinterStatusFlagsAndExitSendLoop: ; 843b6 (21:43b6)
+ ld a, [rSB]
+ ld [wPrinterStatusFlags], a
+ xor a
+ ld [wPrinterOpcode], a
+ ret
+
+Printer_Send0x0f: ; 843c0 (21:43c0)
+ ld a, $f
+ call Printer_SerialSend
+ call Printer_NextInstruction
+ ret
+
+Printer_Send0x00_: ; 843c9 (21:43c9)
+ ld a, $0
+ call Printer_SerialSend
+ call Printer_NextInstruction
+ ret
+
+Printer_Send0x08: ; 843d2 (21:43d2)
+ ld a, $8
+ call Printer_SerialSend
+ call Printer_NextInstruction
+ ret
+
+Printer_SerialSend: ; 843db (21:43db)
+ ld [rSB], a
+ ld a, $1 ; switch to internal clock
+ ld [rSC], a
+ ld a, $81 ; start transfer
+ ld [rSC], a
+ ret
+
+Printer_ReceiveTowPrinterStatusFlagsAndExitSendLoop_: ; 843e6 (21:43e6)
+ ld a, [rSB]
+ ld [wPrinterStatusFlags], a
+ xor a
+ ld [wPrinterOpcode], a
+ ret