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