From 4aae75d753860f854ad977ae9bc8ed57df6e0bbf Mon Sep 17 00:00:00 2001 From: AJR Date: Mon, 27 Jul 2020 14:22:58 -0400 Subject: [PATCH] kl5c80a12: Emulate interrupt controller --- scripts/src/cpu.lua | 2 + src/devices/cpu/z80/kl5c80a12.cpp | 35 ++- src/devices/cpu/z80/kl5c80a12.h | 7 +- src/devices/cpu/z80/kp69.cpp | 453 ++++++++++++++++++++++++++++++ src/devices/cpu/z80/kp69.h | 92 ++++++ src/mame/drivers/ddenlovr.cpp | 46 +-- src/mame/drivers/sigmab98.cpp | 40 ++- 7 files changed, 611 insertions(+), 64 deletions(-) create mode 100644 src/devices/cpu/z80/kp69.cpp create mode 100644 src/devices/cpu/z80/kp69.h diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index e8eabea847c..db3e1e2441a 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -2616,6 +2616,8 @@ if (CPUS["Z80"]~=null) then MAME_DIR .. "src/devices/cpu/z80/tmpz84c015.h", MAME_DIR .. "src/devices/cpu/z80/kl5c80a12.cpp", MAME_DIR .. "src/devices/cpu/z80/kl5c80a12.h", + MAME_DIR .. "src/devices/cpu/z80/kp69.cpp", + MAME_DIR .. "src/devices/cpu/z80/kp69.h", MAME_DIR .. "src/devices/cpu/z80/lz8420m.cpp", MAME_DIR .. "src/devices/cpu/z80/lz8420m.h", } diff --git a/src/devices/cpu/z80/kl5c80a12.cpp b/src/devices/cpu/z80/kl5c80a12.cpp index 6e052b0a216..ebde2f5e1fb 100644 --- a/src/devices/cpu/z80/kl5c80a12.cpp +++ b/src/devices/cpu/z80/kl5c80a12.cpp @@ -13,7 +13,7 @@ — MMU — USART (KP51) (unemulated) — 16-bit timer/counters (KP64, KP63) (unemulated) - — 16-level interrupt controller (KP69) (unemulated) + — 16-level interrupt controller (KP69) — Parallel ports (KP65, KP66) (unemulated) — 512-byte high-speed RAM — External bus interface unit (unemulated) @@ -25,12 +25,19 @@ DEFINE_DEVICE_TYPE(KL5C80A12, kl5c80a12_device, "kl5c80a12", "Kawasaki Steel KL5C80A12") +static const z80_daisy_config fake_daisy_config[] = { { "kp69" }, { nullptr } }; + + +//------------------------------------------------- +// kl5c80a12 - device type constructor +//------------------------------------------------- kl5c80a12_device::kl5c80a12_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : z80_device(mconfig, KL5C80A12, tag, owner, clock) , m_program_config("program", ENDIANNESS_LITTLE, 8, 20, 0, 16, 10, address_map_constructor(FUNC(kl5c80a12_device::internal_ram), this)) , m_opcodes_config("opcodes", ENDIANNESS_LITTLE, 8, 20, 0, 16, 10, address_map_constructor(FUNC(kl5c80a12_device::internal_ram), this)) , m_io_config("io", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(FUNC(kl5c80a12_device::internal_io), this)) + , m_kp69(*this, "kp69") { std::fill_n(&m_mmu_a[0], 4, 0); std::fill_n(&m_mmu_b[0], 5, 0); @@ -55,6 +62,10 @@ void kl5c80a12_device::internal_ram(address_map &map) void kl5c80a12_device::internal_io(address_map &map) { map(0x00, 0x07).mirror(0xff00).rw(FUNC(kl5c80a12_device::mmu_r), FUNC(kl5c80a12_device::mmu_w)); + map(0x34, 0x34).mirror(0xff00).rw(m_kp69, FUNC(kp69_device::isrl_r), FUNC(kp69_device::lerl_pgrl_w)); + map(0x35, 0x35).mirror(0xff00).rw(m_kp69, FUNC(kp69_device::isrh_r), FUNC(kp69_device::lerh_pgrh_w)); + map(0x36, 0x36).mirror(0xff00).rw(m_kp69, FUNC(kp69_device::imrl_r), FUNC(kp69_device::imrl_w)); + map(0x37, 0x37).mirror(0xff00).rw(m_kp69, FUNC(kp69_device::imrh_r), FUNC(kp69_device::ivr_imrh_w)); } @@ -104,6 +115,8 @@ void kl5c80a12_device::device_start() ).mask(0x3ff); } + m_kp69->add_to_state(*this, KP69_IRR); + save_item(NAME(m_mmu_a)); save_item(NAME(m_mmu_b)); } @@ -136,9 +149,27 @@ void kl5c80a12_device::device_post_load() } -/* CPU interface */ +//------------------------------------------------- +// device_add_mconfig - add device-specific +// machine configuration +//------------------------------------------------- + void kl5c80a12_device::device_add_mconfig(machine_config &config) { + KP69(config, m_kp69); + m_kp69->int_callback().set_inputline(*this, INPUT_LINE_IRQ0); +} + + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void kl5c80a12_device::device_config_complete() +{ + set_daisy_config(fake_daisy_config); } diff --git a/src/devices/cpu/z80/kl5c80a12.h b/src/devices/cpu/z80/kl5c80a12.h index 511c1214061..02519e69656 100644 --- a/src/devices/cpu/z80/kl5c80a12.h +++ b/src/devices/cpu/z80/kl5c80a12.h @@ -12,6 +12,7 @@ #pragma once #include "z80.h" +#include "kp69.h" //************************************************************************** @@ -24,7 +25,8 @@ public: enum { KC82_B1 = Z80_WZ + 1, KC82_B2, KC82_B3, KC82_B4, - KC82_A1, KC82_A2, KC82_A3 + KC82_A1, KC82_A2, KC82_A3, + KP69_IRR, KP69_ISR, KP69_IVR, KP69_LER, KP69_PGR, KP69_IMR }; kl5c80a12_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); @@ -32,6 +34,7 @@ public: protected: // device-level overrides virtual void device_add_mconfig(machine_config &config) override; + virtual void device_config_complete() override; virtual void device_start() override; virtual void device_reset() override; virtual void device_post_load() override; @@ -68,6 +71,8 @@ private: u16 m_mmu_a[4]; u8 m_mmu_b[5]; u32 m_mmu_base[0x40]; + + required_device m_kp69; }; diff --git a/src/devices/cpu/z80/kp69.cpp b/src/devices/cpu/z80/kp69.cpp new file mode 100644 index 00000000000..f64adb36269 --- /dev/null +++ b/src/devices/cpu/z80/kp69.cpp @@ -0,0 +1,453 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Kawasaki Steel (Kawatetsu) KP69 Interrupt Controller + + This macro cell is the sole provider of maskable interrupts for + KC80/KC82-based microcontrollers. It responds to the CPU's internal + IACK and EOI outputs (the latter associated with the RETI instruction) + with prioritized Mode 2 vectors and nested in-service lockouts. It + offers no support for polled operation or daisy-chaining other + interrupt controllers, but it does allow code to recognize spurious + interrupts. + + Each of the 16 interrupt sources may be programmed either as level- + triggered or edge-triggered, though the latter is required for + interrupts that are internal timer/counter outputs. These and the + interrupt vector register must be written first after a reset before + the mask and priority group registers can be defined, with no way of + returning to the initial mode once the vector has been set. + +***************************************************************************/ + +#include "emu.h" +#include "kp69.h" + +#define VERBOSE 0 +#include "logmacro.h" + +// device type definition +DEFINE_DEVICE_TYPE(KP69, kp69_device, "kp69", "Kawasaki Steel KP69 Interrupt Controller") + + +//------------------------------------------------- +// kp69_device - device type constructor +//------------------------------------------------- + +kp69_device::kp69_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, KP69, tag, owner, clock) + , device_z80daisy_interface(mconfig, *this) + , m_int_callback(*this) + , m_input_levels(0) + , m_irr(0) + , m_isr(0) + , m_illegal_state(false) + , m_ivr(0) + , m_ivr_written(false) + , m_imr(0xffff) + , m_ler(0) + , m_pgr(0) + , m_int_active(false) +{ +} + + +//------------------------------------------------- +// device_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time +//------------------------------------------------- + +void kp69_device::device_resolve_objects() +{ + // Resolve output callback + m_int_callback.resolve_safe(); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void kp69_device::device_start() +{ + // Register state for saving + save_item(NAME(m_input_levels)); + save_item(NAME(m_irr)); + save_item(NAME(m_isr)); + save_item(NAME(m_illegal_state)); + save_item(NAME(m_ivr)); + save_item(NAME(m_ivr_written)); + save_item(NAME(m_imr)); + save_item(NAME(m_ler)); + save_item(NAME(m_pgr)); + save_item(NAME(m_int_active)); +} + + +//------------------------------------------------- +// add_to_state - debug state interface for MCU +//------------------------------------------------- + +void kp69_device::add_to_state(device_state_interface &state, int index) +{ + state.state_add(index, "IRR", [this]() { return m_irr; }, [this](u16 data) { set_irr(data); }); + state.state_add(index + 1, "ISR", [this]() { return m_isr; }, [this](u16 data) { set_isr(data); }); + state.state_add(index + 2, "IVR", m_ivr).mask(0xe0); + state.state_add(index + 3, "LER", [this]() { return m_ler; }, [this](u16 data) { set_ler(data); }); + state.state_add(index + 4, "PGR", [this]() { return m_pgr; }, [this](u16 data) { set_pgr(data); }); + state.state_add(index + 5, "IMR", [this]() { return m_imr; }, [this](u16 data) { set_imr(data); }); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void kp69_device::device_reset() +{ + // Reset inputs to level mode + m_irr = m_input_levels; + m_ler = 0; + + // Mask all interrupts and end service + m_isr = 0; + m_imr = 0xffff; + m_illegal_state = false; + + // Reset priority groups + m_pgr = 0; + + // Allow LER and IVR to be written first + m_ivr_written = false; + + // Deassert interrupt output + set_int(false); +} + + +//------------------------------------------------- +// isrl_r - read lower 8 bits of ISR +//------------------------------------------------- + +u8 kp69_device::isrl_r() +{ + return m_isr & 0x00ff; +} + + +//------------------------------------------------- +// isrh_r - read upper 8 bits of ISR +//------------------------------------------------- + +u8 kp69_device::isrh_r() +{ + return (m_isr & 0xff00) >> 8; +} + + +//------------------------------------------------- +// imrl_r - read lower 8 bits of IMR +//------------------------------------------------- + +u8 kp69_device::imrl_r() +{ + return m_imr & 0x00ff; +} + + +//------------------------------------------------- +// imrh_r - read upper 8 bits of IMR +//------------------------------------------------- + +u8 kp69_device::imrh_r() +{ + return (m_imr & 0xff00) >> 8; +} + + +//------------------------------------------------- +// lerl_pgrl_w - write lower 8 bits of LER or PGR +//------------------------------------------------- + +void kp69_device::lerl_pgrl_w(u8 data) +{ + if (m_ivr_written) + set_pgr((m_pgr & 0xff00) | data); + else + set_ler((m_ler & 0xff00) | data); +} + + +//------------------------------------------------- +// lerh_pgrh_w - write upper 8 bits of LER or PGR +//------------------------------------------------- + +void kp69_device::lerh_pgrh_w(u8 data) +{ + if (m_ivr_written) + set_pgr(u16(data) << 8 | (m_pgr & 0x00ff)); + else + set_ler(u16(data) << 8 | (m_ler & 0x00ff)); +} + + +//------------------------------------------------- +// imrl_w - write lower 8 bits of IMR +//------------------------------------------------- + +void kp69_device::imrl_w(u8 data) +{ + if (!m_ivr_written) + logerror("%s: IMRL written before IVR\n", machine().describe_context()); + + set_imr((m_imr & 0xff00) | data); +} + + +//------------------------------------------------- +// ivr_imrh_w - write IVR or upper 8 bits of IMR +//------------------------------------------------- + +void kp69_device::ivr_imrh_w(u8 data) +{ + if (m_ivr_written) + set_imr(u16(data) << 8 | (m_imr & 0x00ff)); + else + { + m_ivr = data & 0xe0; + m_ivr_written = true; + } +} + + +//------------------------------------------------- +// int_active - determine whether or not the INT +// output is currently active +//------------------------------------------------- + +bool kp69_device::int_active() const +{ + if (m_illegal_state) + return false; + + // Compare priority of pending interrupt request with any being serviced + u16 requested = m_irr & ~m_imr; + if ((requested & m_pgr) != 0 || (m_isr & m_pgr) != 0) + return count_leading_zeros(u32(requested & m_pgr)) < count_leading_zeros(u32(m_isr & m_pgr)); + else if (requested != 0) + return count_leading_zeros(u32(requested)) < count_leading_zeros(u32(m_isr)); + else + return false; +} + + +//------------------------------------------------- +// set_int - update the INT output state +//------------------------------------------------- + +void kp69_device::set_int(bool active) +{ + if (m_int_active != active) + { + m_int_active = active; + m_int_callback(m_int_active ? ASSERT_LINE : CLEAR_LINE); + } +} + + +//------------------------------------------------- +// set_input_level - set the level state of one +// out of 16 interrupt inputs +//------------------------------------------------- + +void kp69_device::set_input_level(int level, bool state) +{ + if (!BIT(m_input_levels, level) && state) + { + m_input_levels |= 1 << level; + if (!BIT(m_irr, level)) + { + u16 old_ints = m_irr | m_isr; + m_irr |= 1 << level; + LOG("IRR[%d] asserted\n", level); + if (!m_illegal_state && !BIT(m_imr, level) && (1 << level) > (BIT(m_pgr, level) ? old_ints & m_pgr : old_ints)) + set_int(true); + } + } + else if (BIT(m_input_levels, level) && !state) + { + m_input_levels &= ~(1 << level); + if (!BIT(m_ler, level) && BIT(m_irr, level)) + { + m_irr &= ~(1 << level); + LOG("IRR[%d] cleared\n", level); + if (!m_illegal_state && !BIT(m_imr, level)) + set_int(int_active()); + } + } +} + + +//------------------------------------------------- +// set_irr - write a new value to the Interrupt +// Request Register (not accessible by software) +//------------------------------------------------- + +void kp69_device::set_irr(u16 data) +{ + bool update = !m_illegal_state && ((m_irr ^ data) & m_ler & ~m_imr) != 0; + m_irr = (data & m_ler) | (m_input_levels & ~m_ler); + if (update) + set_int(int_active()); +} + + +//------------------------------------------------- +// set_isr - write a new value to the In Service +// Register (not writable by software) +//------------------------------------------------- + +void kp69_device::set_isr(u16 data) +{ + m_isr = data; + set_int(int_active()); +} + + +//------------------------------------------------- +// set_imr - write a new value to the Interrupt +// Mask Register +//------------------------------------------------- + +void kp69_device::set_imr(u16 data) +{ + bool update = !m_illegal_state && (m_irr & ~(m_imr ^ data)) != 0; + m_imr = data; + if (update) + set_int(int_active()); +} + + +//------------------------------------------------- +// set_ler - write a new value to the Level/Edge +// Register +//------------------------------------------------- + +void kp69_device::set_ler(u16 data) +{ + u16 requested = m_irr & ~m_imr; + m_irr = (m_input_levels & ~data) | (m_irr & m_ler & data); + m_ler = data; + if (requested != (m_irr & ~m_imr)) + set_int(int_active()); +} + + +//------------------------------------------------- +// set_pgr - write a new value to the Priority +// Group Register +//------------------------------------------------- + +void kp69_device::set_pgr(u16 data) +{ + if (m_pgr != data) + { + m_pgr = data; + if (!m_illegal_state && m_isr != 0) + set_int(int_active()); + } +} + + +//------------------------------------------------- +// z80daisy_irq_state - return the overall IRQ +// state for this device +//------------------------------------------------- + +int kp69_device::z80daisy_irq_state() +{ + return m_int_active ? (Z80_DAISY_INT | Z80_DAISY_IEO) : Z80_DAISY_IEO; +} + + +//------------------------------------------------- +// z80daisy_irq_ack - acknowledge an IRQ and +// return the appropriate vector +//------------------------------------------------- + +int kp69_device::z80daisy_irq_ack() +{ + u16 requested = m_irr & ~m_imr; + int level = -1; + + // Restrict to high-priority interrupts if any of those are pending + if ((requested & m_pgr) != 0) + { + level = 31 - count_leading_zeros(u32(requested & m_pgr)); + assert(level >= 0 && level < 16); + if ((1 << level) < (m_isr & m_pgr)) + level = -1; + } + else if (requested != 0 && (m_isr & m_pgr) == 0) + { + level = 31 - count_leading_zeros(u32(requested)); + assert(level >= 0 && level < 16); + if ((1 << level) < m_isr) + level = -1; + } + + if (level != -1) + { + u8 vector = m_ivr | (level << 1); + if (BIT(m_ler, level)) + { + LOG("%s: IRR[%d] acknowledged and cleared (vector = %02X)\n", machine().describe_context(), level, vector); + m_irr &= ~(1 << level); + } + else + LOG("%s: IR[%d] acknowledged (vector = %02X)\n", machine().describe_context(), level, vector); + + m_isr |= 1 << level; + set_int(false); + + return vector; + } + + // Illegal interrupt operation: same vector as IR[0] but ISR[0] not set + LOG("%s: Illegal interrupt at IACK (vector = %02X)\n", machine().describe_context(), m_ivr); + m_illegal_state = true; + set_int(false); + return m_ivr; +} + + +//------------------------------------------------- +// z80daisy_irq_reti - clear the interrupt +// pending state to allow other interrupts through +//------------------------------------------------- + +void kp69_device::z80daisy_irq_reti() +{ + if (m_illegal_state) + { + LOG("%s: End of illegal interrupt\n", machine().describe_context()); + m_illegal_state = false; + } + else if (m_isr != 0) + { + int level = 31 - count_leading_zeros(u32((m_isr & m_pgr) != 0 ? (m_isr & m_pgr) : m_isr)); + assert(level >= 0 && level < 16); + + m_isr &= ~(1 << level); + LOG("%s: EOI for ISR[%d]\n", machine().describe_context(), level); + } + else + { + logerror("%s: RETI before interrupt acknowledged\n", machine().describe_context()); + return; + } + + set_int(int_active()); +} diff --git a/src/devices/cpu/z80/kp69.h b/src/devices/cpu/z80/kp69.h new file mode 100644 index 00000000000..03b03b2ee92 --- /dev/null +++ b/src/devices/cpu/z80/kp69.h @@ -0,0 +1,92 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*************************************************************************** + + Kawasaki Steel (Kawatetsu) KP69 Interrupt Controller + +***************************************************************************/ + +#ifndef MAME_CPU_Z80_KP69_H +#define MAME_CPU_Z80_KP69_H + +#pragma once + +#include "machine/z80daisy.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class kp69_device : public device_t, public device_z80daisy_interface +{ +public: + // construction/destruction + kp69_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); + + // callback to CPU + auto int_callback() { return m_int_callback.bind(); } + + // read handlers + u8 isrl_r(); + u8 isrh_r(); + u8 imrl_r(); + u8 imrh_r(); + + // write handlers + void lerl_pgrl_w(u8 data); + void lerh_pgrh_w(u8 data); + void imrl_w(u8 data); + void ivr_imrh_w(u8 data); + + // interrupt inputs + template DECLARE_WRITE_LINE_MEMBER(ir_w) + { + static_assert(N >= 0 && N < 16, "Invalid level"); + set_input_level(N, state); + } + + void add_to_state(device_state_interface &state, int index); + +protected: + // device-level overrides + virtual void device_resolve_objects() override; + virtual void device_start() override; + virtual void device_reset() override; + + // device_z80daisy_interface overrides + virtual int z80daisy_irq_state() override; + virtual int z80daisy_irq_ack() override; + virtual void z80daisy_irq_reti() override; + +private: + // internal helpers + bool int_active() const; + void set_int(bool active); + void set_input_level(int level, bool state); + void set_irr(u16 data); + void set_isr(u16 data); + void set_imr(u16 data); + void set_ler(u16 data); + void set_pgr(u16 data); + + // callback object + devcb_write_line m_int_callback; + + // internal state + u16 m_input_levels; + u16 m_irr; + u16 m_isr; + bool m_illegal_state; + u8 m_ivr; + bool m_ivr_written; + u16 m_imr; + u16 m_ler; + u16 m_pgr; + bool m_int_active; +}; + +// device type declaration +DECLARE_DEVICE_TYPE(KP69, kp69_device) + +#endif // MAME_CPU_Z80_KP69_H diff --git a/src/mame/drivers/ddenlovr.cpp b/src/mame/drivers/ddenlovr.cpp index 16b0e7c0f11..e56cb13e93a 100644 --- a/src/mame/drivers/ddenlovr.cpp +++ b/src/mame/drivers/ddenlovr.cpp @@ -254,10 +254,8 @@ private: DECLARE_WRITE_LINE_MEMBER(ddenlovr_irq); DECLARE_WRITE_LINE_MEMBER(mmpanic_irq); DECLARE_WRITE_LINE_MEMBER(mmpanic_rtc_irq); - DECLARE_WRITE_LINE_MEMBER(hanakanz_irq); DECLARE_WRITE_LINE_MEMBER(funkyfig_sound_irq); DECLARE_WRITE_LINE_MEMBER(mjflove_irq); - DECLARE_WRITE_LINE_MEMBER(hanakanz_rtc_irq); DECLARE_WRITE_LINE_MEMBER(mjflove_rtc_irq); void ddenlovr_bgcolor_w(uint8_t data); @@ -9992,34 +9990,6 @@ void ddenlovr_state::mmpanic(machine_config &config) 0xe2 is from the 6242RTC */ -WRITE_LINE_MEMBER(ddenlovr_state::hanakanz_irq) -{ - if (!state) - return; - - /* I haven't found a irq ack register, so I need this kludge to - make sure I don't lose any interrupt generated by the blitter, - otherwise quizchq would lock up. */ - //if (downcast(m_maincpu)->input_state(0)) - // return; - - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 0xe0); // Z80 -} - -WRITE_LINE_MEMBER(ddenlovr_state::hanakanz_rtc_irq) -{ - if (!state) - return; - - /* I haven't found a irq ack register, so I need this kludge to - make sure I don't lose any interrupt generated by the blitter, - otherwise quizchq would lock up. */ - //if (downcast(drvm_maincpu)->input_state(0)) - // return; - - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 0xe2); // Z80 -} - void ddenlovr_state::hanakanz(machine_config &config) { /* basic machine hardware */ @@ -10038,7 +10008,7 @@ void ddenlovr_state::hanakanz(machine_config &config) m_screen->set_visarea(0, 336-1, 5, 256-11-1); m_screen->set_screen_update(FUNC(ddenlovr_state::screen_update_ddenlovr)); m_screen->set_video_attributes(VIDEO_ALWAYS_UPDATE); - m_screen->screen_vblank().set(FUNC(ddenlovr_state::hanakanz_irq)); + m_screen->screen_vblank().set("maincpu:kp69", FUNC(kp69_device::ir_w<0>)); PALETTE(config, m_palette, palette_device::BLACK).set_entries(0x200); @@ -10054,7 +10024,7 @@ void ddenlovr_state::hanakanz(machine_config &config) /* devices */ msm6242_device &rtc(MSM6242(config, "rtc", XTAL(32'768))); - rtc.out_int_handler().set(FUNC(ddenlovr_state::hanakanz_rtc_irq)); + rtc.out_int_handler().set("maincpu:kp69", FUNC(kp69_device::ir_w<1>)); } void ddenlovr_state::hkagerou(machine_config &config) @@ -10083,7 +10053,7 @@ void ddenlovr_state::kotbinyo(machine_config &config) m_screen->set_visarea(0, 336-1-1, 1+4, 256-15-1+4); m_screen->set_screen_update(FUNC(ddenlovr_state::screen_update_ddenlovr)); m_screen->set_video_attributes(VIDEO_ALWAYS_UPDATE); - m_screen->screen_vblank().set(FUNC(ddenlovr_state::hanakanz_irq)); + m_screen->screen_vblank().set("maincpu:kp69", FUNC(kp69_device::ir_w<0>)); PALETTE(config, m_palette, palette_device::BLACK).set_entries(0x200); @@ -10098,7 +10068,7 @@ void ddenlovr_state::kotbinyo(machine_config &config) m_oki->add_route(ALL_OUTPUTS, "mono", 0.80); /* devices */ -// MSM6242(config, "rtc", XTAL(32'768)).out_int_handler().set(FUNC(ddenlovr_state::hanakanz_rtc_irq)); +// MSM6242(config, "rtc", XTAL(32'768)).out_int_handler().set("maincpu:kp69", FUNC(kp69_device::ir_w<1>)); } void ddenlovr_state::kotbinsp(machine_config &config) @@ -10486,7 +10456,7 @@ void ddenlovr_state::jongtei(machine_config &config) m_screen->set_visarea(0, 336-1, 5, 256-11-1); m_screen->set_screen_update(FUNC(ddenlovr_state::screen_update_ddenlovr)); m_screen->set_video_attributes(VIDEO_ALWAYS_UPDATE); - m_screen->screen_vblank().set(FUNC(ddenlovr_state::hanakanz_irq)); + m_screen->screen_vblank().set("maincpu:kp69", FUNC(kp69_device::ir_w<0>)); PALETTE(config, m_palette, palette_device::BLACK).set_entries(0x200); @@ -10502,7 +10472,7 @@ void ddenlovr_state::jongtei(machine_config &config) OKIM6295(config, m_oki, XTAL(28'636'363) / 28, okim6295_device::PIN7_HIGH).add_route(ALL_OUTPUTS, "mono", 0.80); /* devices */ - MSM6242(config, "rtc", XTAL(32'768)).out_int_handler().set(FUNC(ddenlovr_state::hanakanz_rtc_irq)); + MSM6242(config, "rtc", XTAL(32'768)).out_int_handler().set("maincpu:kp69", FUNC(kp69_device::ir_w<1>)); } void ddenlovr_state::mjgnight(machine_config &config) @@ -10700,7 +10670,7 @@ void ddenlovr_state::daimyojn(machine_config &config) m_screen->set_visarea(0, 336-1-1, 1, 256-15-1); m_screen->set_screen_update(FUNC(ddenlovr_state::screen_update_ddenlovr)); m_screen->set_video_attributes(VIDEO_ALWAYS_UPDATE); - m_screen->screen_vblank().set(FUNC(ddenlovr_state::hanakanz_irq)); + m_screen->screen_vblank().set("maincpu:kp69", FUNC(kp69_device::ir_w<0>)); PALETTE(config, m_palette, palette_device::BLACK).set_entries(0x200); @@ -10714,7 +10684,7 @@ void ddenlovr_state::daimyojn(machine_config &config) OKIM6295(config, m_oki, XTAL(28'636'363) / 28, okim6295_device::PIN7_HIGH).add_route(ALL_OUTPUTS, "mono", 0.80); /* devices */ - MSM6242(config, "rtc", XTAL(32'768)).out_int_handler().set(FUNC(ddenlovr_state::hanakanz_rtc_irq)); + MSM6242(config, "rtc", XTAL(32'768)).out_int_handler().set("maincpu:kp69", FUNC(kp69_device::ir_w<1>)); } diff --git a/src/mame/drivers/sigmab98.cpp b/src/mame/drivers/sigmab98.cpp index d569a04070c..c94917dbffb 100644 --- a/src/mame/drivers/sigmab98.cpp +++ b/src/mame/drivers/sigmab98.cpp @@ -190,9 +190,9 @@ public: sigmab98_state(const machine_config &mconfig, device_type type, const char *tag) : sigmab98_base_state(mconfig, type, tag) , m_maincpu(*this, "maincpu") + , m_hopper(*this, "hopper") , m_nvramdev(*this, "nvram") , m_eeprom(*this, "eeprom") - , m_hopper(*this, "hopper") , m_nvram(*this, "nvram") , m_leds(*this, "led%u", 0U) { } @@ -211,6 +211,8 @@ public: void init_ucytokyu(); protected: + virtual void machine_reset() override; + void gegege_regs_w(offs_t offset, uint8_t data); uint8_t gegege_regs_r(offs_t offset); void gegege_regs2_w(offs_t offset, uint8_t data); @@ -231,8 +233,6 @@ protected: void show_outputs(); void eeprom_w(uint8_t data); - DECLARE_MACHINE_RESET(sigmab98); - INTERRUPT_GEN_MEMBER(sigmab98_vblank_interrupt); void dashhero_io_map(address_map &map); @@ -245,11 +245,11 @@ protected: // Required devices required_device m_maincpu; + required_device m_hopper; // Optional devices optional_device m_nvramdev; // battery backed RAM (should be required, but dashhero breaks with it) optional_device m_eeprom; - optional_device m_hopper; // Shared pointers required_shared_ptr m_nvram; @@ -287,6 +287,9 @@ public: void init_lufykzku(); void lufykzku(machine_config &config); +protected: + virtual void machine_reset() override; + private: required_device m_watchdog; required_device_array m_dsw_shifter; @@ -302,8 +305,6 @@ private: void lufykzku_c8_w(uint8_t data); void lufykzku_watchdog_w(uint8_t data); - DECLARE_MACHINE_RESET(lufykzku); - TIMER_DEVICE_CALLBACK_MEMBER(lufykzku_irq); void lufykzku_io_map(address_map &map); @@ -343,7 +344,6 @@ protected: private: TIMER_DEVICE_CALLBACK_MEMBER(sammymdl_irq); - uint8_t unk_34_r(); uint8_t coin_counter_r(); void coin_counter_w(uint8_t data); uint8_t leds_r(); @@ -1323,12 +1323,6 @@ void sammymdl_state::eeprom_w(uint8_t data) logerror("%s: unknown eeeprom bits written %02x\n", machine().describe_context(), data); } -uint8_t sammymdl_state::unk_34_r() -{ - // mask 0x01? - return 0x01; -} - uint8_t sigmab98_base_state::vblank_r() { // mask 0x04 must be set before writing sprite list @@ -1433,7 +1427,6 @@ void sammymdl_state::animalc_io(address_map &map) map(0x30, 0x30).portr("BUTTON"); map(0x31, 0x31).rw(FUNC(sammymdl_state::coin_counter_r), FUNC(sammymdl_state::coin_counter_w)); map(0x32, 0x32).rw(FUNC(sammymdl_state::leds_r), FUNC(sammymdl_state::leds_w)); - map(0x34, 0x34).r(FUNC(sammymdl_state::unk_34_r)); map(0x90, 0x90).w("oki", FUNC(okim9810_device::write)); map(0x91, 0x91).w("oki", FUNC(okim9810_device::tmp_register_w)); map(0x92, 0x92).r("oki", FUNC(okim9810_device::read)); @@ -1905,7 +1898,7 @@ INPUT_PORTS_END Sigma B-98 Games ***************************************************************************/ -MACHINE_RESET_MEMBER(sigmab98_state,sigmab98) +void sigmab98_state::machine_reset() { m_rombank = 0; membank("rombank")->set_entry(0); @@ -1926,8 +1919,6 @@ void sigmab98_state::sigmab98(machine_config &config) m_maincpu->set_addrmap(AS_IO, &sigmab98_state::gegege_io_map); m_maincpu->set_vblank_int("screen", FUNC(sigmab98_state::sigmab98_vblank_interrupt)); - MCFG_MACHINE_RESET_OVERRIDE(sigmab98_state, sigmab98) - NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); EEPROM_93C46_16BIT(config, "eeprom"); @@ -1988,7 +1979,7 @@ void sigmab98_state::dashhero(machine_config &config) Banpresto Medal Games ***************************************************************************/ -MACHINE_RESET_MEMBER(lufykzku_state,lufykzku) +void lufykzku_state::machine_reset() { m_rombank = 0; membank("romrambank")->set_entry(0); @@ -2013,8 +2004,6 @@ void lufykzku_state::lufykzku(machine_config &config) m_maincpu->set_addrmap(AS_IO, &lufykzku_state::lufykzku_io_map); TIMER(config, "scantimer").configure_scanline(FUNC(lufykzku_state::lufykzku_irq), "screen", 0, 1); - MCFG_MACHINE_RESET_OVERRIDE(lufykzku_state, lufykzku) - NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); // battery backed RAM // No EEPROM @@ -2061,15 +2050,20 @@ void lufykzku_state::lufykzku(machine_config &config) TIMER_DEVICE_CALLBACK_MEMBER(sammymdl_state::sammymdl_irq) { int scanline = param; + uint16_t irqs = 0; if (scanline == 240) - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_vblank_vector); // Z80 + irqs |= 1 << ((m_vblank_vector & 0x1e) >> 1); if (scanline == 128) - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_timer0_vector); // Z80 + irqs |= 1 << ((m_timer0_vector & 0x1e) >> 1); if (scanline == 32) - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, m_timer1_vector); // Z80 + irqs |= 1 << ((m_timer1_vector & 0x1e) >> 1); + + // FIXME: this is not much less of a hack than HOLD_LINE + if (irqs != 0) + m_maincpu->set_state_int(kl5c80a12_device::KP69_IRR, m_maincpu->state_int(kl5c80a12_device::KP69_IRR) | irqs); } void sammymdl_state::sammymdl(machine_config &config)