diff options
author | 2014-10-08 20:49:24 +0000 | |
---|---|---|
committer | 2014-10-08 20:49:24 +0000 | |
commit | 5e8c2a11b2c3b7b68e2e5cc2b92b145743b10986 (patch) | |
tree | 388737f68d2b49f43ef0cdd968a8d381dfda686e | |
parent | d9330a96d62bde0e662fc13e36620e264d75b4ec (diff) |
(MESS) msx.c: Added support for DMK floppy images. [Wilbert Pol]
-rw-r--r-- | .gitattributes | 2 | ||||
-rw-r--r-- | src/lib/formats/dmk_dsk.c | 229 | ||||
-rw-r--r-- | src/lib/formats/dmk_dsk.h | 34 | ||||
-rw-r--r-- | src/mess/drivers/msx.c | 4 |
4 files changed, 268 insertions, 1 deletions
diff --git a/.gitattributes b/.gitattributes index f05d4ad281e..e5848af7f54 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3798,6 +3798,8 @@ src/lib/formats/dfi_dsk.c svneol=native#text/plain src/lib/formats/dfi_dsk.h svneol=native#text/plain src/lib/formats/dim_dsk.c svneol=native#text/plain src/lib/formats/dim_dsk.h svneol=native#text/plain +src/lib/formats/dmk_dsk.c svneol=native#text/plain +src/lib/formats/dmk_dsk.h svneol=native#text/plain src/lib/formats/dmv_dsk.c svneol=native#text/plain src/lib/formats/dmv_dsk.h svneol=native#text/plain src/lib/formats/dsk_dsk.c svneol=native#text/plain diff --git a/src/lib/formats/dmk_dsk.c b/src/lib/formats/dmk_dsk.c new file mode 100644 index 00000000000..af1f134f94a --- /dev/null +++ b/src/lib/formats/dmk_dsk.c @@ -0,0 +1,229 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +/********************************************************************* + + formats/dmk_dsk.h + + DMK disk images + +TODO: +- Add write/format support. +- Add single density support. +- Check support on other drivers besides msx. + +*********************************************************************/ + +#include "emu.h" +#include "dmk_dsk.h" + + +dmk_format::dmk_format() +{ +} + + +const char *dmk_format::name() const +{ + return "dmk"; +} + + +const char *dmk_format::description() const +{ + return "DMK disk image"; +} + + +const char *dmk_format::extensions() const +{ + return "dmk"; +} + + +int dmk_format::identify(io_generic *io, UINT32 form_factor) +{ + const int header_size = 16; + UINT8 header[header_size]; + + UINT64 size = io_generic_size(io); + + io_generic_read(io, header, 0, header_size); + + int tracks = header[1]; + int track_size = ( header[3] << 8 ) | header[2]; + int heads = (header[4] & 0x10) ? 1 : 2; + + // The first header byte must be 00 or FF + if (header[0] != 0x00 && header[0] != 0xff) + { + return 0; + } + + // Bytes C-F must be zero + if (header[0x0c] != 0 || header[0xd] != 0 || header[0xe] != 0 || header[0xf] != 0) + { + return 0; + } + + // Check track size within limits + if (track_size < 0x80 || track_size > 0x3FFF ) + { + return 0; + } + + if (size == header_size + heads * tracks * track_size) + { + return 70; + } + + return 0; +} + + +bool dmk_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) +{ + const int header_size = 16; + UINT8 header[header_size]; + + io_generic_read(io, header, 0, header_size); + + const int tracks = header[1]; + const int track_size = ( header[3] << 8 ) | header[2]; + const int heads = (header[4] & 0x10) ? 1 : 2; + const bool is_sd = (header[4] & 0x40) ? true : false; + const int raw_track_size = 2 * 8 * ( track_size - 0x80 ); + + if (is_sd) + { + if (heads == 2) + { + image->set_variant(floppy_image::DSSD); + } + else + { + image->set_variant(floppy_image::SSSD); + } + } + else + { + if (heads == 2) + { + image->set_variant(floppy_image::DSDD); + } + else + { + image->set_variant(floppy_image::SSDD); + } + } + + for (int track = 0; track < tracks; track++) + { + for (int head = 0; head < heads; head++) + { + dynamic_array<UINT8> track_data(track_size); + dynamic_array<UINT32> raw_track_data(raw_track_size); + int iam_location = -1; + int idam_location[64]; + int dam_location[64]; + int tpos = 0; + + // Read track + io_generic_read(io, track_data, header_size + ( heads * track + head ) * track_size, track_size); + + for (int i = 0; i < 64; i++) + { + idam_location[i] = -1; + dam_location[i] = -1; + } + + // Find IDAM locations + UINT16 track_header_offset = 0; + UINT16 track_offset = ( ( track_data[track_header_offset + 1] << 8 ) | track_data[track_header_offset] ) & 0x3fff; + track_header_offset += 2; + + while ( track_offset != 0 && track_offset >= 0x83 && track_offset < track_size && track_header_offset < 0x80 ) + { + // Assume 3 bytes before IDAM pointers are the start of IDAM indicators + idam_location[(track_header_offset/2) - 1] = track_offset - 3; + + // Scan for DAM location + for (int i = track_offset + 53; i > track_offset + 10; i--) + { + if ((track_data[i] == 0xfb || track_data[i] == 0xf8) && track_data[i-1] == 0xa1 && track_data[i-2] == 0xa1) + { + dam_location[(track_header_offset/2) - 1] = i - 3; + break; + } + } + + track_offset = ( ( track_data[track_header_offset + 1] << 8 ) | track_data[track_header_offset] ) & 0x3fff; + track_header_offset += 2; + }; + + // Find IAM location + for(int i = idam_location[0] - 1; i >= 3; i--) + { + // It's usually 3 bytes but several dumped tracks seem to contain only 2 bytes + if (track_data[i] == 0xfc && track_data[i-1] == 0xc2 && track_data[i-2] == 0xc2) + { + iam_location = i - 3; + break; + } + } + + int idam_index = 0; + int dam_index = 0; + for (int offset = 0x80; offset < track_size; offset++) + { + if (offset == iam_location) + { + // Write IAM + raw_w(raw_track_data, tpos, 16, 0x5224); + raw_w(raw_track_data, tpos, 16, 0x5224); + raw_w(raw_track_data, tpos, 16, 0x5224); + offset += 3; + } + + if (offset == idam_location[idam_index]) + { + raw_w(raw_track_data, tpos, 16, 0x4489); + raw_w(raw_track_data, tpos, 16, 0x4489); + raw_w(raw_track_data, tpos, 16, 0x4489); + idam_index += 1; + offset += 3; + } + + if (offset == dam_location[dam_index]) + { + raw_w(raw_track_data, tpos, 16, 0x4489); + raw_w(raw_track_data, tpos, 16, 0x4489); + raw_w(raw_track_data, tpos, 16, 0x4489); + dam_index += 1; + offset += 3; + } + + mfm_w(raw_track_data, tpos, 8, track_data[offset]); + } + + generate_track_from_levels(track, head, raw_track_data, raw_track_size, 0, image); + } + } + + return true; +} + + +bool dmk_format::save(io_generic *io, floppy_image *image) +{ + return false; +} + + +bool dmk_format::supports_save() const +{ + return false; +} + + +const floppy_format_type FLOPPY_DMK_FORMAT = &floppy_image_format_creator<dmk_format>; + diff --git a/src/lib/formats/dmk_dsk.h b/src/lib/formats/dmk_dsk.h new file mode 100644 index 00000000000..68c4d8deea3 --- /dev/null +++ b/src/lib/formats/dmk_dsk.h @@ -0,0 +1,34 @@ +/********************************************************************* + + formats/dmk_dsk.h + + DMK disk images + +*********************************************************************/ + +#ifndef DMK_DSK_H +#define DMK_DSK_H + +#include "flopimg.h" + +/**************************************************************************/ + +class dmk_format : public floppy_image_format_t +{ +public: + dmk_format(); + + virtual int identify(io_generic *io, UINT32 form_factor); + virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image); + virtual bool save(io_generic *io, floppy_image *image); + + virtual const char *name() const; + virtual const char *description() const; + virtual const char *extensions() const; + virtual bool supports_save() const; +}; + +extern const floppy_format_type FLOPPY_DMK_FORMAT; + +#endif /* DMK_DSK_H */ + diff --git a/src/mess/drivers/msx.c b/src/mess/drivers/msx.c index dad56ba803e..1bead63423a 100644 --- a/src/mess/drivers/msx.c +++ b/src/mess/drivers/msx.c @@ -521,6 +521,7 @@ PCB Layouts missing #include "includes/msx.h" #include "bus/centronics/covox.h" #include "formats/dsk_dsk.h" +#include "formats/dmk_dsk.h" #include "machine/msx_matsushita.h" #include "machine/msx_s1985.h" #include "machine/msx_systemflags.h" @@ -1258,7 +1259,8 @@ static MACHINE_CONFIG_FRAGMENT( msx2_floplist ) MACHINE_CONFIG_END FLOPPY_FORMATS_MEMBER( msx_state::floppy_formats ) - FLOPPY_MSX_FORMAT + FLOPPY_MSX_FORMAT, + FLOPPY_DMK_FORMAT FLOPPY_FORMATS_END static SLOT_INTERFACE_START( msx_floppies ) |