|
|
1.1 ! root 1: /* ! 2: Hatari - dim.c ! 3: ! 4: This file is distributed under the GNU Public License, version 2 or at ! 5: your option any later version. Read the file gpl.txt for details. ! 6: ! 7: DIM disk image support. ! 8: */ ! 9: const char DIM_fileid[] = "Hatari dim.c : " __DATE__ " " __TIME__; ! 10: ! 11: #include <zlib.h> ! 12: ! 13: #include "main.h" ! 14: #include "file.h" ! 15: #include "floppy.h" ! 16: #include "dim.h" ! 17: ! 18: #undef SAVE_TO_DIM_IMAGES ! 19: ! 20: /* ! 21: .DIM FILE FORMAT ! 22: --===============------------------------------------------------------------- ! 23: ! 24: The file format of normal .DIM image files are quite the same as the .ST image ! 25: files (see st.c) - the .DIM image files just have an additional header of ! 26: 32 bytes. However, there are also "compressed" images which only contain the ! 27: used sectors of the disk. It is necessary to parse the FAT to "uncompress" ! 28: these images. ! 29: ! 30: The header contains following information: ! 31: ! 32: Offset Size Description ! 33: ------ -------- ----------- ! 34: 0x0000 Word ID Header (0x4242('BB')) ! 35: 0x0002 Byte 1 = disk configuration has been detected automatically ! 36: 0 = the user specified the disk configuration ! 37: 0x0003 Byte Image contains all sectors (0) or only used sectors (1) ! 38: 0x0006 Byte Sides (0 or 1; add 1 to this to get correct number of sides) ! 39: 0x0008 Byte Sectors per track ! 40: 0x000A Byte Starting Track (0 based) ! 41: 0x000C Byte Ending Track (0 based) ! 42: 0x000D Byte Double-Density(0) or High-Density (1) ! 43: 0x000E 18 Bytes A copy of the Bios Parameter Block (BPB) of this disk. ! 44: */ ! 45: ! 46: ! 47: /*-----------------------------------------------------------------------*/ ! 48: /** ! 49: * Does filename end with a .DIM extension? If so, return TRUE ! 50: */ ! 51: bool DIM_FileNameIsDIM(const char *pszFileName, bool bAllowGZ) ! 52: { ! 53: return(File_DoesFileExtensionMatch(pszFileName,".dim") ! 54: || (bAllowGZ && File_DoesFileExtensionMatch(pszFileName,".dim.gz"))); ! 55: } ! 56: ! 57: ! 58: /*-----------------------------------------------------------------------*/ ! 59: /** ! 60: * Load .DIM file into memory, set number of bytes loaded and return a pointer ! 61: * to the buffer. ! 62: */ ! 63: Uint8 *DIM_ReadDisk(const char *pszFileName, long *pImageSize) ! 64: { ! 65: Uint8 *pDimFile; ! 66: Uint8 *pDiskBuffer = NULL; ! 67: ! 68: /* Load file into buffer */ ! 69: pDimFile = File_Read(pszFileName, pImageSize, NULL); ! 70: if (pDimFile) ! 71: { ! 72: /* Check header for valid image: */ ! 73: if (pDimFile[0x00] != 0x42 || pDimFile[0x01] != 0x42 || ! 74: pDimFile[0x03] != 0 || pDimFile[0x0A] != 0) ! 75: { ! 76: fprintf(stderr, "This is not a valid DIM image!\n"); ! 77: *pImageSize = 0; ! 78: free(pDimFile); ! 79: return NULL; ! 80: } ! 81: ! 82: /* Simply use disk contents without the DIM header: */ ! 83: *pImageSize -= 32; ! 84: pDiskBuffer = malloc(*pImageSize); ! 85: if (pDiskBuffer) ! 86: memcpy(pDiskBuffer, pDimFile+32, *pImageSize); ! 87: else ! 88: perror("DIM_ReadDisk"); ! 89: ! 90: /* Free DIM file we loaded */ ! 91: free(pDimFile); ! 92: } ! 93: ! 94: if (pDiskBuffer == NULL) ! 95: { ! 96: *pImageSize = 0; ! 97: } ! 98: ! 99: return pDiskBuffer; ! 100: } ! 101: ! 102: ! 103: /*-----------------------------------------------------------------------*/ ! 104: /** ! 105: * Save .DIM file from memory buffer. Returns TRUE is all OK ! 106: */ ! 107: bool DIM_WriteDisk(const char *pszFileName, Uint8 *pBuffer, int ImageSize) ! 108: { ! 109: #ifdef SAVE_TO_DIM_IMAGES ! 110: ! 111: Uint8 *pDimFile; ! 112: gzFile hGzFile; ! 113: unsigned short int nSectorsPerTrack, nSides; ! 114: int nTracks; ! 115: bool bRet; ! 116: ! 117: /* Allocate memory for the whole DIM image: */ ! 118: pDimFile = malloc(ImageSize + 32); ! 119: if (!pDimFile) ! 120: { ! 121: perror("DIM_WriteDisk"); ! 122: return false; ! 123: } ! 124: ! 125: /* Try to load the old header data to preserve the header fields that are unknown yet: */ ! 126: hGzFile = gzopen(pszFileName, "rb"); ! 127: if (hGzFile != NULL) ! 128: { ! 129: gzread(hGzFile, pDimFile, 32); ! 130: gzclose(hGzFile); ! 131: } ! 132: else ! 133: { ! 134: memset(pDimFile, 0, 32); ! 135: } ! 136: ! 137: /* Now fill in the new header information: */ ! 138: Floppy_FindDiskDetails(pBuffer, ImageSize, &nSectorsPerTrack, &nSides); ! 139: nTracks = ((ImageSize / NUMBYTESPERSECTOR) / nSectorsPerTrack) / nSides; ! 140: pDimFile[0x00] = pDimFile[0x01] = 0x42; /* ID */ ! 141: pDimFile[0x03] = 0; /* Image contains all sectors */ ! 142: pDimFile[0x06] = nSides - 1; /* Sides */ ! 143: pDimFile[0x08] = nSectorsPerTrack; /* Sectors per track */ ! 144: pDimFile[0x0A] = 0; /* Starting track */ ! 145: pDimFile[0x0C] = nTracks - 1; /* Ending track */ ! 146: pDimFile[0x0D] = (ImageSize > 1024*1024); /* DD / HD flag */ ! 147: ! 148: /* Now copy the disk data: */ ! 149: memcpy(pDimFile + 32, pBuffer, ImageSize); ! 150: ! 151: /* And finally save it: */ ! 152: bRet = File_Save(pszFileName, pDimFile, ImageSize + 32, false); ! 153: ! 154: free(pDimFile); ! 155: ! 156: return bRet; ! 157: ! 158: #else /*SAVE_TO_ST_IMAGES*/ ! 159: ! 160: /* Oops, cannot save */ ! 161: return false; ! 162: ! 163: #endif /*SAVE_TO_ST_IMAGES*/ ! 164: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.