summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Curt Coder <curtcoder@mail.com>2015-04-21 09:18:03 +0300
committer Curt Coder <curtcoder@mail.com>2015-04-21 09:18:03 +0300
commitedd9d41c040fa836b29ccb4d851507f83accdf69 (patch)
tree239ccf1d9c18ff2c162506154b5983d9bbf48763
parentbe04a1d8edf9e49f10399f3a6b89066b60a83678 (diff)
(MESS) victor9k: Added writing to sector dump disk images. [Curt Coder]
-rw-r--r--src/lib/formats/flopimg.c65
-rw-r--r--src/lib/formats/flopimg.h2
-rw-r--r--src/lib/formats/victor9k_dsk.c67
-rw-r--r--src/lib/formats/victor9k_dsk.h15
4 files changed, 140 insertions, 9 deletions
diff --git a/src/lib/formats/flopimg.c b/src/lib/formats/flopimg.c
index cc7e00d0ed4..4588d717c00 100644
--- a/src/lib/formats/flopimg.c
+++ b/src/lib/formats/flopimg.c
@@ -2890,3 +2890,68 @@ void floppy_image_format_t::extract_sectors_from_bitstream_gcr5(const UINT8 *bit
}
}
}
+
+void floppy_image_format_t::extract_sectors_from_bitstream_victor_gcr5(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size)
+{
+ memset(sectors, 0, 256*sizeof(desc_xs));
+
+ // Don't bother if it's just too small
+ if(track_size < 100)
+ return;
+
+ // Start by detecting all id and data blocks
+ int hblk[100], dblk[100];
+ int hblk_count = 0, dblk_count = 0;
+
+ // Precharge the shift register to detect over-the-index stuff
+ UINT16 shift_reg = 0;
+ for(int i=0; i<16; i++)
+ if(sbit_r(bitstream, track_size-16+i))
+ shift_reg |= 0x8000 >> i;
+
+ // Scan the bitstream for sync marks and follow them to check for blocks
+ bool sync = false;
+ for(int i=0; i<track_size; i++) {
+ int bit = sbit_r(bitstream, i);
+ shift_reg = ((shift_reg << 1) | bit) & 0x3ff;
+
+ if (sync && !bit) {
+ UINT8 id = sbyte_gcr5_r(bitstream, i, track_size);
+
+ switch (id) {
+ case 0x07:
+ if(hblk_count < 100)
+ hblk[hblk_count++] = i-10;
+ break;
+
+ case 0x08:
+ if(dblk_count < 100)
+ dblk[dblk_count++] = i-10;
+ break;
+ }
+ }
+
+ sync = (shift_reg == 0x3ff);
+ }
+
+ // Then extract the sectors
+ int sectdata_pos = 0;
+ for(int i=0; i<hblk_count; i++) {
+ int pos = hblk[i];
+ ATTR_UNUSED UINT8 block_id = sbyte_gcr5_r(bitstream, pos, track_size);
+ UINT8 track = sbyte_gcr5_r(bitstream, pos, track_size);
+ UINT8 sector = sbyte_gcr5_r(bitstream, pos, track_size);
+
+ pos = dblk[i];
+ block_id = sbyte_gcr5_r(bitstream, pos, track_size);
+
+ sectors[sector].track = track & 0x7f;
+ sectors[sector].head = BIT(track, 7);
+ sectors[sector].size = 512;
+ sectors[sector].data = sectdata + sectdata_pos;
+ for(int j=0; j<sectors[sector].size; j++) {
+ UINT8 data = sbyte_gcr5_r(bitstream, pos, track_size);
+ sectdata[sectdata_pos++] = data;
+ }
+ }
+}
diff --git a/src/lib/formats/flopimg.h b/src/lib/formats/flopimg.h
index c06788c4e13..59b652643b6 100644
--- a/src/lib/formats/flopimg.h
+++ b/src/lib/formats/flopimg.h
@@ -522,6 +522,8 @@ protected:
void extract_sectors_from_bitstream_fm_pc(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size);
//! Commodore type sectors with GCR5 encoding
void extract_sectors_from_bitstream_gcr5(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size, int head, int tracks);
+ //! Victor 9000 type sectors with GCR5 encoding
+ void extract_sectors_from_bitstream_victor_gcr5(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size);
//! @brief Get a geometry (including sectors) from an image.
diff --git a/src/lib/formats/victor9k_dsk.c b/src/lib/formats/victor9k_dsk.c
index 7376b3208a7..21dc6397e8e 100644
--- a/src/lib/formats/victor9k_dsk.c
+++ b/src/lib/formats/victor9k_dsk.c
@@ -298,14 +298,28 @@ bool victor9k_format::load(io_generic *io, UINT32 form_factor, floppy_image *ima
return true;
}
-bool victor9k_format::supports_save() const
+int victor9k_format::get_rpm(int head, int track)
{
- return false;
+ return rpm[speed_zone[head][track]];
}
-int victor9k_format::get_rpm(int head, int track)
+int victor9k_format::get_image_offset(const format &f, int _head, int _track)
{
- return rpm[speed_zone[head][track]];
+ int offset = 0;
+ if (_head) {
+ for (int track = 0; track < f.track_count; track++) {
+ offset += compute_track_size(f, _head, track);
+ }
+ }
+ for (int track = 0; track < _track; track++) {
+ offset += compute_track_size(f, _head, track);
+ }
+ return offset;
+}
+
+int victor9k_format::compute_track_size(const format &f, int head, int track)
+{
+ return sectors_per_track[head][track] * f.sector_base_size;
}
const victor9k_format::format victor9k_format::formats[] = {
@@ -376,4 +390,49 @@ const int victor9k_format::rpm[9] =
252, 267, 283, 300, 320, 342, 368, 401, 417
};
+bool victor9k_format::save(io_generic *io, floppy_image *image)
+{
+ const format &f = formats[0];
+
+ 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 sectdata[40*512];
+ desc_s sectors[40];
+ int offset = get_image_offset(f, head, track);
+
+ 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);
+ }
+ }
+
+ return true;
+}
+
+void victor9k_format::extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head, int sector_count)
+{
+ UINT8 bitstream[500000/8];
+ UINT8 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));
+
+ 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 *)ds.data + xs.size, 0, xs.size - ds.size);
+ } else
+ memcpy((void *)ds.data, xs.data, ds.size);
+ }
+}
+
const floppy_format_type FLOPPY_VICTOR_9000_FORMAT = &floppy_image_format_creator<victor9k_format>;
diff --git a/src/lib/formats/victor9k_dsk.h b/src/lib/formats/victor9k_dsk.h
index 22f43fa7e3b..1564f1474f7 100644
--- a/src/lib/formats/victor9k_dsk.h
+++ b/src/lib/formats/victor9k_dsk.h
@@ -31,13 +31,10 @@ public:
virtual const char *description() const;
virtual const char *extensions() const;
- int find_size(io_generic *io, UINT32 form_factor);
virtual int identify(io_generic *io, UINT32 form_factor);
- void log_boot_sector(UINT8 *data);
- floppy_image_format_t::desc_e* get_sector_desc(const format &f, int &current_size, int sector_count);
- void build_sector_description(const format &f, UINT8 *sectdata, UINT32 sect_offs, desc_s *sectors, int sector_count) const;
virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image);
- virtual bool supports_save() const;
+ virtual bool save(io_generic *io, floppy_image *image);
+ virtual bool supports_save() const { return true; }
static int get_rpm(int head, int track);
@@ -48,6 +45,14 @@ protected:
static const int sectors_per_track[2][80];
static const int speed_zone[2][80];
static const int rpm[9];
+
+ int find_size(io_generic *io, UINT32 form_factor);
+ void log_boot_sector(UINT8 *data);
+ floppy_image_format_t::desc_e* get_sector_desc(const format &f, int &current_size, int sector_count);
+ void build_sector_description(const format &f, UINT8 *sectdata, UINT32 sect_offs, desc_s *sectors, int sector_count) const;
+ int get_image_offset(const format &f, int head, int track);
+ int compute_track_size(const format &f, int head, int track);
+ void extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head, int sector_count);
};
extern const floppy_format_type FLOPPY_VICTOR_9000_FORMAT;