home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / games / utils / ztools.lha / ztools / src / inforead.c < prev    next >
C/C++ Source or Header  |  1992-12-17  |  4KB  |  151 lines

  1. /* inforead.c V1.0
  2.  *
  3.  * Read Infocom data files from an IBM bootable diskette
  4.  *
  5.  * Usage: inforead datafile-name [start-track [drive#]]
  6.  *
  7.  *    datafile-name is required
  8.  *    start-track is optional (default is 6, should be OK)
  9.  *    drive# is optional (default is 0 for a:, use 1 for b:)
  10.  *
  11.  * The data file is extracted starting at track 6 and continues
  12.  * for the length of the data area. The data file that is created
  13.  * is the correct length and is verified using the checksum in the
  14.  * data area.
  15.  *
  16.  * This only works for type 3 games on IBM 5 1/4" diskettes. I
  17.  * believe that all of the bootable Infocom games were type 3.
  18.  *
  19.  * Once you have extracted the datafile use the /G switch with
  20.  * a type 3 Infocom interpreter, for example:
  21.  *
  22.  * C> zork1/ginfidel.dat
  23.  *
  24.  * NB. no space between the /g and the data file name and nothing
  25.  * after the data file name.
  26.  *
  27.  * This C program was written with MicroSoft C specifically for the
  28.  * IBM PC.
  29.  *
  30.  * I also have a CBM 64/128 version of this program for Commodore disks.
  31.  *
  32.  * Mark Howell 20 January 1992 howell_ma@movies.enet.dec.com
  33.  *
  34.  */
  35.  
  36. #include <bios.h>
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39.  
  40. #define TRACK_SIZE 4096
  41.  
  42. int read_track (int drive, int track, unsigned char *tp);
  43.  
  44. int main (int argc, char *argv[])
  45. {
  46.     int track = 6;
  47.     int drive = 0;
  48.     FILE *fp;
  49.     unsigned char *tp;
  50.     int i, j, size, status;
  51.     unsigned long int glength;
  52.     unsigned short gchksum, chksum = 0;
  53.  
  54.     if (argc >= 4)
  55.         drive = atoi (argv[3]);
  56.     if (drive < 0 || drive > 1) {
  57.         fprintf (stderr, "invalid drive #%d\n", drive);
  58.         exit (1);
  59.     }
  60.     if (argc >= 3)
  61.         track = atoi (argv[2]);
  62.     if (track < 0 || track > 39) {
  63.         fprintf (stderr, "invalid track #%d\n", track);
  64.         exit (1);
  65.     }
  66.     if (argc < 2) {
  67.         fprintf (stderr, "usage: %s datafile-name [start track [drive]]\n",
  68.                  argv[0]);
  69.         exit (1);
  70.     }
  71.  
  72.     if ((tp = (unsigned char *) malloc (TRACK_SIZE)) == NULL) {
  73.         perror ("malloc");
  74.         exit (1);
  75.     }
  76.     if ((fp = fopen (argv[1], "wb")) == NULL) {
  77.         perror ("fopen");
  78.         exit (1);
  79.     }
  80.  
  81.     for (i = track; i < 40; i++) {
  82.         if (status == read_track (drive, i, tp)) {
  83.             fprintf (stderr, "error %d from drive #%d, track #%d\n",
  84.                      status, drive, track);
  85.             exit (1);
  86.         }
  87.         if (i == track) {
  88.             glength = ((unsigned) tp[26] * 256) + tp[27];
  89.             gchksum = ((unsigned) tp[28] * 256) + tp[29];
  90.             glength = (glength * 2) - TRACK_SIZE;
  91.             for (j = 64; j < TRACK_SIZE; j++)
  92.                 chksum += tp[j];
  93.             if (fwrite (tp, TRACK_SIZE, 1, fp) != 1) {
  94.                 perror ("fwrite");
  95.                 exit (1);
  96.             }
  97.         } else {
  98.             if (glength > TRACK_SIZE) {
  99.                 size = TRACK_SIZE;
  100.                 glength -= TRACK_SIZE;
  101.             } else {
  102.                 size = (int) glength;
  103.                 i = 40;
  104.             }
  105.             for (j = 0; j < size; j++)
  106.                 chksum += tp[j];
  107.             if (fwrite (tp, (size_t) size, 1, fp) != 1) {
  108.                 perror ("fwrite");
  109.                 exit (1);
  110.             }
  111.         }
  112.     }
  113.  
  114.     if (gchksum == chksum)
  115.         printf ("game copied OK\n");
  116.     else
  117.         fprintf (stderr, "game copy failed!\n");
  118.  
  119.     free (tp);
  120.     fclose (fp);
  121.  
  122.     exit (0);
  123.  
  124.     return (0);
  125.  
  126. }/* main */
  127.  
  128. int read_track (int drive, int track, unsigned char *tp)
  129. {
  130.     struct diskinfo_t di;
  131.     unsigned int status;
  132.     int i;
  133.  
  134.     di.drive = drive;
  135.     di.head = 0;
  136.     di.track = track;
  137.     di.sector = 1;
  138.     di.nsectors = 8;
  139.     di.buffer = (void far *) tp;
  140.  
  141.     for (i = 0; i < 3; i++) {
  142.         status = _bios_disk (_DISK_READ, &di);
  143.         if (status == 8)
  144.             return (0);
  145.         _bios_disk (_DISK_RESET, NULL);
  146.     }
  147.  
  148.     return (status >> 8);
  149.  
  150. }/* read_track */
  151.