From 22aabcf0d73bc79c79ab9cddd89fdc5aeb70febf Mon Sep 17 00:00:00 2001 From: Miodrag Milanovic Date: Thu, 11 Oct 2012 13:45:30 +0000 Subject: [PATCH] device callback support for 32bit and 64bit handlers (no whatsnew) --- src/emu/devcb.c | 270 ++++++++++++++++++++++++++++++++++++++++++++++ src/emu/devcb.h | 277 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 545 insertions(+), 2 deletions(-) diff --git a/src/emu/devcb.c b/src/emu/devcb.c index 1a27454d59c..e9ad0d87210 100644 --- a/src/emu/devcb.c +++ b/src/emu/devcb.c @@ -51,6 +51,10 @@ UINT8 devcb_resolved_read8::s_null; UINT8 devcb_resolved_write8::s_null; UINT8 devcb_resolved_read16::s_null; UINT8 devcb_resolved_write16::s_null; +UINT8 devcb_resolved_read32::s_null; +UINT8 devcb_resolved_write32::s_null; +UINT8 devcb_resolved_read64::s_null; +UINT8 devcb_resolved_write64::s_null; @@ -921,3 +925,269 @@ void devcb_resolved_write16::to_input(offs_t offset, UINT16 data, UINT16 mask) { m_object.execute->set_input_line(m_helper.input_line, (data & 1) ? ASSERT_LINE : CLEAR_LINE); } + +//************************************************************************** +// DEVCB RESOLVED WRITE32 +//************************************************************************** + +//------------------------------------------------- +// devcb_resolved_write32 - empty constructor +//------------------------------------------------- + +devcb_resolved_write32::devcb_resolved_write32() +{ + m_object.port = NULL; + m_helper.write_line = NULL; +} + + +//------------------------------------------------- +// resolve - resolve to a delegate from a static +// structure definition +//------------------------------------------------- + +void devcb_resolved_write32::resolve(const devcb_write32 &desc, device_t &device) +{ + switch (desc.type) + { + default: + case DEVCB_TYPE_NULL: + m_helper.null_indicator = &s_null; + *static_cast(this) = devcb_write32_delegate(&devcb_resolved_write32::to_null, "(null)", this); + break; + + case DEVCB_TYPE_IOPORT: + m_object.port = devcb_resolver::resolve_port(desc.tag, device); + *static_cast(this) = devcb_write32_delegate(&devcb_resolved_write32::to_port, desc.tag, this); + break; + + case DEVCB_TYPE_DEVICE: + m_object.device = devcb_resolver::resolve_device(desc.index, desc.tag, device); + if (desc.writedevice != NULL) + { + m_helper.write32_device = desc.writedevice; + *static_cast(this) = devcb_write32_delegate(&devcb_resolved_write32::to_write32, desc.name, this); + } + else + { + m_helper.write_line = desc.writeline; + *static_cast(this) = devcb_write32_delegate(&devcb_resolved_write32::to_writeline, desc.name, this); + } + break; + + case DEVCB_TYPE_LEGACY_SPACE: + m_object.space = &devcb_resolver::resolve_space(desc.index, desc.tag, device); + *static_cast(this) = devcb_write32_delegate(desc.writespace, desc.name, m_object.space); + break; + + case DEVCB_TYPE_INPUT_LINE: + m_object.execute = devcb_resolver::resolve_execute_interface(desc.tag, device); + m_helper.input_line = desc.index; + *static_cast(this) = devcb_write32_delegate(&devcb_resolved_write32::to_input, desc.tag, this); + break; + + case DEVCB_TYPE_UNMAP: + m_helper.null_indicator = &s_null; + m_object.device = &device; + *static_cast(this) = devcb_write32_delegate(&devcb_resolved_write32::to_unmap, "unmap", this); + break; + } +} + + +//------------------------------------------------- +// to_null - helper to handle a NULL write +//------------------------------------------------- + +void devcb_resolved_write32::to_null(offs_t offset, UINT32 data, UINT32 mask) +{ +} + + +//------------------------------------------------- +// to_unmap - helper to handle a unmap write +//------------------------------------------------- + +void devcb_resolved_write32::to_unmap(offs_t offset, UINT32 data, UINT32 mask) +{ + logerror("%s: unmapped devcb write %s & %s\n", + m_object.device->tag(), + core_i64_format(data, 2 * sizeof(UINT32),false), + core_i64_format(mask, 2 * sizeof(UINT32),false)); +} + +//------------------------------------------------- +// to_port - helper to convert to an I/O port +// value from a line value +//------------------------------------------------- + +void devcb_resolved_write32::to_port(offs_t offset, UINT32 data, UINT32 mask) +{ + m_object.port->write(data, mask); +} + + +//------------------------------------------------- +// to_write32 - helper to convert to a 32-bit +// memory read value from a line value +//------------------------------------------------- + +void devcb_resolved_write32::to_write32(offs_t offset, UINT32 data, UINT32 mask) +{ + (*m_helper.write32_device)(m_object.device, m_object.device->machine().driver_data()->generic_space(), offset, data, mask); +} + + +//------------------------------------------------- +// to_write32 - helper to convert to a 32-bit +// memory read value from a line value +//------------------------------------------------- + +void devcb_resolved_write32::to_writeline(offs_t offset, UINT32 data, UINT32 mask) +{ + (*m_helper.write_line)(m_object.device, (data & 1) ? ASSERT_LINE : CLEAR_LINE); +} + + +//------------------------------------------------- +// to_input - helper to convert to a device input +// value from a line value +//------------------------------------------------- + +void devcb_resolved_write32::to_input(offs_t offset, UINT32 data, UINT32 mask) +{ + m_object.execute->set_input_line(m_helper.input_line, (data & 1) ? ASSERT_LINE : CLEAR_LINE); +} + +//************************************************************************** +// DEVCB RESOLVED WRITE64 +//************************************************************************** + +//------------------------------------------------- +// devcb_resolved_write64 - empty constructor +//------------------------------------------------- + +devcb_resolved_write64::devcb_resolved_write64() +{ + m_object.port = NULL; + m_helper.write_line = NULL; +} + + +//------------------------------------------------- +// resolve - resolve to a delegate from a static +// structure definition +//------------------------------------------------- + +void devcb_resolved_write64::resolve(const devcb_write64 &desc, device_t &device) +{ + switch (desc.type) + { + default: + case DEVCB_TYPE_NULL: + m_helper.null_indicator = &s_null; + *static_cast(this) = devcb_write64_delegate(&devcb_resolved_write64::to_null, "(null)", this); + break; + + case DEVCB_TYPE_IOPORT: + m_object.port = devcb_resolver::resolve_port(desc.tag, device); + *static_cast(this) = devcb_write64_delegate(&devcb_resolved_write64::to_port, desc.tag, this); + break; + + case DEVCB_TYPE_DEVICE: + m_object.device = devcb_resolver::resolve_device(desc.index, desc.tag, device); + if (desc.writedevice != NULL) + { + m_helper.write64_device = desc.writedevice; + *static_cast(this) = devcb_write64_delegate(&devcb_resolved_write64::to_write64, desc.name, this); + } + else + { + m_helper.write_line = desc.writeline; + *static_cast(this) = devcb_write64_delegate(&devcb_resolved_write64::to_writeline, desc.name, this); + } + break; + + case DEVCB_TYPE_LEGACY_SPACE: + m_object.space = &devcb_resolver::resolve_space(desc.index, desc.tag, device); + *static_cast(this) = devcb_write64_delegate(desc.writespace, desc.name, m_object.space); + break; + + case DEVCB_TYPE_INPUT_LINE: + m_object.execute = devcb_resolver::resolve_execute_interface(desc.tag, device); + m_helper.input_line = desc.index; + *static_cast(this) = devcb_write64_delegate(&devcb_resolved_write64::to_input, desc.tag, this); + break; + + case DEVCB_TYPE_UNMAP: + m_helper.null_indicator = &s_null; + m_object.device = &device; + *static_cast(this) = devcb_write64_delegate(&devcb_resolved_write64::to_unmap, "unmap", this); + break; + } +} + + +//------------------------------------------------- +// to_null - helper to handle a NULL write +//------------------------------------------------- + +void devcb_resolved_write64::to_null(offs_t offset, UINT64 data, UINT64 mask) +{ +} + + +//------------------------------------------------- +// to_unmap - helper to handle a unmap write +//------------------------------------------------- + +void devcb_resolved_write64::to_unmap(offs_t offset, UINT64 data, UINT64 mask) +{ + logerror("%s: unmapped devcb write %s & %s\n", + m_object.device->tag(), + core_i64_format(data, 2 * sizeof(UINT64),false), + core_i64_format(mask, 2 * sizeof(UINT64),false)); +} + +//------------------------------------------------- +// to_port - helper to convert to an I/O port +// value from a line value +//------------------------------------------------- + +void devcb_resolved_write64::to_port(offs_t offset, UINT64 data, UINT64 mask) +{ + m_object.port->write(data, mask); +} + + +//------------------------------------------------- +// to_write64 - helper to convert to a 64-bit +// memory read value from a line value +//------------------------------------------------- + +void devcb_resolved_write64::to_write64(offs_t offset, UINT64 data, UINT64 mask) +{ + (*m_helper.write64_device)(m_object.device, m_object.device->machine().driver_data()->generic_space(), offset, data, mask); +} + + +//------------------------------------------------- +// to_write64 - helper to convert to a 64-bit +// memory read value from a line value +//------------------------------------------------- + +void devcb_resolved_write64::to_writeline(offs_t offset, UINT64 data, UINT64 mask) +{ + (*m_helper.write_line)(m_object.device, (data & 1) ? ASSERT_LINE : CLEAR_LINE); +} + + +//------------------------------------------------- +// to_input - helper to convert to a device input +// value from a line value +//------------------------------------------------- + +void devcb_resolved_write64::to_input(offs_t offset, UINT64 data, UINT64 mask) +{ + m_object.execute->set_input_line(m_helper.input_line, (data & 1) ? ASSERT_LINE : CLEAR_LINE); +} diff --git a/src/emu/devcb.h b/src/emu/devcb.h index 03d4f33a256..617f02814a9 100644 --- a/src/emu/devcb.h +++ b/src/emu/devcb.h @@ -50,6 +50,10 @@ write8_device_func: (device, offset, data) read16_device_func: (device, offset) write16_device_func: (device, offset, data) + read32_device_func: (device, offset) + write32_device_func: (device, offset, data) + read64_device_func: (device, offset) + write64_device_func: (device, offset, data) The adapted callback types supported are: @@ -65,6 +69,14 @@ write16_device_func: (device, offset, data) read16_space_func: (space, offset) write16_space_func: (space, offset, data) + read32_device_func: (device, offset) + write32_device_func: (device, offset, data) + read32_space_func: (space, offset) + write32_space_func: (space, offset, data) + read64_device_func: (device, offset) + write64_device_func: (device, offset, data) + read64_space_func: (space, offset) + write64_space_func: (space, offset, data) ***************************************************************************/ @@ -127,6 +139,22 @@ UINT16 devcb_stub16(device_t *device, address_space &space, offs_t offset, UINT1 return (target->*_Function)(space, offset, mem_mask); } +// static template for a read32 stub function that calls through a given READ32_MEMBER +template +UINT32 devcb_stub32(device_t *device, address_space &space, offs_t offset, UINT32 mem_mask) +{ + _Class *target = downcast<_Class *>(device); + return (target->*_Function)(space, offset, mem_mask); +} + +// static template for a read64 stub function that calls through a given READ64_MEMBER +template +UINT64 devcb_stub64(device_t *device, address_space &space, offs_t offset, UINT64 mem_mask) +{ + _Class *target = downcast<_Class *>(device); + return (target->*_Function)(space, offset, mem_mask); +} + // static template for a write_line stub function that calls through a given WRITE_LINE_MEMBER template void devcb_line_stub(device_t *device, int state) @@ -151,6 +179,22 @@ void devcb_stub16(device_t *device, address_space &space, offs_t offset, UINT16 (target->*_Function)(space, offset, data, mem_mask); } +// static template for a write32 stub function that calls through a given WRITE32_MEMBER +template +void devcb_stub32(device_t *device, address_space &space, offs_t offset, UINT32 data, UINT32 mem_mask) +{ + _Class *target = downcast<_Class *>(device); + (target->*_Function)(space, offset, data, mem_mask); +} + +// static template for a write64 stub function that calls through a given WRITE64_MEMBER +template +void devcb_stub64(device_t *device, address_space &space, offs_t offset, UINT64 data, UINT64 mem_mask) +{ + _Class *target = downcast<_Class *>(device); + (target->*_Function)(space, offset, data, mem_mask); +} + #define DEVCB_NULL { DEVCB_TYPE_NULL } // standard line or read/write handlers with the calling device passed @@ -159,11 +203,15 @@ void devcb_stub16(device_t *device, address_space &space, offs_t offset, UINT16 #define DEVCB_HANDLER(func) { DEVCB_TYPE_DEVICE, 0, "", #func, NULL, func, NULL } #define DEVCB_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, 0, "", #cls "::" #memb, NULL, &devcb_stub, NULL } #define DEVCB_MEMBER16(cls,memb) { DEVCB_TYPE_DEVICE, 0, "", #cls "::" #memb, NULL, &devcb_stub16, NULL } +#define DEVCB_MEMBER32(cls,memb) { DEVCB_TYPE_DEVICE, 0, "", #cls "::" #memb, NULL, &devcb_stub32, NULL } +#define DEVCB_MEMBER64(cls,memb) { DEVCB_TYPE_DEVICE, 0, "", #cls "::" #memb, NULL, &devcb_stub64, NULL } // line or read/write handlers for the driver device #define DEVCB_DRIVER_LINE_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, &devcb_line_stub, NULL, NULL } #define DEVCB_DRIVER_MEMBER(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, NULL, &devcb_stub, NULL } #define DEVCB_DRIVER_MEMBER16(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, NULL, &devcb_stub16, NULL } +#define DEVCB_DRIVER_MEMBER32(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, NULL, &devcb_stub32, NULL } +#define DEVCB_DRIVER_MEMBER64(cls,memb) { DEVCB_TYPE_DEVICE, 0, ":", #cls "::" #memb, NULL, &devcb_stub64, NULL } // line or read/write handlers for another device #define DEVCB_DEVICE_LINE(tag,func) { DEVCB_TYPE_DEVICE, 0, tag, #func, func, NULL, NULL } @@ -171,6 +219,8 @@ void devcb_stub16(device_t *device, address_space &space, offs_t offset, UINT16 #define DEVCB_DEVICE_HANDLER(tag,func) { DEVCB_TYPE_DEVICE, 0, tag, #func, NULL, func, NULL } #define DEVCB_DEVICE_MEMBER(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, NULL, &devcb_stub, NULL } #define DEVCB_DEVICE_MEMBER16(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, NULL, &devcb_stub16, NULL } +#define DEVCB_DEVICE_MEMBER32(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, NULL, &devcb_stub32, NULL } +#define DEVCB_DEVICE_MEMBER64(tag,cls,memb) { DEVCB_TYPE_DEVICE, 0, tag, #cls "::" #memb, NULL, &devcb_stub64, NULL } // constant values #define DEVCB_CONSTANT(value) { DEVCB_TYPE_CONSTANT, value, NULL, NULL, NULL, NULL } @@ -228,6 +278,10 @@ union devcb_resolved_read_helpers read8_space_func read8_space; read16_device_func read16_device; read16_space_func read16_space; + read32_device_func read32_device; + read32_space_func read32_space; + read64_device_func read64_device; + read64_space_func read64_space; }; union devcb_resolved_write_helpers @@ -238,6 +292,10 @@ union devcb_resolved_write_helpers write8_space_func write8_space; write16_device_func write16_device; write16_space_func write16_space; + write32_device_func write32_device; + write32_space_func write32_space; + write64_device_func write64_device; + write64_space_func write64_space; int input_line; }; @@ -471,7 +529,7 @@ struct devcb_read16 // ======================> devcb_resolved_read16 -// base delegate type for a write8 +// base delegate type for a write16 typedef delegate devcb_read16_delegate; // class which wraps resolving a devcb_read16 into a delegate @@ -525,7 +583,7 @@ struct devcb_write16 // ======================> devcb_resolved_write16 -// base delegate type for a write8 +// base delegate type for a write16 typedef delegate devcb_write16_delegate; // class which wraps resolving a devcb_write16 into a delegate @@ -562,5 +620,220 @@ private: static UINT8 s_null; }; +// ======================> devcb_read32 + +// static structure used for device configuration when the desired callback type is a read32_device_func +struct devcb_read32 +{ + UINT16 type; // one of the special DEVCB_TYPE values + UINT16 index; // index related to the above types + const char * tag; // tag of target, where appropriate + const char * name; // name of the target function + read_line_device_func readline; // read line function + read32_device_func readdevice; // read device function + read32_space_func readspace; // read space function +}; + + +// ======================> devcb_resolved_read32 + +// base delegate type for a write32 +typedef delegate devcb_read32_delegate; + +// class which wraps resolving a devcb_read32 into a delegate +class devcb_resolved_read32 : public devcb_read32_delegate +{ + DISABLE_COPYING(devcb_resolved_read32); + +public: + // construction/destruction + devcb_resolved_read32(); + devcb_resolved_read32(const devcb_read32 &desc, device_t &device) { resolve(desc, device); } + + // resolution + void resolve(const devcb_read32 &desc, device_t &device); + + // override parent class' notion of NULL + bool isnull() const { return m_helper.null_indicator == &s_null; } + + // provide default for mem_mask + UINT32 operator()(offs_t offset, UINT32 mem_mask = 0xffff) const { return devcb_read32_delegate::operator()(offset, mem_mask); } + +private: + // internal helpers + UINT32 from_port(offs_t offset, UINT32 mask); + UINT32 from_read32(offs_t offset, UINT32 mask); + UINT32 from_readline(offs_t offset, UINT32 mask); + UINT32 from_constant(offs_t offset, UINT32 mask); + UINT32 from_unmap(offs_t offset, UINT32 mask); + + // internal state + devcb_resolved_objects m_object; + devcb_resolved_read_helpers m_helper; + static UINT8 s_null; +}; + + +// ======================> devcb_write32 + +// static structure used for device configuration when the desired callback type is a write32_device_func +struct devcb_write32 +{ + UINT16 type; // one of the special DEVCB_TYPE values + UINT16 index; // index related to the above types + const char * tag; // tag of target, where appropriate + const char * name; // name of the target function + write_line_device_func writeline; // write line function + write32_device_func writedevice; // write device function + write32_space_func writespace; // write space function +}; + + +// ======================> devcb_resolved_write32 + +// base delegate type for a write32 +typedef delegate devcb_write32_delegate; + +// class which wraps resolving a devcb_write32 into a delegate +class devcb_resolved_write32 : public devcb_write32_delegate +{ + DISABLE_COPYING(devcb_resolved_write32); + +public: + // construction/destruction + devcb_resolved_write32(); + devcb_resolved_write32(const devcb_write32 &desc, device_t &device) { resolve(desc, device); } + + // resolution + void resolve(const devcb_write32 &desc, device_t &device); + + // override parent class' notion of NULL + bool isnull() const { return m_helper.null_indicator == &s_null; } + + // provide default for mem_mask + void operator()(offs_t offset, UINT32 data, UINT32 mem_mask = 0xffff) const { devcb_write32_delegate::operator()(offset, data, mem_mask); } + +private: + // internal helpers + void to_null(offs_t offset, UINT32 data, UINT32 mask); + void to_port(offs_t offset, UINT32 data, UINT32 mask); + void to_write32(offs_t offset, UINT32 data, UINT32 mask); + void to_writeline(offs_t offset, UINT32 data, UINT32 mask); + void to_input(offs_t offset, UINT32 data, UINT32 mask); + void to_unmap(offs_t offset, UINT32 data, UINT32 mask); + + // internal state + devcb_resolved_objects m_object; + devcb_resolved_write_helpers m_helper; + static UINT8 s_null; +}; + +// ======================> devcb_read64 + +// static structure used for device configuration when the desired callback type is a read64_device_func +struct devcb_read64 +{ + UINT16 type; // one of the special DEVCB_TYPE values + UINT16 index; // index related to the above types + const char * tag; // tag of target, where appropriate + const char * name; // name of the target function + read_line_device_func readline; // read line function + read64_device_func readdevice; // read device function + read64_space_func readspace; // read space function +}; + + +// ======================> devcb_resolved_read64 + +// base delegate type for a write64 +typedef delegate devcb_read64_delegate; + +// class which wraps resolving a devcb_read64 into a delegate +class devcb_resolved_read64 : public devcb_read64_delegate +{ + DISABLE_COPYING(devcb_resolved_read64); + +public: + // construction/destruction + devcb_resolved_read64(); + devcb_resolved_read64(const devcb_read64 &desc, device_t &device) { resolve(desc, device); } + + // resolution + void resolve(const devcb_read64 &desc, device_t &device); + + // override parent class' notion of NULL + bool isnull() const { return m_helper.null_indicator == &s_null; } + + // provide default for mem_mask + UINT64 operator()(offs_t offset, UINT64 mem_mask = 0xffff) const { return devcb_read64_delegate::operator()(offset, mem_mask); } + +private: + // internal helpers + UINT64 from_port(offs_t offset, UINT64 mask); + UINT64 from_read64(offs_t offset, UINT64 mask); + UINT64 from_readline(offs_t offset, UINT64 mask); + UINT64 from_constant(offs_t offset, UINT64 mask); + UINT64 from_unmap(offs_t offset, UINT64 mask); + + // internal state + devcb_resolved_objects m_object; + devcb_resolved_read_helpers m_helper; + static UINT8 s_null; +}; + + +// ======================> devcb_write64 + +// static structure used for device configuration when the desired callback type is a write64_device_func +struct devcb_write64 +{ + UINT16 type; // one of the special DEVCB_TYPE values + UINT16 index; // index related to the above types + const char * tag; // tag of target, where appropriate + const char * name; // name of the target function + write_line_device_func writeline; // write line function + write64_device_func writedevice; // write device function + write64_space_func writespace; // write space function +}; + + +// ======================> devcb_resolved_write64 + +// base delegate type for a write64 +typedef delegate devcb_write64_delegate; + +// class which wraps resolving a devcb_write64 into a delegate +class devcb_resolved_write64 : public devcb_write64_delegate +{ + DISABLE_COPYING(devcb_resolved_write64); + +public: + // construction/destruction + devcb_resolved_write64(); + devcb_resolved_write64(const devcb_write64 &desc, device_t &device) { resolve(desc, device); } + + // resolution + void resolve(const devcb_write64 &desc, device_t &device); + + // override parent class' notion of NULL + bool isnull() const { return m_helper.null_indicator == &s_null; } + + // provide default for mem_mask + void operator()(offs_t offset, UINT64 data, UINT64 mem_mask = 0xffff) const { devcb_write64_delegate::operator()(offset, data, mem_mask); } + +private: + // internal helpers + void to_null(offs_t offset, UINT64 data, UINT64 mask); + void to_port(offs_t offset, UINT64 data, UINT64 mask); + void to_write64(offs_t offset, UINT64 data, UINT64 mask); + void to_writeline(offs_t offset, UINT64 data, UINT64 mask); + void to_input(offs_t offset, UINT64 data, UINT64 mask); + void to_unmap(offs_t offset, UINT64 data, UINT64 mask); + + // internal state + devcb_resolved_objects m_object; + devcb_resolved_write_helpers m_helper; + static UINT8 s_null; +}; #endif // __DEVCB_H__