diff options
author | 2012-08-21 10:41:19 +0000 | |
---|---|---|
committer | 2012-08-21 10:41:19 +0000 | |
commit | 7285b359d259b2ae0fdf85096571c386ec8c991a (patch) | |
tree | a027aff57f1a255f9ec6cfd3b68cabe4b6683998 /src/mess/machine/ieee488.c | |
parent | 67c425e90757876a6716b7867df30c0149912e74 (diff) |
Merge of MESS sources (no whatsnew)
Diffstat (limited to 'src/mess/machine/ieee488.c')
-rw-r--r-- | src/mess/machine/ieee488.c | 685 |
1 files changed, 685 insertions, 0 deletions
diff --git a/src/mess/machine/ieee488.c b/src/mess/machine/ieee488.c new file mode 100644 index 00000000000..a20c1e093fc --- /dev/null +++ b/src/mess/machine/ieee488.c @@ -0,0 +1,685 @@ +/********************************************************************** + + IEEE-488.1 General Purpose Interface Bus emulation + (aka HP-IB, GPIB, CBM IEEE) + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "ieee488.h" + + + +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** + +#define LOG 0 + + +static const char *const SIGNAL_NAME[] = { "EOI", "DAV", "NRFD", "NDAC", "IFC", "SRQ", "ATN", "REN" }; + + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type IEEE488 = &device_creator<ieee488_device>; +const device_type IEEE488_SLOT = &device_creator<ieee488_slot_device>; + + + +//************************************************************************** +// DEVICE INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_ieee488_interface - constructor +//------------------------------------------------- + +device_ieee488_interface::device_ieee488_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device) +{ +} + + +//------------------------------------------------- +// ~device_ieee488_interface - destructor +//------------------------------------------------- + +device_ieee488_interface::~device_ieee488_interface() +{ +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// ieee488_slot_device - constructor +//------------------------------------------------- + +ieee488_slot_device::ieee488_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, IEEE488_SLOT, "IEEE-488 slot", tag, owner, clock), + device_slot_interface(mconfig, *this) +{ +} + + +//------------------------------------------------- +// static_set_slot - +//------------------------------------------------- + +void ieee488_slot_device::static_set_slot(device_t &device, int address) +{ + ieee488_slot_device &ieee488_card = dynamic_cast<ieee488_slot_device &>(device); + ieee488_card.m_address = address; +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void ieee488_slot_device::device_start() +{ + ieee488_device* bus = owner()->subdevice<ieee488_device>(IEEE488_TAG); + device_ieee488_interface *dev = dynamic_cast<device_ieee488_interface *>(get_card_device()); + if (dev) bus->add_device(get_card_device(), m_address); +} + + + +//************************************************************************** +// DEVICE CONFIGURATION +//************************************************************************** + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void ieee488_device::device_config_complete() +{ + // inherit a copy of the static data + const ieee488_interface *intf = reinterpret_cast<const ieee488_interface *>(static_config()); + if (intf != NULL) + *static_cast<ieee488_interface *>(this) = *intf; + + // or initialize to defaults if none provided + else + { + memset(&m_out_eoi_cb, 0, sizeof(m_out_eoi_cb)); + memset(&m_out_dav_cb, 0, sizeof(m_out_dav_cb)); + memset(&m_out_nrfd_cb, 0, sizeof(m_out_nrfd_cb)); + memset(&m_out_ndac_cb, 0, sizeof(m_out_ndac_cb)); + memset(&m_out_ifc_cb, 0, sizeof(m_out_ifc_cb)); + memset(&m_out_srq_cb, 0, sizeof(m_out_srq_cb)); + memset(&m_out_atn_cb, 0, sizeof(m_out_atn_cb)); + memset(&m_out_ren_cb, 0, sizeof(m_out_ren_cb)); + } +} + + + +//************************************************************************** +// INLINE HELPERS +//************************************************************************** + +//------------------------------------------------- +// set_signal - +//------------------------------------------------- + +inline void ieee488_device::set_signal(device_t *device, int signal, int state) +{ + bool changed = false; + + if (device == this) + { + if (m_line[signal] != state) + { + if (LOG) logerror("%s IEEE488: '%s' %s %u\n", machine().describe_context(), tag(), SIGNAL_NAME[signal], state); + m_line[signal] = state; + changed = true; + } + } + else + { + daisy_entry *entry = m_device_list.first(); + + while (entry) + { + if (!strcmp(entry->m_device->tag(), device->tag())) + { + if (entry->m_line[signal] != state) + { + if (LOG) logerror("%s IEEE488: '%s' %s %u\n", machine().describe_context(), device->tag(), SIGNAL_NAME[signal], state); + entry->m_line[signal] = state; + changed = true; + } + } + + entry = entry->next(); + } + } + + if (changed) + { + switch (signal) + { + case EOI: m_out_eoi_func(state); break; + case DAV: m_out_dav_func(state); break; + case NRFD: m_out_nrfd_func(state); break; + case NDAC: m_out_ndac_func(state); break; + case IFC: m_out_ifc_func(state); break; + case SRQ: m_out_srq_func(state); break; + case ATN: m_out_atn_func(state); break; + case REN: m_out_ren_func(state); break; + } + + daisy_entry *entry = m_device_list.first(); + + while (entry) + { + switch (signal) + { + case EOI: + entry->m_interface->ieee488_eoi(state); + break; + + case DAV: + entry->m_interface->ieee488_dav(state); + break; + + case NRFD: + entry->m_interface->ieee488_nrfd(state); + break; + + case NDAC: + entry->m_interface->ieee488_ndac(state); + break; + + case IFC: + entry->m_interface->ieee488_ifc(state); + break; + + case SRQ: + entry->m_interface->ieee488_srq(state); + break; + + case ATN: + entry->m_interface->ieee488_atn(state); + break; + + case REN: + entry->m_interface->ieee488_ren(state); + break; + } + + entry = entry->next(); + } + + if (LOG) logerror("IEEE488: EOI %u DAV %u NRFD %u NDAC %u IFC %u SRQ %u ATN %u REN %u DIO %02x\n", + get_signal(EOI), get_signal(DAV), get_signal(NRFD), get_signal(NDAC), + get_signal(IFC), get_signal(SRQ), get_signal(ATN), get_signal(REN), get_data()); + } +} + + +//------------------------------------------------- +// get_signal - +//------------------------------------------------- + +inline int ieee488_device::get_signal(int signal) +{ + int state = m_line[signal]; + + if (state) + { + daisy_entry *entry = m_device_list.first(); + + while (entry) + { + if (!entry->m_line[signal]) + { + state = 0; + break; + } + + entry = entry->next(); + } + } + + return state; +} + + +//------------------------------------------------- +// set_data - +//------------------------------------------------- + +inline void ieee488_device::set_data(device_t *device, UINT8 data) +{ + if (device == this) + { + if (LOG) logerror("%s IEEE488: '%s' DIO %02x\n", machine().describe_context(), tag(), data); + + m_dio = data; + } + else + { + daisy_entry *entry = m_device_list.first(); + + while (entry) + { + if (!strcmp(entry->m_device->tag(), device->tag())) + { + if (entry->m_dio != data) + { + if (LOG) logerror("%s IEEE488: '%s' DIO %02x\n", machine().describe_context(), device->tag(), data); + entry->m_dio = data; + } + } + + entry = entry->next(); + } + } +} + + +//------------------------------------------------- +// get_data - +//------------------------------------------------- + +inline UINT8 ieee488_device::get_data() +{ + UINT8 data = m_dio; + + daisy_entry *entry = m_device_list.first(); + + while (entry) + { + data &= entry->m_dio; + + entry = entry->next(); + } + + return data; +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// ieee488_device - constructor +//------------------------------------------------- + +ieee488_device::ieee488_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, IEEE488, "IEEE488 bus", tag, owner, clock), + m_dio(0xff) +{ + for (int i = 0; i < SIGNAL_COUNT; i++) + { + m_line[i] = 1; + } +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void ieee488_device::device_start() +{ + // resolve callbacks + m_out_eoi_func.resolve(m_out_eoi_cb, *this); + m_out_dav_func.resolve(m_out_dav_cb, *this); + m_out_nrfd_func.resolve(m_out_nrfd_cb, *this); + m_out_ndac_func.resolve(m_out_ndac_cb, *this); + m_out_ifc_func.resolve(m_out_ifc_cb, *this); + m_out_srq_func.resolve(m_out_srq_cb, *this); + m_out_atn_func.resolve(m_out_atn_cb, *this); + m_out_ren_func.resolve(m_out_ren_cb, *this); +} + +//------------------------------------------------- +// device_stop - device-specific stop +//------------------------------------------------- + +void ieee488_device::device_stop() +{ + m_device_list.reset(); +} + + +//------------------------------------------------- +// add_device - +//------------------------------------------------- + +void ieee488_device::add_device(device_t *target, int address) +{ + daisy_entry *entry = auto_alloc(machine(), daisy_entry(target)); + + entry->m_interface->m_bus = this; + entry->m_interface->m_address = address; + + m_device_list.append(*entry); +} + + +//------------------------------------------------- +// daisy_entry - constructor +//------------------------------------------------- + +ieee488_device::daisy_entry::daisy_entry(device_t *device) + : m_next(NULL), + m_device(device), + m_interface(NULL), + m_dio(0xff) +{ + for (int i = 0; i < SIGNAL_COUNT; i++) + { + m_line[i] = 1; + } + + device->interface(m_interface); +} + + +//------------------------------------------------- +// dio_r - +//------------------------------------------------- + +UINT8 ieee488_device::dio_r() +{ + return get_data(); +} + + +//------------------------------------------------- +// dio_r - +//------------------------------------------------- + +READ8_MEMBER( ieee488_device::dio_r ) +{ + return get_data(); +} + + +//------------------------------------------------- +// eoi_r - +//------------------------------------------------- + +READ_LINE_MEMBER( ieee488_device::eoi_r ) +{ + return get_signal(EOI); +} + + +//------------------------------------------------- +// dav_r - +//------------------------------------------------- + +READ_LINE_MEMBER( ieee488_device::dav_r ) +{ + return get_signal(DAV); +} + + +//------------------------------------------------- +// nrfd_r - +//------------------------------------------------- + +READ_LINE_MEMBER( ieee488_device::nrfd_r ) +{ + return get_signal(NRFD); +} + + +//------------------------------------------------- +// ndac_r - +//------------------------------------------------- + +READ_LINE_MEMBER( ieee488_device::ndac_r ) +{ + return get_signal(NDAC); +} + + +//------------------------------------------------- +// ifc_r - +//------------------------------------------------- + +READ_LINE_MEMBER( ieee488_device::ifc_r ) +{ + return get_signal(IFC); +} + + +//------------------------------------------------- +// srq_r - +//------------------------------------------------- + +READ_LINE_MEMBER( ieee488_device::srq_r ) +{ + return get_signal(SRQ); +} + + +//------------------------------------------------- +// atn_r - +//------------------------------------------------- + +READ_LINE_MEMBER( ieee488_device::atn_r ) +{ + return get_signal(ATN); +} + + +//------------------------------------------------- +// ren_r - +//------------------------------------------------- + +READ_LINE_MEMBER( ieee488_device::ren_r ) +{ + return get_signal(REN); +} + + +//------------------------------------------------- +// dio_w - +//------------------------------------------------- + +void ieee488_device::dio_w(UINT8 data) +{ + return set_data(this, data); +} + + +//------------------------------------------------- +// dio_w - +//------------------------------------------------- + +WRITE8_MEMBER( ieee488_device::dio_w ) +{ + return set_data(this, data); +} + + +//------------------------------------------------- +// eoi_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( ieee488_device::eoi_w ) +{ + set_signal(this, EOI, state); +} + + +//------------------------------------------------- +// dav_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( ieee488_device::dav_w ) +{ + set_signal(this, DAV, state); +} + + +//------------------------------------------------- +// nrfd_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( ieee488_device::nrfd_w ) +{ + set_signal(this, NRFD, state); +} + + +//------------------------------------------------- +// ndac_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( ieee488_device::ndac_w ) +{ + set_signal(this, NDAC, state); +} + + +//------------------------------------------------- +// ifc_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( ieee488_device::ifc_w ) +{ + set_signal(this, IFC, state); +} + + +//------------------------------------------------- +// srq_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( ieee488_device::srq_w ) +{ + set_signal(this, SRQ, state); +} + + +//------------------------------------------------- +// atn_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( ieee488_device::atn_w ) +{ + set_signal(this, ATN, state); +} + + +//------------------------------------------------- +// ren_w - +//------------------------------------------------- + +WRITE_LINE_MEMBER( ieee488_device::ren_w ) +{ + set_signal(this, REN, state); +} + + +//------------------------------------------------- +// dio_w - +//------------------------------------------------- + +void ieee488_device::dio_w(device_t *device, UINT8 data) +{ + return set_data(device, data); +} + + +//------------------------------------------------- +// eoi_w - +//------------------------------------------------- + +void ieee488_device::eoi_w(device_t *device, int state) +{ + set_signal(device, EOI, state); +} + + +//------------------------------------------------- +// dav_w - +//------------------------------------------------- + +void ieee488_device::dav_w(device_t *device, int state) +{ + set_signal(device, DAV, state); +} + + +//------------------------------------------------- +// nrfd_w - +//------------------------------------------------- + +void ieee488_device::nrfd_w(device_t *device, int state) +{ + set_signal(device, NRFD, state); +} + + +//------------------------------------------------- +// ndac_w - +//------------------------------------------------- + +void ieee488_device::ndac_w(device_t *device, int state) +{ + set_signal(device, NDAC, state); +} + + +//------------------------------------------------- +// ifc_w - +//------------------------------------------------- + +void ieee488_device::ifc_w(device_t *device, int state) +{ + set_signal(device, IFC, state); +} + + +//------------------------------------------------- +// srq_w - +//------------------------------------------------- + +void ieee488_device::srq_w(device_t *device, int state) +{ + set_signal(device, SRQ, state); +} + + +//------------------------------------------------- +// atn_w - +//------------------------------------------------- + +void ieee488_device::atn_w(device_t *device, int state) +{ + set_signal(device, ATN, state); +} + + +//------------------------------------------------- +// ren_w - +//------------------------------------------------- + +void ieee488_device::ren_w(device_t *device, int state) +{ + set_signal(device, REN, state); +} |