Routines 
Prev: 31AF  Up: Map 
The address of this routine is found in the table of addresses. It is called via the calculator literal +3A by the routine at int.
This subroutine (say I(x)) returns the result of integer truncation of x, the 'last value', towards zero. Thus I(2.4) is 2 and I(2.4) is 2. The subroutine returns at once if x is in the form of a 'short integer'. It returns zero if the exponent byte of x is less than +81 (ABS x is less than 1). If I(x) is a 'short integer' the subroutine returns it in that form. It returns x if the exponent byte is +A0 or greater (x has no significant nonintegral part). Otherwise the correct number of bytes of x are set to zero and, if needed, one more byte is split with a mask.


truncate  3214  LD A,(HL)  Get the exponent byte of x into A.  
3215  AND A  If A is zero, return since x is already a small integer.  
3216  RET Z  
3217  CP $81  Compare e, the exponent, to +81.  
3219  JR NC,T_GR_ZERO  Jump if e is greater than +80.  
321B  LD (HL),$00  Else, set the exponent to zero; enter +20 into A and jump forward to NIL_BYTES to make all the bits of x be zero.  
321D  LD A,$20  
321F  JR NIL_BYTES  
T_GR_ZERO  3221  CP $91  Compare e to +91.  
3223  JR NZ,T_SMALL  Jump if e not +91.  
The next 26 bytes seem designed to test whether x is in fact 65536, i.e. 91 80 00 00 00, and if it is, to set it to 00 FF 00 00 00. This is a mistake. As already stated, the Spectrum system cannot handle this number. The result here is simply to make INT (65536) return the value 1. This is a pity, since the number would have been perfectly all right if left alone. The remedy would seem to be simply to omit the 28 bytes from 3223 above to 323E inclusive from the program.


3225  INC HL  HL is pointed at the fourth byte of x, where the 17 bits of the integer part of x end after the first bit.  
3226  INC HL  
3227  INC HL  
3228  LD A,$80  The first bit is obtained in A, using +80 as a mask.  
322A  AND (HL)  
322B  DEC HL  That bit and the previous 8 bits are tested together for zero.  
322C  OR (HL)  
322D  DEC HL  HL is pointed at the second byte of x.  
322E  JR NZ,T_FIRST  If already nonzero, the test can end.  
3230  LD A,$80  Otherwise, the test for 65536 is now completed: 91 80 00 00 00 will leave the zero flag set now.  
3232  XOR (HL)  
T_FIRST  3233  DEC HL  HL is pointed at the first byte of x.  
3234  JR NZ,T_EXPNENT  If zero reset, the jump is made.  
3236  LD (HL),A  The first byte is set to zero.  
3237  INC HL  HL points to the second byte.  
3238  LD (HL),$FF  The second byte is set to +FF.  
323A  DEC HL  HL again points to the first byte.  
323B  LD A,$18  The last 24 bits are to be zero.  
323D  JR NIL_BYTES  The jump to NIL_BYTES completes the number 00 FF 00 00 00.  
If the exponent byte of x is between +81 and +90 inclusive, I(x) is a 'small integer', and will be compressed into one or two bytes. But first a test is made to see whether x is, after all, large.


T_SMALL  323F  JR NC,X_LARGE  Jump with exponent byte +92 or more (it would be better to jump with +91 too).  
3241  PUSH DE  Save STKEND in DE.  
3242  CPL  Range 129<=A<=144 becomes 126>=A>=111.  
3243  ADD A,$91  Range is now 15>=A>=0.  
3245  INC HL  Point HL at second byte.  
3246  LD D,(HL)  Second byte to D.  
3247  INC HL  Point HL at third byte.  
3248  LD E,(HL)  Third byte to E.  
3249  DEC HL  Point HL at first byte again.  
324A  DEC HL  
324B  LD C,$00  Assume a positive number.  
324D  BIT 7,D  Now test for negative (bit 7 set).  
324F  JR Z,T_NUMERIC  Jump if positive after all.  
3251  DEC C  Change the sign.  
T_NUMERIC  3252  SET 7,D  Insert true numeric bit, 1, in D.  
3254  LD B,$08  Now test whether A>=8 (one byte only) or two bytes needed.  
3256  SUB B  
3257  ADD A,B  Leave A unchanged.  
3258  JR C,T_TEST  Jump if two bytes needed.  
325A  LD E,D  Put the one byte into E.  
325B  LD D,$00  And set D to zero.  
325D  SUB B  Now 1<=A<=7 to count the shifts needed.  
T_TEST  325E  JR Z,T_STORE  Jump if no shift needed.  
3260  LD B,A  B will count the shifts.  
T_SHIFT  3261  SRL D  Shift D and E right B times to produce the correct number.  
3263  RR E  
3265  DJNZ T_SHIFT  Loop until B is zero.  
T_STORE  3267  CALL INT_STORE  Store the result on the stack.  
326A  POP DE  Restore STKEND to DE.  
326B  RET  Finished.  
Large values of x remain to be considered.


T_EXPNENT  326C  LD A,(HL)  Get the exponent byte of x into A.  
X_LARGE  326D  SUB $A0  Subtract +A0 from e.  
326F  RET P  Return on plus  x has no significant nonintegral part. (If the true exponent were reduced to zero, the 'binary point' would come at or after the end of the four bytes of the mantissa.)  
3270  NEG  Else, negate the remainder; this gives the number of bits to become zero (the number of bits after the 'binary point').  
Now the bits of the mantissa can be cleared.


NIL_BYTES  3272  PUSH DE  Save the current value of DE (STKEND).  
3273  EX DE,HL  Make HL point one past the fifth byte.  
3274  DEC HL  HL now points to the fifth byte of x.  
3275  LD B,A  Get the number of bits to be set to zero in B and divide it by 8 to give the number of whole bytes implied.  
3276  SRL B  
3278  SRL B  
327A  SRL B  
327C  JR Z,BITS_ZERO  Jump forward if the result is zero.  
BYTE_ZERO  327E  LD (HL),$00  Else, set the bytes to zero; B counts them.  
3280  DEC HL  
3281  DJNZ BYTE_ZERO  
BITS_ZERO  3283  AND $07  Get A (mod 8); this is the number of bits still to be set to zero.  
3285  JR Z,IX_END  Jump to the end if nothing more to do.  
3287  LD B,A  B will count the bits now.  
3288  LD A,$FF  Prepare the mask.  
LESS_MASK  328A  SLA A  With each loop a zero enters the mask from the right and thereby a mask of the correct length is produced.  
328C  DJNZ LESS_MASK  
328E  AND (HL)  The unwanted bits of (HL) are lost as the masking is performed.  
328F  LD (HL),A  
IX_END  3290  EX DE,HL  Return the pointer to HL.  
3291  POP DE  Return STKEND to DE.  
3292  RET  Finished. 
Prev: 31AF  Up: Map 