summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/unsp/unsp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/unsp/unsp.cpp')
-rw-r--r--src/devices/cpu/unsp/unsp.cpp173
1 files changed, 138 insertions, 35 deletions
diff --git a/src/devices/cpu/unsp/unsp.cpp b/src/devices/cpu/unsp/unsp.cpp
index 2805d3a80e0..6a815b7f441 100644
--- a/src/devices/cpu/unsp/unsp.cpp
+++ b/src/devices/cpu/unsp/unsp.cpp
@@ -20,10 +20,10 @@
#include "unsp.h"
#include "unspfe.h"
-#include "debugger.h"
-
#include "unspdasm.h"
+#include <climits>
+
DEFINE_DEVICE_TYPE(UNSP, unsp_device, "unsp", "SunPlus u'nSP (ISA 1.0)")
// 1.1 is just 1.0 with better CPI?
DEFINE_DEVICE_TYPE(UNSP_11, unsp_11_device, "unsp_11", "SunPlus u'nSP (ISA 1.1)")
@@ -39,12 +39,11 @@ unsp_device::unsp_device(const machine_config &mconfig, device_type type, const
: cpu_device(mconfig, type, tag, owner, clock)
, m_core(nullptr)
, m_program_config("program", ENDIANNESS_BIG, 16, 23, -1, internal)
- , m_program(nullptr)
, m_debugger_temp(0)
#if UNSP_LOG_OPCODES || UNSP_LOG_REGS
, m_log_ops(0)
#endif
- , m_cache(CACHE_SIZE + sizeof(unsp_device))
+ , m_drccache(CACHE_SIZE + sizeof(unsp_device))
, m_drcuml(nullptr)
, m_drcfe(nullptr)
, m_drcoptions(0)
@@ -58,25 +57,31 @@ unsp_device::unsp_device(const machine_config &mconfig, device_type type, const
, m_mem_read(nullptr)
, m_mem_write(nullptr)
, m_enable_drc(false)
+ , m_vectorbase(0xfff0)
{
+ m_iso = 10;
+ m_numregs = 8;
}
unsp_device::unsp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: unsp_device(mconfig, UNSP, tag, owner, clock, address_map_constructor())
{
m_iso = 10;
+ m_numregs = 8;
}
unsp_11_device::unsp_11_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: unsp_device(mconfig, UNSP_11, tag, owner, clock, address_map_constructor())
{
m_iso = 11;
+ m_numregs = 8;
}
unsp_11_device::unsp_11_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal)
: unsp_device(mconfig, type, tag, owner, clock, internal)
{
m_iso = 11;
+ m_numregs = 8;
}
@@ -84,24 +89,28 @@ unsp_12_device::unsp_12_device(const machine_config &mconfig, const char *tag, d
: unsp_11_device(mconfig, UNSP_12, tag, owner, clock, address_map_constructor())
{
m_iso = 12;
+ m_numregs = 8;
}
unsp_12_device::unsp_12_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal)
: unsp_11_device(mconfig, type, tag, owner, clock, internal)
{
m_iso = 12;
+ m_numregs = 8;
}
unsp_20_device::unsp_20_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: unsp_12_device(mconfig, UNSP_20, tag, owner, clock, address_map_constructor())
{
m_iso = 20;
+ m_numregs = 16;
}
unsp_20_device::unsp_20_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal)
: unsp_12_device(mconfig, type, tag, owner, clock, internal)
{
m_iso = 20;
+ m_numregs = 16;
}
unsp_device::~unsp_device()
@@ -119,6 +128,7 @@ char const* const unsp_device::bitops[] =
"tstb", "setb", "clrb", "invb"
};
+// log/barrel shift
char const* const unsp_device::lsft[] =
{
"asr", "asror", "lsl", "lslor", "lsr", "lsror", "rol", "ror"
@@ -180,7 +190,8 @@ void unsp_device::unimplemented_opcode(uint16_t op, uint16_t ximm, uint16_t ximm
void unsp_device::device_start()
{
- m_core = (internal_unsp_state *)m_cache.alloc_near(sizeof(internal_unsp_state));
+
+ m_core = (internal_unsp_state *)m_drccache.alloc_near(sizeof(internal_unsp_state));
memset(m_core, 0, sizeof(internal_unsp_state));
#if ENABLE_UNSP_DRC
@@ -198,13 +209,11 @@ void unsp_device::device_start()
m_debugger_temp = 0;
- m_program = &space(AS_PROGRAM);
- auto cache = m_program->cache<1, -1, ENDIANNESS_BIG>();
- m_pr16 = [cache](offs_t address) -> u16 { return cache->read_word(address); };
- m_prptr = [cache](offs_t address) -> const void * { return cache->read_ptr(address); };
+ space(AS_PROGRAM).cache(m_cache);
+ space(AS_PROGRAM).specific(m_program);
uint32_t umlflags = 0;
- m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, umlflags, 1, 23, 0);
+ m_drcuml = std::make_unique<drcuml_state>(*this, m_drccache, umlflags, 1, 23, 0);
// add UML symbols-
m_drcuml->symbol_add(&m_core->m_r[REG_SP], sizeof(uint32_t), "SP");
@@ -217,9 +226,13 @@ void unsp_device::device_start()
m_drcuml->symbol_add(&m_core->m_r[REG_PC], sizeof(uint32_t), "PC");
m_drcuml->symbol_add(&m_core->m_enable_irq, sizeof(uint32_t), "IRQE");
m_drcuml->symbol_add(&m_core->m_enable_fiq, sizeof(uint32_t), "FIQE");
- m_drcuml->symbol_add(&m_core->m_irq, sizeof(uint32_t), "IRQ");
- m_drcuml->symbol_add(&m_core->m_fiq, sizeof(uint32_t), "FIQ");
+ m_drcuml->symbol_add(&m_core->m_fir_move, sizeof(uint32_t), "FIR_MOV");
m_drcuml->symbol_add(&m_core->m_sb, sizeof(uint32_t), "SB");
+ m_drcuml->symbol_add(&m_core->m_aq, sizeof(uint32_t), "AQ");
+ m_drcuml->symbol_add(&m_core->m_fra, sizeof(uint32_t), "FRA");
+ m_drcuml->symbol_add(&m_core->m_bnk, sizeof(uint32_t), "BNK");
+ m_drcuml->symbol_add(&m_core->m_ine, sizeof(uint32_t), "INE");
+ m_drcuml->symbol_add(&m_core->m_pri, sizeof(uint32_t), "PRI");
m_drcuml->symbol_add(&m_core->m_icount, sizeof(m_core->m_icount), "icount");
/* initialize the front-end helper */
@@ -240,9 +253,13 @@ void unsp_device::device_start()
state_add(UNSP_PC, "PC", m_debugger_temp).callimport().callexport().formatstr("%06X");
state_add(UNSP_IRQ_EN, "IRQE", m_core->m_enable_irq).formatstr("%1u");
state_add(UNSP_FIQ_EN, "FIQE", m_core->m_enable_fiq).formatstr("%1u");
- state_add(UNSP_IRQ, "IRQ", m_core->m_irq).formatstr("%1u");
- state_add(UNSP_FIQ, "FIQ", m_core->m_fiq).formatstr("%1u");
- state_add(UNSP_SB, "SB", m_core->m_sb).formatstr("%1u");
+ state_add(UNSP_FIR_MOV_EN, "FIR_MOV", m_core->m_fir_move).formatstr("%1u");
+ state_add(UNSP_SB, "SB", m_core->m_sb).formatstr("%1X");
+ state_add(UNSP_AQ, "AQ", m_core->m_aq).formatstr("%1u");
+ state_add(UNSP_FRA, "FRA", m_core->m_fra).formatstr("%1u");
+ state_add(UNSP_BNK, "BNK", m_core->m_bnk).formatstr("%1u");
+ state_add(UNSP_INE, "INE", m_core->m_ine).formatstr("%1u");
+ state_add(UNSP_PRI, "PRI", m_core->m_pri).formatstr("%1u");
#if UNSP_LOG_OPCODES || UNSP_LOG_REGS
state_add(UNSP_LOG_OPS,"LOG", m_log_ops).formatstr("%1u");
#endif
@@ -254,24 +271,70 @@ void unsp_device::device_start()
save_item(NAME(m_core->m_enable_irq));
save_item(NAME(m_core->m_enable_fiq));
save_item(NAME(m_core->m_irq));
- save_item(NAME(m_core->m_fiq));
- save_item(NAME(m_core->m_curirq));
+ save_item(NAME(m_core->m_fir_move));
save_item(NAME(m_core->m_sirq));
save_item(NAME(m_core->m_sb));
- save_item(NAME(m_core->m_saved_sb));
+ save_item(NAME(m_core->m_aq));
+ save_item(NAME(m_core->m_fra));
+ save_item(NAME(m_core->m_bnk));
+ save_item(NAME(m_core->m_ine));
+ save_item(NAME(m_core->m_pri));
+ save_item(NAME(m_core->m_divq_bit));
+ save_item(NAME(m_core->m_divq_dividend));
+ save_item(NAME(m_core->m_divq_divisor));
set_icountptr(m_core->m_icount);
}
+void unsp_20_device::device_start()
+{
+ unsp_12_device::device_start();
+
+#if UNSP_LOG_OPCODES || UNSP_LOG_REGS
+ int baseindex = UNSP_LOG_OPS + 1;
+#else
+ int baseindex = UNSP_PRI + 1;
+#endif
+
+ state_add(baseindex + UNSP20_R8, "R8", m_core->m_r[UNSP20_R8+8]).formatstr("%04X");
+ state_add(baseindex + UNSP20_R9, "R9", m_core->m_r[UNSP20_R9+8]).formatstr("%04X");
+ state_add(baseindex + UNSP20_R10, "R10", m_core->m_r[UNSP20_R10+8]).formatstr("%04X");
+ state_add(baseindex + UNSP20_R11, "R11", m_core->m_r[UNSP20_R11+8]).formatstr("%04X");
+ state_add(baseindex + UNSP20_R12, "R12", m_core->m_r[UNSP20_R12+8]).formatstr("%04X");
+ state_add(baseindex + UNSP20_R13, "R13", m_core->m_r[UNSP20_R13+8]).formatstr("%04X");
+ state_add(baseindex + UNSP20_R14, "R14", m_core->m_r[UNSP20_R14+8]).formatstr("%04X");
+ state_add(baseindex + UNSP20_R15, "R15", m_core->m_r[UNSP20_R15+8]).formatstr("%04X");
+}
+
void unsp_device::device_reset()
{
- memset(m_core->m_r, 0, sizeof(uint32_t) * 8);
+ for (int i = 0; i < std::size(m_core->m_r); i++)
+ {
+ if (i < m_numregs)
+ m_core->m_r[i] = 0;
+ else
+ m_core->m_r[i] = 0xdeadbeef;
+ }
- m_core->m_r[REG_PC] = read16(0xfff7);
+ m_core->m_r[REG_PC] = read16(m_vectorbase + 0x7);
m_core->m_enable_irq = 0;
m_core->m_enable_fiq = 0;
- m_core->m_irq = 0;
+ m_core->m_fir_move = 1;
+ m_core->m_sb = 0;
+ m_core->m_aq = 0;
+ m_core->m_fra = 0;
+ m_core->m_bnk = 0;
+ m_core->m_ine = 0;
+ m_core->m_pri = 8;
m_core->m_fiq = 0;
+ m_core->m_irq = 0;
+ m_core->m_sirq = 0;
+ m_core->m_divq_bit = UINT_MAX;
+}
+
+void unsp_20_device::device_reset()
+{
+ unsp_12_device::device_reset();
}
void unsp_device::device_stop()
@@ -350,7 +413,7 @@ void unsp_device::state_import(const device_state_entry &entry)
void unsp_device::update_nzsc(uint32_t value, uint16_t r0, uint16_t r1)
{
m_core->m_r[REG_SR] &= ~(UNSP_N | UNSP_Z | UNSP_S | UNSP_C);
- if (int16_t(r0) < int16_t(~r1))
+ if (BIT(value, 16) != BIT((r0 ^ r1), 15))
m_core->m_r[REG_SR] |= UNSP_S;
if (BIT(value, 15))
m_core->m_r[REG_SR] |= UNSP_N;
@@ -383,35 +446,37 @@ uint16_t unsp_device::pop(uint32_t *reg)
inline void unsp_device::trigger_fiq()
{
- if (!m_core->m_enable_fiq || m_core->m_fiq || m_core->m_irq)
- {
+ if (!m_core->m_enable_fiq || m_core->m_fiq)
return;
- }
+ standard_irq_callback(UNSP_FIQ_LINE, m_core->m_r[REG_PC]);
m_core->m_fiq = 1;
- m_core->m_saved_sb[m_core->m_irq ? 1 : 0] = m_core->m_sb;
- m_core->m_sb = m_core->m_saved_sb[2];
-
push(m_core->m_r[REG_PC], &m_core->m_r[REG_SP]);
push(m_core->m_r[REG_SR], &m_core->m_r[REG_SP]);
- m_core->m_r[REG_PC] = read16(0xfff6);
+ m_core->m_r[REG_PC] = read16(m_vectorbase + 0x06);
m_core->m_r[REG_SR] = 0;
}
inline void unsp_device::trigger_irq(int line)
{
- if (!m_core->m_enable_irq || m_core->m_irq || m_core->m_fiq)
+ if ((m_core->m_ine == 0 && m_core->m_irq == 1) || m_core->m_pri <= line || !m_core->m_enable_irq)
return;
+ standard_irq_callback(UNSP_IRQ0_LINE+line, m_core->m_r[REG_PC]);
m_core->m_irq = 1;
- m_core->m_saved_sb[0] = m_core->m_sb;
- m_core->m_sb = m_core->m_saved_sb[1];
-
push(m_core->m_r[REG_PC], &m_core->m_r[REG_SP]);
push(m_core->m_r[REG_SR], &m_core->m_r[REG_SP]);
- m_core->m_r[REG_PC] = read16(0xfff8 + line);
+ if (m_core->m_ine)
+ {
+ push(get_fr(), &m_core->m_r[REG_SP]);
+ }
+
+ if (m_core->m_ine)
+ m_core->m_pri = line;
+
+ m_core->m_r[REG_PC] = read16(m_vectorbase + 0x08 + line);
m_core->m_r[REG_SR] = 0;
}
@@ -489,7 +554,10 @@ void unsp_device::execute_run()
execute_one(op);
- check_irqs();
+ if (op != 0x9a98)
+ {
+ check_irqs();
+ }
}
}
@@ -543,3 +611,38 @@ void unsp_device::set_ds(uint16_t ds)
m_core->m_r[REG_SR] &= 0x03ff;
m_core->m_r[REG_SR] |= (ds & 0x3f) << 10;
}
+
+void unsp_device::set_fr(uint16_t fr)
+{
+ m_core->m_aq = BIT(fr, 14);
+ const uint32_t old_bank = m_core->m_bnk;
+ m_core->m_bnk = BIT(fr, 13);
+ if (m_core->m_bnk != old_bank)
+ {
+ std::swap<uint32_t>(m_core->m_r[REG_R1], m_core->m_secbank[REG_SR1]);
+ std::swap<uint32_t>(m_core->m_r[REG_R2], m_core->m_secbank[REG_SR2]);
+ std::swap<uint32_t>(m_core->m_r[REG_R3], m_core->m_secbank[REG_SR3]);
+ std::swap<uint32_t>(m_core->m_r[REG_R4], m_core->m_secbank[REG_SR4]);
+ }
+ m_core->m_fra = BIT(fr, 12);
+ m_core->m_fir_move = BIT(fr, 11);
+ m_core->m_sb = (fr >> 7) & 0xf;
+ m_core->m_enable_fiq = BIT(fr, 6);
+ m_core->m_enable_irq = BIT(fr, 5);
+ m_core->m_ine = BIT(fr, 4);
+ m_core->m_pri = fr & 0xf;
+}
+
+uint16_t unsp_device::get_fr()
+{
+ uint16_t fr = m_core->m_aq << 14;
+ fr |= m_core->m_bnk << 13;
+ fr |= m_core->m_fra << 12;
+ fr |= m_core->m_fir_move << 11;
+ fr |= m_core->m_sb << 7;
+ fr |= m_core->m_enable_fiq << 6;
+ fr |= m_core->m_enable_irq << 5;
+ fr |= m_core->m_ine << 4;
+ fr |= m_core->m_pri;
+ return fr;
+}