home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / lambda / soundpot / p / z80macro.lbr / Z80MACRO.LZB / Z80MACRO.LIB
Encoding:
Text File  |  1993-10-25  |  22.4 KB  |  1,459 lines

  1. ; ***************************************************************
  2. ; *                                *
  3. ; *  Z80MACRO.LIB    Macro Library for CP/M System Routines  *
  4. ; *                                *
  5. ; *       Ref: "Mastering CP/M" by Alan R. Miller        *
  6. ; *     Modified and adapted to Z80MR by Rich Brewster        *
  7. ; *     R.D.1  Brackney, PA 18812  (717) 663-2408        *
  8. ; *                                *
  9. ; ***************************************************************
  10.  
  11. ; Z80MACRO.LIB    Table of Contents    06/23 10:15.24
  12.  
  13. ; MACRO        PARAMETERS        FLAG        EMBEDDED MACROS
  14.  
  15. ; AMBIG        UFNFCB,AFNFCB        AMFLAG
  16. ; CLOSE        FCB,ERRJMP         CLFLAG        SYSF
  17. ; CMPBLK    ADDR1,ADDR2,SIZE    CMFLAG
  18. ; CMPDAT    ADDR,SIZE        CMFLAG
  19. ; CPABLK    ADDR1,ADDR2,SIZE    CPFLAG
  20. ; CPATXT    TEXT,ADDR        CPFLAG
  21. ; CPMVER
  22. ; CRLF                    CRFLAG        PCHAR
  23. ; DELETE    FCB,ERRJMP        DEFLAG        CRLF    GCHAR    PFNAME    PRINT    SYSF    UCASE    UNPROT
  24. ; DIVIDE    TWOS            DVFLAG
  25. ; DRIVE                    DRFLAG        SYSF
  26. ; ENTER
  27. ; EXIT        BOOT
  28. ; FILL        ADDR,SIZE,VAL        FLFLAG
  29. ; GCHAR                    CIFLAG        SYSF
  30. ; GFNAME    FCB            FNFLAG        CRLF    PCHAR    PRINT    READB    UCASE
  31. ; HEXHL                    HXFLAG        UCASE
  32. ; HLDEC                    HLFLAG        PCHAR
  33. ; LCHAR                    LOFLAG        SYSF
  34. ; MAKE        FCB,ERRJMP        MKFLAG        SYSF
  35. ; MOVBLK    FROM,TO,SIZE
  36. ; MOVDAT    TO,SIZE
  37. ; MULT        TWOS            MLFLAG
  38. ; OPEN        FCB,ERRJMP        OPFLAG        SYSF
  39. ; OUTBIN                BNFLAG        PCHAR
  40. ; OUTHEX    REG            CXFLAG        PCHAR
  41. ; OUTHL                            OUTHEX
  42. ; PCHAR                    COFLAG        SYSF
  43. ; PFNAME    FCB            PFFLAG        PCHAR    PRINTB
  44. ; PRINT        TEXT            PRFLAG        PCHAR
  45. ; PRINTB    ADDR,SIZE        PRFLAG        PCHAR
  46. ; PROTEC    FCB            PTFLAG        SYSF
  47. ; READB                      RBFLAG
  48. ; READS        FCB,ERRJMP        RSFLAG        SYSF
  49. ; RENAME    FCB            RNFLAG        CRLF    PFNAME    PRINT    SYSF    UNPROT
  50. ; SCAN        CHAR,JMP
  51. ; SETDMA                DMFLAG        SYSF
  52. ; SYSF        FUNC,AE
  53. ; UCASE
  54. ; UNPROT    FCB            PTFLAG        SYSF
  55. ; UPPER
  56. ; VERSN        TEXT
  57. ; WRITES    FCB,ERRJMP        WSFLAG        SYSF
  58.  
  59. ;      *INCLUDE MRFLAGS.H in .AZM files for flag initialization.
  60. ;    See    MRFLAGS.DOC for MACRO/FLAG/GLOBAL cross listing.
  61.  
  62. ; DEFINED CHARACTERS
  63.  
  64. BEL    EQU    07    ; ^G  Console Beep
  65. TAB    EQU    09    ; ^I  Horizontal Tab
  66. LF    EQU    0AH    ; ^J  Line Feed
  67. FF    EQU    0CH    ; ^L  Form Feed
  68. CR    EQU    0DH    ; ^M  Carriage Return
  69. EOF    EQU    1AH    ; ^Z  End of File
  70. ESC    EQU    1BH    ; ^[  Escape
  71. BLANK    EQU    20H    ;     Space
  72.  
  73. ; CP/M CONVENTIONS
  74.  
  75. BOOT    EQU    0    ; Warm Boot entry vector
  76. BDOS    EQU    5    ; BDOS entry vector
  77. FCB1    EQU    5CH    ; Input file control block
  78. FCB2    EQU    6CH    ; Second command line parameter
  79. DBUFF    EQU    80H    ; Default disk sector buffer
  80. TPA    EQU    100H    ; Transient program area
  81.  
  82.  
  83. ; MACRO OPTIONS
  84.  
  85. STKSIZ    EQU    32    ; EXIT macro user stack size
  86. BUFSIZ    EQU    16    ; READB macro console input buffer size
  87.  
  88. ; FLAG SETTINGS
  89.  
  90. FALSE    EQU    0
  91. TRUE    EQU    .NOT.FALSE
  92.  
  93. ; MACROS
  94.  
  95. AMBIG    MACRO    #UFNFCB,#AFNFCB
  96. ;
  97. ; Inline macro to change an ambiguous filename at address #AFNFCB
  98. ; to match an unambiguous filename at address #UFNFCB.
  99. ;
  100. ; e.g.    AMBIG    FCB1,FCB2
  101. ;
  102.     LOCAL    #AROUND
  103.     PUSH    HL
  104.     PUSH    DE
  105.     PUSH    BC
  106.     LD    HL,#AFNFCB+1
  107.     LD    DE,#UFNFCB+1
  108.     LD    B,11        ; number of characters in a filename
  109.     CALL    AMBI2?
  110.     POP    BC
  111.     POP    DE
  112.     POP    HL
  113. ;
  114.     IF    .NOT.AMFLAG
  115.     JP    #AROUND
  116. AMBI2?:
  117.     LD    A,'?'
  118.     CP    (HL)
  119.     JR    NZ,AMBI3?
  120.     LD    A,(DE)        ; get UFN
  121.     LD    (HL),A        ; put AFN
  122. AMBI3?:
  123.     INC    HL
  124.     INC    DE
  125.     DJNZ    AMBI2?
  126.     RET
  127. ;
  128. AMFLAG    DEFL    TRUE
  129. #AROUND:
  130.     ENDIF
  131.                 ; AMBIG
  132.     ENDM
  133.  
  134.  
  135. CLOSE    MACRO    #FCB,#ERRJMP
  136. ;
  137. ; Inline macro to close a file using FCB at address #FCB.
  138. ; Jumps to #ERRJMP if the filename is not in the disk directory.
  139. ;
  140. ; e.g.    CLOSE    DFCB,NOFILE
  141. ;
  142.     LOCAL    #AROUND
  143.     LD    DE,#FCB
  144.     CALL    CLOS2?
  145.     INC    A        ; A returns 0FFH if name not in directory
  146.     JP    Z,#ERRJMP
  147. ;
  148.     IF    .NOT.CLFLAG
  149.     JP    #AROUND
  150. CLOS2?:
  151.     SYSF    16,0        ; Close File
  152. CLFLAG    DEFL    TRUE
  153. #AROUND:
  154.     ENDIF            ; CLOSE
  155.  
  156.     ENDM
  157.  
  158.  
  159. CMPBLK    MACRO    #ADDR1,#ADDR2,#SIZE
  160. ;
  161. ; Inline macro to compare two memory blocks of length
  162. ; #SIZE bytes at addresses #ADDR1 and #ADDR2.
  163. ; Z flag is set if the blocks are identical.
  164. ;
  165. ; e.g.    CMPBLK    FCB1,FCB2,12
  166. ;
  167.     LOCAL    #AROUND
  168.     PUSH    HL
  169.     PUSH    DE
  170.     PUSH    BC
  171.     LD    BC,#SIZE
  172.     LD    HL,#ADDR1
  173.     LD    DE,#ADDR2
  174.     CALL    COMP2?
  175.     POP    BC
  176.     POP    DE
  177.     POP    HL
  178. ;
  179.     IF    .NOT.CMFLAG
  180.     JP    #AROUND
  181. COMP2?:
  182.     LD    A,(DE)
  183.     CPI
  184.     RET    NZ
  185.     INC    DE
  186.     JP    PE,COMP2?
  187.      RET
  188. ;
  189. CMFLAG    DEFL    TRUE
  190. #AROUND:
  191.     ENDIF
  192.                 ; CMPBLK
  193.     ENDM
  194.  
  195.  
  196. CMPDAT    MACRO    #ADDR,#SIZE
  197. ;
  198. ; Inline macro to compare immediately following data
  199. ; of length #SIZE bytes with a memory block at #ADDR.
  200. ; Z flag is set if the data are identical.
  201. ;
  202. ; e.g.    CMPDAT    FCB1+9,5
  203. ;    DB    '???',2,10H
  204. ;
  205.     LOCAL    #DATA
  206.     PUSH    HL
  207.     PUSH    DE
  208.     PUSH    BC
  209.     LD    BC,#SIZE
  210.     LD    HL,#DATA
  211.     LD    DE,#ADDR
  212.     CALL    COMP2?
  213.     POP    BC
  214.     POP    DE
  215.     POP    HL
  216.     JP    #DATA+#SIZE
  217. ;
  218.     IF    .NOT.CMFLAG
  219. COMP2?:
  220.     LD    A,(DE)
  221.     CPI
  222.     RET    NZ
  223.     INC    DE
  224.     JP    PE,COMP2?
  225.      RET
  226. ;
  227. CMFLAG    DEFL    TRUE
  228.     ENDIF
  229. #DATA:
  230.                 ; CMPDAT - DB here
  231.     ENDM
  232.  
  233.  
  234. CPABLK    MACRO    #ADDR1,#ADDR2,#SIZE
  235. ;
  236. ; Inline macro to compare two memory blocks at #ADDR1 and #ADDR2
  237. ; of length #SIZE bytes, 256 bytes max.
  238. ; 7-bit ASCII compare, Z flag is set if the blocks are identical.
  239. ;
  240. ; e.g.    CPABLK    FCB1+1,FCB2+1,11
  241. ;
  242.     LOCAL    #AROUND
  243.     PUSH    HL
  244.     PUSH    DE
  245.     PUSH    BC
  246.     LD    B,#SIZE
  247.     LD    HL,#ADDR1
  248.     LD    DE,#ADDR2
  249.     CALL    CPAS2?
  250.     POP    BC
  251.     POP    DE
  252.     POP    HL
  253. ;
  254.     IF    .NOT.CPFLAG
  255.     JP    #AROUND
  256. CPAS2?:
  257.     LD    A,(DE)
  258.     RES    7,A
  259.     LD    C,A
  260.     LD    A,(HL)
  261.     RES    7,A
  262.     CP    C
  263.     RET    NZ
  264.     INC    HL
  265.     INC    DE
  266.     DJNZ    CPAS2?
  267.     RET
  268. ;
  269. CPFLAG    DEFL    TRUE
  270. #AROUND:
  271.     ENDIF
  272.                 ; CPABLK
  273.     ENDM
  274.  
  275.  
  276. CPATXT    MACRO    #TEXT,#ADDR
  277. ;
  278. ; Inline macro to compare #TEXT string with a memory block at #ADDR.
  279. ; 7-bit ASCII compare, Z flag is set if the strings are identical.
  280. ;
  281. ; e.g.    CPATXT    'COM',FCB1+9
  282. ;
  283.     LOCAL    #AROUND,#STRING
  284.     PUSH    HL
  285.     PUSH    DE
  286.     PUSH    BC
  287.     LD    B,#AROUND-#STRING
  288.     LD    HL,#STRING
  289.     LD    DE,#ADDR
  290.     CALL    CPAS2?
  291.     POP    BC
  292.     POP    DE
  293.     POP    HL
  294.     JP    #AROUND
  295. ;
  296.     IF    .NOT.CPFLAG
  297. CPAS2?:
  298.     LD    A,(DE)
  299.     RES    7,A
  300.     LD    C,A
  301.     LD    A,(HL)
  302.     RES    7,A
  303.     CP    C
  304.     RET    NZ
  305.     INC    HL
  306.     INC    DE
  307.     DJNZ    CPAS2?
  308.     RET
  309. ;
  310. CPFLAG    DEFL    TRUE
  311.     ENDIF
  312. #STRING:
  313.     DB    '#TEXT'
  314. #AROUND:
  315.                 ; CPATXT
  316.     ENDM
  317.  
  318.  
  319. CPMVER    MACRO
  320. ;
  321. ; Inline macro to determine the CP/M version number.
  322. ; Returns version number in A, in BCD times 10.
  323. ;
  324.     PUSH    HL
  325.     PUSH    DE
  326.     PUSH    BC
  327.     LD    C,12        ; BDOS function 12
  328.     CALL    BDOS
  329.     POP    BC
  330.     POP    DE
  331.     POP    HL
  332.                 ; CPMVER
  333.     ENDM
  334.  
  335.  
  336. CRLF    MACRO
  337. ;
  338. ; Inline macro to send carriage return and line feed to console.
  339. ;
  340.     LOCAL    #AROUND
  341.     CALL    CRLF2?
  342. ;
  343.     IF    .NOT.CRFLAG
  344.     JP    #AROUND
  345. CRLF2?:
  346.     PUSH    AF
  347.     LD    A,CR        ; carriage return
  348.     PCHAR
  349.     LD    A,LF        ; line feed
  350.     PCHAR
  351.     POP    AF
  352.     RET
  353. ;
  354. CRFLAG    DEFL    TRUE
  355. #AROUND:
  356.     ENDIF
  357.                 ; CRLF
  358.     ENDM
  359.  
  360.  
  361. DELETE    MACRO    #FCB,#ERRJMP
  362. ;
  363. ; Inline macro to delete an existing disk file using the FCB
  364. ; at address #FCB.
  365. ; Prompts user if file is R/O, and gives option to abort.
  366. ; If aborting the deletion of a R/O file, jumps to #ERRJMP.
  367. ;
  368. ; e.g.    DELETE    FCB1,CONT
  369. ;
  370.     LOCAL    #AROUND,#DEL
  371.     LD    DE,#FCB
  372.     LD    A,(#FCB+9)    ;first char of file type
  373.     BIT    7,A        ;R/O?
  374.     JP    Z,#DEL
  375.     CRLF
  376.     PFNAME    #FCB
  377.     PRINT    ' is R/O, delete?'
  378.     GCHAR
  379.     UCASE
  380.     CP    'Y'
  381.     JP    NZ,#ERRJMP
  382.     UNPROT    #FCB
  383. #DEL:
  384.     CALL    DELE2?
  385. ;
  386.     IF    .NOT.DEFLAG
  387.     JP    #AROUND
  388. DELE2?:
  389.     SYSF    19,0        ; Delete File
  390. DEFLAG    DEFL    TRUE
  391. #AROUND:
  392.     ENDIF
  393.                 ; DELETE
  394.     ENDM
  395.  
  396.  
  397. DIVIDE    MACRO    #TWOS
  398. ;
  399. ; Inline macro to divide HL by #TWOS.
  400. ; #TWOS must be a power of 2.
  401. ; HL unchanged if #TWOS is 0 or 1.
  402. ;
  403. ; e.g.    DIVIDE    4
  404. ;
  405.     LOCAL    #AROUND
  406.     PUSH    BC
  407.     LD    B,#TWOS
  408.     CALL    DIVI2?
  409.     POP    BC
  410. ;
  411.     IF    .NOT.DVFLAG
  412.     JP    #AROUND
  413. DIVI2?:
  414.     LD    A,B
  415.     OR    A
  416.     RET    Z        ; by zero
  417.     RRA
  418.     RET    C        ; by one
  419.     LD    B,A
  420. DIVI3?:
  421.     CALL    DIVI4?
  422.     LD    A,B        ; get divisor
  423.     RRA
  424.     LD    B,A
  425.     JR    NC,DIVI3?
  426.     RET
  427. DIVI4?:
  428.     XOR    A        ; clear carry
  429.     LD    A,H
  430.     RRA
  431.     LD    H,A
  432.     LD    A,L
  433.     RRA
  434.     LD    L,A
  435.     RET
  436. ;
  437. DVFLAG    DEFL    TRUE
  438. #AROUND:
  439.     ENDIF
  440.                 ; DIVIDE
  441.     ENDM
  442.  
  443.  
  444. DRIVE    MACRO
  445. ;
  446. ; Inline macro to return current drive in A.
  447. ; A:=1, B:=2, etc.
  448. ;
  449.     LOCAL    #AROUND
  450.     CALL    DRIV2?
  451.     INC    A        ; func 25 returns 0 for A:
  452. ;
  453.     IF    .NOT.DRFLAG
  454.     JP    #AROUND
  455. DRIV2?:
  456.     SYSF    25,0        ; Return Current Disk
  457. DRFLAG    DEFL    TRUE
  458. #AROUND:
  459.     ENDIF
  460.                 ; DRIVE
  461.     ENDM
  462.  
  463.  
  464. ENTER    MACRO
  465. ;
  466. ; Inline macro to save incoming stack.
  467. ;
  468.     LD    (OLDSTK),SP
  469.     LD    SP,STACK
  470.                 ; ENTER
  471.     ENDM
  472.  
  473.  
  474. EXIT    MACRO    #BOOT
  475. ;
  476. ; Inline macro to restore the stack.
  477. ; If #BOOT is 0 then warm boot on exit.
  478. ;
  479.     LD    SP,(OLDSTK)
  480. ;
  481.     IF    #BOOT
  482.     RET
  483.     ELSE
  484.     LD    C,0        ; warm boot
  485.     CALL    BDOS
  486.     ENDIF
  487. ;
  488. OLDSTK:    DS    2        ; incoming SP saved here
  489.     DS    STKSIZ        ; user stack
  490. STACK    EQU    $        ; stack top here
  491.                 ; EXIT
  492.     ENDM
  493.  
  494.  
  495. FILL    MACRO    #ADDR,#SIZE,#VAL
  496. ;
  497. ; Inline macro to fill memory with byte #VAL,
  498. ; starting at #ADDR, continuing for #SIZE locations.
  499. ;
  500. ; e.g.    FILL    FCB1+1,8,BLANK
  501. ;
  502.     LOCAL    #AROUND
  503.     PUSH    HL
  504.     PUSH    BC
  505.     LD    HL,#ADDR
  506.     LD    BC,#SIZE
  507.     LD    A,#VAL
  508.     CALL    FILL2?
  509.     POP    BC
  510.     POP    HL
  511. ;
  512.     IF    .NOT.FLFLAG
  513.     JP    #AROUND
  514. FILL2?:
  515.     PUSH    DE
  516.     LD    D,A
  517. FILL3?:
  518.     LD    (HL),D
  519.     INC    HL
  520.     DEC    BC
  521.     LD    A,C
  522.     OR    B
  523.     JR    NZ,FILL3?
  524.     POP    DE
  525.     RET
  526. ;
  527. FLFLAG    DEFL    TRUE
  528. #AROUND:
  529.     ENDIF
  530.                 ; FILL
  531.     ENDM
  532.  
  533.  
  534. GCHAR    MACRO
  535. ;
  536. ; Inline macro to read one character from console.
  537. ; Suspends program execution and waits for character.
  538. ; Character is returned in A.
  539. ;
  540.     LOCAL    #AROUND
  541.     CALL    GCHA2?
  542. ;
  543.     IF    .NOT.CIFLAG
  544.     JP    #AROUND
  545. GCHA2?:    
  546.     SYSF    1,0        ; Console Input
  547. CIFLAG    DEFL    TRUE
  548. #AROUND:
  549.     ENDIF
  550.                 ; GCHAR
  551.     ENDM
  552.  
  553.  
  554. GFNAME    MACRO    #FCB
  555. ;
  556. ; Inline macro to get a filename from the
  557. ; console and place it in a memory FCB at address #FCB.
  558. ;
  559. ; e.g.    GFNAME    FCB1
  560. ;
  561.     LOCAL    #AROUND
  562.     PUSH    HL
  563.     PUSH    DE
  564.     PUSH    BC
  565.     LD    HL,#FCB
  566.     LD    (?FCBAD),HL    ; save FCB address
  567.     CALL    GNAM2?
  568.     POP    BC
  569.     POP    DE
  570.     POP    HL
  571. ;
  572.     IF    .NOT.FNFLAG
  573.     JP    #AROUND
  574. ?FCBAD:    DS    2        ; FCB address saved here
  575. GNAM2?:
  576.     CRLF
  577. GNAM3?:
  578.     PRINT    '                                      '
  579.     LD    A,CR
  580.     PCHAR
  581.     PRINT    'Enter file name: '
  582.     LD    HL,(?FCBAD)
  583.     PUSH    HL
  584.     XOR    A        ; 0 = default drive
  585.     LD    (HL),A        ; initialize to default drive
  586.     LD    B,11        ; chars in name
  587.     LD    A,BLANK
  588. ZNAME?:                ; initialize name to blanks
  589.     INC    HL
  590.     LD    (HL),A
  591.     DJNZ    ZNAME?
  592.     POP    DE        ; FCB address
  593.     INC    DE        ; point to first char of name
  594.     READB
  595.     CALL    GETCH?        ; char returns in A
  596.     JP    C,GNAM3?    ; nothing entered, so start again
  597.     CP    BLANK
  598.     JP    Z,GNAM3?    ; leading space entered, so start again
  599.     UCASE
  600.     LD    (DE),A        ; store first char of name
  601.     CALL    GETCH?        ; char returns in A
  602.     RET    C        ; done: short name
  603.     CP    BLANK        ; same, with trailing space
  604.     RET    Z
  605.     LD    B,7        ; 7 characters to go
  606.     UCASE
  607.     CP    '.'
  608.     JP    Z,ENAME?    ; end of name
  609.     CP    ':'
  610.     JP    NZ,PNAME?    ; no drive specification
  611.     LD    A,(DE)        ; get the drive spec
  612.     SUB    40H        ; make it binary
  613.     DEC    DE        ; point to 1st FCB location
  614.     LD    (DE),A        ; put binary drive spec
  615.     CALL    GETCH?        ; start filename
  616.     JP    C,GNAM3?    ; only drive spec entered, so start again
  617.     UCASE
  618.     INC    B        ; 8 characters to go
  619. PNAME?:
  620.     INC    DE
  621.     LD    (DE),A
  622.     CALL    GETCH?
  623.     RET    C
  624.     CP    BLANK
  625.     RET    Z
  626.     UCASE
  627.     CP    '.'
  628.     JP    Z,ENAME?
  629.     DJNZ    PNAME?
  630.     JP    GNAM3?        ; if 9 characters
  631. ENAME?:
  632.     LD    HL,(?FCBAD)    ; get FCB
  633.     LD    DE,9        ; extent offset
  634.     ADD    HL,DE
  635.     EX    DE,HL
  636.     LD    B,3
  637. ENAM2?:
  638.     CALL    GETCH?
  639.     RET    C
  640.     CP    BLANK
  641.     RET    Z
  642.     UCASE
  643.     LD    (DE),A
  644.     INC    DE
  645.     DJNZ    ENAM2?
  646.     RET
  647. ;
  648. FNFLAG    DEFL    TRUE
  649. #AROUND:
  650.     ENDIF
  651.                 ; GFNAME
  652.     ENDM
  653.  
  654.  
  655. HEXHL    MACRO
  656. ;
  657. ; Inline macro to convert ASCII characters in the console 
  658. ; buffer of READB into a 16-bit binary number in HL.
  659. ; Carry flag is set if invalid hex character found.
  660. ;
  661. ; e.g.    READB
  662. ;    HEXHL
  663. ;
  664.     LOCAL    #AROUND
  665.     CALL    RDHL2?
  666. ;
  667.     IF    .NOT.HXFLAG
  668.     JP    #AROUND
  669. RDHL2?:
  670.     LD    HL,0        ; clear HL
  671. RDHL3?:
  672.     CALL    GETCH?
  673.     CCF            ; check for last character
  674.     RET    NC
  675.     UCASE
  676.     CALL    RDHL4?        ; convert to binary
  677.     RET    C        ; error of input
  678.     ADD    HL,HL        ; multiply previous digit by 16
  679.     ADD    HL,HL
  680.     ADD    HL,HL
  681.     ADD    HL,HL
  682.     OR    L        ; combine new
  683.     LD    L,A        ; put back into L
  684.     JR    RDHL3?        ; next
  685. RDHL4?:
  686.     SUB    30H        ; ASCII bias
  687.     RET    C        ; < 0
  688.     CP    17H
  689.     CCF
  690.     RET    C        ; > F
  691.     CP    10
  692.     CCF
  693.     RET    NC        ; 0-9
  694.     SUB    7
  695.     CP    10        ; A-F or error
  696.     RET
  697. ;
  698. HXFLAG    DEFL    TRUE
  699. #AROUND:
  700.     ENDIF
  701.                 ; HEXHL
  702.     ENDM
  703.  
  704.  
  705. HLDEC    MACRO
  706. ;
  707. ; Inline macro to print HL as a decimal string.
  708. ;
  709.     LOCAL    #AROUND
  710.     CALL    HLDC2?
  711. ;
  712.     IF    .NOT.HLFLAG
  713.     JP    #AROUND
  714. HLDC2?:
  715.     PUSH    HL
  716.     PUSH    DE
  717.     PUSH    BC
  718.     LD    B,0        ; leading-zero flag
  719.     LD    DE,-10000    ; two's complement
  720.     CALL    HLDC3?        ; ten thousands
  721.     LD    DE,-1000
  722.     CALL    HLDC3?        ; thousands
  723.     LD    DE,-100
  724.     CALL    HLDC3?        ; hundreds
  725.     LD    DE,-10
  726.     CALL    HLDC3?        ; tens
  727.     LD    A,L
  728.     ADD    A,'0'        ; make ASCII
  729.     PCHAR
  730.     POP    BC
  731.     POP    DE
  732.     POP    HL
  733.     RET
  734. HLDC3?:
  735.     LD    C,'0'-1
  736. HLDC4?:
  737.     INC    C
  738.     ADD    HL,DE        ; add neg until result negative
  739.     JP    C,HLDC4?
  740. ;
  741.     OR    A
  742.     SBC    HL,DE        ; get back last value
  743.     LD    A,C        ; decimal ASCII digit
  744.     CP    '1'
  745.     JP    NC,HLDC5?
  746.     LD    A,B        ; check zero flag
  747.     OR    A
  748.     LD    A,C
  749.     RET    Z        ; don't print if leading zero
  750. ;
  751.     PCHAR            ; print a non-leading zero
  752.     RET
  753. HLDC5?:
  754.     LD    B,0FFH        ; print all zeros from now on
  755.     PCHAR            ; first non-zero digit
  756.     RET
  757. ;
  758. HLFLAG    DEFL    TRUE
  759. #AROUND:
  760.     ENDIF
  761.                 ;HLDEC
  762.     ENDM
  763.  
  764.  
  765. LCHAR    MACRO
  766. ;
  767. ; Inline macro to send char in A to printer.
  768. ;
  769. ; e.g.    LD    A,CR
  770. ;    LCHAR
  771. ;
  772.     LOCAL    #AROUND
  773.     CALL    LOCH2?
  774. ;
  775.     IF    .NOT.LOFLAG
  776.     JP    #AROUND
  777. LOCH2?:
  778.     SYSF    5,1        ; List Output
  779. LOFLAG    DEFL    TRUE
  780. #AROUND:
  781.     ENDIF
  782.                 ; LCHAR
  783.     ENDM
  784.  
  785.  
  786. MAKE    MACRO    #FCB,#ERRJMP
  787. ;
  788. ; Inline macro to create a new disk file
  789. ; using FCB at address #FCB.
  790. ; Jumps to #ERRJMP if disk directory is full.
  791. ;
  792. ; e.g.    MAKE    FCB1,FULDIR
  793. ;
  794.     LOCAL    #AROUND
  795.     LD    DE,#FCB
  796.     XOR    A        ; zero
  797.     LD    (#FCB+12),A    ; ex
  798.     LD    (#FCB+32),A    ; cr
  799.     CALL    MAKE2?
  800.     INC    A        ; A returns 0FFH if no directory space left
  801.     JP    Z,#ERRJMP
  802. ;
  803.     IF    .NOT.MKFLAG
  804.     JP    #AROUND
  805. MAKE2?:
  806.     SYSF    22,0        ; Make File
  807. MKFLAG    DEFL    TRUE
  808. #AROUND:
  809.     ENDIF
  810.                 ; MAKE
  811.     ENDM
  812.  
  813.  
  814. MOVBLK    MACRO    #FROM,#TO,#SIZE
  815. ;
  816. ; Inline macro to move a block of length #SIZE bytes
  817. ; from address #FROM to address #TO.
  818. ;
  819. ; e.g.    MOVBLK    FCB1,4000H,0FH
  820. ;
  821.     PUSH    HL
  822.     PUSH    DE
  823.     PUSH    BC
  824.     LD    HL,#FROM
  825.     LD    DE,#TO
  826.     LD    BC,#SIZE
  827.     LDIR
  828.     POP    BC
  829.     POP    DE
  830.     POP    HL
  831.                 ; MOVBLK
  832.     ENDM
  833.  
  834.  
  835. MOVDAT    MACRO    #TO,#SIZE
  836. ;
  837. ; Inline macro to move immediately following data
  838. ; of length #SIZE bytes to address #TO.
  839. ;
  840. ; e.g.    MOVDAT    NEWBUF,7
  841. ;     DB    30H,CR,LF,'TEST'
  842. ;
  843.     LOCAL    #DATA
  844.     PUSH    HL
  845.     PUSH    DE
  846.     PUSH    BC
  847.     LD    BC,#SIZE
  848.     LD    DE,#TO
  849.     LD    HL,#DATA
  850.     LDIR
  851.     POP    BC
  852.     POP    DE
  853.     POP    HL
  854.     JP    #DATA+#SIZE
  855. #DATA:
  856.                 ; MOVDAT - DB here
  857.     ENDM
  858.  
  859.  
  860. MULT    MACRO    #TWOS
  861. ;
  862. ; Inline macro to multiply HL by #TWOS.
  863. ; #TWOS must be 0, 1, or a power of 2.
  864. ; If #TWOS is 0, A is presumed loaded with multiplier.
  865. ;
  866. ; e.g.    MULT    8
  867. ;
  868.     LOCAL    #AROUND
  869.     PUSH    BC
  870. ;
  871.     IF    #TWOS
  872.     LD    B,#TWOS
  873.     ELSE
  874.     LD    B,A
  875.     ENDIF
  876. ;
  877.     CALL    MULT2?
  878.     POP    BC
  879. ;
  880.     IF    .NOT.MLFLAG
  881.     JP    #AROUND
  882. MULT2?:
  883.     LD    A,B
  884.     OR    A        ; times 0
  885.     JR    NZ,MULT3?
  886.     LD    L,A
  887.     LD    H,A
  888.     RET
  889. MULT3?:
  890.     RRA
  891.     RET    C        ; times 1
  892.     LD    B,A
  893. MULT4?:
  894.     ADD    HL,HL        ; shift left
  895.     LD    A,B
  896.     RRA
  897.     LD    B,A
  898.     JR    NC,MULT4?
  899.     RET
  900. ;
  901. MLFLAG    DEFL    TRUE
  902. #AROUND:
  903.     ENDIF
  904.                 ; MULT
  905.     ENDM
  906.  
  907.  
  908. OPEN    MACRO    #FCB,#ERRJMP
  909. ;
  910. ; Inline macro to open an existing disk file
  911. ; using the FCB at address #FCB.
  912. ; Jumps to #ERRJMP if no file is found.
  913. ;
  914. ; e.g.    OPEN    FCB1,NOFILE
  915. ;
  916.     LOCAL    #AROUND
  917.     LD    DE,#FCB
  918.     XOR    A        ; zero accumulator
  919.     LD    (#FCB+12),A    ; extent
  920.     LD    (#FCB+32),A    ; current record
  921.     CALL    OPEN2?
  922.     INC    A        ; A returns 0FFH if no file
  923.     JP    Z,#ERRJMP
  924. ;
  925.     IF    .NOT.OPFLAG
  926.     JP    #AROUND
  927. OPEN2?:
  928.     SYSF    15,0        ; Open File
  929. OPFLAG    DEFL    TRUE
  930. #AROUND:
  931.     ENDIF
  932.                 ; OPEN
  933.     ENDM
  934.  
  935.  
  936. OUTBIN    MACRO
  937. ;
  938. ; Inline macro to print A as a binary string.
  939. ;
  940.     LOCAL    #AROUND
  941.     CALL    BINB2?
  942. ;
  943.     IF    .NOT.BNFLAG
  944.     JP    #AROUND
  945. BINB2?:
  946.     PUSH    BC
  947.     LD    C,A
  948.     LD    B,8
  949. BINB3?:
  950.     LD    A,C
  951.     ADD    A,A        ; left shift into carry
  952.     LD    C,A
  953.     LD    A,'0'/2
  954.     ADC    A,A        ; yields ASCII '0' or '1'
  955.     PCHAR
  956.     DEC    B
  957.     JP    NZ,BINB3?
  958.     POP    BC
  959.     RET
  960. ;
  961. BNFLAG    DEFL    TRUE
  962. #AROUND:
  963.     ENDIF
  964.                 ; OUTBIN
  965.     ENDM
  966.  
  967.  
  968. OUTHEX    MACRO    #REG
  969. ;
  970. ; Inline macro to convert binary number in register #REG
  971. ; to two hex ASCII characters, and print them.
  972. ; Original number is left in A.
  973. ;
  974. ; e.g.    OUTHEX    A
  975. ;
  976.     LOCAL    #AROUND
  977.     LD    A,#REG
  978.     CALL    OTHX2?
  979. ;
  980.     IF    .NOT.CXFLAG
  981.     JP    #AROUND
  982. OTHX2?:
  983.     PUSH    BC
  984.     LD    C,A        ; save number in C
  985.     RRA            ; shift high nybble to low
  986.     RRA
  987.     RRA
  988.     RRA
  989.     CALL    OTHX3?        ; high byte
  990.     LD    A,C        ; retrieve number
  991.     CALL    OTHX3?        ; low byte
  992.     LD    A,C        ; retrieve again
  993.     POP    BC
  994.     RET
  995. OTHX3?:
  996.     AND    0FH        ; zero upper nybble
  997.     ADD    A,90H        ; ASCII conversion
  998.     DAA
  999.     ADC    A,40H
  1000.     DAA
  1001.     PCHAR            ; send it
  1002.     RET
  1003. ;
  1004. CXFLAG    DEFL    TRUE
  1005. #AROUND:
  1006.     ENDIF
  1007.                 ; OUTHEX
  1008.     ENDM
  1009.  
  1010.  
  1011. OUTHL    MACRO
  1012. ;
  1013. ; Inline macro to print HL as a hexadecimal string.
  1014. ;
  1015.     LOCAL    #OVER
  1016.     LD    A,H
  1017.     OR    A        ; is H zero?
  1018.     JP    Z,#OVER
  1019.     OUTHEX    H
  1020. #OVER:
  1021.     OUTHEX    L
  1022.                 ; OUTHL
  1023.     ENDM
  1024.  
  1025.  
  1026. PCHAR    MACRO
  1027. ;
  1028. ; Inline macro to send char in A to console.
  1029. ;
  1030. ; e.g.    LD    A,(HL)
  1031. ;    PCHAR
  1032. ;
  1033.     LOCAL    #AROUND
  1034.     CALL    PCHR2?
  1035. ;
  1036.     IF    .NOT.COFLAG
  1037.     JP    #AROUND
  1038. PCHR2?:    
  1039.     SYSF    2,1        ; Console Output
  1040. COFLAG    DEFL    TRUE
  1041. #AROUND:
  1042.     ENDIF
  1043.                 ; PCHAR
  1044.     ENDM
  1045.  
  1046.  
  1047. PFNAME    MACRO    #FCB
  1048. ;
  1049. ; Inline macro to print file name in FCB at address #FCB.
  1050. ;
  1051. ; e.g.    PFNAME    FCB1
  1052. ;
  1053.     LOCAL    #AROUND
  1054.     PUSH    HL
  1055.     PUSH    BC
  1056.     LD    B,8        ; length of primary name
  1057.     LD    HL,#FCB+1
  1058.     CALL    PFNA2?
  1059.     POP    BC
  1060.     POP    HL
  1061.     PRINTB    #FCB+9,3    ; the file type
  1062. ;
  1063.     IF    .NOT.PFFLAG
  1064.     JP    #AROUND
  1065. PFNA2?:
  1066.     LD    A,(HL)        ; get char
  1067.     CP    BLANK
  1068.     JP    Z,PFNA3?
  1069.     RES    7,A        ; make printable if 8th bit options used
  1070.     PCHAR
  1071.     INC    HL
  1072.     DEC    B
  1073.     JP    NZ,PFNA2?
  1074. PFNA3?:
  1075.     LD    A,'.'
  1076.     PCHAR
  1077.     RET
  1078. ;
  1079. PFFLAG    DEFL    TRUE
  1080. #AROUND:
  1081.     ENDIF
  1082.                 ; PFNAME
  1083.     ENDM
  1084.  
  1085.  
  1086. PRINT    MACRO    #TEXT
  1087. ;
  1088. ; Inline macro to print a string literal to the console.
  1089. ;
  1090. ; e.g.    PRINT    'Message '
  1091. ;
  1092.     LOCAL    #AROUND,#MESG
  1093.     PUSH    HL
  1094.     PUSH    BC
  1095.     LD    C,#AROUND-#MESG
  1096.     LD    HL,#MESG
  1097.     CALL    PBUF2?
  1098.     POP    BC
  1099.     POP    HL
  1100.     JP    #AROUND
  1101. ;
  1102.     IF    .NOT.PRFLAG
  1103. PBUF2?:
  1104.     LD    A,(HL)
  1105.     PCHAR
  1106.     INC    HL
  1107.     DEC    C
  1108.     JP    NZ,PBUF2?
  1109.     RET
  1110. ;
  1111. PRFLAG    DEFL    TRUE
  1112.     ENDIF
  1113. ;
  1114. #MESG:    DB    '#TEXT'
  1115. #AROUND:
  1116.                 ; PRINT
  1117.     ENDM
  1118.  
  1119.  
  1120. PRINTB    MACRO    #ADDR,#SIZE
  1121. ;
  1122. ; Inline macro to print a string at address #ADDR
  1123. ; of length #SIZE bytes, 256 max.
  1124. ;
  1125. ; e.g.    PRINTB    FCB1+1,11
  1126. ;
  1127.     LOCAL    #AROUND
  1128.     PUSH    HL
  1129.     PUSH    BC
  1130.     LD    C,#SIZE
  1131.     LD    HL,#ADDR
  1132.     CALL    PBUF2?
  1133.     POP    BC
  1134.     POP    HL
  1135. ;
  1136.     IF    .NOT.PRFLAG
  1137.     JP    #AROUND
  1138. PBUF2?:
  1139.     LD    A,(HL)
  1140.     PCHAR
  1141.     INC    HL
  1142.     DEC    C
  1143.     JP    NZ,PBUF2?
  1144.     RET
  1145. ;
  1146. PRFLAG    DEFL    TRUE
  1147. #AROUND:
  1148.     ENDIF
  1149.                 ; PRINTB
  1150.     ENDM
  1151.  
  1152.  
  1153. PROTEC    MACRO    #FCB
  1154. ;
  1155. ; Inline macro to set file attribute to R/O,
  1156. ; using FCB at address #FCB.
  1157. ;
  1158. ; e.g.    PROTEC    FCB1
  1159. ;
  1160.     LOCAL    #AROUND
  1161.     LD    DE,#FCB
  1162.     LD    A,(#FCB+9)    ; get t1' bit
  1163.     SET    7,A        ; set for R/O
  1164.     LD    (#FCB+9),A    ; put it back
  1165.     CALL    PROT2?
  1166. ;
  1167.     IF    .NOT.PTFLAG
  1168.     JP    #AROUND
  1169. PROT2?:
  1170.     SYSF    30,0        ; Set File Attributes
  1171. PTFLAG    DEFL    TRUE
  1172. #AROUND:
  1173.     ENDIF
  1174.                 ; PROTEC
  1175.     ENDM
  1176.  
  1177.  
  1178. READB    MACRO
  1179. ;
  1180. ; Inline macro to read a line from the console into a buffer.
  1181. ; Buffer size is set by BUFSIZ.
  1182. ; GETCH? subroutine retrieves characters from the buffer.
  1183. ;
  1184. ; e.g.    READB
  1185. ;
  1186.     LOCAL    #AROUND
  1187.     CALL    RDBF2?
  1188. ;
  1189.     IF    .NOT.RBFLAG
  1190.     JP    #AROUND
  1191. RDBF2?:
  1192.     PUSH    HL
  1193.     PUSH    DE
  1194.     PUSH    BC
  1195.     LD    DE,?MBUFF    ; address of max length
  1196.     LD    C,10        ; BDOS function 10
  1197.     CALL    BDOS
  1198.     LD    HL,?RBUFF    ; start of buffer
  1199.     LD    (?BUFFP),HL    ; initialize buffer pointer
  1200.     POP    BC
  1201.     POP    DE
  1202.     POP    HL
  1203.     RET
  1204. GETCH?:
  1205.     LD    A,(?CBUFF)    ; get character count
  1206.     SUB    1        ; decrement with carry
  1207.     RET    C        ; no more characters
  1208.     LD    (?CBUFF),A    ; update the count
  1209.     PUSH    HL
  1210.     LD    HL,(?BUFFP)    ; get buffer pointer
  1211.     LD    A,(HL)        ; get the character
  1212.     INC    HL        ; increment pointer
  1213.     LD    (?BUFFP),HL    ; update the pointer
  1214.     POP    HL
  1215.     RET
  1216. ;
  1217. RBFLAG    DEFL    TRUE
  1218. ;
  1219. ?BUFFP:    DW    ?RBUFF        ; buffer pointer is here
  1220. ?MBUFF:    DB    BUFSIZ        ; max buffer length
  1221. ?CBUFF:    DS    1        ; character count placed here by BDOS call
  1222. ?RBUFF:    DS    BUFSIZ        ; buffer is here
  1223. ;
  1224. #AROUND:
  1225.     ENDIF
  1226.                 ; READB
  1227.     ENDM
  1228.  
  1229.     
  1230. READS    MACRO    #FCB,#ERRJMP
  1231. ;
  1232. ; Inline macro to read a disk sector into the DMA buffer,
  1233. ; using FCB at address #FCB.
  1234. ; Jumps to address #ERRJMP if EOF is read.
  1235. ;
  1236. ; e.g.    READS    FCB1,EOFILE
  1237. ;
  1238.     LOCAL    #AROUND
  1239.     LD    DE,#FCB
  1240.     CALL    READ2?
  1241.     OR    A        ; set flags
  1242.     JP    NZ,#ERRJMP    ; EOF read
  1243. ;
  1244.     IF    .NOT.RSFLAG
  1245.     JP    #AROUND
  1246. READ2?:
  1247.     SYSF    20,0        ; Read Sequential
  1248. RSFLAG    DEFL    TRUE
  1249. #AROUND:
  1250.     ENDIF
  1251.                 ; READS
  1252.     ENDM
  1253.  
  1254.  
  1255. RENAME    MACRO    #FCB
  1256. ;
  1257. ; Inline macro to rename an existing disk file.
  1258. ; #FCB is FCB address holding original name.
  1259. ; New name must exist at #FCB + 10H.
  1260. ;
  1261. ; e.g.    RENAME    FCB1
  1262. ;
  1263.     LOCAL    #AROUND
  1264.     UNPROT    #FCB        ; make it R/W
  1265.     CALL    RENA2?
  1266.     CRLF
  1267.     PFNAME    #FCB
  1268.     PRINT    ' renamed to '
  1269.     PFNAME    #FCB+10H
  1270. ;
  1271.     IF    .NOT.RNFLAG
  1272.     JP    #AROUND
  1273. RENA2?:
  1274.     SYSF    23,0        ; Rename File
  1275. RNFLAG    DEFL    TRUE
  1276. #AROUND:
  1277.     ENDIF
  1278.                 ; RENAME
  1279.     ENDM
  1280.  
  1281.  
  1282. SCAN    MACRO    #CHAR,#JMP
  1283. ;
  1284. ; Inline macro which generates a jump to #JMP if
  1285. ; the console key #CHAR has been pressed.
  1286. ;
  1287. ; e.g.    SCAN    3,BOOT        ; Warm boot if ^C pressed
  1288. ;
  1289.     LOCAL    #OVER
  1290.     PUSH    HL
  1291.     PUSH    DE
  1292.     PUSH    BC
  1293.     LD    C,11        ; Get Console Status
  1294.     CALL    BDOS
  1295.     POP    BC
  1296.     POP    DE
  1297.     POP    HL
  1298.     RRCA            ; 0FFH returned if char ready
  1299.     JP    NC,#OVER    ; no char
  1300.     GCHAR
  1301.     CP    #CHAR
  1302.     JP    Z,#JMP
  1303. #OVER:
  1304.                 ; SCAN
  1305.     ENDM
  1306.  
  1307.  
  1308. SETDMA    MACRO
  1309. ;
  1310. ; Inline macro to set the DMA address.
  1311. ; DE must be loaded with the DMA address prior to SETDMA.
  1312. ;
  1313. ; e.g.    SETDMA    BUFFP
  1314. ;
  1315.     LOCAL    #AROUND
  1316.     CALL    SDMA2?
  1317. ;
  1318.     IF    .NOT.DMFLAG
  1319.     JP    #AROUND
  1320. SDMA2?:
  1321.     SYSF    26,0        ; Set DMA Address
  1322. DMFLAG    DEFL    TRUE
  1323. #AROUND:
  1324.     ENDIF
  1325.                 ; SETDMA
  1326.     ENDM
  1327.  
  1328.  
  1329. SYSF    MACRO    #FUNC,#AE
  1330. ;
  1331. ; Macro to generate BDOS call #FUNC.
  1332. ; NOT AN INLINE MACRO: needs branch around instructions.
  1333. ; Referenced only by other macros in Z80MACRO.LIB
  1334. ; If BDOS function is 2,5,8,or 14, then #AE=1; otherwise #AE = 0.
  1335. ;
  1336. ; e.g.    SYSF    9,0        ; Print String
  1337. ;    SYSF    2,1        ; Console Output
  1338. ;
  1339.     PUSH    HL
  1340.     PUSH    DE
  1341.     PUSH    BC
  1342.     LD    C,#FUNC
  1343. ;
  1344.     IF    #AE
  1345.     LD    E,A
  1346.     PUSH    AF
  1347.     CALL    BDOS
  1348.     POP    AF
  1349.     ELSE
  1350.     CALL    BDOS
  1351.     ENDIF
  1352. ;
  1353.     POP    BC
  1354.     POP    DE
  1355.     POP    HL
  1356.     RET
  1357.                 ; SYSF
  1358.     ENDM
  1359.  
  1360.  
  1361. UCASE    MACRO
  1362. ;
  1363. ; Inline macro to convert ASCII char in A to uppercase.
  1364. ; Will not alter values other than ASCII lower case.
  1365. ;
  1366. ; e.g.    UCASE
  1367. ;
  1368.     LOCAL    #SKIP
  1369.     CP    61H
  1370.     JP    C,#SKIP
  1371.     CP    7BH
  1372.     JP    NC,#SKIP
  1373.     AND    5FH        ; make uppercase
  1374. #SKIP:
  1375.                 ; UCASE
  1376.     ENDM
  1377.  
  1378.  
  1379. UNPROT    MACRO    #FCB
  1380. ;
  1381. ; Inline macro to convert R/O file to R/W
  1382. ; using FCB at address #FCB.
  1383. ;
  1384. ; e.g.    UNPROT    FCB1
  1385. ;
  1386.     LOCAL    #AROUND
  1387.     LD    DE,#FCB
  1388.     LD    A,(#FCB+9)    ; get t1' bit
  1389.     RES    7,A        ; reset for R/W
  1390.     LD    (#FCB+9),A    ; put it back
  1391.     CALL    PROT2?
  1392. ;
  1393.     IF    .NOT.PTFLAG    ; PROT2? shared with PROTEC macro
  1394.     JP    #AROUND
  1395. PROT2?:
  1396.     SYSF    30,0        ; Set File Attributes
  1397. PTFLAG    DEFL    TRUE
  1398. #AROUND:
  1399.     ENDIF
  1400.                 ; UNPROT
  1401.     ENDM
  1402.  
  1403.  
  1404. UPPER    MACRO
  1405. ;
  1406. ; Inline macro to isolate upper digit of packed BCD in A
  1407. ; and shift it to lower place.
  1408. ;
  1409. ; e.g.    UPPER
  1410. ;
  1411.     RRA
  1412.     RRA
  1413.     RRA
  1414.     RRA
  1415.     AND    0FH        ; zero upper nybble
  1416.                 ; UPPER
  1417.     ENDM
  1418.  
  1419.  
  1420. VERSN    MACRO    #TEXT
  1421. ;
  1422. ; Inline macro to embed the version number.
  1423. ;
  1424. ; e.g.    VERSN    'dd.mm.yy.NAME'
  1425. ;
  1426.     LOCAL    #AROUND
  1427.     JP    #AROUND
  1428.     DB    'Ver ','#TEXT'
  1429. #AROUND:
  1430.                 ; VERSN
  1431.     ENDM
  1432.  
  1433.  
  1434. WRITES    MACRO    #FCB,#ERRJMP
  1435. ;
  1436. ; Inline macro to write a sector to disk,
  1437. ; using the FCB address at #FCB.
  1438. ; Jumps to #ERRJMP if disk is full.
  1439. ;
  1440. ; e.g.    WRITES    FCB1,FULL
  1441. ;
  1442.     LOCAL    #AROUND
  1443.     LD    DE,#FCB
  1444.     CALL    WRIT2?
  1445.     OR    A        ; A is 0 if successful
  1446.     JP    NZ,#ERRJMP    ; disk is full
  1447. ;
  1448.     IF    .NOT.WSFLAG
  1449.     JP    #AROUND
  1450. WRIT2?:
  1451.     SYSF    21,0        ; Write Sequential
  1452. WSFLAG    DEFL    TRUE
  1453. #AROUND:
  1454.     ENDIF
  1455.                 ; WRITES
  1456.     ENDM
  1457.  
  1458.  
  1459.