![]() |
Routines |
| Prev: 8DCC | Up: Map | Next: 8FD0 |
|
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:
|
||||||||||||||||||||
| PrintHandler | 8DE3 | CP $80 | If the byte is less than 80 jump to PrintHandler_Dispatch. | |||||||||||||||||
| 8DE5 | JR C,PrintHandler_Dispatch | |||||||||||||||||||
| 8DE7 | LD A,$21 | Otherwise replace the byte with 21 ("!"). | ||||||||||||||||||
| 8DE9 | JP PrintHandler_Render | Jump to PrintHandler_Render to render the character. | ||||||||||||||||||
|
Dispatch handler for printing.
|
||||||||||||||||||||
| PrintHandler_Dispatch | 8DEC | CP $20 | If the byte is 20 or higher (printable ASCII), jump to PrintHandler_Render to render it. | |||||||||||||||||
| 8DEE | JP NC,PrintHandler_Render | |||||||||||||||||||
| 8DF1 | CP $0D | If the byte is a carriage return (0D), jump to PrintHandler_Newline. | ||||||||||||||||||
| 8DF3 | JR Z,PrintHandler_Newline | |||||||||||||||||||
| 8DF5 | CP $10 | If the byte is less than 10 jump to PrintHandler_Invalid (unsupported code). | ||||||||||||||||||
| 8DF7 | JR C,PrintHandler_Invalid | |||||||||||||||||||
| 8DF9 | CP $1B | If the byte is 1B or higher, jump to PrintHandler_Invalid (unsupported code). | ||||||||||||||||||
| 8DFB | 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 10 and doubled since each table entry is two bytes wide.
|
||||||||||||||||||||
| 8DFD | LD HL,$8FD0 | HL=ControlCode_DispatchTable (base of the control code dispatch table). | ||||||||||||||||||
| 8E00 | SUB $10 | Zero-index the control code from 10. | ||||||||||||||||||
| 8E02 | LD D,$00 | DE=zero-indexed control code. | ||||||||||||||||||
| 8E04 | LD E,A | |||||||||||||||||||
| 8E05 | ADD HL,DE | Double the index (two bytes per table entry). | ||||||||||||||||||
| 8E06 | ADD HL,DE | |||||||||||||||||||
| 8E07 | LD E,(HL) | Read the handler address from the dispatch table into DE. | ||||||||||||||||||
| 8E08 | INC HL | |||||||||||||||||||
| 8E09 | LD D,(HL) | |||||||||||||||||||
| 8E0A | LD ($800A),DE | Write the handler address to PrintState_Handler. | ||||||||||||||||||
| 8E0E | 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 BC).
|
||||||||||||||||||||
| PrintHandler_Newline | 8E0F | LD HL,$8001 | HL=PrintState_X (X position pointer). | |||||||||||||||||
| 8E12 | LD A,($8005) | A=*PrintState_LeftMargin (left margin X position). | ||||||||||||||||||
| 8E15 | LD (HL),A | Write the left margin value to *HL, resetting X to the left margin. | ||||||||||||||||||
| 8E16 | DEC HL | Decrement HL to point at PrintState_Y (Y position). | ||||||||||||||||||
| PrintHandler_AdvanceRow | 8E17 | LD A,(HL) | A=*HL + font line height (*PrintState_LineHeight). | |||||||||||||||||
| 8E18 | ADD A,(IX+$10) | |||||||||||||||||||
| 8E1B | CP $BC | Wrap the Y position at BC if it has reached or exceeded that value. | ||||||||||||||||||
| 8E1D | JR C,PrintHandler_AdvanceRow_Store | |||||||||||||||||||
| 8E1F | SUB $BC | Subtract BC to wrap Y. | ||||||||||||||||||
| PrintHandler_AdvanceRow_Store | 8E21 | LD (HL),A | Write the new Y position back to *HL. | |||||||||||||||||
| 8E22 | RET | Return. | ||||||||||||||||||
|
Parameter handler for unsupported control codes 14 and 15. Consumes the parameter byte by resetting PrintState_Handler to the default handler, then falls through to PrintHandler_Invalid to print a "?" (3F) placeholder.
|
||||||||||||||||||||
| PrintHandler_Unsupported | 8E23 | LD HL,$8DE3 | Reset PrintState_Handler to PrintHandler (default handler). | |||||||||||||||||
| 8E26 | LD ($800A),HL | |||||||||||||||||||
| PrintHandler_Invalid | 8E29 | LD A,$3F | Replace the byte with 3F ("?"). | |||||||||||||||||
| 8E2B | JP PrintHandler_Render | Jump to PrintHandler_Render to render the character. | ||||||||||||||||||
|
Set INK colour parameter handler. Called on the byte immediately following a 10 (INK) control code. Masks the parameter to the lower three bits (colour 00–07) and writes it into the INK bits (0–2) of the attribute byte at PrintState_Attr.
|
||||||||||||||||||||
| PrintHandler_Ink | 8E2E | LD B,$08 | B=08 (mask limit for INK colour range 00–07). | |||||||||||||||||
| 8E30 | CALL PrintHandler_MaskParam | Call PrintHandler_MaskParam to reset PrintState_Handler and mask B to the colour value. | ||||||||||||||||||
| 8E33 | LD A,($8004) | A=*PrintState_Attr (current attribute byte). | ||||||||||||||||||
| 8E36 | AND %11111000 | Clear the INK bits (F8 = keep PAPER, BRIGHT, FLASH). | ||||||||||||||||||
| 8E38 | OR B | Write the new INK colour into bits 0–2. | ||||||||||||||||||
| 8E39 | LD ($8004),A | Write the updated attribute byte back to *PrintState_Attr. | ||||||||||||||||||
| 8E3C | RET | Return. | ||||||||||||||||||
|
Set PAPER colour parameter handler. Called on the byte immediately following a 11 (PAPER) control code. Masks the parameter to the lower three bits (colour 00–07) and writes it into the PAPER bits (3–5) of the attribute byte at PrintState_Attr.
|
||||||||||||||||||||
| PrintHandler_Paper | 8E3D | LD B,$08 | B=08 (mask limit for PAPER colour range 00–07). | |||||||||||||||||
| 8E3F | CALL PrintHandler_MaskParam | Call PrintHandler_MaskParam to reset PrintState_Handler and mask B to the colour value. | ||||||||||||||||||
| 8E42 | LD A,($8004) | A=*PrintState_Attr (current attribute byte). | ||||||||||||||||||
| 8E45 | AND %11000111 | Clear the PAPER bits (C7 = keep INK, BRIGHT, FLASH). | ||||||||||||||||||
| 8E47 | SLA B | Shift B left three positions to move the colour into bits 3–5. | ||||||||||||||||||
| 8E49 | SLA B | |||||||||||||||||||
| 8E4B | SLA B | |||||||||||||||||||
| 8E4D | OR B | Write the new PAPER colour into bits 3–5. | ||||||||||||||||||
| 8E4E | LD ($8004),A | Write the updated attribute byte back to *PrintState_Attr. | ||||||||||||||||||
| 8E51 | RET | Return. | ||||||||||||||||||
|
Set FLASH parameter handler. Called on the byte immediately following a 12 (FLASH) control code. Sets or clears bit 7 of the attribute byte at PrintState_Attr.
|
||||||||||||||||||||
| PrintHandler_Flash | 8E52 | LD B,$02 | B=02 (mask limit: parameter is 00 or 01). | |||||||||||||||||
| 8E54 | CALL PrintHandler_MaskParam | Call PrintHandler_MaskParam to reset PrintState_Handler and mask B to 00 or 01. | ||||||||||||||||||
| 8E57 | BIT 0,B | Test bit 0 of the masked parameter. | ||||||||||||||||||
| 8E59 | JR Z,PrintHandler_Flash_Off | If the parameter is 00 jump to PrintHandler_Flash_Off to clear FLASH. | ||||||||||||||||||
| 8E5B | SET 7,(IX+$04) | Set the FLASH bit (7) of the attribute byte at PrintState_Attr. | ||||||||||||||||||
| 8E5F | RET | Return. | ||||||||||||||||||
| PrintHandler_Flash_Off | 8E60 | RES 7,(IX+$04) | Clear the FLASH bit (7) of the attribute byte at 8004. | |||||||||||||||||
| 8E64 | RET | Return. | ||||||||||||||||||
|
Set BRIGHT parameter handler. Called on the byte immediately following a 13 (BRIGHT) control code. Sets or clears bit 6 of the attribute byte at 8004.
|
||||||||||||||||||||
| PrintHandler_Bright | 8E65 | LD B,$02 | B=02 (mask limit: parameter is 00 or 01). | |||||||||||||||||
| 8E67 | CALL PrintHandler_MaskParam | Call PrintHandler_MaskParam to reset PrintState_Handler and mask B to 00 or 01. | ||||||||||||||||||
| 8E6A | BIT 0,B | Test bit 0 of the masked parameter. | ||||||||||||||||||
| 8E6C | JR Z,PrintHandler_Bright_Off | If the parameter is 00 jump to PrintHandler_Bright_Off to clear BRIGHT. | ||||||||||||||||||
| 8E6E | SET 6,(IX+$04) | Set the BRIGHT bit (6) of the attribute byte at 8004. | ||||||||||||||||||
| 8E72 | RET | Return. | ||||||||||||||||||
| PrintHandler_Bright_Off | 8E73 | RES 6,(IX+$04) | Clear the BRIGHT bit (6) of the attribute byte at 8004. | |||||||||||||||||
| 8E77 | RET | Return. | ||||||||||||||||||
|
PRINT AT first parameter handler. Called on the byte immediately following a 16 (PRINT AT) control code. Stores the X (column) parameter to 8001 and installs PrintHandler_PrintAt_Y into PrintState_Handler to handle the next byte (the Y position).
|
||||||||||||||||||||
| PrintHandler_PrintAt_X | 8E78 | LD ($8001),A | Write the X column parameter to *PrintState_X. | |||||||||||||||||
| 8E7B | LD HL,$8E82 | HL=PrintHandler_PrintAt_Y (Y position parameter handler). | ||||||||||||||||||
| 8E7E | LD ($800A),HL | Write PrintHandler_PrintAt_Y to PrintState_Handler to consume the next (Y) byte. | ||||||||||||||||||
| 8E81 | RET | Return. | ||||||||||||||||||
|
PRINT AT second parameter handler. Called on the byte immediately following the X parameter. Wraps the Y (row) parameter at BC and stores it to 8000 before restoring the default handler.
|
||||||||||||||||||||
| PrintHandler_PrintAt_Y | 8E82 | LD HL,$8DE3 | Reset PrintState_Handler to PrintHandler (default handler). | |||||||||||||||||
| 8E85 | LD ($800A),HL | |||||||||||||||||||
| 8E88 | CP $BC | If the Y parameter is less than BC jump to PrintHandler_PrintAt_Y_Store. | ||||||||||||||||||
| 8E8A | JR C,PrintHandler_PrintAt_Y_Store | |||||||||||||||||||
| 8E8C | SUB $BC | Subtract BC to wrap the Y position. | ||||||||||||||||||
| PrintHandler_PrintAt_Y_Store | 8E8E | LD ($8000),A | Write the Y position to *PrintState_Y. | |||||||||||||||||
| 8E91 | RET | Return. | ||||||||||||||||||
|
TAB parameter handler. Called on the byte immediately following a 17 (TAB) control code. Sets the X position (8001) 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 | 8E92 | LD HL,$8DE3 | Reset PrintState_Handler to PrintHandler (default handler). | |||||||||||||||||
| 8E95 | LD ($800A),HL | |||||||||||||||||||
| 8E98 | LD C,A | C=target X position (the TAB parameter). | ||||||||||||||||||
| 8E99 | LD A,($8001) | B=*PrintState_X (current X position). | ||||||||||||||||||
| 8E9C | LD B,A | |||||||||||||||||||
| 8E9D | LD A,C | A=target X; write target X to *PrintState_X. | ||||||||||||||||||
| 8E9E | LD ($8001),A | |||||||||||||||||||
| 8EA1 | SUB B | A=target X − current X. | ||||||||||||||||||
| 8EA2 | RET NC | Return if the cursor moved right or stayed (no row advance needed). | ||||||||||||||||||
| 8EA3 | LD HL,$8000 | HL=8000 (Y position pointer). | ||||||||||||||||||
| 8EA6 | CALL PrintHandler_AdvanceRow | Call PrintHandler_AdvanceRow to advance the Y position by one line. | ||||||||||||||||||
| 8EA9 | RET | Return. | ||||||||||||||||||
|
Left margin parameter handler. Called on the byte immediately following a 18 control code. Sets the left margin X position at 8005 to the lower six bits of the parameter.
|
||||||||||||||||||||
| PrintHandler_LeftMargin | 8EAA | LD B,$40 | B=40 (mask limit: lower six bits, 00–3F). | |||||||||||||||||
| 8EAC | CALL PrintHandler_MaskParam | Call PrintHandler_MaskParam to reset PrintState_Handler and mask A to the lower six bits. | ||||||||||||||||||
| 8EAF | LD ($8005),A | Write the masked parameter to *PrintState_LeftMargin (left margin X position). | ||||||||||||||||||
| 8EB2 | RET | Return. | ||||||||||||||||||
|
Right margin parameter handler. Called on the byte immediately following a 19 control code. Stores the right margin X position to 8006. If the parameter is less than 80 a wrap flag is set in 8007 and 80 is OR'd into the value before storing.
|
||||||||||||||||||||
| PrintHandler_RightMargin | 8EB3 | LD HL,$8DE3 | Reset PrintState_Handler to PrintHandler (default handler). | |||||||||||||||||
| 8EB6 | LD ($800A),HL | |||||||||||||||||||
| 8EB9 | CP $80 | If the parameter is 80 or higher, jump to PrintHandler_RightMargin_Store to store it directly. | ||||||||||||||||||
| 8EBB | JR NC,PrintHandler_RightMargin_Store | |||||||||||||||||||
| 8EBD | SET 0,(IX+$07) | Set the wrap flag (bit 0 of *8007). | ||||||||||||||||||
| 8EC1 | OR %10000000 | OR 80 into the parameter. | ||||||||||||||||||
| PrintHandler_RightMargin_Store | 8EC3 | LD ($8006),A | Write the parameter to *PrintState_RightMargin (right margin X position). | |||||||||||||||||
| 8EC6 | RET | Return. | ||||||||||||||||||
|
Select font parameter handler. Called on the byte immediately following a 1A control code. Copies the six-byte font configuration for the selected font index (00–03) from the table at FontConfig_Table into the font state at 800C and loads the font bitmap pointer into 8008.
|
||||||||||||||||||||
| PrintHandler_SelectFont | 8EC7 | LD B,$04 | B=04 (mask limit: font indices 00–03). | |||||||||||||||||
| 8EC9 | CALL PrintHandler_MaskParam | Call PrintHandler_MaskParam to reset PrintState_Handler and mask B to the font index. | ||||||||||||||||||
| 8ECC | LD H,$00 | H=00. | ||||||||||||||||||
| 8ECE | LD L,B | L=B (font index as a 16-bit value in HL). | ||||||||||||||||||
| 8ECF | LD DE,$8FE6 | DE=FontConfig_Table (font configuration table base). | ||||||||||||||||||
|
Multiply the font index by 08 (the size of each font table entry) to compute the byte offset into the font table.
|
||||||||||||||||||||
| 8ED2 | ADD HL,HL | Multiply HL by 08 (three left shifts). | ||||||||||||||||||
| 8ED3 | ADD HL,HL | |||||||||||||||||||
| 8ED4 | ADD HL,HL | |||||||||||||||||||
| 8ED5 | ADD HL,DE | HL=FontConfig_Table + (font index × 08) — pointer to the selected font entry. | ||||||||||||||||||
| 8ED6 | LD DE,$800C | DE=800C (font state destination). | ||||||||||||||||||
| 8ED9 | LD BC,$0006 | BC=06 (six bytes of font configuration to copy). | ||||||||||||||||||
| 8EDC | LDIR | Copy six bytes of font configuration to 800C–8011. | ||||||||||||||||||
| 8EDE | LD E,(HL) | Read the two-byte font bitmap pointer from bytes 07–08 of the entry. | ||||||||||||||||||
| 8EDF | INC HL | |||||||||||||||||||
| 8EE0 | LD D,(HL) | |||||||||||||||||||
| 8EE1 | LD ($8008),DE | Write the font bitmap pointer to *PrintState_FontPtr. | ||||||||||||||||||
| 8EE5 | 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 8007.
|
||||||||||||||||||||
| PrintHandler_MaskParam | 8EE6 | LD HL,$8DE3 | Reset PrintState_Handler to PrintHandler (default handler). | |||||||||||||||||
| 8EE9 | LD ($800A),HL | |||||||||||||||||||
| 8EEC | CP B | Test whether the parameter (A) is within the valid range (B). | ||||||||||||||||||
| 8EED | JR C,PrintHandler_MaskParam_Mask | If the parameter is within range, jump to PrintHandler_MaskParam_Mask. | ||||||||||||||||||
| 8EEF | SET 0,(IX+$07) | Otherwise set the out-of-range flag (bit 0 of *8007). | ||||||||||||||||||
| PrintHandler_MaskParam_Mask | 8EF3 | DEC B | Decrement B to form a bitmask (e.g. 08 → 07 = %00000111). | |||||||||||||||||
| 8EF4 | AND B | Mask A to the valid range. | ||||||||||||||||||
| 8EF5 | LD B,A | B=masked parameter value. | ||||||||||||||||||
| 8EF6 | 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 | 8EF7 | LD ($8003),A | Store the character code to *PrintState_Char. | |||||||||||||||||
|
Select the pixel width for the character. Space (20), "I" (49), "M" (4D) and "W" (57) each have their own width stored in the font state at 800C. All other printable characters use the normal width.
|
||||||||||||||||||||
| 8EFA | CP $20 | If the character is a space (20), jump to PrintHandler_Render_SpaceWidth. | ||||||||||||||||||
| 8EFC | JR Z,PrintHandler_Render_SpaceWidth | |||||||||||||||||||
| 8EFE | CP $49 | If the character is not "I" (49), jump to PrintHandler_Render_WideCheck. | ||||||||||||||||||
| 8F00 | JR NZ,PrintHandler_Render_WideCheck | |||||||||||||||||||
| 8F02 | LD C,(IX+$0D) | C=*PrintState_NarrowWidth (narrow width for "I"). | ||||||||||||||||||
| 8F05 | JR PrintHandler_Render_LineCheck | Jump to PrintHandler_Render_LineCheck. | ||||||||||||||||||
| PrintHandler_Render_SpaceWidth | 8F07 | LD C,(IX+$0F) | C=*PrintState_SpaceWidth (space width). | |||||||||||||||||
| 8F0A | JR PrintHandler_Render_LineCheck | Jump to PrintHandler_Render_LineCheck. | ||||||||||||||||||
|
Check for wide characters: "M" (4D) and "W" (57) use the wide width.
|
||||||||||||||||||||
| PrintHandler_Render_WideCheck | 8F0C | CP $4D | If the character is "M" (4D), jump to PrintHandler_Render_WideWidth. | |||||||||||||||||
| 8F0E | JR Z,PrintHandler_Render_WideWidth | |||||||||||||||||||
| 8F10 | CP $57 | If the character is not "W" (57), jump to PrintHandler_Render_NormalWidth (normal width). | ||||||||||||||||||
| 8F12 | JR NZ,PrintHandler_Render_NormalWidth | |||||||||||||||||||
| PrintHandler_Render_WideWidth | 8F14 | LD C,(IX+$0E) | C=*PrintState_WideWidth (wide width for "M" and "W"). | |||||||||||||||||
| 8F17 | JR PrintHandler_Render_LineCheck | Jump to PrintHandler_Render_LineCheck. | ||||||||||||||||||
|
All other printable characters use the standard (IX+0C) width.
|
||||||||||||||||||||
| PrintHandler_Render_NormalWidth | 8F19 | LD C,(IX+$0C) | 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 8006 a carriage return is inserted automatically before rendering.
|
||||||||||||||||||||
| PrintHandler_Render_LineCheck | 8F1C | LD A,($8001) | B=*PrintState_X (current X position). | |||||||||||||||||
| 8F1F | LD B,A | |||||||||||||||||||
| 8F20 | LD A,($8006) | A=*PrintState_RightMargin (right margin X position). | ||||||||||||||||||
| 8F23 | SUB B | A=right margin − current X − character width. | ||||||||||||||||||
| 8F24 | SUB C | |||||||||||||||||||
| 8F25 | 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).
|
||||||||||||||||||||
| 8F28 | LD A,C | A=character width. | ||||||||||||||||||
| 8F29 | EX AF,AF' | Stash character width in A'. | ||||||||||||||||||
| 8F2A | LD A,($8000) | A=*PrintState_Y (Y pixel position). | ||||||||||||||||||
| 8F2D | LD H,$46 | HL=screen row address LUT entry for pixel row Y (8C00 + Y × 02). | ||||||||||||||||||
| 8F2F | LD L,A | |||||||||||||||||||
| 8F30 | SLA L | |||||||||||||||||||
| 8F32 | RL H | |||||||||||||||||||
| 8F34 | LD A,($8001) | A=*PrintState_X (X pixel position). | ||||||||||||||||||
| 8F37 | AND A | Clear carry; B=00; shift A right three positions with carry into B, deriving the column byte offset (A=X÷8) and sub-byte pixel bits (low 03 bits of X → B). | ||||||||||||||||||
| 8F38 | LD B,$00 | |||||||||||||||||||
| 8F3A | RRA | |||||||||||||||||||
| 8F3B | RR B | |||||||||||||||||||
| 8F3D | RRA | |||||||||||||||||||
| 8F3E | RR B | |||||||||||||||||||
| 8F40 | RRA | |||||||||||||||||||
| 8F41 | RR B | |||||||||||||||||||
| 8F43 | RLC B | Rotate B left three positions to place the sub-byte offset in bits 0–2. | ||||||||||||||||||
| 8F45 | RLC B | |||||||||||||||||||
| 8F47 | RLC B | |||||||||||||||||||
| 8F49 | LD C,A | C=column byte offset (X÷8). | ||||||||||||||||||
| 8F4A | LD A,B | Store the sub-byte pixel shift (X mod 8) to *PrintState_BitShift. | ||||||||||||||||||
| 8F4B | LD ($8002),A | |||||||||||||||||||
| 8F4E | LD DE,$8012 | DE=8012 (screen address workspace). | ||||||||||||||||||
| 8F51 | LD B,(IX+$11) | B=*PrintState_RowCount (number of character pixel rows). | ||||||||||||||||||
| PrintHandler_Render_AddrLoop | 8F54 | LD A,(HL) | Read each two-byte screen row address from the LUT into the workspace at 8012 adding the column byte offset (C) to the first byte of each pair. | |||||||||||||||||
| 8F55 | ADD A,C | |||||||||||||||||||
| 8F56 | LD (DE),A | |||||||||||||||||||
| 8F57 | INC DE | |||||||||||||||||||
| 8F58 | INC HL | |||||||||||||||||||
| 8F59 | LD A,(HL) | |||||||||||||||||||
| 8F5A | LD (DE),A | |||||||||||||||||||
| 8F5B | INC DE | |||||||||||||||||||
| 8F5C | INC HL | |||||||||||||||||||
| 8F5D | 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 08 bytes at font base pointer + (character code × 08).
|
||||||||||||||||||||
| 8F5F | LD A,($8003) | A=*PrintState_Char (character code). | ||||||||||||||||||
| 8F62 | LD H,$00 | HL=character code as a 16-bit value. | ||||||||||||||||||
| 8F64 | LD L,A | |||||||||||||||||||
| 8F65 | LD DE,($8008) | DE=*PrintState_FontPtr (font bitmap base pointer). | ||||||||||||||||||
| 8F69 | ADD HL,HL | HL=font base + (character code × 08). | ||||||||||||||||||
| 8F6A | ADD HL,HL | |||||||||||||||||||
| 8F6B | ADD HL,HL | |||||||||||||||||||
| 8F6C | ADD HL,DE | |||||||||||||||||||
| 8F6D | EX DE,HL | DE=pointer to the character bitmap data. | ||||||||||||||||||
| 8F6E | LD HL,$8022 | HL=8022 (bit-shift workspace). | ||||||||||||||||||
| 8F71 | LD C,(IX+$11) | C=*PrintState_RowCount (number of character pixel rows). | ||||||||||||||||||
| PrintHandler_Render_ShiftLoop | 8F74 | LD A,($8002) | B=*PrintState_BitShift (sub-byte pixel shift count); A=shift count. | |||||||||||||||||
| 8F77 | LD B,A | B=pixel shift count. | ||||||||||||||||||
| 8F78 | LD A,(DE) | Copy one row of font bitmap data from *DE to *HL. | ||||||||||||||||||
| 8F79 | LD (HL),A | |||||||||||||||||||
| 8F7A | XOR A | If the shift count is 00 jump to PrintHandler_Render_ShiftNext (no shift needed). | ||||||||||||||||||
| 8F7B | CP B | |||||||||||||||||||
| 8F7C | JR Z,PrintHandler_Render_ShiftNext | |||||||||||||||||||
| 8F7E | AND A | Clear A (right-hand overflow byte). | ||||||||||||||||||
| PrintHandler_Render_ShiftStep | 8F7F | RR (HL) | Shift *HL right through carry into A, repeating for each shift step. | |||||||||||||||||
| 8F81 | RRA | |||||||||||||||||||
| 8F82 | DJNZ PrintHandler_Render_ShiftStep | |||||||||||||||||||
| PrintHandler_Render_ShiftNext | 8F84 | INC HL | Advance HL to the second byte of the workspace pair. | |||||||||||||||||
| 8F85 | LD (HL),A | Store the shifted overflow byte (right-hand spill) to *HL. | ||||||||||||||||||
| 8F86 | INC HL | Advance HL to the next row pair in the workspace. | ||||||||||||||||||
| 8F87 | INC DE | Advance DE to the next row of font bitmap data. | ||||||||||||||||||
| 8F88 | DEC C | Decrease the row counter. | ||||||||||||||||||
| 8F89 | 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 58 ($5800 base).
|
||||||||||||||||||||
| 8F8B | LD BC,$8022 | BC=8022 (bit-shifted bitmap workspace pointer). | ||||||||||||||||||
| 8F8E | LD HL,$8012 | HL=8012 (screen address workspace pointer). | ||||||||||||||||||
| 8F91 | PUSH HL | Stash HL; read the first screen address pair into DE. | ||||||||||||||||||
| 8F92 | LD E,(HL) | |||||||||||||||||||
| 8F93 | INC HL | |||||||||||||||||||
| 8F94 | LD D,(HL) | |||||||||||||||||||
| 8F95 | DEC HL | Restore HL from the pair. | ||||||||||||||||||
| 8F96 | EX DE,HL | DE=screen pixel row address. | ||||||||||||||||||
| 8F97 | LD A,H | Derive the attribute memory high byte from the pixel address high byte. | ||||||||||||||||||
| 8F98 | RRCA | |||||||||||||||||||
| 8F99 | RRCA | |||||||||||||||||||
| 8F9A | RRCA | |||||||||||||||||||
| 8F9B | AND $03 | |||||||||||||||||||
| 8F9D | OR $58 | H=58 | column third → attribute address high byte. | ||||||||||||||||||
| 8F9F | LD H,A | H=attribute address high byte. | ||||||||||||||||||
| 8FA0 | LD A,($8004) | A=*PrintState_Attr (attribute byte: INK/PAPER/BRIGHT/FLASH). | ||||||||||||||||||
| 8FA3 | LD (HL),A | Write the attribute byte to the two cells at *HL and *(HL+01). | ||||||||||||||||||
| 8FA4 | INC HL | |||||||||||||||||||
| 8FA5 | LD (HL),A | |||||||||||||||||||
| 8FA6 | LD DE,$001F | DE=1F (offset to next attribute row). | ||||||||||||||||||
| 8FA9 | ADD HL,DE | Write the attribute byte to the two cells in the attribute row below. | ||||||||||||||||||
| 8FAA | LD (HL),A | |||||||||||||||||||
| 8FAB | INC HL | |||||||||||||||||||
| 8FAC | LD (HL),A | |||||||||||||||||||
| 8FAD | POP HL | Restore the screen address workspace pointer from the stack. | ||||||||||||||||||
| 8FAE | EXX | Switch to shadow registers; B=*PrintState_RowCount (pixel row count). | ||||||||||||||||||
| 8FAF | LD B,(IX+$11) | |||||||||||||||||||
| PrintHandler_Render_BlitLoop | 8FB2 | EXX | Switch back; DE=next two-byte screen address from 8012+. | |||||||||||||||||
| 8FB3 | LD E,(HL) | |||||||||||||||||||
| 8FB4 | INC HL | |||||||||||||||||||
| 8FB5 | LD D,(HL) | |||||||||||||||||||
| 8FB6 | INC HL | |||||||||||||||||||
| 8FB7 | EX DE,HL | DE=screen pixel row address. | ||||||||||||||||||
| 8FB8 | LD A,(BC) | OR the left bitmap byte from *BC into *DE (left screen byte). | ||||||||||||||||||
| 8FB9 | OR (HL) | |||||||||||||||||||
| 8FBA | LD (HL),A | |||||||||||||||||||
| 8FBB | INC BC | |||||||||||||||||||
| 8FBC | INC HL | Advance HL; OR the right bitmap byte from *BC into *(HL); advance BC. | ||||||||||||||||||
| 8FBD | LD A,(BC) | |||||||||||||||||||
| 8FBE | OR (HL) | |||||||||||||||||||
| 8FBF | LD (HL),A | |||||||||||||||||||
| 8FC0 | INC BC | |||||||||||||||||||
| 8FC1 | EX DE,HL | DE=screen address workspace pointer (restore via EX DE,HL swap). | ||||||||||||||||||
| 8FC2 | EXX | Switch to shadow registers and loop back to PrintHandler_Render_BlitLoop until all pixel rows are blitted to screen memory. | ||||||||||||||||||
| 8FC3 | DJNZ PrintHandler_Render_BlitLoop | |||||||||||||||||||
|
Advance the X position by the character's pixel width and return.
|
||||||||||||||||||||
| 8FC5 | EXX | Switch back to main registers; restore character width from A'. | ||||||||||||||||||
| 8FC6 | EX AF,AF' | |||||||||||||||||||
| 8FC7 | LD C,A | C=character width. | ||||||||||||||||||
| 8FC8 | LD A,($8001) | A=*PrintState_X (current X position). | ||||||||||||||||||
| 8FCB | ADD A,C | A+=character width. | ||||||||||||||||||
| 8FCC | LD ($8001),A | Write the new X position to *PrintState_X. | ||||||||||||||||||
| 8FCF | RET | Return. | ||||||||||||||||||
| Prev: 8DCC | Up: Map | Next: 8FD0 |