home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol090 / sfileio.mac < prev    next >
Encoding:
Text File  |  1984-04-29  |  8.6 KB  |  419 lines

  1. ;
  2. ; SYSLIB Module Name:  SFILEI
  3. ; Author:  Richard Conn
  4. ; SYSLIB Version Number:  2.0
  5. ; Module Version Number:  1.0
  6. ; Module Entry Points:
  7. ;    ADRCPY        F$GET        F$PUT        FI$CLOSE
  8. ;    FI$OPEN        FO$CLOSE    FO$OPEN
  9. ; Module External References:
  10. ;    F$MOPEN        F$OPEN        INITFCB
  11. ;
  12.  
  13. ;
  14. ;  SFILEIO.MAC -- BYTE-ORIENTED FILE I/O FOR SYSLIB
  15. ;    INCLUDED ROUTINES ARE --  FILE INPUT OPEN, FILE OUTPUT OPEN,
  16. ;            FILE INPUT CLOSE, FILE OUTPUT CLOSE,
  17. ;            GET, PUT
  18. ;    Error Diagnostics are returned to the caller via the Zero Flag
  19. ;        (Zero Flag Set - Z - ALWAYS Means No Error Occurred)
  20. ;        and the A Register
  21. ;    If the Zero Flag is Set (Z), then the A Register either contains
  22. ;        a 0 or the required returned value if A is significant for
  23. ;        the particular routine.
  24. ;    If the Zero Flag is Clear (NZ), then the A Register contains the
  25. ;        error code.  No other returned register value in HL, DE, or BC
  26. ;        should be considered to be valid.  The Returned Error Codes
  27. ;        in A are:
  28. ;            Code    Meaning
  29. ;              1    GET or PUT attempted on unopened file
  30. ;              2    Disk Full (Ran out of space)
  31. ;              3    Input File Not Found
  32. ;              4    Attempt to Read Past the EOF
  33. ;              5    Directory Full
  34. ;              6    Error in Closing a File
  35. ;              7    Attempt to Open a File which is already open
  36. ;
  37.  
  38. ;
  39. ;  EXTERNAL LIBRARY FILE DEFINITIONS
  40. ;
  41.     EXT    F$OPEN    ; OPEN FILE
  42.     EXT    F$MOPEN    ; OPEN/CREATE FILE
  43.     EXT    INITFCB    ; INIT FCB
  44.  
  45. ;
  46. ;  CP/M EQUATES AND ASCII CONSTANTS
  47. ;
  48. CPM    EQU    0    ; WARM BOOT FOR CP/M
  49. TBUFF    EQU    80H    ; TEMPORARY FILE I/O BUFFER
  50. CR    EQU    0DH    ; <CR>
  51. LF    EQU    0DH    ; <LF>
  52.  
  53. BDOS    EQU    5    ; BDOS ENTRY POINT
  54. B$CL    EQU    16    ; CLOSE FILE
  55. B$RD    EQU    20    ; READ NEXT RECORD
  56. B$WR    EQU    21    ; WRITE NEXT RECORD
  57. B$DMA    EQU    26    ; SET DMA ADDRESS
  58.  
  59. ;
  60. ;  SUPPORTING MACROS
  61. ;
  62. PUTRG    MACRO        ; SAVE BC, DE, HL
  63.     PUSH    B
  64.     PUSH    D
  65.     PUSH    H
  66.     ENDM
  67. GETRG    MACRO        ; RESTORE HL, DE, BC
  68.     POP    H
  69.     POP    D
  70.     POP    B
  71.     ENDM
  72.  
  73. ;**********************************************************************
  74. ;  SUPPORTING ROUTINES
  75. ;
  76.  
  77. ;
  78. ;  ADDRESS TABLE COPY ROUTINE
  79. ;
  80. ADRCPY::
  81.     LXI    H,I$FLG    ; PT TO FIRST ENTRY
  82.     MVI    B,20    ; 20 BYTES (10 ADDRESSES) TO COPY
  83.     JMP    SFCBL    ; DO COPY
  84.  
  85. ;
  86. ;  GET ONE-LEVEL INDIRECT ADDRESS
  87. ;    HL = ADDRESS CONTAINED AT MEMORY LOCATION PTED TO BY HL
  88. ;
  89. GETADR:
  90.     PUSH    D    ; SAVE DE
  91.     MOV    E,M    ; GET LOW
  92.     INX    H
  93.     MOV    D,M    ; GET HIGH
  94.     MOV    H,D    ; SET HL
  95.     MOV    L,E
  96.     POP    D    ; GET DE
  97.     RET
  98.  
  99. ;
  100. ;  SAVEFCB UTILITY -- COPY FCB FROM DE TO HL
  101. ;
  102. SAVEFCB:
  103.     MVI    B,36    ; 36 BYTES
  104. SFCBL:
  105.     LDAX    D    ; GET BYTE
  106.     MOV    M,A    ; PUT BYTE
  107.     INX    H    ; PT TO NEXT
  108.     INX    D
  109.     DCR    B    ; COUNT DOWN
  110.     JNZ    SFCBL
  111.     RET
  112. ;
  113. ;  F$ABORT -- FILE ERROR -- ABORT
  114. ;
  115. F$ABORT:
  116.     GETRG        ; RESTORE REGISTERS
  117.     ORA    A    ; SET FLAGS
  118.     RET
  119. ;
  120. ;  F$CLOS -- CLOSE FILE
  121. ;
  122. F$CLOS:
  123.     MVI    C,B$CL    ; CLOSE FILE
  124.     CALL    BDOS
  125.     RET
  126. ;
  127. ;  F$READ -- READ ONE 128-BYTE BLOCK VIA CP/M
  128. ;
  129. F$READ:
  130.     MVI    C,B$RD    ; READ BLOCK
  131.     CALL    BDOS
  132.     RET
  133. ;
  134. ;  F$WRIT -- WRITE ONE 128-BYTE BLOCK VIA CP/M
  135. ;
  136. F$WRIT:
  137.     MVI    C,B$WR    ; WRITE BLOCK
  138.     CALL    BDOS
  139.     RET
  140. ;
  141. ;  READ$BLOCK -- READ BLOCK FROM INPUT FILE INTO INPUT BUFFER
  142. ;    ON RETURN, Z=OK AND NZ=NOT OK (PAST EOF)
  143. ;
  144. READ$BLOCK:
  145.     LHLD    I$FCB    ; GET FCB ADDRESS
  146.     XCHG        ; ... IN DE
  147.     CALL    F$READ    ; READ BLOCK
  148.     PUSH    PSW    ; SAVE STATUS
  149.     LHLD    I$BUF    ; PT TO INPUT BUFFER
  150.     LXI    D,TBUFF    ; PT TO TEMP BUFFER
  151.     MVI    B,128    ; 128 BYTES
  152.     CALL    SFCBL    ; COPY FROM DE TO HL FOR B BYTES
  153.     POP    PSW    ; GET STATUS
  154.     ORA    A    ; SET ZERO FLAG IF OK
  155.     RET
  156. ;
  157. ;  WRIT$BLOCK -- WRITE BLOCK TO OUTPUT FILE
  158. ;
  159. WRIT$BLOCK:
  160.     LHLD    O$BUF    ; ADDRESS OF OUTPUT BUFFER
  161.     XCHG        ; ... IN DE
  162.     LXI    H,TBUFF    ; PT TO TEMP BUFFER
  163.     MVI    B,128    ; 128 BYTES
  164.     CALL    SFCBL    ; COPY FROM DE TO HL FOR B BYTES
  165.     LHLD    O$FCB    ; PT TO DEFAULT FCB
  166.     XCHG        ; ... IN DE
  167.     CALL    F$WRIT    ; WRITE BLOCK
  168.     ORA    A    ; OK?
  169.     RZ        ; OK IF ZERO
  170.     MVI    A,2    ; DISK FULL ERROR CODE
  171.     RET
  172. ;
  173. ;  **** BASE ROUTINES ****
  174. ;
  175. ;  FI$OPEN -- OPEN FILE WHOSE FCB IS PTED TO BY DE FOR INPUT
  176. ;
  177. FI$OPEN::
  178.     PUTRG        ; SAVE REGISTERS
  179.     PUSH    D    ; SAVE PTR
  180.     LXI    D,TBUFF    ; SET DMA ADDRESS
  181.     MVI    C,B$DMA
  182.     CALL    BDOS
  183.     POP    D    ; GET PTR
  184.     LHLD    I$FLG    ; ALREADY OPENED?
  185.     MOV    A,M    ; GET FLAG
  186.     ORA    A    ; 0=NO
  187.     JZ    FI$OP0
  188.     MVI    A,7    ; FILE ALREADY OPEN ERROR
  189.     JMP    F$ABORT
  190. FI$OP0:
  191.     LHLD    I$FCB    ; PT TO DEFAULT OPEN FCB
  192.     PUSH    H    ; SAVE PTR TO FCB
  193.     CALL    SAVEFCB    ; CREATE NEW FCB
  194.     POP    D    ; GET PTR TO FCB
  195.     CALL    INITFCB    ; CLEAR FCB FIELDS
  196.     CALL    F$OPEN    ; OPEN FILE
  197.     ORA    A    ; ZERO MEANS OK
  198.     JZ    FI$OP1
  199.     MVI    A,3    ; FILE NOT FOUND FOR INPUT
  200.     JMP    F$ABORT
  201. FI$OP1:
  202.     CALL    READ$BLOCK    ; READ FIRST BLOCK
  203.     JZ    FI$OP2
  204.     MVI    A,4    ; READ PAST EOF ERROR
  205.     JMP    F$ABORT
  206. FI$OP2:
  207.     LHLD    I$BUF    ; PT TO BUFFER
  208.     XCHG        ; ... ADDRESS IN DE
  209.     LHLD    I$PTR    ; SAVE PTR
  210.     MOV    M,E    ; SAVE ADDRESS PTR
  211.     INX    H
  212.     MOV    M,D
  213.     LHLD    I$CNT    ; GET PTR TO COUNT
  214.     MVI    M,128    ; SET COUNT
  215.     LHLD    I$FLG    ; GET PTR TO FLAG
  216.     MVI    M,0FFH    ; SET FILE OPENED FLAG
  217.     GETRG        ; RESTORE REGISTERS
  218.     XRA    A    ; OK RETURN
  219.     RET
  220. ;
  221. ;  FO$OPEN -- OPEN FILE WHOSE FCB IS PTED TO BY DE FOR OUTPUT
  222. ;
  223. FO$OPEN::
  224.     PUTRG        ; SAVE REGISTERS
  225.     PUSH    D    ; SAVE PTR
  226.     LXI    D,TBUFF    ; SET DMA ADDRESS
  227.     MVI    C,B$DMA
  228.     CALL    BDOS
  229.     POP    D    ; GET PTR
  230.     LHLD    O$FLG    ; CHECK FOR FILE ALREADY OPENED
  231.     MOV    A,M    ; GET FLAG
  232.     ORA    A    ; 0 MEANS NOT YET OPENED
  233.     JZ    FO$OP0
  234.     MVI    A,7    ; FILE ALREADY OPENED ERROR
  235.     JMP    F$ABORT
  236. FO$OP0:
  237.     LHLD    O$FCB    ; PT TO DEFAULT OPEN FCB
  238.     PUSH    H    ; SAVE PTR TO FCB
  239.     CALL    SAVEFCB    ; CREATE NEW FCB
  240.     POP    D    ; GET PTR TO FCB
  241.     CALL    INITFCB    ; CLEAR FCB FIELDS
  242.     CALL    F$MOPEN    ; OPEN AND/OR CREATE FILE
  243.     JZ    FO$OP1
  244.     MVI    A,5    ; DIRECTORY FULL
  245.     JMP    F$ABORT
  246. FO$OP1:
  247.     LHLD    O$BUF    ; PT TO BUFFER
  248.     XCHG        ; ... IN DE
  249.     LHLD    O$PTR    ; SAVE PTR
  250.     MOV    M,E    ; SAVE ADDRESS PTR
  251.     INX    H
  252.     MOV    M,D
  253.     LHLD    O$CNT    ; GET PTR TO COUNT
  254.     MVI    M,128    ; SET COUNT
  255.     LHLD    O$FLG    ; GET PTR TO FLAG
  256.     MVI    M,0FFH    ; SET FILE OPENED FLAG
  257.     GETRG        ; RESTORE REGISTERS
  258.     XRA    A    ; OK RETURN
  259.     RET
  260. ;
  261. ;  F$GET -- GET BYTE FROM INPUT FILE; BYTE RETURNED IN REG A
  262. ;    ON RETURN, IF CARRY=0 (NC), THEN OK; IF CARRY=1 (C), THEN PAST EOF
  263. ;
  264. F$GET::
  265.     PUTRG        ; SAVE REGISTERS
  266.     LHLD    I$FLG    ; PT TO FLAG
  267.     MOV    A,M    ; GET IT; INPUT OK?
  268.     ORA    A    ; ZERO MEANS NO
  269.     JNZ    F$G1
  270.     MVI    A,1    ; FILE NOT YET OPENED
  271.     JMP    F$ABORT
  272. F$G1:
  273.     LHLD    I$PTR    ; PT TO NEXT BYTE
  274.     CALL    GETADR    ; GET ADDRESS OF BYTE PTED TO BY PTR
  275.     MOV    A,H    ; EOF WAS REACHED IF POINTER IS ZERO
  276.     ORA    L
  277.     JZ    F$GEOF
  278.     MOV    A,M    ; GET BYTE
  279.     STA    BYTE    ; SAVE BYTE FOR RETURN
  280.     INX    H    ; PT TO NEXT BYTE
  281.     XCHG        ; ... IN DE
  282.     LHLD    I$PTR    ; PT TO POINTER
  283.     MOV    M,E    ; SAVE ADDRESS PTR
  284.     INX    H
  285.     MOV    M,D
  286.     LHLD    I$CNT    ; PT TO COUNT
  287.     DCR    M    ; DECREMENT COUNT
  288.     JNZ    F$GET1
  289. ;  READ IN NEXT BLOCK AND RESET POINTERS
  290.     LHLD    I$BUF    ; PT TO BUFFER
  291.     XCHG        ; ... IN DE
  292.     LHLD    I$PTR
  293.     MOV    M,E    ; SAVE ADDRESS PTR
  294.     INX    H
  295.     MOV    M,D
  296.     LHLD    I$CNT    ; PT TO COUNT
  297.     MVI    M,128    ; SET COUNT
  298.     CALL    READ$BLOCK
  299.     JZ    F$GET1    ; OK RETURN
  300.     LHLD    I$PTR    ; SET POINTER TO ZERO TO INDICATE EOF REACHED
  301.     MVI    M,0    ; STORE ZEROES
  302.     INX    H
  303.     MVI    M,0
  304. ;  NORMAL EXIT
  305. F$GET1:
  306.     GETRG        ; RESTORE REGISTERS
  307.     XRA    A    ; ZERO MEANS OK
  308.     LDA    BYTE    ; GET BYTE VALUE TO RETURN
  309.     RET
  310. ;  EOF EXIT
  311. F$GEOF:
  312.     MVI    A,4    ; EOF
  313.     JMP    F$ABORT
  314.  
  315. ;
  316. ;  F$PUT -- PUT BYTE IN REG A INTO OUTPUT FILE
  317. ;
  318. F$PUT::
  319.     PUTRG        ; SAVE REGISTERS
  320.     STA    BYTE    ; SAVE BYTE TO OUTPUT
  321.     LHLD    O$FLG    ; GET FILE OPENED FLAG
  322.     MOV    A,M    ; GET FLAG
  323.     ORA    A    ; ZERO MEANS NO
  324.     JNZ    F$P1
  325.     POP    PSW    ; CLEAR STACK
  326.     MVI    A,1    ; FILE NOT OPENED
  327.     JMP    F$ABORT
  328. F$P1:
  329.     LHLD    O$PTR    ; GET PTR TO NEXT BYTE
  330.     CALL    GETADR    ; PT TO BYTE PTED TO BY PTR
  331.     LDA    BYTE    ; GET BYTE TO OUTPUT
  332.     MOV    M,A    ; PUT BYTE
  333.     INX    H    ; PT TO NEXT
  334.     XCHG        ; ... IN DE
  335.     LHLD    O$PTR    ; PT TO PTR
  336.     MOV    M,E    ; SAVE ADDRESS
  337.     INX    H
  338.     MOV    M,D
  339.     LHLD    O$CNT    ; PT TO COUNT
  340.     DCR    M    ; COUNT DOWN
  341.     JNZ    F$PUT1    ; RETURN IF OK
  342. ;  BUFFER FULL -- WRITE IT TO DISK AND RESET POINTER AND COUNT
  343.     LHLD    O$BUF    ; RESET POINTER
  344.     XCHG        ; ADDR OF BUFFER IN DE
  345.     LHLD    O$PTR
  346.     MOV    M,E    ; SAVE ADDRESS PTR
  347.     INX    H
  348.     MOV    M,D
  349.     LHLD    O$CNT    ; PT TO COUNT
  350.     MVI    M,128    ; RESET COUNT
  351.     CALL    WRIT$BLOCK
  352.     MVI    A,2    ; ASSUME DISK FULL ERROR
  353.     JNZ    F$ABORT    ; ERROR IN WRITE
  354. ;  NORMAL EXIT
  355. F$PUT1:
  356.     GETRG        ; RESTORE REGISTERS
  357.     XRA    A    ; Z FOR NO ERROR
  358.     LDA    BYTE    ; GET BYTE VALUE
  359.     RET
  360. ;
  361. ;  FI$CLOS -- CLOSE FILE OPENED FOR INPUT
  362. ;
  363. FI$CLOS::
  364.     PUSH    H
  365.     LHLD    I$FLG    ; SET INPUT OPENED FLAG
  366.     MVI    M,0    ; INPUT NOT OPENED NOW
  367.     POP    H
  368.     RET
  369. ;
  370. ;  GENERAL-PURPOSE POINTERS FOR ALL GLOBAL ROUTINES
  371. ;
  372. I$FLG:    DS    2    ; INPUT FILE OPENED FLAG (0=NO)
  373. O$FLG:    DS    2    ; OUTPUT FILE OPENED FLAG (0=NO)
  374. I$FCB:    DS    2    ; INPUT FILE FCB
  375. O$FCB:    DS    2    ; OUTPUT FILE FCB
  376. I$BUF:    DS    2    ; INPUT BUFFER
  377. O$BUF:    DS    2    ; OUTPUT BUFFER
  378. I$PTR:    DS    2    ; INPUT CHAR PTR
  379. O$PTR:    DS    2    ; OUTPUT CHAR PTR
  380. I$CNT:    DS    2    ; INPUT CHAR COUNT
  381. O$CNT:    DS    2    ; OUTPUT CHAR COUNT
  382.  
  383.  
  384. BYTE:    DS    1    ; BYTE STORAGE
  385.  
  386. ;
  387. ;  FO$CLOS -- CLOSE FILE OPENED FOR OUTPUT
  388. ;
  389. FO$CLOS::
  390.     PUTRG        ; SAVE REGS
  391.     STA    BYTE    ; SAVE A
  392.     MVI    A,1AH    ; PUT CTRL-Z
  393.     CALL    F$PUT
  394. CLOSE1:
  395.     LHLD    O$CNT    ; PT TO COUNT
  396.     MOV    A,M    ; GET COUNT
  397.     CPI    128    ; CLOSE IF BLOCK JUST WRITTEN
  398.     JZ    CLOSE2
  399.     XRA    A    ; PUT ZERO
  400.     CALL    F$PUT
  401.     JMP    CLOSE1
  402. CLOSE2:
  403.     LHLD    O$FLG    ; SET OUTPUT OPENED FLAG
  404.     MVI    M,0    ; NOT OPENED
  405.     LHLD    O$FCB    ; PT TO OUTPUT FCB
  406.     XCHG        ; ... PT VIA DE
  407.     CALL    F$CLOS    ; CLOSE FILE
  408.     CPI    0FFH    ; ERROR?
  409.     JNZ    CLOSE3
  410.     MVI    A,6    ; CLOSE ERROR
  411.     JMP    F$ABORT
  412. CLOSE3:
  413.     GETRG        ; RESTORE REGS
  414.     XRA    A    ; OK RETURN
  415.     LDA    BYTE    ; GET ORIGINAL A
  416.     RET
  417.  
  418.     END
  419.