Visit Atarimax Store


Free-Net Logo
The Atari SIG Historical Archive
Created and hosted by: atarimax.com
[ HOME | GO ATARI | 8-BIT | ST/TT | PORTFOLIO | LYNX | JAGUAR | LIBRARY ]


Article #70 (75 is last):
From: Michael Current 
Newsgroups: freenet.sci.comp.atari.prog.8bit.resource
Subject: Recovering old Infocom games from Atari 400/800 disks
Posted-By: xx004 (Atari SIG)
Date: Thu Aug 27 21:47:41 1998

From: jenkin@cs.yorku.ca (Michael Jenkin)
>Newsgroups: rec.games.int-fiction
Subject: recovering old infocom games from atari 400/800 disks
Date: 2 Apr 93 17:45:18 GMT
Organization: York University, CS Dept. Toronto
Lines: 259


The following two programs will extract infocom datafiles from atari800
(yes the 8bit machine, not the st) infocom games. The resulting datafiles
can then be played with either the infocom interpreter or with the
publicly available interpreters that can be found on the net.

To use this you will need to get the raw disk image from the original
infocom disk uploaded to a somewhat larger machine. Each side of an atari
disk has 720 sectors of 128 bytes. Upload these sectors in order into a
binary file on your favourite modern platform.
NB: This is quite a task. The fastest modem I could attach to the atari
was 1200 baud and disk/memory limits make it necessary to break a full
disk into a number of smaller files containg the sectors before downloading.

Two programs follow. zoffset works for single sided games. It takes
the games serial number, the name of a file containing the raw sectors and an
output file and does the conversion. zheader2 does the same thing for
two sided games.

The serial number can be found by either
running the game or by doing a strings -6 on the disk image and look for
something that resembles a date or by running the game on the atari
-- it is printed out first thing.


Michael Jenkin
York University

-------------- zoffset.c

/*
 * a filter to take a raw disk file from an ATARI 800 infocom game
 * (version 3 or earlier) and the serial number (obtained via strings -6)
 * and produce a data file playable with either zmachine or infocom
 *
 * This version works for games written to a single side of the disk only
 * (I've seen zork1, 2, and 3 this way as well as deadline. Later games
 * are written on both sides of the disk. Use the 2 sided utility instead.)
 *
 * Michael Jenkin, 1993
 */
# include 

/* the disk */
unsigned char disk[720*128];

main(argc, argv)
     int argc;
     char *argv[];
{
  int i, offset, len;
  unsigned short sum, gsum;
  FILE *fd;

  if(argc != 4){
    (void) fprintf(stderr,"usage: zoffset   \n");
    exit(1);
  }
  if(strlen(argv[1]) != 6){
    (void) fprintf(stderr, "serial id's are 6 bytes long e.g. 830329\n");
    exit(1);
  }

  if((fd = fopen(argv[2], "r")) == NULL){
    (void) fprintf(stderr, "open of disk file %s failed!\n",argv[2]);
    exit(1);
  }
  if(fread(disk, sizeof(disk), 1, fd) != 1){
    (void) fprintf(stderr, "read of disk file %s failed!\n",argv[2]);
    exit(1);
  }
  (void) fclose(fd);

  /* search for the key */
  offset = -1;
  for(i=0;i<720*128-6;i++)
    if(!strncmp(argv[1], &disk[i], 6)){
      if(offset >= 0)
        (void) fprintf(stderr, "duplicate serial numbers! using first\n");
      else
        offset = i - 18;
    }

  /* verify that this all makes sense */
  if(offset >= 0)
    (void) fprintf(stderr, "data file starts at offset %d\n",offset);
  else {
    (void) fprintf(stderr, "key %s not found in disk image\n",argv[1]);
    exit(1);
  }
  if(disk[offset] != 3)
    (void) fprintf(stderr, "zoffset only tested on version 3 images....\n");
  len = (disk[offset+26] << 8) | disk[offset+27];
  sum = (disk[offset+28] << 8) | disk[offset+29];
  len *= 2;
  (void) fprintf(stderr, "The image has length %d\n",len);
  if((offset + len) >= (128 * 720)){
    (void) fprintf(stderr, "The data file is a little short!\n");
    exit(1);
  }

  /* checksum the game file. checksum starts 64 bytes into disk */
  gsum = 0;
  for(i=64;i
/*
 * take a 2 disk version of an infocom game an piece it together
 *
 * This should work with all of those nasty double sided atari disks
 *
 * Michael Jenkin, 1993.
 */

# define DISKSIZE (720*128)
unsigned char side1[DISKSIZE], side2[DISKSIZE];


main(argc, argv)
  int argc;
  char *argv[];
{
  unsigned char *start1, *keysearch(), *last1, *last2;
  int sum, len, obj, vcb, gbl, cmn, res, i;
  unsigned short gsum;
  FILE *fd;

  if(argc != 5){
    (void) fprintf(stderr,"usage: zheader2    \n");
    exit(1);
  }

  if(strlen(argv[1]) != 6){
    (void) fprintf(stderr, "serial id's are 6 bytes long e.g. 830329\n");
    exit(1);
  }

  /* read the files in. Nice to have enouch memory to store the disk */
  getfile(argv[2], side1);
  getfile(argv[3], side2);

  /* find the start of the game file on side1 */
  start1 = keysearch(side1, argv[1]);

  /* verify the header and extract offsets to important segments */
  printf("Version is %d\n",*start1);
  if(*start1 != 3)
    printf("Only tested on version 3's!\n");
  len = (start1[26] << 8) | start1[27];
  sum = (start1[28] << 8) | start1[29];
  cmn = (start1[24] << 8) | start1[25];
  vcb = (start1[8] << 8) | start1[9];
  obj = (start1[10] << 8) | start1[11];
  gbl = (start1[12] << 8)| start1[13];
  res = (start1[4] << 8)|start1[5];
  len *= 2;
  printf("Game file has length %d checksum %d\n",len,sum);

  printf("cmn %d vcb %d obj %d gbl %d last %d\n",
         cmn, vcb,obj,gbl,&side1[DISKSIZE]-start1);

  printf("Trying to split at res+1...\n");
  checksplit(argv[4],res+1,len, sum, start1, side2);

  printf("oh well. got to search for it. this could take a while...\n");

  for(i=vcb;i<&side1[DISKSIZE]-start1;i++)
    checksplit(argv[4], i, len, sum, start1, side2);
}

checksplit(fname, sp, len, sum, p1, p2)
     int sp, len, sum;
     unsigned char *p1, *p2;
     char *fname;
{
  unsigned short gsum;
  int i;
  FILE *fd;

  if(!(sp % 1000))
    printf("trying %d\n",sp);
  gsum = 0;
  for(i=64;i







    A FREE-NET Logo
  • Bandwidth for this archive donated by ATARIMAX.COM.
  • This archive is maintained by Steven J Tucker (classics@atarimax.com).
  • This web page and the scripts used to generate it are Copytight 2003 Steven J Tucker, except as described below.
  • Articles and other original FreeNet materials are the sole property of their authors.
  • This web site is not endorsed by or affiliated with in any way, Case Western Reserve University.
  • "Freeport" is a registered trademark of Case Western Reserve University.

Visit Atarimax Store