home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ZSYS / SIMTEL20 / SYSLIB / SLIB2.LBR / SFYIO.Z80 < prev    next >
Text File  |  2000-06-30  |  14KB  |  607 lines

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