summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2018-04-29 19:48:38 -0400
committer AJR <ajrhacker@users.noreply.github.com>2018-04-29 19:48:38 -0400
commit1185fb25f3342ea08072fd79f2ccaf0e5aea6a47 (patch)
treeae211b7c83f066c071e267346336640ae6535959 /src/emu
parent9927ef444061fdd3410fda71a79717558d4a0daa (diff)
devcb updates (nw)
- Write callbacks can now be configured as `OUTPUT("item_name")`. This behaves equivalently to a zero-dimensional `output_finder`, while eliminating the need to instantiate and resolve this in driver classes separately from the callback itself. - The width of a callback's default mask now properly depends on its type (as was half-implemented before), instead of always being reset to 0xffffffffffffffff when actually configured. This allows MCFG_DEVCB_INVERT to work with line write callbacks as one might logically expect.
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/devcb.cpp37
-rw-r--r--src/emu/devcb.h17
-rw-r--r--src/emu/output.cpp10
-rw-r--r--src/emu/output.h4
4 files changed, 62 insertions, 6 deletions
diff --git a/src/emu/devcb.cpp b/src/emu/devcb.cpp
index 540c8d249c9..fe8deacfba1 100644
--- a/src/emu/devcb.cpp
+++ b/src/emu/devcb.cpp
@@ -60,7 +60,7 @@ void devcb_base::reset(callback_type type)
m_space = nullptr;
m_target.ptr = nullptr;
m_rshift = 0;
- m_mask = ~u64(0);
+ m_mask = m_defmask;
m_xor = 0;
devcb_reset();
}
@@ -101,6 +101,17 @@ void devcb_base::resolve_membank()
//-------------------------------------------------
+// resolve_output - resolve an output item
+//-------------------------------------------------
+
+void devcb_base::resolve_output()
+{
+ assert(m_target_tag != nullptr);
+ m_target.item = &m_device.machine().output().find_or_create_item(m_target_tag, 0);
+}
+
+
+//-------------------------------------------------
// resolve_inputline - resolve a device and input
// number or fatal error if we can't find it
//-------------------------------------------------
@@ -254,6 +265,9 @@ void devcb_read_base::resolve()
case CALLBACK_MEMBANK:
throw emu_fatalerror("Device read callbacks can't be connected to bank switches\n");
+ case CALLBACK_OUTPUT:
+ throw emu_fatalerror("Device read callbacks can't be connected to output items\n");
+
case CALLBACK_LOG:
m_adapter = &devcb_read_base::read_logged_adapter;
m_mask = 0;
@@ -444,6 +458,10 @@ void devcb_read_base::validity_check(validity_checker &valid) const
osd_printf_error("Device read callbacks can't be connected to bank switches\n");
break;
+ case CALLBACK_OUTPUT:
+ osd_printf_error("Device read callbacks can't be connected to output items\n");
+ break;
+
case CALLBACK_INPUTLINE:
case CALLBACK_ASSERTLINE:
case CALLBACK_CLEARLINE:
@@ -566,6 +584,11 @@ void devcb_write_base::resolve()
m_adapter = (m_target.membank == nullptr) ? &devcb_write_base::write_noop_adapter : &devcb_write_base::write_membank_adapter;
break;
+ case CALLBACK_OUTPUT:
+ resolve_output();
+ m_adapter = (m_target.item == nullptr) ? &devcb_write_base::write_noop_adapter : &devcb_write_base::write_output_adapter;
+ break;
+
case CALLBACK_LOG:
m_adapter = &devcb_write_base::write_logged_adapter;
break;
@@ -636,6 +659,7 @@ void devcb_write_base::validity_check(validity_checker &valid) const
case CALLBACK_LOG:
case CALLBACK_IOPORT:
case CALLBACK_MEMBANK:
+ case CALLBACK_OUTPUT:
break;
case CALLBACK_LINE:
@@ -770,6 +794,17 @@ void devcb_write_base::write_membank_adapter(address_space &space, offs_t offset
//-------------------------------------------------
+// write_output_adapter - set an output item
+//-------------------------------------------------
+
+void devcb_write_base::write_output_adapter(address_space &space, offs_t offset, u64 data, u64 mask)
+{
+ if (m_target.item)
+ m_target.item->set(unshift_mask_xor(data));
+}
+
+
+//-------------------------------------------------
// write_logged_adapter - log write if masked
// value is nonzero
//-------------------------------------------------
diff --git a/src/emu/devcb.h b/src/emu/devcb.h
index 20d19161bff..bbfc273f0be 100644
--- a/src/emu/devcb.h
+++ b/src/emu/devcb.h
@@ -26,6 +26,7 @@
#define DEVCB_NOOP devcb_base::null_desc()
#define DEVCB_IOPORT(_tag) devcb_base::ioport_desc(_tag)
#define DEVCB_MEMBANK(_tag) devcb_base::membank_desc(_tag)
+#define DEVCB_OUTPUT(_tag) devcb_base::output_desc(_tag)
#define DEVCB_CONSTANT(_value) devcb_base::constant_desc(_value)
#define DEVCB_LOGGER(_string) devcb_base::logger_desc(_string)
#define DEVCB_INPUTLINE(_tag, _line) devcb_base::inputline_desc(_tag, _line)
@@ -101,6 +102,7 @@ protected:
CALLBACK_64,
CALLBACK_IOPORT,
CALLBACK_MEMBANK,
+ CALLBACK_OUTPUT,
CALLBACK_LOG,
CALLBACK_CONSTANT,
CALLBACK_INPUTLINE,
@@ -144,6 +146,13 @@ public:
const char *m_tag;
};
+ class output_desc
+ {
+ public:
+ output_desc(const char *tag) { m_tag = tag; }
+ const char *m_tag;
+ };
+
class constant_desc
{
public:
@@ -194,6 +203,7 @@ public:
devcb_base &set_callback(null_desc null) { reset(CALLBACK_NONE); return *this; }
devcb_base &set_callback(ioport_desc ioport) { reset(CALLBACK_IOPORT); m_target_tag = ioport.m_tag; return *this; }
devcb_base &set_callback(membank_desc membank) { reset(CALLBACK_MEMBANK); m_target_tag = membank.m_tag; return *this; }
+ devcb_base &set_callback(output_desc output) { reset(CALLBACK_OUTPUT); m_target_tag = output.m_tag; return *this; }
devcb_base &set_callback(constant_desc constant) { reset(CALLBACK_CONSTANT); m_target_int = constant.m_value; return *this; }
devcb_base &set_callback(logger_desc logger) { reset(CALLBACK_LOG); m_target_tag = logger.m_string; return *this; }
void reset() { reset(CALLBACK_NONE); }
@@ -208,6 +218,7 @@ protected:
virtual void devcb_reset() = 0;
void resolve_ioport();
void resolve_membank();
+ void resolve_output();
void resolve_inputline();
void resolve_space();
@@ -218,6 +229,7 @@ protected:
device_t * device;
ioport_port * ioport;
memory_bank * membank;
+ output_manager::output_item *item;
};
// configuration
@@ -338,6 +350,7 @@ private:
void write64_adapter(address_space &space, offs_t offset, u64 data, u64 mask);
void write_ioport_adapter(address_space &space, offs_t offset, u64 data, u64 mask);
void write_membank_adapter(address_space &space, offs_t offset, u64 data, u64 mask);
+ void write_output_adapter(address_space &space, offs_t offset, u64 data, u64 mask);
void write_logged_adapter(address_space &space, offs_t offset, u64 data, u64 mask);
void write_noop_adapter(address_space &space, offs_t offset, u64 data, u64 mask);
void write_inputline_adapter(address_space &space, offs_t offset, u64 data, u64 mask);
@@ -364,7 +377,7 @@ private:
class devcb_read_line : public devcb_read_base
{
public:
- devcb_read_line(device_t &device) : devcb_read_base(device, 0xff) { }
+ devcb_read_line(device_t &device) : devcb_read_base(device, 1) { }
int operator()() { return read(*m_space, 0, 0xffU) & 1; }
int operator()(address_space &space) { return read((m_space_tag != nullptr) ? *m_space : space, 0, 0xffU) & 1; }
};
@@ -419,7 +432,7 @@ public:
class devcb_write_line : public devcb_write_base
{
public:
- devcb_write_line(device_t &device) : devcb_write_base(device, 0xff) { }
+ devcb_write_line(device_t &device) : devcb_write_base(device, 1) { }
void operator()(int state) { write(*m_space, 0, state & 1, 0xffU); }
void operator()(address_space &space, int state) { write((m_space_tag != nullptr) ? *m_space : space, 0, state & 1, 0xffU); }
};
diff --git a/src/emu/output.cpp b/src/emu/output.cpp
index f31bb0a8e52..5969d1dbfc5 100644
--- a/src/emu/output.cpp
+++ b/src/emu/output.cpp
@@ -58,9 +58,7 @@ void output_manager::output_item::notify(s32 value)
void output_manager::item_proxy::resolve(device_t &device, std::string const &name)
{
assert(!m_item);
- m_item = device.machine().output().find_item(name.c_str());
- if (!m_item)
- m_item = &device.machine().output().create_new_item(name.c_str(), 0);
+ m_item = &device.machine().output().find_or_create_item(name.c_str(), 0);
}
@@ -110,6 +108,12 @@ output_manager::output_item &output_manager::create_new_item(const char *outname
return ins.first->second;
}
+output_manager::output_item &output_manager::find_or_create_item(const char *outname, s32 value)
+{
+ output_item *const item = find_item(outname);
+ return item ? *item : create_new_item(outname, value);
+}
+
/*-------------------------------------------------
output_pause - send pause message
-------------------------------------------------*/
diff --git a/src/emu/output.h b/src/emu/output.h
index f5f06511b16..d766f9dd853 100644
--- a/src/emu/output.h
+++ b/src/emu/output.h
@@ -27,6 +27,9 @@ typedef void (*output_notifier_func)(const char *outname, s32 value, void *param
class output_manager
{
+ friend class devcb_base;
+ friend class devcb_write_base;
+
private:
class output_notify
{
@@ -190,6 +193,7 @@ private:
output_item *find_item(const char *string);
output_item &create_new_item(const char *outname, s32 value);
+ output_item &find_or_create_item(const char *outname, s32 value);
// internal state
running_machine &m_machine; // reference to our machine