home *** CD-ROM | disk | FTP | other *** search
- #include <dos.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <fcntl.h>
-
- /*
- |
- | FROMC.EXE
- |
- | USAGE:
- | FROMC [filename[.ext]]<CR>
- |
- | [filename[.ext]] is used to specify the file(s) which
- | you want to get from COCO disks.
- |
- | This function also has the side effect of giving you
- | directory information as it copies (an added
- | benefit).
- |
- | 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 *.
- |
- */
-
- #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 lastsec;
- FILE *filptr;
- char *fname = " \r";
-
- 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*/
- "???????????";
-
- char inbuff[GSIZE]; /* Input buffer for granules */
-
- union REGS inregs;
- union REGS outregs;
- struct SREGS segregs;
-
- main(argc,argv) /* main -- Start of DIRC.EXE execution */
- int argc;
- char *argv[];
- {
- char far *(far *vec78h);
- char far *bpsvec;
-
- int scnt, ecnt;
- int mode, gran, lbytes, type;
-
- unsigned char *bufp;
-
- checkaok();
-
- printf(" Volume in drive %c is COCO disk\n",DRIVENAME);
- printf(" Copying files from 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;
-
- cread(17,2,fat,1);
-
- for(scnt=0;scnt<9;scnt++) { /* Main loop for directory read */
-
- cread(17,scnt+3,dirbuf,1);
-
- 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("Copying %.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,bufp);
-
- if (filok) {
- printf("%s",typetab[type]);
- if (mode!=0) mode=1; /* now simply ascii or not */
- printf("%s\n",asciitab[mode]);
- }
- }
- bufp += DIRENT;
- }
- }
- printf("Done: %5d File(s) copied\n",fcount);
-
- *bpsvec = (char) nbsec; /* Set byte to MSDOS value */
- }
-
- /* calcdisp -- calculate file size, and display if necessary */
-
- calcdisp(mode,gran,lbytes,type,name)
- int mode,gran,lbytes,type;
- char *name;
- {
- int bytecnt,tgran;
-
- gcount = 0;
- bytecnt = lbytes;
-
- if (filok) openfile(name);
-
- lastsec = lbytes;
-
- do {
- tgran = gran;
- grans--;
- gcount++;
- gran = (int) *(fat+gran);
- if (gran & 0x80) {
- if (filok) copylast(tgran,gran & 0x3f);
- gran = (gran & 0x3f)-1;
- if (gran>0) bytecnt += gran*SECSIZE;
- gran=-1;
- break;
- }
- if (filok) copygran(tgran);
- bytecnt += (int) GSIZE;
- } while (gran>=0);
- if (filok) printf("%5d%5d ",bytecnt,gcount);
- }
-
-
- /* 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;
- FP_OFF(pspfspec) = 0x5d;
-
- chk1 = *pspfspec;
- nbuf=fbuf;
-
- if (chk1==' ' || chk1=='?') filaok=1; else filaok=0;
-
- for(cnt=0;cnt<11;cnt++) {
- *nbuf = *pspfspec++;
- if (*nbuf++!=chk1) 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;
- }
-
- openfile(name)
- char *name;
- {
- int cnt;
- char *fptr;
-
- fptr = fname;
-
- for(cnt=0;cnt<8;cnt++) *fptr++ = *(name+cnt);
- while (*(fptr-1)==' ' && fptr>fname) fptr--;
- *fptr++ = '.';
- for(cnt=8;cnt<11;cnt++) *fptr++ = *(name+cnt);
- while ((*(fptr-1)==' ' || *(fptr-1)=='.') && fptr>fname) fptr--;
- *fptr = 0;
-
- filptr = fopen(fname,"w+b");
- }
-
- copygran(gran)
- int gran;
- {
- int secstart;
-
- if (gran>=34) gran += 2;
- secstart = (gran & 1)*9+1;
- gran /= 2;
-
- cread(gran,secstart,inbuff,9);
-
- fwrite(inbuff,GSIZE,1,filptr);
- }
-
- copylast(gran,nsec)
- int gran,nsec;
- {
- int secstart;
-
- if (gran>=34) gran+=2;
- secstart = (gran & 1)*9+1;
- gran /= 2;
-
- cread(gran,secstart,inbuff,9);
-
- nsec -= 1;
- if (nsec<0) nsec=0;
-
- fwrite(inbuff,SECSIZE*nsec+lastsec,1,filptr);
-
- fclose(filptr);
- }
-
- 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;
- if (trk>39 || sec>18) return(-1);
-
- 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);
- }
-