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

  1. #include <dos.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <fcntl.h>
  5.  
  6. /*
  7.  |
  8.  |    FROMC.EXE
  9.  |
  10.  |    USAGE:
  11.  |        FROMC [filename[.ext]]<CR>
  12.  |
  13.  |        [filename[.ext]] is used to specify the file(s) which
  14.  |            you want to get from COCO disks.
  15.  |
  16.  |        This function also has the side effect of giving you
  17.  |            directory information as it copies (an added
  18.  |            benefit).
  19.  |
  20.  |        The information provided includes the free space on the disk.
  21.  |            The freespace is listed both in Granules and Bytes.
  22.  |            The display for each file includes its size in bytes,
  23.  |                the number of granules it occupies, the file
  24.  |                type, and the file mode.
  25.  |
  26.  |        You may use the global characters ? and * in the filename and
  27.  |            extention parameters.
  28.  |
  29.  |        If you do not specify a filename, it defaults to *.*
  30.  |
  31.  |        If you do not specify a filename extention, it defaults to *.
  32.  |
  33.  */
  34.  
  35. #define    DRIVENAME    'A'
  36. #define    DRIVENO        (DRIVENAME-'A')
  37.  
  38. char *typetab[4] = {    /* Types for COCO directory entries */
  39.     "BASIC    ",
  40.     "Data     ",
  41.     "Program  ",
  42.     "Text     "
  43. };
  44. char *asciitab[2] = {    /* File modes for COCO directory entries */
  45.     "Binary",
  46.     "ASCII"
  47. };
  48.  
  49. int fcount, gcount;    /* File/Granule count for dir info */
  50. int filaok, filok;    /* For wildcarding, always ok and this ok */
  51.  
  52. int grans;
  53.  
  54. #define GRANS    68    /* Number of grans on the disk */
  55. #define GSIZE    2304    /* Number of bytes per granule */
  56. #define SECSIZE    256    /* Number of bytes per sector */
  57. #define DIRENT    32    /* Number of bytes per directory entry */
  58.  
  59. int lastsec;
  60. FILE *filptr;
  61. char *fname = "            \r";
  62.  
  63. int nbsec;        /* Save area for MSDOS value (must restore)*/
  64. char far *thisseg = " ";/* used to find data segment */
  65. char fat[SECSIZE];        /* FAT information buffer from COCO disk */
  66. char dirbuf[SECSIZE];    /* Directory sector buffer from COCO disk */
  67.  
  68. char fbuf[11] =        /* file buffer for comparison to fspec given*/
  69.      "???????????";
  70.  
  71. char inbuff[GSIZE];    /* Input buffer for granules */
  72.  
  73. union REGS inregs;
  74. union REGS outregs;
  75. struct SREGS segregs;
  76.  
  77. main(argc,argv)        /*    main -- Start of DIRC.EXE execution */
  78. int argc;
  79. char *argv[];
  80. {
  81.     char far *(far *vec78h);
  82.     char far *bpsvec;
  83.  
  84.     int scnt, ecnt;
  85.     int mode, gran, lbytes, type;
  86.  
  87.     unsigned char *bufp;
  88.  
  89.     checkaok();
  90.  
  91.     printf(" Volume in drive %c is COCO disk\n",DRIVENAME);
  92.     printf(" Copying files from COCO disk\n\n");
  93.  
  94.     vec78h = (char far *(far *))(0x78);
  95.                 /* 0000:0078, MSDOS disk info pointer */
  96.     bpsvec = 3 + *vec78h;    /* Get MSDOS bytes per sector ptr */
  97.  
  98.     nbsec = (int) *bpsvec;    /* Save byte for restore later */
  99.     *bpsvec = (char) 1;    /* Set byte to 1 (256 bytes/sector) */
  100.  
  101.     fcount = 0;        /* initialize */
  102.     grans = GRANS;
  103.  
  104.     cread(17,2,fat,1);
  105.  
  106.     for(scnt=0;scnt<9;scnt++) {    /* Main loop for directory read */
  107.  
  108.         cread(17,scnt+3,dirbuf,1);
  109.  
  110.         bufp = dirbuf;
  111.  
  112.         for(ecnt=0;ecnt<8;ecnt++) if (*bufp!=0xff) {
  113.                         /* entries per sector = 8 */
  114.                         /* ...for each file entry: */
  115.         if (*bufp) {
  116.             checkfil(bufp);        /* Check if it's ok to list */
  117.                         /* result: filok=1, yes */
  118.             if (filok) {
  119.             fcount++;        /* count it, and print name */
  120.             printf("Copying %.8s %.3s    ",bufp,(char *) bufp+8);
  121.             }
  122.  
  123.             mode = (int) *(bufp+12);
  124.             gran = (int) *(bufp+13);
  125.             lbytes = ( (256 * (int)(*(bufp+14))) +
  126.                  (int)(*(bufp+15)) );/* Count is in 6809 format */
  127.                          /* high, then low byte */
  128.             type = (int) *(bufp+11);
  129.             calcdisp(mode,gran,lbytes,type,bufp);
  130.  
  131.             if (filok) {
  132.             printf("%s",typetab[type]);
  133.             if (mode!=0) mode=1;    /* now simply ascii or not */
  134.             printf("%s\n",asciitab[mode]);
  135.             }
  136.         }
  137.         bufp += DIRENT;
  138.         }
  139.     }
  140.     printf("Done:     %5d File(s) copied\n",fcount);
  141.  
  142.     *bpsvec = (char) nbsec;    /* Set byte to MSDOS value */
  143. }
  144.  
  145. /* calcdisp -- calculate file size, and display if necessary */
  146.  
  147. calcdisp(mode,gran,lbytes,type,name)
  148. int mode,gran,lbytes,type;
  149. char *name;
  150. {
  151.     int bytecnt,tgran;
  152.  
  153.     gcount = 0;
  154.     bytecnt = lbytes;
  155.  
  156.     if (filok) openfile(name);
  157.  
  158.     lastsec = lbytes;
  159.  
  160.     do {
  161.         tgran = gran;
  162.         grans--;
  163.         gcount++;
  164.         gran = (int) *(fat+gran);
  165.         if (gran & 0x80) {
  166.             if (filok) copylast(tgran,gran & 0x3f);
  167.             gran = (gran & 0x3f)-1;
  168.             if (gran>0) bytecnt += gran*SECSIZE;
  169.             gran=-1;
  170.             break;
  171.         }
  172.         if (filok) copygran(tgran);
  173.         bytecnt += (int) GSIZE;
  174.     } while (gran>=0);
  175.     if (filok) printf("%5d%5d  ",bytecnt,gcount);
  176. }
  177.  
  178.  
  179. /* check if all are ok, and if not, set up compare buffer for comparisons */
  180. checkaok()
  181. {
  182.     char far *pspfspec;
  183.     int cnt;
  184.     char chk1;
  185.     char *nbuf;
  186.  
  187.     FP_SEG(pspfspec) = _psp;
  188.     FP_OFF(pspfspec) = 0x5d;
  189.  
  190.     chk1 = *pspfspec;
  191.     nbuf=fbuf;
  192.  
  193.     if (chk1==' ' || chk1=='?') filaok=1; else filaok=0;
  194.  
  195.     for(cnt=0;cnt<11;cnt++) {
  196.         *nbuf = *pspfspec++;
  197.         if (*nbuf++!=chk1) filaok = 0;
  198.     }
  199. }
  200.  
  201. /*    CHECKFIL -- check a file to see if it matches comparison value */
  202. checkfil(nbuf)
  203. char *nbuf;
  204. {
  205.     int cnt;
  206.     filok = 1;
  207.     if (filaok) return;
  208.  
  209.     for (cnt=0;cnt<11;cnt++)
  210.         if ((*(fbuf+cnt) != '?') &&
  211.             (*(fbuf+cnt) != *(nbuf+cnt))) filok=0;
  212.     return;
  213. }
  214.  
  215. openfile(name)
  216. char *name;
  217. {
  218.     int cnt;
  219.     char *fptr;
  220.  
  221.     fptr = fname;
  222.  
  223.     for(cnt=0;cnt<8;cnt++) *fptr++ = *(name+cnt);
  224.     while (*(fptr-1)==' ' && fptr>fname) fptr--;
  225.     *fptr++ = '.';
  226.     for(cnt=8;cnt<11;cnt++) *fptr++ = *(name+cnt);
  227.     while ((*(fptr-1)==' ' || *(fptr-1)=='.') && fptr>fname) fptr--;
  228.     *fptr = 0;
  229.  
  230.     filptr = fopen(fname,"w+b");
  231. }
  232.  
  233. copygran(gran)
  234. int gran;
  235. {
  236.     int secstart;
  237.  
  238.     if (gran>=34) gran += 2;
  239.     secstart = (gran & 1)*9+1;
  240.     gran /= 2;
  241.  
  242.     cread(gran,secstart,inbuff,9);
  243.  
  244.     fwrite(inbuff,GSIZE,1,filptr);
  245. }
  246.  
  247. copylast(gran,nsec)
  248. int gran,nsec;
  249. {
  250.     int secstart;
  251.  
  252.     if (gran>=34) gran+=2;
  253.     secstart = (gran & 1)*9+1;
  254.     gran /= 2;
  255.  
  256.     cread(gran,secstart,inbuff,9);
  257.  
  258.     nsec -= 1;
  259.     if (nsec<0) nsec=0;
  260.  
  261.     fwrite(inbuff,SECSIZE*nsec+lastsec,1,filptr);
  262.  
  263.     fclose(filptr);
  264. }
  265.  
  266. int cread(trk,sec,buf,cnt)
  267. int trk,sec;
  268. char *buf;
  269. int cnt;
  270. {
  271.     int errcnt;
  272.     char *temp;
  273.  
  274.     errcnt = 0;
  275.     for(temp=buf;temp<buf+SECSIZE*cnt;temp++) *temp=0;
  276.     if (trk>39 || sec>18) return(-1);
  277.  
  278.     while (errcnt<4) {
  279.         inregs.x.ax = 0x0200+(cnt & 0xff);/* 2 = read, Count=cnt */
  280.         inregs.x.bx = (int) buf;    /* pointer to buffer */
  281.         inregs.x.cx = (int) (trk & 0xff)*256
  282.                    +(sec & 0xff);/* Track , Sector */
  283.         inregs.x.dx = DRIVENO;        /* Drive select byte */
  284.         segregs.ds = FP_SEG(thisseg);
  285.         segregs.es = FP_SEG(thisseg);
  286.  
  287.         int86x(0x13,&inregs,&outregs,&segregs);
  288.         if (outregs.x.cflag==0) break;
  289.         creset();
  290.         errcnt++;
  291.     }
  292.     return(errcnt);
  293. }
  294.  
  295. int creset()
  296. {
  297.     inregs.x.ax = 0x0000;        /* 2 = read function, Count=cnt */
  298.     inregs.x.dx = DRIVENO;        /* Drive select byte */
  299.     segregs.ds = FP_SEG(thisseg);
  300.     segregs.es = FP_SEG(thisseg);
  301.  
  302.     int86x(0x13,&inregs,&outregs,&segregs);
  303.     return(outregs.x.cflag);
  304. }
  305.