2 Skelton for retropc emulator
\r
4 Author : Takeda.Toshiya
\r
11 #include "../fileio.h"
\r
12 #if defined(_USE_AGAR) || defined(_USE_SDL)
\r
13 #include "agar_logger.h"
\r
17 static const uint16 crc_table[256] = {
\r
18 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
\r
19 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
\r
20 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
\r
21 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
\r
22 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
\r
23 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
\r
24 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
\r
25 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
\r
26 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
\r
27 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
\r
28 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
\r
29 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
\r
30 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
\r
31 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
\r
32 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
\r
33 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
\r
36 // teledisk decoder table
\r
37 static const uint8 d_code[256] = {
\r
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
\r
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
\r
40 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
\r
41 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
\r
42 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
\r
43 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
\r
44 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
\r
45 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
\r
46 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
\r
47 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f,
\r
48 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
\r
49 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
\r
50 0x18, 0x18, 0x19, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e, 0x1f, 0x1f,
\r
51 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
\r
52 0x28, 0x28, 0x29, 0x29, 0x2a, 0x2a, 0x2b, 0x2b, 0x2c, 0x2c, 0x2d, 0x2d, 0x2e, 0x2e, 0x2f, 0x2f,
\r
53 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
\r
55 static const uint8 d_len[256] = {
\r
56 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
\r
57 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
\r
58 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
\r
59 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
\r
60 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
\r
61 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
\r
62 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
\r
63 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
\r
64 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
\r
65 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
\r
66 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
\r
67 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
\r
68 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
\r
69 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
\r
70 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
\r
71 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
\r
73 static const int secsize[8] = {
\r
74 128, 256, 512, 1024, 2048, 4096, 8192, 16384
\r
77 static uint8 tmp_buffer[DISK_BUFFER_SIZE];
\r
81 inserted = ejected = write_protected = changed = false;
\r
83 sector_size = sector_num = 0;
\r
85 drive_type = DRIVE_TYPE_UNK;
\r
97 typedef struct fd_format {
\r
99 int ncyl, nside, nsec, size;
\r
102 static const fd_format fd_formats[] = {
\r
103 { MEDIA_TYPE_2D, 40, 1, 16, 256 }, // 1D 160KB
\r
104 { MEDIA_TYPE_2D , 40, 2, 16, 256 }, // 2D 320KB
\r
106 { MEDIA_TYPE_2DD, 80, 2, 16, 256 }, // 2DD 640KB (MZ-2500)
\r
108 { MEDIA_TYPE_2DD, 80, 2, 8, 512 }, // 2DD 640KB
\r
110 { MEDIA_TYPE_2DD, 80, 2, 9, 512 }, // 2DD 720KB
\r
111 { MEDIA_TYPE_2HD, 80, 2, 15, 512 }, // 2HC 1.20MB
\r
112 { MEDIA_TYPE_2HD, 77, 2, 8, 1024 }, // 2HD 1.25MB
\r
113 { MEDIA_TYPE_144, 80, 2, 18, 512 }, // 2HD 1.44MB
\r
114 { MEDIA_TYPE_144, 80, 2, 36, 512 }, // 2ED 2.88MB
\r
115 { -1, 0, 0, 0, 0 },
\r
118 void DISK::open(_TCHAR path[], int offset)
\r
120 // check current disk image
\r
122 #if defined(_USE_AGAR) || defined(_USE_SDL)
\r
123 AGAR_DebugLog(AGAR_LOG_INFO, "Open disk: %s", path);
\r
125 if(_tcsicmp(orig_path, path) == 0 && file_offset == offset) {
\r
130 memset(buffer, 0, sizeof(buffer));
\r
131 media_type = MEDIA_TYPE_UNK;
\r
132 is_standard_image = is_fdi_image = false;
\r
133 #if defined(_USE_AGAR) || defined(_USE_SDL)
\r
134 AGAR_DebugLog(AGAR_LOG_INFO, "Open disk: %s", path);
\r
138 if(fi->Fopen(path, FILEIO_READ_BINARY)) {
\r
139 bool converted = false;
\r
141 _tcscpy(orig_path, path);
\r
142 _tcscpy(dest_path, path);
\r
143 _stprintf(temp_path, _T("%s.$$$"), path);
\r
146 // check if file protected
\r
147 write_protected = fi->IsProtected(path);
\r
149 // is this d88 format ?
\r
150 if(check_file_extension(path, _T(".d88")) || check_file_extension(path, _T(".d77")) ||
\r
151 check_file_extension(path, _T(".D88")) || check_file_extension(path, _T(".D77"))) {
\r
152 fi->Fseek(offset + 0x1c, FILEIO_SEEK_SET);
\r
153 file_size = fi->Fgetc();
\r
154 file_size |= fi->Fgetc() << 8;
\r
155 file_size |= fi->Fgetc() << 16;
\r
156 file_size |= fi->Fgetc() << 24;
\r
157 fi->Fseek(offset, FILEIO_SEEK_SET);
\r
158 fi->Fread(buffer, file_size, 1);
\r
159 file_offset = offset;
\r
160 inserted = changed = true;
\r
164 fi->Fseek(0, FILEIO_SEEK_END);
\r
165 file_size = fi->Ftell();
\r
166 fi->Fseek(0, FILEIO_SEEK_SET);
\r
169 #if defined(_X1) || defined(_X1TWIN) || defined(_X1TURBO) || defined(_X1TURBOZ)
\r
170 // is this 2d format ?
\r
171 if(check_file_extension(path, _T(".2d"))) {
\r
172 if(standard_to_d88(MEDIA_TYPE_2D, 40, 2, 16, 256)) {
\r
173 inserted = changed = is_standard_image = true;
\r
176 fi->Fseek(0, FILEIO_SEEK_SET);
\r
180 // check image file format
\r
181 for(int i = 0;; i++) {
\r
182 const fd_format *p = &fd_formats[i];
\r
183 if(p->type == -1) {
\r
186 int len = p->ncyl * p->nside * p->nsec * p->size;
\r
187 // 4096 bytes: FDI header ???
\r
188 if(file_size == len || (file_size == (len + 4096) && (len == 655360 || len == 1261568))) {
\r
189 if(file_size == len + 4096) {
\r
190 is_fdi_image = true;
\r
191 fi->Fread(fdi_header, 4096, 1);
\r
193 if(standard_to_d88(p->type, p->ncyl, p->nside, p->nsec, p->size)) {
\r
194 inserted = changed = is_standard_image = true;
\r
199 if(0 < file_size && file_size <= DISK_BUFFER_SIZE) {
\r
200 memset(buffer, 0, sizeof(buffer));
\r
201 fi->Fread(buffer, file_size, 1);
\r
203 // check d88 format (temporary)
\r
204 if(*(uint32 *)(buffer + 0x1c) == file_size) {
\r
205 inserted = changed = true;
\r
208 _stprintf(dest_path, _T("%s.D88"), path);
\r
210 // check file header
\r
212 if(memcmp(buffer, "TD", 2) == 0 || memcmp(buffer, "td", 2) == 0) {
\r
213 // teledisk image file
\r
214 inserted = changed = converted = teledisk_to_d88();
\r
215 } else if(memcmp(buffer, "IMD", 3) == 0) {
\r
216 // imagedisk image file
\r
217 inserted = changed = converted = imagedisk_to_d88();
\r
218 } else if(memcmp(buffer, "MV - CPC", 8) == 0) {
\r
219 // standard cpdread image file
\r
220 inserted = changed = converted = cpdread_to_d88(0);
\r
221 } else if(memcmp(buffer, "EXTENDED", 8) == 0) {
\r
222 // extended cpdread image file
\r
223 inserted = changed = converted = cpdread_to_d88(1);
\r
227 // failed to convert the disk image
\r
228 #if defined(_USE_AGAR) || defined(_USE_SDL)
\r
229 AGAR_DebugLog(AGAR_LOG_INFO, "EE: disk.cpp : Failed to convert disk image.");
\r
234 if(fi->IsOpened()) {
\r
238 fi->Remove(temp_path);
\r
244 FILEIO* fio = new FILEIO();
\r
245 if(fio->Fopen(dest_path, FILEIO_WRITE_BINARY)) {
\r
246 fio->Fwrite(buffer, file_size, 1);
\r
252 crc32 = getcrc32(buffer, file_size);
\r
254 if(buffer[0x1a] != 0) {
\r
255 write_protected = true;
\r
257 if(media_type == MEDIA_TYPE_UNK) {
\r
258 if((media_type = buffer[0x1b]) == MEDIA_TYPE_2HD) {
\r
259 for(int trkside = 0; trkside < 164; trkside++) {
\r
260 uint32 offset = buffer[0x20 + trkside * 4 + 0];
\r
261 offset |= buffer[0x20 + trkside * 4 + 1] << 8;
\r
262 offset |= buffer[0x20 + trkside * 4 + 2] << 16;
\r
263 offset |= buffer[0x20 + trkside * 4 + 3] << 24;
\r
269 uint8 *t = buffer + offset;
\r
270 int sector_num = t[4] | (t[5] << 8);
\r
271 int data_size = t[14] | (t[15] << 8);
\r
273 if(sector_num >= 18 && data_size == 512) {
\r
274 media_type = MEDIA_TYPE_144;
\r
280 // FIXME: ugly patch for X1turbo ALPHA and ARCUS
\r
282 #if defined(_X1TURBO) || defined(_X1TURBOZ)
\r
283 if(media_type == MEDIA_TYPE_2D) {
\r
284 uint32 offset = buffer[0x20] | (buffer[0x21] << 8) | (buffer[0x22] << 16) | (buffer[0x23] << 24);
\r
285 uint8 *t = buffer + offset;
\r
286 is_alpha = (strncmp((char *)(t + 0x11), "turbo ALPHA", 11) == 0);
\r
295 // write disk image
\r
297 if(!write_protected && file_size && getcrc32(buffer, file_size) != crc32) {
\r
299 FILEIO* fio = new FILEIO();
\r
300 if(fio->Fopen(dest_path, FILEIO_READ_WRITE_BINARY)) {
\r
301 fio->Fseek(file_offset, FILEIO_SEEK_SET);
\r
303 fio->Fopen(dest_path, FILEIO_WRITE_BINARY);
\r
305 if(fio->IsOpened()) {
\r
306 if(is_standard_image) {
\r
308 fio->Fwrite(fdi_header, 4096, 1);
\r
310 for(int trkside = 0; trkside < 164; trkside++) {
\r
311 uint32 offset = buffer[0x20 + trkside * 4 + 0];
\r
312 offset |= buffer[0x20 + trkside * 4 + 1] << 8;
\r
313 offset |= buffer[0x20 + trkside * 4 + 2] << 16;
\r
314 offset |= buffer[0x20 + trkside * 4 + 3] << 24;
\r
319 uint8* t = buffer + offset;
\r
320 int sector_num = t[4] | (t[5] << 8);
\r
322 for(int i = 0; i < sector_num; i++) {
\r
323 int data_size = t[14] | (t[15] << 8);
\r
324 fio->Fwrite(t + 0x10, data_size, 1);
\r
325 t += data_size + 0x10;
\r
329 fio->Fwrite(buffer, file_size, 1);
\r
337 inserted = write_protected = false;
\r
339 sector_size = sector_num = 0;
\r
343 bool DISK::get_track(int trk, int side)
\r
345 sector_size = sector_num = 0;
\r
348 // disk not inserted or invalid media type
\r
349 if(!(inserted && check_media_type())) {
\r
354 int trkside = trk * 2 + (side & 1);
\r
355 if(!(0 <= trkside && trkside < 164)) {
\r
358 uint32 offset = buffer[0x20 + trkside * 4 + 0];
\r
359 offset |= buffer[0x20 + trkside * 4 + 1] << 8;
\r
360 offset |= buffer[0x20 + trkside * 4 + 2] << 16;
\r
361 offset |= buffer[0x20 + trkside * 4 + 3] << 24;
\r
368 sector = buffer + offset;
\r
369 sector_num = sector[4] | (sector[5] << 8);
\r
371 // create each sector position in track
\r
372 int sync_size = drive_mfm ? 12 : 6;
\r
373 int am_size = drive_mfm ? 3 : 0;
\r
374 int gap2_size = drive_mfm ? 22 : 11;
\r
376 data_size_shift = 0;
\r
377 too_many_sectors = false;
\r
380 int total = 0, gap3_size;
\r
382 for(int i = 0; i < sector_num; i++) {
\r
383 int data_size = t[14] | (t[15] << 8);
\r
385 if((data_size >> data_size_shift) < 0x80) {
\r
386 too_many_sectors = true;
\r
389 total += sync_size + (am_size + 1) + (4 + 2) + gap2_size + sync_size + (am_size + 1);
\r
390 total += (data_size >> data_size_shift) + 2;
\r
392 t += data_size + 0x10;
\r
394 if(too_many_sectors) {
\r
395 // Too many sectors in this track
\r
397 data_size_shift = 0;
\r
398 } else if((gap3_size = (get_track_size() - total) / (sector_num + 2)) < 12) {
\r
399 // ID:N is modified
\r
404 total = gap3_size * 2;
\r
406 for(int i = 0; i < sector_num; i++) {
\r
407 int data_size = t[14] | (t[15] << 8);
\r
409 if(too_many_sectors) {
\r
410 total = gap3_size * 2 + (get_track_size() - gap3_size * 2) * i / sector_num;
\r
412 sync_position[i] = total;
\r
413 total += sync_size + (am_size + 1);
\r
414 id_position[i] = total;
\r
415 total += (4 + 2) + gap2_size + sync_size + (am_size + 1);
\r
416 data_position[i] = total;
\r
417 total += (data_size >> data_size_shift) + 2 + gap3_size;
\r
419 if(t[2] != i + 1) {
\r
422 t += data_size + 0x10;
\r
427 bool DISK::make_track(int trk, int side)
\r
429 int track_size = get_track_size();
\r
431 if(!get_track(trk, side)) {
\r
432 // create a dummy track
\r
433 for(int i = 0; i < track_size; i++) {
\r
439 // make track image
\r
440 int sync_size = drive_mfm ? 12 : 6;
\r
441 int am_size = drive_mfm ? 3 : 0;
\r
442 int gap2_size = drive_mfm ? 22 : 11;
\r
443 uint8 gap_data = drive_mfm ? 0x4e : 0xff;
\r
446 memset(track, gap_data, track_size);
\r
448 if(sync_position[0] >= (sync_size + am_size + 1) + (8 + 5)) {
\r
449 int p = (sync_position[0] - (sync_size + am_size + 1)) * 8 / (8 + 5);
\r
452 for(int i = 0; i < sync_size; i++) {
\r
456 for(int i = 0; i < am_size; i++) {
\r
465 for(int i = 0; i < sector_num; i++) {
\r
466 int data_size = t[14] | (t[15] << 8);
\r
467 int p = sync_position[i];
\r
470 for(int j = 0; j < sync_size; j++) {
\r
471 if(p < track_size) track[p++] = 0x00;
\r
474 for(int j = 0; j < am_size; j++) {
\r
475 if(p < track_size) track[p++] = 0xa1;
\r
477 if(p < track_size) track[p++] = 0xfe;
\r
479 if(p < track_size) track[p++] = t[0];
\r
480 if(p < track_size) track[p++] = t[1];
\r
481 if(p < track_size) track[p++] = t[2];
\r
482 if(p < track_size) track[p++] = t[3];
\r
484 crc = (uint16)((crc << 8) ^ crc_table[(uint8)(crc >> 8) ^ t[0]]);
\r
485 crc = (uint16)((crc << 8) ^ crc_table[(uint8)(crc >> 8) ^ t[1]]);
\r
486 crc = (uint16)((crc << 8) ^ crc_table[(uint8)(crc >> 8) ^ t[2]]);
\r
487 crc = (uint16)((crc << 8) ^ crc_table[(uint8)(crc >> 8) ^ t[3]]);
\r
488 if(p < track_size) track[p++] = crc >> 8;
\r
489 if(p < track_size) track[p++] = crc & 0xff;
\r
491 for(int j = 0; j < gap2_size; j++) {
\r
492 if(p < track_size) track[p++] = gap_data;
\r
495 for(int j = 0; j < sync_size; j++) {
\r
496 if(p < track_size) track[p++] = 0x00;
\r
499 for(int j = 0; j < am_size; j++) {
\r
500 if(p < track_size) track[p++] = 0xa1;
\r
502 if(p < track_size) track[p++] = (t[7] != 0) ? 0xf8 : 0xfb;
\r
505 for(int j = 0; j < (data_size >> data_size_shift); j++) {
\r
506 if(p < track_size) track[p++] = t[0x10 + j];
\r
507 crc = (uint16)((crc << 8) ^ crc_table[(uint8)(crc >> 8) ^ t[0x10 + j]]);
\r
509 if(p < track_size) track[p++] = crc >> 8;
\r
510 if(p < track_size) track[p++] = crc & 0xff;
\r
512 t += data_size + 0x10;
\r
517 bool DISK::get_sector(int trk, int side, int index)
\r
519 sector_size = sector_num = 0;
\r
522 // disk not inserted or invalid media type
\r
523 if(!(inserted && check_media_type())) {
\r
528 int trkside = trk * 2 + (side & 1);
\r
529 if(!(0 <= trkside && trkside < 164)) {
\r
532 uint32 offset = buffer[0x20 + trkside * 4 + 0];
\r
533 offset |= buffer[0x20 + trkside * 4 + 1] << 8;
\r
534 offset |= buffer[0x20 + trkside * 4 + 2] << 16;
\r
535 offset |= buffer[0x20 + trkside * 4 + 3] << 24;
\r
542 uint8* t = buffer + offset;
\r
543 sector_num = t[4] | (t[5] << 8);
\r
545 if(index >= sector_num) {
\r
550 for(int i = 0; i < index; i++) {
\r
551 t += (t[14] | (t[15] << 8)) + 0x10;
\r
560 crc = (uint16)((crc << 8) ^ crc_table[(uint8)(crc >> 8) ^ t[0]]);
\r
561 crc = (uint16)((crc << 8) ^ crc_table[(uint8)(crc >> 8) ^ t[1]]);
\r
562 crc = (uint16)((crc << 8) ^ crc_table[(uint8)(crc >> 8) ^ t[2]]);
\r
563 crc = (uint16)((crc << 8) ^ crc_table[(uint8)(crc >> 8) ^ t[3]]);
\r
565 id[5] = crc & 0xff;
\r
570 sector_size = t[14] | (t[15] << 8);
\r
575 int DISK::get_rpm()
\r
577 if(drive_rpm != 0) {
\r
579 } else if(inserted) {
\r
580 return (media_type == MEDIA_TYPE_2HD) ? 360 : 300;
\r
582 return (drive_type == DRIVE_TYPE_2HD) ? 360 : 300;
\r
586 int DISK::get_track_size()
\r
589 return media_type == MEDIA_TYPE_144 ? 12500 : media_type == MEDIA_TYPE_2HD ? 10410 : drive_mfm ? 6250 : 3100;
\r
591 return drive_type == DRIVE_TYPE_144 ? 12500 : drive_type == DRIVE_TYPE_2HD ? 10410 : drive_mfm ? 6250 : 3100;
\r
595 double DISK::get_usec_per_bytes(int bytes)
\r
597 return 1000000.0 / (get_track_size() * (get_rpm() / 60.0)) * bytes;
\r
600 bool DISK::check_media_type()
\r
602 switch(drive_type) {
\r
603 case DRIVE_TYPE_2D:
\r
604 return (media_type == MEDIA_TYPE_2D);
\r
605 case DRIVE_TYPE_2DD:
\r
606 return (media_type == MEDIA_TYPE_2D || media_type == MEDIA_TYPE_2DD);
\r
607 case DRIVE_TYPE_2HD:
\r
608 return (media_type == MEDIA_TYPE_2HD);
\r
609 case DRIVE_TYPE_144:
\r
610 return (media_type == MEDIA_TYPE_144);
\r
611 case DRIVE_TYPE_UNK:
\r
612 return true; // always okay
\r
617 // teledisk image decoder
\r
620 this teledisk image decoder is based on:
\r
622 LZHUF.C English version 1.0 based on Japanese version 29-NOV-1988
\r
623 LZSS coded by Haruhiko OKUMURA
\r
624 Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI
\r
625 Edited and translated to English by Kenji RIKITAKE
\r
629 #define COPYBUFFER(src, size) { \
\r
630 if(file_size + (size) > DISK_BUFFER_SIZE) { \
\r
633 memcpy(buffer + file_size, (src), (size)); \
\r
634 file_size += (size); \
\r
637 bool DISK::teledisk_to_d88()
\r
639 struct td_hdr_t hdr;
\r
640 struct td_cmt_t cmt;
\r
641 struct td_trk_t trk;
\r
642 struct td_sct_t sct;
\r
643 struct d88_hdr_t d88_hdr;
\r
644 struct d88_sct_t d88_sct;
\r
647 // check teledisk header
\r
648 fi->Fseek(0, FILEIO_SEEK_SET);
\r
649 fi->Fread(&hdr, sizeof(td_hdr_t), 1);
\r
650 if(hdr.sig[0] == 't' && hdr.sig[1] == 'd') {
\r
651 // decompress to the temporary file
\r
652 FILEIO* fo = new FILEIO();
\r
653 if(!fo->Fopen(temp_path, FILEIO_WRITE_BINARY)) {
\r
660 if((rd = decode(obuf, 512)) > 0) {
\r
661 fo->Fwrite(obuf, rd, 1);
\r
669 // reopen the temporary file
\r
671 if(!fi->Fopen(temp_path, FILEIO_READ_BINARY)) {
\r
675 if(hdr.flag & 0x80) {
\r
677 fi->Fread(&cmt, sizeof(td_cmt_t), 1);
\r
678 fi->Fseek(cmt.len, FILEIO_SEEK_CUR);
\r
681 // create d88 image
\r
684 // create d88 header
\r
685 memset(&d88_hdr, 0, sizeof(d88_hdr_t));
\r
686 strcpy(d88_hdr.title, "TELEDISK");
\r
687 d88_hdr.protect = 0; // non-protected
\r
688 COPYBUFFER(&d88_hdr, sizeof(d88_hdr_t));
\r
691 int trkcnt = 0, trkptr = sizeof(d88_hdr_t);
\r
692 fi->Fread(&trk, sizeof(td_trk_t), 1);
\r
693 while(trk.nsec != 0xff) {
\r
694 d88_hdr.trkptr[trkcnt++] = trkptr;
\r
695 if(hdr.sides == 1) {
\r
696 d88_hdr.trkptr[trkcnt++] = trkptr;
\r
699 // read sectors in this track
\r
700 for(int i = 0; i < trk.nsec; i++) {
\r
701 uint8 buf[2048], dst[2048];
\r
702 memset(buf, 0, sizeof(buf));
\r
703 memset(dst, 0, sizeof(dst));
\r
705 // read sector header
\r
706 fi->Fread(&sct, sizeof(td_sct_t), 1);
\r
708 // create d88 sector header
\r
709 memset(&d88_sct, 0, sizeof(d88_sct_t));
\r
714 d88_sct.nsec = trk.nsec;
\r
715 d88_sct.dens = (hdr.dens & 0x80) ? 0x40 : 0;
\r
716 d88_sct.del = (sct.ctrl & 4) ? 0x10 : 0;
\r
717 d88_sct.stat = (sct.ctrl & 2) ? 0x10 : 0; // crc?
\r
718 d88_sct.size = secsize[sct.n & 3];
\r
720 // create sector image
\r
721 if(sct.ctrl != 0x10) {
\r
722 // read sector source
\r
723 int len = fi->Fgetc();
\r
724 len += fi->Fgetc() * 256 - 1;
\r
725 int flag = fi->Fgetc(), d = 0;
\r
726 fi->Fread(buf, len, 1);
\r
730 memcpy(dst, buf, len);
\r
731 } else if(flag == 1) {
\r
732 int len2 = buf[0] | (buf[1] << 8);
\r
737 } else if(flag == 2) {
\r
738 for(int s = 0; s < len;) {
\r
739 int type = buf[s++];
\r
740 int len2 = buf[s++];
\r
743 dst[d++] = buf[s++];
\r
745 } else if(type < 5) {
\r
748 while(type-- > 1) {
\r
751 for(int j = 0; j < n; j++) {
\r
755 for(int j = 0; j < n; j++) {
\r
760 break; // unknown type
\r
764 break; // unknown flag
\r
771 COPYBUFFER(&d88_sct, sizeof(d88_sct_t));
\r
772 COPYBUFFER(dst, d88_sct.size);
\r
773 trkptr += sizeof(d88_sct_t) + d88_sct.size;
\r
776 fi->Fread(&trk, sizeof(td_trk_t), 1);
\r
778 d88_hdr.type = ((hdr.dens & 3) == 2) ? MEDIA_TYPE_2HD : ((trkcnt >> 1) > 60) ? MEDIA_TYPE_2DD : MEDIA_TYPE_2D;
\r
779 d88_hdr.size = trkptr;
\r
780 memcpy(buffer, &d88_hdr, sizeof(d88_hdr_t));
\r
784 int DISK::next_word()
\r
786 if(ibufndx >= ibufcnt) {
\r
787 ibufndx = ibufcnt = 0;
\r
788 memset(inbuf, 0, 512);
\r
789 for(int i = 0; i < 512; i++) {
\r
790 int d = fi->Fgetc();
\r
801 while(getlen <= 8) {
\r
802 getbuf |= inbuf[ibufndx++] << (8 - getlen);
\r
808 int DISK::get_bit()
\r
810 if(next_word() < 0) {
\r
816 return (i < 0) ? 1 : 0;
\r
819 int DISK::get_byte()
\r
821 if(next_word() != 0) {
\r
831 void DISK::start_huff()
\r
834 for(i = 0; i < N_CHAR; i++) {
\r
836 son[i] = i + TABLE_SIZE;
\r
837 prnt[i + TABLE_SIZE] = i;
\r
840 while(j <= ROOT_POSITION) {
\r
841 freq[j] = freq[i] + freq[i + 1];
\r
843 prnt[i] = prnt[i + 1] = j;
\r
846 freq[TABLE_SIZE] = 0xffff;
\r
847 prnt[ROOT_POSITION] = 0;
\r
850 void DISK::reconst()
\r
854 for(i = 0; i < TABLE_SIZE; i++) {
\r
855 if(son[i] >= TABLE_SIZE) {
\r
856 freq[j] = (freq[i] + 1) / 2;
\r
861 for(i = 0, j = N_CHAR; j < TABLE_SIZE; i += 2, j++) {
\r
863 f = freq[j] = freq[i] + freq[k];
\r
864 for(k = j - 1; f < freq[k]; k--);
\r
867 memmove(&freq[k + 1], &freq[k], l);
\r
869 memmove(&son[k + 1], &son[k], l);
\r
872 for(i = 0; i < TABLE_SIZE; i++) {
\r
873 if((k = son[i]) >= TABLE_SIZE) {
\r
876 prnt[k] = prnt[k + 1] = i;
\r
881 void DISK::update(int c)
\r
884 if(freq[ROOT_POSITION] == MAX_FREQ) {
\r
887 c = prnt[c + TABLE_SIZE];
\r
890 if(k > freq[l = c + 1]) {
\r
891 while(k > freq[++l]);
\r
897 if(i < TABLE_SIZE) {
\r
903 if(j < TABLE_SIZE) {
\r
910 while((c = prnt[c]) != 0);
\r
913 short DISK::decode_char()
\r
916 uint16 c = son[ROOT_POSITION];
\r
917 while(c < TABLE_SIZE) {
\r
918 if((ret = get_bit()) < 0) {
\r
921 c += (unsigned)ret;
\r
929 short DISK::decode_position()
\r
933 if((bit = get_byte()) < 0) {
\r
937 c = (uint16)d_code[i] << 6;
\r
940 if((bit = get_bit()) < 0) {
\r
943 i = (i << 1) + bit;
\r
945 return (c | i & 0x3f);
\r
948 void DISK::init_decode()
\r
950 ibufcnt= ibufndx = bufcnt = getbuf = 0;
\r
953 for(int i = 0; i < STRING_BUFFER_SIZE - LOOKAHEAD_BUFFER_SIZE; i++) {
\r
956 ptr = STRING_BUFFER_SIZE - LOOKAHEAD_BUFFER_SIZE;
\r
959 int DISK::decode(uint8 *buf, int len)
\r
963 for(count = 0; count < len;) {
\r
965 if((c = decode_char()) < 0) {
\r
969 *(buf++) = (uint8)c;
\r
970 text_buf[ptr++] = (uint8)c;
\r
971 ptr &= (STRING_BUFFER_SIZE - 1);
\r
974 if((pos = decode_position()) < 0) {
\r
977 bufpos = (ptr - pos - 1) & (STRING_BUFFER_SIZE - 1);
\r
978 bufcnt = c - 255 + THRESHOLD;
\r
982 while(bufndx < bufcnt && count < len) {
\r
983 c = text_buf[(bufpos + bufndx) & (STRING_BUFFER_SIZE - 1)];
\r
984 *(buf++) = (uint8)c;
\r
986 text_buf[ptr++] = (uint8)c;
\r
987 ptr &= (STRING_BUFFER_SIZE - 1);
\r
990 if(bufndx >= bufcnt) {
\r
991 bufndx = bufcnt = 0;
\r
998 // imagedisk image decoder
\r
1000 bool DISK::imagedisk_to_d88()
\r
1002 struct imd_trk_t trk;
\r
1003 struct d88_hdr_t d88_hdr;
\r
1004 struct d88_sct_t d88_sct;
\r
1007 fi->Fseek(0, FILEIO_SEEK_SET);
\r
1009 while((tmp = fi->Fgetc()) != 0x1a) {
\r
1015 // create d88 image
\r
1018 // create d88 header
\r
1019 memset(&d88_hdr, 0, sizeof(d88_hdr_t));
\r
1020 strcpy(d88_hdr.title, "IMAGEDISK");
\r
1021 d88_hdr.protect = 0; // non-protected
\r
1022 COPYBUFFER(&d88_hdr, sizeof(d88_hdr_t));
\r
1025 int trkptr = sizeof(d88_hdr_t);
\r
1026 int trkcnt = 0, mode;
\r
1028 for(int t = 0; t < 164; t++) {
\r
1029 // check end of file
\r
1030 if(fi->Fread(&trk, sizeof(imd_trk_t), 1) != 1) {
\r
1035 // check track header
\r
1037 mode = trk.mode % 3; // 0=500kbps, 1=300kbps, 2=250kbps
\r
1042 d88_hdr.trkptr[t] = trkptr;
\r
1044 // setup sector id
\r
1045 uint8 c[64], h[64], r[64];
\r
1046 fi->Fread(r, trk.nsec, 1);
\r
1047 if(trk.head & 0x80) {
\r
1048 fi->Fread(c, trk.nsec, 1);
\r
1050 memset(c, trk.cyl, sizeof(c));
\r
1052 if(trk.head & 0x40) {
\r
1053 fi->Fread(h, trk.nsec, 1);
\r
1055 memset(h, trk.head & 1, sizeof(h));
\r
1058 // read sectors in this track
\r
1059 for(int i = 0; i < trk.nsec; i++) {
\r
1060 // create d88 sector header
\r
1061 static const uint8 del[] = {0, 0, 0, 0x10, 0x10, 0, 0, 0x10, 0x10};
\r
1062 static const uint8 err[] = {0, 0, 0, 0, 0, 0x10, 0x10, 0x10, 0x10};
\r
1063 int sectype = fi->Fgetc();
\r
1067 memset(&d88_sct, 0, sizeof(d88_sct_t));
\r
1071 d88_sct.n = trk.size;
\r
1072 d88_sct.nsec = trk.nsec;
\r
1073 d88_sct.dens = (trk.mode < 3) ? 0x40 : 0;
\r
1074 d88_sct.del = del[sectype];
\r
1075 d88_sct.stat = err[sectype];
\r
1076 d88_sct.size = secsize[trk.size & 7];
\r
1078 // create sector image
\r
1080 if(sectype == 1 || sectype == 3 || sectype == 5 || sectype == 7) {
\r
1082 fi->Fread(dst, d88_sct.size, 1);
\r
1083 } else if(sectype == 2 || sectype == 4 || sectype == 6 || sectype == 8) {
\r
1085 int tmp = fi->Fgetc();
\r
1086 memset(dst, tmp, d88_sct.size);
\r
1092 COPYBUFFER(&d88_sct, sizeof(d88_sct_t));
\r
1093 COPYBUFFER(dst, d88_sct.size);
\r
1094 trkptr += sizeof(d88_sct_t) + d88_sct.size;
\r
1097 d88_hdr.type = (mode == 0) ? MEDIA_TYPE_2HD : ((trkcnt >> 1) > 60) ? MEDIA_TYPE_2DD : MEDIA_TYPE_2D;
\r
1098 d88_hdr.size = trkptr;
\r
1099 memcpy(buffer, &d88_hdr, sizeof(d88_hdr_t));
\r
1103 // cpdread image decoder (from MESS formats/dsk_dsk.c)
\r
1105 bool DISK::cpdread_to_d88(int extended)
\r
1107 struct d88_hdr_t d88_hdr;
\r
1108 struct d88_sct_t d88_sct;
\r
1111 // get cylinder number and side number
\r
1112 memcpy(tmp_buffer, buffer, file_size);
\r
1113 int ncyl = tmp_buffer[0x30];
\r
1114 int nside = tmp_buffer[0x31];
\r
1116 // create d88 image
\r
1119 // create d88 header
\r
1120 memset(&d88_hdr, 0, sizeof(d88_hdr_t));
\r
1121 strcpy(d88_hdr.title, "CPDRead");
\r
1122 d88_hdr.protect = 0; // non-protected
\r
1123 COPYBUFFER(&d88_hdr, sizeof(d88_hdr_t));
\r
1126 int trkofs = 0x100, trkofs_ptr = 0x34;
\r
1127 int trkptr = sizeof(d88_hdr_t);
\r
1129 for(int c = 0; c < ncyl; c++) {
\r
1130 for(int h = 0; h < nside; h++) {
\r
1131 // read sectors in this track
\r
1132 uint8 *track_info = tmp_buffer + trkofs;
\r
1133 int cyl = track_info[0x10];
\r
1134 int side = track_info[0x11];
\r
1135 int nsec = track_info[0x15];
\r
1136 int size = 1 << (track_info[0x14] + 7); // standard
\r
1137 int sctofs = trkofs + 0x100;
\r
1141 d88_hdr.trkptr[2 * cyl] = d88_hdr.trkptr[2 * cyl + 1] = trkptr;
\r
1143 d88_hdr.trkptr[2 * cyl + side] = trkptr;
\r
1145 for(int s = 0; s < nsec; s++) {
\r
1146 // get sector size
\r
1147 uint8 *sector_info = tmp_buffer + trkofs + 0x18 + s * 8;
\r
1149 size = sector_info[6] + sector_info[7] * 256;
\r
1152 // create d88 sector header
\r
1153 memset(&d88_sct, 0, sizeof(d88_sct_t));
\r
1154 d88_sct.c = sector_info[0];
\r
1155 d88_sct.h = sector_info[1];
\r
1156 d88_sct.r = sector_info[2];
\r
1157 d88_sct.n = sector_info[3];
\r
1158 d88_sct.nsec = nsec;
\r
1160 d88_sct.del = (sector_info[5] & 0x40) ? 0x10 : 0;
\r
1162 d88_sct.size = size;
\r
1165 COPYBUFFER(&d88_sct, sizeof(d88_sct_t));
\r
1166 COPYBUFFER(tmp_buffer + sctofs, size);
\r
1167 trkptr += sizeof(d88_sct_t) + size;
\r
1173 trkofs += tmp_buffer[trkofs_ptr++] * 256;
\r
1175 trkofs += tmp_buffer[0x32] + tmp_buffer[0x33] * 256;
\r
1179 d88_hdr.type = (total < (368640 + 655360) / 2) ? MEDIA_TYPE_2D : (total < (737280 + 1228800) / 2) ? MEDIA_TYPE_2DD : MEDIA_TYPE_2HD;
\r
1180 d88_hdr.size = trkptr;
\r
1181 memcpy(buffer, &d88_hdr, sizeof(d88_hdr_t));
\r
1185 // standard image decoder
\r
1187 bool DISK::standard_to_d88(int type, int ncyl, int nside, int nsec, int size)
\r
1189 struct d88_hdr_t d88_hdr;
\r
1190 struct d88_sct_t d88_sct;
\r
1195 // create d88 header
\r
1196 memset(&d88_hdr, 0, sizeof(d88_hdr_t));
\r
1197 strcpy(d88_hdr.title, "STANDARD");
\r
1198 d88_hdr.protect = 0; // non-protected
\r
1199 d88_hdr.type = (type == MEDIA_TYPE_144) ? MEDIA_TYPE_2HD : type;
\r
1200 media_type = type;
\r
1201 COPYBUFFER(&d88_hdr, sizeof(d88_hdr_t));
\r
1204 for(int i = 0; i < 8; i++) {
\r
1205 if(size == (128 << i)) {
\r
1212 int trkptr = sizeof(d88_hdr_t);
\r
1213 for(int c = 0; c < ncyl; c++) {
\r
1214 for(int h = 0; h < nside; h++) {
\r
1215 d88_hdr.trkptr[t++] = trkptr;
\r
1218 d88_hdr.trkptr[t++] = trkptr;
\r
1221 // read sectors in this track
\r
1222 for(int s = 0; s < nsec; s++) {
\r
1223 // create d88 sector header
\r
1224 memset(&d88_sct, 0, sizeof(d88_sct_t));
\r
1227 d88_sct.r = s + 1;
\r
1229 d88_sct.nsec = nsec;
\r
1233 d88_sct.size = size;
\r
1235 // create sector image
\r
1237 memset(dst, 0xe5, sizeof(dst));
\r
1238 fi->Fread(dst, size, 1);
\r
1241 COPYBUFFER(&d88_sct, sizeof(d88_sct_t));
\r
1242 COPYBUFFER(dst, size);
\r
1243 trkptr += sizeof(d88_sct_t) + size;
\r
1247 d88_hdr.size = trkptr;
\r
1248 memcpy(buffer, &d88_hdr, sizeof(d88_hdr_t));
\r
1252 #define STATE_VERSION 1
\r
1254 void DISK::save_state(FILEIO* state_fio)
\r
1256 state_fio->FputUint32(STATE_VERSION);
\r
1258 state_fio->Fwrite(buffer, sizeof(buffer), 1);
\r
1259 state_fio->Fwrite(orig_path, sizeof(orig_path), 1);
\r
1260 state_fio->Fwrite(dest_path, sizeof(dest_path), 1);
\r
1261 state_fio->FputInt32(file_size);
\r
1262 state_fio->FputInt32(file_offset);
\r
1263 state_fio->FputUint32(crc32);
\r
1264 state_fio->Fwrite(fdi_header, sizeof(fdi_header), 1);
\r
1265 state_fio->FputBool(inserted);
\r
1266 state_fio->FputBool(ejected);
\r
1267 state_fio->FputBool(write_protected);
\r
1268 state_fio->FputBool(changed);
\r
1269 state_fio->FputUint8(media_type);
\r
1270 state_fio->FputBool(is_standard_image);
\r
1271 state_fio->FputBool(is_fdi_image);
\r
1272 state_fio->FputBool(is_alpha);
\r
1273 state_fio->Fwrite(track, sizeof(track), 1);
\r
1274 state_fio->FputInt32(sector_num);
\r
1275 state_fio->FputInt32(data_size_shift);
\r
1276 state_fio->FputBool(too_many_sectors);
\r
1277 state_fio->FputBool(no_skew);
\r
1278 state_fio->Fwrite(sync_position, sizeof(sync_position), 1);
\r
1279 state_fio->Fwrite(id_position, sizeof(id_position), 1);
\r
1280 state_fio->Fwrite(data_position, sizeof(data_position), 1);
\r
1281 state_fio->FputInt32(sector ? (int)(sector - buffer) : -1);
\r
1282 state_fio->FputInt32(sector_size);
\r
1283 state_fio->Fwrite(id, sizeof(id), 1);
\r
1284 state_fio->FputUint8(density);
\r
1285 state_fio->FputUint8(deleted);
\r
1286 state_fio->FputUint8(status);
\r
1287 state_fio->FputUint8(drive_type);
\r
1288 state_fio->FputInt32(drive_rpm);
\r
1289 state_fio->FputBool(drive_mfm);
\r
1292 bool DISK::load_state(FILEIO* state_fio)
\r
1294 if(state_fio->FgetUint32() != STATE_VERSION) {
\r
1297 state_fio->Fread(buffer, sizeof(buffer), 1);
\r
1298 state_fio->Fread(orig_path, sizeof(orig_path), 1);
\r
1299 state_fio->Fread(dest_path, sizeof(dest_path), 1);
\r
1300 file_size = state_fio->FgetInt32();
\r
1301 file_offset = state_fio->FgetInt32();
\r
1302 crc32 = state_fio->FgetUint32();
\r
1303 state_fio->Fread(fdi_header, sizeof(fdi_header), 1);
\r
1304 inserted = state_fio->FgetBool();
\r
1305 ejected = state_fio->FgetBool();
\r
1306 write_protected = state_fio->FgetBool();
\r
1307 changed = state_fio->FgetBool();
\r
1308 media_type = state_fio->FgetUint8();
\r
1309 is_standard_image = state_fio->FgetBool();
\r
1310 is_fdi_image = state_fio->FgetBool();
\r
1311 is_alpha = state_fio->FgetBool();
\r
1312 state_fio->Fread(track, sizeof(track), 1);
\r
1313 sector_num = state_fio->FgetInt32();
\r
1314 data_size_shift = state_fio->FgetInt32();
\r
1315 too_many_sectors = state_fio->FgetBool();
\r
1316 no_skew = state_fio->FgetBool();
\r
1317 state_fio->Fread(sync_position, sizeof(sync_position), 1);
\r
1318 state_fio->Fread(id_position, sizeof(id_position), 1);
\r
1319 state_fio->Fread(data_position, sizeof(data_position), 1);
\r
1320 int offset = state_fio->FgetInt32();
\r
1321 sector = (offset != -1) ? buffer + offset : NULL;
\r
1322 sector_size = state_fio->FgetInt32();
\r
1323 state_fio->Fread(id, sizeof(id), 1);
\r
1324 density = state_fio->FgetUint8();
\r
1325 deleted = state_fio->FgetUint8();
\r
1326 status = state_fio->FgetUint8();
\r
1327 drive_type = state_fio->FgetUint8();
\r
1328 drive_rpm = state_fio->FgetInt32();
\r
1329 drive_mfm = state_fio->FgetBool();
\r