diff options
Diffstat (limited to 'src/lib/formats/victor9k_dsk.cpp')
-rw-r--r-- | src/lib/formats/victor9k_dsk.cpp | 208 |
1 files changed, 139 insertions, 69 deletions
diff --git a/src/lib/formats/victor9k_dsk.cpp b/src/lib/formats/victor9k_dsk.cpp index 1fbba7502be..803c75303d8 100644 --- a/src/lib/formats/victor9k_dsk.cpp +++ b/src/lib/formats/victor9k_dsk.cpp @@ -2,7 +2,7 @@ // copyright-holders:Curt Coder /********************************************************************* - formats/victor9k_dsk.c + formats/victor9k_dsk.cpp Victor 9000 sector disk image format @@ -30,12 +30,18 @@ 1 4-15 0-7 18 224.5 267 2 16-26 8-18 17 212.2 283 3 27-37 19-29 16 199.9 300 - 4 38-48 30-40 15 187.6 320 - 5 49-59 41-51 14 175.3 342 + 4 38-47* 30-39* 15 187.6 320 + 5 48-59 40-51 14 175.3 342 6 60-70 52-62 13 163.0 368 7 71-79 63-74 12 149.6 401 8 unused 75-79 11 144.0 417 + * The documentation for the Victor lists Zone 4 as ending with Track 48 + on side 1 and track 40 on side two. This is incorrect. The above table + reflects disks analyzed from various machines and matches the assembly + code in the floppy driver. Various written documents contain this + documentation bug. + Interleave factor 3 cell 2.13 usec @@ -97,92 +103,126 @@ zone. */ -#include "emu.h" // osd_printf_verbose, BIT, emu_fatalerror #include "formats/victor9k_dsk.h" +#include "coretmpl.h" // util::BIT +#include "ioprocs.h" + +#include "osdcore.h" // osd_printf_* + +#include <cstring> +#include <iterator> + + victor9k_format::victor9k_format() { } -const char *victor9k_format::name() const +const char *victor9k_format::name() const noexcept { return "victor9k"; } -const char *victor9k_format::description() const +const char *victor9k_format::description() const noexcept { return "Victor 9000 disk image"; } -const char *victor9k_format::extensions() const +const char *victor9k_format::extensions() const noexcept { return "img"; } -int victor9k_format::find_size(io_generic *io, uint32_t form_factor) +int victor9k_format::find_size(util::random_read &io) +{ + uint64_t size; + if (io.length(size)) + return -1; + + for (int i = 0; formats[i].sector_count; i++) { + const format &f = formats[i]; + if(size == uint32_t(f.sector_count*f.sector_base_size)) + return i; + } + + return -1; +} + +int victor9k_format::find_size(util::random_read &io, uint32_t form_factor) +{ + return find_size(io); +} + +int victor9k_format::identify(const floppy_image &image) { - uint64_t size = io_generic_size(io); - for(int i=0; formats[i].sector_count; i++) { + for (int i = 0; formats[i].form_factor; i++) { const format &f = formats[i]; - if(size == (uint32_t) f.sector_count*f.sector_base_size*f.head_count) + if(f.variant == image.get_variant()) return i; } + return -1; } -int victor9k_format::identify(io_generic *io, uint32_t form_factor) + +int victor9k_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const { int type = find_size(io, form_factor); if (type != -1) - return 50; + return FIFID_SIZE; return 0; } -void victor9k_format::log_boot_sector(uint8_t *data) +void victor9k_format::log_boot_sector(const uint8_t *data) { // System disc ID osd_printf_verbose("System disc: %s\n", ((data[0] == 0xff) && (data[1] == 0x00)) ? "yes" : "no"); // Load address - osd_printf_verbose("Load address: %04x\n", (data[1] << 8) | data[2]); + osd_printf_verbose("Load address: %04x\n", (data[2] && data[3])); // Length - osd_printf_verbose("Length: %04x\n", (data[3] << 8) | data[4]); + osd_printf_verbose("Length: %04x\n", (data[4] <<8 | data[5])); // Entry offset - osd_printf_verbose("Entry offset: %04x\n", (data[5] << 8) | data[6]); + osd_printf_verbose("Entry offset: %04x\n", (data[6] << 8 | data[7])); // Entry segment - osd_printf_verbose("Entry segment: %04x\n", (data[7] << 8) | data[8]); + osd_printf_verbose("Entry segment: %04x\n", (data[8] << 8 | data[9])); // I.D. - //osd_printf_verbose("I.D.: %s\n", data[10]); + osd_printf_verbose("Disk I.D.: %s\n", (data[10] << 8 | data[17])); // Part number - //osd_printf_verbose("Part number: %s\n", data[18]); + osd_printf_verbose("Part number: %s\n", (data[18] << 8 | data[25])); // Sector size - osd_printf_verbose("Sector size: %04x\n", (data[25] << 8) | data[26]); + osd_printf_verbose("Sector size: %04d\n", (data[26] << 8 | data[27])); // Data start - osd_printf_verbose("Data start: %04x\n", (data[27] << 8) | data[28]); + osd_printf_verbose("Data start: %04x\n", (data[28] << 8 | data[29])); // Boot start - osd_printf_verbose("Boot start: %04x\n", (data[29] << 8) | data[30]); + osd_printf_verbose("Boot start: %04x\n", (data[30] << 8 | data[31])); + + //Disk type - flags + osd_printf_verbose("%s sided\n", (data[32]) ? "Double" : "Single"); - // Flags - osd_printf_verbose("%s sided\n", BIT(data[33], 0) ? "Double" : "Single"); - osd_printf_verbose("Interleave factor: %u\n", data[32] >> 4); + //Sector Interleave + osd_printf_verbose("Sector Interleave: %02x\n", data[33]); // Disc type switch (data[34]) { - case 0x00: osd_printf_verbose("Disc type: CP/M\n"); break; - case 0x01: osd_printf_verbose("Disc type: MS-DOS\n"); break; - default: osd_printf_verbose("Disc type: unknown\n"); break; + case 0x01: osd_printf_verbose("Disc type: CP/M\n"); break; + case 0x10: osd_printf_verbose("Disc type: MS-DOS\n"); break; + default: osd_printf_verbose("Disc type: unknown\n"); break; } + //reserved + osd_printf_verbose("Part number: %s\n", data[35] << 8 | data[37]); + // Speed table osd_printf_verbose("Speed table: "); for (int i = 38; i < 56; i++) { @@ -210,7 +250,7 @@ floppy_image_format_t::desc_e* victor9k_format::get_sector_desc(const format &f, static floppy_image_format_t::desc_e desc[] = { /* 00 */ { SECTOR_INTERLEAVE_SKEW, 0, 0}, /* 01 */ { SECTOR_LOOP_START, 0, -1 }, - /* 02 */ { SYNC_GCR5, 9 }, + /* 02 */ { SYNC_GCR5, 15 }, /* 03 */ { GCR5, 0x07, 1 }, /* 04 */ { CRC_VICTOR_HDR_START, 1 }, /* 05 */ { TRACK_ID_VICTOR_GCR5 }, @@ -231,13 +271,13 @@ floppy_image_format_t::desc_e* victor9k_format::get_sector_desc(const format &f, /* 20 */ { END } }; - current_size = 90 + (1+1+1+1)*10 + 8*8 + 50 + (1+f.sector_base_size+2)*10 + 8*8; + current_size = 150 + (1+1+1+1)*10 + 8*8 + 50 + (1+f.sector_base_size+2)*10 + 8*8; current_size *= sector_count; return desc; } -void victor9k_format::build_sector_description(const format &f, uint8_t *sectdata, uint32_t sect_offs, desc_s *sectors, int sector_count) const +void victor9k_format::build_sector_description(const format &f, uint8_t *sectdata, uint32_t sect_offs, desc_s *sectors, int sector_count) { for (int i = 0; i < sector_count; i++) { sectors[i].data = sectdata + sect_offs; @@ -248,24 +288,32 @@ void victor9k_format::build_sector_description(const format &f, uint8_t *sectdat } } -bool victor9k_format::load(io_generic *io, uint32_t form_factor, floppy_image *image) +bool victor9k_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image &image) const { - int type = find_size(io, form_factor); - if(type == -1) + int const type = find_size(io, form_factor); + if (type == -1) return false; const format &f = formats[type]; - uint64_t size = io_generic_size(io); - std::vector<uint8_t> img; - img.resize(size); + osd_printf_verbose("Type: %d Head Count: %d Sector Count: %d\n", type, + f.head_count, f.sector_count); - io_generic_read(io, &img[0], 0, size); + uint64_t size; + if (io.length(size)) + return false; + + auto const [err, img, actual] = read_at(io, 0, size); + if (err || (actual != size)) + return false; log_boot_sector(&img[0]); int track_offset = 0; + osd_printf_verbose("load Heads: %01d Tracks: %02d Sectors/track head[1]track[1]: %02d\n ", + f.head_count, f.track_count, sectors_per_track[1][1]); + for (int head = 0; head < f.head_count; head++) { for (int track = 0; track < f.track_count; track++) { int current_size = 0; @@ -276,8 +324,10 @@ bool victor9k_format::load(io_generic *io, uint32_t form_factor, floppy_image *i floppy_image_format_t::desc_e *desc = get_sector_desc(f, current_size, sector_count); int remaining_size = total_size - current_size; - if(remaining_size < 0) - throw emu_fatalerror("victor9k_format: Incorrect track layout, max_size=%d, current_size=%d", total_size, current_size); + if(remaining_size < 0) { + osd_printf_error("victor9k_format: Incorrect track layout, max_size=%d, current_size=%d\n", total_size, current_size); + return false; + } // Fixup the end gap desc[18].p2 = remaining_size / 8; @@ -293,13 +343,14 @@ bool victor9k_format::load(io_generic *io, uint32_t form_factor, floppy_image *i } } - image->set_variant(f.variant); + image.set_variant(f.variant); return true; } int victor9k_format::get_rpm(int head, int track) { + osd_printf_verbose("Head: %1d TracK: %02d \n ", head, track); return rpm[speed_zone[head][track]]; } @@ -307,8 +358,9 @@ int victor9k_format::get_image_offset(const format &f, int _head, int _track) { int offset = 0; if (_head) { + int first_side = 0; //build up offset for first side for (int track = 0; track < f.track_count; track++) { - offset += compute_track_size(f, _head, track); + offset += compute_track_size(f, first_side, track); } } for (int track = 0; track < _track; track++) { @@ -327,7 +379,7 @@ const victor9k_format::format victor9k_format::formats[] = { floppy_image::FF_525, floppy_image::SSDD, 1224, 80, 1, 512 }, { // - floppy_image::FF_525, floppy_image::DSDD, 2448, 80, 2, 512 + floppy_image::FF_525, floppy_image::DSDD, 2391, 80, 2, 512 }, {} }; @@ -353,8 +405,8 @@ const int victor9k_format::sectors_per_track[2][80] = 18, 18, 18, 18, 18, 18, 18, 18, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11 @@ -377,8 +429,8 @@ const int victor9k_format::speed_zone[2][80] = 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8 @@ -390,49 +442,67 @@ const int victor9k_format::rpm[9] = 252, 267, 283, 300, 321, 342, 368, 401, 417 }; -bool victor9k_format::save(io_generic *io, floppy_image *image) +bool victor9k_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, const floppy_image &image) const { - const format &f = formats[0]; + int type = victor9k_format::identify(image); + uint64_t size; + io.length(size); // FIXME: check for errors + osd_printf_verbose("save type: %01d, size: %d\n", type, size); - for(int head=0; head < f.head_count; head++) { + if (type == -1) + return false; + + const format &f = formats[type]; + + osd_printf_verbose("save Heads: %01d Tracks: %02d Sectors/track head[1]track[1]: %02d\n ", + f.head_count, f.track_count, sectors_per_track[1][1]); + for (int head = 0; head < f.head_count; head++) { for(int track=0; track < f.track_count; track++) { int sector_count = sectors_per_track[head][track]; int track_size = compute_track_size(f, head, track); uint8_t sectdata[40*512]; desc_s sectors[40]; int offset = get_image_offset(f, head, track); + osd_printf_verbose(">>type: %s, head: %d, track: %d, sector_count: %d, offset: %d, track_size: %d\n", + f.sector_base_size, head, track, sector_count, offset, track_size); build_sector_description(f, sectdata, 0, sectors, sector_count); extract_sectors(image, f, sectors, track, head, sector_count); - io_generic_write(io, sectdata, offset, track_size); + /*auto const [err, actual] =*/ write_at(io, offset, sectdata, track_size); // FIXME: check for errors } } return true; } -void victor9k_format::extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head, int sector_count) +void victor9k_format::extract_sectors(const floppy_image &image, const format &f, desc_s *sdesc, int track, int head, int sector_count) { - uint8_t bitstream[500000/8]; - uint8_t sectdata[50000]; - desc_xs sectors[256]; - int track_size; - // Extract the sectors - generate_bitstream_from_track(track, head, cell_size[speed_zone[head][track]], bitstream, track_size, image); - extract_sectors_from_bitstream_victor_gcr5(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); + auto bitstream = generate_bitstream_from_track(track, head, cell_size[speed_zone[head][track]], image); + auto sectors = extract_sectors_from_bitstream_victor_gcr5(bitstream); + + if (sectors.size() == 0) { + for(int i=0; i<sector_count; i++) { + std::vector<unsigned char> sector; + sectors.push_back(sector); + } + } - for(int i=0; i<sector_count; i++) { + for (int i = 0; i<sector_count; i++) { desc_s &ds = sdesc[i]; - desc_xs &xs = sectors[ds.sector_id]; - if(!xs.data) - memset((void *)ds.data, 0, ds.size); - else if(xs.size < ds.size) { - memcpy((void *)ds.data, xs.data, xs.size); - memset((uint8_t *)ds.data + xs.size, 0, xs.size - ds.size); + const auto &data = sectors[ds.sector_id]; + osd_printf_verbose("Head: %01d TracK: %02d Total Sectors: %02d Current Sector: %02d ", + head, track, sector_count, i); + if (data.empty()) { + memset((uint8_t *)ds.data, 0, ds.size); + } else if (data.size() < ds.size) { + memcpy((uint8_t *)ds.data, data.data(), data.size() - 1); + memset((uint8_t *)ds.data + data.size() - 1, 0, data.size() - ds.size); + osd_printf_verbose("data.size(): %01d\n", data.size()); } else - memcpy((void *)ds.data, xs.data, ds.size); + memcpy((uint8_t *)ds.data, data.data(), ds.size); + osd_printf_verbose("data.size(): %01d\n", data.size()); } } -const floppy_format_type FLOPPY_VICTOR_9000_FORMAT = &floppy_image_format_creator<victor9k_format>; +const victor9k_format FLOPPY_VICTOR_9000_FORMAT; |