diff options
author | 2013-05-23 12:44:45 +0000 | |
---|---|---|
committer | 2013-05-23 12:44:45 +0000 | |
commit | e697bb3278e70eace602d46d754717af61121131 (patch) | |
tree | a744e14d6fbcd5f572cf9954bb87d4310aa536e9 /src | |
parent | b6d5cc992d6f9b9f878c9ac2ed95da137fed9ce2 (diff) |
td0_dsk: add new floppy system support for teledisk [Carl]
---
Lots of conflicting info out there, need more samples (8", fm)
Diffstat (limited to 'src')
-rw-r--r-- | src/emu/imagedev/floppy.c | 1 | ||||
-rw-r--r-- | src/emu/imagedev/floppy.h | 1 | ||||
-rw-r--r-- | src/lib/formats/td0_dsk.c | 288 | ||||
-rw-r--r-- | src/lib/formats/td0_dsk.h | 24 | ||||
-rw-r--r-- | src/mess/drivers/qx10.c | 17 |
5 files changed, 309 insertions, 22 deletions
diff --git a/src/emu/imagedev/floppy.c b/src/emu/imagedev/floppy.c index c863dafb26d..9ced42d72a6 100644 --- a/src/emu/imagedev/floppy.c +++ b/src/emu/imagedev/floppy.c @@ -40,6 +40,7 @@ const floppy_format_type floppy_image_device::default_floppy_formats[] = { FLOPPY_IPF_FORMAT, FLOPPY_MFI_FORMAT, FLOPPY_MFM_FORMAT, + FLOPPY_TD0_FORMAT, NULL }; diff --git a/src/emu/imagedev/floppy.h b/src/emu/imagedev/floppy.h index 086bde65078..a37d14d82e7 100644 --- a/src/emu/imagedev/floppy.h +++ b/src/emu/imagedev/floppy.h @@ -14,6 +14,7 @@ #include "formats/imd_dsk.h" #include "formats/ipf_dsk.h" #include "formats/mfi_dsk.h" +#include "formats/td0_dsk.h" #define MCFG_FLOPPY_DRIVE_ADD(_tag, _slot_intf, _def_slot, _def_inp, _formats) \ MCFG_DEVICE_ADD(_tag, FLOPPY_CONNECTOR, 0) \ diff --git a/src/lib/formats/td0_dsk.c b/src/lib/formats/td0_dsk.c index 9fbec75fa6a..639cebc09ed 100644 --- a/src/lib/formats/td0_dsk.c +++ b/src/lib/formats/td0_dsk.c @@ -13,6 +13,7 @@ */ #include <string.h> +#include "emu.h" #include "flopimg.h" #define BUFSZ 512 // new input buffer @@ -55,7 +56,7 @@ struct tdlzhuf { struct td0dsk_t { - floppy_image_legacy *floppy_file; + io_generic *floppy_file; UINT64 floppy_file_offset; struct tdlzhuf tdctl; @@ -87,7 +88,12 @@ struct td0dsk_t int Decode(UINT8 *buf, int len); }; -static td0dsk_t td0dsk; +//static td0dsk_t td0dsk; + +struct floppy_image_legacy +{ + struct io_generic io; +}; static struct td0dsk_tag *get_tag(floppy_image_legacy *floppy) @@ -312,10 +318,10 @@ static floperr_t td0_get_indexed_sector_info(floppy_image_legacy *floppy, int he int td0dsk_t::data_read(UINT8 *buf, UINT16 size) { - if (floppy_file_offset + size > floppy_image_size(floppy_file) ) { - size = floppy_image_size(floppy_file) - floppy_file_offset; + if (floppy_file_offset + size > io_generic_size(floppy_file) ) { + size = io_generic_size(floppy_file) - floppy_file_offset; } - floppy_image_read(floppy_file,buf,floppy_file_offset,size); + io_generic_read(floppy_file,buf,floppy_file_offset,size); floppy_file_offset += size; return size; } @@ -654,7 +660,7 @@ int td0dsk_t::Decode(UINT8 *buf, int len) /* Decoding/Uncompressing */ FLOPPY_CONSTRUCT( td0_dsk_construct ) { - td0dsk_t *state = &td0dsk; + td0dsk_t state; struct FloppyCallbacks *callbacks; struct td0dsk_tag *tag; UINT8 *header; @@ -685,12 +691,12 @@ FLOPPY_CONSTRUCT( td0_dsk_construct ) int rd; int off = 12; int size = 0; - state->floppy_file = floppy; - state->init_Decode(); - state->floppy_file_offset = 12; + state.floppy_file = &(floppy->io); + state.init_Decode(); + state.floppy_file_offset = 12; do { - if((rd = state->Decode(obuf, BUFSZ)) > 0) size += rd; + if((rd = state.Decode(obuf, BUFSZ)) > 0) size += rd; } while(rd == BUFSZ); memcpy(obuf,tag->data,12); free(tag->data); @@ -699,11 +705,11 @@ FLOPPY_CONSTRUCT( td0_dsk_construct ) return FLOPPY_ERROR_OUTOFMEMORY; } memcpy(tag->data,obuf,12); - state->floppy_file_offset = 12; - state->init_Decode(); + state.floppy_file_offset = 12; + state.init_Decode(); do { - if((rd = state->Decode(obuf, BUFSZ)) > 0) { + if((rd = state.Decode(obuf, BUFSZ)) > 0) { memcpy(tag->data+off,obuf,rd); off += rd; } @@ -764,3 +770,259 @@ FLOPPY_DESTRUCT( td0_dsk_destruct ) tag->data = NULL; return FLOPPY_ERROR_SUCCESS; } + +/********************************************************************* + + formats/td0_dsk.h + + Teledisk disk images + +*********************************************************************/ + +#include <ctype.h> +#include "td0_dsk.h" + +td0_format::td0_format() +{ +} + +const char *td0_format::name() const +{ + return "td0"; +} + +const char *td0_format::description() const +{ + return "Teledisk disk image"; +} + +const char *td0_format::extensions() const +{ + return "td0"; +} + +int td0_format::identify(io_generic *io, UINT32 form_factor) +{ + UINT8 h[7]; + + io_generic_read(io, h, 0, 7); + if((toupper(h[0]) == 'T') && (toupper(h[1]) == 'D')) + { + if((form_factor == floppy_image::FF_35) && ((h[6] == 3) || (h[6] == 4))) + return 100; + if((form_factor == floppy_image::FF_525) && ((h[6] == 1) || (h[6] == 2) || (h[6] == 3))) + return 100; + } + return 0; +} + +bool td0_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) +{ + int cell_count = 0; + int track_count = 0; + int head_count = 0; + int track_spt; + int offset = 0; + const int max_size = 4*1024*1024; // 4MB ought to be large enough for any floppy + UINT8 *imagebuf = global_alloc_array(UINT8, max_size); + UINT8 header[12]; + + try + { + io_generic_read(io, header, 0, 12); + head_count = header[9]; + + if(header[0] == 't') + { + td0dsk_t disk_decode; + + disk_decode.floppy_file = io; + disk_decode.init_Decode(); + disk_decode.floppy_file_offset = 12; + disk_decode.Decode(imagebuf, max_size); + } + else + io_generic_read(io, imagebuf, 12, io_generic_size(io)); + + if(header[7] & 0x80) + offset = 10 + imagebuf[1] + (imagebuf[2] << 8); + + track_spt = imagebuf[offset]; + if(track_spt == 255) // Empty file? + throw false; + + switch(header[6]) + { + case 2: + if((imagebuf[offset + 2] & 0x7f) == 2) // ? + { + cell_count = 166666; + if(head_count == 2) + image->set_variant(floppy_image::DSHD); + else + throw false; // single side hd? + break; + } + /* no break; could be qd, won't know until tracks are counted */ + case 1: + cell_count = 100000; + if(head_count == 2) + image->set_variant(floppy_image::DSDD); + else + image->set_variant(floppy_image::SSDD); + break; + case 4: + if((imagebuf[offset + 2] & 0x7f) == 2) // ? + { + cell_count = 200000; + if(head_count == 2) + image->set_variant(floppy_image::DSHD); + else + throw false; // single side 3.5? + break; + } + /* no break */ + case 3: + cell_count = 100000; + if(head_count == 2) + { + if(form_factor == floppy_image::FF_525) // is this correct? + image->set_variant(floppy_image::DSQD); + else + image->set_variant(floppy_image::DSDD); + } + else + { + if(form_factor == floppy_image::FF_525) + image->set_variant(floppy_image::SSQD); + else + throw false; // single side 3.5? + } + break; + } + + while(track_spt != 255) + { + desc_pc_sector sects[256]; + UINT8 sect_data[65536]; + int sdatapos = 0; + int track = imagebuf[offset + 1]; + int head = imagebuf[offset + 2] & 1; + bool fm = (header[5] & 0x80) || (imagebuf[offset + 2] & 0x80); // ? + offset += 4; + for(int i = 0; i < track_spt; i++) + { + UINT8 *hs = &imagebuf[offset]; + UINT16 size; + offset += 6; + + sects[i].track = hs[0]; + sects[i].head = hs[1]; + sects[i].sector = hs[2]; + sects[i].size = hs[3]; + sects[i].deleted = (hs[4] & 4) == 4; + sects[i].bad_crc = (hs[4] & 2) == 2; + + if(hs[4] & 0x30) + size = 0; + else + { + offset += 3; + size = 128 << hs[3]; + int j, k; + switch(hs[8]) + { + default: + throw false; + case 0: + memcpy(§_data[sdatapos], &imagebuf[offset], size); + offset += size; + break; + case 1: + offset += 4; + k = (hs[9] + (hs[10] << 8)) * 2; + k = (k <= size) ? k : size; + for(j = 0; j < k; j += 2) + { + sect_data[sdatapos + j] = hs[11]; + sect_data[sdatapos + j + 1] = hs[12]; + } + if(k < size) + memset(§_data[sdatapos + k], '\0', size - k); + break; + case 2: + k = 0; + while(k < size) + { + UINT16 len = imagebuf[offset]; + UINT16 rep = imagebuf[offset + 1]; + offset += 2; + if(!len) + { + memcpy(§_data[sdatapos + k], &imagebuf[offset], rep); + offset += rep; + k += rep; + } + else + { + len = (1 << len); + rep = len * rep; + rep = ((rep + k) <= size) ? rep : (size - k); + for(j = 0; j < rep; j += len) + memcpy(§_data[sdatapos + j + k], &imagebuf[offset], len); + k += rep; + offset += len; + } + } + break; + } + + sects[i].actual_size = size; + + if(size) + { + sects[i].data = §_data[sdatapos]; + sdatapos += size; + } + else + sects[i].data = NULL; + } + } + track_count = track; + if(fm) + build_pc_track_fm(track, head, image, cell_count, track_spt, sects, calc_default_pc_gap3_size(form_factor, sects[0].actual_size)); + else + build_pc_track_mfm(track, head, image, cell_count, track_spt, sects, calc_default_pc_gap3_size(form_factor, sects[0].actual_size)); + track_spt = imagebuf[offset]; + } + if((track_count > 50) && (form_factor == floppy_image::FF_525)) // ? + { + if(image->get_variant() == floppy_image::DSDD) + image->set_variant(floppy_image::DSQD); + else if(image->get_variant() == floppy_image::SSDD) + image->set_variant(floppy_image::SSQD); + } + throw true; + } + catch(bool ret) + { + global_free(imagebuf); + return ret; + } + return false; +} + + +bool td0_format::save(io_generic *io, floppy_image *image) +{ + return false; +} + +bool td0_format::supports_save() const +{ + return false; +} + +const floppy_format_type FLOPPY_TD0_FORMAT = &floppy_image_format_creator<td0_format>; + + diff --git a/src/lib/formats/td0_dsk.h b/src/lib/formats/td0_dsk.h new file mode 100644 index 00000000000..3e5b8e843c5 --- /dev/null +++ b/src/lib/formats/td0_dsk.h @@ -0,0 +1,24 @@ +#ifndef TD0_DSK_H_ +#define TD0_DSK_H_ + +#include "flopimg.h" + + +class td0_format : public floppy_image_format_t +{ +public: + td0_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_TD0_FORMAT; + +#endif /* TD0_DSK_H_ */ diff --git a/src/mess/drivers/qx10.c b/src/mess/drivers/qx10.c index 3e830c7022f..4042d914d6c 100644 --- a/src/mess/drivers/qx10.c +++ b/src/mess/drivers/qx10.c @@ -37,7 +37,7 @@ #include "machine/upd7201.h" #include "machine/mc146818.h" #include "machine/i8255.h" -#include "machine/8237dma.h" +#include "machine/am9517a.h" #include "machine/serial.h" #include "video/upd7220.h" #include "machine/upd765.h" @@ -77,8 +77,8 @@ public: required_device<pic8259_device> m_pic_s; required_device<upd7201_device> m_scc; required_device<i8255_device> m_ppi; - required_device<i8237_device> m_dma_1; - required_device<i8237_device> m_dma_2; + required_device<am9517a_device> m_dma_1; + required_device<am9517a_device> m_dma_2; required_device<upd765a_device> m_fdc; required_device<upd7220_device> m_hgdc; required_device<mc146818_device> m_rtc; @@ -340,7 +340,7 @@ void qx10_state::qx10_upd765_interrupt(bool state) void qx10_state::drq_w(bool state) { - m_dma_1->i8237_dreq0_w(!state); + m_dma_1->dreq0_w(!state); } WRITE8_MEMBER( qx10_state::fdd_motor_w ) @@ -369,9 +369,8 @@ READ8_MEMBER( qx10_state::qx10_30_r ) */ WRITE_LINE_MEMBER(qx10_state::dma_hrq_changed) { - i8237_device *device = machine().device<i8237_device>("8237dma_1"); /* Assert HLDA */ - device->i8237_hlda_w(state); + m_dma_1->hack_w(state); } READ8_MEMBER( qx10_state::gdc_dack_r ) @@ -694,8 +693,8 @@ static ADDRESS_MAP_START( qx10_io , AS_IO, 8, qx10_state) // AM_RANGE(0x3b, 0x3b) GDC light pen req AM_RANGE(0x3c, 0x3c) AM_READWRITE(mc146818_data_r, mc146818_data_w) AM_RANGE(0x3d, 0x3d) AM_WRITE(mc146818_offset_w) - AM_RANGE(0x40, 0x4f) AM_DEVREADWRITE("8237dma_1", i8237_device, i8237_r, i8237_w) - AM_RANGE(0x50, 0x5f) AM_DEVREADWRITE("8237dma_2", i8237_device, i8237_r, i8237_w) + AM_RANGE(0x40, 0x4f) AM_DEVREADWRITE("8237dma_1", am9517a_device, read, write) + AM_RANGE(0x50, 0x5f) AM_DEVREADWRITE("8237dma_2", am9517a_device, read, write) // AM_RANGE(0xfc, 0xfd) Multi-Font comms ADDRESS_MAP_END @@ -920,7 +919,7 @@ void qx10_state::machine_start() void qx10_state::machine_reset() { - m_dma_1->i8237_dreq0_w(1); + m_dma_1->dreq0_w(1); m_memprom = 0; m_memcmos = 0; |