File stakmath.asm * By ASM8 v9.97 Win32 [Monday, December 21, 2020  1:32 pm]

    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) 2020 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                                     Page                macro     PageNumber
   22                                                         mreq      1:PageNumber
   23                                               #if ~#1~ > 7
   24                                                         merror    PageNumber (~1~) must be in range 0..7
   25                                               #endif
   26                                               #ifmmu
   27                                               #if ~#1~ >= 4
   28                                                         #SEG~1~
   29                                               #else
   30                                                         #ROM
   31                                               #endif
   32                                               #endif
   33                                                         endm
   34
   35                                     ;-------------------------------------------------------------------------------
   36
   37                                     ?                   macro     Bits,Page
   38                                                         @@Page    ~2~
   39                                                         #Uses     lib/stkmth{~1~}.sub
   40                                                         endm
   41
   42                                     ;*******************************************************************************
   43                                                         #ROM
   44                                     ;*******************************************************************************
   45
   46                182C                 SIGNED
   47                                                         #MapOff
   48  M                                                      @?        32,4
   48  M                                                      @@Page    4
   48  M                                                      mreq      1:PageNumber
   48  M                                                      endm
   48                                                         #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) 2020 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) 2020 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                                     ;*           : 17.04.03 v8.55 Optimized 24-bit multiply [-2 bytes]
  336                                     ;*           :                Optimized 32-bit multiply [-7 bytes]
  337                                     ;*           : 18.10.23       Suppressed possible warning from JEQ in ?DivStart
  338                                     ;*           : 19.03.04       Added warning in _DoStr macro when using StrNN
  339                                     ;*           :                when NN is different from MATHSIZE and no explicit
  340                                     ;*           :                variable is given
  341                                     ;*           : 19.10.04 v8.56 Minor HC08 mode optimization in SIGNED ?ToStr [-1 byte]
  342                                     ;*           : 20.02.12 v8.57 Replaced #Message with @Msg to silence debugging messages
  343                                     ;*******************************************************************************
  344
  345                                     ;Synopsis (replace * with 16, 24, 32, 40, 48, 56, 64 for corresponding bit version):
  346                                     ;
  347                                     ;Subroutines    Action
  348                                     ;-------------- ----------------------------
  349                                     ;StackAdd*      - TOS := TOS + [TOS+1]       (signed or unsigned) [TOS+1] removed
  350                                     ;StackSub*      - TOS := TOS - [TOS+1]       (signed or unsigned) [TOS+1] removed
  351                                     ;StackMul*      - TOS := TOS * [TOS+1]       (signed or unsigned) [TOS+1] removed
  352                                     ;StackDiv*      - TOS := TOS / [TOS+1]       (signed if SIGNED)   [TOS+1] removed
  353                                     ;StackMod*      - TOS := TOS \ [TOS+1]       (signed if SIGNED)   [TOS+1] removed
  354                                     ;StackAnd*      - TOS := TOS & [TOS+1]       (signed or unsigned) [TOS+1] removed
  355                                     ;StackOr*       - TOS := TOS | [TOS+1]       (signed or unsigned) [TOS+1] removed
  356                                     ;StackXor*      - TOS := TOS ^ [TOS+1]       (signed or unsigned) [TOS+1] removed
  357                                     ;StackShl*      - TOS := TOS < [TOS+1]       (signed or unsigned) [TOS+1] removed
  358                                     ;StackShr*      - TOS := TOS > [TOS+1]       (signed if SIGNED)   [TOS+1] removed
  359                                     ;StackSwap*     - TOS swapped with [TOS+1]   (signed or unsigned)
  360                                     ;StackAbs*      - TOS := ABS(TOS)            (signed)
  361                                     ;StackNegate*   - TOS := -TOS                (signed)
  362                                     ;StackLoad*     - Load const/variable to TOS (signed or unsigned) TOS created
  363                                     ;StackSave*     - Save TOS into variable     (signed or unsigned) TOS removed
  364                                     ;ResizeTOS      - Adjust TOS old size to new (signed or unsigned) TOS resized
  365                                     ;Stack*ToASCIZ  - Convert TOS to ASCIZ str   (signed if SIGNED)
  366                                     ;
  367                                     ;Macros             Purpose             Parameters ([...] means optional part)
  368                                     ;------------------ ------------------- ----------------------------------------
  369                                     ;Load*              Stack const or var  #Number | Variable
  370                                     ;Save*              Unstack a variable  Variable
  371                                     ;Copy*              Load* & Save*       #Number | Variable,Variable
  372                                     ;ResizeTOS          Resize TOS          #FromByteSize,#ToByteSize
  373                                     ;
  374                                     ;Add*               Addition            [Addend[,Adder[,Sum]]]
  375                                     ;Sub*               Subtraction         [Minuend[,Subtrahend[,Difference]]]
  376                                     ;Mul*               Multiplication      [Multiplicand[,Multiplier[,Product]]]
  377                                     ;Div*               Unsigned division   [Dividend[,Divisor[,Quotient]]]
  378                                     ;Mod*               Unsigned modulo     [Dividend[,Divisor[,Remainder]]]
  379                                     ;Abs*               Absolute value      [SourceVariable][,DestinationVariable]
  380                                     ;Neg*               Negation            [SourceVariable][,DestinationVariable]
  381                                     ;Swap*              Swap TOS numbers
  382                                     ;Str*               Number to ASCIZ     [Variable],[ResultString]
  383                                     ;AddDecimalPoint    ... to ASCIZ number [[#]DecimalPlaces[,[#]ASCIZ_String]]
  384
  411
  412                0020                 MATHSIZE            def       32                  ;default wordsize is 32-bit
  413
  417
  418                                     ?                   macro     BitSize
  419                                     #if MATHSIZE = ~1~
  420                                     ?WORD               equ       ~1~/8
  421                                     _STKMTH{MATHSIZE}_                                ;;specific version included
  422                                     _STAKMATH_          def       *                   ;;any version included
  423                                     #endif
  424                                                         endm
  425
  426  M                                                      @?        16                  ;16-bit quantity (on request)
  426                                                         endm
  427  M                                                      @?        24                  ;24-bit quantity (on request)
  427                                                         endm
  428  M                                                      @?        32                  ;32-bit quantity (default)
  428  M             0004                 ?WORD               equ       32/8
  428  M             182C                 _STKMTH32_
  428  M             182C                 _STAKMATH_          def       *
  428                                                         endm
  429  M                                                      @?        40                  ;40-bit quantity (on request)
  429                                                         endm
  430  M                                                      @?        48                  ;48-bit quantity (on request)
  430                                                         endm
  431  M                                                      @?        56                  ;56-bit quantity (on request)
  431                                                         endm
  432  M                                                      @?        64                  ;64-bit quantity (on request)
  432                                                         endm
  433
  439                                                         #Message  MATHSIZE = {MATHSIZE}-bit version
  441                                                         #Message  Signed routines enabled
  443                                     ;*******************************************************************************
  444                                     ; Macros to make operations as simple as with a high-level language
  445                                     ; In operations that require two operands and a result, if only one operand is
  446                                     ; provided, then the operation is done completely on stack (no other variables
  447                                     ; used).  For example, @Add32 A,B,SUM adds A to B and places result in SUM,
  448                                     ; while @Add32 A adds the current stack top to A and leaves result on stack.
  449                                     ; You can use @Load* and @Save* to load the initial value, and store the final
  450                                     ; result, respectively.  (Replace * with 16, 24, 32, 40, 48, 56, or 64)
  451                                     ;*******************************************************************************
  452
  501                                     ;===============================================================================
  550                                     ;===============================================================================
  552
  553                                     Load32              macro     #Number|Variable    ;load constant or variable
  554                                                         @_DoLoad  ~0.{:0-1}~\,~@~
  555                                                         endm
  556
  557                                     Save32              macro     Address
  558                                                         @_DoSave  32\,~@~
  559                                                         endm
  560
  561                                     Copy32              macro     #Constant|Variable,ToAddress
  562                                                         mreq      1,2:#Constant|Variable,ToAddress
  563                                                         @@Load32  ~1~
  564                                                         @Save32   ~2~
  565                                                         endm
  566
  567                                     Swap32              macro
  568                                                         @_DoSwap  32
  569                                                         endm
  570
  571                                     Add32               macro     Addend,Adder,Sum
  572                                                         @_DoMath  ~0~\,32\,~1~\,~2~\,~3~
  573                                                         endm
  574
  575                                     Sub32               macro     Minuend,Subtrahend,Difference
  576                                                         @_DoMath  ~0~\,32\,~1~\,~2~\,~3~
  577                                                         endm
  578
  579                                     Mul32               macro     Multiplicand,Multiplier,Product
  580                                                         @_DoMath  ~0~\,32\,~1~\,~2~\,~3~
  581                                                         endm
  582
  583                                     Div32               macro     Dividend,Divisor,Quotient
  584                                                         @_DoMath  ~0~\,32\,~1~\,~2~\,~3~
  585                                                         endm
  586
  587                                     Mod32               macro     Dividend,Divisor,Remainder
  588                                                         @_DoMath  ~0~\,32\,~1~\,~2~\,~3~
  589                                                         endm
  590
  591                                     Abs32               macro     Source[,Destination]
  592                                                         @_DoAbs   32\,~1~\,~2~
  593                                                         endm
  594
  595                                     Neg32               macro     Source[,Destination]
  596                                                         @_DoNeg   32\,~1~\,~2~
  597                                                         endm
  599                                     ;===============================================================================
  648                                     ;===============================================================================
  697                                     ;===============================================================================
  746                                     ;===============================================================================
  795
  796                                     ;*******************************************************************************
  797                                     ; Common macro(s) for all operations defined above (not to be called directly)
  798                                     ;*******************************************************************************
  799
  801                                     _signed_            macro
  802                                               #ifndef SIGNED
  803                                                         #Warning  SIGNED \@~mfilename~\@ expected
  804                                               #endif
  805                                                         endm
  807                                     ;-------------------------------------------------------------------------------
  867                                     ;-------------------------------------------------------------------------------
  890                                     ;-------------------------------------------------------------------------------
  898                                     ;-------------------------------------------------------------------------------
  916                                     ;===============================================================================
  933                                     ;-------------------------------------------------------------------------------
 1158                                     ;-------------------------------------------------------------------------------
 1160                                     _?sei_              macro
 1161                                               #ifdef _NOCLI_
 1162                                                         mexit
 1163                                               #endif
 1164                                               #ifndef _MTOS_
 1165                                                         mexit
 1166                                               #endif
 1167                                                         mset      #
 1168                                               #ifnb ~','2~ = sp
 1169                                                         mexit
 1170                                               #endif
 1171                                               #ifnb ~','2~ = spx
 1172                                                         mexit
 1173                                               #endif
 1174                                               #ifnb ~','2~ = psp
 1175                                                         mexit
 1176                                               #endif
 1177                                               #ifdef ~1,~
 1178                                                 #if ::~1,~ < 2
 1179                                                         mexit
 1180                                                 #endif
 1181                                               #endif
 1182                                                         sei
 1183                                                         endm
 1185                                     ;-------------------------------------------------------------------------------
 1187                                     _?cli_              macro
 1188                                               #ifdef _NOCLI_
 1189                                                         mexit
 1190                                               #endif
 1191                                               #ifndef _MTOS_
 1192                                                         mexit
 1193                                               #endif
 1194                                                         mset      #
 1195                                               #ifnb ~','2~ = sp
 1196                                                         mexit
 1197                                               #endif
 1198                                               #ifnb ~','2~ = spx
 1199                                                         mexit
 1200                                               #endif
 1201                                               #ifnb ~','2~ = psp
 1202                                                         mexit
 1203                                               #endif
 1204                                               #ifdef ~1,~
 1205                                                 #if ::~1,~ < 2
 1206                                                         mexit
 1207                                                 #endif
 1208                                               #endif
 1209                                                         cli
 1210                                                         endm
 1212                                     ;-------------------------------------------------------------------------------
 1214                                     _DoLoad             macro     BitSize[,Variable]  ;if no Variable, wherever HX points
 1215                                               #if :macronest = 1
 1216                                                         #Warning  Macro NOT to be called directly
 1217                                               #endif
 1218                                                         mreq      1:BitSize[,Variable]
 1219                                                         #temp     ~1~/8               ;;bytesize now in :temp
 1220                                                         mdel      1                   ;;get rid of bitsize parm
 1221                                                         mset      #                   ;;unite all parms into one
 1222                                                         mtrim     1
 1223                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 1224                                                         mset      9                   ;;assume signed (when SIGNED)
 1225                                               #ifparm ~1.1.1~~1.{:1}~ = []
 1226                                                         mset      9,unsigned
 1227                                                         mset      1,~1.2.{:1-2}~
 1228                                               #endif
 1229                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 1230                                                         @@_not_x_ ~1~                 ;;X-mode not allowed
 1231                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 1232                                               #ifnum ~1~
 1233                                                         mset      1,#~1~              ;;numerics use immediate mode
 1234                                               #endif
 1235                                               #ifb ~,1~
 1236                                                 #ifdef ~#1~
 1237                                                   #ifz ::~#1~
 1238                                                         mset      1,#~#1~             ;;named constants use immediate mode
 1239                                                   #endif
 1240                                                 #endif
 1241                                               #endif
 1242                                               #ifnb ~#~                               ;;process immediate mode
 1243                                                         @@Msg     Load{:temp*8} ~1~
 1244                                                         mset      1,~#1~
 1245                                                         mset      0                   ;;use as flag for CLRH usage
 1246                                                         mdo
 1247                                                 #ifz ~#1~>{:mloop-1*8}&$FF
 1248                                                   #ifz :text
 1249                                                         clrh
 1250                                                         mset      0,clrh              ;;flag CLRH was used
 1251                                                   #endif
 1252                                                         pshh
 1253                                                 #else
 1254                                                         ldx       #~#1~>{:mloop-1*8}&$FF
 1255                                                         pshx
 1256                                                 #endif
 1257                                                         mloop     :temp
 1258                                                         mexit
 1259                                               #endif
 1260                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 1261                                               #ifnb ~1,~
 1262                                                 #ifb ~1.1.1~ = .                      ;;except for pointers
 1263                                                   #ifnz ::~1,~                        ;;and constants
 1264                                                     #if ::~1,~ <> :temp               ;;different-size variables
 1265                                                         @@_?sei_  ~1~
 1266                                                         @@pushv   ~1~                 ;;are pushed and then resized
 1267                                                         @@_?cli_  ~1~
 1268                                                         @ResizeTOS #{::~1,~}\,#{:temp}\,\,~9~
 1269                                                         mexit
 1270                                                     #endif
 1271                                                   #endif
 1272                                                 #endif
 1273                                               #endif
 1274                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 1275                                               #ifndef ~1,~
 1276                                                         #Warning  Loading forward \@~1,~\@ as var
 1277                                               #endif
 1278                                                         @@Msg     Load{:temp*8} ~1~
 1279                                                         @@lea     ~1~                 ;;default case
 1280                                                         @@_?sei_  ~1~
 1281                                                         call      StackLoad{:temp*8}  ;;load as is
 1282                                                         @@_?cli_  ~1~
 1283                                               #ifspauto
 1284                                                         #spadd    :temp
 1285                                               #endif
 1286                                                         endm
 1288                                     ;-------------------------------------------------------------------------------
 1290                                     _DoSave             macro     BitSize[,Variable]  ;if no Variable, wherever HX points
 1291                                               #if :macronest = 1
 1292                                                         #Warning  Macro NOT to be called directly
 1293                                               #endif
 1294                                                         mreq      1:BitSize[,Variable]
 1295                                                         mset      2,~@@~
 1296                                                         mtrim     2
 1297                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 1298                                                         mset      9                   ;;assume signed (when SIGNED)
 1299                                               #ifparm ~2.1.1~~2.{:1}~ = []
 1300                                                         mset      9,unsigned
 1301                                                         mset      2,~2.2.{:2-2}~
 1302                                               #endif
 1303                                     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 1304                                                         @@_not_x_ ~2~
 1305                                               #ifnb ~2,~
 1306                                                 #ifb ~2.1.1~ = .                      ;;except for pointers
 1307                                                   #ifnz ::~2,~                        ;;and constants
 1308                                                     #if ::~2,~ <> ~1~/8               ;;different-size variables
 1309                                                         @@ResizeTOS #{~1~/8}\,#{::~2,~}\,\,~9~
 1310                                                         @@_?sei_  ~2~
 1311                                                         @@pullv   ~2~                 ;;are resized and then pulled
 1312                                                         @_?cli_   ~2~
 1313                                                         mexit
 1314                                                     #endif
 1315                                                   #endif
 1316                                                 #endif
 1317                                               #endif
 1318                                                         @@Msg     Save~1~ ~2~
 1319                                                         @@lea     ~2~                 ;;default case
 1320                                                         @@_?sei_  ~2~
 1321                                                         call      StackSave~1~        ;;save as is
 1322                                                         @@_?cli_  ~2~
 1323                                               #ifspauto
 1324                                                         #spadd    -~1~/8
 1325                                               #endif
 1326                                                         endm
 1328                                     ;-------------------------------------------------------------------------------
 1330                                     _DoSwap             macro     BitSize
 1331                                               #if :macronest = 1
 1332                                                         #Warning  Macro NOT to be called directly
 1333                                               #endif
 1334                                                         call      StackSwap~1~
 1335                                                         endm
 1337                                     ;-------------------------------------------------------------------------------
 1339                                     _DoOperation        macro     Operation[,BitSize]
 1340                                               #if :macronest = 1
 1341                                                         #Warning  Macro NOT to be called directly
 1342                                               #endif
 1343                                                         mdef      2,~1.{:1-1}~
 1344                                                         @@Msg     ~1~
 1345                                                         call      Stack~1~
 1346                                               #ifspauto
 1347                                                         #spadd    -~2~/8
 1348                                               #endif
 1349                                                         endm
 1351                                     ;-------------------------------------------------------------------------------
 1353                                     _DoMath             macro     Operation,BitSize[,Operand1[,Operand2[,Answer]]]
 1354                                               #if :macronest = 1
 1355                                                         #Warning  Macro NOT to be called directly
 1356                                               #endif
 1357                                               #ifnoparm ~3~
 1358                                                         @_DoOperation ~1~
 1359                                                         mexit
 1360                                               #endif
 1361                                               #ifnoparm ~4~
 1362                                                         @@Load~2~ ~3~
 1363                                                   #ifnoparm ~1~ = Add~2~
 1364                                                   #ifnoparm ~1~ = Mul~2~
 1365                                               ;except for Add and Mul which are commutative, we must swap the stack
 1366                                                         call      StackSwap~2~        ;one parm is Operand2 (eg, Div32 XXX does TOS/XXX)
 1367                                                   #endif
 1368                                                   #endif
 1369                                                         @_DoOperation ~1~
 1370                                                         mexit
 1371                                               #endif
 1372                                                         @@Load~2~ ~4~
 1373                                                         @@Load~2~ ~3~
 1374                                                         @@_DoOperation ~1~
 1375                                               #ifparm ~5~
 1376                                                         @Save~2~  ~5~
 1377                                               #endif
 1378                                                         endm
 1380                                     ;-------------------------------------------------------------------------------
 1382                                     _DoAbs              macro     BitSize[,Source][,Destination]
 1383                                               #if :macronest = 1
 1384                                                         #Warning  Macro NOT to be called directly
 1385                                               #endif
 1386                                                         @@Msg     Abs~1~ ~@@~
 1387                                                         @@_FindStkMth_ ~1~
 1388                                                         mset      1,{:mexit}
 1389                                               #ifparm ~2~
 1390                                                         @@Load~1~ ~2~
 1391                                               #endif
 1392                                                         call      StackAbs~1~
 1393                                               #ifparm ~2~~3~
 1394                                                         @Save~1~  ~3~
 1395                                               #endif
 1396                                                         endm
 1398                                     ;-------------------------------------------------------------------------------
 1400                                     _DoNeg              macro     BitSize[,Source][,Destination]
 1401                                               #if :macronest = 1
 1402                                                         #Warning  Macro NOT to be called directly
 1403                                               #endif
 1404                                                         @@Msg     Neg~1~ ~@@~
 1405                                                         @@_FindStkMth_ ~1~
 1406                                                         mset      1,{:mexit}
 1407                                               #ifparm ~2~
 1408                                                         @@Load~1~ ~2~
 1409                                               #endif
 1410                                                         call      StackNegate~1~
 1411                                               #ifparm ~2~~3~
 1412                                                         @Save~1~  ~3~
 1413                                               #endif
 1414                                                         endm
 1416                                     ;-------------------------------------------------------------------------------
 1418                                     _DoStr              macro     BitSize,[Variable],[ResultString]
 1419                                               #if :macronest = 1
 1420                                                         #Warning  Macro NOT to be called directly
 1421                                               #endif
 1422                                                         @@_FindStkMth_ ~1~
 1423                                               #ifb ~2~
 1424                                                 #if ~1~ <> :mexit
 1425                                                         #Warning  Size mismatch (Using Str~1~ for MATHSIZE={:mexit})
 1426                                                 #endif
 1427                                               #endif
 1428                                                         mset      1,{:mexit}
 1429                                               #ifparm ~'~,3~'.{:3}~ = x
 1430                                                         pshhx
 1431                                               #endif
 1432                                               #ifparm ~2~
 1433                                                         @@Load~1~ ~2~
 1434                                                    #ifparm ~'~,3~'.{:3}~ = x
 1435                                                         ldhx      ~1~/8+1,asp         ;reload user HX for next LDHX
 1436                                                    #endif
 1437                                               #endif
 1438                                               #ifnb ~2~
 1439                                                         @@Msg     Convert \@~2~\@ ({::~2,~*8}-bit) to ASCIZ in \@~3~\@
 1440                                               #endif
 1441                                                         @@lea     ~3~
 1442                                                         call      Stack~1~ToASCIZ
 1443                                               #ifparm ~2~
 1444                                                         ais       #~1~/8
 1445                                               #endif
 1446                                               #ifparm ~'~,3~'.{:3}~ = x
 1447                                                         pulhx
 1448                                               #endif
 1449                                                         endm
 1451
 1452                                     ;*******************************************************************************
 1453                                     ; External dependencies
 1454                                     ;*******************************************************************************
 1455
 1456                                                         #Uses     string/length.sub
*** BEGIN INCLUDE FILE: lib/string/length.sub ***
    6                182C                 ?_OBJECT_?
    7                                     ;*******************************************************************************
    8                                     ; Purpose: Return the length of an ASCIZ string
    9                                     ; Input  : HX -> string
   10                                     ; Output : A = Length (zero when string is longer than 255)
   11                                     ;        : CCR matches RegA contents (a welcome side effect)
   12                                     ; Note(s):
   13
   14                                     StringLength        macro     [[#]StringVariable] ;if no parm, use current HX
   15                                                         mset      #
   16                                               #ifb ~1~
   17                                                         call      ~0~
   18                                                         mexit
   19                                               #endif
   20                                                         #push
   21                                                         #spauto   :sp
   22                                                         pshhx
   23                                                         @@lea     ~1~
   24                                                         call      ~0~
   25                                                         pulhx
   26                                                         #pull
   27                                                         endm
   28
   29                                     ;-------------------------------------------------------------------------------
   30
   31                                                         #spauto
   32
   33                182C                 StringLength        proc
   34    [182C] 182C:898B            [ 4]                     pshhx
   35    [182E] 182E:4F              [ 1]                     clra
   36    [182F] 182F:7D              [ 3] Loop@@              tst       ,x
   37    [1830] 1830:2704 (1836)     [ 3]                     beq       Done@@              ;on ASCIZ terminator, done
   38    [1832] 1832:AF01            [ 2]                     aix       #1                  ;bump up pointer
   39    [1834] 1834:4BF9 (182F)     [ 4]                     dbnza     Loop@@
   40    [1836] 1836:40              [ 1] Done@@              nega                          ;(now CCR matches A value)
   41    [1837] 1837:8A88            [ 6]                     pulhx
   42    [1839] 1839:81              [ 6]                     rtc
   43
   44                                                         #sp
   45                                     ;*******************************************************************************
*** END   INCLUDE FILE: lib/string/length.sub *** (RESUMING FILE: lib/stakmath.sub)
 1456                                                         #Exit
 1457                                                         #Uses     string/insertchar.sub
*** BEGIN INCLUDE FILE: lib/string/insertchar.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    [183D] 183D:87              [ 2]                     psha      char_to_ins@@       ;next character to insert
   43    [183E] 183E:F6              [ 3] Loop@@              lda       ,x                  ;A = old string character
   44    [183F] 183F:87              [ 2]                     psha                          ;save it for now
   45    [1840] 1840:9EE6 02         [ 4]                     lda       char_to_ins@@,sp    ;A = new character
   46    [1843] 1843:F7              [ 2]                     sta       ,x                  ;save it at current position
   47    [1844] 1844:86              [ 3]                     pula                          ;A = old string character
   48    [1845] 1845:2707 (184E)     [ 3]                     beq       Done@@              ;if at terminator, we're done
   49    [1847] 1847:9EE7 01         [ 4]                     sta       char_to_ins@@,sp    ;save old for next iteration
   50    [184A] 184A:AF01            [ 2]                     aix       #1                  ;HX -> next character position
   51    [184C] 184C:20F0 (183E)     [ 3]                     bra       Loop@@              ;repeat for all characters
   52    [184E] 184E:86              [ 3] Done@@              pula                          ;remove temp variable(s)
   53    [184F] 184F:8A88 86         [ 9]                     pull
   54    [1852] 1852:81              [ 6]                     rtc
   55
   56                                     ;*******************************************************************************
   57                                                         #sp
   58                                     ;*******************************************************************************
*** END   INCLUDE FILE: lib/string/insertchar.sub *** (RESUMING FILE: lib/stakmath.sub)
 1458                                                         #Uses     string/adddecimalpoint.sub
*** BEGIN INCLUDE FILE: lib/string/adddecimalpoint.sub ***
    6                                                         #Uses     length.sub
    7                                                         #Uses     insertchar.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                                                      mset      #
   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/string/adddecimalpoint.sub *** (RESUMING FILE: lib/stakmath.sub)
 1459                188D                 ?_OBJECT_?
 1460                                     ;*******************************************************************************
 1461                                     ; One-based (SP-index) offsets to stacked operands (to be used with #SPAUTO :AB)
 1462                                     ;*******************************************************************************
 1463
 1464                                                         #temp     1
 1465                0001                 ?a                  next      :temp,?WORD         ;top-of-stack (TOS) number (N1)
 1466                0005                 ?b                  next      :temp,?WORD         ;number after TOS (N2)
 1467
 1468                                                         #Cycles                       ;reset the cycles counter
 1469
 1470                                     ;*******************************************************************************
 1471                                     ; Purpose: Add N1 to N2 and place result on top-of-stack. N1 & N2 removed
 1472                                     ; Input  : [TOS+?WORD] = Number2
 1473                                     ;        : [TOS] = Number1
 1474                                     ; Output : [TOS] = Result
 1475                                     ; Note(s): Carry Set on overflow
 1476
 1477                                                         #spauto   :ab
 1478
 1479                188D                 ?Add                proc
 1480    [188D] 188D:8789 8B         [ 6]                     push
 1481    [1890] 1890:95              [ 2]                     tsx
 1482
 1488    [1891] 1891:A604            [ 2]                     lda       #?WORD
 1489    [1893] 1893:98              [ 1]                     clc
 1490                                                                   #Cycles
 1491    [1894] 1894:87              [ 2] Loop@@              psha
 1492    [1895] 1895:E608            [ 3]                     lda       ?a+{::?a-1},spx
 1493    [1897] 1897:E90C            [ 3]                     adc       ?b+{::?b-1},spx
 1494    [1899] 1899:E70C            [ 3]                     sta       ?b+{::?b-1},spx
 1495    [189B] 189B:86              [ 3]                     pula
 1496    [189C] 189C:AFFF            [ 2]                     aix       #-1
 1497    [189E] 189E:4BF4 (1894)     [ 4]                     dbnza     Loop@@
 1498                                                                   #Cycles :cycles*?WORD+:ocycles
 1500    [18A0] 18A0:CC1B 76         [ 4]                     jmp       ?RemoveAndReturn
 1501
 1502                005F                 ?AddCycles          equ       :cycles
 1503
 1504                                     ;*******************************************************************************
 1505                                     ; Purpose: Subtract N2 from N1 and place result on top-of-stack. N1 & N2 removed
 1506                                     ; Input  : [TOS+?WORD] = Number2
 1507                                     ;        : [TOS] = Number1
 1508                                     ; Output : [TOS] = Result
 1509                                     ; Note(s): Carry Set on borrow
 1510
 1511                                                         #spauto   :ab
 1512
 1513                18A3                 ?Subtract           proc
 1514    [18A3] 18A3:8789 8B         [ 6]                     push
 1515    [18A6] 18A6:95              [ 2]                     tsx
 1521    [18A7] 18A7:A604            [ 2]                     lda       #?WORD
 1522    [18A9] 18A9:98              [ 1]                     clc
 1523                                                                   #Cycles
 1524    [18AA] 18AA:87              [ 2] Loop@@              psha
 1525    [18AB] 18AB:E608            [ 3]                     lda       ?a+{::?a-1},spx
 1526    [18AD] 18AD:E20C            [ 3]                     sbc       ?b+{::?b-1},spx
 1527    [18AF] 18AF:E70C            [ 3]                     sta       ?b+{::?b-1},spx
 1528    [18B1] 18B1:86              [ 3]                     pula
 1529    [18B2] 18B2:AFFF            [ 2]                     aix       #-1
 1530    [18B4] 18B4:4BF4 (18AA)     [ 4]                     dbnza     Loop@@
 1531                                                                   #Cycles :cycles*?WORD+:ocycles
 1533    [18B6] 18B6:CC1B 76         [ 4]                     jmp       ?RemoveAndReturn
 1534
 1535                005F                 ?SubCycles          equ       :cycles
 1536
 1540  M                                                      @Msg      Bit ops enabled (define NO_BIT_OPS to disable)
 1540                                                         mexit
 1541                                     ;*******************************************************************************
 1542                                     ; Purpose: AND N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1543                                     ; Input  : [TOS+?WORD] = Number2
 1544                                     ;        : [TOS] = Number1
 1545                                     ; Output : [TOS] = Result
 1546                                     ; Note(s):
 1547                                                         #spauto   :ab
 1548
 1549                18B9                 ?BitAnd             proc
 1550    [18B9] 18B9:8789 8B         [ 6]                     push
 1551    [18BC] 18BC:95              [ 2]                     tsx
 1552
 1558    [18BD] 18BD:A604            [ 2]                     lda       #?WORD
 1559                                                                   #Cycles
 1560    [18BF] 18BF:87              [ 2] Loop@@              psha
 1561    [18C0] 18C0:E608            [ 3]                     lda       ?a+{::?a-1},spx
 1562    [18C2] 18C2:E40C            [ 3]                     and       ?b+{::?b-1},spx
 1563    [18C4] 18C4:E70C            [ 3]                     sta       ?b+{::?b-1},spx
 1564    [18C6] 18C6:86              [ 3]                     pula
 1565    [18C7] 18C7:AFFF            [ 2]                     aix       #-1
 1566    [18C9] 18C9:4BF4 (18BF)     [ 4]                     dbnza     Loop@@
 1567                                                                   #Cycles :cycles*?WORD+:ocycles
 1569    [18CB] 18CB:CC1B 76         [ 4]                     jmp       ?RemoveAndReturn
 1570
 1571                005E                 ?AndCycles          equ       :cycles
 1572
 1573                                     ;*******************************************************************************
 1574                                     ; Purpose: OR N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1575                                     ; Input  : [TOS+?WORD] = Number2
 1576                                     ;        : [TOS] = Number1
 1577                                     ; Output : [TOS] = Result
 1578                                     ; Note(s):
 1579                                                         #spauto   :ab
 1580
 1581                18CE                 ?BitOr              proc
 1582    [18CE] 18CE:8789 8B         [ 6]                     push
 1583    [18D1] 18D1:95              [ 2]                     tsx
 1584
 1590    [18D2] 18D2:A604            [ 2]                     lda       #?WORD
 1591                                                                   #Cycles
 1592    [18D4] 18D4:87              [ 2] Loop@@              psha
 1593    [18D5] 18D5:E608            [ 3]                     lda       ?a+{::?a-1},spx
 1594    [18D7] 18D7:EA0C            [ 3]                     ora       ?b+{::?b-1},spx
 1595    [18D9] 18D9:E70C            [ 3]                     sta       ?b+{::?b-1},spx
 1596    [18DB] 18DB:86              [ 3]                     pula
 1597    [18DC] 18DC:AFFF            [ 2]                     aix       #-1
 1598    [18DE] 18DE:4BF4 (18D4)     [ 4]                     dbnza     Loop@@
 1599                                                                   #Cycles :cycles*?WORD+:ocycles
 1601    [18E0] 18E0:CC1B 76         [ 4]                     jmp       ?RemoveAndReturn
 1602
 1603                005E                 ?OrCycles           equ       :cycles
 1604
 1605                                     ;*******************************************************************************
 1606                                     ; Purpose: XOR N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1607                                     ; Input  : [TOS+?WORD] = Number2
 1608                                     ;        : [TOS] = Number1
 1609                                     ; Output : [TOS] = Result
 1610                                     ; Note(s):
 1611                                                         #spauto   :ab
 1612
 1613                18E3                 ?BitXor             proc
 1614    [18E3] 18E3:8789 8B         [ 6]                     push
 1615    [18E6] 18E6:95              [ 2]                     tsx
 1616
 1622    [18E7] 18E7:A604            [ 2]                     lda       #?WORD
 1623                                                                   #Cycles
 1624    [18E9] 18E9:87              [ 2] Loop@@              psha
 1625    [18EA] 18EA:E608            [ 3]                     lda       ?a+{::?a-1},spx
 1626    [18EC] 18EC:E80C            [ 3]                     eor       ?b+{::?b-1},spx
 1627    [18EE] 18EE:E70C            [ 3]                     sta       ?b+{::?b-1},spx
 1628    [18F0] 18F0:86              [ 3]                     pula
 1629    [18F1] 18F1:AFFF            [ 2]                     aix       #-1
 1630    [18F3] 18F3:4BF4 (18E9)     [ 4]                     dbnza     Loop@@
 1631                                                                   #Cycles :cycles*?WORD+:ocycles
 1633    [18F5] 18F5:CC1B 76         [ 4]                     jmp       ?RemoveAndReturn
 1634
 1635                005E                 ?EorCycles          equ       :cycles
 1636
 1637                                     ;*******************************************************************************
 1638                                     ; Purpose: Shift N1 left N2 times and place result on top-of-stack. N1 & N2 removed
 1639                                     ; Input  : [TOS+?WORD] = Number2
 1640                                     ;        : [TOS] = Number1
 1641                                     ; Output : [TOS] = Result
 1642                                     ; Note(s): CCR[C] = last most significant bit shifted out
 1643                                     ;        : Only LSB of second operand (N2) is used, as shifting more than the
 1644                                     ;        : highest bit version always produces zero.  Any non-zero bytes in the
 1645                                     ;        : N2 operand will cause a zero result, regardless.
 1646
 1647                                                         #spauto   :ab
 1648
 1649                18F8                 ?ShiftLeft          proc
 1650    [18F8] 18F8:8789 8B         [ 6]                     push
 1651                                                         #ais
 1652
 1653    [18FB] 18FB:9EE6 0D         [ 4]                     lda       ?b+{::?b-1},sp      ;A = shift counter
 1654    [18FE] 18FE:87              [ 2]                     psha      counter@@
 1655
 1656    [18FF] 18FF:95              [ 2]                     tsx
 1657
 1658    [1900] 1900:6F0D            [ 5]                     clr       ?b+{::?b-1},spx     ;clear original shift counter
 1659                0005                 b@@                 equ       ?b,::?b-1           ;(b@@ = ?b but excludes final already cleared byte - 2013.11.29 optimization)
 1660  M                                                      @_tst_.s, b@@,spx             ;test whole word for zero (counter <= 8-bit)
 1660  M                                                      mset      #
 1660  M                                                      mreq      1
 1660  M                                                      @@_nosize_ b9,spx
 1660  M                                                      mset      #
 1660  M                                                      mset      0,mstop [_tst_.s] No size (b9,spx)
 1660  M                                                      endm
 1660  M                                                      mdo
 1660  M [1902] 1902:E60A            [ 3]                     lda       b9+0,spx
 1660  M                                                      mloop     ::b9
 1660  M [1904] 1904:EA0B            [ 3]                     ora       b9+1,spx
 1660  M                                                      mloop     ::b9
 1660  M [1906] 1906:EA0C            [ 3]                     ora       b9+2,spx
 1660  M                                                      mloop     ::b9
 1660                                                         endm
 1661    [1908] 1908:270D (1917)     [ 3]                     beq       Go@@                ;if so, proceed normally
 1662
 1663    [190A] 190A:F6              [ 3]                     lda       counter@@,spx       ;if shift counter is less than
 1664    [190B] 190B:A120            [ 2]                     cmpa      #MATHSIZE           ;MATHSIZE, proceed normally,
 1665    [190D] 190D:2508 (1917)     [ 3]                     blo       Go@@                ;else zero and exit
 1666
 1667  M                                                      @clr.s,   b@@,spx             ;else error, so zero result
 1667  M                                                      mset      #' '
 1667  M                                                      mreq      1
 1667  M                                                      @@_nosize_ b9,spx
 1667  M                                                      mset      #
 1667  M                                                      mset      0,mstop [clr.s] No size (b9,spx)
 1667  M                                                      endm
 1667  M                                                      mdef      2,::b9
 1667  M                                                      mdo
 1667  M [190F] 190F:6F0A            [ 5]                     clr       b9+0,spx
 1667  M                                                      mloop     ::b9
 1667  M [1911] 1911:6F0B            [ 5]                     clr       b9+1,spx
 1667  M                                                      mloop     ::b9
 1667  M [1913] 1913:6F0C            [ 5]                     clr       b9+2,spx
 1667  M                                                      mloop     ::b9
 1667                                                         endm
 1668    [1915] 1915:201A (1931)     [ 3]                     bra       Done@@              ;and get out
 1669
 1670  M                                  Go@@                @mova.s   ?a,spx ?b,spx       ;copy operand to result
 1670  M                                                      mset      #' '
 1670  M                                                      mreq      1,2:Source Destination
 1670  M                                                      @@_samesize_ ?a,spx ?b,spx
 1670  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1670  M                                                      mset      0
 1670  M                                                      mdo
 1670  M                                                      mswap     1,1
 1670  M                                                      @@_nosize_ ?a,spx
 1670  M                                                      mset      #
 1670  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1670  M                                                      endm
 1670  M                                                      mset      0,?a,spx
 1670  M                                                      mloop     :n
 1670  M                                                      mswap     1,2
 1670  M                                                      @@_nosize_ ?b,spx
 1670  M                                                      mset      #
 1670  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1670  M                                                      endm
 1670  M                                                      mloop     :n
 1670  M                                                      endm
 1670  M                                                      mset      0
 1670  M                                                      mdo
 1670  M [1917] 1917:E606            [ 3]                     lda       ?a+0,spx
 1670  M [1919] 1919:E70A            [ 3]                     sta       ?b+0,spx
 1670  M                                                      mloop     ::?b
 1670  M [191B] 191B:E607            [ 3]                     lda       ?a+1,spx
 1670  M [191D] 191D:E70B            [ 3]                     sta       ?b+1,spx
 1670  M                                                      mloop     ::?b
 1670  M [191F] 191F:E608            [ 3]                     lda       ?a+2,spx
 1670  M [1921] 1921:E70C            [ 3]                     sta       ?b+2,spx
 1670  M                                                      mloop     ::?b
 1670  M [1923] 1923:E609            [ 3]                     lda       ?a+3,spx
 1670  M [1925] 1925:E70D            [ 3]                     sta       ?b+3,spx
 1670  M                                                      mloop     ::?b
 1670                                                         endm
 1671                                                                   #Cycles
 1672  M                                  Loop@@              @lsl.s,   ?b,spx              ;shift left one bit position
 1672  M                                                      mset      #
 1672  M                                                      mreq      1
 1672  M                                                      @@_nosize_ ?b,spx
 1672  M                                                      mset      #
 1672  M                                                      mset      0,mstop [lsl.s] No size (?b,spx)
 1672  M                                                      endm
 1672  M                                                      mdo
 1672  M [1927] 1927:680D            [ 5]                     lsl       ?b+3,spx
 1672  M                                                      mloop     ::?b
 1672  M [1929] 1929:690C            [ 5]                     rol       ?b+2,spx
 1672  M                                                      mloop     ::?b
 1672  M [192B] 192B:690B            [ 5]                     rol       ?b+1,spx
 1672  M                                                      mloop     ::?b
 1672  M [192D] 192D:690A            [ 5]                     rol       ?b+0,spx
 1672  M                                                      mloop     ::?b
 1672                                                         endm
 1673    [192F] 192F:7BF6 (1927)     [ 6]                     dbnz      counter@@,spx,Loop@@ ;repeat for all bits
 1674                                                                   #Cycles :cycles*{MATHSIZE-1}+:ocycles
 1675                1931                 Done@@
 1677    [1931] 1931:86              [ 3]                     pula
 1681    [1932] 1932:CC1B 76         [ 4]                     jmp       ?RemoveAndReturn
 1682
 1683                037E                 ?ShlCycles          equ       :cycles
 1684
 1685                                     ;*******************************************************************************
 1686                                     ; Purpose: Shift N1 right N2 times and place result on top-of-stack. N1 & N2 removed
 1687                                     ; Input  : [TOS+?WORD] = Number2
 1688                                     ;        : [TOS] = Number1
 1689                                     ; Output : [TOS] = Result
 1690                                     ; Note(s): CCR[C] = last least significant bit shifted out
 1691                                     ;        : Only LSB of second operand (N2) is used, as shifting more than the
 1692                                     ;        : highest bit version always produces zero.  Any non-zero bytes in the
 1693                                     ;        : N2 operand will cause a zero result, regardless.
 1694
 1695                                                         #spauto   :ab
 1696
 1697                1935                 ?ShiftRight         proc
 1698    [1935] 1935:8789 8B         [ 6]                     push
 1699                                                         #ais
 1700
 1701    [1938] 1938:9EE6 0D         [ 4]                     lda       ?b+{::?b-1},sp      ;A = shift counter
 1702    [193B] 193B:87              [ 2]                     psha      counter@@
 1703
 1704    [193C] 193C:95              [ 2]                     tsx
 1705
 1706    [193D] 193D:6F0D            [ 5]                     clr       ?b+{::?b-1},spx     ;clear original shift counter
 1707                0005                 b@@                 equ       ?b,::?b-1           ;(b@@ = ?b but excludes final already cleared byte - 2013.11.29 optimization)
 1708  M                                                      @_tst_.s, b@@,spx             ;test whole word for zero (counter <= 8-bit)
 1708  M                                                      mset      #
 1708  M                                                      mreq      1
 1708  M                                                      @@_nosize_ b10,spx
 1708  M                                                      mset      #
 1708  M                                                      mset      0,mstop [_tst_.s] No size (b10,spx)
 1708  M                                                      endm
 1708  M                                                      mdo
 1708  M [193F] 193F:E60A            [ 3]                     lda       b10+0,spx
 1708  M                                                      mloop     ::b10
 1708  M [1941] 1941:EA0B            [ 3]                     ora       b10+1,spx
 1708  M                                                      mloop     ::b10
 1708  M [1943] 1943:EA0C            [ 3]                     ora       b10+2,spx
 1708  M                                                      mloop     ::b10
 1708                                                         endm
 1709    [1945] 1945:270D (1954)     [ 3]                     beq       Go@@                ;if so, proceed normally
 1710
 1711    [1947] 1947:F6              [ 3]                     lda       counter@@,spx       ;if shift counter is less than
 1712    [1948] 1948:A120            [ 2]                     cmpa      #MATHSIZE           ;MATHSIZE, proceed normally,
 1713    [194A] 194A:2508 (1954)     [ 3]                     blo       Go@@                ;else zero and exit
 1714
 1715  M                                                      @clr.s,   b@@,spx             ;else error, so zero result
 1715  M                                                      mset      #' '
 1715  M                                                      mreq      1
 1715  M                                                      @@_nosize_ b10,spx
 1715  M                                                      mset      #
 1715  M                                                      mset      0,mstop [clr.s] No size (b10,spx)
 1715  M                                                      endm
 1715  M                                                      mdef      2,::b10
 1715  M                                                      mdo
 1715  M [194C] 194C:6F0A            [ 5]                     clr       b10+0,spx
 1715  M                                                      mloop     ::b10
 1715  M [194E] 194E:6F0B            [ 5]                     clr       b10+1,spx
 1715  M                                                      mloop     ::b10
 1715  M [1950] 1950:6F0C            [ 5]                     clr       b10+2,spx
 1715  M                                                      mloop     ::b10
 1715                                                         endm
 1716    [1952] 1952:201A (196E)     [ 3]                     bra       Done@@              ;and get out
 1717
 1718  M                                  Go@@                @mova.s   ?a,spx ?b,spx       ;copy operand to result
 1718  M                                                      mset      #' '
 1718  M                                                      mreq      1,2:Source Destination
 1718  M                                                      @@_samesize_ ?a,spx ?b,spx
 1718  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1718  M                                                      mset      0
 1718  M                                                      mdo
 1718  M                                                      mswap     1,1
 1718  M                                                      @@_nosize_ ?a,spx
 1718  M                                                      mset      #
 1718  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1718  M                                                      endm
 1718  M                                                      mset      0,?a,spx
 1718  M                                                      mloop     :n
 1718  M                                                      mswap     1,2
 1718  M                                                      @@_nosize_ ?b,spx
 1718  M                                                      mset      #
 1718  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1718  M                                                      endm
 1718  M                                                      mloop     :n
 1718  M                                                      endm
 1718  M                                                      mset      0
 1718  M                                                      mdo
 1718  M [1954] 1954:E606            [ 3]                     lda       ?a+0,spx
 1718  M [1956] 1956:E70A            [ 3]                     sta       ?b+0,spx
 1718  M                                                      mloop     ::?b
 1718  M [1958] 1958:E607            [ 3]                     lda       ?a+1,spx
 1718  M [195A] 195A:E70B            [ 3]                     sta       ?b+1,spx
 1718  M                                                      mloop     ::?b
 1718  M [195C] 195C:E608            [ 3]                     lda       ?a+2,spx
 1718  M [195E] 195E:E70C            [ 3]                     sta       ?b+2,spx
 1718  M                                                      mloop     ::?b
 1718  M [1960] 1960:E609            [ 3]                     lda       ?a+3,spx
 1718  M [1962] 1962:E70D            [ 3]                     sta       ?b+3,spx
 1718  M                                                      mloop     ::?b
 1718                                                         endm
 1719                                                                   #Cycles
 1720                1964                 Loop@@
 1722  M                                                      @asr.s,   ?b,spx              ;shift right one bit position
 1722  M                                                      mset      #
 1722  M                                                      mreq      1
 1722  M                                                      @@_nosize_ ?b,spx
 1722  M                                                      mset      #
 1722  M                                                      mset      0,mstop [asr.s] No size (?b,spx)
 1722  M                                                      endm
 1722  M                                                      mdo
 1722  M [1964] 1964:670A            [ 5]                     asr       ?b+0,spx
 1722  M                                                      mloop     ::?b
 1722  M [1966] 1966:660B            [ 5]                     ror       ?b+1,spx
 1722  M                                                      mloop     ::?b
 1722  M [1968] 1968:660C            [ 5]                     ror       ?b+2,spx
 1722  M                                                      mloop     ::?b
 1722  M [196A] 196A:660D            [ 5]                     ror       ?b+3,spx
 1722  M                                                      mloop     ::?b
 1722                                                         endm
 1726    [196C] 196C:7BF6 (1964)     [ 6]                     dbnz      counter@@,spx,Loop@@ ;repeat for all bits
 1727                                                                   #Cycles :cycles*{MATHSIZE-1}+:ocycles
 1728                196E                 Done@@
 1730    [196E] 196E:86              [ 3]                     pula
 1734    [196F] 196F:CC1B 76         [ 4]                     jmp       ?RemoveAndReturn
 1735
 1736                037E                 ?ShrCycles          equ       :cycles
 1738
 1739                                     ;*******************************************************************************
 1740                                     ; Purpose: Multiply N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1741                                     ; Input  : [TOS+?WORD] = Number2
 1742                                     ;        : [TOS] = Number1
 1743                                     ; Output : [TOS] = Result
 1744                                     ; Note(s): Overflows lost, Carry state should be ignored
 1745
 1746                                                         #spauto   :ab
 1747
 1748                1972                 ?Multiply           proc
 1749    [1972] 1972:8789 8B         [ 6]                     push
 1773                                     ;===============================================================================
 1826                                     ;===============================================================================
 1828                                               ;-------------------------------------- ;row 1
 1829    [1975] 1975:95              [ 2]                     tsx
 1830    [1976] 1976:E608            [ 3]                     lda       ?a+3,spx
 1831    [1978] 1978:EE0C            [ 3]                     ldx       ?b+3,spx
 1832    [197A] 197A:42              [ 5]                     mul
 1833    [197B] 197B:8789            [ 4]                     pshxa     ans@@               ;temporary 32-bit result (3rd & 4th bytes)
 1834
 1835    [197D] 197D:95              [ 2]                     tsx
 1836    [197E] 197E:E609            [ 3]                     lda       ?a+2,spx
 1837    [1980] 1980:EE0D            [ 3]                     ldx       ?b+2,spx
 1838    [1982] 1982:42              [ 5]                     mul
 1839    [1983] 1983:8789            [ 4]                     pshxa     ans@@,4             ;temporary 32-bit result (1st & 2nd bytes)
 1840
 1841    [1985] 1985:95              [ 2]                     tsx
 1842    [1986] 1986:E60C            [ 3]                     lda       ?a+3,spx
 1843    [1988] 1988:EE0F            [ 3]                     ldx       ?b+2,spx
 1844    [198A] 198A:42              [ 5]                     mul
 1845    [198B] 198B:9EEB 03         [ 4]                     add       ans@@+2,sp
 1846    [198E] 198E:9EE7 03         [ 4]                     sta       ans@@+2,sp
 1847    [1991] 1991:9F              [ 1]                     txa
 1848    [1992] 1992:95              [ 2]                     tsx
 1849    [1993] 1993:E901            [ 3]                     adc       ans@@+1,spx
 1850    [1995] 1995:E701            [ 3]                     sta       ans@@+1,spx
 1851
 1852    [1997] 1997:E60C            [ 3]                     lda       ?a+3,spx
 1853    [1999] 1999:EE0E            [ 3]                     ldx       ?b+1,spx
 1854    [199B] 199B:42              [ 5]                     mul
 1855    [199C] 199C:9EEB 02         [ 4]                     add       ans@@+1,sp
 1856    [199F] 199F:9EE7 02         [ 4]                     sta       ans@@+1,sp
 1857    [19A2] 19A2:9F              [ 1]                     txa
 1858    [19A3] 19A3:95              [ 2]                     tsx
 1859    [19A4] 19A4:F9              [ 3]                     adc       ans@@,spx
 1860    [19A5] 19A5:F7              [ 2]                     sta       ans@@,spx
 1861
 1862    [19A6] 19A6:E60C            [ 3]                     lda       ?a+3,spx
 1863    [19A8] 19A8:EE0D            [ 3]                     ldx       ?b+0,spx
 1864    [19AA] 19AA:42              [ 5]                     mul
 1865    [19AB] 19AB:95              [ 2]                     tsx
 1866    [19AC] 19AC:FB              [ 3]                     add       ans@@,spx
 1867    [19AD] 19AD:F7              [ 2]                     sta       ans@@,spx
 1868                                               ;-------------------------------------- ;row 2
 1869    [19AE] 19AE:E60B            [ 3]                     lda       ?a+2,spx
 1870    [19B0] 19B0:EE10            [ 3]                     ldx       ?b+3,spx
 1871    [19B2] 19B2:42              [ 5]                     mul
 1872    [19B3] 19B3:9EEB 03         [ 4]                     add       ans@@+2,sp
 1873    [19B6] 19B6:9EE7 03         [ 4]                     sta       ans@@+2,sp
 1874    [19B9] 19B9:9F              [ 1]                     txa
 1875    [19BA] 19BA:95              [ 2]                     tsx
 1876    [19BB] 19BB:E901            [ 3]                     adc       ans@@+1,spx
 1877    [19BD] 19BD:E701            [ 3]                     sta       ans@@+1,spx
 1878    [19BF] 19BF:4F              [ 1]                     clra
 1879    [19C0] 19C0:F9              [ 3]                     adc       ans@@,spx
 1880    [19C1] 19C1:F7              [ 2]                     sta       ans@@,spx
 1881
 1882    [19C2] 19C2:E60B            [ 3]                     lda       ?a+2,spx
 1883    [19C4] 19C4:EE0E            [ 3]                     ldx       ?b+1,spx
 1884    [19C6] 19C6:42              [ 5]                     mul
 1885    [19C7] 19C7:95              [ 2]                     tsx
 1886    [19C8] 19C8:FB              [ 3]                     add       ans@@,spx
 1887    [19C9] 19C9:F7              [ 2]                     sta       ans@@,spx
 1888                                               ;-------------------------------------- ;row 3
 1889    [19CA] 19CA:E60A            [ 3]                     lda       ?a+1,spx
 1890    [19CC] 19CC:EE10            [ 3]                     ldx       ?b+3,spx
 1891    [19CE] 19CE:42              [ 5]                     mul
 1892    [19CF] 19CF:9EEB 02         [ 4]                     add       ans@@+1,sp
 1893    [19D2] 19D2:9EE7 02         [ 4]                     sta       ans@@+1,sp
 1894    [19D5] 19D5:9F              [ 1]                     txa
 1895    [19D6] 19D6:95              [ 2]                     tsx
 1896    [19D7] 19D7:F9              [ 3]                     adc       ans@@,spx
 1897    [19D8] 19D8:F7              [ 2]                     sta       ans@@,spx
 1898
 1899    [19D9] 19D9:E60A            [ 3]                     lda       ?a+1,spx
 1900    [19DB] 19DB:EE0F            [ 3]                     ldx       ?b+2,spx
 1901    [19DD] 19DD:42              [ 5]                     mul
 1902    [19DE] 19DE:95              [ 2]                     tsx
 1903    [19DF] 19DF:FB              [ 3]                     add       ans@@,spx
 1904    [19E0] 19E0:F7              [ 2]                     sta       ans@@,spx
 1905                                               ;-------------------------------------- ;row 4
 1906    [19E1] 19E1:E609            [ 3]                     lda       ?a+0,spx
 1907    [19E3] 19E3:EE10            [ 3]                     ldx       ?b+3,spx
 1908    [19E5] 19E5:42              [ 5]                     mul
 1909    [19E6] 19E6:95              [ 2]                     tsx
 1910    [19E7] 19E7:FB              [ 3]                     add       ans@@,spx
 1911    [19E8] 19E8:F7              [ 2]                     sta       ans@@,spx
 1913                                                                   #temp :cycles
 1914                                     ;===============================================================================
 1915                                               ;--------------------------------------
 1916                                               ; 40, 48, 56, and 64-bit versions use shorter
 1917                                               ; shift/add method (more cycles, though)
 1918                                               ;--------------------------------------
 1945                                               ;--------------------------------------
 1946                                               ; copy result to B while removing from stack
 1947                                               ;--------------------------------------
 1948    [19E9] 19E9:AE04            [ 2]                     ldx       #?WORD
 1949                                                                   #temp :cycles+:temp
 1950    [19EB] 19EB:86              [ 3] CopyResult@@        pula
 1951    [19EC] 19EC:9EE7 0D         [ 4]                     sta       ?b,sp
 1952    [19EF] 19EF:5BFA (19EB)     [ 4]                     dbnzx     CopyResult@@
 1953
 1954                                                         #spadd    1-?WORD
 1955                                                                   #temp :cycles*?WORD+:temp
 1956    [19F1] 19F1:CC1B 76         [ 4]                     jmp       ?RemoveAndReturn
 1957
 1958                0118                 ?MulCycles          equ       :temp+:cycles
 1959
 1960                                     ;*******************************************************************************
 1961                                     ; Purpose: Divide N1 by N2 and place quotient on top-of-stack. N1 & N2 removed
 1962                                     ; Input  : [TOS+?WORD] = Divisor (N2)
 1963                                     ;        : [TOS] = Dividend (N1)
 1964                                     ; Output : [TOS] = Quotient
 1965                                     ;        : Carry Set on error (division by zero)
 1966                                     ; Note(s):
 1967                                                         #spauto   :ab
 1968
 1969                19F4                 ?Divide             proc
 1970    [19F4] 19F4:8789 8B         [ 6]                     push
 1971
 1972    [19F7] 19F7:A601            [ 2]                     lda       #?DIVOP_            ;flag for DIV operation
 1974    [19F9] 19F9:87              [ 2]                     psha
 1975    [19FA] 19FA:95              [ 2]                     tsx
 1976    [19FB] 19FB:E606            [ 3]                     lda       ?a,spx
 1977    [19FD] 19FD:E80A            [ 3]                     eor       ?b,spx
 1978    [19FF] 19FF:86              [ 3]                     pula
 1979    [1A00] 1A00:2A02 (1A04)     [ 3]                     bpl       Skip@@
 1980    [1A02] 1A02:AA80            [ 2]                     ora       #?SIGN_             ;flag for negative
 1981                1A04                 Skip@@
 1983    [1A04] 1A04:87              [ 2]                     psha                          ;save flags on stack
 1984    [1A05] 1A05:202A (1A31)     [ 3]                     bra       ?DivStart
 1985
 1986                001F                 ?DivCycles          equ       :cycles
 1987
 1988                                     ;*******************************************************************************
 1989                                     ; Purpose: Divide N1 by N2 and place remainder on top-of-stack. N1 & N2 removed
 1990                                     ; Input  : [TOS+?WORD] = Divisor (N2)
 1991                                     ;        : [TOS] = Dividend (N1)
 1992                                     ; Output : [TOS] = Remainder
 1993                                     ;        : Carry Set on error (division by zero)
 1994                                     ; Note(s):
 1995                                                         #spauto   :ab
 1996                FFFFFFFF             ?pc                 equ       ::,:ab
 1997
 1998                1A07                 ?Modulo             proc
 1999    [1A07] 1A07:8789 8B         [ 6]                     push
 2000
 2001    [1A0A] 1A0A:4F              [ 1]                     clra                          ;flag for MOD operation
 2003    [1A0B] 1A0B:9E6D 06         [ 5]                     tst       ?a,sp
 2004    [1A0E] 1A0E:2A02 (1A12)     [ 3]                     bpl       Skip@@
 2005    [1A10] 1A10:AA80            [ 2]                     ora       #?SIGN_             ;flag for negative
 2006                1A12                 Skip@@
 2008    [1A12] 1A12:87              [ 2]                     psha                          ;save flags on stack
 2009    [1A13] 1A13:201C (1A31)     [ 3]                     bra       ?DivStart
 2010
 2011                0016                 ?ModCycles          equ       :cycles
 2012
 2013                                     ;*******************************************************************************
 2014
 2015                                                         #temp
 2017                1A15                 ?AbsX               proc
 2018    [1A15] 1A15:7D              [ 3]                     tst       ,ax
 2019    [1A16] 1A16:2A12 (1A2A)     [ 3]                     bpl       Done@@
 2020                                                                   #temp :cycles
 2021                0000                 var@@               equ       0,?WORD
 2022  M                                  ?NegX               @neg.s    var@@,ax
 2022  M                                                      mset      #
 2022  M                                                      mreq      1
 2022  M                                                      @@_nosize_ var14,ax
 2022  M                                                      mset      #
 2022  M                                                      mset      0,mstop [neg.s] No size (var14,ax)
 2022  M                                                      endm
 2022  M                                                      mdo
 2022  M [1A18] 1A18:73              [ 4]                     com       var14+0,ax
 2022  M                                                      mloop     ::var14-1
 2022  M [1A19] 1A19:6301            [ 5]                     com       var14+1,ax
 2022  M                                                      mloop     ::var14-1
 2022  M [1A1B] 1A1B:6302            [ 5]                     com       var14+2,ax
 2022  M                                                      mloop     ::var14-1
 2022  M [1A1D] 1A1D:6003            [ 5]                     neg       var14+3,ax
 2022  M                                                      mdo
 2022  M [1A1F] 1A1F:2609 (1A2A)     [ 3]                     bne       Done$$$
 2022  M [1A21] 1A21:6C02            [ 5]                     inc       var14+2,ax
 2022  M                                                      mloop     ::var14-1
 2022  M [1A23] 1A23:2605 (1A2A)     [ 3]                     bne       Done$$$
 2022  M [1A25] 1A25:6C01            [ 5]                     inc       var14+1,ax
 2022  M                                                      mloop     ::var14-1
 2022  M [1A27] 1A27:2601 (1A2A)     [ 3]                     bne       Done$$$
 2022  M [1A29] 1A29:7C              [ 4]                     inc       var14+0,ax
 2022  M                                                      mloop     ::var14-1
 2022  M             1A2A                 Done$$$
 2022                                                         endm
 2023    [1A2A] 1A2A:81              [ 6] Done@@              rts
 2024
 2025                0030                 ?AbsXCycles         equ       :cycles
 2026                002A                 ?NegxCycles         equ       ?AbsXCycles-:temp
 2028
 2029                                     ;*******************************************************************************
 2030
 2031                0000                 ?SF                 equ       0                   ;stack frame (for X-index use)
 2032
 2033                0000                 ?quotient           next      ?SF,?WORD
 2034                0004                 ?remainder          next      ?SF,?WORD
 2035                0008                 ?temp               next      ?SF,?WORD
 2036                000C                 ?bits               next      ?SF
 2037                000D                 ?flags              next      ?SF
 2038
 2039                0001                 ?DIVOP_             equ       %00000001           ;1 = DIV, 0 = MOD
 2040                0080                 ?SIGN_              equ       %10000000           ;result sign (1 = negative)
 2041
 2042                                                         #push
 2043
 2044    [1A2B] 1A2B:A70E            [ 2] ?DivError           ais       #?SF                ;de-allocate temporaries
 2045    [1A2D] 1A2D:99              [ 1]                     sec                           ;indicate error condition
 2046    [1A2E] 1A2E:CC1B 76         [ 4]                     jmp       ?RemoveAndReturn
 2047
 2048                                                         #pull
 2049                                     ;-------------------------------------------------------------------------------
 2050                1A31                 ?DivStart           proc
 2051                0001                 dividend@@          equ       ?a,::?a
 2052                0005                 divisor@@           equ       ?b,::?b
 2053                0005                 ans@@               equ       ?b,::?b             ;result overwrites divisor
 2054
 2056  M                                                      @lea      dividend@@,sp
 2056  M                                                      mset      #
 2056  M [1A31] 1A31:95              [ 2]                     tsx
 2056  M [1A32] 1A32:AF06            [ 2]                     !aix      #dividend15+:tsx
 2056                                                         mexit
 2057    [1A34] 1A34:ADDF (1A15)     [ 5]                     bsr       ?AbsX
 2058  M                                                      @lea      divisor@@,sp
 2058  M                                                      mset      #
 2058  M [1A36] 1A36:95              [ 2]                     tsx
 2058  M [1A37] 1A37:AF0A            [ 2]                     !aix      #divisor15+:tsx
 2058                                                         mexit
 2059    [1A39] 1A39:ADDA (1A15)     [ 5]                     bsr       ?AbsX
 2060                                                                   #Cycles ?AbsXCycles*2+:cycles
 2062    [1A3B] 1A3B:A7F3            [ 2]                     ais       #-?SF+1             ;quotient, remainder, and temp
 2063    [1A3D] 1A3D:95              [ 2]                     tsx                           ;(+1 for already pushed Flag)
 2064
 2065                                               ; remainder := 0
 2066                                               ; quotient := 0
 2067
 2068  M                                                      @clr.s    ?remainder,x
 2068  M                                                      mset      #' '
 2068  M                                                      mreq      1
 2068  M                                                      @@_nosize_ ?remainder,x
 2068  M                                                      mset      #
 2068  M                                                      mset      0,mstop [clr.s] No size (?remainder,x)
 2068  M                                                      endm
 2068  M                                                      mdef      2,::?remainder
 2068  M                                                      mdo
 2068  M [1A3E] 1A3E:6F04            [ 5]                     clr       ?remainder+0,x
 2068  M                                                      mloop     ::?remainder
 2068  M [1A40] 1A40:6F05            [ 5]                     clr       ?remainder+1,x
 2068  M                                                      mloop     ::?remainder
 2068  M [1A42] 1A42:6F06            [ 5]                     clr       ?remainder+2,x
 2068  M                                                      mloop     ::?remainder
 2068  M [1A44] 1A44:6F07            [ 5]                     clr       ?remainder+3,x
 2068  M                                                      mloop     ::?remainder
 2068                                                         endm
 2069  M                                                      @clr.s    ?quotient,x
 2069  M                                                      mset      #' '
 2069  M                                                      mreq      1
 2069  M                                                      @@_nosize_ ?quotient,x
 2069  M                                                      mset      #
 2069  M                                                      mset      0,mstop [clr.s] No size (?quotient,x)
 2069  M                                                      endm
 2069  M                                                      mdef      2,::?quotient
 2069  M                                                      mdo
 2069  M [1A46] 1A46:7F              [ 4]                     clr       ?quotient+0,x
 2069  M                                                      mloop     ::?quotient
 2069  M [1A47] 1A47:6F01            [ 5]                     clr       ?quotient+1,x
 2069  M                                                      mloop     ::?quotient
 2069  M [1A49] 1A49:6F02            [ 5]                     clr       ?quotient+2,x
 2069  M                                                      mloop     ::?quotient
 2069  M [1A4B] 1A4B:6F03            [ 5]                     clr       ?quotient+3,x
 2069  M                                                      mloop     ::?quotient
 2069                                                         endm
 2070
 2071                                               ; first, test for division by zero error
 2072
 2073  M                                                      @_tst_.s  divisor@@,spx
 2073  M                                                      mset      #
 2073  M                                                      mreq      1
 2073  M                                                      @@_nosize_ divisor15,spx
 2073  M                                                      mset      #
 2073  M                                                      mset      0,mstop [_tst_.s] No size (divisor15,spx)
 2073  M                                                      endm
 2073  M                                                      mdo
 2073  M [1A4D] 1A4D:E617            [ 3]                     lda       divisor15+0,spx
 2073  M                                                      mloop     ::divisor15
 2073  M [1A4F] 1A4F:EA18            [ 3]                     ora       divisor15+1,spx
 2073  M                                                      mloop     ::divisor15
 2073  M [1A51] 1A51:EA19            [ 3]                     ora       divisor15+2,spx
 2073  M                                                      mloop     ::divisor15
 2073  M [1A53] 1A53:EA1A            [ 3]                     ora       divisor15+3,spx
 2073  M                                                      mloop     ::divisor15
 2073                                                         endm
 2074    [1A55] 1A55:27D4 (1A2B)     [ 3]                     beq       ?DivError
 2075
 2076                                               ; if Dividend = 0, we're done
 2077
 2078  M                                                      @_tst_.s  dividend@@,spx
 2078  M                                                      mset      #
 2078  M                                                      mreq      1
 2078  M                                                      @@_nosize_ dividend15,spx
 2078  M                                                      mset      #
 2078  M                                                      mset      0,mstop [_tst_.s] No size (dividend15,spx)
 2078  M                                                      endm
 2078  M                                                      mdo
 2078  M [1A57] 1A57:E613            [ 3]                     lda       dividend15+0,spx
 2078  M                                                      mloop     ::dividend15
 2078  M [1A59] 1A59:EA14            [ 3]                     ora       dividend15+1,spx
 2078  M                                                      mloop     ::dividend15
 2078  M [1A5B] 1A5B:EA15            [ 3]                     ora       dividend15+2,spx
 2078  M                                                      mloop     ::dividend15
 2078  M [1A5D] 1A5D:EA16            [ 3]                     ora       dividend15+3,spx
 2078  M                                                      mloop     ::dividend15
 2078                                                         endm
 2079    [1A5F] 1A5F:2603 CC1B 42    [ 7]                     !jeq      Done@@
 2080
 2081                                               ; if (divisor = dividend) then quotient := 1; return
 2082                                               ; if (divisor > dividend) then remainder := dividend; return
 2083
 2084  M                                                      @_cmp_.s  divisor@@,spx dividend@@,spx
 2084  M                                                      mset      #' '
 2084  M                                                      mreq      1,2:[#]Operand1 [#]Operand2
 2084  M                                                      @@_samesize_ divisor15,spx dividend@@,spx
 2084  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2084  M                                                      mset      0
 2084  M                                                      mdo
 2084  M                                                      mswap     1,1
 2084  M                                                      @@_nosize_ divisor15,spx
 2084  M                                                      mset      #
 2084  M                                                      mset      0,mstop [_samesize_] No size (divisor15,spx)
 2084  M                                                      endm
 2084  M                                                      mset      0,divisor15,spx
 2084  M                                                      mloop     :n
 2084  M                                                      mswap     1,2
 2084  M                                                      @@_nosize_ dividend@@,spx
 2084  M                                                      mset      #
 2084  M                                                      mset      0,mstop [_samesize_] No size (dividend15,spx)
 2084  M                                                      endm
 2084  M                                                      mloop     :n
 2084  M                                                      endm
 2084  M                                                      #temp     1
 2084  M                                                      #temp     ::divisor15
 2084  M                                                      #temp     ::dividend@@
 2084  M                                                      mdo
 2084  M [1A64] 1A64:E617            [ 3]                     lda       divisor15+0,spx
 2084  M [1A66] 1A66:E113            [ 3]                     cmpa      dividend@@+0,spx
 2084  M [1A68] 1A68:2610 (1A7A)     [ 3]                     bne       Done$$$
 2084  M                                                      mloop     :temp
 2084  M [1A6A] 1A6A:E618            [ 3]                     lda       divisor15+1,spx
 2084  M [1A6C] 1A6C:E114            [ 3]                     cmpa      dividend@@+1,spx
 2084  M [1A6E] 1A6E:260A (1A7A)     [ 3]                     bne       Done$$$
 2084  M                                                      mloop     :temp
 2084  M [1A70] 1A70:E619            [ 3]                     lda       divisor15+2,spx
 2084  M [1A72] 1A72:E115            [ 3]                     cmpa      dividend@@+2,spx
 2084  M [1A74] 1A74:2604 (1A7A)     [ 3]                     bne       Done$$$
 2084  M                                                      mloop     :temp
 2084  M [1A76] 1A76:E61A            [ 3]                     lda       divisor15+3,spx
 2084  M [1A78] 1A78:E116            [ 3]                     cmpa      dividend@@+3,spx
 2084  M                                                      mloop     :temp
 2084  M             1A7A                 Done$$$
 2084                                                         endm
 2085    [1A7A] 1A7A:2604 (1A80)     [ 3]                     bne       NotEqual@@
 2086
 2087    [1A7C] 1A7C:6C03            [ 5]                     inc       ?quotient+{::?quotient-1},x  ;quotient := 1
 2088    [1A7E] 1A7E:2012 (1A92)     [ 3]                     bra       ??DivExit           ;and get out
 2089
 2090                1A80                 NotEqual@@         ;@sub.s    divisor@@,spx dividend@@,spx  ;[2012.05.18 REDUNDANT]
 2091    [1A80] 1A80:2513 (1A95)     [ 3]                     blo       Continue@@
 2092
 2093  M                                                      @mova.s   dividend@@,spx ?remainder,x
 2093  M                                                      mset      #' '
 2093  M                                                      mreq      1,2:Source Destination
 2093  M                                                      @@_samesize_ dividend15,spx ?remainder,x
 2093  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2093  M                                                      mset      0
 2093  M                                                      mdo
 2093  M                                                      mswap     1,1
 2093  M                                                      @@_nosize_ dividend15,spx
 2093  M                                                      mset      #
 2093  M                                                      mset      0,mstop [_samesize_] No size (dividend15,spx)
 2093  M                                                      endm
 2093  M                                                      mset      0,dividend15,spx
 2093  M                                                      mloop     :n
 2093  M                                                      mswap     1,2
 2093  M                                                      @@_nosize_ ?remainder,x
 2093  M                                                      mset      #
 2093  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2093  M                                                      endm
 2093  M                                                      mloop     :n
 2093  M                                                      endm
 2093  M                                                      mset      0
 2093  M                                                      mdo
 2093  M [1A82] 1A82:E613            [ 3]                     lda       dividend15+0,spx
 2093  M [1A84] 1A84:E704            [ 3]                     sta       ?remainder+0,x
 2093  M                                                      mloop     ::?remainder
 2093  M [1A86] 1A86:E614            [ 3]                     lda       dividend15+1,spx
 2093  M [1A88] 1A88:E705            [ 3]                     sta       ?remainder+1,x
 2093  M                                                      mloop     ::?remainder
 2093  M [1A8A] 1A8A:E615            [ 3]                     lda       dividend15+2,spx
 2093  M [1A8C] 1A8C:E706            [ 3]                     sta       ?remainder+2,x
 2093  M                                                      mloop     ::?remainder
 2093  M [1A8E] 1A8E:E616            [ 3]                     lda       dividend15+3,spx
 2093  M [1A90] 1A90:E707            [ 3]                     sta       ?remainder+3,x
 2093  M                                                      mloop     ::?remainder
 2093                                                         endm
 2094                1A92                 ??DivExit                                         ;and get out
 2098    [1A92] 1A92:CC1B 42         [ 4]                     jmp       Done@@
 2100
 2101    [1A95] 1A95:A620            [ 2] Continue@@          lda       #MATHSIZE
 2102    [1A97] 1A97:E70C            [ 3]                     sta       ?bits,x             ;bits := 64/56/48/40/32/24/16-bit
 2103
 2104                                               ; while (remainder < divisor) do
 2105
 2106  M                                  While@@             @cop                          ;in case of many iterations
 2106  M [1A99] 1A99:C718 00         [ 4]                     sta       COP
 2106                                                         endm
 2107
 2108  M                                                      @sub.s    ?remainder,x divisor@@,spx
 2108  M                                                      mset      #' '
 2108  M                                                      mreq      1,2:[#]Operand1 [#]Operand2 Destination
 2108  M                                                      @@_samesize_ ?remainder,x divisor15,spx
 2108  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2108  M                                                      mset      0
 2108  M                                                      mdo
 2108  M                                                      mswap     1,1
 2108  M                                                      @@_nosize_ ?remainder,x
 2108  M                                                      mset      #
 2108  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2108  M                                                      endm
 2108  M                                                      mset      0,?remainder,x
 2108  M                                                      mloop     :n
 2108  M                                                      mswap     1,2
 2108  M                                                      @@_nosize_ divisor15,spx
 2108  M                                                      mset      #
 2108  M                                                      mset      0,mstop [_samesize_] No size (divisor15,spx)
 2108  M                                                      endm
 2108  M                                                      mloop     :n
 2108  M                                                      endm
 2108  M                                                      #temp
 2108  M                                                      @@_nosize_ ?remainder,x
 2108  M                                                      mset      #
 2108  M                                                      mset      0,mstop [sub.s] No size (?remainder,x)
 2108  M                                                      endm
 2108  M                                                      #temp     ::?remainder
 2108  M                                                      mset      0,sub
 2108  M                                                      mdo
 2108  M [1A9C] 1A9C:E607            [ 3]                     lda       ?remainder+3,x
 2108  M [1A9E] 1A9E:E01A            [ 3]                     sub    divisor15+3,spx
 2108  M                                                      mset      0,sbc
 2108  M                                                      mloop     :temp
 2108  M [1AA0] 1AA0:E606            [ 3]                     lda       ?remainder+2,x
 2108  M [1AA2] 1AA2:E219            [ 3]                     sbc    divisor15+2,spx
 2108  M                                                      mset      0,sbc
 2108  M                                                      mloop     :temp
 2108  M [1AA4] 1AA4:E605            [ 3]                     lda       ?remainder+1,x
 2108  M [1AA6] 1AA6:E218            [ 3]                     sbc    divisor15+1,spx
 2108  M                                                      mset      0,sbc
 2108  M                                                      mloop     :temp
 2108  M [1AA8] 1AA8:E604            [ 3]                     lda       ?remainder+0,x
 2108  M [1AAA] 1AAA:E217            [ 3]                     sbc    divisor15+0,spx
 2108  M                                                      mset      0,sbc
 2108  M                                                      mloop     :temp
 2108                                                         endm
 2109    [1AAC] 1AAC:2424 (1AD2)     [ 3]                     bcc       EndWhile@@
 2110
 2111                                               ; remainder := (remainder shl 1) or msb(dividend)
 2112                                               ;-------------------------------------- ;2012.12.04 optimization (moved up this code from before DEC to here)
 2113  M                                                      @mova.s   dividend@@,spx ?temp,x  ; temp := dividend
 2113  M                                                      mset      #' '
 2113  M                                                      mreq      1,2:Source Destination
 2113  M                                                      @@_samesize_ dividend15,spx ?temp,x
 2113  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2113  M                                                      mset      0
 2113  M                                                      mdo
 2113  M                                                      mswap     1,1
 2113  M                                                      @@_nosize_ dividend15,spx
 2113  M                                                      mset      #
 2113  M                                                      mset      0,mstop [_samesize_] No size (dividend15,spx)
 2113  M                                                      endm
 2113  M                                                      mset      0,dividend15,spx
 2113  M                                                      mloop     :n
 2113  M                                                      mswap     1,2
 2113  M                                                      @@_nosize_ ?temp,x
 2113  M                                                      mset      #
 2113  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2113  M                                                      endm
 2113  M                                                      mloop     :n
 2113  M                                                      endm
 2113  M                                                      mset      0
 2113  M                                                      mdo
 2113  M [1AAE] 1AAE:E613            [ 3]                     lda       dividend15+0,spx
 2113  M [1AB0] 1AB0:E708            [ 3]                     sta       ?temp+0,x
 2113  M                                                      mloop     ::?temp
 2113  M [1AB2] 1AB2:E614            [ 3]                     lda       dividend15+1,spx
 2113  M [1AB4] 1AB4:E709            [ 3]                     sta       ?temp+1,x
 2113  M                                                      mloop     ::?temp
 2113  M [1AB6] 1AB6:E615            [ 3]                     lda       dividend15+2,spx
 2113  M [1AB8] 1AB8:E70A            [ 3]                     sta       ?temp+2,x
 2113  M                                                      mloop     ::?temp
 2113  M [1ABA] 1ABA:E616            [ 3]                     lda       dividend15+3,spx
 2113  M [1ABC] 1ABC:E70B            [ 3]                     sta       ?temp+3,x
 2113  M                                                      mloop     ::?temp
 2113                                                         endm
 2114  M                                                      @lsl.s    dividend@@,spx      ; dividend := dividend shl 1
 2114  M                                                      mset      #
 2114  M                                                      mreq      1
 2114  M                                                      @@_nosize_ dividend15,spx
 2114  M                                                      mset      #
 2114  M                                                      mset      0,mstop [lsl.s] No size (dividend15,spx)
 2114  M                                                      endm
 2114  M                                                      mdo
 2114  M [1ABE] 1ABE:6816            [ 5]                     lsl       dividend15+3,spx
 2114  M                                                      mloop     ::dividend15
 2114  M [1AC0] 1AC0:6915            [ 5]                     rol       dividend15+2,spx
 2114  M                                                      mloop     ::dividend15
 2114  M [1AC2] 1AC2:6914            [ 5]                     rol       dividend15+1,spx
 2114  M                                                      mloop     ::dividend15
 2114  M [1AC4] 1AC4:6913            [ 5]                     rol       dividend15+0,spx
 2114  M                                                      mloop     ::dividend15
 2114                                                         endm
 2115                                               ;--------------------------------------
 2116  M                                                      @rol.s    ?remainder,x
 2116  M                                                      mset      #
 2116  M                                                      mreq      1
 2116  M                                                      @@_nosize_ ?remainder,x
 2116  M                                                      mset      #
 2116  M                                                      mset      0,mstop [rol.s] No size (?remainder,x)
 2116  M                                                      endm
 2116  M                                                      mdo
 2116  M [1AC6] 1AC6:6907            [ 5]                     rol       ?remainder+3,x
 2116  M                                                      mloop     ::?remainder
 2116  M [1AC8] 1AC8:6906            [ 5]                     rol       ?remainder+2,x
 2116  M                                                      mloop     ::?remainder
 2116  M [1ACA] 1ACA:6905            [ 5]                     rol       ?remainder+1,x
 2116  M                                                      mloop     ::?remainder
 2116  M [1ACC] 1ACC:6904            [ 5]                     rol       ?remainder+0,x
 2116  M                                                      mloop     ::?remainder
 2116                                                         endm
 2117    [1ACE] 1ACE:6A0C            [ 5]                     dec       ?bits,x             ; bits := bits - 1
 2118
 2119                                               ; end while
 2120
 2121    [1AD0] 1AD0:20C7 (1A99)     [ 3]                     bra       While@@
 2122                1AD2                 EndWhile@@
 2123  M                                                      @mova.s   ?temp,x dividend@@,spx  ; dividend := temp
 2123  M                                                      mset      #' '
 2123  M                                                      mreq      1,2:Source Destination
 2123  M                                                      @@_samesize_ ?temp,x dividend15,spx
 2123  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2123  M                                                      mset      0
 2123  M                                                      mdo
 2123  M                                                      mswap     1,1
 2123  M                                                      @@_nosize_ ?temp,x
 2123  M                                                      mset      #
 2123  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2123  M                                                      endm
 2123  M                                                      mset      0,?temp,x
 2123  M                                                      mloop     :n
 2123  M                                                      mswap     1,2
 2123  M                                                      @@_nosize_ dividend15,spx
 2123  M                                                      mset      #
 2123  M                                                      mset      0,mstop [_samesize_] No size (dividend15,spx)
 2123  M                                                      endm
 2123  M                                                      mloop     :n
 2123  M                                                      endm
 2123  M                                                      mset      0
 2123  M                                                      mdo
 2123  M [1AD2] 1AD2:E608            [ 3]                     lda       ?temp+0,x
 2123  M [1AD4] 1AD4:E713            [ 3]                     sta       dividend15+0,spx
 2123  M                                                      mloop     ::dividend15
 2123  M [1AD6] 1AD6:E609            [ 3]                     lda       ?temp+1,x
 2123  M [1AD8] 1AD8:E714            [ 3]                     sta       dividend15+1,spx
 2123  M                                                      mloop     ::dividend15
 2123  M [1ADA] 1ADA:E60A            [ 3]                     lda       ?temp+2,x
 2123  M [1ADC] 1ADC:E715            [ 3]                     sta       dividend15+2,spx
 2123  M                                                      mloop     ::dividend15
 2123  M [1ADE] 1ADE:E60B            [ 3]                     lda       ?temp+3,x
 2123  M [1AE0] 1AE0:E716            [ 3]                     sta       dividend15+3,spx
 2123  M                                                      mloop     ::dividend15
 2123                                                         endm
 2124  M                                                      @lsr.s    ?remainder,x        ; remainder := remainder shr 1
 2124  M                                                      mset      #
 2124  M                                                      mreq      1
 2124  M                                                      @@_nosize_ ?remainder,x
 2124  M                                                      mset      #
 2124  M                                                      mset      0,mstop [lsr.s] No size (?remainder,x)
 2124  M                                                      endm
 2124  M                                                      mdo
 2124  M [1AE2] 1AE2:6404            [ 5]                     lsr       ?remainder+0,x
 2124  M                                                      mloop     ::?remainder
 2124  M [1AE4] 1AE4:6605            [ 5]                     ror       ?remainder+1,x
 2124  M                                                      mloop     ::?remainder
 2124  M [1AE6] 1AE6:6606            [ 5]                     ror       ?remainder+2,x
 2124  M                                                      mloop     ::?remainder
 2124  M [1AE8] 1AE8:6607            [ 5]                     ror       ?remainder+3,x
 2124  M                                                      mloop     ::?remainder
 2124                                                         endm
 2125    [1AEA] 1AEA:6C0C            [ 5]                     inc       ?bits,x             ; bits := bits + 1
 2126
 2127                                               ; for i := bitCounter-1 downto 0 do
 2128
 2129  M                                  For@@               @cop                          ;in case of many iterations
 2129  M [1AEC] 1AEC:C718 00         [ 4]                     sta       COP
 2129                                                         endm
 2130
 2131    [1AEF] 1AEF:6D0C            [ 4]                     tst       ?bits,x
 2133    [1AF1] 1AF1:274F (1B42)     [ 3]                     beq       Done@@
 2137    [1AF3] 1AF3:6A0C            [ 5]                     dec       ?bits,x
 2138
 2139                                               ; remainder := (remainder shl 1) or msb(dividend)
 2140                                               ; dividend := dividend shl 1
 2141
 2142  M                                                      @lsl.s    dividend@@,spx      ;2012.12.04 optimization
 2142  M                                                      mset      #
 2142  M                                                      mreq      1
 2142  M                                                      @@_nosize_ dividend15,spx
 2142  M                                                      mset      #
 2142  M                                                      mset      0,mstop [lsl.s] No size (dividend15,spx)
 2142  M                                                      endm
 2142  M                                                      mdo
 2142  M [1AF5] 1AF5:6816            [ 5]                     lsl       dividend15+3,spx
 2142  M                                                      mloop     ::dividend15
 2142  M [1AF7] 1AF7:6915            [ 5]                     rol       dividend15+2,spx
 2142  M                                                      mloop     ::dividend15
 2142  M [1AF9] 1AF9:6914            [ 5]                     rol       dividend15+1,spx
 2142  M                                                      mloop     ::dividend15
 2142  M [1AFB] 1AFB:6913            [ 5]                     rol       dividend15+0,spx
 2142  M                                                      mloop     ::dividend15
 2142                                                         endm
 2143  M                                                      @rol.s    ?remainder,x
 2143  M                                                      mset      #
 2143  M                                                      mreq      1
 2143  M                                                      @@_nosize_ ?remainder,x
 2143  M                                                      mset      #
 2143  M                                                      mset      0,mstop [rol.s] No size (?remainder,x)
 2143  M                                                      endm
 2143  M                                                      mdo
 2143  M [1AFD] 1AFD:6907            [ 5]                     rol       ?remainder+3,x
 2143  M                                                      mloop     ::?remainder
 2143  M [1AFF] 1AFF:6906            [ 5]                     rol       ?remainder+2,x
 2143  M                                                      mloop     ::?remainder
 2143  M [1B01] 1B01:6905            [ 5]                     rol       ?remainder+1,x
 2143  M                                                      mloop     ::?remainder
 2143  M [1B03] 1B03:6904            [ 5]                     rol       ?remainder+0,x
 2143  M                                                      mloop     ::?remainder
 2143                                                         endm
 2144
 2145                                               ; temp := remainder - divisor
 2146
 2147  M                                                      @sub.s    ?remainder,x divisor@@,spx ?temp,x
 2147  M                                                      mset      #' '
 2147  M                                                      mreq      1,2:[#]Operand1 [#]Operand2 Destination
 2147  M                                                      @@_samesize_ ?remainder,x divisor15,spx ?temp,x
 2147  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2147  M                                                      mset      0
 2147  M                                                      mdo
 2147  M                                                      mswap     1,1
 2147  M                                                      @@_nosize_ ?remainder,x
 2147  M                                                      mset      #
 2147  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2147  M                                                      endm
 2147  M                                                      mset      0,?remainder,x
 2147  M                                                      mloop     :n
 2147  M                                                      mswap     1,2
 2147  M                                                      @@_nosize_ divisor15,spx
 2147  M                                                      mset      #
 2147  M                                                      mset      0,mstop [_samesize_] No size (divisor15,spx)
 2147  M                                                      endm
 2147  M                                                      mloop     :n
 2147  M                                                      mswap     1,3
 2147  M                                                      @@_nosize_ ?temp,x
 2147  M                                                      mset      #
 2147  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2147  M                                                      endm
 2147  M                                                      mloop     :n
 2147  M                                                      endm
 2147  M                                                      #temp
 2147  M                                                      @@_nosize_ ?temp,x
 2147  M                                                      mset      #
 2147  M                                                      mset      0,mstop [sub.s] No size (?temp,x)
 2147  M                                                      endm
 2147  M                                                      #temp     ::?temp
 2147  M                                                      mset      0,sub
 2147  M                                                      mdo
 2147  M [1B05] 1B05:E607            [ 3]                     lda       ?remainder+3,x
 2147  M [1B07] 1B07:E01A            [ 3]                     sub    divisor15+3,spx
 2147  M [1B09] 1B09:E70B            [ 3]                     sta       ?temp+3,x
 2147  M                                                      mset      0,sbc
 2147  M                                                      mloop     :temp
 2147  M [1B0B] 1B0B:E606            [ 3]                     lda       ?remainder+2,x
 2147  M [1B0D] 1B0D:E219            [ 3]                     sbc    divisor15+2,spx
 2147  M [1B0F] 1B0F:E70A            [ 3]                     sta       ?temp+2,x
 2147  M                                                      mset      0,sbc
 2147  M                                                      mloop     :temp
 2147  M [1B11] 1B11:E605            [ 3]                     lda       ?remainder+1,x
 2147  M [1B13] 1B13:E218            [ 3]                     sbc    divisor15+1,spx
 2147  M [1B15] 1B15:E709            [ 3]                     sta       ?temp+1,x
 2147  M                                                      mset      0,sbc
 2147  M                                                      mloop     :temp
 2147  M [1B17] 1B17:E604            [ 3]                     lda       ?remainder+0,x
 2147  M [1B19] 1B19:E217            [ 3]                     sbc    divisor15+0,spx
 2147  M [1B1B] 1B1B:E708            [ 3]                     sta       ?temp+0,x
 2147  M                                                      mset      0,sbc
 2147  M                                                      mloop     :temp
 2147                                                         endm
 2148
 2149                                               ; q := not msb(temp)
 2150
 2151    [1B1D] 1B1D:E608            [ 3]                     lda       ?temp,x
 2152    [1B1F] 1B1F:A880            [ 2]                     eor       #%10000000          ;invert msb
 2153    [1B21] 1B21:A480            [ 2]                     and       #%10000000          ;isolate msb
 2154
 2155                                               ; quotient := (quotient shl 1) or q
 2156
 2157    [1B23] 1B23:87              [ 2]                     psha
 2158    [1B24] 1B24:48              [ 1]                     lsla
 2159    [1B25] 1B25:86              [ 3]                     pula
 2160
 2161  M                                                      @rol.s    ?quotient,x
 2161  M                                                      mset      #
 2161  M                                                      mreq      1
 2161  M                                                      @@_nosize_ ?quotient,x
 2161  M                                                      mset      #
 2161  M                                                      mset      0,mstop [rol.s] No size (?quotient,x)
 2161  M                                                      endm
 2161  M                                                      mdo
 2161  M [1B26] 1B26:6903            [ 5]                     rol       ?quotient+3,x
 2161  M                                                      mloop     ::?quotient
 2161  M [1B28] 1B28:6902            [ 5]                     rol       ?quotient+2,x
 2161  M                                                      mloop     ::?quotient
 2161  M [1B2A] 1B2A:6901            [ 5]                     rol       ?quotient+1,x
 2161  M                                                      mloop     ::?quotient
 2161  M [1B2C] 1B2C:79              [ 4]                     rol       ?quotient+0,x
 2161  M                                                      mloop     ::?quotient
 2161                                                         endm
 2162
 2163                                               ; if q <> 0 then
 2164
 2165    [1B2D] 1B2D:4100 BC(1AEC)   [ 4]                     cbeqa     #0,For@@
 2166
 2167                                               ; remainder := temp
 2168
 2169  M                                                      @mova.s   ?temp,x ?remainder,x
 2169  M                                                      mset      #' '
 2169  M                                                      mreq      1,2:Source Destination
 2169  M                                                      @@_samesize_ ?temp,x ?remainder,x
 2169  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2169  M                                                      mset      0
 2169  M                                                      mdo
 2169  M                                                      mswap     1,1
 2169  M                                                      @@_nosize_ ?temp,x
 2169  M                                                      mset      #
 2169  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2169  M                                                      endm
 2169  M                                                      mset      0,?temp,x
 2169  M                                                      mloop     :n
 2169  M                                                      mswap     1,2
 2169  M                                                      @@_nosize_ ?remainder,x
 2169  M                                                      mset      #
 2169  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2169  M                                                      endm
 2169  M                                                      mloop     :n
 2169  M                                                      endm
 2169  M                                                      mset      0
 2169  M                                                      mdo
 2169  M [1B30] 1B30:E608            [ 3]                     lda       ?temp+0,x
 2169  M [1B32] 1B32:E704            [ 3]                     sta       ?remainder+0,x
 2169  M                                                      mloop     ::?remainder
 2169  M [1B34] 1B34:E609            [ 3]                     lda       ?temp+1,x
 2169  M [1B36] 1B36:E705            [ 3]                     sta       ?remainder+1,x
 2169  M                                                      mloop     ::?remainder
 2169  M [1B38] 1B38:E60A            [ 3]                     lda       ?temp+2,x
 2169  M [1B3A] 1B3A:E706            [ 3]                     sta       ?remainder+2,x
 2169  M                                                      mloop     ::?remainder
 2169  M [1B3C] 1B3C:E60B            [ 3]                     lda       ?temp+3,x
 2169  M [1B3E] 1B3E:E707            [ 3]                     sta       ?remainder+3,x
 2169  M                                                      mloop     ::?remainder
 2169                                                         endm
 2170
 2171                                               ; end if -- end for
 2172
 2174    [1B40] 1B40:20AA (1AEC)     [ 3]                     bra       For@@
 2178
 2179    [1B42] 1B42:E60D            [ 3] Done@@              lda       ?flags,x
 2180    [1B44] 1B44:A501            [ 2]                     bit       #?DIVOP_
 2181    [1B46] 1B46:2711 (1B59)     [ 3]                     beq       ExitMod@@
 2182
 2183                0251                 ?Cycles             equ       :cycles
 2184
 2185                                     ;ExitDiv@@
 2186  M                                                      @mova.s   ?quotient,x ans@@,spx
 2186  M                                                      mset      #' '
 2186  M                                                      mreq      1,2:Source Destination
 2186  M                                                      @@_samesize_ ?quotient,x ans15,spx
 2186  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2186  M                                                      mset      0
 2186  M                                                      mdo
 2186  M                                                      mswap     1,1
 2186  M                                                      @@_nosize_ ?quotient,x
 2186  M                                                      mset      #
 2186  M                                                      mset      0,mstop [_samesize_] No size (?quotient,x)
 2186  M                                                      endm
 2186  M                                                      mset      0,?quotient,x
 2186  M                                                      mloop     :n
 2186  M                                                      mswap     1,2
 2186  M                                                      @@_nosize_ ans15,spx
 2186  M                                                      mset      #
 2186  M                                                      mset      0,mstop [_samesize_] No size (ans15,spx)
 2186  M                                                      endm
 2186  M                                                      mloop     :n
 2186  M                                                      endm
 2186  M                                                      mset      0
 2186  M                                                      mdo
 2186  M [1B48] 1B48:F6              [ 3]                     lda       ?quotient+0,x
 2186  M [1B49] 1B49:E717            [ 3]                     sta       ans15+0,spx
 2186  M                                                      mloop     ::ans15
 2186  M [1B4B] 1B4B:E601            [ 3]                     lda       ?quotient+1,x
 2186  M [1B4D] 1B4D:E718            [ 3]                     sta       ans15+1,spx
 2186  M                                                      mloop     ::ans15
 2186  M [1B4F] 1B4F:E602            [ 3]                     lda       ?quotient+2,x
 2186  M [1B51] 1B51:E719            [ 3]                     sta       ans15+2,spx
 2186  M                                                      mloop     ::ans15
 2186  M [1B53] 1B53:E603            [ 3]                     lda       ?quotient+3,x
 2186  M [1B55] 1B55:E71A            [ 3]                     sta       ans15+3,spx
 2186  M                                                      mloop     ::ans15
 2186                                                         endm
 2187    [1B57] 1B57:2010 (1B69)     [ 3]                     bra       ExitBoth@@
 2188
 2189                028B                 ?DivCycles          set       ?DivCycles+?Cycles+:cycles
 2190
 2191  M                                  ExitMod@@           @mova.s   ?remainder,x ans@@,spx
 2191  M                                                      mset      #' '
 2191  M                                                      mreq      1,2:Source Destination
 2191  M                                                      @@_samesize_ ?remainder,x ans15,spx
 2191  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2191  M                                                      mset      0
 2191  M                                                      mdo
 2191  M                                                      mswap     1,1
 2191  M                                                      @@_nosize_ ?remainder,x
 2191  M                                                      mset      #
 2191  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2191  M                                                      endm
 2191  M                                                      mset      0,?remainder,x
 2191  M                                                      mloop     :n
 2191  M                                                      mswap     1,2
 2191  M                                                      @@_nosize_ ans15,spx
 2191  M                                                      mset      #
 2191  M                                                      mset      0,mstop [_samesize_] No size (ans15,spx)
 2191  M                                                      endm
 2191  M                                                      mloop     :n
 2191  M                                                      endm
 2191  M                                                      mset      0
 2191  M                                                      mdo
 2191  M [1B59] 1B59:E604            [ 3]                     lda       ?remainder+0,x
 2191  M [1B5B] 1B5B:E717            [ 3]                     sta       ans15+0,spx
 2191  M                                                      mloop     ::ans15
 2191  M [1B5D] 1B5D:E605            [ 3]                     lda       ?remainder+1,x
 2191  M [1B5F] 1B5F:E718            [ 3]                     sta       ans15+1,spx
 2191  M                                                      mloop     ::ans15
 2191  M [1B61] 1B61:E606            [ 3]                     lda       ?remainder+2,x
 2191  M [1B63] 1B63:E719            [ 3]                     sta       ans15+2,spx
 2191  M                                                      mloop     ::ans15
 2191  M [1B65] 1B65:E607            [ 3]                     lda       ?remainder+3,x
 2191  M [1B67] 1B67:E71A            [ 3]                     sta       ans15+3,spx
 2191  M                                                      mloop     ::ans15
 2191                                                         endm
 2192
 2193                027F                 ?ModCycles          set       ?ModCycles+?Cycles+:cycles
 2194
 2195                1B69                 ExitBoth@@
 2197    [1B69] 1B69:6D0D            [ 4]                     tst       ?flags,x
 2198    [1B6B] 1B6B:2A06 (1B73)     [ 3]                     bpl       SkipSign@@
 2199  M                                                      @lea      ans@@,sp
 2199  M                                                      mset      #
 2199  M [1B6D] 1B6D:95              [ 2]                     tsx
 2199  M [1B6E] 1B6E:AF17            [ 2]                     !aix      #ans15+:tsx
 2199                                                         mexit
 2200    [1B70] 1B70:CD1A 18         [ 6]                     jsr       ?NegX
 2201                1B73                 SkipSign@@
 2202                                                                   #Cycles ?NegxCycles+:cycles
 2204    [1B73] 1B73:A70E            [ 2]                     ais       #?SF                ;de-allocate temporaries
 2205    [1B75] 1B75:98              [ 1]                     clc                           ;no error(s)
 2206                                     ;                   bra       ?RemoveAndReturn
 2207
 2208                003E                 ?Cycles             set       :cycles
 2209                02C9                 ?DivCycles          set       ?DivCycles+?Cycles
 2210                02BD                 ?ModCycles          set       ?ModCycles+?Cycles
 2211
 2212                                     ;*******************************************************************************
 2213                                     ; Common exit removes lower 32-bit stack element and returns to caller
 2214                                     ;*******************************************************************************
 2215
 2216                1B76                 ?RemoveAndReturn    proc
 2218    [1B76] 1B76:9EFE 04         [ 5]                     ldhx      ?pc,sp              ;our return address moved up
 2219    [1B79] 1B79:9EFF 08         [ 5]                     sthx      ?pc+?WORD,sp        ;above word to remove
 2229    [1B7C] 1B7C:8A88 86         [ 9]                     pull
 2230    [1B7F] 1B7F:A704            [ 2]                     ais       #?WORD              ;remove top-of-stack ?WORD
 2231    [1B81] 1B81:81              [ 6]                     rtc
 2232
 2233                001B                 ?ReturnCycles       equ       :cycles
 2234
 2235                                     ;*******************************************************************************
 2236                                     ; Purpose: Swaps the stacked order of N1 and N2
 2237                                     ; Input  : [TOS+?WORD] = Number2
 2238                                     ;        : [TOS] = Number1
 2239                                     ; Output : [TOS+?WORD] = Number1 -- TOS & [TOS+?WORD] in reverse order
 2240                                     ;        : [TOS] = Number2
 2241                                     ; Note(s): Does not alter stack size
 2242
 2243                                                         #spauto   :ab
 2244
 2245                1B82                 ?Swap               proc
 2246    [1B82] 1B82:8789 8B         [ 6]                     push
 2247
 2248    [1B85] 1B85:A604            [ 2]                     lda       #?WORD
 2249    [1B87] 1B87:87              [ 2]                     psha      bytes@@
 2250
 2251    [1B88] 1B88:95              [ 2]                     tsx
 2252                                                                   #temp :cycles
 2253  M                                  Loop@@              @_swap_,  ?a,spx ?b,spx       ;swap A with B ...
 2253  M                                                      mset      #' '
 2253  M                                                      #push
 2253  M                                                      #spauto   :sp
 2253  M [1B89] 1B89:E606            [ 3]                     lda       ?a,spx
 2253  M [1B8B] 1B8B:87              [ 2]                     psha
 2253  M [1B8C] 1B8C:E60A            [ 3]                     lda       ?b,spx
 2253  M [1B8E] 1B8E:E706            [ 3]                     sta       ?a,spx
 2253  M [1B90] 1B90:86              [ 3]                     pula
 2253  M [1B91] 1B91:E70A            [ 3]                     sta       ?b,spx
 2253  M                                                      #pull
 2253                                                         endm
 2254
 2255    [1B93] 1B93:AF01            [ 2]                     aix       #1                  ;point to next byte
 2256    [1B95] 1B95:9E6B 01F0 (1B89 [ 8]                     dbnz      bytes@@,sp,Loop@@   ;repeat for all bytes
 2257                                                                   #temp :cycles*?WORD+:temp
 2258    [1B99] 1B99:86              [ 3]                     pula
 2259
 2260    [1B9A] 1B9A:8A88 86         [ 9]                     pull
 2261    [1B9D] 1B9D:81              [ 6]                     rtc
 2262
 2263                008A                 ?SwapCycles         set       :cycles+:temp
 2264
 2265                                     ;*******************************************************************************
 2266                                     ; Purpose: Get the absolute value of the top-of-stack number
 2267                                     ; Input  : [TOS] = Number
 2268                                     ; Output : [TOS] = Abs(Number)
 2269                                     ; Note(s): Does not alter stack size
 2270
 2271                                                         #spauto   :ab
 2272
 2273                1B9E                 ?Abs                proc
 2274    [1B9E] 1B9E:9E6D 03         [ 5]                     tst       ?a,sp
 2275    [1BA1] 1BA1:2AFA (1B9D)     [ 3]                     bpl       Done@@
 2276                                     ;                   bra       ?Negate
 2277
 2278                1B9D                 Done@@              equ       :AnRTC
 2279
 2280                0008                 ?AbsCycles          equ       :cycles
 2281
 2282                                     ;*******************************************************************************
 2283                                     ; Purpose: Negate the top-of-stack number
 2284                                     ; Input  : [TOS] = Number
 2285                                     ; Output : [TOS] = -Number
 2286                                     ; Note(s): Does not alter stack size
 2287
 2288                                                         #spauto   :ab
 2289
 2290                1BA3                 ?Negate             proc
 2291    [1BA3] 1BA3:898B            [ 4]                     pshhx
 2293  M                                                      @lea      ?a,sp
 2293  M                                                      mset      #
 2293  M [1BA5] 1BA5:95              [ 2]                     tsx
 2293  M [1BA6] 1BA6:AF04            [ 2]                     !aix      #?a+:tsx
 2293                                                         mexit
 2294    [1BA8] 1BA8:CD1A 18         [ 6]                     jsr       ?NegX
 2295                                                                   #Cycles ?NegxCycles+:cycles
 2300    [1BAB] 1BAB:8A88            [ 6]                     pulhx
 2301    [1BAD] 1BAD:81              [ 6]                     rtc
 2302
 2303                0044                 ?NegateCycles       equ       :cycles
 2304                004C                 ?AbsCycles          set       ?NegateCycles+?AbsCycles
 2305
 2306                                     ;*******************************************************************************
 2307                                     ; Purpose: Create a new top-of-stack and load to it the number pointed to by HX
 2308                                     ; Input  : HX -> [Variable with] Number
 2309                                     ; Output : [TOS] = Number
 2310                                     ; Note(s): This operation makes it easier to load a number to the stack.
 2311                                     ;        : Hint: To make a copy of the TOS, do:
 2312                                     ;        :          tsx
 2313                                     ;        :          call      StackLoad32
 2314                                     ;        : (Stack is expanded)
 2315
 2316                                                         #spauto   :ab
 2317
 2318                1BAE                 ?Load               proc
 2319                FFFFFFFF             old_rts@@           equ       ::,:ab
 2320    [1BAE] 1BAE:A7FC            [ 2]                     ais       #-?WORD             ;allocate new TOS memory
 2321                                                         #temp     ::
 2322                FFFFFFFB             new_rts@@           next      :temp,:ab
 2323                FFFFFFFD             tos_num@@           next      :temp,?WORD
 2324                0001                                     next      :temp,-:ab          ;-:AB as old_rts@@ will be gone
 2325                                                         #ais      :temp
 2326
 2327    [1BB0] 1BB0:87              [ 2]                     psha
 2328  M                                                      @mova.s   old_rts@@,sp new_rts@@,sp  ;move RTS/RTC after new memory
 2328  M                                                      mset      #' '
 2328  M                                                      mreq      1,2:Source Destination
 2328  M                                                      @@_samesize_ old_rts20,sp new_rts@@,sp
 2328  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2328  M                                                      mset      0
 2328  M                                                      mdo
 2328  M                                                      mswap     1,1
 2328  M                                                      @@_nosize_ old_rts20,sp
 2328  M                                                      mset      #
 2328  M                                                      mset      0,mstop [_samesize_] No size (old_rts20,sp)
 2328  M                                                      endm
 2328  M                                                      mset      0,old_rts20,sp
 2328  M                                                      mloop     :n
 2328  M                                                      mswap     1,2
 2328  M                                                      @@_nosize_ new_rts@@,sp
 2328  M                                                      mset      #
 2328  M                                                      mset      0,mstop [_samesize_] No size (new_rts20,sp)
 2328  M                                                      endm
 2328  M                                                      mloop     :n
 2328  M                                                      endm
 2328  M                                                      mset      0
 2328  M                                                      mdo
 2328  M [1BB1] 1BB1:9EE6 06         [ 4]                     lda       old_rts20+0,sp
 2328  M [1BB4] 1BB4:9EE7 02         [ 4]                     sta       new_rts@@+0,sp
 2328  M                                                      mloop     ::new_rts@@
 2328  M [1BB7] 1BB7:9EE6 07         [ 4]                     lda       old_rts20+1,sp
 2328  M [1BBA] 1BBA:9EE7 03         [ 4]                     sta       new_rts@@+1,sp
 2328  M                                                      mloop     ::new_rts@@
 2328                                                         endm
 2329  M                                                      @mova.s   ,x tos_num@@,sp
 2329  M                                                      mset      #' '
 2329  M                                                      mreq      1,2:Source Destination
 2329  M                                                      @@_samesize_ ,x tos_num20,sp
 2329  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2329  M                                                      mset      0
 2329  M                                                      mdo
 2329  M                                                      mswap     1,1
 2329  M                                                      mloop     :n
 2329  M                                                      mswap     1,2
 2329  M                                                      @@_nosize_ tos_num20,sp
 2329  M                                                      mset      #
 2329  M                                                      mset      0,mstop [_samesize_] No size (tos_num20,sp)
 2329  M                                                      endm
 2329  M                                                      mset      0,tos_num20,sp
 2329  M                                                      mloop     :n
 2329  M                                                      endm
 2329  M                                                      mset      0
 2329  M                                                      mdo
 2329  M [1BBD] 1BBD:F6              [ 3]                     lda       +0,x
 2329  M [1BBE] 1BBE:9EE7 04         [ 4]                     sta       tos_num20+0,sp
 2329  M                                                      mloop     ::tos_num20
 2329  M [1BC1] 1BC1:E601            [ 3]                     lda       +1,x
 2329  M [1BC3] 1BC3:9EE7 05         [ 4]                     sta       tos_num20+1,sp
 2329  M                                                      mloop     ::tos_num20
 2329  M [1BC6] 1BC6:E602            [ 3]                     lda       +2,x
 2329  M [1BC8] 1BC8:9EE7 06         [ 4]                     sta       tos_num20+2,sp
 2329  M                                                      mloop     ::tos_num20
 2329  M [1BCB] 1BCB:E603            [ 3]                     lda       +3,x
 2329  M [1BCD] 1BCD:9EE7 07         [ 4]                     sta       tos_num20+3,sp
 2329  M                                                      mloop     ::tos_num20
 2329                                                         endm
 2330    [1BD0] 1BD0:86              [ 3]                     pula
 2331    [1BD1] 1BD1:81              [ 6]                     rtc
 2332
 2333                0039                 ?LoadCycles         equ       :cycles
 2334
 2335                                     ;*******************************************************************************
 2336                                     ; Purpose: Unload the top-of-stack number into a variable pointed to by HX
 2337                                     ; Input  : [TOS] = Number
 2338                                     ;        : HX -> Some 32-bit variable
 2339                                     ; Output : Variable pointed to by HX receives TOS number
 2340                                     ; Note(s): This operation makes it easier to unload a number from the stack.
 2341                                     ;        : Use:
 2342                                     ;        :          ldhx      #MyVar
 2343                                     ;        :          call      StackSave32
 2344                                     ;        : (Stack is reduced)
 2345
 2346                                                         #spauto   :ab
 2347
 2348                1BD2                 ?Save               proc
 2349                                                         #temp     ::
 2350                FFFFFFFF             old_rts@@           next      :temp,:ab
 2351                0001                 tos_num@@           next      :temp,?WORD
 2352                0005                                     next      :temp,-:ab          ;-:AB as old_rts@@ will be gone
 2353                0003                 new_rts@@           next      :temp,:ab
 2354
 2355                0000                 var@@               equ       0,?WORD
 2356
 2357    [1BD2] 1BD2:8789 8B         [ 6]                     push
 2358  M                                                      @mova.s   tos_num@@,sp var@@,x
 2358  M                                                      mset      #' '
 2358  M                                                      mreq      1,2:Source Destination
 2358  M                                                      @@_samesize_ tos_num21,sp var@@,x
 2358  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2358  M                                                      mset      0
 2358  M                                                      mdo
 2358  M                                                      mswap     1,1
 2358  M                                                      @@_nosize_ tos_num21,sp
 2358  M                                                      mset      #
 2358  M                                                      mset      0,mstop [_samesize_] No size (tos_num21,sp)
 2358  M                                                      endm
 2358  M                                                      mset      0,tos_num21,sp
 2358  M                                                      mloop     :n
 2358  M                                                      mswap     1,2
 2358  M                                                      @@_nosize_ var@@,x
 2358  M                                                      mset      #
 2358  M                                                      mset      0,mstop [_samesize_] No size (var21,x)
 2358  M                                                      endm
 2358  M                                                      mloop     :n
 2358  M                                                      endm
 2358  M                                                      mset      0
 2358  M                                                      mdo
 2358  M [1BD5] 1BD5:9EE6 06         [ 4]                     lda       tos_num21+0,sp
 2358  M [1BD8] 1BD8:F7              [ 2]                     sta       var@@+0,x
 2358  M                                                      mloop     ::var@@
 2358  M [1BD9] 1BD9:9EE6 07         [ 4]                     lda       tos_num21+1,sp
 2358  M [1BDC] 1BDC:E701            [ 3]                     sta       var@@+1,x
 2358  M                                                      mloop     ::var@@
 2358  M [1BDE] 1BDE:9EE6 08         [ 4]                     lda       tos_num21+2,sp
 2358  M [1BE1] 1BE1:E702            [ 3]                     sta       var@@+2,x
 2358  M                                                      mloop     ::var@@
 2358  M [1BE3] 1BE3:9EE6 09         [ 4]                     lda       tos_num21+3,sp
 2358  M [1BE6] 1BE6:E703            [ 3]                     sta       var@@+3,x
 2358  M                                                      mloop     ::var@@
 2358                                                         endm
 2359
 2360    [1BE8] 1BE8:95              [ 2]                     tsx
 2361  M                                                      @mova.s   old_rts@@,spx new_rts@@,spx  ;move RTS/RTC before old memory
 2361  M                                                      mset      #' '
 2361  M                                                      mreq      1,2:Source Destination
 2361  M                                                      @@_samesize_ old_rts21,spx new_rts@@,spx
 2361  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2361  M                                                      mset      0
 2361  M                                                      mdo
 2361  M                                                      mswap     1,1
 2361  M                                                      @@_nosize_ old_rts21,spx
 2361  M                                                      mset      #
 2361  M                                                      mset      0,mstop [_samesize_] No size (old_rts21,spx)
 2361  M                                                      endm
 2361  M                                                      mset      0,old_rts21,spx
 2361  M                                                      mloop     :n
 2361  M                                                      mswap     1,2
 2361  M                                                      @@_nosize_ new_rts@@,spx
 2361  M                                                      mset      #
 2361  M                                                      mset      0,mstop [_samesize_] No size (new_rts21,spx)
 2361  M                                                      endm
 2361  M                                                      mloop     :n
 2361  M                                                      endm
 2361  M                                                      mset      0
 2361  M                                                      mdo
 2361  M [1BE9] 1BE9:E603            [ 3]                     lda       old_rts21+0,spx
 2361  M [1BEB] 1BEB:E707            [ 3]                     sta       new_rts@@+0,spx
 2361  M                                                      mloop     ::new_rts@@
 2361  M [1BED] 1BED:E604            [ 3]                     lda       old_rts21+1,spx
 2361  M [1BEF] 1BEF:E708            [ 3]                     sta       new_rts@@+1,spx
 2361  M                                                      mloop     ::new_rts@@
 2361                                                         endm
 2362    [1BF1] 1BF1:8A88 86         [ 9]                     pull
 2363
 2364    [1BF4] 1BF4:A704            [ 2]                     ais       #?WORD              ;de-allocate TOS memory
 2365    [1BF6] 1BF6:81              [ 6]                     rtc
 2366
 2367                0040                 ?SaveCycles         equ       :cycles
 2368
 2369                                     ;*******************************************************************************
 2370                                     ; Purpose: Adjust TOS old size to new
 2371                                     ; Input  : H = old (current) byte size
 2372                                     ;        : X = new byte size
 2373                                     ;        : CCR[C] = 0 -- always positive number
 2374                                     ;        : CCR[C] = 1 -- sign extend
 2375                                     ; Output : None
 2376                                     ; Note(s): RegA deliberately not used for parameter passing (for consistency)
 2377                                     ;        : Macro destroys RegHX (as we must not use PSHHX/PULHX around call)
 2378
 2380
 2381                                     ResizeTOS           macro     #FromByteSize,#ToByteSize,,unsigned_if_present
 2382                                                         mreq      1,2:#FromByteSize,#ToByteSize
 2383                                               #ifb ~1.1.1~~2.1.1~ = ##
 2384                                                         mstop     Usage: ~0~ #FromByteSize,#ToByteSize
 2385                                               #endif
 2386                                                         #temp     {~#2~}-{~#1~}
 2387                                               #ifz :temp
 2388                                                         mexit                         ;;same sizes, nothing to do
 2389                                               #endif
 2390                                               #ifnb ~4~
 2391                                                         @@Msg     {~#1~*8}-bit => {~#2~*8}-bit
 2392                                               #else ifdef SIGNED
 2393                                                         @@Msg     Signed {~#1~*8}-bit => {~#2~*8}-bit
 2394                                               #else
 2395                                                         @@Msg     {~#1~*8}-bit => {~#2~*8}-bit
 2396                                               #endif
 2397                                               #if :temp > 0                           ;;increase stack (optimized)
 2398                                                 #if :temp < 5                         ;;up to size 'long'
 2399                                                         clrx                          ;;assume unsigned
 2400                                                   #ifb ~4~                            ;;if 'unsigned override' not present
 2401                                                     #ifdef SIGNED                     ;;and signed version is used
 2402                                                         tst       1,asp               ;;test operand sign
 2403                                                         bpl       *+3                 ;;skip over following COMX
 2404                                                         !comx                         ;;sign-extend negative number
 2405                                                     #endif
 2406                                                   #endif
 2407                                                         pshx:{:temp}                  ;;(added the curly brackets to make the number visible in LST file)
 2408                                                         mexit
 2409                                                 #endif
 2410                                               #endif
 2411                                               #if :temp < 0                           ;;decrease stack (optimized)
 2412                                                 #if :temp > -5
 2413                                                         ais       #-:temp             ;;release stack bytes (negative :temp => positive)
 2414                                                         mexit
 2415                                                 #endif
 2416                                               #endif
 2417                                                         ldhx      #~#1~<8|{~#2~}      ;;(longer sizes use normal method)
 2418                                               #ifdef SIGNED                           ;;if signed version is used
 2419                                                 #ifb ~4~                              ;;and if 'unsigned override' not present
 2420                                                         sec                           ;;use sign extension
 2421                                                 #else
 2422                                                         clc                           ;;no sign extension
 2423                                                 #endif
 2424                                               #endif
 2425                                                         call      ~0~                 ;;call stack resizing routine
 2426                                                         #spadd    ~#2~-{~#1~}
 2427                                                         endm
 2428                                     ;-------------------------------------------------------------------------------
 2429                                                         #spauto   :ab
 2430
 2431                1BF7                 ResizeTOS           proc
 2432    [1BF7] 1BF7:8789 8B         [ 6]                     push      old@@,1
 2433
 2434    [1BFA] 1BFA:85              [ 1]                     tpa
 2435    [1BFB] 1BFB:87              [ 2]                     psha      ccr@@
 2436
 2437                                                         #ais
 2438                                                         #psp
 2439
 2440    [1BFC] 1BFC:9F              [ 1]                     txa                           ;A = new byte size
 2441    [1BFD] 1BFD:9EE0 02         [ 4]                     sub       old@@,sp            ;A = bytes to add/remove
 2442    [1C00] 1C00:2735 (1C37)     [ 3]                     beq       Done@@              ;nothing to do, get out
 2443    [1C02] 1C02:2B20 (1C24)     [ 3]                     bmi       Shrink@@            ;go take care of 'remove' case
 2444                                               ;---------------------------------------------------------------------
 2445                                               ; "positive" case, going from smaller to larger size
 2446                                               ;---------------------------------------------------------------------
 2447    [1C04] 1C04:87              [ 2] Expand@@            psha      room@@              ;create room for expansion
 2448    [1C05] 1C05:95              [ 2]                     tsx
 2449
 2450    [1C06] 1C06:87              [ 2]                     psha                          ;protect counter
 2451
 2452    [1C07] 1C07:A606            [ 2]                     lda       #:sp-:psp
 2453    [1C09] 1C09:87              [ 2] ExpandLoop@@        psha
 2454    [1C0A] 1C0A:E601            [ 3]                     lda       room@@+1,spx
 2455    [1C0C] 1C0C:F7              [ 2]                     sta       room@@,spx
 2456    [1C0D] 1C0D:86              [ 3]                     pula
 2457    [1C0E] 1C0E:AF01            [ 2]                     aix       #1
 2458    [1C10] 1C10:4BF7 (1C09)     [ 4]                     dbnza     ExpandLoop@@
 2459
 2460    [1C12] 1C12:7F              [ 4]                     clr       ,x                  ;positive sign extension
 2462    [1C13] 1C13:9EE6 02         [ 4]                     lda       ccr@@-1,sp          ;BugFix: 2014.10.14 (WAS: ccr@@,sp)
 2463    [1C16] 1C16:84              [ 1]                     tap
 2464    [1C17] 1C17:2406 (1C1F)     [ 3]                     bcc       ExpandNext@@
 2465
 2466    [1C19] 1C19:9E6D 09         [ 5]                     tst       1,sp
 2467    [1C1C] 1C1C:2A01 (1C1F)     [ 3]                     bpl       ExpandNext@@
 2468    [1C1E] 1C1E:73              [ 4]                     com       ,x                  ;negative sign extension
 2470    [1C1F] 1C1F:86              [ 3] ExpandNext@@        pula
 2471    [1C20] 1C20:4BE2 (1C04)     [ 4]                     dbnza     Expand@@
 2472
 2473    [1C22] 1C22:2013 (1C37)     [ 3]                     bra       Done@@
 2474                                               ;---------------------------------------------------------------------
 2475                                               ; "negative" case, going from larger to smaller size
 2476                                               ;---------------------------------------------------------------------
 2477                                                         #push
 2478                                                         #spadd    -1                  ;account for room@@ PSHA above
 2479                                                         #psp
 2480
 2481    [1C24] 1C24:40              [ 1] Shrink@@            nega                          ;make counter positive
 2482
 2483    [1C25] 1C25:87              [ 2] ShrinkAgain@@       psha
 2484    [1C26] 1C26:95              [ 2]                     tsx
 2485
 2486    [1C27] 1C27:A606            [ 2]                     lda       #:sp-:psp
 2487    [1C29] 1C29:87              [ 2] ShrinkLoop@@        psha
 2488    [1C2A] 1C2A:E606            [ 3]                     lda       1-1,spx
 2489    [1C2C] 1C2C:E707            [ 3]                     sta       1,spx
 2490    [1C2E] 1C2E:86              [ 3]                     pula
 2491    [1C2F] 1C2F:AFFF            [ 2]                     aix       #-1
 2492    [1C31] 1C31:4BF6 (1C29)     [ 4]                     dbnza     ShrinkLoop@@
 2493
 2494    [1C33] 1C33:86              [ 3]                     pula
 2495    [1C34] 1C34:88              [ 3]                     pulx                          ;get rid of extra room (AIS #1)
 2496    [1C35] 1C35:4BEE (1C25)     [ 4]                     dbnza     ShrinkAgain@@
 2497
 2498                                                         #pull
 2499                                               ;---------------------------------------------------------------------
 2500    [1C37] 1C37:A701            [ 2] Done@@              ais       #:ais
 2501    [1C39] 1C39:8A88 86         [ 9]                     pull
 2502    [1C3C] 1C3C:81              [ 6]                     rtc
 2504
 2505                                     ;*******************************************************************************
 2506                                     ; Purpose: Convert 32-bit to ASCIZ string
 2507                                     ; Input  : Stack: 32-bit number
 2508                                     ;        : HX -> Output buffer with enough space to keep the ASCIZ string result
 2509                                     ; Output : None
 2510                                     ; Note(s): Use:
 2511                                     ;        :          ldhx      #Buffer
 2512                                     ;        :          call      Stack32ToASCIZ
 2513
 2514                                                         #spauto   :ab                 ;account for RTS/RTC
 2515
 2516                1C3D                 ?ToStr              proc
 2517    [1C3D] 1C3D:8789 8B         [ 6]                     push
 2518                                                         #ais                          ;mark beginning of temporaries
 2519
 2520    [1C40] 1C40:898B            [ 4]                     pshhx     .buffer@@           ;working copy of pointer to buffer
 2521    [1C42] 1C42:7F              [ 4]                     clr       ,x                  ;make it an ASCIZ string
 2522
 2523  M                                                      @lea      1,sp                ;HX -> TOS number of caller
 2523  M                                                      mset      #
 2523  M [1C43] 1C43:95              [ 2]                     tsx
 2523  M [1C44] 1C44:AF07            [ 2]                     !aix      #1+:tsx
 2523                                                         mexit
 2524    [1C46] 1C46:CD1B AE         [ 6]                     call      ?Load               ;load a working copy on stack
 2525
 2526                                                         #spadd    ?WORD               ;stack has grown by a ?WORD
 2527                FFFFFFF6             number@@            equ       ::,?WORD
 2529    [1C49] 1C49:9E6D 01         [ 5]                     tst       number@@,sp
 2530    [1C4C] 1C4C:2A0F (1C5D)     [ 3]                     bpl       ToStrLoop@@
 2531    [1C4E] 1C4E:CD1B A3         [ 6]                     call      ?Negate
 2533    [1C51] 1C51:9EFE 05         [ 5]                     ldhx      .buffer@@,sp
 2540    [1C54] 1C54:A62D            [ 2]                     lda       #'-'                ;a 'minus' sign
 2541    [1C56] 1C56:F7              [ 2]                     sta       ,x                  ; is saved first
 2542
 2543    [1C57] 1C57:AF01            [ 2]                     aix       #1                  ;HX -> past minus sign
 2544    [1C59] 1C59:7F              [ 4]                     clr       ,x                  ;make it an ASCIZ string
 2546    [1C5A] 1C5A:9EFF 05         [ 5]                     sthx      .buffer@@,sp        ;update pointer past sign
 2552                                     ;                   bra       ToStrLoop@@
 2554                                     ;===============================================================================
 2555
 2556    [1C5D] 1C5D:4500 0A         [ 3] ToStrLoop@@         ldhx      #10                 ;H = 0 (always), X = divisor
 2557  M                                                      @div.s    number@@,sp
 2557  M                                                      mset      #
 2557  M                                                      mreq      1
 2557  M                                                      @@_not_x_ number23,sp
 2557  M                                                      mset      #' '
 2557  M                                                      mdel      1
 2557  M                                                      mtop
 2557  M                                                      mset      #' '
 2557  M                                                      mexit
 2557  M                                                      @@_nosize_ number23,sp
 2557  M                                                      mset      #
 2557  M                                                      mset      0,mstop [div.s] No size (number23,sp)
 2557  M                                                      endm
 2557  M                                                      #temp     1
 2557  M                                                      #temp     2
 2557  M [1C60] 1C60:86              [ 3]                     pula
 2557  M [1C61] 1C61:52              [ 6]                     div
 2557  M [1C62] 1C62:87              [ 2]                     psha
 2557  M                                                      mdo       2
 2557  M [1C63] 1C63:9EE6 02         [ 4]                     lda       number23+1,sp
 2557  M [1C66] 1C66:52              [ 6]                     div
 2557  M [1C67] 1C67:9EE7 02         [ 4]                     sta       number23+1,sp
 2557  M                                                      mloop     ::number23
 2557  M [1C6A] 1C6A:9EE6 03         [ 4]                     lda       number23+2,sp
 2557  M [1C6D] 1C6D:52              [ 6]                     div
 2557  M [1C6E] 1C6E:9EE7 03         [ 4]                     sta       number23+2,sp
 2557  M                                                      mloop     ::number23
 2557  M [1C71] 1C71:9EE6 04         [ 4]                     lda       number23+3,sp
 2557  M [1C74] 1C74:52              [ 6]                     div
 2557  M [1C75] 1C75:9EE7 04         [ 4]                     sta       number23+3,sp
 2557  M                                                      mloop     ::number23
 2557                                                         endm
 2558
 2559    [1C78] 1C78:8B86            [ 5]                     tha                           ;A = remainder
 2560    [1C7A] 1C7A:AB30            [ 2]                     add       #'0'                ;A = ASCII remainder
 2562    [1C7C] 1C7C:9EFE 05         [ 5]                     ldhx      .buffer@@,sp
 2568  M                                                      @StringInsertChar
 2568  M [1C7F] 1C7F:CD18 3A         [ 6]                     call      StringInsertChar                 ;HX and A pre-loaded correctly
 2568                                                         mexit
 2569
 2570    [1C82] 1C82:95              [ 2]                     tsx
 2571
 2572  M                                                      @_tst_.s  number@@,spx
 2572  M                                                      mset      #
 2572  M                                                      mreq      1
 2572  M                                                      @@_nosize_ number23,spx
 2572  M                                                      mset      #
 2572  M                                                      mset      0,mstop [_tst_.s] No size (number23,spx)
 2572  M                                                      endm
 2572  M                                                      mdo
 2572  M [1C83] 1C83:F6              [ 3]                     lda       number23+0,spx
 2572  M                                                      mloop     ::number23
 2572  M [1C84] 1C84:EA01            [ 3]                     ora       number23+1,spx
 2572  M                                                      mloop     ::number23
 2572  M [1C86] 1C86:EA02            [ 3]                     ora       number23+2,spx
 2572  M                                                      mloop     ::number23
 2572  M [1C88] 1C88:EA03            [ 3]                     ora       number23+3,spx
 2572  M                                                      mloop     ::number23
 2572                                                         endm
 2573    [1C8A] 1C8A:26D1 (1C5D)     [ 3]                     bne       ToStrLoop@@
 2574
 2575    [1C8C] 1C8C:A706            [ 2]                     ais       #:ais               ;free temporaries
 2576    [1C8E] 1C8E:8A88 86         [ 9]                     pull
 2577    [1C91] 1C91:81              [ 6]                     rtc
 2578
 2579                                                         #sp                           ;cancel all SP offsets
 2580
 2581                                     ;*******************************************************************************
 2582                                     ; Assign global names to the various library calls, depending on version used.
 2583                                     ; Different names for each version means you can include any at the same time.
 2584                                     ;*******************************************************************************
 2585
 2586                                     ?                   macro     BitSize             ;temp macro to export symbols
 2587                                                         mreq      1:Usage: @~0~ BitSize
 2588                                               #if MATHSIZE = ~1~
 2589                                     StackAdd~1~         exp       ?Add
 2590                                     StackSub~1~         exp       ?Subtract
 2591                                     StackMul~1~         exp       ?Multiply
 2592                                     StackDiv~1~         exp       ?Divide
 2593                                     StackMod~1~         exp       ?Modulo
 2594                                     StackSwap~1~        exp       ?Swap
 2595                                     StackAbs~1~         exp       ?Abs
 2596                                     StackNegate~1~      exp       ?Negate
 2597                                     StackLoad~1~        exp       ?Load
 2598                                     StackSave~1~        exp       ?Save
 2599                                     Stack~1~ToASCIZ     exp       ?ToStr
 2600                                               #ifdef NO_BIT_OPS
 2601                                                         mexit                         ;;bit operations not available
 2602                                               #endif
 2603                                     StackAnd~1~         exp       ?BitAnd
 2604                                     StackOr~1~          exp       ?BitOr
 2605                                     StackXor~1~         exp       ?BitXor
 2606                                     StackShl~1~         exp       ?ShiftLeft
 2607                                     StackShr~1~         exp       ?ShiftRight
 2608                                               #endif
 2609                                                         endm
 2610
 2611  M                                                      @?        64                  ;export 64-bit labels
 2611  M                                                      mreq      1:Usage: @? BitSize
 2611                                                         endm
 2612  M                                                      @?        56                  ;export 56-bit labels
 2612  M                                                      mreq      1:Usage: @? BitSize
 2612                                                         endm
 2613  M                                                      @?        48                  ;export 48-bit labels
 2613  M                                                      mreq      1:Usage: @? BitSize
 2613                                                         endm
 2614  M                                                      @?        40                  ;export 40-bit labels
 2614  M                                                      mreq      1:Usage: @? BitSize
 2614                                                         endm
 2615  M                                                      @?        32                  ;export 32-bit labels
 2615  M                                                      mreq      1:Usage: @? BitSize
 2615  M             188D                 StackAdd32         exp       ?Add
 2615  M             18A3                 StackSub32         exp       ?Subtract
 2615  M             1972                 StackMul32         exp       ?Multiply
 2615  M             19F4                 StackDiv32         exp       ?Divide
 2615  M             1A07                 StackMod32         exp       ?Modulo
 2615  M             1B82                 StackSwap32        exp       ?Swap
 2615  M             1B9E                 StackAbs32         exp       ?Abs
 2615  M             1BA3                 StackNegate32      exp       ?Negate
 2615  M             1BAE                 StackLoad32        exp       ?Load
 2615  M             1BD2                 StackSave32        exp       ?Save
 2615  M             1C3D                 Stack32ToASCIZ     exp       ?ToStr
 2615  M             18B9                 StackAnd32         exp       ?BitAnd
 2615  M             18CE                 StackOr32          exp       ?BitOr
 2615  M             18E3                 StackXor32         exp       ?BitXor
 2615  M             18F8                 StackShl32         exp       ?ShiftLeft
 2615  M             1935                 StackShr32         exp       ?ShiftRight
 2615                                                         endm
 2616  M                                                      @?        24                  ;export 24-bit labels
 2616  M                                                      mreq      1:Usage: @? BitSize
 2616                                                         endm
 2617  M                                                      @?        16                  ;export 16-bit labels
 2617  M                                                      mreq      1:Usage: @? BitSize
 2617                                                         endm
 2618
 2619                                     ;*******************************************************************************
*** 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)
   49  M                                                      @?        16,4
   49  M                                                      @@Page    4
   49  M                                                      mreq      1:PageNumber
   49  M                                                      endm
   49                                                         #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) 2020 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) 2020 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                                     ;*           : 17.04.03 v8.55 Optimized 24-bit multiply [-2 bytes]
  336                                     ;*           :                Optimized 32-bit multiply [-7 bytes]
  337                                     ;*           : 18.10.23       Suppressed possible warning from JEQ in ?DivStart
  338                                     ;*           : 19.03.04       Added warning in _DoStr macro when using StrNN
  339                                     ;*           :                when NN is different from MATHSIZE and no explicit
  340                                     ;*           :                variable is given
  341                                     ;*           : 19.10.04 v8.56 Minor HC08 mode optimization in SIGNED ?ToStr [-1 byte]
  342                                     ;*           : 20.02.12 v8.57 Replaced #Message with @Msg to silence debugging messages
  343                                     ;*******************************************************************************
  344
  345                                     ;Synopsis (replace * with 16, 24, 32, 40, 48, 56, 64 for corresponding bit version):
  346                                     ;
  347                                     ;Subroutines    Action
  348                                     ;-------------- ----------------------------
  349                                     ;StackAdd*      - TOS := TOS + [TOS+1]       (signed or unsigned) [TOS+1] removed
  350                                     ;StackSub*      - TOS := TOS - [TOS+1]       (signed or unsigned) [TOS+1] removed
  351                                     ;StackMul*      - TOS := TOS * [TOS+1]       (signed or unsigned) [TOS+1] removed
  352                                     ;StackDiv*      - TOS := TOS / [TOS+1]       (signed if SIGNED)   [TOS+1] removed
  353                                     ;StackMod*      - TOS := TOS \ [TOS+1]       (signed if SIGNED)   [TOS+1] removed
  354                                     ;StackAnd*      - TOS := TOS & [TOS+1]       (signed or unsigned) [TOS+1] removed
  355                                     ;StackOr*       - TOS := TOS | [TOS+1]       (signed or unsigned) [TOS+1] removed
  356                                     ;StackXor*      - TOS := TOS ^ [TOS+1]       (signed or unsigned) [TOS+1] removed
  357                                     ;StackShl*      - TOS := TOS < [TOS+1]       (signed or unsigned) [TOS+1] removed
  358                                     ;StackShr*      - TOS := TOS > [TOS+1]       (signed if SIGNED)   [TOS+1] removed
  359                                     ;StackSwap*     - TOS swapped with [TOS+1]   (signed or unsigned)
  360                                     ;StackAbs*      - TOS := ABS(TOS)            (signed)
  361                                     ;StackNegate*   - TOS := -TOS                (signed)
  362                                     ;StackLoad*     - Load const/variable to TOS (signed or unsigned) TOS created
  363                                     ;StackSave*     - Save TOS into variable     (signed or unsigned) TOS removed
  364                                     ;ResizeTOS      - Adjust TOS old size to new (signed or unsigned) TOS resized
  365                                     ;Stack*ToASCIZ  - Convert TOS to ASCIZ str   (signed if SIGNED)
  366                                     ;
  367                                     ;Macros             Purpose             Parameters ([...] means optional part)
  368                                     ;------------------ ------------------- ----------------------------------------
  369                                     ;Load*              Stack const or var  #Number | Variable
  370                                     ;Save*              Unstack a variable  Variable
  371                                     ;Copy*              Load* & Save*       #Number | Variable,Variable
  372                                     ;ResizeTOS          Resize TOS          #FromByteSize,#ToByteSize
  373                                     ;
  374                                     ;Add*               Addition            [Addend[,Adder[,Sum]]]
  375                                     ;Sub*               Subtraction         [Minuend[,Subtrahend[,Difference]]]
  376                                     ;Mul*               Multiplication      [Multiplicand[,Multiplier[,Product]]]
  377                                     ;Div*               Unsigned division   [Dividend[,Divisor[,Quotient]]]
  378                                     ;Mod*               Unsigned modulo     [Dividend[,Divisor[,Remainder]]]
  379                                     ;Abs*               Absolute value      [SourceVariable][,DestinationVariable]
  380                                     ;Neg*               Negation            [SourceVariable][,DestinationVariable]
  381                                     ;Swap*              Swap TOS numbers
  382                                     ;Str*               Number to ASCIZ     [Variable],[ResultString]
  383                                     ;AddDecimalPoint    ... to ASCIZ number [[#]DecimalPlaces[,[#]ASCIZ_String]]
  384
  411
  412                0010                 MATHSIZE            def       32                  ;default wordsize is 32-bit
  413
  417
  418                                     ?                   macro     BitSize
  419                                     #if MATHSIZE = ~1~
  420                                     ?WORD               equ       ~1~/8
  421                                     _STKMTH{MATHSIZE}_                                ;;specific version included
  422                                     _STAKMATH_          def       *                   ;;any version included
  423                                     #endif
  424                                                         endm
  425
  426  M                                                      @?        16                  ;16-bit quantity (on request)
  426  M             0002                 ?WORD               equ       16/8
  426  M             1C92                 _STKMTH16_
  426  M             182C                 _STAKMATH_          def       *
  426                                                         endm
  427  M                                                      @?        24                  ;24-bit quantity (on request)
  427                                                         endm
  428  M                                                      @?        32                  ;32-bit quantity (default)
  428                                                         endm
  429  M                                                      @?        40                  ;40-bit quantity (on request)
  429                                                         endm
  430  M                                                      @?        48                  ;48-bit quantity (on request)
  430                                                         endm
  431  M                                                      @?        56                  ;56-bit quantity (on request)
  431                                                         endm
  432  M                                                      @?        64                  ;64-bit quantity (on request)
  432                                                         endm
  433
  439                                                         #Message  MATHSIZE = {MATHSIZE}-bit version
  441                                                         #Message  Signed routines enabled
  443                                     ;*******************************************************************************
  444                                     ; Macros to make operations as simple as with a high-level language
  445                                     ; In operations that require two operands and a result, if only one operand is
  446                                     ; provided, then the operation is done completely on stack (no other variables
  447                                     ; used).  For example, @Add32 A,B,SUM adds A to B and places result in SUM,
  448                                     ; while @Add32 A adds the current stack top to A and leaves result on stack.
  449                                     ; You can use @Load* and @Save* to load the initial value, and store the final
  450                                     ; result, respectively.  (Replace * with 16, 24, 32, 40, 48, 56, or 64)
  451                                     ;*******************************************************************************
  452
  454
  455                                     Load16              macro     #Number|Variable    ;load constant or variable
  456                                                         @_DoLoad  ~0.{:0-1}~\,~@~
  457                                                         endm
  458
  459                                     Save16              macro     Address
  460                                                         @_DoSave  16\,~@~
  461                                                         endm
  462
  463                                     Copy16              macro     #Constant|Variable,ToAddress
  464                                                         mreq      1,2:#Constant|Variable,ToAddress
  465                                                         @@Load16  ~1~
  466                                                         @Save16   ~2~
  467                                                         endm
  468
  469                                     Swap16              macro
  470                                                         @_DoSwap  16
  471                                                         endm
  472
  473                                     Add16               macro     Addend,Adder,Sum
  474                                                         @_DoMath  ~0~\,16\,~1~\,~2~\,~3~
  475                                                         endm
  476
  477                                     Sub16               macro     Minuend,Subtrahend,Difference
  478                                                         @_DoMath  ~0~\,16\,~1~\,~2~\,~3~
  479                                                         endm
  480
  481                                     Mul16               macro     Multiplicand,Multiplier,Product
  482                                                         @_DoMath  ~0~\,16\,~1~\,~2~\,~3~
  483                                                         endm
  484
  485                                     Div16               macro     Dividend,Divisor,Quotient
  486                                                         @_DoMath  ~0~\,16\,~1~\,~2~\,~3~
  487                                                         endm
  488
  489                                     Mod16               macro     Dividend,Divisor,Remainder
  490                                                         @_DoMath  ~0~\,16\,~1~\,~2~\,~3~
  491                                                         endm
  492
  493                                     Abs16               macro     Source[,Destination]
  494                                                         @_DoAbs   16\,~1~\,~2~
  495                                                         endm
  496
  497                                     Neg16               macro     Source[,Destination]
  498                                                         @_DoNeg   16\,~1~\,~2~
  499                                                         endm
  501                                     ;===============================================================================
  550                                     ;===============================================================================
  599                                     ;===============================================================================
  648                                     ;===============================================================================
  697                                     ;===============================================================================
  746                                     ;===============================================================================
  795
  796                                     ;*******************************************************************************
  797                                     ; Common macro(s) for all operations defined above (not to be called directly)
  798                                     ;*******************************************************************************
  799
  807                                     ;-------------------------------------------------------------------------------
  867                                     ;-------------------------------------------------------------------------------
  890                                     ;-------------------------------------------------------------------------------
  898                                     ;-------------------------------------------------------------------------------
  916                                     ;===============================================================================
  933                                     ;-------------------------------------------------------------------------------
 1158                                     ;-------------------------------------------------------------------------------
 1185                                     ;-------------------------------------------------------------------------------
 1212                                     ;-------------------------------------------------------------------------------
 1288                                     ;-------------------------------------------------------------------------------
 1328                                     ;-------------------------------------------------------------------------------
 1337                                     ;-------------------------------------------------------------------------------
 1351                                     ;-------------------------------------------------------------------------------
 1380                                     ;-------------------------------------------------------------------------------
 1398                                     ;-------------------------------------------------------------------------------
 1416                                     ;-------------------------------------------------------------------------------
 1451
 1452                                     ;*******************************************************************************
 1453                                     ; External dependencies
 1454                                     ;*******************************************************************************
 1455
 1456                                                         #Uses     string/length.sub
 1457                                                         #Uses     string/insertchar.sub
 1458                                                         #Uses     string/adddecimalpoint.sub
 1459                1C92                 ?_OBJECT_?
 1460                                     ;*******************************************************************************
 1461                                     ; One-based (SP-index) offsets to stacked operands (to be used with #SPAUTO :AB)
 1462                                     ;*******************************************************************************
 1463
 1464                                                         #temp     1
 1465                0001                 ?a                  next      :temp,?WORD         ;top-of-stack (TOS) number (N1)
 1466                0003                 ?b                  next      :temp,?WORD         ;number after TOS (N2)
 1467
 1468                                                         #Cycles                       ;reset the cycles counter
 1469
 1470                                     ;*******************************************************************************
 1471                                     ; Purpose: Add N1 to N2 and place result on top-of-stack. N1 & N2 removed
 1472                                     ; Input  : [TOS+?WORD] = Number2
 1473                                     ;        : [TOS] = Number1
 1474                                     ; Output : [TOS] = Result
 1475                                     ; Note(s): Carry Set on overflow
 1476
 1477                                                         #spauto   :ab
 1478
 1479                1C92                 ?Add                proc
 1480    [1C92] 1C92:8789 8B         [ 6]                     push
 1481    [1C95] 1C95:95              [ 2]                     tsx
 1482
 1484  M                                                      @add.s    ?a,spx ?b,spx ?b,spx
 1484  M                                                      mset      #' '
 1484  M                                                      mreq      1,2,3:[#]Operand1 [#]Operand2 Destination
 1484  M                                                      @@_samesize_ ?a,spx ?b,spx ?b,spx
 1484  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1484  M                                                      mset      0
 1484  M                                                      mdo
 1484  M                                                      mswap     1,1
 1484  M                                                      @@_nosize_ ?a,spx
 1484  M                                                      mset      #
 1484  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1484  M                                                      endm
 1484  M                                                      mset      0,?a,spx
 1484  M                                                      mloop     :n
 1484  M                                                      mswap     1,2
 1484  M                                                      @@_nosize_ ?b,spx
 1484  M                                                      mset      #
 1484  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1484  M                                                      endm
 1484  M                                                      mloop     :n
 1484  M                                                      mswap     1,3
 1484  M                                                      @@_nosize_ ?b,spx
 1484  M                                                      mset      #
 1484  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1484  M                                                      endm
 1484  M                                                      mloop     :n
 1484  M                                                      endm
 1484  M                                                      mset      0,@@add.b,
 1484  M                                                      mdo
 1484  M                                                      mset      0,@@add.b, ?a+1,spx
 1484  M                                                      mset      0,@@add.b, ?a+1,spx ?b+1,spx
 1484  M                                                      mset      0,@@add.b, ?a+1,spx ?b+1,spx ?b+1,spx
 1484  M                                                      @@add.b, ?a+1,spx ?b+1,spx ?b+1,spx
 1484  M                                                      mswap     1,2
 1484  M                                                      mswap     1,2
 1484  M [1C96] 1C96:E606            [ 3]                     lda       ?a+1,spx
 1484  M [1C98] 1C98:EB08            [ 3]                     add       ?b+1,spx
 1484  M                                                      @_sta_    ?b+1,spx
 1484  M [1C9A] 1C9A:E708            [ 3]                     sta       ?b+1,spx
 1484  M                                                      endm
 1484  M                                                      mset      0,@@adc.b,
 1484  M                                                      mloop     ::?b
 1484  M                                                      mset      0,@@adc.b, ?a+0,spx
 1484  M                                                      mset      0,@@adc.b, ?a+0,spx ?b+0,spx
 1484  M                                                      mset      0,@@adc.b, ?a+0,spx ?b+0,spx ?b+0,spx
 1484  M                                                      @@adc.b, ?a+0,spx ?b+0,spx ?b+0,spx
 1484  M                                                      mswap     1,2
 1484  M                                                      mswap     1,2
 1484  M [1C9C] 1C9C:E605            [ 3]                     lda       ?a+0,spx
 1484  M [1C9E] 1C9E:E907            [ 3]                     adc       ?b+0,spx
 1484  M                                                      @_sta_    ?b+0,spx
 1484  M [1CA0] 1CA0:E707            [ 3]                     sta       ?b+0,spx
 1484  M                                                      endm
 1484  M                                                      mset      0,@@adc.b,
 1484  M                                                      mloop     ::?b
 1484                                                         endm
 1500    [1CA2] 1CA2:CC1E 67         [ 4]                     jmp       ?RemoveAndReturn
 1501
 1502                001E                 ?AddCycles          equ       :cycles
 1503
 1504                                     ;*******************************************************************************
 1505                                     ; Purpose: Subtract N2 from N1 and place result on top-of-stack. N1 & N2 removed
 1506                                     ; Input  : [TOS+?WORD] = Number2
 1507                                     ;        : [TOS] = Number1
 1508                                     ; Output : [TOS] = Result
 1509                                     ; Note(s): Carry Set on borrow
 1510
 1511                                                         #spauto   :ab
 1512
 1513                1CA5                 ?Subtract           proc
 1514    [1CA5] 1CA5:8789 8B         [ 6]                     push
 1515    [1CA8] 1CA8:95              [ 2]                     tsx
 1517  M                                                      @sub.s    ?a,spx ?b,spx ?b,spx
 1517  M                                                      mset      #' '
 1517  M                                                      mreq      1,2:[#]Operand1 [#]Operand2 Destination
 1517  M                                                      @@_samesize_ ?a,spx ?b,spx ?b,spx
 1517  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1517  M                                                      mset      0
 1517  M                                                      mdo
 1517  M                                                      mswap     1,1
 1517  M                                                      @@_nosize_ ?a,spx
 1517  M                                                      mset      #
 1517  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1517  M                                                      endm
 1517  M                                                      mset      0,?a,spx
 1517  M                                                      mloop     :n
 1517  M                                                      mswap     1,2
 1517  M                                                      @@_nosize_ ?b,spx
 1517  M                                                      mset      #
 1517  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1517  M                                                      endm
 1517  M                                                      mloop     :n
 1517  M                                                      mswap     1,3
 1517  M                                                      @@_nosize_ ?b,spx
 1517  M                                                      mset      #
 1517  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1517  M                                                      endm
 1517  M                                                      mloop     :n
 1517  M                                                      endm
 1517  M                                                      #temp
 1517  M                                                      @@_nosize_ ?b,spx
 1517  M                                                      mset      #
 1517  M                                                      mset      0,mstop [sub.s] No size (?b,spx)
 1517  M                                                      endm
 1517  M                                                      #temp     ::?b
 1517  M                                                      mset      0,sub
 1517  M                                                      mdo
 1517  M [1CA9] 1CA9:E606            [ 3]                     lda       ?a+1,spx
 1517  M [1CAB] 1CAB:E008            [ 3]                     sub    ?b+1,spx
 1517  M [1CAD] 1CAD:E708            [ 3]                     sta       ?b+1,spx
 1517  M                                                      mset      0,sbc
 1517  M                                                      mloop     :temp
 1517  M [1CAF] 1CAF:E605            [ 3]                     lda       ?a+0,spx
 1517  M [1CB1] 1CB1:E207            [ 3]                     sbc    ?b+0,spx
 1517  M [1CB3] 1CB3:E707            [ 3]                     sta       ?b+0,spx
 1517  M                                                      mset      0,sbc
 1517  M                                                      mloop     :temp
 1517                                                         endm
 1533    [1CB5] 1CB5:CC1E 67         [ 4]                     jmp       ?RemoveAndReturn
 1534
 1535                001E                 ?SubCycles          equ       :cycles
 1536
 1540  M                                                      @Msg      Bit ops enabled (define NO_BIT_OPS to disable)
 1540                                                         mexit
 1541                                     ;*******************************************************************************
 1542                                     ; Purpose: AND N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1543                                     ; Input  : [TOS+?WORD] = Number2
 1544                                     ;        : [TOS] = Number1
 1545                                     ; Output : [TOS] = Result
 1546                                     ; Note(s):
 1547                                                         #spauto   :ab
 1548
 1549                1CB8                 ?BitAnd             proc
 1550    [1CB8] 1CB8:8789 8B         [ 6]                     push
 1551    [1CBB] 1CBB:95              [ 2]                     tsx
 1552
 1554  M                                                      @and.s    ?a,spx ?b,spx ?b,spx
 1554  M                                                      mset      #' '
 1554  M                                                      mreq      1,2,3:[#]Operand1 [#]Operand2 Destination
 1554  M                                                      @@_samesize_ ?a,spx ?b,spx ?b,spx
 1554  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1554  M                                                      mset      0
 1554  M                                                      mdo
 1554  M                                                      mswap     1,1
 1554  M                                                      @@_nosize_ ?a,spx
 1554  M                                                      mset      #
 1554  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1554  M                                                      endm
 1554  M                                                      mset      0,?a,spx
 1554  M                                                      mloop     :n
 1554  M                                                      mswap     1,2
 1554  M                                                      @@_nosize_ ?b,spx
 1554  M                                                      mset      #
 1554  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1554  M                                                      endm
 1554  M                                                      mloop     :n
 1554  M                                                      mswap     1,3
 1554  M                                                      @@_nosize_ ?b,spx
 1554  M                                                      mset      #
 1554  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1554  M                                                      endm
 1554  M                                                      mloop     :n
 1554  M                                                      endm
 1554  M                                                      mdo
 1554  M [1CBC] 1CBC:E605            [ 3]                     lda       ?a+0,spx
 1554  M [1CBE] 1CBE:E407            [ 3]                     and       ?b+0,spx
 1554  M [1CC0] 1CC0:E707            [ 3]                     sta       ?b+0,spx
 1554  M                                                      mloop     ::?b
 1554  M [1CC2] 1CC2:E606            [ 3]                     lda       ?a+1,spx
 1554  M [1CC4] 1CC4:E408            [ 3]                     and       ?b+1,spx
 1554  M [1CC6] 1CC6:E708            [ 3]                     sta       ?b+1,spx
 1554  M                                                      mloop     ::?b
 1554                                                         endm
 1569    [1CC8] 1CC8:CC1E 67         [ 4]                     jmp       ?RemoveAndReturn
 1570
 1571                001E                 ?AndCycles          equ       :cycles
 1572
 1573                                     ;*******************************************************************************
 1574                                     ; Purpose: OR N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1575                                     ; Input  : [TOS+?WORD] = Number2
 1576                                     ;        : [TOS] = Number1
 1577                                     ; Output : [TOS] = Result
 1578                                     ; Note(s):
 1579                                                         #spauto   :ab
 1580
 1581                1CCB                 ?BitOr              proc
 1582    [1CCB] 1CCB:8789 8B         [ 6]                     push
 1583    [1CCE] 1CCE:95              [ 2]                     tsx
 1584
 1586  M                                                      @ora.s    ?a,spx ?b,spx ?b,spx
 1586  M                                                      mset      #' '
 1586  M                                                      mreq      1,2,3:[#]Operand1 [#]Operand2 Destination
 1586  M                                                      @@_samesize_ ?a,spx ?b,spx ?b,spx
 1586  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1586  M                                                      mset      0
 1586  M                                                      mdo
 1586  M                                                      mswap     1,1
 1586  M                                                      @@_nosize_ ?a,spx
 1586  M                                                      mset      #
 1586  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1586  M                                                      endm
 1586  M                                                      mset      0,?a,spx
 1586  M                                                      mloop     :n
 1586  M                                                      mswap     1,2
 1586  M                                                      @@_nosize_ ?b,spx
 1586  M                                                      mset      #
 1586  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1586  M                                                      endm
 1586  M                                                      mloop     :n
 1586  M                                                      mswap     1,3
 1586  M                                                      @@_nosize_ ?b,spx
 1586  M                                                      mset      #
 1586  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1586  M                                                      endm
 1586  M                                                      mloop     :n
 1586  M                                                      endm
 1586  M                                                      mdo
 1586  M [1CCF] 1CCF:E605            [ 3]                     lda       ?a+0,spx
 1586  M [1CD1] 1CD1:EA07            [ 3]                     ora       ?b+0,spx
 1586  M [1CD3] 1CD3:E707            [ 3]                     sta       ?b+0,spx
 1586  M                                                      mloop     ::?b
 1586  M [1CD5] 1CD5:E606            [ 3]                     lda       ?a+1,spx
 1586  M [1CD7] 1CD7:EA08            [ 3]                     ora       ?b+1,spx
 1586  M [1CD9] 1CD9:E708            [ 3]                     sta       ?b+1,spx
 1586  M                                                      mloop     ::?b
 1586                                                         endm
 1601    [1CDB] 1CDB:CC1E 67         [ 4]                     jmp       ?RemoveAndReturn
 1602
 1603                001E                 ?OrCycles           equ       :cycles
 1604
 1605                                     ;*******************************************************************************
 1606                                     ; Purpose: XOR N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1607                                     ; Input  : [TOS+?WORD] = Number2
 1608                                     ;        : [TOS] = Number1
 1609                                     ; Output : [TOS] = Result
 1610                                     ; Note(s):
 1611                                                         #spauto   :ab
 1612
 1613                1CDE                 ?BitXor             proc
 1614    [1CDE] 1CDE:8789 8B         [ 6]                     push
 1615    [1CE1] 1CE1:95              [ 2]                     tsx
 1616
 1618  M                                                      @eor.s    ?a,spx ?b,spx ?b,spx
 1618  M                                                      mset      #' '
 1618  M                                                      mreq      1,2,3:[#]Operand1 [#]Operand2 Destination
 1618  M                                                      @@_samesize_ ?a,spx ?b,spx ?b,spx
 1618  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1618  M                                                      mset      0
 1618  M                                                      mdo
 1618  M                                                      mswap     1,1
 1618  M                                                      @@_nosize_ ?a,spx
 1618  M                                                      mset      #
 1618  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1618  M                                                      endm
 1618  M                                                      mset      0,?a,spx
 1618  M                                                      mloop     :n
 1618  M                                                      mswap     1,2
 1618  M                                                      @@_nosize_ ?b,spx
 1618  M                                                      mset      #
 1618  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1618  M                                                      endm
 1618  M                                                      mloop     :n
 1618  M                                                      mswap     1,3
 1618  M                                                      @@_nosize_ ?b,spx
 1618  M                                                      mset      #
 1618  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1618  M                                                      endm
 1618  M                                                      mloop     :n
 1618  M                                                      endm
 1618  M                                                      mdo
 1618  M [1CE2] 1CE2:E605            [ 3]                     lda       ?a+0,spx
 1618  M [1CE4] 1CE4:E807            [ 3]                     eor       ?b+0,spx
 1618  M [1CE6] 1CE6:E707            [ 3]                     sta       ?b+0,spx
 1618  M                                                      mloop     ::?b
 1618  M [1CE8] 1CE8:E606            [ 3]                     lda       ?a+1,spx
 1618  M [1CEA] 1CEA:E808            [ 3]                     eor       ?b+1,spx
 1618  M [1CEC] 1CEC:E708            [ 3]                     sta       ?b+1,spx
 1618  M                                                      mloop     ::?b
 1618                                                         endm
 1633    [1CEE] 1CEE:CC1E 67         [ 4]                     jmp       ?RemoveAndReturn
 1634
 1635                001E                 ?EorCycles          equ       :cycles
 1636
 1637                                     ;*******************************************************************************
 1638                                     ; Purpose: Shift N1 left N2 times and place result on top-of-stack. N1 & N2 removed
 1639                                     ; Input  : [TOS+?WORD] = Number2
 1640                                     ;        : [TOS] = Number1
 1641                                     ; Output : [TOS] = Result
 1642                                     ; Note(s): CCR[C] = last most significant bit shifted out
 1643                                     ;        : Only LSB of second operand (N2) is used, as shifting more than the
 1644                                     ;        : highest bit version always produces zero.  Any non-zero bytes in the
 1645                                     ;        : N2 operand will cause a zero result, regardless.
 1646
 1647                                                         #spauto   :ab
 1648
 1649                1CF1                 ?ShiftLeft          proc
 1650    [1CF1] 1CF1:8789 8B         [ 6]                     push
 1651                                                         #ais
 1652
 1653    [1CF4] 1CF4:9EE6 09         [ 4]                     lda       ?b+{::?b-1},sp      ;A = shift counter
 1654    [1CF7] 1CF7:87              [ 2]                     psha      counter@@
 1655
 1656    [1CF8] 1CF8:95              [ 2]                     tsx
 1657
 1658    [1CF9] 1CF9:6F09            [ 5]                     clr       ?b+{::?b-1},spx     ;clear original shift counter
 1659                0003                 b@@                 equ       ?b,::?b-1           ;(b@@ = ?b but excludes final already cleared byte - 2013.11.29 optimization)
 1660  M                                                      @_tst_.s, b@@,spx             ;test whole word for zero (counter <= 8-bit)
 1660  M                                                      mset      #
 1660  M                                                      mreq      1
 1660  M                                                      @@_nosize_ b29,spx
 1660  M                                                      mset      #
 1660  M                                                      mset      0,mstop [_tst_.s] No size (b29,spx)
 1660  M                                                      endm
 1660  M [1CFB] 1CFB:6D08            [ 4]                     tst       b29,spx
 1660                                                         mexit
 1661    [1CFD] 1CFD:2709 (1D08)     [ 3]                     beq       Go@@                ;if so, proceed normally
 1662
 1663    [1CFF] 1CFF:F6              [ 3]                     lda       counter@@,spx       ;if shift counter is less than
 1664    [1D00] 1D00:A110            [ 2]                     cmpa      #MATHSIZE           ;MATHSIZE, proceed normally,
 1665    [1D02] 1D02:2504 (1D08)     [ 3]                     blo       Go@@                ;else zero and exit
 1666
 1667  M                                                      @clr.s,   b@@,spx             ;else error, so zero result
 1667  M                                                      mset      #' '
 1667  M                                                      mreq      1
 1667  M                                                      @@_nosize_ b29,spx
 1667  M                                                      mset      #
 1667  M                                                      mset      0,mstop [clr.s] No size (b29,spx)
 1667  M                                                      endm
 1667  M                                                      mdef      2,::b29
 1667  M                                                      mdo
 1667  M [1D04] 1D04:6F08            [ 5]                     clr       b29+0,spx
 1667  M                                                      mloop     ::b29
 1667                                                         endm
 1668    [1D06] 1D06:200E (1D16)     [ 3]                     bra       Done@@              ;and get out
 1669
 1670  M                                  Go@@                @mova.s   ?a,spx ?b,spx       ;copy operand to result
 1670  M                                                      mset      #' '
 1670  M                                                      mreq      1,2:Source Destination
 1670  M                                                      @@_samesize_ ?a,spx ?b,spx
 1670  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1670  M                                                      mset      0
 1670  M                                                      mdo
 1670  M                                                      mswap     1,1
 1670  M                                                      @@_nosize_ ?a,spx
 1670  M                                                      mset      #
 1670  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1670  M                                                      endm
 1670  M                                                      mset      0,?a,spx
 1670  M                                                      mloop     :n
 1670  M                                                      mswap     1,2
 1670  M                                                      @@_nosize_ ?b,spx
 1670  M                                                      mset      #
 1670  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1670  M                                                      endm
 1670  M                                                      mloop     :n
 1670  M                                                      endm
 1670  M                                                      mset      0
 1670  M                                                      mdo
 1670  M [1D08] 1D08:E606            [ 3]                     lda       ?a+0,spx
 1670  M [1D0A] 1D0A:E708            [ 3]                     sta       ?b+0,spx
 1670  M                                                      mloop     ::?b
 1670  M [1D0C] 1D0C:E607            [ 3]                     lda       ?a+1,spx
 1670  M [1D0E] 1D0E:E709            [ 3]                     sta       ?b+1,spx
 1670  M                                                      mloop     ::?b
 1670                                                         endm
 1671                                                                   #Cycles
 1672  M                                  Loop@@              @lsl.s,   ?b,spx              ;shift left one bit position
 1672  M                                                      mset      #
 1672  M                                                      mreq      1
 1672  M                                                      @@_nosize_ ?b,spx
 1672  M                                                      mset      #
 1672  M                                                      mset      0,mstop [lsl.s] No size (?b,spx)
 1672  M                                                      endm
 1672  M                                                      mdo
 1672  M [1D10] 1D10:6809            [ 5]                     lsl       ?b+1,spx
 1672  M                                                      mloop     ::?b
 1672  M [1D12] 1D12:6908            [ 5]                     rol       ?b+0,spx
 1672  M                                                      mloop     ::?b
 1672                                                         endm
 1673    [1D14] 1D14:7BFA (1D10)     [ 6]                     dbnz      counter@@,spx,Loop@@ ;repeat for all bits
 1674                                                                   #Cycles :cycles*{MATHSIZE-1}+:ocycles
 1675                1D16                 Done@@
 1677    [1D16] 1D16:86              [ 3]                     pula
 1681    [1D17] 1D17:CC1E 67         [ 4]                     jmp       ?RemoveAndReturn
 1682
 1683                012D                 ?ShlCycles          equ       :cycles
 1684
 1685                                     ;*******************************************************************************
 1686                                     ; Purpose: Shift N1 right N2 times and place result on top-of-stack. N1 & N2 removed
 1687                                     ; Input  : [TOS+?WORD] = Number2
 1688                                     ;        : [TOS] = Number1
 1689                                     ; Output : [TOS] = Result
 1690                                     ; Note(s): CCR[C] = last least significant bit shifted out
 1691                                     ;        : Only LSB of second operand (N2) is used, as shifting more than the
 1692                                     ;        : highest bit version always produces zero.  Any non-zero bytes in the
 1693                                     ;        : N2 operand will cause a zero result, regardless.
 1694
 1695                                                         #spauto   :ab
 1696
 1697                1D1A                 ?ShiftRight         proc
 1698    [1D1A] 1D1A:8789 8B         [ 6]                     push
 1699                                                         #ais
 1700
 1701    [1D1D] 1D1D:9EE6 09         [ 4]                     lda       ?b+{::?b-1},sp      ;A = shift counter
 1702    [1D20] 1D20:87              [ 2]                     psha      counter@@
 1703
 1704    [1D21] 1D21:95              [ 2]                     tsx
 1705
 1706    [1D22] 1D22:6F09            [ 5]                     clr       ?b+{::?b-1},spx     ;clear original shift counter
 1707                0003                 b@@                 equ       ?b,::?b-1           ;(b@@ = ?b but excludes final already cleared byte - 2013.11.29 optimization)
 1708  M                                                      @_tst_.s, b@@,spx             ;test whole word for zero (counter <= 8-bit)
 1708  M                                                      mset      #
 1708  M                                                      mreq      1
 1708  M                                                      @@_nosize_ b30,spx
 1708  M                                                      mset      #
 1708  M                                                      mset      0,mstop [_tst_.s] No size (b30,spx)
 1708  M                                                      endm
 1708  M [1D24] 1D24:6D08            [ 4]                     tst       b30,spx
 1708                                                         mexit
 1709    [1D26] 1D26:2709 (1D31)     [ 3]                     beq       Go@@                ;if so, proceed normally
 1710
 1711    [1D28] 1D28:F6              [ 3]                     lda       counter@@,spx       ;if shift counter is less than
 1712    [1D29] 1D29:A110            [ 2]                     cmpa      #MATHSIZE           ;MATHSIZE, proceed normally,
 1713    [1D2B] 1D2B:2504 (1D31)     [ 3]                     blo       Go@@                ;else zero and exit
 1714
 1715  M                                                      @clr.s,   b@@,spx             ;else error, so zero result
 1715  M                                                      mset      #' '
 1715  M                                                      mreq      1
 1715  M                                                      @@_nosize_ b30,spx
 1715  M                                                      mset      #
 1715  M                                                      mset      0,mstop [clr.s] No size (b30,spx)
 1715  M                                                      endm
 1715  M                                                      mdef      2,::b30
 1715  M                                                      mdo
 1715  M [1D2D] 1D2D:6F08            [ 5]                     clr       b30+0,spx
 1715  M                                                      mloop     ::b30
 1715                                                         endm
 1716    [1D2F] 1D2F:200E (1D3F)     [ 3]                     bra       Done@@              ;and get out
 1717
 1718  M                                  Go@@                @mova.s   ?a,spx ?b,spx       ;copy operand to result
 1718  M                                                      mset      #' '
 1718  M                                                      mreq      1,2:Source Destination
 1718  M                                                      @@_samesize_ ?a,spx ?b,spx
 1718  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 1718  M                                                      mset      0
 1718  M                                                      mdo
 1718  M                                                      mswap     1,1
 1718  M                                                      @@_nosize_ ?a,spx
 1718  M                                                      mset      #
 1718  M                                                      mset      0,mstop [_samesize_] No size (?a,spx)
 1718  M                                                      endm
 1718  M                                                      mset      0,?a,spx
 1718  M                                                      mloop     :n
 1718  M                                                      mswap     1,2
 1718  M                                                      @@_nosize_ ?b,spx
 1718  M                                                      mset      #
 1718  M                                                      mset      0,mstop [_samesize_] No size (?b,spx)
 1718  M                                                      endm
 1718  M                                                      mloop     :n
 1718  M                                                      endm
 1718  M                                                      mset      0
 1718  M                                                      mdo
 1718  M [1D31] 1D31:E606            [ 3]                     lda       ?a+0,spx
 1718  M [1D33] 1D33:E708            [ 3]                     sta       ?b+0,spx
 1718  M                                                      mloop     ::?b
 1718  M [1D35] 1D35:E607            [ 3]                     lda       ?a+1,spx
 1718  M [1D37] 1D37:E709            [ 3]                     sta       ?b+1,spx
 1718  M                                                      mloop     ::?b
 1718                                                         endm
 1719                                                                   #Cycles
 1720                1D39                 Loop@@
 1722  M                                                      @asr.s,   ?b,spx              ;shift right one bit position
 1722  M                                                      mset      #
 1722  M                                                      mreq      1
 1722  M                                                      @@_nosize_ ?b,spx
 1722  M                                                      mset      #
 1722  M                                                      mset      0,mstop [asr.s] No size (?b,spx)
 1722  M                                                      endm
 1722  M                                                      mdo
 1722  M [1D39] 1D39:6708            [ 5]                     asr       ?b+0,spx
 1722  M                                                      mloop     ::?b
 1722  M [1D3B] 1D3B:6609            [ 5]                     ror       ?b+1,spx
 1722  M                                                      mloop     ::?b
 1722                                                         endm
 1726    [1D3D] 1D3D:7BFA (1D39)     [ 6]                     dbnz      counter@@,spx,Loop@@ ;repeat for all bits
 1727                                                                   #Cycles :cycles*{MATHSIZE-1}+:ocycles
 1728                1D3F                 Done@@
 1730    [1D3F] 1D3F:86              [ 3]                     pula
 1734    [1D40] 1D40:CC1E 67         [ 4]                     jmp       ?RemoveAndReturn
 1735
 1736                012D                 ?ShrCycles          equ       :cycles
 1738
 1739                                     ;*******************************************************************************
 1740                                     ; Purpose: Multiply N1 with N2 and place result on top-of-stack. N1 & N2 removed
 1741                                     ; Input  : [TOS+?WORD] = Number2
 1742                                     ;        : [TOS] = Number1
 1743                                     ; Output : [TOS] = Result
 1744                                     ; Note(s): Overflows lost, Carry state should be ignored
 1745
 1746                                                         #spauto   :ab
 1747
 1748                1D43                 ?Multiply           proc
 1749    [1D43] 1D43:8789 8B         [ 6]                     push
 1751                                               ;-------------------------------------- ;row 1
 1752    [1D46] 1D46:95              [ 2]                     tsx
 1753    [1D47] 1D47:E606            [ 3]                     lda       ?a+1,spx
 1754    [1D49] 1D49:EE08            [ 3]                     ldx       ?b+1,spx
 1755    [1D4B] 1D4B:42              [ 5]                     mul
 1756    [1D4C] 1D4C:8789            [ 4]                     pshxa     ans@@               ;temporary 16-bit result (2nd byte)
 1757
 1758    [1D4E] 1D4E:95              [ 2]                     tsx
 1759    [1D4F] 1D4F:E608            [ 3]                     lda       ?a+1,spx
 1760    [1D51] 1D51:EE09            [ 3]                     ldx       ?b+0,spx
 1761    [1D53] 1D53:42              [ 5]                     mul
 1762    [1D54] 1D54:95              [ 2]                     tsx
 1763    [1D55] 1D55:FB              [ 3]                     add       ans@@,spx
 1764    [1D56] 1D56:F7              [ 2]                     sta       ans@@,spx
 1765                                               ;-------------------------------------- ;row 2
 1766    [1D57] 1D57:E607            [ 3]                     lda       ?a+0,spx
 1767    [1D59] 1D59:EE0A            [ 3]                     ldx       ?b+1,spx
 1768    [1D5B] 1D5B:42              [ 5]                     mul
 1769    [1D5C] 1D5C:95              [ 2]                     tsx
 1770    [1D5D] 1D5D:FB              [ 3]                     add       ans@@,spx
 1771    [1D5E] 1D5E:F7              [ 2]                     sta       ans@@,spx
 1773                                     ;===============================================================================
 1826                                     ;===============================================================================
 1913                                                                   #temp :cycles
 1914                                     ;===============================================================================
 1915                                               ;--------------------------------------
 1916                                               ; 40, 48, 56, and 64-bit versions use shorter
 1917                                               ; shift/add method (more cycles, though)
 1918                                               ;--------------------------------------
 1945                                               ;--------------------------------------
 1946                                               ; copy result to B while removing from stack
 1947                                               ;--------------------------------------
 1948    [1D5F] 1D5F:AE02            [ 2]                     ldx       #?WORD
 1949                                                                   #temp :cycles+:temp
 1950    [1D61] 1D61:86              [ 3] CopyResult@@        pula
 1951    [1D62] 1D62:9EE7 09         [ 4]                     sta       ?b,sp
 1952    [1D65] 1D65:5BFA (1D61)     [ 4]                     dbnzx     CopyResult@@
 1953
 1954                                                         #spadd    1-?WORD
 1955                                                                   #temp :cycles*?WORD+:temp
 1956    [1D67] 1D67:CC1E 67         [ 4]                     jmp       ?RemoveAndReturn
 1957
 1958                0059                 ?MulCycles          equ       :temp+:cycles
 1959
 1960                                     ;*******************************************************************************
 1961                                     ; Purpose: Divide N1 by N2 and place quotient on top-of-stack. N1 & N2 removed
 1962                                     ; Input  : [TOS+?WORD] = Divisor (N2)
 1963                                     ;        : [TOS] = Dividend (N1)
 1964                                     ; Output : [TOS] = Quotient
 1965                                     ;        : Carry Set on error (division by zero)
 1966                                     ; Note(s):
 1967                                                         #spauto   :ab
 1968
 1969                1D6A                 ?Divide             proc
 1970    [1D6A] 1D6A:8789 8B         [ 6]                     push
 1971
 1972    [1D6D] 1D6D:A601            [ 2]                     lda       #?DIVOP_            ;flag for DIV operation
 1974    [1D6F] 1D6F:87              [ 2]                     psha
 1975    [1D70] 1D70:95              [ 2]                     tsx
 1976    [1D71] 1D71:E606            [ 3]                     lda       ?a,spx
 1977    [1D73] 1D73:E808            [ 3]                     eor       ?b,spx
 1978    [1D75] 1D75:86              [ 3]                     pula
 1979    [1D76] 1D76:2A02 (1D7A)     [ 3]                     bpl       Skip@@
 1980    [1D78] 1D78:AA80            [ 2]                     ora       #?SIGN_             ;flag for negative
 1981                1D7A                 Skip@@
 1983    [1D7A] 1D7A:87              [ 2]                     psha                          ;save flags on stack
 1984    [1D7B] 1D7B:201E (1D9B)     [ 3]                     bra       ?DivStart
 1985
 1986                001F                 ?DivCycles          equ       :cycles
 1987
 1988                                     ;*******************************************************************************
 1989                                     ; Purpose: Divide N1 by N2 and place remainder on top-of-stack. N1 & N2 removed
 1990                                     ; Input  : [TOS+?WORD] = Divisor (N2)
 1991                                     ;        : [TOS] = Dividend (N1)
 1992                                     ; Output : [TOS] = Remainder
 1993                                     ;        : Carry Set on error (division by zero)
 1994                                     ; Note(s):
 1995                                                         #spauto   :ab
 1996                FFFFFFFF             ?pc                 equ       ::,:ab
 1997
 1998                1D7D                 ?Modulo             proc
 1999    [1D7D] 1D7D:8789 8B         [ 6]                     push
 2000
 2001    [1D80] 1D80:4F              [ 1]                     clra                          ;flag for MOD operation
 2003    [1D81] 1D81:9E6D 06         [ 5]                     tst       ?a,sp
 2004    [1D84] 1D84:2A02 (1D88)     [ 3]                     bpl       Skip@@
 2005    [1D86] 1D86:AA80            [ 2]                     ora       #?SIGN_             ;flag for negative
 2006                1D88                 Skip@@
 2008    [1D88] 1D88:87              [ 2]                     psha                          ;save flags on stack
 2009    [1D89] 1D89:2010 (1D9B)     [ 3]                     bra       ?DivStart
 2010
 2011                0016                 ?ModCycles          equ       :cycles
 2012
 2013                                     ;*******************************************************************************
 2014
 2015                                                         #temp
 2017                1D8B                 ?AbsX               proc
 2018    [1D8B] 1D8B:7D              [ 3]                     tst       ,ax
 2019    [1D8C] 1D8C:2A06 (1D94)     [ 3]                     bpl       Done@@
 2020                                                                   #temp :cycles
 2021                0000                 var@@               equ       0,?WORD
 2022  M                                  ?NegX               @neg.s    var@@,ax
 2022  M                                                      mset      #
 2022  M                                                      mreq      1
 2022  M                                                      @@_nosize_ var34,ax
 2022  M                                                      mset      #
 2022  M                                                      mset      0,mstop [neg.s] No size (var34,ax)
 2022  M                                                      endm
 2022  M                                                      mdo
 2022  M [1D8E] 1D8E:73              [ 4]                     com       var34+0,ax
 2022  M                                                      mloop     ::var34-1
 2022  M [1D8F] 1D8F:6001            [ 5]                     neg       var34+1,ax
 2022  M                                                      mdo
 2022  M [1D91] 1D91:2601 (1D94)     [ 3]                     bne       Done$$$
 2022  M [1D93] 1D93:7C              [ 4]                     inc       var34+0,ax
 2022  M                                                      mloop     ::var34-1
 2022  M             1D94                 Done$$$
 2022                                                         endm
 2023    [1D94] 1D94:81              [ 6] Done@@              rts
 2024
 2025                0016                 ?AbsXCycles         equ       :cycles
 2026                0010                 ?NegxCycles         equ       ?AbsXCycles-:temp
 2028
 2029                                     ;*******************************************************************************
 2030
 2031                0000                 ?SF                 equ       0                   ;stack frame (for X-index use)
 2032
 2033                0000                 ?quotient           next      ?SF,?WORD
 2034                0002                 ?remainder          next      ?SF,?WORD
 2035                0004                 ?temp               next      ?SF,?WORD
 2036                0006                 ?bits               next      ?SF
 2037                0007                 ?flags              next      ?SF
 2038
 2039                0001                 ?DIVOP_             equ       %00000001           ;1 = DIV, 0 = MOD
 2040                0080                 ?SIGN_              equ       %10000000           ;result sign (1 = negative)
 2041
 2042                                                         #push
 2043
 2044    [1D95] 1D95:A708            [ 2] ?DivError           ais       #?SF                ;de-allocate temporaries
 2045    [1D97] 1D97:99              [ 1]                     sec                           ;indicate error condition
 2046    [1D98] 1D98:CC1E 67         [ 4]                     jmp       ?RemoveAndReturn
 2047
 2048                                                         #pull
 2049                                     ;-------------------------------------------------------------------------------
 2050                1D9B                 ?DivStart           proc
 2051                0001                 dividend@@          equ       ?a,::?a
 2052                0003                 divisor@@           equ       ?b,::?b
 2053                0003                 ans@@               equ       ?b,::?b             ;result overwrites divisor
 2054
 2056  M                                                      @lea      dividend@@,sp
 2056  M                                                      mset      #
 2056  M [1D9B] 1D9B:95              [ 2]                     tsx
 2056  M [1D9C] 1D9C:AF06            [ 2]                     !aix      #dividend35+:tsx
 2056                                                         mexit
 2057    [1D9E] 1D9E:ADEB (1D8B)     [ 5]                     bsr       ?AbsX
 2058  M                                                      @lea      divisor@@,sp
 2058  M                                                      mset      #
 2058  M [1DA0] 1DA0:95              [ 2]                     tsx
 2058  M [1DA1] 1DA1:AF08            [ 2]                     !aix      #divisor35+:tsx
 2058                                                         mexit
 2059    [1DA3] 1DA3:ADE6 (1D8B)     [ 5]                     bsr       ?AbsX
 2060                                                                   #Cycles ?AbsXCycles*2+:cycles
 2062    [1DA5] 1DA5:A7F9            [ 2]                     ais       #-?SF+1             ;quotient, remainder, and temp
 2063    [1DA7] 1DA7:95              [ 2]                     tsx                           ;(+1 for already pushed Flag)
 2064
 2065                                               ; remainder := 0
 2066                                               ; quotient := 0
 2067
 2068  M                                                      @clr.s    ?remainder,x
 2068  M                                                      mset      #' '
 2068  M                                                      mreq      1
 2068  M                                                      @@_nosize_ ?remainder,x
 2068  M                                                      mset      #
 2068  M                                                      mset      0,mstop [clr.s] No size (?remainder,x)
 2068  M                                                      endm
 2068  M                                                      mdef      2,::?remainder
 2068  M                                                      mdo
 2068  M [1DA8] 1DA8:6F02            [ 5]                     clr       ?remainder+0,x
 2068  M                                                      mloop     ::?remainder
 2068  M [1DAA] 1DAA:6F03            [ 5]                     clr       ?remainder+1,x
 2068  M                                                      mloop     ::?remainder
 2068                                                         endm
 2069  M                                                      @clr.s    ?quotient,x
 2069  M                                                      mset      #' '
 2069  M                                                      mreq      1
 2069  M                                                      @@_nosize_ ?quotient,x
 2069  M                                                      mset      #
 2069  M                                                      mset      0,mstop [clr.s] No size (?quotient,x)
 2069  M                                                      endm
 2069  M                                                      mdef      2,::?quotient
 2069  M                                                      mdo
 2069  M [1DAC] 1DAC:7F              [ 4]                     clr       ?quotient+0,x
 2069  M                                                      mloop     ::?quotient
 2069  M [1DAD] 1DAD:6F01            [ 5]                     clr       ?quotient+1,x
 2069  M                                                      mloop     ::?quotient
 2069                                                         endm
 2070
 2071                                               ; first, test for division by zero error
 2072
 2073  M                                                      @_tst_.s  divisor@@,spx
 2073  M                                                      mset      #
 2073  M                                                      mreq      1
 2073  M                                                      @@_nosize_ divisor35,spx
 2073  M                                                      mset      #
 2073  M                                                      mset      0,mstop [_tst_.s] No size (divisor35,spx)
 2073  M                                                      endm
 2073  M                                                      mdo
 2073  M [1DAF] 1DAF:E60F            [ 3]                     lda       divisor35+0,spx
 2073  M                                                      mloop     ::divisor35
 2073  M [1DB1] 1DB1:EA10            [ 3]                     ora       divisor35+1,spx
 2073  M                                                      mloop     ::divisor35
 2073                                                         endm
 2074    [1DB3] 1DB3:27E0 (1D95)     [ 3]                     beq       ?DivError
 2075
 2076                                               ; if Dividend = 0, we're done
 2077
 2078  M                                                      @_tst_.s  dividend@@,spx
 2078  M                                                      mset      #
 2078  M                                                      mreq      1
 2078  M                                                      @@_nosize_ dividend35,spx
 2078  M                                                      mset      #
 2078  M                                                      mset      0,mstop [_tst_.s] No size (dividend35,spx)
 2078  M                                                      endm
 2078  M                                                      mdo
 2078  M [1DB5] 1DB5:E60D            [ 3]                     lda       dividend35+0,spx
 2078  M                                                      mloop     ::dividend35
 2078  M [1DB7] 1DB7:EA0E            [ 3]                     ora       dividend35+1,spx
 2078  M                                                      mloop     ::dividend35
 2078                                                         endm
 2079    [1DB9] 1DB9:2603 CC1E 43    [ 7]                     !jeq      Done@@
 2080
 2081                                               ; if (divisor = dividend) then quotient := 1; return
 2082                                               ; if (divisor > dividend) then remainder := dividend; return
 2083
 2084  M                                                      @_cmp_.s  divisor@@,spx dividend@@,spx
 2084  M                                                      mset      #' '
 2084  M                                                      mreq      1,2:[#]Operand1 [#]Operand2
 2084  M                                                      @@_samesize_ divisor35,spx dividend@@,spx
 2084  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2084  M                                                      mset      0
 2084  M                                                      mdo
 2084  M                                                      mswap     1,1
 2084  M                                                      @@_nosize_ divisor35,spx
 2084  M                                                      mset      #
 2084  M                                                      mset      0,mstop [_samesize_] No size (divisor35,spx)
 2084  M                                                      endm
 2084  M                                                      mset      0,divisor35,spx
 2084  M                                                      mloop     :n
 2084  M                                                      mswap     1,2
 2084  M                                                      @@_nosize_ dividend@@,spx
 2084  M                                                      mset      #
 2084  M                                                      mset      0,mstop [_samesize_] No size (dividend35,spx)
 2084  M                                                      endm
 2084  M                                                      mloop     :n
 2084  M                                                      endm
 2084  M                                                      #temp     1
 2084  M                                                      #temp     ::divisor35
 2084  M                                                      #temp     ::dividend@@
 2084  M                                                      mdo
 2084  M [1DBE] 1DBE:E60F            [ 3]                     lda       divisor35+0,spx
 2084  M [1DC0] 1DC0:E10D            [ 3]                     cmpa      dividend@@+0,spx
 2084  M [1DC2] 1DC2:2604 (1DC8)     [ 3]                     bne       Done$$$
 2084  M                                                      mloop     :temp
 2084  M [1DC4] 1DC4:E610            [ 3]                     lda       divisor35+1,spx
 2084  M [1DC6] 1DC6:E10E            [ 3]                     cmpa      dividend@@+1,spx
 2084  M                                                      mloop     :temp
 2084  M             1DC8                 Done$$$
 2084                                                         endm
 2085    [1DC8] 1DC8:2604 (1DCE)     [ 3]                     bne       NotEqual@@
 2086
 2087    [1DCA] 1DCA:6C01            [ 5]                     inc       ?quotient+{::?quotient-1},x  ;quotient := 1
 2088    [1DCC] 1DCC:200A (1DD8)     [ 3]                     bra       ??DivExit           ;and get out
 2089
 2090                1DCE                 NotEqual@@         ;@sub.s    divisor@@,spx dividend@@,spx  ;[2012.05.18 REDUNDANT]
 2091    [1DCE] 1DCE:250A (1DDA)     [ 3]                     blo       Continue@@
 2092
 2093  M                                                      @mova.s   dividend@@,spx ?remainder,x
 2093  M                                                      mset      #' '
 2093  M                                                      mreq      1,2:Source Destination
 2093  M                                                      @@_samesize_ dividend35,spx ?remainder,x
 2093  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2093  M                                                      mset      0
 2093  M                                                      mdo
 2093  M                                                      mswap     1,1
 2093  M                                                      @@_nosize_ dividend35,spx
 2093  M                                                      mset      #
 2093  M                                                      mset      0,mstop [_samesize_] No size (dividend35,spx)
 2093  M                                                      endm
 2093  M                                                      mset      0,dividend35,spx
 2093  M                                                      mloop     :n
 2093  M                                                      mswap     1,2
 2093  M                                                      @@_nosize_ ?remainder,x
 2093  M                                                      mset      #
 2093  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2093  M                                                      endm
 2093  M                                                      mloop     :n
 2093  M                                                      endm
 2093  M                                                      mset      0
 2093  M                                                      mdo
 2093  M [1DD0] 1DD0:E60D            [ 3]                     lda       dividend35+0,spx
 2093  M [1DD2] 1DD2:E702            [ 3]                     sta       ?remainder+0,x
 2093  M                                                      mloop     ::?remainder
 2093  M [1DD4] 1DD4:E60E            [ 3]                     lda       dividend35+1,spx
 2093  M [1DD6] 1DD6:E703            [ 3]                     sta       ?remainder+1,x
 2093  M                                                      mloop     ::?remainder
 2093                                                         endm
 2094                1DD8                 ??DivExit                                         ;and get out
 2096    [1DD8] 1DD8:2069 (1E43)     [ 3]                     bra       Done@@
 2100
 2101    [1DDA] 1DDA:A610            [ 2] Continue@@          lda       #MATHSIZE
 2102    [1DDC] 1DDC:E706            [ 3]                     sta       ?bits,x             ;bits := 64/56/48/40/32/24/16-bit
 2103
 2104                                               ; while (remainder < divisor) do
 2105
 2106  M                                  While@@             @cop                          ;in case of many iterations
 2106  M [1DDE] 1DDE:C718 00         [ 4]                     sta       COP
 2106                                                         endm
 2107
 2108  M                                                      @sub.s    ?remainder,x divisor@@,spx
 2108  M                                                      mset      #' '
 2108  M                                                      mreq      1,2:[#]Operand1 [#]Operand2 Destination
 2108  M                                                      @@_samesize_ ?remainder,x divisor35,spx
 2108  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2108  M                                                      mset      0
 2108  M                                                      mdo
 2108  M                                                      mswap     1,1
 2108  M                                                      @@_nosize_ ?remainder,x
 2108  M                                                      mset      #
 2108  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2108  M                                                      endm
 2108  M                                                      mset      0,?remainder,x
 2108  M                                                      mloop     :n
 2108  M                                                      mswap     1,2
 2108  M                                                      @@_nosize_ divisor35,spx
 2108  M                                                      mset      #
 2108  M                                                      mset      0,mstop [_samesize_] No size (divisor35,spx)
 2108  M                                                      endm
 2108  M                                                      mloop     :n
 2108  M                                                      endm
 2108  M                                                      #temp
 2108  M                                                      @@_nosize_ ?remainder,x
 2108  M                                                      mset      #
 2108  M                                                      mset      0,mstop [sub.s] No size (?remainder,x)
 2108  M                                                      endm
 2108  M                                                      #temp     ::?remainder
 2108  M                                                      mset      0,sub
 2108  M                                                      mdo
 2108  M [1DE1] 1DE1:E603            [ 3]                     lda       ?remainder+1,x
 2108  M [1DE3] 1DE3:E010            [ 3]                     sub    divisor35+1,spx
 2108  M                                                      mset      0,sbc
 2108  M                                                      mloop     :temp
 2108  M [1DE5] 1DE5:E602            [ 3]                     lda       ?remainder+0,x
 2108  M [1DE7] 1DE7:E20F            [ 3]                     sbc    divisor35+0,spx
 2108  M                                                      mset      0,sbc
 2108  M                                                      mloop     :temp
 2108                                                         endm
 2109    [1DE9] 1DE9:2414 (1DFF)     [ 3]                     bcc       EndWhile@@
 2110
 2111                                               ; remainder := (remainder shl 1) or msb(dividend)
 2112                                               ;-------------------------------------- ;2012.12.04 optimization (moved up this code from before DEC to here)
 2113  M                                                      @mova.s   dividend@@,spx ?temp,x  ; temp := dividend
 2113  M                                                      mset      #' '
 2113  M                                                      mreq      1,2:Source Destination
 2113  M                                                      @@_samesize_ dividend35,spx ?temp,x
 2113  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2113  M                                                      mset      0
 2113  M                                                      mdo
 2113  M                                                      mswap     1,1
 2113  M                                                      @@_nosize_ dividend35,spx
 2113  M                                                      mset      #
 2113  M                                                      mset      0,mstop [_samesize_] No size (dividend35,spx)
 2113  M                                                      endm
 2113  M                                                      mset      0,dividend35,spx
 2113  M                                                      mloop     :n
 2113  M                                                      mswap     1,2
 2113  M                                                      @@_nosize_ ?temp,x
 2113  M                                                      mset      #
 2113  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2113  M                                                      endm
 2113  M                                                      mloop     :n
 2113  M                                                      endm
 2113  M                                                      mset      0
 2113  M                                                      mdo
 2113  M [1DEB] 1DEB:E60D            [ 3]                     lda       dividend35+0,spx
 2113  M [1DED] 1DED:E704            [ 3]                     sta       ?temp+0,x
 2113  M                                                      mloop     ::?temp
 2113  M [1DEF] 1DEF:E60E            [ 3]                     lda       dividend35+1,spx
 2113  M [1DF1] 1DF1:E705            [ 3]                     sta       ?temp+1,x
 2113  M                                                      mloop     ::?temp
 2113                                                         endm
 2114  M                                                      @lsl.s    dividend@@,spx      ; dividend := dividend shl 1
 2114  M                                                      mset      #
 2114  M                                                      mreq      1
 2114  M                                                      @@_nosize_ dividend35,spx
 2114  M                                                      mset      #
 2114  M                                                      mset      0,mstop [lsl.s] No size (dividend35,spx)
 2114  M                                                      endm
 2114  M                                                      mdo
 2114  M [1DF3] 1DF3:680E            [ 5]                     lsl       dividend35+1,spx
 2114  M                                                      mloop     ::dividend35
 2114  M [1DF5] 1DF5:690D            [ 5]                     rol       dividend35+0,spx
 2114  M                                                      mloop     ::dividend35
 2114                                                         endm
 2115                                               ;--------------------------------------
 2116  M                                                      @rol.s    ?remainder,x
 2116  M                                                      mset      #
 2116  M                                                      mreq      1
 2116  M                                                      @@_nosize_ ?remainder,x
 2116  M                                                      mset      #
 2116  M                                                      mset      0,mstop [rol.s] No size (?remainder,x)
 2116  M                                                      endm
 2116  M                                                      mdo
 2116  M [1DF7] 1DF7:6903            [ 5]                     rol       ?remainder+1,x
 2116  M                                                      mloop     ::?remainder
 2116  M [1DF9] 1DF9:6902            [ 5]                     rol       ?remainder+0,x
 2116  M                                                      mloop     ::?remainder
 2116                                                         endm
 2117    [1DFB] 1DFB:6A06            [ 5]                     dec       ?bits,x             ; bits := bits - 1
 2118
 2119                                               ; end while
 2120
 2121    [1DFD] 1DFD:20DF (1DDE)     [ 3]                     bra       While@@
 2122                1DFF                 EndWhile@@
 2123  M                                                      @mova.s   ?temp,x dividend@@,spx  ; dividend := temp
 2123  M                                                      mset      #' '
 2123  M                                                      mreq      1,2:Source Destination
 2123  M                                                      @@_samesize_ ?temp,x dividend35,spx
 2123  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2123  M                                                      mset      0
 2123  M                                                      mdo
 2123  M                                                      mswap     1,1
 2123  M                                                      @@_nosize_ ?temp,x
 2123  M                                                      mset      #
 2123  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2123  M                                                      endm
 2123  M                                                      mset      0,?temp,x
 2123  M                                                      mloop     :n
 2123  M                                                      mswap     1,2
 2123  M                                                      @@_nosize_ dividend35,spx
 2123  M                                                      mset      #
 2123  M                                                      mset      0,mstop [_samesize_] No size (dividend35,spx)
 2123  M                                                      endm
 2123  M                                                      mloop     :n
 2123  M                                                      endm
 2123  M                                                      mset      0
 2123  M                                                      mdo
 2123  M [1DFF] 1DFF:E604            [ 3]                     lda       ?temp+0,x
 2123  M [1E01] 1E01:E70D            [ 3]                     sta       dividend35+0,spx
 2123  M                                                      mloop     ::dividend35
 2123  M [1E03] 1E03:E605            [ 3]                     lda       ?temp+1,x
 2123  M [1E05] 1E05:E70E            [ 3]                     sta       dividend35+1,spx
 2123  M                                                      mloop     ::dividend35
 2123                                                         endm
 2124  M                                                      @lsr.s    ?remainder,x        ; remainder := remainder shr 1
 2124  M                                                      mset      #
 2124  M                                                      mreq      1
 2124  M                                                      @@_nosize_ ?remainder,x
 2124  M                                                      mset      #
 2124  M                                                      mset      0,mstop [lsr.s] No size (?remainder,x)
 2124  M                                                      endm
 2124  M                                                      mdo
 2124  M [1E07] 1E07:6402            [ 5]                     lsr       ?remainder+0,x
 2124  M                                                      mloop     ::?remainder
 2124  M [1E09] 1E09:6603            [ 5]                     ror       ?remainder+1,x
 2124  M                                                      mloop     ::?remainder
 2124                                                         endm
 2125    [1E0B] 1E0B:6C06            [ 5]                     inc       ?bits,x             ; bits := bits + 1
 2126
 2127                                               ; for i := bitCounter-1 downto 0 do
 2128
 2129  M                                  For@@               @cop                          ;in case of many iterations
 2129  M [1E0D] 1E0D:C718 00         [ 4]                     sta       COP
 2129                                                         endm
 2130
 2131    [1E10] 1E10:6D06            [ 4]                     tst       ?bits,x
 2133    [1E12] 1E12:272F (1E43)     [ 3]                     beq       Done@@
 2137    [1E14] 1E14:6A06            [ 5]                     dec       ?bits,x
 2138
 2139                                               ; remainder := (remainder shl 1) or msb(dividend)
 2140                                               ; dividend := dividend shl 1
 2141
 2142  M                                                      @lsl.s    dividend@@,spx      ;2012.12.04 optimization
 2142  M                                                      mset      #
 2142  M                                                      mreq      1
 2142  M                                                      @@_nosize_ dividend35,spx
 2142  M                                                      mset      #
 2142  M                                                      mset      0,mstop [lsl.s] No size (dividend35,spx)
 2142  M                                                      endm
 2142  M                                                      mdo
 2142  M [1E16] 1E16:680E            [ 5]                     lsl       dividend35+1,spx
 2142  M                                                      mloop     ::dividend35
 2142  M [1E18] 1E18:690D            [ 5]                     rol       dividend35+0,spx
 2142  M                                                      mloop     ::dividend35
 2142                                                         endm
 2143  M                                                      @rol.s    ?remainder,x
 2143  M                                                      mset      #
 2143  M                                                      mreq      1
 2143  M                                                      @@_nosize_ ?remainder,x
 2143  M                                                      mset      #
 2143  M                                                      mset      0,mstop [rol.s] No size (?remainder,x)
 2143  M                                                      endm
 2143  M                                                      mdo
 2143  M [1E1A] 1E1A:6903            [ 5]                     rol       ?remainder+1,x
 2143  M                                                      mloop     ::?remainder
 2143  M [1E1C] 1E1C:6902            [ 5]                     rol       ?remainder+0,x
 2143  M                                                      mloop     ::?remainder
 2143                                                         endm
 2144
 2145                                               ; temp := remainder - divisor
 2146
 2147  M                                                      @sub.s    ?remainder,x divisor@@,spx ?temp,x
 2147  M                                                      mset      #' '
 2147  M                                                      mreq      1,2:[#]Operand1 [#]Operand2 Destination
 2147  M                                                      @@_samesize_ ?remainder,x divisor35,spx ?temp,x
 2147  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2147  M                                                      mset      0
 2147  M                                                      mdo
 2147  M                                                      mswap     1,1
 2147  M                                                      @@_nosize_ ?remainder,x
 2147  M                                                      mset      #
 2147  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2147  M                                                      endm
 2147  M                                                      mset      0,?remainder,x
 2147  M                                                      mloop     :n
 2147  M                                                      mswap     1,2
 2147  M                                                      @@_nosize_ divisor35,spx
 2147  M                                                      mset      #
 2147  M                                                      mset      0,mstop [_samesize_] No size (divisor35,spx)
 2147  M                                                      endm
 2147  M                                                      mloop     :n
 2147  M                                                      mswap     1,3
 2147  M                                                      @@_nosize_ ?temp,x
 2147  M                                                      mset      #
 2147  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2147  M                                                      endm
 2147  M                                                      mloop     :n
 2147  M                                                      endm
 2147  M                                                      #temp
 2147  M                                                      @@_nosize_ ?temp,x
 2147  M                                                      mset      #
 2147  M                                                      mset      0,mstop [sub.s] No size (?temp,x)
 2147  M                                                      endm
 2147  M                                                      #temp     ::?temp
 2147  M                                                      mset      0,sub
 2147  M                                                      mdo
 2147  M [1E1E] 1E1E:E603            [ 3]                     lda       ?remainder+1,x
 2147  M [1E20] 1E20:E010            [ 3]                     sub    divisor35+1,spx
 2147  M [1E22] 1E22:E705            [ 3]                     sta       ?temp+1,x
 2147  M                                                      mset      0,sbc
 2147  M                                                      mloop     :temp
 2147  M [1E24] 1E24:E602            [ 3]                     lda       ?remainder+0,x
 2147  M [1E26] 1E26:E20F            [ 3]                     sbc    divisor35+0,spx
 2147  M [1E28] 1E28:E704            [ 3]                     sta       ?temp+0,x
 2147  M                                                      mset      0,sbc
 2147  M                                                      mloop     :temp
 2147                                                         endm
 2148
 2149                                               ; q := not msb(temp)
 2150
 2151    [1E2A] 1E2A:E604            [ 3]                     lda       ?temp,x
 2152    [1E2C] 1E2C:A880            [ 2]                     eor       #%10000000          ;invert msb
 2153    [1E2E] 1E2E:A480            [ 2]                     and       #%10000000          ;isolate msb
 2154
 2155                                               ; quotient := (quotient shl 1) or q
 2156
 2157    [1E30] 1E30:87              [ 2]                     psha
 2158    [1E31] 1E31:48              [ 1]                     lsla
 2159    [1E32] 1E32:86              [ 3]                     pula
 2160
 2161  M                                                      @rol.s    ?quotient,x
 2161  M                                                      mset      #
 2161  M                                                      mreq      1
 2161  M                                                      @@_nosize_ ?quotient,x
 2161  M                                                      mset      #
 2161  M                                                      mset      0,mstop [rol.s] No size (?quotient,x)
 2161  M                                                      endm
 2161  M                                                      mdo
 2161  M [1E33] 1E33:6901            [ 5]                     rol       ?quotient+1,x
 2161  M                                                      mloop     ::?quotient
 2161  M [1E35] 1E35:79              [ 4]                     rol       ?quotient+0,x
 2161  M                                                      mloop     ::?quotient
 2161                                                         endm
 2162
 2163                                               ; if q <> 0 then
 2164
 2165    [1E36] 1E36:4100 D4(1E0D)   [ 4]                     cbeqa     #0,For@@
 2166
 2167                                               ; remainder := temp
 2168
 2169  M                                                      @mova.s   ?temp,x ?remainder,x
 2169  M                                                      mset      #' '
 2169  M                                                      mreq      1,2:Source Destination
 2169  M                                                      @@_samesize_ ?temp,x ?remainder,x
 2169  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2169  M                                                      mset      0
 2169  M                                                      mdo
 2169  M                                                      mswap     1,1
 2169  M                                                      @@_nosize_ ?temp,x
 2169  M                                                      mset      #
 2169  M                                                      mset      0,mstop [_samesize_] No size (?temp,x)
 2169  M                                                      endm
 2169  M                                                      mset      0,?temp,x
 2169  M                                                      mloop     :n
 2169  M                                                      mswap     1,2
 2169  M                                                      @@_nosize_ ?remainder,x
 2169  M                                                      mset      #
 2169  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2169  M                                                      endm
 2169  M                                                      mloop     :n
 2169  M                                                      endm
 2169  M                                                      mset      0
 2169  M                                                      mdo
 2169  M [1E39] 1E39:E604            [ 3]                     lda       ?temp+0,x
 2169  M [1E3B] 1E3B:E702            [ 3]                     sta       ?remainder+0,x
 2169  M                                                      mloop     ::?remainder
 2169  M [1E3D] 1E3D:E605            [ 3]                     lda       ?temp+1,x
 2169  M [1E3F] 1E3F:E703            [ 3]                     sta       ?remainder+1,x
 2169  M                                                      mloop     ::?remainder
 2169                                                         endm
 2170
 2171                                               ; end if -- end for
 2172
 2174    [1E41] 1E41:20CA (1E0D)     [ 3]                     bra       For@@
 2178
 2179    [1E43] 1E43:E607            [ 3] Done@@              lda       ?flags,x
 2180    [1E45] 1E45:A501            [ 2]                     bit       #?DIVOP_
 2181    [1E47] 1E47:2709 (1E52)     [ 3]                     beq       ExitMod@@
 2182
 2183                0160                 ?Cycles             equ       :cycles
 2184
 2185                                     ;ExitDiv@@
 2186  M                                                      @mova.s   ?quotient,x ans@@,spx
 2186  M                                                      mset      #' '
 2186  M                                                      mreq      1,2:Source Destination
 2186  M                                                      @@_samesize_ ?quotient,x ans35,spx
 2186  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2186  M                                                      mset      0
 2186  M                                                      mdo
 2186  M                                                      mswap     1,1
 2186  M                                                      @@_nosize_ ?quotient,x
 2186  M                                                      mset      #
 2186  M                                                      mset      0,mstop [_samesize_] No size (?quotient,x)
 2186  M                                                      endm
 2186  M                                                      mset      0,?quotient,x
 2186  M                                                      mloop     :n
 2186  M                                                      mswap     1,2
 2186  M                                                      @@_nosize_ ans35,spx
 2186  M                                                      mset      #
 2186  M                                                      mset      0,mstop [_samesize_] No size (ans35,spx)
 2186  M                                                      endm
 2186  M                                                      mloop     :n
 2186  M                                                      endm
 2186  M                                                      mset      0
 2186  M                                                      mdo
 2186  M [1E49] 1E49:F6              [ 3]                     lda       ?quotient+0,x
 2186  M [1E4A] 1E4A:E70F            [ 3]                     sta       ans35+0,spx
 2186  M                                                      mloop     ::ans35
 2186  M [1E4C] 1E4C:E601            [ 3]                     lda       ?quotient+1,x
 2186  M [1E4E] 1E4E:E710            [ 3]                     sta       ans35+1,spx
 2186  M                                                      mloop     ::ans35
 2186                                                         endm
 2187    [1E50] 1E50:2008 (1E5A)     [ 3]                     bra       ExitBoth@@
 2188
 2189                018E                 ?DivCycles          set       ?DivCycles+?Cycles+:cycles
 2190
 2191  M                                  ExitMod@@           @mova.s   ?remainder,x ans@@,spx
 2191  M                                                      mset      #' '
 2191  M                                                      mreq      1,2:Source Destination
 2191  M                                                      @@_samesize_ ?remainder,x ans35,spx
 2191  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2191  M                                                      mset      0
 2191  M                                                      mdo
 2191  M                                                      mswap     1,1
 2191  M                                                      @@_nosize_ ?remainder,x
 2191  M                                                      mset      #
 2191  M                                                      mset      0,mstop [_samesize_] No size (?remainder,x)
 2191  M                                                      endm
 2191  M                                                      mset      0,?remainder,x
 2191  M                                                      mloop     :n
 2191  M                                                      mswap     1,2
 2191  M                                                      @@_nosize_ ans35,spx
 2191  M                                                      mset      #
 2191  M                                                      mset      0,mstop [_samesize_] No size (ans35,spx)
 2191  M                                                      endm
 2191  M                                                      mloop     :n
 2191  M                                                      endm
 2191  M                                                      mset      0
 2191  M                                                      mdo
 2191  M [1E52] 1E52:E602            [ 3]                     lda       ?remainder+0,x
 2191  M [1E54] 1E54:E70F            [ 3]                     sta       ans35+0,spx
 2191  M                                                      mloop     ::ans35
 2191  M [1E56] 1E56:E603            [ 3]                     lda       ?remainder+1,x
 2191  M [1E58] 1E58:E710            [ 3]                     sta       ans35+1,spx
 2191  M                                                      mloop     ::ans35
 2191                                                         endm
 2192
 2193                0182                 ?ModCycles          set       ?ModCycles+?Cycles+:cycles
 2194
 2195                1E5A                 ExitBoth@@
 2197    [1E5A] 1E5A:6D07            [ 4]                     tst       ?flags,x
 2198    [1E5C] 1E5C:2A06 (1E64)     [ 3]                     bpl       SkipSign@@
 2199  M                                                      @lea      ans@@,sp
 2199  M                                                      mset      #
 2199  M [1E5E] 1E5E:95              [ 2]                     tsx
 2199  M [1E5F] 1E5F:AF0F            [ 2]                     !aix      #ans35+:tsx
 2199                                                         mexit
 2200    [1E61] 1E61:CD1D 8E         [ 6]                     jsr       ?NegX
 2201                1E64                 SkipSign@@
 2202                                                                   #Cycles ?NegxCycles+:cycles
 2204    [1E64] 1E64:A708            [ 2]                     ais       #?SF                ;de-allocate temporaries
 2205    [1E66] 1E66:98              [ 1]                     clc                           ;no error(s)
 2206                                     ;                   bra       ?RemoveAndReturn
 2207
 2208                0024                 ?Cycles             set       :cycles
 2209                01B2                 ?DivCycles          set       ?DivCycles+?Cycles
 2210                01A6                 ?ModCycles          set       ?ModCycles+?Cycles
 2211
 2212                                     ;*******************************************************************************
 2213                                     ; Common exit removes lower 32-bit stack element and returns to caller
 2214                                     ;*******************************************************************************
 2215
 2216                1E67                 ?RemoveAndReturn    proc
 2218    [1E67] 1E67:9EFE 04         [ 5]                     ldhx      ?pc,sp              ;our return address moved up
 2219    [1E6A] 1E6A:9EFF 06         [ 5]                     sthx      ?pc+?WORD,sp        ;above word to remove
 2229    [1E6D] 1E6D:8A88 86         [ 9]                     pull
 2230    [1E70] 1E70:A702            [ 2]                     ais       #?WORD              ;remove top-of-stack ?WORD
 2231    [1E72] 1E72:81              [ 6]                     rtc
 2232
 2233                001B                 ?ReturnCycles       equ       :cycles
 2234
 2235                                     ;*******************************************************************************
 2236                                     ; Purpose: Swaps the stacked order of N1 and N2
 2237                                     ; Input  : [TOS+?WORD] = Number2
 2238                                     ;        : [TOS] = Number1
 2239                                     ; Output : [TOS+?WORD] = Number1 -- TOS & [TOS+?WORD] in reverse order
 2240                                     ;        : [TOS] = Number2
 2241                                     ; Note(s): Does not alter stack size
 2242
 2243                                                         #spauto   :ab
 2244
 2245                1E73                 ?Swap               proc
 2246    [1E73] 1E73:8789 8B         [ 6]                     push
 2247
 2248    [1E76] 1E76:A602            [ 2]                     lda       #?WORD
 2249    [1E78] 1E78:87              [ 2]                     psha      bytes@@
 2250
 2251    [1E79] 1E79:95              [ 2]                     tsx
 2252                                                                   #temp :cycles
 2253  M                                  Loop@@              @_swap_,  ?a,spx ?b,spx       ;swap A with B ...
 2253  M                                                      mset      #' '
 2253  M                                                      #push
 2253  M                                                      #spauto   :sp
 2253  M [1E7A] 1E7A:E606            [ 3]                     lda       ?a,spx
 2253  M [1E7C] 1E7C:87              [ 2]                     psha
 2253  M [1E7D] 1E7D:E608            [ 3]                     lda       ?b,spx
 2253  M [1E7F] 1E7F:E706            [ 3]                     sta       ?a,spx
 2253  M [1E81] 1E81:86              [ 3]                     pula
 2253  M [1E82] 1E82:E708            [ 3]                     sta       ?b,spx
 2253  M                                                      #pull
 2253                                                         endm
 2254
 2255    [1E84] 1E84:AF01            [ 2]                     aix       #1                  ;point to next byte
 2256    [1E86] 1E86:9E6B 01F0 (1E7A [ 8]                     dbnz      bytes@@,sp,Loop@@   ;repeat for all bytes
 2257                                                                   #temp :cycles*?WORD+:temp
 2258    [1E8A] 1E8A:86              [ 3]                     pula
 2259
 2260    [1E8B] 1E8B:8A88 86         [ 9]                     pull
 2261    [1E8E] 1E8E:81              [ 6]                     rtc
 2262
 2263                0054                 ?SwapCycles         set       :cycles+:temp
 2264
 2265                                     ;*******************************************************************************
 2266                                     ; Purpose: Get the absolute value of the top-of-stack number
 2267                                     ; Input  : [TOS] = Number
 2268                                     ; Output : [TOS] = Abs(Number)
 2269                                     ; Note(s): Does not alter stack size
 2270
 2271                                                         #spauto   :ab
 2272
 2273                1E8F                 ?Abs                proc
 2274    [1E8F] 1E8F:9E6D 03         [ 5]                     tst       ?a,sp
 2275    [1E92] 1E92:2AFA (1E8E)     [ 3]                     bpl       Done@@
 2276                                     ;                   bra       ?Negate
 2277
 2278                1E8E                 Done@@              equ       :AnRTC
 2279
 2280                0008                 ?AbsCycles          equ       :cycles
 2281
 2282                                     ;*******************************************************************************
 2283                                     ; Purpose: Negate the top-of-stack number
 2284                                     ; Input  : [TOS] = Number
 2285                                     ; Output : [TOS] = -Number
 2286                                     ; Note(s): Does not alter stack size
 2287
 2288                                                         #spauto   :ab
 2289
 2290                1E94                 ?Negate             proc
 2291    [1E94] 1E94:898B            [ 4]                     pshhx
 2293  M                                                      @lea      ?a,sp
 2293  M                                                      mset      #
 2293  M [1E96] 1E96:95              [ 2]                     tsx
 2293  M [1E97] 1E97:AF04            [ 2]                     !aix      #?a+:tsx
 2293                                                         mexit
 2294    [1E99] 1E99:CD1D 8E         [ 6]                     jsr       ?NegX
 2295                                                                   #Cycles ?NegxCycles+:cycles
 2300    [1E9C] 1E9C:8A88            [ 6]                     pulhx
 2301    [1E9E] 1E9E:81              [ 6]                     rtc
 2302
 2303                002A                 ?NegateCycles       equ       :cycles
 2304                0032                 ?AbsCycles          set       ?NegateCycles+?AbsCycles
 2305
 2306                                     ;*******************************************************************************
 2307                                     ; Purpose: Create a new top-of-stack and load to it the number pointed to by HX
 2308                                     ; Input  : HX -> [Variable with] Number
 2309                                     ; Output : [TOS] = Number
 2310                                     ; Note(s): This operation makes it easier to load a number to the stack.
 2311                                     ;        : Hint: To make a copy of the TOS, do:
 2312                                     ;        :          tsx
 2313                                     ;        :          call      StackLoad32
 2314                                     ;        : (Stack is expanded)
 2315
 2316                                                         #spauto   :ab
 2317
 2318                1E9F                 ?Load               proc
 2319                FFFFFFFF             old_rts@@           equ       ::,:ab
 2320    [1E9F] 1E9F:A7FE            [ 2]                     ais       #-?WORD             ;allocate new TOS memory
 2321                                                         #temp     ::
 2322                FFFFFFFD             new_rts@@           next      :temp,:ab
 2323                FFFFFFFF             tos_num@@           next      :temp,?WORD
 2324                0001                                     next      :temp,-:ab          ;-:AB as old_rts@@ will be gone
 2325                                                         #ais      :temp
 2326
 2327    [1EA1] 1EA1:87              [ 2]                     psha
 2328  M                                                      @mova.s   old_rts@@,sp new_rts@@,sp  ;move RTS/RTC after new memory
 2328  M                                                      mset      #' '
 2328  M                                                      mreq      1,2:Source Destination
 2328  M                                                      @@_samesize_ old_rts40,sp new_rts@@,sp
 2328  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2328  M                                                      mset      0
 2328  M                                                      mdo
 2328  M                                                      mswap     1,1
 2328  M                                                      @@_nosize_ old_rts40,sp
 2328  M                                                      mset      #
 2328  M                                                      mset      0,mstop [_samesize_] No size (old_rts40,sp)
 2328  M                                                      endm
 2328  M                                                      mset      0,old_rts40,sp
 2328  M                                                      mloop     :n
 2328  M                                                      mswap     1,2
 2328  M                                                      @@_nosize_ new_rts@@,sp
 2328  M                                                      mset      #
 2328  M                                                      mset      0,mstop [_samesize_] No size (new_rts40,sp)
 2328  M                                                      endm
 2328  M                                                      mloop     :n
 2328  M                                                      endm
 2328  M                                                      mset      0
 2328  M                                                      mdo
 2328  M [1EA2] 1EA2:9EE6 04         [ 4]                     lda       old_rts40+0,sp
 2328  M [1EA5] 1EA5:9EE7 02         [ 4]                     sta       new_rts@@+0,sp
 2328  M                                                      mloop     ::new_rts@@
 2328  M [1EA8] 1EA8:9EE6 05         [ 4]                     lda       old_rts40+1,sp
 2328  M [1EAB] 1EAB:9EE7 03         [ 4]                     sta       new_rts@@+1,sp
 2328  M                                                      mloop     ::new_rts@@
 2328                                                         endm
 2329  M                                                      @mova.s   ,x tos_num@@,sp
 2329  M                                                      mset      #' '
 2329  M                                                      mreq      1,2:Source Destination
 2329  M                                                      @@_samesize_ ,x tos_num40,sp
 2329  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2329  M                                                      mset      0
 2329  M                                                      mdo
 2329  M                                                      mswap     1,1
 2329  M                                                      mloop     :n
 2329  M                                                      mswap     1,2
 2329  M                                                      @@_nosize_ tos_num40,sp
 2329  M                                                      mset      #
 2329  M                                                      mset      0,mstop [_samesize_] No size (tos_num40,sp)
 2329  M                                                      endm
 2329  M                                                      mset      0,tos_num40,sp
 2329  M                                                      mloop     :n
 2329  M                                                      endm
 2329  M                                                      mset      0
 2329  M                                                      mdo
 2329  M [1EAE] 1EAE:F6              [ 3]                     lda       +0,x
 2329  M [1EAF] 1EAF:9EE7 04         [ 4]                     sta       tos_num40+0,sp
 2329  M                                                      mloop     ::tos_num40
 2329  M [1EB2] 1EB2:E601            [ 3]                     lda       +1,x
 2329  M [1EB4] 1EB4:9EE7 05         [ 4]                     sta       tos_num40+1,sp
 2329  M                                                      mloop     ::tos_num40
 2329                                                         endm
 2330    [1EB7] 1EB7:86              [ 3]                     pula
 2331    [1EB8] 1EB8:81              [ 6]                     rtc
 2332
 2333                002B                 ?LoadCycles         equ       :cycles
 2334
 2335                                     ;*******************************************************************************
 2336                                     ; Purpose: Unload the top-of-stack number into a variable pointed to by HX
 2337                                     ; Input  : [TOS] = Number
 2338                                     ;        : HX -> Some 32-bit variable
 2339                                     ; Output : Variable pointed to by HX receives TOS number
 2340                                     ; Note(s): This operation makes it easier to unload a number from the stack.
 2341                                     ;        : Use:
 2342                                     ;        :          ldhx      #MyVar
 2343                                     ;        :          call      StackSave32
 2344                                     ;        : (Stack is reduced)
 2345
 2346                                                         #spauto   :ab
 2347
 2348                1EB9                 ?Save               proc
 2349                                                         #temp     ::
 2350                FFFFFFFF             old_rts@@           next      :temp,:ab
 2351                0001                 tos_num@@           next      :temp,?WORD
 2352                0003                                     next      :temp,-:ab          ;-:AB as old_rts@@ will be gone
 2353                0001                 new_rts@@           next      :temp,:ab
 2354
 2355                0000                 var@@               equ       0,?WORD
 2356
 2357    [1EB9] 1EB9:8789 8B         [ 6]                     push
 2358  M                                                      @mova.s   tos_num@@,sp var@@,x
 2358  M                                                      mset      #' '
 2358  M                                                      mreq      1,2:Source Destination
 2358  M                                                      @@_samesize_ tos_num41,sp var@@,x
 2358  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2358  M                                                      mset      0
 2358  M                                                      mdo
 2358  M                                                      mswap     1,1
 2358  M                                                      @@_nosize_ tos_num41,sp
 2358  M                                                      mset      #
 2358  M                                                      mset      0,mstop [_samesize_] No size (tos_num41,sp)
 2358  M                                                      endm
 2358  M                                                      mset      0,tos_num41,sp
 2358  M                                                      mloop     :n
 2358  M                                                      mswap     1,2
 2358  M                                                      @@_nosize_ var@@,x
 2358  M                                                      mset      #
 2358  M                                                      mset      0,mstop [_samesize_] No size (var41,x)
 2358  M                                                      endm
 2358  M                                                      mloop     :n
 2358  M                                                      endm
 2358  M                                                      mset      0
 2358  M                                                      mdo
 2358  M [1EBC] 1EBC:9EE6 06         [ 4]                     lda       tos_num41+0,sp
 2358  M [1EBF] 1EBF:F7              [ 2]                     sta       var@@+0,x
 2358  M                                                      mloop     ::var@@
 2358  M [1EC0] 1EC0:9EE6 07         [ 4]                     lda       tos_num41+1,sp
 2358  M [1EC3] 1EC3:E701            [ 3]                     sta       var@@+1,x
 2358  M                                                      mloop     ::var@@
 2358                                                         endm
 2359
 2360    [1EC5] 1EC5:95              [ 2]                     tsx
 2361  M                                                      @mova.s   old_rts@@,spx new_rts@@,spx  ;move RTS/RTC before old memory
 2361  M                                                      mset      #' '
 2361  M                                                      mreq      1,2:Source Destination
 2361  M                                                      @@_samesize_ old_rts41,spx new_rts@@,spx
 2361  M                                                      mreq      1,2:Operand1,Operand2[,Operand]*
 2361  M                                                      mset      0
 2361  M                                                      mdo
 2361  M                                                      mswap     1,1
 2361  M                                                      @@_nosize_ old_rts41,spx
 2361  M                                                      mset      #
 2361  M                                                      mset      0,mstop [_samesize_] No size (old_rts41,spx)
 2361  M                                                      endm
 2361  M                                                      mset      0,old_rts41,spx
 2361  M                                                      mloop     :n
 2361  M                                                      mswap     1,2
 2361  M                                                      @@_nosize_ new_rts@@,spx
 2361  M                                                      mset      #
 2361  M                                                      mset      0,mstop [_samesize_] No size (new_rts41,spx)
 2361  M                                                      endm
 2361  M                                                      mloop     :n
 2361  M                                                      endm
 2361  M                                                      mset      0
 2361  M                                                      mdo
 2361  M [1EC6] 1EC6:E603            [ 3]                     lda       old_rts41+0,spx
 2361  M [1EC8] 1EC8:E705            [ 3]                     sta       new_rts@@+0,spx
 2361  M                                                      mloop     ::new_rts@@
 2361  M [1ECA] 1ECA:E604            [ 3]                     lda       old_rts41+1,spx
 2361  M [1ECC] 1ECC:E706            [ 3]                     sta       new_rts@@+1,spx
 2361  M                                                      mloop     ::new_rts@@
 2361                                                         endm
 2362    [1ECE] 1ECE:8A88 86         [ 9]                     pull
 2363
 2364    [1ED1] 1ED1:A702            [ 2]                     ais       #?WORD              ;de-allocate TOS memory
 2365    [1ED3] 1ED3:81              [ 6]                     rtc
 2366
 2367                0032                 ?SaveCycles         equ       :cycles
 2368
 2369                                     ;*******************************************************************************
 2370                                     ; Purpose: Adjust TOS old size to new
 2371                                     ; Input  : H = old (current) byte size
 2372                                     ;        : X = new byte size
 2373                                     ;        : CCR[C] = 0 -- always positive number
 2374                                     ;        : CCR[C] = 1 -- sign extend
 2375                                     ; Output : None
 2376                                     ; Note(s): RegA deliberately not used for parameter passing (for consistency)
 2377                                     ;        : Macro destroys RegHX (as we must not use PSHHX/PULHX around call)
 2378
 2504
 2505                                     ;*******************************************************************************
 2506                                     ; Purpose: Convert 32-bit to ASCIZ string
 2507                                     ; Input  : Stack: 32-bit number
 2508                                     ;        : HX -> Output buffer with enough space to keep the ASCIZ string result
 2509                                     ; Output : None
 2510                                     ; Note(s): Use:
 2511                                     ;        :          ldhx      #Buffer
 2512                                     ;        :          call      Stack32ToASCIZ
 2513
 2514                                                         #spauto   :ab                 ;account for RTS/RTC
 2515
 2516                1ED4                 ?ToStr              proc
 2517    [1ED4] 1ED4:8789 8B         [ 6]                     push
 2518                                                         #ais                          ;mark beginning of temporaries
 2519
 2520    [1ED7] 1ED7:898B            [ 4]                     pshhx     .buffer@@           ;working copy of pointer to buffer
 2521    [1ED9] 1ED9:7F              [ 4]                     clr       ,x                  ;make it an ASCIZ string
 2522
 2523  M                                                      @lea      1,sp                ;HX -> TOS number of caller
 2523  M                                                      mset      #
 2523  M [1EDA] 1EDA:95              [ 2]                     tsx
 2523  M [1EDB] 1EDB:AF07            [ 2]                     !aix      #1+:tsx
 2523                                                         mexit
 2524    [1EDD] 1EDD:CD1E 9F         [ 6]                     call      ?Load               ;load a working copy on stack
 2525
 2526                                                         #spadd    ?WORD               ;stack has grown by a ?WORD
 2527                FFFFFFF8             number@@            equ       ::,?WORD
 2529    [1EE0] 1EE0:9E6D 01         [ 5]                     tst       number@@,sp
 2530    [1EE3] 1EE3:2A0F (1EF4)     [ 3]                     bpl       ToStrLoop@@
 2531    [1EE5] 1EE5:CD1E 94         [ 6]                     call      ?Negate
 2533    [1EE8] 1EE8:9EFE 03         [ 5]                     ldhx      .buffer@@,sp
 2540    [1EEB] 1EEB:A62D            [ 2]                     lda       #'-'                ;a 'minus' sign
 2541    [1EED] 1EED:F7              [ 2]                     sta       ,x                  ; is saved first
 2542
 2543    [1EEE] 1EEE:AF01            [ 2]                     aix       #1                  ;HX -> past minus sign
 2544    [1EF0] 1EF0:7F              [ 4]                     clr       ,x                  ;make it an ASCIZ string
 2546    [1EF1] 1EF1:9EFF 03         [ 5]                     sthx      .buffer@@,sp        ;update pointer past sign
 2552                                     ;                   bra       ToStrLoop@@
 2554                                     ;===============================================================================
 2555
 2556    [1EF4] 1EF4:4500 0A         [ 3] ToStrLoop@@         ldhx      #10                 ;H = 0 (always), X = divisor
 2557  M                                                      @div.s    number@@,sp
 2557  M                                                      mset      #
 2557  M                                                      mreq      1
 2557  M                                                      @@_not_x_ number42,sp
 2557  M                                                      mset      #' '
 2557  M                                                      mdel      1
 2557  M                                                      mtop
 2557  M                                                      mset      #' '
 2557  M                                                      mexit
 2557  M                                                      @@_nosize_ number42,sp
 2557  M                                                      mset      #
 2557  M                                                      mset      0,mstop [div.s] No size (number42,sp)
 2557  M                                                      endm
 2557  M                                                      #temp     1
 2557  M                                                      #temp     2
 2557  M [1EF7] 1EF7:86              [ 3]                     pula
 2557  M [1EF8] 1EF8:52              [ 6]                     div
 2557  M [1EF9] 1EF9:87              [ 2]                     psha
 2557  M                                                      mdo       2
 2557  M [1EFA] 1EFA:9EE6 02         [ 4]                     lda       number42+1,sp
 2557  M [1EFD] 1EFD:52              [ 6]                     div
 2557  M [1EFE] 1EFE:9EE7 02         [ 4]                     sta       number42+1,sp
 2557  M                                                      mloop     ::number42
 2557                                                         endm
 2558
 2559    [1F01] 1F01:8B86            [ 5]                     tha                           ;A = remainder
 2560    [1F03] 1F03:AB30            [ 2]                     add       #'0'                ;A = ASCII remainder
 2562    [1F05] 1F05:9EFE 03         [ 5]                     ldhx      .buffer@@,sp
 2568  M                                                      @StringInsertChar
 2568  M [1F08] 1F08:CD18 3A         [ 6]                     call      StringInsertChar                 ;HX and A pre-loaded correctly
 2568                                                         mexit
 2569
 2570    [1F0B] 1F0B:95              [ 2]                     tsx
 2571
 2572  M                                                      @_tst_.s  number@@,spx
 2572  M                                                      mset      #
 2572  M                                                      mreq      1
 2572  M                                                      @@_nosize_ number42,spx
 2572  M                                                      mset      #
 2572  M                                                      mset      0,mstop [_tst_.s] No size (number42,spx)
 2572  M                                                      endm
 2572  M                                                      mdo
 2572  M [1F0C] 1F0C:F6              [ 3]                     lda       number42+0,spx
 2572  M                                                      mloop     ::number42
 2572  M [1F0D] 1F0D:EA01            [ 3]                     ora       number42+1,spx
 2572  M                                                      mloop     ::number42
 2572                                                         endm
 2573    [1F0F] 1F0F:26E3 (1EF4)     [ 3]                     bne       ToStrLoop@@
 2574
 2575    [1F11] 1F11:A704            [ 2]                     ais       #:ais               ;free temporaries
 2576    [1F13] 1F13:8A88 86         [ 9]                     pull
 2577    [1F16] 1F16:81              [ 6]                     rtc
 2578
 2579                                                         #sp                           ;cancel all SP offsets
 2580
 2581                                     ;*******************************************************************************
 2582                                     ; Assign global names to the various library calls, depending on version used.
 2583                                     ; Different names for each version means you can include any at the same time.
 2584                                     ;*******************************************************************************
 2585
 2586                                     ?                   macro     BitSize             ;temp macro to export symbols
 2587                                                         mreq      1:Usage: @~0~ BitSize
 2588                                               #if MATHSIZE = ~1~
 2589                                     StackAdd~1~         exp       ?Add
 2590                                     StackSub~1~         exp       ?Subtract
 2591                                     StackMul~1~         exp       ?Multiply
 2592                                     StackDiv~1~         exp       ?Divide
 2593                                     StackMod~1~         exp       ?Modulo
 2594                                     StackSwap~1~        exp       ?Swap
 2595                                     StackAbs~1~         exp       ?Abs
 2596                                     StackNegate~1~      exp       ?Negate
 2597                                     StackLoad~1~        exp       ?Load
 2598                                     StackSave~1~        exp       ?Save
 2599                                     Stack~1~ToASCIZ     exp       ?ToStr
 2600                                               #ifdef NO_BIT_OPS
 2601                                                         mexit                         ;;bit operations not available
 2602                                               #endif
 2603                                     StackAnd~1~         exp       ?BitAnd
 2604                                     StackOr~1~          exp       ?BitOr
 2605                                     StackXor~1~         exp       ?BitXor
 2606                                     StackShl~1~         exp       ?ShiftLeft
 2607                                     StackShr~1~         exp       ?ShiftRight
 2608                                               #endif
 2609                                                         endm
 2610
 2611  M                                                      @?        64                  ;export 64-bit labels
 2611  M                                                      mreq      1:Usage: @? BitSize
 2611                                                         endm
 2612  M                                                      @?        56                  ;export 56-bit labels
 2612  M                                                      mreq      1:Usage: @? BitSize
 2612                                                         endm
 2613  M                                                      @?        48                  ;export 48-bit labels
 2613  M                                                      mreq      1:Usage: @? BitSize
 2613                                                         endm
 2614  M                                                      @?        40                  ;export 40-bit labels
 2614  M                                                      mreq      1:Usage: @? BitSize
 2614                                                         endm
 2615  M                                                      @?        32                  ;export 32-bit labels
 2615  M                                                      mreq      1:Usage: @? BitSize
 2615                                                         endm
 2616  M                                                      @?        24                  ;export 24-bit labels
 2616  M                                                      mreq      1:Usage: @? BitSize
 2616                                                         endm
 2617  M                                                      @?        16                  ;export 16-bit labels
 2617  M                                                      mreq      1:Usage: @? BitSize
 2617  M             1C92                 StackAdd16         exp       ?Add
 2617  M             1CA5                 StackSub16         exp       ?Subtract
 2617  M             1D43                 StackMul16         exp       ?Multiply
 2617  M             1D6A                 StackDiv16         exp       ?Divide
 2617  M             1D7D                 StackMod16         exp