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 / CPMUG024.ARK / MACRO.LIB < prev    next >
Text File  |  1984-04-29  |  17KB  |  890 lines

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