File stakmath.asm * By ASM8 v9.70 Win32 [Saturday, December 31, 2016  2:11 am]

    1                                     ;*******************************************************************************
    2                                     ;* Program   : STAKMATH.ASM
    3                                     ;* Programmer: Tony Papadimitriou <tonyp@acm.org>
    4                                     ;* Purpose   : Test the inclusion of the 64/56/48/40/32/24/16-bit versions of
    5                                     ;*           : STAKMATH.SUB
    6                                     ;* Language  : Motorola/Freescale/NXP HC08/9S08 Assembly Language (aspisys.com/ASM8)
    7                                     ;* Status    : FREEWARE Copyright (c) 2017 by Tony Papadimitriou <tonyp@acm.org>
    8                                     ;* History   : N/A
    9                                     ;*******************************************************************************
   10                                     
   14                                     
*** BEGIN INCLUDE FILE: mcu.inc ***
*** BEGIN INCLUDE FILE: GB60.inc ***
*** BEGIN INCLUDE FILE: macros.inc ***
*** END   INCLUDE FILE: macros.inc *** (RESUMING FILE: GB60.inc)
*** BEGIN INCLUDE FILE: common.inc ***
*** END   INCLUDE FILE: common.inc *** (RESUMING FILE: GB60.inc)
*** END   INCLUDE FILE: GB60.inc *** (RESUMING FILE: mcu.inc)
*** END   INCLUDE FILE: mcu.inc *** (RESUMING FILE: lib/demo/stakmath.asm)
   20                                     
   21                                     ;*******************************************************************************
   22                                     
   23                                     Page                macro     PageNumber
   24                                                         mreq      1:PageNumber
   25                                               #if ~#1~ > 7
   26                                                         merror    PageNumber (~1~) must be in range 0..7
   27                                               #endif
   28                                               #ifmmu
   29                                               #if ~#1~ >= 4
   30                                                         #SEG~1~
   31                                               #else
   32                                                         #ROM
   33                                               #endif
   34                                               #endif
   35                                                         endm
   36                                     
   37                                     ;*******************************************************************************
   38                                     
   39                                     ?                   macro     Bits,Page
   40                                                         @@Page    ~2~
   41                                                         #Uses     lib/stkmth{~1~}.sub
   42                                                         endm
   43                                     
   44                                                         #ROM
   45                182C                 SIGNED
   46                                                         #MapOff
   47  M                                                      @?        32,4
   47  M                                                      @@Page    4
   47  M                                                      mreq      1:PageNumber
   47  M                                                      endm
   47                                                         #Uses     lib/stkmth32.sub
*** BEGIN INCLUDE FILE: lib/stkmth32.sub ***
    1                                     ;*******************************************************************************
    2                                     ;* Module    : STKMTH32.SUB
    3                                     ;* Programmer: Tony Papadimitriou <tonyp@acm.org>
    4                                     ;* Purpose   : Wrapper for 32-bit stack-based basic math routines (RPN style)
    5                                     ;* Language  : Motorola/Freescale/NXP HC08/9S08 Assembly Language (aspisys.com/ASM8)
    6                                     ;* Status    : FREEWARE Copyright (c) 2017 by Tony Papadimitriou <tonyp@acm.org>
    7                                     ;* Original  : http://www.aspisys.com/code/hc08/stkmth32.html
    8                                     ;* Note(s)   : See STAKMATH.SUB for details
    9                                     ;*******************************************************************************
   10                                     
   16                                     
   17                                     ?                   macro
   18                                                         mset      1,~BASENAME~
   19                                     MATHSIZE            set       ~1.{:1-1}~
   20                                                         #Include  stakmath.sub
   21                                                         endm
   22                                     
   23  M                                                      @?
   23  M                                                      mset      1,STKMTH32
   23  M             0020                 MATHSIZE            set       32
   23                                                         #Include  stakmath.sub
*** BEGIN INCLUDE FILE: lib/stakmath.sub ***
    1                                     ;*******************************************************************************
    2                                     ;* Module    : STAKMATH.SUB
    3                                     ;* Programmer: Tony Papadimitriou <tonyp@acm.org>
    4                                     ;* Purpose   : 64/56/48/40/32/24/16-bit stack-based basic math routines (RPN style)
    5                                     ;* Language  : Motorola/Freescale/NXP HC08/9S08 Assembly Language (aspisys.com/ASM8)
    6                                     ;* Status    : FREEWARE Copyright (c) 2017 by Tony Papadimitriou <tonyp@acm.org>
    7                                     ;* Original  : http://www.aspisys.com/code/hc08/stakmath.html
    8                                     ;* Note(s)   : Use: #Include stakmath.sub
    9                                     ;*           :
   10                                     ;*           : Several externally defined macros are used throughout this code.
   11                                     ;*           : All these (and many more) macros are inside the most recent
   12                                     ;*           : version of MACROS.INC which can be copied from the web page at
   13                                     ;*           : http://www.aspisys.com/code/hc08/macros.html
   14                                     ;*           : (and COMMON.INC at http://www.aspisys.com/code/hc08/common.html)
   15                                     ;*           :
   16                                     ;*           : The default word size is 32-bit.
   17                                     ;*           :
   18                                     ;*           : By (re)defining the symbol MATHSIZE (to 16) you get 16-bit code.
   19                                     ;*           : By (re)defining the symbol MATHSIZE to 24 you get 24-bit code.
   20                                     ;*           : By (re)defining the symbol MATHSIZE to 40 you get 40-bit code.
   21                                     ;*           : By (re)defining the symbol MATHSIZE to 48 you get 48-bit code.
   22                                     ;*           : By (re)defining the symbol MATHSIZE to 56 you get 56-bit code.
   23                                     ;*           : By (re)defining the symbol MATHSIZE to 64 you get 64-bit code.
   24                                     ;*           :
   25                                     ;*           : You can include all (or some) versions in your program like so:
   26                                     ;*           :
   27                                     ;*           :                #ROM                ;(or else, some paged memory)
   28                                     ;*           :                #Include  stakmath.sub
   29                                     ;*           : MATHSIZE       set       16        ;redefine for 16-bit use
   30                                     ;*           :                #Include  stakmath.sub
   31                                     ;*           : MATHSIZE       set       24        ;redefine for 24-bit use
   32                                     ;*           :                #Include  stakmath.sub
   33                                     ;*           : MATHSIZE       set       40        ;redefine for 40-bit use
   34                                     ;*           :                #Include  stakmath.sub
   35                                     ;*           : MATHSIZE       set       48        ;redefine for 48-bit use
   36                                     ;*           :                #Include  stakmath.sub
   37                                     ;*           : MATHSIZE       set       56        ;redefine for 56-bit use
   38                                     ;*           :                #Include  stakmath.sub
   39                                     ;*           : MATHSIZE       set       64        ;redefine for 64-bit use
   40                                     ;*           :
   41                                     ;*           : or, if you use the related wrapper files, like so:
   42                                     ;*           :
   43                                     ;*           :                #ROM                ;(or else, some paged memory)
   44                                     ;*           :                #Uses     stkmth16.sub
   45                                     ;*           :                #Uses     stkmth24.sub
   46                                     ;*           :                #Uses     stkmth32.sub
   47                                     ;*           :                #Uses     stkmth40.sub
   48                                     ;*           :                #Uses     stkmth48.sub
   49                                     ;*           :                #Uses     stkmth56.sub
   50                                     ;*           :                #Uses     stkmth64.sub
   51                                     ;*           :
   52                                     ;*           : Use CALL if assembled in #MMU mode (regardless of placement).
   53                                     ;*           : By using CALL and #JUMP (or default -J+ command line option), the
   54                                     ;*           : assembler will automatically adjust between CALL and JSR
   55                                     ;*           : depending on the current #MMU mode.
   56                                     ;*           :
   57                                     ;*           : To use the *-bit version of each CALL, use these symbols:
   58                                     ;*           :
   59                                     ;*           : StackAdd*, StackSub*, StackMul*, StackDiv*, StackMod*
   60                                     ;*           : StackSwap*, StackNegate*, StackLoad*, StackSave*,
   61                                     ;*           : Stack*ToASCIZ
   62                                     ;*           :
   63                                     ;*           : replacing * with one of these: 16, 24, 32, 40, 48, 56, or 64.
   64                                     ;*           :
   65                                     ;*           : Various macros allow using these routines in a variety of ways,
   66                                     ;*           : and without worrying about the details of call & parameter setup.
   67                                     ;*           : These macros are: Add*, Sub*, Mul*, Div*, Mod*, DivS*, ModS*,
   68                                     ;*           : Neg*, Load*, Save*, Str*, StrS*, and Swap* (where the * is 16,
   69                                     ;*           : 24, 32, 40, 48, 56, or 64 depending on the version you want to use).
   70                                     ;*           : The signed versions are enabled only when the module is assembled
   71                                     ;*           : with the SIGNED conditional.
   72                                     ;*           :
   73                                     ;*           : If working with fixed-address variables, you can use the various
   74                                     ;*           : macros (such as Add32, Mul64, etc.) to perform operations in the
   75                                     ;*           : easiest possible way, such as:
   76                                     ;*           :                @Mul32    A,B,Answer
   77                                     ;*           : (which multiplies A with B and stores the product in Answer).
   78                                     ;*           : But, you may also use the macros to work directly on stack, or to
   79                                     ;*           : temporarily save partial results on stack instead of fixed vars.
   80                                     ;*           :
   81                                     ;*           :                  I N   G E N E R A L   T H E N
   82                                     ;*           :
   83                                     ;*           : @Operation A,B,Answer works with A and B storing result in Answer
   84                                     ;*           : @Operation A,B        works with A and B leaving result on stack
   85                                     ;*           : @Operation A          works with TOS and A, result left as TOS
   86                                     ;*           : @Operation (no parms) works w/ TOS and [TOS+1], result as new TOS
   87                                     ;*           :
   88                                     ;*           : (Please note the shown order of the operation may be important.)
   89                                     ;*           :
   90                                     ;*           : Finally, the Load* (* = 16, 24, 32, 40, 48, 56, 64) operation can
   91                                     ;*           : directly load either a variable or a constant (leading #) on the
   92                                     ;*           : stack.
   93                                     ;*           :
   94                                     ;*           : Since v7.00, a HLL-like interface is possible by using the new
   95                                     ;*           : Eval* macro (where * = 8, 16, 24, 32, 40, 48, 56, 64)
   96                                     ;*           : This is by far the easiest way to use this library, as it closely
   97                                     ;*           : resembles using expressions in a HLL compiler.  It also can
   98                                     ;*           : automatically resize stack after loading from and before saving
   99                                     ;*           : to any variable.
  100                                     ;*           :
  101                                     ;*           : Examine the test section of this file for examples of macro use.
  102                                     ;*           :
  103                                     ;*           : All routines are re-entrant and work on either the top-of-stack
  104                                     ;*           : (TOS) number alone or the two top-most TOS numbers.  Similar to
  105                                     ;*           : how Reverse Polish Notation (RPN) works.  First, you stack the
  106                                     ;*           : operand(s) and then call the corresponding routine to perform the
  107                                     ;*           : operation.
  108                                     ;*           :
  109                                     ;*           : The result of any operation is always the updated top of stack.
  110                                     ;*           : For operations that require two operands and produce a single
  111                                     ;*           : result, the result replaces the two operands (stack is reduced).
  112                                     ;*           :
  113                                     ;*           : Chain calculations are possible by pushing only the new operand
  114                                     ;*           : between operations.  Alternatively, one can push all operands in
  115                                     ;*           : advance but it's not recommended as stack space may be limited.
  116                                     ;*           : When done evaluating an expression, just pull the final 32-bit
  117                                     ;*           : result from the stack.
  118                                     ;*           :
  119                                     ;*           : The TOS is the first (or only) operand of any operation.
  120                                     ;*           : This is important, for example, for subtraction and division.
  121                                     ;*           :
  122                                     ;*           : If the current order of the stack is not as you want it, use the
  123                                     ;*           : Swap (StackSwap32) operation to change it.
  124                                     ;*           :
  125                                     ;*           : All operands and results are exactly 32-bit wide.  Overflows are
  126                                     ;*           : simply truncated.  The lower 32-bit number is valid, though.
  127                                     ;*           :
  128                                     ;*           : (All references to 32-bit become 16-bit, when MATHSIZE = 16)
  129                                     ;*           : (All references to 32-bit become 24-bit, when MATHSIZE = 24)
  130                                     ;*           : (All references to 32-bit become 40-bit, when MATHSIZE = 40)
  131                                     ;*           : (All references to 32-bit become 48-bit, when MATHSIZE = 48)
  132                                     ;*           : (All references to 32-bit become 56-bit, when MATHSIZE = 56)
  133                                     ;*           : (All references to 32-bit become 64-bit, when MATHSIZE = 64)
  134                                     ;*           :
  135                                     ;*           : 64/56/48/40-bit multiplication is done using the shift-add method,
  136                                     ;*           : which is much shorter in size for such long operands, but it is
  137                                     ;*           : also significantly slower in speed. I opted for size optimization
  138                                     ;*           : because the 64/56/48/40-bit versions are not used quite as often.
  139                                     ;*           : You may want to re-write it for speed optimization by using the
  140                                     ;*           : MUL instruction like it is done for the default 32-bit case.
  141                                     ;*           :
  142                                     ;* History   : 09.05.22 v1.00 Original (Started on 2009.05.07)
  143                                     ;*           : 09.06.04       Optimized by using HX instead of SP, where needed
  144                                     ;*           : 09.11.04       Minor optimizations
  145                                     ;*           : 09.11.05       Add & Subtract now adjust Carry accordingly
  146                                     ;*           :                Division by zero error now checked first
  147                                     ;*           : 09.11.06 v1.01 Added conditional MATHSIZE for use w/ 16-bit words
  148                                     ;*           : 09.11.08 v1.02 Added "Load" operation to ease stack loading
  149                                     ;*           : 09.11.11       Use of new LONG pseudo-opcode
  150                                     ;*           : 09.12.05       Added cycles display using :cycles
  151                                     ;*           : 10.01.06 v1.03 Added MMU auto-support (using :AB internal symbol)
  152                                     ;*           :                Code is no longer placed in #ROM by default
  153                                     ;*           :                The few JMPs in the code use [[ to trim possible page
  154                                     ;*           : 10.01.08       [[ removed from JMPs (latest ASM8 auto-correction)
  155                                     ;*           : 10.01.22 v1.04 Added Save operation for completeness
  156                                     ;*           : 10.01.23 v1.05 Added #SP directive examples (latest ASM8)
  157                                     ;*           : 10.01.29 v1.06 Added shorter/faster Swap version for 9S08 MCUs
  158                                     ;*           : 10.02.01 v1.07 Added #SPAUTO directive
  159                                     ;*           : 10.02.04       Added #X directive
  160                                     ;*           : 10.02.06 v2.00 Added signed math wrapper calls only for DIV & MOD
  161                                     ;*           :                (Addition, Subtraction, and Multiplication calls
  162                                     ;*           :                work either for unsigned or signed operands.)
  163                                     ;*           :                Signed routines enabled w/ SIGNED conditional.
  164                                     ;*           :                Division by zero error now reduces stack (operand
  165                                     ;*           :                A removed) so that the stack is left with same
  166                                     ;*           :                size on either success or failure (in which case
  167                                     ;*           :                the TOS result is invalid.)
  168                                     ;*           : 10.02.08 v2.01 Fixed signed MOD for correct sign (sign of A)
  169                                     ;*           : 10.02.14 v2.10 Added Stack32ToASCIZ and prerequisite StringInsertChar
  170                                     ;*           : 10.02.28 v2.11 Minor optimization in StringInsertChar
  171                                     ;*           : 10.03.23       Made use of :: internal variable (Build 2010/03/23)
  172                                     ;*           : 10.03.30 v2.12 Allowed for HC08 compilation in newer code (?ToStr)
  173                                     ;*           :                Optimized 9S08 Swap version for size and speed
  174                                     ;*           :          v2.13 Optimized Negate for size and speed
  175                                     ;*           : 10.05.08 v3.00 Added MATHSIZE = 64 option for 64-bit math
  176                                     ;*           :                Swap operation optimized only for size
  177                                     ;*           : 10.05.13 v3.01 Optimized for size and speed by using ,SPX
  178                                     ;*           : 10.06.02 v4.00 Added macros for easier use
  179                                     ;*           : 10.06.08 v4.10 Improved macros and added new ones (eg Const32)
  180                                     ;*           : 10.06.23 v4.20 Added MATHSIZE = 48 option for 48-bit math
  181                                     ;*           : 10.06.30 v4.30 Added AddDecimalPoint (to string number)
  182                                     ;*           : 10.07.01 v4.40 Added IFSPAUTO conditional
  183                                     ;*           : 10.07.03       Moved the functionality of Const macros into Load
  184                                     ;*           : 10.07.07       Moved general string routines first
  185                                     ;*           : 10.07.17 v4.50 Str* macros may use TOS (if Number parm is missing)
  186                                     ;*           :                or current HX index (if result pointer is missing)
  187                                     ;*           : 10.07.20       _DoLoad*/_DoSave* address now allows for indexed mode
  188                                     ;*           : 10.07.21       Minor optimizations; macros now latest ASM8
  189                                     ;*           : 10.07.23       Minor bug fix in macro _DoSave for no parm case
  190                                     ;*           : 10.08.18       Optimized by using :MINDEX in latest ASM8
  191                                     ;*           : 10.08.26       Minor optimizations at the source level
  192                                     ;*           : 10.08.31 v4.60 Optimized Load* macros' immediate mode for zeros
  193                                     ;*           : 10.10.19 v4.61 Adapted to latest ASM8 (nested macros in Load)
  194                                     ;*           : 10.10.22 v4.62 Optimized _DoMath (Added @_DoOperation)
  195                                     ;*           : 10.10.26 v4.63 Load48 & Load64 now also accept single #Constant
  196                                     ;*           : 10.12.03 v4.64 Adapted to latest ASM8 => macros OK in @@ sub-mode
  197                                     ;*           : 11.03.31 v4.65 Moved test code at EOF (to use #EXIT optimization)
  198                                     ;*           : 11.04.10 v4.66 Condensed macro definitions (based on MATHSIZE)
  199                                     ;*           : 11.04.11 v4.67 Optimized MUL16/MUL32 size & cycles with ,SPX mode
  200                                     ;*           : 11.04.12 v4.70 Added MATHSIZE = 24 option for 24-bit math
  201                                     ;*           : 11.04.13 v4.71 Reversed some of v4.66's changes
  202                                     ;*           : 11.04.13 v4.80 Added MATHSIZE = 40 option for 40-bit math
  203                                     ;*           : 11.05.02 v4.81 Save protects HX (it was lost during SP => SPX)
  204                                     ;*           : 11.05.05 v4.82 Optimized StringLength by a byte (by using NEGA on exit)
  205                                     ;*           : 11.05.25 v4.83 Removed unused Zero constant from test code
  206                                     ;*           : 11.10.13 v4.84 Optimized MUL16/24/32 size w/ more ,SPX (same cycles)
  207                                     ;*           : 11.11.15 v4.85 Improved StringLength macro
  208                                     ;*           : 12.01.26       Changed test code a bit
  209                                     ;*           : 12.02.06 v4.86 Optimized SP => SPX at ?RemoveAndReturn
  210                                     ;*           : 12.03.05 v4.87 Added ResizeTOS to adjust TOS element's size
  211                                     ;*           : 12.05.09 v4.88 Added CCR[C] parameter to ResizeTOS for unsigned operation
  212                                     ;*                            (signed is default when SIGNED conditional is defined,
  213                                     ;*                            unsigned operation is default, otherwise)
  214                                     ;*           : 12.05.18 v4.89 Removed redundant subtraction in Division (at NotEqual@@)
  215                                     ;*           : 12.10.07 v4.90 Load*/Save* now accept indexed mode without separator override
  216                                     ;*           : 12.10.10 v5.00 Renamed to (more general) STAKMATH.SUB to use
  217                                     ;*           :                wrapper files for each bit version, instead.
  218                                     ;*           : 12.11.05       Added _STKMTH{MATHSIZE}_ for used-version control
  219                                     ;*           : 12.11.09 v6.00 New _LoadStkMthVarAddr macro eases parm address
  220                                     ;*           :                calculation.
  221                                     ;*           : W A R N I N G: SP-based operands now refer to the actual number,
  222                                     ;*           : W A R N I N G: and not its address (as was the case before).
  223                                     ;*           : W A R N I N G: This is INCOMPATIBLE with previous behavior. Code
  224                                     ;*           : W A R N I N G: written for version v5.00 or earlier that uses SP
  225                                     ;*           : W A R N I N G: based operands should be modified to refer to the
  226                                     ;*           : W A R N I N G: actual value and not to a pointer to the value.
  227                                     ;*           : W A R N I N G: Dot-beginning names are still treated as pointers!
  228                                     ;*           : 12.11.10       Use COMMON.INC/LEA instead of _LoadStkMthVarAddr
  229                                     ;*           : 12.12.04 v6.10 Optimized division just a tad by combining steps
  230                                     ;*           : 12.12.12 v6.20 Now use LEA macro inside _DoStr (for ResultString)
  231                                     ;*           : 12.12.20 v6.21 Minor optimization (one byte) in 32-bit ?Multiply
  232                                     ;*           :                (Further 3-byte optimization possible by
  233                                     ;*           :                re-ordering MULs, but not done for code clarity)
  234                                     ;*           : 13.01.09 v6.22 Added Copy* macros to combine Load*/Save* into one
  235                                     ;*           : 13.03.20 v7.00 Added Eval* and supporting macros for HLL-like
  236                                     ;*           :                computations, eg., ans=(a+3)*((1+var,sp)/2)
  237                                     ;*           :                (with or without spaces between operands/operators)
  238                                     ;*           : 13.03.27 v7.50 SIGNED now gives just signed (not unsigned) version
  239                                     ;*           :                DivS*, ModS*, StrS* macros were removed, and also
  240                                     ;*           :                ResizeTOS macro's unsigned flag has been removed
  241                                     ;*           :                BugFix: AddDecimalPoint now prepends zeros after sign
  242                                     ;*           : 13.03.27       Optimized ?Negate in SIGNED case to use ?NegX sub
  243                                     ;*           : 13.03.27 v7.60 Adapted _EVAL_ macro to latest ASM8 (Much faster!)
  244                                     ;*           : 13.04.04 v7.70 _DoLoad and _DoSave macros now auto-adjust the size
  245                                     ;*           :                so you can use with operands of different sizes, even
  246                                     ;*           :                if the respective bitsize version isn't loaded.
  247                                     ;*           : 13.04.04 v7.71 _Eval_ macro leaves assignment result on TOS if
  248                                     ;*           :                assignment variable not already defined.  Then,
  249                                     ;*           :                it gives TOS the specified name, if SP-indexed.
  250                                     ;*           : 13.04.05 v7.72 Added #size for v7.71 change
  251                                     ;*           :                Named constants (labels with size zero) now use
  252                                     ;*           :                immediate mode in Eval/Load
  253                                     ;*           : 13.04.05 v7.73 Added NEG() negate, and ABS() absolute functions
  254                                     ;*           :                in Eval macro, e.g., ans = abs(a - b)
  255                                     ;*           : 13.04.09 v7.80 BugFix: Push/Pull macro calls for SP mode
  256                                     ;*           :                Moved immediate mode to _DoLoad (unified method)
  257                                     ;*           :                (Over 32-bit immediate value loads not possible
  258                                     ;*           :                via macros)
  259                                     ;*           : 13.04.10       Adapted to v9.35 (no functional changes)
  260                                     ;*           : 13.04.11 v7.81 Optimized _DoLoad constant loading by using CLRH
  261                                     ;*           :                (optimization is evident on certain cases only)
  262                                     ;*           : 13.04.15 v7.82 Added _?SEI_ and _?CLI_ macros for multitasker
  263                                     ;*           :                locking / unlocking of multi-byte variables while
  264                                     ;*           :                loading / saving (_DoLoad/_DoSave).  Under OS8 it
  265                                     ;*           :                is enabled automatically.  Otherwise, simply
  266                                     ;*           :                define _MTOS_ anytime before including this file.
  267                                     ;*           :                For keeping code dense, all Eval*/Load*/Save*
  268                                     ;*           :                macros are assumed to be called only while
  269                                     ;*           :                interrupts are enabled, so it will not restore to
  270                                     ;*           :                previous state but always leave as enabled.
  271                                     ;*           :                Define _NOCLI_ (before including this module) for
  272                                     ;*           :                canceling the _?SEI_ and _?CLI_ macro effects.
  273                                     ;*           : 13.04.18 v7.85 Added 'NeedMath' and 'Eval' general-purpose macros
  274                                     ;*           :                for automatic selection of needed bit-size based
  275                                     ;*           :                on only which modules are already included. First,
  276                                     ;*           :                call the NeedMath macro to define the minimum math
  277                                     ;*           :                bit-size you need for the next calculation(s),
  278                                     ;*           :                then call the Eval macro as many times as needed
  279                                     ;*           :                to perform the actual expression evaluation(s).
  280                                     ;*           :                Similary, added new macros Load, Save, StkAdd,
  281                                     ;*           :                StkSub, StkMul, StkDiv, StkMod, StkSwap, StkNeg,
  282                                     ;*           :                StkAbs, StkStr, and CopyMath to work with the
  283                                     ;*           :                NeedMath macro, just like the new Eval macro.
  284                                     ;*           : 13.04.19 v8.00 Moved all Eval* macros into COMMON.INC and allowed
  285                                     ;*           :                for all to be active at all times, regardless if
  286                                     ;*           :                the related bit-version of STAKMATH is included.
  287                                     ;*           :                The _Eval_ macro was improved to allow it to
  288                                     ;*           :                automatically locate the next higher version that
  289                                     ;*           :                is included, if the one requested is not.  So,
  290                                     ;*           :                using Eval32 will use the 32/40/48/64-bit version
  291                                     ;*           :                (whichever is closer to 32 and included) but nothing
  292                                     ;*           :                below 32-bit.  This allows you to use the relevant
  293                                     ;*           :                macro based on a specific expression's requirements
  294                                     ;*           :                but include only one (or just a few) higher bit
  295                                     ;*           :                version(s), not all those referenced in your code.
  296                                     ;*           :                (The general Eval is still available, if needed.)
  297                                     ;*           :                Also, moved all Str* to COMMON.INC
  298                                     ;*           : 13.04.21 v8.10 Corrected v8.00 for pointer cases (.num) to use
  299                                     ;*           :                actual requested size, not next higher.
  300                                     ;*           :                Relevant #Message now in _DoOperation _ResizeTOS etc.
  301                                     ;*           : 13.04.21 v8.11 NeedMath & related macros removed (now redundant)
  302                                     ;*           :                General Eval macro will try to determine best bit-size
  303                                     ;*           : 13.04.23 v8.12 Added EvalS to first check for SIGNED and then call Eval
  304                                     ;*           :                CopyMath removed.  Use "Eval to_var = from_var" instead
  305                                     ;*           :                _StkMthMax_ improved to use higher size on multiplication
  306                                     ;*           : 13.04.25 v8.13 _Eval_ now allows for string constants (eg., @Eval ans = ans + '0')
  307                                     ;*           :                Removed all ?macros because we now use COMMON xxx.s macros
  308                                     ;*           : 13.04.26 v8.15 Corrected test code for Eval when MATHSIZE < 32
  309                                     ;*           :                Commented out auto-higher bit-size (a bit annoying).
  310                                     ;*           :                Use Eval* to say 'no less than', instead.
  311                                     ;*           : 13.04.27 v8.16 BugFix: StrMath macro (2nd parameter was lost)
  312                                     ;*           :                Added SQR() function to get the square
  313                                     ;*           : 13.05.02       Added #size in ToInt* macros (in test code)
  314                                     ;*           : 13.05.03 v8.17 Added size optimization for ADD and SUB operations
  315                                     ;*           :                New SPEED_SIZE constant in COMMON.INC tells us
  316                                     ;*           :                whether we need speed (SPEED_SIZE = 1) or
  317                                     ;*           :                size (SPEED_SIZE = 2) optimization, the current
  318                                     ;*           :                default being SPEED_SIZE = 2 for size optimization.
  319                                     ;*           : 13.05.30       Updated StrMath macro (COMMON.INC and here)
  320                                     ;*           : 13.06.04 v8.20 Added bit functions: AND (&), OR (|), XOR (^), and shifts (< and >)
  321                                     ;*           : 13.06.05 v8.21 BugFix: ShiftRight now uses ASR if SIGNED
  322                                     ;*           : 13.07.25 v8.22 Improved _Eval_ macro (and Push/Pull in COMMON.INC)
  323                                     ;*           :                BugFix: Added { } to ResizeTOS macro's final case
  324                                     ;*           :                (Disable bit functions with NO_BIT_OPS conditional)
  325                                     ;*           : 13.10.06       Minor changes in test code
  326                                     ;*           : 13.11.26       Added warning in _DoLoad: forwards treated as vars
  327                                     ;*           : 13.11.29 v8.23 Optimized ?ShiftLeft and ?ShiftRight a bit
  328                                     ;*           : 13.12.22 v8.30 Added 56-bit version
  329                                     ;*           : 14.01.03       Made use of _CMP_.S macro (instead of custom macro)
  330                                     ;*           : 14.02.07 v8.50 Added [ ... ] unsigned override (if SIGNED)
  331                                     ;*           : 14.02.14 v8.51 Eval macro now uses #HideMacros
  332                                     ;*           : 14.10.14 v8.52 BugFix: Off-by-one error in ResizeTOS when SIGNED
  333                                     ;*           : 15.03.21 v8.53 Replaced string dependencies with corresponding #Uses
  334                                     ;*           : 15.04.08 v8.54 Replaced AddDecimalPoint with corresponding #Uses
  335                                     ;*******************************************************************************
  336                                     
  337                                     ;Synopsis (replace * with 16, 24, 32, 40, 48, 56, 64 for corresponding bit version):
  338                                     ;
  339                                     ;Subroutines    Action
  340                                     ;-------------- ----------------------------
  341                                     ;StackAdd*      - TOS := TOS + [TOS+1]       (signed or unsigned) [TOS+1] removed
  342                                     ;StackSub*      - TOS := TOS - [TOS+1]       (signed or unsigned) [TOS+1] removed
  343                                     ;StackMul*      - TOS := TOS * [TOS+1]       (signed or unsigned) [TOS+1] removed
  344                                     ;StackDiv*      - TOS := TOS / [TOS+1]       (signed if SIGNED)   [TOS+1] removed
  345                                     ;StackMod*      - TOS := TOS \ [TOS+1]       (signed if SIGNED)   [TOS+1] removed
  346                                     ;StackAnd*      - TOS := TOS & [TOS+1]       (signed or unsigned) [TOS+1] removed
  347                                     ;StackOr*       - TOS := TOS | [TOS+1]       (signed or unsigned) [TOS+1] removed
  348                                     ;StackXor*      - TOS := TOS ^ [TOS+1]       (signed or unsigned) [TOS+1] removed
  349                                     ;StackShl*      - TOS := TOS < [TOS+1]       (signed or unsigned) [TOS+1] removed
  350                                     ;StackShr*      - TOS := TOS > [TOS+1]       (signed if SIGNED)   [TOS+1] removed
  351                                     ;StackSwap*     - TOS swapped with [TOS+1]   (signed or unsigned)
  352                                     ;StackAbs*      - TOS := ABS(TOS)            (signed)
  353                                     ;StackNegate*   - TOS := -TOS                (signed)
  354                                     ;StackLoad*     - Load const/variable to TOS (signed or unsigned) TOS created
  355                                     ;StackSave*     - Save TOS into variable     (signed or unsigned) TOS removed
  356                                     ;ResizeTOS      - Adjust TOS old size to new (signed or unsigned) TOS resized
  357                                     ;Stack*ToASCIZ  - Convert TOS to ASCIZ str   (signed if SIGNED)
  358                                     ;
  359                                     ;Macros             Purpose             Parameters ([...] means optional part)
  360                                     ;------------------ ------------------- ----------------------------------------
  361                                     ;Load*              Stack const or var  #Number | Variable
  362                                     ;Save*              Unstack a variable  Variable
  363                                     ;Copy*              Load* & Save*       #Number | Variable,Variable
  364                                     ;ResizeTOS          Resize TOS          #FromByteSize,#ToByteSize
  365                                     ;
  366                                     ;Add*               Addition            [Addend[,Adder[,Sum]]]
  367                                     ;Sub*               Subtraction         [Minuend[,Subtrahend[,Difference]]]
  368                                     ;Mul*               Multiplication      [Multiplicand[,Multiplier[,Product]]]
  369                                     ;Div*               Unsigned division   [Dividend[,Divisor[,Quotient]]]
  370                                     ;Mod*               Unsigned modulo     [Dividend[,Divisor[,Remainder]]]
  371                                     ;Abs*               Absolute value      [SourceVariable][,DestinationVariable]
  372                                     ;Neg*               Negation            [SourceVariable][,DestinationVariable]
  373                                     ;Swap*              Swap TOS numbers
  374                                     ;Str*               Number to ASCIZ     [Variable],[ResultString]
  375                                     ;AddDecimalPoint    ... to ASCIZ number [[#]DecimalPlaces[,[#]ASCIZ_String]]
  376                                     
  403                                     
  404                0020                 MATHSIZE            def       32                  ;default wordsize is 32-bit
  405                                     
  409                                     
  410                                     ?                   macro     BitSize
  411                                     #if MATHSIZE = ~1~
  412                                     ?WORD               equ       ~1~/8
  413                                     _STKMTH{MATHSIZE}_                                ;;specific version included
  414                                     _STAKMATH_          def       *                   ;;any version included
  415                                     #endif
  416                                                         endm
  417                                     
  418  M                                                      @?        16                  ;16-bit quantity (on request)
  418                                                         endm
  419  M                                                      @?        24                  ;24-bit quantity (on request)
  419                                                         endm
  420  M                                                      @?        32                  ;32-bit quantity (default)
  420  M             0004                 ?WORD               equ       32/8
  420  M             182C                 _STKMTH32_
  420  M             182C                 _STAKMATH_          def       *
  420                                                         endm
  421  M                                                      @?        40                  ;40-bit quantity (on request)
  421                                                         endm
  422  M                                                      @?        48                  ;48-bit quantity (on request)
  422                                                         endm
  423  M                                                      @?        56                  ;56-bit quantity (on request)
  423                                                         endm
  424  M                                                      @?        64                  ;64-bit quantity (on request)
  424                                                         endm
  425                                     
  431                                                         #Message  MATHSIZE = {MATHSIZE}-bit version
  432                                     
  434                                                         #Message  Signed routines enabled
  436                                     
  437                                     ;*******************************************************************************
  438                                     ; Macros to make operations as simple as with a high-level language
  439                                     ; In operations that require two operands and a result, if only one operand is
  440                                     ; provided, then the operation is done completely on stack (no other variables
  441                                     ; used).  For example, @Add32 A,B,SUM adds A to B and places result in SUM,
  442                                     ; while @Add32 A adds the current stack top to A and leaves result on stack.
  443                                     ; You can use @Load* and @Save* to load the initial value, and store the final
  444                                     ; result, respectively.  (Replace * with 16, 24, 32, 40, 48, 56, or 64)
  445                                     ;*******************************************************************************
  446                                     
  495                                     ;-------------------------------------------------------------------------------
  544                                     ;-------------------------------------------------------------------------------
  546                                     
  547                                     Load32              macro     #Number|Variable    ;load constant or variable
  548                                                         @_DoLoad  ~0.{:0-1}~~@~
  549                                                         endm
  550                                     
  551                                     Save32              macro     Address
  552                                                         @_DoSave  32~@~
  553                                                         endm
  554                                     
  555                                     Copy32              macro     #Constant|Variable,ToAddress
  556                                                         mreq      1,2:#Constant|Variable,ToAddress
  557                                                         @@Load32  ~1~
  558                                                         @Save32   ~2~
  559                                                         endm
  560                                     
  561                                     Swap32              macro
  562                                                         @_DoSwap  32
  563                                                         endm
  564                                     
  565                                     Add32               macro     Addend,Adder,Sum
  566                                                         @_DoMath  ~0~32~1~~2~~3~
  567                                                         endm
  568                                     
  569                                     Sub32               macro     Minuend,Subtrahend,Difference
  570                                                         @_DoMath  ~0~32~1~~2~~3~
  571                                                         endm
  572                                     
  573                                     Mul32               macro     Multiplicand,Multiplier,Product
  574                                                         @_DoMath  ~0~32~1~~2~~3~
  575                                                         endm
  576                                     
  577                                     Div32               macro     Dividend,Divisor,Quotient
  578                                                         @_DoMath  ~0~32~1~~2~~3~
  579                                                         endm
  580                                     
  581                                     Mod32               macro     Dividend,Divisor,Remainder
  582                                                         @_DoMath  ~0~32~1~~2~~3~
  583                                                         endm
  584                                     
  585                                     Abs32               macro     Source[,Destination]
  586                                                         @_DoAbs   32~1~~2~
  587                                                         endm
  588                                     
  589                                     Neg32               macro     Source[,Destination]
  590                                                         @_DoNeg   32~1~~2~
  591                                                         endm
  593                                     ;-------------------------------------------------------------------------------
  642                                     ;-------------------------------------------------------------------------------
  691                                     ;-------------------------------------------------------------------------------
  740                                     ;-------------------------------------------------------------------------------
  789                                     
  790                                     ;*******************************************************************************
  791                                     ; Common macro(s) for all operations defined above (not to be called directly)
  792                                     ;*******************************************************************************
  793                                     
  795                                     _signed_            macro
  796                                               #ifndef SIGNED
  797                                                         #Warning  SIGNED \@~mfilename~\@ expected
  798                                               #endif
  799                                                         endm
  801                                     
  802                                     ;-------------------------------------------------------------------------------
  803                                     
  863                                     
  864                                     ;-------------------------------------------------------------------------------
  865                                     
  888                                     
  889                                     ;-------------------------------------------------------------------------------
  890                                     
  898                                     
  899                                     ;-------------------------------------------------------------------------------
  900                                     
  918                                     
  919                                     ;===============================================================================
  920                                     
  937                                     
  938                                     ;-------------------------------------------------------------------------------
  939                                     
 1164                                     ;-------------------------------------------------------------------------------
 1166                                     _?sei_              macro
 1167                                               #ifdef _NOCLI_
 1168                                                         mexit
 1169                                               #endif
 1170                                               #ifndef _MTOS_
 1171                                                         mexit
 1172                                               #endif
 1173                                                         mset      #
 1174                                               #ifnb ~','2~ = sp
 1175                                                         mexit
 1176                                               #endif
 1177                                               #ifnb ~','2~ = spx
 1178                                                         mexit
 1179                                               #endif
 1180                                               #ifnb ~','2~ = psp
 1181                                                         mexit
 1182                                               #endif
 1183                                               #ifdef ~1,~
 1184                                                 #if ::~1,~ < 2
 1185                                                         mexit
 1186                                                 #endif
 1187                                               #endif
 1188                                                         sei
 1189                                                         endm
 1191                                     ;-------------------------------------------------------------------------------
 1193                                     _?cli_              macro
 1194                                               #ifdef _NOCLI_
 1195                                                         mexit
 1196                                               #endif
 1197                                               #ifndef _MTOS_
 1198                                                         mexit
 1199                                               #endif
 1200                                                         mset      #
 1201                                               #ifnb ~','2~ = sp
 1202                                                         mexit
 1203                                               #endif
 1204                                               #ifnb ~','2~ = spx
 1205                                                         mexit
 1206                                               #endif
 1207                                               #ifnb ~','2~ = psp
 1208                                                         mexit
 1209                                               #endif
 1210                                               #ifdef ~1,~
 1211                                                 #if ::~1,~ < 2
 1212                                                         mexit
 1213                                                 #endif
 1214                                               #endif
 1215                                                         cli
 1216                                                         endm
 1218                                     ;-------------------------------------------------------------------------------
 1220                                     _DoLoad             macro     BitSize[,Variable]  ;if no Variable, wherever HX points
 1221                                               #if :macronest = 1
 1222                                                         #Warning  Macro NOT to be called directly
 1223                                               #endif
 1224                                                         mreq      1:BitSize[,Variable]
 1225                                                         #temp     ~1~/8               ;;bytesize now in :temp
 1226                                                         mdel      1                   ;;get rid of bitsize parm
 1227                                                         mset      #                   ;;unite all parms into one
 1228                                                         mtrim     1
 1229                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 1230                                                         mset      9                   ;;assume signed (when SIGNED)
 1231                                               #ifparm ~1.1.1~~1.{:1}~ = []
 1232                                                         mset      9,unsigned
 1233                                                         mset      1,~1.2.{:1-2}~
 1234                                               #endif
 1235                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 1236                                                         @@_not_x_ ~1~                 ;;X-mode not allowed
 1237                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 1238                                               #ifnum ~1~
 1239                                                         mset      1,#~1~              ;;numerics use immediate mode
 1240                                               #endif
 1241                                               #ifb ~,1~
 1242                                                 #ifdef ~#1~
 1243                                                   #ifz ::~#1~
 1244                                                         mset      1,#~#1~             ;;named constants use immediate mode
 1245                                                   #endif
 1246                                                 #endif
 1247                                               #endif
 1248                                               #ifnb ~#~                               ;;process immediate mode
 1249                                                         #Message  Load{:temp*8} ~1~
 1250                                                         mset      1,~#1~
 1251                                                         mset      0                   ;;use as flag for CLRH usage
 1252                                                         mdo
 1253                                                 #ifz ~#1~>{:mloop-1*8}&$FF
 1254                                                   #ifz :text
 1255                                                         clrh
 1256                                                         mset      0,clrh              ;;flag CLRH was used
 1257                                                   #endif
 1258                                                         pshh
 1259                                                 #else
 1260                                                         ldx       #~#1~>{:mloop-1*8}&$FF
 1261                                                         pshx
 1262                                                 #endif
 1263                                                         mloop     :temp
 1264                                                         mexit
 1265                                               #endif
 1266                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 1267                                               #ifnb ~1,~
 1268                                                 #ifb ~1.1.1~ = .                      ;;except for pointers
 1269                                                   #ifnz ::~1,~                        ;;and constants
 1270                                                     #if ::~1,~ <> :temp               ;;different-size variables
 1271                                                         @@_?sei_  ~1~
 1272                                                         @@pushv   ~1~                 ;;are pushed and then resized
 1273                                                         @@_?cli_  ~1~
 1274                                                         @ResizeTOS #{::~1,~}#{:temp}~9~
 1275                                                         mexit
 1276                                                     #endif
 1277                                                   #endif
 1278                                                 #endif
 1279                                               #endif
 1280                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 1281                                               #ifndef ~1,~
 1282                                                         #Warning  Loading forward \@~1,~\@ as var
 1283                                               #endif
 1284                                                         #Message  Load{:temp*8} ~1~
 1285                                                         @@lea     ~1~                 ;;default case
 1286                                                         @@_?sei_  ~1~
 1287                                                         call      StackLoad{:temp*8}  ;;load as is
 1288                                                         @@_?cli_  ~1~
 1289                                               #ifspauto
 1290                                                         #spadd    :temp
 1291                                               #endif
 1292                                                         endm
 1294                                     ;-------------------------------------------------------------------------------
 1296                                     _DoSave             macro     BitSize[,Variable]  ;if no Variable, wherever HX points
 1297                                               #if :macronest = 1
 1298                                                         #Warning  Macro NOT to be called directly
 1299                                               #endif
 1300                                                         mreq      1:BitSize[,Variable]
 1301                                                         mset      2,~@@~
 1302                                                         mtrim     2
 1303                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 1304                                                         mset      9                   ;;assume signed (when SIGNED)
 1305                                               #ifparm ~2.1.1~~2.{:1}~ = []
 1306                                                         mset      9,unsigned
 1307                                                         mset      2,~2.2.{:2-2}~
 1308                                               #endif
 1309                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 1310                                                         @@_not_x_ ~2~
 1311                                               #ifnb ~2,~
 1312                                                 #ifb ~2.1.1~ = .                      ;;except for pointers
 1313                                                   #ifnz ::~2,~                        ;;and constants
 1314                                                     #if ::~2,~ <> ~1~/8               ;;different-size variables
 1315                                                         @@ResizeTOS #{~1~/8}#{::~2,~}~9~
 1316                                                         @@_?sei_  ~2~
 1317                                                         @@pullv   ~2~                 ;;are resized and then pulled
 1318                                                         @_?cli_   ~2~
 1319                                                         mexit
 1320                                                     #endif
 1321                                                   #endif
 1322                                                 #endif
 1323                                               #endif
 1324                                                         #Message  Save~1~ ~2~
 1325                                                         @@lea     ~2~                 ;;default case
 1326                                                         @@_?sei_  ~2~
 1327                                                         call      StackSave~1~        ;;save as is
 1328                                                         @@_?cli_  ~2~
 1329                                               #ifspauto
 1330                                                         #spadd    -~1~/8
 1331                                               #endif
 1332                                                         endm
 1334                                     ;-------------------------------------------------------------------------------
 1336                                     _DoSwap             macro     BitSize
 1337                                               #if :macronest = 1
 1338                                                         #Warning  Macro NOT to be called directly
 1339                                               #endif
 1340                                                         call      StackSwap~1~
 1341                                                         endm
 1343                                     ;-------------------------------------------------------------------------------
 1345                                     _DoOperation        macro     Operation[,BitSize]
 1346                                               #if :macronest = 1
 1347                                                         #Warning  Macro NOT to be called directly
 1348                                               #endif
 1349                                                         mdef      2,~1.{:1-1}~
 1350                                                         #Message  ~1~
 1351                                                         call      Stack~1~
 1352                                               #ifspauto
 1353                                                         #spadd    -~2~/8
 1354                                               #endif
 1355                                                         endm
 1357                                     ;-------------------------------------------------------------------------------
 1359                                     _DoMath             macro     Operation,BitSize[,Operand1[,Operand2[,Answer]]]
 1360                                               #if :macronest = 1
 1361                                                         #Warning  Macro NOT to be called directly
 1362                                               #endif
 1363                                               #ifnoparm ~3~
 1364                                                         @_DoOperation ~1~
 1365                                                         mexit
 1366                                               #endif
 1367                                               #ifnoparm ~4~
 1368                                                         @@Load~2~ ~3~
 1369                                                   #ifnoparm ~1~ = Add~2~
 1370                                                   #ifnoparm ~1~ = Mul~2~
 1371                                               ;except for Add and Mul which are commutative, we must swap the stack
 1372                                                         call      StackSwap~2~        ;one parm is Operand2 (eg, Div32 XXX does TOS/XXX)
 1373                                                   #endif
 1374                                                   #endif
 1375                                                         @_DoOperation ~1~
 1376                                                         mexit
 1377                                               #endif
 1378                                                         @@Load~2~ ~4~
 1379                                                         @@Load~2~ ~3~
 1380                                                         @@_DoOperation ~1~
 1381                                               #ifparm ~5~
 1382                                                         @Save~2~  ~5~
 1383                                               #endif
 1384                                                         endm
 1386                                     ;-------------------------------------------------------------------------------
 1388                                     _DoAbs              macro     BitSize[,Source][,Destination]
 1389                                               #if :macronest = 1
 1390                                                         #Warning  Macro NOT to be called directly
 1391                                               #endif
 1392                                                         #Message  Abs~1~ ~@@~
 1393                                                         @@_FindStkMth_ ~1~
 1394                                                         mset      1,{:mexit}
 1395                                               #ifparm ~2~
 1396                                                         @@Load~1~ ~2~
 1397                                               #endif
 1398                                                         call      StackAbs~1~
 1399                                               #ifparm ~2~~3~
 1400                                                         @Save~1~  ~3~
 1401                                               #endif
 1402                                                         endm
 1404                                     ;-------------------------------------------------------------------------------
 1406                                     _DoNeg              macro     BitSize[,Source][,Destination]
 1407                                               #if :macronest = 1
 1408                                                         #Warning  Macro NOT to be called directly
 1409                                               #endif
 1410                                                         #Message  Neg~1~ ~@@~
 1411                                                         @@_FindStkMth_ ~1~
 1412                                                         mset      1,{:mexit}
 1413                                               #ifparm ~2~
 1414                                                         @@Load~1~ ~2~
 1415                                               #endif
 1416                                                         call      StackNegate~1~
 1417                                               #ifparm ~2~~3~
 1418                                                         @Save~1~  ~3~
 1419                                               #endif
 1420                                                         endm
 1422                                     ;-------------------------------------------------------------------------------
 1424                                     _DoStr              macro     BitSize,[Variable],[ResultString]
 1425                                               #if :macronest = 1
 1426                                                         #Warning  Macro NOT to be called directly
 1427                                               #endif
 1428                                                         @@_FindStkMth_ ~1~
 1429                                                         mset      1,{:mexit}
 1430                                               #ifparm ~'~,3~'.{:3}~ = x
 1431                                                         pshhx
 1432                                               #endif
 1433                                               #ifparm ~2~
 1434                                                         @@Load~1~ ~2~
 1435                                                    #ifparm ~'~,3~'.{:3}~ = x
 1436                                                         ldhx      ~1~/8+1,asp         ;reload user HX for next LDHX
 1437                                                    #endif
 1438                                               #endif
 1439                                               #ifnb ~2~
 1440                                                         #Message  Convert \@~2~\@ ({::~2,~*8}-bit) to ASCIZ in \@~3~\@
 1441                                               #endif
 1442                                                         @@lea     ~3~
 1443                                                         call      Stack~1~ToASCIZ
 1444                                               #ifparm ~2~
 1445                                                         ais       #~1~/8
 1446                                               #endif
 1447                                               #ifparm ~'~,3~'.{:3}~ = x
 1448                                                         pulhx
 1449                                               #endif
 1450                                                         endm
 1452                                     
 1453                                     ;*******************************************************************************
 1454                                     ; External dependencies
 1455                                     ;*******************************************************************************
 1456                                     
 1457                                                         #Uses     strings/stringlength.sub
*** BEGIN INCLUDE FILE: lib/strings/stringlength.sub ***
    6                182C                 ?_OBJECT_?
    7                                     ;*******************************************************************************
    8                                     ; Purpose: Return the length of an ASCIZ string
    9                                     ; Input  : HX -> string
   10                                     ; Output : A = Length
   11                                     ;        : CCR matches RegA contents (a welcome side effect)
   12                                     ; Note(s): Returned length is zero when string is longer than 255
   13                                     
   14                                     StringLength        macro     [[#]StringVariable] ;if no parm, use current HX
   15                                               #ifb ~@~
   16                                                         call      ~0~
   17                                                         mexit
   18                                               #endif
   19                                                         #push
   20                                                         #spauto   :sp
   21                                                         pshhx
   22                                                         @@lea     ~@~
   23                                                         call      ~0~
   24                                                         pulhx
   25                                                         #pull
   26                                                         endm
   27                                     
   28                                     ;-------------------------------------------------------------------------------
   29                                     
   30                                                         #spauto
   31                                     
   32                182C                 StringLength        proc
   33    [182C] 182C:898B            [ 4]                     pshhx
   34    [182E] 182E:4F              [ 1]                     clra
   35    [182F] 182F:7D              [ 3] Loop@@              tst       ,x
   36    [1830] 1830:2704 (1836)     [ 3]                     beq       Done@@              ;on ASCIZ terminator, done
   37    [1832] 1832:AF01            [ 2]                     aix       #1                  ;bump up pointer
   38    [1834] 1834:4BF9 (182F)     [ 4]                     dbnza     Loop@@
   39    [1836] 1836:40              [ 1] Done@@              nega                          ;(now CCR matches A value)
   40    [1837] 1837:8A88            [ 6]                     pulhx
   41    [1839] 1839:81              [ 6]                     rtc
   42                                     
   43                                                         #sp
   44                                     ;*******************************************************************************
*** END   INCLUDE FILE: lib/strings/stringlength.sub *** (RESUMING FILE: lib/stakmath.sub)
 1457                                                         #Exit
 1458                                                         #Uses     strings/stringinsertchar.sub
*** BEGIN INCLUDE FILE: lib/strings/stringinsertchar.sub ***
    6                                     
    7                                     ;*******************************************************************************
    8                                     ; Purpose: Insert a character at the beginning of an ASCIZ (sub-)string
    9                                     ; Input  : HX -> position in ASCIZ string where to insert new character
   10                                     ;        : A = character to insert
   11                                     ; Output : None
   12                                     
   13                                     StringInsertChar    macro     [[#]Char[,[#]StringVar]]
   14                                               #ifb ~1~
   15                                                         call      ~0~                 ;HX and A pre-loaded correctly
   16                                                         mexit
   17                                               #endif
   18                                                         #push
   19                                                         #spauto   :sp
   20                                               #ifparm ~2~
   21                                                         push
   22                                                         lda       ~1~
   23                                                         @@lea     ~@@~
   24                                                         call      ~0~
   25                                                         pull
   26                                                         #pull
   27                                                         mexit
   28                                               #endif
   29                                                         psha
   30                                                         lda       ~1~
   31                                                         call      ~0~
   32                                                         pula
   33                                                         #pull
   34                                                         endm
   35                                     
   36                                     ;-------------------------------------------------------------------------------
   37                                     
   38                                                         #spauto
   39                                     
   40                183A                 StringInsertChar    proc
   41    [183A] 183A:8789 8B         [ 6]                     push
   42                                                         #ais
   43    [183D] 183D:87              [ 2]                     psha      char_to_ins@@       ;next character to insert
   44                                     
   45    [183E] 183E:F6              [ 3] Loop@@              lda       ,x                  ;A = old string character
   46    [183F] 183F:87              [ 2]                     psha                          ;save it for now
   47    [1840] 1840:9EE6 02         [ 4]                     lda       char_to_ins@@,sp    ;A = new character
   48    [1843] 1843:F7              [ 2]                     sta       ,x                  ;save it at current position
   49    [1844] 1844:86              [ 3]                     pula                          ;A = old string character
   50    [1845] 1845:2707 (184E)     [ 3]                     beq       Done@@              ;if at terminator, we're done
   51    [1847] 1847:9EE7 01         [ 4]                     sta       char_to_ins@@,sp    ;save old for next iteration
   52                                     
   53    [184A] 184A:AF01            [ 2]                     aix       #1                  ;HX -> next character position
   54    [184C] 184C:20F0 (183E)     [ 3]                     bra       Loop@@              ;repeat for all characters
   55                                     
   56    [184E] 184E:86              [ 3] Done@@              pula                          ;remove temp variable(s)
   57    [184F] 184F:8A88 86         [ 9]                     pull
   58    [1852] 1852:81              [ 6]                     rtc
   59                                     
   60                                     ;*******************************************************************************
   61                                                         #sp
   62                                     ;*******************************************************************************
*** END   INCLUDE FILE: lib/strings/stringinsertchar.sub *** (RESUMING FILE: lib/stakmath.sub)
 1459                                                         #Uses     strings/adddecimalpoint.sub
*** BEGIN INCLUDE FILE: lib/strings/adddecimalpoint.sub ***
    6                                                         #Uses     stringlength.sub
    7                                                         #Uses     stringinsertchar.sub
    8                                     
    9                                     ;*******************************************************************************
   10                                     ; Purpose: Add decimal point to ASCIZ 'number'
   11                                     ; Input  : HX -> ASCIZ string 'number'
   12                                     ;        : A = number of decimal places
   13                                     ; Output : ASCIZ string updated
   14                                     
   15                                     AddDecimalPoint     macro     [[#]DecimalPlaces[,[#]ASCIZ_String]]
   16                                               #ifnoparm ~1~
   17                                                         call      ~0~                 ;HX and A pre-loaded correctly
   18                                                         mexit
   19                                               #endif
   20                                                         #push
   21                                                         #spauto   :sp
   22                                               #ifparm ~2~
   23                                                         push
   24                                                         lda       ~1~
   25                                                         @@lea     ~2~
   26                                                         call      ~0~
   27                                                         pull
   28                                                         #pull
   29                                                         mexit
   30                                               #endif
   31                                                         psha
   32                                                         lda       ~1~
   33                                                         call      ~0~
   34                                                         pula
   35                                                         #pull
   36                                                         endm
   37                                     
   38                                     ;-------------------------------------------------------------------------------
   39                                     
   40                                                         #spauto
   41                                     
   42                1853                 AddDecimalPoint     proc
   43    [1853] 1853:4100 36(188C)   [ 4]                     cbeqa     #0,Return@@         ;zero position is a no-op
   44    [1856] 1856:87              [ 2]                     psha      places@@
   45    [1857] 1857:898B            [ 4]                     pshhx
   47    [1859] 1859:F6              [ 3]                     lda       ,x
   48    [185A] 185A:A12D            [ 2]                     cmpa      #'-'                ;is it a minus sign?
   49    [185C] 185C:2602 (1860)     [ 3]                     bne       DoneSign@@          ;no, continue as usual
   50    [185E] 185E:AF01            [ 2]                     aix       #1                  ;yes, skip the sign
   51                1860                 DoneSign@@
   53  M                                                      @StringLength                 ;get length of ASCIZ number
   53  M [1860] 1860:CD18 2C         [ 6]                     call      StringLength
   53                                                         mexit
   54                                     
   55    [1863] 1863:9EE1 03         [ 4] LeadingZeros@@      cmpa      places@@,sp         ;while length <= decimal digits,
   56    [1866] 1866:220A (1872)     [ 3]                     bhi       AddDot@@
   57  M                                                      @StringInsertChar #'0'        ;... add leading zero
   57  M                                                      #push
   57  M                                                      #spauto   :sp
   57  M [1868] 1868:87              [ 2]                     psha
   57  M [1869] 1869:A630            [ 2]                     lda       #'0'
   57  M [186B] 186B:CD18 3A         [ 6]                     call      StringInsertChar
   57  M [186E] 186E:86              [ 3]                     pula
   57  M                                                      #pull
   57                                                         endm
   58    [186F] 186F:4C              [ 1]                     inca                          ;update string length
   59    [1870] 1870:20F1 (1863)     [ 3]                     bra       LeadingZeros@@
   60                                     
   61    [1872] 1872:9EE0 03         [ 4] AddDot@@            sub       places@@,sp         ;calculate dot insertion index
   62  M                                                      @aax                          ;HX -> dot insertion spot
   62  M                                                      mdef      1,1
   62  M [1875] 1875:879F 9EEB 0197  [23]                     !aax
   62  M             8B86 A900 878A  
   62  M             86              
   62  M                                                      mtop      1
   62                                                         endm
   63  M                                                      @StringInsertChar #'.'        ;insert dot
   63  M                                                      #push
   63  M                                                      #spauto   :sp
   63  M [1882] 1882:87              [ 2]                     psha
   63  M [1883] 1883:A62E            [ 2]                     lda       #'.'
   63  M [1885] 1885:CD18 3A         [ 6]                     call      StringInsertChar
   63  M [1888] 1888:86              [ 3]                     pula
   63  M                                                      #pull
   63                                                         endm
   64                                     
   65    [1889] 1889:8A88 86         [ 9] Done@@              pull
   66    [188C] 188C:81              [ 6] Return@@            rtc
   67                                     
   68                                     ;*******************************************************************************
   69                                                         #sp
   70                                     ;*******************************************************************************
*** END   INCLUDE FILE: lib/strings/adddecimalpoint.sub *** (RESUMING FILE: lib/stakmath.sub)
 1460                188D                 ?_OBJECT_?
 1461                                     ;*******************************************************************************
 1462                                     ; One-based (SP-index) offsets to stacked operands (to be used with #SPAUTO :AB)
 1463                                     ;*******************************************************************************
 1464                                     
 1465                                                         #temp     1
 1466                0001                 ?a                  next      :temp,?WORD         ;top-of-stack (TOS) number (N1)
 1467                0005                 ?b                  next      :temp,?WORD         ;number after TOS (N2)
 1468                                     
 1469                                                         #Cycles                       ;reset the cycles counter
 1470                                     
 1471                                     ;*******************************************************************************
 1472                                     ; Purpose: Add N1 to N2 and place result on top-of-stack. N1 & N2 removed
 1473                                     ; Input  : [TOS+?WORD] = Number2
 1474                                     ;        : [TOS] = Number1
 1475                                     ; Output : [TOS] = Result
 1476                                     ; Note(s): Carry Set on overflow
 1477                                     
 1478                                                         #spauto   :ab
 1479                                     
 1480                188D                 ?Add                proc
 1481    [188D] 188D:8789 8B         [ 6]                     push
 1482    [1890] 1890:95              [ 2]                     tsx
 1483                                     
 1489    [1891] 1891:A604            [ 2]                     lda       #?WORD
 1490    [1893] 1893:98              [ 1]                     clc
 1491                                                                   #Cycles
 1492    [1894] 1894:87              [ 2] Loop@@              psha
 1493    [1895] 1895:E608            [ 3]                     lda       ?a+{::?a-1},spx
 1494    [1897] 1897:E90C            [ 3]                     adc       ?b+{::?b-1},spx
 1495    [1899] 1899:E70C            [ 3]                     sta       ?b+{::?b-1},spx
 1496    [189B] 189B:86              [ 3]                     pula
 1497    [189C] 189C:AFFF            [ 2]                     aix       #-1
 1498    [189E] 189E:4BF4 (1894)     [ 4]                     dbnza     Loop@@
 1499                                                                   #Cycles :cycles*?WORD+:ocycles
 1501    [18A0] 18A0:CC1B 7D         [ 4]                     jmp       ?RemoveAndReturn
 1502                                     
 1503                005F                 ?AddCycles          equ       :cycles
 1504                                     
 1505                                     ;*******************************************************************************
 1506                                     ; Purpose: Subtract N2 from N1 and place result on top-of-stack. N1 & N2 removed
 1507                                     ; Input  : [TOS+?WORD] = Number2
 1508                                     ;        : [TOS] = Number1
 1509                                     ; Output : [TOS] = Result
 1510                                     ; Note(s): Carry Set on borrow
 1511                                     
 1512                                                         #spauto   :ab
 1513                                     
 1514                18A3                 ?Subtract           proc
 1515    [18A3] 18A3:8789 8B         [ 6]                     push
 1516    [18A6] 18A6:95              [ 2]                     tsx
 1522    [18A7] 18A7:A604            [ 2]                     lda       #?WORD
 1523    [18A9] 18A9:98              [ 1]                     clc
 1524                                                                   #Cycles
 1525    [18AA] 18AA:87              [ 2] Loop@@              psha
 1526    [18AB] 18AB:E608            [ 3]                     lda       ?a+{::?a-1},spx
 1527    [18AD] 18AD:E20C            [ 3]                     sbc       ?b+{::?b-1},spx
 1528    [18AF] 18AF:E70C            [ 3]                     sta       ?b+{::?b-1},spx
 1529    [18B1] 18B1:86              [ 3]                     pula
 1530    [18B2] 18B2:AFFF            [ 2]                     aix       #-1
 1531    [18B4] 18B4:4BF4 (18AA)     [ 4]                     dbnza     Loop@@
 1532                                                                   #Cycles :cycles*?WORD+:ocycles
 1534    [18B6] 18B6:CC1B 7D         [ 4]                     jmp       ?RemoveAndReturn
 1535                                     
 1536                005F                 ?SubCycles          equ       :cycles
 1537                                     
 1541                                                         #Message  Bit ops enabled (define NO_BIT_OPS to disable)
 1542                                     ;*******************************************************************************
 1543                                     ; Purpose: AND N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1544                                     ; Input  : [TOS+?WORD] = Number2
 1545                                     ;        : [TOS] = Number1
 1546                                     ; Output : [TOS] = Result
 1547                                     ; Note(s):
 1548                                                         #spauto   :ab
 1549                                     
 1550                18B9                 ?BitAnd             proc
 1551    [18B9] 18B9:8789 8B         [ 6]                     push
 1552    [18BC] 18BC:95              [ 2]                     tsx
 1553                                     
 1559    [18BD] 18BD:A604            [ 2]                     lda       #?WORD
 1560                                                                   #Cycles
 1561    [18BF] 18BF:87              [ 2] Loop@@              psha
 1562    [18C0] 18C0:E608            [ 3]                     lda       ?a+{::?a-1},spx
 1563    [18C2] 18C2:E40C            [ 3]                     and       ?b+{::?b-1},spx
 1564    [18C4] 18C4:E70C            [ 3]                     sta       ?b+{::?b-1},spx
 1565    [18C6] 18C6:86              [ 3]                     pula
 1566    [18C7] 18C7:AFFF            [ 2]                     aix       #-1
 1567    [18C9] 18C9:4BF4 (18BF)     [ 4]                     dbnza     Loop@@
 1568                                                                   #Cycles :cycles*?WORD+:ocycles
 1570    [18CB] 18CB:CC1B 7D         [ 4]                     jmp       ?RemoveAndReturn
 1571                                     
 1572                005E                 ?AndCycles          equ       :cycles
 1573                                     
 1574                                     ;*******************************************************************************
 1575                                     ; Purpose: OR N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1576                                     ; Input  : [TOS+?WORD] = Number2
 1577                                     ;        : [TOS] = Number1
 1578                                     ; Output : [TOS] = Result
 1579                                     ; Note(s):
 1580                                                         #spauto   :ab
 1581                                     
 1582                18CE                 ?BitOr              proc
 1583    [18CE] 18CE:8789 8B         [ 6]                     push
 1584    [18D1] 18D1:95              [ 2]                     tsx
 1585                                     
 1591    [18D2] 18D2:A604            [ 2]                     lda       #?WORD
 1592                                                                   #Cycles
 1593    [18D4] 18D4:87              [ 2] Loop@@              psha
 1594    [18D5] 18D5:E608            [ 3]                     lda       ?a+{::?a-1},spx
 1595    [18D7] 18D7:EA0C            [ 3]                     ora       ?b+{::?b-1},spx
 1596    [18D9] 18D9:E70C            [ 3]                     sta       ?b+{::?b-1},spx
 1597    [18DB] 18DB:86              [ 3]                     pula
 1598    [18DC] 18DC:AFFF            [ 2]                     aix       #-1
 1599    [18DE] 18DE:4BF4 (18D4)     [ 4]                     dbnza     Loop@@
 1600                                                                   #Cycles :cycles*?WORD+:ocycles
 1602    [18E0] 18E0:CC1B 7D         [ 4]                     jmp       ?RemoveAndReturn
 1603                                     
 1604                005E                 ?OrCycles           equ       :cycles
 1605                                     
 1606                                     ;*******************************************************************************
 1607                                     ; Purpose: XOR N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1608                                     ; Input  : [TOS+?WORD] = Number2
 1609                                     ;        : [TOS] = Number1
 1610                                     ; Output : [TOS] = Result
 1611                                     ; Note(s):
 1612                                                         #spauto   :ab
 1613                                     
 1614                18E3                 ?BitXor             proc
 1615    [18E3] 18E3:8789 8B         [ 6]                     push
 1616    [18E6] 18E6:95              [ 2]                     tsx
 1617                                     
 1623    [18E7] 18E7:A604            [ 2]                     lda       #?WORD
 1624                                                                   #Cycles
 1625    [18E9] 18E9:87              [ 2] Loop@@              psha
 1626    [18EA] 18EA:E608            [ 3]                     lda       ?a+{::?a-1},spx
 1627    [18EC] 18EC:E80C            [ 3]                     eor       ?b+{::?b-1},spx
 1628    [18EE] 18EE:E70C            [ 3]                     sta       ?b+{::?b-1},spx
 1629    [18F0] 18F0:86              [ 3]                     pula
 1630    [18F1] 18F1:AFFF            [ 2]                     aix       #-1
 1631    [18F3] 18F3:4BF4 (18E9)     [ 4]                     dbnza     Loop@@
 1632                                                                   #Cycles :cycles*?WORD+:ocycles
 1634    [18F5] 18F5:CC1B 7D         [ 4]                     jmp       ?RemoveAndReturn
 1635                                     
 1636                005E                 ?EorCycles          equ       :cycles
 1637                                     
 1638                                     ;*******************************************************************************
 1639                                     ; Purpose: Shift N1 left N2 times and place result on top-of-stack. N1 & N2 removed
 1640                                     ; Input  : [TOS+?WORD] = Number2
 1641                                     ;        : [TOS] = Number1
 1642                                     ; Output : [TOS] = Result
 1643                                     ; Note(s): CCR[C] = last most significant bit shifted out
 1644                                     ;        : Only LSB of second operand (N2) is used, as shifting more than the
 1645                                     ;        : highest bit version always produces zero.  Any non-zero bytes in the
 1646                                     ;        : N2 operand will cause a zero result, regardless.
 1647                                     
 1648                                                         #spauto   :ab
 1649                                     
 1650                18F8                 ?ShiftLeft          proc
 1651    [18F8] 18F8:8789 8B         [ 6]                     push
 1652                                                         #ais
 1653                                     
 1654    [18FB] 18FB:9EE6 0D         [ 4]                     lda       ?b+{::?b-1},sp      ;A = shift counter
 1655    [18FE] 18FE:87              [ 2]                     psha      counter@@
 1656                                     
 1657    [18FF] 18FF:95              [ 2]                     tsx
 1658                                     
 1659    [1900] 1900:6F0D            [ 5]                     clr       ?b+{::?b-1},spx     ;clear original shift counter
 1660                0005                 b@@                 equ       ?b,::?b-1           ;(b@@ = ?b but excludes final already cleared byte - 2013.11.29 optimization)
 1661  M                                                      @zero?.s, b@@,spx             ;test whole word for zero (counter <= 8-bit)
 1661  M                                                      mset      #
 1661  M                                                      mreq      1
 1661  M                                                      @@_nosize_ b9,spx
 1661  M                                                      mset      #
 1661  M                                                      mset      0,mstop [zero?.s] No size (b9,spx)
 1661  M                                                      endm
 1661  M                                                      mdo
 1661  M [1902] 1902:E60A            [ 3]                     lda       b9+0,spx
 1661  M                                                      mloop     ::b9
 1661  M [1904] 1904:EA0B            [ 3]                     ora       b9+1,spx
 1661  M                                                      mloop     ::b9
 1661  M [1906] 1906:EA0C            [ 3]                     ora       b9+2,spx
 1661  M                                                      mloop     ::b9
 1661                                                         endm
 1662    [1908] 1908:270D (1917)     [ 3]                     beq       Go@@                ;if so, proceed normally
 1663                                     
 1664    [190A] 190A:F6              [ 3]                     lda       counter@@,spx       ;if shift counter is less than
 1665    [190B] 190B:A120            [ 2]                     cmpa      #MATHSIZE           ;MATHSIZE, proceed normally,
 1666    [190D] 190D:2508 (1917)     [ 3]                     blo       Go@@                ;else zero and exit
 1667                                     
 1668  M                                                      @clr.s,   b@@,spx             ;else error, so zero result
 1668  M                                                      mset      #
 1668  M                                                      mreq      1
 1668  M                                                      @@_nosize_ b9,spx
 1668  M                                                      mset      #
 1668  M                                                      mset      0,mstop [clr.s] No size (b9,spx)
 1668  M                                                      endm
 1668  M                                                      mdo
 1668  M [190F] 190F:6F0A            [ 5]                     clr       b9+0,spx
 1668  M                                                      mloop     ::b9
 1668  M [1911] 1911:6F0B            [ 5]                     clr       b9+1,spx
 1668  M                                                      mloop     ::b9
 1668  M [1913] 1913:6F0C            [ 5]                     clr       b9+2,spx
 1668  M                                                      mloop     ::b9
 1668                                                         endm
 1669    [1915] 1915:201A (1931)     [ 3]                     bra       Done@@              ;and get out
 1670                                     
 1671  M                                  Go@@                @mova.s   ?a,spx ?b,spx       ;copy operand to result
 1671  M                                                      mset      #' '
 1671  M                                                      mreq      1,2:Source Destination
 1671  M                                                      @@_samesize_ ?a,spx ?b,spx
 1671  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1671  M                                                      mset      0
 1671  M                                                      mdo
 1671  M                                                      mswap     1,1
 1671  M                                                      @@_nosize_ ?a,spx
 1671  M                                                      mset      #
 1671  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1671  M                                                      endm
 1671  M                                                      mset      0,?a,spx
 1671  M                                                      mloop     :n
 1671  M                                                      mswap     1,2
 1671  M                                                      @@_nosize_ ?b,spx
 1671  M                                                      mset      #
 1671  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1671  M                                                      endm
 1671  M                                                      mloop     :n
 1671  M                                                      endm
 1671  M                                                      mset      0
 1671  M                                                      mdo
 1671  M [1917] 1917:E606            [ 3]                     lda       ?a+0,spx
 1671  M [1919] 1919:E70A            [ 3]                     sta       ?b+0,spx
 1671  M                                                      mloop     ::?b
 1671  M [191B] 191B:E607            [ 3]                     lda       ?a+1,spx
 1671  M [191D] 191D:E70B            [ 3]                     sta       ?b+1,spx
 1671  M                                                      mloop     ::?b
 1671  M [191F] 191F:E608            [ 3]                     lda       ?a+2,spx
 1671  M [1921] 1921:E70C            [ 3]                     sta       ?b+2,spx
 1671  M                                                      mloop     ::?b
 1671  M [1923] 1923:E609            [ 3]                     lda       ?a+3,spx
 1671  M [1925] 1925:E70D            [ 3]                     sta       ?b+3,spx
 1671  M                                                      mloop     ::?b
 1671                                                         endm
 1672                                                                   #Cycles
 1673  M                                  Loop@@              @lsl.s,   ?b,spx              ;shift left one bit position
 1673  M                                                      mset      #
 1673  M                                                      mreq      1
 1673  M                                                      @@_nosize_ ?b,spx
 1673  M                                                      mset      #
 1673  M                                                      mset      0,mstop [lsl.s] No size (?b,spx)
 1673  M                                                      endm
 1673  M                                                      mdo
 1673  M [1927] 1927:680D            [ 5]                     lsl       ?b+3,spx
 1673  M                                                      mloop     ::?b
 1673  M [1929] 1929:690C            [ 5]                     rol       ?b+2,spx
 1673  M                                                      mloop     ::?b
 1673  M [192B] 192B:690B            [ 5]                     rol       ?b+1,spx
 1673  M                                                      mloop     ::?b
 1673  M [192D] 192D:690A            [ 5]                     rol       ?b+0,spx
 1673  M                                                      mloop     ::?b
 1673                                                         endm
 1674    [192F] 192F:7BF6 (1927)     [ 6]                     dbnz      counter@@,spx,Loop@@ ;repeat for all bits
 1675                                                                   #Cycles :cycles*{MATHSIZE-1}+:ocycles
 1676                1931                 Done@@
 1678    [1931] 1931:86              [ 3]                     pula
 1682    [1932] 1932:CC1B 7D         [ 4]                     jmp       ?RemoveAndReturn
 1683                                     
 1684                037E                 ?ShlCycles          equ       :cycles
 1685                                     
 1686                                     ;*******************************************************************************
 1687                                     ; Purpose: Shift N1 right N2 times and place result on top-of-stack. N1 & N2 removed
 1688                                     ; Input  : [TOS+?WORD] = Number2
 1689                                     ;        : [TOS] = Number1
 1690                                     ; Output : [TOS] = Result
 1691                                     ; Note(s): CCR[C] = last least significant bit shifted out
 1692                                     ;        : Only LSB of second operand (N2) is used, as shifting more than the
 1693                                     ;        : highest bit version always produces zero.  Any non-zero bytes in the
 1694                                     ;        : N2 operand will cause a zero result, regardless.
 1695                                     
 1696                                                         #spauto   :ab
 1697                                     
 1698                1935                 ?ShiftRight         proc
 1699    [1935] 1935:8789 8B         [ 6]                     push
 1700                                                         #ais
 1701                                     
 1702    [1938] 1938:9EE6 0D         [ 4]                     lda       ?b+{::?b-1},sp      ;A = shift counter
 1703    [193B] 193B:87              [ 2]                     psha      counter@@
 1704                                     
 1705    [193C] 193C:95              [ 2]                     tsx
 1706                                     
 1707    [193D] 193D:6F0D            [ 5]                     clr       ?b+{::?b-1},spx     ;clear original shift counter
 1708                0005                 b@@                 equ       ?b,::?b-1           ;(b@@ = ?b but excludes final already cleared byte - 2013.11.29 optimization)
 1709  M                                                      @zero?.s, b@@,spx             ;test whole word for zero (counter <= 8-bit)
 1709  M                                                      mset      #
 1709  M                                                      mreq      1
 1709  M                                                      @@_nosize_ b10,spx
 1709  M                                                      mset      #
 1709  M                                                      mset      0,mstop [zero?.s] No size (b10,spx)
 1709  M                                                      endm
 1709  M                                                      mdo
 1709  M [193F] 193F:E60A            [ 3]                     lda       b10+0,spx
 1709  M                                                      mloop     ::b10
 1709  M [1941] 1941:EA0B            [ 3]                     ora       b10+1,spx
 1709  M                                                      mloop     ::b10
 1709  M [1943] 1943:EA0C            [ 3]                     ora       b10+2,spx
 1709  M                                                      mloop     ::b10
 1709                                                         endm
 1710    [1945] 1945:270D (1954)     [ 3]                     beq       Go@@                ;if so, proceed normally
 1711                                     
 1712    [1947] 1947:F6              [ 3]                     lda       counter@@,spx       ;if shift counter is less than
 1713    [1948] 1948:A120            [ 2]                     cmpa      #MATHSIZE           ;MATHSIZE, proceed normally,
 1714    [194A] 194A:2508 (1954)     [ 3]                     blo       Go@@                ;else zero and exit
 1715                                     
 1716  M                                                      @clr.s,   b@@,spx             ;else error, so zero result
 1716  M                                                      mset      #
 1716  M                                                      mreq      1
 1716  M                                                      @@_nosize_ b10,spx
 1716  M                                                      mset      #
 1716  M                                                      mset      0,mstop [clr.s] No size (b10,spx)
 1716  M                                                      endm
 1716  M                                                      mdo
 1716  M [194C] 194C:6F0A            [ 5]                     clr       b10+0,spx
 1716  M                                                      mloop     ::b10
 1716  M [194E] 194E:6F0B            [ 5]                     clr       b10+1,spx
 1716  M                                                      mloop     ::b10
 1716  M [1950] 1950:6F0C            [ 5]                     clr       b10+2,spx
 1716  M                                                      mloop     ::b10
 1716                                                         endm
 1717    [1952] 1952:201A (196E)     [ 3]                     bra       Done@@              ;and get out
 1718                                     
 1719  M                                  Go@@                @mova.s   ?a,spx ?b,spx       ;copy operand to result
 1719  M                                                      mset      #' '
 1719  M                                                      mreq      1,2:Source Destination
 1719  M                                                      @@_samesize_ ?a,spx ?b,spx
 1719  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1719  M                                                      mset      0
 1719  M                                                      mdo
 1719  M                                                      mswap     1,1
 1719  M                                                      @@_nosize_ ?a,spx
 1719  M                                                      mset      #
 1719  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1719  M                                                      endm
 1719  M                                                      mset      0,?a,spx
 1719  M                                                      mloop     :n
 1719  M                                                      mswap     1,2
 1719  M                                                      @@_nosize_ ?b,spx
 1719  M                                                      mset      #
 1719  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1719  M                                                      endm
 1719  M                                                      mloop     :n
 1719  M                                                      endm
 1719  M                                                      mset      0
 1719  M                                                      mdo
 1719  M [1954] 1954:E606            [ 3]                     lda       ?a+0,spx
 1719  M [1956] 1956:E70A            [ 3]                     sta       ?b+0,spx
 1719  M                                                      mloop     ::?b
 1719  M [1958] 1958:E607            [ 3]                     lda       ?a+1,spx
 1719  M [195A] 195A:E70B            [ 3]                     sta       ?b+1,spx
 1719  M                                                      mloop     ::?b
 1719  M [195C] 195C:E608            [ 3]                     lda       ?a+2,spx
 1719  M [195E] 195E:E70C            [ 3]                     sta       ?b+2,spx
 1719  M                                                      mloop     ::?b
 1719  M [1960] 1960:E609            [ 3]                     lda       ?a+3,spx
 1719  M [1962] 1962:E70D            [ 3]                     sta       ?b+3,spx
 1719  M                                                      mloop     ::?b
 1719                                                         endm
 1720                                                                   #Cycles
 1721                1964                 Loop@@
 1723  M                                                      @asr.s,   ?b,spx              ;shift right one bit position
 1723  M                                                      mset      #
 1723  M                                                      mreq      1
 1723  M                                                      @@_nosize_ ?b,spx
 1723  M                                                      mset      #
 1723  M                                                      mset      0,mstop [asr.s] No size (?b,spx)
 1723  M                                                      endm
 1723  M                                                      mdo
 1723  M [1964] 1964:670A            [ 5]                     asr       ?b+0,spx
 1723  M                                                      mloop     ::?b
 1723  M [1966] 1966:660B            [ 5]                     ror       ?b+1,spx
 1723  M                                                      mloop     ::?b
 1723  M [1968] 1968:660C            [ 5]                     ror       ?b+2,spx
 1723  M                                                      mloop     ::?b
 1723  M [196A] 196A:660D            [ 5]                     ror       ?b+3,spx
 1723  M                                                      mloop     ::?b
 1723                                                         endm
 1727    [196C] 196C:7BF6 (1964)     [ 6]                     dbnz      counter@@,spx,Loop@@ ;repeat for all bits
 1728                                                                   #Cycles :cycles*{MATHSIZE-1}+:ocycles
 1729                196E                 Done@@
 1731    [196E] 196E:86              [ 3]                     pula
 1735    [196F] 196F:CC1B 7D         [ 4]                     jmp       ?RemoveAndReturn
 1736                                     
 1737                037E                 ?ShrCycles          equ       :cycles
 1738                                     
 1740                                     
 1741                                     ;*******************************************************************************
 1742                                     ; Purpose: Multiply N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1743                                     ; Input  : [TOS+?WORD] = Number2
 1744                                     ;        : [TOS] = Number1
 1745                                     ; Output : [TOS] = Result
 1746                                     ; Note(s): Overflows lost, Carry state should be ignored
 1747                                     
 1748                                                         #spauto   :ab
 1749                                     
 1750                1972                 ?Multiply           proc
 1751    [1972] 1972:8789 8B         [ 6]                     push
 1752                                     
 1776                                     ;-------------------------------------------------------------------------------
 1827                                     ;-------------------------------------------------------------------------------
 1829                                     
 1830                                               ;row 1
 1831    [1975] 1975:95              [ 2]                     tsx
 1832    [1976] 1976:E608            [ 3]                     lda       ?a+3,spx
 1833    [1978] 1978:EE0C            [ 3]                     ldx       ?b+3,spx
 1834    [197A] 197A:42              [ 5]                     mul
 1835    [197B] 197B:8789            [ 4]                     pshxa     ans@@               ;temporary 32-bit result (3rd & 4th bytes)
 1836                                     
 1837    [197D] 197D:95              [ 2]                     tsx
 1838    [197E] 197E:E60A            [ 3]                     lda       ?a+3,spx
 1839    [1980] 1980:EE0D            [ 3]                     ldx       ?b+2,spx
 1840    [1982] 1982:42              [ 5]                     mul
 1841    [1983] 1983:9EEB 01         [ 4]                     add       ans@@,sp
 1842    [1986] 1986:9EE7 01         [ 4]                     sta       ans@@,sp
 1843    [1989] 1989:9F              [ 1]                     txa
 1844    [198A] 198A:A900            [ 2]                     adc       #0
 1845    [198C] 198C:87              [ 2]                     psha      ans@@,3             ;temporary 32-bit result (2nd byte)
 1846                                     
 1847    [198D] 198D:95              [ 2]                     tsx
 1848    [198E] 198E:E60B            [ 3]                     lda       ?a+3,spx
 1849    [1990] 1990:EE0D            [ 3]                     ldx       ?b+1,spx
 1850    [1992] 1992:42              [ 5]                     mul
 1851    [1993] 1993:9EEB 01         [ 4]                     add       ans@@,sp
 1852    [1996] 1996:9EE7 01         [ 4]                     sta       ans@@,sp
 1853    [1999] 1999:9F              [ 1]                     txa
 1854    [199A] 199A:A900            [ 2]                     adc       #0
 1855    [199C] 199C:87              [ 2]                     psha      ans@@,4             ;temporary 32-bit result (1st byte)
 1856                                     
 1857    [199D] 199D:95              [ 2]                     tsx
 1858    [199E] 199E:E60C            [ 3]                     lda       ?a+3,spx
 1859    [19A0] 19A0:EE0D            [ 3]                     ldx       ?b+0,spx
 1860    [19A2] 19A2:42              [ 5]                     mul
 1861    [19A3] 19A3:95              [ 2]                     tsx
 1862    [19A4] 19A4:FB              [ 3]                     add       ans@@,spx
 1863    [19A5] 19A5:F7              [ 2]                     sta       ans@@,spx
 1864                                               ;row 2
 1865    [19A6] 19A6:E60B            [ 3]                     lda       ?a+2,spx
 1866    [19A8] 19A8:EE10            [ 3]                     ldx       ?b+3,spx
 1867    [19AA] 19AA:42              [ 5]                     mul
 1868    [19AB] 19AB:9EEB 03         [ 4]                     add       ans@@+2,sp
 1869    [19AE] 19AE:9EE7 03         [ 4]                     sta       ans@@+2,sp
 1870    [19B1] 19B1:9F              [ 1]                     txa
 1871    [19B2] 19B2:95              [ 2]                     tsx
 1872    [19B3] 19B3:E901            [ 3]                     adc       ans@@+1,spx
 1873    [19B5] 19B5:E701            [ 3]                     sta       ans@@+1,spx
 1874    [19B7] 19B7:4F              [ 1]                     clra
 1875    [19B8] 19B8:F9              [ 3]                     adc       ans@@,spx
 1876    [19B9] 19B9:F7              [ 2]                     sta       ans@@,spx
 1877                                     
 1878    [19BA] 19BA:E60B            [ 3]                     lda       ?a+2,spx
 1879    [19BC] 19BC:EE0F            [ 3]                     ldx       ?b+2,spx
 1880    [19BE] 19BE:42              [ 5]                     mul
 1881    [19BF] 19BF:9EEB 02         [ 4]                     add       ans@@+1,sp
 1882    [19C2] 19C2:9EE7 02         [ 4]                     sta       ans@@+1,sp
 1883    [19C5] 19C5:9F              [ 1]                     txa
 1884    [19C6] 19C6:95              [ 2]                     tsx
 1885    [19C7] 19C7:F9              [ 3]                     adc       ans@@,spx
 1886    [19C8] 19C8:F7              [ 2]                     sta       ans@@,spx
 1887                                     
 1888    [19C9] 19C9:E60B            [ 3]                     lda       ?a+2,spx
 1889    [19CB] 19CB:EE0E            [ 3]                     ldx       ?b+1,spx
 1890    [19CD] 19CD:42              [ 5]                     mul
 1891    [19CE] 19CE:95              [ 2]                     tsx
 1892    [19CF] 19CF:FB              [ 3]                     add       ans@@,spx
 1893    [19D0] 19D0:F7              [ 2]                     sta       ans@@,spx
 1894                                               ;row 3
 1895    [19D1] 19D1:E60A            [ 3]                     lda       ?a+1,spx
 1896    [19D3] 19D3:EE10            [ 3]                     ldx       ?b+3,spx
 1897    [19D5] 19D5:42              [ 5]                     mul
 1898    [19D6] 19D6:9EEB 02         [ 4]                     add       ans@@+1,sp
 1899    [19D9] 19D9:9EE7 02         [ 4]                     sta       ans@@+1,sp
 1900    [19DC] 19DC:9F              [ 1]                     txa
 1901    [19DD] 19DD:95              [ 2]                     tsx
 1902    [19DE] 19DE:F9              [ 3]                     adc       ans@@,spx
 1903    [19DF] 19DF:F7              [ 2]                     sta       ans@@,spx
 1904                                     
 1905    [19E0] 19E0:E60A            [ 3]                     lda       ?a+1,spx
 1906    [19E2] 19E2:EE0F            [ 3]                     ldx       ?b+2,spx
 1907    [19E4] 19E4:42              [ 5]                     mul
 1908    [19E5] 19E5:95              [ 2]                     tsx
 1909    [19E6] 19E6:FB              [ 3]                     add       ans@@,spx
 1910    [19E7] 19E7:F7              [ 2]                     sta       ans@@,spx
 1911                                               ;row 4
 1912    [19E8] 19E8:E609            [ 3]                     lda       ?a+0,spx
 1913    [19EA] 19EA:EE10            [ 3]                     ldx       ?b+3,spx
 1914    [19EC] 19EC:42              [ 5]                     mul
 1915    [19ED] 19ED:95              [ 2]                     tsx
 1916    [19EE] 19EE:FB              [ 3]                     add       ans@@,spx
 1917    [19EF] 19EF:F7              [ 2]                     sta       ans@@,spx
 1919                                                                   #temp :cycles
 1920                                     ;-------------------------------------------------------------------------------
 1921                                     ; 40, 48, 56, and 64-bit versions use shorter shift/add method (more cycles, though)
 1922                                     
 1949                                     ;-------------------------------------------------------------------------------
 1950                                     
 1951                                               ;copy result to B while removing from stack
 1952                                     
 1953    [19F0] 19F0:AE04            [ 2]                     ldx       #?WORD
 1954                                                                   #temp :cycles+:temp
 1955    [19F2] 19F2:86              [ 3] CopyResult@@        pula
 1956    [19F3] 19F3:9EE7 0D         [ 4]                     sta       ?b,sp
 1957    [19F6] 19F6:5BFA (19F2)     [ 4]                     dbnzx     CopyResult@@
 1958                                     
 1959                                                         #spadd    1-?WORD
 1960                                                                   #temp :cycles*?WORD+:temp
 1961    [19F8] 19F8:CC1B 7D         [ 4]                     jmp       ?RemoveAndReturn
 1962                                     
 1963                011F                 ?MulCycles          equ       :temp+:cycles
 1964                                     
 1965                                     ;*******************************************************************************
 1966                                     ; Purpose: Divide N1 by N2 and place quotient on top-of-stack. N1 & N2 removed
 1967                                     ; Input  : [TOS+?WORD] = Divisor (N2)
 1968                                     ;        : [TOS] = Dividend (N1)
 1969                                     ; Output : [TOS] = Quotient
 1970                                     ;        : Carry Set on error (division by zero)
 1971                                     ; Note(s):
 1972                                                         #spauto   :ab
 1973                                     
 1974                19FB                 ?Divide             proc
 1975    [19FB] 19FB:8789 8B         [ 6]                     push
 1976                                     
 1977    [19FE] 19FE:A601            [ 2]                     lda       #?DIVOP_            ;flag for DIV operation
 1979    [1A00] 1A00:87              [ 2]                     psha
 1980    [1A01] 1A01:95              [ 2]                     tsx
 1981    [1A02] 1A02:E606            [ 3]                     lda       ?a,spx
 1982    [1A04] 1A04:E80A            [ 3]                     eor       ?b,spx
 1983    [1A06] 1A06:86              [ 3]                     pula
 1984    [1A07] 1A07:2A02 (1A0B)     [ 3]                     bpl       Skip@@
 1985    [1A09] 1A09:AA80            [ 2]                     ora       #?SIGN_             ;flag for negative
 1986                1A0B                 Skip@@
 1988    [1A0B] 1A0B:87              [ 2]                     psha                          ;save flags on stack
 1989    [1A0C] 1A0C:202A (1A38)     [ 3]                     bra       ?DivStart
 1990                                     
 1991                001F                 ?DivCycles          equ       :cycles
 1992                                     
 1993                                     ;*******************************************************************************
 1994                                     ; Purpose: Divide N1 by N2 and place remainder on top-of-stack. N1 & N2 removed
 1995                                     ; Input  : [TOS+?WORD] = Divisor (N2)
 1996                                     ;        : [TOS] = Dividend (N1)
 1997                                     ; Output : [TOS] = Remainder
 1998                                     ;        : Carry Set on error (division by zero)
 1999                                     ; Note(s):
 2000                                                         #spauto   :ab
 2001                FFFFFFFF             ?pc                 equ       ::,:ab
 2002                                     
 2003                1A0E                 ?Modulo             proc
 2004    [1A0E] 1A0E:8789 8B         [ 6]                     push
 2005                                     
 2006    [1A11] 1A11:4F              [ 1]                     clra                          ;flag for MOD operation
 2008    [1A12] 1A12:9E6D 06         [ 5]                     tst       ?a,sp
 2009    [1A15] 1A15:2A02 (1A19)     [ 3]                     bpl       Skip@@
 2010    [1A17] 1A17:AA80            [ 2]                     ora       #?SIGN_             ;flag for negative
 2011                1A19                 Skip@@
 2013    [1A19] 1A19:87              [ 2]                     psha                          ;save flags on stack
 2014    [1A1A] 1A1A:201C (1A38)     [ 3]                     bra       ?DivStart
 2015                                     
 2016                0016                 ?ModCycles          equ       :cycles
 2017                                     
 2018                                     ;*******************************************************************************
 2019                                     
 2020                                                         #temp
 2022                1A1C                 ?AbsX               proc
 2023    [1A1C] 1A1C:7D              [ 3]                     tst       ,ax
 2024    [1A1D] 1A1D:2A12 (1A31)     [ 3]                     bpl       Done@@
 2025                                                                   #temp :cycles
 2026                0000                 var@@               equ       0,?WORD
 2027  M                                  ?NegX               @neg.s    var@@,ax
 2027  M                                                      mset      #
 2027  M                                                      mreq      1
 2027  M                                                      @@_nosize_ var14,ax
 2027  M                                                      mset      #
 2027  M                                                      mset      0,mstop [neg.s] No size (var14,ax)
 2027  M                                                      endm
 2027  M                                                      mdo
 2027  M [1A1F] 1A1F:73              [ 4]                     com       var14+0,ax
 2027  M                                                      mloop     ::var14-1
 2027  M [1A20] 1A20:6301            [ 5]                     com       var14+1,ax
 2027  M                                                      mloop     ::var14-1
 2027  M [1A22] 1A22:6302            [ 5]                     com       var14+2,ax
 2027  M                                                      mloop     ::var14-1
 2027  M [1A24] 1A24:6003            [ 5]                     neg       var14+3,ax
 2027  M                                                      mdo
 2027  M [1A26] 1A26:2609 (1A31)     [ 3]                     bne       Done$$$
 2027  M [1A28] 1A28:6C02            [ 5]                     inc       var14+2,ax
 2027  M                                                      mloop     ::var14-1
 2027  M [1A2A] 1A2A:2605 (1A31)     [ 3]                     bne       Done$$$
 2027  M [1A2C] 1A2C:6C01            [ 5]                     inc       var14+1,ax
 2027  M                                                      mloop     ::var14-1
 2027  M [1A2E] 1A2E:2601 (1A31)     [ 3]                     bne       Done$$$
 2027  M [1A30] 1A30:7C              [ 4]                     inc       var14+0,ax
 2027  M                                                      mloop     ::var14-1
 2027  M             1A31                 Done$$$
 2027                                                         endm
 2028    [1A31] 1A31:81              [ 6] Done@@              rts
 2029                                     
 2030                0030                 ?AbsXCycles         equ       :cycles
 2031                002A                 ?NegxCycles         equ       ?AbsXCycles-:temp
 2033                                     
 2034                                     ;*******************************************************************************
 2035                                     
 2036                0000                 ?SF                 equ       0                   ;stack frame (for X-index use)
 2037                                     
 2038                0000                 ?quotient           next      ?SF,?WORD
 2039                0004                 ?remainder          next      ?SF,?WORD
 2040                0008                 ?temp               next      ?SF,?WORD
 2041                000C                 ?bits               next      ?SF
 2042                000D                 ?flags              next      ?SF
 2043                                     
 2044                0001                 ?DIVOP_             equ       %00000001           ;1 = DIV, 0 = MOD
 2045                0080                 ?SIGN_              equ       %10000000           ;result sign (1 = negative)
 2046                                     
 2047                                                         #push
 2048                                     
 2049    [1A32] 1A32:A70E            [ 2] ?DivError           ais       #?SF                ;de-allocate temporaries
 2050    [1A34] 1A34:99              [ 1]                     sec                           ;indicate error condition
 2051    [1A35] 1A35:CC1B 7D         [ 4]                     jmp       ?RemoveAndReturn
 2052                                     
 2053                                                         #pull
 2054                                     
 2055                                     ;-------------------------------------------------------------------------------
 2056                                     
 2057                1A38                 ?DivStart           proc
 2058                0001                 dividend@@          equ       ?a,::?a
 2059                0005                 divisor@@           equ       ?b,::?b
 2060                0005                 ans@@               equ       ?b,::?b             ;result overwrites divisor
 2061                                     
 2063  M                                                      @lea      dividend@@,sp
 2063  M                                                      mset      #
 2063  M [1A38] 1A38:95              [ 2]                     tsx
 2063  M [1A39] 1A39:AF06            [ 2]                     !aix      #dividend15+:tsx
 2063                                                         mexit
 2064    [1A3B] 1A3B:ADDF (1A1C)     [ 5]                     bsr       ?AbsX
 2065  M                                                      @lea      divisor@@,sp
 2065  M                                                      mset      #
 2065  M [1A3D] 1A3D:95              [ 2]                     tsx
 2065  M [1A3E] 1A3E:AF0A            [ 2]                     !aix      #divisor15+:tsx
 2065                                                         mexit
 2066    [1A40] 1A40:ADDA (1A1C)     [ 5]                     bsr       ?AbsX
 2067                                                                   #Cycles ?AbsXCycles*2+:cycles
 2069    [1A42] 1A42:A7F3            [ 2]                     ais       #-?SF+1             ;quotient, remainder, and temp
 2070    [1A44] 1A44:95              [ 2]                     tsx                           ;(+1 for already pushed Flag)
 2071                                     
 2072                                               ; remainder := 0
 2073                                               ; quotient := 0
 2074                                     
 2075  M                                                      @clr.s    ?remainder,x
 2075  M                                                      mset      #
 2075  M                                                      mreq      1
 2075  M                                                      @@_nosize_ ?remainder,x
 2075  M                                                      mset      #
 2075  M                                                      mset      0,mstop [clr.s] No size (?remainder,x)
 2075  M                                                      endm
 2075  M                                                      mdo
 2075  M [1A45] 1A45:6F04            [ 5]                     clr       ?remainder+0,x
 2075  M                                                      mloop     ::?remainder
 2075  M [1A47] 1A47:6F05            [ 5]                     clr       ?remainder+1,x
 2075  M                                                      mloop     ::?remainder
 2075  M [1A49] 1A49:6F06            [ 5]                     clr       ?remainder+2,x
 2075  M                                                      mloop     ::?remainder
 2075  M [1A4B] 1A4B:6F07            [ 5]                     clr       ?remainder+3,x
 2075  M                                                      mloop     ::?remainder
 2075                                                         endm
 2076  M                                                      @clr.s    ?quotient,x
 2076  M                                                      mset      #
 2076  M                                                      mreq      1
 2076  M                                                      @@_nosize_ ?quotient,x
 2076  M                                                      mset      #
 2076  M                                                      mset      0,mstop [clr.s] No size (?quotient,x)
 2076  M                                                      endm
 2076  M                                                      mdo
 2076  M [1A4D] 1A4D:7F              [ 4]                     clr       ?quotient+0,x
 2076  M                                                      mloop     ::?quotient
 2076  M [1A4E] 1A4E:6F01            [ 5]                     clr       ?quotient+1,x
 2076  M                                                      mloop     ::?quotient
 2076  M [1A50] 1A50:6F02            [ 5]                     clr       ?quotient+2,x
 2076  M                                                      mloop     ::?quotient
 2076  M [1A52] 1A52:6F03            [ 5]                     clr       ?quotient+3,x
 2076  M                                                      mloop     ::?quotient
 2076                                                         endm
 2077                                     
 2078                                               ; first, test for division by zero error
 2079                                     
 2080  M                                                      @zero?.s  divisor@@,spx
 2080  M                                                      mset      #
 2080  M                                                      mreq      1
 2080  M                                                      @@_nosize_ divisor15,spx
 2080  M                                                      mset      #
 2080  M                                                      mset      0,mstop [zero?.s] No size (divisor15,spx)
 2080  M                                                      endm
 2080  M                                                      mdo
 2080  M [1A54] 1A54:E617            [ 3]                     lda       divisor15+0,spx
 2080  M                                                      mloop     ::divisor15
 2080  M [1A56] 1A56:EA18            [ 3]                     ora       divisor15+1,spx
 2080  M                                                      mloop     ::divisor15
 2080  M [1A58] 1A58:EA19            [ 3]                     ora       divisor15+2,spx
 2080  M                                                      mloop     ::divisor15
 2080  M [1A5A] 1A5A:EA1A            [ 3]                     ora       divisor15+3,spx
 2080  M                                                      mloop     ::divisor15
 2080                                                         endm
 2081    [1A5C] 1A5C:27D4 (1A32)     [ 3]                     beq       ?DivError
 2082                                     
 2083                                               ; if Dividend = 0, we're done
 2084                                     
 2085  M                                                      @zero?.s  dividend@@,spx
 2085  M                                                      mset      #
 2085  M                                                      mreq      1
 2085  M                                                      @@_nosize_ dividend15,spx
 2085  M                                                      mset      #
 2085  M                                                      mset      0,mstop [zero?.s] No size (dividend15,spx)
 2085  M                                                      endm
 2085  M                                                      mdo
 2085  M [1A5E] 1A5E:E613            [ 3]                     lda       dividend15+0,spx
 2085  M                                                      mloop     ::dividend15
 2085  M [1A60] 1A60:EA14            [ 3]                     ora       dividend15+1,spx
 2085  M                                                      mloop     ::dividend15
 2085  M [1A62] 1A62:EA15            [ 3]                     ora       dividend15+2,spx
 2085  M                                                      mloop     ::dividend15
 2085  M [1A64] 1A64:EA16            [ 3]                     ora       dividend15+3,spx
 2085  M                                                      mloop     ::dividend15
 2085                                                         endm
 2086    [1A66] 1A66:2603 CC1B 49    [ 7]                     jeq       Done@@
 2087                                     
 2088                                               ; if (divisor = dividend) then quotient := 1; return
 2089                                               ; if (divisor > dividend) then remainder := dividend; return
 2090                                     
 2091  M                                                      @_cmp_.s, divisor@@,spx dividend@@,spx
 2091  M                                                      mreq      1,2:[#]Operand1,[#]Operand2
 2091  M                                                      @@_samesize_ divisor15,spx dividend@@,spx
 2091  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2091  M                                                      mset      0
 2091  M                                                      mdo
 2091  M                                                      mswap     1,1
 2091  M                                                      @@_nosize_ divisor15,spx
 2091  M                                                      mset      #
 2091  M                                                      mset      0,mstop [_samesize_] No size (divisor15,spx)
 2091  M                                                      endm
 2091  M                                                      mset      0,divisor15,spx
 2091  M                                                      mloop     :n
 2091  M                                                      mswap     1,2
 2091  M                                                      @@_nosize_ dividend@@,spx
 2091  M                                                      mset      #
 2091  M                                                      mset      0,mstop [_samesize_] No size (dividend15,spx)
 2091  M                                                      endm
 2091  M                                                      mloop     :n
 2091  M                                                      endm
 2091  M                                                      #temp     1
 2091  M                                                      #temp     ::divisor15
 2091  M                                                      #temp     ::dividend@@
 2091  M                                                      mdo
 2091  M [1A6B] 1A6B:E617            [ 3]                     lda       divisor15+0,spx
 2091  M [1A6D] 1A6D:E113            [ 3]                     cmpa      dividend@@+0,spx
 2091  M [1A6F] 1A6F:2610 (1A81)     [ 3]                     bne       Done$$$
 2091  M                                                      mloop     :temp
 2091  M [1A71] 1A71:E618            [ 3]                     lda       divisor15+1,spx
 2091  M [1A73] 1A73:E114            [ 3]                     cmpa      dividend@@+1,spx
 2091  M [1A75] 1A75:260A (1A81)     [ 3]                     bne       Done$$$
 2091  M                                                      mloop     :temp
 2091  M [1A77] 1A77:E619            [ 3]                     lda       divisor15+2,spx
 2091  M [1A79] 1A79:E115            [ 3]                     cmpa      dividend@@+2,spx
 2091  M [1A7B] 1A7B:2604 (1A81)     [ 3]                     bne       Done$$$
 2091  M                                                      mloop     :temp
 2091  M [1A7D] 1A7D:E61A            [ 3]                     lda       divisor15+3,spx
 2091  M [1A7F] 1A7F:E116            [ 3]                     cmpa      dividend@@+3,spx
 2091  M                                                      mloop     :temp
 2091  M             1A81                 Done$$$
 2091                                                         endm
 2092    [1A81] 1A81:2604 (1A87)     [ 3]                     bne       NotEqual@@
 2093                                     
 2094    [1A83] 1A83:6C03            [ 5]                     inc       ?quotient+{::?quotient-1},x  ;quotient := 1
 2095    [1A85] 1A85:2012 (1A99)     [ 3]                     bra       ??DivExit           ;and get out
 2096                                     
 2097                1A87                 NotEqual@@         ;@sub.s,   divisor@@,spx dividend@@,spx  ;[2012.05.18 REDUNDANT]
 2098    [1A87] 1A87:2513 (1A9C)     [ 3]                     blo       Continue@@
 2099                                     
 2100  M                                                      @mova.s   dividend@@,spx ?remainder,x
 2100  M                                                      mset      #' '
 2100  M                                                      mreq      1,2:Source Destination
 2100  M                                                      @@_samesize_ dividend15,spx ?remainder,x
 2100  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2100  M                                                      mset      0
 2100  M                                                      mdo
 2100  M                                                      mswap     1,1
 2100  M                                                      @@_nosize_ dividend15,spx
 2100  M                                                      mset      #
 2100  M                                                      mset      0,mstop [_samesize_] No size (dividend15,spx)
 2100  M                                                      endm
 2100  M                                                      mset      0,dividend15,spx
 2100  M                                                      mloop     :n
 2100  M                                                      mswap     1,2
 2100  M                                                      @@_nosize_ ?remainder,x
 2100  M                                                      mset      #
 2100  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2100  M                                                      endm
 2100  M                                                      mloop     :n
 2100  M                                                      endm
 2100  M                                                      mset      0
 2100  M                                                      mdo
 2100  M [1A89] 1A89:E613            [ 3]                     lda       dividend15+0,spx
 2100  M [1A8B] 1A8B:E704            [ 3]                     sta       ?remainder+0,x
 2100  M                                                      mloop     ::?remainder
 2100  M [1A8D] 1A8D:E614            [ 3]                     lda       dividend15+1,spx
 2100  M [1A8F] 1A8F:E705            [ 3]                     sta       ?remainder+1,x
 2100  M                                                      mloop     ::?remainder
 2100  M [1A91] 1A91:E615            [ 3]                     lda       dividend15+2,spx
 2100  M [1A93] 1A93:E706            [ 3]                     sta       ?remainder+2,x
 2100  M                                                      mloop     ::?remainder
 2100  M [1A95] 1A95:E616            [ 3]                     lda       dividend15+3,spx
 2100  M [1A97] 1A97:E707            [ 3]                     sta       ?remainder+3,x
 2100  M                                                      mloop     ::?remainder
 2100                                                         endm
 2101                1A99                 ??DivExit                                         ;and get out
 2105    [1A99] 1A99:CC1B 49         [ 4]                     jmp       Done@@
 2107                                     
 2108    [1A9C] 1A9C:A620            [ 2] Continue@@          lda       #MATHSIZE
 2109    [1A9E] 1A9E:E70C            [ 3]                     sta       ?bits,x             ;bits := 64/56/48/40/32/24/16-bit
 2110                                     
 2111                                               ; while (remainder < divisor) do
 2112                                     
 2113  M                                  While@@             @cop                          ;in case of many iterations
 2113  M [1AA0] 1AA0:C718 00         [ 4]                     sta       COP
 2113                                                         endm
 2114                                     
 2115  M                                                      @sub.s,   ?remainder,x divisor@@,spx
 2115  M                                                      mreq      1,2:[#]Operand1,[#]Operand2,Destination
 2115  M                                                      @@_samesize_ ?remainder,x divisor15,spx
 2115  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2115  M                                                      mset      0
 2115  M                                                      mdo
 2115  M                                                      mswap     1,1
 2115  M                                                      @@_nosize_ ?remainder,x
 2115  M                                                      mset      #
 2115  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2115  M                                                      endm
 2115  M                                                      mset      0,?remainder,x
 2115  M                                                      mloop     :n
 2115  M                                                      mswap     1,2
 2115  M                                                      @@_nosize_ divisor15,spx
 2115  M                                                      mset      #
 2115  M                                                      mset      0,mstop [_samesize_] No size (divisor15,spx)
 2115  M                                                      endm
 2115  M                                                      mloop     :n
 2115  M                                                      endm
 2115  M                                                      #temp
 2115  M                                                      @@_nosize_ ?remainder,x
 2115  M                                                      mset      #
 2115  M                                                      mset      0,mstop [sub.s] No size (?remainder,x)
 2115  M                                                      endm
 2115  M                                                      #temp     ::?remainder
 2115  M                                                      mset      0,sub
 2115  M                                                      mdo
 2115  M [1AA3] 1AA3:E607            [ 3]                     lda       ?remainder+3,x
 2115  M [1AA5] 1AA5:E01A            [ 3]                     sub    divisor15+3,spx
 2115  M                                                      mset      0,sbc
 2115  M                                                      mloop     :temp
 2115  M [1AA7] 1AA7:E606            [ 3]                     lda       ?remainder+2,x
 2115  M [1AA9] 1AA9:E219            [ 3]                     sbc    divisor15+2,spx
 2115  M                                                      mset      0,sbc
 2115  M                                                      mloop     :temp
 2115  M [1AAB] 1AAB:E605            [ 3]                     lda       ?remainder+1,x
 2115  M [1AAD] 1AAD:E218            [ 3]                     sbc    divisor15+1,spx
 2115  M                                                      mset      0,sbc
 2115  M                                                      mloop     :temp
 2115  M [1AAF] 1AAF:E604            [ 3]                     lda       ?remainder+0,x
 2115  M [1AB1] 1AB1:E217            [ 3]                     sbc    divisor15+0,spx
 2115  M                                                      mset      0,sbc
 2115  M                                                      mloop     :temp
 2115                                                         endm
 2116    [1AB3] 1AB3:2424 (1AD9)     [ 3]                     bcc       EndWhile@@
 2117                                     
 2118                                               ; remainder := (remainder shl 1) or msb(dividend)
 2119                                     
 2120                                               ;--- 2012.12.04 optimization (moved up this code from before DEC to here)
 2121  M                                                      @mova.s   dividend@@,spx ?temp,x  ; temp := dividend
 2121  M                                                      mset      #' '
 2121  M                                                      mreq      1,2:Source Destination
 2121  M                                                      @@_samesize_ dividend15,spx ?temp,x
 2121  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2121  M                                                      mset      0
 2121  M                                                      mdo
 2121  M                                                      mswap     1,1
 2121  M                                                      @@_nosize_ dividend15,spx
 2121  M                                                      mset      #
 2121  M                                                      mset      0,mstop [_samesize_] No size (dividend15,spx)
 2121  M                                                      endm
 2121  M                                                      mset      0,dividend15,spx
 2121  M                                                      mloop     :n
 2121  M                                                      mswap     1,2
 2121  M                                                      @@_nosize_ ?temp,x
 2121  M                                                      mset      #
 2121  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2121  M                                                      endm
 2121  M                                                      mloop     :n
 2121  M                                                      endm
 2121  M                                                      mset      0
 2121  M                                                      mdo
 2121  M [1AB5] 1AB5:E613            [ 3]                     lda       dividend15+0,spx
 2121  M [1AB7] 1AB7:E708            [ 3]                     sta       ?temp+0,x
 2121  M                                                      mloop     ::?temp
 2121  M [1AB9] 1AB9:E614            [ 3]                     lda       dividend15+1,spx
 2121  M [1ABB] 1ABB:E709            [ 3]                     sta       ?temp+1,x
 2121  M                                                      mloop     ::?temp
 2121  M [1ABD] 1ABD:E615            [ 3]                     lda       dividend15+2,spx
 2121  M [1ABF] 1ABF:E70A            [ 3]                     sta       ?temp+2,x
 2121  M                                                      mloop     ::?temp
 2121  M [1AC1] 1AC1:E616            [ 3]                     lda       dividend15+3,spx
 2121  M [1AC3] 1AC3:E70B            [ 3]                     sta       ?temp+3,x
 2121  M                                                      mloop     ::?temp
 2121                                                         endm
 2122  M                                                      @lsl.s    dividend@@,spx      ; dividend := dividend shl 1
 2122  M                                                      mset      #
 2122  M                                                      mreq      1
 2122  M                                                      @@_nosize_ dividend15,spx
 2122  M                                                      mset      #
 2122  M                                                      mset      0,mstop [lsl.s] No size (dividend15,spx)
 2122  M                                                      endm
 2122  M                                                      mdo
 2122  M [1AC5] 1AC5:6816            [ 5]                     lsl       dividend15+3,spx
 2122  M                                                      mloop     ::dividend15
 2122  M [1AC7] 1AC7:6915            [ 5]                     rol       dividend15+2,spx
 2122  M                                                      mloop     ::dividend15
 2122  M [1AC9] 1AC9:6914            [ 5]                     rol       dividend15+1,spx
 2122  M                                                      mloop     ::dividend15
 2122  M [1ACB] 1ACB:6913            [ 5]                     rol       dividend15+0,spx
 2122  M                                                      mloop     ::dividend15
 2122                                                         endm
 2123                                               ;---
 2124  M                                                      @rol.s    ?remainder,x
 2124  M                                                      mset      #
 2124  M                                                      mreq      1
 2124  M                                                      @@_nosize_ ?remainder,x
 2124  M                                                      mset      #
 2124  M                                                      mset      0,mstop [rol.s] No size (?remainder,x)
 2124  M                                                      endm
 2124  M                                                      mdo
 2124  M [1ACD] 1ACD:6907            [ 5]                     rol       ?remainder+3,x
 2124  M                                                      mloop     ::?remainder
 2124  M [1ACF] 1ACF:6906            [ 5]                     rol       ?remainder+2,x
 2124  M                                                      mloop     ::?remainder
 2124  M [1AD1] 1AD1:6905            [ 5]                     rol       ?remainder+1,x
 2124  M                                                      mloop     ::?remainder
 2124  M [1AD3] 1AD3:6904            [ 5]                     rol       ?remainder+0,x
 2124  M                                                      mloop     ::?remainder
 2124                                                         endm
 2125    [1AD5] 1AD5:6A0C            [ 5]                     dec       ?bits,x             ; bits := bits - 1
 2126                                     
 2127                                               ; end while
 2128                                     
 2129    [1AD7] 1AD7:20C7 (1AA0)     [ 3]                     bra       While@@
 2130                1AD9                 EndWhile@@
 2131  M                                                      @mova.s   ?temp,x dividend@@,spx  ; dividend := temp
 2131  M                                                      mset      #' '
 2131  M                                                      mreq      1,2:Source Destination
 2131  M                                                      @@_samesize_ ?temp,x dividend15,spx
 2131  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2131  M                                                      mset      0
 2131  M                                                      mdo
 2131  M                                                      mswap     1,1
 2131  M                                                      @@_nosize_ ?temp,x
 2131  M                                                      mset      #
 2131  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2131  M                                                      endm
 2131  M                                                      mset      0,?temp,x
 2131  M                                                      mloop     :n
 2131  M                                                      mswap     1,2
 2131  M                                                      @@_nosize_ dividend15,spx
 2131  M                                                      mset      #
 2131  M                                                      mset      0,mstop [_samesize_] No size (dividend15,spx)
 2131  M                                                      endm
 2131  M                                                      mloop     :n
 2131  M                                                      endm
 2131  M                                                      mset      0
 2131  M                                                      mdo
 2131  M [1AD9] 1AD9:E608            [ 3]                     lda       ?temp+0,x
 2131  M [1ADB] 1ADB:E713            [ 3]                     sta       dividend15+0,spx
 2131  M                                                      mloop     ::dividend15
 2131  M [1ADD] 1ADD:E609            [ 3]                     lda       ?temp+1,x
 2131  M [1ADF] 1ADF:E714            [ 3]                     sta       dividend15+1,spx
 2131  M                                                      mloop     ::dividend15
 2131  M [1AE1] 1AE1:E60A            [ 3]                     lda       ?temp+2,x
 2131  M [1AE3] 1AE3:E715            [ 3]                     sta       dividend15+2,spx
 2131  M                                                      mloop     ::dividend15
 2131  M [1AE5] 1AE5:E60B            [ 3]                     lda       ?temp+3,x
 2131  M [1AE7] 1AE7:E716            [ 3]                     sta       dividend15+3,spx
 2131  M                                                      mloop     ::dividend15
 2131                                                         endm
 2132  M                                                      @lsr.s    ?remainder,x        ; remainder := remainder shr 1
 2132  M                                                      mset      #
 2132  M                                                      mreq      1
 2132  M                                                      @@_nosize_ ?remainder,x
 2132  M                                                      mset      #
 2132  M                                                      mset      0,mstop [lsr.s] No size (?remainder,x)
 2132  M                                                      endm
 2132  M                                                      mdo
 2132  M [1AE9] 1AE9:6404            [ 5]                     lsr       ?remainder+0,x
 2132  M                                                      mloop     ::?remainder
 2132  M [1AEB] 1AEB:6605            [ 5]                     ror       ?remainder+1,x
 2132  M                                                      mloop     ::?remainder
 2132  M [1AED] 1AED:6606            [ 5]                     ror       ?remainder+2,x
 2132  M                                                      mloop     ::?remainder
 2132  M [1AEF] 1AEF:6607            [ 5]                     ror       ?remainder+3,x
 2132  M                                                      mloop     ::?remainder
 2132                                                         endm
 2133    [1AF1] 1AF1:6C0C            [ 5]                     inc       ?bits,x             ; bits := bits + 1
 2134                                     
 2135                                               ; for i := bitCounter-1 downto 0 do
 2136                                     
 2137  M                                  For@@               @cop                          ;in case of many iterations
 2137  M [1AF3] 1AF3:C718 00         [ 4]                     sta       COP
 2137                                                         endm
 2138                                     
 2139    [1AF6] 1AF6:6D0C            [ 4]                     tst       ?bits,x
 2141    [1AF8] 1AF8:274F (1B49)     [ 3]                     beq       Done@@
 2145    [1AFA] 1AFA:6A0C            [ 5]                     dec       ?bits,x
 2146                                     
 2147                                               ; remainder := (remainder shl 1) or msb(dividend)
 2148                                               ; dividend := dividend shl 1
 2149                                     
 2150  M                                                      @lsl.s    dividend@@,spx      ;2012.12.04 optimization
 2150  M                                                      mset      #
 2150  M                                                      mreq      1
 2150  M                                                      @@_nosize_ dividend15,spx
 2150  M                                                      mset      #
 2150  M                                                      mset      0,mstop [lsl.s] No size (dividend15,spx)
 2150  M                                                      endm
 2150  M                                                      mdo
 2150  M [1AFC] 1AFC:6816            [ 5]                     lsl       dividend15+3,spx
 2150  M                                                      mloop     ::dividend15
 2150  M [1AFE] 1AFE:6915            [ 5]                     rol       dividend15+2,spx
 2150  M                                                      mloop     ::dividend15
 2150  M [1B00] 1B00:6914            [ 5]                     rol       dividend15+1,spx
 2150  M                                                      mloop     ::dividend15
 2150  M [1B02] 1B02:6913            [ 5]                     rol       dividend15+0,spx
 2150  M                                                      mloop     ::dividend15
 2150                                                         endm
 2151  M                                                      @rol.s    ?remainder,x
 2151  M                                                      mset      #
 2151  M                                                      mreq      1
 2151  M                                                      @@_nosize_ ?remainder,x
 2151  M                                                      mset      #
 2151  M                                                      mset      0,mstop [rol.s] No size (?remainder,x)
 2151  M                                                      endm
 2151  M                                                      mdo
 2151  M [1B04] 1B04:6907            [ 5]                     rol       ?remainder+3,x
 2151  M                                                      mloop     ::?remainder
 2151  M [1B06] 1B06:6906            [ 5]                     rol       ?remainder+2,x
 2151  M                                                      mloop     ::?remainder
 2151  M [1B08] 1B08:6905            [ 5]                     rol       ?remainder+1,x
 2151  M                                                      mloop     ::?remainder
 2151  M [1B0A] 1B0A:6904            [ 5]                     rol       ?remainder+0,x
 2151  M                                                      mloop     ::?remainder
 2151                                                         endm
 2152                                     
 2153                                               ; temp := remainder - divisor
 2154                                     
 2155  M                                                      @sub.s,   ?remainder,x divisor@@,spx ?temp,x
 2155  M                                                      mreq      1,2:[#]Operand1,[#]Operand2,Destination
 2155  M                                                      @@_samesize_ ?remainder,x divisor15,spx ?temp,x
 2155  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2155  M                                                      mset      0
 2155  M                                                      mdo
 2155  M                                                      mswap     1,1
 2155  M                                                      @@_nosize_ ?remainder,x
 2155  M                                                      mset      #
 2155  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2155  M                                                      endm
 2155  M                                                      mset      0,?remainder,x
 2155  M                                                      mloop     :n
 2155  M                                                      mswap     1,2
 2155  M                                                      @@_nosize_ divisor15,spx
 2155  M                                                      mset      #
 2155  M                                                      mset      0,mstop [_samesize_] No size (divisor15,spx)
 2155  M                                                      endm
 2155  M                                                      mloop     :n
 2155  M                                                      mswap     1,3
 2155  M                                                      @@_nosize_ ?temp,x
 2155  M                                                      mset      #
 2155  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2155  M                                                      endm
 2155  M                                                      mloop     :n
 2155  M                                                      endm
 2155  M                                                      #temp
 2155  M                                                      @@_nosize_ ?temp,x
 2155  M                                                      mset      #
 2155  M                                                      mset      0,mstop [sub.s] No size (?temp,x)
 2155  M                                                      endm
 2155  M                                                      #temp     ::?temp
 2155  M                                                      mset      0,sub
 2155  M                                                      mdo
 2155  M [1B0C] 1B0C:E607            [ 3]                     lda       ?remainder+3,x
 2155  M [1B0E] 1B0E:E01A            [ 3]                     sub    divisor15+3,spx
 2155  M [1B10] 1B10:E70B            [ 3]                     sta       ?temp+3,x
 2155  M                                                      mset      0,sbc
 2155  M                                                      mloop     :temp
 2155  M [1B12] 1B12:E606            [ 3]                     lda       ?remainder+2,x
 2155  M [1B14] 1B14:E219            [ 3]                     sbc    divisor15+2,spx
 2155  M [1B16] 1B16:E70A            [ 3]                     sta       ?temp+2,x
 2155  M                                                      mset      0,sbc
 2155  M                                                      mloop     :temp
 2155  M [1B18] 1B18:E605            [ 3]                     lda       ?remainder+1,x
 2155  M [1B1A] 1B1A:E218            [ 3]                     sbc    divisor15+1,spx
 2155  M [1B1C] 1B1C:E709            [ 3]                     sta       ?temp+1,x
 2155  M                                                      mset      0,sbc
 2155  M                                                      mloop     :temp
 2155  M [1B1E] 1B1E:E604            [ 3]                     lda       ?remainder+0,x
 2155  M [1B20] 1B20:E217            [ 3]                     sbc    divisor15+0,spx
 2155  M [1B22] 1B22:E708            [ 3]                     sta       ?temp+0,x
 2155  M                                                      mset      0,sbc
 2155  M                                                      mloop     :temp
 2155                                                         endm
 2156                                     
 2157                                               ; q := not msb(temp)
 2158                                     
 2159    [1B24] 1B24:E608            [ 3]                     lda       ?temp,x
 2160    [1B26] 1B26:A880            [ 2]                     eor       #%10000000          ;invert msb
 2161    [1B28] 1B28:A480            [ 2]                     and       #%10000000          ;isolate msb
 2162                                     
 2163                                               ; quotient := (quotient shl 1) or q
 2164                                     
 2165    [1B2A] 1B2A:87              [ 2]                     psha
 2166    [1B2B] 1B2B:48              [ 1]                     lsla
 2167    [1B2C] 1B2C:86              [ 3]                     pula
 2168                                     
 2169  M                                                      @rol.s    ?quotient,x
 2169  M                                                      mset      #
 2169  M                                                      mreq      1
 2169  M                                                      @@_nosize_ ?quotient,x
 2169  M                                                      mset      #
 2169  M                                                      mset      0,mstop [rol.s] No size (?quotient,x)
 2169  M                                                      endm
 2169  M                                                      mdo
 2169  M [1B2D] 1B2D:6903            [ 5]                     rol       ?quotient+3,x
 2169  M                                                      mloop     ::?quotient
 2169  M [1B2F] 1B2F:6902            [ 5]                     rol       ?quotient+2,x
 2169  M                                                      mloop     ::?quotient
 2169  M [1B31] 1B31:6901            [ 5]                     rol       ?quotient+1,x
 2169  M                                                      mloop     ::?quotient
 2169  M [1B33] 1B33:79              [ 4]                     rol       ?quotient+0,x
 2169  M                                                      mloop     ::?quotient
 2169                                                         endm
 2170                                     
 2171                                               ; if q <> 0 then
 2172                                     
 2173    [1B34] 1B34:4100 BC(1AF3)   [ 4]                     cbeqa     #0,For@@
 2174                                     
 2175                                               ; remainder := temp
 2176                                     
 2177  M                                                      @mova.s   ?temp,x ?remainder,x
 2177  M                                                      mset      #' '
 2177  M                                                      mreq      1,2:Source Destination
 2177  M                                                      @@_samesize_ ?temp,x ?remainder,x
 2177  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2177  M                                                      mset      0
 2177  M                                                      mdo
 2177  M                                                      mswap     1,1
 2177  M                                                      @@_nosize_ ?temp,x
 2177  M                                                      mset      #
 2177  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2177  M                                                      endm
 2177  M                                                      mset      0,?temp,x
 2177  M                                                      mloop     :n
 2177  M                                                      mswap     1,2
 2177  M                                                      @@_nosize_ ?remainder,x
 2177  M                                                      mset      #
 2177  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2177  M                                                      endm
 2177  M                                                      mloop     :n
 2177  M                                                      endm
 2177  M                                                      mset      0
 2177  M                                                      mdo
 2177  M [1B37] 1B37:E608            [ 3]                     lda       ?temp+0,x
 2177  M [1B39] 1B39:E704            [ 3]                     sta       ?remainder+0,x
 2177  M                                                      mloop     ::?remainder
 2177  M [1B3B] 1B3B:E609            [ 3]                     lda       ?temp+1,x
 2177  M [1B3D] 1B3D:E705            [ 3]                     sta       ?remainder+1,x
 2177  M                                                      mloop     ::?remainder
 2177  M [1B3F] 1B3F:E60A            [ 3]                     lda       ?temp+2,x
 2177  M [1B41] 1B41:E706            [ 3]                     sta       ?remainder+2,x
 2177  M                                                      mloop     ::?remainder
 2177  M [1B43] 1B43:E60B            [ 3]                     lda       ?temp+3,x
 2177  M [1B45] 1B45:E707            [ 3]                     sta       ?remainder+3,x
 2177  M                                                      mloop     ::?remainder
 2177                                                         endm
 2178                                     
 2179                                               ; end if -- end for
 2180                                     
 2182    [1B47] 1B47:20AA (1AF3)     [ 3]                     bra       For@@
 2186                                     
 2187    [1B49] 1B49:E60D            [ 3] Done@@              lda       ?flags,x
 2188    [1B4B] 1B4B:A501            [ 2]                     bit       #?DIVOP_
 2189    [1B4D] 1B4D:2711 (1B60)     [ 3]                     beq       ExitMod@@
 2190                                     
 2191                0251                 ?Cycles             equ       :cycles
 2192                                     
 2193                                     ;ExitDiv@@
 2194  M                                                      @mova.s   ?quotient,x ans@@,spx
 2194  M                                                      mset      #' '
 2194  M                                                      mreq      1,2:Source Destination
 2194  M                                                      @@_samesize_ ?quotient,x ans15,spx
 2194  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2194  M                                                      mset      0
 2194  M                                                      mdo
 2194  M                                                      mswap     1,1
 2194  M                                                      @@_nosize_ ?quotient,x
 2194  M                                                      mset      #
 2194  M                                                      mset      0,mstop [_samesize_] No size (?quotient,x)
 2194  M                                                      endm
 2194  M                                                      mset      0,?quotient,x
 2194  M                                                      mloop     :n
 2194  M                                                      mswap     1,2
 2194  M                                                      @@_nosize_ ans15,spx
 2194  M                                                      mset      #
 2194  M                                                      mset      0,mstop [_samesize_] No size (ans15,spx)
 2194  M                                                      endm
 2194  M                                                      mloop     :n
 2194  M                                                      endm
 2194  M                                                      mset      0
 2194  M                                                      mdo
 2194  M [1B4F] 1B4F:F6              [ 3]                     lda       ?quotient+0,x
 2194  M [1B50] 1B50:E717            [ 3]                     sta       ans15+0,spx
 2194  M                                                      mloop     ::ans15
 2194  M [1B52] 1B52:E601            [ 3]                     lda       ?quotient+1,x
 2194  M [1B54] 1B54:E718            [ 3]                     sta       ans15+1,spx
 2194  M                                                      mloop     ::ans15
 2194  M [1B56] 1B56:E602            [ 3]                     lda       ?quotient+2,x
 2194  M [1B58] 1B58:E719            [ 3]                     sta       ans15+2,spx
 2194  M                                                      mloop     ::ans15
 2194  M [1B5A] 1B5A:E603            [ 3]                     lda       ?quotient+3,x
 2194  M [1B5C] 1B5C:E71A            [ 3]                     sta       ans15+3,spx
 2194  M                                                      mloop     ::ans15
 2194                                                         endm
 2195    [1B5E] 1B5E:2010 (1B70)     [ 3]                     bra       ExitBoth@@
 2196                                     
 2197                028B                 ?DivCycles          set       ?DivCycles+?Cycles+:cycles
 2198                                     
 2199  M                                  ExitMod@@           @mova.s   ?remainder,x ans@@,spx
 2199  M                                                      mset      #' '
 2199  M                                                      mreq      1,2:Source Destination
 2199  M                                                      @@_samesize_ ?remainder,x ans15,spx
 2199  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2199  M                                                      mset      0
 2199  M                                                      mdo
 2199  M                                                      mswap     1,1
 2199  M                                                      @@_nosize_ ?remainder,x
 2199  M                                                      mset      #
 2199  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2199  M                                                      endm
 2199  M                                                      mset      0,?remainder,x
 2199  M                                                      mloop     :n
 2199  M                                                      mswap     1,2
 2199  M                                                      @@_nosize_ ans15,spx
 2199  M                                                      mset      #
 2199  M                                                      mset      0,mstop [_samesize_] No size (ans15,spx)
 2199  M                                                      endm
 2199  M                                                      mloop     :n
 2199  M                                                      endm
 2199  M                                                      mset      0
 2199  M                                                      mdo
 2199  M [1B60] 1B60:E604            [ 3]                     lda       ?remainder+0,x
 2199  M [1B62] 1B62:E717            [ 3]                     sta       ans15+0,spx
 2199  M                                                      mloop     ::ans15
 2199  M [1B64] 1B64:E605            [ 3]                     lda       ?remainder+1,x
 2199  M [1B66] 1B66:E718            [ 3]                     sta       ans15+1,spx
 2199  M                                                      mloop     ::ans15
 2199  M [1B68] 1B68:E606            [ 3]                     lda       ?remainder+2,x
 2199  M [1B6A] 1B6A:E719            [ 3]                     sta       ans15+2,spx
 2199  M                                                      mloop     ::ans15
 2199  M [1B6C] 1B6C:E607            [ 3]                     lda       ?remainder+3,x
 2199  M [1B6E] 1B6E:E71A            [ 3]                     sta       ans15+3,spx
 2199  M                                                      mloop     ::ans15
 2199                                                         endm
 2200                                     
 2201                027F                 ?ModCycles          set       ?ModCycles+?Cycles+:cycles
 2202                                     
 2203                1B70                 ExitBoth@@
 2205    [1B70] 1B70:6D0D            [ 4]                     tst       ?flags,x
 2206    [1B72] 1B72:2A06 (1B7A)     [ 3]                     bpl       SkipSign@@
 2207  M                                                      @lea      ans@@,sp
 2207  M                                                      mset      #
 2207  M [1B74] 1B74:95              [ 2]                     tsx
 2207  M [1B75] 1B75:AF17            [ 2]                     !aix      #ans15+:tsx
 2207                                                         mexit
 2208    [1B77] 1B77:CD1A 1F         [ 6]                     jsr       ?NegX
 2209                1B7A                 SkipSign@@
 2210                                                                   #Cycles ?NegxCycles+:cycles
 2212    [1B7A] 1B7A:A70E            [ 2]                     ais       #?SF                ;de-allocate temporaries
 2213    [1B7C] 1B7C:98              [ 1]                     clc                           ;no error(s)
 2214                                     
 2215                003E                 ?Cycles             set       :cycles
 2216                02C9                 ?DivCycles          set       ?DivCycles+?Cycles
 2217                02BD                 ?ModCycles          set       ?ModCycles+?Cycles
 2218                                     
 2219                                     ;                   bra       ?RemoveAndReturn
 2220                                     
 2221                                     ;*******************************************************************************
 2222                                     ; Common exit removes lower 32-bit stack element and returns to caller
 2223                                     ;*******************************************************************************
 2224                                     
 2225                1B7D                 ?RemoveAndReturn
 2226                                     
 2228    [1B7D] 1B7D:9EFE 04         [ 5]                     ldhx      ?pc,sp              ;our return address moved up
 2229    [1B80] 1B80:9EFF 08         [ 5]                     sthx      ?pc+?WORD,sp        ;above word to remove
 2234                                     
 2240    [1B83] 1B83:8A88 86         [ 9]                     pull
 2241    [1B86] 1B86:A704            [ 2]                     ais       #?WORD              ;remove top-of-stack ?WORD
 2242    [1B88] 1B88:81              [ 6]                     rtc
 2243                                     
 2244                001B                 ?ReturnCycles       equ       :cycles
 2245                                     
 2246                                     ;*******************************************************************************
 2247                                     ; Purpose: Swaps the stacked order of N1 and N2
 2248                                     ; Input  : [TOS+?WORD] = Number2
 2249                                     ;        : [TOS] = Number1
 2250                                     ; Output : [TOS+?WORD] = Number1 -- TOS & [TOS+?WORD] in reverse order
 2251                                     ;        : [TOS] = Number2
 2252                                     ; Note(s): Does not alter stack size
 2253                                     
 2254                                                         #spauto   :ab
 2255                                     
 2256                1B89                 ?Swap               proc
 2257    [1B89] 1B89:8789 8B         [ 6]                     push
 2258                                     
 2259    [1B8C] 1B8C:A604            [ 2]                     lda       #?WORD
 2260    [1B8E] 1B8E:87              [ 2]                     psha      bytes@@
 2261                                     
 2262    [1B8F] 1B8F:95              [ 2]                     tsx
 2263                                                                   #temp :cycles
 2264  M                                  Loop@@              @_swap_,  ?a,spx ?b,spx       ;swap A with B ...
 2264  M                                                      #push
 2264  M                                                      #spauto   :sp
 2264  M [1B90] 1B90:E606            [ 3]                     lda       ?a,spx
 2264  M [1B92] 1B92:87              [ 2]                     psha
 2264  M [1B93] 1B93:E60A            [ 3]                     lda       ?b,spx
 2264  M [1B95] 1B95:E706            [ 3]                     sta       ?a,spx
 2264  M [1B97] 1B97:86              [ 3]                     pula
 2264  M [1B98] 1B98:E70A            [ 3]                     sta       ?b,spx
 2264  M                                                      #pull
 2264                                                         endm
 2265                                     
 2266    [1B9A] 1B9A:AF01            [ 2]                     aix       #1                  ;point to next byte
 2267    [1B9C] 1B9C:9E6B 01F0 (1B90 [ 8]                     dbnz      bytes@@,sp,Loop@@   ;repeat for all bytes
 2268                                                                   #temp :cycles*?WORD+:temp
 2269    [1BA0] 1BA0:86              [ 3]                     pula
 2270                                     
 2271    [1BA1] 1BA1:8A88 86         [ 9]                     pull
 2272    [1BA4] 1BA4:81              [ 6]                     rtc
 2273                                     
 2274                008A                 ?SwapCycles         set       :cycles+:temp
 2275                                     
 2276                                     ;*******************************************************************************
 2277                                     ; Purpose: Get the absolute value of the top-of-stack number
 2278                                     ; Input  : [TOS] = Number
 2279                                     ; Output : [TOS] = Abs(Number)
 2280                                     ; Note(s): Does not alter stack size
 2281                                     
 2282                                                         #spauto   :ab
 2283                                     
 2284                1BA5                 ?Abs                proc
 2285    [1BA5] 1BA5:9E6D 03         [ 5]                     tst       ?a,sp
 2286    [1BA8] 1BA8:2AFA (1BA4)     [ 3]                     bpl       Done@@
 2287                                     ;                   bra       ?Negate
 2288                                     
 2289                1BA4                 Done@@              equ       :AnRTC
 2290                                     
 2291                0008                 ?AbsCycles          equ       :cycles
 2292                                     
 2293                                     ;*******************************************************************************
 2294                                     ; Purpose: Negate the top-of-stack number
 2295                                     ; Input  : [TOS] = Number
 2296                                     ; Output : [TOS] = -Number
 2297                                     ; Note(s): Does not alter stack size
 2298                                     
 2299                                                         #spauto   :ab
 2300                                     
 2301                1BAA                 ?Negate             proc
 2302    [1BAA] 1BAA:898B            [ 4]                     pshhx
 2304  M                                                      @lea      ?a,sp
 2304  M                                                      mset      #
 2304  M [1BAC] 1BAC:95              [ 2]                     tsx
 2304  M [1BAD] 1BAD:AF04            [ 2]                     !aix      #?a+:tsx
 2304                                                         mexit
 2305    [1BAF] 1BAF:CD1A 1F         [ 6]                     jsr       ?NegX
 2306                                                                   #Cycles ?NegxCycles+:cycles
 2311    [1BB2] 1BB2:8A88            [ 6]                     pulhx
 2312    [1BB4] 1BB4:81              [ 6]                     rtc
 2313                                     
 2314                0044                 ?NegateCycles       equ       :cycles
 2315                004C                 ?AbsCycles          set       ?NegateCycles+?AbsCycles
 2316                                     
 2317                                     ;*******************************************************************************
 2318                                     ; Purpose: Create a new top-of-stack and load to it the number pointed to by HX
 2319                                     ; Input  : HX -> [Variable with] Number
 2320                                     ; Output : [TOS] = Number
 2321                                     ; Note(s): This operation makes it easier to load a number to the stack.
 2322                                     ;        : Hint: To make a copy of the TOS, do:
 2323                                     ;        :          tsx
 2324                                     ;        :          call      StackLoad32
 2325                                     ;        : (Stack is expanded)
 2326                                     
 2327                                                         #spauto   :ab
 2328                                     
 2329                1BB5                 ?Load               proc
 2330                FFFFFFFF             old_rts@@           equ       ::,:ab
 2331    [1BB5] 1BB5:A7FC            [ 2]                     ais       #-?WORD             ;allocate new TOS memory
 2332                                                         #temp     ::
 2333                FFFFFFFB             new_rts@@           next      :temp,:ab
 2334                FFFFFFFD             tos_num@@           next      :temp,?WORD
 2335                0001                                     next      :temp,-:ab          ;-:AB as old_rts@@ will be gone
 2336                                                         #ais      :temp
 2337                                     
 2338    [1BB7] 1BB7:87              [ 2]                     psha
 2339  M                                                      @mova.s   old_rts@@,sp new_rts@@,sp  ;move RTS/RTC after new memory
 2339  M                                                      mset      #' '
 2339  M                                                      mreq      1,2:Source Destination
 2339  M                                                      @@_samesize_ old_rts19,sp new_rts@@,sp
 2339  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2339  M                                                      mset      0
 2339  M                                                      mdo
 2339  M                                                      mswap     1,1
 2339  M                                                      @@_nosize_ old_rts19,sp
 2339  M                                                      mset      #
 2339  M                                                      mset      0,mstop [_samesize_] No size (old_rts19,sp)
 2339  M                                                      endm
 2339  M                                                      mset      0,old_rts19,sp
 2339  M                                                      mloop     :n
 2339  M                                                      mswap     1,2
 2339  M                                                      @@_nosize_ new_rts@@,sp
 2339  M                                                      mset      #
 2339  M                                                      mset      0,mstop [_samesize_] No size (new_rts19,sp)
 2339  M                                                      endm
 2339  M                                                      mloop     :n
 2339  M                                                      endm
 2339  M                                                      mset      0
 2339  M                                                      mdo
 2339  M [1BB8] 1BB8:9EE6 06         [ 4]                     lda       old_rts19+0,sp
 2339  M [1BBB] 1BBB:9EE7 02         [ 4]                     sta       new_rts@@+0,sp
 2339  M                                                      mloop     ::new_rts@@
 2339  M [1BBE] 1BBE:9EE6 07         [ 4]                     lda       old_rts19+1,sp
 2339  M [1BC1] 1BC1:9EE7 03         [ 4]                     sta       new_rts@@+1,sp
 2339  M                                                      mloop     ::new_rts@@
 2339                                                         endm
 2340  M                                                      @mova.s   ,x tos_num@@,sp
 2340  M                                                      mset      #' '
 2340  M                                                      mreq      1,2:Source Destination
 2340  M                                                      @@_samesize_ ,x tos_num19,sp
 2340  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2340  M                                                      mset      0
 2340  M                                                      mdo
 2340  M                                                      mswap     1,1
 2340  M                                                      mloop     :n
 2340  M                                                      mswap     1,2
 2340  M                                                      @@_nosize_ tos_num19,sp
 2340  M                                                      mset      #
 2340  M                                                      mset      0,mstop [_samesize_] No size (tos_num19,sp)
 2340  M                                                      endm
 2340  M                                                      mset      0,tos_num19,sp
 2340  M                                                      mloop     :n
 2340  M                                                      endm
 2340  M                                                      mset      0
 2340  M                                                      mdo
 2340  M [1BC4] 1BC4:F6              [ 3]                     lda       +0,x
 2340  M [1BC5] 1BC5:9EE7 04         [ 4]                     sta       tos_num19+0,sp
 2340  M                                                      mloop     ::tos_num19
 2340  M [1BC8] 1BC8:E601            [ 3]                     lda       +1,x
 2340  M [1BCA] 1BCA:9EE7 05         [ 4]                     sta       tos_num19+1,sp
 2340  M                                                      mloop     ::tos_num19
 2340  M [1BCD] 1BCD:E602            [ 3]                     lda       +2,x
 2340  M [1BCF] 1BCF:9EE7 06         [ 4]                     sta       tos_num19+2,sp
 2340  M                                                      mloop     ::tos_num19
 2340  M [1BD2] 1BD2:E603            [ 3]                     lda       +3,x
 2340  M [1BD4] 1BD4:9EE7 07         [ 4]                     sta       tos_num19+3,sp
 2340  M                                                      mloop     ::tos_num19
 2340                                                         endm
 2341    [1BD7] 1BD7:86              [ 3]                     pula
 2342    [1BD8] 1BD8:81              [ 6]                     rtc
 2343                                     
 2344                0039                 ?LoadCycles         equ       :cycles
 2345                                     
 2346                                     ;*******************************************************************************
 2347                                     ; Purpose: Unload the top-of-stack number into a variable pointed to by HX
 2348                                     ; Input  : [TOS] = Number
 2349                                     ;        : HX -> Some 32-bit variable
 2350                                     ; Output : Variable pointed to by HX receives TOS number
 2351                                     ; Note(s): This operation makes it easier to unload a number from the stack.
 2352                                     ;        : Use:
 2353                                     ;        :          ldhx      #MyVar
 2354                                     ;        :          call      StackSave32
 2355                                     ;        : (Stack is reduced)
 2356                                     
 2357                                                         #spauto   :ab
 2358                                     
 2359                1BD9                 ?Save               proc
 2360                                                         #temp     ::
 2361                FFFFFFFF             old_rts@@           next      :temp,:ab
 2362                0001                 tos_num@@           next      :temp,?WORD
 2363                0005                                     next      :temp,-:ab          ;-:AB as old_rts@@ will be gone
 2364                0003                 new_rts@@           next      :temp,:ab
 2365                                     
 2366                0000                 var@@               equ       0,?WORD
 2367                                     
 2368    [1BD9] 1BD9:8789 8B         [ 6]                     push
 2369  M                                                      @mova.s   tos_num@@,sp var@@,x
 2369  M                                                      mset      #' '
 2369  M                                                      mreq      1,2:Source Destination
 2369  M                                                      @@_samesize_ tos_num20,sp var@@,x
 2369  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2369  M                                                      mset      0
 2369  M                                                      mdo
 2369  M                                                      mswap     1,1
 2369  M                                                      @@_nosize_ tos_num20,sp
 2369  M                                                      mset      #
 2369  M                                                      mset      0,mstop [_samesize_] No size (tos_num20,sp)
 2369  M                                                      endm
 2369  M                                                      mset      0,tos_num20,sp
 2369  M                                                      mloop     :n
 2369  M                                                      mswap     1,2
 2369  M                                                      @@_nosize_ var@@,x
 2369  M                                                      mset      #
 2369  M                                                      mset      0,mstop [_samesize_] No size (var20,x)
 2369  M                                                      endm
 2369  M                                                      mloop     :n
 2369  M                                                      endm
 2369  M                                                      mset      0
 2369  M                                                      mdo
 2369  M [1BDC] 1BDC:9EE6 06         [ 4]                     lda       tos_num20+0,sp
 2369  M [1BDF] 1BDF:F7              [ 2]                     sta       var@@+0,x
 2369  M                                                      mloop     ::var@@
 2369  M [1BE0] 1BE0:9EE6 07         [ 4]                     lda       tos_num20+1,sp
 2369  M [1BE3] 1BE3:E701            [ 3]                     sta       var@@+1,x
 2369  M                                                      mloop     ::var@@
 2369  M [1BE5] 1BE5:9EE6 08         [ 4]                     lda       tos_num20+2,sp
 2369  M [1BE8] 1BE8:E702            [ 3]                     sta       var@@+2,x
 2369  M                                                      mloop     ::var@@
 2369  M [1BEA] 1BEA:9EE6 09         [ 4]                     lda       tos_num20+3,sp
 2369  M [1BED] 1BED:E703            [ 3]                     sta       var@@+3,x
 2369  M                                                      mloop     ::var@@
 2369                                                         endm
 2370                                     
 2371    [1BEF] 1BEF:95              [ 2]                     tsx
 2372  M                                                      @mova.s   old_rts@@,spx new_rts@@,spx  ;move RTS/RTC before old memory
 2372  M                                                      mset      #' '
 2372  M                                                      mreq      1,2:Source Destination
 2372  M                                                      @@_samesize_ old_rts20,spx new_rts@@,spx
 2372  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2372  M                                                      mset      0
 2372  M                                                      mdo
 2372  M                                                      mswap     1,1
 2372  M                                                      @@_nosize_ old_rts20,spx
 2372  M                                                      mset      #
 2372  M                                                      mset      0,mstop [_samesize_] No size (old_rts20,spx)
 2372  M                                                      endm
 2372  M                                                      mset      0,old_rts20,spx
 2372  M                                                      mloop     :n
 2372  M                                                      mswap     1,2
 2372  M                                                      @@_nosize_ new_rts@@,spx
 2372  M                                                      mset      #
 2372  M                                                      mset      0,mstop [_samesize_] No size (new_rts20,spx)
 2372  M                                                      endm
 2372  M                                                      mloop     :n
 2372  M                                                      endm
 2372  M                                                      mset      0
 2372  M                                                      mdo
 2372  M [1BF0] 1BF0:E603            [ 3]                     lda       old_rts20+0,spx
 2372  M [1BF2] 1BF2:E707            [ 3]                     sta       new_rts@@+0,spx
 2372  M                                                      mloop     ::new_rts@@
 2372  M [1BF4] 1BF4:E604            [ 3]                     lda       old_rts20+1,spx
 2372  M [1BF6] 1BF6:E708            [ 3]                     sta       new_rts@@+1,spx
 2372  M                                                      mloop     ::new_rts@@
 2372                                                         endm
 2373    [1BF8] 1BF8:8A88 86         [ 9]                     pull
 2374                                     
 2375    [1BFB] 1BFB:A704            [ 2]                     ais       #?WORD              ;de-allocate TOS memory
 2376    [1BFD] 1BFD:81              [ 6]                     rtc
 2377                                     
 2378                0040                 ?SaveCycles         equ       :cycles
 2379                                     
 2380                                     ;*******************************************************************************
 2381                                     ; Purpose: Adjust TOS old size to new
 2382                                     ; Input  : H = old (current) byte size
 2383                                     ;        : X = new byte size
 2384                                     ;        : CCR[C] = 0 -- always positive number
 2385                                     ;        : CCR[C] = 1 -- sign extend
 2386                                     ; Output : None
 2387                                     ; Note(s): RegA deliberately not used for parameter passing (for consistency)
 2388                                     ;        : Macro destroys RegHX (as we must not use PSHHX/PULHX around call)
 2389                                     
 2391                                     
 2392                                     ResizeTOS           macro     #FromByteSize,#ToByteSize,,unsigned_if_present
 2393                                                         mreq      1,2:#FromByteSize,#ToByteSize
 2394                                               #ifb ~1.1.1~~2.1.1~ = ##
 2395                                                         mstop     Usage: ~0~ #FromByteSize,#ToByteSize
 2396                                               #endif
 2397                                                         #temp     {~#2~}-{~#1~}
 2398                                               #ifz :temp
 2399                                                         mexit                         ;;same sizes, nothing to do
 2400                                               #endif
 2401                                               #ifnb ~4~
 2402                                                         #Message  {~#1~*8}-bit => {~#2~*8}-bit
 2403                                               #else ifdef SIGNED
 2404                                                         #Message  Signed {~#1~*8}-bit => {~#2~*8}-bit
 2405                                               #else
 2406                                                         #Message  {~#1~*8}-bit => {~#2~*8}-bit
 2407                                               #endif
 2408                                               #if :temp > 0                           ;;increase stack (optimized)
 2409                                                 #if :temp < 5                         ;;up to size 'long'
 2410                                                         clrx                          ;;assume unsigned
 2411                                                   #ifb ~4~                            ;;if 'unsigned override' not present
 2412                                                     #ifdef SIGNED                     ;;and signed version is used
 2413                                                         tst       1,asp               ;;test operand sign
 2414                                                         bpl       *+3                 ;;skip over following COMX
 2415                                                         !comx                         ;;sign-extend negative number
 2416                                                     #endif
 2417                                                   #endif
 2418                                                         pshx:{:temp}                  ;;(added the curly brackets to make the number visible in LST file)
 2419                                                         mexit
 2420                                                 #endif
 2421                                               #endif
 2422                                               #if :temp < 0                           ;;decrease stack (optimized)
 2423                                                 #if :temp > -5
 2424                                                         ais       #-:temp             ;;release stack bytes (negative :temp => positive)
 2425                                                         mexit
 2426                                                 #endif
 2427                                               #endif
 2428                                                         ldhx      #~#1~<8|{~#2~}      ;;(longer sizes use normal method)
 2429                                               #ifdef SIGNED                           ;;if signed version is used
 2430                                                 #ifb ~4~                              ;;and if 'unsigned override' not present
 2431                                                         sec                           ;;use sign extension
 2432                                                 #else
 2433                                                         clc                           ;;no sign extension
 2434                                                 #endif
 2435                                               #endif
 2436                                                         call      ~0~                 ;;call stack resizing routine
 2437                                                         #spadd    ~#2~-{~#1~}
 2438                                                         endm
 2439                                     
 2440                                     ;-------------------------------------------------------------------------------
 2441                                     
 2442                                                         #spauto   :ab
 2443                                     
 2444                1BFE                 ResizeTOS           proc
 2445    [1BFE] 1BFE:8789 8B         [ 6]                     push      :temp
 2446                FFFFFFFC             old@@               next      :temp
 2447                                     ;new@@              next      :temp
 2448                                     
 2449    [1C01] 1C01:85              [ 1]                     tpa
 2450    [1C02] 1C02:87              [ 2]                     psha      ccr@@
 2451                                     
 2452                                                         #ais
 2453                                                         #psp
 2454                                     
 2455    [1C03] 1C03:9F              [ 1]                     txa                           ;A = new byte size
 2456    [1C04] 1C04:9EE0 02         [ 4]                     sub       old@@,sp            ;A = bytes to add/remove
 2457    [1C07] 1C07:2735 (1C3E)     [ 3]                     beq       Done@@              ;nothing to do, get out
 2458    [1C09] 1C09:2B20 (1C2B)     [ 3]                     bmi       Shrink@@            ;go take care of 'remove' case
 2459                                     
 2460                                               ;---------------------------------------------------------------------
 2461                                               ; "positive" case, going from smaller to larger size
 2462                                               ;---------------------------------------------------------------------
 2463                                     
 2464    [1C0B] 1C0B:87              [ 2] Expand@@            psha      room@@              ;create room for expansion
 2465    [1C0C] 1C0C:95              [ 2]                     tsx
 2466                                     
 2467    [1C0D] 1C0D:87              [ 2]                     psha                          ;protect counter
 2468                                     
 2469    [1C0E] 1C0E:A606            [ 2]                     lda       #:sp-:psp
 2470    [1C10] 1C10:87              [ 2] ExpandLoop@@        psha
 2471    [1C11] 1C11:E601            [ 3]                     lda       room@@+1,spx
 2472    [1C13] 1C13:F7              [ 2]                     sta       room@@,spx
 2473    [1C14] 1C14:86              [ 3]                     pula
 2474    [1C15] 1C15:AF01            [ 2]                     aix       #1
 2475    [1C17] 1C17:4BF7 (1C10)     [ 4]                     dbnza     ExpandLoop@@
 2476                                     
 2477    [1C19] 1C19:7F              [ 4]                     clr       ,x                  ;positive sign extension
 2479    [1C1A] 1C1A:9EE6 02         [ 4]                     lda       ccr@@-1,sp          ;BugFix: 2014.10.14 (WAS: ccr@@,sp)
 2480    [1C1D] 1C1D:84              [ 1]                     tap
 2481    [1C1E] 1C1E:2406 (1C26)     [ 3]                     bcc       ExpandNext@@
 2482                                     
 2483    [1C20] 1C20:9E6D 09         [ 5]                     tst       1,sp
 2484    [1C23] 1C23:2A01 (1C26)     [ 3]                     bpl       ExpandNext@@
 2485    [1C25] 1C25:73              [ 4]                     com       ,x                  ;negative sign extension
 2487    [1C26] 1C26:86              [ 3] ExpandNext@@        pula
 2488    [1C27] 1C27:4BE2 (1C0B)     [ 4]                     dbnza     Expand@@
 2489                                     
 2490    [1C29] 1C29:2013 (1C3E)     [ 3]                     bra       Done@@
 2491                                     
 2492                                               ;---------------------------------------------------------------------
 2493                                               ; "negative" case, going from larger to smaller size
 2494                                               ;---------------------------------------------------------------------
 2495                                                         #push
 2496                                                         #spadd    -1                  ;account for room@@ PSHA above
 2497                                                         #psp
 2498                                     
 2499    [1C2B] 1C2B:40              [ 1] Shrink@@            nega                          ;make counter positive
 2500                                     
 2501    [1C2C] 1C2C:87              [ 2] ShrinkAgain@@       psha
 2502    [1C2D] 1C2D:95              [ 2]                     tsx
 2503                                     
 2504    [1C2E] 1C2E:A606            [ 2]                     lda       #:sp-:psp
 2505    [1C30] 1C30:87              [ 2] ShrinkLoop@@        psha
 2506    [1C31] 1C31:E606            [ 3]                     lda       1-1,spx
 2507    [1C33] 1C33:E707            [ 3]                     sta       1,spx
 2508    [1C35] 1C35:86              [ 3]                     pula
 2509    [1C36] 1C36:AFFF            [ 2]                     aix       #-1
 2510    [1C38] 1C38:4BF6 (1C30)     [ 4]                     dbnza     ShrinkLoop@@
 2511                                     
 2512    [1C3A] 1C3A:86              [ 3]                     pula
 2513    [1C3B] 1C3B:88              [ 3]                     pulx                          ;get rid of extra room (AIS #1)
 2514    [1C3C] 1C3C:4BEE (1C2C)     [ 4]                     dbnza     ShrinkAgain@@
 2515                                     
 2516                                                         #pull
 2517                                               ;---------------------------------------------------------------------
 2518                                     
 2519    [1C3E] 1C3E:A701            [ 2] Done@@              ais       #:ais
 2520    [1C40] 1C40:8A88 86         [ 9]                     pull
 2521    [1C43] 1C43:81              [ 6]                     rtc
 2523                                     
 2524                                     ;*******************************************************************************
 2525                                     ; Purpose: Convert 32-bit to ASCIZ string
 2526                                     ; Input  : Stack: 32-bit number
 2527                                     ;        : HX -> Output buffer with enough space to keep the ASCIZ string result
 2528                                     ; Output : None
 2529                                     ; Note(s): Use:
 2530                                     ;        :          ldhx      #Buffer
 2531                                     ;        :          call      Stack32ToASCIZ
 2532                                     
 2533                                                         #spauto   :ab                 ;account for RTS/RTC
 2534                                     
 2535                1C44                 ?ToStr              proc
 2536    [1C44] 1C44:8789 8B         [ 6]                     push
 2537                                     
 2538                                                         #psp                          ;mark beginning of temporaries
 2539                                     
 2540    [1C47] 1C47:898B            [ 4]                     pshhx     .buffer@@           ;working copy of pointer to buffer
 2541    [1C49] 1C49:7F              [ 4]                     clr       ,x                  ;make it an ASCIZ string
 2542                                     
 2543  M                                                      @lea      1,sp                ;HX -> TOS number of caller
 2543  M                                                      mset      #
 2543  M [1C4A] 1C4A:95              [ 2]                     tsx
 2543  M [1C4B] 1C4B:AF07            [ 2]                     !aix      #1+:tsx
 2543                                                         mexit
 2544    [1C4D] 1C4D:CD1B B5         [ 6]                     call      ?Load               ;load a working copy on stack
 2545                                     
 2546                                                         #spadd    ?WORD               ;stack has grown by a ?WORD
 2547                FFFFFFF6             number@@            equ       ::,?WORD
 2549    [1C50] 1C50:9E6D 01         [ 5]                     tst       number@@,sp
 2550    [1C53] 1C53:2A0F (1C64)     [ 3]                     bpl       ToStrLoop@@
 2551    [1C55] 1C55:CD1B AA         [ 6]                     call      ?Negate
 2553    [1C58] 1C58:9EFE 05         [ 5]                     ldhx      .buffer@@,sp
 2559    [1C5B] 1C5B:A62D            [ 2]                     lda       #'-'                ;a 'minus' sign
 2560    [1C5D] 1C5D:F7              [ 2]                     sta       ,x                  ; is saved first
 2561                                     
 2562    [1C5E] 1C5E:AF01            [ 2]                     aix       #1                  ;HX -> past minus sign
 2563    [1C60] 1C60:7F              [ 4]                     clr       ,x                  ;make it an ASCIZ string
 2565    [1C61] 1C61:9EFF 05         [ 5]                     sthx      .buffer@@,sp        ;update pointer past sign
 2571                                     ;                   bra       ToStrLoop@@
 2573                                     ;===============================================================================
 2574                                     
 2575    [1C64] 1C64:4500 0A         [ 3] ToStrLoop@@         ldhx      #10                 ;H = 0 (always), X = divisor
 2576  M                                                      @div.s    number@@,sp
 2576  M                                                      mset      #
 2576  M                                                      mreq      1
 2576  M                                                      @@_not_x_ number22,sp
 2576  M                                                      mset      #
 2576  M                                                      endm
 2576  M                                                      @@_nosize_ number22,sp
 2576  M                                                      mset      #
 2576  M                                                      mset      0,mstop [div.s] No size (number22,sp)
 2576  M                                                      endm
 2576  M                                                      #temp     1
 2576  M                                                      #temp     2
 2576  M [1C67] 1C67:86              [ 3]                     pula
 2576  M [1C68] 1C68:52              [ 6]                     div
 2576  M [1C69] 1C69:87              [ 2]                     psha
 2576  M                                                      mdo       2
 2576  M [1C6A] 1C6A:9EE6 02         [ 4]                     lda       number22+1,sp
 2576  M [1C6D] 1C6D:52              [ 6]                     div
 2576  M [1C6E] 1C6E:9EE7 02         [ 4]                     sta       number22+1,sp
 2576  M                                                      mloop     ::number22
 2576  M [1C71] 1C71:9EE6 03         [ 4]                     lda       number22+2,sp
 2576  M [1C74] 1C74:52              [ 6]                     div
 2576  M [1C75] 1C75:9EE7 03         [ 4]                     sta       number22+2,sp
 2576  M                                                      mloop     ::number22
 2576  M [1C78] 1C78:9EE6 04         [ 4]                     lda       number22+3,sp
 2576  M [1C7B] 1C7B:52              [ 6]                     div
 2576  M [1C7C] 1C7C:9EE7 04         [ 4]                     sta       number22+3,sp
 2576  M                                                      mloop     ::number22
 2576                                                         endm
 2577                                     
 2578    [1C7F] 1C7F:8B86            [ 5]                     tha                           ;A = remainder
 2579    [1C81] 1C81:AB30            [ 2]                     add       #'0'                ;A = ASCII remainder
 2581    [1C83] 1C83:9EFE 05         [ 5]                     ldhx      .buffer@@,sp
 2587  M                                                      @StringInsertChar
 2587  M [1C86] 1C86:CD18 3A         [ 6]                     call      StringInsertChar                 ;HX and A pre-loaded correctly
 2587                                                         mexit
 2588                                     
 2589    [1C89] 1C89:95              [ 2]                     tsx
 2590                                     
 2591  M                                                      @zero?.s  number@@,spx
 2591  M                                                      mset      #
 2591  M                                                      mreq      1
 2591  M                                                      @@_nosize_ number22,spx
 2591  M                                                      mset      #
 2591  M                                                      mset      0,mstop [zero?.s] No size (number22,spx)
 2591  M                                                      endm
 2591  M                                                      mdo
 2591  M [1C8A] 1C8A:F6              [ 3]                     lda       number22+0,spx
 2591  M                                                      mloop     ::number22
 2591  M [1C8B] 1C8B:EA01            [ 3]                     ora       number22+1,spx
 2591  M                                                      mloop     ::number22
 2591  M [1C8D] 1C8D:EA02            [ 3]                     ora       number22+2,spx
 2591  M                                                      mloop     ::number22
 2591  M [1C8F] 1C8F:EA03            [ 3]                     ora       number22+3,spx
 2591  M                                                      mloop     ::number22
 2591                                                         endm
 2592    [1C91] 1C91:26D1 (1C64)     [ 3]                     bne       ToStrLoop@@
 2593                                     
 2594    [1C93] 1C93:A706            [ 2]                     ais       #:psp               ;free temporaries
 2595                                     
 2596    [1C95] 1C95:8A88 86         [ 9]                     pull
 2597    [1C98] 1C98:81              [ 6]                     rtc
 2598                                     
 2599                                                         #sp                           ;cancel all SP offsets
 2600                                     
 2601                                     ;*******************************************************************************
 2602                                     ; Assign global names to the various library calls, depending on version used.
 2603                                     ; Different names for each version means you can include any at the same time.
 2604                                     ;*******************************************************************************
 2605                                     
 2606                                     ?                   macro     BitSize             ;temp macro to export symbols
 2607                                                         mreq      1:Usage: @~0~ BitSize
 2608                                               #if MATHSIZE = ~1~
 2609                                     StackAdd~1~         exp       ?Add
 2610                                     StackSub~1~         exp       ?Subtract
 2611                                     StackMul~1~         exp       ?Multiply
 2612                                     StackDiv~1~         exp       ?Divide
 2613                                     StackMod~1~         exp       ?Modulo
 2614                                     StackSwap~1~        exp       ?Swap
 2615                                     StackAbs~1~         exp       ?Abs
 2616                                     StackNegate~1~      exp       ?Negate
 2617                                     StackLoad~1~        exp       ?Load
 2618                                     StackSave~1~        exp       ?Save
 2619                                     Stack~1~ToASCIZ     exp       ?ToStr
 2620                                               #ifdef NO_BIT_OPS
 2621                                                         mexit                         ;;bit operations not available
 2622                                               #endif
 2623                                     StackAnd~1~         exp       ?BitAnd
 2624                                     StackOr~1~          exp       ?BitOr
 2625                                     StackXor~1~         exp       ?BitXor
 2626                                     StackShl~1~         exp       ?ShiftLeft
 2627                                     StackShr~1~         exp       ?ShiftRight
 2628                                               #endif
 2629                                                         endm
 2630                                     
 2631  M                                                      @?        64                  ;export 64-bit labels
 2631  M                                                      mreq      1:Usage: @? BitSize
 2631                                                         endm
 2632  M                                                      @?        56                  ;export 56-bit labels
 2632  M                                                      mreq      1:Usage: @? BitSize
 2632                                                         endm
 2633  M                                                      @?        48                  ;export 48-bit labels
 2633  M                                                      mreq      1:Usage: @? BitSize
 2633                                                         endm
 2634  M                                                      @?        40                  ;export 40-bit labels
 2634  M                                                      mreq      1:Usage: @? BitSize
 2634                                                         endm
 2635  M                                                      @?        32                  ;export 32-bit labels
 2635  M                                                      mreq      1:Usage: @? BitSize
 2635  M             188D                 StackAdd32         exp       ?Add
 2635  M             18A3                 StackSub32         exp       ?Subtract
 2635  M             1972                 StackMul32         exp       ?Multiply
 2635  M             19FB                 StackDiv32         exp       ?Divide
 2635  M             1A0E                 StackMod32         exp       ?Modulo
 2635  M             1B89                 StackSwap32        exp       ?Swap
 2635  M             1BA5                 StackAbs32         exp       ?Abs
 2635  M             1BAA                 StackNegate32      exp       ?Negate
 2635  M             1BB5                 StackLoad32        exp       ?Load
 2635  M             1BD9                 StackSave32        exp       ?Save
 2635  M             1C44                 Stack32ToASCIZ     exp       ?ToStr
 2635  M             18B9                 StackAnd32         exp       ?BitAnd
 2635  M             18CE                 StackOr32          exp       ?BitOr
 2635  M             18E3                 StackXor32         exp       ?BitXor
 2635  M             18F8                 StackShl32         exp       ?ShiftLeft
 2635  M             1935                 StackShr32         exp       ?ShiftRight
 2635                                                         endm
 2636  M                                                      @?        24                  ;export 24-bit labels
 2636  M                                                      mreq      1:Usage: @? BitSize
 2636                                                         endm
 2637  M                                                      @?        16                  ;export 16-bit labels
 2637  M                                                      mreq      1:Usage: @? BitSize
 2637                                                         endm
 2638                                     
 2639                                     ;*******************************************************************************
*** END   INCLUDE FILE: lib/stakmath.sub *** (RESUMING FILE: lib/stkmth32.sub)
   23                                                         #Exit
*** END   INCLUDE FILE: lib/stkmth32.sub *** (RESUMING FILE: lib/demo/stakmath.asm)
   48  M                                                      @?        16,4
   48  M                                                      @@Page    4
   48  M                                                      mreq      1:PageNumber
   48  M                                                      endm
   48                                                         #Uses     lib/stkmth16.sub
*** BEGIN INCLUDE FILE: lib/stkmth16.sub ***
    1                                     ;*******************************************************************************
    2                                     ;* Module    : STKMTH16.SUB
    3                                     ;* Programmer: Tony Papadimitriou <tonyp@acm.org>
    4                                     ;* Purpose   : Wrapper for 16-bit stack-based basic math routines (RPN style)
    5                                     ;* Language  : Motorola/Freescale/NXP HC08/9S08 Assembly Language (aspisys.com/ASM8)
    6                                     ;* Status    : FREEWARE Copyright (c) 2017 by Tony Papadimitriou <tonyp@acm.org>
    7                                     ;* Original  : http://www.aspisys.com/code/hc08/stkmth16.html
    8                                     ;* Note(s)   : See STAKMATH.SUB for details
    9                                     ;*******************************************************************************
   10                                     
   16                                     
   17                                     ?                   macro
   18                                                         mset      1,~BASENAME~
   19                                     MATHSIZE            set       ~1.{:1-1}~
   20                                                         #Include  stakmath.sub
   21                                                         endm
   22                                     
   23  M                                                      @?
   23  M                                                      mset      1,STKMTH16
   23  M             0010                 MATHSIZE            set       16
   23                                                         #Include  stakmath.sub
*** BEGIN INCLUDE FILE: lib/stakmath.sub ***
    1                                     ;*******************************************************************************
    2                                     ;* Module    : STAKMATH.SUB
    3                                     ;* Programmer: Tony Papadimitriou <tonyp@acm.org>
    4                                     ;* Purpose   : 64/56/48/40/32/24/16-bit stack-based basic math routines (RPN style)
    5                                     ;* Language  : Motorola/Freescale/NXP HC08/9S08 Assembly Language (aspisys.com/ASM8)
    6                                     ;* Status    : FREEWARE Copyright (c) 2017 by Tony Papadimitriou <tonyp@acm.org>
    7                                     ;* Original  : http://www.aspisys.com/code/hc08/stakmath.html
    8                                     ;* Note(s)   : Use: #Include stakmath.sub
    9                                     ;*           :
   10                                     ;*           : Several externally defined macros are used throughout this code.
   11                                     ;*           : All these (and many more) macros are inside the most recent
   12                                     ;*           : version of MACROS.INC which can be copied from the web page at
   13                                     ;*           : http://www.aspisys.com/code/hc08/macros.html
   14                                     ;*           : (and COMMON.INC at http://www.aspisys.com/code/hc08/common.html)
   15                                     ;*           :
   16                                     ;*           : The default word size is 32-bit.
   17                                     ;*           :
   18                                     ;*           : By (re)defining the symbol MATHSIZE (to 16) you get 16-bit code.
   19                                     ;*           : By (re)defining the symbol MATHSIZE to 24 you get 24-bit code.
   20                                     ;*           : By (re)defining the symbol MATHSIZE to 40 you get 40-bit code.
   21                                     ;*           : By (re)defining the symbol MATHSIZE to 48 you get 48-bit code.
   22                                     ;*           : By (re)defining the symbol MATHSIZE to 56 you get 56-bit code.
   23                                     ;*           : By (re)defining the symbol MATHSIZE to 64 you get 64-bit code.
   24                                     ;*           :
   25                                     ;*           : You can include all (or some) versions in your program like so:
   26                                     ;*           :
   27                                     ;*           :                #ROM                ;(or else, some paged memory)
   28                                     ;*           :                #Include  stakmath.sub
   29                                     ;*           : MATHSIZE       set       16        ;redefine for 16-bit use
   30                                     ;*           :                #Include  stakmath.sub
   31                                     ;*           : MATHSIZE       set       24        ;redefine for 24-bit use
   32                                     ;*           :                #Include  stakmath.sub
   33                                     ;*           : MATHSIZE       set       40        ;redefine for 40-bit use
   34                                     ;*           :                #Include  stakmath.sub
   35                                     ;*           : MATHSIZE       set       48        ;redefine for 48-bit use
   36                                     ;*           :                #Include  stakmath.sub
   37                                     ;*           : MATHSIZE       set       56        ;redefine for 56-bit use
   38                                     ;*           :                #Include  stakmath.sub
   39                                     ;*           : MATHSIZE       set       64        ;redefine for 64-bit use
   40                                     ;*           :
   41                                     ;*           : or, if you use the related wrapper files, like so:
   42                                     ;*           :
   43                                     ;*           :                #ROM                ;(or else, some paged memory)
   44                                     ;*           :                #Uses     stkmth16.sub
   45                                     ;*           :                #Uses     stkmth24.sub
   46                                     ;*           :                #Uses     stkmth32.sub
   47                                     ;*           :                #Uses     stkmth40.sub
   48                                     ;*           :                #Uses     stkmth48.sub
   49                                     ;*           :                #Uses     stkmth56.sub
   50                                     ;*           :                #Uses     stkmth64.sub
   51                                     ;*           :
   52                                     ;*           : Use CALL if assembled in #MMU mode (regardless of placement).
   53                                     ;*           : By using CALL and #JUMP (or default -J+ command line option), the
   54                                     ;*           : assembler will automatically adjust between CALL and JSR
   55                                     ;*           : depending on the current #MMU mode.
   56                                     ;*           :
   57                                     ;*           : To use the *-bit version of each CALL, use these symbols:
   58                                     ;*           :
   59                                     ;*           : StackAdd*, StackSub*, StackMul*, StackDiv*, StackMod*
   60                                     ;*           : StackSwap*, StackNegate*, StackLoad*, StackSave*,
   61                                     ;*           : Stack*ToASCIZ
   62                                     ;*           :
   63                                     ;*           : replacing * with one of these: 16, 24, 32, 40, 48, 56, or 64.
   64                                     ;*           :
   65                                     ;*           : Various macros allow using these routines in a variety of ways,
   66                                     ;*           : and without worrying about the details of call & parameter setup.
   67                                     ;*           : These macros are: Add*, Sub*, Mul*, Div*, Mod*, DivS*, ModS*,
   68                                     ;*           : Neg*, Load*, Save*, Str*, StrS*, and Swap* (where the * is 16,
   69                                     ;*           : 24, 32, 40, 48, 56, or 64 depending on the version you want to use).
   70                                     ;*           : The signed versions are enabled only when the module is assembled
   71                                     ;*           : with the SIGNED conditional.
   72                                     ;*           :
   73                                     ;*           : If working with fixed-address variables, you can use the various
   74                                     ;*           : macros (such as Add32, Mul64, etc.) to perform operations in the
   75                                     ;*           : easiest possible way, such as:
   76                                     ;*           :                @Mul32    A,B,Answer
   77                                     ;*           : (which multiplies A with B and stores the product in Answer).
   78                                     ;*           : But, you may also use the macros to work directly on stack, or to
   79                                     ;*           : temporarily save partial results on stack instead of fixed vars.
   80                                     ;*           :
   81                                     ;*           :                  I N   G E N E R A L   T H E N
   82                                     ;*           :
   83                                     ;*           : @Operation A,B,Answer works with A and B storing result in Answer
   84                                     ;*           : @Operation A,B        works with A and B leaving result on stack
   85                                     ;*           : @Operation A          works with TOS and A, result left as TOS
   86                                     ;*           : @Operation (no parms) works w/ TOS and [TOS+1], result as new TOS
   87                                     ;*           :
   88                                     ;*           : (Please note the shown order of the operation may be important.)
   89                                     ;*           :
   90                                     ;*           : Finally, the Load* (* = 16, 24, 32, 40, 48, 56, 64) operation can
   91                                     ;*           : directly load either a variable or a constant (leading #) on the
   92                                     ;*           : stack.
   93                                     ;*           :
   94                                     ;*           : Since v7.00, a HLL-like interface is possible by using the new
   95                                     ;*           : Eval* macro (where * = 8, 16, 24, 32, 40, 48, 56, 64)
   96                                     ;*           : This is by far the easiest way to use this library, as it closely
   97                                     ;*           : resembles using expressions in a HLL compiler.  It also can
   98                                     ;*           : automatically resize stack after loading from and before saving
   99                                     ;*           : to any variable.
  100                                     ;*           :
  101                                     ;*           : Examine the test section of this file for examples of macro use.
  102                                     ;*           :
  103                                     ;*           : All routines are re-entrant and work on either the top-of-stack
  104                                     ;*           : (TOS) number alone or the two top-most TOS numbers.  Similar to
  105                                     ;*           : how Reverse Polish Notation (RPN) works.  First, you stack the
  106                                     ;*           : operand(s) and then call the corresponding routine to perform the
  107                                     ;*           : operation.
  108                                     ;*           :
  109                                     ;*           : The result of any operation is always the updated top of stack.
  110                                     ;*           : For operations that require two operands and produce a single
  111                                     ;*           : result, the result replaces the two operands (stack is reduced).
  112                                     ;*           :
  113                                     ;*           : Chain calculations are possible by pushing only the new operand
  114                                     ;*           : between operations.  Alternatively, one can push all operands in
  115                                     ;*           : advance but it's not recommended as stack space may be limited.
  116                                     ;*           : When done evaluating an expression, just pull the final 32-bit
  117                                     ;*           : result from the stack.
  118                                     ;*           :
  119                                     ;*           : The TOS is the first (or only) operand of any operation.
  120                                     ;*           : This is important, for example, for subtraction and division.
  121                                     ;*           :
  122                                     ;*           : If the current order of the stack is not as you want it, use the
  123                                     ;*           : Swap (StackSwap32) operation to change it.
  124                                     ;*           :
  125                                     ;*           : All operands and results are exactly 32-bit wide.  Overflows are
  126                                     ;*           : simply truncated.  The lower 32-bit number is valid, though.
  127                                     ;*           :
  128                                     ;*           : (All references to 32-bit become 16-bit, when MATHSIZE = 16)
  129                                     ;*           : (All references to 32-bit become 24-bit, when MATHSIZE = 24)
  130                                     ;*           : (All references to 32-bit become 40-bit, when MATHSIZE = 40)
  131                                     ;*           : (All references to 32-bit become 48-bit, when MATHSIZE = 48)
  132                                     ;*           : (All references to 32-bit become 56-bit, when MATHSIZE = 56)
  133                                     ;*           : (All references to 32-bit become 64-bit, when MATHSIZE = 64)
  134                                     ;*           :
  135                                     ;*           : 64/56/48/40-bit multiplication is done using the shift-add method,
  136                                     ;*           : which is much shorter in size for such long operands, but it is
  137                                     ;*           : also significantly slower in speed. I opted for size optimization
  138                                     ;*           : because the 64/56/48/40-bit versions are not used quite as often.
  139                                     ;*           : You may want to re-write it for speed optimization by using the
  140                                     ;*           : MUL instruction like it is done for the default 32-bit case.
  141                                     ;*           :
  142                                     ;* History   : 09.05.22 v1.00 Original (Started on 2009.05.07)
  143                                     ;*           : 09.06.04       Optimized by using HX instead of SP, where needed
  144                                     ;*           : 09.11.04       Minor optimizations
  145                                     ;*           : 09.11.05       Add & Subtract now adjust Carry accordingly
  146                                     ;*           :                Division by zero error now checked first
  147                                     ;*           : 09.11.06 v1.01 Added conditional MATHSIZE for use w/ 16-bit words
  148                                     ;*           : 09.11.08 v1.02 Added "Load" operation to ease stack loading
  149                                     ;*           : 09.11.11       Use of new LONG pseudo-opcode
  150                                     ;*           : 09.12.05       Added cycles display using :cycles
  151                                     ;*           : 10.01.06 v1.03 Added MMU auto-support (using :AB internal symbol)
  152                                     ;*           :                Code is no longer placed in #ROM by default
  153                                     ;*           :                The few JMPs in the code use [[ to trim possible page
  154                                     ;*           : 10.01.08       [[ removed from JMPs (latest ASM8 auto-correction)
  155                                     ;*           : 10.01.22 v1.04 Added Save operation for completeness
  156                                     ;*           : 10.01.23 v1.05 Added #SP directive examples (latest ASM8)
  157                                     ;*           : 10.01.29 v1.06 Added shorter/faster Swap version for 9S08 MCUs
  158                                     ;*           : 10.02.01 v1.07 Added #SPAUTO directive
  159                                     ;*           : 10.02.04       Added #X directive
  160                                     ;*           : 10.02.06 v2.00 Added signed math wrapper calls only for DIV & MOD
  161                                     ;*           :                (Addition, Subtraction, and Multiplication calls
  162                                     ;*           :                work either for unsigned or signed operands.)
  163                                     ;*           :                Signed routines enabled w/ SIGNED conditional.
  164                                     ;*           :                Division by zero error now reduces stack (operand
  165                                     ;*           :                A removed) so that the stack is left with same
  166                                     ;*           :                size on either success or failure (in which case
  167                                     ;*           :                the TOS result is invalid.)
  168                                     ;*           : 10.02.08 v2.01 Fixed signed MOD for correct sign (sign of A)
  169                                     ;*           : 10.02.14 v2.10 Added Stack32ToASCIZ and prerequisite StringInsertChar
  170                                     ;*           : 10.02.28 v2.11 Minor optimization in StringInsertChar
  171                                     ;*           : 10.03.23       Made use of :: internal variable (Build 2010/03/23)
  172                                     ;*           : 10.03.30 v2.12 Allowed for HC08 compilation in newer code (?ToStr)
  173                                     ;*           :                Optimized 9S08 Swap version for size and speed
  174                                     ;*           :          v2.13 Optimized Negate for size and speed
  175                                     ;*           : 10.05.08 v3.00 Added MATHSIZE = 64 option for 64-bit math
  176                                     ;*           :                Swap operation optimized only for size
  177                                     ;*           : 10.05.13 v3.01 Optimized for size and speed by using ,SPX
  178                                     ;*           : 10.06.02 v4.00 Added macros for easier use
  179                                     ;*           : 10.06.08 v4.10 Improved macros and added new ones (eg Const32)
  180                                     ;*           : 10.06.23 v4.20 Added MATHSIZE = 48 option for 48-bit math
  181                                     ;*           : 10.06.30 v4.30 Added AddDecimalPoint (to string number)
  182                                     ;*           : 10.07.01 v4.40 Added IFSPAUTO conditional
  183                                     ;*           : 10.07.03       Moved the functionality of Const macros into Load
  184                                     ;*           : 10.07.07       Moved general string routines first
  185                                     ;*           : 10.07.17 v4.50 Str* macros may use TOS (if Number parm is missing)
  186                                     ;*           :                or current HX index (if result pointer is missing)
  187                                     ;*           : 10.07.20       _DoLoad*/_DoSave* address now allows for indexed mode
  188                                     ;*           : 10.07.21       Minor optimizations; macros now latest ASM8
  189                                     ;*           : 10.07.23       Minor bug fix in macro _DoSave for no parm case
  190                                     ;*           : 10.08.18       Optimized by using :MINDEX in latest ASM8
  191                                     ;*           : 10.08.26       Minor optimizations at the source level
  192                                     ;*           : 10.08.31 v4.60 Optimized Load* macros' immediate mode for zeros
  193                                     ;*           : 10.10.19 v4.61 Adapted to latest ASM8 (nested macros in Load)
  194                                     ;*           : 10.10.22 v4.62 Optimized _DoMath (Added @_DoOperation)
  195                                     ;*           : 10.10.26 v4.63 Load48 & Load64 now also accept single #Constant
  196                                     ;*           : 10.12.03 v4.64 Adapted to latest ASM8 => macros OK in @@ sub-mode
  197                                     ;*           : 11.03.31 v4.65 Moved test code at EOF (to use #EXIT optimization)
  198                                     ;*           : 11.04.10 v4.66 Condensed macro definitions (based on MATHSIZE)
  199                                     ;*           : 11.04.11 v4.67 Optimized MUL16/MUL32 size & cycles with ,SPX mode
  200                                     ;*           : 11.04.12 v4.70 Added MATHSIZE = 24 option for 24-bit math
  201                                     ;*           : 11.04.13 v4.71 Reversed some of v4.66's changes
  202                                     ;*           : 11.04.13 v4.80 Added MATHSIZE = 40 option for 40-bit math
  203                                     ;*           : 11.05.02 v4.81 Save protects HX (it was lost during SP => SPX)
  204                                     ;*           : 11.05.05 v4.82 Optimized StringLength by a byte (by using NEGA on exit)
  205                                     ;*           : 11.05.25 v4.83 Removed unused Zero constant from test code
  206                                     ;*           : 11.10.13 v4.84 Optimized MUL16/24/32 size w/ more ,SPX (same cycles)
  207                                     ;*           : 11.11.15 v4.85 Improved StringLength macro
  208                                     ;*           : 12.01.26       Changed test code a bit
  209                                     ;*           : 12.02.06 v4.86 Optimized SP => SPX at ?RemoveAndReturn
  210                                     ;*           : 12.03.05 v4.87 Added ResizeTOS to adjust TOS element's size
  211                                     ;*           : 12.05.09 v4.88 Added CCR[C] parameter to ResizeTOS for unsigned operation
  212                                     ;*                            (signed is default when SIGNED conditional is defined,
  213                                     ;*                            unsigned operation is default, otherwise)
  214                                     ;*           : 12.05.18 v4.89 Removed redundant subtraction in Division (at NotEqual@@)
  215                                     ;*           : 12.10.07 v4.90 Load*/Save* now accept indexed mode without separator override
  216                                     ;*           : 12.10.10 v5.00 Renamed to (more general) STAKMATH.SUB to use
  217                                     ;*           :                wrapper files for each bit version, instead.
  218                                     ;*           : 12.11.05       Added _STKMTH{MATHSIZE}_ for used-version control
  219                                     ;*           : 12.11.09 v6.00 New _LoadStkMthVarAddr macro eases parm address
  220                                     ;*           :                calculation.
  221                                     ;*           : W A R N I N G: SP-based operands now refer to the actual number,
  222                                     ;*           : W A R N I N G: and not its address (as was the case before).
  223                                     ;*           : W A R N I N G: This is INCOMPATIBLE with previous behavior. Code
  224                                     ;*           : W A R N I N G: written for version v5.00 or earlier that uses SP
  225                                     ;*           : W A R N I N G: based operands should be modified to refer to the
  226                                     ;*           : W A R N I N G: actual value and not to a pointer to the value.
  227                                     ;*           : W A R N I N G: Dot-beginning names are still treated as pointers!
  228                                     ;*           : 12.11.10       Use COMMON.INC/LEA instead of _LoadStkMthVarAddr
  229                                     ;*           : 12.12.04 v6.10 Optimized division just a tad by combining steps
  230                                     ;*           : 12.12.12 v6.20 Now use LEA macro inside _DoStr (for ResultString)
  231                                     ;*           : 12.12.20 v6.21 Minor optimization (one byte) in 32-bit ?Multiply
  232                                     ;*           :                (Further 3-byte optimization possible by
  233                                     ;*           :                re-ordering MULs, but not done for code clarity)
  234                                     ;*           : 13.01.09 v6.22 Added Copy* macros to combine Load*/Save* into one
  235                                     ;*           : 13.03.20 v7.00 Added Eval* and supporting macros for HLL-like
  236                                     ;*           :                computations, eg., ans=(a+3)*((1+var,sp)/2)
  237                                     ;*           :                (with or without spaces between operands/operators)
  238                                     ;*           : 13.03.27 v7.50 SIGNED now gives just signed (not unsigned) version
  239                                     ;*           :                DivS*, ModS*, StrS* macros were removed, and also
  240                                     ;*           :                ResizeTOS macro's unsigned flag has been removed
  241                                     ;*           :                BugFix: AddDecimalPoint now prepends zeros after sign
  242                                     ;*           : 13.03.27       Optimized ?Negate in SIGNED case to use ?NegX sub
  243                                     ;*           : 13.03.27 v7.60 Adapted _EVAL_ macro to latest ASM8 (Much faster!)
  244                                     ;*           : 13.04.04 v7.70 _DoLoad and _DoSave macros now auto-adjust the size
  245                                     ;*           :                so you can use with operands of different sizes, even
  246                                     ;*           :                if the respective bitsize version isn't loaded.
  247                                     ;*           : 13.04.04 v7.71 _Eval_ macro leaves assignment result on TOS if
  248                                     ;*           :                assignment variable not already defined.  Then,
  249                                     ;*           :                it gives TOS the specified name, if SP-indexed.
  250                                     ;*           : 13.04.05 v7.72 Added #size for v7.71 change
  251                                     ;*           :                Named constants (labels with size zero) now use
  252                                     ;*           :                immediate mode in Eval/Load
  253                                     ;*           : 13.04.05 v7.73 Added NEG() negate, and ABS() absolute functions
  254                                     ;*           :                in Eval macro, e.g., ans = abs(a - b)
  255                                     ;*           : 13.04.09 v7.80 BugFix: Push/Pull macro calls for SP mode
  256                                     ;*           :                Moved immediate mode to _DoLoad (unified method)
  257                                     ;*           :                (Over 32-bit immediate value loads not possible
  258                                     ;*           :                via macros)
  259                                     ;*           : 13.04.10       Adapted to v9.35 (no functional changes)
  260                                     ;*           : 13.04.11 v7.81 Optimized _DoLoad constant loading by using CLRH
  261                                     ;*           :                (optimization is evident on certain cases only)
  262                                     ;*           : 13.04.15 v7.82 Added _?SEI_ and _?CLI_ macros for multitasker
  263                                     ;*           :                locking / unlocking of multi-byte variables while
  264                                     ;*           :                loading / saving (_DoLoad/_DoSave).  Under OS8 it
  265                                     ;*           :                is enabled automatically.  Otherwise, simply
  266                                     ;*           :                define _MTOS_ anytime before including this file.
  267                                     ;*           :                For keeping code dense, all Eval*/Load*/Save*
  268                                     ;*           :                macros are assumed to be called only while
  269                                     ;*           :                interrupts are enabled, so it will not restore to
  270                                     ;*           :                previous state but always leave as enabled.
  271                                     ;*           :                Define _NOCLI_ (before including this module) for
  272                                     ;*           :                canceling the _?SEI_ and _?CLI_ macro effects.
  273                                     ;*           : 13.04.18 v7.85 Added 'NeedMath' and 'Eval' general-purpose macros
  274                                     ;*           :                for automatic selection of needed bit-size based
  275                                     ;*           :                on only which modules are already included. First,
  276                                     ;*           :                call the NeedMath macro to define the minimum math
  277                                     ;*           :                bit-size you need for the next calculation(s),
  278                                     ;*           :                then call the Eval macro as many times as needed
  279                                     ;*           :                to perform the actual expression evaluation(s).
  280                                     ;*           :                Similary, added new macros Load, Save, StkAdd,
  281                                     ;*           :                StkSub, StkMul, StkDiv, StkMod, StkSwap, StkNeg,
  282                                     ;*           :                StkAbs, StkStr, and CopyMath to work with the
  283                                     ;*           :                NeedMath macro, just like the new Eval macro.
  284                                     ;*           : 13.04.19 v8.00 Moved all Eval* macros into COMMON.INC and allowed
  285                                     ;*           :                for all to be active at all times, regardless if
  286                                     ;*           :                the related bit-version of STAKMATH is included.
  287                                     ;*           :                The _Eval_ macro was improved to allow it to
  288                                     ;*           :                automatically locate the next higher version that
  289                                     ;*           :                is included, if the one requested is not.  So,
  290                                     ;*           :                using Eval32 will use the 32/40/48/64-bit version
  291                                     ;*           :                (whichever is closer to 32 and included) but nothing
  292                                     ;*           :                below 32-bit.  This allows you to use the relevant
  293                                     ;*           :                macro based on a specific expression's requirements
  294                                     ;*           :                but include only one (or just a few) higher bit
  295                                     ;*           :                version(s), not all those referenced in your code.
  296                                     ;*           :                (The general Eval is still available, if needed.)
  297                                     ;*           :                Also, moved all Str* to COMMON.INC
  298                                     ;*           : 13.04.21 v8.10 Corrected v8.00 for pointer cases (.num) to use
  299                                     ;*           :                actual requested size, not next higher.
  300                                     ;*           :                Relevant #Message now in _DoOperation _ResizeTOS etc.
  301                                     ;*           : 13.04.21 v8.11 NeedMath & related macros removed (now redundant)
  302                                     ;*           :                General Eval macro will try to determine best bit-size
  303                                     ;*           : 13.04.23 v8.12 Added EvalS to first check for SIGNED and then call Eval
  304                                     ;*           :                CopyMath removed.  Use "Eval to_var = from_var" instead
  305                                     ;*           :                _StkMthMax_ improved to use higher size on multiplication
  306                                     ;*           : 13.04.25 v8.13 _Eval_ now allows for string constants (eg., @Eval ans = ans + '0')
  307                                     ;*           :                Removed all ?macros because we now use COMMON xxx.s macros
  308                                     ;*           : 13.04.26 v8.15 Corrected test code for Eval when MATHSIZE < 32
  309                                     ;*           :                Commented out auto-higher bit-size (a bit annoying).
  310                                     ;*           :                Use Eval* to say 'no less than', instead.
  311                                     ;*           : 13.04.27 v8.16 BugFix: StrMath macro (2nd parameter was lost)
  312                                     ;*           :                Added SQR() function to get the square
  313                                     ;*           : 13.05.02       Added #size in ToInt* macros (in test code)
  314                                     ;*           : 13.05.03 v8.17 Added size optimization for ADD and SUB operations
  315                                     ;*           :                New SPEED_SIZE constant in COMMON.INC tells us
  316                                     ;*           :                whether we need speed (SPEED_SIZE = 1) or
  317                                     ;*           :                size (SPEED_SIZE = 2) optimization, the current
  318                                     ;*           :                default being SPEED_SIZE = 2 for size optimization.
  319                                     ;*           : 13.05.30       Updated StrMath macro (COMMON.INC and here)
  320                                     ;*           : 13.06.04 v8.20 Added bit functions: AND (&), OR (|), XOR (^), and shifts (< and >)
  321                                     ;*           : 13.06.05 v8.21 BugFix: ShiftRight now uses ASR if SIGNED
  322                                     ;*           : 13.07.25 v8.22 Improved _Eval_ macro (and Push/Pull in COMMON.INC)
  323                                     ;*           :                BugFix: Added { } to ResizeTOS macro's final case
  324                                     ;*           :                (Disable bit functions with NO_BIT_OPS conditional)
  325                                     ;*           : 13.10.06       Minor changes in test code
  326                                     ;*           : 13.11.26       Added warning in _DoLoad: forwards treated as vars
  327                                     ;*           : 13.11.29 v8.23 Optimized ?ShiftLeft and ?ShiftRight a bit
  328                                     ;*           : 13.12.22 v8.30 Added 56-bit version
  329                                     ;*           : 14.01.03       Made use of _CMP_.S macro (instead of custom macro)
  330                                     ;*           : 14.02.07 v8.50 Added [ ... ] unsigned override (if SIGNED)
  331                                     ;*           : 14.02.14 v8.51 Eval macro now uses #HideMacros
  332                                     ;*           : 14.10.14 v8.52 BugFix: Off-by-one error in ResizeTOS when SIGNED
  333                                     ;*           : 15.03.21 v8.53 Replaced string dependencies with corresponding #Uses
  334                                     ;*           : 15.04.08 v8.54 Replaced AddDecimalPoint with corresponding #Uses
  335                                     ;*******************************************************************************
  336                                     
  337                                     ;Synopsis (replace * with 16, 24, 32, 40, 48, 56, 64 for corresponding bit version):
  338                                     ;
  339                                     ;Subroutines    Action
  340                                     ;-------------- ----------------------------
  341                                     ;StackAdd*      - TOS := TOS + [TOS+1]       (signed or unsigned) [TOS+1] removed
  342                                     ;StackSub*      - TOS := TOS - [TOS+1]       (signed or unsigned) [TOS+1] removed
  343                                     ;StackMul*      - TOS := TOS * [TOS+1]       (signed or unsigned) [TOS+1] removed
  344                                     ;StackDiv*      - TOS := TOS / [TOS+1]       (signed if SIGNED)   [TOS+1] removed
  345                                     ;StackMod*      - TOS := TOS \ [TOS+1]       (signed if SIGNED)   [TOS+1] removed
  346                                     ;StackAnd*      - TOS := TOS & [TOS+1]       (signed or unsigned) [TOS+1] removed
  347                                     ;StackOr*       - TOS := TOS | [TOS+1]       (signed or unsigned) [TOS+1] removed
  348                                     ;StackXor*      - TOS := TOS ^ [TOS+1]       (signed or unsigned) [TOS+1] removed
  349                                     ;StackShl*      - TOS := TOS < [TOS+1]       (signed or unsigned) [TOS+1] removed
  350                                     ;StackShr*      - TOS := TOS > [TOS+1]       (signed if SIGNED)   [TOS+1] removed
  351                                     ;StackSwap*     - TOS swapped with [TOS+1]   (signed or unsigned)
  352                                     ;StackAbs*      - TOS := ABS(TOS)            (signed)
  353                                     ;StackNegate*   - TOS := -TOS                (signed)
  354                                     ;StackLoad*     - Load const/variable to TOS (signed or unsigned) TOS created
  355                                     ;StackSave*     - Save TOS into variable     (signed or unsigned) TOS removed
  356                                     ;ResizeTOS      - Adjust TOS old size to new (signed or unsigned) TOS resized
  357                                     ;Stack*ToASCIZ  - Convert TOS to ASCIZ str   (signed if SIGNED)
  358                                     ;
  359                                     ;Macros             Purpose             Parameters ([...] means optional part)
  360                                     ;------------------ ------------------- ----------------------------------------
  361                                     ;Load*              Stack const or var  #Number | Variable
  362                                     ;Save*              Unstack a variable  Variable
  363                                     ;Copy*              Load* & Save*       #Number | Variable,Variable
  364                                     ;ResizeTOS          Resize TOS          #FromByteSize,#ToByteSize
  365                                     ;
  366                                     ;Add*               Addition            [Addend[,Adder[,Sum]]]
  367                                     ;Sub*               Subtraction         [Minuend[,Subtrahend[,Difference]]]
  368                                     ;Mul*               Multiplication      [Multiplicand[,Multiplier[,Product]]]
  369                                     ;Div*               Unsigned division   [Dividend[,Divisor[,Quotient]]]
  370                                     ;Mod*               Unsigned modulo     [Dividend[,Divisor[,Remainder]]]
  371                                     ;Abs*               Absolute value      [SourceVariable][,DestinationVariable]
  372                                     ;Neg*               Negation            [SourceVariable][,DestinationVariable]
  373                                     ;Swap*              Swap TOS numbers
  374                                     ;Str*               Number to ASCIZ     [Variable],[ResultString]
  375                                     ;AddDecimalPoint    ... to ASCIZ number [[#]DecimalPlaces[,[#]ASCIZ_String]]
  376                                     
  403                                     
  404                0010                 MATHSIZE            def       32                  ;default wordsize is 32-bit
  405                                     
  409                                     
  410                                     ?                   macro     BitSize
  411                                     #if MATHSIZE = ~1~
  412                                     ?WORD               equ       ~1~/8
  413                                     _STKMTH{MATHSIZE}_                                ;;specific version included
  414                                     _STAKMATH_          def       *                   ;;any version included
  415                                     #endif
  416                                                         endm
  417                                     
  418  M                                                      @?        16                  ;16-bit quantity (on request)
  418  M             0002                 ?WORD               equ       16/8
  418  M             1C99                 _STKMTH16_
  418  M             182C                 _STAKMATH_          def       *
  418                                                         endm
  419  M                                                      @?        24                  ;24-bit quantity (on request)
  419                                                         endm
  420  M                                                      @?        32                  ;32-bit quantity (default)
  420                                                         endm
  421  M                                                      @?        40                  ;40-bit quantity (on request)
  421                                                         endm
  422  M                                                      @?        48                  ;48-bit quantity (on request)
  422                                                         endm
  423  M                                                      @?        56                  ;56-bit quantity (on request)
  423                                                         endm
  424  M                                                      @?        64                  ;64-bit quantity (on request)
  424                                                         endm
  425                                     
  431                                                         #Message  MATHSIZE = {MATHSIZE}-bit version
  432                                     
  434                                                         #Message  Signed routines enabled
  436                                     
  437                                     ;*******************************************************************************
  438                                     ; Macros to make operations as simple as with a high-level language
  439                                     ; In operations that require two operands and a result, if only one operand is
  440                                     ; provided, then the operation is done completely on stack (no other variables
  441                                     ; used).  For example, @Add32 A,B,SUM adds A to B and places result in SUM,
  442                                     ; while @Add32 A adds the current stack top to A and leaves result on stack.
  443                                     ; You can use @Load* and @Save* to load the initial value, and store the final
  444                                     ; result, respectively.  (Replace * with 16, 24, 32, 40, 48, 56, or 64)
  445                                     ;*******************************************************************************
  446                                     
  448                                     
  449                                     Load16              macro     #Number|Variable    ;load constant or variable
  450                                                         @_DoLoad  ~0.{:0-1}~~@~
  451                                                         endm
  452                                     
  453                                     Save16              macro     Address
  454                                                         @_DoSave  16~@~
  455                                                         endm
  456                                     
  457                                     Copy16              macro     #Constant|Variable,ToAddress
  458                                                         mreq      1,2:#Constant|Variable,ToAddress
  459                                                         @@Load16  ~1~
  460                                                         @Save16   ~2~
  461                                                         endm
  462                                     
  463                                     Swap16              macro
  464                                                         @_DoSwap  16
  465                                                         endm
  466                                     
  467                                     Add16               macro     Addend,Adder,Sum
  468                                                         @_DoMath  ~0~16~1~~2~~3~
  469                                                         endm
  470                                     
  471                                     Sub16               macro     Minuend,Subtrahend,Difference
  472                                                         @_DoMath  ~0~16~1~~2~~3~
  473                                                         endm
  474                                     
  475                                     Mul16               macro     Multiplicand,Multiplier,Product
  476                                                         @_DoMath  ~0~16~1~~2~~3~
  477                                                         endm
  478                                     
  479                                     Div16               macro     Dividend,Divisor,Quotient
  480                                                         @_DoMath  ~0~16~1~~2~~3~
  481                                                         endm
  482                                     
  483                                     Mod16               macro     Dividend,Divisor,Remainder
  484                                                         @_DoMath  ~0~16~1~~2~~3~
  485                                                         endm
  486                                     
  487                                     Abs16               macro     Source[,Destination]
  488                                                         @_DoAbs   16~1~~2~
  489                                                         endm
  490                                     
  491                                     Neg16               macro     Source[,Destination]
  492                                                         @_DoNeg   16~1~~2~
  493                                                         endm
  495                                     ;-------------------------------------------------------------------------------
  544                                     ;-------------------------------------------------------------------------------
  593                                     ;-------------------------------------------------------------------------------
  642                                     ;-------------------------------------------------------------------------------
  691                                     ;-------------------------------------------------------------------------------
  740                                     ;-------------------------------------------------------------------------------
  789                                     
  790                                     ;*******************************************************************************
  791                                     ; Common macro(s) for all operations defined above (not to be called directly)
  792                                     ;*******************************************************************************
  793                                     
  801                                     
  802                                     ;-------------------------------------------------------------------------------
  803                                     
  863                                     
  864                                     ;-------------------------------------------------------------------------------
  865                                     
  888                                     
  889                                     ;-------------------------------------------------------------------------------
  890                                     
  898                                     
  899                                     ;-------------------------------------------------------------------------------
  900                                     
  918                                     
  919                                     ;===============================================================================
  920                                     
  937                                     
  938                                     ;-------------------------------------------------------------------------------
  939                                     
 1164                                     ;-------------------------------------------------------------------------------
 1191                                     ;-------------------------------------------------------------------------------
 1218                                     ;-------------------------------------------------------------------------------
 1294                                     ;-------------------------------------------------------------------------------
 1334                                     ;-------------------------------------------------------------------------------
 1343                                     ;-------------------------------------------------------------------------------
 1357                                     ;-------------------------------------------------------------------------------
 1386                                     ;-------------------------------------------------------------------------------
 1404                                     ;-------------------------------------------------------------------------------
 1422                                     ;-------------------------------------------------------------------------------
 1452                                     
 1453                                     ;*******************************************************************************
 1454                                     ; External dependencies
 1455                                     ;*******************************************************************************
 1456                                     
 1457                                                         #Uses     strings/stringlength.sub
 1458                                                         #Uses     strings/stringinsertchar.sub
 1459                                                         #Uses     strings/adddecimalpoint.sub
 1460                1C99                 ?_OBJECT_?
 1461                                     ;*******************************************************************************
 1462                                     ; One-based (SP-index) offsets to stacked operands (to be used with #SPAUTO :AB)
 1463                                     ;*******************************************************************************
 1464                                     
 1465                                                         #temp     1
 1466                0001                 ?a                  next      :temp,?WORD         ;top-of-stack (TOS) number (N1)
 1467                0003                 ?b                  next      :temp,?WORD         ;number after TOS (N2)
 1468                                     
 1469                                                         #Cycles                       ;reset the cycles counter
 1470                                     
 1471                                     ;*******************************************************************************
 1472                                     ; Purpose: Add N1 to N2 and place result on top-of-stack. N1 & N2 removed
 1473                                     ; Input  : [TOS+?WORD] = Number2
 1474                                     ;        : [TOS] = Number1
 1475                                     ; Output : [TOS] = Result
 1476                                     ; Note(s): Carry Set on overflow
 1477                                     
 1478                                                         #spauto   :ab
 1479                                     
 1480                1C99                 ?Add                proc
 1481    [1C99] 1C99:8789 8B         [ 6]                     push
 1482    [1C9C] 1C9C:95              [ 2]                     tsx
 1483                                     
 1485  M                                                      @add.s,   ?a,spx ?b,spx ?b,spx
 1485  M                                                      mreq      1,2,3:[#]Operand1,[#]Operand2,Destination
 1485  M                                                      @@_samesize_ ?a,spx ?b,spx ?b,spx
 1485  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1485  M                                                      mset      0
 1485  M                                                      mdo
 1485  M                                                      mswap     1,1
 1485  M                                                      @@_nosize_ ?a,spx
 1485  M                                                      mset      #
 1485  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1485  M                                                      endm
 1485  M                                                      mset      0,?a,spx
 1485  M                                                      mloop     :n
 1485  M                                                      mswap     1,2
 1485  M                                                      @@_nosize_ ?b,spx
 1485  M                                                      mset      #
 1485  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1485  M                                                      endm
 1485  M                                                      mloop     :n
 1485  M                                                      mswap     1,3
 1485  M                                                      @@_nosize_ ?b,spx
 1485  M                                                      mset      #
 1485  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1485  M                                                      endm
 1485  M                                                      mloop     :n
 1485  M                                                      endm
 1485  M                                                      mset      0,@@add.b,
 1485  M                                                      mdo
 1485  M                                                      mset      0,@@add.b, ?a+1,spx
 1485  M                                                      mset      0,@@add.b, ?a+1,spx ?b+1,spx
 1485  M                                                      mset      0,@@add.b, ?a+1,spx ?b+1,spx ?b+1,spx
 1485  M                                                      @@add.b, ?a+1,spx ?b+1,spx ?b+1,spx
 1485  M                                                      mswap     1,2
 1485  M                                                      mswap     1,2
 1485  M [1C9D] 1C9D:E606            [ 3]                     lda       ?a+1,spx
 1485  M [1C9F] 1C9F:EB08            [ 3]                     add       ?b+1,spx
 1485  M                                                      @_sta_    ?b+1,spx
 1485  M [1CA1] 1CA1:E708            [ 3]                     sta       ?b+1,spx
 1485  M                                                      endm
 1485  M                                                      mset      0,@@adc.b,
 1485  M                                                      mloop     ::?b
 1485  M                                                      mset      0,@@adc.b, ?a+0,spx
 1485  M                                                      mset      0,@@adc.b, ?a+0,spx ?b+0,spx
 1485  M                                                      mset      0,@@adc.b, ?a+0,spx ?b+0,spx ?b+0,spx
 1485  M                                                      @@adc.b, ?a+0,spx ?b+0,spx ?b+0,spx
 1485  M                                                      mswap     1,2
 1485  M                                                      mswap     1,2
 1485  M [1CA3] 1CA3:E605            [ 3]                     lda       ?a+0,spx
 1485  M [1CA5] 1CA5:E907            [ 3]                     adc       ?b+0,spx
 1485  M                                                      @_sta_    ?b+0,spx
 1485  M [1CA7] 1CA7:E707            [ 3]                     sta       ?b+0,spx
 1485  M                                                      endm
 1485  M                                                      mset      0,@@adc.b,
 1485  M                                                      mloop     ::?b
 1485                                                         endm
 1501    [1CA9] 1CA9:CC1E 6E         [ 4]                     jmp       ?RemoveAndReturn
 1502                                     
 1503                001E                 ?AddCycles          equ       :cycles
 1504                                     
 1505                                     ;*******************************************************************************
 1506                                     ; Purpose: Subtract N2 from N1 and place result on top-of-stack. N1 & N2 removed
 1507                                     ; Input  : [TOS+?WORD] = Number2
 1508                                     ;        : [TOS] = Number1
 1509                                     ; Output : [TOS] = Result
 1510                                     ; Note(s): Carry Set on borrow
 1511                                     
 1512                                                         #spauto   :ab
 1513                                     
 1514                1CAC                 ?Subtract           proc
 1515    [1CAC] 1CAC:8789 8B         [ 6]                     push
 1516    [1CAF] 1CAF:95              [ 2]                     tsx
 1518  M                                                      @sub.s,   ?a,spx ?b,spx ?b,spx
 1518  M                                                      mreq      1,2:[#]Operand1,[#]Operand2,Destination
 1518  M                                                      @@_samesize_ ?a,spx ?b,spx ?b,spx
 1518  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1518  M                                                      mset      0
 1518  M                                                      mdo
 1518  M                                                      mswap     1,1
 1518  M                                                      @@_nosize_ ?a,spx
 1518  M                                                      mset      #
 1518  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1518  M                                                      endm
 1518  M                                                      mset      0,?a,spx
 1518  M                                                      mloop     :n
 1518  M                                                      mswap     1,2
 1518  M                                                      @@_nosize_ ?b,spx
 1518  M                                                      mset      #
 1518  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1518  M                                                      endm
 1518  M                                                      mloop     :n
 1518  M                                                      mswap     1,3
 1518  M                                                      @@_nosize_ ?b,spx
 1518  M                                                      mset      #
 1518  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1518  M                                                      endm
 1518  M                                                      mloop     :n
 1518  M                                                      endm
 1518  M                                                      #temp
 1518  M                                                      @@_nosize_ ?b,spx
 1518  M                                                      mset      #
 1518  M                                                      mset      0,mstop [sub.s] No size (?b,spx)
 1518  M                                                      endm
 1518  M                                                      #temp     ::?b
 1518  M                                                      mset      0,sub
 1518  M                                                      mdo
 1518  M [1CB0] 1CB0:E606            [ 3]                     lda       ?a+1,spx
 1518  M [1CB2] 1CB2:E008            [ 3]                     sub    ?b+1,spx
 1518  M [1CB4] 1CB4:E708            [ 3]                     sta       ?b+1,spx
 1518  M                                                      mset      0,sbc
 1518  M                                                      mloop     :temp
 1518  M [1CB6] 1CB6:E605            [ 3]                     lda       ?a+0,spx
 1518  M [1CB8] 1CB8:E207            [ 3]                     sbc    ?b+0,spx
 1518  M [1CBA] 1CBA:E707            [ 3]                     sta       ?b+0,spx
 1518  M                                                      mset      0,sbc
 1518  M                                                      mloop     :temp
 1518                                                         endm
 1534    [1CBC] 1CBC:CC1E 6E         [ 4]                     jmp       ?RemoveAndReturn
 1535                                     
 1536                001E                 ?SubCycles          equ       :cycles
 1537                                     
 1541                                                         #Message  Bit ops enabled (define NO_BIT_OPS to disable)
 1542                                     ;*******************************************************************************
 1543                                     ; Purpose: AND N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1544                                     ; Input  : [TOS+?WORD] = Number2
 1545                                     ;        : [TOS] = Number1
 1546                                     ; Output : [TOS] = Result
 1547                                     ; Note(s):
 1548                                                         #spauto   :ab
 1549                                     
 1550                1CBF                 ?BitAnd             proc
 1551    [1CBF] 1CBF:8789 8B         [ 6]                     push
 1552    [1CC2] 1CC2:95              [ 2]                     tsx
 1553                                     
 1555  M                                                      @and.s,   ?a,spx ?b,spx ?b,spx
 1555  M                                                      mreq      1,2,3:[#]Operand1,[#]Operand2,Destination
 1555  M                                                      @@_samesize_ ?a,spx ?b,spx ?b,spx
 1555  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1555  M                                                      mset      0
 1555  M                                                      mdo
 1555  M                                                      mswap     1,1
 1555  M                                                      @@_nosize_ ?a,spx
 1555  M                                                      mset      #
 1555  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1555  M                                                      endm
 1555  M                                                      mset      0,?a,spx
 1555  M                                                      mloop     :n
 1555  M                                                      mswap     1,2
 1555  M                                                      @@_nosize_ ?b,spx
 1555  M                                                      mset      #
 1555  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1555  M                                                      endm
 1555  M                                                      mloop     :n
 1555  M                                                      mswap     1,3
 1555  M                                                      @@_nosize_ ?b,spx
 1555  M                                                      mset      #
 1555  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1555  M                                                      endm
 1555  M                                                      mloop     :n
 1555  M                                                      endm
 1555  M                                                      mdo
 1555  M [1CC3] 1CC3:E605            [ 3]                     lda       ?a+0,spx
 1555  M [1CC5] 1CC5:E407            [ 3]                     and       ?b+0,spx
 1555  M [1CC7] 1CC7:E707            [ 3]                     sta       ?b+0,spx
 1555  M                                                      mloop     ::?b
 1555  M [1CC9] 1CC9:E606            [ 3]                     lda       ?a+1,spx
 1555  M [1CCB] 1CCB:E408            [ 3]                     and       ?b+1,spx
 1555  M [1CCD] 1CCD:E708            [ 3]                     sta       ?b+1,spx
 1555  M                                                      mloop     ::?b
 1555                                                         endm
 1570    [1CCF] 1CCF:CC1E 6E         [ 4]                     jmp       ?RemoveAndReturn
 1571                                     
 1572                001E                 ?AndCycles          equ       :cycles
 1573                                     
 1574                                     ;*******************************************************************************
 1575                                     ; Purpose: OR N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1576                                     ; Input  : [TOS+?WORD] = Number2
 1577                                     ;        : [TOS] = Number1
 1578                                     ; Output : [TOS] = Result
 1579                                     ; Note(s):
 1580                                                         #spauto   :ab
 1581                                     
 1582                1CD2                 ?BitOr              proc
 1583    [1CD2] 1CD2:8789 8B         [ 6]                     push
 1584    [1CD5] 1CD5:95              [ 2]                     tsx
 1585                                     
 1587  M                                                      @ora.s,   ?a,spx ?b,spx ?b,spx
 1587  M                                                      mreq      1,2,3:[#]Operand1,[#]Operand2,Destination
 1587  M                                                      @@_samesize_ ?a,spx ?b,spx ?b,spx
 1587  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1587  M                                                      mset      0
 1587  M                                                      mdo
 1587  M                                                      mswap     1,1
 1587  M                                                      @@_nosize_ ?a,spx
 1587  M                                                      mset      #
 1587  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1587  M                                                      endm
 1587  M                                                      mset      0,?a,spx
 1587  M                                                      mloop     :n
 1587  M                                                      mswap     1,2
 1587  M                                                      @@_nosize_ ?b,spx
 1587  M                                                      mset      #
 1587  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1587  M                                                      endm
 1587  M                                                      mloop     :n
 1587  M                                                      mswap     1,3
 1587  M                                                      @@_nosize_ ?b,spx
 1587  M                                                      mset      #
 1587  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1587  M                                                      endm
 1587  M                                                      mloop     :n
 1587  M                                                      endm
 1587  M                                                      mdo
 1587  M [1CD6] 1CD6:E605            [ 3]                     lda       ?a+0,spx
 1587  M [1CD8] 1CD8:EA07            [ 3]                     ora       ?b+0,spx
 1587  M [1CDA] 1CDA:E707            [ 3]                     sta       ?b+0,spx
 1587  M                                                      mloop     ::?b
 1587  M [1CDC] 1CDC:E606            [ 3]                     lda       ?a+1,spx
 1587  M [1CDE] 1CDE:EA08            [ 3]                     ora       ?b+1,spx
 1587  M [1CE0] 1CE0:E708            [ 3]                     sta       ?b+1,spx
 1587  M                                                      mloop     ::?b
 1587                                                         endm
 1602    [1CE2] 1CE2:CC1E 6E         [ 4]                     jmp       ?RemoveAndReturn
 1603                                     
 1604                001E                 ?OrCycles           equ       :cycles
 1605                                     
 1606                                     ;*******************************************************************************
 1607                                     ; Purpose: XOR N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1608                                     ; Input  : [TOS+?WORD] = Number2
 1609                                     ;        : [TOS] = Number1
 1610                                     ; Output : [TOS] = Result
 1611                                     ; Note(s):
 1612                                                         #spauto   :ab
 1613                                     
 1614                1CE5                 ?BitXor             proc
 1615    [1CE5] 1CE5:8789 8B         [ 6]                     push
 1616    [1CE8] 1CE8:95              [ 2]                     tsx
 1617                                     
 1619  M                                                      @eor.s,   ?a,spx ?b,spx ?b,spx
 1619  M                                                      mreq      1,2,3:[#]Operand1,[#]Operand2,Destination
 1619  M                                                      @@_samesize_ ?a,spx ?b,spx ?b,spx
 1619  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1619  M                                                      mset      0
 1619  M                                                      mdo
 1619  M                                                      mswap     1,1
 1619  M                                                      @@_nosize_ ?a,spx
 1619  M                                                      mset      #
 1619  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1619  M                                                      endm
 1619  M                                                      mset      0,?a,spx
 1619  M                                                      mloop     :n
 1619  M                                                      mswap     1,2
 1619  M                                                      @@_nosize_ ?b,spx
 1619  M                                                      mset      #
 1619  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1619  M                                                      endm
 1619  M                                                      mloop     :n
 1619  M                                                      mswap     1,3
 1619  M                                                      @@_nosize_ ?b,spx
 1619  M                                                      mset      #
 1619  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1619  M                                                      endm
 1619  M                                                      mloop     :n
 1619  M                                                      endm
 1619  M                                                      mdo
 1619  M [1CE9] 1CE9:E605            [ 3]                     lda       ?a+0,spx
 1619  M [1CEB] 1CEB:E807            [ 3]                     eor       ?b+0,spx
 1619  M [1CED] 1CED:E707            [ 3]                     sta       ?b+0,spx
 1619  M                                                      mloop     ::?b
 1619  M [1CEF] 1CEF:E606            [ 3]                     lda       ?a+1,spx
 1619  M [1CF1] 1CF1:E808            [ 3]                     eor       ?b+1,spx
 1619  M [1CF3] 1CF3:E708            [ 3]                     sta       ?b+1,spx
 1619  M                                                      mloop     ::?b
 1619                                                         endm
 1634    [1CF5] 1CF5:CC1E 6E         [ 4]                     jmp       ?RemoveAndReturn
 1635                                     
 1636                001E                 ?EorCycles          equ       :cycles
 1637                                     
 1638                                     ;*******************************************************************************
 1639                                     ; Purpose: Shift N1 left N2 times and place result on top-of-stack. N1 & N2 removed
 1640                                     ; Input  : [TOS+?WORD] = Number2
 1641                                     ;        : [TOS] = Number1
 1642                                     ; Output : [TOS] = Result
 1643                                     ; Note(s): CCR[C] = last most significant bit shifted out
 1644                                     ;        : Only LSB of second operand (N2) is used, as shifting more than the
 1645                                     ;        : highest bit version always produces zero.  Any non-zero bytes in the
 1646                                     ;        : N2 operand will cause a zero result, regardless.
 1647                                     
 1648                                                         #spauto   :ab
 1649                                     
 1650                1CF8                 ?ShiftLeft          proc
 1651    [1CF8] 1CF8:8789 8B         [ 6]                     push
 1652                                                         #ais
 1653                                     
 1654    [1CFB] 1CFB:9EE6 09         [ 4]                     lda       ?b+{::?b-1},sp      ;A = shift counter
 1655    [1CFE] 1CFE:87              [ 2]                     psha      counter@@
 1656                                     
 1657    [1CFF] 1CFF:95              [ 2]                     tsx
 1658                                     
 1659    [1D00] 1D00:6F09            [ 5]                     clr       ?b+{::?b-1},spx     ;clear original shift counter
 1660                0003                 b@@                 equ       ?b,::?b-1           ;(b@@ = ?b but excludes final already cleared byte - 2013.11.29 optimization)
 1661  M                                                      @zero?.s, b@@,spx             ;test whole word for zero (counter <= 8-bit)
 1661  M                                                      mset      #
 1661  M                                                      mreq      1
 1661  M                                                      @@_nosize_ b28,spx
 1661  M                                                      mset      #
 1661  M                                                      mset      0,mstop [zero?.s] No size (b28,spx)
 1661  M                                                      endm
 1661  M                                                      mdo
 1661  M [1D02] 1D02:E608            [ 3]                     lda       b28+0,spx
 1661  M                                                      mloop     ::b28
 1661                                                         endm
 1662    [1D04] 1D04:2709 (1D0F)     [ 3]                     beq       Go@@                ;if so, proceed normally
 1663                                     
 1664    [1D06] 1D06:F6              [ 3]                     lda       counter@@,spx       ;if shift counter is less than
 1665    [1D07] 1D07:A110            [ 2]                     cmpa      #MATHSIZE           ;MATHSIZE, proceed normally,
 1666    [1D09] 1D09:2504 (1D0F)     [ 3]                     blo       Go@@                ;else zero and exit
 1667                                     
 1668  M                                                      @clr.s,   b@@,spx             ;else error, so zero result
 1668  M                                                      mset      #
 1668  M                                                      mreq      1
 1668  M                                                      @@_nosize_ b28,spx
 1668  M                                                      mset      #
 1668  M                                                      mset      0,mstop [clr.s] No size (b28,spx)
 1668  M                                                      endm
 1668  M                                                      mdo
 1668  M [1D0B] 1D0B:6F08            [ 5]                     clr       b28+0,spx
 1668  M                                                      mloop     ::b28
 1668                                                         endm
 1669    [1D0D] 1D0D:200E (1D1D)     [ 3]                     bra       Done@@              ;and get out
 1670                                     
 1671  M                                  Go@@                @mova.s   ?a,spx ?b,spx       ;copy operand to result
 1671  M                                                      mset      #' '
 1671  M                                                      mreq      1,2:Source Destination
 1671  M                                                      @@_samesize_ ?a,spx ?b,spx
 1671  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1671  M                                                      mset      0
 1671  M                                                      mdo
 1671  M                                                      mswap     1,1
 1671  M                                                      @@_nosize_ ?a,spx
 1671  M                                                      mset      #
 1671  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1671  M                                                      endm
 1671  M                                                      mset      0,?a,spx
 1671  M                                                      mloop     :n
 1671  M                                                      mswap     1,2
 1671  M                                                      @@_nosize_ ?b,spx
 1671  M                                                      mset      #
 1671  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1671  M                                                      endm
 1671  M                                                      mloop     :n
 1671  M                                                      endm
 1671  M                                                      mset      0
 1671  M                                                      mdo
 1671  M [1D0F] 1D0F:E606            [ 3]                     lda       ?a+0,spx
 1671  M [1D11] 1D11:E708            [ 3]                     sta       ?b+0,spx
 1671  M                                                      mloop     ::?b
 1671  M [1D13] 1D13:E607            [ 3]                     lda       ?a+1,spx
 1671  M [1D15] 1D15:E709            [ 3]                     sta       ?b+1,spx
 1671  M                                                      mloop     ::?b
 1671                                                         endm
 1672                                                                   #Cycles
 1673  M                                  Loop@@              @lsl.s,   ?b,spx              ;shift left one bit position
 1673  M                                                      mset      #
 1673  M                                                      mreq      1
 1673  M                                                      @@_nosize_ ?b,spx
 1673  M                                                      mset      #
 1673  M                                                      mset      0,mstop [lsl.s] No size (?b,spx)
 1673  M                                                      endm
 1673  M                                                      mdo
 1673  M [1D17] 1D17:6809            [ 5]                     lsl       ?b+1,spx
 1673  M                                                      mloop     ::?b
 1673  M [1D19] 1D19:6908            [ 5]                     rol       ?b+0,spx
 1673  M                                                      mloop     ::?b
 1673                                                         endm
 1674    [1D1B] 1D1B:7BFA (1D17)     [ 6]                     dbnz      counter@@,spx,Loop@@ ;repeat for all bits
 1675                                                                   #Cycles :cycles*{MATHSIZE-1}+:ocycles
 1676                1D1D                 Done@@
 1678    [1D1D] 1D1D:86              [ 3]                     pula
 1682    [1D1E] 1D1E:CC1E 6E         [ 4]                     jmp       ?RemoveAndReturn
 1683                                     
 1684                012C                 ?ShlCycles          equ       :cycles
 1685                                     
 1686                                     ;*******************************************************************************
 1687                                     ; Purpose: Shift N1 right N2 times and place result on top-of-stack. N1 & N2 removed
 1688                                     ; Input  : [TOS+?WORD] = Number2
 1689                                     ;        : [TOS] = Number1
 1690                                     ; Output : [TOS] = Result
 1691                                     ; Note(s): CCR[C] = last least significant bit shifted out
 1692                                     ;        : Only LSB of second operand (N2) is used, as shifting more than the
 1693                                     ;        : highest bit version always produces zero.  Any non-zero bytes in the
 1694                                     ;        : N2 operand will cause a zero result, regardless.
 1695                                     
 1696                                                         #spauto   :ab
 1697                                     
 1698                1D21                 ?ShiftRight         proc
 1699    [1D21] 1D21:8789 8B         [ 6]                     push
 1700                                                         #ais
 1701                                     
 1702    [1D24] 1D24:9EE6 09         [ 4]                     lda       ?b+{::?b-1},sp      ;A = shift counter
 1703    [1D27] 1D27:87              [ 2]                     psha      counter@@
 1704                                     
 1705    [1D28] 1D28:95              [ 2]                     tsx
 1706                                     
 1707    [1D29] 1D29:6F09            [ 5]                     clr       ?b+{::?b-1},spx     ;clear original shift counter
 1708                0003                 b@@                 equ       ?b,::?b-1           ;(b@@ = ?b but excludes final already cleared byte - 2013.11.29 optimization)
 1709  M                                                      @zero?.s, b@@,spx             ;test whole word for zero (counter <= 8-bit)
 1709  M                                                      mset      #
 1709  M                                                      mreq      1
 1709  M                                                      @@_nosize_ b29,spx
 1709  M                                                      mset      #
 1709  M                                                      mset      0,mstop [zero?.s] No size (b29,spx)
 1709  M                                                      endm
 1709  M                                                      mdo
 1709  M [1D2B] 1D2B:E608            [ 3]                     lda       b29+0,spx
 1709  M                                                      mloop     ::b29
 1709                                                         endm
 1710    [1D2D] 1D2D:2709 (1D38)     [ 3]                     beq       Go@@                ;if so, proceed normally
 1711                                     
 1712    [1D2F] 1D2F:F6              [ 3]                     lda       counter@@,spx       ;if shift counter is less than
 1713    [1D30] 1D30:A110            [ 2]                     cmpa      #MATHSIZE           ;MATHSIZE, proceed normally,
 1714    [1D32] 1D32:2504 (1D38)     [ 3]                     blo       Go@@                ;else zero and exit
 1715                                     
 1716  M                                                      @clr.s,   b@@,spx             ;else error, so zero result
 1716  M                                                      mset      #
 1716  M                                                      mreq      1
 1716  M                                                      @@_nosize_ b29,spx
 1716  M                                                      mset      #
 1716  M                                                      mset      0,mstop [clr.s] No size (b29,spx)
 1716  M                                                      endm
 1716  M                                                      mdo
 1716  M [1D34] 1D34:6F08            [ 5]                     clr       b29+0,spx
 1716  M                                                      mloop     ::b29
 1716                                                         endm
 1717    [1D36] 1D36:200E (1D46)     [ 3]                     bra       Done@@              ;and get out
 1718                                     
 1719  M                                  Go@@                @mova.s   ?a,spx ?b,spx       ;copy operand to result
 1719  M                                                      mset      #' '
 1719  M                                                      mreq      1,2:Source Destination
 1719  M                                                      @@_samesize_ ?a,spx ?b,spx
 1719  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1719  M                                                      mset      0
 1719  M                                                      mdo
 1719  M                                                      mswap     1,1
 1719  M                                                      @@_nosize_ ?a,spx
 1719  M                                                      mset      #
 1719  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1719  M                                                      endm
 1719  M                                                      mset      0,?a,spx
 1719  M                                                      mloop     :n
 1719  M                                                      mswap     1,2
 1719  M                                                      @@_nosize_ ?b,spx
 1719  M                                                      mset      #
 1719  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1719  M                                                      endm
 1719  M                                                      mloop     :n
 1719  M                                                      endm
 1719  M                                                      mset      0
 1719  M                                                      mdo
 1719  M [1D38] 1D38:E606            [ 3]                     lda       ?a+0,spx
 1719  M [1D3A] 1D3A:E708            [ 3]                     sta       ?b+0,spx
 1719  M                                                      mloop     ::?b
 1719  M [1D3C] 1D3C:E607            [ 3]                     lda       ?a+1,spx
 1719  M [1D3E] 1D3E:E709            [ 3]                     sta       ?b+1,spx
 1719  M                                                      mloop     ::?b
 1719                                                         endm
 1720                                                                   #Cycles
 1721                1D40                 Loop@@
 1723  M                                                      @asr.s,   ?b,spx              ;shift right one bit position
 1723  M                                                      mset      #
 1723  M                                                      mreq      1
 1723  M                                                      @@_nosize_ ?b,spx
 1723  M                                                      mset      #
 1723  M                                                      mset      0,mstop [asr.s] No size (?b,spx)
 1723  M                                                      endm
 1723  M                                                      mdo
 1723  M [1D40] 1D40:6708            [ 5]                     asr       ?b+0,spx
 1723  M                                                      mloop     ::?b
 1723  M [1D42] 1D42:6609            [ 5]                     ror       ?b+1,spx
 1723  M                                                      mloop     ::?b
 1723                                                         endm
 1727    [1D44] 1D44:7BFA (1D40)     [ 6]                     dbnz      counter@@,spx,Loop@@ ;repeat for all bits
 1728                                                                   #Cycles :cycles*{MATHSIZE-1}+:ocycles
 1729                1D46                 Done@@
 1731    [1D46] 1D46:86              [ 3]                     pula
 1735    [1D47] 1D47:CC1E 6E         [ 4]                     jmp       ?RemoveAndReturn
 1736                                     
 1737                012C                 ?ShrCycles          equ       :cycles
 1738                                     
 1740                                     
 1741                                     ;*******************************************************************************
 1742                                     ; Purpose: Multiply N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1743                                     ; Input  : [TOS+?WORD] = Number2
 1744                                     ;        : [TOS] = Number1
 1745                                     ; Output : [TOS] = Result
 1746                                     ; Note(s): Overflows lost, Carry state should be ignored
 1747                                     
 1748                                                         #spauto   :ab
 1749                                     
 1750                1D4A                 ?Multiply           proc
 1751    [1D4A] 1D4A:8789 8B         [ 6]                     push
 1752                                     
 1754                                               ;row 1
 1755    [1D4D] 1D4D:95              [ 2]                     tsx
 1756    [1D4E] 1D4E:E606            [ 3]                     lda       ?a+1,spx
 1757    [1D50] 1D50:EE08            [ 3]                     ldx       ?b+1,spx
 1758    [1D52] 1D52:42              [ 5]                     mul
 1759    [1D53] 1D53:8789            [ 4]                     pshxa     ans@@               ;temporary 16-bit result (2nd byte)
 1760                                     
 1761    [1D55] 1D55:95              [ 2]                     tsx
 1762    [1D56] 1D56:E608            [ 3]                     lda       ?a+1,spx
 1763    [1D58] 1D58:EE09            [ 3]                     ldx       ?b+0,spx
 1764    [1D5A] 1D5A:42              [ 5]                     mul
 1765    [1D5B] 1D5B:95              [ 2]                     tsx
 1766    [1D5C] 1D5C:FB              [ 3]                     add       ans@@,spx
 1767    [1D5D] 1D5D:F7              [ 2]                     sta       ans@@,spx
 1768                                               ;row 2
 1769    [1D5E] 1D5E:E607            [ 3]                     lda       ?a+0,spx
 1770    [1D60] 1D60:EE0A            [ 3]                     ldx       ?b+1,spx
 1771    [1D62] 1D62:42              [ 5]                     mul
 1772    [1D63] 1D63:95              [ 2]                     tsx
 1773    [1D64] 1D64:FB              [ 3]                     add       ans@@,spx
 1774    [1D65] 1D65:F7              [ 2]                     sta       ans@@,spx
 1776                                     ;-------------------------------------------------------------------------------
 1827                                     ;-------------------------------------------------------------------------------
 1919                                                                   #temp :cycles
 1920                                     ;-------------------------------------------------------------------------------
 1921                                     ; 40, 48, 56, and 64-bit versions use shorter shift/add method (more cycles, though)
 1922                                     
 1949                                     ;-------------------------------------------------------------------------------
 1950                                     
 1951                                               ;copy result to B while removing from stack
 1952                                     
 1953    [1D66] 1D66:AE02            [ 2]                     ldx       #?WORD
 1954                                                                   #temp :cycles+:temp
 1955    [1D68] 1D68:86              [ 3] CopyResult@@        pula
 1956    [1D69] 1D69:9EE7 09         [ 4]                     sta       ?b,sp
 1957    [1D6C] 1D6C:5BFA (1D68)     [ 4]                     dbnzx     CopyResult@@
 1958                                     
 1959                                                         #spadd    1-?WORD
 1960                                                                   #temp :cycles*?WORD+:temp
 1961    [1D6E] 1D6E:CC1E 6E         [ 4]                     jmp       ?RemoveAndReturn
 1962                                     
 1963                0059                 ?MulCycles          equ       :temp+:cycles
 1964                                     
 1965                                     ;*******************************************************************************
 1966                                     ; Purpose: Divide N1 by N2 and place quotient on top-of-stack. N1 & N2 removed
 1967                                     ; Input  : [TOS+?WORD] = Divisor (N2)
 1968                                     ;        : [TOS] = Dividend (N1)
 1969                                     ; Output : [TOS] = Quotient
 1970                                     ;        : Carry Set on error (division by zero)
 1971                                     ; Note(s):
 1972                                                         #spauto   :ab
 1973                                     
 1974                1D71                 ?Divide             proc
 1975    [1D71] 1D71:8789 8B         [ 6]                     push
 1976                                     
 1977    [1D74] 1D74:A601            [ 2]                     lda       #?DIVOP_            ;flag for DIV operation
 1979    [1D76] 1D76:87              [ 2]                     psha
 1980    [1D77] 1D77:95              [ 2]                     tsx
 1981    [1D78] 1D78:E606            [ 3]                     lda       ?a,spx
 1982    [1D7A] 1D7A:E808            [ 3]                     eor       ?b,spx
 1983    [1D7C] 1D7C:86              [ 3]                     pula
 1984    [1D7D] 1D7D:2A02 (1D81)     [ 3]                     bpl       Skip@@
 1985    [1D7F] 1D7F:AA80            [ 2]                     ora       #?SIGN_             ;flag for negative
 1986                1D81                 Skip@@
 1988    [1D81] 1D81:87              [ 2]                     psha                          ;save flags on stack
 1989    [1D82] 1D82:201E (1DA2)     [ 3]                     bra       ?DivStart
 1990                                     
 1991                001F                 ?DivCycles          equ       :cycles
 1992                                     
 1993                                     ;*******************************************************************************
 1994                                     ; Purpose: Divide N1 by N2 and place remainder on top-of-stack. N1 & N2 removed
 1995                                     ; Input  : [TOS+?WORD] = Divisor (N2)
 1996                                     ;        : [TOS] = Dividend (N1)
 1997                                     ; Output : [TOS] = Remainder
 1998                                     ;        : Carry Set on error (division by zero)
 1999                                     ; Note(s):
 2000                                                         #spauto   :ab
 2001                FFFFFFFF             ?pc                 equ       ::,:ab
 2002                                     
 2003                1D84                 ?Modulo             proc
 2004    [1D84] 1D84:8789 8B         [ 6]                     push
 2005                                     
 2006    [1D87] 1D87:4F              [ 1]                     clra                          ;flag for MOD operation
 2008    [1D88] 1D88:9E6D 06         [ 5]                     tst       ?a,sp
 2009    [1D8B] 1D8B:2A02 (1D8F)     [ 3]                     bpl       Skip@@
 2010    [1D8D] 1D8D:AA80            [ 2]                     ora       #?SIGN_             ;flag for negative
 2011                1D8F                 Skip@@
 2013    [1D8F] 1D8F:87              [ 2]                     psha                          ;save flags on stack
 2014    [1D90] 1D90:2010 (1DA2)     [ 3]                     bra       ?DivStart
 2015                                     
 2016                0016                 ?ModCycles          equ       :cycles
 2017                                     
 2018                                     ;*******************************************************************************
 2019                                     
 2020                                                         #temp
 2022                1D92                 ?AbsX               proc
 2023    [1D92] 1D92:7D              [ 3]                     tst       ,ax
 2024    [1D93] 1D93:2A06 (1D9B)     [ 3]                     bpl       Done@@
 2025                                                                   #temp :cycles
 2026                0000                 var@@               equ       0,?WORD
 2027  M                                  ?NegX               @neg.s    var@@,ax
 2027  M                                                      mset      #
 2027  M                                                      mreq      1
 2027  M                                                      @@_nosize_ var33,ax
 2027  M                                                      mset      #
 2027  M                                                      mset      0,mstop [neg.s] No size (var33,ax)
 2027  M                                                      endm
 2027  M                                                      mdo
 2027  M [1D95] 1D95:73              [ 4]                     com       var33+0,ax
 2027  M                                                      mloop     ::var33-1
 2027  M [1D96] 1D96:6001            [ 5]                     neg       var33+1,ax
 2027  M                                                      mdo
 2027  M [1D98] 1D98:2601 (1D9B)     [ 3]                     bne       Done$$$
 2027  M [1D9A] 1D9A:7C              [ 4]                     inc       var33+0,ax
 2027  M                                                      mloop     ::var33-1
 2027  M             1D9B                 Done$$$
 2027                                                         endm
 2028    [1D9B] 1D9B:81              [ 6] Done@@              rts
 2029                                     
 2030                0016                 ?AbsXCycles         equ       :cycles
 2031                0010                 ?NegxCycles         equ       ?AbsXCycles-:temp
 2033                                     
 2034                                     ;*******************************************************************************
 2035                                     
 2036                0000                 ?SF                 equ       0                   ;stack frame (for X-index use)
 2037                                     
 2038                0000                 ?quotient           next      ?SF,?WORD
 2039                0002                 ?remainder          next      ?SF,?WORD
 2040                0004                 ?temp               next      ?SF,?WORD
 2041                0006                 ?bits               next      ?SF
 2042                0007                 ?flags              next      ?SF
 2043                                     
 2044                0001                 ?DIVOP_             equ       %00000001           ;1 = DIV, 0 = MOD
 2045                0080                 ?SIGN_              equ       %10000000           ;result sign (1 = negative)
 2046                                     
 2047                                                         #push
 2048                                     
 2049    [1D9C] 1D9C:A708            [ 2] ?DivError           ais       #?SF                ;de-allocate temporaries
 2050    [1D9E] 1D9E:99              [ 1]                     sec                           ;indicate error condition
 2051    [1D9F] 1D9F:CC1E 6E         [ 4]                     jmp       ?RemoveAndReturn
 2052                                     
 2053                                                         #pull
 2054                                     
 2055                                     ;-------------------------------------------------------------------------------
 2056                                     
 2057                1DA2                 ?DivStart           proc
 2058                0001                 dividend@@          equ       ?a,::?a
 2059                0003                 divisor@@           equ       ?b,::?b
 2060                0003                 ans@@               equ       ?b,::?b             ;result overwrites divisor
 2061                                     
 2063  M                                                      @lea      dividend@@,sp
 2063  M                                                      mset      #
 2063  M [1DA2] 1DA2:95              [ 2]                     tsx
 2063  M [1DA3] 1DA3:AF06            [ 2]                     !aix      #dividend34+:tsx
 2063                                                         mexit
 2064    [1DA5] 1DA5:ADEB (1D92)     [ 5]                     bsr       ?AbsX
 2065  M                                                      @lea      divisor@@,sp
 2065  M                                                      mset      #
 2065  M [1DA7] 1DA7:95              [ 2]                     tsx
 2065  M [1DA8] 1DA8:AF08            [ 2]                     !aix      #divisor34+:tsx
 2065                                                         mexit
 2066    [1DAA] 1DAA:ADE6 (1D92)     [ 5]                     bsr       ?AbsX
 2067                                                                   #Cycles ?AbsXCycles*2+:cycles
 2069    [1DAC] 1DAC:A7F9            [ 2]                     ais       #-?SF+1             ;quotient, remainder, and temp
 2070    [1DAE] 1DAE:95              [ 2]                     tsx                           ;(+1 for already pushed Flag)
 2071                                     
 2072                                               ; remainder := 0
 2073                                               ; quotient := 0
 2074                                     
 2075  M                                                      @clr.s    ?remainder,x
 2075  M                                                      mset      #
 2075  M                                                      mreq      1
 2075  M                                                      @@_nosize_ ?remainder,x
 2075  M                                                      mset      #
 2075  M                                                      mset      0,mstop [clr.s] No size (?remainder,x)
 2075  M                                                      endm
 2075  M                                                      mdo
 2075  M [1DAF] 1DAF:6F02            [ 5]                     clr       ?remainder+0,x
 2075  M                                                      mloop     ::?remainder
 2075  M [1DB1] 1DB1:6F03            [ 5]                     clr       ?remainder+1,x
 2075  M                                                      mloop     ::?remainder
 2075                                                         endm
 2076  M                                                      @clr.s    ?quotient,x
 2076  M                                                      mset      #
 2076  M                                                      mreq      1
 2076  M                                                      @@_nosize_ ?quotient,x
 2076  M                                                      mset      #
 2076  M                                                      mset      0,mstop [clr.s] No size (?quotient,x)
 2076  M                                                      endm
 2076  M                                                      mdo
 2076  M [1DB3] 1DB3:7F              [ 4]                     clr       ?quotient+0,x
 2076  M                                                      mloop     ::?quotient
 2076  M [1DB4] 1DB4:6F01            [ 5]                     clr       ?quotient+1,x
 2076  M                                                      mloop     ::?quotient
 2076                                                         endm
 2077                                     
 2078                                               ; first, test for division by zero error
 2079                                     
 2080  M                                                      @zero?.s  divisor@@,spx
 2080  M                                                      mset      #
 2080  M                                                      mreq      1
 2080  M                                                      @@_nosize_ divisor34,spx
 2080  M                                                      mset      #
 2080  M                                                      mset      0,mstop [zero?.s] No size (divisor34,spx)
 2080  M                                                      endm
 2080  M                                                      mdo
 2080  M [1DB6] 1DB6:E60F            [ 3]                     lda       divisor34+0,spx
 2080  M                                                      mloop     ::divisor34
 2080  M [1DB8] 1DB8:EA10            [ 3]                     ora       divisor34+1,spx
 2080  M                                                      mloop     ::divisor34
 2080                                                         endm
 2081    [1DBA] 1DBA:27E0 (1D9C)     [ 3]                     beq       ?DivError
 2082                                     
 2083                                               ; if Dividend = 0, we're done
 2084                                     
 2085  M                                                      @zero?.s  dividend@@,spx
 2085  M                                                      mset      #
 2085  M                                                      mreq      1
 2085  M                                                      @@_nosize_ dividend34,spx
 2085  M                                                      mset      #
 2085  M                                                      mset      0,mstop [zero?.s] No size (dividend34,spx)
 2085  M                                                      endm
 2085  M                                                      mdo
 2085  M [1DBC] 1DBC:E60D            [ 3]                     lda       dividend34+0,spx
 2085  M                                                      mloop     ::dividend34
 2085  M [1DBE] 1DBE:EA0E            [ 3]                     ora       dividend34+1,spx
 2085  M                                                      mloop     ::dividend34
 2085                                                         endm
 2086    [1DC0] 1DC0:2603 CC1E 4A    [ 7]                     jeq       Done@@
 2087                                     
 2088                                               ; if (divisor = dividend) then quotient := 1; return
 2089                                               ; if (divisor > dividend) then remainder := dividend; return
 2090                                     
 2091  M                                                      @_cmp_.s, divisor@@,spx dividend@@,spx
 2091  M                                                      mreq      1,2:[#]Operand1,[#]Operand2
 2091  M                                                      @@_samesize_ divisor34,spx dividend@@,spx
 2091  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2091  M                                                      mset      0
 2091  M                                                      mdo
 2091  M                                                      mswap     1,1
 2091  M                                                      @@_nosize_ divisor34,spx
 2091  M                                                      mset      #
 2091  M                                                      mset      0,mstop [_samesize_] No size (divisor34,spx)
 2091  M                                                      endm
 2091  M                                                      mset      0,divisor34,spx
 2091  M                                                      mloop     :n
 2091  M                                                      mswap     1,2
 2091  M                                                      @@_nosize_ dividend@@,spx
 2091  M                                                      mset      #
 2091  M                                                      mset      0,mstop [_samesize_] No size (dividend34,spx)
 2091  M                                                      endm
 2091  M                                                      mloop     :n
 2091  M                                                      endm
 2091  M                                                      #temp     1
 2091  M                                                      #temp     ::divisor34
 2091  M                                                      #temp     ::dividend@@
 2091  M                                                      mdo
 2091  M [1DC5] 1DC5:E60F            [ 3]                     lda       divisor34+0,spx
 2091  M [1DC7] 1DC7:E10D            [ 3]                     cmpa      dividend@@+0,spx
 2091  M [1DC9] 1DC9:2604 (1DCF)     [ 3]                     bne       Done$$$
 2091  M                                                      mloop     :temp
 2091  M [1DCB] 1DCB:E610            [ 3]                     lda       divisor34+1,spx
 2091  M [1DCD] 1DCD:E10E            [ 3]                     cmpa      dividend@@+1,spx
 2091  M                                                      mloop     :temp
 2091  M             1DCF                 Done$$$
 2091                                                         endm
 2092    [1DCF] 1DCF:2604 (1DD5)     [ 3]                     bne       NotEqual@@
 2093                                     
 2094    [1DD1] 1DD1:6C01            [ 5]                     inc       ?quotient+{::?quotient-1},x  ;quotient := 1
 2095    [1DD3] 1DD3:200A (1DDF)     [ 3]                     bra       ??DivExit           ;and get out
 2096                                     
 2097                1DD5                 NotEqual@@         ;@sub.s,   divisor@@,spx dividend@@,spx  ;[2012.05.18 REDUNDANT]
 2098    [1DD5] 1DD5:250A (1DE1)     [ 3]                     blo       Continue@@
 2099                                     
 2100  M                                                      @mova.s   dividend@@,spx ?remainder,x
 2100  M                                                      mset      #' '
 2100  M                                                      mreq      1,2:Source Destination
 2100  M                                                      @@_samesize_ dividend34,spx ?remainder,x
 2100  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2100  M                                                      mset      0
 2100  M                                                      mdo
 2100  M                                                      mswap     1,1
 2100  M                                                      @@_nosize_ dividend34,spx
 2100  M                                                      mset      #
 2100  M                                                      mset      0,mstop [_samesize_] No size (dividend34,spx)
 2100  M                                                      endm
 2100  M                                                      mset      0,dividend34,spx
 2100  M                                                      mloop     :n
 2100  M                                                      mswap     1,2
 2100  M                                                      @@_nosize_ ?remainder,x
 2100  M                                                      mset      #
 2100  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2100  M                                                      endm
 2100  M                                                      mloop     :n
 2100  M                                                      endm
 2100  M                                                      mset      0
 2100  M                                                      mdo
 2100  M [1DD7] 1DD7:E60D            [ 3]                     lda       dividend34+0,spx
 2100  M [1DD9] 1DD9:E702            [ 3]                     sta       ?remainder+0,x
 2100  M                                                      mloop     ::?remainder
 2100  M [1DDB] 1DDB:E60E            [ 3]                     lda       dividend34+1,spx
 2100  M [1DDD] 1DDD:E703            [ 3]                     sta       ?remainder+1,x
 2100  M                                                      mloop     ::?remainder
 2100                                                         endm
 2101                1DDF                 ??DivExit                                         ;and get out
 2103    [1DDF] 1DDF:2069 (1E4A)     [ 3]                     bra       Done@@
 2107                                     
 2108    [1DE1] 1DE1:A610            [ 2] Continue@@          lda       #MATHSIZE
 2109    [1DE3] 1DE3:E706            [ 3]                     sta       ?bits,x             ;bits := 64/56/48/40/32/24/16-bit
 2110                                     
 2111                                               ; while (remainder < divisor) do
 2112                                     
 2113  M                                  While@@             @cop                          ;in case of many iterations
 2113  M [1DE5] 1DE5:C718 00         [ 4]                     sta       COP
 2113                                                         endm
 2114                                     
 2115  M                                                      @sub.s,   ?remainder,x divisor@@,spx
 2115  M                                                      mreq      1,2:[#]Operand1,[#]Operand2,Destination
 2115  M                                                      @@_samesize_ ?remainder,x divisor34,spx
 2115  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2115  M                                                      mset      0
 2115  M                                                      mdo
 2115  M                                                      mswap     1,1
 2115  M                                                      @@_nosize_ ?remainder,x
 2115  M                                                      mset      #
 2115  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2115  M                                                      endm
 2115  M                                                      mset      0,?remainder,x
 2115  M                                                      mloop     :n
 2115  M                                                      mswap     1,2
 2115  M                                                      @@_nosize_ divisor34,spx
 2115  M                                                      mset      #
 2115  M                                                      mset      0,mstop [_samesize_] No size (divisor34,spx)
 2115  M                                                      endm
 2115  M                                                      mloop     :n
 2115  M                                                      endm
 2115  M                                                      #temp
 2115  M                                                      @@_nosize_ ?remainder,x
 2115  M                                                      mset      #
 2115  M                                                      mset      0,mstop [sub.s] No size (?remainder,x)
 2115  M                                                      endm
 2115  M                                                      #temp     ::?remainder
 2115  M                                                      mset      0,sub
 2115  M                                                      mdo
 2115  M [1DE8] 1DE8:E603            [ 3]                     lda       ?remainder+1,x
 2115  M [1DEA] 1DEA:E010            [ 3]                     sub    divisor34+1,spx
 2115  M                                                      mset      0,sbc
 2115  M                                                      mloop     :temp
 2115  M [1DEC] 1DEC:E602            [ 3]                     lda       ?remainder+0,x
 2115  M [1DEE] 1DEE:E20F            [ 3]                     sbc    divisor34+0,spx
 2115  M                                                      mset      0,sbc
 2115  M                                                      mloop     :temp
 2115                                                         endm
 2116    [1DF0] 1DF0:2414 (1E06)     [ 3]                     bcc       EndWhile@@
 2117                                     
 2118                                               ; remainder := (remainder shl 1) or msb(dividend)
 2119                                     
 2120                                               ;--- 2012.12.04 optimization (moved up this code from before DEC to here)
 2121  M                                                      @mova.s   dividend@@,spx ?temp,x  ; temp := dividend
 2121  M                                                      mset      #' '
 2121  M                                                      mreq      1,2:Source Destination
 2121  M                                                      @@_samesize_ dividend34,spx ?temp,x
 2121  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2121  M                                                      mset      0
 2121  M                                                      mdo
 2121  M                                                      mswap     1,1
 2121  M                                                      @@_nosize_ dividend34,spx
 2121  M                                                      mset      #
 2121  M                                                      mset      0,mstop [_samesize_] No size (dividend34,spx)
 2121  M                                                      endm
 2121  M                                                      mset      0,dividend34,spx
 2121  M                                                      mloop     :n
 2121  M                                                      mswap     1,2
 2121  M                                                      @@_nosize_ ?temp,x
 2121  M                                                      mset      #
 2121  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2121  M                                                      endm
 2121  M                                                      mloop     :n
 2121  M                                                      endm
 2121  M                                                      mset      0
 2121  M                                                      mdo
 2121  M [1DF2] 1DF2:E60D            [ 3]                     lda       dividend34+0,spx
 2121  M [1DF4] 1DF4:E704            [ 3]                     sta       ?temp+0,x
 2121  M                                                      mloop     ::?temp
 2121  M [1DF6] 1DF6:E60E            [ 3]                     lda       dividend34+1,spx
 2121  M [1DF8] 1DF8:E705            [ 3]                     sta       ?temp+1,x
 2121  M                                                      mloop     ::?temp
 2121                                                         endm
 2122  M                                                      @lsl.s    dividend@@,spx      ; dividend := dividend shl 1
 2122  M                                                      mset      #
 2122  M                                                      mreq      1
 2122  M                                                      @@_nosize_ dividend34,spx
 2122  M                                                      mset      #
 2122  M                                                      mset      0,mstop [lsl.s] No size (dividend34,spx)
 2122  M                                                      endm
 2122  M                                                      mdo
 2122  M [1DFA] 1DFA:680E            [ 5]                     lsl       dividend34+1,spx
 2122  M                                                      mloop     ::dividend34
 2122  M [1DFC] 1DFC:690D            [ 5]                     rol       dividend34+0,spx
 2122  M                                                      mloop     ::dividend34
 2122                                                         endm
 2123                                               ;---
 2124  M                                                      @rol.s    ?remainder,x
 2124  M                                                      mset      #
 2124  M                                                      mreq      1
 2124  M                                                      @@_nosize_ ?remainder,x
 2124  M                                                      mset      #
 2124  M                                                      mset      0,mstop [rol.s] No size (?remainder,x)
 2124  M                                                      endm
 2124  M                                                      mdo
 2124  M [1DFE] 1DFE:6903            [ 5]                     rol       ?remainder+1,x
 2124  M                                                      mloop     ::?remainder
 2124  M [1E00] 1E00:6902            [ 5]                     rol       ?remainder+0,x
 2124  M                                                      mloop     ::?remainder
 2124                                                         endm
 2125    [1E02] 1E02:6A06            [ 5]                     dec       ?bits,x             ; bits := bits - 1
 2126                                     
 2127                                               ; end while
 2128                                     
 2129    [1E04] 1E04:20DF (1DE5)     [ 3]                     bra       While@@
 2130                1E06                 EndWhile@@
 2131  M                                                      @mova.s   ?temp,x dividend@@,spx  ; dividend := temp
 2131  M                                                      mset      #' '
 2131  M                                                      mreq      1,2:Source Destination
 2131  M                                                      @@_samesize_ ?temp,x dividend34,spx
 2131  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2131  M                                                      mset      0
 2131  M                                                      mdo
 2131  M                                                      mswap     1,1
 2131  M                                                      @@_nosize_ ?temp,x
 2131  M                                                      mset      #
 2131  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2131  M                                                      endm
 2131  M                                                      mset      0,?temp,x
 2131  M                                                      mloop     :n
 2131  M                                                      mswap     1,2
 2131  M                                                      @@_nosize_ dividend34,spx
 2131  M                                                      mset      #
 2131  M                                                      mset      0,mstop [_samesize_] No size (dividend34,spx)
 2131  M                                                      endm
 2131  M                                                      mloop     :n
 2131  M                                                      endm
 2131  M                                                      mset      0
 2131  M                                                      mdo
 2131  M [1E06] 1E06:E604            [ 3]                     lda       ?temp+0,x
 2131  M [1E08] 1E08:E70D            [ 3]                     sta       dividend34+0,spx
 2131  M                                                      mloop     ::dividend34
 2131  M [1E0A] 1E0A:E605            [ 3]                     lda       ?temp+1,x
 2131  M [1E0C] 1E0C:E70E            [ 3]                     sta       dividend34+1,spx
 2131  M                                                      mloop     ::dividend34
 2131                                                         endm
 2132  M                                                      @lsr.s    ?remainder,x        ; remainder := remainder shr 1
 2132  M                                                      mset      #
 2132  M                                                      mreq      1
 2132  M                                                      @@_nosize_ ?remainder,x
 2132  M                                                      mset      #
 2132  M                                                      mset      0,mstop [lsr.s] No size (?remainder,x)
 2132  M                                                      endm
 2132  M                                                      mdo
 2132  M [1E0E] 1E0E:6402            [ 5]                     lsr       ?remainder+0,x
 2132  M                                                      mloop     ::?remainder
 2132  M [1E10] 1E10:6603            [ 5]                     ror       ?remainder+1,x
 2132  M                                                      mloop     ::?remainder
 2132                                                         endm
 2133    [1E12] 1E12:6C06            [ 5]                     inc       ?bits,x             ; bits := bits + 1
 2134                                     
 2135                                               ; for i := bitCounter-1 downto 0 do
 2136                                     
 2137  M                                  For@@               @cop                          ;in case of many iterations
 2137  M [1E14] 1E14:C718 00         [ 4]                     sta       COP
 2137                                                         endm
 2138                                     
 2139    [1E17] 1E17:6D06            [ 4]                     tst       ?bits,x
 2141    [1E19] 1E19:272F (1E4A)     [ 3]                     beq       Done@@
 2145    [1E1B] 1E1B:6A06            [ 5]                     dec       ?bits,x
 2146                                     
 2147                                               ; remainder := (remainder shl 1) or msb(dividend)
 2148                                               ; dividend := dividend shl 1
 2149                                     
 2150  M                                                      @lsl.s    dividend@@,spx      ;2012.12.04 optimization
 2150  M                                                      mset      #
 2150  M                                                      mreq      1
 2150  M                                                      @@_nosize_ dividend34,spx
 2150  M                                                      mset      #
 2150  M                                                      mset      0,mstop [lsl.s] No size (dividend34,spx)
 2150  M                                                      endm
 2150  M                                                      mdo
 2150  M [1E1D] 1E1D:680E            [ 5]                     lsl       dividend34+1,spx
 2150  M                                                      mloop     ::dividend34
 2150  M [1E1F] 1E1F:690D            [ 5]                     rol       dividend34+0,spx
 2150  M                                                      mloop     ::dividend34
 2150                                                         endm
 2151  M                                                      @rol.s    ?remainder,x
 2151  M                                                      mset      #
 2151  M                                                      mreq      1
 2151  M                                                      @@_nosize_ ?remainder,x
 2151  M                                                      mset      #
 2151  M                                                      mset      0,mstop [rol.s] No size (?remainder,x)
 2151  M                                                      endm
 2151  M                                                      mdo
 2151  M [1E21] 1E21:6903            [ 5]                     rol       ?remainder+1,x
 2151  M                                                      mloop     ::?remainder
 2151  M [1E23] 1E23:6902            [ 5]                     rol       ?remainder+0,x
 2151  M                                                      mloop     ::?remainder
 2151                                                         endm
 2152                                     
 2153                                               ; temp := remainder - divisor
 2154                                     
 2155  M                                                      @sub.s,   ?remainder,x divisor@@,spx ?temp,x
 2155  M                                                      mreq      1,2:[#]Operand1,[#]Operand2,Destination
 2155  M                                                      @@_samesize_ ?remainder,x divisor34,spx ?temp,x
 2155  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2155  M                                                      mset      0
 2155  M                                                      mdo
 2155  M                                                      mswap     1,1
 2155  M                                                      @@_nosize_ ?remainder,x
 2155  M                                                      mset      #
 2155  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2155  M                                                      endm
 2155  M                                                      mset      0,?remainder,x
 2155  M                                                      mloop     :n
 2155  M                                                      mswap     1,2
 2155  M                                                      @@_nosize_ divisor34,spx
 2155  M                                                      mset      #
 2155  M                                                      mset      0,mstop [_samesize_] No size (divisor34,spx)
 2155  M                                                      endm
 2155  M                                                      mloop     :n
 2155  M                                                      mswap     1,3
 2155  M                                                      @@_nosize_ ?temp,x
 2155  M                                                      mset      #
 2155  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2155  M                                                      endm
 2155  M                                                      mloop     :n
 2155  M                                                      endm
 2155  M                                                      #temp
 2155  M                                                      @@_nosize_ ?temp,x
 2155  M                                                      mset      #
 2155  M                                                      mset      0,mstop [sub.s] No size (?temp,x)
 2155  M                                                      endm
 2155  M                                                      #temp     ::?temp
 2155  M                                                      mset      0,sub
 2155  M                                                      mdo
 2155  M [1E25] 1E25:E603            [ 3]                     lda       ?remainder+1,x
 2155  M [1E27] 1E27:E010            [ 3]                     sub    divisor34+1,spx
 2155  M [1E29] 1E29:E705            [ 3]                     sta       ?temp+1,x
 2155  M                                                      mset      0,sbc
 2155  M                                                      mloop     :temp
 2155  M [1E2B] 1E2B:E602            [ 3]                     lda       ?remainder+0,x
 2155  M [1E2D] 1E2D:E20F            [ 3]                     sbc    divisor34+0,spx
 2155  M [1E2F] 1E2F:E704            [ 3]                     sta       ?temp+0,x
 2155  M                                                      mset      0,sbc
 2155  M                                                      mloop     :temp
 2155                                                         endm
 2156                                     
 2157                                               ; q := not msb(temp)
 2158                                     
 2159    [1E31] 1E31:E604            [ 3]                     lda       ?temp,x
 2160    [1E33] 1E33:A880            [ 2]                     eor       #%10000000          ;invert msb
 2161    [1E35] 1E35:A480            [ 2]                     and       #%10000000          ;isolate msb
 2162                                     
 2163                                               ; quotient := (quotient shl 1) or q
 2164                                     
 2165    [1E37] 1E37:87              [ 2]                     psha
 2166    [1E38] 1E38:48              [ 1]                     lsla
 2167    [1E39] 1E39:86              [ 3]                     pula
 2168                                     
 2169  M                                                      @rol.s    ?quotient,x
 2169  M                                                      mset      #
 2169  M                                                      mreq      1
 2169  M                                                      @@_nosize_ ?quotient,x
 2169  M                                                      mset      #
 2169  M                                                      mset      0,mstop [rol.s] No size (?quotient,x)
 2169  M                                                      endm
 2169  M                                                      mdo
 2169  M [1E3A] 1E3A:6901            [ 5]                     rol       ?quotient+1,x
 2169  M                                                      mloop     ::?quotient
 2169  M [1E3C] 1E3C:79              [ 4]                     rol       ?quotient+0,x
 2169  M                                                      mloop     ::?quotient
 2169                                                         endm
 2170                                     
 2171                                               ; if q <> 0 then
 2172                                     
 2173    [1E3D] 1E3D:4100 D4(1E14)   [ 4]                     cbeqa     #0,For@@
 2174                                     
 2175                                               ; remainder := temp
 2176                                     
 2177  M                                                      @mova.s   ?temp,x ?remainder,x
 2177  M                                                      mset      #' '
 2177  M                                                      mreq      1,2:Source Destination
 2177  M                                                      @@_samesize_ ?temp,x ?remainder,x
 2177  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2177  M                                                      mset      0
 2177  M                                                      mdo
 2177  M                                                      mswap     1,1
 2177  M                                                      @@_nosize_ ?temp,x
 2177  M                                                      mset      #
 2177  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2177  M                                                      endm
 2177  M                                                      mset      0,?temp,x
 2177  M                                                      mloop     :n
 2177  M                                                      mswap     1,2
 2177  M                                                      @@_nosize_ ?remainder,x
 2177  M                                                      mset      #
 2177  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2177  M                                                      endm
 2177  M                                                      mloop     :n
 2177  M                                                      endm
 2177  M                                                      mset      0
 2177  M                                                      mdo
 2177  M [1E40] 1E40:E604            [ 3]                     lda       ?temp+0,x
 2177  M [1E42] 1E42:E702            [ 3]                     sta       ?remainder+0,x
 2177  M                                                      mloop     ::?remainder
 2177  M [1E44] 1E44:E605            [ 3]                     lda       ?temp+1,x
 2177  M [1E46] 1E46:E703            [ 3]                     sta       ?remainder+1,x
 2177  M                                                      mloop     ::?remainder
 2177                                                         endm
 2178                                     
 2179                                               ; end if -- end for
 2180                                     
 2182    [1E48] 1E48:20CA (1E14)     [ 3]                     bra       For@@
 2186                                     
 2187    [1E4A] 1E4A:E607            [ 3] Done@@              lda       ?flags,x
 2188    [1E4C] 1E4C:A501            [ 2]                     bit       #?DIVOP_
 2189    [1E4E] 1E4E:2709 (1E59)     [ 3]                     beq       ExitMod@@
 2190                                     
 2191                0160                 ?Cycles             equ       :cycles
 2192                                     
 2193                                     ;ExitDiv@@
 2194  M                                                      @mova.s   ?quotient,x ans@@,spx
 2194  M                                                      mset      #' '
 2194  M                                                      mreq      1,2:Source Destination
 2194  M                                                      @@_samesize_ ?quotient,x ans34,spx
 2194  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2194  M                                                      mset      0
 2194  M                                                      mdo
 2194  M                                                      mswap     1,1
 2194  M                                                      @@_nosize_ ?quotient,x
 2194  M                                                      mset      #
 2194  M                                                      mset      0,mstop [_samesize_] No size (?quotient,x)
 2194  M                                                      endm
 2194  M                                                      mset      0,?quotient,x
 2194  M                                                      mloop     :n
 2194  M                                                      mswap     1,2
 2194  M                                                      @@_nosize_ ans34,spx
 2194  M                                                      mset      #
 2194  M                                                      mset      0,mstop [_samesize_] No size (ans34,spx)
 2194  M                                                      endm
 2194  M                                                      mloop     :n
 2194  M                                                      endm
 2194  M                                                      mset      0
 2194  M                                                      mdo
 2194  M [1E50] 1E50:F6              [ 3]                     lda       ?quotient+0,x
 2194  M [1E51] 1E51:E70F            [ 3]                     sta       ans34+0,spx
 2194  M                                                      mloop     ::ans34
 2194  M [1E53] 1E53:E601            [ 3]                     lda       ?quotient+1,x
 2194  M [1E55] 1E55:E710            [ 3]                     sta       ans34+1,spx
 2194  M                                                      mloop     ::ans34
 2194                                                         endm
 2195    [1E57] 1E57:2008 (1E61)     [ 3]                     bra       ExitBoth@@
 2196                                     
 2197                018E                 ?DivCycles          set       ?DivCycles+?Cycles+:cycles
 2198                                     
 2199  M                                  ExitMod@@           @mova.s   ?remainder,x ans@@,spx
 2199  M                                                      mset      #' '
 2199  M                                                      mreq      1,2:Source Destination
 2199  M                                                      @@_samesize_ ?remainder,x ans34,spx
 2199  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2199  M                                                      mset      0
 2199  M                                                      mdo
 2199  M                                                      mswap     1,1
 2199  M                                                      @@_nosize_ ?remainder,x
 2199  M                                                      mset      #
 2199  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2199  M                                                      endm
 2199  M                                                      mset      0,?remainder,x
 2199  M                                                      mloop     :n
 2199  M                                                      mswap     1,2
 2199  M                                                      @@_nosize_ ans34,spx
 2199  M                                                      mset      #
 2199  M                                                      mset      0,mstop [_samesize_] No size (ans34,spx)
 2199  M                                                      endm
 2199  M                                                      mloop     :n
 2199  M                                                      endm
 2199  M                                                      mset      0
 2199  M                                                      mdo
 2199  M [1E59] 1E59:E602            [ 3]                     lda       ?remainder+0,x
 2199  M [1E5B] 1E5B:E70F            [ 3]                     sta       ans34+0,spx
 2199  M                                                      mloop     ::ans34
 2199  M [1E5D] 1E5D:E603            [ 3]                     lda       ?remainder+1,x
 2199  M [1E5F] 1E5F:E710            [ 3]                     sta       ans34+1,spx
 2199  M                                                      mloop     ::ans34
 2199                                                         endm
 2200                                     
 2201                0182                 ?ModCycles          set       ?ModCycles+?Cycles+:cycles
 2202                                     
 2203                1E61                 ExitBoth@@
 2205    [1E61] 1E61:6D07            [ 4]                     tst       ?flags,x
 2206    [1E63] 1E63:2A06 (1E6B)     [ 3]                     bpl       SkipSign@@
 2207  M                                                      @lea      ans@@,sp
 2207  M                                                      mset      #
 2207  M [1E65] 1E65:95              [ 2]                     tsx
 2207  M [1E66] 1E66:AF0F            [ 2]                     !aix      #ans34+:tsx
 2207                                                         mexit
 2208    [1E68] 1E68:CD1D 95         [ 6]                     jsr       ?NegX
 2209                1E6B                 SkipSign@@
 2210                                                                   #Cycles ?NegxCycles+:cycles
 2212    [1E6B] 1E6B:A708            [ 2]                     ais       #?SF                ;de-allocate temporaries
 2213    [1E6D] 1E6D:98              [ 1]                     clc                           ;no error(s)
 2214                                     
 2215                0024                 ?Cycles             set       :cycles
 2216                01B2                 ?DivCycles          set       ?DivCycles+?Cycles
 2217                01A6                 ?ModCycles          set       ?ModCycles+?Cycles
 2218                                     
 2219                                     ;                   bra       ?RemoveAndReturn
 2220                                     
 2221                                     ;*******************************************************************************
 2222                                     ; Common exit removes lower 32-bit stack element and returns to caller
 2223                                     ;*******************************************************************************
 2224                                     
 2225                1E6E                 ?RemoveAndReturn
 2226                                     
 2228    [1E6E] 1E6E:9EFE 04         [ 5]                     ldhx      ?pc,sp              ;our return address moved up
 2229    [1E71] 1E71:9EFF 06         [ 5]                     sthx      ?pc+?WORD,sp        ;above word to remove
 2234                                     
 2240    [1E74] 1E74:8A88 86         [ 9]                     pull
 2241    [1E77] 1E77:A702            [ 2]                     ais       #?WORD              ;remove top-of-stack ?WORD
 2242    [1E79] 1E79:81              [ 6]                     rtc
 2243                                     
 2244                001B                 ?ReturnCycles       equ       :cycles
 2245                                     
 2246                                     ;*******************************************************************************
 2247                                     ; Purpose: Swaps the stacked order of N1 and N2
 2248                                     ; Input  : [TOS+?WORD] = Number2
 2249                                     ;        : [TOS] = Number1
 2250                                     ; Output : [TOS+?WORD] = Number1 -- TOS & [TOS+?WORD] in reverse order
 2251                                     ;        : [TOS] = Number2
 2252                                     ; Note(s): Does not alter stack size
 2253                                     
 2254                                                         #spauto   :ab
 2255                                     
 2256                1E7A                 ?Swap               proc
 2257    [1E7A] 1E7A:8789 8B         [ 6]                     push
 2258                                     
 2259    [1E7D] 1E7D:A602            [ 2]                     lda       #?WORD
 2260    [1E7F] 1E7F:87              [ 2]                     psha      bytes@@
 2261                                     
 2262    [1E80] 1E80:95              [ 2]                     tsx
 2263                                                                   #temp :cycles
 2264  M                                  Loop@@              @_swap_,  ?a,spx ?b,spx       ;swap A with B ...
 2264  M                                                      #push
 2264  M                                                      #spauto   :sp
 2264  M [1E81] 1E81:E606            [ 3]                     lda       ?a,spx
 2264  M [1E83] 1E83:87              [ 2]                     psha
 2264  M [1E84] 1E84:E608            [ 3]                     lda       ?b,spx
 2264  M [1E86] 1E86:E706            [ 3]                     sta       ?a,spx
 2264  M [1E88] 1E88:86              [ 3]                     pula
 2264  M [1E89] 1E89:E708            [ 3]                     sta       ?b,spx
 2264  M                                                      #pull
 2264                                                         endm
 2265                                     
 2266    [1E8B] 1E8B:AF01            [ 2]                     aix       #1                  ;point to next byte
 2267    [1E8D] 1E8D:9E6B 01F0 (1E81 [ 8]                     dbnz      bytes@@,sp,Loop@@   ;repeat for all bytes
 2268                                                                   #temp :cycles*?WORD+:temp
 2269    [1E91] 1E91:86              [ 3]                     pula
 2270                                     
 2271    [1E92] 1E92:8A88 86         [ 9]                     pull
 2272    [1E95] 1E95:81              [ 6]                     rtc
 2273                                     
 2274                0054                 ?SwapCycles         set       :cycles+:temp
 2275                                     
 2276                                     ;*******************************************************************************
 2277                                     ; Purpose: Get the absolute value of the top-of-stack number
 2278                                     ; Input  : [TOS] = Number
 2279                                     ; Output : [TOS] = Abs(Number)
 2280                                     ; Note(s): Does not alter stack size
 2281                                     
 2282                                                         #spauto   :ab
 2283                                     
 2284                1E96                 ?Abs                proc
 2285    [1E96] 1E96:9E6D 03         [ 5]                     tst       ?a,sp
 2286    [1E99] 1E99:2AFA (1E95)     [ 3]                     bpl       Done@@
 2287                                     ;                   bra       ?Negate
 2288                                     
 2289                1E95                 Done@@              equ       :AnRTC
 2290                                     
 2291                0008                 ?AbsCycles          equ       :cycles
 2292                                     
 2293                                     ;*******************************************************************************
 2294                                     ; Purpose: Negate the top-of-stack number
 2295                                     ; Input  : [TOS] = Number
 2296                                     ; Output : [TOS] = -Number
 2297                                     ; Note(s): Does not alter stack size
 2298                                     
 2299                                                         #spauto   :ab
 2300                                     
 2301                1E9B                 ?Negate             proc
 2302    [1E9B] 1E9B:898B            [ 4]                     pshhx
 2304  M                                                      @lea      ?a,sp
 2304  M                                                      mset      #
 2304  M [1E9D] 1E9D:95              [ 2]                     tsx
 2304  M [1E9E] 1E9E:AF04            [ 2]                     !aix      #?a+:tsx
 2304                                                         mexit
 2305    [1EA0] 1EA0:CD1D 95         [ 6]                     jsr       ?NegX
 2306                                                                   #Cycles ?NegxCycles+:cycles
 2311    [1EA3] 1EA3:8A88            [ 6]                     pulhx
 2312    [1EA5] 1EA5:81              [ 6]                     rtc
 2313                                     
 2314                002A                 ?NegateCycles       equ       :cycles
 2315                0032                 ?AbsCycles          set       ?NegateCycles+?AbsCycles
 2316                                     
 2317                                     ;*******************************************************************************
 2318                                     ; Purpose: Create a new top-of-stack and load to it the number pointed to by HX
 2319                                     ; Input  : HX -> [Variable with] Number
 2320                                     ; Output : [TOS] = Number
 2321                                     ; Note(s): This operation makes it easier to load a number to the stack.
 2322                                     ;        : Hint: To make a copy of the TOS, do:
 2323                                     ;        :          tsx
 2324                                     ;        :          call      StackLoad32
 2325                                     ;        : (Stack is expanded)
 2326                                     
 2327                                                         #spauto   :ab
 2328                                     
 2329                1EA6                 ?Load               proc
 2330                FFFFFFFF             old_rts@@           equ       ::,:ab
 2331    [1EA6] 1EA6:A7FE            [ 2]                     ais       #-?WORD             ;allocate new TOS memory
 2332                                                         #temp     ::
 2333                FFFFFFFD             new_rts@@           next      :temp,:ab
 2334                FFFFFFFF             tos_num@@           next      :temp,?WORD
 2335                0001                                     next      :temp,-:ab          ;-:AB as old_rts@@ will be gone
 2336                                                         #ais      :temp
 2337                                     
 2338    [1EA8] 1EA8:87              [ 2]                     psha
 2339  M                                                      @mova.s   old_rts@@,sp new_rts@@,sp  ;move RTS/RTC after new memory
 2339  M                                                      mset      #' '
 2339  M                                                      mreq      1,2:Source Destination
 2339  M                                                      @@_samesize_ old_rts38,sp new_rts@@,sp
 2339  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2339  M                                                      mset      0
 2339  M                                                      mdo
 2339  M                                                      mswap     1,1
 2339  M                                                      @@_nosize_ old_rts38,sp
 2339  M                                                      mset      #
 2339  M                                                      mset      0,mstop [_samesize_] No size (old_rts38,sp)
 2339  M                                                      endm
 2339  M                                                      mset      0,old_rts38,sp
 2339  M                                                      mloop     :n
 2339  M                                                      mswap     1,2
 2339  M                                                      @@_nosize_ new_rts@@,sp
 2339  M                                                      mset      #
 2339  M                                                      mset      0,mstop [_samesize_] No size (new_rts38,sp)
 2339  M                                                      endm
 2339  M                                                      mloop     :n
 2339  M                                                      endm
 2339  M                                                      mset      0
 2339  M                                                      mdo
 2339  M [1EA9] 1EA9:9EE6 04         [ 4]                     lda       old_rts38+0,sp
 2339  M [1EAC] 1EAC:9EE7 02         [ 4]                     sta       new_rts@@+0,sp
 2339  M                                                      mloop     ::new_rts@@
 2339  M [1EAF] 1EAF:9EE6 05         [ 4]                     lda       old_rts38+1,sp
 2339  M [1EB2] 1EB2:9EE7 03         [ 4]                     sta       new_rts@@+1,sp
 2339  M                                                      mloop     ::new_rts@@
 2339                                                         endm
 2340  M                                                      @mova.s   ,x tos_num@@,sp
 2340  M                                                      mset      #' '
 2340  M                                                      mreq      1,2:Source Destination
 2340  M                                                      @@_samesize_ ,x tos_num38,sp
 2340  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2340  M                                                      mset      0
 2340  M                                                      mdo
 2340  M                                                      mswap     1,1
 2340  M                                                      mloop     :n
 2340  M                                                      mswap     1,2
 2340  M                                                      @@_nosize_ tos_num38,sp
 2340  M                                                      mset      #
 2340  M                                                      mset      0,mstop [_samesize_] No size (tos_num38,sp)
 2340  M                                                      endm
 2340  M                                                      mset      0,tos_num38,sp
 2340  M                                                      mloop     :n
 2340  M                                                      endm
 2340  M                                                      mset      0
 2340  M                                                      mdo
 2340  M [1EB5] 1EB5:F6              [ 3]                     lda       +0,x
 2340  M [1EB6] 1EB6:9EE7 04         [ 4]                     sta       tos_num38+0,sp
 2340  M                                                      mloop     ::tos_num38
 2340  M [1EB9] 1EB9:E601            [ 3]                     lda       +1,x
 2340  M [1EBB] 1EBB:9EE7 05         [ 4]                     sta       tos_num38+1,sp
 2340  M                                                      mloop     ::tos_num38
 2340                                                         endm
 2341    [1EBE] 1EBE:86              [ 3]                     pula
 2342    [1EBF] 1EBF:81              [ 6]                     rtc
 2343                                     
 2344                002B                 ?LoadCycles         equ       :cycles
 2345                                     
 2346                                     ;*******************************************************************************
 2347                                     ; Purpose: Unload the top-of-stack number into a variable pointed to by HX
 2348                                     ; Input  : [TOS] = Number
 2349                                     ;        : HX -> Some 32-bit variable
 2350                                     ; Output : Variable pointed to by HX receives TOS number
 2351                                     ; Note(s): This operation makes it easier to unload a number from the stack.
 2352                                     ;        : Use:
 2353                                     ;        :          ldhx      #MyVar
 2354                                     ;        :          call      StackSave32
 2355                                     ;        : (Stack is reduced)
 2356                                     
 2357                                                         #spauto   :ab
 2358                                     
 2359                1EC0                 ?Save               proc
 2360                                                         #temp     ::
 2361                FFFFFFFF             old_rts@@           next      :temp,:ab
 2362                0001                 tos_num@@           next      :temp,?WORD
 2363                0003                                     next      :temp,-:ab          ;-:AB as old_rts@@ will be gone
 2364                0001                 new_rts@@           next      :temp,:ab
 2365                                     
 2366                0000                 var@@               equ       0,?WORD
 2367                                     
 2368    [1EC0] 1EC0:8789 8B         [ 6]                     push
 2369  M                                                      @mova.s   tos_num@@,sp var@@,x
 2369  M                                                      mset      #' '
 2369  M                                                      mreq      1,2:Source Destination
 2369  M                                                      @@_samesize_ tos_num39,sp var@@,x
 2369  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2369  M                                                      mset      0
 2369  M                                                      mdo
 2369  M                                                      mswap     1,1
 2369  M                                                      @@_nosize_ tos_num39,sp
 2369  M                                                      mset      #
 2369  M                                                      mset      0,mstop [_samesize_] No size (tos_num39,sp)
 2369  M                                                      endm
 2369  M                                                      mset      0,tos_num39,sp
 2369  M                                                      mloop     :n
 2369  M                                                      mswap     1,2
 2369  M                                                      @@_nosize_ var@@,x
 2369  M                                                      mset      #
 2369  M                                                      mset      0,mstop [_samesize_] No size (var39,x)
 2369  M                                                      endm
 2369  M                                                      mloop     :n
 2369  M                                                      endm
 2369  M                                                      mset      0
 2369  M                                                      mdo
 2369  M [1EC3] 1EC3:9EE6 06         [ 4]                     lda       tos_num39+0,sp
 2369  M [1EC6] 1EC6:F7              [ 2]                     sta       var@@+0,x
 2369  M                                                      mloop     ::var@@
 2369  M [1EC7] 1EC7:9EE6 07         [ 4]                     lda       tos_num39+1,sp
 2369  M [1ECA] 1ECA:E701            [ 3]                     sta       var@@+1,x
 2369  M                                                      mloop     ::var@@
 2369                                                         endm
 2370                                     
 2371    [1ECC] 1ECC:95              [ 2]                     tsx
 2372  M                                                      @mova.s   old_rts@@,spx new_rts@@,spx  ;move RTS/RTC before old memory
 2372  M                                                      mset      #' '
 2372  M                                                      mreq      1,2:Source Destination
 2372  M                                                      @@_samesize_ old_rts39,spx new_rts@@,spx
 2372  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2372  M                                                      mset      0
 2372  M                                                      mdo
 2372  M                                                      mswap     1,1
 2372  M                                                      @@_nosize_ old_rts39,spx
 2372  M                                                      mset      #
 2372  M                                                      mset      0,mstop [_samesize_] No size (old_rts39,spx)
 2372  M                                                      endm
 2372  M                                                      mset      0,old_rts39,spx
 2372  M                                                      mloop     :n
 2372  M                                                      mswap     1,2
 2372  M                                                      @@_nosize_ new_rts@@,spx
 2372  M                                                      mset      #
 2372  M                                                      mset      0,mstop [_samesize_] No size (new_rts39,spx)
 2372  M                                                      endm
 2372  M                                                      mloop     :n
 2372  M                                                      endm
 2372  M                                                      mset      0
 2372  M                                                      mdo
 2372  M [1ECD] 1ECD:E603            [ 3]                     lda       old_rts39+0,spx
 2372  M [1ECF] 1ECF:E705            [ 3]                     sta       new_rts@@+0,spx
 2372  M                                                      mloop     ::new_rts@@
 2372  M [1ED1] 1ED1:E604            [ 3]                     lda       old_rts39+1,spx
 2372  M [1ED3] 1ED3:E706            [ 3]                     sta       new_rts@@+1,spx
 2372  M                                                      mloop     ::new_rts@@
 2372                                                         endm
 2373    [1ED5] 1ED5:8A88 86         [ 9]                     pull
 2374                                     
 2375    [1ED8] 1ED8:A702            [ 2]                     ais       #?WORD              ;de-allocate TOS memory
 2376    [1EDA] 1EDA:81              [ 6]                     rtc
 2377                                     
 2378                0032                 ?SaveCycles         equ       :cycles
 2379                                     
 2380                                     ;*******************************************************************************
 2381                                     ; Purpose: Adjust TOS old size to new
 2382                                     ; Input  : H = old (current) byte size
 2383                                     ;        : X = new byte size
 2384                                     ;        : CCR[C] = 0 -- always positive number
 2385                                     ;        : CCR[C] = 1 -- sign extend
 2386                                     ; Output : None
 2387                                     ; Note(s): RegA deliberately not used for parameter passing (for consistency)
 2388                                     ;        : Macro destroys RegHX (as we must not use PSHHX/PULHX around call)
 2389                                     
 2523                                     
 2524                                     ;*******************************************************************************
 2525                                     ; Purpose: Convert 32-bit to ASCIZ string
 2526                                     ; Input  : Stack: 32-bit number
 2527                                     ;        : HX -> Output buffer with enough space to keep the ASCIZ string result
 2528                                     ; Output : None
 2529                                     ; Note(s): Use:
 2530                                     ;        :          ldhx      #Buffer
 2531                                     ;        :          call      Stack32ToASCIZ
 2532                                     
 2533                                                         #spauto   :ab                 ;account for RTS/RTC
 2534                                     
 2535                1EDB                 ?ToStr              proc
 2536    [1EDB] 1EDB:8789 8B         [ 6]                     push
 2537                                     
 2538                                                         #psp                          ;mark beginning of temporaries
 2539                                     
 2540    [1EDE] 1EDE:898B            [ 4]                     pshhx     .buffer@@           ;working copy of pointer to buffer
 2541    [1EE0] 1EE0:7F              [ 4]                     clr       ,x                  ;make it an ASCIZ string
 2542                                     
 2543  M                                                      @lea      1,sp                ;HX -> TOS number of caller
 2543  M                                                      mset      #
 2543  M [1EE1] 1EE1:95              [ 2]                     tsx
 2543  M [1EE2] 1EE2:AF07            [ 2]                     !aix      #1+:tsx
 2543                                                         mexit
 2544    [1EE4] 1EE4:CD1E A6         [ 6]                     call      ?Load               ;load a working copy on stack
 2545                                     
 2546                                                         #spadd    ?WORD               ;stack has grown by a ?WORD
 2547                FFFFFFF8             number@@            equ       ::,?WORD
 2549    [1EE7] 1EE7:9E6D 01         [ 5]                     tst       number@@,sp
 2550    [1EEA] 1EEA:2A0F (1EFB)     [ 3]                     bpl       ToStrLoop@@
 2551    [1EEC] 1EEC:CD1E 9B         [ 6]                     call      ?Negate
 2553    [1EEF] 1EEF:9EFE 03         [ 5]                     ldhx      .buffer@@,sp
 2559    [1EF2] 1EF2:A62D            [ 2]                     lda       #'-'                ;a 'minus' sign
 2560    [1EF4] 1EF4:F7              [ 2]                     sta       ,x                  ; is saved first
 2561                                     
 2562    [1EF5] 1EF5:AF01            [ 2]                     aix       #1                  ;HX -> past minus sign
 2563    [1EF7] 1EF7:7F              [ 4]                     clr       ,x                  ;make it an ASCIZ string
 2565    [1EF8] 1EF8:9EFF 03         [ 5]                     sthx      .buffer@@,sp        ;update pointer past sign
 2571                                     ;                   bra       ToStrLoop@@
 2573                                     ;===============================================================================
 2574                                     
 2575    [1EFB] 1EFB:4500 0A         [ 3] ToStrLoop@@         ldhx      #10                 ;H = 0 (always), X = divisor
 2576  M                                                      @div.s    number@@,sp
 2576  M                                                      mset      #
 2576  M                                                      mreq      1
 2576  M                                                      @@_not_x_ number40,sp
 2576  M                                                      mset      #
 2576  M                                                      endm
 2576  M                                                      @@_nosize_ number40,sp
 2576  M                                                      mset      #
 2576  M                                                      mset      0,mstop [div.s] No size (number40,sp)
 2576  M                                                      endm
 2576  M                                                      #temp     1
 2576  M                                                      #temp     2
 2576  M [1EFE] 1EFE:86              [ 3]                     pula
 2576  M [1EFF] 1EFF:52              [ 6]                     div
 2576  M [1F00] 1F00:87              [ 2]                     psha
 2576  M                                                      mdo       2
 2576  M [1F01] 1F01:9EE6 02         [ 4]                     lda       number40+1,sp
 2576  M [1F04] 1F04:52              [ 6]                     div
 2576  M [1F05] 1F05:9EE7 02         [ 4]                     sta       number40+1,sp
 2576  M                                                      mloop     ::number40
 2576                                                         endm
 2577                                     
 2578    [1F08] 1F08:8B86            [ 5]                     tha                           ;A = remainder
 2579    [1F0A] 1F0A:AB30            [ 2]                     add       #'0'                ;A = ASCII remainder
 2581    [1F0C] 1F0C:9EFE 03         [ 5]                     ldhx      .buffer@@,sp
 2587  M                                                      @StringInsertChar
 2587  M [1F0F] 1F0F:CD18 3A         [ 6]                     call      StringInsertChar                 ;HX and A pre-loaded correctly
 2587                                                         mexit
 2588                                     
 2589    [1F12] 1F12:95              [ 2]                     tsx
 2590                                     
 2591  M                                                      @zero?.s  number@@,spx
 2591  M                                                      mset      #
 2591  M                                                      mreq      1
 2591  M                                                      @@_nosize_ number40,spx
 2591  M                                                      mset      #
 2591  M                                                      mset      0,mstop [zero?.s] No size (number40,spx)
 2591  M                                                      endm
 2591  M                                                      mdo
 2591  M [1F13] 1F13:F6              [ 3]                     lda       number40+0,spx
 2591  M                                                      mloop     ::number40
 2591  M [1F14] 1F14:EA01            [ 3]                     ora       number40+1,spx
 2591  M                                                      mloop     ::number40
 2591                                                         endm
 2592    [1F16] 1F16:26E3 (1EFB)     [ 3]                     bne       ToStrLoop@@
 2593                                     
 2594    [1F18] 1F18:A704            [ 2]                     ais       #:psp