2D7B E END 2DA2 FP TO BC (twice) 2DAD PP DELETE 2DC1 LOG(2**A) 2DE3 PRINT FP 2DF2 PF NEGTVE 2E01 PF LOOP 2E24 PF SMALL (twice) 2ECB PF MORE 2F2D PF COUNT 3588 STR TEST 36A0 n-mod-m 36AF int 36C4 EXP 370E RSLT ZERO 3713 ln 371C VALID (twice) 3783 get-argt 37AA cos 37B5 sin 37DA tan 37E2 atn 37F8 SMALL 3833 asn 3843 acs 384A sqr 3851 to-power fp-calc-2 subroutine 33A2 see also CALCULATE Called from 0028 FP CALC with literal 3B and a calculator literal in 5C67 BREG. Allows the calculator to be used for an operation found from the program, ie not preset by the programmer. In the ROM, used only in the 24FB SCANNING loop to work out expressions froma pile of operations on the machine stack marked with prioritiesto enable them to be evaluated in the right order. No point in calling it direct from m/c, but useful in the sequence RST 0028/3Bh/38h. Input parameters: the literal of the operation to be performed must be in B on calling 0028 FP CALC: it is placed in 5C57 BREG by 335E GEN ENT 1. Action: drop the return address 3365 RE ENTRY; it will bestacked again before RET is reached - put the literal from 5C57 BREG in A. Exit: to 336C SCAN ENT, which jumps to the appropriate routine. Output parameters: operation literal in A - HL' still holds the address of the next literal. Called from: 274C S STK LIST Rems: 335B CALCULATE brief explanation 336C SCAN ENT finds required subroutine FP DELETE 2DAD (2DA2 FP TO BC.) Exit from: 2DA2 FP TO BC FP forms in BASIC line see number marker FP numbers see CALCULATE FP TO A subroutine 2DD5 Puts a positive integer less than 100h/256d from the calculator stack into the A register, without error reports but with flags to indicate overflow etc. Cf: 1E94 FIND INT1 - does the same but reports errors if the number is negative or too big 2314 STK TO A - takes a one-byte number, positive or negative, of absolute value up to 255d, from stack into A with asign marker; reports an error only if the absolute magnitude is out of range. Input parameters: none - a number on the calculator stack. Action: call 2DA2 FP TO BC, which rounds the number to aninteger, puts it in BC, setting carry if it is more than FFFFh/ 65535d, and also puts its lo byte in A. - if carry is set return; "too big" - save the flags - if B is zero jump on to FP A END - (hi byte not zero, the number is still too big for A) set the carry flag; leave the zero flag as made by FP TO BC - return. _2DE1_FP_A_END: recover the flags from FP TO BC. Exit: RET. Output parameters: BC holds bytes 3 and 4 of the FP number after rounding down to an integer; if less than 65536d itwas put in the "small integer" form and BC is its value - A also holds the lo byte - the FP number has been taken off the stack. - NC and Z flag a positive number less than 100h/256d - NZ flags a negative number - carry flags a number over FFh/255d. Called from: 1E85 TWO PARAMS 1E94 FIND INT1 2314 STK TO A 247D CD PRMS1 2CFF ST E PART 2E24 PF SMALL 35C9 chrs 3624 EXP Exit from: 2DC1 LOG (2**A) FP TO BC subroutine 2DA2 Puts a positive integer less than 10000h/65536d from thecalculator stack into the BC register, without error reports butwith flags indicating overflow etc. Cf: 1E99 FIND INT2 - does the same but with error messages 2307 STK TO BC - takes_two integers off the stack and puts one each in B and C 2D7F INT FETCH - copies a small integer into DE, without error reports or flags. Input parameters: none - a number on the calculator stack. Action: call 0028 FP CALC without any operation literal; this points HL at the last value - if the byte at HL is zero jump on to FP DELETE; the last value is already in small integer form - use the calculator to get INT (N + 0.5); this rounds the number to the nearest integer_up_or_down and leaves it in small integer form if it is within the range. _2DAD_FP_DELETE: use the calculator to delete the last value; its number form is still there, pointed to by DE - read its exponent byte - call 2D7F INT FETCH, which puts bytes 3 and 4 of the FP form in DE and its sign byte in C; if it is a small integer DE is its value - if the exponent isn't zero set the carry flag; not a small integer - read the hi bit of the sign byte; Z for positive, NZ for negative - move the values to the registers required for the output parameters. Exit: RET. Output parameters: BC holds the small integer taken from the stack, if it was one, rounded up or down to an integer value, positive or negative - HL points to what is now the last number on the stack,and DE to the stack end, which for the moment holds the unchanged first byte of the number just taken off the stack - NC and Z flag a positive number less than 10000h/ 65536d - NZ flags a negative number - carry flags an integer > FFFFh/65535d. Called from: 19FB E LINE NO 1E99 FIND INT2 25F8 S RND 2DD5 FP TO A FP 0/1 subroutine 350B Writes an FP number in small integer format, one or zerodepending on the carry flag, in the address at HL and the four following; usually on the calculator stack. In small integer format, zero is 00 00 00 00 00 and one is 00 00 01 00 00. Input parameters: HL holds the address - carry is set for one, zero for zero. Action: zero A; not using XOR A, which would clear the carry - load it into the first two bytes at HL - rotate it left, picking up the carry flag in its lo byte - load this into the third byte - rotate it right to zero it again - load it into the last two bytes. Exit: RET Output parameters: changes nothing except A (zeroed) and the FP number. Called from: 2D55 E SAVE (written to mem-0) 3524 no-&-no Exit from: 3501 NOT 351B or 3524 no-&-no fractional part of number see integer part fractional point see "." (code 2E) after end of alphabet FRAMES system variable 5C78 Bytes: 3 Holds a 3-byte integer which is incremented every twentymilliseconds, ie fifty times per second, throughout the computeroperation, except during BEEP and LOAD/SAVE operations. The first byte is the lo byte, the third is hi. FRAMES provides an accurate clock, which can be used in producing clock programs, but it isn't so used in the ROM; whereits only application is in providing a pseudo-random SEED for the random number function - see 25FB S RND and 5C76 SEED. FRAMES is zeroed on start-up, like every byte of the RAM, in 11E2 RAM READ. The incrementing is done in 0038 MASK INT, and the three bytes go through all values from zero to 16,777,215d about every 93.2 hours. The second byte is incremented about every 5 seconds, the third byte about every 20minutes. The third and second bytes can be used as short-term stores in m/c programming; it is best to zero the lo byte. If the interrupt is disabled all three FRAMES bytes are available; they will be incremented by 0038 MASK INT, so in this use it is better to call 0048 KEY INT. Written by: 0038 MASK INT hi byte called FRAMES-3 Read by: 0038 MASK INT two lo only 1E4F RANDOMIZE two lo only Rems: 1219 RAM SET sets clock going 'free' key sets see 02BF KEYBOARD FREE MEM subroutine 1F1A Not used by BASIC or ROM. Returns in BC the amount of memory utilized so far. Can be called from m/c, or from BASIC by PRINT 65536 - USR 7962 which prints out the number of bytes of free memory. The actionis essentially in 1F05 TEST ROOM. F REORDER 1D16 (1D03 FOR) Jumps from: 1D03 FOR frequency of beep see timing FRST LESS 3585 (353B no-l-eql) Jumps from: 3575 SEC PLUS (twice) F USE 1 1D10 (1D03 FOR) Jumps from: 1D03 FOR FULL ADDN 303E The exit from 3014 addition if either of the numbers to be added, or the result of adding them, is outside the small integer range. "Addition" here includes subtraction, which is simply addition in which one of the numbers is negative. Addition of numbers X and Y in full FP format isn't simple: 1. The first mantissa byte of each number must be correctedto a "true mantissa"; positive numbers have bit 7 zeroed. 2. The mantissa of the smaller number must be shifted to the right, with corresponding increment of the exponent, till the two exponents are the same. 3. Now the mantissas can be added like ordinary numbers. 4. If the resulting mantissa is more than one, it must be shifted right and the exponent incremented. 5. The mantissa must be corrected back to a full FP format mantissa, with bit 7 of the first byte showing the sign. Further complications arise if either number is negative, and if the result is negative: this is dealt with by temporarily replacing the exponent byte of each number with a leading fifth mantissa byte, 00 for a positive number or FF for a negative one, and negating the four mantissa bytes if it is negative. A parallel to steps 2 to 4 can be seen in the case of adding E-format numbers in their standard BASIC form, in which the mantissa is always between one and ten: here the exponent isa power of ten, not a power of two, and right shifting is decimal shifting not binary shifting, but much else is the same: Eg to add X = 9.97142 E +7 and Y = 9.23076 E +6 Exp Mant X: 7 9.97142 + Y: 6 9.23076 Step 2. Shift Y right: X: 7 9.97142 + Y: 7 0.923076 (one shift right) Step 3. Add mantissas: ---------------- X + Y: 7 10.894496 (direct sum of mantissas) Step 4. Normalize result mantissa: X + Y: 8 1.0894496 (one shift right) and the answer is 1.0894496E+8. Step 4 is tricky. Remember that (a) the original four-byte mantissas were always between half and one, so their high bit was set; (b) but if they were negative, they have been negated, so their high bit is now zero; (c) they have been expanded to_five-byte mantissas by addinga sign byte at the start of the mantissa, 00 for positive numbers and FF for negative (d) the mantissa of Y may have been shifted right, which puts one in the hi bit of (the four-byte mantissa of) negative numbers and zero in the hi bit of positive ones. If both numbers are positive, and there is carry from the addition of the mantissas, the mantissa needs to be shifted one place right. But also if they were both negative and there is_no carry: for this means that two numbers whose absolute values areeach more than a half have been added. The situation would be the same with one-byte addition: if 03 and 17h represent the negative numbers -FD and -E9, their sum 1A (-E6) represents the sum of -FD and -E9 (-1E6) only if a carry is added. And adding F9 and ED, representing addition of -07 and -13h, gives 1E6; which represents the answer -1Ah only if you _ignore the carry. If one of X and Y is positive and the other negative, since both their original mantissas were between half and one there is no way that the sum could produce a mantissa more than one which requires shifting_right; left perhaps, but that will be sorted out in "normalization". The ROM copes with these complexities quite ingeniously: Add together the sign bytes of X and Y, 00 for positive,FF for negative, with the carry from the addition of the mantissas. The possibilities are both positive, no shift: 00 + 00 + no carry = 00 both positive, must shift: 00 + 00 + carry = 01