////////////////////////////////////////////////////////////////////////////// /// px8_d88 /// wrc 20190123 /// Read .d88 file and create epson px8 raw disk image /// ////////////////////////////////////////////////////////////////////////////// #include #include #include #define DISK_SIDES 2 #define DISK_TRACKS 40 #define DISK_SECTORS 16 #define DISK_TOTAL_SECTORS ( DISK_SECTORS * DISK_TRACKS * DISK_SIDES ) #define DISK_SECTOR_SIZE 256 #define DISK_TOTAL_BYTES (DISK_TOTAL_SECTORS * DISK_SECTOR_SIZE) #define FILE_HEADER_SIZE 0x2b0 #define FILE_SECTOR_HEADER_SIZE 16 #define FILE_SECTOR_SIZE (DISK_SECTOR_SIZE + \ FILE_SECTOR_HEADER_SIZE) ////////////////////////////////////////////////////////////////////////////// // .d88 file format // // Header (0 to 2af) // 000000: Image name ASCII text (xx chars, 0 term?) // 000012: Reserved // 0000??: Protect & type // 00001c: Size of file !!! Differs from fjkraan (4 bytes, LE) // 000022: Track index // // Sector Header ( 16 bytes ) // 00: Track ( 0 to N-1) // 01: Side ( 0 to N-1) // 02: Sector ( 1 to N ) // 03: Sector Size ( 0 = 128, 1 = 256, 2 = 512, 3 = 1024) // 04: NSecLow Number sectors in this track // 05: NSecHigh // 06: Density ( 0 = double, 1 = high, ?? = single ) // 07: Del ?? // 08: Stat ?? // 09: RESERVED // 0A: RESERVED // 0B: RESERVED // 0C: RESERVED // 0D: RESERVED // 0E: Data Size ( 2 bytes, LE ) // 0F: Data Size // 0002b0: First Sector ( HDR: DATA ) // 0003c0: Second Sector // // Keep track of which sectors were written uint8_t sectorsWritten[ DISK_TOTAL_SECTORS ]; uint8_t sectorBuffer[ FILE_SECTOR_SIZE ]; // Hold an incoming sector uint8_t diskImage[ DISK_TOTAL_BYTES ]; // Image of entire disk FILE* infile; FILE* outfile; int readSector(int s, uint8_t* buff); int writeSector(uint8_t* buff, uint8_t* img); int main(int argc, char **argv) { int rtn = 0; printf("argc is %d \n", argc); if(argc != 3) { printf("usage: px8_d88 infile.d88 outfile.img \n\n"); exit(1); } infile = fopen(argv[1], "r"); outfile = fopen(argv[2], "w"); if(infile == NULL) { printf("Could not open input file \n"); exit(1); } if(outfile == NULL) { printf("Could not open outpuf file \n"); exit(1); } for(int i = 0; i < DISK_TOTAL_BYTES; i++) { diskImage[i] = 0xe5; // clear the image } for(int sec = 0; sec < DISK_TOTAL_SECTORS; sec++) { readSector(sec, sectorBuffer); writeSector(sectorBuffer, diskImage); } fclose(infile); printf("Following sectors written more or less than once! \n"); for(int sec = 0; sec < DISK_TOTAL_SECTORS; sec++) { if(sectorsWritten[sec] != 1) { printf("%4d %2d \n", sec, sectorsWritten[sec]); } } printf("Writing image file %s \n", argv[2]); for(int b = 0; b < DISK_TOTAL_BYTES; b++) { fputc(diskImage[b], outfile); } fclose(outfile); return rtn; } int readSector(int s, uint8_t* buff) { int rtn = 0; fseek(infile, FILE_HEADER_SIZE + FILE_SECTOR_SIZE * s, SEEK_SET); fread(sectorBuffer, FILE_SECTOR_SIZE, 1, infile); return rtn; } int writeSector(uint8_t* buff, uint8_t* img) { int track = buff[0]; int side = buff[1]; int sector = buff[2] - 1; // sector #'s start at 1 // assume sector size of 256 bytes int thisSector = track * DISK_SIDES * DISK_SECTORS; thisSector += side * DISK_SECTORS; thisSector += sector; printf("Writing sector %d\n", thisSector); sectorsWritten[thisSector]++; int offset = thisSector * DISK_SECTOR_SIZE; for(int i = 0; i < DISK_SECTOR_SIZE; i++) { diskImage[ offset + i ] = sectorBuffer[ i + FILE_SECTOR_HEADER_SIZE ]; } return 0; }