diff options
Diffstat (limited to 'src/lib/formats')
-rw-r--r-- | src/lib/formats/c3040_dsk.c | 101 | ||||
-rw-r--r-- | src/lib/formats/c3040_dsk.h | 40 | ||||
-rw-r--r-- | src/lib/formats/c4040_dsk.c | 91 | ||||
-rw-r--r-- | src/lib/formats/c4040_dsk.h | 38 | ||||
-rw-r--r-- | src/lib/formats/c8280_dsk.c | 69 | ||||
-rw-r--r-- | src/lib/formats/c8280_dsk.h | 30 | ||||
-rw-r--r-- | src/lib/formats/cbm_crt.c | 6 | ||||
-rw-r--r-- | src/lib/formats/cbm_crt.h | 2 | ||||
-rw-r--r-- | src/lib/formats/ccvf_dsk.c | 10 | ||||
-rw-r--r-- | src/lib/formats/d64_dsk.c | 68 | ||||
-rw-r--r-- | src/lib/formats/d64_dsk.h | 7 | ||||
-rw-r--r-- | src/lib/formats/d67_dsk.c | 56 | ||||
-rw-r--r-- | src/lib/formats/d67_dsk.h | 36 | ||||
-rw-r--r-- | src/lib/formats/flopimg.c | 154 | ||||
-rw-r--r-- | src/lib/formats/flopimg.h | 6 | ||||
-rw-r--r-- | src/lib/formats/imd_dsk.c | 86 | ||||
-rw-r--r-- | src/lib/formats/victor9k_dsk.c | 67 | ||||
-rw-r--r-- | src/lib/formats/victor9k_dsk.h | 15 |
18 files changed, 768 insertions, 114 deletions
diff --git a/src/lib/formats/c3040_dsk.c b/src/lib/formats/c3040_dsk.c new file mode 100644 index 00000000000..9fb6669ab20 --- /dev/null +++ b/src/lib/formats/c3040_dsk.c @@ -0,0 +1,101 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************* + + formats/c3040_dsk.c + + Commodore 3040 sector disk image format + +*********************************************************************/ + +#include <assert.h> + +#include "formats/c3040_dsk.h" + +c3040_format::c3040_format() : d64_format(file_formats) +{ +} + +const char *c3040_format::name() const +{ + return "c3040"; +} + +const char *c3040_format::description() const +{ + return "Commodore 3040 disk image"; +} + +const char *c3040_format::extensions() const +{ + return "d67"; +} + +const c3040_format::format c3040_format::file_formats[] = { + { // d67, dos 1, 35 tracks, head 48 tpi, stepper 96 tpi + floppy_image::FF_525, floppy_image::SSSD, 690, 35, 1, 256, 9, 8 + }, + {} +}; + +const int c3040_format::c3040_sectors_per_track[] = +{ + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, // 1-17 + 20, 20, 20, 20, 20, 20, 20, // 18-24 + 18, 18, 18, 18, 18, 18, // 25-30 + 17, 17, 17, 17, 17, // 31-35 + 17, 17, 17, 17, 17, // 36-40 + 17, 17 // 41-42 +}; + +const int c3040_format::c3040_gap2[] = +{ + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // 1-17 + 8, 8, 8, 8, 8, 8, 8, // 18-24 + 15, 15, 15, 15, 15, 15, // 25-30 + 12, 12, 12, 12, 12 // 31-35 +}; + +floppy_image_format_t::desc_e* c3040_format::get_sector_desc(const format &f, int ¤t_size, int sector_count, UINT8 id1, UINT8 id2, int gap_2) +{ + static floppy_image_format_t::desc_e desc[] = { + /* 00 */ { SECTOR_LOOP_START, 0, -1 }, + /* 01 */ { SYNC_GCR5, 2 }, + /* 02 */ { GCR5, 0x08, 1 }, + /* 03 */ { CRC, 1 }, + /* 04 */ { CRC_CBM_START, 1 }, + /* 05 */ { SECTOR_ID_GCR5 }, + /* 06 */ { TRACK_ID_DOS2_GCR5 }, + /* 07 */ { GCR5, id2, 1 }, + /* 08 */ { GCR5, id1, 1 }, + /* 09 */ { CRC_END, 1 }, + /* 10 */ { GCR5, 0x00, f.gap_1 }, + /* 11 */ { SYNC_GCR5, 2 }, + /* 12 */ { GCR5, 0x07, 1 }, + /* 13 */ { CRC_CBM_START, 2 }, + /* 14 */ { SECTOR_DATA_GCR5, -1 }, + /* 15 */ { CRC_END, 2 }, + /* 16 */ { CRC, 2 }, + /* 17 */ { GCR5, 0x00, gap_2 }, + /* 18 */ { SECTOR_LOOP_END }, + /* 19 */ { GCR5, 0x00, 0 }, + /* 20 */ { RAWBITS, 0x14a, 0 }, + /* 21 */ { END } + }; + + desc[17].p2 = gap_2; // TODO why?!? + + current_size = 20 + (1+1+4)*10 + f.gap_1*10 + 20 + (1+f.sector_base_size+1)*10 + gap_2*10; + + current_size *= sector_count; + return desc; +} + +void c3040_format::fix_end_gap(floppy_image_format_t::desc_e* desc, int remaining_size) +{ + desc[19].p2 = remaining_size / 10; + desc[20].p2 = remaining_size % 10; + desc[20].p1 >>= remaining_size & 0x01; +} + +const floppy_format_type FLOPPY_C3040_FORMAT = &floppy_image_format_creator<c3040_format>; diff --git a/src/lib/formats/c3040_dsk.h b/src/lib/formats/c3040_dsk.h new file mode 100644 index 00000000000..cbf320273a8 --- /dev/null +++ b/src/lib/formats/c3040_dsk.h @@ -0,0 +1,40 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************* + + formats/c3040_dsk.h + + Commodore 3040 sector disk image format + +*********************************************************************/ + +#ifndef C3040_DSK_H_ +#define C3040_DSK_H_ + +#include "d64_dsk.h" + +class c3040_format : public d64_format { +public: + c3040_format(); + + virtual const char *name() const; + virtual const char *description() const; + virtual const char *extensions() const; + +protected: + virtual int get_sectors_per_track(const format &f, int track) { return c3040_sectors_per_track[track]; } + virtual floppy_image_format_t::desc_e* get_sector_desc(const format &f, int ¤t_size, int sector_count, UINT8 id1, UINT8 id2, int gap_2); + virtual int get_gap2(const format &f, int head, int track) { return c3040_gap2[track]; } + virtual void fix_end_gap(floppy_image_format_t::desc_e* desc, int remaining_size); + + static const format file_formats[]; + + static const int c3040_gap2[]; + static const int c3040_sectors_per_track[]; +}; + +extern const floppy_format_type FLOPPY_C3040_FORMAT; + + + +#endif diff --git a/src/lib/formats/c4040_dsk.c b/src/lib/formats/c4040_dsk.c new file mode 100644 index 00000000000..9e6dff7f627 --- /dev/null +++ b/src/lib/formats/c4040_dsk.c @@ -0,0 +1,91 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************* + + formats/c4040_dsk.c + + Commodore 4040 sector disk image format + +*********************************************************************/ + +#include <assert.h> + +#include "formats/c4040_dsk.h" + +c4040_format::c4040_format() : d64_format(file_formats) +{ +} + +const char *c4040_format::name() const +{ + return "c4040"; +} + +const char *c4040_format::description() const +{ + return "Commodore 4040 disk image"; +} + +const char *c4040_format::extensions() const +{ + return "d64"; +} + +const c4040_format::format c4040_format::file_formats[] = { + { // c4040, dos 2, 35 tracks, head 48 tpi, stepper 96 tpi + floppy_image::FF_525, floppy_image::SSSD, 683, 35, 1, 256, 9, 8 + }, + {} +}; + +const int c4040_format::c4040_gap2[] = +{ + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, // 1-17 + 19, 19, 19, 19, 19, 19, 19, // 18-24 + 15, 15, 15, 15, 15, 15, // 25-30 + 12, 12, 12, 12, 12 // 31-35 +}; + +floppy_image_format_t::desc_e* c4040_format::get_sector_desc(const format &f, int ¤t_size, int sector_count, UINT8 id1, UINT8 id2, int gap_2) +{ + static floppy_image_format_t::desc_e desc[] = { + /* 00 */ { SECTOR_LOOP_START, 0, -1 }, + /* 01 */ { SYNC_GCR5, 4 }, + /* 02 */ { GCR5, 0x08, 1 }, + /* 03 */ { CRC, 1 }, + /* 04 */ { CRC_CBM_START, 1 }, + /* 05 */ { SECTOR_ID_GCR5 }, + /* 06 */ { TRACK_ID_DOS2_GCR5 }, + /* 07 */ { GCR5, id2, 1 }, + /* 08 */ { GCR5, id1, 1 }, + /* 09 */ { CRC_END, 1 }, + /* 10 */ { GCR5, 0x00, f.gap_1 }, + /* 11 */ { SYNC_GCR5, 4 }, + /* 12 */ { GCR5, 0x07, 1 }, + /* 13 */ { CRC_CBM_START, 2 }, + /* 14 */ { SECTOR_DATA_GCR5, -1 }, + /* 15 */ { CRC_END, 2 }, + /* 16 */ { CRC, 2 }, + /* 17 */ { GCR5, 0x00, gap_2 }, + /* 18 */ { SECTOR_LOOP_END }, + /* 19 */ { GCR5, 0x00, 0 }, + /* 20 */ { RAWBITS, 0x14a, 0 }, + /* 21 */ { END } + }; + + desc[17].p2 = gap_2; // TODO why?!? + + current_size = 40 + (1+1+4)*10 + f.gap_1*10 + 40 + (1+f.sector_base_size+1)*10 + gap_2*10; + + current_size *= sector_count; + return desc; +} + +void c4040_format::fix_end_gap(floppy_image_format_t::desc_e* desc, int remaining_size) +{ + desc[19].p2 = remaining_size / 10; + desc[20].p2 = remaining_size % 10; + desc[20].p1 >>= remaining_size & 0x01; +} + +const floppy_format_type FLOPPY_C4040_FORMAT = &floppy_image_format_creator<c4040_format>; diff --git a/src/lib/formats/c4040_dsk.h b/src/lib/formats/c4040_dsk.h new file mode 100644 index 00000000000..231b961c765 --- /dev/null +++ b/src/lib/formats/c4040_dsk.h @@ -0,0 +1,38 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************* + + formats/c4040_dsk.h + + Commodore 4040 sector disk image format + +*********************************************************************/ + +#ifndef C4040_DSK_H_ +#define C4040_DSK_H_ + +#include "d64_dsk.h" + +class c4040_format : public d64_format { +public: + c4040_format(); + + virtual const char *name() const; + virtual const char *description() const; + virtual const char *extensions() const; + +protected: + virtual floppy_image_format_t::desc_e* get_sector_desc(const format &f, int ¤t_size, int sector_count, UINT8 id1, UINT8 id2, int gap_2); + virtual int get_gap2(const format &f, int head, int track) { return c4040_gap2[track]; } + virtual void fix_end_gap(floppy_image_format_t::desc_e* desc, int remaining_size); + + static const format file_formats[]; + + static const int c4040_gap2[]; +}; + +extern const floppy_format_type FLOPPY_C4040_FORMAT; + + + +#endif diff --git a/src/lib/formats/c8280_dsk.c b/src/lib/formats/c8280_dsk.c new file mode 100644 index 00000000000..cb39b5c3ea5 --- /dev/null +++ b/src/lib/formats/c8280_dsk.c @@ -0,0 +1,69 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************* + + formats/c8280_dsk.c + + Commodore 8280 disk image format + +*********************************************************************/ + +#include "formats/c8280_dsk.h" + +c8280_format::c8280_format() : wd177x_format(formats) +{ +} + +const char *c8280_format::name() const +{ + return "c8280"; +} + +const char *c8280_format::description() const +{ + return "Commodore 8280 disk image"; +} + +const char *c8280_format::extensions() const +{ + return "dsk"; +} + +const c8280_format::format c8280_format::formats[] = { + // 80x4e 12x00 3xf6 fc + // 50x4e 12x00 3xf5 fe 2x00 01 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 02 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 03 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 04 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 05 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 06 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 07 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 08 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 09 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 0a 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 0b 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 0c 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 0d 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 0e 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 0f 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 10 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 11 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 12 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 13 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 14 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 15 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 16 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 17 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 18 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 19 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 54x4e 12x00 3xf5 fe 2x00 1a 01 f7 22x4e 12x00 3xf5 fb 256xaa f7 + // 653x4e + { + floppy_image::FF_8, floppy_image::DSDD, floppy_image::MFM, + 1200, 26, 77, 2, 256, {}, 1, {}, 50, 22, 54 + }, + + {} +}; + +const floppy_format_type FLOPPY_C8280_FORMAT = &floppy_image_format_creator<c8280_format>; diff --git a/src/lib/formats/c8280_dsk.h b/src/lib/formats/c8280_dsk.h new file mode 100644 index 00000000000..eed34f5d846 --- /dev/null +++ b/src/lib/formats/c8280_dsk.h @@ -0,0 +1,30 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************* + + formats/c8280_dsk.h + + Commodore 8280 disk image format + +*********************************************************************/ + +#ifndef C8280_DSK_H_ +#define C8280_DSK_H_ + +#include "wd177x_dsk.h" + +class c8280_format : public wd177x_format { +public: + c8280_format(); + + virtual const char *name() const; + virtual const char *description() const; + virtual const char *extensions() const; + +private: + static const format formats[]; +}; + +extern const floppy_format_type FLOPPY_C8280_FORMAT; + +#endif diff --git a/src/lib/formats/cbm_crt.c b/src/lib/formats/cbm_crt.c index 3be90b29ab1..dce20d6e603 100644 --- a/src/lib/formats/cbm_crt.c +++ b/src/lib/formats/cbm_crt.c @@ -122,7 +122,7 @@ static const char * CRT_C64_SLOT_NAMES[_CRT_C64_COUNT] = // cbm_crt_get_card - get slot interface card //------------------------------------------------- -void cbm_crt_get_card(astring &result, core_file *file) +void cbm_crt_get_card(std::string &result, core_file *file) { // read the header cbm_crt_header header; @@ -132,11 +132,11 @@ void cbm_crt_get_card(astring &result, core_file *file) { UINT16 hardware = pick_integer_be(header.hardware, 0, 2); - result.cpy(CRT_C64_SLOT_NAMES[hardware]); + result.assign(CRT_C64_SLOT_NAMES[hardware]); return; } - result.reset(); + result.clear(); } diff --git a/src/lib/formats/cbm_crt.h b/src/lib/formats/cbm_crt.h index 8049ddacff7..9be37bc0740 100644 --- a/src/lib/formats/cbm_crt.h +++ b/src/lib/formats/cbm_crt.h @@ -135,7 +135,7 @@ struct cbm_crt_chip // FUNCTION PROTOTYPES //************************************************************************** -void cbm_crt_get_card(astring &result, core_file *file); +void cbm_crt_get_card(std::string &result, core_file *file); bool cbm_crt_read_header(core_file* file, size_t *roml_size, size_t *romh_size, int *exrom, int *game); bool cbm_crt_read_data(core_file* file, UINT8 *roml, UINT8 *romh); diff --git a/src/lib/formats/ccvf_dsk.c b/src/lib/formats/ccvf_dsk.c index 03ee6fd0dbc..44d919bc88e 100644 --- a/src/lib/formats/ccvf_dsk.c +++ b/src/lib/formats/ccvf_dsk.c @@ -93,18 +93,18 @@ bool ccvf_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) dynamic_buffer img(size); io_generic_read(io, &img[0], 0, size); - astring ccvf = astring((const char *)&img[0], size); + std::string ccvf = std::string((const char *)&img[0], size); dynamic_buffer bytes(78720); int start = 0, end = 0; - astring line; + std::string line; UINT32 byteoffs = 0; char hex[3] = {0}; do { - end = ccvf.chr(start, 10); - line.cpysubstr(ccvf, start, end); - if (line.find(0, "Compucolor Virtual Floppy Disk Image") && line.find(0, "Label") && line.find(0, "Track")) { + end = ccvf.find_first_of(10, start); + line.assign(ccvf.substr(start, end)); + if (line.find("Compucolor Virtual Floppy Disk Image") != std::string::npos && line.find("Label") != std::string::npos && line.find("Track") != std::string::npos) { for (int byte = 0; byte < 32; byte++) { if (byteoffs==78720) break; hex[0]=line[byte * 2]; diff --git a/src/lib/formats/d64_dsk.c b/src/lib/formats/d64_dsk.c index 3bcbee87727..531ce441b99 100644 --- a/src/lib/formats/d64_dsk.c +++ b/src/lib/formats/d64_dsk.c @@ -122,6 +122,25 @@ void d64_format::get_disk_id(const format &f, io_generic *io, UINT8 &id1, UINT8 id2 = id[1]; } +int d64_format::get_image_offset(const format &f, int _head, int _track) +{ + int offset = 0; + if (_head) { + for (int track = 0; track < f.track_count; track++) { + offset += compute_track_size(f, track); + } + } + for (int track = 0; track < _track; track++) { + offset += compute_track_size(f, track); + } + return offset; +} + +int d64_format::compute_track_size(const format &f, int track) +{ + return this->get_sectors_per_track(f, track) * f.sector_base_size; +} + UINT32 d64_format::get_cell_size(const format &f, int track) { return cell_size[speed_zone[track]]; @@ -220,8 +239,9 @@ bool d64_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) int physical_track = this->get_physical_track(f, head, track); int sector_count = this->get_sectors_per_track(f, track); int track_size = sector_count*f.sector_base_size; + int gap2 = this->get_gap2(f, head, track); - floppy_image_format_t::desc_e *desc = this->get_sector_desc(f, current_size, sector_count, id1, id2, f.gap_2); + floppy_image_format_t::desc_e *desc = this->get_sector_desc(f, current_size, sector_count, id1, id2, gap2); int remaining_size = total_size - current_size; if(remaining_size < 0) @@ -244,9 +264,51 @@ bool d64_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) return true; } -bool d64_format::supports_save() const +bool d64_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 = this->get_sectors_per_track(f, track); + int track_size = compute_track_size(f, track); + UINT8 sectdata[40*256] = { 0 }; + desc_s sectors[40]; + int offset = get_image_offset(f, head, track); + + build_sector_description(f, sectdata, 0, 0, sectors, sector_count); + extract_sectors(image, f, sectors, track, head, sector_count); + io_generic_write(io, sectdata, offset, track_size); + } + } + + return true; +} + +void d64_format::extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head, int sector_count) { - return false; + UINT8 bitstream[500000/8]; + UINT8 sectdata[50000]; + desc_xs sectors[256]; + int physical_track = this->get_physical_track(f, head, track); + int cell_size = this->get_cell_size(f, track); + int track_size; + + // Extract the sectors + generate_bitstream_from_track(physical_track, head, cell_size, bitstream, track_size, image); + extract_sectors_from_bitstream_gcr5(bitstream, track_size, sectors, sectdata, sizeof(sectdata), head, f.track_count); + + 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_D64_FORMAT = &floppy_image_format_creator<d64_format>; diff --git a/src/lib/formats/d64_dsk.h b/src/lib/formats/d64_dsk.h index 573bbab4cbc..558d4ebf1c2 100644 --- a/src/lib/formats/d64_dsk.h +++ b/src/lib/formats/d64_dsk.h @@ -36,7 +36,8 @@ public: virtual int identify(io_generic *io, UINT32 form_factor); 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; } protected: enum @@ -63,9 +64,13 @@ protected: virtual int get_sectors_per_track(const format &f, int track); virtual int get_disk_id_offset(const format &f); void get_disk_id(const format &f, io_generic *io, UINT8 &id1, UINT8 &id2); + virtual int get_image_offset(const format &f, int head, int track); + int compute_track_size(const format &f, int track); + virtual int get_gap2(const format &f, int head, int track) { return f.gap_2; } virtual floppy_image_format_t::desc_e* get_sector_desc(const format &f, int ¤t_size, int sector_count, UINT8 id1, UINT8 id2, int gap_2); void build_sector_description(const format &f, UINT8 *sectdata, UINT32 sect_offs, UINT32 error_offs, desc_s *sectors, int sector_count) const; virtual void fix_end_gap(floppy_image_format_t::desc_e* desc, int remaining_size); + void extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head, int sector_count); static const format file_formats[]; diff --git a/src/lib/formats/d67_dsk.c b/src/lib/formats/d67_dsk.c deleted file mode 100644 index b512e55b694..00000000000 --- a/src/lib/formats/d67_dsk.c +++ /dev/null @@ -1,56 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Curt Coder -/********************************************************************* - - formats/d67_dsk.c - - Commodore 2040 sector disk image format - -*********************************************************************/ - -#include <assert.h> - -#include "formats/d67_dsk.h" - -d67_format::d67_format() : d64_format(file_formats) -{ -} - -const char *d67_format::name() const -{ - return "d67"; -} - -const char *d67_format::description() const -{ - return "Commodore 2040 disk image"; -} - -const char *d67_format::extensions() const -{ - return "d67"; -} - -const d67_format::format d67_format::file_formats[] = { - { // d67, dos 1, 35 tracks, head 48 tpi, stepper 96 tpi - floppy_image::FF_525, floppy_image::SSSD, 690, 35, 1, 256, 9, 8 - }, - {} -}; - -const int d67_format::d67_sectors_per_track[] = -{ - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, // 1-17 - 20, 20, 20, 20, 20, 20, 20, // 18-24 - 18, 18, 18, 18, 18, 18, // 25-30 - 17, 17, 17, 17, 17, // 31-35 - 17, 17, 17, 17, 17, // 36-40 - 17, 17 // 41-42 -}; - -int d67_format::get_sectors_per_track(const format &f, int track) -{ - return d67_sectors_per_track[track]; -} - -const floppy_format_type FLOPPY_D67_FORMAT = &floppy_image_format_creator<d67_format>; diff --git a/src/lib/formats/d67_dsk.h b/src/lib/formats/d67_dsk.h deleted file mode 100644 index c28c1a4d37f..00000000000 --- a/src/lib/formats/d67_dsk.h +++ /dev/null @@ -1,36 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Curt Coder -/********************************************************************* - - formats/d67_dsk.h - - Commodore 2040 sector disk image format - -*********************************************************************/ - -#ifndef D67_DSK_H_ -#define D67_DSK_H_ - -#include "d64_dsk.h" - -class d67_format : public d64_format { -public: - d67_format(); - - virtual const char *name() const; - virtual const char *description() const; - virtual const char *extensions() const; - -protected: - virtual int get_sectors_per_track(const format &f, int track); - - static const format file_formats[]; - - static const int d67_sectors_per_track[]; -}; - -extern const floppy_format_type FLOPPY_D67_FORMAT; - - - -#endif diff --git a/src/lib/formats/flopimg.c b/src/lib/formats/flopimg.c index 0f17c7e3b4d..35ab1af359d 100644 --- a/src/lib/formats/flopimg.c +++ b/src/lib/formats/flopimg.c @@ -2366,6 +2366,16 @@ UINT8 floppy_image_format_t::sbyte_mfm_r(const UINT8 *bitstream, int &pos, int t return res; } +UINT8 floppy_image_format_t::sbyte_gcr5_r(const UINT8 *bitstream, int &pos, int track_size) +{ + UINT16 gcr = 0; + for(int i=0; i<10; i++) { + if(sbit_rp(bitstream, pos, track_size)) + gcr |= 0x200 >> i; + } + + return (gcr5bw_tb[gcr >> 5] << 4) | gcr5bw_tb[gcr & 0x1f]; +} void floppy_image_format_t::extract_sectors_from_bitstream_mfm_pc(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size) { @@ -2801,3 +2811,147 @@ void floppy_image_format_t::build_pc_track_mfm(int track, int head, floppy_image generate_track_from_levels(track, head, track_data, 0, image); } + +void floppy_image_format_t::extract_sectors_from_bitstream_gcr5(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size, int head, int tracks) +{ + 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 0x08: + if(hblk_count < 100) + hblk[hblk_count++] = i-10; + break; + + case 0x07: + 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 crc = sbyte_gcr5_r(bitstream, pos, track_size); + UINT8 sector = sbyte_gcr5_r(bitstream, pos, track_size); + UINT8 track = sbyte_gcr5_r(bitstream, pos, track_size); + UINT8 id2 = sbyte_gcr5_r(bitstream, pos, track_size); + UINT8 id1 = sbyte_gcr5_r(bitstream, pos, track_size); + + if (crc ^ sector ^ track ^ id2 ^ id1) { + // header crc mismatch + } + + pos = dblk[i]; + block_id = sbyte_gcr5_r(bitstream, pos, track_size); + + if (track > tracks) track -= tracks; + sectors[sector].track = track; + sectors[sector].head = head; + sectors[sector].size = 256; + sectors[sector].data = sectdata + sectdata_pos; + UINT8 data_crc = 0; + for(int j=0; j<sectors[sector].size; j++) { + UINT8 data = sbyte_gcr5_r(bitstream, pos, track_size); + data_crc ^= data; + sectdata[sectdata_pos++] = data; + } + data_crc ^= sbyte_gcr5_r(bitstream, pos, track_size); + if (data_crc) { + // data crc mismatch + } + } +} + +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 aaae76530ac..59b652643b6 100644 --- a/src/lib/formats/flopimg.h +++ b/src/lib/formats/flopimg.h @@ -471,6 +471,7 @@ protected: C1541 tr 18-24 3.50 300 3500 C1541 tr 25-30 3.75 300 3750 C1541 tr 31+ 4.00 300 4000 + 8" DD 1 360 1200 5.25" SD 4 300 4000 5.25" DD 2 300 2000 5.25" HD 1 360 1200 @@ -519,6 +520,10 @@ protected: void extract_sectors_from_bitstream_mfm_pc(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size); //! PC-type sectors with FM encoding 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. @@ -572,6 +577,7 @@ protected: void gcr6_decode(UINT8 e0, UINT8 e1, UINT8 e2, UINT8 e3, UINT8 &va, UINT8 &vb, UINT8 &vc); UINT8 sbyte_mfm_r(const UINT8 *bitstream, int &pos, int track_size); + UINT8 sbyte_gcr5_r(const UINT8 *bitstream, int &pos, int track_size); private: enum { CRC_NONE, CRC_AMIGA, CRC_CBM, CRC_CCITT, CRC_CCITT_FM, CRC_MACHEAD, CRC_FCS, CRC_VICTOR_HDR, CRC_VICTOR_DATA }; diff --git a/src/lib/formats/imd_dsk.c b/src/lib/formats/imd_dsk.c index 463b5b771d2..8600590c735 100644 --- a/src/lib/formats/imd_dsk.c +++ b/src/lib/formats/imd_dsk.c @@ -135,6 +135,91 @@ static floperr_t imd_read_indexed_sector(floppy_image_legacy *floppy, int head, return internal_imd_read_sector(floppy, head, track, sector, TRUE, buffer, buflen); } +static floperr_t imd_expand_file(floppy_image_legacy *floppy , UINT64 offset , size_t amount) +{ + if (amount == 0) { + return FLOPPY_ERROR_SUCCESS; + } + + UINT64 file_size = floppy_image_size(floppy); + + if (offset > file_size) { + return FLOPPY_ERROR_INTERNAL; + } + + UINT64 size_after_off = file_size - offset; + + if (size_after_off == 0) { + return FLOPPY_ERROR_SUCCESS; + } + + UINT8 *buffer = global_alloc_array(UINT8 , size_after_off); + + // Read the part of file after offset + floppy_image_read(floppy , buffer , offset , size_after_off); + + // Add zeroes + floppy_image_write_filler(floppy , 0 , offset , amount); + + // Write back the part of file after offset + floppy_image_write(floppy, buffer, offset + amount, size_after_off); + + global_free_array(buffer); + + // Update track offsets + struct imddsk_tag *tag = get_tag(floppy); + for (int track = 0; track < tag->tracks; track++) { + for (int head = 0; head < tag->heads; head++) { + UINT64 *track_off = &(tag->track_offsets[ (track << 1) + head ]); + if (*track_off >= offset) { + *track_off += amount; + } + } + } + + return FLOPPY_ERROR_SUCCESS; +} + +static floperr_t imd_write_indexed_sector(floppy_image_legacy *floppy, int head, int track, int sector_index, const void *buffer, size_t buflen, int ddam) +{ + UINT64 offset; + floperr_t err; + UINT8 header[1]; + + // take sector offset + err = get_offset(floppy, head, track, sector_index, TRUE, &offset); + if (err) + return err; + + floppy_image_read(floppy, header, offset, 1); + + switch (header[ 0 ]) { + case 0: + return FLOPPY_ERROR_SEEKERROR; + + default: + // Expand image file (from 1 byte to a whole sector) + err = imd_expand_file(floppy , offset , buflen - 1); + if (err) { + return err; + } + // Fall through! + + case 1: + case 3: + case 5: + case 7: + // Turn every kind of sector into type 1 (normal data) + header[ 0 ] = 1; + floppy_image_write(floppy, header, offset, 1); + // Write sector + floppy_image_write(floppy, buffer, offset + 1, buflen); + break; + } + + return FLOPPY_ERROR_SUCCESS; +} + static floperr_t imd_get_sector_length(floppy_image_legacy *floppy, int head, int track, int sector, UINT32 *sector_length) { floperr_t err; @@ -266,6 +351,7 @@ FLOPPY_CONSTRUCT( imd_dsk_construct ) callbacks = floppy_callbacks(floppy); callbacks->read_sector = imd_read_sector; callbacks->read_indexed_sector = imd_read_indexed_sector; + callbacks->write_indexed_sector = imd_write_indexed_sector; callbacks->get_sector_length = imd_get_sector_length; callbacks->get_heads_per_disk = imd_get_heads_per_disk; callbacks->get_tracks_per_disk = imd_get_tracks_per_disk; 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; |