|
|
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:
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:
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:
1.1.1.4 root 24: The file format of normal .DIM image files are quite the same as the .ST image
1.1 root 25: files (see st.c) - the .DIM image files just have an additional header of
1.1.1.4 root 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.
1.1 root 29:
1.1.1.4 root 30: The header contains following information:
1.1 root 31:
1.1.1.4 root 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.
1.1 root 44: */
45:
46:
47: /*-----------------------------------------------------------------------*/
1.1.1.5 root 48: /**
49: * Does filename end with a .DIM extension? If so, return TRUE
50: */
1.1.1.9 ! root 51: bool DIM_FileNameIsDIM(const char *pszFileName, bool bAllowGZ)
1.1 root 52: {
53: return(File_DoesFileExtensionMatch(pszFileName,".dim")
54: || (bAllowGZ && File_DoesFileExtensionMatch(pszFileName,".dim.gz")));
55: }
56:
57:
58: /*-----------------------------------------------------------------------*/
1.1.1.5 root 59: /**
60: * Load .DIM file into memory, set number of bytes loaded and return a pointer
61: * to the buffer.
62: */
1.1.1.9 ! root 63: Uint8 *DIM_ReadDisk(const char *pszFileName, long *pImageSize)
1.1 root 64: {
65: Uint8 *pDimFile;
1.1.1.3 root 66: Uint8 *pDiskBuffer = NULL;
1.1 root 67:
68: /* Load file into buffer */
1.1.1.5 root 69: pDimFile = File_Read(pszFileName, pImageSize, NULL);
1.1 root 70: if (pDimFile)
71: {
72: /* Check header for valid image: */
1.1.1.4 root 73: if (pDimFile[0x00] != 0x42 || pDimFile[0x01] != 0x42 ||
74: pDimFile[0x03] != 0 || pDimFile[0x0A] != 0)
1.1 root 75: {
76: fprintf(stderr, "This is not a valid DIM image!\n");
77: *pImageSize = 0;
78: free(pDimFile);
79: return NULL;
80: }
81:
1.1.1.3 root 82: /* Simply use disk contents without the DIM header: */
1.1 root 83: *pImageSize -= 32;
1.1.1.3 root 84: pDiskBuffer = malloc(*pImageSize);
85: if (pDiskBuffer)
86: memcpy(pDiskBuffer, pDimFile+32, *pImageSize);
1.1 root 87: else
1.1.1.3 root 88: perror("DIM_ReadDisk");
1.1 root 89:
90: /* Free DIM file we loaded */
91: free(pDimFile);
92: }
93:
1.1.1.3 root 94: if (pDiskBuffer == NULL)
1.1 root 95: {
96: *pImageSize = 0;
97: }
98:
1.1.1.3 root 99: return pDiskBuffer;
1.1 root 100: }
101:
102:
103: /*-----------------------------------------------------------------------*/
1.1.1.5 root 104: /**
105: * Save .DIM file from memory buffer. Returns TRUE is all OK
106: */
1.1.1.9 ! root 107: bool DIM_WriteDisk(const char *pszFileName, Uint8 *pBuffer, int ImageSize)
1.1 root 108: {
109: #ifdef SAVE_TO_DIM_IMAGES
110:
111: Uint8 *pDimFile;
112: gzFile hGzFile;
113: unsigned short int nSectorsPerTrack, nSides;
114: int nTracks;
1.1.1.6 root 115: bool bRet;
1.1 root 116:
117: /* Allocate memory for the whole DIM image: */
118: pDimFile = malloc(ImageSize + 32);
119: if (!pDimFile)
120: {
1.1.1.3 root 121: perror("DIM_WriteDisk");
1.1.1.8 root 122: return false;
1.1 root 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: */
1.1.1.3 root 138: Floppy_FindDiskDetails(pBuffer, ImageSize, &nSectorsPerTrack, &nSides);
1.1 root 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:
1.1.1.3 root 148: /* Now copy the disk data: */
1.1 root 149: memcpy(pDimFile + 32, pBuffer, ImageSize);
150:
151: /* And finally save it: */
1.1.1.8 root 152: bRet = File_Save(pszFileName, pDimFile, ImageSize + 32, false);
1.1 root 153:
154: free(pDimFile);
155:
156: return bRet;
157:
158: #else /*SAVE_TO_ST_IMAGES*/
159:
160: /* Oops, cannot save */
1.1.1.8 root 161: return false;
1.1 root 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.