summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author cracyc <cracyc@users.noreply.github.com>2013-05-23 12:44:45 +0000
committer cracyc <cracyc@users.noreply.github.com>2013-05-23 12:44:45 +0000
commite697bb3278e70eace602d46d754717af61121131 (patch)
treea744e14d6fbcd5f572cf9954bb87d4310aa536e9 /src
parentb6d5cc992d6f9b9f878c9ac2ed95da137fed9ce2 (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.c1
-rw-r--r--src/emu/imagedev/floppy.h1
-rw-r--r--src/lib/formats/td0_dsk.c288
-rw-r--r--src/lib/formats/td0_dsk.h24
-rw-r--r--src/mess/drivers/qx10.c17
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(&sect_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(&sect_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(&sect_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(&sect_data[sdatapos + j + k], &imagebuf[offset], len);
+ k += rep;
+ offset += len;
+ }
+ }
+ break;
+ }
+
+ sects[i].actual_size = size;
+
+ if(size)
+ {
+ sects[i].data = &sect_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;