Critical fixes (nw)

- Prevent tmpz84c015_device::irq_priority_w from crashing or corrupting the daisy chain
- Eliminate the need for TMPZ84C015_DAISY_INTERNAL by not overwriting elements in the daisy list
- Removed leftover MCFG_SEGAZ80_SET_DECRYPTED_TAG from macros in system1.cpp, which lets all drivers validate without crashing
This commit is contained in:
AJR 2016-04-16 16:37:31 -04:00
parent 8c8aca795e
commit 7ffbd45c6c
6 changed files with 43 additions and 12 deletions

View File

@ -155,7 +155,7 @@ WRITE8_MEMBER(tmpz84c015_device::irq_priority_w)
{ 1, 2, 0 } // 5: sio -> pio -> ctc -> ext { 1, 2, 0 } // 5: sio -> pio -> ctc -> ext
}; };
// reconfigure first 3 entries in daisy chain // reconfigure daisy chain
const z80_daisy_config daisy_chain[] = const z80_daisy_config daisy_chain[] =
{ {
{ dev[prio[data][0]] }, { dev[prio[data][0]] },
@ -163,6 +163,8 @@ WRITE8_MEMBER(tmpz84c015_device::irq_priority_w)
{ dev[prio[data][2]] }, { dev[prio[data][2]] },
{ nullptr } { nullptr }
}; };
// insert these 3 entries in order before any externally linked devices
daisy_init(daisy_chain); daisy_init(daisy_chain);
m_irq_priority = data; m_irq_priority = data;

View File

@ -23,9 +23,6 @@
DEVICE CONFIGURATION MACROS DEVICE CONFIGURATION MACROS
***************************************************************************/ ***************************************************************************/
// If an external daisy chain is used, insert this before your own device tags:
#define TMPZ84C015_DAISY_INTERNAL { "tmpz84c015_ctc" }, { "tmpz84c015_sio" }, { "tmpz84c015_pio" }
// SIO callbacks // SIO callbacks
#define MCFG_TMPZ84C015_OUT_TXDA_CB(_devcb) \ #define MCFG_TMPZ84C015_OUT_TXDA_CB(_devcb) \
devcb = &tmpz84c015_device::set_out_txda_callback(*device, DEVCB_##_devcb); devcb = &tmpz84c015_device::set_out_txda_callback(*device, DEVCB_##_devcb);

View File

@ -87,6 +87,8 @@ void z80_daisy_chain_interface::interface_post_start()
void z80_daisy_chain_interface::daisy_init(const z80_daisy_config *daisy) void z80_daisy_chain_interface::daisy_init(const z80_daisy_config *daisy)
{ {
assert(daisy != nullptr);
// create a linked list of devices // create a linked list of devices
device_z80daisy_interface **tailptr = &m_chain; device_z80daisy_interface **tailptr = &m_chain;
for ( ; daisy->devname != nullptr; daisy++) for ( ; daisy->devname != nullptr; daisy++)
@ -105,12 +107,23 @@ void z80_daisy_chain_interface::daisy_init(const z80_daisy_config *daisy)
if (!target->interface(intf)) if (!target->interface(intf))
fatalerror("Device '%s' does not implement the z80daisy interface!\n", daisy->devname); fatalerror("Device '%s' does not implement the z80daisy interface!\n", daisy->devname);
// append to the end, or overwrite existing entry // splice it out of the list if it was previously added
device_z80daisy_interface *next = (*tailptr != nullptr) ? (*tailptr)->m_daisy_next : nullptr; device_z80daisy_interface **oldtailptr = tailptr;
while (*oldtailptr != nullptr)
{
if (*oldtailptr == intf)
*oldtailptr = (*oldtailptr)->m_daisy_next;
else
oldtailptr = &(*oldtailptr)->m_daisy_next;
}
// add the interface to the list
intf->m_daisy_next = *tailptr;
*tailptr = intf; *tailptr = intf;
(*tailptr)->m_daisy_next = next;
tailptr = &(*tailptr)->m_daisy_next; tailptr = &(*tailptr)->m_daisy_next;
} }
osd_printf_verbose("Daisy chain = %s\n", daisy_show_chain().c_str());
} }
@ -193,3 +206,24 @@ void z80_daisy_chain_interface::daisy_call_reti_device()
} }
//logerror("z80daisy_call_reti_device: failed to find an device to reti!\n"); //logerror("z80daisy_call_reti_device: failed to find an device to reti!\n");
} }
//-------------------------------------------------
// daisy_show_chain - list devices in the chain
// in string format (for debugging purposes)
//-------------------------------------------------
std::string z80_daisy_chain_interface::daisy_show_chain() const
{
std::ostringstream result;
// loop over all devices
for (device_z80daisy_interface *intf = m_chain; intf != nullptr; intf = intf->m_daisy_next)
{
if (intf != m_chain)
result << " -> ";
result << intf->device().tag();
}
return result.str();
}

View File

@ -85,6 +85,7 @@ public:
// getters // getters
bool daisy_chain_present() const { return (m_chain != nullptr); } bool daisy_chain_present() const { return (m_chain != nullptr); }
std::string daisy_show_chain() const;
protected: protected:
// interface-level overrides // interface-level overrides

View File

@ -102,7 +102,6 @@ WRITE_LINE_MEMBER( pve500_state::external_monitor_w )
static const z80_daisy_config maincpu_daisy_chain[] = static const z80_daisy_config maincpu_daisy_chain[] =
{ {
TMPZ84C015_DAISY_INTERNAL,
{ "external_ctc" }, { "external_ctc" },
{ "external_sio" }, { "external_sio" },
{ nullptr } { nullptr }

View File

@ -2222,15 +2222,13 @@ MACHINE_CONFIG_END
MCFG_CPU_PROGRAM_MAP(system1_map) \ MCFG_CPU_PROGRAM_MAP(system1_map) \
MCFG_CPU_DECRYPTED_OPCODES_MAP(decrypted_opcodes_map) \ MCFG_CPU_DECRYPTED_OPCODES_MAP(decrypted_opcodes_map) \
MCFG_CPU_IO_MAP(system1_ppi_io_map) \ MCFG_CPU_IO_MAP(system1_ppi_io_map) \
MCFG_CPU_VBLANK_INT_DRIVER("screen", system1_state, irq0_line_hold) \ MCFG_CPU_VBLANK_INT_DRIVER("screen", system1_state, irq0_line_hold)
MCFG_SEGAZ80_SET_DECRYPTED_TAG(":decrypted_opcodes")
#define ENCRYPTED_SYS1PIO_MAPS \ #define ENCRYPTED_SYS1PIO_MAPS \
MCFG_CPU_PROGRAM_MAP(system1_map) \ MCFG_CPU_PROGRAM_MAP(system1_map) \
MCFG_CPU_DECRYPTED_OPCODES_MAP(decrypted_opcodes_map) \ MCFG_CPU_DECRYPTED_OPCODES_MAP(decrypted_opcodes_map) \
MCFG_CPU_IO_MAP(system1_pio_io_map) \ MCFG_CPU_IO_MAP(system1_pio_io_map) \
MCFG_CPU_VBLANK_INT_DRIVER("screen", system1_state, irq0_line_hold) \ MCFG_CPU_VBLANK_INT_DRIVER("screen", system1_state, irq0_line_hold)
MCFG_SEGAZ80_SET_DECRYPTED_TAG(":decrypted_opcodes")
static MACHINE_CONFIG_DERIVED( sys1ppix_315_5178, sys1ppi ) static MACHINE_CONFIG_DERIVED( sys1ppix_315_5178, sys1ppi )