summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Andrew Gardner <andrew-gardner@users.noreply.github.com>2008-10-30 05:21:45 +0000
committer Andrew Gardner <andrew-gardner@users.noreply.github.com>2008-10-30 05:21:45 +0000
commitc33d3a4f52b8d584949c427f614e04ab66cb6a8f (patch)
tree0395f9f30cbb9dc7d5d535cdeb1a46bbc03d7976
parent9ebd7a57f381eb5e5554b8186f4b8eb3d84a2f82 (diff)
Rewrite of the Motorola DSP56k CPU core. (Andrew Gardner)
* Partially implemented move, asr4, and mpy ops.
-rw-r--r--src/emu/cpu/dsp56k/dsp56ops.c100
-rw-r--r--src/mame/drivers/plygonet.c2
2 files changed, 94 insertions, 8 deletions
diff --git a/src/emu/cpu/dsp56k/dsp56ops.c b/src/emu/cpu/dsp56k/dsp56ops.c
index b4980a621b7..cdccc7243a3 100644
--- a/src/emu/cpu/dsp56k/dsp56ops.c
+++ b/src/emu/cpu/dsp56k/dsp56ops.c
@@ -181,6 +181,7 @@ static void decode_IIII_table(UINT16 IIII, typed_pointer* src_ret, typed_pointe
static void decode_JJJF_table(UINT16 JJJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
static void decode_JJF_table(UINT16 JJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
static void decode_QQF_special_table(UINT16 QQ, UINT16 F, void **S1, void **S2, void **D);
+static void decode_QQQF_special_table(UINT16 QQQ, UINT16 F, void **S1, void **S2, void **D);
static void decode_RR_table(UINT16 RR, typed_pointer* ret);
static void decode_Z_table(UINT16 Z, typed_pointer* ret);
@@ -1236,9 +1237,17 @@ static size_t dsp56k_op_add(const UINT16 op_byte, typed_pointer* d_register, UIN
/* MOVE : .... .... 0001 0001 : A-128 */
static size_t dsp56k_op_move(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
{
+ /* Equivalent to a nop with a parallel move */
+ /* These can't be used later. Hopefully compilers would pick this up. */
+ *p_accum = 0;
+ d_register->addr = NULL;
+ d_register->data_type = DT_BYTE;
+
/* S L E U N Z V C */
/* * * - - - - - - */
- return 0;
+ /* TODO: S, L */
+ cycles += 2; /* TODO: + mv oscillator cycles */
+ return 1;
}
/* TFR : .... .... 0001 FJJJ : A-212 */
@@ -1670,9 +1679,41 @@ static size_t dsp56k_op_cmpm(const UINT16 op_byte, typed_pointer* d_register, UI
/* MPY : .... .... 1k00 FQQQ : A-160 -- CONFIRMED TYPO IN DOCS (HHHH vs HHHW) */
static size_t dsp56k_op_mpy(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
{
+ UINT16 k = 0;
+ INT64 result = 0;
+
+ INT32 s1 = 0;
+ INT32 s2 = 0;
+
+ void* D = NULL;
+ void* S1 = NULL;
+ void* S2 = NULL;
+
+ decode_QQQF_special_table(BITS(op_byte,0x0007), BITS(op_byte,0x0008), &S1, &S2, &D);
+
+ k = BITS(op_byte,0x0040);
+
+ /* Negative sign */
+ if (!k)
+ s1 = *((INT16*)S1);
+ else
+ s1 = (*((INT16*)S1)) * -1;
+
+ s2 = *((INT16*)S2);
+
+ /* Fixed-point 2's complement multiplication requires a shift */
+ result = ( s1 * s2 ) << 1;
+
+ (*((UINT64*)D)) = result & U64(0x000000ffffffffff);
+
/* S L E U N Z V C */
/* * * * * * * * - */
- return 0;
+ /* TODO: S, L, E, V */
+ if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(1);
+ if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(1);
+
+ cycles += 2; /* TODO: +mv oscillator cycles */
+ return 1;
}
/* MPYR : .... .... 1k01 FQQQ : A-162 */
@@ -1753,10 +1794,7 @@ static size_t dsp56k_op_asl4(const UINT16 op, UINT8* cycles)
p_accum = *((UINT64*)D.addr);
- *((UINT64*)D.addr) = (*((UINT64*)D.addr)) << 1;
- *((UINT64*)D.addr) = (*((UINT64*)D.addr)) << 1;
- *((UINT64*)D.addr) = (*((UINT64*)D.addr)) << 1;
- *((UINT64*)D.addr) = (*((UINT64*)D.addr)) << 1;
+ *((UINT64*)D.addr) = (*((UINT64*)D.addr)) << 4;
*((UINT64*)D.addr) = (*((UINT64*)D.addr)) & U64(0x000000ffffffffff);
/* S L E U N Z V C */
@@ -1777,10 +1815,32 @@ static size_t dsp56k_op_asl4(const UINT16 op, UINT8* cycles)
/* ASR4 : 0001 0101 0011 F000 : A-34 */
static size_t dsp56k_op_asr4(const UINT16 op, UINT8* cycles)
{
+ UINT64 p_accum = 0;
+ typed_pointer D = {NULL, DT_BYTE};
+ decode_F_table(BITS(op,0x0008), &D);
+
+ p_accum = *((UINT64*)D.addr);
+
+ *((UINT64*)D.addr) = (*((UINT64*)D.addr)) >> 4;
+ *((UINT64*)D.addr) = (*((UINT64*)D.addr)) & U64(0x000000ffffffffff);
+
+ /* The top 4 bits become the old bit 39 */
+ if (p_accum & U64(0x0000008000000000))
+ *((UINT64*)D.addr) |= U64(0x000000f000000000);
+ else
+ *((UINT64*)D.addr) &= (~U64(0x000000f000000000));
+
/* S L E U N Z V C */
/* - * * * * * 0 ? */
+ /* TODO: E, U */
/* C - Set if bit 3 of source operand is set. Cleared otherwise. */
- return 0;
+ if (*((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(1); else N_bit_set(0);
+ if (*((UINT64*)D.addr) == 0) Z_bit_set(1); else Z_bit_set(0);
+ V_bit_set(0);
+ if (p_accum & U64(0x0000000000000008)) C_bit_set(1); else C_bit_set(0);
+
+ cycles += 2;
+ return 1;
}
/* ASR16 : 0001 0101 0111 F000 : A-36 */
@@ -2555,6 +2615,7 @@ static size_t dsp56k_op_macsuuu(const UINT16 op, UINT8* cycles)
else
{
/* Signed * Unsigned */
+ /* TODO: THERE IS A HUGE CHANCE THIS DOESN'T WORK RIGHT */
UINT32 s1 = (UINT32)((INT32)(*((UINT16*)S1)));
UINT32 s2 = (UINT32)(*((UINT16*)S2));
result = ( s1 * s2 ) << 1;
@@ -3467,6 +3528,31 @@ static void decode_QQF_special_table(UINT16 QQ, UINT16 F, void **S1, void **S2,
}
}
+static void decode_QQQF_special_table(UINT16 QQQ, UINT16 F, void **S1, void **S2, void **D)
+{
+ UINT16 switchVal = (QQQ << 1) | F;
+
+ switch(switchVal)
+ {
+ case 0x0: *S1 = &X0; *S2 = &X0; *D = &A; break;
+ case 0x1: *S1 = &X0; *S2 = &X0; *D = &B; break;
+ case 0x2: *S1 = &X1; *S2 = &X0; *D = &A; break;
+ case 0x3: *S1 = &X1; *S2 = &X0; *D = &B; break;
+ case 0x4: *S1 = &A1; *S2 = &Y0; *D = &A; break;
+ case 0x5: *S1 = &A1; *S2 = &Y0; *D = &B; break;
+ case 0x6: *S1 = &B1; *S2 = &X0; *D = &A; break;
+ case 0x7: *S1 = &B1; *S2 = &X0; *D = &B; break;
+ case 0x8: *S1 = &Y0; *S2 = &X0; *D = &A; break;
+ case 0x9: *S1 = &Y0; *S2 = &X0; *D = &B; break;
+ case 0xa: *S1 = &Y1; *S2 = &X0; *D = &A; break;
+ case 0xb: *S1 = &Y1; *S2 = &X0; *D = &B; break;
+ case 0xc: *S1 = &Y0; *S2 = &X1; *D = &A; break;
+ case 0xd: *S1 = &Y0; *S2 = &X1; *D = &B; break;
+ case 0xe: *S1 = &Y1; *S2 = &X1; *D = &A; break;
+ case 0xf: *S1 = &Y1; *S2 = &X1; *D = &B; break;
+ }
+}
+
static void decode_RR_table(UINT16 RR, typed_pointer* ret)
{
switch(RR)
diff --git a/src/mame/drivers/plygonet.c b/src/mame/drivers/plygonet.c
index e8ce6e34f88..4ef9f8f2cc0 100644
--- a/src/mame/drivers/plygonet.c
+++ b/src/mame/drivers/plygonet.c
@@ -512,7 +512,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( dsp_data_map, ADDRESS_SPACE_DATA, 16 )
AM_RANGE(0x0800, 0x5fff) AM_RAM /* Appears to not be affected by banking? */
AM_RANGE(0x6000, 0x6fff) AM_READWRITE(dsp56k_ram_bank00_read, dsp56k_ram_bank00_write)
- AM_RANGE(0x7000, 0x7fff) AM_READWRITE(dsp56k_ram_bank01_read, dsp56k_ram_bank01_write) /* Mirrored in program space @ 0x8000 */
+ AM_RANGE(0x7000, 0x7fff) AM_READWRITE(dsp56k_ram_bank01_read, dsp56k_ram_bank01_write) /* Mirrored in program space @ 0x7000 */
AM_RANGE(0x8000, 0xbfff) AM_READWRITE(dsp56k_ram_bank02_read, dsp56k_ram_bank02_write)
AM_RANGE(0xc000, 0xdfff) AM_READWRITE(dsp56k_shared_ram_read, dsp56k_shared_ram_write)
AM_RANGE(0xe000, 0xffbf) AM_READWRITE(dsp56k_ram_bank04_read, dsp56k_ram_bank04_write)