



        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Macro Definitions                                            ;
        ;...............................................................;

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Real Time Dos Macro Include File                             ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                               ;
        ;  Macro include file.                                          ;
        ;                                                               ;
        ;                                                               ;
        ;  (c) Copyright 1990, 1997. Api Software and Mike Podanoffsky  ;
        ;      All Rights Reserved Worldwide.                           ;
        ;                                                               ;
        ;  This product is protected under copyright laws and  may not  ;
        ;  be reproduced  in whole  or in part, in any form  or media,  ;
        ;  included but not limited to source listing, facsimile, data  ;
        ;  transmission, cd-rom, or  floppy disk without the expressed  ;
        ;  written consent of the author.                               ;
        ;                                                               ;
        ;  License  for  distribution  for commercial  use  or  resale  ;
        ;  required from:                                               ;
        ;                                                               ;
        ;  Api Software                                                 ;
        ;  12 South Walker Street                                       ;
        ;  Lowell,  MA   01851                                          ;
        ;                                                               ;
        ;  internet: mikep@world.std.com                                ;
        ;                                                               ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;  Compile with MASM 5.1                                        ;
        ;...............................................................;

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Macros                                                       ;
        ;...............................................................;

zero                            equ 0
one                             equ 1
two                             equ 2
minusOne                        equ -1
null                            equ 0

NO                              equ 0
YES                             equ 1

_OFF                            equ 0
_ON                             equ 1

FALSE                           equ 0
TRUE                            equ 1

__pointer                       equ 0
__segment                       equ 2

_pointer                        equ __pointer
_segment                        equ __segment

_LOW                            equ _pointer
_HIGH                           equ _segment

PARAGRAPH                       equ 16

quote                           equ "'"
singleQuote                     equ "'"
doubleQuote                     equ '"'
openBracket                     equ '['
closeBracket                    equ ']'

comma                           equ ','
period                          equ '.'
colon                           equ ':'
semicolon                       equ ';'
asterisk                        equ '*'
questionMark                    equ '?'

ControlC                        equ 'C' - 40h
ControlI                        equ 'I' - 40h
ControlJ                        equ 'J' - 40h
ControlM                        equ 'M' - 40h
ControlQ                        equ 'Q' - 40h
ControlS                        equ 'S' - 40h
ControlZ                        equ 'Z' - 40h

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Caller's Stack Frame                                         ;
        ;...............................................................;

_Flags                          equ   6
_CS                             equ   4
_IP                             equ   2
_ExtraSegment                   equ   0
_DataSegment                    equ  -2
_BP                             equ  -4
_DI                             equ  -6
_SI                             equ  -8
_DX                             equ -10
_CX                             equ -12
_BX                             equ -14
_AX                             equ -16
sizeStackFrame                  equ  16

RxDOSUserStackPointer           equ 0

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Other Register Definitions.                                  ;
        ;...............................................................;

_AL                             equ 00
_AH                             equ 01

_BL                             equ 00
_BH                             equ 01

_CL                             equ 00
_CH                             equ 01

_DL                             equ 00
_DH                             equ 01

_SIL                            equ 00
_SIH                            equ 01

_DIL                            equ 00
_DIH                            equ 01

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Color.                                                       ;
        ;...............................................................;

Black                           equ 00
Blue                            equ 01
Green                           equ 02
Cyan                            equ 03
Magenta                         equ 05
Red                             equ 06
Gray                            equ 07

lightBlack                      equ 09
lightBlue                       equ 09
lightGreen                      equ 10
lightCyan                       equ 11
lightRed                        equ 12
lightMagenta                    equ 13
Yellow                          equ 14
White                           equ 15

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Color Define                                                 ;
        ;...............................................................;

color   macro foreg, backg

    ifb <backg>
        db foreg
        else
        db (backg shl 4) + foreg
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Check for Bad Label                                          ;
        ;...............................................................;
        
chklabel    macro label

    ifidn <label>,<offset>
        error 'bad label'
        endif

    ifidn <label>,<org>
        error 'bad label'
        endif

    ifidn <label>,<ptr>
        error 'bad label'
        endif

    ifidn <label>,<end>
        error 'bad label'
        endif

    ifidn <label>,<endp>
        error 'bad label'
        endif

    ifidn <label>,<even>
        error 'bad label'
        endif

    ifidn <label>,<segment>
        error 'bad label'
        endif

        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Get Double Argument.                                         ;
        ;...............................................................;
        
getdarg  macro seg,reg,label
loadedflag  = no

   ifidn <seg>,<es>
        les reg,dword ptr label [bp]
        loadedflag = yes
        endif

   ifidn <seg>,<ds>
        lds reg, dword ptr label [bp]
        loadedflag = yes
        endif

   ife loadedflag-no
        mov reg, word ptr label [ bp._pointer ]
        mov seg, word ptr label [ bp._segment ]
        endif
        endm
        
        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Get Argument.                                                ;
        ;...............................................................;
        
getarg  macro reg,label
        mov reg,word ptr label [ bp ]
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Store Double Argument.                                       ;
        ;...............................................................;
        
stordarg  macro label, seg, reg
        mov word ptr label [ bp._pointer ], reg
        mov word ptr label [ bp._segment ], seg
        endm
        
        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Store Argument.                                              ;
        ;...............................................................;
        
storarg macro label, reg
        mov word ptr label [bp], reg
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Internal Push.                                               ;
        ;...............................................................;
        
tpush   macro reg
    ifidn <reg>, <t>
        pushf
        else
        push reg        
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Internal Pop.                                                ;
        ;...............................................................;
        
tpop   macro reg
    ifidn <reg>, <t>
        popf
        else
        pop reg        
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Save All Registers.                                          ;
        ;...............................................................;
        
saveAllRegisters macro

        push es
        push ds
        push bp
        push di
        push si
        push dx
        push cx
        push bx
        push ax

        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Restore All Registers.                                       ;
        ;...............................................................;
        
restoreAllRegisters macro

        pop ax
        pop bx
        pop cx
        pop dx
        pop si
        pop di
        pop bp
        pop ds
        pop es

        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Save Registers.                                              ;
        ;...............................................................;
        
saveRegisters macro reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, reg0
   ifnb <reg1>
        tpush reg1
        endif
   ifnb <reg2>
        tpush reg2
        endif
   ifnb <reg3>
        tpush reg3
        endif
   ifnb <reg4>
        tpush reg4
        endif
   ifnb <reg5>
        tpush reg5
        endif
   ifnb <reg6>
        tpush reg6
        endif
   ifnb <reg7>
        tpush reg7
        endif
   ifnb <reg8>
        tpush reg8
        endif
   ifnb <reg9>
        tpush reg9
        endif
   ifnb <reg0>
        tpush reg0
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Restore Registers.                                           ;
        ;...............................................................;
        
restoreRegisters macro reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, reg0
   ifnb <reg1>
        tpop reg1
        endif
   ifnb <reg2>
        tpop reg2
        endif
   ifnb <reg3>
        tpop reg3
        endif
   ifnb <reg4>
        tpop reg4
        endif
   ifnb <reg5>
        tpop reg5
        endif
   ifnb <reg6>
        tpop reg6
        endif
   ifnb <reg7>
        tpop reg7
        endif
   ifnb <reg8>
        tpop reg8
        endif
   ifnb <reg9>
        tpop reg9
        endif
   ifnb <reg0>
        tpop reg0
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Save Segments.                                               ;
        ;...............................................................;
        
saveSegments macro reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, reg0

        push ds
        push es

   ifnb <reg1>
        tpush reg1
        endif
   ifnb <reg2>
        tpush reg2
        endif
   ifnb <reg3>
        tpush reg3
        endif
   ifnb <reg4>
        tpush reg4
        endif
   ifnb <reg5>
        tpush reg5
        endif
   ifnb <reg6>
        tpush reg6
        endif
   ifnb <reg7>
        tpush reg7
        endif
   ifnb <reg8>
        tpush reg8
        endif
   ifnb <reg9>
        tpush reg9
        endif
   ifnb <reg0>
        tpush reg0
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Restore Segments.                                            ;
        ;...............................................................;
        
restoreSegments macro reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, reg0

   ifnb <reg1>
        tpop reg1
        endif
   ifnb <reg2>
        tpop reg2
        endif
   ifnb <reg3>
        tpop reg3
        endif
   ifnb <reg4>
        tpop reg4
        endif
   ifnb <reg5>
        tpop reg5
        endif
   ifnb <reg6>
        tpop reg6
        endif
   ifnb <reg7>
        tpop reg7
        endif
   ifnb <reg8>
        tpop reg8
        endif
   ifnb <reg9>
        tpop reg9
        endif
   ifnb <reg0>
        tpop reg0
        endif

        pop es
        pop ds
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Current Data Segment                                         ;
        ;...............................................................;

CurrSegment macro reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, reg0

   ifnb <reg1>
        push ss
        pop reg1
        endif
   ifnb <reg2>
        push ss
        pop reg2
        endif
   ifnb <reg3>
        push ss
        pop reg3
        endif
   ifnb <reg4>
        push ss
        pop reg4
        endif
   ifnb <reg5>
        push ss
        pop reg5
        endif
   ifnb <reg6>
        push ss
        pop reg6
        endif
   ifnb <reg7>
        push ss
        pop reg7
        endif
   ifnb <reg8>
        push ss
        pop reg8
        endif
   ifnb <reg9>
        push ss
        pop reg9
        endif
   ifnb <reg0>
        push ss
        pop reg0
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Standard Save                                                ;
        ;...............................................................;

saveStandard    macro  reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, reg0
        push ds
        push es
        push si
        push di

   ifnb <reg1>
        tpush reg1
        endif
   ifnb <reg2>
        tpush reg2
        endif
   ifnb <reg3>
        tpush reg3
        endif
   ifnb <reg4>
        tpush reg4
        endif
   ifnb <reg5>
        tpush reg5
        endif
   ifnb <reg6>
        tpush reg6
        endif
   ifnb <reg7>
        tpush reg7
        endif
   ifnb <reg8>
        tpush reg8
        endif
   ifnb <reg9>
        tpush reg9
        endif
   ifnb <reg0>
        tpush reg0
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Standard Restore                                             ;
        ;...............................................................;

restoreStandard macro  reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, reg0

   ifnb <reg1>
        tpop reg1
        endif
   ifnb <reg2>
        tpop reg2
        endif
   ifnb <reg3>
        tpop reg3
        endif
   ifnb <reg4>
        tpop reg4
        endif
   ifnb <reg5>
        tpop reg5
        endif
   ifnb <reg6>
        tpop reg6
        endif
   ifnb <reg7>
        tpop reg7
        endif
   ifnb <reg8>
        tpop reg8
        endif
   ifnb <reg9>
        tpop reg9
        endif
   ifnb <reg0>
        tpop reg0
        endif

        pop di
        pop si
        pop es
        pop ds
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Set Seg Register                                             ;
        ;...............................................................;

setSeg  macro seg, reg

    segcopied = no

    irp treg, <es, ds, cs, ss>
      ifidn <reg>, <treg>
        segcopied = yes
        push reg
        pop seg
        endif
        endm

    ife (segcopied NE no)
        mov seg, reg
        endif

        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Set DS                                                       ;
        ;...............................................................;

setDS   macro reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, reg0

   ifnb <reg1>
        setSeg ds, reg1
        endif
   ifnb <reg2>
        setSeg ds, reg2
        endif
   ifnb <reg3>
        setSeg ds, reg3
        endif
   ifnb <reg4>
        setSeg ds, reg4
        endif
   ifnb <reg5>
        setSeg ds, reg5
        endif
   ifnb <reg6>
        setSeg ds, reg6
        endif
   ifnb <reg7>
        setSeg ds, reg7
        endif
   ifnb <reg8>
        setSeg ds, reg8
        endif
   ifnb <reg9>
        setSeg ds, reg9
        endif
   ifnb <reg0>
        setSeg ds, reg0
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Set ES                                                       ;
        ;...............................................................;

setES   macro reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, reg0

   ifnb <reg1>
        setSeg es, reg1
        endif
   ifnb <reg2>
        setSeg es, reg2
        endif
   ifnb <reg3>
        setSeg es, reg3
        endif
   ifnb <reg4>
        setSeg es, reg4
        endif
   ifnb <reg5>
        setSeg es, reg5
        endif
   ifnb <reg6>
        setSeg es, reg6
        endif
   ifnb <reg7>
        setSeg es, reg7
        endif
   ifnb <reg8>
        setSeg es, reg8
        endif
   ifnb <reg9>
        setSeg es, reg9
        endif
   ifnb <reg0>
        setSeg es, reg0
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Set SS                                                       ;
        ;...............................................................;

setSS   macro reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, reg0

   ifnb <reg1>
        setSeg ss, reg1
        endif
   ifnb <reg2>
        setSeg ss, reg2
        endif
   ifnb <reg3>
        setSeg ss, reg3
        endif
   ifnb <reg4>
        setSeg ss, reg4
        endif
   ifnb <reg5>
        setSeg ss, reg5
        endif
   ifnb <reg6>
        setSeg ss, reg6
        endif
   ifnb <reg7>
        setSeg ss, reg7
        endif
   ifnb <reg8>
        setSeg ss, reg8
        endif
   ifnb <reg9>
        setSeg ss, reg9
        endif
   ifnb <reg0>
        setSeg ss, reg0
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Adds an offset to a seg register pair                        ;
        ;...............................................................;

offsetAddr macro seg, reg, offs
        local no_ovf
        segspecial = no
        add reg, offs
        jnc no_ovf

     irp treg, <es, ds, cs, ss>
      ifidn <seg>, <treg>
        segspecial = yes
        mov ax, seg
        add ax, 1000h                           ; account for carry
        mov seg, ax
        endif
        endm

     ife segspecial-no                          ; if seg register not special
        add seg, 1000h                          ; account for carry
        endif

no_ovf:
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Defines a standard subr entry point                          ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                               ;
        ;  saves bp and sets bp to value of sp at entry.                ;
        ;  Must use Return macro to exit.                               ;
        ;                                                               ;
        ;...............................................................;

Entry   macro __args                            ; # word entries

        push bp                                 ; save bp
        mov bp,sp                               ; set bp to point to stack

        _defEntry = 0
        _maxArgs  = 0

    ifnb <__args>
        _retEntry = __args
        _maxArgs  = 2 * __args
        _argEntry = 2 * __args + 4              ; assumes NEAR
    else    
        _retEntry = 0
        _argEntry = 4                           ; assumes NEAR
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Defines a standard subr far entry point                      ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                               ;
        ;  saves bp and sets bp to value of sp at entry.                ;
        ;  Must use Return macro to exit.                               ;
        ;                                                               ;
        ;...............................................................;

FarEntry        macro __args                    ; word entries

        push bp                                 ; save bp
        mov bp,sp                               ; set bp to point to stack

        _defEntry = 0
        _maxArgs  = 0

    ifnb <__args>
        _retEntry = __args
        _maxArgs  = 2 * __args
        _argEntry = 2 * __args + 6              ; assumes FAR
    else    
        _retEntry = 0
        _argEntry = 6                           ; assumes FAR
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Special Entry does not alter registers                       ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                               ;
        ;  ...but sets argument parameters.                             ;
        ;  Must use Return macro to exit.                               ;
        ;                                                               ;
        ;...............................................................;

SpecialEntry  macro __args                      ; word entries

        _defEntry  = 0
        _maxArgs   = 0

    ifnb <__args>
        _retEntry = __args
        _maxArgs  = 2 * __args
        _argEntry = 2 * __args + 4              ; (no bp pushed )
    else    
        _retEntry = 0
        _argEntry = 4                           ; assumes FAR (no bp pushed)
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Defines a word call parameter argument                       ;
        ;...............................................................;

Arg     macro arg_name

    if ( _maxArgs LT 2 )
        error 'Arg definition does not match Entry'
        endif

    ifb <arg_name>
        error 'Arg must have an arg_name parameter.'
        endif

        _argEntry = _argEntry - 2
        arg_name  = _argEntry
        chklabel arg_name        
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Defines a double word call parameter argument                ;
        ;...............................................................;

DArg    macro arg_name

    if ( _maxArgs LT 4 )
        error 'Arg definition does not match Entry'
        endif

    ifb <arg_name>
        error 'Arg must have an arg_name parameter.'
        endif

        _argEntry = _argEntry - 4
        arg_name  = _argEntry
        chklabel arg_name        
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Arg References (Args pushed after call, but before entry)    ;
        ;...............................................................;

rArg    macro arg_name, arg_ref

    ifb <arg_name>
        error 'Arg must have an arg_name parameter.'
        endif

    ifb <arg_ref>
        error 'rArg: 2nd argument must exist.'
        endif

        arg_name  = arg_ref
        chklabel arg_name        
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Arg References (Args pushed after call, but before entry)    ;
        ;...............................................................;

rDArg   macro arg_name, arg_ref

    ifb <arg_name>
        error 'Arg must have an arg_name parameter.'
        endif

    ifb <arg_ref>
        error 'rArg: 2nd argument must exist.'
        endif

        arg_name  = arg_ref
        chklabel arg_name        
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Defines a word argument on stack                             ;
        ;...............................................................;

Def     macro arg_name, reg

    ifb <arg_name>
        error 'Def must have an arg_name parameter.'
        endif

        _defEntry = _defEntry - 2
        arg_name  = _defEntry

pushedreg = no

    ifb <reg>
        push ax
        pushedreg = yes
        endif

    ifnb <reg>
     irp treg,<ax,bx,cx,dx,bp,si,di,es,ds,ss,cs,f>
      ifidn <reg>,<treg>
        tpush reg
        pushedreg = yes
        endif
        endm
        endif

     ife pushedreg-no                           ; if not pushed
        push ax
        mov word ptr arg_name [bp],reg          ; really a value.
        endif
        chklabel arg_name
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Defines a double word argument on stack                      ;
        ;...............................................................;

DDef    macro arg_name, seg, reg

    ifb <arg_name>
        error 'Def must have an arg_name parameter.'
        endif

_defEntry       = _defEntry - 4
arg_name        = _defEntry

pushedreg       = no
pushedseg       = no

    ifb <seg>
        push ax
        push ax
        pushedseg = yes
        pushedreg = yes
        endif

    ifnb <seg>
     irp tseg,<ax,bx,cx,dx,bp,si,di,es,ds,ss,cs,f>
      ifidn <seg>,<tseg>
        tpush seg
        pushedseg = yes
        endif
        endm
        endif

     ife pushedseg-no                           ; if not pushed
        push ax
        mov word ptr arg_name [bp+2],seg        ; really a value.
        endif

    ifnb <reg>
     irp treg,<ax,bx,cx,dx,bp,si,di,es,ds,ss,cs,f>
      ifidn <reg>,<treg>
        tpush reg
        pushedreg = yes
        endif
        endm

     ife pushedreg-no                           ; if not pushed (while reg not blank)
        push ax
        mov word ptr arg_name [bp],reg
        endif

        else
        ife pushedseg-no                        ; if not pushed
          push ax ;
          endif
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Defines n word arguments on stack                            ;
        ;...............................................................;

DefWords macro arg_name, size

    ifb <arg_name>
        error 'Def must have an arg_name parameter.'
        endif

?tempSize       = ( 2 * size )
_defEntry       = _defEntry - ?tempSize
arg_name        = _defEntry

        sub sp, ?tempSize
        endm
        
        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Defines n byte arguments on stack (ends on even boundry)     ;
        ;...............................................................;

DefBytes macro arg_name, size

    ifb <arg_name>
        error 'Def must have an arg_name parameter.'
        endif

?tempSize       = ((size + 1) AND 0FFFEh)
_defEntry       = _defEntry - ?tempSize
arg_name        = _defEntry

        sub sp, ?tempSize
        endm
        
        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Creates an argument definition but you must do the push      ;
        ;...............................................................;

Temp    macro arg_name

    ifb <arg_name>
        error 'Temp must have an arg_name parameter.'
        endif

        _defEntry = _defEntry - 2
        arg_name  = _defEntry
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Creates a dd argument definition but you must do the push    ;
        ;...............................................................;

DTemp   macro arg_name

    ifb <arg_name>
        error 'Def must have an arg_name parameter.'
        endif

        _defEntry = _defEntry - 4
        arg_name  = _defEntry
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Returns from Entry or FarEntry                               ;
        ;...............................................................;

Return  macro
        mov sp, bp
        pop bp
        ret (2 * _retEntry)
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Set Error                                                    ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                               ;
        ;  sets carry,                                                  ;
        ;  loads an error value into ax,                                ;
        ;  optionally jumps to an address.                              ;
        ;                                                               ;
        ;...............................................................;

SetError macro errcode, opt_jumpto
        stc
        mov ax, offset errcode

    ifnb < opt_jumpto >
        jmp opt_jumpto
        endif
        endm

iferror macro errcode, opt_jumpto
        local label
        
    ifb < opt_jumpto >
        error 'must have a goto label'
        else
        jnc label
        mov ax, offset errcode
        jmp opt_jumpto

label:
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Compare and Goto                                             ;
        ;...............................................................;

Goto            macro value, loc
        local label

      if ( value GT 00ffh )
        cmp ax, value
        else
        cmp al, value
        endif

        jnz label
        jmp loc 

label:
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Long Cond Jumps (ifCarry, ifNCarry)                          ;
        ;...............................................................;

ifc     macro addr
        local label
        jnc label
        jmp addr

label:
        endm

ifnc    macro addr
        local label
        jc label
        jmp addr

label:
        endm

ifz     macro addr
        local label
        jnz label
        jmp addr

label:
        endm

ifnz    macro addr
        local label
        jz label
        jmp addr

label:
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Jump Far                                                     ;
        ;...............................................................;

Jmp_far macro seg, addr
        db 0EAh
        dw addr, seg
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Normalize Seg and Offset                                     ;
        ;...............................................................;

NormalizeBuffer macro seg, offset

        push offset
        shr offset, 1
        shr offset, 1
        shr offset, 1
        shr offset, 1

        push ax
        mov ax, seg
        add ax, offset
        mov seg, ax
        pop ax

        pop offset
        and offset, 000fh
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Clear Memory (assumes start address at ES:DI)                ;
        ;...............................................................;

clearMemory     macro size, init
        local skip

        push di
        push ax
        push cx
    ifnb < size >
        mov cx, size
        endif

    ifnb < init >
        mov ax, init
        else
        xor ax, ax
        endif

        shr cx, 1
        rep stosw
        jnc skip
        stosb

skip:
        pop cx
        pop ax
        pop di
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Fast Move                                                    ;
        ;...............................................................;

fastmove        macro arg1, arg2                ; args not used
        local label
        shr cx, 1                               ; optimize for words
        rep movsw                               ; move them
        jnc label                               ; even bytes -->
        movsb                                   ; move odd byte

label:
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Return Called Stack Frame                                    ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                               ;
        ;  reg defined contains stack reference at current Int 21.      ;
        ;                                                               ;
        ;...............................................................;

RetCallersStackFrame macro seg, reg

    ifb < seg >
        error "must have both seg and reg"
        exitm
        endif
        
    ifb < reg >
        error "must have both seg and reg"
        exitm
        endif

    ifidn <seg>,<ss>
        error "can't seg change to ss"
        exitm

        else
        call _RetCallersStackFrame
        pop reg
        pop seg

        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Define Command                                               ;
        ;...............................................................;

Cmnd    macro loc, asciz1, asciz2, asciz3, asciz4, asciz5, asciz6

        dw loc
    ifnb <asciz1>
        db asciz1, 0
        endif

    ifnb <asciz2>
        db asciz2, 0
        endif

    ifnb <asciz3>
        db asciz3, 0
        endif

    ifnb <asciz4>
        db asciz4, 0
        endif

    ifnb <asciz5>
        db asciz5, 0
        endif

    ifnb <asciz6>
        db asciz6, 0
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Define Switches                                              ;
        ;...............................................................;

Switch  macro letter, flags, min, max, value

    ifb <letter>
        db -1
    else    
     ifb <flags>
        db letter
        dw 00, 0000, 0000, 0000
    else    
     ifb <min>
        db letter
        dw flags, 0000, 0000, 0000
    else    
     ifb <max>
        db letter
        dw flags, min,  0000, 0000
    else    
     ifb <value>
        db letter
        dw flags, min,  max,  0000
    else    
        db letter
        dw flags, min,  max,  value
        endif
        endif
        endif
        endif
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Asciz                                                        ;
        ;...............................................................;

Asciz   macro arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9

    ifnb <arg1>
        db arg1
        endif

    ifnb <arg2>
        db arg2
        endif

    ifnb <arg3>
        db arg3
        endif

    ifnb <arg4>
        db arg4
        endif

    ifnb <arg5>
        db arg5
        endif

    ifnb <arg6>
        db arg6
        endif

    ifnb <arg7>
        db arg7
        endif

    ifnb <arg8>
        db arg8
        endif

    ifnb <arg9>
        db arg9
        endif

        db 0
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  IFS                                                          ;
        ;...............................................................;

IFS     macro fct

    ifnb <fct>
        mov al, fct
        endif

        pushf
        call Interrupt2F
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Internal Int21 Emulation call                                ;
        ;...............................................................;

Int21   macro arg1, arg2

   ifnb < arg1 >
    ifnb < arg2 >
      if ( arg1 GT 00ffh )
        mov ax, arg1 + arg2
        else
        mov ax, ( arg1 * 256 + arg2 )
        endif
        endif

    ifb < arg2 >
      if ( arg1 GT 00ffh )
        mov ax, arg1
        else
        mov ah, arg1
        endif
        endif
        endif

    IFNDEF RxDOS_DEBUG
        int 21h                                         ;** DOS
        else
        int 21h                                         ;** debug
        endif
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Int 2E                                                       ;
        ;...............................................................;

Int2E   macro arg1, arg2

   ifnb < arg1 >
    ifnb < arg2 >
      if ( arg1 GT 00ffh )
        mov ax, arg1 + arg2
        else
        mov ax, ( arg1 * 256 + arg2 )
        endif
        endif

    ifb < arg2 >
      if ( arg1 GT 00ffh )
        mov ax, arg1
        else
        mov ah, arg1
        endif
        endif
        endif

        int 2Eh
        endm

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Extended Int Function                                        ;
        ;...............................................................;

ExInt   macro arg

        push bp
        int arg
        pop bp
        endm
