summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/formats/victor9k_dsk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/formats/victor9k_dsk.cpp')
-rw-r--r--src/lib/formats/victor9k_dsk.cpp200
1 files changed, 134 insertions, 66 deletions
diff --git a/src/lib/formats/victor9k_dsk.cpp b/src/lib/formats/victor9k_dsk.cpp
index 188b4c250e4..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
@@ -99,90 +105,124 @@
#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 = io_generic_size(io);
- for(int i=0; formats[i].sector_count; i++) {
+ 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*f.head_count)
+ if(size == uint32_t(f.sector_count*f.sector_base_size))
return i;
}
+
return -1;
}
-int victor9k_format::identify(io_generic *io, uint32_t form_factor)
+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)
+{
+ for (int i = 0; formats[i].form_factor; i++) {
+ const format &f = formats[i];
+ if(f.variant == image.get_variant())
+ return i;
+ }
+
+ return -1;
+}
+
+
+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", util::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;
@@ -295,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]];
}
@@ -309,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++) {
@@ -329,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
},
{}
};
@@ -355,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
@@ -379,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
@@ -392,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;