summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/dsp16/dsp16.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/dsp16/dsp16.cpp')
-rw-r--r--src/devices/cpu/dsp16/dsp16.cpp704
1 files changed, 233 insertions, 471 deletions
diff --git a/src/devices/cpu/dsp16/dsp16.cpp b/src/devices/cpu/dsp16/dsp16.cpp
index b9b970cdeb5..2026cf5d80e 100644
--- a/src/devices/cpu/dsp16/dsp16.cpp
+++ b/src/devices/cpu/dsp16/dsp16.cpp
@@ -77,7 +77,8 @@
#include "emu.h"
#include "dsp16.h"
-#include "dsp16dis.h"
+#include "dsp16core.ipp"
+#include "dsp16rc.h"
#include "debugger.h"
@@ -184,15 +185,13 @@ dsp16_device_base::dsp16_device_base(
{ "rom", ENDIANNESS_BIG, 16, 16, -1, address_map_constructor(FUNC(dsp16_device_base::program_map), this) },
{ "ram", ENDIANNESS_BIG, 16, yaau_bits, -1, std::move(data_map) },
{ "exm", ENDIANNESS_BIG, 16, 16, -1 } }
- , m_yaau_mask(u16((u32(1) << yaau_bits) - 1)), m_yaau_sign(u16(1) << (yaau_bits - 1))
+ , m_yaau_bits(yaau_bits)
, m_spaces{ nullptr, nullptr, nullptr }, m_direct(nullptr)
- , m_icount(0), m_cache_mode(cache::NONE), m_phase(phase::PURGE), m_int_enable{ 0U, 0U }, m_flags(FLAGS_NONE), m_cache_ptr(0U), m_cache_limit(0U), m_cache_iterations(0U)
+ , m_drc_cache(CACHE_SIZE), m_core(nullptr, [] (core_state *core) { core->~core_state(); }), m_recompiler()
+ , m_cache_mode(cache::NONE), m_phase(phase::PURGE), m_int_enable{ 0U, 0U }, m_flags(FLAGS_NONE), m_cache_ptr(0U), m_cache_limit(0U), m_cache_iterations(0U)
, m_exm_in(1U), m_int_in(CLEAR_LINE), m_iack_out(1U)
, m_ick_in(1U), m_ild_in(CLEAR_LINE), m_do_out(1U), m_ock_in(1U), m_old_in(CLEAR_LINE), m_ose_out(1U)
, m_psel_out(0U), m_pids_out(1U), m_pods_out(1U)
- , m_xaau_pc(0U), m_xaau_pt(0U), m_xaau_pr(0U), m_xaau_pi(0U), m_xaau_i(0)
- , m_yaau_r{ 0U, 0U, 0U, 0U }, m_yaau_rb(0U), m_yaau_re(0U), m_yaau_j(0), m_yaau_k(0)
- , m_dau_x(0), m_dau_y(0), m_dau_p(0), m_dau_a{ 0, 0 }, m_dau_c{ 0, 0, 0 }, m_dau_auc(0U), m_dau_psw(0U), m_dau_temp(0)
, m_sio_sioc(0U), m_sio_obuf(0U), m_sio_osr(0U), m_sio_ofsr(0U)
, m_sio_clk(1U), m_sio_clk_div(0U), m_sio_clk_res(0U), m_sio_ld(1U), m_sio_ld_div(0U), m_sio_flags(SIO_FLAGS_NONE)
, m_pio_pioc(0U), m_pio_pdx_in(0U), m_pio_pdx_out(0U), m_pio_pids_cnt(0U), m_pio_pods_cnt(0U)
@@ -225,38 +224,43 @@ void dsp16_device_base::device_resolve_objects()
void dsp16_device_base::device_start()
{
- m_icountptr = &m_icount;
+ m_core.reset(reinterpret_cast<core_state *>(m_drc_cache.alloc_near(sizeof(core_state))));
+ new (m_core.get()) core_state(m_yaau_bits);
+ m_icountptr = &m_core->icount;
m_spaces[AS_PROGRAM] = &space(AS_PROGRAM);
m_spaces[AS_DATA] = &space(AS_DATA);
m_spaces[AS_IO] = &space(AS_IO);
m_direct = m_spaces[AS_PROGRAM]->direct<-1>();
- state_add(STATE_GENPC, "PC", m_xaau_pc);
+ if (allow_drc())
+ m_recompiler.reset(new recompiler(*this, 0)); // TODO: what are UML flags for?
+
+ state_add(STATE_GENPC, "PC", m_core->xaau_pc);
state_add(STATE_GENPCBASE, "CURPC", m_st_pcbase).noshow();
state_add(STATE_GENFLAGS, "GENFLAGS", m_st_genflags).mask(0x0fU).noshow().callexport().formatstr("%16s");
- state_add(DSP16_PT, "PT", m_xaau_pt);
- state_add(DSP16_PR, "PR", m_xaau_pr);
- state_add(DSP16_PI, "PI", m_xaau_pi);
- state_add(DSP16_I, "I", m_xaau_i).mask((s16(1) << 12) - 1).callimport();
- state_add(DSP16_R0, "R0", m_yaau_r[0]).mask(m_yaau_mask);
- state_add(DSP16_R1, "R1", m_yaau_r[1]).mask(m_yaau_mask);
- state_add(DSP16_R2, "R2", m_yaau_r[2]).mask(m_yaau_mask);
- state_add(DSP16_R3, "R3", m_yaau_r[3]).mask(m_yaau_mask);
- state_add(DSP16_RB, "RB", m_yaau_rb).mask(m_yaau_mask);
- state_add(DSP16_RE, "RE", m_yaau_re).mask(m_yaau_mask);
- state_add(DSP16_J, "J", m_yaau_j).mask(m_yaau_mask).callimport();
- state_add(DSP16_K, "K", m_yaau_k).mask(m_yaau_mask).callimport();
- state_add(DSP16_X, "X", m_dau_x);
- state_add(DSP16_Y, "Y", m_dau_y);
- state_add(DSP16_P, "P", m_dau_p);
- state_add(DSP16_A0, "A0", m_dau_a[0]).mask(DAU_A_MASK).callimport();
- state_add(DSP16_A1, "A1", m_dau_a[1]).mask(DAU_A_MASK).callimport();
- state_add(DSP16_C0, "C0", m_dau_c[0]);
- state_add(DSP16_C1, "C1", m_dau_c[1]);
- state_add(DSP16_C2, "C2", m_dau_c[2]);
- state_add(DSP16_AUC, "AUC", m_dau_auc).mask(0x7fU);
- state_add(DSP16_PSW, "PSW", m_dau_psw).callimport().callexport();
+ state_add(DSP16_PT, "PT", m_core->xaau_pt);
+ state_add(DSP16_PR, "PR", m_core->xaau_pr);
+ state_add(DSP16_PI, "PI", m_core->xaau_pi);
+ state_add(DSP16_I, "I", m_core->xaau_i).mask((s16(1) << 12) - 1).callimport();
+ state_add(DSP16_R0, "R0", m_core->yaau_r[0]).mask(m_core->yaau_mask);
+ state_add(DSP16_R1, "R1", m_core->yaau_r[1]).mask(m_core->yaau_mask);
+ state_add(DSP16_R2, "R2", m_core->yaau_r[2]).mask(m_core->yaau_mask);
+ state_add(DSP16_R3, "R3", m_core->yaau_r[3]).mask(m_core->yaau_mask);
+ state_add(DSP16_RB, "RB", m_core->yaau_rb).mask(m_core->yaau_mask);
+ state_add(DSP16_RE, "RE", m_core->yaau_re).mask(m_core->yaau_mask);
+ state_add(DSP16_J, "J", m_core->yaau_j).mask(m_core->yaau_mask).callimport();
+ state_add(DSP16_K, "K", m_core->yaau_k).mask(m_core->yaau_mask).callimport();
+ state_add(DSP16_X, "X", m_core->dau_x);
+ state_add(DSP16_Y, "Y", m_core->dau_y);
+ state_add(DSP16_P, "P", m_core->dau_p);
+ state_add(DSP16_A0, "A0", m_core->dau_a[0]).mask(DAU_A_MASK).callimport();
+ state_add(DSP16_A1, "A1", m_core->dau_a[1]).mask(DAU_A_MASK).callimport();
+ state_add(DSP16_C0, "C0", m_core->dau_c[0]);
+ state_add(DSP16_C1, "C1", m_core->dau_c[1]);
+ state_add(DSP16_C2, "C2", m_core->dau_c[2]);
+ state_add(DSP16_AUC, "AUC", m_core->dau_auc).mask(0x7fU);
+ state_add(DSP16_PSW, "PSW", m_core->dau_psw).callimport().callexport();
state_add(DSP16_YH, "YH", m_st_yh).noshow().callimport().callexport();
state_add(DSP16_A0H, "A0H", m_st_ah[0]).noshow().callimport().callexport();
state_add(DSP16_A1H, "A1H", m_st_ah[1]).noshow().callimport().callexport();
@@ -264,6 +268,8 @@ void dsp16_device_base::device_start()
state_add(DSP16_A0L, "A0L", m_st_al[0]).noshow().callimport().callexport();
state_add(DSP16_A1L, "A1L", m_st_al[1]).noshow().callimport().callexport();
+ m_core->register_save_items(*this);
+
save_item(NAME(m_cache_mode));
save_item(NAME(m_phase));
save_item(NAME(m_int_enable));
@@ -289,27 +295,6 @@ void dsp16_device_base::device_start()
save_item(NAME(m_pids_out));
save_item(NAME(m_pods_out));
- save_item(NAME(m_xaau_pc));
- save_item(NAME(m_xaau_pt));
- save_item(NAME(m_xaau_pr));
- save_item(NAME(m_xaau_pi));
- save_item(NAME(m_xaau_i));
-
- save_item(NAME(m_yaau_r));
- save_item(NAME(m_yaau_rb));
- save_item(NAME(m_yaau_re));
- save_item(NAME(m_yaau_j));
- save_item(NAME(m_yaau_k));
-
- save_item(NAME(m_dau_x));
- save_item(NAME(m_dau_y));
- save_item(NAME(m_dau_p));
- save_item(NAME(m_dau_a));
- save_item(NAME(m_dau_c));
- save_item(NAME(m_dau_auc));
- save_item(NAME(m_dau_psw));
- save_item(NAME(m_dau_temp));
-
save_item(NAME(m_sio_sioc));
save_item(NAME(m_sio_obuf));
save_item(NAME(m_sio_osr));
@@ -333,6 +318,11 @@ void dsp16_device_base::device_start()
external_memory_enable(*m_spaces[AS_PROGRAM], !m_exm_in);
}
+void dsp16_device_base::device_stop()
+{
+ m_recompiler.reset();
+}
+
void dsp16_device_base::device_reset()
{
cpu_device::device_reset();
@@ -342,9 +332,9 @@ void dsp16_device_base::device_reset()
std::fill(std::begin(m_int_enable), std::end(m_int_enable), 0U);
m_flags = FLAGS_NONE;
m_cache_ptr = 0U;
- m_xaau_pc = 0U;
- m_yaau_rb = 0U;
- m_yaau_re = 0U;
+ m_core->xaau_pc = 0U;
+ m_core->yaau_rb = 0U;
+ m_core->yaau_re = 0U;
m_sio_sioc = 0U;
m_sio_ofsr = 0U;
m_sio_clk = 1U;
@@ -391,7 +381,7 @@ void dsp16_device_base::device_reset()
void dsp16_device_base::execute_run()
{
- while (0 < m_icount)
+ while (m_core->icount_remaining())
{
// execute one cycle of an instruction
switch (m_cache_mode)
@@ -404,7 +394,7 @@ void dsp16_device_base::execute_run()
execute_one_cache();
break;
}
- --m_icount;
+ m_core->decrement_icount();
// step the serial I/O clock divider
if (m_sio_clk_div)
@@ -538,46 +528,33 @@ void dsp16_device_base::state_import(device_state_entry const &entry)
switch (entry.index())
{
// extend signed registers that aren't a power-of-two size
- case DSP16_I:
- m_xaau_i = (m_xaau_i & XAAU_I_MASK) | ((m_xaau_i & XAAU_I_SIGN) ? XAAU_I_EXT : 0);
- break;
- case DSP16_J:
- m_yaau_j = (m_yaau_j & m_yaau_mask) | ((m_yaau_j & m_yaau_sign) ? ~m_yaau_mask : 0);
- break;
- case DSP16_K:
- m_yaau_k = (m_yaau_k & m_yaau_mask) | ((m_yaau_k & m_yaau_sign) ? ~m_yaau_mask : 0);
- break;
- case DSP16_A0:
- m_dau_a[0] = (m_dau_a[0] & DAU_A_MASK) | ((m_dau_a[0] & DAU_A_SIGN) ? DAU_A_EXT : 0);
- break;
- case DSP16_A1:
- m_dau_a[1] = (m_dau_a[1] & DAU_A_MASK) | ((m_dau_a[1] & DAU_A_SIGN) ? DAU_A_EXT : 0);
- break;
+ case DSP16_I: m_core->xaau_extend_i(); break;
+ case DSP16_J: m_core->yaau_extend_j(); break;
+ case DSP16_K: m_core->yaau_extend_k(); break;
+ case DSP16_A0: m_core->dau_extend_a<0>(); break;
+ case DSP16_A1: m_core->dau_extend_a<1>(); break;
// guard bits of accumulators are accessible via status word
- case DSP16_PSW:
- m_dau_a[0] = u64(u32(m_dau_a[0])) | (u64(m_dau_psw & 0x000fU) << 32) | (BIT(m_dau_psw, 3) ? DAU_A_EXT : 0U);
- m_dau_a[1] = u64(u32(m_dau_a[1])) | (u64(m_dau_psw & 0x01e0U) << 27) | (BIT(m_dau_psw, 8) ? DAU_A_EXT : 0U);
- break;
+ case DSP16_PSW: m_core->dau_import_psw(); break;
// put partial registers in the appropriate places
case DSP16_YH:
- m_dau_y = (s32(m_st_yh) << 16) | (m_dau_y & ((s32(1) << 16) - 1));
+ m_core->dau_y = (s32(m_st_yh) << 16) | (m_core->dau_y & ((s32(1) << 16) - 1));
break;
case DSP16_A0H:
- m_dau_a[0] = (s32(m_st_ah[0]) << 16) | s32(m_dau_a[0] & ((s32(1) << 16) - 1));
+ m_core->dau_a[0] = (s32(m_st_ah[0]) << 16) | s32(m_core->dau_a[0] & ((s32(1) << 16) - 1));
break;
case DSP16_A1H:
- m_dau_a[1] = (s32(m_st_ah[1]) << 16) | s32(m_dau_a[1] & ((s32(1) << 16) - 1));
+ m_core->dau_a[1] = (s32(m_st_ah[1]) << 16) | s32(m_core->dau_a[1] & ((s32(1) << 16) - 1));
break;
case DSP16_YL:
- m_dau_y = (m_dau_y & ~((s32(1) << 16) - 1)) | u32(m_st_yl);
+ m_core->dau_y = (m_core->dau_y & ~((s32(1) << 16) - 1)) | u32(m_st_yl);
break;
case DSP16_A0L:
- m_dau_a[0] = (m_dau_a[0] & ~((s64(1) << 16) - 1)) | u64(m_st_al[0]);
+ m_core->dau_a[0] = (m_core->dau_a[0] & ~((s64(1) << 16) - 1)) | u64(m_st_al[0]);
break;
case DSP16_A1L:
- m_dau_a[1] = (m_dau_a[1] & ~((s64(1) << 16) - 1)) | u64(m_st_al[1]);
+ m_core->dau_a[1] = (m_core->dau_a[1] & ~((s64(1) << 16) - 1)) | u64(m_st_al[1]);
break;
}
}
@@ -587,28 +564,26 @@ void dsp16_device_base::state_export(device_state_entry const &entry)
switch (entry.index())
{
// guard bits of accumulators are accessible via status word
- case DSP16_PSW:
- m_dau_psw = (m_dau_psw & 0xfe10U) | (u16(u64(m_dau_a[0]) >> 32) & 0x000fU) | (u16(u64(m_dau_a[1]) >> 27) & 0x01e0U);
- break;
+ case DSP16_PSW: m_core->dau_export_psw(); break;
// put partial registers in the appropriate places
case DSP16_YH:
- m_st_yh = m_dau_y >> 16;
+ m_st_yh = m_core->dau_y >> 16;
break;
case DSP16_A0H:
- m_st_ah[0] = u16(u64(m_dau_a[0]) >> 16);
+ m_st_ah[0] = u16(u64(m_core->dau_a[0]) >> 16);
break;
case DSP16_A1H:
- m_st_ah[1] = u16(u64(m_dau_a[1]) >> 16);
+ m_st_ah[1] = u16(u64(m_core->dau_a[1]) >> 16);
break;
case DSP16_YL:
- m_st_yl = u16(u32(m_dau_y));
+ m_st_yl = u16(u32(m_core->dau_y));
break;
case DSP16_A0L:
- m_st_al[0] = u16(u64(m_dau_a[0]));
+ m_st_al[0] = u16(u64(m_core->dau_a[0]));
break;
case DSP16_A1L:
- m_st_al[1] = u16(u64(m_dau_a[1]));
+ m_st_al[1] = u16(u64(m_core->dau_a[1]));
break;
}
}
@@ -621,10 +596,10 @@ void dsp16_device_base::state_string_export(device_state_entry const &entry, std
case STATE_GENFLAGS:
str = util::string_format(
"%s%s%s%s",
- dau_psw_lmi() ? "LMI " : "",
- dau_psw_leq() ? "LEQ " : "",
- dau_psw_llv() ? "LLV " : "",
- dau_psw_lmv() ? "LMV " : "");
+ m_core->dau_psw_lmi() ? "LMI " : "",
+ m_core->dau_psw_leq() ? "LEQ " : "",
+ m_core->dau_psw_llv() ? "LLV " : "",
+ m_core->dau_psw_lmv() ? "LMV " : "");
break;
}
}
@@ -655,28 +630,28 @@ dsp16_disassembler::cpu::predicate dsp16_device_base::check_con(offs_t pc, u16 o
switch (con >> 1)
{
case 0x0: // mi/pl
- result = dau_psw_lmi();
+ result = m_core->dau_psw_lmi();
break;
case 0x1: // eq/ne
- result = dau_psw_leq();
+ result = m_core->dau_psw_leq();
break;
case 0x2: // lvs/lvc
- result = dau_psw_llv();
+ result = m_core->dau_psw_llv();
break;
case 0x3: // mvs/mvc
- result = dau_psw_lmv();
+ result = m_core->dau_psw_lmv();
break;
case 0x4: // heads/tails
return predicate::INDETERMINATE; // FIXME: implement PRNG
case 0x5: // c0ge/c0lt
case 0x6: // c1ge/c1lt
- result = 0 <= m_dau_c[(con >> 1) - 0x05];
+ result = 0 <= m_core->dau_c[(con >> 1) - 0x05];
break;
case 0x7: // true/false
result = true;
break;
case 0x8: // gt/le
- result = !dau_psw_lmi() && !dau_psw_leq();
+ result = !m_core->dau_psw_lmi() && !m_core->dau_psw_leq();
break;
default: // Reserved
return predicate::INDETERMINATE;
@@ -729,7 +704,7 @@ inline void dsp16_device_base::execute_one_rom()
switch (m_phase)
{
case phase::PURGE:
- fetch_addr = m_xaau_pc;
+ fetch_addr = m_core->xaau_pc;
m_phase = phase::OP1;
break;
@@ -815,9 +790,9 @@ inline void dsp16_device_base::execute_one_rom()
(pio_int_enable() && pio_int_status()) ? " INT" : "",
m_st_pcbase);
set_iack(FLAGS_IACK_SET);
- fetch_addr = (m_xaau_pc & 0xf000U) | ((m_xaau_pc + 1) & 0x0fffU);
+ fetch_addr = m_core->xaau_next_pc();
m_int_enable[0] = m_int_enable[1];
- m_xaau_pc = 0x0001U;
+ m_core->xaau_pc = 0x0001U;
m_phase = phase::PURGE;
break;
}
@@ -825,7 +800,7 @@ inline void dsp16_device_base::execute_one_rom()
}
// normal opcode execution
- fetch_addr = set_xaau_pc_offset(m_xaau_pc + 1);
+ fetch_addr = set_xaau_pc_offset(m_core->xaau_pc + 1);
m_int_enable[0] = m_int_enable[1];
switch (op >> 11)
{
@@ -836,7 +811,7 @@ inline void dsp16_device_base::execute_one_rom()
if (check_predicate())
{
if (BIT(op, 15))
- m_xaau_pr = m_xaau_pc;
+ m_core->xaau_pr = m_core->xaau_pc;
set_xaau_pc_offset(op_ja(op));
}
m_phase = phase::PURGE;
@@ -856,28 +831,28 @@ inline void dsp16_device_base::execute_one_rom()
case 0x05: // F1 ; Z : aT[l]
{
fetch_target = nullptr;
- s64 const d(dau_f1(op));
- m_dau_temp = u16(u64(dau_saturate(op_d(~op))) >> (op_x(op) ? 16 : 0));
- op_dau_ad(op) = d;
- set_dau_at(op, yaau_read(op));
+ s64 const d(m_core->dau_f1(op));
+ m_core->dau_temp = u16(u64(dau_saturate(op_d(~op))) >> (op_x(op) ? 16 : 0));
+ m_core->op_dau_ad(op) = d;
+ m_core->dau_set_at(op, yaau_read(op));
m_phase = phase::OP2;
}
break;
case 0x06: // F1 ; Y
- op_dau_ad(op) = dau_f1(op);
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
yaau_read(op);
break;
case 0x07: // F1 ; aT[l] = Y
- op_dau_ad(op) = dau_f1(op);
- set_dau_at(op, yaau_read(op));
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
+ m_core->dau_set_at(op, yaau_read(op));
break;
case 0x08: // aT = R
assert(!(op & 0x000fU)); // reserved field?
fetch_target = nullptr;
- set_dau_at(op, get_r(op));
+ m_core->dau_set_at(op, get_r(op));
m_phase = phase::OP2;
break;
@@ -903,7 +878,7 @@ inline void dsp16_device_base::execute_one_rom()
case 0x0d: // Z : R
fetch_target = nullptr;
- m_dau_temp = get_r(op);
+ m_core->dau_temp = get_r(op);
set_r(op, yaau_read(op));
m_phase = phase::OP2;
break;
@@ -940,42 +915,42 @@ inline void dsp16_device_base::execute_one_rom()
case 0x12: // ifc CON F2
{
bool const con(op_dau_con(op, false));
- ++m_dau_c[1];
+ ++m_core->dau_c[1];
if (con)
{
- dau_f2(op);
- m_dau_c[2] = m_dau_c[1];
+ m_core->dau_f2(op);
+ m_core->dau_c[2] = m_core->dau_c[1];
}
}
break;
case 0x13: // if CON F2
if (op_dau_con(op, true))
- dau_f2(op);
+ m_core->dau_f2(op);
break;
case 0x14: // F1 ; Y = y[l]
fetch_target = nullptr;
- op_dau_ad(op) = dau_f1(op);
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
m_phase = phase::OP2;
break;
case 0x15: // F1 ; Z : y[l]
fetch_target = nullptr;
- op_dau_ad(op) = dau_f1(op);
- m_dau_temp = u16(u32(m_dau_y) >> (op_x(op) ? 16 : 0));
- set_dau_y(op, yaau_read(op));
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
+ m_core->dau_temp = m_core->dau_get_y(op);
+ m_core->dau_set_y(op, yaau_read(op));
m_phase = phase::OP2;
break;
case 0x16: // F1 ; x = Y
- op_dau_ad(op) = dau_f1(op);
- m_dau_x = yaau_read(op);
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
+ m_core->dau_x = yaau_read(op);
break;
case 0x17: // F1 ; y[l] = Y
- op_dau_ad(op) = dau_f1(op);
- set_dau_y(op, yaau_read(op));
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
+ m_core->dau_set_y(op, yaau_read(op));
break;
case 0x18: // goto B
@@ -984,24 +959,24 @@ inline void dsp16_device_base::execute_one_rom()
{
case 0x0: // return
if (check_predicate())
- m_xaau_pc = m_xaau_pr;
+ m_core->xaau_pc = m_core->xaau_pr;
break;
case 0x1: // ireturn
if (m_iack_out)
logerror("DSP16: ireturn when not servicing interrupt (PC = %04X)\n", m_st_pcbase);
LOGINT("DSP16: return from interrupt (PC = %04X)\n", m_st_pcbase);
set_iack(FLAGS_IACK_CLEAR);
- m_xaau_pc = m_xaau_pi;
+ m_core->xaau_pc = m_core->xaau_pi;
break;
case 0x2: // goto pt
if (check_predicate())
- m_xaau_pc = m_xaau_pt;
+ m_core->xaau_pc = m_core->xaau_pt;
break;
case 0x3: // call pt
if (check_predicate())
{
- m_xaau_pr = m_xaau_pc;
- m_xaau_pc = m_xaau_pt;
+ m_core->xaau_pr = m_core->xaau_pc;
+ m_core->xaau_pc = m_core->xaau_pt;
}
break;
case 0x4: // Reserved
@@ -1011,7 +986,7 @@ inline void dsp16_device_base::execute_one_rom()
throw emu_fatalerror("DSP16: reserved B value %01X (PC = %04X)\n", op_b(op), m_st_pcbase);
}
if (m_iack_out)
- m_xaau_pi = m_xaau_pc;
+ m_core->xaau_pi = m_core->xaau_pc;
m_phase = phase::PURGE;
break;
@@ -1019,13 +994,13 @@ inline void dsp16_device_base::execute_one_rom()
case 0x1b: // F1 ; y = a1 ; x = *pt++[i]
{
assert(!(op & 0x000fU)); // reserved field?
- s64 const d(dau_f1(op));
- s64 a(m_dau_a[BIT(op, 12)]);
+ s64 const d(m_core->dau_f1(op));
+ s64 a(m_core->dau_a[BIT(op, 12)]);
// FIXME: is saturation applied when transferring a to y?
- m_dau_y = u32(u64(a));
- op_dau_ad(op) = d;
+ m_core->dau_y = u32(u64(a));
+ m_core->op_dau_ad(op) = d;
fetch_target = nullptr;
- m_rom_data = m_spaces[AS_PROGRAM]->read_word(m_xaau_pt);
+ m_rom_data = m_spaces[AS_PROGRAM]->read_word(m_core->xaau_pt);
m_phase = phase::OP2;
}
break;
@@ -1042,11 +1017,11 @@ inline void dsp16_device_base::execute_one_rom()
break;
case 0x1d: // F1 ; Z : y ; x = *pt++[i]
- op_dau_ad(op) = dau_f1(op);
- m_dau_temp = s16(m_dau_y >> 16);
- m_dau_y = (u32(u16(yaau_read(op))) << 16) | u32(BIT(m_dau_psw, 6) ? u16(u32(m_dau_y)) : u16(0));
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
+ m_core->dau_temp = s16(m_core->dau_y >> 16);
+ m_core->dau_set_y(yaau_read(op));
fetch_target = nullptr;
- m_rom_data = m_spaces[AS_PROGRAM]->read_word(m_xaau_pt);
+ m_rom_data = m_spaces[AS_PROGRAM]->read_word(m_core->xaau_pt);
m_phase = phase::OP2;
break;
@@ -1055,10 +1030,10 @@ inline void dsp16_device_base::execute_one_rom()
break;
case 0x1f: // F1 ; y = Y ; x = *pt++[i]
- op_dau_ad(op) = dau_f1(op);
- m_dau_y = (u32(u16(yaau_read(op))) << 16) | u32(BIT(m_dau_psw, 6) ? u16(u32(m_dau_y)) : u16(0));
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
+ m_core->dau_set_y(yaau_read(op));
fetch_target = nullptr;
- m_rom_data = m_spaces[AS_PROGRAM]->read_word(m_xaau_pt);
+ m_rom_data = m_spaces[AS_PROGRAM]->read_word(m_core->xaau_pt);
m_phase = phase::OP2;
break;
@@ -1091,7 +1066,7 @@ inline void dsp16_device_base::execute_one_rom()
case 0x04: // F1 ; Y = a1[l]
case 0x1c: // F1 ; Y = a0[l]
yaau_write(op, u16(u64(dau_saturate(BIT(~op, 14))) >> (op_x(op) ? 16 : 0)));
- op_dau_ad(op) = dau_f1(op);
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
break;
case 0x05: // F1 ; Z : aT[l]
@@ -1106,7 +1081,7 @@ inline void dsp16_device_base::execute_one_rom()
break;
case 0x0a: // R = N
- set_xaau_pc_offset(m_xaau_pc + 1);
+ set_xaau_pc_offset(m_core->xaau_pc + 1);
set_r(op, m_rom_data);
break;
@@ -1118,14 +1093,14 @@ inline void dsp16_device_base::execute_one_rom()
break;
case 0x14: // F1 ; Y = y[l]
- yaau_write(op, u16(u32(m_dau_y) >> (op_x(op) ? 16 : 0)));
+ yaau_write(op, m_core->dau_get_y(op));
break;
case 0x19: // F1 ; y = a0 ; x = *pt++[i]
case 0x1b: // F1 ; y = a1 ; x = *pt++[i]
case 0x1f: // F1 ; y = Y ; x = *pt++[i]
- xaau_increment_pt(op_xaau_increment(op));
- m_dau_x = m_rom_data;
+ m_core->xaau_increment_pt(op);
+ m_core->dau_x = m_rom_data;
break;
case 0x1a: // icall
@@ -1143,14 +1118,14 @@ inline void dsp16_device_base::execute_one_rom()
(pio_int_enable() && pio_int_status()) ? " INT" : "",
m_st_pcbase);
set_iack(FLAGS_IACK_SET);
- m_xaau_pc = 0x0002U;
+ m_core->xaau_pc = 0x0002U;
}
m_phase = phase::PURGE;
break;
case 0x1d: // F1 ; Z : y ; x = *pt++[i]
- xaau_increment_pt(op_xaau_increment(op));
- m_dau_x = m_rom_data;
+ m_core->xaau_increment_pt(op);
+ m_core->dau_x = m_rom_data;
yaau_write_z(op);
break;
@@ -1168,7 +1143,7 @@ inline void dsp16_device_base::execute_one_rom()
}
else
{
- fetch_addr = m_xaau_pc;
+ fetch_addr = m_core->xaau_pc;
if (cache_load)
m_cache_ptr = cache_next;
}
@@ -1188,7 +1163,7 @@ inline void dsp16_device_base::execute_one_rom()
if (phase::OP1 == m_phase)
{
if (cache::EXECUTE != m_cache_mode)
- m_st_pcbase = m_xaau_pc;
+ m_st_pcbase = m_core->xaau_pc;
else
m_st_pcbase = (m_cache_pcbase & 0xf000U) | ((m_cache_pcbase + m_cache_ptr) & 0x0fffU);
}
@@ -1219,27 +1194,27 @@ inline void dsp16_device_base::execute_one_cache()
case 0x05: // F1 ; Z : aT[l]
{
- s64 const d(dau_f1(op));
- m_dau_temp = u16(u64(dau_saturate(op_d(~op))) >> (op_x(op) ? 16 : 0));
- op_dau_ad(op) = d;
- set_dau_at(op, yaau_read(op));
+ s64 const d(m_core->dau_f1(op));
+ m_core->dau_temp = u16(u64(dau_saturate(op_d(~op))) >> (op_x(op) ? 16 : 0));
+ m_core->op_dau_ad(op) = d;
+ m_core->dau_set_at(op, yaau_read(op));
m_phase = phase::OP2;
}
break;
case 0x06: // F1 ; Y
- op_dau_ad(op) = dau_f1(op);
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
yaau_read(op);
break;
case 0x07: // F1 ; aT[l] = Y
- op_dau_ad(op) = dau_f1(op);
- set_dau_at(op, yaau_read(op));
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
+ m_core->dau_set_at(op, yaau_read(op));
break;
case 0x08: // aT = R
assert(!(op & 0x000fU)); // reserved field?
- set_dau_at(op, get_r(op));
+ m_core->dau_set_at(op, get_r(op));
m_phase = phase::OP2;
break;
@@ -1256,7 +1231,7 @@ inline void dsp16_device_base::execute_one_cache()
break;
case 0x0d: // Z : R
- m_dau_temp = get_r(op);
+ m_core->dau_temp = get_r(op);
set_r(op, yaau_read(op));
m_phase = phase::OP2;
break;
@@ -1270,84 +1245,84 @@ inline void dsp16_device_base::execute_one_cache()
case 0x12: // ifc CON F2
{
bool const con(op_dau_con(op, false));
- ++m_dau_c[1];
+ ++m_core->dau_c[1];
if (con)
{
- dau_f2(op);
- m_dau_c[2] = m_dau_c[1];
+ m_core->dau_f2(op);
+ m_core->dau_c[2] = m_core->dau_c[1];
}
}
break;
case 0x13: // if CON F2
if (op_dau_con(op, true))
- dau_f2(op);
+ m_core->dau_f2(op);
break;
case 0x14: // F1 ; Y = y[l]
- op_dau_ad(op) = dau_f1(op);
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
m_phase = phase::OP2;
break;
case 0x15: // F1 ; Z : y[l]
- op_dau_ad(op) = dau_f1(op);
- m_dau_temp = u16(u32(m_dau_y) >> (op_x(op) ? 16 : 0));
- set_dau_y(op, yaau_read(op));
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
+ m_core->dau_temp = m_core->dau_get_y(op);
+ m_core->dau_set_y(op, yaau_read(op));
m_phase = phase::OP2;
break;
case 0x16: // F1 ; x = Y
- op_dau_ad(op) = dau_f1(op);
- m_dau_x = yaau_read(op);
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
+ m_core->dau_x = yaau_read(op);
break;
case 0x17: // F1 ; y[l] = Y
- op_dau_ad(op) = dau_f1(op);
- set_dau_y(op, yaau_read(op));
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
+ m_core->dau_set_y(op, yaau_read(op));
break;
case 0x19: // F1 ; y = a0 ; x = *pt++[i]
case 0x1b: // F1 ; y = a1 ; x = *pt++[i]
{
assert(!(op & 0x000fU)); // reserved field?
- s64 const d(dau_f1(op));
- s64 a(m_dau_a[BIT(op, 12)]);
+ s64 const d(m_core->dau_f1(op));
+ s64 a(m_core->dau_a[BIT(op, 12)]);
// FIXME: is saturation applied when transferring a to y?
- m_dau_y = u32(u64(a));
- op_dau_ad(op) = d;
+ m_core->dau_y = u32(u64(a));
+ m_core->op_dau_ad(op) = d;
if (last_instruction)
{
- m_rom_data = m_direct->read_word(m_xaau_pt);
+ m_rom_data = m_direct->read_word(m_core->xaau_pt);
m_phase = phase::OP2;
}
else
{
- xaau_increment_pt(op_xaau_increment(op));
- m_dau_x = m_rom_data;
+ m_core->xaau_increment_pt(op);
+ m_core->dau_x = m_rom_data;
}
}
break;
case 0x1d: // F1 ; Z : y ; x = *pt++[i]
- op_dau_ad(op) = dau_f1(op);
- m_dau_temp = s16(m_dau_y >> 16);
- m_dau_y = (u32(u16(yaau_read(op))) << 16) | u32(BIT(m_dau_psw, 6) ? u16(u32(m_dau_y)) : u16(0));
- m_rom_data = m_direct->read_word(m_xaau_pt);
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
+ m_core->dau_temp = s16(m_core->dau_y >> 16);
+ m_core->dau_set_y(yaau_read(op));
+ m_rom_data = m_direct->read_word(m_core->xaau_pt);
m_phase = phase::OP2;
break;
case 0x1f: // F1 ; y = Y ; x = *pt++[i]
- op_dau_ad(op) = dau_f1(op);
- m_dau_y = (u32(u16(yaau_read(op))) << 16) | u32(BIT(m_dau_psw, 6) ? u16(u32(m_dau_y)) : u16(0));
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
+ m_core->dau_set_y(yaau_read(op));
if (last_instruction)
{
- m_rom_data = m_direct->read_word(m_xaau_pt);
+ m_rom_data = m_direct->read_word(m_core->xaau_pt);
m_phase = phase::OP2;
}
else
{
- xaau_increment_pt(op_xaau_increment(op));
- m_dau_x = m_rom_data;
+ m_core->xaau_increment_pt(op);
+ m_core->dau_x = m_rom_data;
}
break;
@@ -1363,7 +1338,7 @@ inline void dsp16_device_base::execute_one_cache()
case 0x04: // F1 ; Y = a1[l]
case 0x1c: // F1 ; Y = a0[l]
yaau_write(op, u16(u64(dau_saturate(BIT(~op, 14))) >> (op_x(op) ? 16 : 0)));
- op_dau_ad(op) = dau_f1(op);
+ m_core->op_dau_ad(op) = m_core->dau_f1(op);
break;
case 0x05: // F1 ; Z : aT[l]
@@ -1385,20 +1360,20 @@ inline void dsp16_device_base::execute_one_cache()
break;
case 0x14: // F1 ; Y = y[l]
- yaau_write(op, u16(u32(m_dau_y) >> (op_x(op) ? 16 : 0)));
+ yaau_write(op, m_core->dau_get_y(op));
break;
case 0x19: // F1 ; y = a0 ; x = *pt++[i]
case 0x1b: // F1 ; y = a1 ; x = *pt++[i]
case 0x1f: // F1 ; y = Y ; x = *pt++[i]
assert(last_instruction);
- xaau_increment_pt(op_xaau_increment(op));
- m_dau_x = m_rom_data;
+ m_core->xaau_increment_pt(op);
+ m_core->dau_x = m_rom_data;
break;
case 0x1d: // F1 ; Z : y ; x = *pt++[i]
- xaau_increment_pt(op_xaau_increment(op));
- m_dau_x = m_rom_data;
+ m_core->xaau_increment_pt(op);
+ m_core->dau_x = m_rom_data;
yaau_write_z(op);
break;
@@ -1426,8 +1401,8 @@ inline void dsp16_device_base::execute_one_cache()
{
// overlapped fetch of next instruction from ROM
m_cache_mode = cache::NONE;
- m_cache[m_cache_ptr = 0] = m_direct->read_word(m_xaau_pc);
- m_st_pcbase = m_xaau_pc;
+ m_cache[m_cache_ptr = 0] = m_direct->read_word(m_core->xaau_pc);
+ m_st_pcbase = m_core->xaau_pc;
}
else
{
@@ -1458,7 +1433,7 @@ inline void dsp16_device_base::overlap_rom_data_read()
case 0x19: // F1 ; y = a0 ; x = *pt++[i]
case 0x1b: // F1 ; y = a1 ; x = *pt++[i]
case 0x1f: // F1 ; y = Y ; x = *pt++[i]
- m_rom_data = m_direct->read_word(m_xaau_pt);
+ m_rom_data = m_direct->read_word(m_core->xaau_pt);
break;
}
}
@@ -1470,49 +1445,48 @@ inline void dsp16_device_base::yaau_short_immediate_load(u16 op)
switch (r)
{
case 0x0: // j
- m_yaau_j = m | ((m & m_yaau_sign) ? ~m_yaau_mask : 0);
+ m_core->yaau_j = m | ((m & m_core->yaau_sign) ? ~m_core->yaau_mask : 0);
break;
case 0x1: // k
- m_yaau_k = m | ((m & m_yaau_sign) ? ~m_yaau_mask : 0);
+ m_core->yaau_k = m | ((m & m_core->yaau_sign) ? ~m_core->yaau_mask : 0);
break;
case 0x2: // rb
- m_yaau_rb = m;
+ m_core->yaau_rb = m;
break;
case 0x3: // re
- m_yaau_re = m;
+ m_core->yaau_re = m;
break;
case 0x4: // r0
case 0x5: // r1
case 0x6: // r2
case 0x7: // r3
- m_yaau_r[r & 0x0003U] = m;
+ m_core->yaau_r[r & 0x0003U] = m;
break;
}
}
inline s16 dsp16_device_base::yaau_read(u16 op)
{
- s16 const result(m_spaces[AS_DATA]->read_word(op_yaau_r(op)));
- yaau_postmodify_r(op);
+ s16 const result(m_spaces[AS_DATA]->read_word(m_core->op_yaau_r(op)));
+ m_core->yaau_postmodify_r(op);
return result;
}
inline void dsp16_device_base::yaau_write(u16 op, s16 value)
{
- m_spaces[AS_DATA]->write_word(op_yaau_r(op), value);
- yaau_postmodify_r(op);
+ m_spaces[AS_DATA]->write_word(m_core->op_yaau_r(op), value);
+ m_core->yaau_postmodify_r(op);
}
void dsp16_device_base::yaau_write_z(u16 op)
{
- u16 &r(op_yaau_r(op));
- m_spaces[AS_DATA]->write_word(r, m_dau_temp);
+ u16 &r(m_core->op_yaau_r(op));
+ m_spaces[AS_DATA]->write_word(r, m_core->dau_temp);
switch (op & 0x0003U)
{
case 0x0: // *rNzp
- // TODO: does virtual shift register addressing apply here?
- if (m_yaau_re && (m_yaau_re == r))
- r = m_yaau_rb;
+ if (m_core->yaau_re && (m_core->yaau_re == r))
+ r = m_core->yaau_rb;
else
++r;
break;
@@ -1522,134 +1496,10 @@ void dsp16_device_base::yaau_write_z(u16 op)
r += 2;
break;
case 0x3: // *rNjk;
- r += m_yaau_k;
- break;
- }
- r &= m_yaau_mask;
-}
-
-inline u64 dsp16_device_base::dau_f1(u16 op)
-{
- s64 const &s(op_dau_as(op));
- s64 d(0);
- switch (op_f1(op))
- {
- case 0x0: // aD = p ; p = x*y
- d = get_dau_p_aligned();
- m_dau_p = m_dau_x * (m_dau_y >> 16);
- break;
- case 0x1: // aD = aS + p ; p = x*y
- d = s + get_dau_p_aligned();
- m_dau_p = m_dau_x * (m_dau_y >> 16);
- break;
- case 0x2: // p = x*y
- m_dau_p = m_dau_x * (m_dau_y >> 16);
- return op_dau_ad(op);
- case 0x3: // aD = aS - p ; p = x*y
- d = s - get_dau_p_aligned();
- m_dau_p = m_dau_x * (m_dau_y >> 16);
- break;
- case 0x4: // aD = p
- d = get_dau_p_aligned();
- break;
- case 0x5: // aD = aS + p
- d = s + get_dau_p_aligned();
- break;
- case 0x6: // NOP
- return op_dau_ad(op);
- case 0x7: // aD = aS - p
- d = s - get_dau_p_aligned();
- break;
- case 0x8: // aD = aS | y
- d = s | m_dau_y;
- break;
- case 0x9: // aD = aS ^ y
- d = s ^ m_dau_y;
- break;
- case 0xa: // aS & y
- set_dau_psw_flags(s & m_dau_y);
- return op_dau_ad(op);
- case 0xb: // aS - y
- set_dau_psw_flags(s - m_dau_y);
- return op_dau_ad(op);
- case 0xc: // aD = y
- d = m_dau_y;
- break;
- case 0xd: // aD = aS + y
- d = s + m_dau_y;
- break;
- case 0xe: // aD = aS & y
- d = s & m_dau_y;
- break;
- case 0xf: // aD = aS - y
- d = s - m_dau_y;
- break;
- }
- return set_dau_psw_flags(d);
-}
-
-inline void dsp16_device_base::dau_f2(u16 op)
-{
- s64 const &s(op_dau_as(op));
- s64 &d(op_dau_ad(op));
- switch (op_f2(op))
- {
- case 0x0: // aD = aS >> 1
- d = s >> 1;
- break;
- case 0x1: // aD = aS << 1
- d = s32(u32(u64(s)) << 1);
- break;
- case 0x2: // aD = aS >> 4
- d = s >> 4;
- break;
- case 0x3: // aD = aS << 4
- d = s32(u32(u64(s)) << 4);
- break;
- case 0x4: // aD = aS >> 8
- d = s >> 8;
- break;
- case 0x5: // aD = aS << 8
- d = s32(u32(u64(s)) << 8);
- break;
- case 0x6: // aD = aS >> 16
- d = s >> 16;
- break;
- case 0x7: // aD = aS << 16
- d = s32(u32(u64(s)) << 16);
- break;
- case 0x8: // aD = p
- d = get_dau_p_aligned();
- break;
- case 0x9: // aDh = aSh + 1
- d = s64(s32(u32(u64(s)) & ~((u32(1) << 16) - 1))) + (s32(1) << 16);
- if (BIT(m_dau_auc, op_s(op) + 4))
- d |= op_dau_ad(op) & ((s64(1) << 16) - 1);
- break;
- case 0xa: // Reserved
- throw emu_fatalerror("DSP16: reserved F2 value %01X (PC = %04X)\n", op_f2(op), m_st_pcbase);
- case 0xb: // aD = rnd(aS)
- // FIXME: behaviour is not clear
- // p 3-13: "Round upper 20 bits of accumulator."
- // p 3-14: "The contents of the source accumulator, aS, are rounded to 16 bits, and the sign-extended result is placed in aD[35 - 16] with zeroes in aD[15 - 0]."
- // It presumably rounds to nearest, but does it yield a 16-bit or 20-bit result, and what does it do about overflow?
- d = (s + ((0 > s) ? -(s16(1) << 15) : (s16(1) << 15))) & ~((u64(1) << 16) - 1);
- break;
- case 0xc: // aD = y
- d = m_dau_y;
- break;
- case 0xd: // aD = aS + 1
- d = s + 1;
- break;
- case 0xe: // aD = aS
- d = s;
- break;
- case 0xf: // aD = -aS
- // FIXME: does this detect negation of largest negative number as overflow?
- d = -s;
+ r += m_core->yaau_k;
break;
}
- d = set_dau_psw_flags(d);
+ r &= m_core->yaau_mask;
}
/***********************************************************************
@@ -1707,10 +1557,10 @@ inline bool dsp16_device_base::check_predicate()
inline u16 &dsp16_device_base::set_xaau_pc_offset(u16 offset)
{
- m_xaau_pc = (m_xaau_pc & XAAU_I_EXT) | (offset & XAAU_I_MASK);
+ m_core->xaau_pc = (m_core->xaau_pc & XAAU_I_EXT) | (offset & XAAU_I_MASK);
if (m_iack_out)
- m_xaau_pi = m_xaau_pc;
- return m_xaau_pc;
+ m_core->xaau_pi = m_core->xaau_pc;
+ return m_core->xaau_pc;
}
inline s16 dsp16_device_base::get_r(u16 op)
@@ -1721,38 +1571,38 @@ inline s16 dsp16_device_base::get_r(u16 op)
case 0x01: // r1 (u)
case 0x02: // r2 (u)
case 0x03: // r3 (u)
- return m_yaau_r[op_r(op)];
+ return m_core->yaau_r[op_r(op)];
case 0x04: // j (s)
- return m_yaau_j;
+ return m_core->yaau_j;
case 0x05: // k (s)
- return m_yaau_k;
+ return m_core->yaau_k;
case 0x06: // rb (u)
- return m_yaau_rb;
+ return m_core->yaau_rb;
case 0x07: // re (u)
- return m_yaau_re;
+ return m_core->yaau_re;
case 0x08: // pt
- return m_xaau_pt;
+ return m_core->xaau_pt;
case 0x09: // pr
- return m_xaau_pr;
+ return m_core->xaau_pr;
case 0x0a: // pi
- return m_xaau_pi;
+ return m_core->xaau_pi;
case 0x0b: // i (s)
- return m_xaau_i;
+ return m_core->xaau_i;
case 0x10: // x
- return m_dau_x;
+ return m_core->dau_x;
case 0x11: // y
- return u16(u32(m_dau_y >> 16));
+ return u16(u32(m_core->dau_y >> 16));
case 0x12: // yl
- return u16(u32(m_dau_y));
+ return u16(u32(m_core->dau_y));
break;
case 0x13: // auc (u)
- return m_dau_auc;
+ return m_core->dau_auc;
case 0x14: // psw
- return m_dau_psw = (m_dau_psw & 0xfe10U) | (u16(u64(m_dau_a[0]) >> 32) & 0x000fU) | (u16(u64(m_dau_a[1]) >> 27) & 0x01e0U);
+ return m_core->dau_export_psw();
case 0x15: // c0 (s)
case 0x16: // c1 (s)
case 0x17: // c2 (s)
- return m_dau_c[op_r(op) - 0x15];
+ return m_core->dau_c[op_r(op) - 0x15];
case 0x18: // sioc
return m_sio_sioc;
case 0x19: // srta
@@ -1782,55 +1632,54 @@ inline void dsp16_device_base::set_r(u16 op, s16 value)
case 0x01: // r1 (u)
case 0x02: // r2 (u)
case 0x03: // r3 (u)
- m_yaau_r[op_r(op)] = value & m_yaau_mask;
+ m_core->yaau_r[op_r(op)] = value & m_core->yaau_mask;
break;
case 0x04: // j (s)
- m_yaau_j = (value & m_yaau_mask) | ((value & m_yaau_sign) ? ~m_yaau_mask : 0);
+ m_core->yaau_set_j(value);
break;
case 0x05: // k (s)
- m_yaau_k = (value & m_yaau_mask) | ((value & m_yaau_sign) ? ~m_yaau_mask : 0);
+ m_core->yaau_set_k(value);
break;
case 0x06: // rb (u)
- m_yaau_rb = value & m_yaau_mask;
+ m_core->yaau_set_rb(value);
break;
case 0x07: // re (u)
- m_yaau_re = value & m_yaau_mask;
+ m_core->yaau_set_re(value);
break;
case 0x08: // pt
- m_xaau_pt = value;
+ m_core->xaau_pt = value;
break;
case 0x09: // pr
- m_xaau_pr = value;
+ m_core->xaau_pr = value;
break;
case 0x0a: // pi
// FIXME: reset PRNG
if (!m_iack_out)
- m_xaau_pi = value;
+ m_core->xaau_pi = value;
break;
case 0x0b: // i (s)
- m_xaau_i = (value & XAAU_I_MASK) | ((value & XAAU_I_SIGN) ? XAAU_I_EXT : 0);
+ m_core->xaau_i = (value & XAAU_I_MASK) | ((value & XAAU_I_SIGN) ? XAAU_I_EXT : 0);
break;
case 0x10: // x
- m_dau_x = value;
+ m_core->dau_x = value;
break;
case 0x11: // y
- m_dau_y = (u32(u16(value)) << 16) | u32(BIT(m_dau_auc, 6) ? u16(u32(m_dau_y)) : u16(0));
+ m_core->dau_set_y(value);
break;
case 0x12: // yl
- m_dau_y = (m_dau_y & 0xffff'0000) | u32(u16(value));
+ m_core->dau_set_yl(value);
break;
case 0x13: // auc (u)
- m_dau_auc = u8(value & 0x007f);
+ m_core->dau_auc = u8(value & 0x007f);
break;
case 0x14: // psw
- m_dau_psw = value;
- m_dau_a[0] = u64(u32(m_dau_a[0])) | (u64(value & 0x000fU) << 32) | (BIT(value, 3) ? DAU_A_EXT : 0U);
- m_dau_a[1] = u64(u32(m_dau_a[1])) | (u64(value & 0x01e0U) << 27) | (BIT(value, 8) ? DAU_A_EXT : 0U);
+ m_core->dau_psw = value;
+ m_core->dau_import_psw();
break;
case 0x15: // c0 (s)
case 0x16: // c1 (s)
case 0x17: // c2 (s)
- m_dau_c[op_r(op) - 0x15] = u8(u16(value));
+ m_core->dau_c[op_r(op) - 0x15] = u8(u16(value));
break;
case 0x18: // sioc
sio_sioc_write(value);
@@ -1860,99 +1709,12 @@ inline void dsp16_device_base::set_r(u16 op, s16 value)
}
}
-inline void dsp16_device_base::yaau_postmodify_r(u16 op)
-{
- u16 &r(op_yaau_r(op));
- switch (op & 0x0003U)
- {
- case 0x0: // *rN
- break;
- case 0x1: // *rN++
- if (m_yaau_re && (m_yaau_re == r))
- r = m_yaau_rb;
- else
- ++r;
- break;
- case 0x2: // *rN--
- --r;
- break;
- case 0x3: // *rN++j
- r += m_yaau_j;
- break;
- }
- r &= m_yaau_mask;
-}
-
-inline void dsp16_device_base::set_dau_y(u16 op, s16 value)
-{
- if (op_x(op))
- {
- bool const clear(!BIT(m_dau_psw, 6));
- m_dau_y = (u32(u16(value)) << 16) | u32(clear ? u16(0) : u16(u32(m_dau_y)));
- }
- else
- {
- m_dau_y = (m_dau_y & ~((s32(1) << 16) - 1)) | u32(u16(value));
- }
-}
-
s64 dsp16_device_base::dau_saturate(u16 a) const
{
- if (dau_auc_sat(a))
- return m_dau_a[a];
- else
- return std::min<s64>(std::max<s64>(m_dau_a[a], std::numeric_limits<s32>::min()), std::numeric_limits<s32>::max());
-}
-
-inline void dsp16_device_base::set_dau_at(u16 op, s16 value)
-{
- s64 &at(op_dau_at(op));
- if (op_x(op))
- {
- bool const clear(!BIT(m_dau_psw, 4 + op_d(~op)));
- at = s32((u32(u16(value)) << 16) | u32(clear ? u16(0) : u16(u64(at))));
- }
- else
- {
- at = (at & ~((s64(1) << 16) - 1)) | u64(u16(value));
- }
-}
-
-inline u64 dsp16_device_base::set_dau_psw_flags(s64 d)
-{
- m_dau_psw &= 0x0fffU;
- bool const negative(d & DAU_A_SIGN);
- if (negative)
- m_dau_psw |= 0x8000U;
- if (!(d & DAU_A_MASK))
- m_dau_psw |= 0x4000U;
- if ((d >> 36) != (negative ? -1 : 0))
- m_dau_psw |= 0x2000U;
- if (((d >> 32) & ((1 << 4) - 1)) != (BIT(d, 31) ? 15 : 0))
- m_dau_psw |= 0x1000U;
- if (negative)
- return d | DAU_A_EXT;
+ if (m_core->dau_auc_sat(a))
+ return m_core->dau_a[a];
else
- return d & DAU_A_MASK;
-}
-
-inline u64 dsp16_device_base::get_dau_p_aligned() const
-{
- // TODO: manual is contradictory
- // p 2-10: "Bits 1 and 2 of the accumulator are not changed by the load of the accumulator with the data in p, since 00 is added to or copied into these accumulator bits as indicated in Figure 2-8."
- // I'm reading this as copying p to aD clears the low two bits, but adding it leaves them unchanged.
- switch (dau_auc_align())
- {
- case 0x0:
- return m_dau_p;
- case 0x1:
- return m_dau_p >> 2;
- case 0x2:
- return u64(m_dau_p) << 2;
- case 0x3:
- default:
- throw emu_fatalerror("DSP16: reserved ALIGN value %01X (PC = %04X)\n", dau_auc_align(), m_st_pcbase);
- }
+ return std::min<s64>(std::max<s64>(m_core->dau_a[a], std::numeric_limits<s32>::min()), std::numeric_limits<s32>::max());
}
inline bool dsp16_device_base::op_dau_con(u16 op, bool inc)
@@ -1962,23 +1724,23 @@ inline bool dsp16_device_base::op_dau_con(u16 op, bool inc)
switch (con >> 1)
{
case 0x0: // mi/pl
- result = dau_psw_lmi();
+ result = m_core->dau_psw_lmi();
break;
case 0x1: // eq/ne
- result = dau_psw_leq();
+ result = m_core->dau_psw_leq();
break;
case 0x2: // lvs/lvc
- result = dau_psw_llv();
+ result = m_core->dau_psw_llv();
break;
case 0x3: // mvs/mvc
- result = dau_psw_lmv();
+ result = m_core->dau_psw_lmv();
break;
case 0x4: // heads/tails
throw emu_fatalerror("DSP16: unimplemented CON value %02X (PC = %04X)\n", con, m_st_pcbase);
case 0x5: // c0ge/c0lt
case 0x6: // c1ge/c1lt
{
- s8 &c(m_dau_c[(con >> 1) - 0x05]);
+ s8 &c(m_core->dau_c[(con >> 1) - 0x05]);
result = 0 <= c;
if (inc)
++c;
@@ -1988,7 +1750,7 @@ inline bool dsp16_device_base::op_dau_con(u16 op, bool inc)
result = true;
break;
case 0x8: // gt/le
- result = !dau_psw_lmi() && !dau_psw_leq();
+ result = !m_core->dau_psw_lmi() && !m_core->dau_psw_leq();
break;
default: // Reserved
throw emu_fatalerror("DSP16: reserved CON value %02X (PC = %04X)\n", con, m_st_pcbase);