home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / znode3 / uploads / sfxio.z80 < prev    next >
Encoding:
Text File  |  1994-09-02  |  14.3 KB  |  602 lines

  1.     TITLE    SYSLIB - Byte-Oriented I/O w User-Supplied Buffers, Append
  2. ;
  3. ; SYSLIB Module Name:  SFXIO
  4. ; Author:  Richard Conn
  5. ; SYSLIB Version Number:  3.6
  6. ; Module Version Number:  1.3
  7.  
  8.     public    fxi$open,fx$get,fxi$close
  9.     public    fxo$open,fx$put,fxo$close
  10.     public    fxa$open
  11.  
  12. ;  Date:     10 Nov 86
  13. ;  Revised: Michael Bate
  14. ;  Changes:    - Added new entry point FXA$OPEN to open a file for
  15. ;          appending.  Called same as FXO$OPEN, except that
  16. ;          If the file already exists, text will be appended
  17. ;          to the text that is in it already.
  18. ;
  19. ;  Date:     28 Apr 85
  20. ;  Revised: Al Dunsmuir
  21. ;  Changes:    - FX$GET and FX$PUT routines optimized for speed
  22. ;          (PUTADR/GETADR not used if disk I/O not required)
  23. ;        - Use direct DMA vs DMA to TBUFF and software move.
  24. ;          Makes byte I/O a bit faster AND safer.
  25. ;        - Some misc. code optimization also performed.
  26. ;            
  27. ;   Previous Version:    1.0 (16 Jan 84)
  28.  
  29. ;
  30. ;    SFXIO provides a group of routines which can perform byte-oriented
  31. ; file I/O with a user-defined buffer size.  All of these routines work with
  32. ; an I/O Control Block which is structured as follows:
  33. ;
  34. ;        Byte    Length (Bytes)    Function
  35. ;          0         1    Number of 128-byte pages in
  36. ;                        working buffer (set by user)
  37. ;          1         1    End of File Flag (set and used
  38. ;                        by SFXIO)
  39. ;          2         2    Byte Counter (set and used by SFXIO)
  40. ;          4         2    Next Byte Pointer (set and used by
  41. ;                        SFXIO)
  42. ;          6         2    Address of Working Buffer (set by user)
  43. ;          8        36    FCB of File (FN and FT Fields set by
  44. ;                        user, rest set by SFXIO)
  45. ;
  46. ;    The following DB/DS structure can be used in the calling program
  47. ; to implement the I/O Control Block:
  48. ;
  49. ;    IOCTL:    DB    8    ; Use 8 128-byte pages (1K)
  50. ;        DS    1    ; Filled by SFXIO
  51. ;        DS    2    ; Filled by SFXIO
  52. ;        DS    2    ; Filled by SFXIO
  53. ;        DW    WORKBF    ; Address of Working Buffer
  54. ;
  55. ;    IOCFCB:    DB    0    ; Current Disk (Inited by SFXIO)
  56. ;        DB    'MYFILE  '    ; File Name
  57. ;        DB    'TXT'        ; File Type
  58. ;        DS    24    ; Fill Out 36 Bytes
  59. ;
  60. ;    WORKBF:    DS    1024    ; Working Buffer
  61. ;
  62. ;    All uses of the routines contain the address of IOCTL in DE.
  63. ; Note that if you use a buffer for input, DO NOT use it for output also!
  64. ;
  65.  
  66. ;
  67. ;  External SYSLIB References
  68. ;
  69.     EXT    F$OPEN        ;Open File
  70.     EXT    F$MOPEN        ;Open/Create file
  71.     EXT    INITFCB        ;Init FCB
  72.     EXT    F$CLOSE        ;Close file
  73.     EXT    SHFTRH        ;Shift HL right one bit.
  74.     EXT    SHFTLH        ;Shift HL left one bit.
  75.     EXT    f$exist        ;File existence test
  76.     EXT    f$appl        ;Append to a file
  77.  
  78. ;  CP/M Equates and ASCII Constants
  79. ;
  80. TBUFF    EQU    80H        ;Temporary File I/O buffer
  81. CTRLZ    EQU    'Z'-'@'        ;^Z
  82.  
  83. BDOS    EQU    5        ;BDOS entry point
  84. B$CL    EQU    16        ; Close file
  85. B$RD    EQU    20        ; Read next record
  86. B$WR    EQU    21        ; Write next record
  87. B$DMA    EQU    26        ; Set DMA address
  88.  
  89.  
  90. ; **** Macro Routines for FXIO ****
  91. ;
  92. PUTRG    MACRO            ;Save BC, DE, HL
  93.     PUSH    BC
  94.     PUSH    DE
  95.     PUSH    HL
  96.     ENDM
  97.  
  98. GETRG    MACRO            ;Restore BC, DE, HL
  99.     POP    HL
  100.     POP    DE
  101.     POP    BC
  102.     ENDM
  103.  
  104.  
  105. ; **** Support Routines for FXIO ****
  106. ;
  107. ;
  108. ;  FXIO0 - Routine to read next buffer-full from disk
  109. ;
  110. FXIO0:    LD    A,(EOF)        ;Check for EOF
  111.     OR    A        ;Abort if already at EOF
  112.     RET    NZ        ;NZ is error code
  113. ;
  114.     LD    HL,(BUFADR)    ;Get address of input buffer
  115.     LD    A,(BCNT)    ;Get block count
  116.     LD    B,A        ;... in B 
  117.  
  118. FXIO1:    PUSH    BC        ;Save remaining block count.    
  119.     PUSH    HL        ;Save current Input buffer ptr
  120.     EX    DE,HL        ;Get buffer addr in DE
  121.     LD    C,B$DMA        ;Point BDOS DMA ptr to input buffer
  122.     CALL    BDOS
  123. ;
  124.     LD    HL,(FCB)    ;Get FCB address
  125.     EX    DE,HL        ;... IN DE
  126.     LD    C,B$RD        ;Read block via BDOS
  127.     CALL    BDOS
  128.     POP    HL        ;Restore input buffer ptr
  129.     POP    BC        ;Restore remaining block count
  130.     OR    A        ;Check Read return code.
  131.     JR    NZ,FXIO2    ;Br if End-of-File
  132. ;
  133.     LD    DE,128        ;Get block length
  134.     ADD    HL,DE        ;Update buffer addr to point to next block
  135. ;
  136.     djnz    FXIO1        ;Loop until all blocks written.
  137.     JR    FXIO3        ;Done.
  138.  
  139. FXIO2:    LD    A,0FFH        ;Set "EOF" condition
  140.     LD    (EOF),A        ;Set EOF flag
  141. ;
  142. FXIO3:    LD    HL,(BUFADR)    ;Pt to first byte in buffer
  143.     LD    (BYTENXT),HL    ; as "next byte" address
  144. ;
  145.     LD    A,(BCNT)    ;Get block count
  146.     SUB    B        ;Adjust by # empty blocks
  147.     LD    H,A        ;Convert to bytes
  148.     LD    L,0
  149.     CALL    SHFTRH        
  150.     LD    (BYTECNT),HL    ;Set byte count
  151. ;
  152.     PUSH    HL        ;Save byte count
  153.     LD    DE,TBUFF    ;Reset DMA address (for compatability)
  154.     LD    C,B$DMA
  155.     CALL    BDOS
  156.     POP    HL        ;Get byte count
  157. ;
  158.     LD    A,H        ;Set EOF return code based on byte count
  159.     OR    L
  160.     JR    Z,FXIO4
  161.     XOR    A        ;Set no error (data available)
  162.     RET
  163. FXIO4:
  164.     OR    0FFH        ;Set error (no data available)
  165.     RET
  166.  
  167. ;
  168. ;  FXOO0 - Routine to flush buffer to disk and set up for next write
  169. ;
  170. FXOO0:    LD    HL,(BYTECNT)    ;Get # of bytes yet to go
  171.     CALL    SHFTLH        ;Convert to blocks
  172.     LD    A,(BCNT)    ;Get # of blocks in buffer
  173.     SUB    H        ;Compute number to write
  174.     LD    B,A        ;Get final block count in B
  175.     LD    HL,(BUFADR)    ;Pt to first byte to write
  176. ;
  177. FXOO1:    LD    A,B        ;Check if write complete
  178.     OR    A        ;0=Done
  179.     JR    Z,FXOO2
  180. ;
  181.     DEC    B        ;Decrement block counter
  182.     PUSH    BC        ;Save remaining block count
  183.     PUSH    HL        ;Save current Output buffer ptr
  184.     EX    DE,HL        ;Get buffer addr in DE
  185.     LD    C,B$DMA        ;Point BDOS DMA ptr to output buffer
  186.     CALL    BDOS
  187. ;
  188.     LD    HL,(FCB)    ;Get FCB address
  189.     EX    DE,HL        ;... IN DE
  190.     LD    C,B$WR        ;Write block via BDOS
  191.     CALL    BDOS
  192.     POP    HL        ;Restore output buffer ptr
  193.     POP    BC        ;Restore remaining block count
  194. ;
  195.     LD    DE,128        ;Get block length
  196.     ADD    HL,DE        ;Update buffer addr to point to next block
  197. ;
  198.     OR    A        ;Check Write return code.
  199.     JR    Z,FXOO1        ;If OK, Loop until all blocks have been written
  200. ;
  201.     OR    0FFH        ;Set error code
  202.     RET
  203.  
  204.  
  205. ;  FXOO2 - Routine to init buffers for next write
  206. ;
  207. FXOO2:    LD    HL,(BUFADR)    ;Pt to first byte in buffer
  208.     LD    (BYTENXT),HL    ; as "next byte" address
  209. ;
  210.     XOR    A        ;SET NO EOF
  211.     LD    (EOF),A
  212. ;
  213.     LD    A,(BCNT)    ;Get block count
  214.     LD    H,A        ;Convert to bytes
  215.     LD    L,0
  216.     CALL    SHFTRH        
  217.     LD    (BYTECNT),HL    ;Set byte count
  218. ;
  219.     LD    DE,TBUFF    ;Reset DMA address (for compatability)
  220.     LD    C,B$DMA
  221.     CALL    BDOS
  222. ;
  223.     XOR    A        ;No Error
  224.     RET
  225.  
  226.  
  227. ; **** Base Routines for FXIO ****
  228. ;
  229. ;
  230. ;  FXI$OPEN - Open file/buffers for Byte-Oriented Input (GET)
  231. ;    on input, DE pts to I/O Control Block
  232. ;    on output, A=0 and Zero flag set if error (File not found)
  233. ;
  234. FXI$OPEN:
  235.     PUTRG            ;Save registers
  236.     CALL    PUTADR        ;Copy I/O Control Block data
  237.     XOR    A        ;Set no EOF
  238.     LD    (EOF),A
  239.     LD    HL,(FCB)    ;Get FCB address
  240.     EX    DE,HL        ;... in DE 
  241.     CALL    INITFCB        ;Init FCB
  242.     CALL    F$OPEN        ;Attempt to open file
  243.     JR    NZ,ERRET    ;NZ = Error (File not found)
  244. ;
  245.     CALL    FXIO0        ;OK - Fill buffer with data
  246. ;
  247. ;   Normal return
  248. ;
  249. OKRET:    CALL    GETADR        ;Update I/O Control Block data
  250.     GETRG            ;Restore regs
  251.     OR    0FFH        ;Indicate success
  252.     RET
  253.  
  254. ;   Error return    
  255. ;
  256. ERRET:    GETRG            ;Restore regs
  257.     XOR    A        ;Indicate Error
  258.     RET
  259.  
  260.  
  261. ;  FXO$OPEN - Open file/buffers for Byte-Oriented Output (PUT)
  262. ;    on input, DE pts to I/O Control Block
  263. ;    on output, A=0 and Zero flag set if error (No Directory space)
  264. ;
  265. FXO$OPEN:
  266.     PUTRG            ;Save registers
  267.     CALL    PUTADR        ;Copy I/O Control Block data
  268.     CALL    FXOO2        ;Init buffers
  269.     LD    HL,(FCB)    ;Get FCB address
  270.     EX    DE,HL        ;... in DE 
  271.     CALL    INITFCB        ;Init FCB
  272.     CALL    F$MOPEN        ;Open and/or Create file
  273.     JR    NZ,ERRET    ;NZ = Error (No Directory Space)
  274.     JR    OKRET        ;OK- Return and update I/O Control Block
  275.  
  276.  
  277. ;  FXA$OPEN - Open file/buffers for Byte-Oriented Output (PUT) with Append
  278. ;    on input, DE pts to I/O Control Block
  279. ;    on output, A=0 and Zero flag set if error (No Directory space or
  280. ;                            File is full)
  281. ;
  282. FXA$OPEN:
  283.     PUTRG            ;Save registers
  284.     CALL    PUTADR        ;Copy I/O Control Block data
  285.     CALL    FXOO2        ;Init buffers
  286.     LD    HL,(FCB)    ;Get FCB address
  287.     EX    DE,HL        ;... in DE 
  288.     CALL    INITFCB        ;Init FCB
  289.     CALL    F$EXIST        ; See if file exists
  290.     JR    NZ,START
  291.     CALL    F$MOPEN        ; File does NOT exist -- create it
  292.     JR    NZ,ERRET    ; NZ = Error (No Directory Space)
  293.     JR    OKRET
  294. start:
  295.     CALL    F$APPL        ; Open file for append
  296.     JR    Z,START1
  297.     CP    3
  298.     JR    NZ,ERRET    ; Error - file full
  299.     JR    OKRET        ; take this jump if file is empty
  300. start1:
  301.     LD    DE,(BUFADR)    ; Scan buffer for Ctl-Z
  302.     LD    HL,TBUFF
  303.     PUSH    DE
  304.     LD    BC,080h
  305.     PUSH    BC
  306.     LDIR
  307.     POP    BC
  308.     POP    HL
  309.     LD    A,CTRLZ
  310.     CPIR
  311.     JR    NZ,START2    ; ctl-Z not found
  312.     DEC    HL        ; found ctl-Z in buffer
  313.     INC    BC
  314. start2:
  315.     LD    (BYTENXT),HL    ; Set place to store next byte
  316.     LD    A,(BCNT)    ; Get count of blocks minus 1
  317.     DEC    A
  318.     LD    H,A        ; Convert to bytes
  319.     LD    L,0
  320.     CALL    SHFTRH
  321.     ADD    HL,BC        ; Add # bytes from first sector
  322.     LD    (BYTECNT),HL    ; Store in # available bytes
  323.     JR    OKRET
  324. ;
  325. ;  FX$GET - Get next byte from buffer/file 
  326. ;    on input, DE pts to I/O Control Block
  327. ;    on output, A=Char and Zero flag set if past EOF
  328. ;
  329. FX$GET:
  330.     PUTRG            ;Save registers
  331. ;
  332. ; Check if data byte is in buffer. 
  333. ;
  334.     EX    DE,HL        ;HL -> I/O Control Block data
  335.     INC    HL        ;Get caller's BYTECNT in DE
  336.     INC    HL
  337.     LD    E,(HL)
  338.     INC    HL
  339.     LD    D,(HL)
  340.  
  341.     DEC    HL        ;Pt to caller's BYTECNT again.
  342.     LD    A,D        ;Is the data byte in the buffer?
  343.     OR    E
  344.     JR    Z,FXGET1    ;No - Fill buffer and GET byte.
  345. ;
  346. ; It is. GET it and update BYTECNT, BYTENXT as quickly as possible.
  347.     DEC    DE        ;Update byte count
  348.     LD    (HL),E        ;Update caller's BYTECNT.
  349.     INC    HL
  350.     LD    (HL),D
  351. ;
  352.     INC    HL        ;Get caller's BYTENXT.
  353.     LD    E,(HL)
  354.     INC    HL
  355.     LD    D,(HL)    
  356. ;
  357.     LD    A,(DE)        ;GET data byte from buffer
  358.     LD    (BYTE),A    ;Save for return.
  359. ;
  360.     INC    DE        ;Update caller's BYTENXT.
  361.     LD    (HL),D
  362.     DEC    HL
  363.     LD    (HL),E
  364. ;
  365.     GETRG            ;Restore regs
  366.     OR    0FFH        ;Indicate success
  367.     LD    A,(BYTE)    ;Get data byte
  368.     RET
  369. ;
  370. ; Data byte not in buffer - Fill buffer from file first
  371. ;
  372. FXGET1:    EX    DE,HL        ;DE -> I/O Control Block data.
  373.     DEC    DE
  374.     DEC    DE
  375.     CALL    PUTADR        ;Copy I/O Control Block data
  376.     CALL    FXIO0        ;Fill buffer from file
  377.     JP    NZ,ERRET    ;NZ = Error (End of File)
  378. ;
  379.     LD    HL,(BYTENXT)    ;Pt to first byte in buffer
  380.     LD    A,(HL)        ;GET from buffer
  381.     LD    (BYTE),A    ;Save it
  382.     INC    HL        ;Pt to next byte
  383.     LD    (BYTENXT),HL    ;Update next byte pointer
  384.     LD    HL,(BYTECNT)    ;One less byte in buffer
  385.     DEC    HL
  386.     LD    (BYTECNT),HL    ;Update byte count
  387. ;
  388. ;   Normal return
  389. ;
  390. OKRET1:    CALL    GETADR        ;Update I/O Control Block data
  391.     GETRG            ;Restore regs
  392.     OR    0FFH        ;Indicate success
  393.     LD    A,(BYTE)    ;Get data byte
  394.     RET
  395.  
  396.  
  397. ;  FX$PUT - Put next byte into buffer/file 
  398. ;    on input, A=char and DE pts to I/O Control Block
  399. ;    on output, A=Char and Zero flag set if write error
  400. ;
  401. FX$PUT:
  402.     PUTRG            ;Save registers
  403.     LD    (BYTE),A    ;Save byte to output 
  404. ;
  405. ; Check if data byte will fit in buffer. 
  406. ;
  407.     EX    DE,HL        ;HL -> I/O Control Block data
  408.     INC    HL        ;Get caller's BYTECNT in DE
  409.     INC    HL
  410.     LD    E,(HL)
  411.     INC    HL
  412.     LD    D,(HL)
  413.  
  414.     DEC    HL        ;Pt to caller's BYTECNT again.
  415.     LD    A,D        ;Will the data byte fit in the buffer?
  416.     OR    E
  417.     JR    Z,FXPUT1    ;No - Flush buffer to file and PUT byte.
  418. ;
  419. ; It is. PUT it and update BYTECNT, BYTENXT as quickly as possible.
  420.     DEC    DE        ;Update byte count
  421.     LD    (HL),E        ;Update caller's BYTECNT.
  422.     INC    HL
  423.     LD    (HL),D
  424. ;
  425.     INC    HL        ;Get caller's BYTENXT.
  426.     LD    E,(HL)
  427.     INC    HL
  428.     LD    D,(HL)    
  429. ;
  430.     LD    A,(BYTE)    ;Get data byte
  431.     LD    (DE),A        ;PUT data byte in buffer
  432. ;
  433.     INC    DE        ;Update caller's BYTENXT.
  434.     LD    (HL),D
  435.     DEC    HL
  436.     LD    (HL),E
  437. ;
  438.     GETRG            ;Restore regs
  439.     OR    0FFH        ;Indicate success
  440.     LD    A,(BYTE)    ;Get data byte
  441.     RET
  442. ;
  443. ; Data byte will not fit in buffer - Flush buffer to file first.
  444. ;
  445. FXPUT1:    EX    DE,HL        ;DE -> I/O Control Block data.
  446.     DEC    DE
  447.     DEC    DE
  448.     CALL    PUTADR        ;Copy I/O Control Block data
  449.     CALL    FXOO0        ;NO - Flush buffer to file
  450.     JP    NZ,ERRET    ;NZ = Error (Write error)
  451. ;
  452.     LD    HL,(BYTENXT)    ;Pt to first byte in buffer
  453.     LD    A,(BYTE)    ;Get next byte
  454.     LD    (HL),A        ;PUT in buffer
  455.     INC    HL        ;Pt to next byte
  456.     LD    (BYTENXT),HL    ;Update next byte pointer
  457.     LD    HL,(BYTECNT)    ;One less byte of free space in buffer
  458.     DEC    HL
  459.     LD    (BYTECNT),HL    ;Update byte count
  460.     JR    OKRET1        ;OK-return with byte and updated control block
  461.  
  462.  
  463. ;  FXI$CLOSE - Close file/buffers for Byte-Oriented Input (GET)
  464. ;    on input, DE pts to I/O Control Block
  465. ;    on output, A=0 and Zero flag set if error (Error in closing file)
  466. ;
  467. FXI$CLOSE:
  468.     PUTRG            ;Save registers
  469.     CALL    PUTADR        ;Copy I/O Control Block data
  470.     LD    HL,(FCB)    ;Get FCB address
  471.     EX    DE,HL        ;... in DE 
  472.     CALL    F$CLOSE        ;Close file
  473.     JP    NZ,ERRET    ;NZ = Error (Close file error)
  474.     JP    OKRET        ;OK- Return and update I/O Control Block
  475.  
  476.  
  477. ;  FXO$CLOSE - Close file/buffers for Byte-Oriented Output (PUT)
  478. ;    on input, DE pts to I/O Control Block
  479. ;    on output, A=0 and Zero flag set if error (Error in closing file)
  480. ;
  481. FXO$CLOSE:
  482.     PUTRG            ;Save registers
  483.     CALL    PUTADR        ;Copy I/O Control Block data
  484. ;
  485. ;  Fill last block with ^Z
  486. ;
  487. FXOCL1:    LD    HL,(BYTECNT)    ;Get free space count.
  488.     LD    A,L        ;If on page boundary, done
  489.     AND    7FH
  490.     JR    Z,FXOCL2
  491.     DEC    HL        ;One less byte of free space in buffer
  492.     LD    (BYTECNT),HL    ;Update byte count
  493.     LD    HL,(BYTENXT)    ;Pt to next byte
  494.     LD    (HL),CTRLZ    ;Store EOF char
  495.     INC    HL
  496.     LD    (BYTENXT),HL
  497.     JR    FXOCL1        ;Loop until last block is full
  498. ;
  499. ;  Close file and exit
  500. ;
  501. FXOCL2:    CALL    FXOO0        ;Flush buffers to disk
  502.     LD    HL,(FCB)    ;Get FCB address
  503.     EX    DE,HL        ;... in DE 
  504.     CALL    F$CLOSE        ;Close file
  505.     JP    NZ,ERRET    ;NZ = Error (Close file error)
  506.     JP    OKRET        ;OK- Return and update I/O Control Block
  507.  
  508.  
  509. ;  PUTADR - Copy I/O Control Block data to local storage
  510. ;
  511. PUTADR:    EX    DE,HL        ;Get I/O Control Block addr in HL
  512.     LD    (BUFFER),HL    ;Save I/O Control Block address
  513. ;
  514.     LD    A,(HL)        ;Get block count
  515.     LD    (BCNT),A
  516. ;
  517.     INC    HL
  518.     LD    A,(HL)        ;Get eof flag
  519.     LD    (EOF),A
  520. ;
  521.     INC    HL
  522.     LD    E,(HL)        ;Get low count
  523.     INC    HL
  524.     LD    D,(HL)
  525.     EX    DE,HL
  526.     LD    (BYTECNT),HL    ;Put byte count
  527. ;
  528.     EX    DE,HL
  529.     INC    HL
  530.     LD    E,(HL)        ;Get low address
  531.     INC    HL
  532.     LD    D,(HL)
  533.     EX    DE,HL
  534.     LD    (BYTENXT),HL    ;Put next byte ptr
  535. ;
  536.     EX    DE,HL
  537.     INC    HL
  538.     LD    E,(HL)        ;Get low address
  539.     INC    HL
  540.     LD    D,(HL)
  541.     EX    DE,HL
  542.     LD    (BUFADR),HL    ;Put buffer address ptr
  543. ;
  544.     EX    DE,HL
  545.     INC    HL
  546.     LD    (FCB),HL    ;Save address of FCB
  547.     RET
  548.  
  549.  
  550. ;  GETADR - Update I/O Control Block data from local storage
  551. ;
  552. GETADR:    LD    HL,(BUFFER)    ;Get I/O Control Block address
  553. ;
  554.     INC    HL        ;Skip block count
  555. ;
  556.     LD    A,(EOF)        ;Get EOF flag
  557.     LD    (HL),A
  558. ;
  559.     EX    DE,HL
  560.     LD    HL,(BYTECNT)    ;Get byte count
  561.     EX    DE,HL
  562.     INC    HL
  563.     LD    (HL),E        ;Set low count
  564.     INC    HL
  565.     LD    (HL),D
  566.     EX    DE,HL
  567. ;
  568.     LD    HL,(BYTENXT)    ;Get next byte pointer
  569.     EX    DE,HL
  570.     INC    HL
  571.     LD    (HL),E        ;Set low address
  572.     INC    HL
  573.     LD    (HL),D
  574.     RET
  575.  
  576. ;
  577. ;  BUFFERS
  578. ;
  579. BYTE:    DS    1        ;Data byte
  580. BUFFER:    DS    2        ;Starting address of I/O control block
  581.  
  582. ;  The following mirrors the structure of the I/O Control Block
  583. ;
  584. BCNT:     DS    1        ;Number of blocks in buffer
  585. EOF:     DS    1        ;EOF flag (0=not at EOF, 0FFH=at EOF)
  586. BYTECNT: DS    2        ;Number of bytes to go yet
  587. BYTENXT: DS    2        ;Address of next byte to PUT/GET
  588. BUFADR:     DS    2        ;Address of working buffer
  589. FCB:     DS    2        ;Address of FCB
  590.  
  591.     END
  592. ress
  593.     INC    HL
  594.     LD    D,(HL)
  595.     EX    DE,HL
  596.     LD    (BUFADR),HL    ;Put buffer address ptr
  597. ;
  598.     EX    DE,HL
  599.     INC    HL
  600.     LD    (FCB),HL    ;S