diff options
author | Vas Crabb <vas@vastheman.com> | 2018-07-07 02:40:29 +1000 |
---|---|---|
committer | Vas Crabb <vas@vastheman.com> | 2018-07-07 02:40:29 +1000 |
commit | c3fb11c2c98a5c28ece6a27093a0f9def350ac64 (patch) | |
tree | c68b38f05ed1d32358add721fda7f45e8803479f /src/devices/bus/ti99 | |
parent | 5d9e33b786d7ef452317439359f3cbd8cc920513 (diff) |
devcb3
There are multiple issues with the current device callbacks:
* They always dispatch through a pointer-to-member
* Chained callbacks are a linked list so the branch unit can't predict the early
* There's a runtime decision made on the left/right shift direction
* There are runtime NULL checks on various objects
* Binding a lambda isn't practical
* Arbitrary transformations are not supported
* When chaining callbacks it isn't clear what the MCFG_DEVCB_ modifiers apply to
* It isn't possible to just append to a callback in derived configuration
* The macros need a magic, hidden local called devcb
* Moving code that uses the magic locals around is error-prone
* Writing the MCFG_ macros to make a device usable is a pain
* You can't discover applicable MCFG_ macros with intellisense
* Macros are not scoped
* Using an inappropriate macro isn't detected at compile time
* Lots of other things
This changeset overcomes the biggest obstacle to remving MCFG_ macros
altogether. Essentially, to allow a devcb to be configured, call
.bind() and expose the result (a bind target for the callback). Bind
target methods starting with "set" repace the current callbacks; methods
starting with "append" append to them. You can't reconfigure a callback
after resolving it. There's no need to use a macro matching the
handler signatures - use FUNC for everything. Current device is implied
if no tag/finder is supplied (no need for explicit this).
Lambdas are supported, and the memory space and offset are optional.
These kinds of things work:
* .read_cb().set([this] () { return something; });
* .read_cb().set([this] (offs_t offset) { return ~offset; });
* .write_cb().set([this] (offs_t offset, u8 data) { m_array[offset] = data; });
* .write_cb().set([this] (int state) { some_var = state; });
Arbitrary transforms are allowed, and they can modify offset/mask for example:
* .read_cb().set(FUNC(my_state::handler)).transform([] (u8 data) { return bitswap<4>(data, 1, 3, 0, 2); });
* .read_cb().set(m_dev, FUNC(some_device::member)).transform([] (offs_t &offset, u8 data) { offset ^= 3; return data; });
It's possible to stack arbitrary transforms, at the cost of compile
time (the whole transform stack gets inlined at compile time). Shifts
count as an arbitrary transform, but mask/exor does not.
Order of mask/shift/exor now matters. Modifications are applied in the
specified order. These are NOT EQUIVALENT:
* .read_cb().set(FUNC(my_state::handler)).mask(0x06).lshift(2);
* .read_cb().set(FUNC(my_state::handler)).lshift(2).mask(0x06);
The bit helper no longer reverses its behaviour for read callbacks, and
I/O ports are no longer aware of the field mask. Binding a read
callback to no-op is not supported - specify a constant. The GND and
VCC aliases have been removed intentionally - they're TTL-centric, and
were already being abused.
Other quirks have been preserved, including write logger only logging
when the data is non-zero (quite unhelpful in many of the cases where
it's used). Legacy syntax is still supported for simple cases, but will
be phased out. New devices should not have MCFG_ macros.
I don't think I've missed any fundamental issues, but if I've broken
something, let me know.
Diffstat (limited to 'src/devices/bus/ti99')
-rw-r--r-- | src/devices/bus/ti99/gromport/gromport.h | 4 | ||||
-rw-r--r-- | src/devices/bus/ti99/internal/992board.h | 8 | ||||
-rw-r--r-- | src/devices/bus/ti99/internal/998board.h | 8 | ||||
-rw-r--r-- | src/devices/bus/ti99/internal/datamux.h | 2 | ||||
-rw-r--r-- | src/devices/bus/ti99/internal/evpcconn.h | 2 | ||||
-rw-r--r-- | src/devices/bus/ti99/internal/genboard.h | 4 | ||||
-rw-r--r-- | src/devices/bus/ti99/internal/ioport.h | 4 | ||||
-rw-r--r-- | src/devices/bus/ti99/joyport/joyport.h | 2 | ||||
-rw-r--r-- | src/devices/bus/ti99/peb/peribox.h | 8 |
9 files changed, 21 insertions, 21 deletions
diff --git a/src/devices/bus/ti99/gromport/gromport.h b/src/devices/bus/ti99/gromport/gromport.h index 3f7941e9641..7d370ce39d6 100644 --- a/src/devices/bus/ti99/gromport/gromport.h +++ b/src/devices/bus/ti99/gromport/gromport.h @@ -106,10 +106,10 @@ void gromport8(device_slot_interface &device); MCFG_DEVICE_SLOT_INTERFACE(gromport8, "single", false) #define MCFG_GROMPORT_READY_HANDLER( _ready ) \ - devcb = &downcast<bus::ti99::gromport::gromport_device &>(*device).set_ready_callback(DEVCB_##_ready); + downcast<bus::ti99::gromport::gromport_device &>(*device).set_ready_callback(DEVCB_##_ready); #define MCFG_GROMPORT_RESET_HANDLER( _reset ) \ - devcb = &downcast<bus::ti99::gromport::gromport_device &>(*device).set_reset_callback(DEVCB_##_reset); + downcast<bus::ti99::gromport::gromport_device &>(*device).set_reset_callback(DEVCB_##_reset); DECLARE_DEVICE_TYPE_NS(TI99_GROMPORT, bus::ti99::gromport, gromport_device) diff --git a/src/devices/bus/ti99/internal/992board.h b/src/devices/bus/ti99/internal/992board.h index 02ffb5b25d1..7e79c8d1358 100644 --- a/src/devices/bus/ti99/internal/992board.h +++ b/src/devices/bus/ti99/internal/992board.h @@ -163,16 +163,16 @@ public: bus::ti99::internal::video992_device::TOTAL_VERT_NTSC, bus::ti99::internal::video992_device::VERT_DISPLAY_START_NTSC - 12, bus::ti99::internal::video992_device::VERT_DISPLAY_START_NTSC + 192 + 12 ) #define MCFG_VIDEO992_MEM_ACCESS_CB(_devcb) \ - devcb = &downcast<bus::ti99::internal::video992_device &>(*device).set_readmem_callback(DEVCB_##_devcb); + downcast<bus::ti99::internal::video992_device &>(*device).set_readmem_callback(DEVCB_##_devcb); #define MCFG_VIDEO992_HOLD_CB(_devcb) \ - devcb = &downcast<bus::ti99::internal::video992_device &>(*device).set_hold_callback(DEVCB_##_devcb); + downcast<bus::ti99::internal::video992_device &>(*device).set_hold_callback(DEVCB_##_devcb); #define MCFG_VIDEO992_INT_CB(_devcb) \ - devcb = &downcast<bus::ti99::internal::video992_device &>(*device).set_int_callback(DEVCB_##_devcb); + downcast<bus::ti99::internal::video992_device &>(*device).set_int_callback(DEVCB_##_devcb); #define MCFG_SET_ROMBANK_HANDLER( _devcb ) \ - devcb = &downcast<bus::ti99::internal::io992_device &>(*device).set_rombank_callback(DEVCB_##_devcb); + downcast<bus::ti99::internal::io992_device &>(*device).set_rombank_callback(DEVCB_##_devcb); DECLARE_DEVICE_TYPE_NS(VIDEO99224, bus::ti99::internal, video992_24_device) DECLARE_DEVICE_TYPE_NS(VIDEO99232, bus::ti99::internal, video992_32_device) diff --git a/src/devices/bus/ti99/internal/998board.h b/src/devices/bus/ti99/internal/998board.h index 820199f536d..e59e80b437e 100644 --- a/src/devices/bus/ti99/internal/998board.h +++ b/src/devices/bus/ti99/internal/998board.h @@ -702,16 +702,16 @@ private: } } } // end namespace bus::ti99::internal #define MCFG_MAINBOARD8_READY_CALLBACK(_write) \ - devcb = &downcast<bus::ti99::internal::mainboard8_device &>(*device).set_ready_wr_callback(DEVCB_##_write); + downcast<bus::ti99::internal::mainboard8_device &>(*device).set_ready_wr_callback(DEVCB_##_write); #define MCFG_MAINBOARD8_RESET_CALLBACK(_write) \ - devcb = &downcast<bus::ti99::internal::mainboard8_device &>(*device).set_reset_wr_callback(DEVCB_##_write); + downcast<bus::ti99::internal::mainboard8_device &>(*device).set_reset_wr_callback(DEVCB_##_write); #define MCFG_MAINBOARD8_HOLD_CALLBACK(_write) \ - devcb = &downcast<bus::ti99::internal::mainboard8_device &>(*device).set_hold_wr_callback(DEVCB_##_write); + downcast<bus::ti99::internal::mainboard8_device &>(*device).set_hold_wr_callback(DEVCB_##_write); #define MCFG_OSO_INT_CALLBACK(_int) \ - devcb = &downcast<bus::ti99::internal::oso_device &>(*device).set_int_callback(DEVCB##_int); + downcast<bus::ti99::internal::oso_device &>(*device).set_int_callback(DEVCB##_int); DECLARE_DEVICE_TYPE_NS(TI99_MAINBOARD8, bus::ti99::internal, mainboard8_device) DECLARE_DEVICE_TYPE_NS(TI99_VAQUERRO, bus::ti99::internal, vaquerro_device) diff --git a/src/devices/bus/ti99/internal/datamux.h b/src/devices/bus/ti99/internal/datamux.h index 47d2d1f84c3..72695279332 100644 --- a/src/devices/bus/ti99/internal/datamux.h +++ b/src/devices/bus/ti99/internal/datamux.h @@ -141,7 +141,7 @@ private: /******************************************************************************/ #define MCFG_DMUX_READY_HANDLER( _intcallb ) \ - devcb = &downcast<bus::ti99::internal::datamux_device &>(*device).set_ready_callback(DEVCB_##_intcallb); + downcast<bus::ti99::internal::datamux_device &>(*device).set_ready_callback(DEVCB_##_intcallb); } } } // end namespace bus::ti99::internal diff --git a/src/devices/bus/ti99/internal/evpcconn.h b/src/devices/bus/ti99/internal/evpcconn.h index 9f1af61ccf9..67e5784cd4f 100644 --- a/src/devices/bus/ti99/internal/evpcconn.h +++ b/src/devices/bus/ti99/internal/evpcconn.h @@ -37,6 +37,6 @@ DECLARE_DEVICE_TYPE_NS(TI99_EVPCCONN, bus::ti99::internal, evpc_clock_connector) #define MCFG_ADD_EVPC_CONNECTOR( _tag, _vdpint ) \ MCFG_DEVICE_ADD(_tag, TI99_EVPCCONN, 0) \ - devcb = &downcast<bus::ti99::internal::evpc_clock_connector &>(*device).set_vdpint_callback(DEVCB_##_vdpint); + downcast<bus::ti99::internal::evpc_clock_connector &>(*device).set_vdpint_callback(DEVCB_##_vdpint); #endif // MAME_BUS_TI99_INTERNAL_EVPCCONN_H diff --git a/src/devices/bus/ti99/internal/genboard.h b/src/devices/bus/ti99/internal/genboard.h index 260f02932b1..e83e81cfc26 100644 --- a/src/devices/bus/ti99/internal/genboard.h +++ b/src/devices/bus/ti99/internal/genboard.h @@ -108,7 +108,7 @@ private: }; #define MCFG_GENEVE_KBINT_HANDLER( _intcallb ) \ - devcb = &downcast<bus::ti99::internal::geneve_keyboard_device &>(*device).set_int_callback(DEVCB_##_intcallb); + downcast<bus::ti99::internal::geneve_keyboard_device &>(*device).set_int_callback(DEVCB_##_intcallb); /*****************************************************************************/ @@ -308,7 +308,7 @@ private: }; #define MCFG_GENEVE_READY_HANDLER( _intcallb ) \ - devcb = &downcast<bus::ti99::internal::geneve_mapper_device &>(*device).set_ready_callback(DEVCB_##_intcallb); + downcast<bus::ti99::internal::geneve_mapper_device &>(*device).set_ready_callback(DEVCB_##_intcallb); } } } // end namespace bus::ti99::internal diff --git a/src/devices/bus/ti99/internal/ioport.h b/src/devices/bus/ti99/internal/ioport.h index 4c21a11651e..0468649a72f 100644 --- a/src/devices/bus/ti99/internal/ioport.h +++ b/src/devices/bus/ti99/internal/ioport.h @@ -99,9 +99,9 @@ void ti99_io_port_ev(device_slot_interface &device); MCFG_DEVICE_SLOT_INTERFACE(ti99_io_port_ev, "peb", false) #define MCFG_IOPORT_EXTINT_HANDLER( _extint ) \ - devcb = &downcast<bus::ti99::internal::ioport_device &>(*device).set_extint_callback(DEVCB_##_extint); + downcast<bus::ti99::internal::ioport_device &>(*device).set_extint_callback(DEVCB_##_extint); #define MCFG_IOPORT_READY_HANDLER( _ready ) \ - devcb = &downcast<bus::ti99::internal::ioport_device &>(*device).set_ready_callback(DEVCB_##_ready); + downcast<bus::ti99::internal::ioport_device &>(*device).set_ready_callback(DEVCB_##_ready); #endif /* __TI99IOPORT__ */ diff --git a/src/devices/bus/ti99/joyport/joyport.h b/src/devices/bus/ti99/joyport/joyport.h index c455058c387..3808f5bff7c 100644 --- a/src/devices/bus/ti99/joyport/joyport.h +++ b/src/devices/bus/ti99/joyport/joyport.h @@ -75,7 +75,7 @@ void ti99_joystick_port_gen(device_slot_interface &device); DECLARE_DEVICE_TYPE_NS(TI99_JOYPORT, bus::ti99::joyport, joyport_device) #define MCFG_JOYPORT_INT_HANDLER( _intcallb ) \ - devcb = &downcast<bus::ti99::joyport::joyport_device &>(*device).set_int_callback(DEVCB_##_intcallb); + downcast<bus::ti99::joyport::joyport_device &>(*device).set_int_callback(DEVCB_##_intcallb); #define MCFG_GENEVE_JOYPORT_ADD( _tag ) \ MCFG_DEVICE_ADD(_tag, TI99_JOYPORT, 0) \ diff --git a/src/devices/bus/ti99/peb/peribox.h b/src/devices/bus/ti99/peb/peribox.h index 71ad9eb589b..d83c8f0aa44 100644 --- a/src/devices/bus/ti99/peb/peribox.h +++ b/src/devices/bus/ti99/peb/peribox.h @@ -250,16 +250,16 @@ private: MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _default, false) #define MCFG_PERIBOX_INTA_HANDLER( _inta ) \ - devcb = &downcast<bus::ti99::peb::peribox_device &>(*device).set_inta_callback(DEVCB_##_inta); + downcast<bus::ti99::peb::peribox_device &>(*device).set_inta_callback(DEVCB_##_inta); #define MCFG_PERIBOX_INTB_HANDLER( _intb ) \ - devcb = &downcast<bus::ti99::peb::peribox_device &>(*device).set_intb_callback(DEVCB_##_intb); + downcast<bus::ti99::peb::peribox_device &>(*device).set_intb_callback(DEVCB_##_intb); #define MCFG_PERIBOX_READY_HANDLER( _ready ) \ - devcb = &downcast<bus::ti99::peb::peribox_device &>(*device).set_ready_callback(DEVCB_##_ready); + downcast<bus::ti99::peb::peribox_device &>(*device).set_ready_callback(DEVCB_##_ready); #define MCFG_PERIBOX_LCP_HANDLER( _lcp ) \ - devcb = &downcast<bus::ti99::peb::peribox_device &>(*device).set_lcp_callback(DEVCB_##_lcp); + downcast<bus::ti99::peb::peribox_device &>(*device).set_lcp_callback(DEVCB_##_lcp); } } } // end namespace bus::ti99::peb |