- each time a report message is printed by the call to 1650 SET MIN from 1313 MAIN G - each time a statement is executed by the call to 16BF SET WORK from 1B29 STMT L 1 - and on a few other occasions. The main uses of the work space are: - compilation of the header for SAVE/LOAD commands - on a MERGE command, the whole program and variables block is first loaded into the work space, and then fitted into the existing program and variables as appropriate - INPUTs are compiled in the work space. FLAGX bit 5 being on signals "input mode", which requires inputs to be sent to the work space - some strings/slices are compiled in the work space, andcopied to the variables area if they are to be preserved - for the VAL function, an expression is copied to the work space and evaluated from there; similarly, for the STR$ function, the value of an expression is output to the work spaceand can be copied from there. 0030 BC SPACES makes room in work space 0605 SAVE ETC header is constructed in work space 0621 SA SPACE makes space for header 064B SA NAME name transferred to work space 0672 SA V OLD length of array block to work space 06F9 SA CODE 4 start/ length of code block to work space 073A SA TYPE 6 program/variables params to work space 075A SA ALL tape header will also go into work space 08B6 ME CONTRL whole data block goes into work space 0958 ME ENT 3 new items moved one by one from work space 1097 CLEAR SP clears work space (or editing area) 1190 SET HL marks first/last address if FLAGX bit 5 set 169E RESERVE makes room in work space 16B0 SET MIN clears work space etc 16BF SET WORK clears work space etc 1B29 STMT L 1 clears work space 20FA IN PROMPT prompt for INPUT prepared in work space 219B IN VAR 6 input measured in work space 21B9 IN ASSIGN expression read from work space 255D S SC ROWS one character put in work space 25BE S Q AGAIN work space prepared for string 25CB S Q COPY copy string to work space 2634 S INKEY$ one character put in work space 28B2 LOOK VARS variable name in work space or program 2B72 L DELETE$ string slices compiled in work space 2B9B L LENGTH new string copied to work space 2BA6 L ENTER string moved from work space to vbles area 359C str-add two strings put end to end in work space 35C9 chr$ single character put in work space 35DE val expression evaluated from work space 361F str$ expression output to work space 3645 read-in one character put in work space wrong number In "ROM Disassembled" there are several notes on the difficult number -65536d, pointing out among other things at least two mistakes in the ROM over handling it: see Introduction, 3014 addition, 3214 truncate and the note on page 229. A few additional comments may be helpful: 65536d = 1,0000h = 1,0000,0000,0000,0000b = 2**10h/2**16d The full FP form of +65536d is 91 00 00 00 00, with an exponent and mantissa, corrected to their "true" forms, of 11h and 80 00 00 00 respectively: 65536d = 2**11h times one half. Sofar so good: 65536d is just like any other power of two. 65536d can't be put in small integer form: the largest number which can be so expressed is 65535d, 00 00 FF FF 00 in small integer form. One more than this, in small integer form, would come out as 00 00 00 00 00, which means zero _Minus 65536d also produces no problems so long as it is in full FP form: 91 80 00 00 00 is again just like any other negative power of two. So what is the problem? If the programmers had been content to exclude minus 65536d from small integer format like plus 65536d, there probably wouldn't be any. But this leaves onefive-byte number form without an interpretation: 00 FF 00 00 00.The 00 in its first byte shows it is a small integer, the FF in its sign byte shows it is negative, the third and fourth bytes show it is zero; minus zero is the same as plus zero, and indeedthe ROM corrects minus zero to plus zero after any arithmetic operation in 315E SKIP ZERO, see under 3155 TEST NORM. At some point in the development of the Spectrum ROM someone seems to have had the bright idea that -65536d needn't be excluded from small integer format, it could be represented by 00 FF 00 00 00: -0000h being made to stand for -10000h. But this idea wasn't properly implemented, and 00 FF 00 00 00 is thereal "wrong number". The wrong number 00 FF 00 00 00 can't be produced directly by reading decimal numbers from the BASIC, because suchnumbers are always read as absolute values, in 2C9B DEC TO FP, called from 268D S DECIMAL: 65536d couldn't be put on the calculator stack as a small integer and 346E negate can't changea full FP number to a small integer. In addition, which includes subtraction, the wrong number can be produced by adding two small integers, but only ifboth are negative. Take the example in the notes: compare the process in 3014 addition of adding -65000 + -536 = -65536d ie 00 FF 18 02 + 00 FF E8 FD with -65000 + -535 = -65535d ie 00 FF 18 02 + 00 FF E9 FD and +65000 + +536 = +65536d ie 00 00 E8 FD + 00 00 18 02 First case, -65000 + -536 = -65536d: ADD HL,BC: 0218 + FDE8 = 0000 and carry ADC A, (HL) (the two sign bytes): FF + FF + 1 = FF and carry RRCA: FF and carry ADC A,00: 00 and carry SBC A,A: FF. Second case, -65000 + -535 = -65535d: ADD HL,BC: 0218 + FDE9 = 0001 and carry ADC A, (HL) (the two sign bytes): FF + FF + 1 = FF and carry RRCA: FF and carry ADC A,00: 00 and carry SBC A,A: FF. Third case, +65000 + +536 = +65536d: ADD HL,BC: FDE8 + 0218 = 0000 and carry ADC A, (HL) (the two sign bytes): 00 + 00 + 1 = 01, no carry RRCA: 00 and carry ADC A,00: 01, no carry As the result isn't zero, this third case jumps on to ADDN OFLW. Thus the wrong number can be produced by addition/ subtraction: if it is to be excluded, it seems to me the simplest way would be to jump on to ADDN OFLW if ADD HL,BC produces zero with carry - a lot simpler than the alternative coding suggested in the Appendix on page 230 of the notes. 30CA multiply and 31AF division never produce the wrong number as a result, because such a result of either would alwaysbe in full FP form. The only other function which can actually produce the wrong number seems to be INT, as in PRINT INT (-65535.5). This is the result of the misconceived manoeuvres of 3221 T GR ZERO in 3214 truncate; a self-inflicted wound, because as the notes point out this section of the ROM achieves nothing except to rewrite the full FP form of -65536d as the wrong number: _3221_T_GR_ZERO (see index entry on 3214 truncate; X has an exponent more than 80h, which is in the A register, and its address is in HL): if the exponent isn't 91h precisely jump on to T SMALL; now X is between 65536d (91 00 00 00 00) and 131,071.999d (91 0F FF FF FF), or if X is negative, -X is between these values. All bits of the last two mantissa bytes except the hi bit are in the fractional part of X - move the pointer on the the third mantissa byte - make a mask 10000000b/80h to separate the hi bit of this byte; the only one in the integer part of X - AND the mask with the third byte - OR this hi bit with the second mantissa byte - if this makes NZ jump on to T FIRST; they aren't all zero bits - (the second mantissa byte and the hi bit of the third are all zero) XOR the first mantissa byte with 80h; making NZ ifit isn't 80h precisely. _3233_T_FIRST: move the pointer back to the exponent byte -if X isn't 91 80 00 XX XX, with the hi bit of the XXs being zero, jump on to T EXPNENT, see 3214 truncate; ie with anynumber which doesn't truncate to -65536d precisely - (the result is to be 00 FF 00 00 00) set the first twobytes to 00 FF - jump on to NIL BYTES with 24d in the counter to zero the last three bytes. The wrong number could be excluded by just omitting thispart of the routine, and if the change suggested above were madein 3014 addition the wrong number could never arise at all. Much more would need to be done to save the wrong numberas a representation of -65536d: - the wrong number isn't printed correctly: 2DE3 PRINT FPrecognises it as a negative number, and when 2DF2 PF NEGTVE calls 346A abs it is recognised as a negative small integer, but3483 INT CASE changes it to zero. As the test for zero in PRINT FP has been bypassed, it isn't printed as zero but as the smallest possible number -1E-38 - if the wrong number is in the_input of an arithmetic operation it is evaluated as zero. In addition/subtraction and in division, eg PRINT -65000 - 536 + X PRINT (-65000-536)/X 3293 RE ST TWO restacks it as zero; in 30CA multiply, eg AUTOLOAD