diff options
Diffstat (limited to 'src/emu/cpu/z80/z80daisy.c')
-rw-r--r-- | src/emu/cpu/z80/z80daisy.c | 184 |
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); +} |