_3195_OFLOW_CLR (we now have a correct normalized exponent in its proper place in the result, and the hi bit of the sign byte is also correct in its place; the mantissa is between half and one, but it is still a true mantissa and still in D'E'DE): set a pointer on the sign byte - move the true mantissa into ACDE - shift the hi byte left, losing the hi bit; a one in all cases - shift the sign bit left into carry from its temporary store in the result sign byte - shift back the hi byte of the mantissa taking the hi bit from carry. - step through the four result mantissa bytes loading ACDE into them - get back the two calculator stack pointers. Exit: RET, from OFLOW CLR. Output parameters: HL points to the first byte of the result - DE to the byte beyond the result - HL' to the "return address" holding the next literal. Exit from: 30A5 GO NC MULT (3014 addition) 3151 OFLW2 CLR (30CA multiply, 313D DIVN EXPT) Rems: 303E FULL ADDN normalizes result with correct sign bit 30F0 MULT LONG performed in TEST NORM as part of this 3146 OFLW1 CLR check for overflow if in normal form 3151 OFLW2 CLR any overflow needed in normalization 3155 TEST NORM if no carry, no further adjustment reqd 316C NORMALISE executes normalization 3186 NORML NOW handles carry TEST ROOM subroutine 1F05 see also GO SUB stack, memory The room available for expansion of the RAM part of the Spectrum operation is the "spare" space between the top of the calculator stack which expands upwards, and the "top" of the machine/GO SUB stack which expands downwards. If this space ever contracted to nothing, the calculatorstack and machine stack would collide, overwriting each other, with unpredictable but certainly disastrous results. No check is really possible on expansion of the machine stack, but every other expansion of memory uses the TEST ROOM subroutine to check that there is enough space for the command called for, and to abort it if not: eg "making room" in the various system areas (1655 MAKE ROOM), adding a value to the calculator stack (33A9 TEST 5 SP) or putting another address on the GO SUB stack (1EED GO SUB). RUN the following simple program: 10 GO SUB 10 It goes on piling up RETURN addresses on the GO SUB stack untilthe whole of the spare memory is full of RETURN addresses, when it breaks off with the report "4 Out of memory, 10:1". The defence adopted against over-expansion of the machine stack is to make an allowance in TEST ROOM of eighty bytes for it; assuming that no more than forty 2-byte values will ever be on the machine stack at once. This assumption is presumably valid for all the ROM routines, but it is perhaps worth bearing in mind as a limitation on m/c programs. The subroutine is also used to return the amount of memory used so far by the subroutine 1F1A FREE MEM, which can becalled from BASIC only by USR 7962, or by m/c equivalents. 10 PRINT 65536-USR 7962: GO SUB 10 makes an interesting demonstration. Input parameters: BC holds the room count, the amount of space which it is proposed to take up; usually with a bit of spare "for contingencies", eg 20d spare bytes when it is proposed to add to the GO SUB stack. Action: get the address of the top of the calculator stack from 5C65 STKEND - add the room count - if this is already more than FFFFh report "Out of memory"; apparently a duplication, but a carry here would invalidate the carry signal of later operations - add eighty bytes; to allow for PUSHes and CALLs extending the machine stack - if this is now more than FFFFh report "Out of memory" - check the pointer against SP, the machine stack pointer; making carry if the room count comes out below the stack pointer, ie there is enough spare memory - if there is no carry report "Out of memory". Exit: RET. Output parameters: HL holds the number of bytes in use - including all the ROM etc. The "free memory" is 10000h/65536d- HL. Called from: 0825 LD CONT 2 (BC=length of load block plus 5) 0FA9 ED EDIT (BC=length of edit line plus 10) 1655 MAKE ROOM (BC=length of space to be made) 1F1A FREE MEM (BC=zero) 33A9 TEST 5 SP (BC=5) Exit from: 1EED GO SUB (BC=20) TEST ZERO subroutine 34E9 Checks a FP number to see if it is zero. Zero can only be represented as a "small integer"; in this format the fifth byte is immaterial, so only the first four need to be looked at.All must be zero for the number to be zero. Input parameters: HL holds the first address of the number. Action: get the first byte - OR the second with it, then the third with that resultand the fourth with the result again; any non-zero byte will flag NZ - if the result flags Z set the carry. Exit: RET. Output parameters: all registers are saved unchanged - returns with carry as well as Z if the number was zero. Called from: 1CF0 IF 30C0 PREP M/D 346E NEGATE 3492 sgn 34F9 greater-0 3501 not 351B or 3524 no-&-no 352D str-&-no TEST 5 SP subroutine 33A9 see also TEST ROOM Tests whether 5 spaces can be made without memory overflow - enough to put a number on the calculator stack. Input parameters: none. Action: call 1F05 TEST ROOM with five in BC. Exit: RET. Output parameters: HL and DE are saved unchanged - BC holds five - otherwise none; there must be room, or there would be an "Out of memory" report from TEST ROOM. Called from: 2AB6 STK STORE 33C0 MOVE FP 33C8 STK CONST T EXPNENT 326C (3214 truncate) Jumps from: 3233 T FIRST T FIRST 3233 (3214 truncate) Jumps from: 3221 T GR ZERO T GR ZERO 3221 (3214 truncate) Jumps from: 3214 truncate THEN key (CB) see also KEYBOARD_SCANNING, 026A symbol code table (a) The G key with symbol shift produces the token THEN; itsonly use is in IF commands, to introduce the command which is tobe executed if the IF expression is "true". When the IF command is scanned by the statement loop in 1B6F SEPARATOR, reading the syntax parameters at 1A81, the command is checked to ensure that THEN is there. By this time the value of the IF expression, "true" or "false", is already last value on the calculator stack; whether "true" or "false", the THEN token is simply skipped. But like the colon it marks the end of a statement, and at 2713 S CONT 3 leading to 2723 S OPERTR and 2734 S LOOP, it triggers the evaluation of the IF expression. The keystroke following THEN is always read in K mode, even in REMs or INPUT ... LINE. This is sometimes useful. 1937 OUT CHAR leaves K mode in FLAGS 19A5 EACH S 4 jump for THEN 19AD EACH S 5 counts as end of statement 2712 S CONT 2 marks end of expression 'third' of display see DISPLAY AREA tighter binding see 24FB SCANNING time period, time-up, timing constant, timing loop, timing period Executing the various instructions of the Z80 chip, which is the "central processing unit" of the Spectrum, takes various lengths of time which are measured in a unit called a _T_state, or sometimes a_clock_cycle. The details can be found in various reference books, eg "Z80 Instruction Handbook" by NatWadsworth, publ. Hayden Book Company, Rochelle Park NJ. The fastest instructions, such as LD A,B or EX DE,HL or NOP, "no operation", take only four T states, the slowest, eg INC (IX+index), as many as 23d T states. Most conditional instructions, including DJNZ, take longer if their condition is met than if it isn't; DJNZ takes 13d T states to loop back, but only eight to exit if B is zero. Given the reference books, it is a fairly simple matter to compute the duration in T states ofany string of instructions or loop of your m/c. The actual duration of a T state depends on the computerbeing used: the Spectrum "system clock" is set to drive through 3.5 million T states per second, which means it performs 875,000d of the four-T-state instructions per second. This is sofast that there is no appreciable delay in carrying out any ordinary BASIC instruction, even a quite complicated one, and the programmers have in several places been able to sacrifice speed for compression of the coding; see under the subroutine 2535 S SCRN$ S. It takes a little ingenuity to write a m/c program that takes more than a fraction of a second to produce auseful result, unless delays are deliberately put in the code. A simple_delay_loop or_timing_loop is the instruction 0514 SA BIT 1 DJNZ 0514 SA BIT 1 which merely repeats itself as many times as allowed by the B counter before continuing. The duration of the timing loop will be thirteen times B minus five T states. B is called the _timing_constant. A long delay loop is sometimes called a_waiting_period; eg in 0574 LD WAIT, see under 0556 LD BYTES, where the length ofthe delay is 0415 * (1A + 100 * 0D)h = 35,8B22h = 3,504,930d T states. Much longer delays can conveniently be introduced by theHALT command: a single HALT stops execution of the m/c for 70,000d T states, 1/50th second. However HALT cannot be used with the interrupt disabled, and is little used in the ROM. There are also indefinite waiting loops such as 15DE WAIT KEY1 which continue to loop, for ever if necessary, until some input from outside, in this case a keystroke, allows them to break out. Timing is important in two sections of the ROM routines: 1. Save/load routines, see 0556 LD BYTES, 04C2 SA BYTES, ports _edges,_edge_types: an "edge" in general means the changefrom zero/off to one/on or vice versa. In this context it means the change from MIC ON to MIC OFF or vice versa. The_edge-type means the MIC setting after the change. _leader_signal: both header and main block are preceded by a "leader signal", lasting five seconds for the header and two seconds for the block. The leader signal consists of a regular series of pulses at a frequency of about 800d hz; each pulse both BEEPs to the loudspeaker and changes the border colour from CYAN to RED and back, so that the leader pulse is audible as a whistling note and visible as stripes in the border. _pulses,_leader_pulses,_sync_pulse: a pulse is defined asa period of MIC on followed by a period of MIC off, ie two edges. The leader pulses constituting the leader signal are followed by a much shorter sync pulse, which signals the end of the leader, and then by the bit pulses signalling the SAVEd code, long pulses for one and short for zero; these too are signalled to the speaker and the border, making YELLOW/BLUE stripes. 2._BEEP_routines, see 03F8 BEEP and 03B5 BEEPER _note: the note in musical terminology: C, C sharp, etc. _frequency: the number of pulses per second, measured in hertz: middle C is 261.63d hz. Doubling the frequency raises thenote by one octave: as there are twelve semitones in an octave, the multiple to raise the note by one semitone is the number which when multiplied twelve times by itself makes two, ie the twelfth root of two, see 03F8 BEEP _pitch: used in the notes to mean the number given by BASIC specifying the note required: zero for middle C, plus one for each semitone above. Introduction stable pitch 0310 K REPEAT key repeat delays 03B5 BEEPER pulse on/off timing loop is 4 times L T states, with fine tuning in IX 03D1 BE IX+3 loop entered one NOP earlier for each fine tuning adjustment 03D6 BE H&L LP start of timing loop - calculated delay between OUT signals 03F2 BE AGAIN four short instructions quicker than previous paragraph 03F8 BEEP pitch is last value, frequency and loop time calculated 0425 BE i OK frequency 0427 BE OCTAVE finds octave, frequency, loop time 046E semitone table 04D8 SA LEADER leader pulses have cycle 4336dT = 807dhz 04EA SA SYNC 1 off 667dT=0.2 thousandths/sec; sync pulse 735dT=0.4 thousandths/sec 04F2 SA SYNC 2 timing constant set to 3Bh/59d 0511 SA BIT 2 bits: "zero" 855dT shorter than "one" 0514 SA BIT 1 timing loop; now timer set to 42h/66d 051A SA SET timing loop 051C SA OUT timer set to 3Eh/62d 0525 SA 8 BITS timer set to 31h/49d 053C SA DELAY note on length of data bit pulses 056B LD BREAK wait till pulse received 056C LD START waits about 4 thousandths/sec 0574 LD WAIT B was zero, so the DJNZ loop cycles 256d times; the next four instructions take 26d T states; HL set to 415h/1045d counts repeats of the whole cycle, making (13 * 256 + 8 + 26) * 1045 = 3,513,290 T states 0580 LD LEADER looks for leader pulses, half-cycle 2168 T; timer for LD EDGE 9Ch/156d 058F LD SYNC look for sync pulse 05C4 LD DEC timer for LD EDGE B2h/178d 05CA LD 8 BITS checks bit; one bit (including "off" time) will be 2 * 801 + 855 = 2457dT, zero bit will be 1602dT. Set timer again to B0h/176d 05E3 LD EDGE 2 looks for 1 or 2 edges in given time 05E7 LD EDGE 1 4 T for DEC A, 12 T for JR NZ; times 22d = 352d, plus 7 for JR NZ again and 4 for AND A 05ED LD SAMPLE loop takes 60 T each pass 0970 SA CONTRL set delay of fifty HALTS, one second 11CB START/NEW six NOPs, 4 T each T NUMERIC 3252 (3214 truncate) Jumps from: 323F T SMALL TO key (CC) see also KEYBOARD SCANNING, 026A symbol code table (a) The F key with symbol shift produces the token TO; it has two quite different uses, as a separator in FOR ... NEXT loops and as a signal for slicing of strings.