Prev: 8EE6 Up: Map Next: 8FD0
8EF7: Print Handler: Render
Used by the routines at PrintHandler and PrintHandler_Unsupported.
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 lookup table (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 lookup table 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 lookup table 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: 8EE6 Up: Map Next: 8FD0