home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume4 / dos2coco / dirc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-03  |  6.4 KB  |  242 lines

  1. #include <dos.h>
  2. #include <stdlib.h>
  3.  
  4. /*
  5.  |
  6.  |    DIRC.EXE
  7.  |
  8.  |    USAGE:
  9.  |        DIRC [filename[.ext]]<CR>
  10.  |
  11.  |        [filename[.ext]] is used to specify the file(s) whose
  12.  |            directory you want to list.
  13.  |
  14.  |        The information provided includes the free space on the disk.
  15.  |            The freespace is listed both in Granules and Bytes.
  16.  |            The display for each file includes its size in bytes,
  17.  |                the number of granules it occupies, the file
  18.  |                type, and the file mode.
  19.  |
  20.  |        You may use the global characters ? and * in the filename and
  21.  |            extention parameters.
  22.  |
  23.  |        If you do not specify a filename, it defaults to *.*
  24.  |
  25.  |        If you do not specify a filename extention, it defaults to *.
  26.  |
  27.  |    Notes:  Currently sector errors are not dealt with very well, but
  28.  |        then again, I've never seen one.  The funtions do return
  29.  |        error values, but they are not checked.  Also note that
  30.  |        this program was very closely based on my working assembler
  31.  |        from about two years ago, and I just did a quick translation
  32.  |        without doing much careful thought about improvements, of
  33.  |        which there are probably many.
  34.  */
  35.  
  36. #define    DRIVENAME    'A'
  37. #define    DRIVENO        (DRIVENAME-'A')
  38.  
  39. char *typetab[4] = {    /* Types for COCO directory entries */
  40.     "BASIC    ",
  41.     "Data     ",
  42.     "Program  ",
  43.     "Text     "
  44. };
  45. char *asciitab[2] = {    /* File modes for COCO directory entries */
  46.     "Binary",
  47.     "ASCII"
  48. };
  49.  
  50. int fcount, gcount;    /* File/Granule count for dir info */
  51. int filaok, filok;    /* For wildcarding, always ok and this ok */
  52.  
  53. int grans;
  54.  
  55. #define GRANS    68    /* Number of grans on the disk */
  56. #define GSIZE    2304    /* Number of bytes per granule */
  57. #define SECSIZE    256    /* Number of bytes per sector */
  58. #define DIRENT    32    /* Number of bytes per directory entry */
  59.  
  60. int nbsec;        /* Save area for MSDOS value (must restore)*/
  61. char far *thisseg = " ";/* used to find data segment */
  62. char fat[SECSIZE];        /* FAT information buffer from COCO disk */
  63. char dirbuf[SECSIZE];    /* Directory sector buffer from COCO disk */
  64.  
  65. char fbuf[11] =        /* file buffer for comparison to fspec given*/
  66.      "???????????";
  67.  
  68. union REGS inregs;
  69. union REGS outregs;
  70. struct SREGS segregs;
  71.  
  72. main(argc,argv)        /*    main -- Start of DIRC.EXE execution */
  73. int argc;        /* I did not use argc/argv in lieu of DOS's */
  74. char *argv[];        /* PSP for sake of easy wildcard expansions */
  75. {
  76.     char far *(far *vec78h);    /* We need to play with the disk */
  77.     char far *bpsvec;        /* control block area         */
  78.  
  79.     int scnt, ecnt;            /* sector count and entry count     */
  80.     int mode, gran, lbytes, type;
  81.  
  82.     unsigned char *bufp;
  83.  
  84.     checkaok();            /* a little parsing on the PSP     */
  85.  
  86.     printf(" Volume in drive %c is COCO disk\n",DRIVENAME);
  87.     printf(" Directory of COCO disk\n\n");
  88.  
  89.     vec78h = (char far *(far *))(0x78);
  90.                 /* 0000:0078, MSDOS disk info pointer */
  91.     bpsvec = 3 + *vec78h;    /* Get MSDOS bytes per sector ptr */
  92.  
  93.     nbsec = (int) *bpsvec;    /* Save byte for restore later */
  94.     *bpsvec = (char) 1;    /* Set byte to 1 (256 bytes/sector) */
  95.  
  96.     fcount = 0;        /* initialize */
  97.     grans = GRANS;        /* will be used to count down available */
  98.  
  99.     cread(17,2,fat,1);    /* Read coco sector, track 17 sec 2 */
  100.  
  101.     for(scnt=0;scnt<9;scnt++) {    /* Main loop for directory read */
  102.  
  103.         cread(17,scnt+3,dirbuf,1);    /* Read directory sectors    */
  104.  
  105.         bufp = dirbuf;
  106.  
  107.         for(ecnt=0;ecnt<8;ecnt++) if (*bufp!=0xff) {
  108.                         /* entries per sector = 8 */
  109.                         /* ...for each file entry: */
  110.         if (*bufp) {
  111.             checkfil(bufp);        /* Check if it's ok to list */
  112.                         /* result: filok=1, yes */
  113.             if (filok) {
  114.             fcount++;        /* count it, and print name */
  115.             printf("%.8s %.3s    ",bufp,(char *) bufp+8);
  116.             }
  117.  
  118.             mode = (int) *(bufp+12);
  119.             gran = (int) *(bufp+13);
  120.             lbytes = ( (256 * (int)(*(bufp+14))) +
  121.                  (int)(*(bufp+15)) );/* Count is in 6809 format */
  122.                          /* high, then low byte     */
  123.             type = (int) *(bufp+11);
  124.             calcdisp(mode,gran,lbytes,type);
  125.  
  126.             if (filok) {
  127.             printf("%s",typetab[type]);
  128.             if (mode!=0) mode=1;    /* now simply ascii or not */
  129.             printf("%s\n",asciitab[mode]);
  130.             }
  131.         }
  132.         bufp += DIRENT;
  133.         }
  134.     }
  135.     printf("   %5d File(s)%5d Grans, %6ld Bytes free\n",
  136.         fcount, grans,(long) grans*GSIZE);
  137.  
  138.     *bpsvec = (char) nbsec;    /* Set byte to MSDOS value */
  139. }
  140.  
  141. /* calcdisp -- calculate file size, and display if necessary */
  142.  
  143. calcdisp(mode,gran,lbytes,type)
  144. int mode,gran,lbytes,type;
  145. {
  146.     int bytecnt;
  147.  
  148.     gcount = 0;
  149.     bytecnt = lbytes;
  150.  
  151.     do {
  152.         grans--;            /* one less granule avail  */
  153.         gcount++;            /* one more allocated here */
  154.         gran = (int) *(fat+gran);    /* point to next granule   */
  155.         if (gran & 0x80) {        /* if high bit set, last   */
  156.             gran = (gran & 0x3f)-1;    /* find remaining sectors  */
  157.             if (gran>0) bytecnt += gran*SECSIZE;
  158.             break;            /* done               */
  159.         }
  160.         bytecnt += GSIZE;        /* add gran length       */
  161.     } while (gran>=0);            /* we'll actually break    */
  162.     if (filok) printf("%5d%5d  ",bytecnt,gcount); /* print if needed   */
  163. }
  164.  
  165.  
  166. /* check if all are ok, and if not, set up compare buffer for comparisons */
  167. checkaok()
  168. {
  169.     char far *pspfspec;
  170.     int cnt;
  171.     char chk1;
  172.     char *nbuf;
  173.  
  174.     FP_SEG(pspfspec) = _psp;        /* Use the PSP, dos is nice */
  175.     FP_OFF(pspfspec) = 0x5d;        /* to us on wildcards        */
  176.  
  177.     chk1 = *pspfspec;            /* get first character        */
  178.     nbuf=fbuf;
  179.  
  180.     if (chk1==' ' || chk1=='?') {
  181.         filaok=1;            /* if all blank or all '?'  */
  182.         for(cnt=0;cnt<11;cnt++) {
  183.             *nbuf = *pspfspec++;
  184.             if (*nbuf++!=chk1) filaok = 0;
  185.         }                /* if filaok then ALL files */
  186.     } else filaok=0;
  187. }
  188.  
  189. /*    checkfil -- check a file to see if it matches comparison value */
  190. checkfil(nbuf)
  191. char *nbuf;
  192. {
  193.     int cnt;
  194.     filok = 1;
  195.     if (filaok) return;
  196.  
  197.     for (cnt=0;cnt<11;cnt++)
  198.         if ((*(fbuf+cnt) != '?') &&
  199.             (*(fbuf+cnt) != *(nbuf+cnt))) filok=0;
  200.     return;
  201. }
  202.  
  203. int cread(trk,sec,buf,cnt)
  204. int trk,sec;
  205. char *buf;
  206. int cnt;
  207. {
  208.     int errcnt;
  209.     char *temp;
  210.  
  211.     errcnt = 0;
  212.     for(temp=buf;temp<buf+SECSIZE*cnt;temp++) *temp=0; /* zero buff */
  213.     if (trk>39 || sec>18) return(-1);    /* don't read bad ptr's */
  214.  
  215.     while (errcnt<4) {
  216.         inregs.x.ax = 0x0200+(cnt & 0xff);/* 2 = read, Count=cnt */
  217.         inregs.x.bx = (int) buf;    /* pointer to buffer */
  218.         inregs.x.cx = (int) (trk & 0xff)*256
  219.                    +(sec & 0xff);/* Track , Sector */
  220.         inregs.x.dx = DRIVENO;        /* Drive select byte */
  221.         segregs.ds = FP_SEG(thisseg);
  222.         segregs.es = FP_SEG(thisseg);
  223.  
  224.         int86x(0x13,&inregs,&outregs,&segregs);
  225.         if (outregs.x.cflag==0) break;
  226.         creset();
  227.         errcnt++;
  228.     }
  229.     return(errcnt);
  230. }
  231.  
  232. int creset()
  233. {
  234.     inregs.x.ax = 0x0000;        /* 2 = read function, Count=cnt */
  235.     inregs.x.dx = DRIVENO;        /* Drive select byte */
  236.     segregs.ds = FP_SEG(thisseg);
  237.     segregs.es = FP_SEG(thisseg);
  238.  
  239.     int86x(0x13,&inregs,&outregs,&segregs);
  240.     return(outregs.x.cflag);
  241. }
  242.