mirror of
https://github.com/holub/mame
synced 2025-06-05 20:33:45 +03:00
(MESS) g64_dsk: Fixed modern image loading. (nw)
This commit is contained in:
parent
e7b95675bd
commit
e04ec2a3dd
@ -32,7 +32,7 @@ const char *g64_format::extensions() const
|
||||
return "g64,g41,g71";
|
||||
}
|
||||
|
||||
const UINT32 g64_format::c1541_cell_size[] =
|
||||
const UINT32 g64_format::cell_size[] =
|
||||
{
|
||||
4000, // 16MHz/16/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)
|
||||
{
|
||||
UINT8 header[8];
|
||||
char h[8];
|
||||
|
||||
io_generic_read(io, &header, 0, sizeof(header));
|
||||
if ( memcmp( header, G64_FORMAT_HEADER, 8 ) == 0) {
|
||||
io_generic_read(io, h, 0, 8);
|
||||
if (!memcmp(h, G64_FORMAT_HEADER, 8)) {
|
||||
return 100;
|
||||
}
|
||||
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);
|
||||
io_generic_read(io, img, 0, size);
|
||||
|
||||
int version = img[0x08];
|
||||
if (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;
|
||||
if (img[VERSION]) {
|
||||
throw emu_fatalerror("g64_format: Unsupported version %u", img[VERSION]);
|
||||
}
|
||||
|
||||
int speed_zone_offset[84*2];
|
||||
for(int track = 0; track < track_count; track++) {
|
||||
speed_zone_offset[track] = pick_integer_le(img, pos, 4);
|
||||
pos += 4;
|
||||
}
|
||||
int track_count = img[TRACK_COUNT];
|
||||
|
||||
for(int track = 0; track < track_count; track++) {
|
||||
int track_size = 0;
|
||||
pos = track_offset[track];
|
||||
if (pos > 0) {
|
||||
track_size = pick_integer_le(img, pos, 2);
|
||||
pos +=2;
|
||||
for (int track = 0; track < track_count; track++)
|
||||
{
|
||||
offs_t track_offset = pick_integer_le(img, TRACK_OFFSET + (track * 4), 4);
|
||||
if (track_offset > size) throw emu_fatalerror("g64_format: Track %u offset %06x out of bounds", track, track_offset);
|
||||
|
||||
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)
|
||||
throw emu_fatalerror("g64_format: Unsupported variable speed zones on track %d", track);
|
||||
size_t track_bytes = pick_integer_le(img, track_offset, 2);
|
||||
track_offset += 2;
|
||||
size_t track_cells = track_bytes * 8;
|
||||
|
||||
UINT32 cell_size = c1541_cell_size[speed_zone_offset[track]];
|
||||
int total_size = 200000000/cell_size;
|
||||
UINT32 *buffer = global_alloc_array_clear(UINT32, total_size);
|
||||
int offset = 0;
|
||||
size_t track_size = MAX(track_cells, max_cells);
|
||||
UINT32 *trackbuf = global_alloc_array_clear(UINT32, track_size);
|
||||
offs_t trackbuf_offs = 0;
|
||||
|
||||
for (int i=0; i<track_size; i++, pos++) {
|
||||
for (int bit=7; bit>=0; bit--) {
|
||||
bit_w(buffer, offset++, BIT(img[pos], bit), cell_size);
|
||||
if (offset == total_size) break;
|
||||
}
|
||||
while (trackbuf_offs < track_cells) {
|
||||
for (int bit=7; bit>=0; bit--) {
|
||||
bit_w(trackbuf, trackbuf_offs++, BIT(img[track_offset], bit), cell_size);
|
||||
}
|
||||
|
||||
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);
|
||||
track_offset++;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool g64_format::save(io_generic *io, floppy_image *image)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool g64_format::supports_save() const
|
||||
{
|
||||
return false;
|
||||
|
@ -24,11 +24,21 @@ public:
|
||||
|
||||
virtual int identify(io_generic *io, UINT32 form_factor);
|
||||
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;
|
||||
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user