home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol097 / m80lib00.mac < prev    next >
Encoding:
Text File  |  1984-04-29  |  17.7 KB  |  921 lines

  1. .XLIST
  2. ;            M80LIB00.MAC
  3. ;            renamed from
  4. ;            MACRO LIBRARY
  5. ;
  6. ;    Last Updated on:
  7. ;    23 June 1982
  8. ;    John S. Wilson
  9. ;
  10. ;    This is the MACRO-80 version of Digital Research's MAC macro 
  11. ;    assembler library MACRO.LIB.
  12. ;    Specific changes are:
  13. ;
  14. ;    1):  Tests for null arguments use IFB <arg> and IFNB <arg> 
  15. ;    2):  Argument lists for REPT/IRP/IRPC enclosed in angle brackets < >
  16. ;    3):  Argument lists for REPT/IRP/IRPC which contained bracketed 
  17. ;         arguements within brackets altered to have single brackets
  18. ;         (See SAVE and RESTORE in the original library)
  19. ;    4):  Labels are terminated with a colon.
  20. ;
  21. ;    As MACRO.LIB does not work with Microsoft's MACRO-80 (M80),
  22. ;    this library will not work with Digital Research's MAC.
  23. ;    Ain't that always the way, anyhow!!
  24. ;
  25. ;******************************************************************************
  26. ;    SAVE MACRO    SAVE SPECIFIED REGISTERS
  27. ;
  28. ;    SAVE    R1,R2,R3,R4
  29. ;
  30. ;        R1-R4 MAY BE B,D,H OR PSW  SAVED IN ORDER SPECIFIED
  31. ;        IF REGS ARE OMITTED SAVE B,D AND H
  32. ;
  33. SAVE    MACRO    R1,R2,R3,R4
  34.     IFNB     <R1&R2&R3&R4>        ;;Altered form
  35.     IRP    R,<R1,R2,R3,R4>
  36.     IFB <R>                ;;Altered form
  37.     EXITM
  38.     ENDIF
  39.     PUSH    R
  40.     ENDM
  41.     ELSE
  42.     IRPC    REG,<BDH>
  43.     PUSH    REG
  44.     ENDM
  45.     ENDIF
  46.     ENDM
  47. ;
  48. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  49. ;
  50. ;    RESTORE MACRO    RESTORE REGISTERS  (INVERSE OF SAVE)
  51. ;
  52. ;    RESTORE    R1,R2,R3,R4
  53. ;
  54. ;        R1-R4 MAY BE B,D,H OR PSW  RESTORED IN ORDER SPECIFIED
  55. ;        IF REGS OMITTED RESTORE H,D AND B
  56. ;
  57. RESTORE    MACRO    R1,R2,R3,R4
  58.     IFNB     <R1&R2&R3&R4>        ;;Altered form
  59.     IRP    R,<R1,R2,R3,R4>
  60.     IFB    <R>            ;;Altered form
  61.     EXITM
  62.     ENDIF
  63.     POP    R
  64.     ENDM
  65.     ELSE
  66.     IRPC    REG,<HDB>
  67.     POP    REG
  68.     ENDM
  69.     ENDIF
  70.     ENDM
  71. ;
  72. ;
  73. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  74. ;
  75. ;    CHARIN MACRO    CONSOLE INPUT TO A
  76. ;
  77. ;    CHARIN    ADDR
  78. ;
  79. CHARIN    MACRO    ADDR
  80.     MVI    C,1        ;;CONSOLE INPUT
  81.     CALL    5        ;;CALL BDOS
  82.     IFNB     <ADDR>        ;;altered form
  83.     STA    ADDR
  84.     ENDIF
  85.     ENDM
  86. ;
  87. ;
  88. ;    . . . . . . . . . . . . . . ... ... . .. . . . . . . . .
  89. ;
  90. ;    CHAROUT MACRO    CONSOLE OUTPUT FROM A
  91. ;
  92. ;    CHAROUT    ADDR
  93. ;
  94. CHAROUT    MACRO    ADDR
  95.     IFNB     <ADDR>        ;;Altered form
  96.     LDA    ADDR
  97.     ENDIF
  98.     MVI    C,2        ;;CONOUT
  99.     MOV    E,A        ;;CHAR TO E
  100.     CALL    5        ;;CALL BDOS
  101.     ENDM
  102. ;
  103. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  104. ;
  105. ;    CHARSTAT MACRO    CHECK CONSOLE STATUS
  106. ;
  107. ;            RETURN TRUE (FF) IF CHAR READY FALSE (0) IF NOT
  108. ;
  109. CHARSTAT MACRO
  110.     LOCAL    EXIT
  111.     MVI    C,11
  112.     CALL    5
  113.     ORA    A
  114.     JZ    EXIT
  115.     MVI    A,0FFH
  116. EXIT:    ENDM
  117. ;
  118. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  119. ;
  120. ;    INPUT MACRO    INPUT CHARACTER STRING FROM CONSOLE
  121. ;
  122. ;    INPUT    ADDR,BUFLEN
  123. ;
  124. ;        ADDR    START OF TEXT BUFFER
  125. ;        BUFLEN    LENGTH OF BUFFER  (DEFAULT IS 127)
  126. ;
  127. INPUT    MACRO    ADDR,BUFLEN
  128.     MVI    C,10
  129.     IFNB     <ADDR>        ;;Altered form
  130.     LXI    D,ADDR        ;;SET BUFFER ADDRESS
  131.     ENDIF
  132.     IFNB     <BUFLEN>    ;;Altered form
  133.     MVI    A,BUFLEN    ;;SET BUFFER LENGTH
  134.     STAX    D
  135.     ELSE
  136.     MVI    A,127
  137.     STAX    D        ;;SET BUFFER DEFAULT MAXIMUM
  138.     ENDIF
  139.     CALL    5        ;;BDOS ENTRY
  140.     ENDM
  141. ;
  142. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  143. ;
  144. ;    PRINT MACRO    PRINT A STRING ON CONSOLE
  145. ;
  146. ;    PRINT                (CARRIAGE RETURN, LINE FEED)
  147. ;    PRINT    'LITERAL'
  148. ;    PRINT    <'LITERAL',CR,LF,'SECOND LITERAL'>
  149. ;
  150. ;    PRINT    ADDR,$            (ASCII OUTPUT UNTIL $)
  151. ;    PRINT    ADDR,L,H        (HEX OUTPUT L CHARACTERS)
  152. ;
  153. ;    Note that for the following usage of the macro PRINT the string 
  154. ;    referenced by ADDR must contain (via db) enough characters to 
  155. ;    match the length requirement in L.  Stated another way L is 
  156. ;    --- NOT --- a character repeat specification but rather a spec.
  157. ;    to extract <L> characters from the string.
  158. ;    PRINT    ADDR,L,A        (ASCII OUTPUT L CHARACTERS)
  159. ;
  160. ;        LITERALS MUST BE IN SINGLE QUOTES  'LIT'
  161. ;        IF LITERAL CONTAINS CONTROL CODES ENTIRE STRING IN <> BRACKETS
  162. ;        MACRO ALSO ASSEMBLES
  163. ;            CR = CARRIAGE RETURN
  164. ;            LF = LINE FEED
  165. ;            BEL = BELL CODE
  166. ;
  167. ;        MACRO ASSUMES ADDR ALREADY LOADED TO HL IF ARGUMENT OMITTED
  168. ;
  169. PRINT    MACRO    ?STRING,LEN,TC
  170.     LOCAL    @OVER,@MESS,PLOOP,PASTCR,@CRLF
  171. CR    SET    0DH
  172. LF    SET    0AH
  173. BEL    SET    07H
  174.     IFB     <?STRING&LEN&TC>    ;;Altered form
  175.     JMP    PASTCR
  176. @CRLF:    DB    CR
  177.     DB    LF
  178.     DB    '$'
  179. PASTCR:    LXI    D,@CRLF
  180.     MVI    C,9
  181.     CALL    5
  182.     ELSE
  183.     IFB    <LEN&TC>
  184.     JMP    @OVER
  185. @MESS:    DB    ?STRING
  186.     DB    '$'
  187. @OVER:    LXI    D,@MESS
  188.     MVI    C,9
  189.     CALL    5        ;;BDOS ENTRY
  190.     ELSE
  191.     IFB    <TC>        ;;Altered form
  192.     IFNB    <?STRING>    ;;Altered form
  193.     LXI    D,?STRING    ;;POINTER TO STRING
  194.     ENDIF
  195.     MVI    C,9
  196.     CALL    5        ;;BDOS ENTRY
  197.     ELSE
  198.     IFNB    <?STRING>    ;;Altered form
  199.     LXI    H,?STRING    ;;POINTER TO STRING
  200.     ENDIF
  201.     MVI    C,LEN        ;;LENGTH OF STRING
  202. PLOOP:    PUSH    B
  203.     PUSH    H
  204.     IF    TC=H
  205.     MOV    A,M        ;;GET A BYTE
  206.     HEXOUT            ;;CONV TO HEX & OUTPUT
  207.     ELSE
  208.     MOV    E,M        ;;GET A BYTE
  209.     MVI    C,2        ;;OUT FROM E
  210.     CALL    5
  211.     ENDIF
  212.     POP    H
  213.     POP    B
  214.     INX    H
  215.     DCR    C        ;;DECR LENGTH
  216.     JNZ    PLOOP        ;;CONTINUE TILL LEN 0
  217.     ENDIF
  218.     ENDIF
  219.     ENDIF
  220.     ENDM
  221. ;
  222. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  223. ;
  224. ;    HEXOUT MACRO    CONVERT BINARY NO AND OUTPUT TO CONSOLE
  225. ;
  226. ;    HEXOUT    ADDR
  227. ;
  228. ;        NUMBER ASSUMED IN A IF NO ARGUMENT
  229. ;
  230. HEXOUT    MACRO    ADDR
  231.     LOCAL    OUTCHR,HEXEND
  232.     JMP    HEXEND
  233. HEXPRN:    SAVE    PSW
  234.     RRC
  235.     RRC
  236.     RRC
  237.     RRC            ;;SHIFT RIGHT 4
  238.     CALL    OUTCHR
  239.     RESTORE    PSW
  240. OUTCHR: ANI    0FH        ;;MASK 4 BITS
  241.     ADI    90H        ;;ADD OFFSET
  242.     DAA            ;;DEC ADJUST
  243.     ACI    40H        ;;ADD OFFSET
  244.     DAA            ;;DEC ADJUST
  245.     MOV    E,A        ;;TO E FOR OUTPUT
  246.     MVI    C,2        ;;CONOUT
  247.     JMP    5        ;;CALL BDOS
  248. HEXEND:
  249. HEXOUT    MACRO    ?ADDR
  250.     IFNB    <?ADDR>        ;;Altered form
  251.     LDA    ?ADDR
  252.     ENDIF
  253.     CALL    HEXPRN
  254.     ENDM
  255.     HEXOUT    ADDR
  256.     ENDM
  257. ;
  258. ;
  259. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  260. ;
  261. ;    HEXIN MACRO    CONVERT A NUMBER IN MEMORY FROM HEX TO BINARY
  262. ;
  263. ;            IF NO ARGUMENT MACRO ASSUMES ADDR OF HEX STRING IN HL
  264. ;            ANSWER LEFT IN HL WITH LEAST SIGNIFICANT 8 BITS IN A
  265. ;            CARRY SET ON ERROR. CONVERSION STOPS WHEN ZERO IS
  266. ;            FOUND IN HEX STRING.
  267. ;
  268. HEXIN    MACRO    ADDR
  269.     LOCAL    IN1,IN2,OVERSUB
  270.     JMP    OVERSUB
  271. @HEXIN:    LXI    H,0        ;;ZERO NUMBER
  272. IN1:    LDAX    D        ;;GET A CHAR
  273.     ORA    A        ;;CHECK FOR END OF BUFFER
  274.     RZ
  275.     SUI    '0'        ;;CHECK < 0 AND CONVERT TO HEX
  276.     RC
  277.     ADI    '0'-'G'        ;;CHECK > F
  278.     RC
  279.     ADI    6
  280.     JP    IN2        ;;NO BETWEEN A AND F
  281.     ADI    7
  282.     RC
  283. IN2:    ADI    10
  284.     ORA    A        ;;CLEAR CARRY
  285.     MOV    C,A        ;;HEX DIGIT TO C
  286.     MVI    B,0        ;;ZERO TO B
  287.     DAD    H
  288.     DAD    H
  289.     DAD    H
  290.     DAD    H        ;;SHIFT LEFT 4
  291.     DAD    B        ;;ADD IN NEW DIGIT
  292.     INX    D        ;;INCR BUFFER POINTER
  293.     JMP    IN1        ;;RETURN FOR MORE INPUT
  294. OVERSUB:
  295. HEXIN    MACRO    ?ADDR
  296.     IFNB    <?ADDR>        ;;Altered form
  297.     LXI    D,?ADDR        ;;LOAD BUFFER ADDR
  298.     ELSE
  299.     XCHG
  300.     ENDIF
  301.     CALL    @HEXIN
  302.     MOV    A,L        ;;LEAST SIGNIFICANT 8 BITS TO A
  303.     ENDM
  304.     HEXIN    ADDR
  305.     ENDM
  306. ;
  307. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  308. ;
  309. ;    DECOUT MACRO    CONVERT A POSITIVE INTEGER TO DECIMAL AND OUTPUT 
  310. ;            TO THE CONSOLE.
  311. ;
  312. ;    DECOUT    ADDR
  313. ;
  314. ;        IF ADDR OMITTED, NUMBER ASSUMED TO BE IN HL, ELSE LOADED TO HL
  315. ;        LEADING ZEROS SUPRESSED. MAXIMUM NUMBER 65,767
  316. ;
  317. DECOUT    MACRO    ADDR
  318.     LOCAL    ENDDEC,DX
  319.     JMP    ENDDEC
  320. @DECOUT:SAVE            ;;PUSH STACK
  321.     LXI    B,-10        ;;RADIX FOR CONVERSION
  322.     LXI    D,-1        ;;THIS BECOMES NO DIVIDED BY RADIX
  323. DX:    DAD    B        ;;SUBTRACT 10
  324.     INX    D
  325.     JC    DX
  326.     LXI    B,10
  327.     DAD    B        ;;ADD RADIX BACK IN ONCE
  328.     XCHG
  329.     MOV    A,H
  330.     ORA    L        ;;TEST FOR ZERO
  331.     CNZ    @DECOUT        ;;RECURSIVE CALL
  332.     MOV    A,E
  333.     ADI    '0'        ;;CONVERT FROM BCD TO HEX
  334.     MOV    E,A        ;;TO E FOR OUTPUT
  335.     CHAROUT            ;;CONSOLE OUTPUT
  336.     RESTORE            ;;POP STACK
  337.     RET
  338. ENDDEC:
  339. DECOUT    MACRO    ?ADDR
  340.     IFNB    <?ADDR>        ;;Altered form
  341.     LHLD    ?ADDR
  342.     ENDIF
  343.     CALL    @DECOUT        ;;CALL THE SUBROUTINE
  344.     ENDM
  345.     DECOUT    ADDR
  346.     ENDM
  347. ;
  348. ;
  349. ;
  350. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  351. ;
  352. ;    DECIN MACRO    CONVERT A NUMBER IN MEMORY FROM ASCII TO BINARY
  353. ;
  354. ;    DECIN    ADDR
  355. ;
  356. ;        ADDR POINTS TO MEMORY LOCATION OF START OF NO, IF
  357. ;        ARG OMITTED POINTER ASSUMED LOADED TO HL
  358. ;        MACRO RETURNS WITH CARRY SET IF ALPHABETIC CHAR FOUND
  359. ;        CONVERSION STOPS WHEN CHAR LESS THAN ZERO IS FOUND.
  360. ;        BINARY NUMBER IS LEFT IN HL, MAXIMUM 65,767
  361. ;        LEAST SIGNIFICANT 8 BITS OF NUMBER IN A.
  362. ;
  363. DECIN    MACRO    ADDR
  364.     LOCAL    DLOOP,OVERSUB
  365.     JMP    OVERSUB
  366. @DECIN:    LXI    D,0        ;;ZERO DE
  367.     XCHG            ;;ADDR POINTER TO DE, ZERO TO HL
  368. DLOOP:    LDAX    D        ;;GET A ASCII DIGIT
  369.     SUI    '0'        ;;CONVERT TO BCD AND TEST
  370.     ANA    A        ;;RESET CARRY
  371.     RM            ;;TERMINATE CONVERSION IF < ZERO
  372.     CPI    10        ;;CHECK LEGITIMATE DIGIT (0-9)
  373.     CMC            ;;COMPLEMENT CARRY
  374.     RC            ;;RET WITH CARRY SET IF ERROR
  375.     INX    D        ;;INCR ADDR POINTER
  376.     DAD    H        ;;SHIFT LEFT 1
  377.     PUSH    H        ;;SAVE RESULT
  378.     DAD    H
  379.     DAD    H        ;;SHIFT LEFT 2
  380.     POP    B        ;;NO * 2 TO B
  381.     DAD    B        ;;HL NOW CONTAINS 10*NO
  382.     MOV    C,A        ;;ADD PRODUCT TO DIGIT
  383.     MVI    B,0
  384.     DAD    B
  385.     JMP    DLOOP        ;;BACK FOR ANOTHER DIGIT
  386. OVERSUB:
  387. DECIN    MACRO    ?ADDR
  388.     IFNB    <?ADDR>        ;;Altered form
  389.     LXI    H,?ADDR
  390.     ENDIF
  391.     CALL    @DECIN        ;;CALL THE SUBROUTINE
  392.     MOV    A,L        ;;LEAST SIGNIFICANT HALF OF NO TO A
  393.     ENDM
  394.     DECIN    ADDR
  395.     ENDM
  396. ;
  397. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  398. ;
  399. ;    MOVE MACRO    MOVE A BLOCK FROM SOURCE TO DEST
  400. ;
  401. ;    MOVE    SOURCE,DEST,COUNT
  402. ;
  403. ;        SOURCE TO HL    MACRO ASSUMES REGISTERS ALREADY
  404. ;        DEST TO DE    LOADED IF ARG OMITTED
  405. ;        COUNT TO BC
  406. ;
  407. MOVE    MACRO    SOURCE,DEST,COUNT
  408.     LOCAL    OVERSUB
  409.     JMP    OVERSUB
  410. @MOVE:    MOV    A,B
  411.     ORA    C
  412.     RZ            ;;EXIT COUNT ZERO
  413.     MOV    A,M        ;;GET A BYTE
  414.     STAX    D        ;;STORE IT
  415.     INX    H
  416.     INX    D
  417.     DCX    B
  418.     JMP    @MOVE        ;;BACK TO MOVE LOOP
  419. OVERSUB:
  420. MOVE    MACRO    SRC,?D,?C
  421.     IFNB    <SRC>        ;;Altered form
  422.     LXI    H,SRC
  423.     ENDIF
  424.     IFNB    <?D>        ;;Altered form
  425.     LXI    D,?D
  426.     ENDIF
  427.     IFNB    <?C>        ;;Altered form
  428.     LXI    B,?C
  429.     ENDIF
  430.     CALL    @MOVE        ;;CALL THE MOVE SUBROUTINE
  431.     ENDM
  432.     MOVE    SOURCE,DEST,COUNT
  433.     ENDM
  434. ;
  435. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  436. ;
  437. ;    FILL MACRO - FILL A BLOCK OF MEMORY WITH A CONSTANT
  438. ;
  439. ;    FILL    START,STOP,CONSTANT
  440. ;
  441. ;        CONSTANT OMITTED, FILL WITH 0
  442. ;        END OMITTED, FILL ONE BYTE
  443. ;
  444. FILL    MACRO    START,STOP,CONST
  445.     LOCAL    @FILL,BLKLEN
  446. BLKLEN:    SET    STOP-START+1
  447.     LXI    H,START        ;;LOAD START ADDR
  448.     IFNB    <STOP>        ;;Altered form
  449.     IF    BLKLEN GT 255
  450.     LXI    B,BLKLEN    ;;LOAD BLOCK LENGTH
  451.     ELSE
  452.     MVI    C,BLKLEN
  453.     ENDIF
  454.     IFNB    <CONST>        ;;Altered form
  455.     MVI    E,CONST        ;;LOAD CONST IF NOT NULL
  456.     ELSE
  457.     MVI    E,0
  458.     ENDIF
  459. @FILL:    MOV    M,E        ;;STORE A BYTE
  460.     INX    H        ;;INCR MEMORY POINTER
  461.     IF    BLKLEN GT 255
  462.     DCX    B        ;;DECR COUNT
  463.     MOV    A,C        ;;TEST LIMIT
  464.     ORA    B
  465.     JNZ    @FILL        ;;CONTINUE
  466.     ELSE
  467.     DCR    C
  468.     JNZ    @FILL
  469.     ENDIF
  470.     ELSE
  471.     IFB    <CONST>        ;;Altered form
  472.     MVI    M,0        ;;STORE A ZERO
  473.     ELSE
  474.     MVI    M,CONST        ;;STORE SINGLE BYTE
  475.     ENDIF
  476.     ENDIF
  477.     ENDM
  478. ;
  479. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  480. ;
  481. ;
  482. ;    MATCH MACRO    COMPARE 2 STRINGS OF SAME LENGTH SET CARRY IF EQUAL
  483. ;
  484. ;    MATCH    STR1,'LITERAL STRING'
  485. ;    MATCH    STR1,STR2,LENGTH
  486. ;    MATCH
  487. ;
  488. ;        DE POINTS TO STR1    MACRO WILL LOAD REG IF ARG
  489. ;        HL POINTS TO STR2    PRESENT
  490. ;        C CONTAINS LENGTH
  491. ;
  492. ;        SUBTRACT STR2 FROM STR1 AND SET FLAGS, ZERO INDICATES MATCH.
  493. ;        NORMALLY THE SECOND ARG IS A LITERAL STRING AND THE LENGTH
  494. ;        IS OMITTED. IF THE LEN ARG IS PRESENT THE SECOND STRING
  495. ;        ARG IS ASSUMED TO BE A MEMORY ADDR. IF ALL ARGUMENTS OMITTED
  496. ;        REGISTERS ASSUMED ALREADY LOADED.
  497. ;
  498. MATCH    MACRO    STR1,STR2,LEN
  499.     LOCAL    OVERSUB,M1
  500.     JMP    OVERSUB
  501. @MATCH:    INR    C        ;;PRE INCREMENT COUNT (IT MIGHT BE ZERO)
  502. M1:    DCR    C        ;;DECR LENGTH COUNT
  503.     RZ            ;;RETURN IF MATCH FOUND
  504.     LDAX    D        ;;GET A BYTE FROM ONE STRING
  505.     SUB    M        ;;COMPARE WITH OTHER
  506.     RNZ            ;;RETURN
  507.     INX    H
  508.     INX    D        ;;INCR STRING POINTERS
  509.     JMP    M1        ;;TRY SOME MORE
  510. OVERSUB:
  511. MATCH    MACRO    ?STR1,?STR2,?LEN
  512.     LOCAL    LITSTR,ENDLIT
  513.     IFB    <?STR1&?STR2&?LEN>    ;;Altered form
  514.     CALL    @MATCH
  515.     ELSE
  516.     IFNB    <?STR1>        ;;Altered form
  517.     LXI    D,?STR1        ;;LOAD STRING1 POINTER
  518.     ENDIF
  519.     IFB    <?LEN>        ;;Altered form  -  TEST FOR LITERAL
  520.     MVI    C,ENDLIT-LITSTR    ;;LENGTH OF LITERAL STRING
  521.     LXI    H,LITSTR    ;;POINTER TO LITERAL
  522.     CALL    @MATCH
  523.     JMP    ENDLIT
  524. LITSTR:    DB    ?STR2        ;;LITERAL STRING
  525. ENDLIT:                ;;END OF STRING
  526.     ELSE
  527.     IFNB    <?STR2>        ;;Altered form
  528.     LXI    H,?STR2        ;;LOAD POINTER TO STRING2
  529.     ENDIF
  530.     MVI    C,?LEN        ;;LOAD STRING LENGTH
  531.     CALL    @MATCH        ;;CALL MATCH SUBROUTINE
  532.     ENDIF
  533.     ENDIF
  534.     ENDM
  535.     MATCH    STR1,STR2,LEN
  536.     ENDM
  537. ;
  538. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  539. ;
  540. ;    INSTR MACRO    SEARCH STRING FOR SUBSTRING AND SET CARRY IF FOUND
  541. ;
  542. ;    INSTR    STRING,LENGTH,SUBSTR
  543. ;
  544. ;        HL    POINTS TO STRING
  545. ;        DE    POINTS TO SUBSTRING
  546. ;        B    CONTAINS STRING LENGTH
  547. ;        C    CONTAINS SUBSTRING LENGTH
  548. ;
  549. ;        MACRO RETURNS POINTER TO END OF SUBSTRING IN HL
  550. ;
  551. INSTR    MACRO    STRING,LENGTH,SUBSTR
  552.     LOCAL    OVERSUB,S1,SSX
  553.     JMP    OVERSUB
  554. @INSTR:    MOV    A,B        ;;STRING LENGTH
  555.     SUB    C        ;;SUBTRACT SUBSTR LENGTH
  556.     CMC            ;;COMP CARRY
  557.     RNC            ;;ERROR RETURN SUBSTR > STRING
  558.     MOV    B,A        ;;NEW STRING LIMIT TO B
  559. S1:    SAVE
  560.     MATCH
  561.     RESTORE
  562.     JZ    SSX        ;;MATCH IF ZERO ON RET
  563.     ANA    A        ;;RESET CARRY
  564.     DCR    B        ;;BYTES LEFT
  565.     RM            ;;FINISHED IF MINUS, NO MATCH
  566.     INX    H        ;;INCR STRING POINTER
  567.     JMP    S1        ;;TRY AGAIN
  568. SSX:    MVI    B,0        ;;SET D TO 0
  569.     DAD    B
  570.     STC            ;;SET CARRY
  571.     RET
  572. OVERSUB:
  573. INSTR    MACRO    ?STR,?LEN,?SUBSTR
  574.     LOCAL    LITSTR,ENDLIT
  575.     IFNB    <?STR>        ;;Altered form
  576.     LXI    H,?STR
  577.     ENDIF
  578.     MVI    B,?LEN
  579.     MVI    C,ENDLIT-LITSTR
  580.     LXI    D,LITSTR
  581.     CALL    @INSTR
  582.     JMP    ENDLIT
  583. LITSTR:    DB    ?SUBSTR
  584. ENDLIT:
  585.     ENDM
  586.     INSTR    STRING,LENGTH,SUBSTR
  587.     ENDM
  588. ;
  589. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  590. ;
  591. ;    SCAN MACRO    SCAN A STRING UNTIL A CHAR IS FOUND, SKIP BLANKS
  592. ;            AND CONTROL CHARACTERS
  593. ;
  594. ;            CARRY SET IF NUMERIC, CARRY OFF IF ALPHABETIC
  595. ;
  596. ;
  597. SCAN    MACRO    ADDR
  598.     LOCAL    OVERSUB
  599.     JMP    OVERSUB
  600. @SCAN:    MOV    A,M        ;;GET A BYTE
  601.     CPI    21H        ;;SPACE OR LESS?
  602.     RP
  603.     INX    H        ;;INCR POINTER
  604.     JMP    @SCAN        ;;KEEP SEARCHING
  605. OVERSUB:
  606. SCAN    MACRO    ?ADDR
  607.     IFNB    <?ADDR>        ;;Altered form
  608.     LXI    H,?ADDR
  609.     ENDIF
  610.     CALL    @SCAN        ;;CALL SUBROUTINE
  611.     CPI    3AH        ;;NUMBER OR ALPHA
  612.     ENDM
  613.     SCAN    ADDR
  614.     ENDM
  615. ;
  616. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  617. ;
  618. ;    DISKIO MACRO    EXECUTE BDOS DISK ACCESS PRIMITIVES
  619. ;
  620. ;    DISKIO    FUNCTION,PARAMETER
  621. ;
  622. ;        NO    FUNCTION    ENTRY PARAM
  623. ;
  624. ;        12    LIFTHEAD
  625. ;        13    INITIAL
  626. ;        14    LOGIN        DISK NO 0 - 1
  627. ;        15    OPEN        FCB
  628. ;        16    CLOSE        FCB
  629. ;        17    SEARCH        FCB
  630. ;        18    SERNXT        FCB
  631. ;        19    DELETE        FCB
  632. ;        20    READ        FCB
  633. ;        21    WRITE        FCB
  634. ;        22    MAKE        FCB
  635. ;        23    RENAME        FCB
  636. ;        24    ?LOGIN
  637. ;        25    ?DRIVE
  638. ;        26    SETDMA        BUFFER
  639. ;        27    ?ALLOC
  640. ;        SEE CP/M INTERFACE GUIDE FOR DETAILED INFORMATION ON THE
  641. ;        DISK ACCESS PRIMITIVES
  642. ;
  643. ;    DISKIO    READ,FCB    (TYPICAL MACRO CALL)
  644. ;
  645. DISKIO    MACRO    FUNCTION,PARAMETER
  646. LIFTHEAD    SET    12
  647. INITIAL        SET    13
  648. LOGIN        SET    14
  649. OPEN        SET    15
  650. CLOSE        SET    16
  651. SEARCH        SET    17
  652. SERNXT        SET    18
  653. DELETE        SET    19
  654. READ        SET    20
  655. WRITE        SET    21
  656. MAKE        SET    22
  657. RENAME        SET    23
  658. ?LOGIN        SET    24
  659. ?DRIVE        SET    25
  660. SETDMA        SET    26
  661. ?ALLOC        SET    27
  662. ;
  663. ?C    SET    FUNCTION
  664.     IFNB    <PARAMETER>    ;;Altered form
  665.     LXI    D,PARAMETER
  666.     ENDIF
  667.     MVI    C,?C
  668.     CALL    5        ;;BDOS ENTRY
  669.     ENDM
  670. ;
  671. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  672. ;
  673. ;    CALLBIOS MACRO    CALL BIOS ROUTINES DIRECTLY
  674. ;
  675. ;    CALLBIOS    FUNCTION,PARAM
  676. ;
  677. CALLBIOS    MACRO    FUNCT,PARAM
  678.     LOCAL    @CALL
  679. ;
  680. DCOLD    SET    00H
  681. DWBOOT    SET    03H
  682. DSTAT    SET    06H
  683. DCONIN    SET    09H
  684. DCONOUT    SET    0CH        ;;CHAR IN C
  685. DLIST    SET    0FH        ;;CHAR IN C
  686. DPUNCH    SET    12H
  687. DREADER    SET    15H
  688. DHOME    SET    18H
  689. DSELDSK    SET    1BH
  690. DSETTRK    SET    1EH
  691. DSETSEC    SET    21H        ;;SECTOR NO IN C
  692. DSETDMA    SET    24H        ;;DMA ADDR IN BC
  693. DREAD    SET    27H
  694. DWRITE    SET    2AH
  695. ;
  696. ?F    SET    FUNCT
  697.     IFNB    <PARAM>        ;;Altered form
  698.     MVI    C,PARAM
  699.     ENDIF
  700.     LHLD    1        ;;ADDR OF BIOS
  701.     MVI    L,?F        ;;JUMP OFFSET
  702.     SHLD    @CALL+1        ;;MODIFY CALL ADDR
  703. @CALL:    CALL    0
  704.     ENDM
  705. ;
  706. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  707. ;
  708. ;    DLOAD MACRO    DOUBLE PRECISION INDEXED LOAD HL
  709. ;
  710. ;        LOAD (ADDR + INDX) TO HL
  711. ;
  712. DLOAD    MACRO    ADDR,INDX
  713.     IFB    <INDX>        ;;Altered form
  714.     LHLD    ADDR
  715.     ELSE
  716.     LHLD    INDX
  717.     LXI    D,ADDR
  718.     DAD    D
  719.     MOV    E,M
  720.     INX    H
  721.     MOV    D,M
  722.     XCHG
  723.     ENDIF
  724.     ENDM
  725. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  726. ;
  727. ;    CPHL MACRO    SUBTRACT DE FROM HL AND SET FLAGS
  728. ;
  729. CPHL    MACRO
  730.     LOCAL    @END
  731.     MOV    A,H
  732.     CMP    D        ;;COMPARE HIGH BYTES
  733.     JNZ    @END
  734.     MOV    A,L
  735.     CMP    E        ;;COMPARE LOW BYTES
  736. @END:    ENDM
  737. ;
  738. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  739. ;
  740. ;    DJZ MACRO    DOUBLE PRECISION TEST HL AND JUMP ON ZERO
  741. ;
  742. DJZ    MACRO    ADDR
  743.     MOV    A,H
  744.     ORA    L
  745.     JZ    ADDR
  746.     ENDM
  747. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  748. ;
  749. ;    DSTORE MACRO    DOUBLE PRECISION INDEXED STORE HL
  750. ;
  751. ;        STORE (HL) IN (ADDR + INDX)
  752. ;
  753. DSTORE    MACRO    ADDR,INDX
  754.     IFB    <INDX>        ;;Altered form
  755.     SHLD    ADDR
  756.     ELSE
  757.     SAVE    H
  758.     LHLD    INDX
  759.     XCHG
  760.     LXI    H,ADDR
  761.     DAD    D
  762.     RESTORE    D
  763.     MOV    M,E
  764.     INX    H
  765.     MOV    M,D
  766.     ENDIF
  767.     ENDM
  768. ;
  769. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  770. ;
  771. ;    INDEX MACRO    INDEX AN ADDRESS POINTER BY A CONSTANT
  772. ;
  773. ;    INDEX    POINTER,INCR
  774. ;
  775. INDEX    MACRO    POINTER,INCR
  776.     LHLD    POINTER
  777.     LXI    D,INCR
  778.     DAD    D        ;;DOUBLE ADD
  779.     SHLD    POINTER
  780.     ENDM
  781. ;
  782. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . .
  783. ;
  784. ;    FILFCB    MACRO    FILL IN THE ID FIELDS OF FCB
  785. ;
  786. ;    FILFCB    FCB,IDSTRING
  787. ;
  788. ;        IDSTRING CONTAINS FILE NAME AND TYPE  (FILNAM.TYP)
  789. ;        CARRY SET IF ERROR  (NAME TOO LONG)
  790. ;
  791. FILFCB    MACRO    FCB,IDSTRING
  792.     LOCAL    OVERSUB,F1,F2,F3,F4,F5,F6
  793.     JMP    OVERSUB
  794. @FLFCB: MVI    M,0        ;;CLEAR FIRST BYTE OF FCB
  795.     INX    H
  796.     PUSH    H        ;;SAVE POINTER TO NAME
  797.     MVI    C,11        ;;SIZE OF ID FIELD
  798.     MVI    A,' '        ;;SPACE TO A
  799. F1:    MOV    M,A        ;;FILL NAME WITH SPACES
  800.     INX    H
  801.     DCR    C
  802.     JNZ    F1
  803.     POP    H        ;;RESTORE NAME POINTER
  804.     MVI    C,8        ;;MAXIMUM SIZE OF NAME
  805. F2:    LDAX    D        ;;GET BYTE FROM ID FIELD
  806.     CPI    ' '        ;;LEADING SPACES?
  807.     JNZ    F3
  808.     INX    D        ;;SKIP LEADING SPACES
  809.     JMP    F2
  810. F3:    LDAX    D        ;;GET ID BYTE
  811.     CPI    0        ;;ZERO END OF FIELD
  812.     RZ
  813.     CPI    ' '        ;;SPACE END OF FIELD
  814.     RZ
  815.     CPI    '.'        ;;PERIOD TYPE SEPARATOR
  816.     JZ    F4        ;;DO TYPE
  817.     MOV    M,A        ;;STORE NAME BYTE
  818.      INX    H
  819.     INX    D        ;;INCR POINTERS
  820.     DCR    C        ;;DECR MAXIMUM COUNT
  821.     JP    F3        ;;LOOP BACK
  822.     STC            ;;SET CARRY NAME TOO LARGE
  823.     RET
  824. F4:    INX    D        ;;SKIP THE PERIOD
  825.     MOV    A,C
  826.     ORA    A
  827.     JZ    F6        ;;TEST C FOR ZERO
  828. F5:    INX    H
  829.     DCR    C
  830.     JNZ    F5        ;;INDEX TO TYPE FIELD
  831. F6:    MVI    C,3        ;;SIZE OF TYPE FIELD
  832. F7:    LDAX    D        ;;GET ID BYTE
  833.     CPI    0        ;;ZERO?
  834.     RZ            ;;FINISHED
  835.     CPI    ' '        ;;SPACE?
  836.     RZ
  837.     MOV    M,A        ;;STORE TYPE BYTE
  838.     INX    H
  839.     INX    D        ;INCR POINTERS
  840.     DCR    C        ;;DECR MAX COUNT
  841.     JNZ    F7        ;;LOOP BACK
  842.     RET
  843. OVERSUB:
  844. FILFCB    MACRO    ?FCB,?ID
  845.     IFNB    <?ID>        ;;Altered form
  846.     LXI    D,?ID
  847.     ENDIF
  848.     IFNB    <?FCB>        ;;Altered form
  849.     LXI    H,?FCB
  850.     ENDIF
  851.     CALL    @FLFCB
  852.     XCHG
  853.     ENDM
  854.     FILFCB    FCB,IDSTRING
  855.     ENDM
  856. ;
  857. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  858. ;
  859. ;    SETTRK MACRO    SET AND TEST TRACK NUMBER
  860. ;
  861. ;            CARRY SET IF > 76
  862. ;
  863. SETTRK    MACRO    TRKNO
  864.     LOCAL    ENDTRK
  865.     IFNB    <TRKNO>        ;;Altered form
  866.     LDA    TRKNO
  867.     ENDIF
  868.     CPI    77
  869.     CMC
  870.     JC    ENDTRK
  871.     MOV    C,A        ;;TRACK NO TO C
  872.     CALLBIOS DSETTRK
  873. ENDTRK:    ENDM
  874. ;
  875. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  876. ;
  877. ;    SETSEC MACRO    SET AND TEST SECTOR NUMBER
  878. ;
  879. ;        RETURN WITH CARRY SET < 1 OR > 26
  880. ;
  881. SETSEC    MACRO    SECNO
  882.     LOCAL    ENDSEC
  883.     IFNB    <SECNO>        ;;Altered form
  884.     LDA    SECNO
  885.     ENDIF
  886.     ORA    A        ;CHECK ZERO
  887.     STC
  888.     JZ    ENDSEC
  889.     CPI    27        ;CHECK > 26
  890.     CMC
  891.     JC    ENDSEC
  892.     MOV    C,A        ;MOVE TO C
  893.     CALLBIOS DSETSEC
  894. ENDSEC:    ENDM
  895. ;    . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  896. ;
  897. ;    HALF MACRO    DIVIDES A 16 BIT NUMBER BY 2
  898. ;
  899. HALF    MACRO    I
  900.     LOCAL    OVER
  901.     JMP    OVER
  902. @HALF:    XRA    A        ;;CLEAR CARRY
  903.     MOV    A,H
  904.     RAR            ;;SHIFT UPPER HALF
  905.     MOV    H,A
  906.     MOV    A,L
  907.     RAR            ;;SHIFT LOWER HALF
  908.     MOV    L,A
  909.     RET
  910. OVER:
  911. HALF    MACRO    ?I
  912.     IFNB    <?I>        ;;Altered form
  913.     LHLD    ?I
  914.     ENDIF
  915.     CALL    @HALF
  916.     ENDM
  917.     HALF    I
  918.     ENDM
  919. .LIST
  920.