summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/adsp2100/adsp2100.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/adsp2100/adsp2100.cpp')
-rw-r--r--src/devices/cpu/adsp2100/adsp2100.cpp1908
1 files changed, 1908 insertions, 0 deletions
diff --git a/src/devices/cpu/adsp2100/adsp2100.cpp b/src/devices/cpu/adsp2100/adsp2100.cpp
new file mode 100644
index 00000000000..8142a6a7a34
--- /dev/null
+++ b/src/devices/cpu/adsp2100/adsp2100.cpp
@@ -0,0 +1,1908 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles
+/***************************************************************************
+
+ ADSP2100.c
+
+ ADSP-21xx series emulator.
+
+****************************************************************************
+
+ For ADSP-2101, ADSP-2111
+ ------------------------
+
+ MMAP = 0 MMAP = 1
+
+ Automatic boot loading No auto boot loading
+
+ Program Space: Program Space:
+ 0000-07ff = 2k Internal RAM (booted) 0000-37ff = 14k External access
+ 0800-3fff = 14k External access 3800-3fff = 2k Internal RAM
+
+ Data Space: Data Space:
+ 0000-03ff = 1k External DWAIT0 0000-03ff = 1k External DWAIT0
+ 0400-07ff = 1k External DWAIT1 0400-07ff = 1k External DWAIT1
+ 0800-2fff = 10k External DWAIT2 0800-2fff = 10k External DWAIT2
+ 3000-33ff = 1k External DWAIT3 3000-33ff = 1k External DWAIT3
+ 3400-37ff = 1k External DWAIT4 3400-37ff = 1k External DWAIT4
+ 3800-3bff = 1k Internal RAM 3800-3bff = 1k Internal RAM
+ 3c00-3fff = 1k Internal Control regs 3c00-3fff = 1k Internal Control regs
+
+
+ For ADSP-2105, ADSP-2115
+ ------------------------
+
+ MMAP = 0 MMAP = 1
+
+ Automatic boot loading No auto boot loading
+
+ Program Space: Program Space:
+ 0000-03ff = 1k Internal RAM (booted) 0000-37ff = 14k External access
+ 0400-07ff = 1k Reserved 3800-3bff = 1k Internal RAM
+ 0800-3fff = 14k External access 3c00-3fff = 1k Reserved
+
+ Data Space: Data Space:
+ 0000-03ff = 1k External DWAIT0 0000-03ff = 1k External DWAIT0
+ 0400-07ff = 1k External DWAIT1 0400-07ff = 1k External DWAIT1
+ 0800-2fff = 10k External DWAIT2 0800-2fff = 10k External DWAIT2
+ 3000-33ff = 1k External DWAIT3 3000-33ff = 1k External DWAIT3
+ 3400-37ff = 1k External DWAIT4 3400-37ff = 1k External DWAIT4
+ 3800-39ff = 512 Internal RAM 3800-39ff = 512 Internal RAM
+ 3a00-3bff = 512 Reserved 3a00-3bff = 512 Reserved
+ 3c00-3fff = 1k Internal Control regs 3c00-3fff = 1k Internal Control regs
+
+
+ For ADSP-2104
+ -------------
+
+ MMAP = 0 MMAP = 1
+
+ Automatic boot loading No auto boot loading
+
+ Program Space: Program Space:
+ 0000-01ff = 512 Internal RAM (booted) 0000-37ff = 14k External access
+ 0400-07ff = 1k Reserved 3800-3bff = 1k Internal RAM
+ 0800-3fff = 14k External access 3c00-3fff = 1k Reserved
+
+ Data Space: Data Space:
+ 0000-03ff = 1k External DWAIT0 0000-03ff = 1k External DWAIT0
+ 0400-07ff = 1k External DWAIT1 0400-07ff = 1k External DWAIT1
+ 0800-2fff = 10k External DWAIT2 0800-2fff = 10k External DWAIT2
+ 3000-33ff = 1k External DWAIT3 3000-33ff = 1k External DWAIT3
+ 3400-37ff = 1k External DWAIT4 3400-37ff = 1k External DWAIT4
+ 3800-38ff = 256 Internal RAM 3800-38ff = 256 Internal RAM
+ 3a00-3bff = 512 Reserved 3a00-3bff = 512 Reserved
+ 3c00-3fff = 1k Internal Control regs 3c00-3fff = 1k Internal Control regs
+
+
+ For ADSP-2181
+ -------------
+
+ MMAP = 0 MMAP = 1
+
+ Program Space: Program Space:
+ 0000-1fff = 8k Internal RAM 0000-1fff = 8k External access
+ 2000-3fff = 8k Internal RAM or Overlay 2000-3fff = 8k Internal
+
+ Data Space: Data Space:
+ 0000-1fff = 8k Internal RAM or Overlay 0000-1fff = 8k Internal RAM or Overlay
+ 2000-3fdf = 8k-32 Internal RAM 2000-3fdf = 8k-32 Internal RAM
+ 3fe0-3fff = 32 Internal Control regs 3fe0-3fff = 32 Internal Control regs
+
+ I/O Space: I/O Space:
+ 0000-01ff = 512 External IOWAIT0 0000-01ff = 512 External IOWAIT0
+ 0200-03ff = 512 External IOWAIT1 0200-03ff = 512 External IOWAIT1
+ 0400-05ff = 512 External IOWAIT2 0400-05ff = 512 External IOWAIT2
+ 0600-07ff = 512 External IOWAIT3 0600-07ff = 512 External IOWAIT3
+
+***************************************************************************/
+
+#include "emu.h"
+#include "debugger.h"
+#include "adsp2100.h"
+
+
+// device type definitions
+const device_type ADSP2100 = &device_creator<adsp2100_device>;
+const device_type ADSP2101 = &device_creator<adsp2101_device>;
+const device_type ADSP2104 = &device_creator<adsp2104_device>;
+const device_type ADSP2105 = &device_creator<adsp2105_device>;
+const device_type ADSP2115 = &device_creator<adsp2115_device>;
+const device_type ADSP2181 = &device_creator<adsp2181_device>;
+
+
+//**************************************************************************
+// DEVICE INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// adsp21xx_device - constructor
+//-------------------------------------------------
+
+adsp21xx_device::adsp21xx_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT32 chiptype, const char *shortname, const char *source)
+ : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source),
+ m_program_config("program", ENDIANNESS_LITTLE, 32, 14, -2),
+ m_data_config("data", ENDIANNESS_LITTLE, 16, 14, -1),
+ m_chip_type(chiptype),
+ m_pc(0),
+ m_ppc(0),
+ m_loop(0),
+ m_loop_condition(0),
+ m_cntr(0),
+ m_astat(0),
+ m_sstat(0),
+ m_mstat(0),
+ m_mstat_prev(0),
+ m_astat_clear(0),
+ m_idle(0),
+ m_px(0),
+ m_pc_sp(0),
+ m_cntr_sp(0),
+ m_stat_sp(0),
+ m_loop_sp(0),
+ m_flagout(0),
+ m_flagin(0),
+ m_fl0(0),
+ m_fl1(0),
+ m_fl2(0),
+ m_idma_addr(0),
+ m_idma_cache(0),
+ m_idma_offs(0),
+ m_imask(0),
+ m_icntl(0),
+ m_ifc(0),
+ m_icount(0),
+ m_mstat_mask((m_chip_type >= CHIP_TYPE_ADSP2101) ? 0x7f : 0x0f),
+ m_imask_mask((m_chip_type >= CHIP_TYPE_ADSP2181) ? 0x3ff :
+ (m_chip_type >= CHIP_TYPE_ADSP2101) ? 0x3f : 0x0f),
+ m_sport_rx_cb(*this),
+ m_sport_tx_cb(*this),
+ m_timer_fired_cb(*this)
+{
+ // initialize remaining state
+ memset(&m_core, 0, sizeof(m_core));
+ memset(&m_alt, 0, sizeof(m_alt));
+ memset(&m_i, 0, sizeof(m_i));
+ memset(&m_m, 0, sizeof(m_m));
+ memset(&m_l, 0, sizeof(m_l));
+ memset(&m_lmask, 0, sizeof(m_lmask));
+ memset(&m_base, 0, sizeof(m_base));
+ memset(&m_loop_stack, 0, sizeof(m_loop_stack));
+ memset(&m_cntr_stack, 0, sizeof(m_cntr_stack));
+ memset(&m_pc_stack, 0, sizeof(m_pc_stack));
+ memset(&m_stat_stack, 0, sizeof(m_stat_stack));
+ memset(&m_irq_state, 0, sizeof(m_irq_state));
+ memset(&m_irq_latch, 0, sizeof(m_irq_latch));
+
+ // create the tables
+ create_tables();
+
+ // set up read register group 0 pointers
+ m_read0_ptr[0x00] = &m_core.ax0.s;
+ m_read0_ptr[0x01] = &m_core.ax1.s;
+ m_read0_ptr[0x02] = &m_core.mx0.s;
+ m_read0_ptr[0x03] = &m_core.mx1.s;
+ m_read0_ptr[0x04] = &m_core.ay0.s;
+ m_read0_ptr[0x05] = &m_core.ay1.s;
+ m_read0_ptr[0x06] = &m_core.my0.s;
+ m_read0_ptr[0x07] = &m_core.my1.s;
+ m_read0_ptr[0x08] = &m_core.si.s;
+ m_read0_ptr[0x09] = &m_core.se.s;
+ m_read0_ptr[0x0a] = &m_core.ar.s;
+ m_read0_ptr[0x0b] = &m_core.mr.mrx.mr0.s;
+ m_read0_ptr[0x0c] = &m_core.mr.mrx.mr1.s;
+ m_read0_ptr[0x0d] = &m_core.mr.mrx.mr2.s;
+ m_read0_ptr[0x0e] = &m_core.sr.srx.sr0.s;
+ m_read0_ptr[0x0f] = &m_core.sr.srx.sr1.s;
+
+ // set up read register group 1 + 2 pointers
+ for (int index = 0; index < 4; index++)
+ {
+ m_read1_ptr[0x00 + index] = &m_i[0 + index];
+ m_read1_ptr[0x04 + index] = (UINT32 *)&m_m[0 + index];
+ m_read1_ptr[0x08 + index] = &m_l[0 + index];
+ m_read1_ptr[0x0c + index] = &m_l[0 + index];
+ m_read2_ptr[0x00 + index] = &m_i[4 + index];
+ m_read2_ptr[0x04 + index] = (UINT32 *)&m_m[4 + index];
+ m_read2_ptr[0x08 + index] = &m_l[4 + index];
+ m_read2_ptr[0x0c + index] = &m_l[4 + index];
+ }
+
+ // set up ALU register pointers
+ m_alu_xregs[0] = &m_core.ax0;
+ m_alu_xregs[1] = &m_core.ax1;
+ m_alu_xregs[2] = &m_core.ar;
+ m_alu_xregs[3] = &m_core.mr.mrx.mr0;
+ m_alu_xregs[4] = &m_core.mr.mrx.mr1;
+ m_alu_xregs[5] = &m_core.mr.mrx.mr2;
+ m_alu_xregs[6] = &m_core.sr.srx.sr0;
+ m_alu_xregs[7] = &m_core.sr.srx.sr1;
+ m_alu_yregs[0] = &m_core.ay0;
+ m_alu_yregs[1] = &m_core.ay1;
+ m_alu_yregs[2] = &m_core.af;
+ m_alu_yregs[3] = &m_core.zero;
+
+ // set up MAC register pointers
+ m_mac_xregs[0] = &m_core.mx0;
+ m_mac_xregs[1] = &m_core.mx1;
+ m_mac_xregs[2] = &m_core.ar;
+ m_mac_xregs[3] = &m_core.mr.mrx.mr0;
+ m_mac_xregs[4] = &m_core.mr.mrx.mr1;
+ m_mac_xregs[5] = &m_core.mr.mrx.mr2;
+ m_mac_xregs[6] = &m_core.sr.srx.sr0;
+ m_mac_xregs[7] = &m_core.sr.srx.sr1;
+ m_mac_yregs[0] = &m_core.my0;
+ m_mac_yregs[1] = &m_core.my1;
+ m_mac_yregs[2] = &m_core.mf;
+ m_mac_yregs[3] = &m_core.zero;
+
+ // set up shift register pointers
+ m_shift_xregs[0] = &m_core.si;
+ m_shift_xregs[1] = &m_core.si;
+ m_shift_xregs[2] = &m_core.ar;
+ m_shift_xregs[3] = &m_core.mr.mrx.mr0;
+ m_shift_xregs[4] = &m_core.mr.mrx.mr1;
+ m_shift_xregs[5] = &m_core.mr.mrx.mr2;
+ m_shift_xregs[6] = &m_core.sr.srx.sr0;
+ m_shift_xregs[7] = &m_core.sr.srx.sr1;
+}
+
+adsp2100_device::adsp2100_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : adsp21xx_device(mconfig, ADSP2100, "ADSP-2100", tag, owner, clock, CHIP_TYPE_ADSP2100, "adsp2100", __FILE__) { }
+
+adsp2101_device::adsp2101_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : adsp21xx_device(mconfig, ADSP2101, "ADSP-2101", tag, owner, clock, CHIP_TYPE_ADSP2101, "adsp2101", __FILE__) { }
+
+adsp2101_device::adsp2101_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT32 chiptype, const char *shortname, const char *source)
+ : adsp21xx_device(mconfig, type, name, tag, owner, clock, chiptype, shortname, source) { }
+
+adsp2104_device::adsp2104_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : adsp2101_device(mconfig, ADSP2104, "ADSP-2104", tag, owner, clock, CHIP_TYPE_ADSP2104, "adsp2104", __FILE__) { }
+
+adsp2105_device::adsp2105_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : adsp2101_device(mconfig, ADSP2105, "ADSP-2105", tag, owner, clock, CHIP_TYPE_ADSP2105, "adsp2105", __FILE__) { }
+
+adsp2115_device::adsp2115_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : adsp2101_device(mconfig, ADSP2115, "ADSP-2115", tag, owner, clock, CHIP_TYPE_ADSP2115, "adsp2115", __FILE__) { }
+
+adsp2181_device::adsp2181_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : adsp21xx_device(mconfig, ADSP2181, "ADSP-2181", tag, owner, clock, CHIP_TYPE_ADSP2181, "adsp2181", __FILE__),
+ m_io_config("I/O", ENDIANNESS_LITTLE, 16, 11, -1) { }
+
+
+//-------------------------------------------------
+// ~adsp21xx_device - destructor
+//-------------------------------------------------
+
+adsp21xx_device::~adsp21xx_device()
+{
+#if ADSP_TRACK_HOTSPOTS
+ FILE *log = fopen("adsp.hot", "w");
+ while (1)
+ {
+ int maxindex = 0, i;
+ for (i = 1; i < 0x4000; i++)
+ if (m_pcbucket[i] > m_pcbucket[maxindex])
+ maxindex = i;
+ if (m_pcbucket[maxindex] == 0)
+ break;
+ fprintf(log, "PC=%04X (%10d hits)\n", maxindex, pcbucket[maxindex]);
+ m_pcbucket[maxindex] = 0;
+ }
+ fclose(log);
+#endif
+}
+
+
+//-------------------------------------------------
+// load_boot_data - load the boot data from an
+// 8-bit ROM
+//-------------------------------------------------
+
+void adsp21xx_device::load_boot_data(UINT8 *srcdata, UINT32 *dstdata)
+{
+ // see how many words we need to copy
+ int pagelen = (srcdata[3] + 1) * 8;
+ for (int i = 0; i < pagelen; i++)
+ {
+ UINT32 opcode = (srcdata[i*4+0] << 16) | (srcdata[i*4+1] << 8) | srcdata[i*4+2];
+ dstdata[i] = opcode;
+ }
+}
+
+
+//-------------------------------------------------
+// idma_addr_w - write the IDMA address register
+//-------------------------------------------------
+
+void adsp2181_device::idma_addr_w(UINT16 data)
+{
+ m_idma_addr = data;
+ m_idma_offs = 0;
+}
+
+
+//-------------------------------------------------
+// idma_addr_r - read the IDMA address register
+//-------------------------------------------------
+
+UINT16 adsp2181_device::idma_addr_r()
+{
+ return m_idma_addr;
+}
+
+
+//-------------------------------------------------
+// idma_data_w - write the IDMA data register
+//-------------------------------------------------
+
+void adsp2181_device::idma_data_w(UINT16 data)
+{
+ // program memory?
+ if (!(m_idma_addr & 0x4000))
+ {
+ // upper 16 bits
+ if (m_idma_offs == 0)
+ {
+ m_idma_cache = data;
+ m_idma_offs = 1;
+ }
+
+ // lower 8 bits
+ else
+ {
+ program_write(m_idma_addr++ & 0x3fff, (m_idma_cache << 8) | (data & 0xff));
+ m_idma_offs = 0;
+ }
+ }
+
+ // data memory
+ else
+ data_write(m_idma_addr++ & 0x3fff, data);
+}
+
+
+//-------------------------------------------------
+// idma_data_r - read the IDMA data register
+//-------------------------------------------------
+
+UINT16 adsp2181_device::idma_data_r()
+{
+ UINT16 result = 0xffff;
+
+ // program memory?
+ if (!(m_idma_addr & 0x4000))
+ {
+ // upper 16 bits
+ if (m_idma_offs == 0)
+ {
+ result = program_read(m_idma_addr & 0x3fff) >> 8;
+ m_idma_offs = 1;
+ }
+
+ // lower 8 bits
+ else
+ {
+ result = program_read(m_idma_addr++ & 0x3fff) & 0xff;
+ m_idma_offs = 0;
+ }
+ }
+
+ // data memory
+ else
+ result = data_read(m_idma_addr++ & 0x3fff);
+
+ return result;
+}
+
+
+//-------------------------------------------------
+// device_start - start up the device
+//-------------------------------------------------
+
+void adsp21xx_device::device_start()
+{
+ m_sport_rx_cb.resolve();
+ m_sport_tx_cb.resolve();
+ m_timer_fired_cb.resolve();
+
+ // get our address spaces
+ m_program = &space(AS_PROGRAM);
+ m_direct = &m_program->direct();
+ m_data = &space(AS_DATA);
+ m_io = has_space(AS_IO) ? &space(AS_IO) : NULL;
+
+ // "core"
+ save_item(NAME(m_core.ax0.u));
+ save_item(NAME(m_core.ax1.u));
+ save_item(NAME(m_core.ay0.u));
+ save_item(NAME(m_core.ay1.u));
+ save_item(NAME(m_core.ar.u));
+ save_item(NAME(m_core.af.u));
+ save_item(NAME(m_core.mx0.u));
+ save_item(NAME(m_core.mx1.u));
+ save_item(NAME(m_core.my0.u));
+ save_item(NAME(m_core.my1.u));
+ save_item(NAME(m_core.mr.mr));
+ save_item(NAME(m_core.mf.u));
+ save_item(NAME(m_core.si.u));
+ save_item(NAME(m_core.se.u));
+ save_item(NAME(m_core.sb.u));
+ save_item(NAME(m_core.sr.sr));
+ save_item(NAME(m_core.zero.u));
+
+ // "alt"
+ save_item(NAME(m_alt.ax0.u));
+ save_item(NAME(m_alt.ax1.u));
+ save_item(NAME(m_alt.ay0.u));
+ save_item(NAME(m_alt.ay1.u));
+ save_item(NAME(m_alt.ar.u));
+ save_item(NAME(m_alt.af.u));
+ save_item(NAME(m_alt.mx0.u));
+ save_item(NAME(m_alt.mx1.u));
+ save_item(NAME(m_alt.my0.u));
+ save_item(NAME(m_alt.my1.u));
+ save_item(NAME(m_alt.mr.mr));
+ save_item(NAME(m_alt.mf.u));
+ save_item(NAME(m_alt.si.u));
+ save_item(NAME(m_alt.se.u));
+ save_item(NAME(m_alt.sb.u));
+ save_item(NAME(m_alt.sr.sr));
+ save_item(NAME(m_alt.zero.u));
+
+ save_item(NAME(m_i));
+ save_item(NAME(m_m));
+ save_item(NAME(m_l));
+ save_item(NAME(m_lmask));
+ save_item(NAME(m_base));
+ save_item(NAME(m_px));
+
+ save_item(NAME(m_pc));
+ save_item(NAME(m_ppc));
+ save_item(NAME(m_loop));
+ save_item(NAME(m_loop_condition));
+ save_item(NAME(m_cntr));
+ save_item(NAME(m_astat));
+ save_item(NAME(m_sstat));
+ save_item(NAME(m_mstat));
+ save_item(NAME(m_mstat_prev));
+ save_item(NAME(m_astat_clear));
+ save_item(NAME(m_idle));
+
+ save_item(NAME(m_loop_stack));
+ save_item(NAME(m_cntr_stack));
+ save_item(NAME(m_pc_stack));
+ save_item(NAME(m_stat_stack));
+
+ save_item(NAME(m_pc_sp));
+ save_item(NAME(m_cntr_sp));
+ save_item(NAME(m_stat_sp));
+ save_item(NAME(m_loop_sp));
+
+ save_item(NAME(m_flagout));
+ save_item(NAME(m_flagin));
+ save_item(NAME(m_fl0));
+ save_item(NAME(m_fl1));
+ save_item(NAME(m_fl2));
+ save_item(NAME(m_idma_addr));
+ save_item(NAME(m_idma_cache));
+ save_item(NAME(m_idma_offs));
+
+ save_item(NAME(m_imask));
+ save_item(NAME(m_icntl));
+ save_item(NAME(m_ifc));
+ save_item(NAME(m_irq_state));
+ save_item(NAME(m_irq_latch));
+
+ // register state with the debugger
+ state_add(ADSP2100_PC, "PC", m_pc);
+ state_add(STATE_GENPC, "GENPC", m_pc).noshow();
+ state_add(STATE_GENPCBASE, "GENPCBASE", m_ppc).noshow();
+ state_add(STATE_GENFLAGS, "GENFLAGS", m_astat).mask(0xff).noshow().formatstr("%8s");
+
+ state_add(ADSP2100_AX0, "AX0", m_core.ax0.u);
+ state_add(ADSP2100_AX1, "AX1", m_core.ax1.u);
+ state_add(ADSP2100_AY0, "AY0", m_core.ay0.u);
+ state_add(ADSP2100_AY1, "AY1", m_core.ay1.u);
+ state_add(ADSP2100_AR, "AR", m_core.ar.u);
+ state_add(ADSP2100_AF, "AF", m_core.af.u);
+
+ state_add(ADSP2100_MX0, "MX0", m_core.mx0.u);
+ state_add(ADSP2100_MX1, "MX1", m_core.mx1.u);
+ state_add(ADSP2100_MY0, "MY0", m_core.my0.u);
+ state_add(ADSP2100_MY1, "MY1", m_core.my1.u);
+ state_add(ADSP2100_MR0, "MR0", m_core.mr.mrx.mr0.u);
+ state_add(ADSP2100_MR1, "MR1", m_core.mr.mrx.mr1.u);
+ state_add(ADSP2100_MR2, "MR2", m_core.mr.mrx.mr2.u).signed_mask(0xff);
+ state_add(ADSP2100_MF, "MF", m_core.mf.u);
+
+ state_add(ADSP2100_SI, "SI", m_core.si.u);
+ state_add(ADSP2100_SE, "SE", m_core.se.u).signed_mask(0xff);
+ state_add(ADSP2100_SB, "SB", m_core.sb.u).signed_mask(0x1f);
+ state_add(ADSP2100_SR0, "SR0", m_core.sr.srx.sr0.u);
+ state_add(ADSP2100_SR1, "SR1", m_core.sr.srx.sr1.u);
+
+ state_add(ADSP2100_AX0_SEC, "AX0_SEC", m_alt.ax0.u);
+ state_add(ADSP2100_AX1_SEC, "AX1_SEC", m_alt.ax1.u);
+ state_add(ADSP2100_AY0_SEC, "AY0_SEC", m_alt.ay0.u);
+ state_add(ADSP2100_AY1_SEC, "AY1_SEC", m_alt.ay1.u);
+ state_add(ADSP2100_AR_SEC, "AR_SEC", m_alt.ar.u);
+ state_add(ADSP2100_AF_SEC, "AF_SEC", m_alt.af.u);
+
+ state_add(ADSP2100_MX0_SEC, "MX0_SEC", m_alt.mx0.u);
+ state_add(ADSP2100_MX1_SEC, "MX1_SEC", m_alt.mx1.u);
+ state_add(ADSP2100_MY0_SEC, "MY0_SEC", m_alt.my0.u);
+ state_add(ADSP2100_MY1_SEC, "MY1_SEC", m_alt.my1.u);
+ state_add(ADSP2100_MR0_SEC, "MR0_SEC", m_alt.mr.mrx.mr0.u);
+ state_add(ADSP2100_MR1_SEC, "MR1_SEC", m_alt.mr.mrx.mr1.u);
+ state_add(ADSP2100_MR2_SEC, "MR2_SEC", m_alt.mr.mrx.mr2.u).signed_mask(0xff);
+ state_add(ADSP2100_MF_SEC, "MF_SEC", m_alt.mf.u);
+
+ state_add(ADSP2100_SI_SEC, "SI_SEC", m_alt.si.u);
+ state_add(ADSP2100_SE_SEC, "SE_SEC", m_alt.se.u).signed_mask(0xff);
+ state_add(ADSP2100_SB_SEC, "SB_SEC", m_alt.sb.u).signed_mask(0x1f);
+ state_add(ADSP2100_SR0_SEC, "SR0_SEC", m_alt.sr.srx.sr0.u);
+ state_add(ADSP2100_SR1_SEC, "SR1_SEC", m_alt.sr.srx.sr1.u);
+
+ std::string tempstring;
+ for (int ireg = 0; ireg < 8; ireg++)
+ state_add(ADSP2100_I0 + ireg, strformat(tempstring, "I%d", ireg).c_str(), m_i[ireg]).mask(0x3fff).callimport();
+
+ for (int lreg = 0; lreg < 8; lreg++)
+ state_add(ADSP2100_L0 + lreg, strformat(tempstring, "L%d", lreg).c_str(), m_l[lreg]).mask(0x3fff).callimport();
+
+ for (int mreg = 0; mreg < 8; mreg++)
+ state_add(ADSP2100_M0 + mreg, strformat(tempstring, "M%d", mreg).c_str(), m_m[mreg]).signed_mask(0x3fff);
+
+ state_add(ADSP2100_PX, "PX", m_px);
+ state_add(ADSP2100_CNTR, "CNTR", m_cntr).mask(0x3fff);
+ state_add(ADSP2100_ASTAT, "ASTAT", m_astat).mask(0xff);
+ state_add(ADSP2100_SSTAT, "SSTAT", m_sstat).mask(0xff);
+ state_add(ADSP2100_MSTAT, "MSTAT", m_mstat).mask((m_chip_type == CHIP_TYPE_ADSP2100) ? 0x0f : 0x7f).callimport();
+
+ state_add(ADSP2100_PCSP, "PCSP", m_pc_sp).mask(0xff);
+ state_add(STATE_GENSP, "GENSP", m_pc_sp).mask(0xff).noshow();
+ state_add(ADSP2100_CNTRSP, "CNTRSP", m_cntr_sp).mask(0xf);
+ state_add(ADSP2100_STATSP, "STATSP", m_stat_sp).mask(0xf);
+ state_add(ADSP2100_LOOPSP, "LOOPSP", m_loop_sp).mask(0xf);
+
+ state_add(ADSP2100_IMASK, "IMASK", m_imask).mask((m_chip_type == CHIP_TYPE_ADSP2100) ? 0x00f : (m_chip_type == CHIP_TYPE_ADSP2181) ? 0x3ff : 0x07f).callimport();
+ state_add(ADSP2100_ICNTL, "ICNTL", m_icntl).mask(0x1f).callimport();
+
+ for (int irqnum = 0; irqnum < 4; irqnum++)
+ if (irqnum < 4 || m_chip_type == CHIP_TYPE_ADSP2100)
+ state_add(ADSP2100_IRQSTATE0 + irqnum, strformat(tempstring, "IRQ%d", irqnum).c_str(), m_irq_state[irqnum]).mask(1).callimport();
+
+ state_add(ADSP2100_FLAGIN, "FLAGIN", m_flagin).mask(1);
+ state_add(ADSP2100_FLAGOUT, "FLAGOUT", m_flagout).mask(1);
+ state_add(ADSP2100_FL0, "FL0", m_fl0).mask(1);
+ state_add(ADSP2100_FL1, "FL1", m_fl1).mask(1);
+ state_add(ADSP2100_FL2, "FL2", m_fl2).mask(1);
+
+ // set our instruction counter
+ m_icountptr = &m_icount;
+}
+
+
+//-------------------------------------------------
+// device_reset - reset the device
+//-------------------------------------------------
+
+void adsp21xx_device::device_reset()
+{
+ // ensure that zero is zero
+ m_core.zero.u = m_alt.zero.u = 0;
+
+ // recompute the memory registers with their current values
+ write_reg1(0x08, m_l[0]); write_reg1(0x00, m_i[0]);
+ write_reg1(0x09, m_l[1]); write_reg1(0x01, m_i[1]);
+ write_reg1(0x0a, m_l[2]); write_reg1(0x02, m_i[2]);
+ write_reg1(0x0b, m_l[3]); write_reg1(0x03, m_i[3]);
+ write_reg2(0x08, m_l[4]); write_reg2(0x00, m_i[4]);
+ write_reg2(0x09, m_l[5]); write_reg2(0x01, m_i[5]);
+ write_reg2(0x0a, m_l[6]); write_reg2(0x02, m_i[6]);
+ write_reg2(0x0b, m_l[7]); write_reg2(0x03, m_i[7]);
+
+ // reset PC and loops
+ m_pc = (m_chip_type >= CHIP_TYPE_ADSP2101) ? 0 : 4;
+ m_ppc = -1;
+ m_loop = 0xffff;
+ m_loop_condition = 0;
+
+ // reset status registers
+ m_astat_clear = ~(CFLAG | VFLAG | NFLAG | ZFLAG);
+ m_mstat = 0;
+ m_sstat = 0x55;
+ m_idle = 0;
+ update_mstat();
+
+ // reset stacks
+ m_pc_sp = 0;
+ m_cntr_sp = 0;
+ m_stat_sp = 0;
+ m_loop_sp = 0;
+
+ // reset external I/O
+ m_flagout = 0;
+ m_flagin = 0;
+ m_fl0 = 0;
+ m_fl1 = 0;
+ m_fl2 = 0;
+
+ // reset interrupts
+ m_imask = 0;
+ for (int irq = 0; irq < 8; irq++)
+ m_irq_state[irq] = m_irq_latch[irq] = CLEAR_LINE;
+}
+
+
+//-------------------------------------------------
+// memory_space_config - return the configuration
+// of the specified address space, or NULL if
+// the space doesn't exist
+//-------------------------------------------------
+
+const address_space_config *adsp2100_device::memory_space_config(address_spacenum spacenum) const
+{
+ return (spacenum == AS_PROGRAM) ? &m_program_config :
+ (spacenum == AS_DATA) ? &m_data_config :
+ NULL;
+}
+
+const address_space_config *adsp2101_device::memory_space_config(address_spacenum spacenum) const
+{
+ return (spacenum == AS_PROGRAM) ? &m_program_config :
+ (spacenum == AS_DATA) ? &m_data_config :
+ NULL;
+}
+
+const address_space_config *adsp2181_device::memory_space_config(address_spacenum spacenum) const
+{
+ return (spacenum == AS_PROGRAM) ? &m_program_config :
+ (spacenum == AS_DATA) ? &m_data_config :
+ (spacenum == AS_IO) ? &m_io_config :
+ NULL;
+}
+
+
+//-------------------------------------------------
+// state_import - import state into the device,
+// after it has been set
+//-------------------------------------------------
+
+void adsp21xx_device::state_import(const device_state_entry &entry)
+{
+ switch (entry.index())
+ {
+ case ADSP2100_MSTAT:
+ update_mstat();
+ break;
+
+ case ADSP2100_IMASK:
+ case ADSP2100_ICNTL:
+ case ADSP2100_IRQSTATE0:
+ case ADSP2100_IRQSTATE1:
+ case ADSP2100_IRQSTATE2:
+ case ADSP2100_IRQSTATE3:
+ check_irqs();
+ break;
+
+ case ADSP2100_I0:
+ case ADSP2100_I1:
+ case ADSP2100_I2:
+ case ADSP2100_I3:
+ case ADSP2100_I4:
+ case ADSP2100_I5:
+ case ADSP2100_I6:
+ case ADSP2100_I7:
+ update_i(entry.index() - ADSP2100_I0);
+ break;
+
+ case ADSP2100_L0:
+ case ADSP2100_L1:
+ case ADSP2100_L2:
+ case ADSP2100_L3:
+ case ADSP2100_L4:
+ case ADSP2100_L5:
+ case ADSP2100_L6:
+ case ADSP2100_L7:
+ update_l(entry.index() - ADSP2100_L0);
+ break;
+
+ default:
+ fatalerror("CPU_IMPORT_STATE(adsp21xx) called for unexpected value\n");
+ }
+}
+
+
+//-------------------------------------------------
+// state_string_export - export state as a string
+// for the debugger
+//-------------------------------------------------
+
+void adsp21xx_device::state_string_export(const device_state_entry &entry, std::string &str)
+{
+ switch (entry.index())
+ {
+ case STATE_GENFLAGS:
+ strprintf(str, "%c%c%c%c%c%c%c%c",
+ m_astat & 0x80 ? 'X':'.',
+ m_astat & 0x40 ? 'M':'.',
+ m_astat & 0x20 ? 'Q':'.',
+ m_astat & 0x10 ? 'S':'.',
+ m_astat & 0x08 ? 'C':'.',
+ m_astat & 0x04 ? 'V':'.',
+ m_astat & 0x02 ? 'N':'.',
+ m_astat & 0x01 ? 'Z':'.');
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// disasm_min_opcode_bytes - return the length
+// of the shortest instruction, in bytes
+//-------------------------------------------------
+
+UINT32 adsp21xx_device::disasm_min_opcode_bytes() const
+{
+ return 4;
+}
+
+
+//-------------------------------------------------
+// disasm_max_opcode_bytes - return the length
+// of the longest instruction, in bytes
+//-------------------------------------------------
+
+UINT32 adsp21xx_device::disasm_max_opcode_bytes() const
+{
+ return 4;
+}
+
+
+//-------------------------------------------------
+// disasm_disassemble - call the disassembly
+// helper function
+//-------------------------------------------------
+
+offs_t adsp21xx_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
+{
+ extern CPU_DISASSEMBLE( adsp21xx );
+ return CPU_DISASSEMBLE_NAME(adsp21xx)(this, buffer, pc, oprom, opram, options);
+}
+
+
+
+
+/***************************************************************************
+ MEMORY ACCESSORS
+***************************************************************************/
+
+inline UINT16 adsp21xx_device::data_read(UINT32 addr)
+{
+ return m_data->read_word(addr << 1);
+}
+
+inline void adsp21xx_device::data_write(UINT32 addr, UINT16 data)
+{
+ m_data->write_word(addr << 1, data);
+}
+
+inline UINT16 adsp21xx_device::io_read(UINT32 addr)
+{
+ return m_io->read_word(addr << 1);
+}
+
+inline void adsp21xx_device::io_write(UINT32 addr, UINT16 data)
+{
+ m_io->write_word(addr << 1, data);
+}
+
+inline UINT32 adsp21xx_device::program_read(UINT32 addr)
+{
+ return m_program->read_dword(addr << 2);
+}
+
+inline void adsp21xx_device::program_write(UINT32 addr, UINT32 data)
+{
+ m_program->write_dword(addr << 2, data & 0xffffff);
+}
+
+inline UINT32 adsp21xx_device::opcode_read()
+{
+ return m_direct->read_dword(m_pc << 2);
+}
+
+
+/***************************************************************************
+ IMPORT CORE UTILITIES
+***************************************************************************/
+
+#include "2100ops.inc"
+
+
+
+/***************************************************************************
+ IRQ HANDLING
+***************************************************************************/
+
+bool adsp2100_device::generate_irq(int which, int indx)
+{
+ // skip if masked
+ if (!(m_imask & (1 << which)))
+ return false;
+
+ // clear the latch
+ m_irq_latch[which] = 0;
+
+ // push the PC and the status
+ pc_stack_push();
+ stat_stack_push();
+
+ // vector to location & stop idling
+ m_pc = indx;
+ m_idle = 0;
+
+ // mask other interrupts based on the nesting bit
+ if (m_icntl & 0x10) m_imask &= ~((2 << which) - 1);
+ else m_imask &= ~0xf;
+
+ return true;
+}
+
+
+bool adsp2101_device::generate_irq(int which, int indx)
+{
+ // skip if masked
+ if (!(m_imask & (0x20 >> indx)))
+ return false;
+
+ // clear the latch
+ m_irq_latch[which] = 0;
+
+ // push the PC and the status
+ pc_stack_push();
+ stat_stack_push();
+
+ // vector to location & stop idling
+ m_pc = 0x04 + indx * 4;
+ m_idle = 0;
+
+ // mask other interrupts based on the nesting bit
+ if (m_icntl & 0x10) m_imask &= ~(0x3f >> indx);
+ else m_imask &= ~0x3f;
+
+ return true;
+}
+
+
+bool adsp2181_device::generate_irq(int which, int indx)
+{
+ // skip if masked
+ if (!(m_imask & (0x200 >> indx)))
+ return false;
+
+ // clear the latch
+ m_irq_latch[which] = 0;
+
+ // push the PC and the status
+ pc_stack_push();
+ stat_stack_push();
+
+ // vector to location & stop idling
+ m_pc = 0x04 + indx * 4;
+ m_idle = 0;
+
+ // mask other interrupts based on the nesting bit
+ if (m_icntl & 0x10) m_imask &= ~(0x3ff >> indx);
+ else m_imask &= ~0x3ff;
+
+ return true;
+}
+
+
+void adsp2100_device::check_irqs()
+{
+ UINT8 check;
+
+ // check IRQ3
+ check = (m_icntl & 8) ? m_irq_latch[ADSP2100_IRQ3] : m_irq_state[ADSP2100_IRQ3];
+ if (check && generate_irq(ADSP2100_IRQ3, 3))
+ return;
+
+ // check IRQ2
+ check = (m_icntl & 4) ? m_irq_latch[ADSP2100_IRQ2] : m_irq_state[ADSP2100_IRQ2];
+ if (check && generate_irq(ADSP2100_IRQ2, 2))
+ return;
+
+ // check IRQ1
+ check = (m_icntl & 2) ? m_irq_latch[ADSP2100_IRQ1] : m_irq_state[ADSP2100_IRQ1];
+ if (check && generate_irq(ADSP2100_IRQ1, 1))
+ return;
+
+ // check IRQ0
+ check = (m_icntl & 1) ? m_irq_latch[ADSP2100_IRQ0] : m_irq_state[ADSP2100_IRQ0];
+ if (check && generate_irq(ADSP2100_IRQ0, 0))
+ return;
+}
+
+
+void adsp2101_device::check_irqs()
+{
+ UINT8 check;
+
+ // check IRQ2
+ check = (m_icntl & 4) ? m_irq_latch[ADSP2101_IRQ2] : m_irq_state[ADSP2101_IRQ2];
+ if (check && generate_irq(ADSP2101_IRQ2, 0))
+ return;
+
+ // check SPORT0 transmit
+ check = m_irq_latch[ADSP2101_SPORT0_TX];
+ if (check && generate_irq(ADSP2101_SPORT0_TX, 1))
+ return;
+
+ // check SPORT0 receive
+ check = m_irq_latch[ADSP2101_SPORT0_RX];
+ if (check && generate_irq(ADSP2101_SPORT0_RX, 2))
+ return;
+
+ // check IRQ1/SPORT1 transmit
+ check = (m_icntl & 2) ? m_irq_latch[ADSP2101_IRQ1] : m_irq_state[ADSP2101_IRQ1];
+ if (check && generate_irq(ADSP2101_IRQ1, 3))
+ return;
+
+ // check IRQ0/SPORT1 receive
+ check = (m_icntl & 1) ? m_irq_latch[ADSP2101_IRQ0] : m_irq_state[ADSP2101_IRQ0];
+ if (check && generate_irq(ADSP2101_IRQ0, 4))
+ return;
+
+ // check timer
+ check = m_irq_latch[ADSP2101_TIMER];
+ if (check && generate_irq(ADSP2101_TIMER, 5))
+ return;
+}
+
+
+void adsp2181_device::check_irqs()
+{
+ UINT8 check;
+
+ // check IRQ2
+ check = (m_icntl & 4) ? m_irq_latch[ADSP2181_IRQ2] : m_irq_state[ADSP2181_IRQ2];
+ if (check && generate_irq(ADSP2181_IRQ2, 0))
+ return;
+
+ // check IRQL1
+ check = m_irq_state[ADSP2181_IRQL1];
+ if (check && generate_irq(ADSP2181_IRQL1, 1))
+ return;
+
+ // check IRQL2
+ check = m_irq_state[ADSP2181_IRQL2];
+ if (check && generate_irq(ADSP2181_IRQL2, 2))
+ return;
+
+ // check SPORT0 transmit
+ check = m_irq_latch[ADSP2181_SPORT0_TX];
+ if (check && generate_irq(ADSP2181_SPORT0_TX, 3))
+ return;
+
+ // check SPORT0 receive
+ check = m_irq_latch[ADSP2181_SPORT0_RX];
+ if (check && generate_irq(ADSP2181_SPORT0_RX, 4))
+ return;
+
+ // check IRQE
+ check = m_irq_latch[ADSP2181_IRQE];
+ if (check && generate_irq(ADSP2181_IRQE, 5))
+ return;
+
+ // check BDMA interrupt
+
+ // check IRQ1/SPORT1 transmit
+ check = (m_icntl & 2) ? m_irq_latch[ADSP2181_IRQ1] : m_irq_state[ADSP2181_IRQ1];
+ if (check && generate_irq(ADSP2181_IRQ1, 7))
+ return;
+
+ // check IRQ0/SPORT1 receive
+ check = (m_icntl & 1) ? m_irq_latch[ADSP2181_IRQ0] : m_irq_state[ADSP2181_IRQ0];
+ if (check && generate_irq(ADSP2181_IRQ0, 8))
+ return;
+
+ // check timer
+ check = m_irq_latch[ADSP2181_TIMER];
+ if (check && generate_irq(ADSP2181_TIMER, 9))
+ return;
+}
+
+
+
+/***************************************************************************
+ INITIALIZATION AND SHUTDOWN
+***************************************************************************/
+
+void adsp21xx_device::create_tables()
+{
+ // initialize the bit reversing table
+ for (int i = 0; i < 0x4000; i++)
+ {
+ UINT16 data = 0;
+
+ data |= (i >> 13) & 0x0001;
+ data |= (i >> 11) & 0x0002;
+ data |= (i >> 9) & 0x0004;
+ data |= (i >> 7) & 0x0008;
+ data |= (i >> 5) & 0x0010;
+ data |= (i >> 3) & 0x0020;
+ data |= (i >> 1) & 0x0040;
+ data |= (i << 1) & 0x0080;
+ data |= (i << 3) & 0x0100;
+ data |= (i << 5) & 0x0200;
+ data |= (i << 7) & 0x0400;
+ data |= (i << 9) & 0x0800;
+ data |= (i << 11) & 0x1000;
+ data |= (i << 13) & 0x2000;
+
+ m_reverse_table[i] = data;
+ }
+
+ // initialize the mask table
+ for (int i = 0; i < 0x4000; i++)
+ {
+ if (i > 0x2000) m_mask_table[i] = 0x0000;
+ else if (i > 0x1000) m_mask_table[i] = 0x2000;
+ else if (i > 0x0800) m_mask_table[i] = 0x3000;
+ else if (i > 0x0400) m_mask_table[i] = 0x3800;
+ else if (i > 0x0200) m_mask_table[i] = 0x3c00;
+ else if (i > 0x0100) m_mask_table[i] = 0x3e00;
+ else if (i > 0x0080) m_mask_table[i] = 0x3f00;
+ else if (i > 0x0040) m_mask_table[i] = 0x3f80;
+ else if (i > 0x0020) m_mask_table[i] = 0x3fc0;
+ else if (i > 0x0010) m_mask_table[i] = 0x3fe0;
+ else if (i > 0x0008) m_mask_table[i] = 0x3ff0;
+ else if (i > 0x0004) m_mask_table[i] = 0x3ff8;
+ else if (i > 0x0002) m_mask_table[i] = 0x3ffc;
+ else if (i > 0x0001) m_mask_table[i] = 0x3ffe;
+ else m_mask_table[i] = 0x3fff;
+ }
+
+ // initialize the condition table
+ for (int i = 0; i < 0x100; i++)
+ {
+ int az = ((i & ZFLAG) != 0);
+ int an = ((i & NFLAG) != 0);
+ int av = ((i & VFLAG) != 0);
+ int ac = ((i & CFLAG) != 0);
+ int mv = ((i & MVFLAG) != 0);
+ int as = ((i & SFLAG) != 0);
+
+ m_condition_table[i | 0x000] = az;
+ m_condition_table[i | 0x100] = !az;
+ m_condition_table[i | 0x200] = !((an ^ av) | az);
+ m_condition_table[i | 0x300] = (an ^ av) | az;
+ m_condition_table[i | 0x400] = an ^ av;
+ m_condition_table[i | 0x500] = !(an ^ av);
+ m_condition_table[i | 0x600] = av;
+ m_condition_table[i | 0x700] = !av;
+ m_condition_table[i | 0x800] = ac;
+ m_condition_table[i | 0x900] = !ac;
+ m_condition_table[i | 0xa00] = as;
+ m_condition_table[i | 0xb00] = !as;
+ m_condition_table[i | 0xc00] = mv;
+ m_condition_table[i | 0xd00] = !mv;
+ m_condition_table[i | 0xf00] = 1;
+ }
+}
+
+
+
+/***************************************************************************
+ CORE EXECUTION LOOP
+***************************************************************************/
+
+//-------------------------------------------------
+// execute_min_cycles - return minimum number of
+// cycles it takes for one instruction to execute
+//-------------------------------------------------
+
+UINT32 adsp21xx_device::execute_min_cycles() const
+{
+ return 1;
+}
+
+
+//-------------------------------------------------
+// execute_max_cycles - return maximum number of
+// cycles it takes for one instruction to execute
+//-------------------------------------------------
+
+UINT32 adsp21xx_device::execute_max_cycles() const
+{
+ return 1;
+}
+
+
+//-------------------------------------------------
+// execute_input_lines - return the number of
+// input/interrupt lines
+//-------------------------------------------------
+
+UINT32 adsp2100_device::execute_input_lines() const
+{
+ return 4;
+}
+
+UINT32 adsp2101_device::execute_input_lines() const
+{
+ return 5;
+}
+
+UINT32 adsp2181_device::execute_input_lines() const
+{
+ return 9;
+}
+
+
+void adsp21xx_device::execute_set_input(int inputnum, int state)
+{
+ // update the latched state
+ if (state != CLEAR_LINE && m_irq_state[inputnum] == CLEAR_LINE)
+ m_irq_latch[inputnum] = 1;
+
+ // update the absolute state
+ m_irq_state[inputnum] = state;
+}
+
+
+void adsp21xx_device::execute_run()
+{
+ bool check_debugger = ((device_t::machine().debug_flags & DEBUG_FLAG_ENABLED) != 0);
+
+ check_irqs();
+
+ do
+ {
+ // debugging
+ m_ppc = m_pc; // copy PC to previous PC
+ if (check_debugger)
+ debugger_instruction_hook(this, m_pc);
+
+#if ADSP_TRACK_HOTSPOTS
+ m_pcbucket[m_pc & 0x3fff]++;
+#endif
+
+ // instruction fetch
+ UINT32 op = opcode_read();
+
+ // advance to the next instruction
+ if (m_pc != m_loop)
+ m_pc++;
+
+ // handle looping
+ else
+ {
+ // condition not met, keep looping
+ if (condition(m_loop_condition))
+ m_pc = pc_stack_top();
+
+ // condition met; pop the PC and loop stacks and fall through
+ else
+ {
+ loop_stack_pop();
+ pc_stack_pop_val();
+ m_pc++;
+ }
+ }
+
+ // parse the instruction
+ UINT32 temp;
+ switch ((op >> 16) & 0xff)
+ {
+ case 0x00:
+ // 00000000 00000000 00000000 NOP
+ break;
+ case 0x01:
+ // 00000001 0xxxxxxx xxxxxxxx dst = IO(x)
+ // 00000001 1xxxxxxx xxxxxxxx IO(x) = dst
+ // ADSP-218x only
+ if (m_chip_type >= CHIP_TYPE_ADSP2181)
+ {
+ if ((op & 0x008000) == 0x000000)
+ write_reg0(op & 15, io_read((op >> 4) & 0x7ff));
+ else
+ io_write((op >> 4) & 0x7ff, read_reg0(op & 15));
+ }
+ break;
+ case 0x02:
+ // 00000010 0000xxxx xxxxxxxx modify flag out
+ // 00000010 10000000 00000000 idle
+ // 00000010 10000000 0000xxxx idle (n)
+ if (op & 0x008000)
+ {
+ m_idle = 1;
+ m_icount = 0;
+ }
+ else
+ {
+ if (condition(op & 15))
+ {
+ if (op & 0x020) m_flagout = 0;
+ if (op & 0x010) m_flagout ^= 1;
+ if (m_chip_type >= CHIP_TYPE_ADSP2101)
+ {
+ if (op & 0x080) m_fl0 = 0;
+ if (op & 0x040) m_fl0 ^= 1;
+ if (op & 0x200) m_fl1 = 0;
+ if (op & 0x100) m_fl1 ^= 1;
+ if (op & 0x800) m_fl2 = 0;
+ if (op & 0x400) m_fl2 ^= 1;
+ }
+ }
+ }
+ break;
+ case 0x03:
+ // 00000011 xxxxxxxx xxxxxxxx call or jump on flag in
+ if (op & 0x000002)
+ {
+ if (m_flagin)
+ {
+ if (op & 0x000001)
+ pc_stack_push();
+ m_pc = ((op >> 4) & 0x0fff) | ((op << 10) & 0x3000);
+ }
+ }
+ else
+ {
+ if (!m_flagin)
+ {
+ if (op & 0x000001)
+ pc_stack_push();
+ m_pc = ((op >> 4) & 0x0fff) | ((op << 10) & 0x3000);
+ }
+ }
+ break;
+ case 0x04:
+ // 00000100 00000000 000xxxxx stack control
+ if (op & 0x000010) pc_stack_pop_val();
+ if (op & 0x000008) loop_stack_pop();
+ if (op & 0x000004) cntr_stack_pop();
+ if (op & 0x000002)
+ {
+ if (op & 0x000001) stat_stack_pop();
+ else stat_stack_push();
+ }
+ break;
+ case 0x05:
+ // 00000101 00000000 00000000 saturate MR
+ if (GET_MV)
+ {
+ if (m_core.mr.mrx.mr2.u & 0x80)
+ m_core.mr.mrx.mr2.u = 0xffff, m_core.mr.mrx.mr1.u = 0x8000, m_core.mr.mrx.mr0.u = 0x0000;
+ else
+ m_core.mr.mrx.mr2.u = 0x0000, m_core.mr.mrx.mr1.u = 0x7fff, m_core.mr.mrx.mr0.u = 0xffff;
+ }
+ break;
+ case 0x06:
+ // 00000110 000xxxxx 00000000 DIVS
+ {
+ int xop = (op >> 8) & 7;
+ int yop = (op >> 11) & 3;
+
+ xop = ALU_GETXREG_UNSIGNED(xop);
+ yop = ALU_GETYREG_UNSIGNED(yop);
+
+ temp = xop ^ yop;
+ m_astat = (m_astat & ~QFLAG) | ((temp >> 10) & QFLAG);
+ m_core.af.u = (yop << 1) | (m_core.ay0.u >> 15);
+ m_core.ay0.u = (m_core.ay0.u << 1) | (temp >> 15);
+ }
+ break;
+ case 0x07:
+ // 00000111 00010xxx 00000000 DIVQ
+ {
+ int xop = (op >> 8) & 7;
+ int res;
+
+ xop = ALU_GETXREG_UNSIGNED(xop);
+
+ if (GET_Q)
+ res = m_core.af.u + xop;
+ else
+ res = m_core.af.u - xop;
+
+ temp = res ^ xop;
+ m_astat = (m_astat & ~QFLAG) | ((temp >> 10) & QFLAG);
+ m_core.af.u = (res << 1) | (m_core.ay0.u >> 15);
+ m_core.ay0.u = (m_core.ay0.u << 1) | ((~temp >> 15) & 0x0001);
+ }
+ break;
+ case 0x08:
+ // 00001000 00000000 0000xxxx reserved
+ break;
+ case 0x09:
+ // 00001001 00000000 000xxxxx modify address register
+ temp = (op >> 2) & 4;
+ modify_address(temp + ((op >> 2) & 3), temp + (op & 3));
+ break;
+ case 0x0a:
+ // 00001010 00000000 000xxxxx conditional return
+ if (condition(op & 15))
+ {
+ pc_stack_pop();
+
+ // RTI case
+ if (op & 0x000010)
+ stat_stack_pop();
+ }
+ break;
+ case 0x0b:
+ // 00001011 00000000 xxxxxxxx conditional jump (indirect address)
+ if (condition(op & 15))
+ {
+ if (op & 0x000010)
+ pc_stack_push();
+ m_pc = m_i[4 + ((op >> 6) & 3)] & 0x3fff;
+ }
+ break;
+ case 0x0c:
+ // 00001100 xxxxxxxx xxxxxxxx mode control
+ if (m_chip_type >= CHIP_TYPE_ADSP2101)
+ {
+ if (op & 0x000008) m_mstat = (m_mstat & ~MSTAT_GOMODE) | ((op << 5) & MSTAT_GOMODE);
+ if (op & 0x002000) m_mstat = (m_mstat & ~MSTAT_INTEGER) | ((op >> 8) & MSTAT_INTEGER);
+ if (op & 0x008000) m_mstat = (m_mstat & ~MSTAT_TIMER) | ((op >> 9) & MSTAT_TIMER);
+ }
+ if (op & 0x000020) m_mstat = (m_mstat & ~MSTAT_BANK) | ((op >> 4) & MSTAT_BANK);
+ if (op & 0x000080) m_mstat = (m_mstat & ~MSTAT_REVERSE) | ((op >> 5) & MSTAT_REVERSE);
+ if (op & 0x000200) m_mstat = (m_mstat & ~MSTAT_STICKYV) | ((op >> 6) & MSTAT_STICKYV);
+ if (op & 0x000800) m_mstat = (m_mstat & ~MSTAT_SATURATE) | ((op >> 7) & MSTAT_SATURATE);
+ update_mstat();
+ break;
+ case 0x0d:
+ // 00001101 0000xxxx xxxxxxxx internal data move
+ switch ((op >> 8) & 15)
+ {
+ case 0x00: write_reg0((op >> 4) & 15, read_reg0(op & 15)); break;
+ case 0x01: write_reg0((op >> 4) & 15, read_reg1(op & 15)); break;
+ case 0x02: write_reg0((op >> 4) & 15, read_reg2(op & 15)); break;
+ case 0x03: write_reg0((op >> 4) & 15, read_reg3(op & 15)); break;
+ case 0x04: write_reg1((op >> 4) & 15, read_reg0(op & 15)); break;
+ case 0x05: write_reg1((op >> 4) & 15, read_reg1(op & 15)); break;
+ case 0x06: write_reg1((op >> 4) & 15, read_reg2(op & 15)); break;
+ case 0x07: write_reg1((op >> 4) & 15, read_reg3(op & 15)); break;
+ case 0x08: write_reg2((op >> 4) & 15, read_reg0(op & 15)); break;
+ case 0x09: write_reg2((op >> 4) & 15, read_reg1(op & 15)); break;
+ case 0x0a: write_reg2((op >> 4) & 15, read_reg2(op & 15)); break;
+ case 0x0b: write_reg2((op >> 4) & 15, read_reg3(op & 15)); break;
+ case 0x0c: write_reg3((op >> 4) & 15, read_reg0(op & 15)); break;
+ case 0x0d: write_reg3((op >> 4) & 15, read_reg1(op & 15)); break;
+ case 0x0e: write_reg3((op >> 4) & 15, read_reg2(op & 15)); break;
+ case 0x0f: write_reg3((op >> 4) & 15, read_reg3(op & 15)); break;
+ }
+ break;
+ case 0x0e:
+ // 00001110 0xxxxxxx xxxxxxxx conditional shift
+ if (condition(op & 15)) shift_op(op);
+ break;
+ case 0x0f:
+ // 00001111 0xxxxxxx xxxxxxxx shift immediate
+ shift_op_imm(op);
+ break;
+ case 0x10:
+ // 00010000 0xxxxxxx xxxxxxxx shift with internal data register move
+ shift_op(op);
+ temp = read_reg0(op & 15);
+ write_reg0((op >> 4) & 15, temp);
+ break;
+ case 0x11:
+ // 00010001 xxxxxxxx xxxxxxxx shift with pgm memory read/write
+ if (op & 0x8000)
+ {
+ pgm_write_dag2(op, read_reg0((op >> 4) & 15));
+ shift_op(op);
+ }
+ else
+ {
+ shift_op(op);
+ write_reg0((op >> 4) & 15, pgm_read_dag2(op));
+ }
+ break;
+ case 0x12:
+ // 00010010 xxxxxxxx xxxxxxxx shift with data memory read/write DAG1
+ if (op & 0x8000)
+ {
+ data_write_dag1(op, read_reg0((op >> 4) & 15));
+ shift_op(op);
+ }
+ else
+ {
+ shift_op(op);
+ write_reg0((op >> 4) & 15, data_read_dag1(op));
+ }
+ break;
+ case 0x13:
+ // 00010011 xxxxxxxx xxxxxxxx shift with data memory read/write DAG2
+ if (op & 0x8000)
+ {
+ data_write_dag2(op, read_reg0((op >> 4) & 15));
+ shift_op(op);
+ }
+ else
+ {
+ shift_op(op);
+ write_reg0((op >> 4) & 15, data_read_dag2(op));
+ }
+ break;
+ case 0x14: case 0x15: case 0x16: case 0x17:
+ // 000101xx xxxxxxxx xxxxxxxx do until
+ loop_stack_push(op & 0x3ffff);
+ pc_stack_push();
+ break;
+ case 0x18: case 0x19: case 0x1a: case 0x1b:
+ // 000110xx xxxxxxxx xxxxxxxx conditional jump (immediate addr)
+ if (condition(op & 15))
+ {
+ m_pc = (op >> 4) & 0x3fff;
+ // check for a busy loop
+ if (m_pc == m_ppc)
+ m_icount = 0;
+ }
+ break;
+ case 0x1c: case 0x1d: case 0x1e: case 0x1f:
+ // 000111xx xxxxxxxx xxxxxxxx conditional call (immediate addr)
+ if (condition(op & 15))
+ {
+ pc_stack_push();
+ m_pc = (op >> 4) & 0x3fff;
+ }
+ break;
+ case 0x20: case 0x21:
+ // 0010000x xxxxxxxx xxxxxxxx conditional MAC to MR
+ if (condition(op & 15))
+ {
+ if (m_chip_type >= CHIP_TYPE_ADSP2181 && (op & 0x0018f0) == 0x000010)
+ mac_op_mr_xop(op);
+ else
+ mac_op_mr(op);
+ }
+ break;
+ case 0x22: case 0x23:
+ // 0010001x xxxxxxxx xxxxxxxx conditional ALU to AR
+ if (condition(op & 15))
+ {
+ if (m_chip_type >= CHIP_TYPE_ADSP2181 && (op & 0x000010) == 0x000010)
+ alu_op_ar_const(op);
+ else
+ alu_op_ar(op);
+ }
+ break;
+ case 0x24: case 0x25:
+ // 0010010x xxxxxxxx xxxxxxxx conditional MAC to MF
+ if (condition(op & 15))
+ {
+ if (m_chip_type >= CHIP_TYPE_ADSP2181 && (op & 0x0018f0) == 0x000010)
+ mac_op_mf_xop(op);
+ else
+ mac_op_mf(op);
+ }
+ break;
+ case 0x26: case 0x27:
+ // 0010011x xxxxxxxx xxxxxxxx conditional ALU to AF
+ if (condition(op & 15))
+ {
+ if (m_chip_type >= CHIP_TYPE_ADSP2181 && (op & 0x000010) == 0x000010)
+ alu_op_af_const(op);
+ else
+ alu_op_af(op);
+ }
+ break;
+ case 0x28: case 0x29:
+ // 0010100x xxxxxxxx xxxxxxxx MAC to MR with internal data register move
+ temp = read_reg0(op & 15);
+ mac_op_mr(op);
+ write_reg0((op >> 4) & 15, temp);
+ break;
+ case 0x2a: case 0x2b:
+ // 0010101x xxxxxxxx xxxxxxxx ALU to AR with internal data register move
+ if (m_chip_type >= CHIP_TYPE_ADSP2181 && (op & 0x0000ff) == 0x0000aa)
+ alu_op_none(op);
+ else
+ {
+ temp = read_reg0(op & 15);
+ alu_op_ar(op);
+ write_reg0((op >> 4) & 15, temp);
+ }
+ break;
+ case 0x2c: case 0x2d:
+ // 0010110x xxxxxxxx xxxxxxxx MAC to MF with internal data register move
+ temp = read_reg0(op & 15);
+ mac_op_mf(op);
+ write_reg0((op >> 4) & 15, temp);
+ break;
+ case 0x2e: case 0x2f:
+ // 0010111x xxxxxxxx xxxxxxxx ALU to AF with internal data register move
+ temp = read_reg0(op & 15);
+ alu_op_af(op);
+ write_reg0((op >> 4) & 15, temp);
+ break;
+ case 0x30: case 0x31: case 0x32: case 0x33:
+ // 001100xx xxxxxxxx xxxxxxxx load non-data register immediate (group 0)
+ write_reg0(op & 15, (INT32)(op << 14) >> 18);
+ break;
+ case 0x34: case 0x35: case 0x36: case 0x37:
+ // 001101xx xxxxxxxx xxxxxxxx load non-data register immediate (group 1)
+ write_reg1(op & 15, (INT32)(op << 14) >> 18);
+ break;
+ case 0x38: case 0x39: case 0x3a: case 0x3b:
+ // 001110xx xxxxxxxx xxxxxxxx load non-data register immediate (group 2)
+ write_reg2(op & 15, (INT32)(op << 14) >> 18);
+ break;
+ case 0x3c: case 0x3d: case 0x3e: case 0x3f:
+ // 001111xx xxxxxxxx xxxxxxxx load non-data register immediate (group 3)
+ write_reg3(op & 15, (INT32)(op << 14) >> 18);
+ break;
+ case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
+ case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
+ // 0100xxxx xxxxxxxx xxxxxxxx load data register immediate
+ write_reg0(op & 15, (op >> 4) & 0xffff);
+ break;
+ case 0x50: case 0x51:
+ // 0101000x xxxxxxxx xxxxxxxx MAC to MR with pgm memory read
+ mac_op_mr(op);
+ write_reg0((op >> 4) & 15, pgm_read_dag2(op));
+ break;
+ case 0x52: case 0x53:
+ // 0101001x xxxxxxxx xxxxxxxx ALU to AR with pgm memory read
+ alu_op_ar(op);
+ write_reg0((op >> 4) & 15, pgm_read_dag2(op));
+ break;
+ case 0x54: case 0x55:
+ // 0101010x xxxxxxxx xxxxxxxx MAC to MF with pgm memory read
+ mac_op_mf(op);
+ write_reg0((op >> 4) & 15, pgm_read_dag2(op));
+ break;
+ case 0x56: case 0x57:
+ // 0101011x xxxxxxxx xxxxxxxx ALU to AF with pgm memory read
+ alu_op_af(op);
+ write_reg0((op >> 4) & 15, pgm_read_dag2(op));
+ break;
+ case 0x58: case 0x59:
+ // 0101100x xxxxxxxx xxxxxxxx MAC to MR with pgm memory write
+ pgm_write_dag2(op, read_reg0((op >> 4) & 15));
+ mac_op_mr(op);
+ break;
+ case 0x5a: case 0x5b:
+ // 0101101x xxxxxxxx xxxxxxxx ALU to AR with pgm memory write
+ pgm_write_dag2(op, read_reg0((op >> 4) & 15));
+ alu_op_ar(op);
+ break;
+ case 0x5c: case 0x5d:
+ // 0101110x xxxxxxxx xxxxxxxx ALU to MR with pgm memory write
+ pgm_write_dag2(op, read_reg0((op >> 4) & 15));
+ mac_op_mf(op);
+ break;
+ case 0x5e: case 0x5f:
+ // 0101111x xxxxxxxx xxxxxxxx ALU to MF with pgm memory write
+ pgm_write_dag2(op, read_reg0((op >> 4) & 15));
+ alu_op_af(op);
+ break;
+ case 0x60: case 0x61:
+ // 0110000x xxxxxxxx xxxxxxxx MAC to MR with data memory read DAG1
+ mac_op_mr(op);
+ write_reg0((op >> 4) & 15, data_read_dag1(op));
+ break;
+ case 0x62: case 0x63:
+ // 0110001x xxxxxxxx xxxxxxxx ALU to AR with data memory read DAG1
+ alu_op_ar(op);
+ write_reg0((op >> 4) & 15, data_read_dag1(op));
+ break;
+ case 0x64: case 0x65:
+ // 0110010x xxxxxxxx xxxxxxxx MAC to MF with data memory read DAG1
+ mac_op_mf(op);
+ write_reg0((op >> 4) & 15, data_read_dag1(op));
+ break;
+ case 0x66: case 0x67:
+ // 0110011x xxxxxxxx xxxxxxxx ALU to AF with data memory read DAG1
+ alu_op_af(op);
+ write_reg0((op >> 4) & 15, data_read_dag1(op));
+ break;
+ case 0x68: case 0x69:
+ // 0110100x xxxxxxxx xxxxxxxx MAC to MR with data memory write DAG1
+ data_write_dag1(op, read_reg0((op >> 4) & 15));
+ mac_op_mr(op);
+ break;
+ case 0x6a: case 0x6b:
+ // 0110101x xxxxxxxx xxxxxxxx ALU to AR with data memory write DAG1
+ data_write_dag1(op, read_reg0((op >> 4) & 15));
+ alu_op_ar(op);
+ break;
+ case 0x6c: case 0x6d:
+ // 0111110x xxxxxxxx xxxxxxxx MAC to MF with data memory write DAG1
+ data_write_dag1(op, read_reg0((op >> 4) & 15));
+ mac_op_mf(op);
+ break;
+ case 0x6e: case 0x6f:
+ // 0111111x xxxxxxxx xxxxxxxx ALU to AF with data memory write DAG1
+ data_write_dag1(op, read_reg0((op >> 4) & 15));
+ alu_op_af(op);
+ break;
+ case 0x70: case 0x71:
+ // 0111000x xxxxxxxx xxxxxxxx MAC to MR with data memory read DAG2
+ mac_op_mr(op);
+ write_reg0((op >> 4) & 15, data_read_dag2(op));
+ break;
+ case 0x72: case 0x73:
+ // 0111001x xxxxxxxx xxxxxxxx ALU to AR with data memory read DAG2
+ alu_op_ar(op);
+ write_reg0((op >> 4) & 15, data_read_dag2(op));
+ break;
+ case 0x74: case 0x75:
+ // 0111010x xxxxxxxx xxxxxxxx MAC to MF with data memory read DAG2
+ mac_op_mf(op);
+ write_reg0((op >> 4) & 15, data_read_dag2(op));
+ break;
+ case 0x76: case 0x77:
+ // 0111011x xxxxxxxx xxxxxxxx ALU to AF with data memory read DAG2
+ alu_op_af(op);
+ write_reg0((op >> 4) & 15, data_read_dag2(op));
+ break;
+ case 0x78: case 0x79:
+ // 0111100x xxxxxxxx xxxxxxxx MAC to MR with data memory write DAG2
+ data_write_dag2(op, read_reg0((op >> 4) & 15));
+ mac_op_mr(op);
+ break;
+ case 0x7a: case 0x7b:
+ // 0111101x xxxxxxxx xxxxxxxx ALU to AR with data memory write DAG2
+ data_write_dag2(op, read_reg0((op >> 4) & 15));
+ alu_op_ar(op);
+ break;
+ case 0x7c: case 0x7d:
+ // 0111110x xxxxxxxx xxxxxxxx MAC to MF with data memory write DAG2
+ data_write_dag2(op, read_reg0((op >> 4) & 15));
+ mac_op_mf(op);
+ break;
+ case 0x7e: case 0x7f:
+ // 0111111x xxxxxxxx xxxxxxxx ALU to AF with data memory write DAG2
+ data_write_dag2(op, read_reg0((op >> 4) & 15));
+ alu_op_af(op);
+ break;
+ case 0x80: case 0x81: case 0x82: case 0x83:
+ // 100000xx xxxxxxxx xxxxxxxx read data memory (immediate addr) to reg group 0
+ write_reg0(op & 15, data_read((op >> 4) & 0x3fff));
+ break;
+ case 0x84: case 0x85: case 0x86: case 0x87:
+ // 100001xx xxxxxxxx xxxxxxxx read data memory (immediate addr) to reg group 1
+ write_reg1(op & 15, data_read((op >> 4) & 0x3fff));
+ break;
+ case 0x88: case 0x89: case 0x8a: case 0x8b:
+ // 100010xx xxxxxxxx xxxxxxxx read data memory (immediate addr) to reg group 2
+ write_reg2(op & 15, data_read((op >> 4) & 0x3fff));
+ break;
+ case 0x8c: case 0x8d: case 0x8e: case 0x8f:
+ // 100011xx xxxxxxxx xxxxxxxx read data memory (immediate addr) to reg group 3
+ write_reg3(op & 15, data_read((op >> 4) & 0x3fff));
+ break;
+ case 0x90: case 0x91: case 0x92: case 0x93:
+ // 1001xxxx xxxxxxxx xxxxxxxx write data memory (immediate addr) from reg group 0
+ data_write((op >> 4) & 0x3fff, read_reg0(op & 15));
+ break;
+ case 0x94: case 0x95: case 0x96: case 0x97:
+ // 1001xxxx xxxxxxxx xxxxxxxx write data memory (immediate addr) from reg group 1
+ data_write((op >> 4) & 0x3fff, read_reg1(op & 15));
+ break;
+ case 0x98: case 0x99: case 0x9a: case 0x9b:
+ // 1001xxxx xxxxxxxx xxxxxxxx write data memory (immediate addr) from reg group 2
+ data_write((op >> 4) & 0x3fff, read_reg2(op & 15));
+ break;
+ case 0x9c: case 0x9d: case 0x9e: case 0x9f:
+ // 1001xxxx xxxxxxxx xxxxxxxx write data memory (immediate addr) from reg group 3
+ data_write((op >> 4) & 0x3fff, read_reg3(op & 15));
+ break;
+ case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7:
+ case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf:
+ // 1010xxxx xxxxxxxx xxxxxxxx data memory write (immediate) DAG1
+ data_write_dag1(op, (op >> 4) & 0xffff);
+ break;
+ case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
+ case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf:
+ // 1011xxxx xxxxxxxx xxxxxxxx data memory write (immediate) DAG2
+ data_write_dag2(op, (op >> 4) & 0xffff);
+ break;
+ case 0xc0: case 0xc1:
+ // 1100000x xxxxxxxx xxxxxxxx MAC to MR with data read to AX0 & pgm read to AY0
+ mac_op_mr(op);
+ m_core.ax0.u = data_read_dag1(op);
+ m_core.ay0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xc2: case 0xc3:
+ // 1100001x xxxxxxxx xxxxxxxx ALU to AR with data read to AX0 & pgm read to AY0
+ alu_op_ar(op);
+ m_core.ax0.u = data_read_dag1(op);
+ m_core.ay0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xc4: case 0xc5:
+ // 1100010x xxxxxxxx xxxxxxxx MAC to MR with data read to AX1 & pgm read to AY0
+ mac_op_mr(op);
+ m_core.ax1.u = data_read_dag1(op);
+ m_core.ay0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xc6: case 0xc7:
+ // 1100011x xxxxxxxx xxxxxxxx ALU to AR with data read to AX1 & pgm read to AY0
+ alu_op_ar(op);
+ m_core.ax1.u = data_read_dag1(op);
+ m_core.ay0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xc8: case 0xc9:
+ // 1100100x xxxxxxxx xxxxxxxx MAC to MR with data read to MX0 & pgm read to AY0
+ mac_op_mr(op);
+ m_core.mx0.u = data_read_dag1(op);
+ m_core.ay0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xca: case 0xcb:
+ // 1100101x xxxxxxxx xxxxxxxx ALU to AR with data read to MX0 & pgm read to AY0
+ alu_op_ar(op);
+ m_core.mx0.u = data_read_dag1(op);
+ m_core.ay0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xcc: case 0xcd:
+ // 1100110x xxxxxxxx xxxxxxxx MAC to MR with data read to MX1 & pgm read to AY0
+ mac_op_mr(op);
+ m_core.mx1.u = data_read_dag1(op);
+ m_core.ay0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xce: case 0xcf:
+ // 1100111x xxxxxxxx xxxxxxxx ALU to AR with data read to MX1 & pgm read to AY0
+ alu_op_ar(op);
+ m_core.mx1.u = data_read_dag1(op);
+ m_core.ay0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xd0: case 0xd1:
+ // 1101000x xxxxxxxx xxxxxxxx MAC to MR with data read to AX0 & pgm read to AY1
+ mac_op_mr(op);
+ m_core.ax0.u = data_read_dag1(op);
+ m_core.ay1.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xd2: case 0xd3:
+ // 1101001x xxxxxxxx xxxxxxxx ALU to AR with data read to AX0 & pgm read to AY1
+ alu_op_ar(op);
+ m_core.ax0.u = data_read_dag1(op);
+ m_core.ay1.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xd4: case 0xd5:
+ // 1101010x xxxxxxxx xxxxxxxx MAC to MR with data read to AX1 & pgm read to AY1
+ mac_op_mr(op);
+ m_core.ax1.u = data_read_dag1(op);
+ m_core.ay1.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xd6: case 0xd7:
+ // 1101011x xxxxxxxx xxxxxxxx ALU to AR with data read to AX1 & pgm read to AY1
+ alu_op_ar(op);
+ m_core.ax1.u = data_read_dag1(op);
+ m_core.ay1.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xd8: case 0xd9:
+ // 1101100x xxxxxxxx xxxxxxxx MAC to MR with data read to MX0 & pgm read to AY1
+ mac_op_mr(op);
+ m_core.mx0.u = data_read_dag1(op);
+ m_core.ay1.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xda: case 0xdb:
+ // 1101101x xxxxxxxx xxxxxxxx ALU to AR with data read to MX0 & pgm read to AY1
+ alu_op_ar(op);
+ m_core.mx0.u = data_read_dag1(op);
+ m_core.ay1.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xdc: case 0xdd:
+ // 1101110x xxxxxxxx xxxxxxxx MAC to MR with data read to MX1 & pgm read to AY1
+ mac_op_mr(op);
+ m_core.mx1.u = data_read_dag1(op);
+ m_core.ay1.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xde: case 0xdf:
+ // 1101111x xxxxxxxx xxxxxxxx ALU to AR with data read to MX1 & pgm read to AY1
+ alu_op_ar(op);
+ m_core.mx1.u = data_read_dag1(op);
+ m_core.ay1.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xe0: case 0xe1:
+ // 1110000x xxxxxxxx xxxxxxxx MAC to MR with data read to AX0 & pgm read to MY0
+ mac_op_mr(op);
+ m_core.ax0.u = data_read_dag1(op);
+ m_core.my0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xe2: case 0xe3:
+ // 1110001x xxxxxxxx xxxxxxxx ALU to AR with data read to AX0 & pgm read to MY0
+ alu_op_ar(op);
+ m_core.ax0.u = data_read_dag1(op);
+ m_core.my0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xe4: case 0xe5:
+ // 1110010x xxxxxxxx xxxxxxxx MAC to MR with data read to AX1 & pgm read to MY0
+ mac_op_mr(op);
+ m_core.ax1.u = data_read_dag1(op);
+ m_core.my0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xe6: case 0xe7:
+ // 1110011x xxxxxxxx xxxxxxxx ALU to AR with data read to AX1 & pgm read to MY0
+ alu_op_ar(op);
+ m_core.ax1.u = data_read_dag1(op);
+ m_core.my0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xe8: case 0xe9:
+ // 1110100x xxxxxxxx xxxxxxxx MAC to MR with data read to MX0 & pgm read to MY0
+ mac_op_mr(op);
+ m_core.mx0.u = data_read_dag1(op);
+ m_core.my0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xea: case 0xeb:
+ // 1110101x xxxxxxxx xxxxxxxx ALU to AR with data read to MX0 & pgm read to MY0
+ alu_op_ar(op);
+ m_core.mx0.u = data_read_dag1(op);
+ m_core.my0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xec: case 0xed:
+ // 1110110x xxxxxxxx xxxxxxxx MAC to MR with data read to MX1 & pgm read to MY0
+ mac_op_mr(op);
+ m_core.mx1.u = data_read_dag1(op);
+ m_core.my0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xee: case 0xef:
+ // 1110111x xxxxxxxx xxxxxxxx ALU to AR with data read to MX1 & pgm read to MY0
+ alu_op_ar(op);
+ m_core.mx1.u = data_read_dag1(op);
+ m_core.my0.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xf0: case 0xf1:
+ // 1111000x xxxxxxxx xxxxxxxx MAC to MR with data read to AX0 & pgm read to MY1
+ mac_op_mr(op);
+ m_core.ax0.u = data_read_dag1(op);
+ m_core.my1.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xf2: case 0xf3:
+ // 1111001x xxxxxxxx xxxxxxxx ALU to AR with data read to AX0 & pgm read to MY1
+ alu_op_ar(op);
+ m_core.ax0.u = data_read_dag1(op);
+ m_core.my1.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xf4: case 0xf5:
+ // 1111010x xxxxxxxx xxxxxxxx MAC to MR with data read to AX1 & pgm read to MY1
+ mac_op_mr(op);
+ m_core.ax1.u = data_read_dag1(op);
+ m_core.my1.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xf6: case 0xf7:
+ // 1111011x xxxxxxxx xxxxxxxx ALU to AR with data read to AX1 & pgm read to MY1
+ alu_op_ar(op);
+ m_core.ax1.u = data_read_dag1(op);
+ m_core.my1.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xf8: case 0xf9:
+ // 1111100x xxxxxxxx xxxxxxxx MAC to MR with data read to MX0 & pgm read to MY1
+ mac_op_mr(op);
+ m_core.mx0.u = data_read_dag1(op);
+ m_core.my1.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xfa: case 0xfb:
+ // 1111101x xxxxxxxx xxxxxxxx ALU to AR with data read to MX0 & pgm read to MY1
+ alu_op_ar(op);
+ m_core.mx0.u = data_read_dag1(op);
+ m_core.my1.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xfc: case 0xfd:
+ // 1111110x xxxxxxxx xxxxxxxx MAC to MR with data read to MX1 & pgm read to MY1
+ mac_op_mr(op);
+ m_core.mx1.u = data_read_dag1(op);
+ m_core.my1.u = pgm_read_dag2(op >> 4);
+ break;
+ case 0xfe: case 0xff:
+ // 1111111x xxxxxxxx xxxxxxxx ALU to AR with data read to MX1 & pgm read to MY1
+ alu_op_ar(op);
+ m_core.mx1.u = data_read_dag1(op);
+ m_core.my1.u = pgm_read_dag2(op >> 4);
+ break;
+ }
+
+ m_icount--;
+ } while (m_icount > 0);
+}