Prev: 36300 Up: Map Next: 36816
36323: Print Handler
The default print handler for the state machine pointer at PrintState_Handler. Called on initialisation, and restored after each byte is consumed. Dispatches each byte of a messaging string to the appropriate action based on its value:
Byte Action
32–127 Print the ASCII character.
128–255 Replace with 33 ("!") and print.
13 Carriage return: reset X to left margin, advance Y by one line.
16–26 Control code: install a parameter handler into PrintState_Handler.
All others Replace with 63 ("?") and print.
Input
A Byte to print or control code
PrintHandler 36323 CP 128 If the byte is less than 128 jump to PrintHandler_Dispatch.
36325 JR C,PrintHandler_Dispatch
36327 LD A,33 Otherwise replace the byte with 33 ("!").
36329 JP PrintHandler_Render Jump to PrintHandler_Render to render the character.
Dispatch handler for printing.
PrintHandler_Dispatch 36332 CP 32 If the byte is 32 or higher (printable ASCII), jump to PrintHandler_Render to render it.
36334 JP NC,PrintHandler_Render
36337 CP 13 If the byte is a carriage return (13), jump to PrintHandler_Newline.
36339 JR Z,PrintHandler_Newline
36341 CP 16 If the byte is less than 16 jump to PrintHandler_Invalid (unsupported code).
36343 JR C,PrintHandler_Invalid
36345 CP 27 If the byte is 27 or higher, jump to PrintHandler_Invalid (unsupported code).
36347 JR NC,PrintHandler_Invalid
Look up the two-byte handler address from the control code dispatch table at ControlCode_DispatchTable. The code is zero-indexed from 16 and doubled since each table entry is two bytes wide.
36349 LD HL,36816 HL=ControlCode_DispatchTable (base of the control code dispatch table).
36352 SUB 16 Zero-index the control code from 16.
36354 LD D,0 DE=zero-indexed control code.
36356 LD E,A
36357 ADD HL,DE Double the index (two bytes per table entry).
36358 ADD HL,DE
36359 LD E,(HL) Read the handler address from the dispatch table into DE.
36360 INC HL
36361 LD D,(HL)
36362 LD (32778),DE Write the handler address to PrintState_Handler.
36366 RET Return.
Carriage return handler: resets the X position to the left margin, then advances the Y position by one font line height (wrapping at 188).
PrintHandler_Newline 36367 LD HL,32769 HL=PrintState_X (X position pointer).
36370 LD A,(32773) A=*PrintState_LeftMargin (left margin X position).
36373 LD (HL),A Write the left margin value to *HL, resetting X to the left margin.
36374 DEC HL Decrement HL to point at PrintState_Y (Y position).
PrintHandler_AdvanceRow 36375 LD A,(HL) A=*HL + font line height (*PrintState_LineHeight).
36376 ADD A,(IX+16)
36379 CP 188 Wrap the Y position at 188 if it has reached or exceeded that value.
36381 JR C,PrintHandler_AdvanceRow_Store
36383 SUB 188 Subtract 188 to wrap Y.
PrintHandler_AdvanceRow_Store 36385 LD (HL),A Write the new Y position back to *HL.
36386 RET Return.
Parameter handler for unsupported control codes 20 and 21. Consumes the parameter byte by resetting PrintState_Handler to the default handler, then falls through to PrintHandler_Invalid to print a "?" (63) placeholder.
PrintHandler_Unsupported 36387 LD HL,36323 Reset PrintState_Handler to PrintHandler (default handler).
36390 LD (32778),HL
PrintHandler_Invalid 36393 LD A,63 Replace the byte with 63 ("?").
36395 JP PrintHandler_Render Jump to PrintHandler_Render to render the character.
Set INK colour parameter handler. Called on the byte immediately following a 16 (INK) control code. Masks the parameter to the lower three bits (colour 0–7) and writes it into the INK bits (0–2) of the attribute byte at PrintState_Attr.
PrintHandler_Ink 36398 LD B,8 B=8 (mask limit for INK colour range 0–7).
36400 CALL PrintHandler_MaskParam Call PrintHandler_MaskParam to reset PrintState_Handler and mask B to the colour value.
36403 LD A,(32772) A=*PrintState_Attr (current attribute byte).
36406 AND %11111000 Clear the INK bits (248 = keep PAPER, BRIGHT, FLASH).
36408 OR B Write the new INK colour into bits 0–2.
36409 LD (32772),A Write the updated attribute byte back to *PrintState_Attr.
36412 RET Return.
Set PAPER colour parameter handler. Called on the byte immediately following a 17 (PAPER) control code. Masks the parameter to the lower three bits (colour 0–7) and writes it into the PAPER bits (3–5) of the attribute byte at PrintState_Attr.
PrintHandler_Paper 36413 LD B,8 B=8 (mask limit for PAPER colour range 0–7).
36415 CALL PrintHandler_MaskParam Call PrintHandler_MaskParam to reset PrintState_Handler and mask B to the colour value.
36418 LD A,(32772) A=*PrintState_Attr (current attribute byte).
36421 AND %11000111 Clear the PAPER bits (199 = keep INK, BRIGHT, FLASH).
36423 SLA B Shift B left three positions to move the colour into bits 3–5.
36425 SLA B
36427 SLA B
36429 OR B Write the new PAPER colour into bits 3–5.
36430 LD (32772),A Write the updated attribute byte back to *PrintState_Attr.
36433 RET Return.
Set FLASH parameter handler. Called on the byte immediately following a 18 (FLASH) control code. Sets or clears bit 7 of the attribute byte at PrintState_Attr.
PrintHandler_Flash 36434 LD B,2 B=2 (mask limit: parameter is 0 or 1).
36436 CALL PrintHandler_MaskParam Call PrintHandler_MaskParam to reset PrintState_Handler and mask B to 0 or 1.
36439 BIT 0,B Test bit 0 of the masked parameter.
36441 JR Z,PrintHandler_Flash_Off If the parameter is 0 jump to PrintHandler_Flash_Off to clear FLASH.
36443 SET 7,(IX+4) Set the FLASH bit (7) of the attribute byte at PrintState_Attr.
36447 RET Return.
PrintHandler_Flash_Off 36448 RES 7,(IX+4) Clear the FLASH bit (7) of the attribute byte at 32772.
36452 RET Return.
Set BRIGHT parameter handler. Called on the byte immediately following a 19 (BRIGHT) control code. Sets or clears bit 6 of the attribute byte at 32772.
PrintHandler_Bright 36453 LD B,2 B=2 (mask limit: parameter is 0 or 1).
36455 CALL PrintHandler_MaskParam Call PrintHandler_MaskParam to reset PrintState_Handler and mask B to 0 or 1.
36458 BIT 0,B Test bit 0 of the masked parameter.
36460 JR Z,PrintHandler_Bright_Off If the parameter is 0 jump to PrintHandler_Bright_Off to clear BRIGHT.
36462 SET 6,(IX+4) Set the BRIGHT bit (6) of the attribute byte at 32772.
36466 RET Return.
PrintHandler_Bright_Off 36467 RES 6,(IX+4) Clear the BRIGHT bit (6) of the attribute byte at 32772.
36471 RET Return.
PRINT AT first parameter handler. Called on the byte immediately following a 22 (PRINT AT) control code. Stores the X (column) parameter to 32769 and installs PrintHandler_PrintAt_Y into PrintState_Handler to handle the next byte (the Y position).
PrintHandler_PrintAt_X 36472 LD (32769),A Write the X column parameter to *PrintState_X.
36475 LD HL,36482 HL=PrintHandler_PrintAt_Y (Y position parameter handler).
36478 LD (32778),HL Write PrintHandler_PrintAt_Y to PrintState_Handler to consume the next (Y) byte.
36481 RET Return.
PRINT AT second parameter handler. Called on the byte immediately following the X parameter. Wraps the Y (row) parameter at 188 and stores it to 32768 before restoring the default handler.
PrintHandler_PrintAt_Y 36482 LD HL,36323 Reset PrintState_Handler to PrintHandler (default handler).
36485 LD (32778),HL
36488 CP 188 If the Y parameter is less than 188 jump to PrintHandler_PrintAt_Y_Store.
36490 JR C,PrintHandler_PrintAt_Y_Store
36492 SUB 188 Subtract 188 to wrap the Y position.
PrintHandler_PrintAt_Y_Store 36494 LD (32768),A Write the Y position to *PrintState_Y.
36497 RET Return.
TAB parameter handler. Called on the byte immediately following a 23 (TAB) control code. Sets the X position (32769) to the parameter value. If the parameter is less than the current X position (i.e., the cursor would move left), the Y position advances to the next row.
PrintHandler_Tab 36498 LD HL,36323 Reset PrintState_Handler to PrintHandler (default handler).
36501 LD (32778),HL
36504 LD C,A C=target X position (the TAB parameter).
36505 LD A,(32769) B=*PrintState_X (current X position).
36508 LD B,A
36509 LD A,C A=target X; write target X to *PrintState_X.
36510 LD (32769),A
36513 SUB B A=target X − current X.
36514 RET NC Return if the cursor moved right or stayed (no row advance needed).
36515 LD HL,32768 HL=32768 (Y position pointer).
36518 CALL PrintHandler_AdvanceRow Call PrintHandler_AdvanceRow to advance the Y position by one line.
36521 RET Return.
Left margin parameter handler. Called on the byte immediately following a 24 control code. Sets the left margin X position at 32773 to the lower six bits of the parameter.
PrintHandler_LeftMargin 36522 LD B,64 B=64 (mask limit: lower six bits, 0–63).
36524 CALL PrintHandler_MaskParam Call PrintHandler_MaskParam to reset PrintState_Handler and mask A to the lower six bits.
36527 LD (32773),A Write the masked parameter to *PrintState_LeftMargin (left margin X position).
36530 RET Return.
Right margin parameter handler. Called on the byte immediately following a 25 control code. Stores the right margin X position to 32774. If the parameter is less than 128 a wrap flag is set in 32775 and 128 is OR'd into the value before storing.
PrintHandler_RightMargin 36531 LD HL,36323 Reset PrintState_Handler to PrintHandler (default handler).
36534 LD (32778),HL
36537 CP 128 If the parameter is 128 or higher, jump to PrintHandler_RightMargin_Store to store it directly.
36539 JR NC,PrintHandler_RightMargin_Store
36541 SET 0,(IX+7) Set the wrap flag (bit 0 of *32775).
36545 OR %10000000 OR 128 into the parameter.
PrintHandler_RightMargin_Store 36547 LD (32774),A Write the parameter to *PrintState_RightMargin (right margin X position).
36550 RET Return.
Select font parameter handler. Called on the byte immediately following a 26 control code. Copies the six-byte font configuration for the selected font index (0–3) from the table at FontConfig_Table into the font state at 32780 and loads the font bitmap pointer into 32776.
PrintHandler_SelectFont 36551 LD B,4 B=4 (mask limit: font indices 0–3).
36553 CALL PrintHandler_MaskParam Call PrintHandler_MaskParam to reset PrintState_Handler and mask B to the font index.
36556 LD H,0 H=0.
36558 LD L,B L=B (font index as a 16-bit value in HL).
36559 LD DE,36838 DE=FontConfig_Table (font configuration table base).
Multiply the font index by 8 (the size of each font table entry) to compute the byte offset into the font table.
36562 ADD HL,HL Multiply HL by 8 (three left shifts).
36563 ADD HL,HL
36564 ADD HL,HL
36565 ADD HL,DE HL=FontConfig_Table + (font index × 8) — pointer to the selected font entry.
36566 LD DE,32780 DE=32780 (font state destination).
36569 LD BC,6 BC=6 (six bytes of font configuration to copy).
36572 LDIR Copy six bytes of font configuration to 32780–32785.
36574 LD E,(HL) Read the two-byte font bitmap pointer from bytes 7–8 of the entry.
36575 INC HL
36576 LD D,(HL)
36577 LD (32776),DE Write the font bitmap pointer to *PrintState_FontPtr.
36581 RET Return.
Parameter mask and validation utility. Called by control code parameter handlers before processing their byte. Resets PrintState_Handler to the default handler (PrintHandler), then masks A to the valid range defined by B (which must be a power of two). If the parameter is out of range, sets a flag in 32775.
PrintHandler_MaskParam 36582 LD HL,36323 Reset PrintState_Handler to PrintHandler (default handler).
36585 LD (32778),HL
36588 CP B Test whether the parameter (A) is within the valid range (B).
36589 JR C,PrintHandler_MaskParam_Mask If the parameter is within range, jump to PrintHandler_MaskParam_Mask.
36591 SET 0,(IX+7) Otherwise set the out-of-range flag (bit 0 of *32775).
PrintHandler_MaskParam_Mask 36595 DEC B Decrement B to form a bitmask (e.g. 8 → 7 = %00000111).
36596 AND B Mask A to the valid range.
36597 LD B,A B=masked parameter value.
36598 RET Return.
Character renderer. Determines the pixel width of the character, checks whether it fits on the current line (inserting a carriage return if not), computes the screen address from the current X and Y pixel positions, bit-shifts the character bitmap from the font table, ORs it into screen memory row by row, writes the attribute byte to the attribute area, and finally advances the X position.
PrintHandler_Render 36599 LD (32771),A Store the character code to *PrintState_Char.
Select the pixel width for the character. Space (32), "I" (73), "M" (77) and "W" (87) each have their own width stored in the font state at 32780. All other printable characters use the normal width.
36602 CP 32 If the character is a space (32), jump to PrintHandler_Render_SpaceWidth.
36604 JR Z,PrintHandler_Render_SpaceWidth
36606 CP 73 If the character is not "I" (73), jump to PrintHandler_Render_WideCheck.
36608 JR NZ,PrintHandler_Render_WideCheck
36610 LD C,(IX+13) C=*PrintState_NarrowWidth (narrow width for "I").
36613 JR PrintHandler_Render_LineCheck Jump to PrintHandler_Render_LineCheck.
PrintHandler_Render_SpaceWidth 36615 LD C,(IX+15) C=*PrintState_SpaceWidth (space width).
36618 JR PrintHandler_Render_LineCheck Jump to PrintHandler_Render_LineCheck.
Check for wide characters: "M" (77) and "W" (87) use the wide width.
PrintHandler_Render_WideCheck 36620 CP 77 If the character is "M" (77), jump to PrintHandler_Render_WideWidth.
36622 JR Z,PrintHandler_Render_WideWidth
36624 CP 87 If the character is not "W" (87), jump to PrintHandler_Render_NormalWidth (normal width).
36626 JR NZ,PrintHandler_Render_NormalWidth
PrintHandler_Render_WideWidth 36628 LD C,(IX+14) C=*PrintState_WideWidth (wide width for "M" and "W").
36631 JR PrintHandler_Render_LineCheck Jump to PrintHandler_Render_LineCheck.
All other printable characters use the standard (IX+12) width.
PrintHandler_Render_NormalWidth 36633 LD C,(IX+12) C=*PrintState_Width (normal character width).
Check whether the character fits within the right margin. If adding the character width to the current X position would exceed the right margin stored at 32774 a carriage return is inserted automatically before rendering.
PrintHandler_Render_LineCheck 36636 LD A,(32769) B=*PrintState_X (current X position).
36639 LD B,A
36640 LD A,(32774) A=*PrintState_RightMargin (right margin X position).
36643 SUB B A=right margin − current X − character width.
36644 SUB C
36645 CALL C,PrintHandler_Newline Call PrintHandler_Newline if the result is negative (character exceeds the right margin).
Calculate the screen address and sub-byte bit-shift from the current X and Y pixel positions. The screen row address LUT (indexed by Y) provides the base pixel row address; three right-shifts of X derive the column byte offset and the within-byte pixel shift (0–7 bits).
36648 LD A,C A=character width.
36649 EX AF,AF' Stash character width in A'.
36650 LD A,(32768) A=*PrintState_Y (Y pixel position).
36653 LD H,70 HL=screen row address LUT entry for pixel row Y (35840 + Y × 2).
36655 LD L,A
36656 SLA L
36658 RL H
36660 LD A,(32769) A=*PrintState_X (X pixel position).
36663 AND A Clear carry; B=0; shift A right three positions with carry into B, deriving the column byte offset (A=X÷8) and sub-byte pixel bits (low 3 bits of X → B).
36664 LD B,0
36666 RRA
36667 RR B
36669 RRA
36670 RR B
36672 RRA
36673 RR B
36675 RLC B Rotate B left three positions to place the sub-byte offset in bits 0–2.
36677 RLC B
36679 RLC B
36681 LD C,A C=column byte offset (X÷8).
36682 LD A,B Store the sub-byte pixel shift (X mod 8) to *PrintState_BitShift.
36683 LD (32770),A
36686 LD DE,32786 DE=32786 (screen address workspace).
36689 LD B,(IX+17) B=*PrintState_RowCount (number of character pixel rows).
PrintHandler_Render_AddrLoop 36692 LD A,(HL) Read each two-byte screen row address from the LUT into the workspace at 32786 adding the column byte offset (C) to the first byte of each pair.
36693 ADD A,C
36694 LD (DE),A
36695 INC DE
36696 INC HL
36697 LD A,(HL)
36698 LD (DE),A
36699 INC DE
36700 INC HL
36701 DJNZ PrintHandler_Render_AddrLoop Decrease the row counter and loop back to PrintHandler_Render_AddrLoop until all rows are done.
Look up the character bitmap in the font table. Each character occupies 8 bytes at font base pointer + (character code × 8).
36703 LD A,(32771) A=*PrintState_Char (character code).
36706 LD H,0 HL=character code as a 16-bit value.
36708 LD L,A
36709 LD DE,(32776) DE=*PrintState_FontPtr (font bitmap base pointer).
36713 ADD HL,HL HL=font base + (character code × 8).
36714 ADD HL,HL
36715 ADD HL,HL
36716 ADD HL,DE
36717 EX DE,HL DE=pointer to the character bitmap data.
36718 LD HL,32802 HL=32802 (bit-shift workspace).
36721 LD C,(IX+17) C=*PrintState_RowCount (number of character pixel rows).
PrintHandler_Render_ShiftLoop 36724 LD A,(32770) B=*PrintState_BitShift (sub-byte pixel shift count); A=shift count.
36727 LD B,A B=pixel shift count.
36728 LD A,(DE) Copy one row of font bitmap data from *DE to *HL.
36729 LD (HL),A
36730 XOR A If the shift count is 0 jump to PrintHandler_Render_ShiftNext (no shift needed).
36731 CP B
36732 JR Z,PrintHandler_Render_ShiftNext
36734 AND A Clear A (right-hand overflow byte).
PrintHandler_Render_ShiftStep 36735 RR (HL) Shift *HL right through carry into A, repeating for each shift step.
36737 RRA
36738 DJNZ PrintHandler_Render_ShiftStep
PrintHandler_Render_ShiftNext 36740 INC HL Advance HL to the second byte of the workspace pair.
36741 LD (HL),A Store the shifted overflow byte (right-hand spill) to *HL.
36742 INC HL Advance HL to the next row pair in the workspace.
36743 INC DE Advance DE to the next row of font bitmap data.
36744 DEC C Decrease the row counter.
36745 JR NZ,PrintHandler_Render_ShiftLoop Loop back to PrintHandler_Render_ShiftLoop until all rows have been bit-shifted.
Write the attribute byte to the four attribute cells covering the character. Derives the attribute address from the screen pixel address high byte by rotating right three times, masking to two bits, and OR-ing with 88 ($5800 base).
36747 LD BC,32802 BC=32802 (bit-shifted bitmap workspace pointer).
36750 LD HL,32786 HL=32786 (screen address workspace pointer).
36753 PUSH HL Stash HL; read the first screen address pair into DE.
36754 LD E,(HL)
36755 INC HL
36756 LD D,(HL)
36757 DEC HL Restore HL from the pair.
36758 EX DE,HL DE=screen pixel row address.
36759 LD A,H Derive the attribute memory high byte from the pixel address high byte.
36760 RRCA
36761 RRCA
36762 RRCA
36763 AND 3
36765 OR 88 H=88 | column third → attribute address high byte.
36767 LD H,A H=attribute address high byte.
36768 LD A,(32772) A=*PrintState_Attr (attribute byte: INK/PAPER/BRIGHT/FLASH).
36771 LD (HL),A Write the attribute byte to the two cells at *HL and *(HL+1).
36772 INC HL
36773 LD (HL),A
36774 LD DE,31 DE=31 (offset to next attribute row).
36777 ADD HL,DE Write the attribute byte to the two cells in the attribute row below.
36778 LD (HL),A
36779 INC HL
36780 LD (HL),A
36781 POP HL Restore the screen address workspace pointer from the stack.
36782 EXX Switch to shadow registers; B=*PrintState_RowCount (pixel row count).
36783 LD B,(IX+17)
PrintHandler_Render_BlitLoop 36786 EXX Switch back; DE=next two-byte screen address from 32786+.
36787 LD E,(HL)
36788 INC HL
36789 LD D,(HL)
36790 INC HL
36791 EX DE,HL DE=screen pixel row address.
36792 LD A,(BC) OR the left bitmap byte from *BC into *DE (left screen byte).
36793 OR (HL)
36794 LD (HL),A
36795 INC BC
36796 INC HL Advance HL; OR the right bitmap byte from *BC into *(HL); advance BC.
36797 LD A,(BC)
36798 OR (HL)
36799 LD (HL),A
36800 INC BC
36801 EX DE,HL DE=screen address workspace pointer (restore via EX DE,HL swap).
36802 EXX Switch to shadow registers and loop back to PrintHandler_Render_BlitLoop until all pixel rows are blitted to screen memory.
36803 DJNZ PrintHandler_Render_BlitLoop
Advance the X position by the character's pixel width and return.
36805 EXX Switch back to main registers; restore character width from A'.
36806 EX AF,AF'
36807 LD C,A C=character width.
36808 LD A,(32769) A=*PrintState_X (current X position).
36811 ADD A,C A+=character width.
36812 LD (32769),A Write the new X position to *PrintState_X.
36815 RET Return.
Prev: 36300 Up: Map Next: 36816