home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / SIMTEL / CPMUG / CPMUG038.ARK / MACRO.LIB < prev    next >
Text File  |  1984-04-29  |  18KB  |  949 lines

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