home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 23 / IOPROG_23.ISO / SOFT / ASM / ASMPWR10.ZIP / ASMPOWER.MAC next >
Encoding:
Text File  |  1996-07-29  |  74.7 KB  |  2,235 lines

  1.                 IF1
  2.                   DISPLAY "       ░▒▓█ Using ASM POWER v1.0 assembly language extension █▓▒░"
  3.                   DISPLAY "       ░▒▓█              Earl Hammon, July 1996              █▓▒░"
  4.                 ENDIF
  5.  
  6.                 _@@mcx?? = 1
  7.                 _@@orx?? = 0
  8.                 _@@ifx?? = 0
  9.                 _@@ifv?? = 1
  10.                 _@@dox?? = 0
  11.                 _@@whilex?? = 0
  12.                 _@@swx?? = 0
  13.                 _@@syntax?? = 0
  14.                 _@@uwd?? = 0
  15.                 _@@pwd?? = 0
  16.                 _@@cwd?? = 0
  17.                 _@@prct?? = 0FFFFh
  18.                 _@@use?? = 0
  19.                 _@@skip?? = 0
  20.  
  21. JUMPIF          MACRO   cond, jumploc, syntax_chk
  22.                 _@@use?? = 0
  23.                 IFNB <syntax_chk>
  24.                   IF2
  25.                     ERR
  26.                     DISPLAY ">> ERROR - Syntax error in JUMPIF"
  27.                     IFE _@@syntax??
  28.                       DISPLAY ">>   Usage:  JUMPIF <expression> location"
  29.                       DISPLAY ">>   See the spec file for valid expressions."
  30.                       _@@syntax?? = 1
  31.                     ENDIF
  32.                   ENDIF
  33.                   EXITM
  34.                 ENDIF
  35.                 _@@NQ@ cond, jumploc
  36.                 IF _@@go??
  37.                   IFB <cond>
  38.                     IF2
  39.                       ERR
  40.                       DISPLAY ">> ERROR - No condition specified in JUMPIF"
  41.                       IFE _@@syntax??
  42.                         DISPLAY ">>   Usage:  JUMPIF <expression> location"
  43.                         DISPLAY ">>   See the spec file for valid expressions."
  44.                         _@@syntax?? = 1
  45.                       ENDIF
  46.                     ENDIF
  47.                     EXITM
  48.                   ENDIF
  49.                   IFB <jumploc>
  50.                     IF2
  51.                       ERR
  52.                       DISPLAY ">> ERROR - No location specified in JUMPIF"
  53.                       IFE _@@syntax??
  54.                         DISPLAY ">>   Usage:  JUMPIF <expression> location"
  55.                         DISPLAY ">>   See the spec file for valid expressions."
  56.                         _@@syntax?? = 1
  57.                       ENDIF
  58.                     ENDIF
  59.                     EXITM
  60.                   ENDIF
  61.                   @@loc INSTR <cond>,< EQ >
  62.                   IF @@loc
  63.                     @@arg1 SUBSTR <cond>,1,@@loc-1
  64.                     @@arg2 SUBSTR <cond>,@@loc+4
  65.                     _@@OZ@  e, &@@arg1, &@@arg2, <jumploc>
  66.                     EXITM
  67.                   ENDIF
  68.                   @@loc INSTR <cond>,< NE >
  69.                   IF @@loc
  70.                     @@arg1 SUBSTR <cond>,1,@@loc-1
  71.                     @@arg2 SUBSTR <cond>,@@loc+4
  72.                     _@@OZ@  ne, &@@arg1, &@@arg2, <jumploc>
  73.                     EXITM
  74.                   ENDIF
  75.                   @@loc INSTR <cond>,< GT >
  76.                   IF @@loc
  77.                     @@arg1 SUBSTR <cond>,1,@@loc-1
  78.                     @@arg2 SUBSTR <cond>,@@loc+4
  79.                     _@@OZ@  g, &@@arg1, &@@arg2, <jumploc>
  80.                     EXITM
  81.                   ENDIF
  82.                   @@loc INSTR <cond>,< GE >
  83.                   IF @@loc
  84.                     @@arg1 SUBSTR <cond>,1,@@loc-1
  85.                     @@arg2 SUBSTR <cond>,@@loc+4
  86.                     _@@OZ@  ge, &@@arg1, &@@arg2, <jumploc>
  87.                     EXITM
  88.                   ENDIF
  89.                   @@loc INSTR <cond>,< LT >
  90.                   IF @@loc
  91.                     @@arg1 SUBSTR <cond>,1,@@loc-1
  92.                     @@arg2 SUBSTR <cond>,@@loc+4
  93.                     _@@OZ@  l, &@@arg1, &@@arg2, <jumploc>
  94.                     EXITM
  95.                   ENDIF
  96.                   @@loc INSTR <cond>,< LE >
  97.                   IF &@@loc
  98.                     @@arg1 SUBSTR <cond>,1,@@loc-1
  99.                     @@arg2 SUBSTR <cond>,@@loc+4
  100.                     _@@OZ@  le, &@@arg1, &@@arg2, <jumploc>
  101.                     EXITM
  102.                   ENDIF
  103.                   IFIDN   <cond>, <CARRY>
  104.         jc      &jumploc
  105.                     EXITM
  106.                   ENDIF
  107.                   IFIDN   <cond>, <NO CARRY>
  108.         jnc     &jumploc
  109.                     EXITM
  110.                   ENDIF
  111.                   IFIDN   <cond>, <ZERO>
  112.         jz      &jumploc
  113.                     EXITM
  114.                   ENDIF
  115.                   IFIDN   <cond>, <NOT ZERO>
  116.         jnz     &jumploc
  117.                     EXITM
  118.                   ENDIF
  119.                   IFIDN   <cond>, <EQUAL>
  120.         je      &jumploc
  121.                     EXITM
  122.                   ENDIF
  123.                   IFIDN   <cond>, <NOT EQUAL>
  124.         jne     &jumploc
  125.                     EXITM
  126.                   ENDIF
  127.                   IFIDN   <cond>, <POSITIVE>
  128.         jns     &jumploc
  129.                     EXITM
  130.                   ENDIF
  131.                   IFIDN   <cond>, <NEGATIVE>
  132.         js      &jumploc
  133.                     EXITM
  134.                   ENDIF
  135.                   IFIDN   <cond>, <LESS>
  136.         jl      &jumploc
  137.                     EXITM
  138.                   ENDIF
  139.                   IFIDN   <cond>, <LESS OR EQUAL>
  140.         jle     &jumploc
  141.                     EXITM
  142.                   ENDIF
  143.                   IFIDN   <cond>, <GREATER>
  144.         jg      &jumploc
  145.                     EXITM
  146.                   ENDIF
  147.                   IFIDN   <cond>, <GREATER OR EQUAL>
  148.         jge     &jumploc
  149.                     EXITM
  150.                   ENDIF
  151.                   IFIDN   <cond>, <OVERFLOW>
  152.         jo      &jumploc
  153.                     EXITM
  154.                   ENDIF
  155.                   IFIDN   <cond>, <NO OVERFLOW>
  156.         jno     &jumploc
  157.                     EXITM
  158.                   ENDIF
  159.                   IFIDN   <cond>, <EVEN PARITY>
  160.         jpe     &jumploc
  161.                     EXITM
  162.                   ENDIF
  163.                   IFIDN   <cond>, <ODD PARITY>
  164.         jpo     &jumploc
  165.                     EXITM
  166.                   ENDIF
  167.                   @@loc INSTR <cond>, <NOT >
  168.                   IF @@loc EQ 1
  169.                     @@arg SUBSTR <cond>,4
  170.                     _@@OY@ z, @@arg, <jumploc>
  171.                   ELSE
  172.                     _@@OY@ nz, cond, <jumploc>
  173.                   ENDIF
  174.                 ENDIF
  175. ENDM
  176.  
  177. _@@NQ@          MACRO   arg1, link, arg2, dest
  178.                 _@@go?? = 1
  179.                 IFIDN <link>,<AND>
  180.                   IF_ <arg1>
  181.                   JUMPIF <arg2> dest
  182.                   _@@go?? = 0
  183.                 ELSE
  184.                   IFIDN <link>,<OR>
  185.                     JUMPIF <arg1> dest
  186.                     JUMPIF <arg2> dest
  187.                     _@@go?? = 0
  188.                   ENDIF
  189.                 ENDIF
  190. ENDM
  191.  
  192. _@@OY@          MACRO   test, arg, jumploc
  193.                 IFIDN <test>,<z>
  194.                   IF (.TYPE arg) AND 16
  195.                     IF arg EQ cx
  196.         jcxz    &jumploc
  197.                       EXITM
  198.                     ENDIF
  199.                   ENDIF
  200.                 ENDIF
  201.                 IF (.TYPE arg) AND 16
  202.         or      arg, arg
  203.                 ELSE
  204.                   @@size = (TYPE arg)
  205.                   _@@KZ@ % @@size
  206.         mov     _@@use??, arg
  207.         or      _@@use??, _@@use??
  208.                   _@@KY@
  209.                 ENDIF
  210.         j&test    &jumploc
  211. ENDM
  212.  
  213. _@@OZ@          MACRO   test, arg1, arg2, jumploc
  214.                 IFIDN <test>,<e>
  215.                   IF ((.TYPE arg2) AND 20) NE 0) AND ((.TYPE arg1) AND 20) NE 0)
  216.                     IF (arg2 EQ 0 AND arg1 EQ cx) OR (arg1 EQ 0 AND arg2 EQ cx)
  217.         jcxz    &jumploc
  218.                       EXITM
  219.                     ENDIF
  220.                   ENDIF
  221.                 ENDIF
  222.                 IF ((.TYPE arg1) AND 16) OR ((.TYPE arg2) AND 16)
  223.         cmp    &arg1, &arg2
  224.                 ELSEIF ((.TYPE arg1) AND 4 EQ 0) AND ((.TYPE arg2) AND 4 EQ 4)
  225.         cmp    &arg1, &arg2
  226.                 ELSE
  227.                   @@size = (TYPE arg2)
  228.                   _@@KZ@ % @@size
  229.         mov     _@@use??, &arg1
  230.         cmp     _@@use??, &arg2
  231.                   _@@KY@
  232.                 ENDIF
  233.                 j&test &jumploc
  234. ENDM
  235.  
  236.  
  237. IF_             MACRO   cond, syntax_chk
  238.                 _@@use?? = 0
  239.                 IFNB <syntax_chk>
  240.                   IF2
  241.                     ERR
  242.                     DISPLAY ">> ERROR - Syntax error in IF_"
  243.                     IFE _@@syntax??
  244.                       DISPLAY ">>   Usage:  IF_ <expression>"
  245.                       DISPLAY ">>   See the spec file for valid expressions."
  246.                       _@@syntax?? = 1
  247.                     ENDIF
  248.                   ENDIF
  249.                   EXITM
  250.                 ENDIF
  251.                 _@@NR@  cond, syntax_chk
  252.                 IF _@@go??
  253.                   _@@ifx?? = _@@ifx??+1
  254.                   IFB <cond>
  255.                     IF2
  256.                       ERR
  257.                       DISPLAY ">> ERROR - No condition specified in IF_"
  258.                       IFE _@@syntax??
  259.                         DISPLAY ">>   Usage:  IF_ <expression>"
  260.                         DISPLAY ">>   See the spec file for valid expressions."
  261.                         _@@syntax?? = 1
  262.                       ENDIF
  263.                     ENDIF
  264.                     EXITM
  265.                   ENDIF
  266.                   @@loc INSTR <cond>,< EQ >
  267.                   IF @@loc
  268.                     @@arg1 SUBSTR <cond>,1,@@loc-1
  269.                     @@arg2 SUBSTR <cond>,@@loc+4
  270.                     _@@MZ@  ne, &@@arg1, &@@arg2, % _@@ifx??
  271.                     EXITM
  272.                   ENDIF
  273.                   @@loc INSTR <cond>,< NE >
  274.                   IF @@loc
  275.                     @@arg1 SUBSTR <cond>,1,@@loc-1
  276.                     @@arg2 SUBSTR <cond>,@@loc+4
  277.                     _@@MZ@  e, &@@arg1, &@@arg2, % _@@ifx??
  278.                     EXITM
  279.                   ENDIF
  280.                   @@loc INSTR <cond>,< GT >
  281.                   IF @@loc
  282.                     @@arg1 SUBSTR <cond>,1,@@loc-1
  283.                     @@arg2 SUBSTR <cond>,@@loc+4
  284.                     _@@MZ@  le, &@@arg1, &@@arg2, % _@@ifx??
  285.                     EXITM
  286.                   ENDIF
  287.                   @@loc INSTR <cond>,< GE >
  288.                   IF @@loc
  289.                     @@arg1 SUBSTR <cond>,1,@@loc-1
  290.                     @@arg2 SUBSTR <cond>,@@loc+4
  291.                     _@@MZ@  l, &@@arg1, &@@arg2, % _@@ifx??
  292.                     EXITM
  293.                   ENDIF
  294.                   @@loc INSTR <cond>,< LT >
  295.                   IF @@loc
  296.                     @@arg1 SUBSTR <cond>,1,@@loc-1
  297.                     @@arg2 SUBSTR <cond>,@@loc+4
  298.                     _@@MZ@  ge, &@@arg1, &@@arg2, % _@@ifx??
  299.                     EXITM
  300.                   ENDIF
  301.                   @@loc INSTR <cond>,< LE >
  302.                   IF &@@loc
  303.                     @@arg1 SUBSTR <cond>,1,@@loc-1
  304.                     @@arg2 SUBSTR <cond>,@@loc+4
  305.                     _@@MZ@  g, &@@arg1, &@@arg2, % _@@ifx??
  306.                     EXITM
  307.                   ENDIF
  308.                   IFIDN   <cond>, <CARRY>
  309.                     _@@MX@  nc, % _@@ifx??
  310.                     EXITM
  311.                   ENDIF
  312.                   IFIDN   <cond>, <NO CARRY>
  313.                     _@@MX@  c, % _@@ifx??
  314.                     EXITM
  315.                   ENDIF
  316.                   IFIDN   <cond>, <ZERO>
  317.                     _@@MX@  nz, % _@@ifx??
  318.                     EXITM
  319.                   ENDIF
  320.                   IFIDN   <cond>, <NOT ZERO>
  321.                     _@@MX@  z, % _@@ifx??
  322.                     EXITM
  323.                   ENDIF
  324.                   IFIDN   <cond>, <EQUAL>
  325.                     _@@MX@  ne, % _@@ifx??
  326.                     EXITM
  327.                   ENDIF
  328.                   IFIDN   <cond>, <NOT EQUAL>
  329.                     _@@MX@  e, % _@@ifx??
  330.                     EXITM
  331.                   ENDIF
  332.                   IFIDN   <cond>, <POSITIVE>
  333.                     _@@MX@  s, % _@@ifx??
  334.                     EXITM
  335.                   ENDIF
  336.                   IFIDN   <cond>, <NEGATIVE>
  337.                     _@@MX@  ns, % _@@ifx??
  338.                     EXITM
  339.                   ENDIF
  340.                   IFIDN   <cond>, <LESS>
  341.                     _@@MX@  ge, % _@@ifx??
  342.                     EXITM
  343.                   ENDIF
  344.                   IFIDN   <cond>, <LESS OR EQUAL>
  345.                     _@@MX@  g, % _@@ifx??
  346.                     EXITM
  347.                   ENDIF
  348.                   IFIDN   <cond>, <GREATER>
  349.                     _@@MX@  le, % _@@ifx??
  350.                     EXITM
  351.                   ENDIF
  352.                   IFIDN   <cond>, <GREATER OR EQUAL>
  353.                     _@@MX@  l, % _@@ifx??
  354.                     EXITM
  355.                   ENDIF
  356.                   IFIDN   <cond>, <OVERFLOW>
  357.                     _@@MX@  o, % _@@ifx??
  358.                     EXITM
  359.                   ENDIF
  360.                   IFIDN   <cond>, <NO OVERFLOW>
  361.                     _@@MX@  no, % _@@ifx??
  362.                     EXITM
  363.                   ENDIF
  364.                   IFIDN   <cond>, <EVEN PARITY>
  365.                     _@@MX@  pe, % _@@ifx??
  366.                     EXITM
  367.                   ENDIF
  368.                   IFIDN   <cond>, <ODD PARITY>
  369.                     _@@MX@  po, % _@@ifx??
  370.                     EXITM
  371.                   ENDIF
  372.                   @@loc INSTR <cond>, <NOT >
  373.                   IF @@loc EQ 1
  374.                     @@arg SUBSTR <cond>,4
  375.                     _@@MY@ nz, @@arg, % _@@ifx??
  376.                   ELSE
  377.                     _@@MY@ z, cond, % _@@ifx??
  378.                   ENDIF
  379.                 ENDIF
  380. ENDM
  381.  
  382. _@@NR@          MACRO   arg1, link, arg2
  383.                 _@@go?? = 1
  384.                 IFIDN <link>,<AND>
  385.                   IF_ <arg1>
  386.                   _@@ifv?? = 3
  387.                   IF_ <arg2>
  388.                   _@@ifv?? = 1
  389.                   _@@go?? = 0
  390.                 ELSE
  391.                   IFIDN <link>,<OR>
  392.                     _@@orx?? = _@@orx?? + 1
  393.                     _@@NS@ <arg1>, % _@@orx??, <arg2>
  394.                     _@@go?? = 0
  395.                   ENDIF
  396.                 ENDIF
  397. ENDM
  398.  
  399. _@@NS@          MACRO   cond, num, cond2
  400.                 JUMPIF <cond> _@o?&num&@
  401.                 IF_ <cond2>
  402. _@o?&num&@:
  403. ENDM
  404.  
  405. _@@MX@          MACRO   test, num
  406.                 IF num LT 10
  407.                   IF _@@skip??
  408.         j&test&    _@@onskip??
  409.                   ELSE
  410.         j&test&    _@a?000&num&@
  411.                   ENDIF
  412.                   _@a?000&num&?? = _@@ifv??
  413.                   IF2
  414.                     IFNDEF _@a?000&num&@
  415.                       ERR
  416.                       DISPLAY ">> ERROR - IF_ without _ENDIF or WHILE_ without _WEND"
  417.                     ENDIF
  418.                   ENDIF
  419.                 ELSEIF num LT 100
  420.                   IF _@@skip??
  421.         j&test&    _@@onskip??
  422.                   ELSE
  423.         j&test&     _@a?00&num&@
  424.                   ENDIF
  425.                   _@a?00&num&?? = _@@ifv??
  426.                   IF2
  427.                     IFNDEF _@a?00&num&@
  428.                       ERR
  429.                       DISPLAY ">> ERROR - IF_ without _ENDIF or WHILE_ without _WEND"
  430.                     ENDIF
  431.                   ENDIF
  432.                 ELSEIF num LT 1000
  433.                   IF _@@skip??
  434.         j&test&    _@@onskip??
  435.                   ELSE
  436.         j&test&     _@a?0&num&@
  437.                   ENDIF
  438.                   _@a?0&num&?? = _@@ifv??
  439.                   IF2
  440.                     IFNDEF _@a?0&num&@
  441.                       ERR
  442.                       DISPLAY ">> ERROR - IF_ without _ENDIF or WHILE_ without _WEND"
  443.                     ENDIF
  444.                   ENDIF
  445.                 ELSE
  446.                   IF _@@skip??
  447.         j&test&    _@@onskip??
  448.                   ELSE
  449.         j&test&     _@a?&num&@
  450.                   ENDIF
  451.                   _@a?&num&?? = _@@ifv??
  452.                   IF2
  453.                     IFNDEF _@a?&num&@
  454.                       ERR
  455.                       DISPLAY ">> ERROR - IF_ without _ENDIF or WHILE_ without _WEND"
  456.                     ENDIF
  457.                   ENDIF
  458.                 ENDIF
  459.                 _@@skip?? = 0
  460. ENDM
  461.  
  462. _@@MY@          MACRO   test, arg, num
  463.                 IFIDN <test>,<z>
  464.                   IF (.TYPE arg) AND 16
  465.                     IF arg EQ cx
  466.                       _@@MX@ cxz, % num
  467.                       EXITM
  468.                     ENDIF
  469.                   ENDIF
  470.                 ENDIF
  471.                 IF (.TYPE arg) AND 16
  472.         or      arg, arg
  473.                 ELSE
  474.                   _@@KZ@ % (TYPE arg)
  475.         mov     _@@use??, arg
  476.         or      _@@use??, _@@use??
  477.                   _@@KY@
  478.                 ENDIF
  479.                 _@@MX@ &test, % num
  480. ENDM
  481.  
  482. _@@MZ@          MACRO   test, arg1, arg2, num
  483.                 IFIDN <test>,<e>
  484.                   IF ((.TYPE arg2) AND 20 NE 0) AND ((.TYPE arg1) AND 20 NE 0)
  485.                     IF (arg2 EQ 0 AND arg1 EQ cx) OR (arg1 EQ 0 AND arg2 EQ cx)
  486.                       _@@MX@ cxz, % num
  487.                       EXITM
  488.                     ENDIF
  489.                   ENDIF
  490.                 ENDIF
  491.                 IF ((.TYPE arg1) AND 16) OR ((.TYPE arg2) AND 16)
  492.         cmp    &arg1, &arg2
  493.                 ELSEIF ((.TYPE arg1) AND 4 EQ 0) AND ((.TYPE arg2) AND 4 EQ 4)
  494.         cmp    &arg1, &arg2
  495.                 ELSE
  496.                   _@@KZ@ % (TYPE arg2)
  497.         mov     _@@use??, &arg1
  498.         cmp     _@@use??, &arg2
  499.                   _@@KY@
  500.                 ENDIF
  501.                 _@@MX@ test, % num
  502. ENDM
  503.  
  504.  
  505. _ELSE_          MACRO
  506.                 _@@QQ@ % _@@ifx??
  507.                 _ENDIF
  508.                 _@@ifx?? = _@@ifx??+1
  509. ENDM
  510.  
  511.  
  512. _ELSEIF_        MACRO   cond, syntax_chk
  513.                 _ELSE_
  514.                 _@@ifv?? = 2
  515.                 IF_  <cond>, <syntax_chk>
  516.                 _@@ifv?? = 1
  517. ENDM
  518.  
  519.  
  520. _ENDIF          MACRO
  521.                 _@@use?? = 0
  522.                 _@@QZ@ % _@@ifx??
  523. ENDM
  524.  
  525. _@@QP@          MACRO   num
  526.                 IF num LT 10
  527.                   _@@QR@ _@a?000&num&??
  528.                 ELSEIF num LT 100
  529.                   _@@QR@ _@a?00&num&??
  530.                 ELSEIF num LT 1000
  531.                   _@@QR@ _@a?0&num&??
  532.                 ELSE
  533.                   _@@QR@ _@a?&num&??
  534.                 ENDIF
  535. ENDM
  536.  
  537. _@@QQ@          MACRO   num
  538.                 _@@done?? = 0
  539.                 _@@try?? = num
  540.                 REPT num
  541.                   _@@QP@ % _@@try??
  542.                   IF  _@@done??
  543.                     EXITM
  544.                   ENDIF
  545.                   _@@try?? = _@@try?? - 1
  546.                 ENDM
  547.                 _@@MX@ <mp>, % _@@ifx??+1
  548.                 _@@ifv?? = 1
  549. ENDM
  550.  
  551. _@@QR@          MACRO   loc
  552.                 IF (&loc EQ 1) OR (&loc EQ 2)
  553.                   _@@ifv?? = &loc
  554.                   &loc = 1
  555.                   _@@done?? = 1
  556.                 ELSEIF (&loc EQ 3)
  557.                   &loc = 2
  558.                   _@@ifv?? = 1
  559.                   _@@done?? = 1
  560.                 ENDIF
  561. ENDM
  562.  
  563. _@@QX@          MACRO   num
  564.                 IF num LT 10
  565.                   _@@QY@ _@a?000&num&
  566.                 ELSEIF num LT 100
  567.                   _@@QY@ _@a?00&num&
  568.                 ELSEIF num LT 1000
  569.                   _@@QY@ _@a?0&num&
  570.                 ELSE
  571.                   _@@QY@ _@a?&num&
  572.                 ENDIF
  573. ENDM
  574.  
  575. _@@QY@          MACRO   loc
  576.                 IF &loc&??
  577.         &loc&@:
  578.                   IF &loc&?? EQ 1
  579.                     _@@done?? = 1
  580.                   ENDIF
  581.                   &loc&?? = 0
  582.                 ENDIF
  583. ENDM
  584.  
  585. _@@QZ@          MACRO   num
  586.                 _@@done?? = 0
  587.                 _@@try?? = num
  588.                 REPT num
  589.                   _@@QX@ % _@@try??
  590.                   IF  _@@done??
  591.                     EXITM
  592.                   ENDIF
  593.                   _@@try?? = _@@try?? - 1
  594.                 ENDM
  595.                 IFE _@@done??
  596.                   IF2
  597.                     ERR
  598.                     DISPLAY  "_ENDIF without IF_"
  599.                   ENDIF
  600.                 ENDIF
  601. ENDM
  602.  
  603.  
  604. DO_             MACRO
  605.                 _@@use?? = 0
  606.                 _@@dox?? = _@@dox?? + 1
  607.                 _@@DZ@ % _@@dox??
  608. ENDM
  609.  
  610. _@@DZ@          MACRO   num
  611.                 IF num LT 10
  612.         _@d?000&num&@:
  613.                   _@d?000&num&?? = 0
  614.                   IF2
  615.                     IFNDEF _@d?000&num&@
  616.                       ERR
  617.                       DISPLAY ">> ERROR - DO_ without _WHILE"
  618.                     ENDIF
  619.                   ENDIF
  620.                 ELSEIF num LT 100
  621.         _@d?00&num&@:
  622.                   _@d?00&num&?? = 0
  623.                   IF2
  624.                     IFNDEF _@d?00&num&@
  625.                       ERR
  626.                       DISPLAY ">> ERROR - DO_ without _WHILE"
  627.                     ENDIF
  628.                   ENDIF
  629.                 ELSEIF num LT 1000
  630.         _@d?0&num&@:
  631.                   _@d?0&num&?? = 0
  632.                   IF2
  633.                     IFNDEF _@d?0&num&@
  634.                       ERR
  635.                       DISPLAY ">> ERROR - DO_ without _WHILE"
  636.                     ENDIF
  637.                   ENDIF
  638.                 ELSE
  639.         _@d?&num&@:
  640.                   _@d?&num&?? = 0
  641.                   IF2
  642.                     IFNDEF _@d?&num&@
  643.                       ERR
  644.                       DISPLAY ">> ERROR - DO_ without _WHILE"
  645.                     ENDIF
  646.                   ENDIF
  647.                 ENDIF
  648. ENDM
  649.  
  650.  
  651. _WHILE          MACRO   cond, syntax_chk
  652.                 _@@use?? = 0
  653.                 _@@WW@ % _@@dox??
  654.                 IFE _@@done??
  655.                   IF2
  656.                     ERR
  657.                     DISPLAY ">> ERROR - _WHILE without DO_"
  658.                   ENDIF
  659.                 ELSE
  660.                   JUMPIF <cond>, _@jump??, <syntax_chk>
  661.                 ENDIF
  662. ENDM
  663.  
  664. _@@WW@          MACRO   num
  665.                 _@@done?? = 0
  666.                 _@@try?? = num
  667.                 REPT num
  668.                   _@@WX@ % _@@try??
  669.                   IF  _@@done??
  670.                     EXITM
  671.                   ENDIF
  672.                 ENDM
  673. ENDM
  674.  
  675. _@@WX@          MACRO   num
  676.                 IF num LT 10
  677.                   _@@WY@ _@d?000&num&
  678.                 ELSEIF num LT 100
  679.                   _@@WY@ _@d?00&num&
  680.                 ELSEIF num LT 1000
  681.                   _@@WY@ _@d?0&num&
  682.                 ELSE
  683.                   _@@WY@ _@d?&num&
  684.                 ENDIF
  685. ENDM
  686.  
  687. _@@WY@          MACRO   loc
  688.                 IFE  &loc&??
  689.                   _@jump?? = &loc&@
  690.                   &loc&?? = 1
  691.                   _@@done?? = 1
  692.                 ELSE
  693.                   _@@try?? = _@@try?? - 1
  694.                 ENDIF
  695. ENDM
  696.  
  697. _@@WZ@          MACRO   num
  698.                 IF num LT 10
  699.         _@b?000&num&@:
  700.                   _@b?000&num&?? = 0
  701.                 ELSEIF num LT 100
  702.         _@b?00&num&@:
  703.                   _@b?00&num&?? = 0
  704.                 ELSEIF num LT 1000
  705.         _@b?0&num&@:
  706.                   _@b?0&num&?? = 0
  707.                 ELSE
  708.         _@b?&num&@:
  709.                   _@b?&num&?? = 0
  710.                 ENDIF
  711. ENDM
  712.  
  713.  
  714. WHILE_          MACRO   cond, syntax_chk
  715.                 _@@use?? = 0
  716.                 _@@whilex?? = _@@whilex?? + 1
  717.                 _@@WZ@ % _@@whilex??
  718.                 _@@ifv?? = 1
  719.                 IF_ <&cond&>, <&syntax_chk&>
  720. ENDM
  721.  
  722.  
  723. _WEND           MACRO
  724.                 _@@PZ@ % _@@whilex??
  725.                 _ENDIF
  726. ENDM
  727.  
  728. _@@PX@          MACRO   num
  729.                 IF num LT 10
  730.                   _@@PY@ _@b?000&num&
  731.                 ELSEIF num LT 100
  732.                   _@@PY@ _@b?00&num&
  733.                 ELSEIF num LT 1000
  734.                   _@@PY@ _@b?0&num&
  735.                 ELSE
  736.                   _@@PY@ _@b?&num&
  737.                 ENDIF
  738. ENDM
  739.  
  740. _@@PY@          MACRO   check
  741.                 IFE &check&??
  742.                   &check&?? = 1
  743.         jmp     &check&@
  744.                   _@@done?? = 1
  745.                 ELSE
  746.                   _@@try?? = _@@try?? - 1
  747.                 ENDIF
  748. ENDM
  749.  
  750. _@@PZ@          MACRO   num
  751.                 _@@done?? = 0
  752.                 _@@try?? = num
  753.                 REPT num
  754.                   _@@PX@ % _@@try??
  755.                   IF  _@@done??
  756.                     EXITM
  757.                   ENDIF
  758.                 ENDM
  759.                 IFE _@@done??
  760.                   IF2
  761.                     ERR
  762.                     DISPLAY  "_WEND without WHILE_"
  763.                   ENDIF
  764.                 ENDIF
  765. ENDM
  766.  
  767.  
  768. SWITCH_         MACRO   arg, syntax_chk
  769.                 _@@use?? = 0
  770.                 IFB <arg>
  771.                   IF2
  772.                     ERR
  773.                     DISPLAY ">> ERROR - No argument specified in SWITCH_"
  774.                   ENDIF
  775.                   EXITM
  776.                 ENDIF
  777.                 IFNB <syntax_chk>
  778.                   IF2
  779.                     ERR
  780.                     DISPLAY ">> ERROR - Syntax error in SWITCH_"
  781.                   ENDIF
  782.                   EXITM
  783.                 ENDIF
  784.                 _@@swx?? = _@@swx?? + 1
  785.                 _@@casex?? = 0
  786.                 _@@SE@ % _@@swx??
  787.                 IF (.TYPE arg) AND 16
  788.                   _@@sa?? = arg
  789.                 ELSE
  790.                   _@@KZ@ % (TYPE arg)
  791.                   _@@sa?? = _@@use??
  792.         mov     _@@sa??, arg
  793.                 ENDIF
  794.                 _@@break?? = $
  795. ENDM
  796.  
  797. _@@SE@          MACRO   snum
  798.                 IF2
  799.                   IF snum LT 10
  800.                     IFDEF _@s?000&snum&@
  801.                       EXITM
  802.                     ENDIF
  803.                   ELSEIF snum LT 100
  804.                     IFDEF _@s?00&snum&@
  805.                       EXITM
  806.                     ENDIF
  807.                   ELSEIF snum LT 1000
  808.                     IFDEF _@s?0&snum&@
  809.                       EXITM
  810.                     ENDIF
  811.                   ELSE
  812.                     IFDEF _@s?&snum&@
  813.                       EXITM
  814.                     ENDIF
  815.                   ENDIF
  816.                   ERR
  817.                   DISPLAY ">> ERROR - SWITCH_ without _ENDS"
  818.                 ENDIF
  819. ENDM
  820.  
  821. CASE_           MACRO   arg, syntax_chk
  822.                 local   _@skip@
  823.                 _@@use?? = 0
  824.                 IFB <arg>
  825.                   IF2
  826.                     ERR
  827.                     DISPLAY ">> ERROR - No argument specified in CASE_"
  828.                   ENDIF
  829.                   EXITM
  830.                 ENDIF
  831.                 IFNB <syntax_chk>
  832.                   IF2
  833.                     ERR
  834.                     DISPLAY ">> ERROR - Syntax error in CASE_"
  835.                   ENDIF
  836.                   EXITM
  837.                 ENDIF
  838.                 IF _@@break?? NE $
  839.         jmp   short   _@skip@
  840.                 ENDIF
  841.                 _@@ZZ@ % _@@swx??
  842.                 _@@casex?? = _@@casex?? + 1
  843.         cmp     _@@sa??, arg
  844.                 _@@ZY@ % _@@swx??
  845.                 _@@KY@
  846.         _@skip@:
  847. ENDM
  848.  
  849. JUMPCASE        MACRO   arg, location, syntax_chk
  850.                 local   _@skip@
  851.                 _@@use?? = 0
  852.                 IFE _@@needpop??
  853.                   SENDSKIPTO <location>
  854.                 ENDIF
  855.                 IFB <arg>
  856.                   IF2
  857.                     ERR
  858.                     DISPLAY ">> ERROR - No argument specified in CASE_"
  859.                   ENDIF
  860.                   EXITM
  861.                 ENDIF
  862.                 IFNB <syntax_chk>
  863.                   IF2
  864.                     ERR
  865.                     DISPLAY ">> ERROR - Syntax error in CASE_"
  866.                   ENDIF
  867.                   EXITM
  868.                 ENDIF
  869.                 IF _@@break?? NE $
  870.         jmp   short   _@skip@
  871.                 ENDIF
  872.                 _@@ZZ@ % _@@swx??
  873.                 _@@casex?? = _@@casex?? + 1
  874.         cmp     _@@sa??, arg
  875.                 _@@ZY@ % _@@swx??
  876.                 _@@KY@
  877.                 IF _@@needpop??
  878.         jmp     location
  879.                 ENDIF
  880.                 _@@break?? = $
  881.         _@skip@:
  882. ENDM
  883.                 
  884. MULTICASE_      MACRO   arg, syntax
  885.                 _@@ZQ@ % _@@mcx??
  886.                 IFE _@@needpop??
  887.                   CASE_ <arg>, syntax
  888.                   _ENDCASE
  889.                 ELSE
  890.                   _@@needpop?? = 0
  891.                   CASE_ <arg>, syntax
  892.                   _ENDCASE
  893.                   _@@needpop?? = 1
  894.                 ENDIF
  895. ENDM
  896.  
  897. LASTCASE_       MACRO   arg, syntax
  898.                 local   _@skip@
  899.                 _@@use?? = 0
  900.                 IFB <arg>
  901.                   IF2
  902.                     ERR
  903.                     DISPLAY ">> ERROR - No argument specified in LASTCASE_"
  904.                   ENDIF
  905.                   EXITM
  906.                 ENDIF
  907.                 IFNB <syntax>
  908.                   IF2
  909.                     ERR
  910.                     DISPLAY ">> ERROR - Syntax error in LASTCASE_"
  911.                   ENDIF
  912.                   EXITM
  913.                 ENDIF
  914.                 IF _@@break?? NE $
  915.         jmp   short   _@skip@
  916.                 ENDIF
  917.                 _@@ZZ@ % _@@swx??
  918.                 _@@casex?? = _@@casex?? + 1
  919.         cmp     _@@sa??, arg
  920.                 _@@ZY@ % _@@swx??
  921.                 _@@ZR@ % _@@mcx??
  922.                 _@@KY@
  923.         _@skip@:
  924. ENDM
  925.  
  926. _@@ZQ@          MACRO   num
  927.                 IF2
  928.                   IFNDEF _@mc?&num&@
  929.                     ERR
  930.                     DISPLAY ">> ERROR - MULTICASE_ without LASTCASE_"
  931.                   ENDIF
  932.                 ELSE
  933.                   SENDSKIPTO _@mc?&num&@
  934.                 ENDIF
  935. ENDM
  936.  
  937. _@@ZR@          MACRO   num
  938.         _@mc?&num&@:
  939.                 _@@mcx?? = num+1
  940. ENDM
  941.  
  942. _@@ZW@          MACRO   spart, cnum
  943.                 IF _@@skip??
  944.         je      _@@onskip??
  945.                 _@@skip?? = 0
  946.                 ELSE
  947.                   IF cnum LT 10
  948.         jne     &spart&c?000&cnum&@
  949.                   ELSEIF cnum LT 100
  950.         jne     &spart&c?00&cnum&@
  951.                   ELSEIF cnum LT 1000
  952.         jne     &spart&c?0&cnum&@
  953.                   ELSE
  954.         jne     &spart&c?&cnum&@
  955.                   ENDIF
  956.                 ENDIF
  957. ENDM
  958.  
  959. _@@ZX@          MACRO   spart, cnum
  960.                 IF cnum LT 10
  961.         &spart&c?000&cnum&@:
  962.                 ELSEIF cnum LT 100
  963.         &spart&c?00&cnum&@:
  964.                 ELSEIF cnum LT 1000
  965.         &spart&c?0&cnum&@:
  966.                 ELSE
  967.         &spart&c?&cnum&@:
  968.                 ENDIF
  969. ENDM
  970.  
  971. _@@ZY@          MACRO   snum
  972.                 IF snum LT 10
  973.                   _@@ZW@ _@s?000&snum&, % _@@casex??
  974.                 ELSEIF snum LT 100
  975.                   _@@ZW@ _@s?00&snum&, % _@@casex??
  976.                 ELSEIF snum LT 1000
  977.                   _@@ZW@ _@s?0&snum&, % _@@casex??
  978.                 ELSE
  979.                   _@@ZW@ _@s?&snum&, % _@@casex??
  980.                 ENDIF
  981. ENDM
  982.  
  983. _@@ZZ@          MACRO   snum
  984.                 IF snum LT 10
  985.                   _@@ZX@ _@s?000&snum&, % _@@casex??
  986.                 ELSEIF snum LT 100
  987.                   _@@ZX@ _@s?00&snum&, % _@@casex??
  988.                 ELSEIF snum LT 1000
  989.                   _@@ZX@ _@s?0&snum&, % _@@casex??
  990.                 ELSE
  991.                   _@@ZX@ _@s?&snum&, % _@@casex??
  992.                 ENDIF
  993. ENDM
  994.  
  995.  
  996. _ENDCASE        MACRO
  997.                 _@@use?? = 0
  998.                 _@@break?? = $
  999. ENDM
  1000.  
  1001.  
  1002. _BREAK          MACRO
  1003.                 _@@use?? = 0
  1004.                 _@@YZ@ % _@@swx??
  1005.                 _@@break?? = $
  1006. ENDM
  1007.  
  1008. _@@YZ@          MACRO   snum
  1009.                 IF snum LT 10
  1010.         jmp _@s?000&snum&@
  1011.                 ELSEIF snum LT 100
  1012.         jmp _@s?00&snum&@
  1013.                 ELSEIF snum LT 1000
  1014.         jmp _@s?0&snum&@
  1015.                 ELSE
  1016.         jmp _@s?&snum&@
  1017.                 ENDIF
  1018. ENDM
  1019.  
  1020.                             
  1021. DEFAULT_        MACRO
  1022.                 LOCAL   _@skip@
  1023.                 _@@use?? = 0
  1024.                 IF _@@break?? NE $
  1025.         jmp   short   _@skip@
  1026.                 ENDIF
  1027.                 _@@ZZ@ % _@@swx??
  1028.                 _@@casex?? = _@@casex?? + 1
  1029.                 _@@KY@
  1030.         _@skip@:
  1031. ENDM
  1032.  
  1033.  
  1034. _ENDS           MACRO
  1035.                 LOCAL   _@skip@
  1036.                 _@@use?? = 0
  1037.                 IF _@@break?? NE $
  1038.         jmp   short   _@skip@
  1039.                 ENDIF
  1040.                 _@@KY@
  1041.         _@skip@:
  1042.                 _@@XZ@ % _@@swx??
  1043.                 _@@ZZ@ % _@@swx??
  1044. ENDM
  1045.  
  1046. _@@XZ@          MACRO   snum
  1047.                 IF snum LT 10
  1048.         _@s?000&snum&@:
  1049.                   _@s?000&snum&?? = 1
  1050.                 ELSEIF snum LT 100
  1051.         _@s?000&snum&@:
  1052.                   _@s?00&snum&?? = 1
  1053.                 ELSEIF snum LT 1000
  1054.         _@s?000&snum&@:
  1055.                   _@s?0&snum&?? = 1
  1056.                 ELSE
  1057.         _@s?000&snum&@:
  1058.                   _@s?&snum&?? = 1
  1059.                 ENDIF
  1060. ENDM
  1061.  
  1062.  
  1063. _@@KY@          MACRO
  1064.                 IF _@@needpop??
  1065.                   IF _@@use?? EQ al
  1066.         pop     ax
  1067.                   ELSEIF _@@use?? EQ ax
  1068.         pop     ax
  1069.                   ELSEIF @Cpu AND 8
  1070.                     IF _@@use?? EQ eax
  1071.         pop     eax
  1072.                     ENDIF
  1073.                   ELSE
  1074.                     IF2
  1075.                       DISPLAY ">> ERROR - Need to pop unknown register."
  1076.                       _@@IM@
  1077.                     ENDIF
  1078.                   ENDIF
  1079.                 ENDIF
  1080. ENDM
  1081.  
  1082. _@@KZ@          MACRO   size
  1083.                 _@@needpop?? = 0
  1084.                 IF (size EQ 1)
  1085.                   _@@try?? = 0000000000000001b
  1086.                   IRP use, <al,ah,cl,ch,bl,bh,dl,dh>
  1087.                     IFE _@@prct?? AND _@@try??
  1088.                       _@@use?? = use
  1089.                       EXITM
  1090.                     ENDIF
  1091.                     _@@try?? = _@@try?? SHL 1
  1092.                   ENDM
  1093.                   IF _@@try?? EQ 100000000b
  1094.         push    ax
  1095.                     _@@needpop?? = 1
  1096.                     _@@use?? = al
  1097.                   ENDIF
  1098.                 ELSEIF size EQ 2
  1099.                   _@@try?? = 0000000000000011b
  1100.                   IRP use, <ax,cx,bx,dx,si,di,bp>
  1101.                     IFE _@@prct?? AND _@@try??
  1102.                       _@@use?? = use
  1103.                       EXITM
  1104.                     ENDIF
  1105.                     _@@try?? = _@@try?? SHL 2
  1106.                   ENDM
  1107.                   IF _@@try?? EQ 1100000000000000b
  1108.         push    ax
  1109.                     _@@needpop?? = 1
  1110.                     _@@use?? = ax
  1111.                   ENDIF
  1112.                 ELSEIF size EQ 4
  1113.                   IRP use, <eax,ecx,ebx,edx,ebp,edi,esi>
  1114.                     IFE _@@prct?? AND _@@try??
  1115.                       _@@use?? = use
  1116.                       EXITM
  1117.                     ENDIF
  1118.                     _@@try?? = _@@try?? SHL 2
  1119.                   ENDM
  1120.                   IF _@@try?? EQ 1100000000000000b
  1121.         push    eax
  1122.                     _@@needpop?? = 1
  1123.                     _@@use?? = eax
  1124.                   ENDIF
  1125.                 ELSE
  1126.                   IF2
  1127.                     ERR
  1128.                     DISPLAY ">> ERROR - Bad data size:  must be byte, word, or dword"
  1129.                   ENDIF
  1130.                 ENDIF
  1131.                 PROTECT _@@use??
  1132. ENDM
  1133.  
  1134.  
  1135. PROTECT         MACRO   reglist
  1136.                 IFIDN   <reglist>,<ALL>
  1137.                   _@@prct?? = 1111111111111111b
  1138.                   EXITM
  1139.                 ELSE
  1140.                   IFIDN <reglist>,<NONE>
  1141.                     _@@prct?? = 0000000000000000b
  1142.                     EXITM
  1143.                   ENDIF
  1144.                 ENDIF
  1145.                 IRP save, <reglist>
  1146.                   IFE (.TYPE save) AND 16
  1147.                     IF2
  1148.                       ERR
  1149.                       DISPLAY ">> ERROR - Argument to PROTECT must be <register list>, ALL, or NONE"
  1150.                     ENDIF
  1151.                     EXITM
  1152.                   ENDIF
  1153.                   _@@done?? = 0
  1154.                   _@@try?? = 0000000000000011b
  1155.                   IRP reg, <ax,cx,bx,dx,si,di,bp>
  1156.                     IF save EQ reg
  1157.                       _@@prct?? = _@@prct?? OR _@@try??
  1158.                       _@@done?? = 1
  1159.                       EXITM
  1160.                     ENDIF
  1161.                     _@@try?? = _@@try?? SHL 2
  1162.                   ENDM
  1163.                   IF @Cpu AND 8
  1164.                     IFE _@@done??
  1165.                       _@@try?? = 0000000000000011b
  1166.                       IRP reg, <eax,ecx,ebx,edx,esi,edi,ebp>
  1167.                         IF save EQ reg
  1168.                           _@@prct?? = _@@prct?? OR _@@try??
  1169.                           _@@done?? = 1
  1170.                           EXITM
  1171.                         ENDIF
  1172.                         _@@try?? = _@@try?? SHL 2
  1173.                       ENDM
  1174.                     ENDIF
  1175.                   ENDIF
  1176.                   IFE _@@done??
  1177.                     _@@try?? = 0000000000000001b
  1178.                     IRP reg, <al,ah,cl,ch,bl,bh,dl,dh>
  1179.                       IF save EQ reg
  1180.                         _@@prct?? = _@@prct?? OR _@@try??
  1181.                         _@@done?? = 1
  1182.                         EXITM
  1183.                       ENDIF
  1184.                       _@@try?? = _@@try?? SHL 1
  1185.                     ENDM
  1186.                   ENDIF
  1187.                   IFE _@@done??
  1188.                     IF2
  1189.                       DISPLAY ">> WARNING - register in PROTECT ignored"
  1190.                       IFE _@@pwd??
  1191.                         DISPLAY ">>   PROTECT only recognizes EAX, ECX, EBX, EDX, ESI, EDI, and EBP"
  1192.                         DISPLAY ">>   PROTECT can also be used with just part of a register (e.g., AH, BP)."
  1193.                         DISPLAY ">>   These are the only registers ever used by a USE directive."
  1194.                         _@@pwd?? = 1
  1195.                       ENDIF
  1196.                     ENDIF
  1197.                   ENDIF
  1198.                 ENDM
  1199. ENDM
  1200.  
  1201.  
  1202. USE             MACRO   register
  1203.                 PROTECT ALL
  1204.                 CANUSE register
  1205. ENDM
  1206.  
  1207. CANUSE          MACRO   reglist
  1208.                 _@@use?? = 0
  1209.                 IFIDN   <reglist>,<ALL>
  1210.                   _@@prct?? = 0000000000000000b
  1211.                   EXITM
  1212.                 ELSE
  1213.                   IFIDN <reglist>,<NONE>
  1214.                     _@@prct?? = 1111111111111111b
  1215.                     EXITM
  1216.                   ENDIF
  1217.                 ENDIF
  1218.                 IRP save, <reglist>
  1219.                   IFE (.TYPE save) AND 16
  1220.                     IF2
  1221.                       ERR
  1222.                       DISPLAY ">> ERROR - Argument to USE must be <register list>, ALL, or NONE"
  1223.                     ENDIF
  1224.                     EXITM
  1225.                   ENDIF
  1226.                   _@@done?? = 0
  1227.                   _@@try?? = 1111111111111100b
  1228.                   IRP reg, <ax,cx,bx,dx,si,di,bp>
  1229.                     IF save EQ reg
  1230.                       _@@prct?? = _@@prct?? AND _@@try??
  1231.                       _@@done?? = 1
  1232.                       EXITM
  1233.                     ENDIF
  1234.                     _@@try?? = (_@@try?? SHL 2) OR 0000000000000011b
  1235.                   ENDM
  1236.                   IF @Cpu AND 8
  1237.                     IFE _@@done??
  1238.                       _@@try?? = 1111111111111100b
  1239.                       IRP reg, <eax,ecx,ebx,edx,esi,edi,ebp>
  1240.                         IF save EQ reg
  1241.                           _@@prct?? = _@@prct?? AND _@@try??
  1242.                           _@@done?? = 1
  1243.                           EXITM
  1244.                         ENDIF
  1245.                         _@@try?? = (_@@try?? SHL 2) OR 0000000000000011b
  1246.                       ENDM
  1247.                     ENDIF
  1248.                   ENDIF
  1249.                   IFE _@@done??
  1250.                     _@@try?? = 1111111111111110b
  1251.                     IRP reg, <al,ah,cl,ch,bl,bh,dl,dh>
  1252.                       IF save EQ reg
  1253.                         _@@prct?? = _@@prct?? AND _@@try??
  1254.                         _@@done?? = 1
  1255.                         EXITM
  1256.                       ENDIF
  1257.                       _@@try?? = (_@@try?? SHL 1) OR 0000000000000001b
  1258.                     ENDM
  1259.                   ENDIF
  1260.                   IFE _@@done??
  1261.                     IF2
  1262.                       DISPLAY ">> WARNING - register in USE ignored"
  1263.                       IFE _@@uwd??
  1264.                         DISPLAY ">>   USE only utilizes EAX, ECX, EBX, EDX, ESI, EDI, and EBP"
  1265.                         DISPLAY ">>   USE can also use just part of a register (e.g., AH, BP)."
  1266.                         _@@uwd?? = 1
  1267.                       ENDIF
  1268.                     ENDIF
  1269.                   ENDIF
  1270.                 ENDM
  1271. ENDM
  1272.  
  1273.  
  1274. SENDSKIPTO      MACRO   dest, syntax
  1275.                 _@@use?? = 0
  1276.                 IFNB <syntax>
  1277.                   IF2
  1278.                     ERR
  1279.                     DISPLAY ">> ERROR - Syntax error in SENDSKIPTO"
  1280.                   ENDIF
  1281.                 ENDIF
  1282.                 _@@onskip?? = dest
  1283.                 _@@skip?? = 1
  1284. ENDM
  1285.  
  1286.  
  1287. DECLARE         MACRO   rtp, name, arglist, spec1, spec2
  1288.                 _@@use?? = 0
  1289.                 IF1
  1290.                   IFDEF   _@@&name&??
  1291.                     ERR
  1292.                     %OUT  >> ERROR - Function "&name&" already defined
  1293.                   ENDIF
  1294.                   IFIDN <spec1>,<near>
  1295.                     IFIDN <spec2>,<pascal>
  1296.                       GLOBAL &name&:near
  1297.                     ELSE
  1298.                       GLOBAL _&name&:near
  1299.                     ENDIF
  1300.                   ELSE
  1301.                     IFIDN <spec2>,<near>
  1302.                       IFIDN <spec1>,<pascal>
  1303.                         GLOBAL &name&:near
  1304.                       ELSE
  1305.                         GLOBAL _&name&:near
  1306.                       ENDIF
  1307.                     ELSE
  1308.                       IFIDN <spec2>,<far>
  1309.                         IFIDN <spec1>,<pascal>
  1310.                           GLOBAL &name&:near
  1311.                         ELSE
  1312.                           GLOBAL _&name&:near
  1313.                         ENDIF
  1314.                       ELSE
  1315.                         IFIDN <spec1>,<far>
  1316.                           IFIDN <spec2>,<pascal>
  1317.                             GLOBAL &name&:far
  1318.                           ELSE
  1319.                             GLOBAL _&name&:far
  1320.                           ENDIF
  1321.                         ELSE
  1322.                           IFIDN <spec2>,<pascal>
  1323.                             GLOBAL &name&:near
  1324.                           ELSE
  1325.                             GLOBAL _&name&:near
  1326.                           ENDIF
  1327.                         ENDIF
  1328.                       ENDIF
  1329.                     ENDIF
  1330.                   ENDIF
  1331.                   IFIDN <rtp>,<void>
  1332.                     _@@r_&name&?? = 0
  1333.                   ELSE
  1334.                     IFIDN <rtp>,<byte>
  1335.                       _@@r_&name&?? = 1
  1336.                     ELSE
  1337.                       IFIDN <rtp>,<char>
  1338.                         _@@r_&name&?? = 1
  1339.                       ELSE
  1340.                         IFIDN <rtp>,<word>
  1341.                           _@@r_&name&?? = 2
  1342.                         ELSE
  1343.                           IFIDN <rtp>,<dword>
  1344.                             _@@r_&name&?? = 4
  1345.                           ELSE
  1346.                             IFIDN <rtp>,<near>
  1347.                               _@@r_&name&?? = @WordSize
  1348.                             ELSE
  1349.                               IFIDN <rtp>,<far>
  1350.                                 _@@r_&name&?? = 2+@WordSize
  1351.                               ELSE
  1352.                                 ERR
  1353.                                 %OUT  >> ERROR - Bad return type for function "&name&"
  1354.                               ENDIF
  1355.                             ENDIF
  1356.                           ENDIF
  1357.                         ENDIF
  1358.                       ENDIF
  1359.                     ENDIF
  1360.                   ENDIF
  1361.                   _@q?? = 0
  1362.                   _@@s_&name&?? = 0
  1363.                   IRP q, <arglist>
  1364.                     @@pos INSTR <q>, <static >
  1365.                     @@pos0 INSTR <q>, <byte >
  1366.                     @@pos1 INSTR <q>, <char >
  1367.                     @@pos2 INSTR <q>, <word >
  1368.                     @@pos3 INSTR <q>, <near >
  1369.                     @@pos4 INSTR <q>, <dword >
  1370.                     IF @@pos4
  1371.                       @@pos2 = 0
  1372.                     ENDIF
  1373.                     IF @@pos
  1374.                       @@pos = 6
  1375.                     ENDIF
  1376.                     @@pos5 INSTR <q>, <far >
  1377.                     @@pos6 INSTR <q>, <=>
  1378.                     IF @@pos6
  1379.                       IF @@pos0
  1380.                         @@lab SUBSTR <q>, @@pos0+5, @@pos6-@@pos0-5
  1381.                       ELSEIF @@pos1
  1382.                         @@lab SUBSTR <q>, @@pos1+5, @@pos6-@@pos1-5
  1383.                       ELSEIF @@pos2
  1384.                         @@lab SUBSTR <q>, @@pos2+5, @@pos6-@@pos2-5
  1385.                       ELSEIF @@pos3
  1386.                         @@lab SUBSTR <q>, @@pos3+5, @@pos6-@@pos3-5
  1387.                       ELSEIF @@pos4
  1388.                         @@lab SUBSTR <q>, @@pos4+6, @@pos6-@@pos4-6
  1389.                       ELSEIF @@pos5
  1390.                         @@lab SUBSTR <q>, @@pos5+4, @@pos6-@@pos5-4
  1391.                       ELSE
  1392.                         @@lab SUBSTR <q>, 1, @@pos6-1
  1393.                         IFE (.TYPE @@lab) AND 16
  1394.                           _@@DA@  % _@q??+1, &name
  1395.                         ENDIF
  1396.                       ENDIF
  1397.                     ELSE
  1398.                       IF @@pos0
  1399.                         @@lab SUBSTR <q>, @@pos0+5
  1400.                       ELSEIF @@pos1
  1401.                         @@lab SUBSTR <q>, @@pos1+5
  1402.                       ELSEIF @@pos2
  1403.                         @@lab SUBSTR <q>, @@pos2+5
  1404.                       ELSEIF @@pos3
  1405.                         @@lab SUBSTR <q>, @@pos3+5
  1406.                       ELSEIF @@pos4
  1407.                         @@lab SUBSTR <q>, @@pos4+6
  1408.                       ELSEIF @@pos5
  1409.                         @@lab SUBSTR <q>, @@pos5+3
  1410.                       ELSE
  1411.                         @@lab SUBSTR <q>, 1,80
  1412.                         IFE (.TYPE @@lab) AND 16
  1413.                           _@@DA@  % _@q??+1, &name
  1414.                         ENDIF
  1415.                       ENDIF
  1416.                     ENDIF
  1417.                     IF (.TYPE @@lab) AND 16
  1418.                       IRP r,<al,ah,bl,bh,cl,ch,dl,dh>
  1419.                         IF r EQ @@lab
  1420.                           _@r?? = 1
  1421.                           EXITM
  1422.                         ENDIF
  1423.                       ENDM
  1424.                       IRP r,<ax,bx,cx,dx,si,di,sp,bp,cs,ds,es,ss>
  1425.                         IF r EQ @@lab
  1426.                           _@r?? = 2
  1427.                           EXITM
  1428.                         ENDIF
  1429.                       ENDM
  1430.                       IF @WordSize EQ 4
  1431.                         IF r EQ fs OR r EQ gs
  1432.                           _@r?? = 2
  1433.                         ELSE
  1434.                           _@r?? = 4
  1435.                         ENDIF
  1436.                       ENDIF
  1437.                       IF (_@r?? EQ 1)
  1438.                         IF @@pos2 OR @@pos3 OR @@pos4 OR @@pos5
  1439.                           DISPLAY ":) STUPIDITY - register size different from declared size!!"
  1440.                           DISPLAY ":)   Register size used."
  1441.                         ENDIF
  1442.                       ELSEIF (_@r?? EQ 2)
  1443.                         IF @@pos0 OR @@pos1 OR (@@pos3 NE 0 AND @WordSize NE 2) OR @@pos4 OR @@pos5
  1444.                           DISPLAY ":) STUPIDITY - register size different from declared size!!"
  1445.                           DISPLAY ":)   Register size used."
  1446.                         ENDIF
  1447.                       ELSE
  1448.                         IF @@pos0 OR @@pos1 OR @@pos2 OR (@@pos3 NE 0 AND @WordSize NE 4) OR (@@pos5 NE 0 AND @WordSize NE 2)
  1449.                           DISPLAY ":) STUPIDITY - register size different from declared size!!"
  1450.                           DISPLAY ":)   Register size used."
  1451.                         ENDIF
  1452.                       ENDIF
  1453.                     ELSEIF @@pos0 OR @@pos1
  1454.                       _@r?? = 1
  1455.                     ELSEIF @@pos2
  1456.                       _@r?? = 2
  1457.                     ELSEIF @@pos3
  1458.                       _@r?? = @WordSize
  1459.                     ELSEIF @@pos4
  1460.                       _@r?? = 4
  1461.                     ELSEIF @@pos5
  1462.                       _@r?? = 2+@WordSize
  1463.                     ELSE
  1464.                       _@@DA@ % _@q?? + 1, &name
  1465.                     ENDIF
  1466.                     IF @@pos OR ((.TYPE @@lab) AND 16)
  1467.                       _@r?? = _@r??+8
  1468.                       _@@DQ@ name, % _@q??, @@lab
  1469.                     ELSE
  1470.                       _@@s_&name&?? = _@@s_&name&?? + _@r??
  1471.                     ENDIF
  1472.                     @@pos INSTR <q>, <=>
  1473.                     IF @@pos
  1474.                       _@r?? = _@r?? + 16
  1475.                       @@val SUBSTR <q>, @@pos+1
  1476.                       _@@DY@ name, % _@q??, @@val
  1477.                     ENDIF
  1478.                     _@@DW@ name, % _@q??, % _@r??
  1479.                     _@q?? = _@q?? + 1
  1480.                   ENDM
  1481.                   _@@&name&?? = _@q??
  1482.  
  1483.                   IFIDN <spec1>,<pascal>
  1484.                     _&name&_c_ = 0
  1485.         @&name  MACRO   args
  1486.                         _@@use?? = 0
  1487.                         _@q?? = 0
  1488.                         IRP q, <args>
  1489.                           _@@FZ@ name, % _@q??
  1490.                           _@@DX@ _@r??, name, % _@q??, &q
  1491.                           _@q?? = _@q?? + 1
  1492.                         ENDM
  1493.                         IF _@@&name&?? GT _@q??
  1494.                           REPT _@@&name&?? - _@q??
  1495.                             _@@FZ@ name, % _@q??
  1496.                             _@@DR@ _@r??, name, % _@q??
  1497.                             _@q?? = _@q?? + 1
  1498.                           ENDM
  1499.                         ENDIF
  1500.                 call    &name
  1501.                 ENDM
  1502.                   ELSE
  1503.                     IFIDN <spec2>,<pascal>
  1504.                       _&name&_c_ = 0
  1505.         @&name  MACRO   args
  1506.                         _@@use?? = 0
  1507.                         _@q?? = 0
  1508.                         IRP q, <args>
  1509.                           _@@FZ@ name, % _@q??
  1510.                           _@@DX@ _@r??, name, % _@q??, &q
  1511.                           _@q?? = _@q?? + 1
  1512.                         ENDM
  1513.                         IF _@@&name&?? GT _@q??
  1514.                           REPT _@@&name&?? - _@q??
  1515.                             _@@FZ@ name, % _@q??
  1516.                             _@@DR@ _@r??, name, % _@q??
  1517.                             _@q?? = _@q?? + 1
  1518.                           ENDM
  1519.                         ENDIF
  1520.                 call    &name
  1521.                 ENDM
  1522.                     ELSE
  1523.                       _&name&_c_ = 1
  1524.         &name   MACRO   args                 
  1525.                         _@@use?? = 0
  1526.                         _@q?? = 0
  1527.                         IRP q,<args>
  1528.                           _@q?? = _@q??+1
  1529.                         ENDM
  1530.                         _@@qq?? = _@q??
  1531.                         IF _@@&name&?? GT _@q??
  1532.                           _@q?? = _@@&name&??
  1533.                           REPT _@@&name&??-_@@qq??
  1534.                             _@q?? = _@q??-1
  1535.                             _@@FZ@ name, % _@q??
  1536.                             _@@DR@ _@r??, name, % _@q??
  1537.                           ENDM
  1538.                         ENDIF
  1539.                         _@@qq?? = _@q??
  1540.                         REPT _@@qq??
  1541.                           _@@qq?? = _@@qq??-1
  1542.                           _@q?? = 0
  1543.                           IRP q,<args>
  1544.                             IF _@q?? EQ _@@qq??
  1545.                               _@@FZ@ name, % _@q??
  1546.                               _@@DX@ _@r??, name, % _@q??, &q
  1547.                             ENDIF
  1548.                             _@q?? = _@q?? + 1
  1549.                           ENDM
  1550.                         ENDM
  1551.                 call    _&name
  1552.                         IF @WordSize EQ 2
  1553.                 add     sp, _@@s_&name&??
  1554.                         ELSE
  1555.                 add     esp, _@@s_&name&??
  1556.                         ENDIF
  1557.                 ENDM
  1558.                     ENDIF
  1559.                   ENDIF
  1560.                 ENDIF
  1561. ENDM
  1562.  
  1563. _@@DA@          MACRO   num, name
  1564.                 ERR
  1565.                 %OUT  >> ERROR - Bad or missing type for argument &num of function "&name&"
  1566. ENDM
  1567.  
  1568. _@@DQ@          MACRO   name, num, lab
  1569.                 _@@&name&?&num&@ EQU lab
  1570. ENDM
  1571.  
  1572. _@@DR@          MACRO   mode, name, num
  1573.                 IF _@@&name&?&num&?? AND 16
  1574.                   def = _@@d_&name&?&num&??
  1575.                   _@@DX@ mode, name, num, def
  1576.                 ELSE
  1577.                   _@@MA@ % num+1, &name
  1578.                 ENDIF
  1579. ENDM
  1580.  
  1581. _@@MA@          MACRO   num, name
  1582.                 IF2
  1583.                   ERR
  1584.                   %OUT  >> ERROR - Missing argument &num to function "&name&"
  1585.                 ENDIF
  1586. ENDM
  1587.  
  1588. _@@DW@          MACRO   name, num, val
  1589.                 _@@&name&?&num&?? EQU val
  1590. ENDM
  1591.  
  1592. _@@DX@          MACRO   mode, name, num, arg
  1593.                 @@loc INSTR <arg>,<|>
  1594.                 IF (mode AND 8)
  1595.                   IFE @@loc
  1596.                     IF (.TYPE _@@&name&?&num&@) EQ (.TYPE arg)
  1597.                       IF _@@&name&?&num&@ EQ arg
  1598.                         EXITM
  1599.                       ENDIF
  1600.                     ENDIF
  1601.                   ENDIF
  1602.                   IF (@@loc NE 0) AND ((_@@&name&?&num&?? AND 7) EQ 4)
  1603.                     arg1 SUBSTR <arg>,1,@@loc-1
  1604.                     arg2 SUBSTR <arg>,@@loc+1
  1605.         mov     word ptr [2+offset ds:_@@&name&?&num&@], arg1
  1606.         mov     word ptr [offset ds:_@@&name&?&num&@], arg2
  1607.                   ELSEIF (@@loc NE 0) AND ((_@@&name&?&num&?? AND 7) EQ 6)
  1608.                     arg1 SUBSTR <arg>,1,@@loc-1
  1609.                     arg2 SUBSTR <arg>,@@loc+1
  1610.         mov     word ptr [2+offset ds:_@@&name&?&num&@], arg1
  1611.         mov     dword ptr [offset ds:_@@&name&?&num&@], arg2
  1612.                   ELSEIF (.TYPE arg) AND 2
  1613.                     _@@size?? = mode AND 7
  1614.                     IF @WordSize LT _@@size??
  1615.                       _@@size?? = @WordSize
  1616.                     ENDIF
  1617.                     _@@KZ@ % _@@size??
  1618.                     IF _@@needpop??
  1619.                       IF2
  1620.                         ERR
  1621.                         %OUT  >> ERROR - Need a free register to call function "&name&"
  1622.                         IFE _@@cwd??
  1623.                           %OUT  >>   Use "USE reg" to specify which register to use
  1624.                           %OUT  >>   See the spec file for more detailed information
  1625.                           _@@cwd?? = 1
  1626.                         ENDIF
  1627.                       ENDIF
  1628.                     ELSEIF (mode AND 7) LE @WordSize
  1629.         mov     _@@use??, arg
  1630.         mov     _@@&name&?&num&@, _@@use??
  1631.                       USE _@@use??
  1632.                     ELSE
  1633.         mov     _@@use??, word ptr arg
  1634.         mov     word ptr [offset ds:_@@&name&?&num&@], _@@use??
  1635.         mov     _@@use??, word ptr (2+offset ds:arg)
  1636.         mov     word ptr [2+offset ds:_@@&name&?&num&@], _@@use??
  1637.                       USE _@@use??
  1638.                     ENDIF
  1639.                   ELSE
  1640.         mov     _@@&name&?&num&@, arg
  1641.                   ENDIF
  1642.                 ELSEIF (@Cpu AND 0FEh)
  1643.                   IF (@@loc NE 0) AND ((mode AND 7) EQ 4)
  1644.                     arg1 SUBSTR <arg>,1,@@loc-1
  1645.                     arg2 SUBSTR <arg>,@@loc+1
  1646.         push    arg1
  1647.         push    arg2
  1648.                   ELSEIF (mode AND 7) EQ 1
  1649.                     IF (.TYPE arg) AND 16
  1650.                       IF (arg EQ al) OR (arg EQ ah)
  1651.         push    ax
  1652.                       ELSEIF (arg EQ bl) OR (arg EQ bh)
  1653.         push    bx
  1654.                       ELSEIF (arg EQ cl) OR (arg EQ ch)
  1655.         push    cx
  1656.                       ELSEIF (arg EQ dl) OR (arg EQ dh)
  1657.         push    dx
  1658.                       ELSEIF @WordSize EQ 2
  1659.         push    arg
  1660.                         IF2
  1661.                           %OUT  >> WARNING - register size mismatch, high byte ignored
  1662.                         ENDIF
  1663.                       ENDIF
  1664.                     ELSE
  1665.         push    word ptr arg
  1666.                     ENDIF
  1667.                   ELSEIF (mode AND 7) LE @WordSize
  1668.         push    arg
  1669.                   ELSEIF (.TYPE arg) AND 4
  1670.         push    word ptr ((arg SHR 16) AND 0FFFFh)
  1671.         push    word ptr (arg AND 0FFFFh)
  1672.                   ELSE
  1673.         push    word ptr [2+offset ds:arg]
  1674.         push    word ptr [offset ds:arg]
  1675.                   ENDIF
  1676.                 ELSE
  1677.                   _@@KZ@ 2
  1678.                   IF _@@needpop??
  1679.                     IF2
  1680.                       ERR
  1681.                       %OUT  >> ERROR - Need a free register to call function "&name&"
  1682.                       IFE _@@cwd??
  1683.                         %OUT  >>   Use "USE reg" to specify which register to use
  1684.                         %OUT  >>   See the spec file for more detailed information
  1685.                         _@@cwd?? = 1
  1686.                       ENDIF
  1687.                     ENDIF
  1688.                   ELSE
  1689.         mov     _@@use??, word ptr (2+offset ds:arg)
  1690.         push    _@@use??
  1691.         mov     _@@use??, word ptr arg
  1692.         push    _@@use??
  1693.                     USE _@@use??
  1694.                   ENDIF
  1695.                 ENDIF
  1696. ENDM
  1697.  
  1698. _@@DY@          MACRO   name, num, val
  1699.                 _@@d_&name&?&num&?? = val
  1700. ENDM
  1701.  
  1702.  
  1703. FUNCTION_       MACRO   rtp, name, args, spec1, spec2
  1704.                 _@@use?? = 0
  1705.                 IFNDEF _@@&name&??
  1706.                   DECLARE rtp name <args> spec1 spec2
  1707.                 ENDIF
  1708.                 IFIDN <spec1>,<far>
  1709.                   _@@base?? = 2+@WordSize*2
  1710.                 ELSE
  1711.                   IFIDN <spec2>,<far>
  1712.                     _@@base?? = 2+@WordSize*2
  1713.                   ELSE
  1714.                     _@@base?? = @WordSize*2
  1715.                   ENDIF
  1716.                 ENDIF
  1717.                 _@@colleen?? = _@@base??
  1718.                 IF _&name&_c_
  1719.                   _@q?? = 0
  1720.                   IRP q, <args>
  1721.                     _@@FX@ &name, % _@q??, % _@@base??, & q
  1722.                   ENDM
  1723.                   _@@cf?? = 1
  1724.                   IFIDN <spec1>,<far>
  1725.         _&name  PROC    FAR
  1726.                   ELSE
  1727.                     IFIDN <spec2>,<far>
  1728.         _&name  PROC    FAR
  1729.                     ELSE
  1730.         _&name  PROC    NEAR
  1731.                     ENDIF
  1732.                   ENDIF
  1733.                 ELSE
  1734.                   _@@qq?? = _@@&name&??
  1735.                   REPT _@@qq??
  1736.                     _@@qq?? = _@@qq?? - 1
  1737.                     _@q?? = 0
  1738.                     IRP q, <args>
  1739.                       IF _@q?? EQ _@@qq??
  1740.                         _@@FX@ &name, % _@q??, % _@@base??, & q
  1741.                       ENDIF
  1742.                       _@q?? = _@q?? + 1
  1743.                     ENDM
  1744.                   ENDM
  1745.                   _@@cf?? = 0
  1746.                   IFIDN <spec1>,<far>
  1747.         &name   PROC    FAR
  1748.                   ELSE
  1749.                     IFIDN <spec2>,<far>
  1750.         &name   PROC    FAR
  1751.                     ELSE
  1752.         &name   PROC    NEAR
  1753.                     ENDIF
  1754.                   ENDIF
  1755.                 ENDIF
  1756.                 _@@rs?? = _@@r_&name&??
  1757.                 IF _@@colleen?? NE _@@base??
  1758.                   IF @WordSize EQ 2
  1759.         push    bp
  1760.         mov     bp, sp
  1761.                   ELSE
  1762.         push    ebp
  1763.         mov     ebp, esp
  1764.                   ENDIF
  1765.                 ENDIF
  1766. ENDM
  1767.  
  1768. _@@FE@          MACRO   name, num
  1769.                 IF2
  1770.                   ERR
  1771.                   %OUT  >> ERROR - Bad or missing data size for argument &num& from declaration of "&name&"
  1772.                 ENDIF
  1773. ENDM
  1774.  
  1775. _@@IM@          MACRO
  1776.                 DISPLAY "└─────????"
  1777.                 DISPLAY "░▒▓█  CONGRATULATIONS - YOU'VE JUST DONE THE IMPOSSIBLE!                █▓▒░"
  1778.                 DISPLAY "░▒▓█  Please contact me so I can (hopefully) make it impossible again.  █▓▒░"
  1779.                 DISPLAY ""
  1780. ENDM
  1781.  
  1782. _@@FX@          MACRO   name, num, off, mask1, mask2, mask3
  1783.                 IFIDN <mask1>, <static>
  1784.                   IF1
  1785.                     IFNDEF mask3
  1786.                       _@@d_&mask3&@ = 1
  1787.                       IFIDN <mask2>,<byte>
  1788.         mask3     DB     ?
  1789.                       ELSE
  1790.                         IFIDN <mask2>,<char>
  1791.         mask3     DB     ?
  1792.                         ELSE
  1793.                           IFIDN <mask2>,<word>
  1794.         mask3     DW     ?
  1795.                           ELSE
  1796.                             IFIDN <mask2>,<dword>
  1797.         mask3     DD     ?
  1798.                             ELSE
  1799.                               IFIDN <mask2>,<near>
  1800.                                 IF @WordSize EQ 2
  1801.         mask3     DW     ?
  1802.                                 ELSE
  1803.         mask3     DD     ?
  1804.                                 ENDIF
  1805.                               ELSE
  1806.                                 IFIDN <mask2>,<far>
  1807.                                   IF @WordSize EQ 2
  1808.         mask3     DD     ?
  1809.                                   ELSE
  1810.         mask3     DW     ?
  1811.                   DD     ?
  1812.                                   ENDIF
  1813.                                 ENDIF
  1814.                               ENDIF
  1815.                             ENDIF
  1816.                           ENDIF
  1817.                         ENDIF
  1818.                       ENDIF
  1819.                     ENDIF
  1820.                   ELSE
  1821.                     IFDEF _@@d_&mask3&@
  1822.                       IFIDN <mask2>,<byte>
  1823.         mask3     DB     ?
  1824.                       ELSE
  1825.                         IFIDN <mask2>,<char>
  1826.         mask3     DB     ?
  1827.                         ELSE
  1828.                           IFIDN <mask2>,<word>
  1829.         mask3     DW     ?
  1830.                           ELSE
  1831.                             IFIDN <mask2>,<dword>
  1832.         mask3     DD     ?
  1833.                             ELSE
  1834.                               IFIDN <mask2>,<near>
  1835.                                 IF @WordSize EQ 2
  1836.         mask3     DW     ?
  1837.                                 ELSE
  1838.         mask3     DD     ?
  1839.                                 ENDIF
  1840.                               ELSE
  1841.                                 IFIDN <mask2>,<far>
  1842.                                   IF @WordSize EQ 2
  1843.         mask3     DD     ?
  1844.                                   ELSE
  1845.         mask3     DW     ?
  1846.                   DD     ?
  1847.                                   ENDIF
  1848.                                 ENDIF
  1849.                               ENDIF
  1850.                             ENDIF
  1851.                           ENDIF
  1852.                         ENDIF
  1853.                       ENDIF
  1854.                     ENDIF
  1855.                   ENDIF
  1856.                 ELSEIF ((.TYPE mask1) AND 16) EQ 0
  1857.                   _@@FY@ name, num, off, mask2
  1858.                 ENDIF
  1859. ENDM
  1860.  
  1861. _@@FY@          MACRO   name, num, off, mask
  1862.                 IF (_@@&name&?&num&?? AND 8)
  1863.                   mask = _@@&name&?&num&??
  1864.                 ELSE
  1865.                   IF (_@@&name&?&num&?? AND 7) EQ 4
  1866.                     IF @WordSize EQ 2
  1867.                       mask = (dword ptr [bp+off])
  1868.                     ELSE
  1869.                       mask = dword ptr [ebp+off]
  1870.                     ENDIF
  1871.                   ELSEIF (_@@&name&?&num&?? AND 7) EQ 2
  1872.                     IF @WordSize EQ 2
  1873.                       mask = word ptr [bp+off]
  1874.                     ELSE
  1875.                       mask = word ptr [ebp+off]
  1876.                     ENDIF
  1877.                   ELSEIF (_@@&name&?&num&?? AND 7) EQ 1
  1878.                     IF @WordSize EQ 2
  1879.                       mask = byte ptr [bp+off]
  1880.                     ELSE
  1881.                       mask = byte ptr [ebp+off]
  1882.                     ENDIF
  1883.                   ELSE
  1884.                     _@@FE@ &name, % num + 1
  1885.                   ENDIF
  1886.                   _@@base?? = off + (_@@&name&?&num&?? AND 6) + (_@@&name&?&num&?? AND 1)*2
  1887.                 ENDIF
  1888. ENDM
  1889.  
  1890. _@@FZ@          MACRO   name, num
  1891.                 IF num LT _@@&name&??
  1892.                   _@r?? = _@@&name&?&num&??
  1893.                 ELSEIF num EQ _@@&name&??
  1894.                   IF2
  1895.                     ERR
  1896.                     %OUT  >> ERROR - Too many arguments to function "&name&"
  1897.                   ENDIF
  1898.                 ENDIF
  1899. ENDM
  1900.  
  1901.  
  1902. RETURN          MACRO   val
  1903.                 _@@use?? = 0
  1904.                 IFDIF <val>,<NOTHING>
  1905.                   _@@RC@ val
  1906.                 ENDIF
  1907.                 IF _@@colleen?? NE _@@base??
  1908.                   IF @WordSize EQ 2
  1909.         pop     bp
  1910.                   ELSE
  1911.         pop     ebp
  1912.                   ENDIF
  1913.                 ENDIF
  1914.                 IF (_@@cf?? NE 0) OR (_@@colleen?? EQ _@@base??)
  1915.                   ret
  1916.                 ELSE
  1917.                   ret _@@base??-_@@colleen??
  1918.                 ENDIF
  1919.                 _@@ra?? = $
  1920. ENDM
  1921.  
  1922. _@@RC@          MACRO   val                  
  1923.                 IFNB <val>
  1924.                   IF _@@rs?? EQ 0
  1925.                     IF2
  1926.                       %OUT  :) STUPIDITY - "void" functions don't return values!!
  1927.                       %OUT  :)   Return value ignored
  1928.                     ENDIF
  1929.                   ELSEIF _@@rs?? EQ 1
  1930.                     IF ((.TYPE val) AND 16) EQ 0
  1931.         mov     al, val
  1932.                     ELSEIF val NE al
  1933.                       IFIDN <val>,<0>
  1934.         xor     al, al
  1935.                       ELSE
  1936.         mov     al, val
  1937.                       ENDIF
  1938.                     ENDIF
  1939.                   ELSEIF _@@rs?? EQ 2
  1940.                     IF ((.TYPE val) AND 16) EQ 0
  1941.                       IFIDN <val>,<0>
  1942.         xor     ax, ax
  1943.                       ELSE
  1944.         mov     ax, val
  1945.                       ENDIF
  1946.                     ELSEIF (val NE ax)
  1947.         mov     ax, val
  1948.                     ENDIF
  1949.                   ELSEIF _@@rs?? EQ 4
  1950.                     IF @WordSize EQ 2
  1951.                       @@loc INSTR <val>,<|>
  1952.                       IF @@loc
  1953.                         arg1 SUBSTR <val>,1,@@loc-1
  1954.                         arg2 SUBSTR <val>,@@loc+1
  1955.                         IF ((.TYPE arg2) AND 16)
  1956.                           IF arg2 EQ dx
  1957.                             IF ((.TYPE arg1) AND 16)
  1958.                               IF arg1 EQ ax
  1959.         xchg    ax, dx
  1960.                               ELSE
  1961.         mov     ax, dx
  1962.                               ENDIF
  1963.                             ELSE
  1964.         mov     ax, dx
  1965.                             ENDIF
  1966.                           ENDIF
  1967.                         ENDIF
  1968.                         IF ((.TYPE arg1) AND 4) EQ 4 AND (arg1 EQ 0)
  1969.         xor     dx, dx
  1970.                         ELSEIF ((.TYPE arg2) AND 16)
  1971.                           IF arg1 NE dx AND arg1 NE ax
  1972.         mov     dx, arg1
  1973.                           ELSEIF arg1 EQ ax
  1974.                             IFE ((.TYPE arg2) AND 16)
  1975.         mov     dx, arg1
  1976.                             ELSEIF arg2 NE dx
  1977.         mov     dx, arg1
  1978.                             ENDIF
  1979.                           ENDIF
  1980.                         ELSE
  1981.         mov     dx, arg1
  1982.                         ENDIF
  1983.                         IF ((.TYPE arg2) AND 4) EQ 4
  1984.                           IF arg2 EQ 0
  1985.         xor     ax, ax
  1986.                           ELSE
  1987.         mov     ax, arg2
  1988.                           ENDIF
  1989.                         ELSEIF ((.TYPE arg2) AND 16)
  1990.                           IF arg2 NE ax AND arg2 NE dx
  1991.         mov     ax, arg2
  1992.                           ENDIF
  1993.                         ELSE
  1994.         mov     ax, arg2
  1995.                         ENDIF
  1996.                       ELSEIF (.TYPE val) AND 4
  1997.                         @@loc INSTR <val>,<:>
  1998.                         IF @@loc
  1999.         mov     dx, word ptr [2+val]
  2000.         mov     ax, word ptr [val]
  2001.                         ELSE
  2002.                           IF ((val SHR 16) AND 0FFFFh)
  2003.         mov     dx, (val SHR 16) AND 0FFFFh
  2004.                           ELSE
  2005.         xor     dx, dx
  2006.                           ENDIF
  2007.                           IF (val AND 0FFFFh)
  2008.         mov     ax, val AND 0FFFFh
  2009.                           ELSE
  2010.         xor     ax, ax
  2011.                           ENDIF
  2012.                         ENDIF
  2013.                       ELSEIF (.TYPE val) AND 2
  2014.                         @@loc INSTR <val>,<:>
  2015.                         IFE @@loc
  2016.         mov     dx, word ptr [2+offset ds:val]
  2017.         mov     ax, word ptr [offset ds:val]
  2018.                         ELSE
  2019.         mov     dx, word ptr [2+offset val]
  2020.         mov     ax, word ptr [offset val]
  2021.                         ENDIF
  2022.                       ELSE
  2023.                         IF2
  2024.                           ERR
  2025.                           %OUT  >> ERROR - Bad or missing data type for return value
  2026.                         ENDIF
  2027.                       ENDIF
  2028.                     ELSE
  2029.                       IFE (.TYPE val) AND 16
  2030.                         IF (.TYPE val) AND 4
  2031.                           IFE val
  2032.         xor     eax, eax
  2033.                           ELSE
  2034.         mov     eax, val
  2035.                           ENDIF
  2036.                         ELSE
  2037.         mov     eax, val
  2038.                         ENDIF
  2039.                       ELSEIF val NE eax
  2040.         mov     eax, val
  2041.                       ENDIF
  2042.                     ENDIF
  2043.                   ELSEIF _@@rs?? EQ 6
  2044.                     IF @WordSize EQ 4
  2045.                       @@loc INSTR <val>,<|>
  2046.                       IF @@loc
  2047.                         arg1 SUBSTR <val>,1,@@loc-1
  2048.                         arg2 SUBSTR <val>,@@loc+1
  2049.                         IF (.TYPE arg2) AND (.TYPE arg1) AND 16
  2050.                           IF arg2 EQ edx AND arg1 EQ ax
  2051.         xchg    eax, edx
  2052.                           ELSEIF arg2 EQ edx
  2053.         mov     eax, edx
  2054.                           ENDIF
  2055.                         ENDIF
  2056.                         IF ((.TYPE arg1) AND 4) EQ 4 AND (arg1 EQ 0)
  2057.         xor     dx, dx
  2058.                         ELSEIF ((.TYPE arg2) AND 16)
  2059.                           IF arg1 NE dx AND arg1 NE ax
  2060.         mov     dx, arg1
  2061.                           ELSEIF arg1 EQ ax
  2062.                             IFE ((.TYPE arg2) AND 16)
  2063.         mov     dx, arg1
  2064.                             ELSEIF arg2 NE edx
  2065.         mov     dx, arg1
  2066.                             ENDIF
  2067.                           ENDIF
  2068.                         ELSE
  2069.         mov     dx, arg1
  2070.                         ENDIF
  2071.                         IF ((.TYPE arg2) AND 4) EQ 4
  2072.                           IF arg2 EQ 0
  2073.         xor     eax, eax
  2074.                           ELSE
  2075.         mov     eax, arg2
  2076.                           ENDIF
  2077.                         ELSEIF ((.TYPE arg2) AND 16)
  2078.                           IF arg2 NE eax AND arg2 NE edx
  2079.         mov     eax, arg2
  2080.                           ENDIF
  2081.                         ELSE
  2082.         mov     eax, arg2
  2083.                         ENDIF
  2084.                       ELSEIF (.TYPE val) AND 4
  2085.                         @@loc INSTR <val>,<:>
  2086.                         IF @@loc
  2087.         mov     dx, word ptr [4+val]
  2088.         mov     eax, dword ptr [val]
  2089.                         ELSE
  2090.         xor     dx, dx
  2091.                           IF val
  2092.         mov     ax, val
  2093.                           ELSE
  2094.         xor     ax, ax
  2095.                           ENDIF
  2096.                         ENDIF
  2097.                       ELSEIF (.TYPE val) AND 2
  2098.                         @@loc INSTR <val>,<:>
  2099.                         IFE @@loc
  2100.         mov     dx, word ptr [4+offset ds:val]
  2101.         mov     eax, dword ptr [offset ds:val]
  2102.                         ELSE
  2103.         mov     dx, word ptr [4+offset val]
  2104.         mov     eax, dword ptr [offset val]
  2105.                         ENDIF
  2106.                       ELSE
  2107.                         IF2
  2108.                           ERR
  2109.                           %OUT  >> ERROR - Bad or missing data type for return value
  2110.                         ENDIF
  2111.                       ENDIF
  2112.                     ELSE
  2113.                       IFE (.TYPE val) AND 16
  2114.                         IF (.TYPE val) AND 4
  2115.                           IFE val
  2116.         xor     eax, eax
  2117.                           ELSE
  2118.         mov     eax, val
  2119.                           ENDIF
  2120.                         ELSE
  2121.         mov     eax, val
  2122.                         ENDIF
  2123.                       ELSEIF val NE eax
  2124.         mov     eax, val
  2125.                       ENDIF
  2126.                     ENDIF
  2127.                   ENDIF
  2128.                 ELSEIF _@@rs??
  2129.                   IF2
  2130.                     DISPLAY ">> WARNING - function should return a value"
  2131.                   ENDIF
  2132.                 ENDIF
  2133. ENDM
  2134.  
  2135. _ENDFUNC        MACRO   name
  2136.                 _@@use?? = 0
  2137.                 IF _@@ra?? NE $
  2138.                   RETURN NOTHING
  2139.                 ENDIF
  2140.                 IFB <name>
  2141.                 ENDP
  2142.                 ELSEIF _@@cf??
  2143.         _&name  ENDP
  2144.                 ELSE
  2145.         &name   ENDP
  2146.                 ENDIF
  2147. ENDM
  2148.  
  2149. DISP            MACRO    arg1, arg2
  2150.                 IFB <arg2>
  2151.                   DISPLAY "&arg1&"
  2152.                 ELSE
  2153.                   DISPLAY  "&arg1& = &arg2&"
  2154.                 ENDIF
  2155. ENDM
  2156.  
  2157.  
  2158. FLAG            MACRO   text
  2159.                 IF2
  2160.                   IFE (.TYPE _@@use??) AND 16
  2161.                     %OUT  &text&:  no reg, no stack
  2162.                   ELSEIF _@@needpop??
  2163.                     IF _@@use?? EQ al
  2164.                       %OUT  &text&:  reg AL, stack AX
  2165.                     ELSEIF _@@use?? EQ ax
  2166.                       %OUT  &text&:  reg AX, stack AX
  2167.                     ELSEIF @WordSize EQ 4
  2168.                       IF _@@use?? EQ eax
  2169.                         %OUT  &text&:  reg EAX, stack EAX
  2170.                       ELSE
  2171.                         %OUT  &text&:  reg unknown, stack unknown
  2172.                         _@@IM@
  2173.                       ENDIF
  2174.                     ELSE
  2175.                       %OUT  &text&:  reg unknown, stack AX
  2176.                       _@@IM@
  2177.                     ENDIF
  2178.                   ELSE
  2179.                     IF _@@use?? EQ al
  2180.                       %OUT  &text&:  reg AL, no stack
  2181.                     ELSEIF _@@use?? EQ ah
  2182.                       %OUT  &text&:  reg AH, no stack
  2183.                     ELSEIF _@@use?? EQ bl
  2184.                       %OUT  &text&:  reg BL, no stack
  2185.                     ELSEIF _@@use?? EQ bh
  2186.                       %OUT  &text&:  reg BH, no stack
  2187.                     ELSEIF _@@use?? EQ cl
  2188.                       %OUT  &text&:  reg CL, no stack
  2189.                     ELSEIF _@@use?? EQ ch
  2190.                       %OUT  &text&:  reg CH, no stack
  2191.                     ELSEIF _@@use?? EQ dl
  2192.                       %OUT  &text&:  reg DL, no stack
  2193.                     ELSEIF _@@use?? EQ dh
  2194.                       %OUT  &text&:  reg DH, no stack
  2195.                     ELSEIF _@@use?? EQ ax
  2196.                       %OUT  &text&:  reg AX, no stack
  2197.                     ELSEIF _@@use?? EQ bx
  2198.                       %OUT  &text&:  reg BX, no stack
  2199.                     ELSEIF _@@use?? EQ cx
  2200.                       %OUT  &text&:  reg CX, no stack
  2201.                     ELSEIF _@@use?? EQ dx
  2202.                       %OUT  &text&:  reg DX, no stack
  2203.                     ELSEIF _@@use?? EQ si
  2204.                       %OUT  &text&:  reg SI, no stack
  2205.                     ELSEIF _@@use?? EQ di
  2206.                       %OUT  &text&:  reg DI, no stack
  2207.                     ELSEIF _@@use?? EQ bp
  2208.                       %OUT  &text&:  reg BP, no stack
  2209.                     ELSEIF @WordSize EQ 4
  2210.                       IF _@@use?? EQ eax
  2211.                         %OUT  &text&:  reg EAX, no stack
  2212.                       ELSEIF _@@use?? EQ ebx
  2213.                         %OUT  &text&:  reg EBX, no stack
  2214.                       ELSEIF _@@use?? EQ ecx
  2215.                         %OUT  &text&:  reg ECX, no stack
  2216.                       ELSEIF _@@use?? EQ edx
  2217.                         %OUT  &text&:  reg EDX, no stack
  2218.                       ELSEIF _@@use?? EQ esi
  2219.                         %OUT  &text&:  reg ESI, no stack
  2220.                       ELSEIF _@@use?? EQ edi
  2221.                         %OUT  &text&:  reg EDI, no stack
  2222.                       ELSEIF _@@use?? EQ ebp
  2223.                         %OUT  &text&:  reg EBP, no stack
  2224.                       ELSE
  2225.                         %OUT  &text&:  reg unknown, no stack
  2226.                         _@@IM@
  2227.                       ENDIF
  2228.                     ELSE
  2229.                       %OUT  &text&:  reg unknown, no stack
  2230.                       _@@IM@
  2231.                     ENDIF
  2232.                   ENDIF
  2233.                 ENDIF
  2234. ENDM
  2235.