PUSHS "Printer Variables", WRAM0[PRINTER_VARS_START] vTooBusyForPrinter: db ; one if we're too busy to use the async thread for printer stuff vPrinterState: db ; options: NONE, READY, ERROR, FULL, PRINTING def PS_NONE equ 0 def PS_READY equ 1 def PS_ERROR equ 2 def PS_FULL equ 3 def PS_PRINTING equ 4 vPrinterReturnValue: dw vPrinterReturnValuePrevious: dw vPrinterReturnValueChanged: db vBuildingByte: dw vPrinterIsReady: db vPrinterRow: db vPrinterStart: db POPS CheckForPrinter: ld a, $F ld hl, ZEROES ld bc, 0 call SendPacket ret UpdatePrintUI: ld a, [vPrinterState] cp a, PS_NONE ld hl, BanishPrinterUI jp z, Async_Spawn_HL cp a, PS_READY ld hl, SummonPrinterUI jp z, Async_Spawn_HL cp a, PS_ERROR ld hl, ShowErrorUI jp z, Async_Spawn_HL cp a, PS_PRINTING ld hl, ShowPrinting jp z, Async_Spawn_HL cp a, PS_FULL ld hl, ShowFull jp z, Async_Spawn_HL ld hl, BanishPrinterUI jp Async_Spawn_HL UpdatePrintUIImmediate: ld a, [vPrinterReturnValue] cp a, $81 call z, SummonPrinterUI ld a, [vPrinterReturnValue] cp a, $81 call nz, BanishPrinterUI ret BanishPrinterUI: ld hl, PrinterNotDetected ld de, _SCRN0 + 32*1 + 17 ld b, 2 ld c, 2 call CopyTilesToMap ret ShowErrorUI: ld hl, PrinterError ld de, _SCRN0 + 32*1 + 17 ld b, 2 ld c, 2 call CopyTilesToMap ret ShowPrinting: ld hl, PrinterPrinting ld de, _SCRN0 + 32*1 + 17 ld b, 2 ld c, 2 call CopyTilesToMap ret ShowFull: ld hl, PrinterFull ld de, _SCRN0 + 32*1 + 17 ld b, 2 ld c, 2 call CopyTilesToMap ret SummonPrinterUI: ld hl, PrinterAvailable ld de, _SCRN0 + 32*1 + 17 ld b, 2 ld c, 2 call CopyTilesToMap ret SendPacket: ; a should be the command byte ; hl shoulld point at data to send ; bc should be the length of data ; squashes de for the checksum. push af ld a, $88 call SendByte ld a, $33 call SendByte pop af ld d, 0 ld e, a ; the checksum always starts with a vallue of whatever the command is call SendByte ld a, $00 call SendByte ld a, c call SendByte ld a, b call SendByte ld a, e add a, b ld e, a ld a, d adc a, 0 ld d, a ld a, e add a, c ld e, a ld a, d adc a, 0 ld d, a ld a, b or a, c jp z, .doneWithByteLoop .byteLoop ld a, [hl] add a, e ld e, a ld a, d adc a, 0 ld d, a ld a, [hl+] call SendByte dec bc ld a, b or a, c jp nz, .byteLoop .doneWithByteLoop ld a, e call SendByte ld a, d call SendByte ld a, $00 call SendByte ld [vPrinterReturnValue], a ld a, $00 call SendByte ld [vPrinterReturnValue+1], a call UpdatePrinterStatus ret UpdatePrinterStatus: ;vPrinterState: db ; options: NONE, READY, ERROR, FULL, PRINTING ld a, PS_NONE ld [vPrinterState], a ld a, [vPrinterReturnValue] cp a, $81 ret nz ; if the alive byte isn't $81, return with PS_NONE ld a, PS_ERROR ld [vPrinterState], a ld a, [vPrinterReturnValue+1] and a, $F0 ret nz ; if the top nibble is non-zero, there's some error ld a, PS_FULL ld [vPrinterState], a ld a, [vPrinterReturnValue+1] bit 2, a ret nz ; if the FULL bit iis set then it's full\ ld a, PS_PRINTING ld [vPrinterState], a ld a, [vPrinterReturnValue+1] bit 1, a ret nz ; if the printing bit is set then it's printing ld a, PS_READY ld [vPrinterState], a ret ; if we didn't find any of the bits we check for, it's good to go PrepNetwork: ld a, 0 ld [vPrinterStart], a ld a, $1 ld [rSC], a ret SendByte: ; waits until the thing is free, then sends the byte in a. puts the receiived ; byte in a anad returns. push af .waitForFree ld a, [rSC] bit 7, a jp nz, .waitForFree pop af ld [rSB], a ld a, 0 set 7, a ; request transfer set 0, a ; set to leader ld [rSC], a .waitForResponse ld a, [rSC] bit 7, a jp nz, .waitForResponse ld a, [rSB] ret KickOffPrintJob: ld a, 1 ld [vBlocked], a ld a, 1 ld [vPrinterStart],a ld a, 0 ld [vPrinterRow], a ret RunPrintJob: ld a, [vPrinterStart] cp a, 0 ret z ld a, [vPrinterRow] bit 0, a jp z, WaitForPrintable cp a, 1 jp nz, :+ call PlanTopRow call BuildTopRow call DoubleTheBuffer call PrintTheBuffer ld a, [vPrinterRow] inc a ld [vPrinterRow], a ret : cp a, 35 jp z, DoBottomRow cp a, 37 jp z, FinishUp call PlanRowA call BuildTopRow ld b, 8 ; pre-increment so that when we pre-decrement in the loop later it works sla a sla a sla a ; mullitply by 8 add a, 24 ; offset for the border and overscan add a, b ; start from the bottom row of these tiles, a*8 + 7 .addSpriteLinesLoop dec a ld [vCurrentScanline], a call AddSpritesToLine dec b jp nz, .addSpriteLinesLoop .doneAddSpriteLinesLoop call DoubleTheBuffer call PrintTheBuffer ld a, [vPrinterRow] inc a ld [vPrinterRow], a ret PlanTopRow: ; draw the top of a card as tile ids in buffer one ld hl, CardBrowse.UITilemap ld bc, 10 ld de, BUFFER_ONE call CopyRange ; copy tiles for the top row to the first buffer ld b, b ret PlanRowA: srl a ; divide by two and subtract one to get row numbre in card space dec a push af ld de, BUFFER_ONE ld a, $0b ld [de], a inc de pop af push af call FindCardTileMap ; now hl points at the beginning of the tile map sla a sla a sla a ld b, 0 ld c, a ; need to advance it by a*8 bytes. add hl, bc ld b, 8 : ld a, [hl+] ld [de], a inc de dec b jp nz, :- ld a, $0c ld [de], a pop af ret BuildTopRow: ; assuming buffer one contains a sequence of ten tile IDs ; this writes the tile data for each of those tiles sequentially into BUFFER_TWO push af ld hl, BUFFER_ONE ld de, BUFFER_TWO ld c, 10 .loop push bc ld a, [hl+] ; fetch a tile ID push hl ld hl, UITiles cp a, 26 jp c, :+ ; if the tile id is greater than 26, then we need to fetch from the card data sub a, 26 ; and undo the offset encoded into the tile map call FindCardKeyTiles : call FindTileData ; now hl points to tile data, de points to a spot in buffer 2 ld bc, 16 call CopyRange pop hl pop bc dec c jp nz, .loop ld b, b pop af ret DoubleTheBuffer: ld hl, BUFFER_TWO ld de, BUFFER_ONE ld a, 10 .topHalfLoop push hl push af call WriteTopHalfDoubledTile pop af pop hl ld bc, 16 add hl, bc dec a jp nz, .topHalfLoop ld hl, BUFFER_TWO ld a, 10 .bottomHalfLoop push hl push af ld bc, 8 add hl, bc call WriteTopHalfDoubledTile pop af pop hl ld bc, 16 add hl, bc dec a jp nz, .bottomHalfLoop ld b, b ret PrintTheBuffer: call ClearBuffer ld a, 4 ; fill buffer ld hl, BUFFER_ONE ld bc, $280 call SendPacket call SendEmpty call SendPrint ret WaitForPrintable: ld a, $F ld hl, ZEROES ld bc, 0 call SendPacket ; NONE, READY, ERROR, FULL, PRINTING ld a, [vPrinterState] cp a, PS_PRINTING ret z cp a, PS_ERROR ret z cp a, PS_NONE ret z call ClearBuffer ld a, [vPrinterState] cp a, PS_FULL ret z ld a, [vPrinterRow] inc a ld [vPrinterRow], a ret DoMiddleRow: call ClearBuffer ld a, [vPrinterRow] srl a dec a call SendRowA call SendEmpty call SendPrint ld a, [vPrinterRow] inc a ld [vPrinterRow], a ret DoBottomRow: call ClearBuffer call SendBottomRow call SendPrint ld a, [vPrinterRow] inc a ld [vPrinterRow], a ret FinishUp: call ClearBuffer ld a, 0 ld [vBlocked], a ld [vPrinterStart],a ld [vPrinterRow], a ld a, 1 ld [vPrinterIsReady], a ret SendEmpty: ld a, 4 ld hl, ZEROES ld bc, 0 call SendPacket ret SendBottomRow: ; draw the top of a card ld de, BUFFER_ONE ; top half of border ld a, $11 ld hl, UITiles call FindTileData call WriteTopHalfDoubledTile ld c, 8 .loop push bc ld a, $0d ld hl, UITiles call FindTileData call WriteTopHalfDoubledTile pop bc dec c ld a, 0 or a, c jp nz, .loop ld a, $10 ld hl, UITiles call FindTileData call WriteTopHalfDoubledTile ; bottom half of border ld a, $11 ld hl, UITiles call FindTileData call WriteBottomHalfDoubledTile ld c, 8 .loop2 push bc ld a, $0d ld hl, UITiles call FindTileData call WriteBottomHalfDoubledTile pop bc dec c jp nz, .loop2 ld a, $10 ld hl, UITiles call FindTileData call WriteBottomHalfDoubledTile ld a, 4 ; fill buffer ld hl, BUFFER_ONE ld bc, $280 call SendPacket ret SendTopRow: ; draw the top of a card ld de, BUFFER_ONE ; top half of border ld a, $0e ld hl, UITiles call FindTileData ; give it a=index into some tiles, hl=what to start from call WriteTopHalfDoubledTile ld c, 8 .loop push bc ld a, $0a ld hl, UITiles call FindTileData call WriteTopHalfDoubledTile pop bc dec c ld a, 0 or a, c jp nz, .loop ld a, $0f ld hl, UITiles call FindTileData call WriteTopHalfDoubledTile ; bottom half of border ld a, $0e ld hl, UITiles call FindTileData call WriteBottomHalfDoubledTile ld c, 8 .loop2 push bc ld a, $0a ld hl, UITiles call FindTileData call WriteBottomHalfDoubledTile pop bc dec c jp nz, .loop2 ld a, $0f ld hl, UITiles call FindTileData call WriteBottomHalfDoubledTile ld a, 4 ; fill buffer ld hl, BUFFER_ONE ld bc, $280 call SendPacket ret SendRowA: push af ld de, BUFFER_ONE ; left side border ld a, $0b ld hl, UITiles call FindTileData call WriteTopHalfDoubledTile ; find the row of tile data we're looking for pop af push af ; a might be from 0-16, and we needd to multiply it by 8. that should stay ; within 256 tho so we can just sla three times call FindCardTileMap sla a sla a sla a ld b, 0 ld c, a add hl, bc push hl ; hl now holds the row of the tile map we're interested in. ld c, 8 .loop push bc ld a, [hl+] sub a, 26 ; undo the offset normally encoded into the tile data push hl call FindCardKeyTiles call FindTileData call WriteTopHalfDoubledTile pop hl pop bc dec c jp nz, .loop ; right side border ld a, $0c ld hl, UITiles call FindTileData call WriteTopHalfDoubledTile ld a, $0b ld hl, UITiles call FindTileData call WriteBottomHalfDoubledTile pop hl ld c, 8 .loop2 push bc ld a, [hl+] sub a, 26 ; undo the offset normally encoded into the tile data push hl call FindCardKeyTiles call FindTileData call WriteBottomHalfDoubledTile pop hl pop bc dec c ld a, 0 or a, c jp nz, .loop2 ld a, $0c ld hl, UITiles call FindTileData call WriteBottomHalfDoubledTile pop af ; a holds the row we're on ld b, 8 ; pre-increment so that when we pre-decrement in the loop later it works sla a sla a sla a ; mullitply by 8 add a, 24 ; offset for the border and overscan add a, b ; start from the bottom row of these tiles, a*8 + 7 .addSpriteLinesLoop dec a ld [vCurrentScanline], a call AddSpritesToLine dec b jp nz, .addSpriteLinesLoop .doneAddSpriteLinesLoop ld a, 4 ; fill buffer ld hl, BUFFER_ONE ld bc, $280 call SendPacket ret SendPrint: call SendEmpty ld hl, BUFFER_ONE ld a, 1 ; number of sheets ld [hl+], a ld a, $00 ; margins ld [hl+], a ld a, $e4 ; palette ld [hl+], a ld a, $7f ; exposure ld [hl+], a ld a, 2 ; print ld hl, BUFFER_ONE ld bc, 4 call SendPacket ret ClearBuffer: ld a, $1 ld hl, ZEROES ld bc, 0 call SendPacket ret PrinterTiles: db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 db $00,$1c,$00,$0e,$38,$3f,$64,$7f,$7f,$7f,$7f,$40,$7f,$40,$3f,$3f db $00,$00,$00,$00,$00,$00,$06,$b6,$ff,$ff,$ff,$11,$ff,$11,$fe,$fe db $00,$00,$00,$80,$0e,$8e,$12,$9e,$24,$bc,$38,$b8,$00,$80,$00,$00 db $00,$00,$00,$00,$5a,$5a,$92,$92,$5a,$5a,$52,$52,$9b,$9b,$00,$00 db $00,$00,$18,$98,$18,$98,$18,$98,$18,$98,$00,$80,$18,$98,$00,$00 db $00,$00,$00,$00,$d8,$d8,$94,$94,$d8,$d8,$94,$94,$d2,$d2,$00,$00 db $00,$00,$00,$80,$19,$99,$15,$95,$19,$99,$11,$91,$11,$91,$00,$00 db $00,$00,$00,$00,$92,$92,$5a,$5a,$96,$96,$52,$52,$52,$52,$00,$00 db $00,$00,$00,$80,$1d,$9d,$11,$91,$19,$99,$11,$91,$11,$91,$00,$00 db $00,$00,$00,$00,$52,$52,$52,$52,$52,$52,$52,$52,$db,$db,$00,$00 PrinterTiles.End: ; $22 PrinterNotDetected: db $00, $00 db $13, $00 PrinterAvailable: db $f1, $f2 db $f3, $f4 PrinterPrinting: db $f1, $f2 db $f7, $f8 PrinterError: db $f1, $f2 db $f5, $f6 PrinterFull: db $f1, $f2 db $f9, $fa