diff options
Diffstat (limited to 'src/lib/formats')
-rw-r--r-- | src/lib/formats/flopimg.c | 65 | ||||
-rw-r--r-- | src/lib/formats/flopimg.h | 2 | ||||
-rw-r--r-- | src/lib/formats/victor9k_dsk.c | 67 | ||||
-rw-r--r-- | src/lib/formats/victor9k_dsk.h | 15 |
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 ¤t_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 ¤t_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; |