summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/dsp16
diff options
context:
space:
mode:
author Andrew Gardner <andrew-gardner@users.noreply.github.com>2013-01-05 01:40:33 +0000
committer Andrew Gardner <andrew-gardner@users.noreply.github.com>2013-01-05 01:40:33 +0000
commita33f00ff556dc807e995a5935669ac8195c941c9 (patch)
treed7d1b912063b69657c97335a7b8c1628250fea9f /src/emu/cpu/dsp16
parentb547e0ac7b58b2e0c68edb71d10d1073b916c604 (diff)
dsp16: Added 16-bit immediate load opcode. [Andrew Gardner]
Fixed reset behavior. Code reorganization.
Diffstat (limited to 'src/emu/cpu/dsp16')
-rw-r--r--src/emu/cpu/dsp16/dsp16.c257
-rw-r--r--src/emu/cpu/dsp16/dsp16.h10
-rw-r--r--src/emu/cpu/dsp16/dsp16ops.c314
3 files changed, 332 insertions, 249 deletions
diff --git a/src/emu/cpu/dsp16/dsp16.c b/src/emu/cpu/dsp16/dsp16.c
index 9e66bd2cb13..2b7663b0553 100644
--- a/src/emu/cpu/dsp16/dsp16.c
+++ b/src/emu/cpu/dsp16/dsp16.c
@@ -137,7 +137,14 @@ void dsp16_device::device_start()
void dsp16_device::device_reset()
{
- m_pc = m_ppc = 0x0000;
+ // Page 7-5
+ m_pc = 0x0000;
+ m_sioc = 0x0000;
+ m_pioc = 0x0008;
+ m_rb = 0x0000;
+ m_re = 0x0000;
+ // AUC is not affected by reset
+ m_ppc = m_pc;
}
@@ -163,7 +170,7 @@ void dsp16_device::state_string_export(const device_state_entry &entry, astring
switch (entry.index())
{
case STATE_GENFLAGS:
- string.printf("(see below)");
+ string.printf("(multiple below)");
break;
// Placeholder for a better view later (TODO)
@@ -294,248 +301,4 @@ void dsp16_device::execute_run()
} while (m_icount > 0);
}
-
-void dsp16_device::execute_one(const UINT16 op, UINT8& cycles, UINT8& pcAdvance)
-{
- cycles = 1;
- pcAdvance = 1;
-
- const UINT8 opcode = (op >> 11) & 0x1f;
- switch(opcode)
- {
- // Format 1: Multiply/ALU Read/Write Group
- case 0x06:
- {
- // F1, Y
- //const UINT8 Y = (op & 0x000f);
- //const UINT8 S = (op & 0x0200) >> 9;
- //const UINT8 D = (op & 0x0400) >> 10;
- //const UINT8 F1 = (op & 0x01e0) >> 5;
- break;
- }
- case 0x04: case 0x1c:
- {
- // F1 Y=a0[1] | F1 Y=a1[1]
- //const UINT8 Y = (op & 0x000f);
- //const UINT8 S = (op & 0x0200) >> 9;
- //const UINT8 D = (op & 0x0400) >> 10;
- //const UINT8 F1 = (op & 0x01e0) >> 5;
- break;
- }
- case 0x16:
- {
- // F1, x = Y
- //const UINT8 Y = (op & 0x000f);
- //const UINT8 S = (op & 0x0200) >> 9;
- //const UINT8 D = (op & 0x0400) >> 10;
- //const UINT8 F1 = (op & 0x01e0) >> 5;
- break;
- }
- case 0x17:
- {
- // F1, y[l] = Y
- //const UINT8 Y = (op & 0x000f);
- //const UINT8 X = (op & 0x0010) >> 4;
- //const UINT8 S = (op & 0x0200) >> 9;
- //const UINT8 D = (op & 0x0400) >> 10;
- //const UINT8 F1 = (op & 0x01e0) >> 5;
- break;
- }
- case 0x1f:
- {
- // F1, y = Y, x = *pt++[i]
- //const UINT8 Y = (op & 0x000f);
- //const UINT8 X = (op & 0x0010) >> 4;
- //const UINT8 S = (op & 0x0200) >> 9;
- //const UINT8 D = (op & 0x0400) >> 10;
- //const UINT8 F1 = (op & 0x01e0) >> 5;
- break;
- }
- case 0x19: case 0x1b:
- {
- // F1, y = a0|1, x = *pt++[i]
- //const UINT8 Y = (op & 0x000f);
- //const UINT8 X = (op & 0x0010) >> 4;
- //const UINT8 S = (op & 0x0200) >> 9;
- //const UINT8 D = (op & 0x0400) >> 10;
- //const UINT8 F1 = (op & 0x01e0) >> 5;
- break;
- }
- case 0x14:
- {
- // F1, Y = y[1]
- //const UINT8 Y = (op & 0x000f);
- //const UINT8 X = (op & 0x0010) >> 4;
- //const UINT8 S = (op & 0x0200) >> 9;
- //const UINT8 D = (op & 0x0400) >> 10;
- //const UINT8 F1 = (op & 0x01e0) >> 5;
- break;
- }
-
- // Format 1a: Multiply/ALU Read/Write Group (major typo in docs on p3-51)
- case 0x07:
- {
- // F1, At[1] = Y
- //const UINT8 Y = (op & 0x000f);
- //const UINT8 S = (op & 0x0200) >> 9;
- //const UINT8 aT = (op & 0x0400) >> 10;
- //const UINT8 F1 = (op & 0x01e0) >> 5;
- break;
- }
-
- // Format 2: Multiply/ALU Read/Write Group
- case 0x15:
- {
- // F1, Z : y[1]
- //const UINT8 Z = (op & 0x000f);
- //const UINT8 X = (op & 0x0010) >> 4;
- //const UINT8 S = (op & 0x0200) >> 9;
- //const UINT8 D = (op & 0x0400) >> 10;
- //const UINT8 F1 = (op & 0x01e0) >> 5;
- break;
- }
- case 0x1d:
- {
- // F1, Z : y, x=*pt++[i]
- //const UINT8 Z = (op & 0x000f);
- //const UINT8 X = (op & 0x0010) >> 4;
- //const UINT8 S = (op & 0x0200) >> 9;
- //const UINT8 D = (op & 0x0400) >> 10;
- //const UINT8 F1 = (op & 0x01e0) >> 5;
- break;
- }
-
- // Format 2a: Multiply/ALU Read/Write Group
- case 0x05:
- {
- // F1, Z : aT[1]
- //const UINT8 Z = (op & 0x000f);
- //const UINT8 X = (op & 0x0010) >> 4;
- //const UINT8 S = (op & 0x0200) >> 9;
- //const UINT8 aT = (op & 0x0400) >> 10;
- //const UINT8 F1 = (op & 0x01e0) >> 5;
- break;
- }
-
- // Format 3: Special Functions
- case 0x12:
- case 0x13:
- {
- // if|ifc CON F2
- //const UINT8 CON = (op & 0x001f);
- //const UINT8 S = (op & 0x0200) >> 9;
- //const UINT8 D = (op & 0x0400) >> 10;
- //const UINT8 F2 = (op & 0x01e0) >> 5;
- break;
- }
-
- // Format 4: Branch Direct Group
- case 0x00: case 0x01:
- {
- // goto JA
- const UINT16 JA = (op & 0x0fff) | (m_pc & 0xf000);
- m_pc = JA;
- pcAdvance = 0;
- break;
- }
-
- case 0x10: case 0x11:
- {
- // call JA
- //const UINT16 JA = (op & 0x0fff) | (m_pc & 0xf000);
- break;
- }
-
- // Format 5: Branch Indirect Group
- case 0x18:
- {
- // goto B
- //const UINT8 B = (op & 0x0700) >> 8;
- break;
- }
-
- // Format 6: Contitional Branch Qualifier/Software Interrupt (icall)
- case 0x1a:
- {
- // if CON [goto/call/return]
- //const UINT8 CON = (op & 0x001f);
- break;
- }
-
- // Format 7: Data Move Group
- case 0x09: case 0x0b:
- {
- // R = aS
- //const UINT8 R = (op & 0x03f0) >> 4;
- //const UINT8 S = (op & 0x1000) >> 12;
- break;
- }
- case 0x08:
- {
- // aT = R
- //const UINT8 R = (op & 0x03f0) >> 4;
- //const UINT8 aT = (op & 0x0400) >> 10;
- break;
- }
- case 0x0f:
- {
- // R = Y
- //const UINT8 Y = (op & 0x000f);
- //const UINT8 R = (op & 0x03f0) >> 4;
- break;
- }
- case 0x0c:
- {
- // Y = R
- //const UINT8 Y = (op & 0x000f);
- //const UINT8 R = (op & 0x03f0) >> 4;
- break;
- }
- case 0x0d:
- {
- // Z : R
- //const UINT8 Z = (op & 0x000f);
- //const UINT8 R = (op & 0x03f0) >> 4;
- break;
- }
-
- // Format 8: Data Move (immediate operand - 2 words)
- case 0x0a:
- {
- // R = N
- //const UINT8 R = (op & 0x03f0) >> 4;
- pcAdvance++;
- break;
- }
-
- // Format 9: Short Immediate Group
- case 0x02: case 0x03:
- {
- // R = M
- //const UINT8 M = (op & 0x00ff);
- //const UINT8 R = (op & 0x0e00) >> 9;
- break;
- }
-
- // Format 10: do - redo
- case 0x0e:
- {
- // do|redo K
- //const UINT8 K = (op & 0x007f);
- //const UINT8 NI = (op & 0x0780) >> 7;
- break;
- }
-
- // RESERVED
- case 0x1e:
- {
- break;
- }
-
- // UNKNOWN
- default:
- {
- break;
- }
- }
-}
+#include "dsp16ops.c"
diff --git a/src/emu/cpu/dsp16/dsp16.h b/src/emu/cpu/dsp16/dsp16.h
index 14078fa132a..1375adca048 100644
--- a/src/emu/cpu/dsp16/dsp16.h
+++ b/src/emu/cpu/dsp16/dsp16.h
@@ -88,7 +88,7 @@ protected:
UINT8 m_c0;
UINT8 m_c1;
UINT8 m_c2;
- // Serial, parallel, etc.
+ // Serial and parallel interfaces
UINT16 m_sioc;
UINT16 m_pioc;
@@ -108,7 +108,13 @@ protected:
int m_icount;
// operations
- void execute_one(const UINT16 op, UINT8& cycles, UINT8& pcAdvance);
+ void execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance);
+
+ void* registerFromRTable(const UINT8& R);
+
+ // helpers
+ void* addressYL();
+ //void writeYxRegister(const UINT16& value);
};
diff --git a/src/emu/cpu/dsp16/dsp16ops.c b/src/emu/cpu/dsp16/dsp16ops.c
new file mode 100644
index 00000000000..cd88bab7feb
--- /dev/null
+++ b/src/emu/cpu/dsp16/dsp16ops.c
@@ -0,0 +1,314 @@
+#include "dsp16.h"
+
+
+// The YL register is the lower half of the 32 bit Y register
+void* dsp16_device::addressYL()
+{
+ return (((UINT8*)&m_y)+0x4);
+}
+
+void* dsp16_device::registerFromRTable(const UINT8 &R)
+{
+ switch (R)
+ {
+ case 0x00: return (void*)&m_r0;
+ case 0x01: return (void*)&m_r1;
+ case 0x02: return (void*)&m_r2;
+ case 0x03: return (void*)&m_r3;
+ case 0x04: return (void*)&m_j;
+ case 0x05: return (void*)&m_k;
+ case 0x06: return (void*)&m_rb;
+ case 0x07: return (void*)&m_re;
+ case 0x08: return (void*)&m_pt;
+ case 0x09: return (void*)&m_pr;
+ case 0x0a: return (void*)&m_pi;
+ case 0x0b: return (void*)&m_i;
+
+ case 0x10: return (void*)&m_x;
+ case 0x11: return (void*)&m_y;
+ case 0x12: return (void*)addressYL();
+ case 0x13: return (void*)&m_auc;
+ case 0x14: return (void*)&m_psw;
+ case 0x15: return (void*)&m_c0;
+ case 0x16: return (void*)&m_c1;
+ case 0x17: return (void*)&m_c2;
+ case 0x18: return (void*)&m_sioc;
+ //case 0x19: return (void*)&m_srta;
+ //case 0x1a: return (void*)&m_sdx;
+ //case 0x1b: return (void*)&m_tdms;
+ case 0x1c: return (void*)&m_pioc;
+ //case 0x1d: return (void*)&m_pdx0;
+ //case 0x1e: return (void*)&m_pdx1;
+
+ default: return NULL;
+ }
+ return NULL;
+}
+
+
+void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance)
+{
+ cycles = 1;
+ pcAdvance = 1;
+
+ const UINT8 opcode = (op >> 11) & 0x1f;
+ switch(opcode)
+ {
+ // Format 1: Multiply/ALU Read/Write Group
+ case 0x06:
+ {
+ // F1, Y
+ //const UINT8 Y = (op & 0x000f);
+ //const UINT8 S = (op & 0x0200) >> 9;
+ //const UINT8 D = (op & 0x0400) >> 10;
+ //const UINT8 F1 = (op & 0x01e0) >> 5;
+ break;
+ }
+ case 0x04: case 0x1c:
+ {
+ // F1 Y=a0[1] | F1 Y=a1[1]
+ //const UINT8 Y = (op & 0x000f);
+ //const UINT8 S = (op & 0x0200) >> 9;
+ //const UINT8 D = (op & 0x0400) >> 10;
+ //const UINT8 F1 = (op & 0x01e0) >> 5;
+ break;
+ }
+ case 0x16:
+ {
+ // F1, x = Y
+ //const UINT8 Y = (op & 0x000f);
+ //const UINT8 S = (op & 0x0200) >> 9;
+ //const UINT8 D = (op & 0x0400) >> 10;
+ //const UINT8 F1 = (op & 0x01e0) >> 5;
+ break;
+ }
+ case 0x17:
+ {
+ // F1, y[l] = Y
+ //const UINT8 Y = (op & 0x000f);
+ //const UINT8 X = (op & 0x0010) >> 4;
+ //const UINT8 S = (op & 0x0200) >> 9;
+ //const UINT8 D = (op & 0x0400) >> 10;
+ //const UINT8 F1 = (op & 0x01e0) >> 5;
+ break;
+ }
+ case 0x1f:
+ {
+ // F1, y = Y, x = *pt++[i]
+ //const UINT8 Y = (op & 0x000f);
+ //const UINT8 X = (op & 0x0010) >> 4;
+ //const UINT8 S = (op & 0x0200) >> 9;
+ //const UINT8 D = (op & 0x0400) >> 10;
+ //const UINT8 F1 = (op & 0x01e0) >> 5;
+ break;
+ }
+ case 0x19: case 0x1b:
+ {
+ // F1, y = a0|1, x = *pt++[i]
+ //const UINT8 Y = (op & 0x000f);
+ //const UINT8 X = (op & 0x0010) >> 4;
+ //const UINT8 S = (op & 0x0200) >> 9;
+ //const UINT8 D = (op & 0x0400) >> 10;
+ //const UINT8 F1 = (op & 0x01e0) >> 5;
+ break;
+ }
+ case 0x14:
+ {
+ // F1, Y = y[1]
+ //const UINT8 Y = (op & 0x000f);
+ //const UINT8 X = (op & 0x0010) >> 4;
+ //const UINT8 S = (op & 0x0200) >> 9;
+ //const UINT8 D = (op & 0x0400) >> 10;
+ //const UINT8 F1 = (op & 0x01e0) >> 5;
+ break;
+ }
+
+ // Format 1a: Multiply/ALU Read/Write Group (major typo in docs on p3-51)
+ case 0x07:
+ {
+ // F1, At[1] = Y
+ //const UINT8 Y = (op & 0x000f);
+ //const UINT8 S = (op & 0x0200) >> 9;
+ //const UINT8 aT = (op & 0x0400) >> 10;
+ //const UINT8 F1 = (op & 0x01e0) >> 5;
+ break;
+ }
+
+ // Format 2: Multiply/ALU Read/Write Group
+ case 0x15:
+ {
+ // F1, Z : y[1]
+ //const UINT8 Z = (op & 0x000f);
+ //const UINT8 X = (op & 0x0010) >> 4;
+ //const UINT8 S = (op & 0x0200) >> 9;
+ //const UINT8 D = (op & 0x0400) >> 10;
+ //const UINT8 F1 = (op & 0x01e0) >> 5;
+ break;
+ }
+ case 0x1d:
+ {
+ // F1, Z : y, x=*pt++[i]
+ //const UINT8 Z = (op & 0x000f);
+ //const UINT8 X = (op & 0x0010) >> 4;
+ //const UINT8 S = (op & 0x0200) >> 9;
+ //const UINT8 D = (op & 0x0400) >> 10;
+ //const UINT8 F1 = (op & 0x01e0) >> 5;
+ break;
+ }
+
+ // Format 2a: Multiply/ALU Read/Write Group
+ case 0x05:
+ {
+ // F1, Z : aT[1]
+ //const UINT8 Z = (op & 0x000f);
+ //const UINT8 X = (op & 0x0010) >> 4;
+ //const UINT8 S = (op & 0x0200) >> 9;
+ //const UINT8 aT = (op & 0x0400) >> 10;
+ //const UINT8 F1 = (op & 0x01e0) >> 5;
+ break;
+ }
+
+ // Format 3: Special Functions
+ case 0x12:
+ case 0x13:
+ {
+ // if|ifc CON F2
+ //const UINT8 CON = (op & 0x001f);
+ //const UINT8 S = (op & 0x0200) >> 9;
+ //const UINT8 D = (op & 0x0400) >> 10;
+ //const UINT8 F2 = (op & 0x01e0) >> 5;
+ break;
+ }
+
+ // Format 4: Branch Direct Group
+ case 0x00: case 0x01:
+ {
+ // goto JA
+ const UINT16 JA = (op & 0x0fff) | (m_pc & 0xf000);
+ m_pc = JA;
+ cycles = 2;
+ pcAdvance = 0;
+ break;
+ }
+
+ case 0x10: case 0x11:
+ {
+ // call JA
+ //const UINT16 JA = (op & 0x0fff) | (m_pc & 0xf000);
+ break;
+ }
+
+ // Format 5: Branch Indirect Group
+ case 0x18:
+ {
+ // goto B
+ //const UINT8 B = (op & 0x0700) >> 8;
+ break;
+ }
+
+ // Format 6: Contitional Branch Qualifier/Software Interrupt (icall)
+ case 0x1a:
+ {
+ // if CON [goto/call/return]
+ //const UINT8 CON = (op & 0x001f);
+ break;
+ }
+
+ // Format 7: Data Move Group
+ case 0x09: case 0x0b:
+ {
+ // R = aS
+ //const UINT8 R = (op & 0x03f0) >> 4;
+ //const UINT8 S = (op & 0x1000) >> 12;
+ break;
+ }
+ case 0x08:
+ {
+ // aT = R
+ //const UINT8 R = (op & 0x03f0) >> 4;
+ //const UINT8 aT = (op & 0x0400) >> 10;
+ break;
+ }
+ case 0x0f:
+ {
+ // R = Y
+ //const UINT8 Y = (op & 0x000f);
+ //const UINT8 R = (op & 0x03f0) >> 4;
+ break;
+ }
+ case 0x0c:
+ {
+ // Y = R
+ //const UINT8 Y = (op & 0x000f);
+ //const UINT8 R = (op & 0x03f0) >> 4;
+ break;
+ }
+ case 0x0d:
+ {
+ // Z : R
+ //const UINT8 Z = (op & 0x000f);
+ //const UINT8 R = (op & 0x03f0) >> 4;
+ break;
+ }
+
+ // Format 8: Data Move (immediate operand - 2 words)
+ case 0x0a:
+ {
+ // R = N
+ const UINT8 R = (op & 0x03f0) >> 4;
+ const UINT16 iVal = opcode_read(1);
+ void* reg = registerFromRTable(R);
+ if (reg == &m_auc || reg == &m_c0 || reg == &m_c1 || reg == &m_c2)
+ {
+ *(UINT8*)reg = iVal & 0x00ff; // 8 bit registers
+ }
+ else if (reg == &m_i)
+ {
+ *(UINT16*)reg = iVal & 0x0fff; // 12 bit register
+ }
+ else if (reg == &m_y || reg == addressYL())
+ {
+ *(UINT16*)reg = iVal; // Temporary
+ //writeYxRegister(iVal); // TODO
+ }
+ else
+ {
+ *(UINT16*)reg = iVal; // The rest
+ }
+
+ cycles = 2;
+ pcAdvance = 2;
+ break;
+ }
+
+ // Format 9: Short Immediate Group
+ case 0x02: case 0x03:
+ {
+ // R = M
+ //const UINT8 M = (op & 0x00ff);
+ //const UINT8 R = (op & 0x0e00) >> 9;
+ break;
+ }
+
+ // Format 10: do - redo
+ case 0x0e:
+ {
+ // do|redo K
+ //const UINT8 K = (op & 0x007f);
+ //const UINT8 NI = (op & 0x0780) >> 7;
+ break;
+ }
+
+ // RESERVED
+ case 0x1e:
+ {
+ break;
+ }
+
+ // UNKNOWN
+ default:
+ {
+ break;
+ }
+ }
+}