summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine')
-rw-r--r--src/devices/machine/gt913_kbd.cpp14
-rw-r--r--src/devices/machine/gt913_kbd.h16
-rw-r--r--src/devices/machine/vic_pl192.cpp375
-rw-r--r--src/devices/machine/vic_pl192.h99
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