summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/machine
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2013-02-22 10:53:15 +0000
committer Miodrag Milanovic <mmicko@gmail.com>2013-02-22 10:53:15 +0000
commit2b25f4a87f24cbac5480d658085517283ad67b3b (patch)
tree05259271a2a59ca6e6ee706ab96a8de0b909813b /src/mess/machine
parentb25a1c367a3409865f2b049851a0235526b96978 (diff)
Moved some mess devices to proper place (nw)
Diffstat (limited to 'src/mess/machine')
-rw-r--r--src/mess/machine/a2diskii.c2
-rw-r--r--src/mess/machine/appldriv.c334
-rw-r--r--src/mess/machine/appldriv.h86
-rw-r--r--src/mess/machine/apple2.c4
-rw-r--r--src/mess/machine/apple3.c2
-rw-r--r--src/mess/machine/microdrv.c203
-rw-r--r--src/mess/machine/microdrv.h103
-rw-r--r--src/mess/machine/sonydriv.c571
-rw-r--r--src/mess/machine/sonydriv.h70
-rw-r--r--src/mess/machine/zx8302.c2
10 files changed, 1372 insertions, 5 deletions
diff --git a/src/mess/machine/a2diskii.c b/src/mess/machine/a2diskii.c
index ab2d93cc52a..f9dce090dc7 100644
--- a/src/mess/machine/a2diskii.c
+++ b/src/mess/machine/a2diskii.c
@@ -10,7 +10,7 @@
#include "includes/apple2.h"
#include "imagedev/flopdrv.h"
#include "formats/ap2_dsk.h"
-#include "devices/appldriv.h"
+#include "machine/appldriv.h"
#include "machine/applefdc.h"
#include "machine/a2diskii.h"
diff --git a/src/mess/machine/appldriv.c b/src/mess/machine/appldriv.c
new file mode 100644
index 00000000000..6c91161d067
--- /dev/null
+++ b/src/mess/machine/appldriv.c
@@ -0,0 +1,334 @@
+/*********************************************************************
+
+ appldriv.c
+
+ Apple 5.25" floppy drive emulation (to be interfaced with applefdc.c)
+
+*********************************************************************/
+#include "emu.h"
+#include "appldriv.h"
+#include "imagedev/flopdrv.h"
+#include "formats/ap2_dsk.h"
+
+// our parent's device is the Disk II card (Apple II) or main driver (Mac, IIgs)
+// either way, get the drive from there.
+#define PARENT_FLOPPY_0 "^floppy0"
+#define PARENT_FLOPPY_1 "^floppy1"
+#define PARENT_FLOPPY_2 "^floppy2"
+#define PARENT_FLOPPY_3 "^floppy3"
+
+INLINE apple525_floppy_image_device *get_device(device_t *device)
+{
+ assert(device != NULL);
+ assert(device->type() == FLOPPY_APPLE);
+
+ return (apple525_floppy_image_device *) downcast<apple525_floppy_image_device *>(device);
+}
+
+static int apple525_enable_mask = 1;
+
+device_t *apple525_get_subdevice(device_t *device, int drive)
+{
+ switch(drive) {
+ case 0 : return device->subdevice(PARENT_FLOPPY_0);
+ case 1 : return device->subdevice(PARENT_FLOPPY_1);
+ case 2 : return device->subdevice(PARENT_FLOPPY_2);
+ case 3 : return device->subdevice(PARENT_FLOPPY_3);
+ }
+ return NULL;
+}
+
+device_t *apple525_get_device_by_type(device_t *device, int ftype, int drive)
+{
+ int i;
+ int cnt = 0;
+ for (i=0;i<4;i++) {
+ device_t *disk = apple525_get_subdevice(device, i);
+ if (floppy_get_drive_type(disk)==ftype) {
+ if (cnt==drive) {
+ return disk;
+ }
+ cnt++;
+ }
+ }
+ return NULL;
+}
+
+void apple525_set_enable_lines(device_t *device,int enable_mask)
+{
+ apple525_enable_mask = enable_mask;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static void apple525_load_current_track(device_t *image)
+{
+ int len;
+ apple525_floppy_image_device *disk;
+
+ disk = get_device(image);
+ len = sizeof(disk->track_data);
+
+ floppy_drive_read_track_data_info_buffer(image, 0, disk->track_data, &len);
+ disk->track_loaded = 1;
+ disk->track_dirty = 0;
+}
+
+static void apple525_save_current_track(device_t *image, int unload)
+{
+ int len;
+ apple525_floppy_image_device *disk;
+
+ disk = get_device(image);
+
+ if (disk->track_dirty)
+ {
+ len = sizeof(disk->track_data);
+ floppy_drive_write_track_data_info_buffer(image, 0, disk->track_data, &len);
+ disk->track_dirty = 0;
+ }
+ if (unload)
+ disk->track_loaded = 0;
+}
+
+static void apple525_seek_disk(device_t *img, signed int step)
+{
+ int track;
+ int pseudo_track;
+ apple525_floppy_image_device *disk;
+
+ disk = get_device(img);
+
+ apple525_save_current_track(img, FALSE);
+
+ track = floppy_drive_get_current_track(img);
+ pseudo_track = (track * 2) + disk->tween_tracks;
+
+ pseudo_track += step;
+ if (pseudo_track < 0)
+ pseudo_track = 0;
+ else if (pseudo_track/2 >= APPLE2_TRACK_COUNT)
+ pseudo_track = APPLE2_TRACK_COUNT*2-1;
+
+ if (pseudo_track/2 != track)
+ {
+ floppy_drive_seek(img, pseudo_track/2 - floppy_drive_get_current_track(img));
+ disk->track_loaded = 0;
+ }
+
+ if (pseudo_track & 1)
+ disk->tween_tracks = 1;
+ else
+ disk->tween_tracks = 0;
+}
+
+static void apple525_disk_set_lines(device_t *device,device_t *image, UINT8 new_state)
+{
+ apple525_floppy_image_device *cur_disk;
+ UINT8 old_state;
+ unsigned int phase;
+
+ cur_disk = get_device(image);
+
+ old_state = cur_disk->state;
+ cur_disk->state = new_state;
+
+ if ((new_state & 0x0F) > (old_state & 0x0F))
+ {
+ phase = 0;
+ switch((old_state ^ new_state) & 0x0F)
+ {
+ case 1: phase = 0; break;
+ case 2: phase = 1; break;
+ case 4: phase = 2; break;
+ case 8: phase = 3; break;
+ }
+
+ phase -= floppy_drive_get_current_track(image) * 2;
+ if (cur_disk->tween_tracks)
+ phase--;
+ phase %= 4;
+
+ switch(phase)
+ {
+ case 1:
+ apple525_seek_disk(image, +1);
+ break;
+ case 3:
+ apple525_seek_disk(image, -1);
+ break;
+ }
+ }
+}
+
+int apple525_get_count(device_t *device)
+{
+ int cnt = 0;
+ if ((device->subdevice("^"FLOPPY_0)!=NULL) && (floppy_get_drive_type(device->subdevice("^"FLOPPY_0)) == FLOPPY_TYPE_APPLE) && (get_device(device->subdevice(PARENT_FLOPPY_0))!=NULL)) cnt++;
+ if ((device->subdevice("^"FLOPPY_1)!=NULL) && (floppy_get_drive_type(device->subdevice("^"FLOPPY_1)) == FLOPPY_TYPE_APPLE) && (get_device(device->subdevice(PARENT_FLOPPY_1))!=NULL)) cnt++;
+ if ((device->subdevice("^"FLOPPY_2)!=NULL) && (floppy_get_drive_type(device->subdevice("^"FLOPPY_2)) == FLOPPY_TYPE_APPLE) && (get_device(device->subdevice(PARENT_FLOPPY_2))!=NULL)) cnt++;
+ if ((device->subdevice("^"FLOPPY_3)!=NULL) && (floppy_get_drive_type(device->subdevice("^"FLOPPY_3)) == FLOPPY_TYPE_APPLE) && (get_device(device->subdevice(PARENT_FLOPPY_3))!=NULL)) cnt++;
+
+ return cnt;
+}
+
+void apple525_set_lines(device_t *device, UINT8 lines)
+{
+ int i, count;
+ device_t *image;
+
+ count = apple525_get_count(device);
+ for (i = 0; i < count; i++)
+ {
+ if (apple525_enable_mask & (1 << i))
+ {
+ image = apple525_get_device_by_type(device, FLOPPY_TYPE_APPLE, i);
+ if (image)
+ apple525_disk_set_lines(device,image, lines);
+ }
+ }
+}
+
+/* reads/writes a byte; write_value is -1 for read only */
+static UINT8 apple525_process_byte(device_t *img, int write_value)
+{
+ UINT8 read_value;
+ apple525_floppy_image_device *disk;
+ int spinfract_divisor;
+ int spinfract_dividend;
+ apple525_floppy_image_device *config = get_device(img);
+ device_image_interface *image = dynamic_cast<device_image_interface *>(img);
+
+ disk = get_device(img);
+ spinfract_dividend = config->get_dividend();
+ spinfract_divisor = config->get_divisor();
+
+ /* no image initialized for that drive ? */
+ if (!image->exists())
+ return 0xFF;
+
+ /* check the spin count if reading*/
+ if (write_value < 0)
+ {
+ disk->spin_count++;
+ disk->spin_count %= spinfract_divisor;
+ if (disk->spin_count >= spinfract_dividend)
+ return 0x00;
+ }
+
+ /* load track if need be */
+ if (disk->track_loaded == 0)
+ apple525_load_current_track(img);
+
+ /* perform the read */
+ read_value = disk->track_data[disk->position];
+
+ /* perform the write, if applicable */
+ if (write_value >= 0)
+ {
+ disk->track_data[disk->position] = write_value;
+ disk->track_dirty = 1;
+ }
+
+ disk->position++;
+ disk->position %= ARRAY_LENGTH(disk->track_data);
+
+ /* when writing; save the current track after every full sector write */
+ if ((write_value >= 0) && ((disk->position % APPLE2_NIBBLE_SIZE) == 0))
+ apple525_save_current_track(img, FALSE);
+
+ return read_value;
+}
+
+static device_t *apple525_selected_image(device_t *device)
+{
+ int i,count;
+
+ count = apple525_get_count(device);
+
+ for (i = 0; i < count; i++)
+ {
+ if (apple525_enable_mask & (1 << i))
+ return apple525_get_device_by_type(device, FLOPPY_TYPE_APPLE, i);
+ }
+ return NULL;
+}
+
+UINT8 apple525_read_data(device_t *device)
+{
+ device_t *image;
+ image = apple525_selected_image(device);
+ return image ? apple525_process_byte(image, -1) : 0xFF;
+}
+
+void apple525_write_data(device_t *device,UINT8 data)
+{
+ device_t *image;
+ image = apple525_selected_image(device);
+ if (image)
+ apple525_process_byte(image, data);
+}
+
+int apple525_read_status(device_t *device)
+{
+ int i, count, result = 0;
+ device_image_interface *image;
+
+ count = apple525_get_count(device);
+
+ for (i = 0; i < count; i++)
+ {
+ if (apple525_enable_mask & (1 << i))
+ {
+ image = dynamic_cast<device_image_interface *>(apple525_get_device_by_type(device, FLOPPY_TYPE_APPLE, i));
+ if (image && image->is_readonly())
+ result = 1;
+ }
+ }
+ return result;
+}
+
+// device type definition
+const device_type FLOPPY_APPLE = &device_creator<apple525_floppy_image_device>;
+
+//-------------------------------------------------
+// apple525_floppy_image_device - constructor
+//-------------------------------------------------
+
+apple525_floppy_image_device::apple525_floppy_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : legacy_floppy_image_device(mconfig, FLOPPY_APPLE, "Apple Disk II", tag, owner, clock)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void apple525_floppy_image_device::device_start()
+{
+ legacy_floppy_image_device::device_start();
+ floppy_set_type(this,FLOPPY_TYPE_APPLE);
+
+ state = 0;
+ tween_tracks = 0;
+ track_loaded = 0;
+ track_dirty = 0;
+ position = 0;
+ spin_count = 0;
+ memset(track_data, 0, sizeof(track_data));
+}
+
+bool apple525_floppy_image_device::call_load()
+{
+ int result = legacy_floppy_image_device::call_load();
+ floppy_drive_seek(*this, -999);
+ floppy_drive_seek(*this, +35/2);
+ return result;
+}
+
+void apple525_floppy_image_device::call_unload()
+{
+ apple525_save_current_track(this, TRUE);
+
+ legacy_floppy_image_device::call_unload();
+}
diff --git a/src/mess/machine/appldriv.h b/src/mess/machine/appldriv.h
new file mode 100644
index 00000000000..29cf2759aa0
--- /dev/null
+++ b/src/mess/machine/appldriv.h
@@ -0,0 +1,86 @@
+/*********************************************************************
+
+ appldriv.h
+
+ Apple 5.25" floppy drive emulation (to be interfaced with applefdc.c)
+
+*********************************************************************/
+
+#ifndef APPLDRIV_H
+#define APPLDRIV_H
+
+#include "emu.h"
+#include "imagedev/flopdrv.h"
+#include "formats/ap2_dsk.h"
+
+void apple525_set_lines(device_t *device,UINT8 lines);
+void apple525_set_enable_lines(device_t *device,int enable_mask);
+
+UINT8 apple525_read_data(device_t *device);
+void apple525_write_data(device_t *device,UINT8 data);
+int apple525_read_status(device_t *device);
+int apple525_get_count(running_machine &machine);
+
+class apple525_floppy_image_device : public legacy_floppy_image_device
+{
+public:
+ // construction/destruction
+ apple525_floppy_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ virtual bool call_load();
+ virtual void call_unload();
+ void set_params(int dividend, int divisor) { m_dividend = dividend; m_divisor = divisor;}
+
+ int get_dividend() { return m_dividend; }
+ int get_divisor() { return m_divisor; }
+
+ // these elements should be private, but are not yet
+ unsigned int state : 4; /* bits 0-3 are the phase */
+ unsigned int tween_tracks : 1;
+ unsigned int track_loaded : 1;
+ unsigned int track_dirty : 1;
+ int position;
+ int spin_count; /* simulate drive spin to fool RWTS test at $BD34 */
+ UINT8 track_data[APPLE2_NIBBLE_SIZE * APPLE2_SECTOR_COUNT];
+
+protected:
+ virtual void device_start();
+
+private:
+ int m_dividend;
+ int m_divisor;
+};
+
+// device type definition
+extern const device_type FLOPPY_APPLE;
+
+#define MCFG_LEGACY_FLOPPY_APPLE_PARAMS(_dividend,_divisor) \
+ downcast<apple525_floppy_image_device *>(device)->set_params(_dividend,_divisor);
+
+#define MCFG_LEGACY_FLOPPY_APPLE_2_DRIVES_ADD(_config,_dividend,_divisor) \
+ MCFG_DEVICE_ADD(FLOPPY_0, FLOPPY_APPLE, 0) \
+ MCFG_DEVICE_CONFIG(_config) \
+ MCFG_LEGACY_FLOPPY_APPLE_PARAMS(_dividend,_divisor) \
+ MCFG_DEVICE_ADD(FLOPPY_1, FLOPPY_APPLE, 0) \
+ MCFG_DEVICE_CONFIG(_config) \
+ MCFG_LEGACY_FLOPPY_APPLE_PARAMS(_dividend,_divisor)
+
+#define MCFG_LEGACY_FLOPPY_APPLE_4_DRIVES_ADD(_config,_dividend,_divisor) \
+ MCFG_DEVICE_ADD(FLOPPY_0, FLOPPY_APPLE, 0) \
+ MCFG_DEVICE_CONFIG(_config) \
+ MCFG_LEGACY_FLOPPY_APPLE_PARAMS(_dividend,_divisor) \
+ MCFG_DEVICE_ADD(FLOPPY_1, FLOPPY_APPLE, 0) \
+ MCFG_DEVICE_CONFIG(_config) \
+ MCFG_LEGACY_FLOPPY_APPLE_PARAMS(_dividend,_divisor) \
+ MCFG_DEVICE_ADD(FLOPPY_2, FLOPPY_APPLE, 0) \
+ MCFG_DEVICE_CONFIG(_config) \
+ MCFG_LEGACY_FLOPPY_APPLE_PARAMS(_dividend,_divisor) \
+ MCFG_DEVICE_ADD(FLOPPY_3, FLOPPY_APPLE, 0) \
+ MCFG_DEVICE_CONFIG(_config) \
+ MCFG_LEGACY_FLOPPY_APPLE_PARAMS(_dividend,_divisor)
+
+#define MCFG_LEGACY_FLOPPY_APPLE_2_DRIVES_REMOVE() \
+ MCFG_DEVICE_REMOVE(FLOPPY_0) \
+ MCFG_DEVICE_REMOVE(FLOPPY_1)
+
+#endif /* APPLDRIV_H */
diff --git a/src/mess/machine/apple2.c b/src/mess/machine/apple2.c
index 4e02a320424..8e428d77bee 100644
--- a/src/mess/machine/apple2.c
+++ b/src/mess/machine/apple2.c
@@ -15,8 +15,8 @@
#include "machine/a2bus.h"
#include "machine/ay3600.h"
#include "machine/applefdc.h"
-#include "devices/sonydriv.h"
-#include "devices/appldriv.h"
+#include "machine/sonydriv.h"
+#include "machine/appldriv.h"
#include "imagedev/flopdrv.h"
#include "imagedev/cassette.h"
#include "sound/speaker.h"
diff --git a/src/mess/machine/apple3.c b/src/mess/machine/apple3.c
index 55ec3a6f90b..7843c322c14 100644
--- a/src/mess/machine/apple3.c
+++ b/src/mess/machine/apple3.c
@@ -20,7 +20,7 @@
#include "machine/6522via.h"
#include "machine/ay3600.h"
#include "machine/applefdc.h"
-#include "devices/appldriv.h"
+#include "machine/appldriv.h"
#include "machine/mos6551.h"
#include "machine/ram.h"
diff --git a/src/mess/machine/microdrv.c b/src/mess/machine/microdrv.c
new file mode 100644
index 00000000000..fb3e43fed72
--- /dev/null
+++ b/src/mess/machine/microdrv.c
@@ -0,0 +1,203 @@
+/*********************************************************************
+
+ microdrv.c
+
+ MESS interface to the Sinclair Microdrive image abstraction code
+
+*********************************************************************/
+
+#include "emu.h"
+#include "microdrv.h"
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+#define LOG 1
+
+#define MDV_SECTOR_COUNT 255
+#define MDV_SECTOR_LENGTH 686
+#define MDV_IMAGE_LENGTH (MDV_SECTOR_COUNT * MDV_SECTOR_LENGTH)
+
+#define MDV_PREAMBLE_LENGTH 12
+#define MDV_GAP_LENGTH 120
+
+#define MDV_OFFSET_HEADER_PREAMBLE 0
+#define MDV_OFFSET_HEADER MDV_OFFSET_HEADER_PREAMBLE + MDV_PREAMBLE_LENGTH
+#define MDV_OFFSET_DATA_PREAMBLE 28
+#define MDV_OFFSET_DATA MDV_OFFSET_DATA_PREAMBLE + MDV_PREAMBLE_LENGTH
+#define MDV_OFFSET_GAP 566
+
+#define MDV_BITRATE 120000 // invalid, from ZX microdrive
+
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+
+// device type definition
+const device_type MICRODRIVE = &device_creator<microdrive_image_device>;
+
+//-------------------------------------------------
+// microdrive_image_device - constructor
+//-------------------------------------------------
+
+microdrive_image_device::microdrive_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, MICRODRIVE, "Microdrive", tag, owner, clock),
+ device_image_interface(mconfig, *this)
+{
+}
+
+//-------------------------------------------------
+// microdrive_image_device - destructor
+//-------------------------------------------------
+
+microdrive_image_device::~microdrive_image_device()
+{
+}
+
+//-------------------------------------------------
+// device_config_complete - perform any
+// operations now that the configuration is
+// complete
+//-------------------------------------------------
+
+void microdrive_image_device::device_config_complete()
+{
+ // inherit a copy of the static data
+ const microdrive_interface *intf = reinterpret_cast<const microdrive_interface *>(static_config());
+ if (intf != NULL)
+ *static_cast<microdrive_interface *>(this) = *intf;
+
+ // or initialize to defaults if none provided
+ else
+ {
+ memset(&m_out_comms_out_cb, 0, sizeof(m_out_comms_out_cb));
+ memset(&m_interface, 0, sizeof(m_interface));
+ memset(&m_device_displayinfo, 0, sizeof(m_device_displayinfo));
+ }
+
+ // set brief and instance name
+ update_names();
+}
+
+
+void microdrive_image_device::device_start()
+{
+ // resolve callbacks
+ m_out_comms_out_func.resolve(m_out_comms_out_cb, *this);
+
+ // allocate track buffers
+ m_left = auto_alloc_array(machine(), UINT8, MDV_IMAGE_LENGTH / 2);
+ m_right = auto_alloc_array(machine(), UINT8, MDV_IMAGE_LENGTH / 2);
+
+ // allocate timers
+ m_bit_timer = timer_alloc();
+ m_bit_timer->adjust(attotime::zero, 0, attotime::from_hz(MDV_BITRATE));
+ m_bit_timer->enable(0);
+}
+
+bool microdrive_image_device::call_load()
+{
+ if (length() != MDV_IMAGE_LENGTH)
+ return IMAGE_INIT_FAIL;
+
+ for (int i = 0; i < MDV_IMAGE_LENGTH / 2; i++)
+ {
+ fread(m_left, 1);
+ fread(m_right, 1);
+ }
+
+ m_bit_offset = 0;
+ m_byte_offset = 0;
+
+ return IMAGE_INIT_PASS;
+}
+
+void microdrive_image_device::call_unload()
+{
+ memset(m_left, 0, MDV_IMAGE_LENGTH / 2);
+ memset(m_right, 0, MDV_IMAGE_LENGTH / 2);
+}
+
+void microdrive_image_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ m_bit_offset++;
+
+ if (m_bit_offset == 8)
+ {
+ m_bit_offset = 0;
+ m_byte_offset++;
+
+ if (m_byte_offset == MDV_IMAGE_LENGTH)
+ {
+ m_byte_offset = 0;
+ }
+ }
+}
+
+WRITE_LINE_MEMBER( microdrive_image_device::clk_w )
+{
+ if (LOG) logerror("Microdrive '%s' CLK: %u\n", tag(), state);
+ if (!m_clk && state)
+ {
+ m_comms_out = m_comms_in;
+ if (LOG) logerror("Microdrive '%s' COMMS OUT: %u\n", tag(), m_comms_out);
+ m_out_comms_out_func(m_comms_out);
+ m_bit_timer->enable(m_comms_out);
+ }
+ m_clk = state;
+}
+
+WRITE_LINE_MEMBER( microdrive_image_device::comms_in_w )
+{
+ if (LOG) logerror("Microdrive '%s' COMMS IN: %u\n", tag(), state);
+ m_comms_in = state;
+}
+
+WRITE_LINE_MEMBER( microdrive_image_device::erase_w )
+{
+ if (LOG) logerror("Microdrive '%s' ERASE: %u\n", tag(), state);
+ m_erase = state;
+}
+
+WRITE_LINE_MEMBER( microdrive_image_device::read_write_w )
+{
+ if (LOG) logerror("Microdrive '%s' READ/WRITE: %u\n", tag(), state);
+ m_read_write = state;
+}
+
+WRITE_LINE_MEMBER( microdrive_image_device::data1_w )
+{
+ if (m_comms_out && !m_read_write)
+ {
+ // TODO
+ }
+}
+
+WRITE_LINE_MEMBER( microdrive_image_device::data2_w )
+{
+ if (m_comms_out && !m_read_write)
+ {
+ // TODO
+ }
+}
+
+READ_LINE_MEMBER( microdrive_image_device::data1_r )
+{
+ int data = 0;
+ if (m_comms_out && m_read_write)
+ {
+ data = BIT(m_left[m_byte_offset], 7 - m_bit_offset);
+ }
+ return data;
+}
+
+READ_LINE_MEMBER( microdrive_image_device::data2_r )
+{
+ int data = 0;
+ if (m_comms_out && m_read_write)
+ {
+ data = BIT(m_right[m_byte_offset], 7 - m_bit_offset);
+ }
+ return data;
+}
diff --git a/src/mess/machine/microdrv.h b/src/mess/machine/microdrv.h
new file mode 100644
index 00000000000..65cd535f458
--- /dev/null
+++ b/src/mess/machine/microdrv.h
@@ -0,0 +1,103 @@
+/*********************************************************************
+
+ microdrv.h
+
+ MESS interface to the Sinclair Microdrive image abstraction code
+
+*********************************************************************/
+
+#pragma once
+
+#ifndef __MICRODRV__
+#define __MICRODRV__
+
+/***************************************************************************
+ TYPE DEFINITIONS
+***************************************************************************/
+// ======================> microdrive_interface
+
+struct microdrive_interface
+{
+ devcb_write_line m_out_comms_out_cb;
+ const char * m_interface;
+ device_image_display_info_func m_device_displayinfo;
+};
+
+// ======================> microdrive_image_device
+
+class microdrive_image_device : public device_t,
+ public microdrive_interface,
+ public device_image_interface
+{
+public:
+ // construction/destruction
+ microdrive_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+ virtual ~microdrive_image_device();
+
+ // image-level overrides
+ virtual bool call_load();
+ virtual void call_unload();
+ virtual void call_display_info() { if (m_device_displayinfo) m_device_displayinfo(*this); }
+ virtual bool call_softlist_load(char *swlist, char *swname, rom_entry *start_entry) { return load_software(swlist, swname, start_entry); }
+
+ virtual iodevice_t image_type() const { return IO_CASSETTE; }
+
+ virtual bool is_readable() const { return 1; }
+ virtual bool is_writeable() const { return 1; }
+ virtual bool is_creatable() const { return 0; }
+ virtual bool must_be_loaded() const { return 0; }
+ virtual bool is_reset_on_load() const { return 0; }
+ virtual const char *image_interface() const { return "ql_cass"; }
+ virtual const char *file_extensions() const { return "mdv"; }
+ virtual const option_guide *create_option_guide() const { return NULL; }
+
+ // specific implementation
+ DECLARE_WRITE_LINE_MEMBER( clk_w );
+ DECLARE_WRITE_LINE_MEMBER( comms_in_w );
+ DECLARE_WRITE_LINE_MEMBER( erase_w );
+ DECLARE_WRITE_LINE_MEMBER( read_write_w );
+ DECLARE_WRITE_LINE_MEMBER( data1_w );
+ DECLARE_WRITE_LINE_MEMBER( data2_w );
+ DECLARE_READ_LINE_MEMBER ( data1_r );
+ DECLARE_READ_LINE_MEMBER ( data2_r );
+protected:
+ // device-level overrides
+ virtual void device_config_complete();
+ virtual void device_start();
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
+private:
+ devcb_resolved_write_line m_out_comms_out_func;
+
+ int m_clk;
+ int m_comms_in;
+ int m_comms_out;
+ int m_erase;
+ int m_read_write;
+
+ UINT8 *m_left;
+ UINT8 *m_right;
+
+ int m_bit_offset;
+ int m_byte_offset;
+
+ emu_timer *m_bit_timer;
+};
+
+// device type definition
+extern const device_type MICRODRIVE;
+
+/***************************************************************************
+ DEVICE CONFIGURATION MACROS
+***************************************************************************/
+
+#define MDV_1 "mdv1"
+#define MDV_2 "mdv2"
+
+#define MCFG_MICRODRIVE_ADD(_tag, _config) \
+ MCFG_DEVICE_ADD(_tag, MICRODRIVE, 0) \
+ MCFG_DEVICE_CONFIG(_config)
+
+#define MICRODRIVE_CONFIG(_name) \
+ const microdrive_interface (_name) =
+
+#endif
diff --git a/src/mess/machine/sonydriv.c b/src/mess/machine/sonydriv.c
new file mode 100644
index 00000000000..8424473ada1
--- /dev/null
+++ b/src/mess/machine/sonydriv.c
@@ -0,0 +1,571 @@
+/*********************************************************************
+
+ sonydriv.c
+
+ Apple/Sony 3.5" floppy drive emulation (to be interfaced with iwm.c)
+
+ Nate Woods, Raphael Nabet, R. Belmont
+
+ This floppy drive was present in all variants of Lisa 2 (including Mac XL),
+ all Apple IIgs and IIc Plus machines, and in all Macintoshes in production
+ before 1988, when SWIM and SuperDrive were introduced.
+
+ There were three major variants :
+ - A single-sided 400k unit which was used on Lisa 2/Mac XL, and Macintosh
+ 128k/512k. This unit needs the computer to send the proper pulses to
+ control the drive motor rotation. It can be connected to all early
+ Macintosh (but not Mac Classic?) as an external unit.
+ - A double-sided 800k unit which was used on Macintosh Plus, 512ke, and
+ early SE and II*. This unit generates its own drive motor rotation
+ control signals. It can be connected to earlier (and later) Macintosh as
+ an external or internal unit. Some Lisa2/10 and Mac XL were upgraded to
+ use it, too, but a fdc ROM upgrade was required.
+ - A double-sided 1440k unit. This is fully back compatible with the 800k
+ drive, and adds 1440k MFM capability. This drive, called FDHD or
+ SuperDrive by Apple, came in automatic and manual-inject versions.
+
+ TODO :
+ * support for other image formats?
+ * should we support more than 2 floppy disk units? (Mac SE supported 3 drives)
+
+*********************************************************************/
+
+#include "emu.h"
+#include "machine/applefdc.h"
+#include "sonydriv.h"
+#include "formats/ap_dsk35.h"
+#include "imagedev/flopdrv.h"
+
+
+#ifdef MAME_DEBUG
+#define LOG_SONY 1
+#define LOG_SONY_EXTRA 0
+#else
+#define LOG_SONY 0
+#define LOG_SONY_EXTRA 0
+#endif
+
+/*
+ These lines are normally connected to the PHI0-PHI3 lines of the IWM
+*/
+enum
+{
+ SONY_CA0 = 0x01,
+ SONY_CA1 = 0x02,
+ SONY_CA2 = 0x04,
+ SONY_LSTRB = 0x08
+};
+
+/*
+ Structure that describes the state of a floppy drive, and the associated
+ disk image
+*/
+struct floppy_t
+{
+ device_t *img;
+ emu_file *fd;
+
+ unsigned int disk_switched : 1; /* disk-in-place status bit */
+ unsigned int head : 1; /* active head (-> floppy side) */
+ unsigned int step : 1;
+ int motor_on;
+
+ unsigned int loadedtrack_valid : 1; /* is data in track buffer valid ? */
+ unsigned int loadedtrack_dirty : 1; /* has data in track buffer been modified? */
+ size_t loadedtrack_size; /* size of loaded track */
+ size_t loadedtrack_pos; /* position within loaded track */
+ UINT8 *loadedtrack_data; /* pointer to track buffer */
+
+ int is_fdhd; /* is drive an FDHD? */
+ int is_400k; /* drive is single-sided, which means 400K */
+};
+
+struct sonydriv_t
+{
+ int lines; /* four lines SONY_CA0 - SONY_LSTRB */
+
+ int floppy_enable; /* whether a drive is enabled or not (-> enable line) */
+ int floppy_select; /* which drive is enabled */
+
+ int sel_line; /* one single line Is 0 or 1 */
+
+ unsigned int rotation_speed; /* drive rotation speed - ignored if ext_speed_control == 0 */
+ floppy_t floppy[2]; /* data for two floppy disk units */
+};
+static sonydriv_t sony;
+
+/* bit of code used in several places - I am unsure why it is here */
+static int sony_enable2(void)
+{
+ return (sony.lines & SONY_CA1) && (sony.lines & SONY_LSTRB);
+}
+
+static void load_track_data(device_t *device,int floppy_select)
+{
+ int track_size;
+ device_image_interface *cur_image;
+ UINT8 *new_data;
+ floppy_t *f;
+
+ f = &sony.floppy[floppy_select];
+ cur_image = dynamic_cast<device_image_interface *>(floppy_get_device_by_type(device->machine(), FLOPPY_TYPE_SONY, floppy_select));
+
+ floppy_image_legacy *fimg = flopimg_get_image(&cur_image->device());
+
+ if (!fimg)
+ {
+ return;
+ }
+
+ track_size = floppy_get_track_size(fimg, f->head, floppy_drive_get_current_track(&cur_image->device()));
+ if (f->loadedtrack_data) auto_free(device->machine(),f->loadedtrack_data);
+ new_data = auto_alloc_array(device->machine(),UINT8,track_size);
+ if (!new_data)
+ {
+ return;
+ }
+
+ floppy_drive_read_track_data_info_buffer(&cur_image->device(), f->head, new_data, &track_size);
+ f->loadedtrack_valid = 1;
+ f->loadedtrack_dirty = 0;
+ f->loadedtrack_size = track_size;
+ f->loadedtrack_data = new_data;
+ f->loadedtrack_pos = 0;
+}
+
+
+
+static void save_track_data(device_t *device, int floppy_select)
+{
+ device_image_interface *cur_image;
+ floppy_t *f;
+ int len;
+
+ f = &sony.floppy[floppy_select];
+ cur_image = dynamic_cast<device_image_interface *>(floppy_get_device_by_type(device->machine(), FLOPPY_TYPE_SONY, floppy_select));
+
+ if (f->loadedtrack_dirty)
+ {
+ len = f->loadedtrack_size;
+ floppy_drive_write_track_data_info_buffer(&cur_image->device(), f->head, f->loadedtrack_data, &len);
+ f->loadedtrack_dirty = 0;
+ }
+}
+
+
+
+UINT8 sony_read_data(device_t *device)
+{
+ UINT8 result = 0;
+ device_image_interface *cur_image;
+ floppy_t *f;
+
+ if (sony_enable2() || (! sony.floppy_enable))
+ return 0xFF; /* right ??? */
+
+ f = &sony.floppy[sony.floppy_select];
+ cur_image = dynamic_cast<device_image_interface *>(floppy_get_device_by_type(device->machine(), FLOPPY_TYPE_SONY, sony.floppy_select));
+ if (!cur_image->exists())
+ return 0xFF;
+
+ if (!f->loadedtrack_valid)
+ load_track_data(device, sony.floppy_select);
+
+ if (!f->loadedtrack_data)
+ {
+ return 0xFF;
+ }
+
+ result = sony_fetchtrack(f->loadedtrack_data, f->loadedtrack_size, &f->loadedtrack_pos);
+ return result;
+}
+
+
+
+void sony_write_data(device_t *device,UINT8 data)
+{
+ device_image_interface *cur_image;
+ floppy_t *f;
+
+ f = &sony.floppy[sony.floppy_select];
+ cur_image = dynamic_cast<device_image_interface *>(floppy_get_device_by_type(device->machine(), FLOPPY_TYPE_SONY, sony.floppy_select));
+ if (!cur_image->exists())
+ return;
+
+ if (!f->loadedtrack_valid)
+ load_track_data(device,sony.floppy_select);
+
+ if (!f->loadedtrack_data)
+ {
+ return;
+ }
+
+ sony_filltrack(f->loadedtrack_data, f->loadedtrack_size, &f->loadedtrack_pos, data);
+ f->loadedtrack_dirty = 1;
+}
+
+
+
+static int sony_rpm(floppy_t *f, device_t *cur_image)
+{
+ int result = 0;
+ device_image_interface *image =dynamic_cast<device_image_interface *>(cur_image);
+ /*
+ * The Mac floppy controller was interesting in that its speed was adjusted
+ * while the thing was running. On the tracks closer to the rim, it was
+ * sped up so that more data could be placed on it. Hence, this function
+ * has different results depending on the track number
+ *
+ * The Mac Plus (and probably the other Macs that use the IWM) verify that
+ * the speed of the floppy drive is within a certain range depending on
+ * what track the floppy is at. These RPM values are just guesses and are
+ * probably not fully accurate, but they are within the range that the Mac
+ * Plus expects and thus are probably in the right ballpark.
+ *
+ * Note - the timing values are the values returned by the Mac Plus routine
+ * that calculates the speed; I'm not sure what units they are in
+ */
+
+ if ((f->is_400k) && (sony.rotation_speed))
+ {
+ /* 400k unit : rotation speed should be controlled by computer */
+ result = sony.rotation_speed;
+ }
+ else
+ { /* 800k unit : rotation speed controlled by drive */
+#if 1 /* Mac Plus */
+ static const int speeds[] =
+ {
+ 500, /* 00-15: timing value 117B (acceptable range {1135-11E9} */
+ 550, /* 16-31: timing value ???? (acceptable range {12C6-138A} */
+ 600, /* 32-47: timing value ???? (acceptable range {14A7-157F} */
+ 675, /* 48-63: timing value ???? (acceptable range {16F2-17E2} */
+ 750 /* 64-79: timing value ???? (acceptable range {19D0-1ADE} */
+ };
+#else /* Lisa 2 */
+ /* 237 + 1.3*(256-reg) */
+ static const int speeds[] =
+ {
+ 293, /* 00-15: timing value ???? (acceptable range {0330-0336} */
+ 322, /* 16-31: timing value ???? (acceptable range {02ED-02F3} */
+ 351, /* 32-47: timing value ???? (acceptable range {02A7-02AD} */
+ 394, /* 48-63: timing value ???? (acceptable range {0262-0266} */
+ 439 /* 64-79: timing value ???? (acceptable range {021E-0222} */
+ };
+#endif
+ if (cur_image && image->exists())
+ result = speeds[floppy_drive_get_current_track(cur_image) / 16];
+ }
+ return result;
+}
+
+int sony_read_status(device_t *device)
+{
+ int result = 1;
+ int action;
+ floppy_t *f;
+ device_image_interface *cur_image;
+
+ action = ((sony.lines & (SONY_CA1 | SONY_CA0)) << 2) | (sony.sel_line << 1) | ((sony.lines & SONY_CA2) >> 2);
+
+ if (LOG_SONY_EXTRA)
+ {
+ printf("sony.status(): action=%x pc=0x%08x%s\n",
+ action, (int) device->machine().firstcpu->pc(), sony.floppy_enable ? "" : " (no drive enabled)");
+ }
+
+ if ((! sony_enable2()) && sony.floppy_enable)
+ {
+ f = &sony.floppy[sony.floppy_select];
+ cur_image = dynamic_cast<device_image_interface *>(floppy_get_device_by_type(device->machine(), FLOPPY_TYPE_SONY, sony.floppy_select));
+ if (!cur_image->exists())
+ cur_image = NULL;
+
+ switch(action) {
+ case 0x00: /* Step direction */
+ result = f->step;
+ break;
+ case 0x01: /* Lower head activate */
+ if (f->head != 0)
+ {
+ save_track_data(device,sony.floppy_select);
+ f->head = 0;
+ f->loadedtrack_valid = 0;
+ }
+ result = 0;
+ break;
+ case 0x02: /* Disk in place */
+ result = cur_image ? 0 : 1; /* 0=disk 1=nodisk */
+ break;
+ case 0x03: /* Upper head activate (not on 400k) */
+ if ((f->head != 1) && !(f->is_400k))
+ {
+ save_track_data(device,sony.floppy_select);
+ f->head = 1;
+ f->loadedtrack_valid = 0;
+ }
+ result = 0;
+ break;
+ case 0x04: /* Disk is stepping 0=stepping 1=not stepping*/
+ result = 1;
+ break;
+ case 0x05: /* Drive is SuperDrive: 0 = 400/800k, 1 = SuperDrive */
+ result = f->is_fdhd ? 1: 0;
+ break;
+ case 0x06: /* Disk is locked 0=locked 1=unlocked */
+ if (cur_image)
+ result = floppy_wpt_r(&cur_image->device());
+ else
+ result = 0;
+ break;
+ case 0x08: /* Motor on 0=on 1=off */
+ result = f->motor_on;
+ break;
+ case 0x09: /* Number of sides: 0=single sided, 1=double sided */
+ if (cur_image)
+ {
+ floppy_image_legacy *fimg = flopimg_get_image(&cur_image->device());
+ if (fimg)
+ {
+ result = floppy_get_heads_per_disk(fimg) - 1;
+ f->is_400k = result ? 0 : 1;
+ }
+ }
+ break;
+ case 0x0a: /* At track 0: 0=track zero 1=not track zero */
+ logerror("sony.status(): reading Track 0 pc=0x%08x\n", (int) device->machine().firstcpu->pc());
+ if (cur_image)
+ result = floppy_tk00_r(&cur_image->device());
+ else
+ result = 0;
+ break;
+ case 0x0b: /* Disk ready: 0=ready, 1=not ready */
+ result = 0;
+ break;
+ case 0x0c: /* Disk switched */
+ {
+ if (cur_image)
+ {
+ if (!floppy_dskchg_r(&cur_image->device()))
+ {
+ f->disk_switched = 1;
+ }
+ }
+ result = f->disk_switched;
+ }
+ break;
+ case 0x0d: /* Unknown */
+ /* I'm not sure what this one does, but the Mac Plus executes the
+ * following code that uses this status:
+ *
+ * 417E52: moveq #$d, D0 ; Status 0x0d
+ * 417E54: bsr 4185fe ; Query IWM status
+ * 417E58: bmi 417e82 ; If result=1, then skip
+ *
+ * This code is called in the Sony driver's open method, and
+ * _AddDrive does not get called if this status 0x0d returns 1.
+ * Hence, we are returning 0
+ */
+ result = 0;
+ break;
+ case 0x0e: /* Tachometer */
+ /* (time in seconds) / (60 sec/minute) * (rounds/minute) * (60 pulses) * (2 pulse phases) */
+ if (cur_image)
+ {
+ result = ((int) (device->machine().time().as_double() / 60.0 * sony_rpm(f, &cur_image->device()) * 60.0 * 2.0)) & 1;
+ }
+ break;
+ case 0x0f: /* 400k/800k: Drive installed: 0=drive connected, 1=drive not connected */
+ /* FDHD: Inserted disk density: 0=HD, 1=DD */
+ if (f->is_fdhd)
+ {
+ result = 1;
+ }
+ else
+ {
+ result = 0;
+ }
+ break;
+ default:
+ if (LOG_SONY)
+ logerror("sony_status(): unknown action\n");
+ break;
+ }
+ }
+
+ return result;
+}
+
+static void sony_doaction(device_t *device)
+{
+ int action;
+ floppy_t *f;
+ device_image_interface *cur_image;
+
+ action = ((sony.lines & (SONY_CA1 | SONY_CA0)) << 2) | ((sony.lines & SONY_CA2) >> 2) | (sony.sel_line << 1);
+
+ if (LOG_SONY)
+ {
+ logerror("sony_doaction(): action=%d pc=0x%08x%s\n",
+ action, (int) device->machine().firstcpu->pc(), (sony.floppy_enable) ? "" : " (MOTOR OFF)");
+ }
+
+ if (sony.floppy_enable)
+ {
+ f = &sony.floppy[sony.floppy_select];
+ cur_image = dynamic_cast<device_image_interface *>(floppy_get_device_by_type(device->machine(), FLOPPY_TYPE_SONY, sony.floppy_select));
+ if (!cur_image->exists())
+ cur_image = NULL;
+
+ switch(action)
+ {
+ case 0x00: /* Set step inward (higher tracks) */
+ f->step = 0;
+ break;
+ case 0x01: /* Set step outward (lower tracks) */
+ f->step = 1;
+ break;
+ case 0x03: /* Reset diskswitched */
+ f->disk_switched = 0;
+ break;
+ case 0x04: /* Step disk */
+ if (cur_image)
+ {
+ save_track_data(device,sony.floppy_select);
+ if (f->step)
+ floppy_drive_seek(&cur_image->device(), -1);
+ else
+ floppy_drive_seek(&cur_image->device(), +1);
+ f->loadedtrack_valid = 0;
+ }
+ break;
+ case 0x08: /* Turn motor on */
+ f->motor_on = CLEAR_LINE;
+ if (cur_image)
+ floppy_mon_w(&cur_image->device(), f->motor_on);
+ break;
+ case 0x09: /* Turn motor off */
+ f->motor_on = ASSERT_LINE;
+ if (cur_image)
+ floppy_mon_w(&cur_image->device(), f->motor_on);
+ break;
+ case 0x0d: /* Eject disk */
+ if (cur_image)
+ cur_image->unload();
+ break;
+ default:
+ if (LOG_SONY)
+ logerror("sony_doaction(): unknown action %d\n", action);
+ break;
+ }
+ }
+}
+
+void sony_set_lines(device_t *device,UINT8 lines)
+{
+ int old_sony_lines = sony.lines;
+
+ sony.lines = lines & 0x0F;
+
+ {
+ //int action = ((sony.lines & (SONY_CA1 | SONY_CA0)) << 2) | (sony.sel_line << 1) | ((sony.lines & SONY_CA2) >> 2);
+ //printf("sony.set_lines: %02x, action now %d\n", lines&0xf, action);
+ }
+
+ /* have we just set LSTRB ? */
+ if ((sony.lines & ~old_sony_lines) & SONY_LSTRB)
+ {
+ /* if so, write drive reg */
+ sony_doaction(device);
+ }
+
+ if (LOG_SONY_EXTRA)
+ logerror("sony.set_lines(): %d\n", lines);
+}
+
+void sony_set_enable_lines(device_t *device,int enable_mask)
+{
+ switch (enable_mask)
+ {
+ case 0:
+ default: /* well, we have to do something, right ? */
+ sony.floppy_enable = 0;
+ break;
+ case 1:
+ sony.floppy_enable = 1;
+ sony.floppy_select = 0;
+ break;
+ case 2:
+ sony.floppy_enable = 1;
+ sony.floppy_select = 1;
+ break;
+ }
+
+ if (LOG_SONY_EXTRA)
+ logerror("sony.set_enable_lines(): %d\n", enable_mask);
+}
+
+void sony_set_sel_line(device_t *device,int sel)
+{
+ sony.sel_line = sel ? 1 : 0;
+
+ {
+ //int action = ((sony.lines & (SONY_CA1 | SONY_CA0)) << 2) | (sony.sel_line << 1) | ((sony.lines & SONY_CA2) >> 2);
+ //printf("sony.set_sel_line: %d, action now %d\n", sony.sel_line, action);
+ }
+
+ if (LOG_SONY_EXTRA)
+ logerror("sony.set_sel_line(): %s line IWM_SEL\n", sony.sel_line ? "setting" : "clearing");
+}
+
+void sony_set_speed(int speed)
+{
+ sony.rotation_speed = speed;
+}
+
+// device type definition
+const device_type FLOPPY_SONY = &device_creator<sonydriv_floppy_image_device>;
+
+//-------------------------------------------------
+// sonydriv_floppy_image_device - constructor
+//-------------------------------------------------
+
+sonydriv_floppy_image_device::sonydriv_floppy_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : legacy_floppy_image_device(mconfig, FLOPPY_SONY, "Floppy Disk [Sony]", tag, owner, clock)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void sonydriv_floppy_image_device::device_start()
+{
+ legacy_floppy_image_device::device_start();
+ floppy_set_type(this, FLOPPY_TYPE_SONY);
+
+ sony.floppy[0].is_fdhd = 0;
+ sony.floppy[1].is_fdhd = 0;
+ sony.floppy[0].is_400k = 0;
+ sony.floppy[1].is_400k = 0;
+ sony.floppy[0].loadedtrack_data = NULL;
+ sony.floppy[1].loadedtrack_data = NULL;
+ sony.floppy[0].head = 0;
+ sony.floppy[1].head = 0;
+ sony.rotation_speed = 0;
+}
+
+void sonydriv_floppy_image_device::call_unload()
+{
+ int id;
+ device_t *fdc;
+
+ /* locate the FDC */
+ fdc = machine().device("fdc");
+
+ id = floppy_get_drive_by_type(this,FLOPPY_TYPE_SONY);
+ save_track_data(fdc, id);
+ memset(&sony.floppy[id], 0, sizeof(sony.floppy[id]));
+
+ legacy_floppy_image_device::call_unload();
+}
diff --git a/src/mess/machine/sonydriv.h b/src/mess/machine/sonydriv.h
new file mode 100644
index 00000000000..059a33238cd
--- /dev/null
+++ b/src/mess/machine/sonydriv.h
@@ -0,0 +1,70 @@
+/*********************************************************************
+
+ sonydriv.h
+
+ Apple/Sony 3.5" floppy drive emulation (to be interfaced with applefdc.c)
+
+*********************************************************************/
+
+#ifndef SONYDRIV_H
+#define SONYDRIV_H
+
+#include "image.h"
+#include "imagedev/flopdrv.h"
+
+#if 0
+enum
+{
+ SONY_FLOPPY_ALLOW400K = 0x0001,
+ SONY_FLOPPY_ALLOW800K = 0x0002,
+
+ SONY_FLOPPY_SUPPORT2IMG = 0x4000,
+ SONY_FLOPPY_EXT_SPEED_CONTROL = 0x8000 // means the speed is controlled by computer
+};
+#endif
+
+void sony_set_lines(device_t *device,UINT8 lines);
+void sony_set_enable_lines(device_t *device,int enable_mask);
+void sony_set_sel_line(device_t *device,int sel);
+
+void sony_set_speed(int speed);
+
+UINT8 sony_read_data(device_t *device);
+void sony_write_data(device_t *device,UINT8 data);
+int sony_read_status(device_t *device);
+
+class sonydriv_floppy_image_device : public legacy_floppy_image_device
+{
+public:
+ // construction/destruction
+ sonydriv_floppy_image_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ virtual void call_unload();
+protected:
+ virtual void device_start();
+};
+
+// device type definition
+extern const device_type FLOPPY_SONY;
+
+#define MCFG_LEGACY_FLOPPY_SONY_2_DRIVES_ADD(_config) \
+ MCFG_DEVICE_ADD(FLOPPY_0, FLOPPY_SONY, 0) \
+ MCFG_DEVICE_CONFIG(_config) \
+ MCFG_DEVICE_ADD(FLOPPY_1, FLOPPY_SONY, 0) \
+ MCFG_DEVICE_CONFIG(_config)
+
+#define MCFG_LEGACY_FLOPPY_SONY_2_DRIVES_ADDITIONAL_ADD(_config) \
+ MCFG_DEVICE_ADD(FLOPPY_2, FLOPPY_SONY, 0) \
+ MCFG_DEVICE_CONFIG(_config) \
+ MCFG_DEVICE_ADD(FLOPPY_3, FLOPPY_SONY, 0) \
+ MCFG_DEVICE_CONFIG(_config)
+
+#define MCFG_LEGACY_FLOPPY_SONY_2_DRIVES_MODIFY(_config) \
+ MCFG_DEVICE_MODIFY(FLOPPY_0) \
+ MCFG_DEVICE_CONFIG(_config) \
+ MCFG_DEVICE_MODIFY(FLOPPY_1) \
+ MCFG_DEVICE_CONFIG(_config)
+
+
+
+#endif /* SONYDRIV_H */
diff --git a/src/mess/machine/zx8302.c b/src/mess/machine/zx8302.c
index b77609d7cf2..1fab0e55310 100644
--- a/src/mess/machine/zx8302.c
+++ b/src/mess/machine/zx8302.c
@@ -21,7 +21,7 @@
#include "emu.h"
#include <time.h>
-#include "devices/microdrv.h"
+#include "machine/microdrv.h"
#include "zx8302.h"