home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / znode3 / uploads / zslsrc36.lbr / ZFILEIO.ZZ0 / ZFILEIO.Z80
Encoding:
Text File  |  1992-02-04  |  11.5 KB  |  384 lines

  1. ; Library:    ZSLIB
  2. ; Version:    3.5
  3. ; Module:    ZFILEIO
  4. ; Version:    1.0
  5. ; Author:    Gene Pizzetta
  6. ; Date:        December 15, 1991
  7. ; Changes:    Based on SYSLIB 3.6 SFILEIO module by Richard Conn and Al
  8. ;        Dunsmuir.  Added drive and user support.  Code is heavily
  9. ;        modified and tightened for a considerable size savings.
  10. ;
  11. ; This module is for internal use by the byte-oriented file I/O routines
  12. ; in the Z0FILE to Z3FILE modules.  Entry points here are not appropriate
  13. ; for calling from user programs.
  14. ; FR@OPEN, FW@OPEN -- Open files for byte-oriented input and output.
  15. ; FR@CLOSE, FW@CLOSE -- Close files after byte-oriented input and output.
  16. ; F@GET -- Returns next byte from the input file.
  17. ; F@PUT -- Inserts a byte into the output file.
  18. ;
  19. ; The open routines obtain the current drive and user area from the DOS
  20. ; store them in the control table.  The other routines log into the drive
  21. ; and user in the control table whenever disk access is needed; no further
  22. ; attention need be paid to the drive/user by the calling routines or by
  23. ; the programmer.
  24. ;
  25. ; Only the first 12 bytes of the user's file control block are significant
  26. ; when opening a file.  The open routines use only the filename and filetype;
  27. ; the drive byte is ignored.  Once a file is open, its original file control
  28. ; block is no longer referenced.  Thus a single abbreviated FCB may be used
  29. ; and re-used to open multiple files.  Both an input and output file can be
  30. ; opened from the default file control blocks at 5Ch and 6Ch without moving
  31. ; the filenames.
  32. ;
  33. ; Do not use the same buffer for both input and output.
  34. ;
  35. ; Error Diagnostics are returned to the caller via the zero flag and the A
  36. ; register.  If the zero flag is set (Z), it always means no error occurred
  37. ; and the A register contains either 0 or the required returned value.  If
  38. ; the zero flag is reset (NZ), the A register contains an error code and no
  39. ; other register value should be considered to be valid.  The returned error
  40. ; codes in A are as follows:
  41. ;
  42. ;     Code    Meaning
  43. ;    1    Get or put attempted on unopened file (F@GET and F@PUT)
  44. ;    2    Disk full (F@PUT and FW@OPEN)
  45. ;    3    Input file not found (FR@OPEN)
  46. ;    4    End of file (F@GET) or input file empty (FR@OPEN)
  47. ;    5    Directory full (FW@OPEN)
  48. ;    6    Error in closing a file (FR@CLOSE and FW@CLOSE)
  49. ;    7    Attempt to open file that is already open (FR@OPEN and FW@OPEN)
  50. ;
  51. ; Error code 1 is actually returned to the program by the calling routines
  52. ; in the ZnFILE modules and not by the routines in this module.  Error code
  53. ; 4 for F@GET is not really an error, but indicates that the end of the file
  54. ; has been reached and there is no more data.  F@GET, F@PUT, and the close
  55. ; routines are not called by the ZnFILE routines if the file is not open
  56. ; (an attempt to close an unopened file does nothing, but returns no error).
  57. ;
  58. ; FR@OPEN -- Opens file for input.
  59. ; Entry:  DE = address of FCB, HL = address of input control table,
  60. ;      Zero flag reset (NZ) if file already opened
  61. ; Exit:      A = 0, zero flag set (Z) if okay
  62. ;      A = code, zero flag reset (NZ) if error
  63. ;        3 = file not found
  64. ;        4 = file empty
  65. ;        7 = file already open
  66. ; Uses:      AF, HL
  67. ;
  68. ; FW@OPEN -- Open file for output.
  69. ; Entry:  DE = address of FCB, HL = address of output control table
  70. ;      Zero flag reset (NZ) if file already opened
  71. ; Exit:      A = 0, zero flag set (Z) if okay
  72. ;      A = code, zero flag reset (NZ) if error
  73. ;        5 = directory full
  74. ;        7 = file already open
  75. ; Uses:      AF, HL
  76. ;
  77. ; FR@CLOSE -- Close file opened for input.
  78. ; Entry:  HL = address of input control table
  79. ; Exit:      A = 0, zero flag set (Z) if okay
  80. ;      A = code, zero flag reset (NZ) if error
  81. ;        6 = close error
  82. ; Uses:      AF, HL
  83. ;
  84. ; FW@CLOSE -- Close file opened for output.
  85. ; Entry:  HL = address of output control table
  86. ; Exit:      A = 0, zero flag set (Z) if okay
  87. ;      A = code, zero flag reset (NZ) if error
  88. ;        2 = disk full
  89. ;        6 = close error
  90. ; Uses:      AF, HL
  91. ;
  92. ; F@GET -- Get byte from input file.
  93. ; Entry:  HL = address of input control table
  94. ;      HL should have been pushed onto the stack
  95. ; Exit:      A = byte, zero flag set (Z) if okay
  96. ;      A = code, zero flag reset (NZ) if error
  97. ;        4 = end of file (not really an error)
  98. ;      HL is popped from the stack
  99. ; Uses:      AF
  100. ;
  101. ; F@PUT -- Put byte in A into output file.
  102. ; Entry:  A = byte
  103. ;      HL = address of output control table
  104. ;      HL should have been pushed onto stack
  105. ; Exit:      A = byte, zero flag set (Z) if okay
  106. ;      A = code, zero flag reset (NZ) if error
  107. ;        2 = disk full
  108. ;      HL is popped from the stack
  109. ; Uses:      AF
  110. ;
  111.     PUBLIC    FR@OPEN,FR@CLOSE,F@GET
  112.     PUBLIC    FW@OPEN,FW@CLOSE,F@PUT
  113. ;
  114.     EXTRN    SETDMA,INITFCB,RETUD,LOGUD        ; SYSLIB
  115.     EXTRN    F$OPEN,F$MOPEN,F$CLOSE,F$READ,F$WRITE
  116. ;
  117. Bdos    equ    5        ; BDOS entry
  118. CpmDma    equ    80h        ; default DMA buffer
  119. CpmEof    equ    1Ah        ; CP/M end of file (^Z)
  120. ;
  121. ; FR@OPEN -- Opens file for input.
  122. ;
  123. FR@OPEN:
  124.     ld    a,7        ; error code (already open error)
  125.     ret    nz        ; (if so, exit)
  126.     push    bc        ; save BC, DE
  127.     push    de
  128.     call    iniopn        ; prepare for open
  129.     call    F$OPEN        ; open file
  130.     ld    a,3        ; error code (input file not found)    
  131.     jr    nz,fexit    ; (if so, exit)
  132.     call    rdblk        ; read first block
  133.     jr    z,fopen1    ; (OK, so set up file table)
  134.     ld    a,4        ; error code (file empty)
  135.     jr    fexit
  136. ;
  137. ; FW@OPEN -- Open file for output.
  138. ;
  139. FW@OPEN:
  140.     ld    a,7        ; error code (file already open)
  141.     ret    nz        ; (if so, exit)
  142.     push    bc        ; save BC, DE
  143.     push    de
  144.     call    iniopn        ; prepare for open
  145.     call    F$MOPEN        ; open or create file
  146.     ld    a,5        ; error code (directory full)
  147.     jr    nz,fexit    ; (if so, exit)
  148. ;
  149. fopen1:    ld    hl,(iotbl)    ; get address of control table
  150.     inc    hl        ; set character count
  151.     inc    hl
  152.     ld    (hl),128
  153.     inc    hl        ; point to character pointer
  154.     ex    de,hl        ; ..and move it to DE
  155.     ld    hl,36+2        ; get buffer address
  156.     add    hl,de
  157.     ex    de,hl        ; ..into DE
  158.     ld    (hl),e        ; save buffer start address
  159.     inc    hl
  160.     ld    (hl),d
  161.     xor    a        ; file opened OK, so fall through
  162. ;
  163. fexit:    pop    de        ; restore registers
  164.     pop    bc
  165.     or    a        ; set flags
  166.     ret
  167. ;
  168. ; FR@CLOSE -- Close file opened for input.
  169. ;
  170. FR@CLOSE:
  171.     push    bc        ; save BC, DE
  172.     push    de
  173.     call    setdu
  174. ;
  175. close1:    inc    hl        ; get FCB address
  176.     inc    hl
  177.     inc    hl
  178.     ex    de,hl        ; ..in DE
  179.     call    F$CLOSE        ; close file
  180.     ld    a,6        ; error code (close error)
  181.     jr    nz,fexit    ; (if so, exit)
  182.     xor    a        ; input/output file closed OK
  183.     jr    fexit        ; restore registers and exit
  184. ;
  185. ; FW@CLOSE -- Close file opened for output.
  186. ;
  187. FW@CLOSE:
  188.     push    bc        ; save BC, DE
  189.     push    de
  190.     ld    (iotbl),hl    ; save output control table address
  191.     call    setdu
  192.     ld    a,(hl)        ; get bytes remaining (buffer free space count)
  193.     cp    128
  194.     jr    z,close1    ; (if buffer is empty, close)
  195.     ld    a,CpmEof    ; put ^Z
  196.     call    FPutI
  197. closlp:    ld    a,(hl)        ; get number of bytes remaining
  198.     cp    128
  199.     jr    z,close1    ; (if block just written, close)
  200.     xor    a        ; put zeroes to fill buffer
  201.     call    FPutI
  202.     jr    closlp        ; loop while space remains
  203. ;
  204. ; FPutI - Internal call to F@PUT with stack management
  205. ;
  206. FPutI:    push    hl        ; save HL
  207.     ld    hl,(iotbl)    ; get address of output control table
  208. ;
  209. ; F@PUT -- Put byte in A into output file.
  210. ;
  211. F@PUT:    push    bc        ; save BC, DE
  212.     push    de
  213.     ld    (byte),a    ; save byte to output
  214.     ld    (iotbl),hl    ; save address of output control table
  215.     inc    hl        ; ->user
  216.     inc    hl        ; pt to char pointer
  217.     inc    hl
  218.     ld    e,(hl)        ; get char pointer
  219.     inc    hl
  220.     ld    d,(hl)
  221.     ld    a,(byte)    ; get byte to output
  222.     ld    (de),a        ; PUT data byte
  223.     inc    de        ; pt to next output byte
  224.     ld    (hl),d        ; update current Output buffer address
  225.     dec    hl
  226.     ld    (hl),e
  227.     dec    hl        ; pt to buffer data count
  228.     dec    (hl)        ; decrement count
  229.     jr    nz,gpexit    ; (exit if space remains in buffer)
  230. ;
  231. ; Output buffer is full, so write it and reset pointers and count
  232. ;
  233.     ld    (hl),128    ; set char count
  234.     inc    hl        ; pt to char pointer
  235.     ex    de,hl        ; ..in DE
  236.     ld    hl,36+2        ; get buffer address
  237.     add    hl,de
  238.     ex    de,hl        ; ..in DE
  239.     ld    (hl),e        ; save buffer start address
  240.     inc    hl
  241.     ld    (hl),d
  242.     call    wrtblk        ; write next block
  243.     jr    z,gpexit    ; (PUT completed OK, exit)
  244.     ld    a,2        ; error code (disk full)
  245. gperr:    or    a        ; reset zero flag
  246.     jr    gpxit2
  247. ;
  248. ; F@GET -- Get byte from input file.
  249. ;
  250. F@GET:    push    bc        ; save BC, DE
  251.     push    de
  252.     ld    (iotbl),hl    ; save address of input control table
  253.     inc    hl
  254.     inc    hl        ; point to character pointer
  255.     inc    hl
  256.     ld    e,(hl)        ; get character pointer
  257.     inc    hl
  258.     ld    d,(hl)
  259.     ld    a,d        ; EOF was reached if pointer is zero
  260.     or    e
  261.     ld    a,4        ; error code (end of file)
  262.     jr    z,gperr        ; (end of file, exit)
  263.     ld    a,(de)        ; GET data byte
  264.     ld    (byte),a    ; save byte for return
  265.     inc    de        ; point to next input byte
  266.     ld    (hl),d        ; update current input buffer address
  267.     dec    hl
  268.     ld    (hl),e
  269.     dec    hl        ; point to buffer data count
  270.     dec    (hl)        ; decrement count
  271.     jr    nz,gpexit    ; exit if data remains in buffer
  272. ;
  273. ; Input buffer empty, so read next block and reset pointers and count
  274. ;
  275.     ld    (hl),128    ; set char count
  276.     inc    hl        ; point to char pointer
  277.     ex    de,hl        ; ..in DE
  278.     ld    hl,36+2        ; get buffer address
  279.     add    hl,de
  280.     ex    de,hl        ; ..in DE
  281.     ld    (hl),e        ; save buffer start address
  282.     inc    hl
  283.     ld    (hl),d
  284.     call    rdblk        ; read next block
  285.     jr    z,gpexit    ; (all okay)
  286.     ld    hl,(iotbl)    ; get address of input/output control table
  287.     inc    hl
  288.     inc    hl        ; point to character pointer
  289.     inc    hl
  290.     ld    (hl),0        ; zero indicates EOF reached
  291.     inc    hl
  292.     ld    (hl),0
  293. ;
  294. ; Exits for GET or PUT
  295. ;
  296. gpexit:    xor    a        ; all is okay
  297.     ld    a,(byte)    ; get data byte to return
  298. gpxit2:    pop    de        ; restore registers
  299.     pop    bc
  300.     pop    hl        ; HL was saved before entry
  301.     ret
  302. ;
  303. ; Subroutines . . .
  304. ;
  305. ; rdblk -- Read block from input file into input buffer.
  306. ; Entry:  None
  307. ; Exit:      Zero flag set (Z) if okay, zero flag reset (NZ) if end of file
  308. ; Uses:      AF, BC, DE, HL
  309. ;
  310. rdblk:    ld    de,(iotbl)    ; get input control table address into DE
  311.     ld    hl,36+2+1+2    ; get buffer address into HL
  312.     add    hl,de
  313.     call    SETDMA
  314.     ex    de,hl        ; control table address to HL
  315.     call    setdu        ; log into file directory
  316.     ex    de,hl
  317.     inc    de        ; point to input FCB
  318.     inc    de
  319.     inc    de
  320.     call    F$READ        ; read in a block from file
  321.     ld    hl,CpmDma    ; reset DMA address (for compatability)
  322.     jp    SETDMA        ; return Z to caller if read okay
  323. ;
  324. ; wrtblk -- Write block from output buffer into output file.
  325. ; Entry:  None
  326. ; Exit:      Zero flag set (Z) if okay, zero flag reset (NZ) if disk full
  327. ; Uses:      AF, BC, DE, HL
  328. ;
  329. wrtblk:    ld    de,(iotbl)    ; get output control table address into DE
  330.     ld    hl,36+2+1+2    ; get buffer address into HL
  331.     add    hl,de
  332.     call    SETDMA
  333.     ex    de,hl        ; control table address to HL
  334.     call    setdu        ; log into file directory
  335.     ex    de,hl
  336.     inc    de        ; get address of output FCB
  337.     inc    de
  338.     inc    de
  339.     call    F$WRITE        ; write block to file
  340.     ld    hl,CpmDma    ; reset DMA address (for compatability)
  341.     jp    SETDMA        ; return Z to caller if write okay
  342. ;
  343. ; iniopn -- Gets file directory, moves filename, and initializes FCB for
  344. ; open routines.
  345. ; Entry:  HL = address of input control table, DE = address of user's FCB
  346. ; Exit:      DE = address of our FCB
  347. ; Uses:      BC, DE, HL
  348. ;
  349. iniopn:    ld    (iotbl),hl    ; save address of input control table
  350.     call    RETUD        ; get drive and user
  351.     ld    (hl),b
  352.     inc    hl
  353.     ld    (hl),c
  354.     inc    hl        ; point to open FCB
  355.     inc    hl
  356.     inc    hl
  357.     inc    hl
  358.     push    hl        ; save our FCB pointer
  359.     ld    bc,12        ; we only need the first 12 bytes
  360.     ex    de,hl        ; HL = user's FCB, DE = our FCB
  361.     ldir
  362.     pop    de        ; get our FCB pointer into DE
  363.     jp    INITFCB        ; initialize FCB and return
  364. ;
  365. ; setdu -- Sets drive and user for current file.
  366. ; Entry:  HL = address of drive byte, followed by user byte.
  367. ; Return:  HL = address of byte following user.  Also uses BC.
  368. ;
  369. setdu:    ld    b,(hl)        ; get drive
  370.     inc    hl
  371.     ld    c,(hl)        ; get user
  372.     inc    hl
  373.     jp    LOGUD        ; jump and return to caller
  374. ;
  375. ; Storage for all global routines
  376. ;
  377.     DSEG
  378. ;
  379. iotbl:    ds    2        ; address of input/output control table
  380. byte:    ds    1        ; data byte storage
  381. ;
  382.     end
  383.