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

  1.         FNs can be nested, ie one DEF FN can use as arguments   expressions involving another FN, or even the same FN. When the routine is evaluating the right-hand side of the DEF FN         statement in SF VALUE, it stacks the address from 5C0B DEFADD   and replaces it with the pointer to the first argument in the   new DEF FN; thus nested FN expressions will make a stack of     DEFADD addresses, with zero at the bottom. As evaluation of eachDEF FN is completed, an old DEFADD address is removed from the  stack and restored to 5C08 DEFADD, which thus holds a zero when the whole nest has been cleared. Any non-zero address from 5C08 DEFADD is used by 2951 STK F ARG, called by V TEST FN in 28B2   LOOK VARS, called by 24FB SCANNING, to find variable values whenevaluating FN expressions, in preference to those from the      variables area.                                                         Since 5C0B DEFADD is always in the program area and is  used only in run time, it doesn't require adjustment for any    MAKE ROOM or RECLAIM; hence it isn't included in the "fourteen  pointers" as one might expect.                                         Input parameters: none                                           - 5C5D CH ADD holds a BASIC pointer to the FN token.           Action: jump straight on to S FN SBRN.                          _27BD_S_FN_SBRN: in run time, jump on to SF RUN                  - (syntax checking) move on the BASIC pointer; now it   should be on the function letter                                        - call 2C8D ALPHA; if the code is a letter it returns   with carry                                                              - if not a letter report "Nonsense in BASIC"                    - move on the BASIC pointer                                     - check if the code is 24h $ and stack the Z/NZ flag            - if not "$" jump on to SF BRKT 1                               - (it is "$") move the pointer on again.                       _27D0_SF_BRKT_1: if the code isn't 28h ( report "Nonsensein BASIC"                                                               - move on the pointer                                           - if the code is 29h ) already jump on to S FLAG 6;     there are no arguments in the FN statement.                            _27D9_SF_ARGMTS (still checking syntax; there are        arguments): call 24FB SCANNING, which checks the syntax of the  next argument expression and puts an FP number form after any   plain number mentioned in it; it leaves the BASIC pointer on thelast code of the expression                                             - if the code at the pointer isn't 2C comma jump on to  SF BRKT 2; there are no more arguments                                  - (more arguments in syntax checking) move the pointer  on again                                                                - loop back to SF ARGMTS to read the next argument.            _27E4_SF_BRKT_2 (still syntax checking, no more          arguments): check if the code is 29h ).                                _27E6_SF_RPRT_C: if there is no match report "Nonsense inBASIC".                                                                _27E9_SF_FLAG_6: move the pointer on again                       - zero bit 6 of FLAGS; string result                            - recover the flag stacked in S FN SBRN; Z indicates a  "$" after the argument letter                                           - if there was a "$" jump on to SF SYN EN                       - (numeric argument) set bit 6 of FLAGS; numeric result.       _27F4_SF_SYN_EN: exit to 2712 S CONT 2.                         _27F7_SF_RUN (run time): move on the BASIC pointer; to   the FN letter                                                           - AND it with 11011111b/DFh to make it upper case               - move on the BASIC pointer                                     - subtract 24h for "$" from the code after the letter;  this makes a string/numeric flag, zero for a string                     - if the result isn't zero jump on to SF ARGMT1;        "numeric" flag                                                          - (zero flag, string argument) move on the pointer past the "$".                                                               _2802_SF_ARGMT1: move on the pointer; to the first code  of the arguments                                                        - save this address; it will be used in SF VALUES below for 5C08 DEFADD                                                         - make a DEF FN pointer just before the address in 5C53 PROG, the start of the program area.                                   _2808_SF_FND_DF: make a statement counter 00 and         comparison byte CE DEF FN                                               - call 1D86 LOOK PROG to find a DEF FN command from     statement zero                                                          - if none is found report "FN without DEF".                    _2814_SF_CP_DEF: stack the pointer to the DEF FN command         - call 2B2B FN SKPOVR to move the DEF FN pointer to the function letter; not 0020 NEXT CHAR, which moves the FN pointer         - AND it with 11011111b/DFh to make it upper case               - if it doesn't match the function letter of the FN jumpon to SF NOT FD                                                         - (the letters match) call 2B2B FN SKPOVR to move the   DEF FN pointer on again                                                 - subtract 24h $ from the code following the DEF FN     letter                                                                  - if it matches the string/numeric flag from the FN     letter jump on to SF VALUES.                                           _2825_SF_NOT_FD (mismatch): recover the pointer to the   DEF FN command                                                          - move it back one                                              - make a statement counter 02                                   - call 198B EACH STMT again to look for the next        statement                                                               - loop back to SF FND DF to look for another DEF FN.           _2831_SF_VALUES (matching DEF FN found): if the string/  numeric signal from the FN letter is zero move on to the next   code; "$" was found after the variable letter, but either way   the DEF FN pointer is now on "("                                        - drop the pointer to the DEF FN token; there is still apointer to DEF FN, on the "(" before the first argument                 - get the FN pointer and put it in 5C5D CH ADD; now     calls to 0020 NEXT CHAR move the FN pointer, calls to 28AB FN   SKPOVR move the DEF FN pointer, and both subroutines skip colourcontrols etc                                                            - move the DEF FN pointer on to the first argument              - if it is on ")" jump on to SF R BR 2; there are no    arguments in the DEF FN statement.                                     _2843_SF_ARG_LP: increment the DEF FN pointer, not       skipping colour controls etc; one after the argument letter             - if the code is a number marker jump on to SF ARG VL   with the signal 01000000b/40h; a numeric argument. There cannot be any colour controls between a numeric argument letter and itsnumber marker                                                           - (number marker not found yet) move the DEF FN pointer back on to the argument letter                                          - move it on one skipping control codes; there could be some between a string argument letter and its "$"                       - increment the pointer; now past the "$", this must be the number marker with the string parameters                            - make the numeric/string flag zero for a string.              _2852_SF_ARG_VL: increment the DEF FN pointer; now on thefirst byte of the FP number form                                        - save this pointer and the numeric/string flag                 - call 24FB SCANNING to evaluate the expression at the  FN pointer in 5C5D CH ADD; it returns with the evaluation on thecalculator stack and a numeric/string flag in bit 6 of FLAGS            - XOR the numeric/string flag from SF ARG LP with the   flag from SCANNING                                                      - AND the result with 01000000b/40h; both flags are in  bit 6, so the XOR will zero bit 6 if they are alike, and the ANDwill make zero if they are alike, 40h if not                            - if the result isn't zero report "Parameter error"; oneis a string, the other numeric                                          - (the evaluation is OK) move 5C65 STKEND back 5 places so as to clear the stack                                                - copy what was the last value on the stack into the 5- byte space in DEF FN; the value of that argument                        - move the DEF FN pointer back one and then on again,   skipping any colour controls which might follow the FP number   form                                                                    - if the next code in DEF FN is 29h ) jump on to SF R BR2; there are no more arguments                                          - (no ")" in DEF FN yet) look at the code in FN                 - if it isn't 2C comma report "Parameter error"; there  are no more arguments in the FN statement                               - move on both DEF FN and FN pointers                           - loop back to SF ARG LP to evaluate the next argument.        _2885_SF_R_BR_2 (closing bracket found in DEF FN): look  at the code in FN                                                       - if it isn't 29h ) report "Parameter error".                  _288D_SF_VALUE (all the arguments on the left-hand side  of the DEF FN statement now have their evaluations recorded in  FP number forms following the argument letter): move the DEF FN pointer into 5C5D CH ADD to make it the BASIC pointer; on the   closing bracket of the left side of the DEF FN statement                - get the address in 5C0B DEFADD and exchange it with   the one on top of the stack; the one from DEFADD is a pointer tothe first argument of any nested DEF FN statement, or zero if   there is none, the one from the stack is a pointer to the first argument of the present DEF FN statement, which was stacked way back in SF ARGMT1                                                       - put the current pointer in 5C08 DEFADD                        - move the BASIC pointer on twice, to the start of the  right side of DEF FN                                                    - call 24FB SCANNING to evaluate the right side of the  DEF FN statement; the result on the calculator stack is the     value of the FN expression                                              - put the BASIC pointer into 5C5D CH ADD; on the ")" of the FN statement, marking the point reached by 24FB SCANNING so far                                                                     - put the stacked DEF FN pointer into 5C08 DEFADD; this points to the first argument of any nested DEF FN statement, or zero if there is none                                                   - move on the BASIC pointer again.                             Exit: from SF VALUES or SF SYN EN, back into the scanningloop at 2712 S CONT 2; the entry point if the next code might bea binary operator.                                                     Output parameters: HL holds the address from 5C5D CH ADD         - A holds the code at that address, the statement       terminator after the FN statement                                       - 5C08 DEFADD has been restored unchanged.                                                                                  SF NOT FD 2825 (25F5 S FN)                                         Jumps from:                                                      2814 SF CP DEF                                                                                                              S FN SBRN 27BD (25F5 S FN)                                         Jumps from:                                                      25F5 S FN                                                                                                                   SF R BR 2 2885 (25F5 S FN)                                         Jumps from:                                                      2831 SF VALUES                                                  2852 SF ARG VL                                                                                                              SF RPRT C 27E6 (25F5 S FN)                                         Jumps from:                                                      27D0 SF BRKT 1                                                                                                              SF RUN 27F7 (25F5 S FN)                                            Jumps from:                                                      27BD S FN SBRN                                                                                                              SF SYN EN 27F4 (25F5 S FN)                                         Jumps from:                                                      27E9 SF FLAG 6                                                                                                              SF VALUE 288D (25F5 S FN)                                          Jumps from:                                                      2885 SF R BR 2                                                                                                              SF VALUES 2831 (25F5 S FN)                                         Jumps from:                                                      2814 SF CP DEF                                                                                                              SGN key (BC) see also commands, functions and operators,    KEYBOARD SCANNING, 022C extended mode table (b)                         The F key in E mode without shift produces the function SGN; it requires one numeric operand X, and the value of the    function is -1 for negative X, zero for zero, and one for       positive X.                                                             On execution, 24FB SCANNING quickly leads to 26DF S     NEGATE. This converts the key code BC first to 0D, then to E9,  and adds the priority 10h/16d. Code and priority 10E9 are now   pushed on to the machine stack (270D S PUSH PO) while the       expression following SGN is evaluated.                                  When the code is taken off the stack (2734 S LOOP), it  is converted (2773 S TIGHTER) from E9 to 29, the calculator     offset for 3492 sgn.                                                                                                                sgn subroutine 3492                                                 Called from 0028 FP CALC with literal 29; the executive subroutine of the SGN X function. Not used in ROM otherwise.    Could be called direct from m/c, with X located anywhere in RAM.        Given X, a 5-byte FP number, it replaces X with one if Xis positive, zero if zero, and -1 if negative. X can be in      either full or "small integer" format, but the result is always a "small integer".                                                     Input parameters: HL points to the first byte of X.             Action: call 34E9 TEST ZERO                                      - if it returns with carry, return without further      action; X is zero                                                       - make a byte 01; the absolute value of the result              - shift the sign byte left into carry                           - use SBC A,A to make a sign flag; zero for a positive, FF for a negative X                                                     - call 2D8E INT STORE; this puts the absolute value on  the stack with the appropriate sign, as a small integer.               Exit: RET.                                                      Output parameters: HL and DE are preserved unchanged.                                                                        shift byte see KEYBOARD SCANNING                                                                                                SHIFT FP subroutine 2FDD see also 335B CALCULATE                    Shifts the true mantissa of a FP number to the right by a specified number of binary places, corresponding to an        adjustment of the exponent made by the calling routine; the     result still expresses the same number 2**E times M, but it     isn't in standard FP format, since M is a true mantissa and may not be between a half and one.                                          This operation is required                                     - in addition, including subtraction, of FP numbers; see 303E FULL ADDN. SHIFT FP performs step 2                               - in printing out FP numbers; see 2ECF PF FRACTN under   the index entry 2DE3 PRINT FP.                                          It is an essentially simple operation, but there are twocomplications:                                                       1. Negative numbers. This isn't a problem for PRINT FP,    which is only concerned with absolute values. For addition/     subtraction the mantissa has been prepared by 2F9B PREP ADD     before SHIFT FP is called. PREP ADD                                      sets the hi bit so that the mantissa is a true         representation of the number                                             negates the mantissa if it is a negative number, ie    subtracts it from 1 00 00 00 00h                                         adds a fifth byte at the start of the mantissa, zero   for a positive number or 11111111b/FFh for a negative number;   thus if the mantissa was C9 0F DA A2, representing -pi/4, it nowbecomes FF 36 F0 25 5E. When the mantissa is shifted right, thissign byte remains unchanged but its lo bit, the_sign_marker_bit,is shifted into the hi bit of the mantissa on each shift.            2. The Spectrum handles numbers with a precision of not    more than 32d binary digits, a bit more than 9 decimal digits.          If right shifting of the binary digits pushes a one intothe 33rd digit, the 32nd digit is rounded up in normal binary   rounding. This could, with a small negative number, and with thesign marker bits coming in from the left, round the whole numberup to zero.                                                             If the right shift called for is more than 32d places,  the result will be indistinguishable from zero, within the      margin of accuracy of the Spectrum; although if the number is   negative, the result may actually be 1111111 ... 11b/FFFFh.             In either case the subroutine sets the result to zero.         Input parameters: A holds the number of shifts to be made        - a_five-byte mantissa, as adjusted by 2F9B PREP ADD, isin the five registers L'D'E'DE; L' is the sign byte.                   Action: if the shift number is zero, return at once; no  shifts to be made                                                       - if the shift number is more than 20h/32d, jump on to  ADDEND 0; more than 32d shifts will make the mantissa zero              - make a shift counter for the loop.                           _2FE5_ONE_SHIFT: shift the sign byte right; copying its  hi bit and shifting its lo bit into carry                               - shift the mantissa bytes right; carry to hi bit, lo   bit to carry each time                                                  - loop back to ONE SHIFT till the shift counter goes to zero