Rems: 0D6E CLS LOWER copied from BORDCR 1646 CHAN S 1 set on exit through 0D4D TEMPS 2258 CO TEMP B altered on colour change augend see addend auto Abbreviation used in this index to mean "contains a jumpback to the same routine" AUTO LIST subroutine 1795 see also TV FLAG bit 4 Produces an_automatic_listing, with the_current_line on screen, ie the line with the > cursor. Calling this routine has exactly the same effect as the LIST command, except that LIST sets the current line number to zero. Try RANDOMIZE USR 6037. The routine first calculates a suitable line number fromwhich to start the listing, which is kept in 5C6C S TOP. The actual listing is performed by a call to 1835 LIST ALL from 17EDAUTO L 4. With the "auto listing" flag set this will keep on listing and scrolling without any "scroll?" prompt till the current line is on screen, so the line number in S TOP needn't be calculated precisely provided it isn't too high. The routine uses the current line number for S TOP provided it is before the line number already in S TOP, otherwise moves S TOP on to the line number of each following line till it finds one whose start is less than 02C0h/704d bytesabove the start address of the current line. There are 704d bytes in the 22d screen lines of one full screen display; some of them will be tokens, requiring more bytes, but there will also be spaces at the ends of the lines, requiring less. If scrolling is required, it is performed by 0CD2 PO SCR 3 in 0C55 PO SCR, called by 0B93 PR ALL 1 in 0B7F PR ALL, the exit from 0B65 PO CHAR and 0B24 PO ANY, which is called by 0AD9 PO ABLE, which is called by 09F4 PRINT OUT, the channel output routine of 0010 PRINT A 1, called by 1835 LIST ALL, in the house that Jack built. The test whether scrolling is required is made by PO SCR3 itself, before the character has been printed on screen; but the test includes a check of 5C67 BREG, which is one till the current line has been printed on screen. If BREG is zero, the current line has been printed, and a return from AUTO LIST is required. But the test is made in a sub-sub-sub-sub-sub-subroutine, nested six deep! This situation is handled by saving the stack pointer in a system variable 5C3FLIST SP at the start of AUTO LIST, before any of the subroutine calls is made, and retrieving it for the return from PO SCR 3. [The subroutine call at 17ED AUTO L 4 is to the address 1833, the LD E,01 one line before the line labelled LIST ALL in "ROM Disassembled"; this line really ought to have a label of its own. The looping jump within the section LIST ALL is correctly shown as returning to 1835 LIST ALL.] Input parameters: none. Action: save the stack pointer in 5C3F LIST SP - flag "auto list" in TV FLAG bit 4 and zero its other bits - call 0DAF CL ALL to clear the upper screen; zero in TVFLAG bit zero flags for upper screen - set TV FLAG bit zero; lower screen now - get the value from 5C6B DF SZ; the number of lines in the lower screen - call 0E44 CL LINE to clear this many lines in the lower screen - flag "upper screen" again in TV FLAG bit zero and "screen clear" in FLAGX bit zero - if the current line number in 5C49 E PPC is less than the screen start line number in 5C6C S TOP, jump on to AUTO L 2 - (the current line is beyond the screen start line) call 196E LINE ADDR to get the address of the start of the current line - subtract it from 02C0h/704d to get a test value for the new screen start - call 196E LINE ADDR again to get the address of the start of the S TOP line. _17CE_AUTO_L_1: call 19B8 NEXT ONE to get the start address of the next line; the provisional screen start - add the test value: it is 2C0 minus the current start,so the addition gives 2C0 - (current start - screen start) and there will be carry if this is_positive - if there is carry jump on to AUTO L 3; the current line start is less than 704 bytes further down than the provisional screen start - (the provisional screen start is too high) put its line number in S TOP and loop back to AUTO L 1 to move it on oneline. _17E1_AUTO_L_2 (the current line is above the screen start): put the current line number in S TOP. _17E4_AUTO_L_3 (either way, S TOP now holds the line number from which to start the listing): call 196E LINE ADDR to make sure the starting line number is the number of an actual line; use the next actual line start if not, LINE ADDR returns it in DE. _17ED_AUTO_L_4: call 1833 LIST ALL [see note above] to print the listing; if scrolling is necessary it will scroll tillthe current line is on screen, without any "scroll?" prompt, andreturn using the 5C3F LIST SP stack pointer when scrolling is complete; with one bound Jack was free, the return is right out of the AUTO LIST subroutine - (no scrolling was needed) flag "screen not cleared" inTV FLAG bit 4. Exit: RET, from 17ED AUTO L 4 - or via the sextuple return to the 5C3F LIST SP address. Output parameters: none. Called from: 106E ED LIST 12A2 MAIN EXEC Rems: 1386 MAIN 9 no listing till requested AUTO L 1 17CE (1795 AUTO LIST) Jumps from: auto AUTO L 2 17E1 (1795 AUTO LIST) Jumps from: 1795 AUTO LIST AUTO L 3 17E4 (1795 AUTO LIST) Jumps from: 17CE AUTO L 1 AUTO L 4 17ED (1795 AUTO LIST) Exit from: 1795 AUTO LIST 17E4 AUTO L 3 automatic line number, automatic listing see TV FLAG bit 4 ----- backspace see CURSOR LEFT, 1007 ED LEFT base address of channel, etc see channel, etc BASIC INTERPRETER see also commands, functions and operators, 1B8A LINE RUN, 24FB SCANNING "ROM Disassembled" isn't very helpful in explaining how the ROM actually performs the commands, etc, in a BASIC program.What happens is this: The main execution loop is entered at 12A9 MAIN 1 in 12A2 MAIN EXEC after the start-up routines finish. MAIN EXEC isn't a subroutine - it has no RET, indeed there is no return address on the stack for it to return to - but the "beginning" of ROM operation which calls all the subroutines. It extends to 15AB MAIN ADD 2, which loops back to MAIN EXEC if there has beenno loop back already. There is therefore no exit and no output parameters. All routes through the ROM return one way or another to 1303 MAIN 4, even for example NEW, though in this case most of the system is reset first. The loop sequence is: - call 1795 AUTO LIST to give a listing, then 0F2C EDITOR to prompt an input of BASIC, then 1B17 LINE SCAN to check the syntax of the line just input, by a "dummy run" with the syntax checking flag set; EDITOR doesn't check syntax, the only errors it reports are "Outof memory" and "Out of screen". Until LINE SCAN is called there is still no RET address on the stack, and nothing PUSHed, so thereturn address from this call to LINE SCAN is the bottom addresson the machine stack, and is at the stack position to which the error stack pointer 5C3D ERR SP was pointed by 1219 RAM SET. So not only does LINE SCAN itself return to here in the normal course of events, but most REPORT calls through 0008 ERROR 1 return here as well; if the error report isn't FF "OK", execution returns to MAIN 2, the EDITOR is called again to show the input line with an error cursor - if it is a program line, with line number, add it to the program (155D MAIN ADD) and make a listing - if it is a direct command, with no line number, executeit by a call to 1B8A LINE RUN, misprinted PROG RUN in the listing. See under LINE RUN for a description of the way it works the BASIC commands and functions - if the command contains a RUN or GO TO command, continue execution still within the LINE RUN loop; but now 1BB3 LINE END will loop on into following numbered BASIC lines till the end of the program is reached. When LINE RUN is called thereis again no RET address on the stack, and nothing PUSHed, so thereturn address from this call to LINE RUN, address 1303 MAIN 4, is now the "error address" - on return to the main loop, print an error report, which may be "OK", and loop back to wait for another input. _Action: _12A2_MAIN_EXEC (the loop re-entry point from MAIN 3 or MAIN ADD2 after a line has been put in the program): put 2 in 5C6B DF SZ; set the lower screen to two lines, one blank and onefor input - call 1795 AUTO LIST for an automatic listing. _12A9_MAIN_1 (the entry point on start-up): call 16B0 SETMIN to clear the editing area, work space and calculator stack. _12AC_MAIN_2 (the entry point after a command has been executed and the error report printed): call 1601 CHAN OPEN withstream zero to open channel K for keyboard input - call 0F2C EDITOR, which handles the typing in of a BASIC line, with or without line number, in the lower screen; execution doesn't return from the EDITOR loop till you press ENTER - call 1B17 LINE SCAN to check the syntax of the line just input - check the hi bit of 5C3A ERR NR; the only error numberwhich has its hi bit set is FF "OK" - if there is no error jump on to MAIN 3 - (there is an error) check bit 4 of FLAGS2 - if it is zero jump on to MAIN 4; input is coming from some peripheral, not from the keyboard - get the start address of the error line from 5C59 E LINE - call 11A7 REMOVE FP to take the FP number forms out ofthe line; see under "number marker" - put FF in 5C3A ERR NR; errors aren't reported till runtime - loop back to MAIN 2; this time, when EDITOR prints outthe edit line there will be an error address in 5C5F X PTR whichwill produce a flashing "?" as an error cursor. _12CF_MAIN_3 (no error in input line) put a pointer in 5C5D CH ADD from 5C59 E LINE; the start of the line just input - call 19FB E LINE NO to see if it has a line number - it returns zero if it doesn't find one - if there is one jump on to MAIN ADD - (no line number) if the edit line is just a newline jump back to MAIN EXEC, without an error report - (the edit line is a BASIC command, without line number) check bit zero of FLAGS2; zero if the screen is cleared - clear the upper screen if it needs it, and the lower screen anyway - set the scroll counter 5C5C SCR CT at 19h less the current print position line number; see DISPLAY AREA. If a scroll is called for this will put the current print position atthe top of the screen - set the "run" flag FLAGS bit 7 - put the "OK" message number in 5C3A ERR NR - set the statement counter 5C44 NSPPC to one - call 1B8A LINE RUN (misprinted PROG RUN) to execute the un-numbered BASIC command. _1303_MAIN_4 [the HALT at the start of MAIN 4 is a littlemysterious; it doesn't enable the interrupt, as the notes might imply. I think its purpose is to allow one more call to the maskable interrupt after execution is complete, making sure thatthe lower screen flags and system variables are ready to print the error report]: zero bit 5 of FLAGS "waiting for a key" - if bit 1 of FLAGS2 is set call 0ECD COPY BUFF to clearit; "something in the printer buffer" - increment the error number; "OK" will go to zero, "1" -> "9" to one -> 9, and the lettered reports A -> R will go to 0A -> 1B. _1313_MAIN_G (this entry point is used by REPORT G): zero5C71 FLAGX; "editing mode" in bit 5 - zero 5C55 X PTR; no error cursor - zero 5C0B DEFADD; not using DEF FN variables - make sure the keyboard stream zero has the right channel offset - call 16B0 SET MIN to clear the editing area, work space and calculator stack - zero bit 5 of FLAGX; again! an error - call 0D6E CLS LOWER to clear the lower screen - set bit 5 of TV FLAG; "lower screen needs clearing" - adjust the report code, if it is report A to R, so that the correct letter will be printed by OUT CODE, which adds 30h/48d. _133C_MAIN_5: call 15EF OUT CODE to print the report code - call 0010 PRINT A 1 to print a space - call 0C0A PO MSG to print the report message - and again to print "comma space" - call 1A1B OUT NUM 1 to print the line number - call 0010 PRINT A 1 to print a comma - call 1A1B OUT NUM 1 to print the statement number; seven calls to four different subroutines to print a one-line message! But m/c printing on screen often involves such complexities - call 1097 CLEAR SP to clear the editing area; surely redundant after the call to SET MIN in MAIN G - if the error number is FF "OK" jump on to MAIN 9 - if it was 08 "STOP" jump on to MAIN 6 - if it was_not 14 "BREAK" jump on to MAIN 7. _1373_MAIN_6 (STOP or BREAK): increment the statement number in 5C67 SUBPPC, so that CONTINUE will resume execution from the next statement; all interruptions_except STOP and BREAKresume from the statement where they stopped, which presumably contained an error. _1376_MAIN_7: make a byte counter three - make end pointers for copying from 5C44 NSPPC to 5C70 OSPCC; this will copy 5C42 NEWPPC lo -> 5C6E OLDPPC lo 5C43 NEWPPC hi -> 5C6F OLDPPC hi 5C44 NSPPC -> 5C70 OSPCC - check the hi bit of NSPPC - if it is zero jump on to MAIN 8; there is a statement number in the lo bit of NSPPC, indicating a jump to NEWPPC/ NSPPC, since NSPPC hi will be FF unless the last command called for a jump - add three to the 5C44 NSPPC pointer; now the copying will be from the current line/statement OLDPPC/OSPCC: 5C45 PPC lo -> 5C6E OLDPPC lo 5C46 PPC hi -> 5C6F OLDPPC hi 5C47 SUBPPC -> 5C70 OSPCC [I don't know why OSPCC ends -PCC when all the others end -PPC, but it is the same in all Spectrum literature.] _1384_MAIN_8: copy the three bytes. _138C_MAIN_9: load FF into NSPPC; "no jump" - zero bit 3 of FLAGS; "K mode" - zero bit 3 of FLAGS; "K mode" - jump back to MAIN 2. _1391 [Here the report messages are interpolated - see "tables" in this index.] _155D_MAIN_ADD (jump to here from MAIN 3 if the editing input had a line number; the edit line has passed syntax, has a newline at the end, and has had its FP number forms inserted, but