summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/z80/z80daisy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/z80/z80daisy.c')
-rw-r--r--src/emu/cpu/z80/z80daisy.c184
1 files changed, 134 insertions, 50 deletions
diff --git a/src/emu/cpu/z80/z80daisy.c b/src/emu/cpu/z80/z80daisy.c
index 06cab99dd04..185a47bc829 100644
--- a/src/emu/cpu/z80/z80daisy.c
+++ b/src/emu/cpu/z80/z80daisy.c
@@ -10,99 +10,183 @@
#include "z80daisy.h"
-struct _z80_daisy_state
+//**************************************************************************
+// DEVICE CONFIG Z80 DAISY INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_config_z80daisy_interface - constructor
+//-------------------------------------------------
+
+device_config_z80daisy_interface::device_config_z80daisy_interface(const machine_config &mconfig, device_config &devconfig)
+ : device_config_interface(mconfig, devconfig)
+{
+}
+
+
+//-------------------------------------------------
+// ~device_config_z80daisy_interface - destructor
+//-------------------------------------------------
+
+device_config_z80daisy_interface::~device_config_z80daisy_interface()
+{
+}
+
+
+
+//**************************************************************************
+// DEVICE Z80 DAISY INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_z80daisy_interface - constructor
+//-------------------------------------------------
+
+device_z80daisy_interface::device_z80daisy_interface(running_machine &machine, const device_config &config, device_t &device)
+ : device_interface(machine, config, device),
+ m_z80daisy_config(dynamic_cast<const device_config_z80daisy_interface &>(config))
{
- z80_daisy_state * next; /* next device */
- running_device * device; /* associated device */
- z80_daisy_irq_state irq_state; /* IRQ state callback */
- z80_daisy_irq_ack irq_ack; /* IRQ ack callback */
- z80_daisy_irq_reti irq_reti; /* IRQ reti callback */
-};
+}
+
+//-------------------------------------------------
+// ~device_z80daisy_interface - destructor
+//-------------------------------------------------
-z80_daisy_state *z80daisy_init(running_device *cpudevice, const z80_daisy_chain *daisy)
+device_z80daisy_interface::~device_z80daisy_interface()
{
- astring tempstring;
- z80_daisy_state *head = NULL;
- z80_daisy_state **tailptr = &head;
+}
- /* create a linked list of devices */
+
+
+//**************************************************************************
+// Z80 DAISY CHAIN
+//**************************************************************************
+
+//-------------------------------------------------
+// z80_daisy_chain - constructor
+//-------------------------------------------------
+
+z80_daisy_chain::z80_daisy_chain()
+ : m_daisy_list(NULL)
+{
+}
+
+
+//-------------------------------------------------
+// init - allocate the daisy chain based on the
+// provided configuration
+//-------------------------------------------------
+
+void z80_daisy_chain::init(device_t *cpudevice, const z80_daisy_config *daisy)
+{
+ // create a linked list of devices
+ daisy_entry **tailptr = &m_daisy_list;
for ( ; daisy->devname != NULL; daisy++)
{
- *tailptr = auto_alloc(cpudevice->machine, z80_daisy_state);
- (*tailptr)->next = NULL;
- (*tailptr)->device = cpudevice->machine->device(cpudevice->siblingtag(tempstring, daisy->devname));
- if ((*tailptr)->device == NULL)
+ // find the device
+ device_t *target = cpudevice->siblingdevice(daisy->devname);
+ if (target == NULL)
fatalerror("Unable to locate device '%s'", daisy->devname);
- (*tailptr)->irq_state = (z80_daisy_irq_state)(*tailptr)->device->get_config_fct(DEVINFO_FCT_IRQ_STATE);
- (*tailptr)->irq_ack = (z80_daisy_irq_ack)(*tailptr)->device->get_config_fct(DEVINFO_FCT_IRQ_ACK);
- (*tailptr)->irq_reti = (z80_daisy_irq_reti)(*tailptr)->device->get_config_fct(DEVINFO_FCT_IRQ_RETI);
- tailptr = &(*tailptr)->next;
+
+ // make sure it has an interface
+ device_z80daisy_interface *intf;
+ if (!target->interface(intf))
+ fatalerror("Device '%s' does not implement the z80daisy interface!", daisy->devname);
+
+ // append to the end
+ *tailptr = auto_alloc(cpudevice->machine, daisy_entry(target));
+ tailptr = &(*tailptr)->m_next;
}
-
- return head;
}
-void z80daisy_reset(z80_daisy_state *daisy)
+//-------------------------------------------------
+// reset - send a reset signal to all chained
+// devices
+//-------------------------------------------------
+
+void z80_daisy_chain::reset()
{
- /* loop over all devices and call their reset function */
- for ( ; daisy != NULL; daisy = daisy->next)
- daisy->device->reset();
+ // loop over all devices and call their reset function
+ for (daisy_entry *daisy = m_daisy_list; daisy != NULL; daisy = daisy->m_next)
+ daisy->m_device->reset();
}
-int z80daisy_update_irq_state(z80_daisy_state *daisy)
+//-------------------------------------------------
+// update_irq_state - update the IRQ state and
+// return assert/clear based on the state
+//-------------------------------------------------
+
+int z80_daisy_chain::update_irq_state()
{
- /* loop over all devices; dev[0] is highest priority */
- for ( ; daisy != NULL; daisy = daisy->next)
+ // loop over all devices; dev[0] is highest priority
+ for (daisy_entry *daisy = m_daisy_list; daisy != NULL; daisy = daisy->m_next)
{
- int state = (*daisy->irq_state)(daisy->device);
-
- /* if this device is asserting the INT line, that's the one we want */
+ // if this device is asserting the INT line, that's the one we want
+ int state = daisy->m_interface->z80daisy_irq_state();
if (state & Z80_DAISY_INT)
return ASSERT_LINE;
- /* if this device is asserting the IEO line, it blocks everyone else */
+ // if this device is asserting the IEO line, it blocks everyone else
if (state & Z80_DAISY_IEO)
return CLEAR_LINE;
}
-
return CLEAR_LINE;
}
-int z80daisy_call_ack_device(z80_daisy_state *daisy)
+//-------------------------------------------------
+// call_ack_device - acknowledge an interrupt
+// from a chained device and return the vector
+//-------------------------------------------------
+
+int z80_daisy_chain::call_ack_device()
{
- /* loop over all devices; dev[0] is the highest priority */
- for ( ; daisy != NULL; daisy = daisy->next)
+ // loop over all devices; dev[0] is the highest priority
+ for (daisy_entry *daisy = m_daisy_list; daisy != NULL; daisy = daisy->m_next)
{
- int state = (*daisy->irq_state)(daisy->device);
-
- /* if this device is asserting the INT line, that's the one we want */
+ // if this device is asserting the INT line, that's the one we want
+ int state = daisy->m_interface->z80daisy_irq_state();
if (state & Z80_DAISY_INT)
- return (*daisy->irq_ack)(daisy->device);
+ return daisy->m_interface->z80daisy_irq_ack();
}
-
logerror("z80daisy_call_ack_device: failed to find an device to ack!\n");
return 0;
}
-void z80daisy_call_reti_device(z80_daisy_state *daisy)
+//-------------------------------------------------
+// call_reti_device - signal a RETI operator to
+// the chain
+//-------------------------------------------------
+
+void z80_daisy_chain::call_reti_device()
{
- /* loop over all devices; dev[0] is the highest priority */
- for ( ; daisy != NULL; daisy = daisy->next)
+ // loop over all devices; dev[0] is the highest priority
+ for (daisy_entry *daisy = m_daisy_list; daisy != NULL; daisy = daisy->m_next)
{
- int state = (*daisy->irq_state)(daisy->device);
-
- /* if this device is asserting the IEO line, that's the one we want */
+ // if this device is asserting the IEO line, that's the one we want
+ int state = daisy->m_interface->z80daisy_irq_state();
if (state & Z80_DAISY_IEO)
{
- (*daisy->irq_reti)(daisy->device);
+ daisy->m_interface->z80daisy_irq_reti();
return;
}
}
-
logerror("z80daisy_call_reti_device: failed to find an device to reti!\n");
}
+
+
+//-------------------------------------------------
+// daisy_entry - constructor
+//-------------------------------------------------
+
+z80_daisy_chain::daisy_entry::daisy_entry(device_t *device)
+ : m_next(NULL),
+ m_device(device),
+ m_interface(NULL)
+{
+ device->interface(m_interface);
+}