Victor9k fix disk handling (#10315)

* Victor9k Fixing bug in floppy disk sync header sizes

* Victor9K adding support for ramsize CLI flag

* Fixed zone 4 documentation bug

* Correcting mistake in data header sync size, 5 not 6 bytes

* fixed error in sector size comparison & sector count for DS disks

* single-sided disks read/write correctly; double-sided read correctly. DS still corrupting on write

* fixed bug in offset calculation for DS disks

* fixing bug with -ramsize=896K

* updated todo comment

Co-authored-by: Paul Devine <pauldevine+git@gmail.com>
This commit is contained in:
Paul Devine 2022-09-07 03:40:23 -07:00 committed by GitHub
parent 7b2aae2fd6
commit b008567de0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 127 additions and 53 deletions

View File

@ -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
@ -105,6 +111,7 @@
#include "osdcore.h" // osd_printf_*
#include <cstring>
#include <iterator>
victor9k_format::victor9k_format()
@ -126,7 +133,7 @@ const char *victor9k_format::extensions() const
return "img";
}
int victor9k_format::find_size(util::random_read &io, uint32_t form_factor)
int victor9k_format::find_size(util::random_read &io)
{
uint64_t size;
if(io.length(size))
@ -134,13 +141,30 @@ int victor9k_format::find_size(util::random_read &io, uint32_t form_factor)
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::find_size(util::random_read &io, uint32_t form_factor)
{
return find_size(io);
}
int victor9k_format::identify(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);
@ -157,43 +181,48 @@ void victor9k_format::log_boot_sector(uint8_t *data)
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]));
// Flags
osd_printf_verbose("%s sided\n", util::BIT(data[33], 0) ? "Double" : "Single");
osd_printf_verbose("Interleave factor: %u\n", data[32] >> 4);
//Disk type - flags
osd_printf_verbose("%s sided\n", (data[32]) ? "Double" : "Single");
//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++) {
@ -221,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 },
@ -242,7 +271,7 @@ 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;
@ -267,6 +296,9 @@ bool victor9k_format::load(util::random_read &io, uint32_t form_factor, const st
const format &f = formats[type];
osd_printf_verbose("Type: %d Head Count: %d Sector Count: %d\n", type,
f.head_count, f.sector_count);
uint64_t size;
if(io.length(size))
return false;
@ -282,6 +314,9 @@ bool victor9k_format::load(util::random_read &io, uint32_t form_factor, const st
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;
@ -318,6 +353,7 @@ bool victor9k_format::load(util::random_read &io, uint32_t form_factor, const st
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]];
}
@ -325,8 +361,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++) {
@ -345,7 +382,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
},
{}
};
@ -371,8 +408,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
@ -395,8 +432,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
@ -410,8 +447,18 @@ const int victor9k_format::rpm[9] =
bool victor9k_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) const
{
const format &f = formats[0];
int type = victor9k_format::identify(image);
uint64_t size;
io.length(size);
osd_printf_verbose("save type: %01d, size: %d\n", type, size);
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];
@ -419,6 +466,8 @@ bool victor9k_format::save(util::random_read_write &io, const std::vector<uint32
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);
@ -432,20 +481,32 @@ bool victor9k_format::save(util::random_read_write &io, const std::vector<uint32
void victor9k_format::extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head, int sector_count)
{
// Extract the sectors
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++) {
desc_s &ds = sdesc[i];
const auto &data = sectors[ds.sector_id];
if(data.empty())
memset((void *)ds.data, 0, ds.size);
else if(data.size() < ds.size) {
memcpy((void *)ds.data, data.data(), data.size());
memset((uint8_t *)ds.data + data.size(), 0, data.size() - ds.size);
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, data.data(), ds.size);
memcpy((uint8_t *)ds.data, data.data(), ds.size);
osd_printf_verbose("data.size(): %01d\n", data.size());
}
}

View File

@ -49,7 +49,9 @@ protected:
static const int speed_zone[2][80];
static const int rpm[9];
static int find_size(util::random_read &io);
static int find_size(util::random_read &io, uint32_t form_factor);
static int identify(floppy_image *image);
static void log_boot_sector(uint8_t *data);
static floppy_image_format_t::desc_e* get_sector_desc(const format &f, int &current_size, int sector_count);
static void build_sector_description(const format &f, uint8_t *sectdata, uint32_t sect_offs, desc_s *sectors, int sector_count);

View File

@ -639,6 +639,19 @@ void victor9k_state::machine_start()
m_rom->base()[0x1d53] = 0x90;
m_rom->base()[0x1d54] = 0x90;
#endif
//update RAM for ramsize
int m_ram_size = m_ram->size();
u8 *m_ram_ptr = m_ram->pointer();
int ramsize = m_ram_size;
if (ramsize > 0) {
address_space& space = m_maincpu->space(AS_PROGRAM);
if (ramsize > 0xdffff) //the 896KB option overlaps 1 bit with
ramsize = 0xdffff; //the I/O memory space, truncating
if (LOG) logerror("install_ram ramsize %x\n", ramsize);
space.install_ram(0x0, ramsize, m_ram_ptr);
}
}
void victor9k_state::machine_reset()
@ -775,7 +788,7 @@ void victor9k_state::victor9k(machine_config &config)
m_fdc->syn_wr_callback().set(I8259A_TAG, FUNC(pic8259_device::ir0_w)).invert();
m_fdc->lbrdy_wr_callback().set_inputline(I8088_TAG, INPUT_LINE_TEST).invert();
RAM(config, m_ram).set_default_size("128K");
RAM(config, m_ram).set_default_size("128K").set_extra_options("128K,256K,512K,640K,768K,896K");
SOFTWARE_LIST(config, "flop_list").set_original("victor9k_flop");
}

View File

@ -34,8 +34,6 @@
- communication error with SCP after loading boot sector
- bp ff1a8
- patch ff1ab=c3
- single/double sided jumper
- header sync length unknown (6 is too short)
- 8048 spindle speed control
*/
@ -944,14 +942,14 @@ uint8_t victor_9000_fdc_device::via6_pb_r()
bit description
PB0 RDY0 from SCP
PB1 RDY1 from SCP
PB2
PB3 _DS1
PB4 _DS0
PB0 RDY0 to SCP Motor speed status, drive A
PB1 RDY1 to SCP Motor speed status, drive B
PB2 _SCRESET Motor speed controller (8048) reset, output
PB3 DS1 Door B sense, input ->order is correct, leads with B
PB4 DSO Door A sense, input
PB5 SINGLE/_DOUBLE SIDED
PB6
PB7
PB6 STP0 Stepper enable A
PB7 STP1 Stepper enable B
*/
@ -970,7 +968,7 @@ uint8_t victor_9000_fdc_device::via6_pb_r()
data |= ((m_floppy0->get_device() && m_floppy0->get_device()->exists()) ? 0 : 1) << 4;
// single/double sided jumper
//data |= 0x20;
data |= (2U << 5);
return data;
}
@ -981,14 +979,14 @@ void victor_9000_fdc_device::via6_pb_w(uint8_t data)
bit description
PB0 RDY0 to SCP
PB1 RDY1 to SCP
PB2 _SCRESET
PB3
PB4
PB5
PB6 STP0
PB7 STP1
PB0 RDY0 to SCP Motor speed status, drive A
PB1 RDY1 to SCP Motor speed status, drive B
PB2 _SCRESET Motor speed controller (8048) reset, output
PB3 DS1 Door B sense, input ->order is correct, leads with B
PB4 DSO Door A sense, input
PB5 SINGLE/_DOUBLE SIDED
PB6 STP0 Stepper enable A
PB7 STP1 Stepper enable B
*/