home *** CD-ROM | disk | FTP | other *** search
/ Outlet 52 / outlet-52.mgt / f5 < prev    next >
Text File  |  2021-04-18  |  20KB  |  1 lines

  1.   one  negative,   no shift: 00 + FF + carry    = 00 and carry    both negative, must shift: FF + FF + no carry = FE and carry    both negative,   no shift: FF + FF + carry    = FF and carry.         The resulting "indicator" will be 01 with no carry or FEwith carry if a shift is required, 00 or FF with or without     carry if not.                                                           Shift the indicator right with carry into bit 7; now                -    "must shift" is 00 or FF                                   - "needn't shift" is 00, 7F, 80 or FF.                      XOR this result with the original indicator, so that                -    "must shift" becomes 01 in both cases; odd                 - "needn't shift" becomes 00 or 80        ; even            The hi bit of the indicator also shows the sign of the  result: zero if both X and Y were positive, one if they were    both negative. And if only one of X and Y was negative, the hi  bit of the indicator is set, ie negative, if there was_no carry and zero if there was carry; and this also correctly indicates  the sign of the result. The carry is the result of a five-byte  addition of numbers which are positive if the hi bit of their hibyte is zero, negative if not; the rules are just the same as   for one-byte additions. Adding F0h/minus 10h to 16h gives 06h   with carry; the result is positive. Adding F0h/minus 10h to 06h gives F6h/minus 0Ah without carry; the result is negative.             Input parameters: HL' holds the "return address" of the  calculator subroutine, containing the next literal address              - the numbers X and Y are on the calculator stack; one  or both may be in small integer format                                  - HL points to the start of the first and DE to the     start of the second, the last on the stack; in the notes, X is  called the "augend" and Y the "addend". See under addend for    these tedious terms.                                                   Action: call 3293 RE ST TWO to put both numbers in full  FP format                                                               - stack the "return address" and both pointers; SHIFT   LEN below is going to take all the registers the law allows             - call 2F9B PREP ADD for X; it gets the exponent, sets  the sign byte for a true mantissa, puts zero in byte 1 for a    positive, FF for a negative number, and subtracts the mantissa  from zero if it is a negative number                                    - save the exponent                                             - call PREP ADD again for Y                                     - save its exponent; this completes step 1, and gets    ready to deal with negative numbers as well                             - if X has a smaller exponent than Y, or they are the   same, jump on to SHIFT LEN                                              - (X > Y) exchange the exponents and pointers; now HL ispointing to the number with the smaller exponent, and from now  on the addend Y will mean the smaller of what were X and Y, the augend X will mean the larger.                                         _3055_SHIFT_LEN (step 2): subtract the exponents; the    difference is R, the number of right shifts to make in Y                - call 2FBA FETCH TWO, which puts the mantissa of the   larger X in H'B'C'CB and the mantissa of the smaller Y in       L'D'E'DE; H' and L' are the sign markers, FF for negative and   zero for positive, not as usual the exponent bytes. In effect   these are five-byte mantissas                                           - call 2FDD SHIFT FP to execute step 2, shifting        L'D'E'DE to the right by R binary digits; rounding up as        necessary for the bits which fall off to the right and feeding  in bits on the left to match the ones there already - so that inthe leading byte FF stays as FF and 00 as 00                            - add the two pairs of lo bytes, and the two pairs of hibytes with any carry from the addition of the lo bytes; step 3          - perform step 4; add the exponents with the carry from the mantissa addition                                                   - rotate the indicator right with carry into the hi bit         - XOR the result with the indicator                             - if the result is even jump on to TEST NEG; no shift           - (must shift) call 2FDD SHIFT FP with a count of one tomake a single right shift                                               - increment the exponent to compensate for the shift            - if the exponent goes to zero jump on to ADD REP 6;    arithmetic overflow.                                                   _307C_TEST_NEG: AND the indicator with 10000000b/80h             - put the result in the sign byte position of the resulton the calculator stack; it shows the sign of X + Y, 80h for    negative and zero for positive                                          - if it was zero jump on to GO NC MLT; positive result          - (negative result) negate the 4-byte result mantissa   byte by byte; from the right, with carry from each to the next          - if it doesn't produce final carry jump on to END COMPL        - [still a negative result; final carry means the resultmantissa was FF FF FF FF, now 00 00 00 00. The result is an     exact power of 2. Negative numbers -2**(X - 1) which are powers of 2 are expressed in FP format as 8X 80 00 00 00] rotate the   carry into the hi bit of the second result byte, making it 80           - increment the exponent.                                      _309F_ADD_REP_6: if the exponent adds up to zero, report "Number too big".                                                      _30A3_END_COMPL: put the first byte in place; now the    result mantissa is in D'E'DE, but it may require normalizing.          _30A5_GO_NC_MLT: zero the A register and exit.                  Exit: into 3155 TEST NORM; it normalizes the result      mantissa, ie puts it into FP format (step 5), and stacks it.           Output parameters (as required for TEST NORM):                   - the four true mantissa bytes are in DED'E'                    - A is zero                                                     - HL points to the exponent byte of the result, which   holds the normalized exponent byte                                      - the second position of the result holds 00 or 80h for a positive or negative result                                           - the carry flag shows NC for addition.                        Exit from:                                                       3014 addition                                                   303C ADDN OFLW (3014 addition)                                                                                              full FP format numbers see CALCULATE                                                                                            full multiplication see 30CA multiply                                                                                           functions see commands, functions and operators, 1F60 DEF FN                                                                    FUNCTION SKIPOVER SUBROUTINE see 28AB FN SKPOVER                                                                                                         -----                                                                                                  GEN ENT 1 335E (0028 FP CALC)                                       Entry point to FP CALC used by 3449 series-06, for no   clear reason (see under FP CALC).                                                                                                   GEN ENT 2 3362 (0028 FP CALC)                                       Entry point to FP CALC used by 3449 series-06 for       looping calls, to avoid resetting 5C67 BREG.                           Called from:                                                     3453 G LOOP                                                                                                                 get-argt subroutine 3783                                            Called from 0028 FP CALC with literal 39; not otherwise called from ROM.                                                        Finds a_reduced_argument corresponding to X for the     calculation of COS X or SIN X. The argument X of a COS or SIN   function can have any value at all, which represents an angle.          Those who have difficulty visualizing the meaning of SINand COS may find it helpful to think in terms of a clock face,  without hands. The angles are represented by the numbers on the clock, but the convention in trigonometry is to measure them    anti-clockwise from the "three-o'clock" position. Negative      angles are measured clockwise from the same start position.             SIN X is a measure of the height of the clock number    above the middle of the clock, COS X is a measure of the        distance of the clock number to the right of the middle. Nine   o'clock to three o'clock have positive SIN, three to nine       o'clock have negative SIN: twelve to six have positive COS, six to twelve negative COS.                                                 For the moment, consider the angle as measured in       degrees. An angle of say 500d degrees represents a complete     circle, 360 degrees, plus 140d degrees: going right round the   circle leaves SIN and COS as they were, ie                                      SIN (X + 360d degrees) = SIN X,                  and the same for COS. Analogously, 1400 hours in the twenty-   four hour clock is the same as 2 p.m. in the twelve-hour clock, and has the same SIN and COS                                            So for all calculations of SIN or COS, X may be reduced any number of times by 360d degrees without affecting the       result: eg SIN 1000d degrees = SIN 280d degrees.                        In Spectrum calculations, angles are measured not in    degrees but in radians: radians are a measure of angles, like   degrees or the numbers on the clock face, but 2pi radians = 360 degrees; so a right angle is pi/2 radians, 45 degrees is pi/4   radians, etc. For trigonometry, calculus etc, radians are a muchmore convenient unit than degrees, but for practical purposes   they are rather a nuisance.                                             If X is more than a complete circle 2pi, both its SIN   and its COS are the same as those of X - 2pi; SIN and COS are   called "cyclic" functions for this reason. There are further    equivalences within the circle itself, which make it possible toreduce the argument further than by merely subtracting complete circles; try visualizing them in terms of the clock face:               SIN (-X)     = -SIN X          COS (-X) =  COS X                SIN (pi - X) =  SIN X      COS (pi - X) = -COS X                SIN (X - pi) = -SIN X      COS (X - pi) = -COS X                SIN (pi + X) = -SIN X      COS (pi + X) = -COS X                The get-argt subroutine simplifies the calculation of   SIN and COS by finding a reduced argument V, between a positive and a negative right angle, which has the same SIN as X, and thesame COS except for a possible change of sign. "Between a       positive and a negative right angle" means between -pi/2 and    +pi/2 radians, or between twelve and six o'clock.                       It finds this value through a series of steps:               1. Divide X by 2pi and subtract the_nearest_integer_above  _or_below; this is the first reduced argument Y.                        Y represents the same angle as X, but with a change of  units: instead of radians, the unit is now the circle, 2pi      radians, so an angle 4 represents four complete circles, 0.25d  represents a right angle, etc.                                          The usual procedure for finding the nearest integer is  followed, ie add a half and then discard the fractional part; soY is a fraction of a circle, less than a half, positive if X is between nine o'clock and three o'clock, otherwise negative. Y   will always be between minus a half circle and plus a half; ie  it ranges anticlockwise once over the whole circle from nine    o'clock round to nine o'clock again. The sign of SIN Y circles  will be the same as that of SIN X radians. Subtracting an       integer makes no further change in SIN or COS.                       2. Multiply Y by 4: the result is the second reduced       argument Z = 4*Y. Multiplying by 4 changes the unit of angle    again: Z is in units of a 1/4 circle, ie a right angle, pi/2    radians. Z ranges from -2 to +2 right angles, still once round  the circle anticlockwise from nine o'clock to nine o'clock.             Now make a sign flag for COS by subtracting one from ABSZ; because the units are now right angles, one represents a     right angle. If ABS Z is more than a right angle, the angle is  in the left half of the circle, six to twelve o'clock; ABS Z - 1is positive, signalling "COS negative". Otherwise ABS Z - 1 is  negative, signalling "COS positive".                                 3. The third and final reduced argument V is in the same   units as Z, right angles, but its range is reduced to minus one to plus one right angles, the half circle from twelve to six    o'clock. There is already a flag for the sign of COS, so it is  only necessary to ensure that SIN V right angles has the same   sign as SIN Z right angles, which already has the same sign as  SIN X radians. There are three cases:                                   3.1. ABS Z is less than one: Z is OK, so put V = Z              3.2. ABS Z is more than one, Z is positive: put V = 2 - Z. Now V has been put in range, and since 2 means two right     angles, ie pi, as seen above SIN (pi - X) = SIN X; in this case,if Z was "ten o'clock" V is put at "two o'clock"                        3.3. ABS Z is more than one, Z is negative: put V = ABS Z - 2. Again this puts V in range, and since SIN (x - pi) = -SINX the sign has been corrected; if Z was "eight o'clock", ABS Z  is "ten o'clock" and V is "four o'clock".                              Input parameters: none                                           - X is the last value on the calculator stack; it must  be the last value even for direct calls.                               Action (step 1): use the calculator to divide X by 2pi           - find the nearest integer above or below; INT (X/2pi + 0.5d)                                                                   - subtract it from X/2pi; the result is Y                       - calculate Z = 4*Y; step 2                                     - keep Z and take one from ABS Z [Z in the notes is usedfor what I call ABS Z - 1]                                              - keep ABS Z - 1 and get its sign; one for ABS Z > 1 andzero for ABS Z < 1                                                      - store it in mem-0; this is the COS sign flag                  - if it is one jump on to ZPLUS; more than a right angle        - (case 3.1, Z positive and less than a right angle)    return with V = Z = 4*Y on the stack.                                  _37A1_ZPLUS (more than a right angle): get ABS Z - 2             - check the sign of Z                                           - if Z is negative jump on to YNEG; negative angle              - (case 3.2, Z positive and more than a right angle)    negate ABS Z - 2 and return; with V = 2 - ABS Z                                                  = 2 - Z                                                         = 2 - 4*Y on the stack.               _37A8_YNEG (case 3.3, Z negative and more than a right   angle): return with V = ABS Z - 2                                                     = -4*Y - 2 on the stack.                         Exit: RET.                                                      Output parameters: V has replaced X on the calculator    stack                                                                   - the flag in mem-0 is one if the COS is negative.             Called from:                                                     37AA cos                                                        37B5 sin                                                                                                                    GET CHAR subroutine 0018                                            Just like 0020 NEXT CHAR, except that 5C5D CH ADD isn't incremented at the start; it reads the_present_character, the   next printable character from the BASIC program or editing      areas; see character codes. 20h space is_not a printable        character.                                                             Input parameters: none                                           - the BASIC pointer 5C5D CH ADD is on the start address.       Action: get the character from the pointer in A.                _001C_TEST_CHAR: call 007D SKIP OVER, which moves 5C5D CHADD forward over the parameters of control codes and sets the C flag for other unprintable codes                                        - if the flag shows NC, return; ie if any printable     character or newline is found.                                         Exit: RET, from 001C TEST CHAR                                   - or into 0020 NEXT CHAR, which moves 5C5D CH ADD       forward and loops back to TEST CHAR.                                   Output parameters: A holds the character code                    - HL holds the address in 5C5D CH ADD.                         Called from:                                                     0652 SA DATA                                                    06E1 SA CODE 1                                                  12CF MAIN 3 (label omitted, misprint)                           17FB LIST 1 (twice)                                             1B29 STMT L 1                                                   1B55 GET PARAM                                                  1B6F SEPARATOR                                                  1BF4 STMT NEXT                                                  1CBE CLASS 09                                                   1DED READ                                                       1E0A READ 1                                                     1E1E READ 2                                                     1FDF PRINT 2                                                    1FFC PR ITEM 1                                                  204E PR POSN 1                                                  20C1 IN ITEM 1                                                  21B9 IN ASSIGN (twice)                                          21E2 CO TEMP 2                                                  2320 CIRCLE                                                     2382 DRAW                                                       24FB SCANNING                                                   2522 S 2 COORD                                                  25B3 S QUOTE                                                    268D S DECIMAL                                                  26B5 S STK DEC                                                  2712 S CONT 2                                                   27D9 SF ARGMTS                                                  2852 SF ARG VL                                                  2885 SF R BR 2                                                  28B2 LOOK VARS                                                  2934 V SYNTAX                                                   293F V FOUND 2                                                  29A1 SV SIMPLE$                                                 29AE SV ARRAYS                                                  29C3 SV COMMA                                                   29E0 SV CH ADD                                                  29EA SV LOOP