(MESS) g64_dsk: Fixed modern image loading. (nw)

This commit is contained in:
Curt Coder 2014-01-21 21:32:41 +00:00
parent e7b95675bd
commit e04ec2a3dd
2 changed files with 52 additions and 58 deletions

View File

@ -32,7 +32,7 @@ const char *g64_format::extensions() const
return "g64,g41,g71"; return "g64,g41,g71";
} }
const UINT32 g64_format::c1541_cell_size[] = const UINT32 g64_format::cell_size[] =
{ {
4000, // 16MHz/16/4 4000, // 16MHz/16/4
3750, // 16MHz/15/4 3750, // 16MHz/15/4
@ -42,10 +42,10 @@ const UINT32 g64_format::c1541_cell_size[] =
int g64_format::identify(io_generic *io, UINT32 form_factor) int g64_format::identify(io_generic *io, UINT32 form_factor)
{ {
UINT8 header[8]; char h[8];
io_generic_read(io, &header, 0, sizeof(header)); io_generic_read(io, h, 0, 8);
if ( memcmp( header, G64_FORMAT_HEADER, 8 ) == 0) { if (!memcmp(h, G64_FORMAT_HEADER, 8)) {
return 100; return 100;
} }
return 0; return 0;
@ -57,73 +57,57 @@ bool g64_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
UINT8 *img = global_alloc_array(UINT8, size); UINT8 *img = global_alloc_array(UINT8, size);
io_generic_read(io, img, 0, size); io_generic_read(io, img, 0, size);
int version = img[0x08]; if (img[VERSION]) {
if (version) throw emu_fatalerror("g64_format: Unsupported version %u", img[VERSION]);
throw emu_fatalerror("g64_format: Unsupported version %u", version);
int track_count = img[0x09];
int pos = 0x0c;
int track_offset[84*2];
for(int track = 0; track < track_count; track++) {
track_offset[track] = pick_integer_le(img, pos, 4);
pos += 4;
} }
int speed_zone_offset[84*2]; int track_count = img[TRACK_COUNT];
for(int track = 0; track < track_count; track++) {
speed_zone_offset[track] = pick_integer_le(img, pos, 4);
pos += 4;
}
for(int track = 0; track < track_count; track++) { for (int track = 0; track < track_count; track++)
int track_size = 0; {
pos = track_offset[track]; offs_t track_offset = pick_integer_le(img, TRACK_OFFSET + (track * 4), 4);
if (pos > 0) { if (track_offset > size) throw emu_fatalerror("g64_format: Track %u offset %06x out of bounds", track, track_offset);
track_size = pick_integer_le(img, pos, 2);
pos +=2; offs_t speed_zone = pick_integer_le(img, SPEED_ZONE + (track * 4), 4);
if (speed_zone > 3) throw emu_fatalerror("g64_format: Unsupported variable speed zones on track %d", track);
size_t cell_size = c1541_cell_size[speed_zone];
size_t max_cells = 200000000/cell_size;
if (speed_zone_offset[track] > 3) size_t track_bytes = pick_integer_le(img, track_offset, 2);
throw emu_fatalerror("g64_format: Unsupported variable speed zones on track %d", track); track_offset += 2;
size_t track_cells = track_bytes * 8;
UINT32 cell_size = c1541_cell_size[speed_zone_offset[track]]; size_t track_size = MAX(track_cells, max_cells);
int total_size = 200000000/cell_size; UINT32 *trackbuf = global_alloc_array_clear(UINT32, track_size);
UINT32 *buffer = global_alloc_array_clear(UINT32, total_size); offs_t trackbuf_offs = 0;
int offset = 0;
for (int i=0; i<track_size; i++, pos++) { while (trackbuf_offs < track_cells) {
for (int bit=7; bit>=0; bit--) { for (int bit=7; bit>=0; bit--) {
bit_w(buffer, offset++, BIT(img[pos], bit), cell_size); bit_w(trackbuf, trackbuf_offs++, BIT(img[track_offset], bit), cell_size);
if (offset == total_size) break;
}
} }
track_offset++;
if (offset < total_size) {
// pad the remainder of the track with sync
int count = (total_size-offset);
for (int i=0; i<count;i++) {
bit_w(buffer, offset++, 1, cell_size);
}
}
int physical_track = track >= 84 ? track - 84 : track;
int head = track >= 84;
generate_track_from_levels(physical_track, head, buffer, total_size, 0, image);
global_free(buffer);
} }
// pad the remainder of the track with sync
while (trackbuf_offs < max_cells) {
bit_w(trackbuf, trackbuf_offs++, 1, cell_size);
}
int head = 0;
int splice_pos = 0;
generate_track_from_levels(track, head, trackbuf, track_size, splice_pos, image);
global_free(trackbuf);
} }
global_free(img);
image->set_variant(floppy_image::SSSD); image->set_variant(floppy_image::SSSD);
return true; return true;
} }
bool g64_format::save(io_generic *io, floppy_image *image)
{
return false;
}
bool g64_format::supports_save() const bool g64_format::supports_save() const
{ {
return false; return false;

View File

@ -24,11 +24,21 @@ public:
virtual int identify(io_generic *io, UINT32 form_factor); virtual int identify(io_generic *io, UINT32 form_factor);
virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image); virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image);
virtual bool save(io_generic *io, floppy_image *image);
virtual bool supports_save() const; virtual bool supports_save() const;
protected: protected:
static const UINT32 c1541_cell_size[]; enum
{
SIGNATURE = 0x0,
VERSION = 0x8,
TRACK_COUNT = 0x9,
MAX_TRACK_SIZE = 0xa,
TRACK_OFFSET = 0xc,
SPEED_ZONE = 0x15c,
MASTERING = 0x2ac
};
static const UINT32 cell_size[];
}; };
extern const floppy_format_type FLOPPY_G64_FORMAT; extern const floppy_format_type FLOPPY_G64_FORMAT;