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

  1. #include <dos.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <fcntl.h>
  5. #include <io.h>
  6.  
  7. /*
  8.  |
  9.  |    TOC.EXE
  10.  |
  11.  |    USAGE:
  12.  |        TOC filename.ext {BDPT} {AB}<CR>
  13.  |
  14.  |        filename.ext is used to specify the file which you want
  15.  |            to transfer.  NO wildcards are supported, and you
  16.  |            MUST include a file type and mode.
  17.  |
  18.  |        This is a derivitive of DIRC.C (can you tell?)
  19.  */
  20.  
  21. #define    DRIVENAME    'A'
  22. #define    DRIVENO        (DRIVENAME-'A')
  23.  
  24. char *typetab[4] = {    /* Types for COCO directory entries */
  25.     "BASIC    ",
  26.     "Data     ",
  27.     "Program  ",
  28.     "Text     "
  29. };
  30. char *asciitab[2] = {    /* File modes for COCO directory entries */
  31.     "Binary",
  32.     "ASCII"
  33. };
  34.  
  35. int fcount, gcount;    /* File/Granule count for dir info */
  36. int filaok, filok;    /* For wildcarding, always ok and this ok */
  37.  
  38. int grans;
  39.  
  40. #define GRANS    68    /* Number of grans on the disk */
  41. #define GSIZE    2304    /* Number of bytes per granule */
  42. #define SECSIZE    256    /* Number of bytes per sector */
  43. #define DIRENT    32    /* Number of bytes per directory entry */
  44.  
  45. int lastsec;
  46. FILE *filptr;
  47. char *fname = "            \r";
  48.  
  49. int nbsec;        /* Save area for MSDOS value (must restore)*/
  50. char far *thisseg = " ";/* used to find data segment */
  51. char fat[SECSIZE];        /* FAT information buffer from COCO disk */
  52. char dirbuf[SECSIZE];    /* Directory sector buffer from COCO disk */
  53.  
  54. char fbuf[11] =        /* file buffer for comparison to fspec given*/
  55.      "???????????";
  56.  
  57. char inbuff[GSIZE];    /* Input buffer for granules */
  58.  
  59. union REGS inregs;
  60. union REGS outregs;
  61. struct SREGS segregs;
  62.  
  63. unsigned long int numb;
  64. unsigned int numg,numrs,numrb;
  65.  
  66. main(argc,argv)        /*    main -- Start of DIRC.EXE execution */
  67. int argc;
  68. char *argv[];
  69. {
  70.     char far *(far *vec78h);
  71.     char far *bpsvec;
  72.  
  73.     int scnt, ecnt, cnt, lcnt;
  74.     unsigned int mode, gran, lbytes, type;
  75.  
  76.     unsigned char *bufp;
  77.  
  78.     if (argc!=4) {
  79.         printf("Usage:   toc (fspec) {BDPT} {AB}\n");
  80.         exit(1);
  81.     }
  82.     switch (*argv[2]) {
  83.         case 'b':
  84.         case 'B': {
  85.             type = 0;
  86.             break;
  87.         }
  88.         case 'd':
  89.         case 'D': {
  90.             type = 1;
  91.             break;
  92.         }
  93.         case 'p':
  94.         case 'P': {
  95.             type = 2;
  96.             break;
  97.         }
  98.         case 't':
  99.         case 'T': {
  100.             type = 3;
  101.             break;
  102.         }
  103.         default: {
  104.             printf("Bad parameter: %c\n",*argv[2]);
  105.             exit(1);
  106.         }
  107.     }
  108.     switch (*argv[3]) {
  109.         case 'a':
  110.         case 'A': {
  111.             mode = 1;
  112.             break;
  113.         }
  114.         case 'b':
  115.         case 'B': {
  116.             mode = 0;
  117.             break;
  118.         }
  119.         default: {
  120.             printf("Bad parameter: %c\n",*argv[3]);
  121.             exit(1);
  122.         }
  123.     }
  124.     checkaok();
  125.     openfile(fbuf);
  126.     numb = filelength(fileno(filptr));
  127.     numg = (int) (numb/GSIZE)+1;
  128.     numrb = numb - (numg-1)*GSIZE;
  129.     numrs = (int) (numrb/SECSIZE)+1;
  130.     numrb -= (numrs-1)*SECSIZE;
  131.  
  132.     printf(" Copying %s to COCO disk in drive %c\n",fname,DRIVENAME);
  133.     printf("    Type = %s",typetab[type]);
  134.     printf("    Mode = %s",asciitab[mode]);
  135.     printf("    %d Grans\n\n",numg);
  136.     vec78h = (char far *(far *))(0x78);
  137.                 /* 0000:0078, MSDOS disk info pointer */
  138.     bpsvec = 3 + *vec78h;    /* Get MSDOS bytes per sector ptr */
  139.  
  140.     nbsec = (int) *bpsvec;    /* Save byte for restore later */
  141.     *bpsvec = (char) 1;    /* Set byte to 1 (256 bytes/sector) */
  142.  
  143.     fcount = 0;        /* initialize */
  144.     grans = GRANS;
  145.  
  146.     cread(17,2,fat,1);
  147.  
  148.     for(cnt=0;cnt<GRANS;cnt++)
  149.         if (*(fat+cnt)!=(char) 0xff) grans--;
  150.  
  151.     if (grans<numg) {
  152.         printf(" Not enough space:  Only %d grans free\n\n",grans);
  153.     } else {
  154.         for(scnt=0;scnt<9;scnt++) {    /* Main loop for directory read */
  155.         cread(17,scnt+3,dirbuf,1);
  156.         bufp = dirbuf;
  157.         for(ecnt=0;ecnt<8;ecnt++) if (*bufp!=0xff) {
  158.             if (*bufp==0) *bufp=0xff; else bufp+=DIRENT;
  159.         }
  160.         if (*bufp==0xff) break;
  161.         }
  162.         if (*bufp!=0xff) {
  163.         printf("No more directory entries left.\n\n");
  164.         exit(1);
  165.         }
  166.         lcnt = -1;
  167.         for(cnt=0;cnt<11;cnt++) *(bufp+cnt) = *(fbuf+cnt);
  168.         for(cnt=11;cnt<DIRENT;cnt++) *(bufp+cnt) = (char) 0;
  169.         *(bufp+11) = (char) type;
  170.         *(bufp+12) = (char) mode*0xff;
  171.         *(bufp+15) = (char) numrb;
  172.         for(cnt=0;cnt<GRANS;cnt++)
  173.         if (*(fat+cnt)==(char) 0xff) {
  174.             if (lcnt<0) *(bufp+13)=(char) cnt;
  175.                 else    *(fat+lcnt)=(char) cnt;
  176.             lcnt=cnt;
  177.             if (numg > 1) {
  178.             copygran(cnt);
  179.             } else {
  180.             copylast(cnt,numrs);
  181.             break;
  182.             }
  183.             numg--;
  184.         }
  185.         *(fat+cnt)=(char) 0xc0+numrs;
  186.         cwrite(17,scnt+3,dirbuf,1);
  187.         cwrite(17,2,fat,1);
  188.         fclose(filptr);
  189.     }
  190.     *bpsvec = (char) nbsec;    /* Set byte to MSDOS value */
  191. }
  192.  
  193. /* check if all are ok, and if not, set up compare buffer for comparisons */
  194. checkaok()
  195. {
  196.     char far *pspfspec;
  197.     int cnt;
  198.     char *nbuf;
  199.  
  200.     FP_SEG(pspfspec) = _psp;
  201.     FP_OFF(pspfspec) = 0x5d;
  202.  
  203.     filok = 0;
  204.     filaok = 1;
  205.     nbuf=fbuf;
  206.  
  207.     for(cnt=0;cnt<11;cnt++) {
  208.         *nbuf = *pspfspec++;
  209.         if (*nbuf!=' ') filok = 1;
  210.         if (*nbuf++=='?') filaok = 0;
  211.     }
  212.     if (filaok==0) {
  213.         printf("Wildcards not currently supported\n");
  214.         exit(1);
  215.     }
  216.     if (filok==0) {
  217.         printf("No file name given\n");
  218.         exit(1);
  219.     }
  220. }
  221.  
  222. int cwrite(trk,sec,buf,cnt)
  223. int trk,sec;
  224. char *buf;
  225. int cnt;
  226. {
  227.     int errcnt,seccnt;
  228.     if (trk>39 || sec>18) return(-1);
  229.  
  230.     for(seccnt=0;seccnt<cnt;seccnt++) {
  231.         errcnt = 0;
  232.  
  233.         while (errcnt<4) {
  234.         inregs.x.ax = 0x0301;        /* 3 = write, Count=cnt */
  235.         inregs.x.bx = (int) buf+SECSIZE*seccnt;
  236.                         /* pointer to buffer */
  237.         inregs.x.cx = (int) (trk & 0xff)*256
  238.                    +((sec+seccnt) & 0xff);
  239.                         /* Track , Sector */
  240.         inregs.x.dx = DRIVENO;        /* Drive select byte */
  241.         segregs.ds = FP_SEG(thisseg);
  242.         segregs.es = FP_SEG(thisseg);
  243.  
  244.         int86x(0x13,&inregs,&outregs,&segregs);
  245.         if (outregs.x.cflag==0) break;
  246.         creset();
  247.         errcnt++;
  248.         }
  249.         if (errcnt==4)
  250.         printf(" Error writing track %d sector %d\n",trk,sec+seccnt);
  251.     }
  252.     return(0);
  253. }
  254.  
  255. int cread(trk,sec,buf,cnt)
  256. int trk,sec;
  257. char *buf;
  258. int cnt;
  259. {
  260.     int errcnt;
  261.     char *temp;
  262.  
  263.     errcnt = 0;
  264.     for(temp=buf;temp<buf+SECSIZE*cnt;temp++) *temp=0; /* zero buff */
  265.     if (trk>39 || sec>18) return(-1);
  266.  
  267.     while (errcnt<4) {
  268.         inregs.x.ax = 0x0200+(cnt & 0xff);/* 2 = read, Count=cnt */
  269.         inregs.x.bx = (int) buf;    /* pointer to buffer */
  270.         inregs.x.cx = (int) (trk & 0xff)*256
  271.                    +(sec & 0xff);/* Track , Sector */
  272.         inregs.x.dx = DRIVENO;        /* Drive select byte */
  273.         segregs.ds = FP_SEG(thisseg);
  274.         segregs.es = FP_SEG(thisseg);
  275.  
  276.         int86x(0x13,&inregs,&outregs,&segregs);
  277.         if (outregs.x.cflag==0) break;
  278.         creset();
  279.         errcnt++;
  280.     }
  281.     return(errcnt);
  282. }
  283.  
  284. int creset()
  285. {
  286.     inregs.x.ax = 0x0000;        /* 2 = read function, Count=cnt */
  287.     inregs.x.dx = DRIVENO;        /* Drive select byte */
  288.     segregs.ds = FP_SEG(thisseg);
  289.     segregs.es = FP_SEG(thisseg);
  290.  
  291.     int86x(0x13,&inregs,&outregs,&segregs);
  292.     return(outregs.x.cflag);
  293. }
  294.  
  295. openfile(name)
  296. char *name;
  297. {
  298.     int cnt;
  299.     char *fptr;
  300.  
  301.     fptr = fname;
  302.  
  303.     for(cnt=0;cnt<8;cnt++) *fptr++ = *(name+cnt);    /* parse filename */
  304.     while (*(fptr-1)==' ' && fptr>fname) fptr--;
  305.     *fptr++ = '.';                    /* put in '.'      */
  306.     for(cnt=8;cnt<11;cnt++) *fptr++ = *(name+cnt);
  307.     while ((*(fptr-1)==' ' || *(fptr-1)=='.') && fptr>fname) fptr--;
  308.     *fptr = 0;
  309.  
  310.     if ((filptr = fopen(fname,"rb"))==NULL) {
  311.         printf("File not found\n");
  312.         exit(1);
  313.     }
  314. }
  315.  
  316. copygran(gran)
  317. int gran;
  318. {
  319.     int secstart;
  320.  
  321.     if (gran>=34) gran += 2;        /* adjust around directory */
  322.     secstart = (gran & 1)*9+1;        /* Find start sector       */
  323.     gran /= 2;                /* Now is track pointer       */
  324.     fread(inbuff,GSIZE,1,filptr);        /* read in file from DOS   */
  325.     cwrite(gran,secstart,inbuff,9);        /* write out file to coco  */
  326.     cwrite(gran,secstart,inbuff,9);        /* I did have some write   */
  327.                         /* errors and this does       */
  328.                         /* cure them, probably the */
  329.                         /* lack of delay on first  */
  330.                         /* write causes a problem  */
  331.                         /* anyone else?           */
  332. }
  333.  
  334. copylast(gran,nsec)
  335. int gran,nsec;
  336. {
  337.     int secstart;
  338.  
  339.     if (gran>=34) gran+=2;            /* skip directory */
  340.     secstart = (gran & 1)*9+1;        /* find sector      */
  341.     gran /= 2;                /* find track      */
  342.  
  343.     fread(inbuff,GSIZE,1,filptr);        /* read source      */
  344.  
  345.     cwrite(gran,secstart,inbuff,9);        /* write destination */
  346. }
  347.