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 / SFXIO.Z80 < prev    next >
Text File  |  2000-06-30  |  13KB  |  537 lines

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