X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ffileio.cpp;fp=src%2Ffileio.cpp;h=efa4c61b6d9c2dd9c0ceb9fd449497957a8ee958;hb=63762cef81da80d12773c646a3b3154e3ae1d0fc;hp=0000000000000000000000000000000000000000;hpb=31d2453ee7e0b2f8b550fdc17f13b92bb9fab7ee;p=apple2 diff --git a/src/fileio.cpp b/src/fileio.cpp new file mode 100644 index 0000000..efa4c61 --- /dev/null +++ b/src/fileio.cpp @@ -0,0 +1,279 @@ +// +// 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 +}; + + +// +// Note that size *must* be a valid pointer, otherwise this will go BOOM +// +uint8_t * ReadFile(const char * filename, uint32_t * size) +{ + FILE * fp = fopen(filename, "rb"); + + if (!fp) + return NULL; + + fseek(fp, 0, SEEK_END); + *size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + uint8_t * buffer = (uint8_t *)malloc(*size); + fread(buffer, 1, *size, fp); + fclose(fp); + + 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; +} +