gb-tarot/Printing.inc
2025-04-25 20:24:12 -04:00

758 lines
13 KiB
PHP

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