Prev: 36582 Up: Map Next: 36816
36599: 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 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 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).
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 lookup table 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 lookup table 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: 36582 Up: Map Next: 36816