home *** CD-ROM | disk | FTP | other *** search
- #include <dos.h>
- #include <stdlib.h>
-
- /*
- |
- | DIRC.EXE
- |
- | USAGE:
- | DIRC [filename[.ext]]<CR>
- |
- | [filename[.ext]] is used to specify the file(s) whose
- | directory you want to list.
- |
- | The information provided includes the free space on the disk.
- | The freespace is listed both in Granules and Bytes.
- | The display for each file includes its size in bytes,
- | the number of granules it occupies, the file
- | type, and the file mode.
- |
- | You may use the global characters ? and * in the filename and
- | extention parameters.
- |
- | If you do not specify a filename, it defaults to *.*
- |
- | If you do not specify a filename extention, it defaults to *.
- |
- | Notes: Currently sector errors are not dealt with very well, but
- | then again, I've never seen one. The funtions do return
- | error values, but they are not checked. Also note that
- | this program was very closely based on my working assembler
- | from about two years ago, and I just did a quick translation
- | without doing much careful thought about improvements, of
- | which there are probably many.
- */
-
- #define DRIVENAME 'A'
- #define DRIVENO (DRIVENAME-'A')
-
- char *typetab[4] = { /* Types for COCO directory entries */
- "BASIC ",
- "Data ",
- "Program ",
- "Text "
- };
- char *asciitab[2] = { /* File modes for COCO directory entries */
- "Binary",
- "ASCII"
- };
-
- int fcount, gcount; /* File/Granule count for dir info */
- int filaok, filok; /* For wildcarding, always ok and this ok */
-
- int grans;
-
- #define GRANS 68 /* Number of grans on the disk */
- #define GSIZE 2304 /* Number of bytes per granule */
- #define SECSIZE 256 /* Number of bytes per sector */
- #define DIRENT 32 /* Number of bytes per directory entry */
-
- int nbsec; /* Save area for MSDOS value (must restore)*/
- char far *thisseg = " ";/* used to find data segment */
- char fat[SECSIZE]; /* FAT information buffer from COCO disk */
- char dirbuf[SECSIZE]; /* Directory sector buffer from COCO disk */
-
- char fbuf[11] = /* file buffer for comparison to fspec given*/
- "???????????";
-
- union REGS inregs;
- union REGS outregs;
- struct SREGS segregs;
-
- main(argc,argv) /* main -- Start of DIRC.EXE execution */
- int argc; /* I did not use argc/argv in lieu of DOS's */
- char *argv[]; /* PSP for sake of easy wildcard expansions */
- {
- char far *(far *vec78h); /* We need to play with the disk */
- char far *bpsvec; /* control block area */
-
- int scnt, ecnt; /* sector count and entry count */
- int mode, gran, lbytes, type;
-
- unsigned char *bufp;
-
- checkaok(); /* a little parsing on the PSP */
-
- printf(" Volume in drive %c is COCO disk\n",DRIVENAME);
- printf(" Directory of COCO disk\n\n");
-
- vec78h = (char far *(far *))(0x78);
- /* 0000:0078, MSDOS disk info pointer */
- bpsvec = 3 + *vec78h; /* Get MSDOS bytes per sector ptr */
-
- nbsec = (int) *bpsvec; /* Save byte for restore later */
- *bpsvec = (char) 1; /* Set byte to 1 (256 bytes/sector) */
-
- fcount = 0; /* initialize */
- grans = GRANS; /* will be used to count down available */
-
- cread(17,2,fat,1); /* Read coco sector, track 17 sec 2 */
-
- for(scnt=0;scnt<9;scnt++) { /* Main loop for directory read */
-
- cread(17,scnt+3,dirbuf,1); /* Read directory sectors */
-
- bufp = dirbuf;
-
- for(ecnt=0;ecnt<8;ecnt++) if (*bufp!=0xff) {
- /* entries per sector = 8 */
- /* ...for each file entry: */
- if (*bufp) {
- checkfil(bufp); /* Check if it's ok to list */
- /* result: filok=1, yes */
- if (filok) {
- fcount++; /* count it, and print name */
- printf("%.8s %.3s ",bufp,(char *) bufp+8);
- }
-
- mode = (int) *(bufp+12);
- gran = (int) *(bufp+13);
- lbytes = ( (256 * (int)(*(bufp+14))) +
- (int)(*(bufp+15)) );/* Count is in 6809 format */
- /* high, then low byte */
- type = (int) *(bufp+11);
- calcdisp(mode,gran,lbytes,type);
-
- if (filok) {
- printf("%s",typetab[type]);
- if (mode!=0) mode=1; /* now simply ascii or not */
- printf("%s\n",asciitab[mode]);
- }
- }
- bufp += DIRENT;
- }
- }
- printf(" %5d File(s)%5d Grans, %6ld Bytes free\n",
- fcount, grans,(long) grans*GSIZE);
-
- *bpsvec = (char) nbsec; /* Set byte to MSDOS value */
- }
-
- /* calcdisp -- calculate file size, and display if necessary */
-
- calcdisp(mode,gran,lbytes,type)
- int mode,gran,lbytes,type;
- {
- int bytecnt;
-
- gcount = 0;
- bytecnt = lbytes;
-
- do {
- grans--; /* one less granule avail */
- gcount++; /* one more allocated here */
- gran = (int) *(fat+gran); /* point to next granule */
- if (gran & 0x80) { /* if high bit set, last */
- gran = (gran & 0x3f)-1; /* find remaining sectors */
- if (gran>0) bytecnt += gran*SECSIZE;
- break; /* done */
- }
- bytecnt += GSIZE; /* add gran length */
- } while (gran>=0); /* we'll actually break */
- if (filok) printf("%5d%5d ",bytecnt,gcount); /* print if needed */
- }
-
-
- /* check if all are ok, and if not, set up compare buffer for comparisons */
- checkaok()
- {
- char far *pspfspec;
- int cnt;
- char chk1;
- char *nbuf;
-
- FP_SEG(pspfspec) = _psp; /* Use the PSP, dos is nice */
- FP_OFF(pspfspec) = 0x5d; /* to us on wildcards */
-
- chk1 = *pspfspec; /* get first character */
- nbuf=fbuf;
-
- if (chk1==' ' || chk1=='?') {
- filaok=1; /* if all blank or all '?' */
- for(cnt=0;cnt<11;cnt++) {
- *nbuf = *pspfspec++;
- if (*nbuf++!=chk1) filaok = 0;
- } /* if filaok then ALL files */
- } else filaok=0;
- }
-
- /* checkfil -- check a file to see if it matches comparison value */
- checkfil(nbuf)
- char *nbuf;
- {
- int cnt;
- filok = 1;
- if (filaok) return;
-
- for (cnt=0;cnt<11;cnt++)
- if ((*(fbuf+cnt) != '?') &&
- (*(fbuf+cnt) != *(nbuf+cnt))) filok=0;
- return;
- }
-
- int cread(trk,sec,buf,cnt)
- int trk,sec;
- char *buf;
- int cnt;
- {
- int errcnt;
- char *temp;
-
- errcnt = 0;
- for(temp=buf;temp<buf+SECSIZE*cnt;temp++) *temp=0; /* zero buff */
- if (trk>39 || sec>18) return(-1); /* don't read bad ptr's */
-
- while (errcnt<4) {
- inregs.x.ax = 0x0200+(cnt & 0xff);/* 2 = read, Count=cnt */
- inregs.x.bx = (int) buf; /* pointer to buffer */
- inregs.x.cx = (int) (trk & 0xff)*256
- +(sec & 0xff);/* Track , Sector */
- inregs.x.dx = DRIVENO; /* Drive select byte */
- segregs.ds = FP_SEG(thisseg);
- segregs.es = FP_SEG(thisseg);
-
- int86x(0x13,&inregs,&outregs,&segregs);
- if (outregs.x.cflag==0) break;
- creset();
- errcnt++;
- }
- return(errcnt);
- }
-
- int creset()
- {
- inregs.x.ax = 0x0000; /* 2 = read function, Count=cnt */
- inregs.x.dx = DRIVENO; /* Drive select byte */
- segregs.ds = FP_SEG(thisseg);
- segregs.es = FP_SEG(thisseg);
-
- int86x(0x13,&inregs,&outregs,&segregs);
- return(outregs.x.cflag);
- }
-