diff options
Diffstat (limited to 'src/devices/machine')
-rw-r--r-- | src/devices/machine/gt913_kbd.cpp | 14 | ||||
-rw-r--r-- | src/devices/machine/gt913_kbd.h | 16 | ||||
-rw-r--r-- | src/devices/machine/vic_pl192.cpp | 375 | ||||
-rw-r--r-- | src/devices/machine/vic_pl192.h | 99 |
4 files changed, 427 insertions, 77 deletions
diff --git a/src/devices/machine/gt913_kbd.cpp b/src/devices/machine/gt913_kbd.cpp index b22197153b8..ba7a2ff521c 100644 --- a/src/devices/machine/gt913_kbd.cpp +++ b/src/devices/machine/gt913_kbd.cpp @@ -28,15 +28,15 @@ DEFINE_DEVICE_TYPE(GT913_KBD_HLE, gt913_kbd_hle_device, "gt913_kbd_hle", "Casio gt913_kbd_hle_device::gt913_kbd_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, GT913_KBD_HLE, tag, owner, clock), - device_matrix_keyboard_interface(mconfig, *this, "KO0", "KO1", "KO2", "KO3", "KO4", "KO5", "KO6", "KO7", "KO8", "KO9", "KO10", "KO11", "KO12"), - m_intc(nullptr), m_intc_tag(nullptr), m_irq(0), - m_velocity(*this, "VELOCITY") + device_matrix_keyboard_interface(mconfig, *this, "FI0", "FI1", "FI2", "FI3", "FI4", "FI5", "FI6", "FI7", "FI8", "FI9", "FI10", "KI0", "KI1", "KI2"), + m_velocity(*this, "VELOCITY"), + m_irq_cb(*this) { } void gt913_kbd_hle_device::device_start() { - m_intc = siblingdevice<h8_intc_device>(m_intc_tag); + m_irq_cb.resolve_safe(); save_item(NAME(m_status)); save_item(NAME(m_fifo)); @@ -51,7 +51,7 @@ void gt913_kbd_hle_device::device_reset() m_fifo_read = m_fifo_write = 0; reset_key_state(); - start_processing(attotime::from_hz(1200)); + start_processing(attotime::from_hz(9600)); } void gt913_kbd_hle_device::key_add(uint8_t row, uint8_t column, int state) @@ -75,7 +75,9 @@ void gt913_kbd_hle_device::update_status() m_status |= 0x8000; if (BIT(m_status, 15) && BIT(m_status, 14)) - m_intc->internal_interrupt(m_irq); + m_irq_cb(1); + else + m_irq_cb(0); } uint16_t gt913_kbd_hle_device::read() diff --git a/src/devices/machine/gt913_kbd.h b/src/devices/machine/gt913_kbd.h index 3823442ff86..3bf2ced327e 100644 --- a/src/devices/machine/gt913_kbd.h +++ b/src/devices/machine/gt913_kbd.h @@ -9,7 +9,6 @@ #pragma once -#include "cpu/h8/h8_intc.h" #include "keyboard.h" //************************************************************************** @@ -18,17 +17,13 @@ // ======================> gt913_kbd_hle_device -class gt913_kbd_hle_device : public device_t, protected device_matrix_keyboard_interface<13> +class gt913_kbd_hle_device : public device_t, protected device_matrix_keyboard_interface<14> { public: // construction/destruction gt913_kbd_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); - gt913_kbd_hle_device(const machine_config &mconfig, const char *tag, device_t *owner, const char *intc, int irq) - : gt913_kbd_hle_device(mconfig, tag, owner, 0) - { - m_intc_tag = intc; - m_irq = irq; - } + + auto irq_cb() { return m_irq_cb.bind(); } uint16_t read(); void status_w(uint16_t data); @@ -46,11 +41,10 @@ protected: void key_add(uint8_t row, uint8_t column, int state); void update_status(); private: - h8_intc_device *m_intc; - const char *m_intc_tag; - int m_irq; optional_ioport m_velocity; + devcb_write_line m_irq_cb; + uint16_t m_status; uint8_t m_fifo[16]; uint8_t m_fifo_read, m_fifo_write; diff --git a/src/devices/machine/vic_pl192.cpp b/src/devices/machine/vic_pl192.cpp index 5c37d03abee..bd7c4de4e2c 100644 --- a/src/devices/machine/vic_pl192.cpp +++ b/src/devices/machine/vic_pl192.cpp @@ -1,10 +1,9 @@ // license:BSD-3-Clause -// copyright-holders:Melissa Goad +// copyright-holders:Devin Acker, Melissa Goad -// ARM PrimeCell PL192 VIC emulation +// ARM PrimeCell PL910/PL192 VIC emulation #include "emu.h" -#include "machine/bankdev.h" #include "machine/vic_pl192.h" #define LOG_GENERAL (1U << 0) @@ -12,19 +11,22 @@ #define VERBOSE (LOG_GENERAL) #include "logmacro.h" -void vic_pl192_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +DEFINE_DEVICE_TYPE(PL190_VIC, vic_pl190_device, "vic_pl190", "ARM PL190 VIC") +DEFINE_DEVICE_TYPE(UPD800468_VIC, vic_upd800468_device, "vic_upd800468", "NEC uPD800468 VIC") +DEFINE_DEVICE_TYPE(PL192_VIC, vic_pl192_device, "vic_pl192", "ARM PL192 VIC") + +void vic_pl190_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { - if(u32 intrs = (raw_intr | soft_intr) & intr_en) - { - if(intrs & intr_select) m_out_fiq_func(1); - else m_out_fiq_func(0); + u32 intrs = (raw_intr | soft_intr) & intr_en; - if(intrs & ~intr_select) m_out_irq_func(1); - else m_out_irq_func(0); - } + if (intrs & intr_select) m_out_fiq_func(1); + else m_out_fiq_func(0); + + if (intrs & ~intr_select & priority_mask) m_out_irq_func(1); + else m_out_irq_func(0); } -void vic_pl192_device::set_irq_line(int irq, int state) +void vic_pl190_device::set_irq_line(int irq, int state) { u32 mask = (1 << irq); @@ -40,22 +42,173 @@ void vic_pl192_device::set_irq_line(int irq, int state) timer_set(attotime::zero, TIMER_CHECK_IRQ); } -void vic_pl192_device::map(address_map &map) +u32 vic_pl190_device::irq_status_r() +{ + return raw_intr & ~intr_select; +} + +u32 vic_pl190_device::fiq_status_r() +{ + return raw_intr & intr_select; +} + +u32 vic_pl190_device::raw_intr_r() +{ + return raw_intr; +} + +u32 vic_pl190_device::int_select_r() +{ + return intr_select; +} + +void vic_pl190_device::int_select_w(u32 data) +{ + intr_select = data; + timer_set(attotime::zero, TIMER_CHECK_IRQ); +} + +u32 vic_pl190_device::int_enable_r() +{ + return intr_en; +} + +void vic_pl190_device::int_enable_w(u32 data) +{ + intr_en |= data; + timer_set(attotime::zero, TIMER_CHECK_IRQ); +} + +void vic_pl190_device::int_en_clear_w(u32 data) +{ + intr_en &= ~data; + timer_set(attotime::zero, TIMER_CHECK_IRQ); +} + +u32 vic_pl190_device::soft_int_r() +{ + return soft_intr; +} + +void vic_pl190_device::soft_int_w(u32 data) +{ + soft_intr |= data; + timer_set(attotime::zero, TIMER_CHECK_IRQ); +} + +void vic_pl190_device::soft_int_clear_w(u32 data) +{ + soft_intr &= ~data; + timer_set(attotime::zero, TIMER_CHECK_IRQ); +} + +u8 vic_pl190_device::protection_r() +{ + return protection; +} + +void vic_pl190_device::protection_w(u8 data) { - map(0x000, 0x003).lr32([this](offs_t offset){ return raw_intr & ~intr_select; }, "irq_status"); //IRQ_STATUS - map(0x004, 0x007).lr32([this](offs_t offset){ return raw_intr & intr_select; }, "fiq_status"); //FIQ_STATUS - map(0x008, 0x00b).lr32([this](offs_t offset){ return raw_intr; }, "raw_intr"); - map(0x00c, 0x00f).lrw32(NAME([this](offs_t offset){ return intr_select; }), NAME([this](offs_t offset, u32 data){ intr_select = data; timer_set(attotime::zero, TIMER_CHECK_IRQ); })); - map(0x010, 0x013).lrw32(NAME([this](offs_t offset){ return intr_en; }), NAME([this](offs_t offset, u32 data){ intr_en = data; timer_set(attotime::zero, TIMER_CHECK_IRQ); })); - map(0x014, 0x017).lw32([this](u32 data){ intr_en &= ~data; }, "intr_en_clear"); - map(0x018, 0x01b).lrw32(NAME([this](offs_t offset){ return soft_intr; }), NAME([this](offs_t offset, u32 data){ soft_intr = data; timer_set(attotime::zero, TIMER_CHECK_IRQ); })); - map(0x01c, 0x01f).lw32([this](u32 data){ soft_intr &= ~data; }, "soft_intr_clear"); - map(0x020, 0x020).lrw8(NAME([this](offs_t offset){ return protection; }), NAME([this](offs_t offset, u8 data){ protection = data & 1; })).umask32(0x000000ff); - map(0x024, 0x025).lrw8(NAME([this](offs_t offset){ return sw_priority_mask; }), NAME([this](offs_t offset, u16 data){ sw_priority_mask = data; })).umask32(0x0000ffff); - map(0x028, 0x028).lrw8(NAME([this](offs_t offset){ return daisy_priority; }), NAME([this](offs_t offset, u8 data){ daisy_priority = data & 0xf; })).umask32(0x000000ff); - map(0x100, 0x17f).lrw32(NAME([this](offs_t offset){ return vectaddr[(offset & 0x7c) >> 2]; }), NAME([this](offs_t offset, u32 data){ vectaddr[(offset & 0x7c) >> 2] = data; })); - map(0x200, 0x27f).lrw8(NAME([this](offs_t offset){ return vectprio[(offset & 0x7c) >> 2]; }), NAME([this](offs_t offset, u32 data){ vectprio[(offset & 0x7c) >> 2] = data & 0xf; })); - map(0xf00, 0xf03).lrw32(NAME([this](offs_t offset){ return vicaddress; }), NAME([this](offs_t offset, u32 data){ vectaddr[(offset & 0x7c) >> 2] = data; })); + protection = BIT(data, 0); +} + +u32 vic_pl190_device::cur_vect_addr_r() +{ + if (!machine().side_effects_disabled()) + update_vector(); + + return vicaddress; +} + +void vic_pl190_device::cur_vect_addr_w(u32 data) +{ + priority_mask = ~0; + priority = ~0; + timer_set(attotime::zero, TIMER_CHECK_IRQ); +} + +u32 vic_pl190_device::def_vect_addr_r() +{ + return defaddress; +} + +void vic_pl190_device::def_vect_addr_w(u32 data) +{ + defaddress = data; +} + +u32 vic_pl190_device::vect_addr_r(offs_t offset) +{ + return vectaddr[offset]; +} + +void vic_pl190_device::vect_addr_w(offs_t offset, u32 data) +{ + vectaddr[offset] = data; +} + +u32 vic_pl190_device::vect_ctl_r(offs_t offset) +{ + return vectctl[offset]; +} + +void vic_pl190_device::vect_ctl_w(offs_t offset, u32 data) +{ + vectctl[offset] = data; +} + +void vic_pl190_device::update_vector() +{ + u32 intrs = (raw_intr | soft_intr) & intr_en & ~intr_select; + u32 newmask = 0; + + for (u8 i = 0; i < std::min(priority, num_vectors); i++) + { + u8 irq = vectctl[i] & 0x1f; + + if (!BIT(vectctl[i], 5)) + { + // vector is disabled + continue; + } + else if (BIT(intrs, irq)) + { + // this interrupt is enabled and pending + // take it and update priority_mask to only allow higher priority interrupts + priority_mask = newmask; + priority = i; + vicaddress = vectaddr[i]; + return; + } + else + { + // interrupt isn't pending, but it's higher priority + // allow it to be taken later + newmask |= (1 << irq); + } + } + + // no vectored interrupt taken, use the default + priority_mask = ~0; + priority = ~0; + vicaddress = defaddress; +} + +void vic_pl190_device::map(address_map &map) +{ + map(0x000, 0x003).r(FUNC(vic_pl190_device::irq_status_r)); + map(0x004, 0x007).r(FUNC(vic_pl190_device::fiq_status_r)); + map(0x008, 0x00b).r(FUNC(vic_pl190_device::raw_intr_r)); + map(0x00c, 0x00f).rw(FUNC(vic_pl190_device::int_select_r), FUNC(vic_pl190_device::int_select_w)); + map(0x010, 0x013).rw(FUNC(vic_pl190_device::int_enable_r), FUNC(vic_pl190_device::int_enable_w)); + map(0x014, 0x017).w(FUNC(vic_pl190_device::int_en_clear_w)); + map(0x018, 0x01b).rw(FUNC(vic_pl190_device::soft_int_r), FUNC(vic_pl190_device::soft_int_w)); + map(0x01c, 0x01f).w(FUNC(vic_pl190_device::soft_int_clear_w)); + map(0x020, 0x020).rw(FUNC(vic_pl190_device::protection_r), FUNC(vic_pl190_device::protection_w)).umask32(0x000000ff); + map(0x030, 0x033).rw(FUNC(vic_pl190_device::cur_vect_addr_r), FUNC(vic_pl190_device::cur_vect_addr_w)); + map(0x034, 0x037).rw(FUNC(vic_pl190_device::def_vect_addr_r), FUNC(vic_pl190_device::def_vect_addr_w)); + map(0x100, 0x13f).rw(FUNC(vic_pl190_device::vect_addr_r), FUNC(vic_pl190_device::vect_addr_w)); + map(0x200, 0x23f).rw(FUNC(vic_pl190_device::vect_ctl_r), FUNC(vic_pl190_device::vect_ctl_w)); map(0xfe0, 0xfe0).lr8([this](offs_t offset){ return periph_id[0]; }, "periph_id0").umask32(0x000000ff); map(0xfe4, 0xfe4).lr8([this](offs_t offset){ return periph_id[1]; }, "periph_id1").umask32(0x000000ff); map(0xfe8, 0xfe8).lr8([this](offs_t offset){ return periph_id[2]; }, "periph_id2").umask32(0x000000ff); @@ -66,65 +219,191 @@ void vic_pl192_device::map(address_map &map) map(0xffc, 0xffc).lr8([this](offs_t offset){ return pcell_id[3]; }, "pcell_id3").umask32(0x000000ff); } -device_memory_interface::space_config_vector vic_pl192_device::memory_space_config() const +device_memory_interface::space_config_vector vic_pl190_device::memory_space_config() const { return space_config_vector{ std::make_pair(0, &m_mmio_config) }; } -void vic_pl192_device::device_resolve_objects() +void vic_pl190_device::device_resolve_objects() { // resolve callbacks m_out_irq_func.resolve_safe(); m_out_fiq_func.resolve_safe(); } -void vic_pl192_device::device_start() +void vic_pl190_device::device_start() { save_item(NAME(raw_intr)); save_item(NAME(intr_select)); save_item(NAME(intr_en)); save_item(NAME(soft_intr)); save_item(NAME(vectaddr)); + save_item(NAME(defaddress)); save_item(NAME(vicaddress)); + save_item(NAME(priority_mask)); + save_item(NAME(priority)); save_item(NAME(protection)); - save_item(NAME(sw_priority_mask)); - save_item(NAME(daisy_priority)); - save_item(NAME(vectprio)); } -void vic_pl192_device::device_reset() +void vic_pl190_device::device_reset() { - raw_intr = intr_select = intr_en = soft_intr = vicaddress = protection = 0; - sw_priority_mask = 0xffff; - daisy_priority = 0xf; + raw_intr = intr_select = intr_en = soft_intr = 0; + defaddress = vicaddress = protection = 0; - for(int i = 0; i < 32; i++) - { - vectaddr[i] = 0; - } + priority_mask = ~0; + priority = ~0; for(int i = 0; i < 32; i++) { - vectprio[i] = 0xf; + vectaddr[i] = 0; + vectctl[i] = 0; } } -DEFINE_DEVICE_TYPE(PL192_VIC, vic_pl192_device, "vic_pl192", "ARM PL192 VIC") - -vic_pl192_device::vic_pl192_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +vic_pl190_device::vic_pl190_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) , device_memory_interface(mconfig, *this) + , num_vectors(16) + , periph_id{0x92, 0x11, 0x04, 0x00} + , pcell_id{0x0d, 0xf0, 0x05, 0xb1} , m_mmio_config("mmio", ENDIANNESS_LITTLE, 32, 32, 0) , m_out_irq_func(*this) , m_out_fiq_func(*this) - , periph_id{0x92, 0x11, 0x04, 0x00} - , pcell_id{0x0d, 0xf0, 0x05, 0xb1} { } +vic_pl190_device::vic_pl190_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : vic_pl190_device(mconfig, PL190_VIC, tag, owner, clock) +{ +} + + + + +void vic_upd800468_device::int_clear_w(u32 data) +{ + raw_intr &= ~data; + timer_set(attotime::zero, TIMER_CHECK_IRQ); +} + +void vic_upd800468_device::map(address_map &map) +{ + vic_pl190_device::map(map); + + map(0x100, 0x17f).rw(FUNC(vic_pl190_device::vect_addr_r), FUNC(vic_pl190_device::vect_addr_w)); + map(0x200, 0x27f).rw(FUNC(vic_pl190_device::vect_ctl_r), FUNC(vic_pl190_device::vect_ctl_w)); + map(0x2c8, 0x2cb).w(FUNC(vic_upd800468_device::int_clear_w)); +} + +vic_upd800468_device::vic_upd800468_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : vic_pl190_device(mconfig, UPD800468_VIC, tag, owner, clock) +{ + num_vectors = 32; +} + + + + +u16 vic_pl192_device::sw_priority_r() +{ + return sw_priority_mask; +} + +void vic_pl192_device::sw_priority_w(u16 data) +{ + sw_priority_mask = data; +} + +u8 vic_pl192_device::daisy_priority_r() +{ + return daisy_priority; +} + +void vic_pl192_device::daisy_priority_w(u8 data) +{ + daisy_priority = data & 0xf; +} + +void vic_pl192_device::update_vector() +{ + u32 intrs = (raw_intr | soft_intr) & intr_en & ~intr_select; + u32 newmask = 0; + + // see if there's a higher priority active interrupt to take + for (u8 i = 0; i < num_vectors; i++) + { + u8 new_prio = vectctl[i] & 0xf; + if (BIT(sw_priority_mask, new_prio) && BIT(intrs, i) && new_prio < priority) + { + // this interrupt is enabled and pending, take it + priority = new_prio; + vicaddress = vectaddr[i]; + } + } + + // update priority_mask to only allow higher priority interrupts + for (u8 i = 0; i < num_vectors; i++) + { + u8 new_prio = vectctl[i] & 0xf; + if (BIT(sw_priority_mask, new_prio) && new_prio < priority) + { + newmask |= (1 << i); + } + } + priority_mask = newmask; +} + +void vic_pl192_device::map(address_map &map) +{ + map(0x000, 0x003).r(FUNC(vic_pl190_device::irq_status_r)); + map(0x004, 0x007).r(FUNC(vic_pl190_device::fiq_status_r)); + map(0x008, 0x00b).r(FUNC(vic_pl190_device::raw_intr_r)); + map(0x00c, 0x00f).rw(FUNC(vic_pl190_device::int_select_r), FUNC(vic_pl190_device::int_select_w)); + map(0x010, 0x013).rw(FUNC(vic_pl190_device::int_enable_r), FUNC(vic_pl190_device::int_enable_w)); + map(0x014, 0x017).w(FUNC(vic_pl190_device::int_en_clear_w)); + map(0x018, 0x01b).rw(FUNC(vic_pl190_device::soft_int_r), FUNC(vic_pl190_device::soft_int_w)); + map(0x01c, 0x01f).w(FUNC(vic_pl190_device::soft_int_clear_w)); + map(0x020, 0x020).rw(FUNC(vic_pl190_device::protection_r), FUNC(vic_pl190_device::protection_w)).umask32(0x000000ff); + map(0x024, 0x025).rw(FUNC(vic_pl192_device::sw_priority_r), FUNC(vic_pl192_device::sw_priority_w)).umask32(0x0000ffff); + map(0x028, 0x028).rw(FUNC(vic_pl192_device::daisy_priority_r), FUNC(vic_pl192_device::daisy_priority_w)).umask32(0x000000ff); + map(0x100, 0x17f).rw(FUNC(vic_pl190_device::vect_addr_r), FUNC(vic_pl190_device::vect_addr_w)); + map(0x200, 0x27f).rw(FUNC(vic_pl190_device::vect_ctl_r), FUNC(vic_pl190_device::vect_ctl_w)); + map(0xf00, 0xf03).rw(FUNC(vic_pl190_device::cur_vect_addr_r), FUNC(vic_pl190_device::cur_vect_addr_w)); + map(0xfe0, 0xfe0).lr8([this](offs_t offset) { return periph_id[0]; }, "periph_id0").umask32(0x000000ff); + map(0xfe4, 0xfe4).lr8([this](offs_t offset) { return periph_id[1]; }, "periph_id1").umask32(0x000000ff); + map(0xfe8, 0xfe8).lr8([this](offs_t offset) { return periph_id[2]; }, "periph_id2").umask32(0x000000ff); + map(0xfec, 0xfec).lr8([this](offs_t offset) { return periph_id[3]; }, "periph_id3").umask32(0x000000ff); + map(0xff0, 0xff0).lr8([this](offs_t offset) { return pcell_id[0]; }, "pcell_id0").umask32(0x000000ff); + map(0xff4, 0xff4).lr8([this](offs_t offset) { return pcell_id[1]; }, "pcell_id1").umask32(0x000000ff); + map(0xff8, 0xff8).lr8([this](offs_t offset) { return pcell_id[2]; }, "pcell_id2").umask32(0x000000ff); + map(0xffc, 0xffc).lr8([this](offs_t offset) { return pcell_id[3]; }, "pcell_id3").umask32(0x000000ff); +} + +void vic_pl192_device::device_start() +{ + vic_pl190_device::device_start(); + + save_item(NAME(sw_priority_mask)); + save_item(NAME(daisy_priority)); +} + +void vic_pl192_device::device_reset() +{ + vic_pl190_device::device_start(); + + sw_priority_mask = 0xffff; + daisy_priority = 0xf; + + for (int i = 0; i < 32; i++) + { + vectctl[i] = 0xf; + } +} + vic_pl192_device::vic_pl192_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : vic_pl192_device(mconfig, PL192_VIC, tag, owner, clock) + : vic_pl190_device(mconfig, PL192_VIC, tag, owner, clock) { + num_vectors = 32; } diff --git a/src/devices/machine/vic_pl192.h b/src/devices/machine/vic_pl192.h index 9936b369fb6..cb07a8854d5 100644 --- a/src/devices/machine/vic_pl192.h +++ b/src/devices/machine/vic_pl192.h @@ -1,26 +1,70 @@ // license:BSD-3-Clause -// copyright-holders:Melissa Goad +// copyright-holders:Devin Acker, Melissa Goad -// ARM PrimeCell PL192 VIC emulation +// ARM PrimeCell PL910/PL192 VIC emulation #ifndef MAME_MACHINE_VIC_PL192_H #define MAME_MACHINE_VIC_PL192_H -class vic_pl192_device : public device_t, public device_memory_interface +class vic_pl190_device : public device_t, public device_memory_interface { public: - vic_pl192_device(const machine_config &mconfig, const char* tag, device_t *owner, uint32_t clock = 0); + vic_pl190_device(const machine_config &mconfig, const char* tag, device_t *owner, uint32_t clock = 0); auto out_irq_cb() { return m_out_irq_func.bind(); } auto out_fiq_cb() { return m_out_fiq_func.bind(); } template<unsigned IRQ> - DECLARE_WRITE_LINE_MEMBER( irq_w ) { set_irq_line(IRQ, state); } + DECLARE_WRITE_LINE_MEMBER(irq_w) { set_irq_line(IRQ, state); } void map(address_map &map); + u32 irq_status_r(); + u32 fiq_status_r(); + u32 raw_intr_r(); + + u32 int_select_r(); + void int_select_w(u32 data); + + u32 int_enable_r(); + void int_enable_w(u32 data); + void int_en_clear_w(u32 data); + + u32 soft_int_r(); + void soft_int_w(u32 data); + void soft_int_clear_w(u32 data); + + u8 protection_r(); + void protection_w(u8 data); + + u32 cur_vect_addr_r(); + void cur_vect_addr_w(u32 data); + + u32 def_vect_addr_r(); + void def_vect_addr_w(u32 data); + + u32 vect_addr_r(offs_t offset); + void vect_addr_w(offs_t offset, u32 data); + + u32 vect_ctl_r(offs_t offset); + void vect_ctl_w(offs_t offset, u32 data); + protected: - vic_pl192_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + static constexpr device_timer_id TIMER_CHECK_IRQ = 0; + + vic_pl190_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + virtual void update_vector(); + + u8 num_vectors; // number of available vectored interrupts + + u32 raw_intr, intr_select, intr_en, soft_intr; + u32 vectaddr[32], vectctl[32], defaddress, vicaddress; + int protection; + + u32 priority_mask; // mask for interrupts which can take priority over the current one + u8 priority; // priority level of the current interrupt, if any + u8 periph_id[4], pcell_id[4]; // device-level overrides virtual void device_resolve_objects() override; @@ -31,21 +75,52 @@ protected: virtual space_config_vector memory_space_config() const override; private: - static constexpr device_timer_id TIMER_CHECK_IRQ = 0; - void set_irq_line(int irq, int state); address_space_config m_mmio_config; devcb_write_line m_out_irq_func; devcb_write_line m_out_fiq_func; - u32 raw_intr, intr_select, intr_en, soft_intr, vectaddr[32], vicaddress; - int protection; +}; + +class vic_upd800468_device : public vic_pl190_device +{ +public: + vic_upd800468_device(const machine_config &mconfig, const char* tag, device_t *owner, uint32_t clock = 0); + + void map(address_map &map); + + void int_clear_w(u32 data); +}; + +class vic_pl192_device : public vic_pl190_device +{ +public: + vic_pl192_device(const machine_config &mconfig, const char* tag, device_t *owner, uint32_t clock = 0); + + void map(address_map &map); + + u16 sw_priority_r(); + void sw_priority_w(u16 data); + + u8 daisy_priority_r(); + void daisy_priority_w(u8 data); + +protected: + + virtual void update_vector() override; + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + +private: u16 sw_priority_mask; - u8 daisy_priority, vectprio[32]; - u8 periph_id[4], pcell_id[4]; + u8 daisy_priority; }; +DECLARE_DEVICE_TYPE(PL190_VIC, vic_pl190_device) +DECLARE_DEVICE_TYPE(UPD800468_VIC, vic_upd800468_device) DECLARE_DEVICE_TYPE(PL192_VIC, vic_pl192_device) #endif // MAME_MACHINE_VIC_PL192_H |