7
7
**************************************************************************/
10
#include "formats/basicdsk.h"
13
#define SAD_HEADER_LEN 22
14
#define SAD_SIGNATURE "Aley's disk backup"
16
#define SDF_TRACKSIZE (512 * 12)
10
#include "formats/coupedsk.h"
13
const floppy_image_format_t::desc_e mgt_format::desc_10[] = {
15
{ SECTOR_LOOP_START, 0, 9 },
17
{ CRC_CCITT_START, 1 },
28
{ CRC_CCITT_START, 2 },
27
/*************************************
29
* MGT disk image format
31
*************************************/
34
Straight rip without any header
46
FLOPPY_CONSTRUCT( coupe_mgt_construct )
48
struct basicdsk_geometry geometry;
50
memset(&geometry, 0, sizeof(geometry));
53
geometry.sector_length = 512;
54
geometry.first_sector_id = 1;
59
geometry.sectors = option_resolution_lookup_int(params, PARAM_SECTORS);
64
UINT64 size = floppy_image_size(floppy);
67
if (size != 737280 && size != 819200)
68
return FLOPPY_ERROR_INVALIDIMAGE;
70
geometry.sectors = size / 81920;
74
return basicdsk_construct(floppy, &geometry);
78
FLOPPY_IDENTIFY( coupe_mgt_identify )
82
size = floppy_image_size(floppy);
84
*vote = (size == 737280 || size == 819200) ? 100 : 0;
85
return FLOPPY_ERROR_SUCCESS;
90
/*************************************
92
* SAD disk image format
94
*************************************/
99
0-17 "Aley's disk backup"
102
20 number of sectors per track
103
21 sector size divided by 64
117
static UINT64 coupe_sad_translate_offset(floppy_image *floppy,
118
const struct basicdsk_geometry *geom, int track, int head, int sector)
120
return head * geom->tracks * geom->sectors + geom->sectors * track + sector;
124
static void coupe_sad_interpret_header(floppy_image *floppy,
125
int *heads, int *tracks, int *sectors, int *sector_size)
127
UINT8 header[SAD_HEADER_LEN];
129
floppy_image_read(floppy, header, 0, SAD_HEADER_LEN);
132
*tracks = header[19];
133
*sectors = header[20];
134
*sector_size = header[21] << 6;
138
FLOPPY_CONSTRUCT( coupe_sad_construct )
140
struct basicdsk_geometry geometry;
141
int heads, tracks, sectors, sector_length;
143
memset(&geometry, 0, sizeof(geometry));
148
UINT8 header[SAD_HEADER_LEN];
150
/* get format options */
151
heads = option_resolution_lookup_int(params, PARAM_HEADS);
152
tracks = option_resolution_lookup_int(params, PARAM_TRACKS);
153
sectors = option_resolution_lookup_int(params, PARAM_SECTORS);
154
sector_length = option_resolution_lookup_int(params, PARAM_SECTOR_LENGTH);
156
/* build the header */
157
memset(header, 0, SAD_HEADER_LEN);
158
memcpy(header, SAD_SIGNATURE, 18);
161
header[20] = sectors;
162
header[21] = sector_length >> 6;
164
/* and write it to disk */
165
floppy_image_write(floppy, header, 0, sizeof(header));
170
coupe_sad_interpret_header(floppy, &heads, &tracks, §ors, §or_length);
173
/* fill in the data */
174
geometry.offset = SAD_HEADER_LEN;
175
geometry.heads = heads;
176
geometry.tracks = tracks;
177
geometry.sectors = sectors;
178
geometry.first_sector_id = 1;
179
geometry.sector_length = sector_length;
180
geometry.translate_offset = coupe_sad_translate_offset;
182
return basicdsk_construct(floppy, &geometry);
186
FLOPPY_IDENTIFY( coupe_sad_identify )
188
int heads, tracks, sectors, sector_size;
189
UINT64 size, calculated_size;
191
size = floppy_image_size(floppy);
193
/* read values from SAD header */
194
coupe_sad_interpret_header(floppy, &heads, &tracks, §ors, §or_size);
196
/* calculate expected disk image size */
197
calculated_size = SAD_HEADER_LEN + heads * tracks * sectors * sector_size;
199
*vote = (size == calculated_size) ? 100 : 0;
200
return FLOPPY_ERROR_SUCCESS;
205
/*************************************
207
* SDF disk image format
209
* TODO: wd17xx status codes are
212
*************************************/
214
static int coupe_sdf_get_heads_per_disk(floppy_image *floppy)
216
struct sdf_tag *tag = (sdf_tag *)floppy_tag(floppy);
221
static int coupe_sdf_get_tracks_per_disk(floppy_image *floppy)
223
struct sdf_tag *tag = (sdf_tag *)floppy_tag(floppy);
228
static UINT32 coupe_sdf_get_track_size(floppy_image *floppy, int head, int track)
230
return SDF_TRACKSIZE;
234
static floperr_t coupe_sdf_get_offset(floppy_image *floppy,
235
int head, int track, UINT64 *offset)
237
struct sdf_tag *tag = (sdf_tag *)floppy_tag(floppy);
239
if (head > tag->heads || track > tag->tracks)
240
return FLOPPY_ERROR_SEEKERROR;
242
*offset = (head * tag->tracks + track) * SDF_TRACKSIZE;
244
return FLOPPY_ERROR_SUCCESS;
248
static floperr_t coupe_sdf_read_track(floppy_image *floppy,
249
int head, int track, UINT64 offset, void *buffer, size_t buflen)
254
/* get the offset to this track */
255
err = coupe_sdf_get_offset(floppy, head, track, &track_offset);
258
/* read track data into buffer */
259
floppy_image_read(floppy, buffer, offset + track_offset, buflen);
261
return FLOPPY_ERROR_SUCCESS;
265
static floperr_t coupe_sdf_write_track(floppy_image *floppy,
266
int head, int track, UINT64 offset, const void *buffer, size_t buflen)
271
/* get the offset to this track */
272
err = coupe_sdf_get_offset(floppy, head, track, &track_offset);
275
/* write buffer to image */
276
floppy_image_write(floppy, buffer, offset + track_offset, buflen);
278
return FLOPPY_ERROR_SUCCESS;
282
static floperr_t coupe_sdf_get_sector_offset(floppy_image *floppy,
283
int head, int track, int sector, UINT64 *offset)
286
UINT8 buffer[SDF_TRACKSIZE];
287
int i, buffer_pos = 1;
290
err = coupe_sdf_read_track(floppy, head, track, 0, &buffer, SDF_TRACKSIZE);
293
/* check if the sector is available in this track */
294
if (sector >= buffer[0])
295
return FLOPPY_ERROR_SEEKERROR;
297
/* find the right sector in this track */
298
for (i = 0; i < buffer[0]; i++)
300
int sector_number = buffer[buffer_pos + 4];
302
if (sector_number - 1 == sector)
304
*offset = buffer_pos;
305
return FLOPPY_ERROR_SUCCESS;
308
buffer_pos += (128 << buffer[buffer_pos + 5]) + 8;
311
return FLOPPY_ERROR_INVALIDIMAGE;
315
static floperr_t coupe_sdf_get_total_sector_offset(floppy_image *floppy,
316
int head, int track, int sector, UINT64 *offset)
319
UINT64 track_offset, sector_offset;
321
/* get offset to the track start */
322
err = coupe_sdf_get_offset(floppy, head, track, &track_offset);
325
/* get offset to the start of the sector */
326
err = coupe_sdf_get_sector_offset(floppy, head, track, sector, §or_offset);
329
*offset = track_offset + sector_offset;
331
return FLOPPY_ERROR_SUCCESS;
335
static floperr_t coupe_sdf_get_sector_length(floppy_image *floppy,
336
int head, int track, int sector, UINT32 *sector_length)
339
UINT8 buffer[SDF_TRACKSIZE];
343
err = coupe_sdf_read_track(floppy, head, track, 0, &buffer, SDF_TRACKSIZE);
346
/* get offset to the start of the sector */
347
err = coupe_sdf_get_sector_offset(floppy, head, track, sector, &offset);
351
*sector_length = 128 << buffer[offset + 5];
353
return FLOPPY_ERROR_SUCCESS;
357
static floperr_t coupe_sdf_get_indexed_sector_info(floppy_image *floppy,
358
int head, int track, int sector_index,
359
int *cylinder, int *side, int *sector, UINT32 *sector_length,
360
unsigned long *flags)
363
UINT8 buffer[SDF_TRACKSIZE];
367
err = coupe_sdf_read_track(floppy, head, track, 0, &buffer, SDF_TRACKSIZE);
370
/* get offset to the start of the sector */
371
err = coupe_sdf_get_sector_offset(floppy, head, track, sector_index, &offset);
375
if (cylinder) *cylinder = buffer[offset + 2];
376
if (side) *side = buffer[offset + 3];
377
if (sector) *sector = buffer[offset + 4];
378
if (sector_length) *sector_length = 128 << buffer[offset + 5];
379
if (flags) *flags = 0; /* TODO: read DAM or DDAM and determine flags */
381
return FLOPPY_ERROR_SUCCESS;
385
static floperr_t coupe_sdf_read_indexed_sector(floppy_image *floppy,
386
int head, int track, int sector, void *buffer, size_t buflen)
391
err = coupe_sdf_get_total_sector_offset(floppy, head, track, sector, &offset);
394
/* read sector data into buffer */
395
floppy_image_read(floppy, buffer, offset + 8, buflen);
397
return FLOPPY_ERROR_SUCCESS;
401
static floperr_t coupe_sdf_write_indexed_sector(floppy_image *floppy,
402
int head, int track, int sector, const void *buffer, size_t buflen, int ddam)
407
err = coupe_sdf_get_total_sector_offset(floppy, head, track, sector, &offset);
410
/* write buffer into image */
411
floppy_image_write(floppy, buffer, offset + 8, buflen);
413
return FLOPPY_ERROR_SUCCESS;
417
static void coupe_sdf_interpret_header(floppy_image *floppy, int *heads, int *tracks)
419
UINT64 size = floppy_image_size(floppy);
421
if (size % SDF_TRACKSIZE == 0)
424
*tracks = size / (SDF_TRACKSIZE * 2);
434
FLOPPY_CONSTRUCT( coupe_sdf_construct )
436
struct FloppyCallbacks *callbacks;
443
return FLOPPY_ERROR_UNSUPPORTED;
448
coupe_sdf_interpret_header(floppy, &heads, &tracks);
451
tag = (sdf_tag *)floppy_create_tag(floppy, sizeof(struct sdf_tag));
454
return FLOPPY_ERROR_OUTOFMEMORY;
457
tag->tracks = tracks;
459
callbacks = floppy_callbacks(floppy);
460
callbacks->read_track = coupe_sdf_read_track;
461
callbacks->write_track = coupe_sdf_write_track;
462
callbacks->get_heads_per_disk = coupe_sdf_get_heads_per_disk;
463
callbacks->get_tracks_per_disk = coupe_sdf_get_tracks_per_disk;
464
callbacks->get_track_size = coupe_sdf_get_track_size;
465
callbacks->get_sector_length = coupe_sdf_get_sector_length;
466
callbacks->read_indexed_sector = coupe_sdf_read_indexed_sector;
467
callbacks->write_indexed_sector = coupe_sdf_write_indexed_sector;
468
callbacks->get_indexed_sector_info = coupe_sdf_get_indexed_sector_info;
470
return FLOPPY_ERROR_SUCCESS;
474
FLOPPY_IDENTIFY( coupe_sdf_identify )
478
/* read header values */
479
coupe_sdf_interpret_header(floppy, &heads, &tracks);
481
/* check for sensible values */
482
if (heads > 0 && heads < 3 && tracks > 0 && tracks < 84)
487
return FLOPPY_ERROR_SUCCESS;
40
mgt_format::mgt_format()
44
const char *mgt_format::name() const
49
const char *mgt_format::description() const
51
return "Sam Coupe MGT image format";
54
const char *mgt_format::extensions() const
59
bool mgt_format::supports_save() const
64
int mgt_format::identify(io_generic *io)
66
int size = io_generic_size(io);
68
if(/*size == 737280 || */ size == 819200)
74
bool mgt_format::load(io_generic *io, floppy_image *image)
76
int size = io_generic_size(io);
77
int sector_count = size == 737280 ? 9 : 10;
79
UINT8 sectdata[10*512];
81
for(int i=0; i<sector_count; i++) {
82
sectors[i].data = sectdata + 512*i;
83
sectors[i].size = 512;
84
sectors[i].sector_id = i + 1;
87
int track_size = sector_count*512;
88
for(int head=0; head < 2; head++) {
89
for(int track=0; track < 80; track++) {
90
io_generic_read(io, sectdata, (track*2+head)*track_size, track_size);
91
generate_track(desc_10, track, head, sectors, sector_count+1, 100000, image);
98
bool mgt_format::save(io_generic *io, floppy_image *image)
100
int track_count, head_count, sector_count;
101
get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);
103
if(sector_count > 10)
105
else if(sector_count < 9)
108
UINT8 sectdata[10*512];
109
int track_size = sector_count*512;
111
for(int head=0; head < 2; head++) {
112
for(int track=0; track < 80; track++) {
113
get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
114
io_generic_write(io, sectdata, (head*80 + track)*track_size, track_size);
121
const floppy_format_type FLOPPY_MGT_FORMAT = &floppy_image_format_creator<mgt_format>;