summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/formats
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/formats')
-rw-r--r--src/lib/formats/c3040_dsk.c101
-rw-r--r--src/lib/formats/c3040_dsk.h40
-rw-r--r--src/lib/formats/c4040_dsk.c91
-rw-r--r--src/lib/formats/c4040_dsk.h38
-rw-r--r--src/lib/formats/c8280_dsk.c69
-rw-r--r--src/lib/formats/c8280_dsk.h30
-rw-r--r--src/lib/formats/cbm_crt.c6
-rw-r--r--src/lib/formats/cbm_crt.h2
-rw-r--r--src/lib/formats/ccvf_dsk.c10
-rw-r--r--src/lib/formats/d64_dsk.c68
-rw-r--r--src/lib/formats/d64_dsk.h7
-rw-r--r--src/lib/formats/d67_dsk.c56
-rw-r--r--src/lib/formats/d67_dsk.h36
-rw-r--r--src/lib/formats/flopimg.c154
-rw-r--r--src/lib/formats/flopimg.h6
-rw-r--r--src/lib/formats/imd_dsk.c86
-rw-r--r--src/lib/formats/victor9k_dsk.c67
-rw-r--r--src/lib/formats/victor9k_dsk.h15
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 &current_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 &current_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 &current_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 &current_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 &current_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 &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;