| Routines

02852: THE 'PRINT ANY CHARACTER(S)' SUBROUTINE

Used by the routine at PO_ABLE. Ordinary character codes, token codes and user-defined graphic codes, and graphic codes are dealt with separately.
Input
A | Character code
B | Line number
C | Column number
HL | Display file address or printer buffer address
PO_ANY | 02852 | CP 128 | Jump forward with ordinary character codes.
| 02854 | JR C,PO_CHAR
| 02856 | CP 144 | Jump forward with token codes and UDG codes.
| 02858 | JR NC,PO_T_UDG
| 02860 | LD B,A | Move the graphic code.
| 02861 | CALL PO_GR_1 | Construct the graphic form.
| 02864 | CALL PO_FETCH | HL has been disturbed so 'fetch' again.
| 02867 | LD DE,23698 | Make DE point to the start of the graphic form, i.e. MEMBOT.
| 02870 | JR PR_ALL | Jump forward to print the graphic character.
Graphic characters are constructed in an ad hoc manner in the calculator's memory area, i.e. mem-0 and mem-1.
PO_GR_1 | 02872 | LD HL,23698 | This is MEMBOT.
| 02875 | CALL PO_GR_2 | In effect call the following subroutine twice.
PO_GR_2 | 02878 | RR B | Determine bit 0 (and later bit 2) of the graphic code.
| 02880 | SBC A,A
| 02881 | AND 15 | The A register will hold 0 or 15 depending on the value of the bit in the code.
| 02883 | LD C,A | Save the result in C.
| 02884 | RR B | Determine bit 1 (and later bit 3) of the graphic code.
| 02886 | SBC A,A
| 02887 | AND 240 | The A register will hold 0 or 240.
| 02889 | OR C | The two results are combined.
| 02890 | LD C,4 | The A register holds half the character form and has to be used four times. This is done for the upper half of the character form and then the lower.
PO_GR_3 | 02892 | LD (HL),A
| 02893 | INC HL
| 02894 | DEC C
| 02895 | JR NZ,PO_GR_3
| 02897 | RET
Token codes and user-defined graphic codes are now separated.
PO_T_UDG | 02898 | SUB 165 | Jump forward with token codes.
| 02900 | JR NC,PO_T
| 02902 | ADD A,21 | UDG codes are now 0 to 15.
| 02904 | PUSH BC | Save the current position values on the machine stack.
| 02905 | LD BC,(23675) | Fetch the base address of the UDG area (from UDG) and jump forward.
| 02909 | JR PO_CHAR_2
PO_T | 02911 | CALL PO_TOKENS | Now print the token and return via PO_FETCH.
| 02914 | JP PO_FETCH
This entry point is used by the routine at PO_RIGHT. The required character form is identified.
PO_CHAR | 02917 | PUSH BC | The current position is saved.
| 02918 | LD BC,(23606) | The base address of the character area is fetched (CHARS).
PO_CHAR_2 | 02922 | EX DE,HL | The print address is saved.
| 02923 | LD HL,23611 | This is FLAGS.
| 02926 | RES 0,(HL) | Allow for a leading space.
| 02928 | CP " " | Jump forward if the character is not a 'space'.
| 02930 | JR NZ,PO_CHAR_3
| 02932 | SET 0,(HL) | But 'suppress' if it is.
PO_CHAR_3 | 02934 | LD H,0 | Now pass the character code to the HL register pair.
| 02936 | LD L,A
| 02937 | ADD HL,HL | The character code is in effect multiplied by 8.
| 02938 | ADD HL,HL
| 02939 | ADD HL,HL
| 02940 | ADD HL,BC | The base address of the character form is found.
| 02941 | POP BC | The current position is fetched and the base address passed to the DE register pair.
| 02942 | EX DE,HL
The following subroutine is used to print all '8*8' bit characters. On entry the DE register pair holds the base address of the character form, the HL register the destination address and the BC register pair the current 'line and column' values.
PR_ALL | 02943 | LD A,C | Fetch the column number.
| 02944 | DEC A | Move one column rightwards.
| 02945 | LD A,33 | Jump forward unless a new line is indicated.
| 02947 | JR NZ,PR_ALL_1
| 02949 | DEC B | Move down one line.
| 02950 | LD C,A | Column number is 33.
| 02951 | BIT 1,(IY+1) | Jump forward if handling the screen (bit 1 of FLAGS reset).
| 02955 | JR Z,PR_ALL_1
| 02957 | PUSH DE | Save the base address whilst the printer buffer is emptied.
| 02958 | CALL COPY_BUFF
| 02961 | POP DE
| 02962 | LD A,C | Copy the new column number.
PR_ALL_1 | 02963 | CP C | Test whether a new line is being used. If it is see if the display requires to be scrolled.
| 02964 | PUSH DE
| 02965 | CALL Z,PO_SCR
| 02968 | POP DE
Now consider the present state of INVERSE and OVER.
| 02969 | PUSH BC | Save the position values and the destination address on the machine stack.
| 02970 | PUSH HL
| 02971 | LD A,(23697) | Fetch P-FLAG and read bit 0.
| 02974 | LD B,255 | Prepare the 'OVER mask' in the B register, i.e. OVER 0=0 and OVER 1=255.
| 02976 | RRA
| 02977 | JR C,PR_ALL_2
| 02979 | INC B
PR_ALL_2 | 02980 | RRA | Read bit 2 of P-FLAG and prepare the 'INVERSE mask' in the C register, i.e. INVERSE 0=0 and INVERSE 1=255.
| 02981 | RRA
| 02982 | SBC A,A
| 02983 | LD C,A
| 02984 | LD A,8 | Set the A register to hold the 'pixel-line' counter and clear the carry flag.
| 02986 | AND A
| 02987 | BIT 1,(IY+1) | Jump forward if handling the screen (bit 1 of FLAGS reset).
| 02991 | JR Z,PR_ALL_3
| 02993 | SET 1,(IY+48) | Signal 'printer buffer no longer empty' (set bit 1 of FLAGS2).
| 02997 | SCF | Set the carry flag to show that the printer is being used.
PR_ALL_3 | 02998 | EX DE,HL | Exchange the destination address with the base address before entering the loop.
The character can now be printed. Eight passes of the loop are made - one for each 'pixel-line'.
PR_ALL_4 | 02999 | EX AF,AF' | The carry flag is set when using the printer. Save this flag in F'.
| 03000 | LD A,(DE) | Fetch the existing 'pixel-line'.
| 03001 | AND B | Use the 'OVER mask' and then 'XOR' the result with the 'pixel-line' of the character form.
| 03002 | XOR (HL)
| 03003 | XOR C | Finally consider the 'INVERSE mask'.
| 03004 | LD (DE),A | Enter the result.
| 03005 | EX AF,AF' | Fetch the printer flag and jump forward if required.
| 03006 | JR C,PR_ALL_6
| 03008 | INC D | Update the destination address.
PR_ALL_5 | 03009 | INC HL | Update the 'pixel-line' address of the character form.
| 03010 | DEC A | Decrease the counter and loop back unless it is zero.
| 03011 | JR NZ,PR_ALL_4
Once the character has been printed the attribute byte is to be set as required.
| 03013 | EX DE,HL | Make the H register hold a correct high-address for the character area.
| 03014 | DEC H
| 03015 | BIT 1,(IY+1) | Set the attribute byte only if handling the screen (bit 1 of FLAGS reset).
| 03019 | CALL Z,PO_ATTR
| 03022 | POP HL | Restore the original destination address and the position values.
| 03023 | POP BC
| 03024 | DEC C | Decrease the column number and increase the destination address before returning.
| 03025 | INC HL
| 03026 | RET
When the printer is being used the destination address has to be updated in increments of 32.
PR_ALL_6 | 03027 | EX AF,AF' | Save the printer flag again.
| 03028 | LD A,32 | The required increment value.
| 03030 | ADD A,E | Add the value and pass the result back to the E register.
| 03031 | LD E,A
| 03032 | EX AF,AF' | Fetch the flag.
| 03033 | JR PR_ALL_5 | Jump back into the loop.