home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / lambda / soundpot / p / sclib2.lbr / FILELIB.MZC / FILELIB.MAC
Encoding:
Text File  |  1993-10-25  |  9.3 KB  |  536 lines

  1. ; filelib.mac
  2. ;
  3. ;        Small-C     File  Library  Version 1.0
  4. ;
  5. ;                by
  6. ;
  7. ;            Fred A. Scacchitti
  8. ;            25 Glenview Lane
  9. ;            Roch., NY 14609
  10. ;
  11. ;              11 - 24 - 84
  12. ;
  13. ;    This module is a derivative of RUNTIME.MAC by Glen Fisher
  14. ;    and Bill Randle. It contains the constructs necessary for
  15. ;    handling file i/o for C programs compiled by Version 2.08
  16. ;    (and later) of the Small-C compiler.
  17. ;
  18. ;    This module contains the following routines:
  19. ;
  20. ;    fopen(name,mode)
  21. ;
  22. ;    fclose(name)
  23. ;
  24. ;    fcb()
  25. ;
  26. ;    fcbpad()
  27. ;
  28. ;    fcbsize()
  29. ;
  30. ;
  31. ; Now then here's the file i/o code
  32. ;
  33. CBDOS    EQU    5    ;/* bdos entry point */
  34. CPMARG    EQU    128    ;/* CP/M command line */
  35. MAXARG    EQU    32    ;/* Maximum number of input args */
  36. STDIN    EQU    0
  37. STDOUT    EQU    1
  38. STDERR    EQU    2
  39. STDLST    EQU    4
  40. CTRLZ    EQU    26    ;control z
  41. NULL    EQU    0    ;pointer to nothing
  42. FCBSIZE    EQU    36    ;size, in bytes, of an FCB
  43. NEXTP    EQU    0    ;offset    to next-char. pointer in I/O struct.
  44. UNUSED    EQU    2    ;offset    to unused-pos.-count in I/O struct.
  45. BUFFER    EQU    6    ;offset    to disk    sector buf. in I/O struct.
  46. UNGOT    EQU    5    ;offset to char ungotten by ungetc()
  47. FLAG    EQU    33    ;file-type flag    byte (in unused    part of    FCB)
  48. FREEFLG    EQU    128    ;This I/O structure is available
  49. EOF    EQU    0FFH
  50. EOFFLG    EQU    2    ;The end of this file has been hit
  51. WRTFLG    EQU    1    ;This file open    for writing
  52. BUFSIZ    EQU    1024    ;how long the sector buffer is
  53. NBUFS    EQU    8    ;number    of I/O buffers
  54. TBUFF    EQU    128    ;default cpm buffer
  55. LF    EQU    10
  56. EOL    EQU    13
  57. ;
  58. ; CP/M BDOS CALLS 
  59. ;
  60. CLOSE    EQU    16    ;close a file
  61. CPMSTR    EQU    9    ;print '$' delimited string on console
  62. CREATE    EQU    22    ;make a    file
  63. DMA    EQU    26    ;set DMA (I/O address)
  64. DELETE    EQU    19    ;delete    a file
  65. GETCH    EQU    1    ;read character    from console
  66. GETSTR    EQU    10    ;read string from console
  67. LSTOUT    EQU    5    ;write character to list device
  68. OPEN    EQU    15    ;open a    file
  69. PUTCH    EQU    2    ;write character to console
  70. QUERY    EQU    25    ;get logged-in drive id
  71. READ    EQU    20    ;read a    sector
  72. SELECT    EQU    14    ;log-in    a drive
  73. WRITE    EQU    21    ;write a sector
  74. ;
  75. ;
  76. ;    File i/o storage varibles found in ZZFIO.MAC
  77. ;
  78. ;
  79. EXTRN    ZZUNIT
  80. EXTRN    ZZIP
  81. EXTRN    ZZCHP
  82. EXTRN    ZZDP
  83. EXTRN    ZZFILE
  84. EXTRN    ZZMODE
  85. EXTRN    ZZCH
  86. EXTRN    ZZT
  87. EXTRN    ZZFN
  88. EXTRN    ZZNUBU
  89. EXTRN    ZZMXSC
  90. EXTRN    ZZSVCH
  91. ;
  92. ;
  93. ;
  94. ;    Characteristics variable storage found in ulink()    
  95. ;
  96. ;
  97. EXTRN    ZZDFLT
  98. EXTRN    ZZSTAK
  99. EXTRN    ZZMEM
  100. EXTRN    ZZTEMP
  101. ;
  102. ;    Start of file buffers found at end of program
  103. ;
  104. EXTRN    GRABIO
  105. EXTRN    FREEIO
  106. EXTRN    CPMIO
  107. EXTRN    CPMDISK
  108. ;
  109. ;    Required to set buffer in append mode
  110. ;
  111. EXTRN    PUTC
  112. ;
  113. ;    Default disk I/O buffer
  114. ;
  115. EXTRN    ZZBUF
  116. ;
  117. ; Storage variables used by append mode
  118. ;
  119. CURREC:    DB    0
  120. CUREXT:    DB    0
  121. OLDREC:    DB    0
  122. OLDEXT:    DB    0
  123. ;
  124. ;    fopen(name,mode)
  125. ;
  126. FOPEN::
  127. ;
  128.     POP    B            ;get args
  129.     POP    H            ;mode
  130.     SHLD    ZZMODE
  131.     POP    D
  132.     XCHG
  133.     SHLD    ZZFILE
  134.     PUSH    H
  135.     PUSH    D
  136.     PUSH    B
  137.     CALL    GRABIO            ; unit = grabio();
  138.     SHLD    ZZUNIT
  139.     MOV    A,H            ; if(unit==NULL)
  140.     ORA    L            ;    return(NULL);
  141.     RZ
  142.     LXI    D,FCBSIZE        ; ZZIP = unit+FCBSIZE;
  143.     DAD    D
  144.     SHLD    ZZIP
  145. ;
  146.     LXI    D,UNGOT            ;# OFFSET TO UNGOTTEN CHAR
  147.     DAD    D
  148.     MVI    M,0FFH            ;# EOF TO AVOID EXTRA CHAR
  149. ;
  150.     DCX    H            ;# POINT TO ERROR BYTE
  151.     MVI    M,0            ;# CLEAR IT
  152. ;
  153.     LHLD    ZZIP            ;ZZIP[NEXTP]=&ZZIP[BUFFER];
  154.     LXI    D,BUFFER
  155.     DAD    D
  156.     XCHG
  157.     LHLD    ZZIP
  158.     LXI    B,NEXTP
  159.     DAD    B
  160.     MOV    M,E
  161.     INX    H
  162.     MOV    M,D
  163.     LHLD    ZZUNIT            ; fcb(unit,name);
  164.     PUSH    H
  165.     LHLD    ZZFILE
  166.     PUSH    H
  167.     CALL    FCB
  168.     POP    H
  169.     POP    H
  170.     LHLD    ZZUNIT            ; cpmdisk(*unit);
  171.     MOV    L,M
  172.     MVI    H,0
  173.     PUSH    H
  174.     CALL    CPMDISK
  175.     POP    H
  176.     LHLD    ZZMODE            ;if(*mode=='R'||*mode=='A'){
  177.     MOV    A,M
  178. ;
  179.     ANI    5FH            ;# CONVERT TO UPPERCASE
  180.     CPI    'R'            ;# MODE = R ?
  181.     JNZ    FOPIF1
  182. ;
  183. FOPIF0:
  184.     MVI    C,OPEN            ;    if(cpm(OPEN,unit)<0){
  185.     LHLD    ZZUNIT
  186.     XCHG
  187.     CALL    CBDOS        ; (mod toÇcbdos (fas))
  188.     ORA    A
  189.     JP    FOPIF2
  190.     LHLD    ZZUNIT        ;        freeio(unit);
  191.     PUSH    H
  192.     CALL    FREEIO
  193.     POP    H
  194.     LXI    H,NULL        ;        return(NULL);
  195.     RET
  196.                 ;        }
  197. FOPIF2:
  198.     LHLD    ZZIP        ;    ZZIP[UNUSED] = 0;
  199.     LXI    D,UNUSED
  200.     DAD    D
  201.     LXI    D,0
  202.     MOV    M,E
  203.     INX    H
  204.     MOV    M,D
  205.                 ;    }
  206.     JMP    FOPIFX
  207. FOPIF1:                ; else if(*mode=='W'){
  208.     LHLD    ZZMODE    
  209.     MOV    A,M
  210.     ANI    5FH
  211.     CPI    'W'        ;# WRITE MODE ?
  212.     JZ    FOPIFA        ;# YES - GO DO IT
  213.     CPI    'A'        ;# APPEND MODE ?
  214.     JNZ    FOPIF5        ;# NO  - BACK TO CALLER OF FOPEN
  215. ;                ;#     NO MODES LEFT TO TRY
  216. ;
  217.     MVI    C,OPEN        ;# FIRST LET'S SEE IF IT'S THERE
  218.     LHLD    ZZUNIT
  219.     XCHG
  220.     CALL    CBDOS
  221.     ORA    A
  222.     JP    FOPIF3        ;# YES  - SET IT UP FOR USE
  223. ;
  224.                 ;# NO   - LET'S MAKE ONE
  225.     LHLD    ZZMODE        ;# SET MODE TO 'W' ON NEW FILE
  226.     MVI    M,'W'        ;# TO AVOID WASTING TIME AND CODE
  227.                 ;# SEARCHING AN EMPTY FILE
  228. ;
  229. FOPIFA:
  230.     MVI    C,DELETE    ;    cpm(DELETE,unit);
  231.     LHLD    ZZUNIT
  232.     XCHG
  233.     CALL    CBDOS        ; (mod to cbdos(fas))
  234.     MVI    C,CREATE    ;    if(cpm(CREATE,unit)<0){
  235.     LHLD    ZZUNIT
  236.     XCHG
  237.     CALL    CBDOS        ; (mod to cbdos(fas))
  238.     ORA    A
  239.     JP    FOPIF3
  240.     LHLD    ZZUNIT        ;        freeio(unit);
  241.     PUSH    H
  242.     CALL    FREEIO
  243.     POP    H
  244.     LXI    H,NULL        ;        return(NULL);
  245.     RET
  246.                 ;        }
  247. FOPIF3:
  248.     LHLD    ZZIP        ;    ZZIP[UNUSED] = BUFSIZ;
  249.     LXI    D,UNUSED
  250.     DAD    D
  251.     LXI    D,BUFSIZ
  252.     MOV    M,E
  253.     INX    H
  254.     MOV    M,D
  255.     LHLD    ZZUNIT        ;    unit[FLAG] = WRITE_FL;
  256.     LXI    D,FLAG
  257.     DAD    D
  258.     MVI    A,WRTFLG
  259.     ORA    M
  260.     MOV    M,A
  261.     JMP    FOPIF4
  262.                 ;    }
  263. FOPIF5:
  264.     LHLD    ZZUNIT        ; else{    freeio(unit);
  265.     PUSH    H
  266.     CALL    FREEIO
  267.     POP    H
  268.     LXI    H,NULL        ;    return(NULL);
  269.     RET
  270. ;
  271.                 ;    }
  272. FOPIF4:
  273. ;
  274.     LHLD    ZZMODE        ;#
  275.     MOV    A,M        ;# GET MODE
  276.     ANI    5FH
  277.     CPI    'A'        ;# APPEND MODE ?
  278.     JNZ    FOPIFX        ;# NO  -  RETURN NORMALLY
  279. ;
  280. AMSCRD:
  281. ;
  282.     LDA    CUREXT        ;# SAVE EXTENT AND RECORD NUMBERS
  283.     STA    OLDEXT        ;#    TWO DEEP
  284.     LDA    CURREC
  285.     STA    OLDREC
  286.     LHLD    ZZUNIT
  287.     LXI    D,12
  288.     DAD    D
  289.     MOV    A,M        ;# GET CURRENT EXTENT #
  290.     STA    CUREXT
  291.     LXI    D,20
  292.     DAD    D
  293.     MOV    A,M        ;# GET CURRENT RECORD #
  294.     STA    CURREC
  295. ;
  296.     LHLD    ZZUNIT        ;# YES -  LET'S READ TO THE END
  297.     XCHG            ;# DE --> FCB
  298.     MVI    C,READ
  299.     CALL    CBDOS        ;# READ A SECTOR
  300.     ORA    A
  301.     JZ    AMSCRD        ;# READ TO PHYSICAL END OF FILE
  302. ;
  303.     LHLD    ZZUNIT
  304.     LXI    D,12
  305.     DAD    D
  306.     LDA    OLDEXT
  307.     MOV    M,A        ;# RESTORE LAST EXTENT #
  308.     LXI    D,20
  309.     DAD    D
  310.     LDA    OLDREC
  311.     MOV    M,A        ;# RESTORE LAST RECORD #
  312. ;
  313.     LXI    H,ZZBUF
  314.     SHLD    ZZTEMP        ;# SAVE THE BUFF. WE'RE READING FROM
  315. AMCHRD:
  316.     LHLD    ZZTEMP        ;# HL --> TEMPORARY BUFFER
  317.     MOV    A,M
  318. ;
  319.     CPI    0AH        ;# LINE FEED CHECK
  320.     JNZ    NOTLF
  321.     INX    H        ;# INCREMENT POINTER 
  322.     SHLD    ZZTEMP        ;#  AND GO ON TO NEXT CHARACTER
  323.     JMP    AMCHRD
  324. ;
  325. NOTLF:    CPI    1AH        ;# END OF FILE MARKER ?
  326.     JZ    FOPIFX        ;# YES - EXIT GRACEFULLY
  327.     MOV    C,A
  328.     MVI    B,0        ;# BC CONTAINS THE CHARACTER
  329.     INX    H
  330.     SHLD    ZZTEMP        ;# SAVE UPDATED POINTER
  331.     MOV    A,L
  332.     ORA    A        ;# END OF BUFFER ?
  333.     JZ    FOPIFX        ;# YES - EXIT JUST AS GRACEFUL
  334.     LHLD    ZZUNIT
  335.     PUSH    B
  336.     PUSH    H
  337.     CALL    PUTC        ;# PUTC(CHAR,ZZUNIT)
  338.     POP    B
  339.     POP    B
  340.     JMP    AMCHRD        ;# CONTINUE SCANNING
  341. ;
  342. FOPIFX:
  343.     LHLD    ZZUNIT        ; return(unit);
  344.     RET
  345. ;
  346. FCLOSE::
  347.     POP    B
  348.     POP    H
  349.     SHLD    ZZUNIT
  350.     PUSH    H
  351.     PUSH    B
  352.     MOV    A,H        ; if (unit<256)
  353.     ORA    A        ; /* assume stdin, stdout, etc. */
  354.     MVI    L,0    
  355.     RZ            ;     return NULL;
  356.     LXI    H,1        ; t = 1;
  357.     SHLD    ZZT
  358.     LHLD    ZZUNIT        ; if(unit[FLAG]    & WRITE_FL){
  359.     LXI    D,FLAG
  360.     DAD    D
  361.     MOV    A,M
  362.     ANI    WRTFLG
  363.     JZ    FCLIF1
  364.     LXI    H,CTRLZ        ;    putc(CTRL_Z,unit);    
  365.     PUSH    H
  366.     LHLD    ZZUNIT
  367.     PUSH    H
  368.     CALL    PUTC
  369.     POP    H
  370.     POP    H
  371.     LHLD    ZZUNIT        ;    ZZIP = unit + FCBSIZE;
  372.     LXI    D,FCBSIZE
  373.     DAD    D
  374.     SHLD    ZZIP
  375.     LHLD    ZZIP        ;        cp = ZZIP[NEXTP];
  376.     LXI    D,NEXTP
  377.     DAD    D
  378.     MOV    E,M
  379.     INX    H
  380.     MOV    D,M
  381.     XCHG
  382.     SHLD    ZZCHP
  383.     LHLD    ZZIP        ;    ZZDP = &ZZIP[BUFFER]+BUFSIZ;
  384.     LXI    D,BUFFER+BUFSIZ
  385.     DAD    D
  386.     SHLD    ZZDP
  387. FCLWH1:                ;        while(cp<ZZDP)
  388.     LHLD    ZZCHP
  389.     XCHG
  390.     LHLD    ZZDP
  391.     MOV    A,D
  392.     CMP    H
  393.     JC    FCLWH2
  394.     JNZ    FCLWH3
  395.     MOV    A,E
  396.     CMP    L
  397.     JNC    FCLWH3
  398. FCLWH2:                ;        *cp++ =    CTRL_Z;
  399.     LHLD    ZZCHP
  400.     MVI    M,CTRLZ
  401.     INX    H
  402.     SHLD    ZZCHP
  403.     JMP    FCLWH1
  404. FCLWH3:
  405.     LXI    H,WRITE        ;    if(cpmio(WRITE,unit)<0)
  406.     PUSH    H
  407.     LHLD    ZZUNIT
  408.     PUSH    H
  409.     CALL    CPMIO
  410.     POP    D
  411.     POP    D
  412.     MOV    A,H
  413.     ORA    A
  414.     JP    FCLIF4
  415.     LXI    H,0        ;            t = 0;
  416.     SHLD    ZZT
  417. FCLIF4:
  418.                 ;        }
  419. FCLIF3:
  420.                 ;    }
  421. FCLIF1:
  422.     MVI    C,CLOSE        ; if(cpm(CLOSE,unit)<0)
  423.     LHLD    ZZUNIT
  424.     XCHG
  425.     CALL    CBDOS        ; (mod tocbdos(fas))
  426.     ORA    A
  427.     JP    FCLIF5
  428.     LXI    H,0        ;    t = 0;
  429.     SHLD    ZZT
  430. FCLIF5:
  431.     LHLD    ZZUNIT        ; freeio(unit);
  432.     PUSH    H
  433.     CALL    FREEIO
  434.     POP    H
  435.     LHLD    ZZT        ; return(NULL+t);
  436.     RET
  437. ;
  438. ;    fcb(fp,name)
  439. ;
  440. FCB::
  441.     POP    H        ;get args
  442.     POP    D        ;name
  443.     POP    B        ;fp
  444.     PUSH    B
  445.     PUSH    D
  446.     PUSH    H
  447.     INX    D        ; if(name[1]==':'){
  448.     LDAX    D
  449.     DCX    D
  450.     CPI    ':'
  451.     JNZ    FCBIF1
  452.     LDAX    D        ;    A = *name - '@';
  453.     SUI    40H        ; '@' 9    Jun 80 rj
  454.         
  455.     INX    D        ;    name +=    2;
  456.     INX    D
  457.     
  458.     CPI    61H-41H        ;   if(A>'a'-'A') /* lower case? */
  459.     JC    FCBIF2
  460.     SUI    61H-41H        ;       A -= 'a'-'A'
  461.     JMP    FCBIF2        ;    }
  462. FCBIF1:
  463.     LDA    ZZDFLT        ; else    A = default_drive;
  464. FCBIF2:
  465.     STAX    B        ; *fp++    = A;
  466.     INX    B
  467.     MVI    H,' '        ; fp = fcbfill(fp,name,' ',8);
  468.     MVI    L,8
  469.     CALL    FCBFILL
  470.     MVI    L,3        ; fp = fcbfill(fp,name,' ',3);
  471.     CALL    FCBFILL
  472.     MVI    H,0        ; fp = fcbpad(fp,0,4);
  473.     MVI    L,4
  474.     CALL    FCBPAD
  475.     LXI    H,16        ; fp[16] = 0;
  476.     DAD    B
  477.     MVI    M,0
  478.     RET            ; return;
  479. ;
  480. ;    fcbfill(dest,name,pad,size)
  481. ;        B    D      H   L
  482. ;
  483. FCBFILL::
  484.     MOV    A,L        ; while(L>0 && (A= *D)~='.' && A~=0){
  485.     ORA    A
  486.     JZ    FILL2
  487.     LDAX    D
  488.     CPI    '.'
  489.     JZ    FILL2
  490.     CPI    0
  491.     JZ    FILL2
  492.     CPI    61H        ;    if(A>='a' && A<='z')
  493.     JC    FILL1
  494.     CPI    7AH+1        ; 'z' 9    Jun 80 rj
  495.     JNC    FILL1
  496.     SUI    61H-41H        ;        A = A -    'a' + 'A';
  497. FILL1:
  498.     STAX    B        ;    *B++ = A;
  499.     INX    B
  500.     INX    D        ;    D++;
  501.     DCR    L        ;    L--;
  502.     JMP    FCBFILL        ;    }
  503. FILL2:
  504.     LDAX    D        ; while(*D~='.'    && *D~=0)    
  505.     CPI    '.'
  506.     JZ    FILL3
  507.     CPI    0
  508.     JZ    FILL3
  509.     INX    D        ;    D++;
  510.     JMP    FILL2
  511. FILL3:
  512.     CPI    '.'        ; if(*D=='.')
  513.     JNZ    FILL4
  514.     INX    D        ;    D++;
  515. FILL4:
  516. ;    fall into...
  517. ;
  518. ;    fcbpad(dest,pad,size)
  519. ;        B   H    L
  520. ;
  521. FCBPAD::
  522.     MOV    A,L        ; while(L>0){
  523.     ORA    A
  524.     JZ    PAD2
  525.     MOV    A,H        ;    *B++ = H;
  526.     STAX    B
  527.     INX    B
  528.     DCR    L        ;    L--;
  529.     JMP    FCBPAD        ;    }
  530. PAD2:
  531.     RET            ; return;
  532. ;
  533. ;
  534.     END
  535.  
  536.