home *** CD-ROM | disk | FTP | other *** search
- #include <dos.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <io.h>
-
- /*
- |
- | TOC.EXE
- |
- | USAGE:
- | TOC filename.ext {BDPT} {AB}<CR>
- |
- | filename.ext is used to specify the file which you want
- | to transfer. NO wildcards are supported, and you
- | MUST include a file type and mode.
- |
- | This is a derivitive of DIRC.C (can you tell?)
- */
-
- #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;
-
- unsigned long int numb;
- unsigned int numg,numrs,numrb;
-
- main(argc,argv) /* main -- Start of DIRC.EXE execution */
- int argc;
- char *argv[];
- {
- char far *(far *vec78h);
- char far *bpsvec;
-
- int scnt, ecnt, cnt, lcnt;
- unsigned int mode, gran, lbytes, type;
-
- unsigned char *bufp;
-
- if (argc!=4) {
- printf("Usage: toc (fspec) {BDPT} {AB}\n");
- exit(1);
- }
- switch (*argv[2]) {
- case 'b':
- case 'B': {
- type = 0;
- break;
- }
- case 'd':
- case 'D': {
- type = 1;
- break;
- }
- case 'p':
- case 'P': {
- type = 2;
- break;
- }
- case 't':
- case 'T': {
- type = 3;
- break;
- }
- default: {
- printf("Bad parameter: %c\n",*argv[2]);
- exit(1);
- }
- }
- switch (*argv[3]) {
- case 'a':
- case 'A': {
- mode = 1;
- break;
- }
- case 'b':
- case 'B': {
- mode = 0;
- break;
- }
- default: {
- printf("Bad parameter: %c\n",*argv[3]);
- exit(1);
- }
- }
- checkaok();
- openfile(fbuf);
- numb = filelength(fileno(filptr));
- numg = (int) (numb/GSIZE)+1;
- numrb = numb - (numg-1)*GSIZE;
- numrs = (int) (numrb/SECSIZE)+1;
- numrb -= (numrs-1)*SECSIZE;
-
- printf(" Copying %s to COCO disk in drive %c\n",fname,DRIVENAME);
- printf(" Type = %s",typetab[type]);
- printf(" Mode = %s",asciitab[mode]);
- printf(" %d Grans\n\n",numg);
- 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(cnt=0;cnt<GRANS;cnt++)
- if (*(fat+cnt)!=(char) 0xff) grans--;
-
- if (grans<numg) {
- printf(" Not enough space: Only %d grans free\n\n",grans);
- } else {
- 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) {
- if (*bufp==0) *bufp=0xff; else bufp+=DIRENT;
- }
- if (*bufp==0xff) break;
- }
- if (*bufp!=0xff) {
- printf("No more directory entries left.\n\n");
- exit(1);
- }
- lcnt = -1;
- for(cnt=0;cnt<11;cnt++) *(bufp+cnt) = *(fbuf+cnt);
- for(cnt=11;cnt<DIRENT;cnt++) *(bufp+cnt) = (char) 0;
- *(bufp+11) = (char) type;
- *(bufp+12) = (char) mode*0xff;
- *(bufp+15) = (char) numrb;
- for(cnt=0;cnt<GRANS;cnt++)
- if (*(fat+cnt)==(char) 0xff) {
- if (lcnt<0) *(bufp+13)=(char) cnt;
- else *(fat+lcnt)=(char) cnt;
- lcnt=cnt;
- if (numg > 1) {
- copygran(cnt);
- } else {
- copylast(cnt,numrs);
- break;
- }
- numg--;
- }
- *(fat+cnt)=(char) 0xc0+numrs;
- cwrite(17,scnt+3,dirbuf,1);
- cwrite(17,2,fat,1);
- fclose(filptr);
- }
- *bpsvec = (char) nbsec; /* Set byte to MSDOS value */
- }
-
- /* check if all are ok, and if not, set up compare buffer for comparisons */
- checkaok()
- {
- char far *pspfspec;
- int cnt;
- char *nbuf;
-
- FP_SEG(pspfspec) = _psp;
- FP_OFF(pspfspec) = 0x5d;
-
- filok = 0;
- filaok = 1;
- nbuf=fbuf;
-
- for(cnt=0;cnt<11;cnt++) {
- *nbuf = *pspfspec++;
- if (*nbuf!=' ') filok = 1;
- if (*nbuf++=='?') filaok = 0;
- }
- if (filaok==0) {
- printf("Wildcards not currently supported\n");
- exit(1);
- }
- if (filok==0) {
- printf("No file name given\n");
- exit(1);
- }
- }
-
- int cwrite(trk,sec,buf,cnt)
- int trk,sec;
- char *buf;
- int cnt;
- {
- int errcnt,seccnt;
- if (trk>39 || sec>18) return(-1);
-
- for(seccnt=0;seccnt<cnt;seccnt++) {
- errcnt = 0;
-
- while (errcnt<4) {
- inregs.x.ax = 0x0301; /* 3 = write, Count=cnt */
- inregs.x.bx = (int) buf+SECSIZE*seccnt;
- /* pointer to buffer */
- inregs.x.cx = (int) (trk & 0xff)*256
- +((sec+seccnt) & 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++;
- }
- if (errcnt==4)
- printf(" Error writing track %d sector %d\n",trk,sec+seccnt);
- }
- return(0);
- }
-
- 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);
-
- 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);
- }
-
- openfile(name)
- char *name;
- {
- int cnt;
- char *fptr;
-
- fptr = fname;
-
- for(cnt=0;cnt<8;cnt++) *fptr++ = *(name+cnt); /* parse filename */
- while (*(fptr-1)==' ' && fptr>fname) fptr--;
- *fptr++ = '.'; /* put in '.' */
- for(cnt=8;cnt<11;cnt++) *fptr++ = *(name+cnt);
- while ((*(fptr-1)==' ' || *(fptr-1)=='.') && fptr>fname) fptr--;
- *fptr = 0;
-
- if ((filptr = fopen(fname,"rb"))==NULL) {
- printf("File not found\n");
- exit(1);
- }
- }
-
- copygran(gran)
- int gran;
- {
- int secstart;
-
- if (gran>=34) gran += 2; /* adjust around directory */
- secstart = (gran & 1)*9+1; /* Find start sector */
- gran /= 2; /* Now is track pointer */
- fread(inbuff,GSIZE,1,filptr); /* read in file from DOS */
- cwrite(gran,secstart,inbuff,9); /* write out file to coco */
- cwrite(gran,secstart,inbuff,9); /* I did have some write */
- /* errors and this does */
- /* cure them, probably the */
- /* lack of delay on first */
- /* write causes a problem */
- /* anyone else? */
- }
-
- copylast(gran,nsec)
- int gran,nsec;
- {
- int secstart;
-
- if (gran>=34) gran+=2; /* skip directory */
- secstart = (gran & 1)*9+1; /* find sector */
- gran /= 2; /* find track */
-
- fread(inbuff,GSIZE,1,filptr); /* read source */
-
- cwrite(gran,secstart,inbuff,9); /* write destination */
- }
-