First line of characters: (00) (01) (02) (1F) (4000) 00000000 00000000 00000000 ... 00000000 (401F) (4100) 00000000 00000000 00000000 ... 00000000 (411F) (4200) 00000000 00000000 00000000 ... 00000000 (421F) (4300) 00000000 00000000 00000000 ... 00000000 (431F) (4400) 00000000 00000000 00000000 ... 00000000 (441F) (4500) 00000000 00000000 00000000 ... 00000000 (451F) (4600) 00000000 00000000 00000000 ... 00000000 (461F) (4700) 00000000 00000000 00000000 ... 00000000 (471F) Second line of characters: (00) (01) (02) (1F) (4020) 00000000 00000000 00000000 ... 00000000 (403F) (4120) 00000000 00000000 00000000 ... 00000000 (413F) etc, to (4720) 00000000 00000000 00000000 ... 00000000 (473F) Third line: Fourth line: Fifth line: (4040) ... (405F) (4060) ... (407F) (4080) ... (409F) (4140) ... (415F) (4160) ... (417F) (4180) ... (419F) to to to (4740) ... (475F) (4760) ... (477F) (4780) ... (479F) Sixth line: Seventh line: (40A0) ... (40BF) (40C0) ... (40DF) (41A0) ... (41BF) (41C0) ... (41DF) to to (47A0) ... (47BF) (47C0) ... (47DF) Eighth line: (E0) (E1) (E2) (FF) (40E0) 00000000 00000000 00000000 ... 00000000 (40FF) (41E0) 00000000 00000000 00000000 ... 00000000 (41FF) (42E0) 00000000 00000000 00000000 ... 00000000 (42FF) (43E0) 00000000 00000000 00000000 ... 00000000 (43FF) (44E0) 00000000 00000000 00000000 ... 00000000 (44FF) (45E0) 00000000 00000000 00000000 ... 00000000 (45FF) (46E0) 00000000 00000000 00000000 ... 00000000 (46FF) (47E0) 00000000 00000000 00000000 ... 00000000 (47FF) The second and last thirds are similarly organized, withall the addresses increased by 800h and 1000h respectively. Try the command: FOR f=16384 TO 22527: POKE f,PIXELS: NEXT f with various values in PIXELS: BIN 10101010/170d, BIN 11001100/204d and BIN 11110000/240d are obvious ones to start with. This will probably help you to get a grip on the above explanation. 2. There are at least three_coordinate_systems for locations on the screen. The two used in BASIC are the_AT/TAB_coordinates, in which character lines are numbered from zero at the top of the screen to 23d at the bottom, and columns or tabs from zero on the left-hand edge to 31d at the right the_pixel_coordinates, numbered from zero at the bottom of the screen to 176d at the top and from zero on the left to 255 on the right, as for BASIC PLOT commands. But in ROM the_print_position_coordinates or_position _values are more often used for character coordinates; in these the character_line_numbers are from one at the bottom of the screen to 18h/24d at the top, and the_column_numbers from one atthe end of the line to 20h/32d at the beginning. There are two complications: 2.1. Of the 18h/24d print lines on the screen, normally 16h/22d lines are used as the_upper_part, where program listingsand most program outputs are displayed, and two lines as the _lower_part where the editing or INPUT display appears; the top line of the lower part is always left blank, so there is effectively only one. But this_lower_screen is automatically expanded if more lines are needed; see scrolling. The upper and lower screen have their_print_lines numbered separately, in both cases starting from 18h at the top:so after a CLS the upper screen lines run from 18h/24d down to 03, the lower screen from 18h/24d to 17h/23d. 2.2. The print position held in system variables is always the last position printed: to print a new position the column number is decremented, and if it reaches zero a new line is started. When a new line is started, the column number put inthe system variables is 21h/33d. Column number zero is never stored. Position values and AT/TAB coordinates both give positions for_character_areas of eight pixel bytes each, which are not consecutive bytes in the display area. 3. The same output routine 09F4 PRINT OUT is used to print on all parts of the screen, and on the ZX printer; it is the output routine of all the standard channels except channel "R". However, when the channel is selected, various flags areadjusted by 1615 CHAN FLAG, including TV FLAG bit zero which is set for channel K to print to the lower part of the screen, cleared for channel S to print to the upper part. So all keyboard input (channel K) appears first in the lower screen. You can print in the lower screen from BASIC or m/c by selecting streams zero or one, or in the upper by selecting stream two, by PRINT #0 and PRINT #2, or from m/c by a call to 1601 CHAN OPEN with zero, one or two in the A register. 4. Three current position values and two display area addresses are stored at all times in system variables, and updated by 0ADC PO STORE each time the position value changes: 5C88 S POSN holds the position value in the upper screen 5C8A S POSNL holds the one in the lower screen 5C7F P POSN holds the column number only of the position in the print buffer, not of course a screen address; this is a one-byte sv 5C84 DF CC holds the display area address corresponding to the first byte of the upper screen print position 5C86 DF CCL holds the display area address corresponding to the lower screen print position Other system variables holding position information are: 5C82 ECHO E is a back-up for the lower screen position values, used to restore it after the flashing "?" error cursor has been printed. 5C7D COORDS holds the PLOT coordinates of the last point PLOTted or DRAWn on screen. 5C6B DF SZ holds the number of print lines currently being used in the lower screen; this is also the position value line number of the blank top line of the lower screen. 5C8D ATTR P holds the attributes to be used in printing the next character in the upper screen; in the lower screen the colours in 5C48 BORDCR are used. See colours. Introduction output may be to upper or lower screen 06A0 SA SCR$ display + attributes are 1B00 bytes 0767 LD LOOK H display filename on screen 09F4 PRINT OUT output may be to upper or lower screen 0A23 PO BACK 1 manipulates position values: mistake 0A38 PO BACK 2 col no 21h for start of line 0A4F PO ENTER down a line, test for 'scroll?' 0A5F PO COMMA manipulates column number 0A87 PO CONT coordinates of AT become position values 0AAC PO AT ERR lower screen may need scrolling for AT 0AC3 PO FILL figure no of spaces to TAB 0ADC PO STORE loads svs for upper screen 0AF0 PO ST E loads svs for lower screen 0B03 PO FETCH position values got from svs 0B52 PO T&UDG position values stacked 0B65 PO CHAR "character area", read "character set" 0B76 PO CHAR 3 position values unstacked 0B7F PR ALL "destination address" means address of the pixel byte in the display area, "line & column values" means position values 0B93 PO ALL 1 scrolling may be required after down move 0BA4 PR ALL 2 "pixel line" here means "pixel byte"; prints eight for each character 0BB7 PR ALL 4 display address on 100h for each pixel 0BC1 PR ALL 5 position values and display address incremented after each print 0BDB PO ATTR converts display address to attribute 0C55 PO SCR test if print position requires scroll 0C88 PO SCR 2 lower to be cleared after keystroke 0CD2 PO SCR 3 scrolling display area is complex 0CF0 PO SCR 3A gets last line of upper screen 0D02 PO SCR 4 handles scrolling of lower screen 0D1C PO SCR 4A handles scrolling of lower screen 0D2D PO SCR 4B signals "using lower screen" 0D4D TEMPS permanent colours for upper screen in ATTR P, for lower in BORDCR 0D5B TEMPS 1 different handling of P FLAG 0D6B CLS lower screen reformed after clearing screen 0D6D CLS clears whole screen and resets lower to 2 lines 0D6E CLS LOWER clears lower screen 0D8E CLS 3 set lower screen at two lines 0DA0 CL CHAN A lower print line set at 17h/23d 0DAF CL ALL 24d lines cleared, start posn value is 1821h 0DD9 CL SET finds line number in lower screen from line number on screen 0DEE CL SET 1 gets line start address from position value 0DF4 CL SET 2 adds current TAB for display address 0DFE CL SC ALL count of lines to be scrolled 0E00 CL SCROLL prepare to scroll eight pixel lines 0E05 CL SCR 1 checks for scrolling across thirds 0E0D CL SCR 2 moving across thirds boundaries 0E19 CL SCR 3 scrolling within thirds 0E44 CL LINE bottom B lines cleared 0E4A CL LINE 1 clear eight pixel line 0E4D CL LINE 2 loop to clear pixel row of a whole third; uses BORDCR for lower screen attributes 0E80 CL LINE 3 line start position is column 21h 0E88 CL ATTR converts display to attribute address 0E9B CL ADDR finds start address of Bth line from bottom 0EAC COPY all pixel bytes sent to printer 0EB2 COPY 1 complex loop; sends 20h bytes to printer for each pixel line, jumping correctly to next line and to next third when necessary 0EC9 COPY 2 counts 176 pixel lines 0ECD COPY BUFF eight pixel lines sent to printer 0ED3 COPY 3 counts eight pixel lines 0EF4 COPY LINE sends one line of 20h pixels to printer 10A8 KEY INPUT print edit line to screen with new cursor and clear lower screen if required 111D ED COPY copy edit or input line to lower screen 1150 ED BLANK overwrite surplus of old line with spaces 117C ED DONE edit or INPUT line copied to lower screen 117E ED C END old position values saved in ECHO E 1219 RAM SET clear and set screen with copyright message 12A2 MAIN EXEC make lower display 2 lines 12CF MAIN 3 on direct command, clear lower screen and upper if appropriate 1313 MAIN G clear lower screen 15D4 WAIT KEY screen clearing signal on entry 1634 CHAN K signal "using lower screen" 1795 AUTO LIST clear both parts of screen 1CBE CLASS 09 set flag for main screen 1EAC CLEAR clears display 1EB7 CLEAR 1 calls 0D6B CLS to clear display 2089 INPUT embedded print items in lower screen 2096 INPUT 1 resets upper print position if lower screen was expanded 20AD INPUT 2 restore flag to "main screen" 2161 IN VAR 4 input line displayed and ECHO E used 22AA PIXEL ADD finds display address of pixel bit from PLOT coordinates (Ath bit of (HL)) 22CB POINT SUB checks if a pixel is INK or PAPER 22DC PLOT plots pixel at given coordinates 22E5 PLOT SUB sets counter to find pixel bit 22F0 PLOT LOOP makes pixel zero at given address 22FD PL TST IN pixel zero or one depending on INVERSE 2535 S SCRN$ S find character code given AT/TAB address 254F S SCRN$ LP screen pixel byte matched with char form 255D S SC ROWS checks seven more pixel bytes with form 2580 S ATTR S find attribute code given AT/TAB address 361F str$ work space is output to as if screen division subroutine 31AF see also precision Called frequently in ROM from 0028 FP CALC with the literal 05; not otherwise called from ROM. Can be called direct from m/c. Executes the "M/N" operator; divides the last value N onthe calculator stack into the second last M. This calculator subroutine doesn't itself use the calculator. Consideration of the structure of FP numbers suggests that division or multiplication is really rather simpler than addition or subtraction; see 335B CALCULATE. Essentially what isrequired is - divide the mantissa of M by the mantissa of N - subtract the exponent of N from the exponent of M. We are of course talking "true mantissas" and "true exponents" here: FP numbers as stored have their sign indicated by zeroing the hi bit of the true mantissa for positive numbers,and the true exponent incremented by 80h. The actual division of the mantissas, call them M' and N', is done by repeated subtraction, analogous to the schoolbooklong division algorithm, what the notes call_restoring_division.Long division is simpler in binary arithmetic than in decimals: take N' from M' if there is carry, it "doesn't go", so add it back, put azero on the result, shift N' right and subtract again; if there is no carry, put a one on the result, shift N' right and subtract again. Like long division, the algorithm isn't self-terminatingunless N' divides M' exactly or N' is a power of two; you can goon with a "recurring binary fraction" as long as you like, with ever-increasing apparent precision in the result. But it isn't worth going on to more precision than you had in the first place. The mantissas are 32-digit binary numbers, so the 33rd digit of the result is significant. The 34th digit is also significant if N' is greater than M'; for both M' and N' are between half and one, so the result mantissa has one leading zero in this case, which will be shifted out of its hi bit when it is normalized, with the 33rd put in the lo bit. Then the 34thshould be used to round the 33rd. So the subtracting loop is turned 33d times, putting 32ddigits in the result mantissa and the 33rd in the carry flag on the stack; then it is turned a 34th time, without altering the digits in the result mantissa, but putting the 34th digit on thestack on top of the 33rd. [However, there is an error in COUNT ONE, where the programmer made a jump back to DIV START when he should have jumped to DIV 34TH instead; so the right shift of N' doesn't getdone on this last subtraction, and the 34th bit always comes outzero even when it should be one. Thus in practice the ROM only gives 33-digit precision even though it is at pains to provide 34 digits. The effect of the error isn't often seen, but if you type PRINT 10**8 * (0.1 - 1/10) you will find the answer comes out as one, which is wrong - it should be zero.] The only serious complication is that even after the exponents have been put on the machine stack out of the way, thirteen bytes have to be handled simultaneously: four each for the mantissas of M, N and M/N, plus a loop counter. However, thelong division can just be handled by repeated subtraction of D'E'DE from H'L'HL, with the result going into B'C'CA and the counter in B; A' isn't used! The rest is just careful checking to reject overflow results, make sure the precision of the result is neither inadequate or redundant, and "normalize" the result, ie adjust its sign bit and exponent to standard FP number format and make its mantissa come out between a half and one. Input parameters: HL points to the first byte of M, DE tothe first of N; they must be FP numbers consecutive in RAM, N after M. For a call through the calculator they must be the two last values on the calculator stack, but for a direct call they could be located anywhere in RAM; not in the ROM, because the position at HL is overwritten with the result. Action: call 3293 RE ST TWO to reformat M and N in full FP format; it reformats them at any position, not necessarily onthe stack - make a zero sign byte; its hi bit will be set for a negative result - call 30C0 PREP M/D to check and modify N: if N is negative, it makes the sign flag negative, and it sets the hi bit of the mantissa to make the true mantissa N' - if N is zero report "Number too big"; can't divide by zero - call PREP M/D again with M: if M is negative, it changes the sign flag again, and it makes the true mantissa M' - if M is zero, return: the result is zero, and the deletion of N from the stack will be automatic on arrival at 3365 RE ENTRY - stack the "return address" pointer in HL' and the pointers to M and N; all the two-byte registers are going to be needed