2A12 SV RPT C 2A2C SV ELEM$ 2A52 SLICING (twice) 2A81 SL SECOND 2C2E D NO LOOP 2CDA NXT DGT 1 35DE val Exit from: 2734 S LOOP GET FROM MEMORY AREA SUBROUTINE see 340F get-mem GET HL*DE subroutine 2AF4 Multiplies together the contents of two registers, with an error report "Out of memory" for overflow. One would expect a report "Number too big"; but the subroutine is only used in the ROM when arrays are being set up in the variables area, and "Out of memory" explains the error better in the circumstances. Cf 30A9 HL=HL*DE, which merely sets a flag for overflow. Input parameters: values in HL and DE. Action: if syntax is being checked return at once - otherwise call 30A9 HL=HL*DE - if the carry flag is set report "Out of memory". Exit: RET. Output parameters: HL holds the result of the multiplication - A is corrupted, others unchanged. Called from: 29FB SV MULT 2A22 SV NUMBER 2A2C SV ELEM$ 2C2E D NO LOOP Rems: 30A9 HL=HL*DE called by get-mem subroutine 340F see also 342D st-mem Retrieves a FP number from the calculator memory. Called from 0028 FP CALC with literals E0 to E5, depending on the memory location to be found; mem-0 is found by get-mem-0, literal E0, and so on. Can be called direct from m/c, though this isn't done inthe ROM. Also: 1. The number from memory is always placed on the calculator stack in ROM calls, but this isn't necessary in direct calls. 2. Literals E6 to FF could be used, even through FP CALC, to address up to 20h/32d memory locations; but the memory must be relocated before doing this by putting a new address in 5C68 MEM, or the values read will overlap the last system variables. If the subroutine is called direct with the location number in A, up to 33h/51d memory locations could be used; more would confuse 3406 LOC MEM. Input parameters: A holds the memory location number - DE the address to which the number is to be copied; inROM, this is always the address in 5C65 STKEND, so that the number is added to the calculator stack. Action (the coding is line for line the same as st-mem, except that it leaves out some EX DE,HLs which reverse the direction of copying): call 3406 LOC MEM with a memory pointer from 5C68 MEM to find the first byte of the selected memory location - call 33C0 MOVE FP to copy the FP number from the A'th memory location addressed by the memory pointer to the designated address. Exit: RET. Output parameters: the number in the memory location is still there, but is now copied to the chosen destination - HL holds the address of the first byte of this destination - DE that of the next address after its last byte; return to the calculator will put this in 5C65 STKEND. Called from: 0427 BE OCTAVE (twice) 1D16 F REORDER 1DAB NEXT (twice) 1DDA NEXT LOOP (3 times) 233B C R GRE 1 235A C ARC GE1 (3 times) 23A3 DR SIN NZ (4 times) 23C1 DR PRMS (16 times) 2425 ARC LOOP (7 times) 2439 ARC START (4 times) 247D CD PRMS1 2497 DRAW SAVE 2CDA NXT DGT 1 2D60 E LOOP 2D6E E FETCH 2E01 PF LOOP 2E24 PF SMALL (twice) 2ECB PF MORE 3453 G LOOP (twice) 36A0 n-mod-m (3 times) 36B7 X NEG 36C4 EXP 37AA cos Rems: 342D st-mem much the same with pointers exchanged GET PARAM 1B55 (18BA LINE RUN) Stacks return addresses to 1B52 SCAN LOOP and a commmandclass routine; although apparently an exit routine it is merely a mechanism for taking a turn through the statement loop. Exit from: 1B29 STMT L 1 1B52 SCAN LOOP G LOOP 3453 (3449 series-06) Jumps from: auto G mode (graphics mode) see 5C41 MODE GO NC MLT 30A5 (303E FULL ADDN) Jumps from: 307C TEST NEG GO SUB key (ED) see also commands, functions and operators, KEYBOARD SCANNING The H key in K mode produces the command GO SUB, which must be followed by a numeric expression. It produces a jump in BASIC execution to the line number given by the expression and stores the next statement number so execution can jump back to it when RETURN is reached. The command is read by 1B29 STMT L 1 referring through the syntax offset table 1A48 to the syntax parameter table 1A7A.1A86 P GO SUB makes a jump via 1C82 CLASS 06 to get the line number and 1C16 JUMP C R to the executive routine 1EED GO SUB. GO SUB subroutine 1EED see also GO SUB stack Called only from the statement loop by 1A86 P GO SUB in the syntax parameter table; executes the GO SUB command. 1. Prepares for RETURN, by putting three bytes on the GO SUB stack: the current line number and the statement number incremented by one. If there is no statement corresponding to this number return will be to the following line. These numbers are subsequently read by 1F23 RETURN. 2. Prepares to jump to the BASIC subroutine line, by putting the line number from the GO SUB command in 5C42 NEWPPC and a zero statement number in 5C44 NSPPC; these will be read onreturn to 1B76 STMT RET for the next turn of the statement loop. 3. Makes a precautionary check of the memory available by exiting to 1F05 TEST ROOM with a counter specifying an allowanceof 14h/20d bytes. Together with the standard 50h/80d allowance made by TEST ROOM this makes 64h/100d bytes, which seems rather generous considering only three have been added to the stack. Input parameters: none - the GO SUB line number expression has been evaluated and is on the calculator stack - the machine stack has been cleared down to the error address and the return address 1B76 STMT RET. Action: unstack the STMT RET address - get the current statement number from 5C47 SUBPPC and increment it; RETURN will be to the statement after the GO SUB - take the error address off the stack and put this statement number on the machine stack in the hi byte; ie in the upper of the two positions just occupied by the error address - move the stack pointer up one place; the lo byte of the number just stacked is immaterial and can be overwritten - get the current line number from 5C45 PPC and stack it - restack the error address - put this stack pointer in 5C3D ERR SP; the error stackpointer - restack the STMT RET address - call 1E67 GO TO (misprinted GO TO 1), which gets the GO SUB line number from the calculator stack and loads it and a zero statement number in 5C42 NEWPPC and 5C44 NSPPC - make a counter of 14h/20d. Exit: into 1F05 TEST ROOM, which reports an error unless there are 64h/100d bytes of memory available. Output parameters: BC holds the byte counter. GO SUB stack As all machine code programmers know, the machine stack is an area of memory extending_upwards in address numbers from the stack pointer address held in the SP register; its bytes areusually taken in pairs, eg - POP commands read the byte at SP as lo byte and the next above it as hi byte into the chosen register, and move SP up two places - RET jumps to the lo-hi address in SP and SP + 1 and moves SP up two places - and so on. The machine stack is_upside_down: the "number at the topof the stack" is the one with the_lowest address, and the size of the stack is_reduced by INC SP, increased by DEC SP. For the Spectrum ROM there are effectively two machine stacks, both upside down, one on top of the other: - the normal machine stack for m/c CALL/RETs and PUSH/ POPs - and the GO SUB stack for BASIC GOSUB/RETURNs underneathit separated by the "error address", see under 5C3D ERR SP. The calculator stack, see CALCULATE, is at a different location, andis the "right way up". At start-up 1219 RAM SET sets the two stacks up like this, assuming a 48K Spectrum and no Microdrive maps: (top of memory) P RAMT FFFF (168d bytes of UDG forms) ... UDG FF59 RAMTOP FF58 3E ERR SP FF57 00 <-- stack pointer on FF57 FF56 00 00 FF54 00 00 : 00 00 : 00 00 ... (many bytes) STKEND/STKBOT 5CE2 (empty calculator stack) There is no calculator stack, and the bottom of the machine stack is placed at the address in 5CB2 RAMTOP, where there is an address 3E00; the reason for this address will be explained shortly - and see 1F23 RETURN. As the machine stack builds up, its top marked by the stack pointer moves downwards towards the address in 5C65 STKEND; initially this is an enormous distance of empty addresses, around 9A00h/39424d bytes, but it gets filled up fromthe bottom by the BASIC program, variables, the calculator stack, etc, and from the top by the machine stack and GO SUB stack. After a few nested GO SUBs have been called from BASIC, and a few nested CALLs to ROM subroutines are in operation, the double stack might look like this: (top of memory) RAMTOP FF58 3E 00 FF56 SS HH LL (stmt/line number for RETURN 1) FF53 SS HH LL (stmt/line number for RETURN 2) FF50 SS HH LL (stmt/line number for RETURN 3) FF4D 13 ERR SP 03 (MAIN 4) FF4B 1B 76 (STMT RET) FF49 HH LL (PUSH 1) FF47 HH LL (PUSH 2) FF45 HH LL (RET 2) FF43 HH LL (PUSH 3) FF41 HH LL (RET 3) FF3F HH LL (RET 4) <-- stack pointer on FF40 : 00 00 (somewhere above 5CE2, address held in 5C65 STKEND) STKEND ???? XX XX XX XX XX (FP numbers on the calculator ???? XX XX XX XX XX stack) : STKBOT ???? The addresses look the "wrong way round", because the RAM is being displayed upside down. Everything read from it should be read from the lowest address first. The lower part from the address in 5C3D ERR SP to the address in 5CB2 RAMTOP is the GO SUB stack, the upper part from the stack pointer to the address in 5C3D ERR SP is the machine stack. The address in 5C3D ERR SP is the current error address,the address to which execution jumps if an error is detected. When it is needed, the stack pointer is given the value in 5C3D ERR SP, usually by 0053 ERROR 2, and the next RET after 16C5 SETSTK then jumps to the error address. The error address is normally 1303 MAIN 4, where the error reports are printed. If 5C3D ERR SP holds this stack address, resetting the stack pointer to the address in it clears the machine stack to the bottom. No system variable points to the start of the GO SUB stack. Both the GO SUB and the RETURN subroutines are arranged to operate when the machine stack has been cleared down to the 1B76 STMT RET and the error addresses, so both these routines simply pick off the two addresses and read the GO SUB stack below. The GO SUB stack is loaded and read_three bytes at a time: the first byte put on is the statement number within the line to which return will be made from GO SUB, the next two are the line number. At the bottom of the GO SUB stack there is the_end _marker_of_the_GO_SUB_stack, the number 3E00 put there by 1219 RAM SET; this is at the address in 5CB2 RAMTOP. It isn't a possible RETURN address from a BASIC subroutine (it would be line number 15872d) and if it is found by the RETURN routine theerror report "RETURN without GO SUB" gets printed. The total size of the two machine stacks is indeterminate, it depends on how many PUSHes and nested CALLs and GO SUBs are presently operating. It has to fit in between the address in 5C65 STKEND and the address in 5CB2 RAMTOP; pushing too many bytes on to either stack could actually corruptthe calculator stack below the address in 5C65 STKEND, and it isn't possible to guard against this when working in machine code. So on the GO SUB command, at 1EED GO SUB and in 1F05 TEST ROOM, an allowance of 64h/100d bytes is made for possible machine code stacking - perhaps a bit generous. 1EAC CLEAR stack rebuilt, clearing GO SUB stack 1EDC CLEAR 2 new 3E marker, GO SUB stack cleared 1EED GO SUB_three bytes put on GO SUB stack 1F23 RETURN_three bytes taken off GO SUB stack GO TO key (EC) see also commands, functions and operators, KEYBOARD SCANNING The G key in K mode produces the command GO TO, which must be followed by a numeric expression. It produces a jump in BASIC execution to the line number given by the expression. The command is read by 1B29 STMT L 1 referring through the syntax offset table 1A48 to the syntax parameter table 1A7A.1A7D P GO TO causes a jump via 1C82 CLASS 06, which gets the line number, and 1C16 JUMP C R to the executive routine 1E67 GO TO. GO TO subroutine 1E67 Called from the statement loop by 1A7D P GO TO in the syntax parameter table; the executive routine of the GO TO command. Also called from other command routines which make jumps in BASIC execution. Jumps to the specified BASIC line, by putting its numberin 5C42 NEWPPC and zero in 5C44 NSPPC, so that execution will continue from there on the next turn of the statement loop.