home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol073 / macro3.lib < prev    next >
Encoding:
Text File  |  1984-04-29  |  19.7 KB  |  1,025 lines

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