home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progasm / asmlib1.arj / MACROS.8 next >
Encoding:
Text File  |  1991-06-01  |  30.3 KB  |  779 lines

  1. ;                             ╔═══════════════════╗
  2. ;                             ║  GENERAL EQUATES  ║
  3. ;                             ╚═══════════════════╝
  4. CR      EQU     0D      ;carriage return
  5. DLR     EQU     "$"     ;dollar sign
  6. LF      EQU     0A      ;line feed
  7. MINUS1  EQU     -1      ;minus one
  8. FR      EQU     FAR     ;short form for FAR operator
  9. NR      EQU     NEAR    ;short form for NEAR operator
  10. O       EQU     OFFSET  ;short form for OFFSET operator
  11. S       EQU     SHORT   ;short form for SHORT operator
  12. L       EQU     LONG    ;short form for LONG operator
  13. TAB     EQU     9       ;tab
  14. ;                             ╔═══════════════════╗
  15. ;                             ║ LOW MEMORY FIELDS ║
  16. ;                             ╚═══════════════════╝
  17.         ORG     0
  18. LO      EQU     $
  19. LOFAORB EQU     B[LO + 0504]  ;         floppy drive A or B
  20.    FDRA    EQU     0       ;drive A
  21.    FDRB    EQU     1       ;drive B
  22. LOFCTDN EQU     B[LO + 0440]  ;         fd countdown
  23. LOFMOTR EQU     B[LO + 043F]  ;         bit n = motor fd drive n
  24.    FMODRA  EQU     01      ;drive A
  25.    FMODRB  EQU     02      ;drive B
  26.    FMODRC  EQU     04      ;drive C
  27.    FMODRD  EQU     08      ;drive D
  28. LOFSTAT EQU     B[LO + 0441]  ;         fd status
  29.    FSTADDR EQU     002     ;address not found
  30.    FSTCHIP EQU     020     ;chip failed
  31.    FSTCMND EQU     001     ;command invalid
  32.    FSTCRC  EQU     010     ;CRC failed
  33.    FSTDMA  EQU     008     ;DMA error
  34.    FSTSECT EQU     004     ;sector error
  35.    FSTSEEK EQU     040     ;seek failed
  36.    FSTTOUT EQU     080     ;timeout
  37. LOKSTAT EQU     B[LO + 0417]  ;         keyboard status
  38.    KSTALT  EQU     008     ;alt
  39.    KSTCAPS EQU     040     ;caps lock
  40.    KSTCTRL EQU     004     ;control
  41.    KSTINS  EQU     080     ;insert
  42.    KSTNUM  EQU     020     ;num lock
  43.    KSTSCRL EQU     010     ;scroll lock
  44.    KSTSH   EQU     003     ;shift
  45.    KSTSHL  EQU     002     ;left shift
  46.    KSTSHR  EQU     001     ;right shift
  47. LOMSIZE EQU     W[LO + 0413]  ;         memory size (k)
  48. LOMTIME EQU     D[LO + 046C]  ;         memory time of day
  49. LOVCTBL EQU     W[LO + 0450]  ;w x 8    video cursor table
  50. LOVCURS EQU     W[LO + 0460]  ;         video cursor shape
  51. LOVLINE EQU     W[LO + 044A]  ;         video line width
  52. LOVMODE EQU     B[LO + 0449]  ;         video mode
  53.    VMOBW40 EQU     0       ;b/w 40 cols
  54.    VMOBWMR EQU     5       ;b/w 40 cols medium res
  55.    VMOBW80 EQU     2       ;b/w 80 cols
  56.    VMOCO40 EQU     1       ;col 40 cols
  57.    VMOCO80 EQU     3       ;col 80 cols
  58.    VMOCOHR EQU     6       ;col 80 cols high res
  59.    VMOCOMR EQU     4       ;col 40 cols medium res
  60.    VMOMONO EQU     7       ;MDA 80 columns
  61. LOVOFST EQU     W[LO + 044E]  ;         video buffer offset
  62. LOVPAGE EQU     B[LO + 0462]  ;         video page
  63. LOVPORT EQU     W[LO + 0463]  ;         video port
  64. LOVROWS EQU     B[LO + 0484]  ;         video number of rows - 1
  65. LOVSIZE EQU     W[LO + 044C]  ;         video buffer size
  66. ;                             ╔═══════════════════╗
  67. ;                             ║    PSP FIELDS     ║
  68. ;                             ╚═══════════════════╝
  69.         ORG     0
  70. PSP     EQU     $
  71. PSPENV  EQU     W[PSP + 02C]  ;         seg of environment
  72. PSPFCB1 EQU     B[PSP + 05C]  ;         FCB 1
  73. PSPFCB2 EQU     B[PSP + 06C]  ;         FCB 2
  74.    FCBDR   EQU     0       ;b      filename drive
  75.    FCBHEAD EQU     1       ;b x 8  filename head
  76.    FCBTAIL EQU     9       ;b x 3  filename tail
  77. PSPHI   EQU     W[PSP + 002]  ;         high paragraph
  78. PSPI20  EQU     B[PSP + 000]  ;b x 2    int 020
  79. PSPI21  EQU     B[PSP + 050]  ;b x 3    int 021 ; retf
  80. PSPLINK EQU     W[PSP + 016]  ;         seg link to parent
  81. PSPPARM EQU     B[PSP + 081]  ;         parameters
  82. PSPPLEN EQU     B[PSP + 080]  ;         param length
  83. ;╔════════════════╗     ROUTINE
  84. ;║      ABORT     ╟─────────────────────────────────────────────┐
  85. ;╚╤═══════════════╝  Invoke ABORT sequence (ERRORLEVEL = AL)    │
  86. ; └─────────────────────────────────────────────────────────────┘
  87. @@ABORT   =     0
  88. ABORT      MACRO
  89.   @@ABORT    =  1
  90.   JMPL  $ABORT
  91.   #EM
  92. ;
  93. ;╔════════════════╗
  94. ;║     ASCIIZ     ╟─────────────────────────────────────────────┐
  95. ;╚╤═══════════════╝         ASCII string with ZERO added        │
  96. ; └─────────────────────────────────────────────────────────────┘
  97. ASCIIZ  MACRO
  98. ##IF #NL
  99.  #RX1L
  100.         DB #X,0
  101.  #ER
  102. ##ELSE
  103.         DB 0
  104. ##ENDIF
  105. #EM
  106. ;╔════════════════╗
  107. ;║     BIN2DEC    ╟─────────────────────────────────────────────┐
  108. ;╚╤═══════════════╝  BIN2DEC  -  AL (bin) ──> AX (dec zoned 2)  │
  109. ; └─────────────────────────────────────────────────────────────┘
  110. BIN2DEC EQU     AAM
  111. ;╔════════════════╗
  112. ;║      BIN2X     ╟─────────────────────────────────────────────┐
  113. ;╚╤═══════════════╝  BIN2X base - AL (bin) ──> AX (base zoned 0)│
  114. ; └─────────────────────────────────────────────────────────────┘
  115. BIN2X   MACRO   AAM #1 #EM
  116. ;╔════════════════╗
  117. ;║        C       ╟─────────────────────────────────────────────┐
  118. ;╚╤═══════════════╝         COPYRIGHT                           │
  119. ; └─────────────────────────────────────────────────────────────┘
  120. C       MACRO
  121.         ORG     0100
  122.         JMPS    >M0
  123.         DB      CR,#1
  124. CARRET  DB      CR,LF,0,01A,DLR,01A
  125.         EVEN
  126. M0:     CLD
  127. @@LOOKUP = 1
  128.         MOV     SI,080                  ;START WITH COMMAND LINE
  129.         MOV     DI,SI                   ;REWRITING THIS LINE
  130.         INC     SI                      ;MOVE TO FIRST BYTE
  131.         PUSH    SI                      ;SAVE THIS FOR LATER
  132.         JMPS    >M2                     ;START PROCESSING
  133. M1:     STOSB                           ;USE THIS BYTE
  134.         LODSB                           ;LOOK AT NEXT ONE
  135.         CMP     AL,020                  ;IS IT A SPACE ?
  136.         JNZ     >M4                     ;NO  - STILL IN PARAMETER
  137. M2:     XOR     AX,AX                   ;SET A NULL..
  138.         STOSB                           ;..BEFORE EACH PARAMETER
  139. M3:     LODSB                           ;PICK UP A BYTE
  140.         CMP     AL,020                  ;IS IT A SPACE ?
  141.         JZ      M3                      ;YES - IGNORE IT
  142. M4:     CMP     AL,CR                   ;IS IT ENDED YET ?
  143.         JNZ     M1                      ;NO  - USE THIS ONE
  144.         XOR     AX,AX                   ;CLEAR AX..
  145.         STOSW                           ;..AND SET A DOUBLE NULL
  146.         POP     SI                      ;START AT THE BEGINNING
  147. ; ┌─────────────────────────────────────────────────────────────┐
  148. ; │    At this point, the command-line parameters have been     │
  149. ; │    massaged into an ASCIIZ table starting at 0080h with     │
  150. ; │    a null, and terminated by a double-null sequence.        │
  151. ; └─────────────────────────────────────────────────────────────┘
  152. #EM
  153. ;╔════════════════╗     ROUTINE
  154. ;║      CRLF      ╟─────────────────────────────────────────────┐
  155. ;╚╤═══════════════╝    Print a blank line on STDOUT             │
  156. ; └─────────────────────────────────────────────────────────────┘
  157. @@CRLF    =     0       ;print new line
  158. CRLF       MACRO
  159.   @@CRLF     =  1
  160.   CALL  $CRLF
  161.   #EM
  162. ;╔════════════════╗     ROUTINE
  163. ;║    DBINTODEC   ╟─────────────────────────────────────────────┐
  164. ;╚╤═══════════════╝         DOUBLEWORD Binary to Decimal        │
  165. ; │  i/p : DX | AX                                              │
  166. ; │  o/p : at DI with length CX (not counting 0,$)              │
  167. ; │        max space taken up is 15 bytes: max CX=000D (13)     │
  168. ; └─────────────────────────────────────────────────────────────┘
  169. @@DBINTODEC=    0       ;doubleword binary to decimal
  170. DBINTODEC MACRO
  171.   @@DBINTODEC = 1
  172.   @@WBINTODEC = 1
  173.   CALL  $DBINTODEC
  174.   #EM
  175. DBIN2DEC   MACRO
  176.   DBINTODEC
  177.   #EM
  178. ;╔════════════════╗     ROUTINE
  179. ;║     DELEVAR    ╟─────────────────────────────────────────────┐
  180. ;╚╤═══════════════╝      Delete a system environment variable   │
  181. ; │                      DS:SI - location of variable name      │
  182. ; └─────────────────────────────────────────────────────────────┘
  183. @@DELEVAR =     0       ;delete environment variable
  184. DELEVAR    MACRO
  185.   @@DELEVAR  =  1
  186.   CALL  $DELEVAR
  187.   #EM
  188. ;╔════════════════╗
  189. ;║       DBW      ╟─────────────────────────────────────────────┐
  190. ;╚╤═══════════════╝               DB + DW in pairs              │
  191. ; └─────────────────────────────────────────────────────────────┘
  192. DBW     MACRO
  193.  #RX1L
  194.         DB      #X
  195.         DW      #AX
  196.  #E2
  197. #EM
  198. ;╔════════════════╗
  199. ;║     DEC2BIN    ╟─────────────────────────────────────────────┐
  200. ;╚╤═══════════════╝ DEC2BIN - AX (dec zoned 0) ──> AX (bin)     │
  201. ; └─────────────────────────────────────────────────────────────┘
  202. DEC2BIN EQU     AAD
  203. ;╔════════════════╗
  204. ;║ Dshift;Drotate ╟─────────────────────────────────────────────┐
  205. ;╚╤═══════════════╝    DOUBLE-register SHIFTs and ROTATEs       │
  206. ; └─────────────────────────────────────────────────────────────┘
  207. DSAL    MACRO
  208.         SAL     #2,1
  209.         RCL     #1,1
  210.         #EM
  211. DSHL    MACRO   DSAL #1,#2 #EM
  212. DSAR    MACRO
  213.         SAR     #1,1
  214.         RCR     #2,1
  215.         #EM
  216. DSHR    MACRO
  217.         SHR     #1,1
  218.         RCR     #2,1
  219.         #EM
  220. DRCL    MACRO
  221.         RCL     #2,1
  222.         RCL     #1,1
  223.         #EM
  224. DROL    MACRO
  225.         DSAL    #1,#2
  226.         PUSHF
  227.         ADC     BX,1
  228.         POPF
  229.         #EM
  230. DRCR    MACRO
  231.         RCR     #1,1
  232.         RCR     #2,1
  233.         #EM
  234. DROR    MACRO
  235.         PUSH    BX
  236.         SHR     #2,1
  237.         POP     BX
  238.         DRCR    #1,#2
  239.         #EM
  240. ;╔════════════════╗     ROUTINE
  241. ;║     ERROR      ╟─────────────────────────────────────────────┐
  242. ;╚╤═══════════════╝Errors are accessed in "ERRORS" via BP.      │
  243. ; │                This routine reports and then resigns with   │
  244. ; │                ERRORLEVEL = BP.   "Conditional" entry via   │
  245. ; │                     ERRIFccc < Z, NZ, C, NC, B, A >.        │
  246. ; └─────────────────────────────────────────────────────────────┘
  247. @@ERROR = 0
  248. ERRIFA     MACRO        ;error in BP if A flag set
  249.   @@ERROR    =  1
  250.   CALL  $ERRIFA
  251.   #EM
  252. ERRIFB     MACRO        ;error in BP if B flag set
  253.   @@ERROR    =  1
  254.   CALL  $ERRIFB
  255.   #EM
  256. ERRIFC     MACRO        ;error in BP if C flag set
  257.   ERRIFB
  258.   #EM
  259. ERRIFNC    MACRO        ;error in BP if C flag not set
  260.   @@ERROR    =  1
  261.   CALL  $ERRIFNC
  262.   #EM
  263. ERRIFNZ    MACRO        ;error in BP if Z flag not set
  264.   @@ERROR    =  1
  265.   CALL  $ERRIFNZ
  266.   #EM
  267. ERRIFZ     MACRO        ;error in BP if Z flag set
  268.   @@ERROR    =  1
  269.   CALL  $ERRIFZ
  270.   #EM
  271. ERROR      MACRO
  272.   @@ERROR    =  1
  273.   JMPL  $ERROR
  274.   #EM
  275. ;╔════════════════╗     ROUTINE
  276. ;║    FRJULIAN    ╟─────────────────────────────────────────────┐
  277. ;╚╤═══════════════╝  Calculate day/month/year from Julian date  │
  278. ; │                                                             │
  279. ; │ i/p: BX = "Julian" date                                     │
  280. ; │                                                             │
  281. ; │ o/p: AL = day (0=Sunday, 1=Monday..)                        │
  282. ; │      CX = year (including century)                          │
  283. ; │      DH = month                                             │
  284. ; │      DL = day                                               │
  285. ; ├─────────────────────────────────────────────────────────────┤
  286. ; │     The "Julian" date here is the number of days since      │
  287. ; │     20th November 1937: it applies to all dates from then   │
  288. ; │     up to 31st December 2099.  It is related to the         │
  289. ; │     Clarion date and to Scaliger's date function.           │
  290. ; │                                                             │
  291. ; │                Clarion  = Julian +    50,000                │
  292. ; │                Scaliger = Julian + 2,428,858                │
  293. ; └─────────────────────────────────────────────────────────────┘
  294. @@FRJULIAN =    0       ;from Julian to dd/mm/yy
  295. FRJULIAN   MACRO
  296.   @@FRJULIAN =  1
  297.   CALL  $FRJULIAN
  298.   #EM
  299. ;╔════════════════╗     ROUTINE
  300. ;║     GETENV     ╟─────────────────────────────────────────────┐
  301. ;╚╤═══════════════╝      Get address of system environment      │
  302. ; │                                                             │
  303. ; │                      ES:DI - location of environment        │
  304. ; │                      CX - length of environment             │
  305. ; │                      CARRY set if environment not found     │
  306. ; └─────────────────────────────────────────────────────────────┘
  307. @@GETENV  =     0       ;get environment address
  308. GETENV     MACRO
  309.   @@GETENV   =  1
  310.   CALL  $GETENV
  311.   #EM
  312. ;╔════════════════╗     ROUTINE
  313. ;║     GETENVT    ╟─────────────────────────────────────────────┐
  314. ;╚╤═══════════════╝                                             │
  315. ; │     Get address of system environment tail                  │
  316. ; │                                                             │
  317. ; │     ES:DI - location of environment's tail                  │
  318. ; │     CX    - available room in environment                   │
  319. ; │     CARRY set if no room found                              │
  320. ; └─────────────────────────────────────────────────────────────┘
  321. @@GETENVT =     0       ;get environment tail
  322. GETENVT    MACRO
  323.   @@GETENVT  =  1
  324.   CALL  $GETENVT
  325.   #EM
  326. ;╔════════════════╗     ROUTINE
  327. ;║     GETEVAR    ╟─────────────────────────────────────────────┐
  328. ;╚╤═══════════════╝                                             │
  329. ; │     Get address of a system environment variable            │
  330. ; │                                                             │
  331. ; │     DS:SI - location of variable name (input)               │
  332. ; │                                                             │
  333. ; │     ES:DI - location of environment's variable              │
  334. ; │     CX    - available room in environment                   │
  335. ; │     CARRY set if variable not found                         │
  336. ; └─────────────────────────────────────────────────────────────┘
  337. @@GETEVAR =     0       ;get environment variable
  338. GETEVAR    MACRO
  339.   @@GETEVAR  =  1
  340.   CALL  $GETEVAR
  341.   #EM
  342. ;╔════════════════╗     ROUTINE
  343. ;║     GETPAGE    ╟─────────────────────────────────────────────┐
  344. ;╚╤═══════════════╝                Get video page               │
  345. ; └─────────────────────────────────────────────────────────────┘
  346. @@VIDDATA =     0
  347. @@GETPAGE =     0       ;get page
  348. GETPAGE    MACRO
  349.   @@GETPAGE  =  1
  350.   CALL  $GETPAGE
  351.   #EM
  352. ;╔════════════════╗     ROUTINE
  353. ;║     GETPOS     ╟─────────────────────────────────────────────┐
  354. ;╚╤═══════════════╝              Get video position             │
  355. ; └─────────────────────────────────────────────────────────────┘
  356. @@VIDDATA =     0
  357. @@GETPOS  =     0       ;get position
  358. GETPOS     MACRO
  359.   @@GETPOS   =  1
  360.   CALL  $GETPOS
  361.   #EM
  362. ;╔════════════════╗
  363. ;║      JMPL      ╟─────────────────────────────────────────────┐
  364. ;╚╤═══════════════╝                   JMP long                  │
  365. ; └─────────────────────────────────────────────────────────────┘
  366. JMPL    MACRO
  367.         DB      0E9
  368.         DW      #1-$-2
  369.         #EM
  370. ;╔════════════════╗
  371. ;║      JMPS      ╟─────────────────────────────────────────────┐
  372. ;╚╤═══════════════╝                  JMP short                  │
  373. ; └─────────────────────────────────────────────────────────────┘
  374. JMPS    MACRO
  375.         DB      0EB
  376.         DB      #1-$-1
  377.         #EM
  378. ;╔════════════════╗
  379. ;║ Jconditional   ╟─────────────────────────────────────────────┐
  380. ;╚╤═══════════════╝    Extra conditional JUMP routines          │
  381. ; └─────────────────────────────────────────────────────────────┘
  382. JAZ     EQU     JAE
  383. JBZ     EQU     JBE
  384. JCE     EQU     JBE
  385. JCZ     EQU     JBE
  386. JGZ     EQU     JGE
  387. JLZ     EQU     JLE
  388. JNAZ    EQU     JNAE
  389. JNBZ    EQU     JNBE
  390. JNCE    EQU     JNBE
  391. JNCZ    EQU     JNBE
  392. JNGZ    EQU     JNGE
  393. JNLZ    EQU     JNLE
  394. ;╔════════════════╗
  395. ;║      JCXNZ     ╟─────────────────────────────────────────────┐
  396. ;╚╤═══════════════╝               Negative of JCXZ              │
  397. ; └─────────────────────────────────────────────────────────────┘
  398. JCXNZ   MACRO
  399.         INC     CX
  400.         LOOP    #1
  401.         #EM
  402. ;╔════════════════╗     ROUTINE
  403. ;║     LENSTR     ╟─────────────────────────────────────────────┐
  404. ;╚╤═══════════════╝           Length of ASCIIZ string           │
  405. ; │               input pointer DS:SI       output CX           │
  406. ; │                 or ES:DI or DS:DX                           │
  407. ; └─────────────────────────────────────────────────────────────┘
  408. @@LENSTR        =     0       ;length of ASCIIZ string
  409. LENSTR     MACRO
  410.   @@LENSTR   =  1
  411.   ##IF #S1 = 2
  412.    ##IF '#1' = 'SI'
  413.    ##ELSEIF '#1' = 'DI'
  414.      SWAP
  415.    ##ELSEIF '#1' = 'DX'
  416.      XCHG SI,DX
  417.    ##ELSE
  418.      PUSH SI
  419.      MOV  SI,o #1
  420.    ##ENDIF
  421.   ##ELSE
  422.      PUSH SI
  423.      MOV  SI,o #1
  424.   ##ENDIF
  425.   CALL  $LENSTR
  426.   ##IF #S1 = 2
  427.    ##IF '#1' = 'SI'
  428.    ##ELSEIF '#1' = 'DI'
  429.      SWAP
  430.    ##ELSEIF '#1' = 'DX'
  431.      XCHG SI,DX
  432.    ##ELSE
  433.      POP SI
  434.    ##ENDIF
  435.   ##ELSE
  436.      POP si
  437.   ##ENDIF
  438.   #EM
  439. ;╔════════════════╗     ROUTINE
  440. ;║     LOOKUP     ╟─────────────────────────────────────────────┐
  441. ;╚╤═══════════════╝  Lookup into table (DS:SI) to item N        │
  442. ; │                  BP = item number (N) - starts at 1         │
  443. ; │                  SI updated  -  carry set if not found      │
  444. ; └─────────────────────────────────────────────────────────────┘
  445. @@LOOKUP  =     0       ;lookup BP in table at SI
  446. LOOKUP     MACRO
  447.   @@LOOKUP   =  1
  448.   CALL  $LOOKUP
  449.   #EM
  450. ;╔════════════════╗     ROUTINE
  451. ;║     NLPRINT    ╟─────────────────────────────────────────────┐
  452. ;╚╤═══════════════╝   print new line + ASCIIZ message in DS:DX  │
  453. ; └─────────────────────────────────────────────────────────────┘
  454. @@NLPRINT =     0       ;new line print
  455. NLPRINT    MACRO
  456.   @@NLPRINT  =  1
  457.   CALL  $NLPRINT
  458.   #EM
  459. ;╔════════════════╗
  460. ;║     OLDINT     ╟─────────────────────────────────────────────┐
  461. ;╚╤═══════════════╝   (for TSR): perform old interrupt          │
  462. ; │                  (as designated by operand)                 │
  463. ; └─────────────────────────────────────────────────────────────┘
  464. OLDINT  MACRO
  465.         PUSHF
  466.         CS CALL D OLD#1+1
  467.         #EM
  468. ;╔════════════════╗     ROUTINE
  469. ;║      PARSE     ╟─────────────────────────────────────────────┐
  470. ;╚╤═══════════════╝           Parse filename                    │
  471. ; │             DS:SI - pointer to ASCIIZ filename              │
  472. ; │         o/p 5D-64 major name parsed                         │
  473. ; │         o/p 65-67 minor name parsed                         │
  474. ; │         -CF set if ambiguity involved                       │
  475. ; └─────────────────────────────────────────────────────────────┘
  476. @@PARSE   =     0       ;parse a path/filename
  477. PARSE      MACRO
  478.   @@PARSE    =  1
  479.   CALL $PARSE
  480.   #EM
  481. ;╔════════════════╗
  482. ;║     POPALL     ╟─────────────────────────────────────────────┐
  483. ;╚╤═══════════════╝       POP all normal registers, flags       │
  484. ; │                              (match to PUSHALL)             │
  485. ; └─────────────────────────────────────────────────────────────┘
  486. POPALL  MACRO
  487.         POP     ES,DS,DI,SI,BP,DX,CX,BX,AX
  488.         POPF
  489.         #EM
  490. ;╔════════════════╗     ROUTINE
  491. ;║    POS2ADR     ╟─────────────────────────────────────────────┐
  492. ;╚╤═══════════════╝  Convert video row/col (AX) to offset (DI)  │
  493. ; └─────────────────────────────────────────────────────────────┘
  494. @@POS2ADR =     0       ;get address
  495. POS2ADR    MACRO
  496.   @@POS2ADR = 1
  497.   CALL  $POS2ADR
  498.   #EM
  499. ;╔════════════════╗     ROUTINE
  500. ;║     PRINT      ╟─────────────────────────────────────────────┐
  501. ;╚╤═══════════════╝        print ASCIIZ message in DS:DX        │
  502. ; └─────────────────────────────────────────────────────────────┘
  503. @@PRINT   =     0       ;print
  504. PRINT      MACRO
  505.   @@PRINT    =  1
  506.   CALL  $PRINT
  507.   #EM
  508. ;╔════════════════╗     ROUTINE
  509. ;║     PRIOERR    ╟─────────────────────────────────────────────┐
  510. ;╚╤═══════════════╝        Print I/O error (if Cflag on)        │
  511. ; │                          input = AX                         │
  512. ; └─────────────────────────────────────────────────────────────┘
  513. @@PRIOERR =     0       ;print if I/O error
  514. PRIOERR    MACRO
  515.   @@PRIOERR  =  1
  516.   CALL  $PRIOERR
  517.   #EM
  518. ;╔════════════════╗
  519. ;║     PUSHALL    ╟─────────────────────────────────────────────┐
  520. ;╚╤═══════════════╝       PUSH all normal registers, flags      │
  521. ; │                              (match to POPALL)              │
  522. ; └─────────────────────────────────────────────────────────────┘
  523. PUSHALL MACRO
  524.         PUSHF
  525.         PUSH    AX,BX,CX,DX,BP,SI,DI,DS,ES
  526.         #EM
  527. ;╔════════════════╗     ROUTINE
  528. ;║     RESIGN     ╟─────────────────────────────────────────────┐
  529. ;╚╤═══════════════╝   Invoke termination with ERRORLEVEL = 0    │
  530. ; └─────────────────────────────────────────────────────────────┘
  531. @@RESIGN  =     0       ;sign off program with ERRORLEVEL = 0
  532. RESIGN     MACRO
  533.   @@RESIGN   =  1
  534.   JMPL  $RESIGN
  535.   #EM
  536. ;╔════════════════╗
  537. ;║ Sshift;Srotate ╟─────────────────────────────────────────────┐
  538. ;╚╤═══════════════╝    SINGLE-register SHIFTs and ROTATEs       │
  539. ; └─────────────────────────────────────────────────────────────┘
  540. SSAL    MACRO   SAL  #1,1 #EM
  541. SSHL    MACRO   SSAL #1   #EM
  542. SSAR    MACRO   SAR  #1,1 #EM
  543. SSHR    MACRO   SHR  #1,1 #EM
  544. SRCL    MACRO   RCL  #1,1 #EM
  545. SROL    MACRO   ROL  #1,1 #EM
  546. SRCR    MACRO   RCR  #1,1 #EM
  547. SROR    MACRO   ROR  #1,1 #EM
  548. ;╔════════════════╗     ROUTINE
  549. ;║     SETEVAR    ╟─────────────────────────────────────────────┐
  550. ;╚╤═══════════════╝                                             │
  551. ; │     Set a system environment variable                       │
  552. ; │                                                             │
  553. ; │     DS:SI - location of variable name (input)               │
  554. ; │                                                             │
  555. ; │     CARRY set if not done                                   │
  556. ; └─────────────────────────────────────────────────────────────┘
  557. @@SETEVAR =     0       ;set new environment variable
  558. SETEVAR    MACRO
  559.   @@SETEVAR  =  1
  560.   CALL  $SETEVAR
  561.   #EM
  562. ;╔════════════════╗     ROUTINE
  563. ;║     SETPAGE    ╟─────────────────────────────────────────────┐
  564. ;╚╤═══════════════╝      Set video page (i/p $$VIDPAGE)         │
  565. ; └─────────────────────────────────────────────────────────────┘
  566. @@SETPAGE =     0       ;set page
  567. @@VIDDATA =     0
  568. SETPAGE    MACRO
  569.   @@SETPAGE  =  1
  570.   CALL  $SETPAGE
  571.   #EM
  572. ;╔════════════════╗     ROUTINE
  573. ;║     SETPOS     ╟─────────────────────────────────────────────┐
  574. ;╚╤═══════════════╝      Set video position (i/p $$VIDPAGE)     │
  575. ; └─────────────────────────────────────────────────────────────┘
  576. @@SETPOS  =     0       ;set position
  577. @@VIDDATA =     0
  578. SETPOS     MACRO
  579.   @@SETPOS   =  1
  580.   CALL  $SETPOS
  581.   #EM
  582. ;╔════════════════╗
  583. ;║       STK      ╟─────────────────────────────────────────────┐
  584. ;╚╤═══════════════╝   STK (plus many variables) - put on stack  │
  585. ; └─────────────────────────────────────────────────────────────┘
  586. STK     MACRO
  587.  #RX1L
  588.         PUSH #X
  589.  #ER
  590.  #QXL1
  591.         POP  #X
  592.  #EQ
  593.         #EM
  594. ;╔════════════════╗
  595. ;║      SWAP      ╟─────────────────────────────────────────────┐
  596. ;╚╤═══════════════╝               DS:SI <--> ES:DI              │
  597. ; └─────────────────────────────────────────────────────────────┘
  598. SWAP    MACRO
  599.         XCHG    SI,DI
  600.         XCHG    DS,ES
  601.         #EM
  602. ;╔════════════════╗     ROUTINE
  603. ;║     SWAPSCR    ╟─────────────────────────────────────────────┐
  604. ;╚╤═══════════════╝                                             │
  605. ; │         Swap memory (DS:SI) with screen (segment ES)        │
  606. ; │ 1st word = row/col    2nd word = rows/cols    others = bytes│
  607. ; └─────────────────────────────────────────────────────────────┘
  608. @@SWAPSCR =     0       ;swap screen (ES) with memory
  609. SWAPSCR    MACRO
  610.   @@SWAPSCR  =  1
  611.   CALL  $SWAPSCR
  612.   #EM
  613. ;╔════════════════╗
  614. ;║      SYNCH     ╟─────────────────────────────────────────────┐
  615. ;╚╤═══════════════╝    SYNCH [DS]  -  DS:SI ───> ES:DI          │
  616. ; │                    SYNCH  ES   -  DS:SI <─── ES:DI          │
  617. ; └─────────────────────────────────────────────────────────────┘
  618. SYNCH   MACRO
  619. ##IF '#1' = 'ES'
  620.         PUSH    ES,DI
  621.         POP     SI,DS
  622. ##ELSE
  623.         PUSH    DS,SI
  624.         POP     DI,ES
  625. ##ENDIF
  626. #EM
  627. ;╔════════════════╗     ROUTINE
  628. ;║    TOJULIAN    ╟─────────────────────────────────────────────┐
  629. ;╚╤═══════════════╝  Calculate Julian date from day/month/year  │
  630. ; │                                                             │
  631. ; │ i/p: CX = year (including century)                          │
  632. ; │      DH = month                                             │
  633. ; │      DL = day                                               │
  634. ; │                                                             │
  635. ; │ o/p: AL = day (0=Sunday, 1=Monday..)                        │
  636. ; │      BX = "Julian" date                                     │
  637. ; ├─────────────────────────────────────────────────────────────┤
  638. ; │     The "Julian" date here is the number of days since      │
  639. ; │     20th November 1937: it applies to all dates from then   │
  640. ; │     up to 31st December 2099.  It is related to the         │
  641. ; │     Clarion date and to Scaliger's date function.           │
  642. ; │                                                             │
  643. ; │                Clarion  = Julian +    50,000                │
  644. ; │                Scaliger = Julian + 2,428,858                │
  645. ; └─────────────────────────────────────────────────────────────┘
  646. @@TOJULIAN =    0       ;dd/mm/yy to Julian
  647. TOJULIAN   MACRO
  648.   @@TOJULIAN =  1
  649.   CALL  $TOJULIAN
  650.   #EM
  651. ;╔════════════════╗
  652. ;║      TRAP      ╟─────────────────────────────────────────────┐
  653. ;╚╤═══════════════╝ Trap an Interrupt (as specified by operand) │
  654. ; └─────────────────────────────────────────────────────────────┘
  655. TRAP    MACRO
  656.         MOV     AX,035 BY #1
  657.         INT     021
  658.         MOV     W OLD#1+3,ES
  659.         MOV     W OLD#1+1,BX
  660.         MOV     AH,025
  661.         MOV     DX,O NEW#1
  662.         INT     021
  663.         #EM
  664. ;╔════════════════╗
  665. ;║       TSR      ╟─────────────────────────────────────────────┐
  666. ;╚╤═══════════════╝            Terminate & Stay Ready           │
  667. ; │     (optional operand specifies start of transient area)    │
  668. ; └─────────────────────────────────────────────────────────────┘
  669. TSR     MACRO
  670. ##IF '#1' = ''
  671.         MOV     DX,(TRANSIENT + 0F)/010
  672. ##ELSE
  673.         MOV     DX,(#1 + 0F)/010
  674. ##ENDIF
  675.         MOV     AX,031 BY 0
  676.         INT     021
  677.         #EM
  678. ;╔════════════════╗
  679. ;║      UNSTK     ╟─────────────────────────────────────────────┐
  680. ;╚╤═══════════════╝   UNSTK (plus variables) - take off stack   │
  681. ; └─────────────────────────────────────────────────────────────┘
  682. UNSTK   MACRO
  683.  #RX1L
  684.         POP  #X
  685.  #ER
  686.  #QXL1
  687.         PUSH #X
  688.  #EQ
  689.         #EM
  690. ;╔════════════════╗     ROUTINE
  691. ;║    VALIDHEX    ╟─────────────────────────────────────────────┐
  692. ;╚╤═══════════════╝   VALIDHEX:  validate a byte as HEX         │
  693. ; │                     i/p - AL                                │
  694. ; │                     o/p - AL (binary equivalent)            │
  695. ; │                     Zflag set if good  - Cflag if bad       │
  696. ; └─────────────────────────────────────────────────────────────┘
  697. @@VALIDHEX =    0       ;validate AL as hex
  698. VALIDHEX   MACRO
  699.   @@VALIDHEX =  1
  700.   CALL  $VALIDHEX
  701.   #EM
  702. ;╔════════════════╗     ROUTINE
  703. ;║    VALIDNUM    ╟─────────────────────────────────────────────┐
  704. ;╚╤═══════════════╝   VALIDNUM:  validate a byte as NUMERIC     │
  705. ; │                     i/p - AL                                │
  706. ; │                     o/p - AL (binary equivalent)            │
  707. ; │                     Zflag set if good  - Cflag if bad       │
  708. ; └─────────────────────────────────────────────────────────────┘
  709. @@VALIDNUM =    0       ;validate AL as number
  710. VALIDNUM   MACRO
  711.   @@VALIDNUM =  1
  712.   CALL  $VALIDNUM
  713.   #EM
  714. ;╔════════════════╗     ROUTINE
  715. ;║      VIDEO     ╟─────────────────────────────────────────────┐
  716. ;╚╤═══════════════╝      Establish Video mode and addresses     │
  717. ; │                                                             │
  718. ; │             output: ES:DI --> $VIDSEG, $VIDADR              │
  719. ; │                    $VIDMODE  - current mode                 │
  720. ; │                    $VIDCOLS  - number of cols in this mode  │
  721. ; │                    $VIDPAGE  - current active page          │
  722. ; │                    $VIDSHAPE - cursor shape                 │
  723. ; │                    $VIDPOSN  - [$VIDROW, $VIDCOL]           │
  724. ; │             CF if not correct mode                          │
  725. ; └─────────────────────────────────────────────────────────────┘
  726. @@GETPAGE  =    0       ;video service
  727. VIDEO      MACRO
  728.   GETPAGE
  729.   #EM
  730. ;╔════════════════╗     ROUTINE
  731. ;║    WBINTODEC   ╟─────────────────────────────────────────────┐
  732. ;╚╤═══════════════╝            WORD Binary to Decimal           │
  733. ; │  i/p : AX                                                   │
  734. ; │  o/p : at DI with length CX (not counting 0,$)              │
  735. ; │        max space taken up is 8 bytes: max CX=0006           │
  736. ; └─────────────────────────────────────────────────────────────┘
  737. @@WBINTODEC=    0       ;word binary to decimal
  738. WBINTODEC MACRO
  739.   @@WBINTODEC = 1
  740.   CALL  $WBINTODEC
  741.   #EM
  742. WBIN2DEC   MACRO
  743.   WBINTODEC
  744.   #EM
  745. ;╔════════════════╗     ROUTINE
  746. ;║    WDECTOBIN   ╟─────────────────────────────────────────────┐
  747. ;╚╤═══════════════╝            WORD Decimal to Binary           │
  748. ; │                         i/p : at SI                         │
  749. ; │   cf if error           o/p : AX                            │
  750. ; └─────────────────────────────────────────────────────────────┘
  751. @@WDECTOBIN=    0       ;word decimal to binary
  752. WDECTOBIN MACRO
  753.   @@WDECTOBIN = 1
  754.   CALL  $WDECTOBIN
  755.   #EM
  756. WDEC2BIN   MACRO
  757.   WDECTOBIN
  758.   #EM
  759. ;╔════════════════╗     ROUTINE
  760. ;║    WEEKDAYJ    ╟─────────────────────────────────────────────┐
  761. ;╚╤═══════════════╝     Calculate weekday from a Julian date    │
  762. ; │                                                             │
  763. ; │ i/p: BX = "Julian" date                                     │
  764. ; │ o/p: AL = day (0=Sunday, 1=Monday..)                        │
  765. ; ├─────────────────────────────────────────────────────────────┤
  766. ; │     The "Julian" date here is the number of days since      │
  767. ; │     20th November 1937: it applies to all dates from then   │
  768. ; │     up to 31st December 2099.  It is related to the         │
  769. ; │     Clarion date and to Scaliger's date function.           │
  770. ; │                                                             │
  771. ; │                Clarion  = Julian +    50,000                │
  772. ; │                Scaliger = Julian + 2,428,858                │
  773. ; └─────────────────────────────────────────────────────────────┘
  774. @@WEEKDAYJ =    0       ;Julian weekday
  775. WEEKDAYJ   MACRO
  776.   @@WEEKDAYJ =  1
  777.   CALL  $WEEKDAYJ
  778.   #EM
  779.