// // fileio.cpp: File handling (mainly disk related) // // by James Hammons // (C) 2019 Underground Software // #include "fileio.h" #include #include #include "crc32.h" #include "log.h" uint8_t woz1Header[8] = { 'W', 'O', 'Z', '1', 0xFF, 0x0A, 0x0D, 0x0A }; uint8_t woz2Header[8] = { 'W', 'O', 'Z', '2', 0xFF, 0x0A, 0x0D, 0x0A }; uint8_t standardTMAP[160] = { 0, 0, 0xFF, 1, 1, 1, 0xFF, 2, 2, 2, 0xFF, 3, 3, 3, 0xFF, 4, 4, 4, 0xFF, 5, 5, 5, 0xFF, 6, 6, 6, 0xFF, 7, 7, 7, 0xFF, 8, 8, 8, 0xFF, 9, 9, 9, 0xFF, 10, 10, 10, 0xFF, 11, 11, 11, 0xFF, 12, 12, 12, 0xFF, 13, 13, 13, 0xFF, 14, 14, 14, 0xFF, 15, 15, 15, 0xFF, 16, 16, 16, 0xFF, 17, 17, 17, 0xFF, 18, 18, 18, 0xFF, 19, 19, 19, 0xFF, 20, 20, 20, 0xFF, 21, 21, 21, 0xFF, 22, 22, 22, 0xFF, 23, 23, 23, 0xFF, 24, 24, 24, 0xFF, 25, 25, 25, 0xFF, 26, 26, 26, 0xFF, 27, 27, 27, 0xFF, 28, 28, 28, 0xFF, 29, 29, 29, 0xFF, 30, 30, 30, 0xFF, 31, 31, 31, 0xFF, 32, 32, 32, 0xFF, 33, 33, 33, 0xFF, 34, 34, 34, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; // // sizePtr is optional // uint8_t * ReadFile(const char * filename, uint32_t * sizePtr/*= NULL*/) { FILE * fp = fopen(filename, "rb"); if (!fp) return NULL; fseek(fp, 0, SEEK_END); uint32_t size = ftell(fp); fseek(fp, 0, SEEK_SET); uint8_t * buffer = (uint8_t *)malloc(size); fread(buffer, 1, size, fp); fclose(fp); if (sizePtr != NULL) *sizePtr = size; return buffer; } // // This initializes the WOZ type 2 headers // void InitWOZ2Headers(WOZ2 & woz) { // Set up header (leave CRC as 0 for now) memcpy(woz.magic, woz2Header, 8); woz.crc32 = 0; // INFO header memcpy(woz.infoTag, "INFO", 4); woz.infoSize = Uint32LE(60); woz.infoVersion = 2; woz.diskType = 1; woz.writeProtected = 0; woz.synchronized = 0; woz.cleaned = 1; memset(woz.creator, ' ', 32); memcpy(woz.creator, "Apple2 emulator v1.0.0", 22); woz.diskSides = 1; woz.bootSectorFmt = 1; woz.optimalBitTmg = 32; woz.largestTrack = Uint16LE(13); // TMAP header memcpy(woz.tmapTag, "TMAP", 4); woz.tmapSize = Uint32LE(160); // TRKS header memcpy(woz.trksTag, "TRKS", 4); } // // This is used mainly to initialize blank disks and upconvert non-WOZ disks // uint8_t * InitWOZ(uint32_t * pSize/*= NULL*/) { uint32_t size = 1536 + (35 * (13 * 512)); uint8_t * data = (uint8_t *)malloc(size); WOZ2 & woz = *((WOZ2 *)data); // Zero out WOZ image in memory memset(&woz, 0, size); // Set up headers InitWOZ2Headers(woz); memcpy(woz.tmap, standardTMAP, 160); woz.trksSize = Uint32LE(35 * (13 * 512)); for(int i=0; i<35; i++) { woz.track[i].startingBlock = Uint16LE(3 + (i * 13)); woz.track[i].blockCount = Uint16LE(13); woz.track[i].bitCount = Uint32LE(51200); } // META header (how to handle? prolly with a separate pointer) if (pSize) *pSize = size; return data; } uint8_t * UpconvertWOZ1ToWOZ2(uint8_t * woz1Data, uint32_t woz1Size, uint32_t * newSize) { WOZ1 & woz1 = *((WOZ1 *)woz1Data); // First, figure out how large the new structure will be in comparison to // the old one... uint32_t numTracks = woz1.trksSize / sizeof(WOZ1Track); uint32_t metadataSize = woz1Size - (Uint32LE(woz1.trksSize) + 256); // N.B.: # of blocks for each track will *always* be <= 13 for WOZ1 *newSize = 0x600 + (numTracks * (13 * 512)) + metadataSize; uint8_t * woz2Data = (uint8_t *)malloc(*newSize); memset(woz2Data, 0, *newSize); WOZ2 & woz2 = *((WOZ2 *)woz2Data); InitWOZ2Headers(woz2); // Copy parts of INFO & TMAP chunks over memcpy(&woz2.diskType, &woz1.diskType, 36); memcpy(woz2.tmap, woz1.tmap, 160); //note: should check the CRC32 integrity 1st before attempting to recreate it here... (the CRC is written out when it's saved anyway, so no need to fuck with this right now) woz2.crc32 = 0; woz2.trksSize = Uint32LE(numTracks * (13 * 512)); // Finally, copy over the tracks for(uint32_t i=0; icrc32 = Uint32LE(CRC32(woz->infoTag, size - 12)); // META header (skip for now) (actually, should be in the disk[] image already) // Finally, write the damn image FILE * file = fopen(filename, "wb"); if (file == NULL) { WriteLog("FILEIO: Failed to open image file '%s' for writing...\n", filename); return false; } fwrite((uint8_t *)woz, 1, size, file); fclose(file); WriteLog("FILEIO: Successfully wrote image file '%s'...\n", filename); return true; }