/* converts a raw disk image file into a nibble disk image */ /* Copyright (c) 2001 by Christopher Bachmann (c-bachmann@northwestern.edu) Feel free to redistribute it, port it, copy it around, but if you change it, improve it, base something else on it, etc. Please let me know, so that I can keep this up to date, and incorporate the best of everything. */ #include static long int start[35]; /* start positions for each track */ static long int length[35]; /* length of each track */ /* open the file for reading as binary */ FILE *openfile(char *filename) { FILE *fileno; fileno = fopen(filename, "rb"); return fileno; } /* read in information from the header */ void readheader (FILE *fileid) { int i; fseek (fileid, (long) 0x2b0, 0); /* point to first data field */ for (i=0; i < 35; i++) { start[i] = 0; start[i] = ((((long) getc (fileid)) & 0xff) << 16) | start[i]; start[i] = ((((long) getc (fileid)) & 0xff) << 8) | start[i]; start[i] = ((((long) getc (fileid)) & 0xff)) | start[i]; start[i] = ((((long) getc (fileid)) & 0xff) << 24) | start[i]; /* start[i] = ((getc(fileid) & 0xff) << 16) | ((getc(fileid) & 0xff) << 8) | ((getc(fileid) & 0xff)) | ((getc(fileid) & 0xff) << 24); */ /* printf ("%x ",start[i]); */ } /* printf ("\n"); */ fseek (fileid, (long) 0x440, 0); for (i=0; i < 35; i++) { length[i] = 0; length[i] = ((((long) getc (fileid)) & 0xff)) | length[i]; length[i] = ((((long) getc (fileid)) & 0xff) << 8) | length[i]; length[i] = ((((long) getc (fileid)) & 0xff) << 16) | length[i]; length[i] = ((((long) getc (fileid)) & 0xff) << 24) | length[i]; /* length[i] = ((getc(fileid) & 0xff)) | ((getc(fileid) & 0xff) << 8) | ((getc(fileid) & 0xff) << 16) | ((getc(fileid) & 0xff) << 24); */ /* printf ("%x ",length[i]); */ } /* printf ("\n"); */ for (i=0; i < 35; i++) { printf ("%x: %x %x\n",i,start[i],length[i]); } } /* print the short as 4 hex digits, with a line number */ void printbyte (short number) { int high,low; high = (number >> 8) & 0xff; low = number & 0xff; /* if (high < 16) printf ("0%x",high); else printf ("%x",high); */ if (low < 16) printf ("0%x ",low); else printf ("%x ",low); } /* write out a raw track */ /* Note: we can't just copy the bytes, because the option board includes the sync bits. The nibble format includes a lot of information, but drops them for some reason */ write_track(FILE *fileid,FILE *fileno) { int address[14]; /* address information */ int done = 0; /* flag */ int buffer = 0xffff; /* bit buffer (like apple latch) */ int input_byte; /* input byte */ int input_bit; /* current bit */ int bit_count; /* number of bits shifted in so far */ int index=0; /* index into address array */ while (!done) { input_byte = getc(fileid); if (input_byte == EOF) { /* check for end of file ?? */ done = 1; } else { for (input_bit = 0; input_bit < 8; input_bit++) { /* get current bit */ buffer = ((buffer << 1) & 0xfffe) | ((input_byte >> 7) & 1); input_byte = input_byte << 1; /* update count */ bit_count++; /* test for valid data */ if ((bit_count >= 8) && ((buffer & 0x0080) != 0)) { /* printbyte (buffer); */ putc(buffer & 0xff,fileno); index++; /* this is clumsy, as we might write a partial sector at the end */ /* however, it's better than nothing, and more accurate */ if (index==6656) { done = 1; } bit_count = 0; /* reset bit counter */ buffer = 0xffff; /* and buffer */ } /* end valid data */ } /* end current byte */ } /* end EOF test */ } /* end while loop */ } /* process the file as if we are a real apple reading the disk */ void process(FILE *fileid, char *filename) { FILE *fileno; int trk; /* track */ int j; /* byte */ printf ("Processing "); fileno = fopen(filename, "wb"); for (trk=0; trk < 35; trk++) { /* printf ("Track %d\n",trk); */ printf ("."); fseek (fileid, start[trk], 0); /* seek to start of track */ /* write out the track */ write_track(fileid,fileno); } fclose (fileno); printf ("Done\n"); } /* close the file after reading */ void closefile(FILE *fileid) { fclose (fileid); } int main(int argc, char *argv[]) { FILE *fileid; if (argc < 3) { printf ("img2nib \n"); } else { fileid = openfile(argv[1]); if (fileid == NULL) { printf ("Filename not found\n"); } else { readheader (fileid); process (fileid, argv[2]); closefile(fileid); } } return(0); }