home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 223_02 / filelib.mac < prev    next >
Text File  |  1989-02-23  |  10KB  |  541 lines

  1. ; filelib.mac
  2. ;
  3. ;        Small-C     File  Library  Version 2.0
  4. ;
  5. ;                by
  6. ;
  7. ;            Fred A. Scacchitti
  8. ;            25 Glenview Lane
  9. ;            Roch., NY 14609
  10. ;
  11. ;              3 - 22 - 86
  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.70
  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. ;
  316.     XRA    A
  317.     STA    OLDREC        ;# use oldrec for a counter
  318. AMCHRD:
  319.     LHLD    ZZTEMP        ;# HL --> TEMPORARY BUFFER
  320.     MOV    A,M
  321. ;
  322.     CPI    0AH        ;# LINE FEED CHECK
  323.     JNZ    NOTLF
  324.     INX    H        ;# INCREMENT POINTER 
  325.     SHLD    ZZTEMP        ;#  AND GO ON TO NEXT CHARACTER
  326.     JMP    AMCHRD
  327. ;
  328. NOTLF:    CPI    1AH        ;# END OF FILE MARKER ?
  329.     JZ    FOPIFX        ;# YES - EXIT GRACEFULLY
  330.     MOV    C,A
  331.     MVI    B,0        ;# BC CONTAINS THE CHARACTER
  332.     INX    H
  333.     SHLD    ZZTEMP        ;# SAVE UPDATED POINTER
  334.     LHLD    ZZUNIT
  335.     PUSH    B
  336.     PUSH    H
  337.     CALL    PUTC        ;# PUTC(CHAR,ZZUNIT)
  338.     POP    B
  339.     POP    B
  340. ;
  341.     LDA    OLDREC        ;# get the counter
  342.     INR    A        ;# add a count
  343.     STA    OLDREC        ;# store it
  344. ;
  345.     JNZ    AMCHRD        ;# keep going (max 128 bytes)
  346. ;
  347. FOPIFX:
  348.     LHLD    ZZUNIT        ; return(unit);
  349.     RET
  350. ;
  351. FCLOSE::
  352.     POP    B
  353.     POP    H
  354.     SHLD    ZZUNIT
  355.     PUSH    H
  356.     PUSH    B
  357.     MOV    A,H        ; if (unit<256)
  358.     ORA    A        ; /* assume stdin, stdout, etc. */
  359.     MVI    L,0    
  360.     RZ            ;     return NULL;
  361.     LXI    H,1        ; t = 1;
  362.     SHLD    ZZT
  363.     LHLD    ZZUNIT        ; if(unit[FLAG]    & WRITE_FL){
  364.     LXI    D,FLAG
  365.     DAD    D
  366.     MOV    A,M
  367.     ANI    WRTFLG
  368.     JZ    FCLIF1
  369.     LXI    H,CTRLZ        ;    putc(CTRL_Z,unit);    
  370.     PUSH    H
  371.     LHLD    ZZUNIT
  372.     PUSH    H
  373.     CALL    PUTC
  374.     POP    H
  375.     POP    H
  376.     LHLD    ZZUNIT        ;    ZZIP = unit + FCBSIZE;
  377.     LXI    D,FCBSIZE
  378.     DAD    D
  379.     SHLD    ZZIP
  380.     LHLD    ZZIP        ;        cp = ZZIP[NEXTP];
  381.     LXI    D,NEXTP
  382.     DAD    D
  383.     MOV    E,M
  384.     INX    H
  385.     MOV    D,M
  386.     XCHG
  387.     SHLD    ZZCHP
  388.     LHLD    ZZIP        ;    ZZDP = &ZZIP[BUFFER]+BUFSIZ;
  389.     LXI    D,BUFFER+BUFSIZ
  390.     DAD    D
  391.     SHLD    ZZDP
  392. FCLWH1:                ;        while(cp<ZZDP)
  393.     LHLD    ZZCHP
  394.     XCHG
  395.     LHLD    ZZDP
  396.     MOV    A,D
  397.     CMP    H
  398.     JC    FCLWH2
  399.     JNZ    FCLWH3
  400.     MOV    A,E
  401.     CMP    L
  402.     JNC    FCLWH3
  403. FCLWH2:                ;        *cp++ =    CTRL_Z;
  404.     LHLD    ZZCHP
  405.     MVI    M,CTRLZ
  406.     INX    H
  407.     SHLD    ZZCHP
  408.     JMP    FCLWH1
  409. FCLWH3:
  410.     LXI    H,WRITE        ;    if(cpmio(WRITE,unit)<0)
  411.     PUSH    H
  412.     LHLD    ZZUNIT
  413.     PUSH    H
  414.     CALL    CPMIO
  415.     POP    D
  416.     POP    D
  417.     MOV    A,H
  418.     ORA    A
  419.     JP    FCLIF4
  420.     LXI    H,0        ;            t = 0;
  421.     SHLD    ZZT
  422. FCLIF4:
  423.                 ;        }
  424. FCLIF3:
  425.                 ;    }
  426. FCLIF1:
  427.     MVI    C,CLOSE        ; if(cpm(CLOSE,unit)<0)
  428.     LHLD    ZZUNIT
  429.     XCHG
  430.     CALL    CBDOS        ; (mod tocbdos(fas))
  431.     ORA    A
  432.     JP    FCLIF5
  433.     LXI    H,0        ;    t = 0;
  434.     SHLD    ZZT
  435. FCLIF5:
  436.     LHLD    ZZUNIT        ; freeio(unit);
  437.     PUSH    H
  438.     CALL    FREEIO
  439.     POP    H
  440.     LHLD    ZZT        ; return(NULL+t);
  441.     RET
  442. ;
  443. ;    fcb(fp,name)
  444. ;
  445. FCB::
  446.     POP    H        ;get args
  447.     POP    D        ;name
  448.     POP    B        ;fp
  449.     PUSH    B
  450.     PUSH    D
  451.     PUSH    H
  452.     INX    D        ; if(name[1]==':'){
  453.     LDAX    D
  454.     DCX    D
  455.     CPI    ':'
  456.     JNZ    FCBIF1
  457.     LDAX    D        ;    A = *name - '@';
  458.     SUI    40H        ; '@' 9    Jun 80 rj
  459.         
  460.     INX    D        ;    name +=    2;
  461.     INX    D
  462.     
  463.     CPI    61H-41H        ;   if(A>'a'-'A') /* lower case? */
  464.     JC    FCBIF2
  465.     SUI    61H-41H        ;       A -= 'a'-'A'
  466.     JMP    FCBIF2        ;    }
  467. FCBIF1:
  468.     LDA    ZZDFLT        ; else    A = default_drive;
  469. FCBIF2:
  470.     STAX    B        ; *fp++    = A;
  471.     INX    B
  472.     MVI    H,' '        ; fp = fcbfill(fp,name,' ',8);
  473.     MVI    L,8
  474.     CALL    FCBFILL
  475.     MVI    L,3        ; fp = fcbfill(fp,name,' ',3);
  476.     CALL    FCBFILL
  477.     MVI    H,0        ; fp = fcbpad(fp,0,4);
  478.     MVI    L,4
  479.     CALL    FCBPAD
  480.     LXI    H,16        ; fp[16] = 0;
  481.     DAD    B
  482.     MVI    M,0
  483.     RET            ; return;
  484. ;
  485. ;    fcbfill(dest,name,pad,size)
  486. ;        B    D      H   L
  487. ;
  488. FCBFILL::
  489.     MOV    A,L        ; while(L>0 && (A= *D)~='.' && A~=0){
  490.     ORA    A
  491.     JZ    FILL2
  492.     LDAX    D
  493.     CPI    '.'
  494.     JZ    FILL2
  495.     CPI    0
  496.     JZ    FILL2
  497.     CPI    61H        ;    if(A>='a' && A<='z')
  498.     JC    FILL1
  499.     CPI    7AH+1        ; 'z' 9    Jun 80 rj
  500.     JNC    FILL1
  501.     SUI    61H-41H        ;        A = A -    'a' + 'A';
  502. FILL1:
  503.     STAX    B        ;    *B++ = A;
  504.     INX    B
  505.     INX    D        ;    D++;
  506.     DCR    L        ;    L--;
  507.     JMP    FCBFILL        ;    }
  508. FILL2:
  509.     LDAX    D        ; while(*D~='.'    && *D~=0)    
  510.     CPI    '.'
  511.     JZ    FILL3
  512.     CPI    0
  513.     JZ    FILL3
  514.     INX    D        ;    D++;
  515.     JMP    FILL2
  516. FILL3:
  517.     CPI    '.'        ; if(*D=='.')
  518.     JNZ    FILL4
  519.     INX    D        ;    D++;
  520. FILL4:
  521. ;    fall into...
  522. ;
  523. ;    fcbpad(dest,pad,size)
  524. ;        B   H    L
  525. ;
  526. FCBPAD::
  527.     MOV    A,L        ; while(L>0){
  528.     ORA    A
  529.     JZ    PAD2
  530.     MOV    A,H        ;    *B++ = H;
  531.     STAX    B
  532.     INX    B
  533.     DCR    L        ;    L--;
  534.     JMP    FCBPAD        ;    }
  535. PAD2:
  536.     RET            ; return;
  537. ;
  538. ;
  539.     END
  540.  
  541.