summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/dsp56k
diff options
context:
space:
mode:
author Andrew Gardner <andrew-gardner@users.noreply.github.com>2008-10-18 18:10:59 +0000
committer Andrew Gardner <andrew-gardner@users.noreply.github.com>2008-10-18 18:10:59 +0000
commite138837002fc37f58ea2f50023a44ce74b0f4dd0 (patch)
treebd75defa9c56f2e44f06e3768c162bf1b46e7df7 /src/emu/cpu/dsp56k
parent191767f62f4f1e6fa75e59065ce3d01ba198814e (diff)
Rewrite of the Motorola DSP56k CPU core. (Andrew Gardner)
* Complete rewrite focusing on legibility and extensibility. * 27/121 opcodes (mostly) implemented. * Bugfix for reset status of interrupt priority bits. * Bugfix for disassembly of register-to-register parallel data move. [[These changes bring the driver up to the point where the plygonet hardware begins banking memory. The behavior is understood, so I should have the driver back to where it was before the rewrite soon. Then real progress can be made.]]
Diffstat (limited to 'src/emu/cpu/dsp56k')
-rw-r--r--src/emu/cpu/dsp56k/dsp56dsm.c16
-rw-r--r--src/emu/cpu/dsp56k/dsp56k.c4
-rw-r--r--src/emu/cpu/dsp56k/dsp56ops.c4622
-rw-r--r--src/emu/cpu/dsp56k/dsp56pcu.c6
4 files changed, 2738 insertions, 1910 deletions
diff --git a/src/emu/cpu/dsp56k/dsp56dsm.c b/src/emu/cpu/dsp56k/dsp56dsm.c
index 1a98d2a4a57..6e8c864e76a 100644
--- a/src/emu/cpu/dsp56k/dsp56dsm.c
+++ b/src/emu/cpu/dsp56k/dsp56dsm.c
@@ -52,7 +52,7 @@ static size_t dsp56k_dasm_lsl (const UINT16 op_byte, char* opcode_str, char* ar
static size_t dsp56k_dasm_eor (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register);
static size_t dsp56k_dasm_subl (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register);
static size_t dsp56k_dasm_sub (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register);
-static size_t dsp56k_dasm_clr2 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register);
+static size_t dsp56k_dasm_clr24 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register);
static size_t dsp56k_dasm_sbc (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register);
static size_t dsp56k_dasm_cmp (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register);
static size_t dsp56k_dasm_neg (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register);
@@ -461,7 +461,7 @@ offs_t dsp56k_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opr
/* CLR24 : .... .... 0101 F001 : A-62 */
else if ((op_byte & 0x00f7) == 0x0051)
{
- size = dsp56k_dasm_clr2(op_byte, opcode_str, arg_str, d_register);
+ size = dsp56k_dasm_clr24(op_byte, opcode_str, arg_str, d_register);
}
/* SBC : .... .... 0101 F01J : A-198 */
else if ((op_byte & 0x00f6) == 0x0052)
@@ -1408,7 +1408,7 @@ static size_t dsp56k_dasm_sub(const UINT16 op_byte, char* opcode_str, char* arg_
}
/* CLR24 : .... .... 0101 F001 : A-62 */
-static size_t dsp56k_dasm_clr2(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register)
+static size_t dsp56k_dasm_clr24(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register)
{
char D[32];
decode_F_table(BITS(op_byte,0x08), D);
@@ -1820,7 +1820,7 @@ static size_t dsp56k_dasm_bscc_1(const UINT16 op, char* opcode_str, char* arg_st
static size_t dsp56k_dasm_bsr(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc)
{
sprintf(opcode_str, "bsr");
- sprintf(arg_str, "%d (0x%04x)", (INT16)op2, pc + 2 + (INT16)op2);
+ sprintf(arg_str, "%x (0x%04x)", (INT16)op2, pc + 2 + (INT16)op2);
return (2 | DASMFLAG_STEP_OVER);
}
@@ -2606,6 +2606,12 @@ static void decode_register_to_register_data_move(const UINT16 op, char* paralle
decode_IIII_table(BITS(op,0x0f00), S, D);
+ if (S[0] == 'F')
+ {
+ S[0] = d_register[0];
+ S[1] = 0x00;
+ }
+
if (D[0] == '^' && D[1] == 'F')
{
if (d_register[0] == 'B')
@@ -2613,7 +2619,7 @@ static void decode_register_to_register_data_move(const UINT16 op, char* paralle
else if (d_register[0] == 'A')
sprintf(D, "B");
else
- sprintf(D, "A");
+ sprintf(D, "A"); /* In the case of no data ALU operation */
}
sprintf(parallel_move_str, "%s,%s", S, D);
diff --git a/src/emu/cpu/dsp56k/dsp56k.c b/src/emu/cpu/dsp56k/dsp56k.c
index c685063b219..0ed44f98a7e 100644
--- a/src/emu/cpu/dsp56k/dsp56k.c
+++ b/src/emu/cpu/dsp56k/dsp56k.c
@@ -461,9 +461,7 @@ static void dsp56k_exit(void)
CORE INCLUDE
***************************************************************************/
-#define OP core.op
-#define ROPCODE(pc) cpu_readop16(pc)
-
+#define OP (core.op)
#include "dsp56ops.c"
/***************************************************************************
diff --git a/src/emu/cpu/dsp56k/dsp56ops.c b/src/emu/cpu/dsp56k/dsp56ops.c
index cb0fd76c13a..e000cc508e9 100644
--- a/src/emu/cpu/dsp56k/dsp56ops.c
+++ b/src/emu/cpu/dsp56k/dsp56ops.c
@@ -15,2147 +15,3085 @@
//
//
-// Helper functions and macros
+/************************/
+/* Datatypes and macros */
+/************************/
+enum dataType { DT_BYTE,
+ DT_WORD,
+ DT_DOUBLE_WORD,
+ DT_LONG_WORD };
+
+struct _typed_pointer
+{
+ void* addr;
+ char data_type;
+};
+typedef struct _typed_pointer typed_pointer;
+
+
+#define WORD(X) (X<<1)
#define BITS(CUR,MASK) (Dsp56kOpMask(CUR,MASK))
-static UINT16 Dsp56kOpMask(UINT16 op, UINT16 mask) ;
-
-enum dataType { DT_BYTE, DT_WORD, DT_DOUBLE_WORD, DT_LONG_WORD } ;
-
-// This function's areguments are written source->destination to fall in line with the processor's paradigm...
-static void SetDestinationValue(void *sourcePointer, unsigned char sourceType,
- void *destinationPointer, unsigned char destinationType) ;
-
-static void SetDataMemoryValue (void *sourcePointer, unsigned char sourceType, UINT32 destinationAddr) ;
-static void SetProgramMemoryValue(void *sourcePointer, unsigned char sourceType, UINT32 destinationAddr) ;
-
-
-// Main opcode categories
-static unsigned ExecuteDataALUOpcode(int parallelType) ;
-static unsigned ExecuteDXMDROpcode(void) ;
-static unsigned ExecuteNPMOpcode(void) ;
-static unsigned ExecuteMisfitOpcode(void) ;
-static unsigned ExecuteSpecialOpcode(void) ;
-
-
-// Actual opcode implementations
-
-// Data ALU Ops
-static int ClrOperation(void **wd, UINT64 *pa) ;
-static int AddOperation(void **wd, UINT64 *pa) ;
-static int NotOperation(void **wd, UINT64 *pa) ;
-static int LsrOperation(void **wd, UINT64 *pa) ;
-static int AsrOperation(void **wd, UINT64 *pa) ;
-static int TfrDataALUOperation(void **wd, UINT64 *pa) ;
-static int EorOperation(void **wd, UINT64 *pa) ;
-static int CmpOperation(void **wd, UINT64 *pa) ;
-static int Dec24Operation(void **wd, UINT64 *pa) ;
-static int AndOperation(void **wd, UINT64 *pa) ;
-static int OrOperation(void **wd, UINT64 *pa) ;
-static int TstOperation(void **wd, UINT64 *pa) ;
-
-static int MoveCOperation(void) ;
-static int MoveMOperation(void) ;
-static int MoveIOperation(void) ;
-static int MovePOperation(void) ;
-
-static int AndiOperation(void) ;
-//static int OriOperation(void) ;
-
-static int BitfieldOperation(void) ;
-static int JmpOperation(void) ;
-static int BsrOperation(void) ;
-static int JsrOperation(void) ;
-static int DoOperation(void) ;
-static int TccOperation(void) ;
-static int BraOperation(void) ;
-static int BsccOperation(void) ;
-static int BccOperation(void) ;
-static int Tst2Operation(void) ;
-static int MACsuuuOperation(void) ;
-static int RepOperation(void) ;
-
-static void EndOfLoopProcessing(void) ;
-static void EndOfRepProcessing(void) ;
-
-// Parallel memory data moves
-static void XMDMOperation(UINT16 parameters, void *working, UINT64 *pa) ;
-static void XMDMSpecialOperation(UINT16 parameters, void *working) ;
-static void ARUOperation(UINT16 parameters) ;
-static void RRDMOperation(UINT16 parameters, void *working, UINT64 *pa) ;
-
-// For decoding the different types of tables...
-static void *DecodeDDDDDTable(UINT16 DDDDD, unsigned char *dt) ;
-static void *DecodeRRTable(UINT16 RR, unsigned char *dt) ;
-static void *DecodeDDTable(UINT16 DD, unsigned char *dt) ;
-static void *DecodeHHHTable(UINT16 HHH, unsigned char *dt) ;
-static void *DecodeHHTable(UINT16 HH, unsigned char *dt) ;
-static void *DecodeZTable(UINT16 Z, unsigned char *dt) ;
-static UINT16 DecodeBBBBitMask(UINT16 BBB, UINT16 *iVal) ;
-static int DecodeccccTable(UINT16 cccc) ;
-static void Decodeh0hFTable(UINT16 h0h, UINT16 F, void **source, unsigned char *st, void **dest, unsigned char *dt) ;
-static void *DecodeFTable(UINT16 F, unsigned char *dt) ;
-static void DecodeJJJFTable(UINT16 JJJ, UINT16 F, void **source, unsigned char *st, void **dest, unsigned char *dt) ;
-static void DecodeJJFTable(UINT16 JJ, UINT16 F, void **source, unsigned char *st, void **dest, unsigned char *dt) ;
-static void DecodeQQFTableSp(UINT16 QQ, UINT16 F, void **S1, void **S2, void **D) ;
-static void DecodeIIIITable(UINT16 IIII, void **source, unsigned char *st, void **dest, unsigned char *dt, void *working) ;
-
-static void ExecuteMMTable(int x, UINT16 MM) ;
-static void ExecutemTable(int x, UINT16 m) ;
-static void ExecutezTable(int x, UINT16 z) ;
-static UINT16 ExecuteqTable(int x, UINT16 q) ;
-
-static UINT16 AssembleDFromPTable(UINT16 P, UINT16 ppppp) ;
-
-static UINT16 AssembleAddressFromIOShortAddress(UINT16 pp) ;
-static UINT16 AssembleAddressFrom6BitSignedRelativeShortAddress(UINT16 srs) ;
-/***************************************************************************
- IMPLEMENTATION
-***************************************************************************/
+/*********************/
+/* Opcode prototypes */
+/*********************/
+static size_t dsp56k_op_add_2 (const UINT16 op_byte, UINT8* cycles);
+static size_t dsp56k_op_mac_1 (const UINT16 op_byte, UINT8* cycles);
+static size_t dsp56k_op_macr_1 (const UINT16 op_byte, UINT8* cycles);
+static size_t dsp56k_op_move_1 (const UINT16 op_byte, UINT8* cycles);
+static size_t dsp56k_op_mpy_1 (const UINT16 op_byte, UINT8* cycles);
+static size_t dsp56k_op_mpyr_1 (const UINT16 op_byte, UINT8* cycles);
+static size_t dsp56k_op_sub_1 (const UINT16 op_byte, UINT8* cycles);
+static size_t dsp56k_op_tfr_2 (const UINT16 op_byte, UINT8* cycles);
+static size_t dsp56k_op_mpy_2 (const UINT16 op_byte, UINT8* cycles);
+static size_t dsp56k_op_mac_2 (const UINT16 op_byte, UINT8* cycles);
+static size_t dsp56k_op_clr (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_add (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_move (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_tfr (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_rnd (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_tst (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_inc (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_inc24 (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_or (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_asr (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_asl (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_lsr (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_lsl (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_eor (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_subl (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_sub (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_clr24 (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_sbc (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_cmp (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_neg (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_not (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_dec (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_dec24 (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_and (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_abs (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_ror (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_rol (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_cmpm (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_mpy (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_mpyr (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_mac (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_macr (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles);
+static size_t dsp56k_op_adc (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_andi (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_asl4 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_asr4 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_asr16 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_bfop (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_bfop_1 (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_bfop_2 (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_bcc (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_bcc_1 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_bcc_2 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_bra (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_bra_1 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_bra_2 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_brkc (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_bscc (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_bscc_1 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_bsr (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_bsr_1 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_chkaau (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_debug (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_debugcc (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_div (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_dmac (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_do (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_do_1 (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_do_2 (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_doforever(const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_enddo (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_ext (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_illegal (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_imac (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_impy (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_jcc (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_jcc_1 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_jmp (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_jmp_1 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_jscc (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_jscc_1 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_jsr (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_jsr_1 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_jsr_2 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_lea (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_lea_1 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_macsuuu (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_move_2 (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_movec (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_movec_1 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_movec_2 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_movec_3 (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_movec_4 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_movec_5 (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_movei (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_movem (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_movem_1 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_movem_2 (const UINT16 op, const UINT16 op2, UINT8* cycles);
+static size_t dsp56k_op_movep (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_movep_1 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_moves (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_mpysuuu (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_negc (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_nop (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_norm (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_ori (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_rep (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_rep_1 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_rep_2 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_repcc (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_reset (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_rti (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_rts (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_stop (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_swap (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_swi (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_tcc (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_tfr2 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_tfr3 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_tst2 (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_wait (const UINT16 op, UINT8* cycles);
+static size_t dsp56k_op_zero (const UINT16 op, UINT8* cycles);
+
+
+static void execute_register_to_register_data_move(const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value);
+static void execute_x_memory_data_move (const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value);
+static void execute_x_memory_data_move2(const UINT16 op, typed_pointer* d_register);
+
+
+static UINT16 decode_BBB_bitmask(UINT16 BBB, UINT16 *iVal);
+static int decode_cccc_table(UINT16 cccc);
+static void decode_DDDDD_table(UINT16 DDDDD, typed_pointer* ret);
+static void decode_DD_table(UINT16 DD, typed_pointer* ret);
+static void decode_F_table(UINT16 F, typed_pointer* ret);
+static void decode_h0hF_table(UINT16 h0h, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret);
+static void decode_HH_table(UINT16 HH, typed_pointer* ret);
+static void decode_HHH_table(UINT16 HHH, typed_pointer* ret);
+static void decode_IIII_table(UINT16 IIII, typed_pointer* src_ret, typed_pointer* dst_ret, void *working);
+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_RR_table(UINT16 RR, typed_pointer* ret);
#ifdef UNUSED_FUNCTION
-static void unimplemented(void)
-{
- fatalerror("Unimplemented OP @ %04X: %04X", PC-2, OP) ;
-}
+static void decode_Z_table(UINT16 Z, typed_pointer* ret);
+#endif
+static void execute_m_table(int x, UINT16 m);
+static void execute_MM_table(UINT16 rnum, UINT16 MM);
+#ifdef UNUSED_FUNCTION
+static UINT16 execute_q_table(int x, UINT16 q);
+static void execute_z_table(int x, UINT16 z);
+static UINT16 assemble_D_from_P_table(UINT16 P, UINT16 ppppp);
+#endif
+static UINT16 assemble_address_from_IO_short_address(UINT16 pp);
+#ifdef UNUSED_FUNCTION
+static UINT16 assemble_address_from_6bit_signed_relative_short_address(UINT16 srs);
#endif
+static void dsp56k_process_loop(void);
+static void dsp56k_process_rep(size_t repSize);
+
+
+
+/********************/
+/* Helper Functions */
+/********************/
+static UINT16 Dsp56kOpMask(UINT16 op, UINT16 mask);
+
+/* These arguments are written source->destination to fall in line with the processor's paradigm. */
+static void SetDestinationValue(typed_pointer source, typed_pointer dest);
+
+static void SetDataMemoryValue(typed_pointer source, UINT32 destinationAddr);
+static void SetProgramMemoryValue(typed_pointer source, UINT32 destinationAddr);
+
+
+
+/***************************************************************************
+ IMPLEMENTATION
+***************************************************************************/
static void execute_one(void)
{
- unsigned size = 666 ;
+ UINT16 op;
+ UINT16 op2;
+ size_t size = 0x1337;
+ UINT8 cycle_count = 0;
+ /* For MAME */
debugger_instruction_hook(Machine, PC);
- OP = ROPCODE(PC<<1);
+ OP = ROPCODE(WORD(PC));
- if (BITS(OP,0x8000)) // First, the parallel data move instructions
- {
- size = ExecuteDataALUOpcode(PARALLEL_TYPE_XMDM) ;
- }
- else if (BITS(OP,0xf000) == 0x5)
- {
- size = ExecuteDataALUOpcode(PARALLEL_TYPE_XMDM_SPECIAL) ;
- }
- else if (BITS(OP,0xff00) == 0x4a)
- {
- size = ExecuteDataALUOpcode(PARALLEL_TYPE_NODM) ;
- }
- else if (BITS(OP,0xf000) == 0x04)
- {
- size = ExecuteDataALUOpcode(PARALLEL_TYPE_RRDM) ;
- }
- else if (BITS(OP,0xf800) == 0x06)
- {
- size = ExecuteDataALUOpcode(PARALLEL_TYPE_ARU) ;
- }
+ /* The words we're going to be working with */
+ op = ROPCODE(WORD(PC));
+ op2 = ROPCODE(WORD(PC) + WORD(1));
- else if (BITS(OP,0x4000))
- {
- size = ExecuteDXMDROpcode() ;
- }
- else if (BITS(OP,0xf000) == 0x1)
+ /* DECODE */
+ /* Dual X Memory Data Read : 011m mKKK -rr- ---- : A-142*/
+ if ((op & 0xe000) == 0x6000)
{
- size = ExecuteNPMOpcode() ;
- }
- else if (BITS(OP,0x2000))
- {
- size = ExecuteMisfitOpcode() ;
+ /* Quote: (MOVE, MAC(R), MPY(R), ADD, SUB, TFR) */
+ UINT16 op_byte = op & 0x00ff;
+
+ /* ADD : 011m mKKK 0rru Fuuu : A-22 */
+ if ((op & 0xe080) == 0x6000)
+ {
+ size = dsp56k_op_add_2(op_byte, &cycle_count);
+ }
+ /* MAC : 011m mKKK 1xx0 F1QQ : A-122 */
+ else if ((op & 0xe094) == 0x6084)
+ {
+ size = dsp56k_op_mac_1(op_byte, &cycle_count);
+ }
+ /* MACR: 011m mKKK 1--1 F1QQ : A-124 */
+ else if ((op & 0xe094) == 0x6094)
+ {
+ size = dsp56k_op_macr_1(op_byte, &cycle_count);
+ }
+ /* MOVE : 011m mKKK 0rr1 0000 : A-128 */
+ else if ((op & 0xe09f) == 0x6010)
+ {
+ size = dsp56k_op_move_1(op_byte, &cycle_count);
+ }
+ /* MPY : 011m mKKK 1xx0 F0QQ : A-160 */
+ else if ((op & 0xe094) == 0x6080)
+ {
+ size = dsp56k_op_mpy_1(op_byte, &cycle_count);
+ }
+ /* MPYR : 011m mKKK 1--1 F0QQ : A-162 */
+ else if ((op & 0xe094) == 0x6090)
+ {
+ size = dsp56k_op_mpyr_1(op_byte, &cycle_count);
+ }
+ /* SUB : 011m mKKK 0rru Fuuu : A-202 */
+ else if ((op & 0xe080) == 0x6000)
+ {
+ size = dsp56k_op_sub_1(op_byte, &cycle_count);
+ }
+ /* TFR : 011m mKKK 0rr1 F0DD : A-212 */
+ else if ((op & 0xe094) == 0x6010)
+ {
+ size = dsp56k_op_tfr_2(op_byte, &cycle_count);
+ }
+
+ /* Now evaluate the parallel data move */
+ // TODO // decode_dual_x_memory_data_read(op, parallel_move_str, parallel_move_str2);
}
- else if (BITS(OP,0xf000) == 0x0)
+ /* X Memory Data Write and Register Data Move : 0001 011k RRDD ---- : A-140 */
+ else if ((op & 0xfe00) == 0x1600)
{
- size = ExecuteSpecialOpcode();
- }
+ /* Quote: (MPY or MAC) */
+ UINT16 op_byte = op & 0x00ff;
- if (size == 666)
- {
- mame_printf_debug("unimplemented at %04x\n", PC) ;
- size = 1 ; // Just to get the debugger past the bad opcode
+ /* MPY : 0001 0110 RRDD FQQQ : A-160 */
+ if ((op & 0xff00) == 0x1600)
+ {
+ size = dsp56k_op_mpy_2(op_byte, &cycle_count);
+ }
+ /* MAC : 0001 0111 RRDD FQQQ : A-122 */
+ else if ((op & 0xff00) == 0x1700)
+ {
+ size = dsp56k_op_mac_2(op_byte, &cycle_count);
+ }
+
+ /* Now evaluate the parallel data move */
+ // TODO // decode_x_memory_data_write_and_register_data_move(op, parallel_move_str, parallel_move_str2);
}
+ /* Handle Other parallel types */
+ else
+ {
+ /***************************************/
+ /* 32 General parallel move operations */
+ /***************************************/
+
+ enum pType { kNoParallelDataMove,
+ kRegisterToRegister,
+ kAddressRegister,
+ kXMemoryDataMove,
+ kXMemoryDataMove2,
+ kXMemoryDataMoveWithDisp };
+
+ int parallelType = -1;
+ UINT16 op_byte = 0x0000;
+ typed_pointer d_register = {NULL, DT_BYTE};
+ UINT64 prev_accum_value = U64(0x0000000000000000);
+
+ /* Note: it's important that NPDM comes before RtRDM here */
+ /* No Parallel Data Move : 0100 1010 ---- ---- : A-131 */
+ if ((op & 0xff00) == 0x4a00)
+ {
+ op_byte = op & 0x00ff;
+ parallelType = kNoParallelDataMove;
+ }
+ /* Register to Register Data Move : 0100 IIII ---- ---- : A-133 */
+ else if ((op & 0xf000) == 0x4000)
+ {
+ op_byte = op & 0x00ff;
+ parallelType = kRegisterToRegister;
+ }
+ /* Address Register Update : 0011 0zRR ---- ---- : A-135 */
+ else if ((op & 0xf800) == 0x3000)
+ {
+ op_byte = op & 0x00ff;
+ parallelType = kAddressRegister;
+ }
+ /* X Memory Data Move : 1mRR HHHW ---- ---- : A-137 */
+ else if ((op & 0x8000) == 0x8000)
+ {
+ op_byte = op & 0x00ff;
+ parallelType = kXMemoryDataMove;
+ }
+ /* X Memory Data Move : 0101 HHHW ---- ---- : A-137 */
+ else if ((op & 0xf000) == 0x5000)
+ {
+ op_byte = op & 0x00ff;
+ parallelType = kXMemoryDataMove2;
+ }
+ /* X Memory Data Move with short displacement : 0000 0101 BBBB BBBB ---- HHHW ---- ---- : A-139 */
+ else if ((op & 0xff00) == 0x0500)
+ {
+ /* See notes at top of file! */
+ /* op_byte = op2 & 0x00ff; */
+ /* parallelType = kXMemoryDataMoveWithDisp; */
+ /* DO NOTHING FOR NOW */
+ }
- PC += size ;
- change_pc(PC) ;
- // Loop processing
- if (LF_bit())
- {
- if (PC == LA)
+ if (parallelType != -1)
{
- // You're on the last instruction of the loop...
- if (LC != 1) // Strange, the == 1 thing...
+ /* Note: There is much overlap between opcodes down here */
+ /* To this end, certain ops must come before others in the list */
+
+ /* CLR : .... .... 0000 F001 : A-60 */
+ if ((op_byte & 0x00f7) == 0x0001)
{
- LC-- ;
- PC = SSH ;
- change_pc(PC) ;
+ size = dsp56k_op_clr(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else
+ /* ADD : .... .... 0000 FJJJ : A-22 */
+ else if ((op_byte & 0x00f0) == 0x0000)
{
- EndOfLoopProcessing() ;
+ size = dsp56k_op_add(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- }
- }
- // Rep processing
- if (core.repFlag)
- {
- if (PC == core.repAddr)
- {
- if (LC != 1)
+
+ /* MOVE : .... .... 0001 0001 : A-128 */
+ else if ((op_byte & 0x00ff) == 0x0011)
{
- LC-- ;
- PC -= size ; // Eh, seems reasonable :)
- change_pc(PC) ;
+ size = dsp56k_op_move(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else
+ /* TFR : .... .... 0001 FJJJ : A-212 */
+ else if ((op_byte & 0x00f0) == 0x0010)
{
- EndOfRepProcessing() ;
+ size = dsp56k_op_tfr(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- }
- }
-
- dsp56k_icount -= 4; /* Temporarily hard-coded at 4 clocks per opcode */
-}
-static unsigned ExecuteDataALUOpcode(int parallelType)
-{
- unsigned retSize = 666 ;
-
- void *workingDest = 0x00 ;
-
- // Whenever an instruction uses an accumulator as both a destination operand for a Data ALU operation and
- // as a source for a parallel move operation, the parallel move operation will use the value in the accumulator
- // prior to execution of any Data ALU operation.
- UINT64 previousAccum = 0 ;
-
- switch(BITS(OP,0x0070))
- {
-
- case 0x0:
- if (BITS(OP,0x0007) == 0x1)
+ /* RND : .... .... 0010 F000 : A-188 */
+ else if ((op_byte & 0x00f7) == 0x0020)
{
- // CLR - 1mRR HHHW 0000 F001
- retSize = ClrOperation(&workingDest, &previousAccum) ;
+ size = dsp56k_op_rnd(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else
+ /* TST : .... .... 0010 F001 : A-218 */
+ else if ((op_byte & 0x00f7) == 0x0021)
{
- // ADD - 1mRR HHHW 0000 FJJJ
- retSize = AddOperation(&workingDest, &previousAccum) ;
+ size = dsp56k_op_tst(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- break ;
-
- case 0x1:
- if (BITS(OP,0x000f) == 0x1)
+ /* INC : .... .... 0010 F010 : A-104 */
+ else if ((op_byte & 0x00f7) == 0x0022)
{
- // MOVE - 1mRR HHHW 0001 0001
- retSize = 1 ;
+ size = dsp56k_op_inc(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else
+ /* INC24 : .... .... 0010 F011 : A-106 */
+ else if ((op_byte & 0x00f7) == 0x0023)
+ {
+ size = dsp56k_op_inc24(op_byte, &d_register, &prev_accum_value, &cycle_count);
+ }
+ /* OR : .... .... 0010 F1JJ : A-176 */
+ else if ((op_byte & 0x00f4) == 0x0024)
{
- // TFR - 1mRR HHHW 0001 FJJJ
- retSize = TfrDataALUOperation(&workingDest, &previousAccum) ;
+ size = dsp56k_op_or(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- break ;
- case 0x2:
- if (BITS(OP,0x0007) == 0x0)
+
+ /* ASR : .... .... 0011 F000 : A-32 */
+ else if ((op_byte & 0x00f7) == 0x0030)
{
- // RND - 1mRR HHHW 0010 F000
+ size = dsp56k_op_asr(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else if (BITS(OP,0x0007) == 0x1)
+ /* ASL : .... .... 0011 F001 : A-28 */
+ else if ((op_byte & 0x00f7) == 0x0031)
{
- // TST - 1mRR HHHW 0010 F001
- retSize = TstOperation(&workingDest, &previousAccum);
+ size = dsp56k_op_asl(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else if (BITS(OP,0x0007) == 0x2)
+ /* LSR : .... .... 0011 F010 : A-120 */
+ else if ((op_byte & 0x00f7) == 0x0032)
{
- // INC - 1mRR HHHW 0010 F010
+ size = dsp56k_op_lsr(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else if (BITS(OP,0x0007) == 0x3)
+ /* LSL : .... .... 0011 F011 : A-118 */
+ else if ((op_byte & 0x00f7) == 0x0033)
{
- // INC24 - 1mRR HHHW 0010 F011
+ size = dsp56k_op_lsl(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else
+ /* EOR : .... .... 0011 F1JJ : A-94 */
+ else if ((op_byte & 0x00f4) == 0x0034)
{
- // OR - 1mRR HHHW 0010 F1JJ
- retSize = OrOperation(&workingDest, &previousAccum) ;
+ size = dsp56k_op_eor(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- break ;
- case 0x3:
- if (BITS(OP,0x0007) == 0x0)
+
+ /* SUBL : .... .... 0100 F001 : A-204 */
+ else if ((op_byte & 0x00f7) == 0x0041)
{
- // ASR - 1mRR HHHW 0011 F000
- retSize = AsrOperation(&workingDest, &previousAccum) ;
+ size = dsp56k_op_subl(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else if (BITS(OP,0x0007) == 0x1)
+ /* SUB : .... .... 0100 FJJJ : A-202 */
+ else if ((op_byte & 0x00f0) == 0x0040)
{
- // ASL - 1mRR HHHW 0011 F001
+ size = dsp56k_op_sub(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else if (BITS(OP,0x0007) == 0x2)
+
+
+ /* CLR24 : .... .... 0101 F001 : A-62 */
+ else if ((op_byte & 0x00f7) == 0x0051)
{
- // LSR - 1mRR HHHW 0011 F010
- retSize = LsrOperation(&workingDest, &previousAccum) ;
+ size = dsp56k_op_clr24(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else if (BITS(OP,0x0007) == 0x3)
+ /* SBC : .... .... 0101 F01J : A-198 */
+ else if ((op_byte & 0x00f6) == 0x0052)
{
- // LSL - 1mRR HHHW 0011 F011
+ size = dsp56k_op_sbc(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else
+ /* CMP : .... .... 0101 FJJJ : A-64 */
+ else if ((op_byte & 0x00f0) == 0x0050)
{
- // EOR - 1mRR HHHW 0011 F1JJ
- retSize = EorOperation(&workingDest, &previousAccum) ;
+ size = dsp56k_op_cmp(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- break ;
-/*
- case 0x4:
- if (BITS(op,0x0007) == 0x1)
- {
- // SUBL - 1mRR HHHW 0100 F001
- }
- else
- {
- // SUB - 1mRR HHHW 0100 FJJJ
- }
- break ;
-*/
- case 0x5:
- if (BITS(OP,0x0007) == 0x1)
+
+
+ /* NEG : .... .... 0110 F000 : A-166 */
+ else if ((op_byte & 0x00f7) == 0x0060)
{
- // CLR24 - 1mRR HHHW 0101 F001
+ size = dsp56k_op_neg(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else if (BITS(OP,0x0006) == 0x1)
+ /* NOT : .... .... 0110 F001 : A-174 */
+ else if ((op_byte & 0x00f7) == 0x0061)
{
- // SBC - 1mRR HHHW 0101 F01J
+ size = dsp56k_op_not(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else
+ /* DEC : .... .... 0110 F010 : A-72 */
+ else if ((op_byte & 0x00f7) == 0x0062)
{
- // CMP - 1mRR HHHW 0101 FJJJ
- retSize = CmpOperation(&workingDest, &previousAccum) ;
+ size = dsp56k_op_dec(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- break ;
-
- case 0x6:
- if (BITS(OP,0x0007) == 0x0)
+ /* DEC24 : .... .... 0110 F011 : A-74 */
+ else if ((op_byte & 0x00f7) == 0x0063)
{
- // NEG - 1mRR HHHW 0110 F000
+ size = dsp56k_op_dec24(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else if (BITS(OP,0x0007) == 0x1)
+ /* AND : .... .... 0110 F1JJ : A-24 */
+ else if ((op_byte & 0x00f4) == 0x0064)
{
- // NOT - 1mRR HHHW 0110 F001
- retSize = NotOperation(&workingDest, &previousAccum) ;
+ size = dsp56k_op_and(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else if (BITS(OP,0x0007) == 0x2)
+
+
+ /* ABS : .... .... 0111 F001 : A-18 */
+ if ((op_byte & 0x00f7) == 0x0071)
{
- // DEC - 1mRR HHHW 0110 F010
+ size = dsp56k_op_abs(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else if (BITS(OP,0x0007) == 0x3)
+ /* ROR : .... .... 0111 F010 : A-192 */
+ else if ((op_byte & 0x00f7) == 0x0072)
{
- // DEC24 - 1mRR HHHW 0110 F011
- retSize = Dec24Operation(&workingDest, &previousAccum) ;
+ size = dsp56k_op_ror(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- else
+ /* ROL : .... .... 0111 F011 : A-190 */
+ else if ((op_byte & 0x00f7) == 0x0073)
{
- // AND - 1mRR HHHW 0110 F1JJ
- retSize = AndOperation(&workingDest, &previousAccum) ;
+ size = dsp56k_op_rol(op_byte, &d_register, &prev_accum_value, &cycle_count);
+ }
+ /* CMPM : .... .... 0111 FJJJ : A-66 */
+ else if ((op_byte & 0x00f0) == 0x0070)
+ {
+ size = dsp56k_op_cmpm(op_byte, &d_register, &prev_accum_value, &cycle_count);
}
- break ;
-/*
- case 0x7:
- if (BITS(op,0x0007) == 0x1)
- {
- // ABS - 1mRR HHHW 0111 F001
- }
- if (BITS(op,0x0007) == 0x2)
- {
- // ROR - 1mRR HHHW 0111 F010
- }
- if (BITS(op,0x0007) == 0x3)
- {
- // ROL - 1mRR HHHW 0111 F011
- }
- else
- {
- // CMPM - 1mRR HHHW 0111 FJJJ
- }
-
- break ;
-*/
- }
-
-/*
- // Otherwise you're looking at a MPY/MAC operation...
- if (BITS(op,0x0080)) // Maybe i should un-consolidate here?
- {
- DecodeQQQFTable(BITS(op,0x0007), BITS(op,0x0008), S1, S2, D) ;
- DecodekSignTable(BITS(op,0x0040), sign) ;
-
- switch(BITS(op,0x00b0))
- {
- // MPY - 1mRR HHHH 1k00 FQQQ
- case 0x4: sprintf(buffer, "mpy (%s)%s,%s,%s", sign, S2, S1, D) ; break ;
- // MPYR - 1mRR HHHH 1k01 FQQQ
- case 0x5: sprintf(buffer, "mpyr (%s)%s,%s,%s", sign, S2, S1, D) ; break ;
- // MAC - 1mRR HHHH 1k10 FQQQ
- case 0x6: sprintf(buffer, "mac (%s)%s,%s,%s", sign, S2, S1, D) ; break ;
+ /* MPY : .... .... 1k00 FQQQ : A-160 -- CONFIRMED TYPO IN DOCS (HHHH vs HHHW) */
+ else if ((op_byte & 0x00b0) == 0x0080)
+ {
+ size = dsp56k_op_mpy(op_byte, &d_register, &prev_accum_value, &cycle_count);
+ }
+ /* MPYR : .... .... 1k01 FQQQ : A-162 */
+ else if ((op_byte & 0x00b0) == 0x0090)
+ {
+ size = dsp56k_op_mpyr(op_byte, &d_register, &prev_accum_value, &cycle_count);
+ }
+ /* MAC : .... .... 1k10 FQQQ : A-122 */
+ else if ((op_byte & 0x00b0) == 0x00a0)
+ {
+ size = dsp56k_op_mac(op_byte, &d_register, &prev_accum_value, &cycle_count);
+ }
+ /* MACR : .... .... 1k11 FQQQ : A-124 -- DRAMA - rr vs xx (805) */
+ else if ((op_byte & 0x00b0) == 0x00b0)
+ {
+ size = dsp56k_op_macr(op_byte, &d_register, &prev_accum_value, &cycle_count);
+ }
- // MACR - 1mRR HHHH 1k11 FQQQ
- case 0x7: sprintf(buffer, "macr (%s)%s,%s,%s", sign, S1, S2, D) ; break ;
- // !! It's a little odd that macr is S1,S2 while everyone else is S2,S1 !!
- }
- retSize = 1 ;
- }
-*/
+ /* Now evaluate the parallel data move */
+ switch (parallelType)
+ {
+ case kNoParallelDataMove:
+ /* DO NOTHING */
+ break;
+ case kRegisterToRegister:
+ execute_register_to_register_data_move(op, &d_register, &prev_accum_value);
+ break;
+ case kAddressRegister:
+ // TODO // decode_address_register_update(op, parallel_move_str);
+ break;
+ case kXMemoryDataMove:
+ execute_x_memory_data_move(op, &d_register, &prev_accum_value);
+ break;
+ case kXMemoryDataMove2:
+ execute_x_memory_data_move2(op, &d_register);
+ break;
+ case kXMemoryDataMoveWithDisp:
+ // TODO // decode_x_memory_data_move_with_short_displacement(op, op2, parallel_move_str);
+ break;
+ }
+ }
+ }
- // Do the parallel move parallel'y :)
- // Someday we may have to check against the special cases to throw exceptions !!
- switch (parallelType)
+ /* Drop out if you've already completed your work. */
+ if (size != 0x1337)
{
- case PARALLEL_TYPE_XMDM:
- XMDMOperation(BITS(OP,0xff00), workingDest, &previousAccum) ;
- break ;
-
- case PARALLEL_TYPE_RRDM:
- RRDMOperation(BITS(OP,0xff00), workingDest, &previousAccum) ;
- break ;
-
- case PARALLEL_TYPE_XMDM_SPECIAL:
- // pa is not needed because the XMDM dest is always the .opposite. of the regular dest.
- XMDMSpecialOperation(BITS(OP,0xff00), workingDest) ;
- break ;
+ PC += size;
+ change_pc(PC);
- case PARALLEL_TYPE_NODM:
- // do nothing
- break ;
+ dsp56k_process_loop();
+ dsp56k_process_rep(size);
- case PARALLEL_TYPE_ARU:
- ARUOperation(BITS(OP,0xff00)) ;
- break ;
+ dsp56k_icount -= 4; /* Temporarily hard-coded at 4 clocks per opcode */ /* cycle_count */
+ return;
}
- return retSize ;
-}
-
-static unsigned ExecuteDXMDROpcode(void)
-{
- unsigned retSize = 666 ;
-
- return retSize ;
-}
-static unsigned ExecuteNPMOpcode(void)
-{
- unsigned retSize = 666 ;
+ /******************************/
+ /* Remaining non-parallel ops */
+ /******************************/
- if (BITS(OP,0x0f00) == 0x4)
+ /* ADC : 0001 0101 0000 F01J : A-20 */
+ if ((op & 0xfff6) == 0x1502)
{
- retSize = BitfieldOperation() ;
+ size = dsp56k_op_adc(op, &cycle_count);
}
- else if (BITS(OP,0x0f00) == 0x5)
+ /* ANDI : 0001 1EE0 iiii iiii : A-26 */
+ /* (MoveP sneaks in here if you don't check 0x0600) */
+ else if (((op & 0xf900) == 0x1800) & ((op & 0x0600) != 0x0000))
{
- switch(BITS(OP,0x0074))
- {
- case 0x0:
- if (BITS(OP,0x0006) == 0x0)
- {
- // TFR(2) - 0001 0101 0000 F00J
- retSize = 1 ;
- }
- else if (BITS(OP,0x0006) == 0x1)
- {
- // ADC - 0001 0101 0000 F01J
- retSize = 1 ;
- }
- break ;
-
- case 0x3:
- // TST(2) - 0001 0101 0001 -1DD
- retSize = Tst2Operation() ; break ;
-
- case 0x4:
- // NORM - 0001 0101 0010 F0RR
- retSize = 1 ; break ;
-
- case 0x6:
- if (BITS(OP,0x0003) == 0x0)
- {
- // ASR4 - 0001 0101 0011 F000
- retSize = 1 ;
- }
- else if (BITS(OP,0x0003) == 0x1)
- {
- // ASL4 - 0001 0101 0011 F001
- retSize = 1 ;
- }
- break ;
-
- case 0x1: case 0x5: case 0x9: case 0xd:
- // DIV - 0001 0101 0--0 F1DD
- retSize = 1 ; break ;
-
- case 0xa:
- if (BITS(OP,0x0003) == 0x0)
- {
- // ZERO - 0001 0101 0101 F000
- retSize = 1 ;
- }
- else if (BITS(OP,0x0003) == 0x2)
- {
- // EXT - 0001 0101 0101 F010
- retSize = 1 ;
- }
- break ;
-
- case 0xc:
- if (BITS(OP,0x0003) == 0x0)
- {
- // NEGC - 0001 0101 0110 F000
- retSize = 1 ;
- }
- break ;
-
- case 0xe:
- if (BITS(OP,0x0003) == 0x0)
- {
- // ASR16 - 0001 0101 0111 F000
- retSize = 1 ;
- }
- else if (BITS(OP,0x0003) == 0x1)
- {
- // SWAP - 0001 0101 0111 F001
- retSize = 1 ;
- }
- break ;
- }
-
- switch(BITS(OP,0x00f0))
- {
- case 0x8:
- // IMPY - 0001 0101 1000 FQQQ
- retSize = 1 ; break ;
- case 0xa:
- // IMAC - 0001 0101 1010 FQQQ
- retSize = 1 ; break ;
- case 0x9: case 0xb:
- // DMAC(ss,su,uu) - 0001 0101 10s1 FsQQ
- retSize = 1 ; break ;
- case 0xc:
- // MPY(su,uu) - 0001 0101 1100 FsQQ
- retSize = 1 ; break ;
- case 0xe:
- // MAC(su,uu) - 0001 0101 1110 FsQQ
- retSize = MACsuuuOperation() ; break ;
- }
+ size = dsp56k_op_andi(op, &cycle_count);
}
- else if ((BITS(OP,0x0f00) == 0x6))
+ /* ASL4 : 0001 0101 0011 F001 : A-30 */
+ else if ((op & 0xfff7) == 0x1531)
{
- retSize = 1 ;
+ size = dsp56k_op_asl4(op, &cycle_count);
}
- else if ((BITS(OP,0x0f00) == 0x7))
+ /* ASR4 : 0001 0101 0011 F000 : A-34 */
+ else if ((op & 0xfff7) == 0x1530)
{
- retSize = 1 ;
+ size = dsp56k_op_asr4(op, &cycle_count);
}
- else if ((BITS(OP,0x0800) == 0x1))
+ /* ASR16 : 0001 0101 0111 F000 : A-36 */
+ else if ((op & 0xfff7) == 0x1570)
{
- if (BITS(OP,0x0600))
- {
- if (!BITS(OP,0x0100))
- {
- // ANDI - 0001 1EE0 iiii iiii
- retSize = AndiOperation() ;
- }
- else
- {
- // ORI - 0001 1EE1 iiii iiii
- }
- }
- else
- {
- if (!BITS(OP,0x0020))
- {
- // MOVE(S) - 0001 100W HH0a aaaa
- }
- else
- {
- // MOVE(P) - 0001 100W HH1p pppp
- retSize = MovePOperation() ;
- }
- }
+ size = dsp56k_op_asr16(op, &cycle_count);
}
- else if ((BITS(OP,0x0c00) == 0x0))
+ /* BFCHG : 0001 0100 11Pp pppp BBB1 0010 iiii iiii : A-38 */
+ else if (((op & 0xffc0) == 0x14c0) && ((op2 & 0x1f00) == 0x1200))
{
- retSize = TccOperation() ;
+ size = dsp56k_op_bfop(op, op2, &cycle_count);
}
-
- return retSize ;
-}
-
-static unsigned ExecuteMisfitOpcode(void)
-{
- unsigned retSize = 666 ;
-
- if (BITS(OP,0x1000)== 0x0)
+ /* BFCHG : 0001 0100 101- --RR BBB1 0010 iiii iiii : A-38 */
+ else if (((op & 0xffe0) == 0x14a0) && ((op2 & 0x1f00) == 0x1200))
{
- switch(BITS(OP,0x0c00))
- {
- // MOVE(I) - 0010 00DD BBBB BBBB
- case 0x0:
- retSize = MoveIOperation() ;
- break ;
-
-/*
- case 0x1:
- // TFR(3) - 0010 01mW RRDD FHHH
- break ;
-*/
- case 0x2:
- // MOVE(C) - 0010 10dd dddD DDDD
- retSize = MoveCOperation() ;
- break ;
-
- case 0x3:
- // B.cc - 0010 11cc ccee eeee
- retSize = BccOperation() ;
- break ;
- }
+ size = dsp56k_op_bfop_1(op, op2, &cycle_count);
}
- else
+ /* BFCHG : 0001 0100 100D DDDD BBB1 0010 iiii iiii : A-38 */
+ else if (((op & 0xffe0) == 0x1480) && ((op2 & 0x1f00) == 0x1200))
{
- // MOVE(C) - 0011 1WDD DDD0 MMRR
- // MOVE(C) - 0011 1WDD DDD1 q0RR
- // MOVE(C) - 0011 1WDD DDD1 t10- xxxx xxxx xxxx xxxx
- // MOVE(C) - 0011 1WDD DDD1 Z11-
- retSize = MoveCOperation() ;
+ size = dsp56k_op_bfop_2(op, op2, &cycle_count);
}
-
- return retSize ;
-}
-
-static unsigned ExecuteSpecialOpcode(void)
-{
- unsigned retSize = 666 ;
-
- if (BITS(OP,0x0ff0) == 0x0)
+ /* BFCLR : 0001 0100 11Pp pppp BBB0 0100 iiii iiii : A-40 */
+ else if (((op & 0xffc0) == 0x14c0) && ((op2 & 0x1f00) == 0x0400))
{
- switch (BITS(OP,0x000f))
- {
- // NOP - 0000 0000 0000 0000
- case 0x0:
- retSize = 1 ;
- break ;
-
- // DO FOREVER - 0000 0000 0000 0010 xxxx xxxx xxxx xxxx
- case 0x2:
- // !!! IMPLEMENT ME NEXT;
- retSize = 0;
- break;
-
- // RTS - 0000 0000 0000 0110
- case 0x6:
- PC = SSH ;
- SR = SSL ;
- SP-- ;
- retSize = 0 ;
- change_pc(PC) ;
- break ;
-
- // RTI - 0000 0000 0000 0111
- case 0x7:
- PC = SSH;
- SR = SSL;
- SP--;
- retSize = 0;
- change_pc(PC);
- break;
- }
+ size = dsp56k_op_bfop(op, op2, &cycle_count);
}
- else if (BITS(OP,0x0f00) == 0x0)
+ /* BFCLR : 0001 0100 101- --RR BBB0 0100 iiii iiii : A-40 */
+ else if (((op & 0xffe0) == 0x14a0) && ((op2 & 0x1f00) == 0x0400))
{
- retSize = 1 ;
+ size = dsp56k_op_bfop_1(op, op2, &cycle_count);
}
- else if (BITS(OP,0x0f00) == 0x1)
+ /* BFCLR : 0001 0100 100D DDDD BBB0 0100 iiii iiii : A-40 */
+ else if (((op & 0xffe0) == 0x1480) && ((op2 & 0x1f00) == 0x0400))
{
- if (BITS(OP,0x00f0) == 0x1)
- {
- retSize = 1 ;
- }
- else if (BITS(OP,0x00f0) == 0x2)
- {
- switch(BITS(OP,0x000c)) // Consolidation can happen here
- {
- // JSR - 0000 0001 0010 00RR
- // JMP - 0000 0001 0010 01RR
- case 0x1: retSize = JmpOperation(); break;
- // BSR - 0000 0001 0010 10RR
- // BRA - 0000 0001 0010 11RR
- default: retSize = 1;
- }
- }
- else if (BITS(OP,0x00f0) == 0x3)
- {
- switch(BITS(OP,0x000c))
- {
- // JSR - 0000 0001 0011 00-- xxxx xxxx xxxx xxxx
- case 0x0: retSize = JsrOperation() ; break ;
- // JMP - 0000 0001 0011 01-- xxxx xxxx xxxx xxxx
- case 0x1: retSize = JmpOperation() ; break ;
- // BSR - 0000 0001 0011 10-- xxxx xxxx xxxx xxxx
- case 0x2: retSize = BsrOperation() ; break ;
- }
- }
- else if (BITS(OP,0x00f0) == 0x5)
- {
- retSize = 1 ;
- }
- else if (BITS(OP,0x0080) == 0x1)
- {
- retSize = 1 ;
- }
+ size = dsp56k_op_bfop_2(op, op2, &cycle_count);
}
- else if (BITS(OP,0x0e00) == 0x1)
+ /* BFSET : 0001 0100 11Pp pppp BBB1 1000 iiii iiii : A-42 */
+ else if (((op & 0xffc0) == 0x14c0) && ((op2 & 0x1f00) == 0x1800))
{
- if (BITS(OP,0x0020) == 0x0)
- {
- // MOVE(M) - 0000 001W RR0M MHHH
- retSize = MoveMOperation() ;
- }
+ size = dsp56k_op_bfop(op, op2, &cycle_count);
}
- else if (BITS(OP,0x0f00) == 0x4)
+ /* BFSET : 0001 0100 101- --RR BBB1 1000 iiii iiii : A-42 */
+ else if (((op & 0xffe0) == 0x14a0) && ((op2 & 0x1f00) == 0x1800))
{
- if (BITS(OP,0x0020) == 0x0)
- {
- // DO - 0000 0100 000D DDDD xxxx xxxx xxxx xxxx
- retSize = DoOperation() ;
- }
- else
- {
- // REP - 0000 0100 001D DDDD
- retSize = RepOperation() ;
- }
+ size = dsp56k_op_bfop_1(op, op2, &cycle_count);
}
- else if (BITS(OP,0x0f00) == 0x5)
+ /* BFSET : 0001 0100 100D DDDD BBB1 1000 iiii iiii : A-42 */
+ else if (((op & 0xffe0) == 0x1480) && ((op2 & 0x1f00) == 0x1800))
{
- UINT16 op2 = ROPCODE((PC<<1)+2) ;
-
- if (BITS(op2,0xfe20) == 0x02)
- {
- // MOVE(M) - 0000 0101 BBBB BBBB | 0000 001W --0- -HHH
- retSize = MoveMOperation() ;
- }
- else if (BITS(op2,0xf810) == 0x0e)
- {
- // MOVE(C) - 0000 0101 BBBB BBBB | 0011 1WDD DDD0 ----
- }
- else if (BITS(op2,0x00ff) == 0x11)
- {
- // MOVE - 0000 0101 BBBB BBBB | ---- HHHW 0001 0001
- }
+ size = dsp56k_op_bfop_2(op, op2, &cycle_count);
}
- else if (BITS(OP,0x0f00) == 0x6)
+ /* BFTSTH : 0001 0100 01Pp pppp BBB1 0000 iiii iiii : A-44 */
+ else if (((op & 0xffc0) == 0x1440) && ((op2 & 0x1f00) == 0x1000))
{
- retSize = 1 ;
+ size = dsp56k_op_bfop(op, op2, &cycle_count);
}
- else if (BITS(OP,0x0f00) == 0x7)
+ /* BFTSTH : 0001 0100 001- --RR BBB1 0000 iiii iiii : A-44 */
+ else if (((op & 0xffe0) == 0x1420) && ((op2 & 0x1f00) == 0x1000))
{
- switch(BITS(OP,0x0030))
- {
- // BS.cc - 0000 0111 RR00 cccc
- case 0x0: retSize = 1 ; break ;
-
- // BS.cc - 0000 0111 --01 cccc xxxx xxxx xxxx xxxx
- case 0x1: retSize = BsccOperation() ; break ;
-
- // B.cc - 0000 0111 RR10 cccc
- case 0x2: retSize = 1 ; break ;
-
- // B.cc - 0000 0111 --11 cccc xxxx xxxx xxxx xxxx
- case 0x3: retSize = BccOperation() ; break ;
- }
+ size = dsp56k_op_bfop_1(op, op2, &cycle_count);
}
- else if (BITS(OP,0x0800))
+ /* BFTSTH : 0001 0100 000D DDDD BBB1 0000 iiii iiii : A-44 */
+ else if (((op & 0xffe0) == 0x1400) && ((op2 & 0x1f00) == 0x1000))
{
- switch (BITS(OP,0x0700))
- {
- // BRA - 0000 1011 aaaa aaaa
- case 0x3: retSize = BraOperation() ; break ;
-
- // MOVE(P) - 0000 110W RRmp pppp
- case 0x4: case 0x5: retSize = MovePOperation() ; break ;
-
- // DO - 0000 1110 iiii iiii xxxx xxxx xxxx xxxx
- case 0x6: retSize = DoOperation() ; break ;
-
- // REP - 0000 1111 iiii iiii
- case 0x7: retSize = RepOperation() ; break ;
- }
+ size = dsp56k_op_bfop_2(op, op2, &cycle_count);
+ }
+ /* BFTSTL : 0001 0100 01Pp pppp BBB0 0000 iiii iiii : A-46 */
+ else if (((op & 0xffc0) == 0x1440) && ((op2 & 0x1f00) == 0x0000))
+ {
+ size = dsp56k_op_bfop(op, op2, &cycle_count);
+ }
+ /* BFTSTL : 0001 0100 001- --RR BBB0 0000 iiii iiii : A-46 */
+ else if (((op & 0xffe0) == 0x1420) && ((op2 & 0x1f00) == 0x0000))
+ {
+ size = dsp56k_op_bfop_1(op, op2, &cycle_count);
+ }
+ /* BFTSTL : 0001 0100 000D DDDD BBB0 0000 iiii iiii : A-46 */
+ else if (((op & 0xffe0) == 0x1400) && ((op2 & 0x1f00) == 0x0000))
+ {
+ size = dsp56k_op_bfop_2(op, op2, &cycle_count);
+ }
+ /* Bcc : 0000 0111 --11 cccc xxxx xxxx xxxx xxxx : A-48 */
+ else if (((op & 0xff30) == 0x0730) && ((op2 & 0x0000) == 0x0000))
+ {
+ size = dsp56k_op_bcc(op, op2, &cycle_count);
+ }
+ /* Bcc : 0010 11cc ccee eeee : A-48 */
+ else if ((op & 0xfc00) == 0x2c00)
+ {
+ size = dsp56k_op_bcc_1(op, &cycle_count);
+ }
+ /* Bcc : 0000 0111 RR10 cccc : A-48 */
+ else if ((op & 0xff30) == 0x0720)
+ {
+ size = dsp56k_op_bcc_2(op, &cycle_count);
+ }
+ /* BRA : 0000 0001 0011 11-- xxxx xxxx xxxx xxxx : A-50 */
+ else if (((op & 0xfffc) == 0x013c) && ((op2 & 0x0000) == 0x0000))
+ {
+ size = dsp56k_op_bra(op, op2, &cycle_count);
+ }
+ /* BRA : 0000 1011 aaaa aaaa : A-50 */
+ else if ((op & 0xff00) == 0x0b00)
+ {
+ size = dsp56k_op_bra_1(op, &cycle_count);
+ }
+ /* BRA : 0000 0001 0010 11RR : A-50 */
+ else if ((op & 0xfffc) == 0x012c)
+ {
+ size = dsp56k_op_bra_2(op, &cycle_count);
+ }
+ /* BRKc : 0000 0001 0001 cccc : A-52 */
+ else if ((op & 0xfff0) == 0x0110)
+ {
+ size = dsp56k_op_brkc(op, &cycle_count);
+ }
+ /* BScc : 0000 0111 --01 cccc xxxx xxxx xxxx xxxx : A-54 */
+ else if (((op & 0xff30) == 0x0710) && ((op2 & 0x0000) == 0x0000))
+ {
+ size = dsp56k_op_bscc(op, op2, &cycle_count);
+ }
+ /* BScc : 0000 0111 RR00 cccc : A-54 */
+ else if ((op & 0xff30) == 0x0700)
+ {
+ size = dsp56k_op_bscc_1(op, &cycle_count);
+ }
+ /* BSR : 0000 0001 0011 10-- xxxx xxxx xxxx xxxx : A-56 */
+ else if (((op & 0xfffc) == 0x0138) && ((op2 & 0x0000) == 0x0000))
+ {
+ size = dsp56k_op_bsr(op, op2, &cycle_count);
+ }
+ /* BSR : 0000 0001 0010 10RR : A-56 */
+ else if ((op & 0xfffc) == 0x0128)
+ {
+ size = dsp56k_op_bsr_1(op, &cycle_count);
+ }
+ /* CHKAAU : 0000 0000 0000 0100 : A-58 */
+ else if ((op & 0xffff) == 0x0004)
+ {
+ size = dsp56k_op_chkaau(op, &cycle_count);
+ }
+ /* DEBUG : 0000 0000 0000 0001 : A-68 */
+ else if ((op & 0xffff) == 0x0001)
+ {
+ size = dsp56k_op_debug(op, &cycle_count);
+ }
+ /* DEBUGcc : 0000 0000 0101 cccc : A-70 */
+ else if ((op & 0xfff0) == 0x0050)
+ {
+ size = dsp56k_op_debugcc(op, &cycle_count);
+ }
+ /* DIV : 0001 0101 0--0 F1DD : A-76 */
+ /* WARNING : DOCS SAY THERE IS A PARALLEL MOVE HERE !!! */
+ else if ((op & 0xff94) == 0x1504)
+ {
+ size = dsp56k_op_div(op, &cycle_count);
+ }
+ /* DMAC : 0001 0101 10s1 FsQQ : A-80 */
+ else if ((op & 0xffd0) == 0x1590)
+ {
+ size = dsp56k_op_dmac(op, &cycle_count);
+ }
+ /* DO : 0000 0000 110- --RR xxxx xxxx xxxx xxxx : A-82 */
+ else if (((op & 0xffe0) == 0x00c0) && ((op2 & 0x0000) == 0x0000))
+ {
+ size = dsp56k_op_do(op, op2, &cycle_count);
+ }
+ /* DO : 0000 1110 iiii iiii xxxx xxxx xxxx xxxx : A-82 */
+ else if (((op & 0xff00) == 0x0e00) && ((op2 & 0x0000) == 0x0000))
+ {
+ size = dsp56k_op_do_1(op, op2, &cycle_count);
+ }
+ /* DO : 0000 0100 000D DDDD xxxx xxxx xxxx xxxx : A-82 */
+ else if (((op & 0xffe0) == 0x0400) && ((op2 & 0x0000) == 0x0000))
+ {
+ size = dsp56k_op_do_2(op, op2, &cycle_count);
+ }
+ /* DO FOREVER : 0000 0000 0000 0010 xxxx xxxx xxxx xxxx : A-88 */
+ else if (((op & 0xffff) == 0x0002) && ((op2 & 0x0000) == 0x0000))
+ {
+ size = dsp56k_op_doforever(op, op2, &cycle_count);
+ }
+ /* ENDDO : 0000 0000 0000 1001 : A-92 */
+ else if ((op & 0xffff) == 0x0009)
+ {
+ size = dsp56k_op_enddo(op, &cycle_count);
+ }
+ /* EXT : 0001 0101 0101 F010 : A-96 */
+ else if ((op & 0xfff7) == 0x1552)
+ {
+ size = dsp56k_op_ext(op, &cycle_count);
+ }
+ /* ILLEGAL : 0000 0000 0000 1111 : A-98 */
+ else if ((op & 0xffff) == 0x000f)
+ {
+ size = dsp56k_op_illegal(op, &cycle_count);
+ }
+ /* IMAC : 0001 0101 1010 FQQQ : A-100 */
+ else if ((op & 0xfff0) == 0x15a0)
+ {
+ size = dsp56k_op_imac(op, &cycle_count);
+ }
+ /* IMPY : 0001 0101 1000 FQQQ : A-102 */
+ else if ((op & 0xfff0) == 0x1580)
+ {
+ size = dsp56k_op_impy(op, &cycle_count);
+ }
+ /* Jcc : 0000 0110 --11 cccc xxxx xxxx xxxx xxxx : A-108 */
+ else if (((op & 0xff30) == 0x0630) && ((op2 & 0x0000) == 0x0000))
+ {
+ size = dsp56k_op_jcc(op, op2, &cycle_count);
+ }
+ /* Jcc : 0000 0110 RR10 cccc : A-108 */
+ else if ((op & 0xff30) == 0x0620 )
+ {
+ size = dsp56k_op_jcc_1(op, &cycle_count);
+ }
+ /* JMP : 0000 0001 0011 01-- xxxx xxxx xxxx xxxx : A-110 */
+ else if (((op & 0xfffc) == 0x0134) && ((op2 & 0x0000) == 0x0000))
+ {
+ size = dsp56k_op_jmp(op, op2, &cycle_count);
+ }
+ /* JMP : 0000 0001 0010 01RR : A-110 */
+ else if ((op & 0xfffc) == 0x0124)
+ {
+ size = dsp56k_op_jmp_1(op, &cycle_count);
+ }
+ /* JScc : 0000 0110 --01 cccc xxxx xxxx xxxx xxxx : A-112 */
+ else if (((op & 0xff30) == 0x0610) && ((op2 & 0x0000) == 0x0000))
+ {
+ size = dsp56k_op_jscc(op, op2, &cycle_count);
+ }
+ /* JScc : 0000 0110 RR00 cccc : A-112 */
+ else if ((op & 0xff30) == 0x0600)
+ {
+ size = dsp56k_op_jscc_1(op, &cycle_count);
+ }
+ /* JSR : 0000 0001 0011 00-- xxxx xxxx xxxx xxxx : A-114 */
+ else if (((op & 0xfffc) == 0x0130) && ((op2 & 0x0000) == 0x0000))
+ {
+ size = dsp56k_op_jsr(op, op2, &cycle_count);
+ }
+ /* JSR : 0000 1010 AAAA AAAA : A-114 */
+ else if ((op & 0xff00) == 0x0a00)
+ {
+ size = dsp56k_op_jsr_1(op, &cycle_count);
+ }
+ /* JSR : 0000 0001 0010 00RR : A-114 */
+ else if ((op & 0xfffc) == 0x0120)
+ {
+ size = dsp56k_op_jsr_2(op, &cycle_count);
+ }
+ /* LEA : 0000 0001 11TT MMRR : A-116 */
+ else if ((op & 0xffc0) == 0x01c0)
+ {
+ size = dsp56k_op_lea(op, &cycle_count);
+ }
+ /* LEA : 0000 0001 10NN MMRR : A-116 */
+ else if ((op & 0xffc0) == 0x0180)
+ {
+ size = dsp56k_op_lea_1(op, &cycle_count);
+ }
+ /* MAC(su,uu) : 0001 0101 1110 FsQQ : A-126 */
+ else if ((op & 0xfff0) == 0x15e0)
+ {
+ size = dsp56k_op_macsuuu(op, &cycle_count);
+ }
+ /* MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 */
+ else if (((op & 0xff00) == 0x0500) && ((op2 & 0x00ff) == 0x0011))
+ {
+ size = dsp56k_op_move_2(op, op2, &cycle_count);
+ }
+ /* MOVE(C) : 0011 1WDD DDD0 MMRR : A-144 */
+ else if ((op & 0xf810) == 0x3800)
+ {
+ size = dsp56k_op_movec(op, &cycle_count);
+ }
+ /* MOVE(C) : 0011 1WDD DDD1 q0RR : A-144 */
+ else if ((op & 0xf814) == 0x3810)
+ {
+ size = dsp56k_op_movec_1(op, &cycle_count);
+ }
+ /* MOVE(C) : 0011 1WDD DDD1 Z11- : A-144 */
+ else if ((op & 0xf816) == 0x3816)
+ {
+ size = dsp56k_op_movec_2(op, &cycle_count);
+ }
+ /* MOVE(C) : 0011 1WDD DDD1 t10- xxxx xxxx xxxx xxxx : A-144 */
+ else if (((op & 0xf816) == 0x3814) && ((op2 & 0x0000) == 0x0000))
+ {
+ size = dsp56k_op_movec_3(op, op2, &cycle_count);
+ }
+ /* MOVE(C) : 0010 10dd dddD DDDD : A-144 */
+ else if ((op & 0xfc00) == 0x2800)
+ {
+ size = dsp56k_op_movec_4(op, &cycle_count);
+ }
+ /* MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 */
+ else if (((op & 0xff00) == 0x0500) && ((op2 & 0xf810) == 0x3800))
+ {
+ size = dsp56k_op_movec_5(op, op2, &cycle_count);
+ }
+ /* MOVE(I) : 0010 00DD BBBB BBBB : A-150 */
+ else if ((op & 0xfc00) == 0x2000)
+ {
+ size = dsp56k_op_movei(op, &cycle_count);
+ }
+ /* MOVE(M) : 0000 001W RR0M MHHH : A-152 */
+ else if ((op & 0xfe20) == 0x0200)
+ {
+ size = dsp56k_op_movem(op, &cycle_count);
+ }
+ /* MOVE(M) : 0000 001W RR11 mmRR : A-152 */
+ else if ((op & 0xfe30) == 0x0230)
+ {
+ size = dsp56k_op_movem_1(op, &cycle_count);
+ }
+ /* MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 */
+ else if (((op & 0xff00) == 0x0500) && ((op2 & 0xfe20) == 0x0200))
+ {
+ size = dsp56k_op_movem_2(op, op2, &cycle_count);
+ }
+ /* MOVE(P) : 0001 100W HH1p pppp : A-156 */
+ else if ((op & 0xfe20) == 0x1820)
+ {
+ size = dsp56k_op_movep(op, &cycle_count);
+ }
+ /* MOVE(P) : 0000 110W RRmp pppp : A-156 */
+ else if ((op & 0xfe00) == 0x0c00)
+ {
+ size = dsp56k_op_movep_1(op, &cycle_count);
+ }
+ /* MOVE(S) : 0001 100W HH0a aaaa : A-158 */
+ else if ((op & 0xfe20) == 0x1800)
+ {
+ size = dsp56k_op_moves(op, &cycle_count);
+ }
+ /* MPY(su,uu) : 0001 0101 1100 FsQQ : A-164 */
+ else if ((op & 0xfff0) == 0x15c0)
+ {
+ size = dsp56k_op_mpysuuu(op, &cycle_count);
+ }
+ /* NEGC : 0001 0101 0110 F000 : A-168 */
+ else if ((op & 0xfff7) == 0x1560)
+ {
+ size = dsp56k_op_negc(op, &cycle_count);
+ }
+ /* NOP : 0000 0000 0000 0000 : A-170 */
+ else if ((op & 0xffff) == 0x0000)
+ {
+ size = dsp56k_op_nop(op, &cycle_count);
+ }
+ /* NORM : 0001 0101 0010 F0RR : A-172 */
+ else if ((op & 0xfff4) == 0x1520)
+ {
+ size = dsp56k_op_norm(op, &cycle_count);
+ }
+ /* ORI : 0001 1EE1 iiii iiii : A-178 */
+ else if ((op & 0xf900) == 0x1900)
+ {
+ size = dsp56k_op_ori(op, &cycle_count);
+ }
+ /* REP : 0000 0000 111- --RR : A-180 */
+ else if ((op & 0xffe0) == 0x00e0)
+ {
+ size = dsp56k_op_rep(op, &cycle_count);
+ }
+ /* REP : 0000 1111 iiii iiii : A-180 */
+ else if ((op & 0xff00) == 0x0f00)
+ {
+ size = dsp56k_op_rep_1(op, &cycle_count);
+ }
+ /* REP : 0000 0100 001D DDDD : A-180 */
+ else if ((op & 0xffe0) == 0x0420)
+ {
+ size = dsp56k_op_rep_2(op, &cycle_count);
+ }
+ /* REPcc : 0000 0001 0101 cccc : A-184 */
+ else if ((op & 0xfff0) == 0x0150)
+ {
+ size = dsp56k_op_repcc(op, &cycle_count);
+ }
+ /* RESET : 0000 0000 0000 1000 : A-186 */
+ else if ((op & 0xffff) == 0x0008)
+ {
+ size = dsp56k_op_reset(op, &cycle_count);
+ }
+ /* RTI : 0000 0000 0000 0111 : A-194 */
+ else if ((op & 0xffff) == 0x0007)
+ {
+ size = dsp56k_op_rti(op, &cycle_count);
+ }
+ /* RTS : 0000 0000 0000 0110 : A-196 */
+ else if ((op & 0xffff) == 0x0006)
+ {
+ size = dsp56k_op_rts(op, &cycle_count);
+ }
+ /* STOP : 0000 0000 0000 1010 : A-200 */
+ else if ((op & 0xffff) == 0x000a)
+ {
+ size = dsp56k_op_stop(op, &cycle_count);
+ }
+ /* SWAP : 0001 0101 0111 F001 : A-206 */
+ else if ((op & 0xfff7) == 0x1571)
+ {
+ size = dsp56k_op_swap(op, &cycle_count);
+ }
+ /* SWI : 0000 0000 0000 0101 : A-208 */
+ else if ((op & 0xffff) == 0x0005)
+ {
+ size = dsp56k_op_swi(op, &cycle_count);
+ }
+ /* Tcc : 0001 00cc ccTT Fh0h : A-210 */
+ else if ((op & 0xfc02) == 0x1000)
+ {
+ size = dsp56k_op_tcc(op, &cycle_count);
+ }
+ /* TFR(2) : 0001 0101 0000 F00J : A-214 */
+ else if ((op & 0xfff6) == 0x1500)
+ {
+ size = dsp56k_op_tfr2(op, &cycle_count);
+ }
+ /* TFR(3) : 0010 01mW RRDD FHHH : A-216 */
+ else if ((op & 0xfc00) == 0x2400)
+ {
+ size = dsp56k_op_tfr3(op, &cycle_count);
+ }
+ /* TST(2) : 0001 0101 0001 -1DD : A-220 */
+ else if ((op & 0xfff4) == 0x1514)
+ {
+ size = dsp56k_op_tst2(op, &cycle_count);
+ }
+ /* WAIT : 0000 0000 0000 1011 : A-222 */
+ else if ((op & 0xffff) == 0x000b)
+ {
+ size = dsp56k_op_wait(op, &cycle_count);
+ }
+ /* ZERO : 0001 0101 0101 F000 : A-224 */
+ else if ((op & 0xfff7) == 0x1550)
+ {
+ size = dsp56k_op_zero(op, &cycle_count);
}
- return retSize ;
-}
-
-/*
-IMPLEMENTATIONS
-*/
-static int BitfieldOperation(void)
-{
- int retSize = 0 ;
+ /* Not recognized? Nudge debugger onto the next word */
+ if (size == 0x1337)
+ {
+ logerror("DSP56k: Unimplemented opcode at 0x%04x : %04x\n", PC, op);
+ size = 1 ; // Just to get the debugger past the bad opcode
+ }
- // BITFIELD OPERATIONS
- // ONLY PARTIALLY IMPLEMENTED !!!
+ /* Must have been a good opcode */
+ PC += size;
+ change_pc(PC);
- // Get the next part of the opcode...
- UINT16 op2 = ROPCODE((PC<<1)+2) ;
+ dsp56k_process_loop();
+ dsp56k_process_rep(size);
- unsigned char dt = 0x00 ;
- void *destinationReg = 0x00 ;
- void *rReg = 0x00 ;
+ dsp56k_icount -= 4; /* Temporarily hard-coded at 4 clocks per opcode */ /* cycle_count */
+}
- UINT16 destAddr = 0x00 ;
- UINT16 opVal ;
- // Get the universal immediate value and its proper mask...
- UINT16 iVal = op2 & 0x00ff ;
- DecodeBBBBitMask(BITS(op2,0xe000), &iVal) ;
- // Figure out where data you'll be dealing with comes from...
- switch(BITS(OP,0x00e0))
- {
- case 0x6: case 0x7: case 0x2: case 0x3:
- destAddr = AssembleDFromPTable(BITS(OP,0x0020), BITS(OP,0x001f)) ;
- break ;
+/***************************************************************************
+ Opcode implementations
+***************************************************************************/
- case 0x5: case 0x1:
- rReg = DecodeRRTable(BITS(OP,0x0003), &dt) ;
- destAddr = *((UINT16*)rReg) ;
- break ;
+/*******************************/
+/* 32 Parallel move operations */
+/*******************************/
- case 0x4: case 0x0:
- destinationReg = DecodeDDDDDTable(BITS(OP,0x001f), &dt) ;
- break ;
- }
+/* ADD : 011m mKKK 0rru Fuuu : A-22 */
+static size_t dsp56k_op_add_2(const UINT16 op_byte, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * * */
+ return 0;
+}
- // Grab the value to operate on...
- if (destinationReg)
- {
- if (dt == DT_LONG_WORD)
- opVal = (*((PAIR64*)destinationReg)).w.h ;
- else
- opVal = *((UINT16*)destinationReg) ;
- }
- else
- opVal = data_read_word_16le(destAddr<<1) ;
-
- // Do the necessary bitfield operation...
- switch(BITS(op2,0x1f00))
- {
- // bfchg
- case 0x12:
- if ((iVal & opVal) == iVal) C_bit_set(1); // test
- else C_bit_set(0) ;
-
- opVal ^= iVal ; // and change
- break ;
-
- // bfclr
- case 0x04:
- opVal &= (~iVal) ;
- break ;
-
- // bfset
- case 0x18:
- opVal |= iVal ;
- break ;
-
- // bfsth
- case 0x10:
- mame_printf_debug("BFSTH - not here yet") ;
- break ;
-
- // bftstl
- case 0x00:
- if ((iVal & opVal) == 0) C_bit_set(1);
- else C_bit_set(0);
- retSize = 2; return retSize; /* It's just a test - no need to go on */
- break ;
- }
-
- // Put the data back where it belongs
- // !!! When setting A and B, I'm pretty sure if it's supposed to pass through the normal 'setDestValue' pipe but not entirely !!!
- // (in other words, does clearing ff.ffff.ffff with 001c really result in ff.ffe3.0000 or ff.ffe3.ffff) ???
- if (destinationReg)
- SetDestinationValue(&opVal, DT_WORD, destinationReg, dt) ;
- else
- SetDataMemoryValue(&opVal, DT_WORD, destAddr<<1) ;
+/* MAC : 011m mKKK 1xx0 F1QQ : A-122 */
+static size_t dsp56k_op_mac_1(const UINT16 op_byte, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * - */
+ return 0;
+}
- retSize = 2 ;
- return retSize ;
+/* MACR: 011m mKKK 1--1 F1QQ : A-124 */
+static size_t dsp56k_op_macr_1(const UINT16 op_byte, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * - */
+ return 0;
}
-static int MoveCOperation(void)
+/* MOVE : 011m mKKK 0rr1 0000 : A-128 */
+static size_t dsp56k_op_move_1(const UINT16 op_byte, UINT8* cycles)
{
- int retSize = 0 ;
+ /* S L E U N Z V C */
+ /* * * - - - - - - */
+ return 0;
+}
- unsigned char W = 0x00 ;
+/* MPY : 011m mKKK 1xx0 F0QQ : A-160 */
+static size_t dsp56k_op_mpy_1(const UINT16 op_byte, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * - */
+ return 0;
+}
- unsigned char sdt = 0x00 ;
- void *SD ;
+/* MPYR : 011m mKKK 1--1 F0QQ : A-162 */
+static size_t dsp56k_op_mpyr_1(const UINT16 op_byte, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * - */
+ return 0;
+}
- // ONLY PARTIALLY IMPLEMENTED !!!
+/* SUB : 011m mKKK 0rru Fuuu : A-202 */
+static size_t dsp56k_op_sub_1(const UINT16 op_byte, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * * */
+ return 0;
+}
- SD = DecodeDDDDDTable(BITS(OP,0x03e0), &sdt) ;
- W = BITS(OP,0x0400) ;
+/* TFR : 011m mKKK 0rr1 F0DD : A-212 */
+static size_t dsp56k_op_tfr_2(const UINT16 op_byte, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- if (BITS(OP,0x1000))
- {
- // Single source/destination move(c)
- if (!BITS(OP,0x0010))
- {
- // MM in move(c)
+/* MPY : 0001 0110 RRDD FQQQ : A-160 */
+static size_t dsp56k_op_mpy_2(const UINT16 op_byte, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * - */
+ return 0;
+}
- // Get the r register...
- unsigned char rt = 0x00 ;
- void *R ;
+/* MAC : 0001 0111 RRDD FQQQ : A-122 */
+static size_t dsp56k_op_mac_2(const UINT16 op_byte, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * - */
+ return 0;
+}
- R = DecodeRRTable(BITS(OP,0x0003), &rt) ;
+/* CLR : .... .... 0000 F001 : A-60 */
+static size_t dsp56k_op_clr(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ typed_pointer D = {NULL, DT_LONG_WORD};
+ typed_pointer clear = {NULL, DT_LONG_WORD};
+ UINT64 clear_val = U64(0x0000000000000000);
- if (W)
- {
- // !!! does this work ???
- UINT16 data = data_read_word_16le((*((UINT16*)R))<<1) ;
- SetDestinationValue(&data, DT_WORD, SD, sdt) ;
- }
- else
- {
- SetDataMemoryValue(SD, sdt, (*((UINT16*)R))<<1) ;
- }
+ decode_F_table(BITS(op_byte,0x0008), &D);
- ExecuteMMTable(BITS(OP,0x0003), BITS(OP,0x000c)) ;
- retSize = 1 ;
- }
- else
- {
- if (!BITS(OP,0x0004))
- {
- // q in move(c)
-
- // Figure out the true addr...
- UINT16 addr = ExecuteqTable(BITS(OP,0x0003), BITS(OP,0x0008));
-
- if (W)
- {
- // !!! does this work ???
- UINT16 data = data_read_word_16le(addr<<1) ;
- SetDestinationValue(&data, DT_WORD, SD, sdt) ;
- }
- else
- {
- SetDataMemoryValue(SD, sdt, addr<<1);
- }
-
- retSize = 1 ;
- }
- else
- {
- if (BITS(OP,0x0002))
- {
- // Z in move(c)
- unsigned char rt = 0x00;
- void *Z;
-
- Z = DecodeZTable(BITS(OP,0x0008), &rt);
-
- if (W)
- {
- // Unimplemented
- retSize = 666 ;
- }
- else
- {
- SetDataMemoryValue(SD, sdt, (*((UINT16*)Z))<<1);
- retSize = 1;
- }
- }
- else
- {
- // 2-word move(c)
- UINT16 nextWord = ROPCODE((PC<<1)+2) ;
-
- if (BITS(OP,0x0008))
- {
- // #xxxx - value read directly out of the opcode
- SetDestinationValue(&nextWord, DT_WORD, SD, sdt) ;
- }
- else
- {
- // X:xxxx = value resides in X memory...
- if (W)
- {
- // Read from X-data memory...
- // !!! Does this work ???
- UINT16 data = data_read_word_16le(nextWord<<1) ;
- SetDestinationValue(&data, DT_WORD, SD, sdt) ;
- }
- else
- {
- // Write to X-data memory...
- SetDataMemoryValue(SD, sdt, nextWord<<1) ;
- }
- }
-
- retSize = 2 ;
- }
- }
- }
- }
- else if (BITS(OP,0x2000))
- {
- // Source and Destination explicit
- unsigned char dt = 0x00 ;
- void *D ;
+ *p_accum = *((UINT64*)D.addr);
- D = DecodeDDDDDTable(BITS(OP,0x001f), &dt) ;
- SetDestinationValue(SD, sdt, D, dt) ;
+ clear.addr = &clear_val;
+ clear.data_type = DT_LONG_WORD;
+ SetDestinationValue(clear, D);
- retSize = 1 ;
- }
- else
- {
- // Double source/destination move(c)
+ d_register->addr = D.addr;
+ d_register->data_type = D.data_type;
- retSize = 666 ;
- }
+ /* S L E U N Z V C */
+ /* * * * * * * 0 - */
+ /* TODO - S&L */
+ E_bit_set(0);
+ U_bit_set(1);
+ N_bit_set(0);
+ Z_bit_set(1);
+ V_bit_set(0);
- return retSize ;
+ cycles += 2; /* TODO: + mv oscillator clock cycles */
+ return 1;
}
-static int MoveMOperation(void)
+/* ADD : .... .... 0000 FJJJ : A-22 */
+static size_t dsp56k_op_add(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
{
- int retSize = 0 ;
+ UINT64 addVal = 0;
+
+ typed_pointer S = {NULL, DT_BYTE};
+ typed_pointer D = {NULL, DT_BYTE};
+ decode_JJJF_table(BITS(op_byte,0x0007),BITS(op_byte,0x0008), &S, &D);
- // ONLY PARTIALLY IMPLEMENTED !!!
+ *p_accum = *((UINT64*)D.addr);
- if (BITS(OP,0x0400))
+ switch(S.data_type)
{
- // The double word MoveM operation...
- UINT16 nextWord = ROPCODE((PC<<1)+2) ;
+ case DT_WORD: addVal = (UINT64)*((UINT16*)S.addr) << 16; break;
+ case DT_DOUBLE_WORD: addVal = (UINT64)*((UINT32*)S.addr); break;
+ case DT_LONG_WORD: addVal = (UINT64)*((UINT64*)S.addr); break;
+ }
- UINT8 increment = BITS(OP,0x00ff) ;
+ /* TODO: Verify : Sign-extend everyone for proper addition op */
+ if (addVal & U64(0x0000000080000000))
+ addVal |= U64(0xffffffff00000000);
- int W = BITS(nextWord, 0x0100) ;
+ /* Operate*/
+ *((UINT64*)D.addr) += addVal;
- unsigned char sdt = 0x00 ;
- void *sdReg = 0x00 ;
- sdReg = DecodeHHHTable(BITS(nextWord,0x0007), &sdt) ;
+ d_register->addr = D.addr;
+ d_register->data_type = D.data_type;
- if (W)
- {
- // Read from Program Memory...
- UINT16 data = program_read_word_16le((R2<<1)+(increment<<1)) ;
- SetDestinationValue(&data, DT_WORD, sdReg, sdt) ;
- }
- else
- {
- // Write to Program Memory...
- // !!! Does this work ???
- // SetMemoryValue(sdReg, sdt, ((R2<<1)+(increment<<1))) ;
- }
+ /* S L E U N Z V C */
+ /* * * * * * * * * */
+ /* TODO S, L, E, U, V, C */
+ if (*((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(1);
+ if (*((UINT64*)D.addr) == 0) Z_bit_set(1);
- retSize = 2 ;
- }
- else
- {
- // The single word MoveM operation...
+ cycles += 2; /* TODO: + mv oscillator cycles */
+ return 1;
+}
- // Decode which way the data is going...
- int W = BITS(OP,0x0100) ;
+/* MOVE : .... .... 0001 0001 : A-128 */
+static size_t dsp56k_op_move(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * - - - - - - */
+ return 0;
+}
- // Decode which R Register we're working with...
- unsigned char rt = 0x00 ;
- void *rReg = 0x00 ;
- rReg = DecodeRRTable(BITS(OP,0x00c0), &rt) ;
+/* TFR : .... .... 0001 FJJJ : A-212 */
+static size_t dsp56k_op_tfr(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- if (BITS(OP,0x0020))
- {
- // R and R operation
- retSize = 666 ;
- }
- else
- {
- // R and SD operation
- // Decode the SD register...
- unsigned char sdt = 0x00 ;
- void *sdReg = 0x00 ;
- sdReg = DecodeHHHTable(BITS(OP,0x0007), &sdt) ;
+/* RND : .... .... 0010 F000 : A-188 */
+static size_t dsp56k_op_rnd(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * - */
+ return 0;
+}
- if (W)
- {
- // Read from Program Memory...
- UINT16 data = program_read_word_16le( (*((UINT16*)rReg)) << 1 ) ;
- SetDestinationValue(&data, DT_WORD, sdReg, sdt) ;
- }
- else
- {
- // Write to Program Memory...
- SetProgramMemoryValue(sdReg, sdt, (*((UINT16*)rReg)) << 1 ) ;
- }
+/* TST : .... .... 0010 F001 : A-218 */
+static size_t dsp56k_op_tst(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* 0 * * * * * 0 0 */
+ return 0;
+}
- // Execute the increment part of the opcode...
- ExecuteMMTable(BITS(OP,0x00c0), BITS(OP,0x0018)) ;
+/* INC : .... .... 0010 F010 : A-104 */
+static size_t dsp56k_op_inc(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * * */
+ return 0;
+}
- retSize = 1 ;
- }
- }
+/* INC24 : .... .... 0010 F011 : A-106 */
+static size_t dsp56k_op_inc24(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * ? * * */
+ /* Z - Set if the 24 most significant bits of the destination result are all zeroes. */
+ return 0;
+}
- return retSize ;
+/* OR : .... .... 0010 F1JJ : A-176 */
+static size_t dsp56k_op_or(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * - - ? ? 0 - */
+ /* N - Set if bit 31 of the result is set. Cleared otherwise. */
+ /* Z - Set if bits 16-31 of the result are zero. Cleared otherwise. */
+ return 0;
}
-static int MoveIOperation(void)
+/* ASR : .... .... 0011 F000 : A-32 */
+static size_t dsp56k_op_asr(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
{
- int retSize = 1 ;
+ typed_pointer D = {NULL, DT_BYTE};
+ decode_F_table(BITS(op_byte,0x0008), &D);
- // The 8-bit signed immediate operand is stored in the low byte of destination
- // register D after having been sign extended.
+ *p_accum = *((UINT64*)D.addr);
- INT8 immediateVal = OP & 0x00ff ;
- UINT16 immediateWord ;
+ *((UINT64*)D.addr) = (*((UINT64*)D.addr)) >> 1;
- unsigned char dt = 0x00 ;
- void *destinationReg = 0x00 ;
+ /* Make sure the MSB is maintained */
+ if (*p_accum & U64(0x0000008000000000))
+ *((UINT64*)D.addr) |= U64(0x0000008000000000);
+ else
+ *((UINT64*)D.addr) &= (~U64(0x0000008000000000));
- destinationReg = DecodeDDTable(BITS(OP,0x0300), &dt) ;
+ /* For the parallel move */
+ d_register->addr = D.addr;
+ d_register->data_type = D.data_type;
- // Sign extend the immediate value...
- // !!! On Intel architecture this works correctly, does it work everywhere ???
- immediateWord = (INT16)immediateVal ;
+ /* S L E U N Z V C */
+ /* * * * * * * 0 ? */
+ /* TODO: S, L, E, U */
+ if (*((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(1);
+ if (*((UINT64*)D.addr) == 0) Z_bit_set(1);
+ V_bit_set(0);
+ if (*p_accum & U64(0x0000000000000001)) C_bit_set(1);
+
+ cycles += 2; /* TODO: + mv oscillator cycles */
+ return 1;
+}
+
+/* ASL : .... .... 0011 F001 : A-28 */
+static size_t dsp56k_op_asl(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * ? ? */
+ /* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if the most significant
+ bit of the destination operand is changed as a result of the left shift. Cleared otherwise. */
+ /* C - Set if bit 39 of source operand is set. Cleared otherwise. */
+ return 0;
+}
+
+/* LSR : .... .... 0011 F010 : A-120 */
+static size_t dsp56k_op_lsr(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ typed_pointer D = {NULL, DT_BYTE};
+ decode_F_table(BITS(op_byte,0x0008), &D);
+
+ *p_accum = *((UINT64*)D.addr);
+
+ ((PAIR64*)D.addr)->w.h = (((PAIR64*)D.addr)->w.h) >> 1;
+
+ /* Make sure bit 31 gets a 0 */
+ ((PAIR64*)D.addr)->w.h &= (~0x8000);
+
+ /* For the parallel move */
+ d_register->addr = D.addr;
+ d_register->data_type = D.data_type;
+
+ /* S L E U N Z V C */
+ /* * * - - ? ? 0 ? */
+ /* TODO: S, L */
+ N_bit_set(0);
+ if (((PAIR64*)D.addr)->w.h == 0) Z_bit_set(1);
+ V_bit_set(0);
+ if (*p_accum & U64(0x0000000000010000)) C_bit_set(1);
+
+ cycles += 2; /* TODO: + mv oscillator cycles */
+ return 1;
+}
- SetDestinationValue(&immediateWord, DT_WORD, destinationReg, dt) ;
+/* LSL : .... .... 0011 F011 : A-118 */
+static size_t dsp56k_op_lsl(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * - - ? ? 0 ? */
+ /* N - Set if bit 31 of the result is set. Cleared otherwise. */
+ /* Z - Set if bits 16-31 of the result are zero. Cleared otherwise. */
+ /* C - Set if bit 31 of the source operand is set. Cleared otherwise. */
+ return 0;
+}
- return retSize ;
+/* EOR : .... .... 0011 F1JJ : A-94 */
+static size_t dsp56k_op_eor(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * - - ? ? 0 - */
+ /* N - Set if bit 31 of the result is set. Cleared otherwise. */
+ /* Z - Set if bits 16-31 of the result are zero. Cleared otherwise. */
+ return 0;
}
-static int MovePOperation(void)
+/* SUBL : .... .... 0100 F001 : A-204 */
+static size_t dsp56k_op_subl(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
{
- int retSize = 1 ;
+ /* S L E U N Z V C */
+ /* * * * * * * ? * */
+ /* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if the most significant
+ bit of the destination operand is changed as a result of the left shift. Cleared otherwise. */
+ return 0;
+}
- if (BITS(OP,0x1000))
- {
- // X:<pp> and SD
- UINT16 pp ;
- UINT16 W ;
+/* SUB : .... .... 0100 FJJJ : A-202 */
+static size_t dsp56k_op_sub(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * * */
+ return 0;
+}
- unsigned char sdt = 0x00 ;
- void *SD = 0x00 ;
+/* CLR24 : .... .... 0101 F001 : A-62 */
+static size_t dsp56k_op_clr24(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * ? 0 - */
+ /* Z - Set if the 24 most significant bits of the destination result are all zeroes. */
+ return 0;
+}
- SD = DecodeHHTable(BITS(OP,0x00c0), &sdt) ;
+/* SBC : .... .... 0101 F01J : A-198 */
+static size_t dsp56k_op_sbc(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * * */
+ return 0;
+}
- pp = BITS(OP,0x001f) ;
- pp = AssembleAddressFromIOShortAddress(pp) ;
+/* CMP : .... .... 0101 FJJJ : A-64 */
+static size_t dsp56k_op_cmp(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ UINT64 cmpVal = 0;
+ UINT64 result = 0;
- W = BITS(OP,0x0100) ;
+ typed_pointer S = {NULL, DT_BYTE};
+ typed_pointer D = {NULL, DT_BYTE};
- if (W)
- {
- UINT16 data = data_read_word_16le(pp<<1) ;
- SetDestinationValue(&data, DT_WORD, SD, sdt) ;
- }
- else
- {
- SetDataMemoryValue(SD, sdt, pp<<1) ;
- }
- }
- else
- {
- // X:<Rx> and X:<pp>
- UINT16 pp ;
- UINT16 W ;
+ decode_JJJF_table(BITS(op_byte,0x0007),BITS(op_byte,0x0008), &S, &D);
- unsigned char sdrt = 0x00 ;
- void *sdrReg = 0x00 ;
- sdrReg = DecodeRRTable(BITS(OP,0x00c0), &sdrt) ;
+ *p_accum = *((UINT64*)D.addr);
- pp = BITS(OP,0x001f) ;
- pp = AssembleAddressFromIOShortAddress(pp) ;
+ switch(S.data_type)
+ {
+ case DT_WORD: cmpVal = (UINT64)*((UINT16*)S.addr); break;
+ case DT_DOUBLE_WORD: cmpVal = (UINT64)*((UINT32*)S.addr); break;
+ case DT_LONG_WORD: cmpVal = (UINT64)*((UINT64*)S.addr); break;
+ }
- W = BITS(OP,0x0100) ;
+ result = *((UINT64*)D.addr) - cmpVal;
- // A little different than most W if's - opposite read and write thingies...
- if (W)
- {
- UINT16 data = data_read_word_16le( (*((UINT16*)sdrReg))<<1 ) ; // read the word out
- SetDataMemoryValue(&data, DT_WORD, pp<<1) ;
- }
- else
- {
- mame_printf_debug("NOTHING HERE (yet)\n") ;
- }
+ d_register->addr = D.addr;
+ d_register->data_type = D.data_type;
- // Postincrement
- ExecutemTable(BITS(OP,0x00c0), BITS(OP,0x0020)) ;
- }
+ /* S L E U N Z V C */
+ /* * * * * * * * * */
+ /* TODO: S, L, E, U, N, V, C */
+ if (result == 0) Z_bit_set(1); /* TODO: Do you clear it if this isn't true? */
- return retSize ;
+
+ cycles += 2; /* TODO: + mv oscillator clock cycles */
+ return 1;
}
+/* NEG : .... .... 0110 F000 : A-166 */
+static size_t dsp56k_op_neg(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * * */
+ return 0;
+}
-static int JmpOperation(void)
+/* NOT : .... .... 0110 F001 : A-174 */
+static size_t dsp56k_op_not(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
{
- int retSize = 0 ;
+ typed_pointer D = {NULL, DT_BYTE};
+ decode_F_table(BITS(op_byte,0x0008), &D);
- core.ppc = PC;
+ *p_accum = *((UINT64*)D.addr);
- if (BITS(OP,0x0010))
- {
- PC = (ROPCODE((PC<<1)+2)) ; // Can this offset by 2 bytes be handled better? Say, for example, by moving "1 word"?
- change_pc(PC) ;
- }
- else
- {
- unsigned char rt = 0x00 ;
- void *R = 0x00 ;
+ /* Invert bits [16:31] of D */
+ ((PAIR64*)D.addr)->w.h = ~(((PAIR64*)D.addr)->w.h);
- R = DecodeRRTable(BITS(OP,0x0003), &rt);
+ d_register->addr = D.addr;
+ d_register->data_type = D.data_type;
- PC = *((UINT16*)R);
- change_pc(PC);
- }
+ /* S L E U N Z V C */
+ /* * * - - ? ? 0 - */
+ /* TODO: S?, L */
+ if ( *((UINT64*)D.addr) & U64(0x0000000080000000)) N_bit_set(1);
+ if ((*((UINT64*)D.addr) & U64(0x00000000ffff0000)) == 0) Z_bit_set(1);
+ V_bit_set(0);
- retSize = 0 ; // Jump with no offset.
+ cycles += 2; /* TODO: + mv oscillator cycles */
+ return 1;
+}
- return retSize ;
+/* DEC : .... .... 0110 F010 : A-72 */
+static size_t dsp56k_op_dec(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * * */
+ return 0;
}
-static int BsrOperation(void)
+/* DEC24 : .... .... 0110 F011 : A-74 */
+static size_t dsp56k_op_dec24(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
{
- int retSize = 0 ;
+ UINT32 workBits24;
- INT16 branchOffset = (ROPCODE((PC<<1)+2)) ; // Can this offset by 2 bytes be handled better? Say, for example, by moving "1 word"?
+ typed_pointer D = {NULL, DT_BYTE};
+ decode_F_table(BITS(op_byte,0x0008), &D);
- // "The PC Contains the address of the next instruction"
- PC += 2 ;
- core.ppc = PC ;
+ /* Save some data for the parallel move */
+ *p_accum = *((UINT64*)D.addr);
- // Push the PC to the stack...
- SP++ ; // !!! I'm not so sure about this 'pre-increment'
- // The reason it might be there is that SSH and SSL are supposed to point to the top of the
- // stack (and the docs seem to imply this behaviour). But it wastes the first stack entry ???
- // !!! I think i've read somewhere that PC == 1 when the stack is empty ???
- // !!! I also .know. there are only 15 stack entries - could this be why ???
- SSH = PC ;
- SSL = SR ;
+ /* TODO: I wonder if workBits24 should be signed? */
+ workBits24 = ((*((UINT64*)D.addr)) & U64(0x000000ffffff0000)) >> 16;
+ workBits24--;
+ workBits24 &= 0x00ffffff; /* Solves -x issues */
- PC += branchOffset ;
+ /* Set the D bits with the dec result */
+ *((UINT64*)D.addr) &= U64(0x000000000000ffff);
+ *((UINT64*)D.addr) |= (((UINT64)(workBits24)) << 16);
- retSize = 0 ; // Branch and then no offset.
+ d_register->addr = D.addr;
+ d_register->data_type = D.data_type;
- change_pc(PC) ;
+ /* S L E U N Z V C */
+ /* * * * * * ? * * */
+ /* TODO: S, L, E, U, V, C */
+ if ( *((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(1);
+ if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) Z_bit_set(1);
- return retSize ;
+ cycles += 2; /* TODO: + mv oscillator clock cycles */
+ return 1;
}
-static int JsrOperation(void)
+/* AND : .... .... 0110 F1JJ : A-24 */
+static size_t dsp56k_op_and(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
{
- int retSize = 0;
+ typed_pointer S = {NULL, DT_BYTE};
+ typed_pointer D = {NULL, DT_BYTE};
+
+ decode_JJF_table(BITS(op_byte,0x0003), BITS(op_byte,0x0008), &S, &D);
+
+ /* Save some data for the parallel move */
+ *p_accum = *((UINT64*)D.addr);
+
+ /* AND a word of S with A1|B1 */
+ ((PAIR64*)D.addr)->w.h = *((UINT16*)S.addr) & ((PAIR64*)D.addr)->w.h;
+
+ /* S L E U N Z V C */
+ /* * * - - ? ? 0 - */
+ /* TODO: S, L */
+ if ( *((UINT64*)D.addr) & U64(0x0000000080000000)) N_bit_set(1);
+ if ((*((UINT64*)D.addr) & U64(0x00000000ffff0000)) == 0) Z_bit_set(1);
+ V_bit_set(0);
- // Handle other JSR types!
- INT16 branchOffset = (ROPCODE((PC<<1)+2)) ; // Can this offset by 2 bytes be handled better? Say, for example, by moving "1 word"?
+ cycles += 2; /* TODO: + mv oscillator cycles */
+ return 1;
+}
- // The docs say nothing of this, but I swear it *must* be true
- PC += 2 ;
- core.ppc = PC ;
+/* ABS : .... .... 0111 F001 : A-18 */
+static size_t dsp56k_op_abs(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * - */
+ return 0;
+}
- // See bsr operation
- SP++;
- SSH = PC;
- SSL = SR;
+/* ROR : .... .... 0111 F010 : A-192 */
+static size_t dsp56k_op_ror(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * - - ? ? 0 ? */
+ /* N - Set if bit 31 of the result is set. Cleared otherwise. */
+ /* Z - Set if bits 16-31 of the result are zero. Cleared otherwise. */
+ /* C - Set if bit 16 of the source operand is set. Cleared otherwise. */
+ return 0;
+}
- PC = branchOffset;
+/* ROL : .... .... 0111 F011 : A-190 */
+static size_t dsp56k_op_rol(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * - - ? ? 0 ? */
+ /* N - Set if bit 31 of the result is set. Cleared otherwise. */
+ /* Z - Set if bits 16-31 of the result are zero. Cleared otherwise. */
+ /* C - Set if bit 31 of the source operand is set. Cleared otherwise. */
+ return 0;
+}
- return retSize;
+/* CMPM : .... .... 0111 FJJJ : A-66 */
+static size_t dsp56k_op_cmpm(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * * */
+ return 0;
}
-static int BraOperation(void)
+/* 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)
{
- int retSize = 0 ;
+ /* S L E U N Z V C */
+ /* * * * * * * * - */
+ return 0;
+}
- // Branch to the location in program memory at location PC+displacement.
- INT16 branchOffset = 0x00;
+/* MPYR : .... .... 1k01 FQQQ : A-162 */
+static size_t dsp56k_op_mpyr(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * - */
+ return 0;
+}
- if (BITS(OP,0x0800))
- {
- // 8 bit immediate (relative) offset
- branchOffset = (INT8)BITS(OP,0x00ff) ;
+/* MAC : .... .... 1k10 FQQQ : A-122 */
+static size_t dsp56k_op_mac(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * - */
+ return 0;
+}
- // "The PC Contains the address of the next instruction"
- PC += 1 ;
- }
- else if (BITS(OP,0x0010))
- {
- // 16 bit immediate (relative) offset
- retSize = 666 ;
- }
- else if (!BITS(OP,0x0010))
- {
- // 16 bit Rx offset
- retSize = 666 ;
- }
+/* MACR : .... .... 1k11 FQQQ : A-124 -- DRAMA - rr vs xx (805) */
+static size_t dsp56k_op_macr(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * * * * * * - */
+ return 0;
+}
- core.ppc = PC ;
- PC += branchOffset ;
- change_pc(PC) ;
+/******************************/
+/* Remaining non-parallel ops */
+/******************************/
- return retSize ;
+/* ADC : 0001 0101 0000 F01J : A-20 */
+static size_t dsp56k_op_adc(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * * * * * * * */
+ return 0;
}
+/* ANDI : 0001 1EE0 iiii iiii : A-26 */
+static size_t dsp56k_op_andi(const UINT16 op, UINT8* cycles)
+{
+ UINT16 immediate = BITS(op,0x00ff);
+
+ /* There is not currently a good way to refer to CCR or MR. Explicitly decode here. */
+ switch(BITS(op,0x0600))
+ {
+ case 0x01: /* MR */
+ SR &= ((immediate << 8) | 0x00ff);
+ break;
+
+ case 0x02: /* CCR */
+ SR &= (immediate | 0xff00);
+ break;
+
+ case 0x03: /* OMR */
+ OMR &= (UINT8)(immediate);
+ break;
-static int DoOperation(void)
+ default:
+ fatalerror("DSP56k - BAD EE value in andi operation") ;
+ }
+
+ /* S L E U N Z V C */
+ /* - ? ? ? ? ? ? ? */
+ /* All ? bits - Cleared if the corresponding bit in the immediate data is cleared and if the operand
+ is the CCR. Not affected otherwise. */
+ cycles += 2;
+ return 1;
+}
+
+/* ASL4 : 0001 0101 0011 F001 : A-30 */
+static size_t dsp56k_op_asl4(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - ? * * * * ? ? */
+ /* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if bit 5 through 39 are
+ not the same. */
+ /* C - Set if bit 36 of source operand is set. Cleared otherwise. */
+ return 0;
+}
+
+/* ASR4 : 0001 0101 0011 F000 : A-34 */
+static size_t dsp56k_op_asr4(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * * * * * 0 ? */
+ /* C - Set if bit 3 of source operand is set. Cleared otherwise. */
+ return 0;
+}
+
+/* ASR16 : 0001 0101 0111 F000 : A-36 */
+static size_t dsp56k_op_asr16(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * * * * * 0 ? */
+ /* C - Set if bit 15 of source operand is set. Cleared otherwise. */
+ return 0;
+}
+
+/* BFCHG : 0001 0100 11Pp pppp BBB1 0010 iiii iiii : A-38 */
+/* BFCLR : 0001 0100 11Pp pppp BBB0 0100 iiii iiii : A-40 */
+/* BFSET : 0001 0100 11Pp pppp BBB1 1000 iiii iiii : A-42 */
+/* BFTSTH : 0001 0100 01Pp pppp BBB1 0000 iiii iiii : A-44 */
+/* BFTSTL : 0001 0100 01Pp pppp BBB0 0000 iiii iiii : A-46 */
+static size_t dsp56k_op_bfop(const UINT16 op, const UINT16 op2, UINT8* cycles)
{
- int retSize = 0 ;
+ /* S L E U N Z V C */
+ /* - * - - - - - ? */
+ /* C - Set if all bits specified by the mask are set. Cleared otherwise. Ignore bits which are
+ not set in the mask. (BFCHG, BFSET, BFTSTH) */
+ /* C - Set if all bits specified by the mask are cleared. Cleared otherwise. Ignore bits which
+ are not set in the mask. (BFCLR, BFTSTL) */
+ return 0;
+}
- UINT16 offset ;
+/* BFCHG : 0001 0100 101- --RR BBB1 0010 iiii iiii : A-38 */
+/* BFCLR : 0001 0100 101- --RR BBB0 0100 iiii iiii : A-40 */
+/* BFSET : 0001 0100 101- --RR BBB1 1000 iiii iiii : A-42 */
+/* BFTSTH : 0001 0100 001- --RR BBB1 0000 iiii iiii : A-44 */
+/* BFTSTL : 0001 0100 001- --RR BBB0 0000 iiii iiii : A-46 */
+static size_t dsp56k_op_bfop_1(const UINT16 op, const UINT16 op2, UINT8* cycles)
+{
+ UINT16 workAddr = 0x0000;
+ UINT16 workingWord = 0x0000;
+ UINT16 previousValue = 0x0000;
+ typed_pointer R = { NULL, DT_BYTE };
+ typed_pointer tempTP = { NULL, DT_BYTE };
- // First instruction cycle
- SP++ ;
- SSH = LA ;
- SSL = LC ;
+ UINT16 iVal = op2 & 0x00ff;
- if (BITS(OP,0x0800))
- {
- // #xx,expr
- LC = BITS(OP,0x00ff) ;
- retSize = 2 ;
- }
- else if (BITS(OP,0x0400))
- {
- // S,expr
- unsigned char sdt = 0x00 ;
- void *SD ;
+ decode_RR_table(BITS(op,0x0003), &R);
+ decode_BBB_bitmask(BITS(op2,0xe000), &iVal);
- // !!! Watch out for the special cases (FamilyManual page 276) !!!
- SD = DecodeDDDDDTable(BITS(OP,0x001f), &sdt) ;
- SetDestinationValue(SD, sdt, &LC, DT_WORD) ;
- retSize = 2 ;
- }
- else
+ workAddr = *((UINT16*)R.addr);
+ previousValue = data_read_word_16le(WORD(workAddr));
+ workingWord = previousValue;
+
+ switch(BITS(op2, 0x1f00))
{
- // X:(Rn),expr
- retSize = 666 ;
+ case 0x12: /* BFCHG */
+ workingWord = ~workingWord;
+ workingWord &= iVal;
+ break;
+ case 0x04: /* BFCLR */
+ workingWord = workingWord & (~iVal);
+ break;
+ case 0x18: /* BFSET */
+ workingWord = workingWord | iVal;
+ break;
+ case 0x10: /* BFTSTH */
+ /* Just the test below */
+ break;
+ case 0x00: /* BFTSTL */
+ /* Just the test below */
+ break;
}
+ tempTP.addr = &workingWord;
+ tempTP.data_type = DT_WORD;
+ SetDataMemoryValue(tempTP, WORD(workAddr));
- // Second instruction cycle
- SP++ ;
- SSH = PC+2 ; // The value in the Program Counter (PC) register pushed onto the system stack is the address of the first instruction following the DO instruction
- SSL = SR ;
-
- offset = 0x00 ; // The offset is the same for all DO instructions...
- offset = (ROPCODE((PC<<1)+2)) ;
- offset += PC+2 ;
- LA = offset ;
+ /* S L E U N Z V C */
+ /* - * - - - - - ? */
+ switch(BITS(op2, 0x1f00))
+ {
+ case 0x12: /* BFCHG */
+ if ((iVal & previousValue) == iVal) C_bit_set(1); break;
+ case 0x04: /* BFCLR */
+ if ((iVal & previousValue) == iVal) C_bit_set(1); else C_bit_set(0); break;
+ case 0x18: /* BFSET */
+ if ((iVal & previousValue) == iVal) C_bit_set(1); break;
+ case 0x10: /* BFTSTH */
+ if ((iVal & previousValue) == iVal) C_bit_set(1); break;
+ case 0x00: /* BFTSTL */
+ if ((iVal & previousValue) == 0x0000) C_bit_set(1); break;
+ }
+ cycles += 4; /* TODO: + mvb oscillator clock cycles */
+ return 2;
+}
- // Third instruction cycle
- LF_bit_set(1);
+/* BFCHG : 0001 0100 100D DDDD BBB1 0010 iiii iiii : A-38 */
+/* BFCLR : 0001 0100 100D DDDD BBB0 0100 iiii iiii : A-40 */
+/* BFSET : 0001 0100 100D DDDD BBB1 1000 iiii iiii : A-42 */
+/* BFTSTH : 0001 0100 000D DDDD BBB1 0000 iiii iiii : A-44 */
+/* BFTSTL : 0001 0100 000D DDDD BBB0 0000 iiii iiii : A-46 */
+static size_t dsp56k_op_bfop_2(const UINT16 op, const UINT16 op2, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * - - - - - ? */
+ /* C - Set if all bits specified by the mask are set. Cleared otherwise. Ignore bits which are
+ not set in the mask. (BFCHG, BFSET, BFTSTH) */
+ /* C - Set if all bits specified by the mask are cleared. Cleared otherwise. Ignore bits which
+ are not set in the mask. (BFCLR, BFTSTL) */
+ return 0;
+}
- return retSize ;
+/* Bcc : 0000 0111 --11 cccc xxxx xxxx xxxx xxxx : A-48 */
+static size_t dsp56k_op_bcc(const UINT16 op, const UINT16 op2, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
}
-static void EndOfLoopProcessing(void)
+/* Bcc : 0010 11cc ccee eeee : A-48 */
+static size_t dsp56k_op_bcc_1(const UINT16 op, UINT8* cycles)
{
- SR = SSL ;
- SP-- ;
- LA = SSH ;
- LC = SSL ;
- SP-- ;
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
}
-static int Dec24Operation(void **wd, UINT64 *pa)
+/* Bcc : 0000 0111 RR10 cccc : A-48 */
+static size_t dsp56k_op_bcc_2(const UINT16 op, UINT8* cycles)
{
- int retSize = 1 ;
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- UINT64 decMe ;
+/* BRA : 0000 0001 0011 11-- xxxx xxxx xxxx xxxx : A-50 */
+static size_t dsp56k_op_bra(const UINT16 op, const UINT16 op2, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- unsigned char drt = 0x00 ;
- void *D = 0x00 ;
- D = DecodeFTable(BITS(OP,0x0008), &drt) ;
+/* BRA : 0000 1011 aaaa aaaa : A-50 */
+static size_t dsp56k_op_bra_1(const UINT16 op, UINT8* cycles)
+{
+ /* 8 bit immediate, relative offset */
+ INT8 branchOffset = (INT8)BITS(op,0x00ff);
- *pa = *((UINT64*)D) ; // backup the previous value
+ /* "The PC Contains the address of the next instruction" */
+ PC += 1;
- // !! I wonder if this should be a signed int instead !!
- decMe = (*((UINT64*)D) & (UINT64)U64(0xffffff0000)) >> 16 ;
- decMe-- ;
- decMe &= (UINT64)U64(0x0000000000ffffff) ; // For wraparound - Make sure no bits get set improperly in A/B
+ /* Jump */
+ core.ppc = PC;
+ PC += branchOffset;
+ change_pc(PC);
-// UINT8 carryBit = (*((UINT64*)D) & 0x0000008000000000) >> 39 ; // For determinating carry status...
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ cycles += 4; /* TODO: + jx oscillator clock cycles */
+ return 0;
+}
- *((UINT64*)D) &= (UINT64)U64(0x000000000000ffff) ; // Prepare the destination to be set...
- *((UINT64*)D) |= (decMe << 16) ; // Set the top 24 bits accordingly...
+/* BRA : 0000 0001 0010 11RR : A-50 */
+static size_t dsp56k_op_bra_2(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- // Carry flag (C) - HACK
-// if (decMe == 0x0000000000ff7fff)
-// SET_cBIT() ;
-// else
-// CLEAR_cBIT() ;
+/* BRKc : 0000 0001 0001 cccc : A-52 */
+static size_t dsp56k_op_brkc(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- // Carry flag (C)
-// UINT8 postCarryBit = (*((UINT64*)D) & 0x0000008000000000) >> 39 ;
-// if (postCarryBit != carryBit) SET_cBIT() ;
-// else CLEAR_cBIT() ;
+/* BScc : 0000 0111 --01 cccc xxxx xxxx xxxx xxxx : A-54 */
+static size_t dsp56k_op_bscc(const UINT16 op, const UINT16 op2, UINT8* cycles)
+{
+ int shouldBranch = decode_cccc_table(BITS(op,0x000f));
- *wd = D ;
+ if (shouldBranch)
+ {
+ /* The PC Contains the address of the next instruction */
+ PC += 2;
-/*
- UINT32 decMe = ((*((PAIR64*)D)).b.h4 << 16) | (*((PAIR64*)D)).w.h ;
+ /* Push */
+ SP++;
+ SSH = PC;
+ SSL = SR;
- int fflag = 0 ;
- if (decMe == 0x00007fff) fflag = 1 ;
+ /* Change */
+ core.ppc = PC;
+ PC = PC + (INT16)op2;
+ change_pc(PC);
+ }
- if (fflag) mame_printf_debug("%08x\n", decMe) ;
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ cycles += 4; /* TODO: + jx oscillator clock cycles */
+ return 2;
+}
- decMe-- ;
+/* BScc : 0000 0111 RR00 cccc : A-54 */
+static size_t dsp56k_op_bscc_1(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- if (fflag) mame_printf_debug("%08x\n", decMe) ;
+/* BSR : 0000 0001 0011 10-- xxxx xxxx xxxx xxxx : A-56 */
+static size_t dsp56k_op_bsr(const UINT16 op, const UINT16 op2, UINT8* cycles)
+{
+ /* The PC Contains the address of the next instruction */
+ PC += 2;
- decMe &= 0x00ffffff ;
+ /* Push */
+ SP++;
+ SSH = PC;
+ SSL = SR;
- if (fflag) mame_printf_debug("%08x\n", decMe) ;
+ /* Change */
+ core.ppc = PC;
+ PC = PC + (INT16)op2;
+ change_pc(PC);
- UINT8 carryBit = ((*((PAIR64*)D)).b.h4 & 0x80) >> 7 ;
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ cycles += 4; /* TODO: + jx oscillator clock cycles */
+ return 0;
+}
- (*((PAIR64*)D)).b.h4 = (decMe & 0x00ff0000) >> 16 ;
- (*((PAIR64*)D)).w.h = (decMe & 0x0000ffff) ;
+/* BSR : 0000 0001 0010 10RR : A-56 */
+static size_t dsp56k_op_bsr_1(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- if (fflag) mame_printf_debug("%2x\n", (*((PAIR64*)D)).b.h4) ;
- if (fflag) mame_printf_debug("%4x\n", (*((PAIR64*)D)).w.h) ;
+/* CHKAAU : 0000 0000 0000 0100 : A-58 */
+static size_t dsp56k_op_chkaau(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - ? ? ? - */
+ /* V - Set if the result of the last address ALU update performed a modulo wrap. Cleared if
+ result of the last address ALU did not perform a modulo wrap.*/
+ /* Z - Set if the result of the last address ALU update is 0. Cleared if the result of the last
+ address ALU is positive. */
+ /* N - Set if the result of the last address ALU update is negative. Cleared if the result of the
+ last address ALU is positive. */
+ return 0;
+}
- // Carry flag (C)
- UINT8 postCarryBit = ((*((PAIR64*)D)).b.h4 & 0x80) >> 7 ;
- if (postCarryBit != carryBit) SET_cBIT() ;
- else CLEAR_cBIT() ;
+/* DEBUG : 0000 0000 0000 0001 : A-68 */
+static size_t dsp56k_op_debug(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- *wd = D ;
-*/
- return retSize ;
+/* DEBUGcc : 0000 0000 0101 cccc : A-70 */
+static size_t dsp56k_op_debugcc(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
}
-static int AddOperation(void **wd, UINT64 *pa)
+/* DIV : 0001 0101 0--0 F1DD : A-76 */
+/* WARNING : DOCS SAY THERE IS A PARALLEL MOVE HERE !!! */
+static size_t dsp56k_op_div(const UINT16 op, UINT8* cycles)
{
- UINT64 addVal = 0x00;
+ /* S L E U N Z V C */
+ /* - * - - - - ? ? */
+ /* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if the most significantst
+ bit of the destination operand is changed as a result of the left shift. Cleared otherwise. */
+ /* C - Set if bit 39 of the result is cleared. Cleared otherwise. */
+ return 0;
+}
- unsigned char st = 0x00, dt = 0x00 ;
- void *S = 0x00, *D = 0x00;
+/* DMAC : 0001 0101 10s1 FsQQ : A-80 */
+static size_t dsp56k_op_dmac(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * * * * * * - */
+ return 0;
+}
- DecodeJJJFTable(BITS(OP,0x0007),BITS(OP,0x0008), &S, &st, &D, &dt) ;
+/* DO : 0000 0000 110- --RR xxxx xxxx xxxx xxxx : A-82 */
+static size_t dsp56k_op_do(const UINT16 op, const UINT16 op2, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * - - - - - - */
+ return 0;
+}
- *pa = *((UINT64*)D) ; // backup the previous value
+/* DO : 0000 1110 iiii iiii xxxx xxxx xxxx xxxx : A-82 */
+static size_t dsp56k_op_do_1(const UINT16 op, const UINT16 op2, UINT8* cycles)
+{
+ UINT8 iValue = BITS(op,0x00ff);
- switch(st)
+ /* Don't execute if the loop counter == 0 */
+ if (iValue != 0x00)
{
- case DT_WORD: addVal = (UINT64)*((UINT16*)S) << 16 ; break ;
- case DT_DOUBLE_WORD: addVal = (UINT64)*((UINT32*)S) ; break ;
- case DT_LONG_WORD: addVal = (UINT64)*((UINT64*)S) ; break ;
- }
+ /* First instruction cycle */
+ SP++; /* TODO: Should i really inc here first? */
+ SSH = LA;
+ SSL = LC;
+ LC = (UINT16)iValue;
- *((UINT64*)D) += addVal ;
- *wd = D ;
+ /* Second instruction cycle */
+ SP++; /* TODO: See above */
+ SSH = PC + 2; /* Keep these stack entries in 'word-based-index' space */
+ SSL = SR;
+ LA = PC + 2 + op2; /* TODO: The docs subtract 1 from here? */
- return 1 ;
-}
-
-static int LsrOperation(void **wd, UINT64 *pa)
-{
- int retSize = 1 ;
-
- UINT16 result ;
- unsigned char dt = 0x00 ;
- void *D = 0x00 ;
+ /* Third instruction cycle */
+ LF_bit_set(1);
- D = DecodeFTable(BITS(OP,0x0008), &dt) ;
- *pa = *((UINT64*)D) ; // backup the previous value
+ /* S L E U N Z V C */
+ /* - * - - - - - - */
+ /* TODO : L */
- // !!! Make sure to hold the MS bit and shift the LS bit properly !!!
-
- result = (*((PAIR64*)D)).w.h >> 1 ;
- (*((PAIR64*)D)).w.h = result ;
+ cycles += 6; /* TODO: + mv oscillator cycles */
+ }
+ else
+ {
+ cycles += 10; /* TODO: + mv oscillator cycles */
+ }
- *wd = D ;
- return retSize ;
+ return 2;
}
-static int AsrOperation(void **wd, UINT64 *pa)
+/* DO : 0000 0100 000D DDDD xxxx xxxx xxxx xxxx : A-82 */
+static size_t dsp56k_op_do_2(const UINT16 op, const UINT16 op2, UINT8* cycles)
{
- int retSize = 1 ;
+ UINT16 lValue = 0x0000;
+ typed_pointer S = {NULL, DT_BYTE};
+ decode_DDDDD_table(BITS(op,0x001f), &S);
- unsigned char dt = 0x00 ;
- void *D = 0x00 ;
+ /* TODO: Does not work for sources A&B - Fix per the docs */
+ lValue = *((UINT16*)S.addr);
- D = DecodeFTable(BITS(OP,0x0008), &dt) ;
+ /* TODO: Fix for special cased SP S */
+ if (S.addr == &SP)
+ logerror("DSP56k: do with SP as the source not properly implemented yet.\n");
- *pa = *((UINT64*)D) ; // backup the previous value
+ /* TODO: Fix for special cased SSSL S */
+ if (S.addr == &SSL)
+ logerror("DSP56k: do with SP as the source not properly implemented yet.\n");
- // !!! Make sure to hold the MS bit and shift the LS bit properly !!!
+ /* Don't execute if the loop counter == 0 */
+ if (lValue != 0x00)
+ {
+ /* First instruction cycle */
+ SP++; /* TODO: Should i really inc here first? */
+ SSH = LA;
+ SSL = LC;
+ LC = (UINT16)lValue;
- *((UINT64*)D) = (*((UINT64*)D)) >> 1 ;
- *wd = D ;
- return retSize ;
-}
+ /* Second instruction cycle */
+ SP++; /* TODO: See above */
+ SSH = PC + 2; /* Keep these stack entries in 'word-based-index' space */
+ SSL = SR;
+ LA = PC + 2 + op2; /* TODO: The docs subtract 1 from here? */
-static int NotOperation(void **wd, UINT64 *pa)
-{
- int retSize = 1 ;
- unsigned char dt = 0x00 ;
- void *D = 0x00 ;
+ /* Third instruction cycle */
+ LF_bit_set(1);
- D = DecodeFTable(BITS(OP,0x0008), &dt) ;
- *pa = *((UINT64*)D) ; // backup the previous value
+ /* S L E U N Z V C */
+ /* - * - - - - - - */
+ /* TODO : L */
- (*((PAIR64*)D)).w.h ^= 0xffff ;
+ cycles += 6; /* TODO: + mv oscillator cycles */
+ }
+ else
+ {
+ cycles += 10; /* TODO: + mv oscillator cycles */
+ }
- *wd = D ;
- return retSize ;
+ return 2;
}
-
-static int EorOperation(void **wd, UINT64 *pa)
+/* DO FOREVER : 0000 0000 0000 0010 xxxx xxxx xxxx xxxx : A-88 */
+static size_t dsp56k_op_doforever(const UINT16 op, const UINT16 op2, UINT8* cycles)
{
- int retSize = 1 ;
-
- UINT16 result ;
-
- unsigned char st = 0x00, dt = 0x00 ;
- void *S = 0x00, *D = 0x00;
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- DecodeJJFTable(BITS(OP,0x0003),BITS(OP,0x0008), &S, &st, &D, &dt) ;
+/* ENDDO : 0000 0000 0000 1001 : A-92 */
+static size_t dsp56k_op_enddo(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- *pa = *((UINT64*)D) ; // backup the previous value
+/* EXT : 0001 0101 0101 F010 : A-96 */
+static size_t dsp56k_op_ext(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * * * * * * - */
+ return 0;
+}
- // This operation does an XOR of a word of S with A1/B1...
- result = *((UINT16*)S) ^ (*((PAIR64*)D)).w.h ;
- (*((PAIR64*)D)).w.h = result ;
+/* ILLEGAL : 0000 0000 0000 1111 : A-98 */
+static size_t dsp56k_op_illegal(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- *wd = D ;
- return retSize ;
+/* IMAC : 0001 0101 1010 FQQQ : A-100 */
+static size_t dsp56k_op_imac(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * ? ? * ? ? - */
+ /* Z - Set if the 24 most significant bits of the destination result are all zeroes. */
+ /* U,E - Will not be set correctly by this instruction*/
+ /* V - Set to zero regardless of the overflow */
+ return 0;
}
-static int TfrDataALUOperation(void **wd, UINT64 *pa)
+/* IMPY : 0001 0101 1000 FQQQ : A-102 */
+static size_t dsp56k_op_impy(const UINT16 op, UINT8* cycles)
{
- int retSize = 1 ;
+ /* S L E U N Z V C */
+ /* - * ? ? * ? ? - */
+ /* Z - Set if the 24 most significant bits of the destination result are all zeroes. */
+ /* U,E - Will not be set correctly by this instruction*/
+ /* V - Set to zero regardless of the overflow */
+ return 0;
+}
- unsigned char st = 0x00, dt = 0x00 ;
- void *S = 0x00, *D = 0x00;
+/* Jcc : 0000 0110 --11 cccc xxxx xxxx xxxx xxxx : A-108 */
+static size_t dsp56k_op_jcc(const UINT16 op, const UINT16 op2, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- DecodeJJJFTable(BITS(OP,0x0007),BITS(OP,0x0008), &S, &st, &D, &dt) ;
+/* Jcc : 0000 0110 RR10 cccc : A-108 */
+static size_t dsp56k_op_jcc_1(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- *pa = *((UINT64*)D) ; // backup the previous value
+/* JMP : 0000 0001 0011 01-- xxxx xxxx xxxx xxxx : A-110 */
+static size_t dsp56k_op_jmp(const UINT16 op, const UINT16 op2, UINT8* cycles)
+{
+ core.ppc = PC;
+ PC = op2;
+ change_pc(PC);
- SetDestinationValue(S, st, D, dt) ;
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
- *wd = D ;
- return retSize ;
+ cycles += 4; /* TODO: + jx */
+ return 0;
}
-static int AndOperation(void **wd, UINT64 *pa)
+/* JMP : 0000 0001 0010 01RR : A-110 */
+static size_t dsp56k_op_jmp_1(const UINT16 op, UINT8* cycles)
{
- int retSize = 1 ;
+ typed_pointer R = { NULL, DT_BYTE };
+ decode_RR_table(BITS(op,0x0003), &R);
- UINT16 result ;
+ core.ppc = PC;
+ PC = *((UINT16*)R.addr);
+ change_pc(PC);
- unsigned char st = 0x00, dt = 0x00 ;
- void *S = 0x00, *D = 0x00;
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
- DecodeJJFTable(BITS(OP,0x0003),BITS(OP,0x0008), &S, &st, &D, &dt) ;
+ cycles += 4; /* TODO: + jx */
+ return 0;
+}
- *pa = *((UINT64*)D) ; // backup the previous value
+/* JScc : 0000 0110 --01 cccc xxxx xxxx xxxx xxxx : A-112 */
+static size_t dsp56k_op_jscc(const UINT16 op, const UINT16 op2, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- // This operation does an AND of a word of S with A1/B1...
- result = *((UINT16*)S) & (*((PAIR64*)D)).w.h ;
- (*((PAIR64*)D)).w.h = result ;
+/* JScc : 0000 0110 RR00 cccc : A-112 */
+static size_t dsp56k_op_jscc_1(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- *wd = D ;
- return retSize ;
+/* JSR : 0000 0001 0011 00-- xxxx xxxx xxxx xxxx : A-114 */
+static size_t dsp56k_op_jsr(const UINT16 op, const UINT16 op2, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
}
-static int OrOperation(void **wd, UINT64 *pa)
+/* JSR : 0000 1010 AAAA AAAA : A-114 */
+static size_t dsp56k_op_jsr_1(const UINT16 op, UINT8* cycles)
{
- int retSize = 1 ;
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- UINT16 result ;
+/* JSR : 0000 0001 0010 00RR : A-114 */
+static size_t dsp56k_op_jsr_2(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- unsigned char st = 0x00, dt = 0x00 ;
- void *S = 0x00, *D = 0x00;
+/* LEA : 0000 0001 11TT MMRR : A-116 */
+static size_t dsp56k_op_lea(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- DecodeJJFTable(BITS(OP,0x0003),BITS(OP,0x0008), &S, &st, &D, &dt) ;
+/* LEA : 0000 0001 10NN MMRR : A-116 */
+static size_t dsp56k_op_lea_1(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- *pa = *((UINT64*)D) ; // backup the previous value
+/* MAC(su,uu) : 0001 0101 1110 FsQQ : A-126 */
+static size_t dsp56k_op_macsuuu(const UINT16 op, UINT8* cycles)
+{
+ UINT8 s = 0;
+ INT64 result = 0;
- // This operation does an OR of a word of S with A1/B1...
- result = *((UINT16*)S) | (*((PAIR64*)D)).w.h ;
- (*((PAIR64*)D)).w.h = result ;
+ void* D = NULL;
+ void* S1 = NULL;
+ void* S2 = NULL;
+
+ decode_QQF_special_table(BITS(op,0x0003), BITS(op,0x0008), &S1, &S2, &D);
+
+ s = BITS(op,0x0004);
+
+ /* Fixed-point 2's complement multiplication requires a shift */
+ if (s)
+ {
+ /* Unsigned * Unsigned */
+ UINT32 s1 = (UINT32)(*((UINT16*)S1));
+ UINT32 s2 = (UINT32)(*((UINT16*)S2));
+ result = ( s1 * s2 ) << 1;
+ }
+ else
+ {
+ /* Signed * Unsigned */
+ UINT32 s1 = (UINT32)((INT32)(*((UINT16*)S1)));
+ UINT32 s2 = (UINT32)(*((UINT16*)S2));
+ result = ( s1 * s2 ) << 1;
+ }
+
+ (*((UINT64*)D)) += result;
+
+ /* S L E U N Z V C */
+ /* - * * * * * * - */
+ /* TODO: L, E, U, V */
+ if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(1);
+ if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(1);
- *wd = D ;
- return retSize ;
+ cycles += 2;
+ return 1;
}
+/* MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 */
+static size_t dsp56k_op_move_2(const UINT16 op, const UINT16 op2, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * - - - - - - */
+ return 0;
+}
-static int TccOperation(void)
+/* MOVE(C) : 0011 1WDD DDD0 MMRR : A-144 */
+static size_t dsp56k_op_movec(const UINT16 op, UINT8* cycles)
{
- int retSize = 1 ;
+ UINT8 W;
+ typed_pointer R = { NULL, DT_BYTE };
+ typed_pointer SD = { NULL, DT_BYTE };
+
+ W = BITS(op,0x0400);
+ decode_DDDDD_table(BITS(op,0x03e0), &SD);
+ decode_RR_table(BITS(op,0x0003), &R);
- int transfer = DecodeccccTable(BITS(OP,0x03c0)) ;
+ if (W)
+ {
+ /* Write D */
+ UINT16 value = data_read_word_16le(WORD(*((UINT16*)R.addr))) ;
+ typed_pointer temp_src = { &value, DT_WORD };
+ SetDestinationValue(temp_src, SD);
+ }
+ else
+ {
+ /* Read S */
+ UINT16 dataMemOffset = *((UINT16*)R.addr);
+ SetDataMemoryValue(SD, WORD(dataMemOffset));
+ }
- // !!! WARNING === TESTING !!!
- // transfer = 1 ;
+ execute_MM_table(BITS(op,0x0003), BITS(op,0x000c));
- if (transfer)
+ /* S L E U N Z V C */
+ /* * ? ? ? ? ? ? ? */
+ /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
+ bit of the source operand. If SR is not specified as a destination operand, L is set if data
+ limiting occurred. All ? bits are not affected otherwise.*/
+ if (W && (SD.addr != &SR))
{
- unsigned char st = 0x00, dt = 0x00 ;
- void *S = 0x00, *D = 0x00;
+ /* If you're writing to something other than the SR */
+ /* TODO */
+ }
+
+ cycles += 2; /* TODO: + mvc */
+ return 1;
+}
- unsigned char drt = 0x00 ;
- void *destinationReg = 0x00 ;
+/* MOVE(C) : 0011 1WDD DDD1 q0RR : A-144 */
+static size_t dsp56k_op_movec_1(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * ? ? ? ? ? ? ? */
+ /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
+ bit of the source operand. If SR is not specified as a destination operand, L is set if data
+ limiting occurred. All ? bits are not affected otherwise.*/
+ return 0;
+}
- Decodeh0hFTable(BITS(OP,0x0007),BITS(OP,0x0008), &S, &st, &D, &dt) ;
+/* MOVE(C) : 0011 1WDD DDD1 Z11- : A-144 */
+static size_t dsp56k_op_movec_2(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * ? ? ? ? ? ? ? */
+ /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
+ bit of the source operand. If SR is not specified as a destination operand, L is set if data
+ limiting occurred. All ? bits are not affected otherwise.*/
+ return 0;
+}
- SetDestinationValue(S, st, D, dt) ;
+/* MOVE(C) : 0011 1WDD DDD1 t10- xxxx xxxx xxxx xxxx : A-144 */
+static size_t dsp56k_op_movec_3(const UINT16 op, const UINT16 op2, UINT8* cycles)
+{
+ UINT8 W;
+ UINT8 t;
+ typed_pointer SD = { NULL, DT_BYTE };
- // !!! What's up with that A,A* thing in the docs? Does that mean "do not transfer R0 to Rn ???
- destinationReg = DecodeRRTable(BITS(OP,0x0030), &drt) ; // Actually a TT table, but it's the same
+ W = BITS(op,0x0400);
+ t = BITS(op,0x0008);
+ decode_DDDDD_table(BITS(op,0x03e0), &SD);
- SetDestinationValue(&R0, DT_WORD, destinationReg, drt) ;
+ if (W)
+ {
+ /* Write D */
+ if (t)
+ {
+ /* 16-bit long data */
+ typed_pointer temp_src = { (void*)&op2, DT_WORD };
+ SetDestinationValue(temp_src, SD);
+ }
+ else
+ {
+ /* 16-bit long address */
+ UINT16 tempD = data_read_word_16le(WORD(op2));
+ typed_pointer tempTP = {&tempD, DT_WORD};
+ SetDestinationValue(tempTP, SD);
+ }
+ }
+ else
+ {
+ /* Read S */
+ if (t)
+ {
+ /* 16-bit long data */
+ logerror("DSP56k: Movec - I don't think this exists?");
+ }
+ else
+ {
+ /* 16-bit long address */
+ SetDataMemoryValue(SD, WORD(op2));
+ }
}
- // Otherwise it's a NOP
+ /* S L E U N Z V C */
+ /* * ? ? ? ? ? ? ? */
+ /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
+ bit of the source operand. If SR is not specified as a destination operand, L is set if data
+ limiting occurred. All ? bits are not affected otherwise.*/
+ if (W && (SD.addr != &SR))
+ {
+ /* If you're writing to something other than the SR */
+ /* TODO */
+ }
- return retSize ;
+ cycles += 2; /* TODO: + mvc */
+ return 2;
}
-static int ClrOperation(void **wd, UINT64 *pa)
+/* MOVE(C) : 0010 10dd dddD DDDD : A-144 */
+static size_t dsp56k_op_movec_4(const UINT16 op, UINT8* cycles)
{
- int retSize = 1 ;
-
- UINT64 clearValue = 0 ;
-
- unsigned char drt = 0x00 ;
- void *destinationReg = 0x00 ;
+ typed_pointer S = {NULL, DT_BYTE};
+ typed_pointer D = {NULL, DT_BYTE};
- destinationReg = DecodeFTable(BITS(OP,0x0008), &drt) ;
+ decode_DDDDD_table(BITS(op,0x03e0), &S);
+ decode_DDDDD_table(BITS(op,0x001f), &D);
- *pa = *((UINT64*)destinationReg) ; // backup the previous value
+ SetDestinationValue(S, D);
- SetDestinationValue(&clearValue, DT_LONG_WORD, destinationReg, drt) ;
+ /* S L E U N Z V C */
+ /* * ? ? ? ? ? ? ? */
+ /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
+ bit of the source operand. If SR is not specified as a destination operand, L is set if data
+ limiting occurred. All ? bits are not affected otherwise.*/
+ if (D.addr != &SR)
+ {
+ /* If you're writing to something other than the SR */
+ /* TODO */
+ }
- *wd = destinationReg ;
- return retSize ;
+ cycles += 2;
+ return 1;
}
-static int TstOperation(void **wd, UINT64 *pa)
+/* MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 */
+static size_t dsp56k_op_movec_5(const UINT16 op, const UINT16 op2, UINT8* cycles)
{
- int retSize = 1 ;
-
- unsigned char drt = 0x00 ;
- void *destinationReg = 0x00 ;
- destinationReg = DecodeFTable(BITS(OP,0x0008), &drt) ;
+ /* S L E U N Z V C */
+ /* * ? ? ? ? ? ? ? */
+ /* All ? bits - If SR is specified as a destination operand, set according to the corresponding
+ bit of the source operand. If SR is not specified as a destination operand, L is set if data
+ limiting occurred. All ? bits are not affected otherwise.*/
+ return 0;
+}
- // S - "computed according to the standard definition (section A.4)"
- // L - can't be done until after data move
- // E - set if signed integer portion is in use
- // U - set according to the standard definition of the U bit
- // N - set if bit 39 is set
- if (*((UINT64*)destinationReg) & (UINT64)U64(0x8000000000)) N_bit_set(1);
- else N_bit_set(0);
+/* MOVE(I) : 0010 00DD BBBB BBBB : A-150 */
+static size_t dsp56k_op_movei(const UINT16 op, UINT8* cycles)
+{
+ typed_pointer D = {NULL, DT_BYTE};
+ typed_pointer immTP = {NULL, DT_BYTE};
- // Z - set if == 0
- if (*((UINT64*)destinationReg) == 0) Z_bit_set(1);
- else Z_bit_set(0);
+ /* Typecasting to INT16 sign-extends the BBBBBBBB operand */
+ UINT16 immediateSignExtended = (INT16)(op & 0x00ff);
+ immTP.addr = &immediateSignExtended;
+ immTP.data_type = DT_WORD;
- // V&C - always cleared
- V_bit_set(0);
- C_bit_set(0);
+ decode_DD_table(BITS(op,0x0300), &D);
- *pa = *((UINT64*)destinationReg) ; // backup the previous value (no change here)
- *wd = destinationReg;
+ SetDestinationValue(immTP, D);
- return retSize ;
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ cycles += 2;
+ return 1;
}
-static int AndiOperation(void)
+/* MOVE(M) : 0000 001W RR0M MHHH : A-152 */
+static size_t dsp56k_op_movem(const UINT16 op, UINT8* cycles)
{
- int retSize = 1 ;
+ UINT8 W;
+ typed_pointer R = { NULL, DT_BYTE };
+ typed_pointer SD = { NULL, DT_BYTE };
- UINT16 andMe = BITS(OP,0x00ff) ;
+ W = BITS(op,0x0100);
+ decode_RR_table(BITS(op,0x00c0), &R);
+ decode_HHH_table(BITS(op,0x0007), &SD);
- // Because I don't have a good way to access MR and CCR right now, i'm going to
- // hard-code decoding EE here and in the OriOperation as well...
- switch(BITS(OP,0x0600))
+ if (W)
{
- // MR
- case 0x01:
- SR &= ((andMe << 8) | 0x00ff) ;
- break ;
-
- // CCR
- case 0x03:
- SR &= ((andMe) | 0xff00) ;
- break ;
+ /* Read from Program Memory */
+ typed_pointer data;
+ UINT16 ldata = program_read_word_16le(WORD(*((UINT16*)R.addr)));
- // OMR
- case 0x02:
- OMR &= (UINT8)(andMe) ;
- break ;
-
- default:
- fatalerror("DSP56k - BAD EE value in andi operation") ;
+ data.addr = &ldata;
+ data.data_type = DT_WORD;
+ SetDestinationValue(data, SD) ;
+ }
+ else
+ {
+ /* Write to Program Memory */
+ SetProgramMemoryValue(SD, WORD(*((UINT16*)R.addr))) ;
}
+ execute_MM_table(BITS(op,0x00c0), BITS(op,0x0018));
- return retSize ;
+ /* S L E U N Z V C */
+ /* * * - - - - - - */
+ /* TODO: S, L */
+ cycles += 2; /* TODO: + mvm oscillator clock cycles */
+ return 1;
}
-#ifdef UNUSED_FUNCTION
-// !!! NOT IMPLEMENTED YET - JUST PUT HERE TO BE NEXT TO ANDI SOMEDAY !!!
-static int OriOperation(void)
+/* MOVE(M) : 0000 001W RR11 mmRR : A-152 */
+static size_t dsp56k_op_movem_1(const UINT16 op, UINT8* cycles)
{
- int retSize = 1 ;
-
- return retSize ;
+ /* S L E U N Z V C */
+ /* * * - - - - - - */
+ return 0;
}
-#endif
-static int CmpOperation(void **wd, UINT64 *pa)
+/* MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 */
+static size_t dsp56k_op_movem_2(const UINT16 op, const UINT16 op2, UINT8* cycles)
{
- int retSize = 1 ;
+ /* S L E U N Z V C */
+ /* * * - - - - - - */
+ return 0;
+}
- UINT64 cmpVal ;
- UINT64 result ;
+/* MOVE(P) : 0001 100W HH1p pppp : A-156 */
+static size_t dsp56k_op_movep(const UINT16 op, UINT8* cycles)
+{
+ UINT16 W;
+ UINT16 pp;
+ typed_pointer SD = {NULL, DT_BYTE};
- unsigned char st = 0x00, dt = 0x00 ;
- void *S = 0x00, *D = 0x00;
+ decode_HH_table(BITS(op,0x00c0), &SD);
+ /* TODO: Special cases for A & B */
- DecodeJJJFTable(BITS(OP,0x0007),BITS(OP,0x0008), &S, &st, &D, &dt) ;
+ pp = op & 0x001f;
+ pp = assemble_address_from_IO_short_address(pp);
- *pa = *((UINT64*)D) ; // backup the previous value - not necessary for cmp :)
+ W = BITS(op,0x0100);
- switch(st)
+ if (W)
{
- default:
- case DT_WORD: cmpVal = (UINT64)*((UINT16*)S) ; break ;
- case DT_DOUBLE_WORD: cmpVal = (UINT64)*((UINT32*)S) ; break ;
- case DT_LONG_WORD: cmpVal = (UINT64)*((UINT64*)S) ; break ;
- }
+ UINT16 data = data_read_word_16le(WORD(pp));
- result = *((UINT64*)D) - cmpVal ;
+ typed_pointer tempTP;
+ tempTP.addr = &data;
+ tempTP.data_type = DT_WORD;
- if (result == 0)
- Z_bit_set(1) ;
+ SetDestinationValue(tempTP, SD);
+ }
else
- Z_bit_set(0) ;
+ {
+ SetDataMemoryValue(SD, WORD(pp));
+ }
+
+ /* S L E U N Z V C */
+ /* * * - - - - - - */
+ /* TODO: S, L */
- *wd = D ;
- return retSize ;
+ cycles += 4; /* TODO: + mvp oscillator cycles */
+ return 1;
}
-static int BsccOperation(void)
+/* MOVE(P) : 0000 110W RRmp pppp : A-156 */
+static size_t dsp56k_op_movep_1(const UINT16 op, UINT8* cycles)
{
- int retSize = 0 ;
+ /* S L E U N Z V C */
+ /* * * - - - - - - */
+ return 0;
+}
- // Decode the condition
- int transfer = DecodeccccTable(BITS(OP,0x000f)) ;
+/* MOVE(S) : 0001 100W HH0a aaaa : A-158 */
+static size_t dsp56k_op_moves(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * - - - - - - */
+ return 0;
+}
- // TESTING !!!
- // transfer = 0 ;
+/* MPY(su,uu) : 0001 0101 1100 FsQQ : A-164 */
+static size_t dsp56k_op_mpysuuu(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * * * * * * - */
+ return 0;
+}
- // 1 or 2 word operation...
- if (transfer)
- {
- if (BITS(OP,0x0010))
- {
- // 2 word immediate offset...
- INT16 branchOffset = (INT16)ROPCODE((PC<<1)+2) ;
+/* NEGC : 0001 0101 0110 F000 : A-168 */
+static size_t dsp56k_op_negc(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * * * * * * * */
+ return 0;
+}
- // "The PC Contains the address of the next instruction"
- PC += 2 ;
- core.ppc = PC ;
+/* NOP : 0000 0000 0000 0000 : A-170 */
+static size_t dsp56k_op_nop(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- SP++ ;
- SSH = PC ;
- SSL = SR ;
+/* NORM : 0001 0101 0010 F0RR : A-172 */
+static size_t dsp56k_op_norm(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * * * * * ? - */
+ /* V - Set if an arithmetic overflow occurs in the 40 bit result. Also set if the most significantst
+ bit of the destination operand is changed as a result of the left shift. Cleared otherwise. */
+ return 0;
+}
- PC += branchOffset ;
+/* ORI : 0001 1EE1 iiii iiii : A-178 */
+static size_t dsp56k_op_ori(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - ? ? ? ? ? ? ? */
+ /* All ? bits - Set if the corresponding bit in the immediate data is set and if the operand is the
+ CCR. Not affected otherwise. */
+ return 0;
+}
- change_pc(PC) ;
- }
- else
- {
- // 1 word Rx offset...
- }
+/* REP : 0000 0000 111- --RR : A-180 */
+static size_t dsp56k_op_rep(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * - - - - - - */
+ return 0;
+}
- retSize = 0 ;
+/* REP : 0000 1111 iiii iiii : A-180 */
+static size_t dsp56k_op_rep_1(const UINT16 op, UINT8* cycles)
+{
+ /* TODO: This is non-interruptable, probably have to turn off interrupts here */
+ UINT16 iVal = op & 0x00ff;
+
+ if (iVal != 0)
+ {
+ TEMP = LC;
+ LC = iVal;
+
+ core.repFlag = 1;
+ core.repAddr = PC + WORD(1);
+
+ cycles += 4; /* TODO: + mv oscillator clock cycles */
}
else
{
- if (BITS(OP,0x0010))
- retSize = 2 ;
- else
- retSize = 1 ;
+ cycles += 6; /* TODO: + mv oscillator clock cycles */
}
+
+
+ /* S L E U N Z V C */
+ /* - * - - - - - - */
+ /* TODO */
+ return 1;
+}
- return retSize ;
+/* REP : 0000 0100 001D DDDD : A-180 */
+static size_t dsp56k_op_rep_2(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * - - - - - - */
+ return 0;
}
-static int BccOperation(void)
+/* REPcc : 0000 0001 0101 cccc : A-184 */
+static size_t dsp56k_op_repcc(const UINT16 op, UINT8* cycles)
{
- int retSize = 0 ;
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- if (!BITS(OP,0x2000))
- {
- int branch = DecodeccccTable(BITS(OP,0x000f)) ;
+/* RESET : 0000 0000 0000 1000 : A-186 */
+static size_t dsp56k_op_reset(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- if (branch)
- {
- if (BITS(OP,0x0010))
- {
- // B.cc xxxx
- INT16 op2 = ROPCODE((PC<<1)+2) ;
+/* RTI : 0000 0000 0000 0111 : A-194 */
+static size_t dsp56k_op_rti(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - ? ? ? ? ? ? ? */
+ /* All ? bits - Set according to value pulled from the stack. */
+ return 0;
+}
- // The PC contains the address of the next instruction
- PC += 2 ;
- core.ppc = PC ;
- PC += op2 ;
+/* RTS : 0000 0000 0000 0110 : A-196 */
+static size_t dsp56k_op_rts(const UINT16 op, UINT8* cycles)
+{
+ /* Pop */
+ core.ppc = PC;
+ PC = SSH;
+ change_pc(PC);
- change_pc(PC) ;
- }
- else
- {
- // B.cc Rn
- }
- }
- else
- {
- if (BITS(OP,0x0010))
- retSize = 2 ;
- else
- retSize = 1 ;
- }
- }
- else
- {
- // B.cc aa
- int branch = DecodeccccTable(BITS(OP,0x03c0)) ;
+ /* SR = SSL; The status register is not affected. */
- if (branch)
- {
- INT16 offset = (INT16)AssembleAddressFrom6BitSignedRelativeShortAddress(BITS(OP,0x003f)) ;
+ SP--;
- PC += 1 ;
- core.ppc = PC ;
- PC += offset ;
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ cycles += 4; /* TODO: + rx oscillator clock cycles */
+ return 0;
+}
- change_pc(PC) ;
- }
- else
- {
- retSize = 1 ;
- }
- }
+/* STOP : 0000 0000 0000 1010 : A-200 */
+static size_t dsp56k_op_stop(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- return retSize ;
+/* SWAP : 0001 0101 0111 F001 : A-206 */
+static size_t dsp56k_op_swap(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
}
-static int Tst2Operation(void)
+/* SWI : 0000 0000 0000 0101 : A-208 */
+static size_t dsp56k_op_swi(const UINT16 op, UINT8* cycles)
{
- int retSize = 1 ;
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- unsigned char dt = 0x00 ;
- void *destinationReg = 0x00 ;
+/* Tcc : 0001 00cc ccTT Fh0h : A-210 */
+static size_t dsp56k_op_tcc(const UINT16 op, UINT8* cycles)
+{
+ int shouldTransfer = decode_cccc_table(BITS(op,0x03c0));
- destinationReg = DecodeDDTable(BITS(OP,0x0003), &dt) ;
+ if (shouldTransfer)
+ {
+ typed_pointer S = {NULL, DT_BYTE};
+ typed_pointer D = {NULL, DT_BYTE};
+ typed_pointer S2 = {&R0, DT_WORD};
+ typed_pointer D2 = {NULL, DT_BYTE};
- // unnormalized
+ decode_h0hF_table(BITS(op,0x0007),BITS(op,0x0008), &S, &D);
+ SetDestinationValue(S, D);
- // negative
- // bit 31 of A or B ???
+ /* TODO: What's up with that A,A* thing in the docs? Can you only ignore the R0->RX transfer if you do an A,A? */
+ decode_RR_table(BITS(op,0x0030), &D2); /* TT is the same as RR */
+ SetDestinationValue(S2, D2);
+ }
- // zero
- if ( (*((UINT16*)destinationReg)) == 0)
- Z_bit_set(1);
- else
- Z_bit_set(0);
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ cycles += 2;
+ return 1;
+}
- // always clear C flag
- C_bit_set(0) ;
+/* TFR(2) : 0001 0101 0000 F00J : A-214 */
+static size_t dsp56k_op_tfr2(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * - - - - - - */
+ return 0;
+}
+
+/* TFR(3) : 0010 01mW RRDD FHHH : A-216 */
+static size_t dsp56k_op_tfr3(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* * * - - - - - - */
+ return 0;
+}
- return retSize ;
+/* TST(2) : 0001 0101 0001 -1DD : A-220 */
+static size_t dsp56k_op_tst2(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * * * * * 0 0 */
+ /* (L,E,U should be set to 0) */
+ return 0;
}
-static int MACsuuuOperation(void)
+/* WAIT : 0000 0000 0000 1011 : A-222 */
+static size_t dsp56k_op_wait(const UINT16 op, UINT8* cycles)
{
- int retSize = 1 ;
+ /* S L E U N Z V C */
+ /* - - - - - - - - */
+ return 0;
+}
- INT64 result = 0 ;
+/* ZERO : 0001 0101 0101 F000 : A-224 */
+static size_t dsp56k_op_zero(const UINT16 op, UINT8* cycles)
+{
+ /* S L E U N Z V C */
+ /* - * * * * * * - */
+ return 0;
+}
- int s ;
- void *S1 = 0x00, *S2 = 0x00, *D = 0x00 ;
- DecodeQQFTableSp(BITS(OP,0x0003), BITS(OP,0x0008), &S1, &S2, &D) ;
- s = BITS(OP,0x0004) ;
+/***************************************************************************
+ Table decoding
+***************************************************************************/
+static UINT16 decode_BBB_bitmask(UINT16 BBB, UINT16 *iVal)
+{
+ UINT16 retVal = 0x0000;
- // !!! There is no way this is right - wtf is EXT:MSP:LSP format ???
- if (!s)
- {
- // su
- result = ( (INT32)(*((UINT16*)S1)) * (UINT32)(*((UINT16*)S2)) ) << 1 ;
- }
- else
+ switch(BBB)
{
- // uu
- result = ( (UINT32)(*((UINT16*)S1)) * (UINT32)(*((UINT16*)S2)) ) << 1 ;
+ case 0x4: retVal = 0xff00; *iVal <<= 8; break;
+ case 0x2: retVal = 0x0ff0; *iVal <<= 4; break;
+ case 0x1: retVal = 0x00ff; *iVal <<= 0; break;
}
- (*((UINT64*)D)) += result ;
-
- return retSize ;
+ return retVal;
}
-static int RepOperation(void)
+static int decode_cccc_table(UINT16 cccc)
{
- int retSize = 1 ;
-
- UINT16 count = 0x0000 ;
+ int retVal = 0;
- if (BITS(OP,0x0f00) == 0xf)
+ /* Not fully tested */
+ switch (cccc)
{
- // immediate
- count = BITS(OP,0x00ff) ;
+ /* Arranged according to mnemonic table - not decoding table */
+ case 0x0: if( C_bit() == 0) retVal = 1; break; // cc(hs)
+ case 0x8: if( C_bit() == 1) retVal = 1; break; // cs(lo)
+ case 0x5: if( E_bit() == 0) retVal = 1; break; // ec
+ case 0xa: if( Z_bit() == 1) retVal = 1; break; // eq
+ case 0xd: if( E_bit() == 1) retVal = 1; break; // es
+ case 0x1: if((N_bit() ^ V_bit()) == 0) retVal = 1; break; // ge
+ case 0x7: if((Z_bit() | (N_bit() ^ V_bit())) == 0) retVal = 1; break; // gt
+ case 0x6: if( L_bit() == 0) retVal = 1; break; // lc
+ case 0xf: if((Z_bit() | (N_bit() ^ V_bit())) == 1) retVal = 1; break; // le
+ case 0xe: if( L_bit() == 1) retVal = 1; break; // ls
+ case 0x9: if((N_bit() ^ V_bit()) == 1) retVal = 1; break; // lt
+ case 0xb: if( N_bit() == 1) retVal = 1; break; // mi
+ case 0x2: if( Z_bit() == 0) retVal = 1; break; // ne
+ case 0xc: if((Z_bit() | ((!U_bit()) & (!E_bit()))) == 1) retVal = 1; break; // nr
+ case 0x3: if( N_bit() == 0) retVal = 1; break; // pl
+ case 0x4: if((Z_bit() | ((!U_bit()) & (!E_bit()))) == 0) retVal = 1; break; // nn
}
- else if (BITS(OP,0x0f00) == 0x4)
- {
- // SD
- unsigned char st = 0x00 ;
- void *S ;
- S = DecodeDDDDDTable(BITS(OP,0x001f), &st) ;
- SetDestinationValue(S, st, &count, DT_WORD);
- }
- else
+ return retVal;
+}
+
+static void decode_DDDDD_table(UINT16 DDDDD, typed_pointer* ret)
+{
+ switch(DDDDD)
{
- // X:(Rn)
+ case 0x00: ret->addr = &X0; ret->data_type = DT_WORD; break;
+ case 0x01: ret->addr = &Y0; ret->data_type = DT_WORD; break;
+ case 0x02: ret->addr = &X1; ret->data_type = DT_WORD; break;
+ case 0x03: ret->addr = &Y1; ret->data_type = DT_WORD; break;
+ case 0x04: ret->addr = &A ; ret->data_type = DT_LONG_WORD; break;
+ case 0x05: ret->addr = &B ; ret->data_type = DT_LONG_WORD; break;
+ case 0x06: ret->addr = &A0; ret->data_type = DT_WORD; break;
+ case 0x07: ret->addr = &B0; ret->data_type = DT_WORD; break;
+ case 0x08: ret->addr = &LC; ret->data_type = DT_WORD; break;
+ case 0x09: ret->addr = &SR; ret->data_type = DT_WORD; break;
+ case 0x0a: ret->addr = &OMR; ret->data_type = DT_BYTE; break;
+ case 0x0b: ret->addr = &SP; ret->data_type = DT_BYTE; break;
+ case 0x0c: ret->addr = &A1; ret->data_type = DT_WORD; break;
+ case 0x0d: ret->addr = &B1; ret->data_type = DT_WORD; break;
+ case 0x0e: ret->addr = &A2; ret->data_type = DT_BYTE; break;
+ case 0x0f: ret->addr = &B2; ret->data_type = DT_BYTE; break;
+
+ case 0x10: ret->addr = &R0; ret->data_type = DT_WORD; break;
+ case 0x11: ret->addr = &R1; ret->data_type = DT_WORD; break;
+ case 0x12: ret->addr = &R2; ret->data_type = DT_WORD; break;
+ case 0x13: ret->addr = &R3; ret->data_type = DT_WORD; break;
+ case 0x14: ret->addr = &M0; ret->data_type = DT_WORD; break;
+ case 0x15: ret->addr = &M1; ret->data_type = DT_WORD; break;
+ case 0x16: ret->addr = &M2; ret->data_type = DT_WORD; break;
+ case 0x17: ret->addr = &M3; ret->data_type = DT_WORD; break;
+ case 0x18: ret->addr = &SSH; ret->data_type = DT_WORD; break;
+ case 0x19: ret->addr = &SSL; ret->data_type = DT_WORD; break;
+ case 0x1a: ret->addr = &LA; ret->data_type = DT_WORD; break;
+ //no 0x1b
+ case 0x1c: ret->addr = &N0; ret->data_type = DT_WORD; break;
+ case 0x1d: ret->addr = &N1; ret->data_type = DT_WORD; break;
+ case 0x1e: ret->addr = &N2; ret->data_type = DT_WORD; break;
+ case 0x1f: ret->addr = &N3; ret->data_type = DT_WORD; break;
}
-
- TEMP = LC ;
- LC = count ;
-
- core.repFlag = 1 ;
- core.repAddr = PC + (retSize<<1) ;
-
- return retSize ;
}
-static void EndOfRepProcessing(void)
+static void decode_DD_table(UINT16 DD, typed_pointer* ret)
{
- LC = TEMP ;
-
- core.repFlag = 0 ;
- core.repAddr = 0x0000 ;
+ switch(DD)
+ {
+ case 0x00: ret->addr = &X0; ret->data_type = DT_WORD; break;
+ case 0x01: ret->addr = &Y0; ret->data_type = DT_WORD; break;
+ case 0x02: ret->addr = &X1; ret->data_type = DT_WORD; break;
+ case 0x03: ret->addr = &Y1; ret->data_type = DT_WORD; break;
+ }
}
-
-/*
-DECODERS
-*/
-static void *DecodeDDDDDTable(UINT16 DDDDD, unsigned char *dt)
+static void decode_F_table(UINT16 F, typed_pointer* ret)
{
- void *retAddress = 0x00 ;
-
- switch(DDDDD)
+ switch(F)
{
- case 0x00: retAddress = &X0 ; *dt = DT_WORD ; break ;
- case 0x01: retAddress = &Y0 ; *dt = DT_WORD ; break ;
- case 0x02: retAddress = &X1 ; *dt = DT_WORD ; break ;
- case 0x03: retAddress = &Y1 ; *dt = DT_WORD ; break ;
- case 0x04: retAddress = &A ; *dt = DT_LONG_WORD ; break ;
- case 0x05: retAddress = &B ; *dt = DT_LONG_WORD ; break ;
- case 0x06: retAddress = &A0 ; *dt = DT_WORD ; break ;
- case 0x07: retAddress = &B0 ; *dt = DT_WORD ; break ;
- case 0x08: retAddress = &LC ; *dt = DT_WORD ; break ;
- case 0x09: retAddress = &SR ; *dt = DT_WORD ; break ;
- case 0x0a: retAddress = &OMR ; *dt = DT_BYTE ; break ;
- case 0x0b: retAddress = &SP ; *dt = DT_BYTE ; break ;
- case 0x0c: retAddress = &A1 ; *dt = DT_WORD ; break ;
- case 0x0d: retAddress = &B1 ; *dt = DT_WORD ; break ;
- case 0x0e: retAddress = &A2 ; *dt = DT_BYTE ; break ;
- case 0x0f: retAddress = &B2 ; *dt = DT_BYTE ; break ;
-
- case 0x10: retAddress = &R0 ; *dt = DT_WORD ; break ;
- case 0x11: retAddress = &R1 ; *dt = DT_WORD ; break ;
- case 0x12: retAddress = &R2 ; *dt = DT_WORD ; break ;
- case 0x13: retAddress = &R3 ; *dt = DT_WORD ; break ;
- case 0x14: retAddress = &M0 ; *dt = DT_WORD ; break ;
- case 0x15: retAddress = &M1 ; *dt = DT_WORD ; break ;
- case 0x16: retAddress = &M2 ; *dt = DT_WORD ; break ;
- case 0x17: retAddress = &M3 ; *dt = DT_WORD ; break ;
- case 0x18: retAddress = &SSH ; *dt = DT_WORD ; break ;
- case 0x19: retAddress = &SSL ; *dt = DT_WORD ; break ;
- case 0x1a: retAddress = &LA ; *dt = DT_WORD ; break ;
- //no 0x1b
- case 0x1c: retAddress = &N0 ; *dt = DT_WORD ; break ;
- case 0x1d: retAddress = &N1 ; *dt = DT_WORD ; break ;
- case 0x1e: retAddress = &N2 ; *dt = DT_WORD ; break ;
- case 0x1f: retAddress = &N3 ; *dt = DT_WORD ; break ;
+ case 0x0: ret->addr = &A; ret->data_type = DT_LONG_WORD; break;
+ case 0x1: ret->addr = &B; ret->data_type = DT_LONG_WORD; break;
}
-
- return retAddress ;
}
-static void *DecodeRRTable(UINT16 RR, unsigned char *dt)
+static void decode_h0hF_table(UINT16 h0h, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret)
{
- void *retAddress = 0x00 ;
+ UINT16 switchVal = (h0h << 1) | F ;
- switch(RR)
+ switch (switchVal)
{
- case 0x00: retAddress = &R0 ; *dt = DT_WORD ; break ;
- case 0x01: retAddress = &R1 ; *dt = DT_WORD ; break ;
- case 0x02: retAddress = &R2 ; *dt = DT_WORD ; break ;
- case 0x03: retAddress = &R3 ; *dt = DT_WORD ; break ;
+ case 0x8: src_ret->addr = &X0; src_ret->data_type = DT_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x9: src_ret->addr = &X0; src_ret->data_type = DT_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0xa: src_ret->addr = &Y0; src_ret->data_type = DT_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0xb: src_ret->addr = &Y0; src_ret->data_type = DT_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x2: src_ret->addr = &A; src_ret->data_type = DT_LONG_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x1: src_ret->addr = &A; src_ret->data_type = DT_LONG_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x0: src_ret->addr = &B; src_ret->data_type = DT_LONG_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x3: src_ret->addr = &B; src_ret->data_type = DT_LONG_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
}
-
- return retAddress ;
}
-static void *DecodeDDTable(UINT16 DD, unsigned char *dt)
+static void decode_HH_table(UINT16 HH, typed_pointer* ret)
{
- void *retAddress = 0x00 ;
-
- switch(DD)
+ switch(HH)
{
- case 0x00: retAddress = &X0 ; *dt = DT_WORD ; break ;
- case 0x01: retAddress = &Y0 ; *dt = DT_WORD ; break ;
- case 0x02: retAddress = &X1 ; *dt = DT_WORD ; break ;
- case 0x03: retAddress = &Y1 ; *dt = DT_WORD ; break ;
+ case 0x0: ret->addr = &X0; ret->data_type = DT_WORD; break;
+ case 0x1: ret->addr = &Y0; ret->data_type = DT_WORD; break;
+ case 0x2: ret->addr = &A; ret->data_type = DT_LONG_WORD; break;
+ case 0x3: ret->addr = &B; ret->data_type = DT_LONG_WORD; break;
}
-
- return retAddress ;
}
-static void *DecodeHHHTable(UINT16 HHH, unsigned char *dt)
+static void decode_HHH_table(UINT16 HHH, typed_pointer* ret)
{
- void *retAddress = 0x00 ;
-
switch(HHH)
{
- case 0x0: retAddress = &X0 ; *dt = DT_WORD ; break ;
- case 0x1: retAddress = &Y0 ; *dt = DT_WORD ; break ;
- case 0x2: retAddress = &X1 ; *dt = DT_WORD ; break ;
- case 0x3: retAddress = &Y1 ; *dt = DT_WORD ; break ;
- case 0x4: retAddress = &A ; *dt = DT_LONG_WORD ; break ;
- case 0x5: retAddress = &B ; *dt = DT_LONG_WORD ; break ;
- case 0x6: retAddress = &A0 ; *dt = DT_WORD ; break ;
- case 0x7: retAddress = &B0 ; *dt = DT_WORD ; break ;
+ case 0x0: ret->addr = &X0; ret->data_type = DT_WORD; break;
+ case 0x1: ret->addr = &Y0; ret->data_type = DT_WORD; break;
+ case 0x2: ret->addr = &X1; ret->data_type = DT_WORD; break;
+ case 0x3: ret->addr = &Y1; ret->data_type = DT_WORD; break;
+ case 0x4: ret->addr = &A; ret->data_type = DT_LONG_WORD; break;
+ case 0x5: ret->addr = &B; ret->data_type = DT_LONG_WORD; break;
+ case 0x6: ret->addr = &A0; ret->data_type = DT_WORD; break;
+ case 0x7: ret->addr = &B0; ret->data_type = DT_WORD; break;
}
-
- return retAddress ;
}
-static void *DecodeHHTable(UINT16 HH, unsigned char *dt)
+static void decode_IIII_table(UINT16 IIII, typed_pointer* src_ret, typed_pointer* dst_ret, void *working)
{
- void *retAddress = 0x00 ;
+ void *opposite = 0x00 ;
- switch(HH)
+ if (working == &A) opposite = &B ;
+ else opposite = &A ;
+
+ switch(IIII)
{
- case 0x0: retAddress = &X0 ; *dt = DT_WORD ; break ;
- case 0x1: retAddress = &Y0 ; *dt = DT_WORD ; break ;
- case 0x2: retAddress = &A ; *dt = DT_LONG_WORD ; break ;
- case 0x3: retAddress = &B ; *dt = DT_LONG_WORD ; break ;
+ case 0x0: src_ret->addr = &X0; src_ret->data_type = DT_WORD; dst_ret->addr = opposite; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x1: src_ret->addr = &Y0; src_ret->data_type = DT_WORD; dst_ret->addr = opposite; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x2: src_ret->addr = &X1; src_ret->data_type = DT_WORD; dst_ret->addr = opposite; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x3: src_ret->addr = &Y1; src_ret->data_type = DT_WORD; dst_ret->addr = opposite; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x4: src_ret->addr = &A; src_ret->data_type = DT_LONG_WORD; dst_ret->addr = &X0; dst_ret->data_type = DT_WORD; break;
+ case 0x5: src_ret->addr = &B; src_ret->data_type = DT_LONG_WORD; dst_ret->addr = &Y0; dst_ret->data_type = DT_WORD; break;
+ case 0x6: src_ret->addr = &A0; src_ret->data_type = DT_WORD; dst_ret->addr = &X0; dst_ret->data_type = DT_WORD; break;
+ case 0x7: src_ret->addr = &B0; src_ret->data_type = DT_WORD; dst_ret->addr = &Y0; dst_ret->data_type = DT_WORD; break;
+ case 0x8: src_ret->addr = working; src_ret->data_type = DT_LONG_WORD; dst_ret->addr = opposite; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x9: src_ret->addr = working; src_ret->data_type = DT_LONG_WORD; dst_ret->addr = opposite; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0xc: src_ret->addr = &A; src_ret->data_type = DT_LONG_WORD; dst_ret->addr = &X1; dst_ret->data_type = DT_WORD; break;
+ case 0xd: src_ret->addr = &B; src_ret->data_type = DT_LONG_WORD; dst_ret->addr = &Y1; dst_ret->data_type = DT_WORD; break;
+ case 0xe: src_ret->addr = &A0; src_ret->data_type = DT_WORD; dst_ret->addr = &X1; dst_ret->data_type = DT_WORD; break;
+ case 0xf: src_ret->addr = &B0; src_ret->data_type = DT_WORD; dst_ret->addr = &Y1; dst_ret->data_type = DT_WORD; break;
}
-
- return retAddress ;
}
-static void *DecodeZTable(UINT16 Z, unsigned char *dt)
+static void decode_JJJF_table(UINT16 JJJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret)
{
- void *retAddress = 0x00 ;
+ UINT16 switchVal = (JJJ << 1) | F ;
- switch(Z)
+ switch(switchVal)
{
- // Fixed as per the Family Manual addendum
- case 0x01: retAddress = &A1 ; *dt = DT_WORD ; break ;
- case 0x00: retAddress = &B1 ; *dt = DT_WORD ; break ;
+ case 0x0: src_ret->addr = &B; src_ret->data_type = DT_LONG_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x1: src_ret->addr = &A; src_ret->data_type = DT_LONG_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x4: src_ret->addr = &X; src_ret->data_type = DT_DOUBLE_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x5: src_ret->addr = &X; src_ret->data_type = DT_DOUBLE_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x6: src_ret->addr = &Y; src_ret->data_type = DT_DOUBLE_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x7: src_ret->addr = &Y; src_ret->data_type = DT_DOUBLE_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x8: src_ret->addr = &X0; src_ret->data_type = DT_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x9: src_ret->addr = &X0; src_ret->data_type = DT_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0xa: src_ret->addr = &Y0; src_ret->data_type = DT_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0xb: src_ret->addr = &Y0; src_ret->data_type = DT_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0xc: src_ret->addr = &X1; src_ret->data_type = DT_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0xd: src_ret->addr = &X1; src_ret->data_type = DT_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0xe: src_ret->addr = &Y1; src_ret->data_type = DT_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0xf: src_ret->addr = &Y1; src_ret->data_type = DT_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
}
-
- return retAddress ;
}
-
-static UINT16 DecodeBBBBitMask(UINT16 BBB, UINT16 *iVal)
+static void decode_JJF_table(UINT16 JJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret)
{
- UINT16 retVal = 0x00 ;
+ UINT16 switchVal = (JJ << 1) | F ;
- switch(BBB)
+ switch (switchVal)
{
- case 0x4: retVal = 0xff00 ; *iVal <<= 8 ; break ;
- case 0x2: retVal = 0x0ff0 ; *iVal <<= 4 ; break ;
- case 0x1: retVal = 0x00ff ; *iVal <<= 0 ; break ;
+ case 0x0: src_ret->addr = &X0; src_ret->data_type = DT_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x1: src_ret->addr = &X0; src_ret->data_type = DT_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x2: src_ret->addr = &Y0; src_ret->data_type = DT_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x3: src_ret->addr = &Y0; src_ret->data_type = DT_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x4: src_ret->addr = &X1; src_ret->data_type = DT_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x5: src_ret->addr = &X1; src_ret->data_type = DT_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x6: src_ret->addr = &Y1; src_ret->data_type = DT_WORD; dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break;
+ case 0x7: src_ret->addr = &Y1; src_ret->data_type = DT_WORD; dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break;
}
+}
+
+static void decode_QQF_special_table(UINT16 QQ, UINT16 F, void **S1, void **S2, void **D)
+{
+ UINT16 switchVal = (QQ << 1) | F ;
- return retVal ;
+ switch(switchVal)
+ {
+ case 0x0: *S1 = &Y0; *S2 = &X0; *D = &A; break;
+ case 0x1: *S1 = &Y0; *S2 = &X0; *D = &B; break;
+ case 0x2: *S1 = &Y1; *S2 = &X0; *D = &A; break;
+ case 0x3: *S1 = &Y1; *S2 = &X0; *D = &B; break;
+ case 0x4: *S1 = &X1; *S2 = &Y0; *D = &A; break;
+ case 0x5: *S1 = &X1; *S2 = &Y0; *D = &B; break;
+ case 0x6: *S1 = &X1; *S2 = &Y1; *D = &A; break;
+ case 0x7: *S1 = &X1; *S2 = &Y1; *D = &B; break;
+ }
}
-static void ExecuteMMTable(int x, UINT16 MM)
+static void decode_RR_table(UINT16 RR, typed_pointer* ret)
+{
+ switch(RR)
+ {
+ case 0x00: ret->addr = &R0; ret->data_type = DT_WORD; break;
+ case 0x01: ret->addr = &R1; ret->data_type = DT_WORD; break;
+ case 0x02: ret->addr = &R2; ret->data_type = DT_WORD; break;
+ case 0x03: ret->addr = &R3; ret->data_type = DT_WORD; break;
+ }
+}
+#ifdef UNUSED_FUNCTION
+static void decode_Z_table(UINT16 Z, typed_pointer* ret)
+{
+ switch(Z)
+ {
+ /* Fixed as per the Family Manual addendum */
+ case 0x01: ret->addr = &A1; ret->data_type = DT_WORD; break;
+ case 0x00: ret->addr = &B1; ret->data_type = DT_WORD; break;
+ }
+}
+#endif
+static void execute_m_table(int x, UINT16 m)
{
UINT16 *rX = 0x00 ;
UINT16 *nX = 0x00 ;
switch(x)
{
- case 0x0: rX = &R0 ; nX = &N0 ; break ;
- case 0x1: rX = &R1 ; nX = &N1 ; break ;
- case 0x2: rX = &R2 ; nX = &N2 ; break ;
- case 0x3: rX = &R3 ; nX = &N3 ; break ;
+ case 0x0: rX = &R0; nX = &N0; break;
+ case 0x1: rX = &R1; nX = &N1; break;
+ case 0x2: rX = &R2; nX = &N2; break;
+ case 0x3: rX = &R3; nX = &N3; break;
}
- switch(MM)
+ switch(m)
{
- case 0x0: /* do nothing */ break ;
- case 0x1: (*rX)++ ; break ;
- case 0x2: (*rX)-- ; break ;
- case 0x3: (*rX) = (*rX)+(*nX) ; break ;
+ case 0x0: (*rX)++; break;
+ case 0x1: (*rX) = (*rX)+(*nX); break;
}
}
-static void ExecutemTable(int x, UINT16 m)
+static void execute_MM_table(UINT16 rnum, UINT16 MM)
{
UINT16 *rX = 0x00 ;
UINT16 *nX = 0x00 ;
- switch(x)
+ switch(rnum)
{
- case 0x0: rX = &R0 ; nX = &N0 ; break ;
- case 0x1: rX = &R1 ; nX = &N1 ; break ;
- case 0x2: rX = &R2 ; nX = &N2 ; break ;
- case 0x3: rX = &R3 ; nX = &N3 ; break ;
+ case 0x0: rX = &R0; nX = &N0; break;
+ case 0x1: rX = &R1; nX = &N1; break;
+ case 0x2: rX = &R2; nX = &N2; break;
+ case 0x3: rX = &R3; nX = &N3; break;
}
- switch(m)
+ switch(MM)
{
- case 0x0: (*rX)++ ; break ;
- case 0x1: (*rX) = (*rX)+(*nX) ; break ;
+ case 0x0: /* do nothing */ break;
+ case 0x1: (*rX)++ ; break;
+ case 0x2: (*rX)-- ; break;
+ case 0x3: (*rX) = (*rX)+(*nX) ; break;
}
}
-
-static void ExecutezTable(int x, UINT16 z)
+#ifdef UNUSED_FUNCTION
+// Returns R address
+static UINT16 execute_q_table(int x, UINT16 q)
{
UINT16 *rX = 0x00 ;
UINT16 *nX = 0x00 ;
@@ -2168,18 +3106,17 @@ static void ExecutezTable(int x, UINT16 z)
case 0x3: rX = &R3 ; nX = &N3 ; break ;
}
- if (!z)
- {
- (*rX)-- ;
- }
- else
+ switch(q)
{
- (*rX) = (*rX)+(*nX) ;
+ case 0x0: /* No permanent changes */ ; return (*rX)+(*nX); break;
+ case 0x1: (*rX)--; return (*rX); break; // This one is special - it's a *PRE-decrement*!
}
+
+ exit(1);
+ return 0x00;
}
-// Returns R address
-static UINT16 ExecuteqTable(int x, UINT16 q)
+static void execute_z_table(int x, UINT16 z)
{
UINT16 *rX = 0x00 ;
UINT16 *nX = 0x00 ;
@@ -2192,309 +3129,197 @@ static UINT16 ExecuteqTable(int x, UINT16 q)
case 0x3: rX = &R3 ; nX = &N3 ; break ;
}
- switch(q)
+ if (!z)
{
- case 0x0: /* No permanent changes */ ; return (*rX)+(*nX); break;
- case 0x1: (*rX)--; return (*rX); break; // This one is special - it's a *PRE-decrement*!
+ (*rX)-- ;
+ }
+ else
+ {
+ (*rX) = (*rX)+(*nX) ;
}
-
- exit(1);
- return 0x00;
}
-static UINT16 AssembleDFromPTable(UINT16 P, UINT16 ppppp)
+static UINT16 assemble_D_from_P_table(UINT16 P, UINT16 ppppp)
{
UINT16 destAddr = 0x00 ;
switch (P)
{
case 0x0: destAddr = ppppp ; break ;
- case 0x1: destAddr = AssembleAddressFromIOShortAddress(ppppp) ; break ;
+ case 0x1: destAddr = assemble_address_from_IO_short_address(ppppp) ; break ;
}
return destAddr ;
}
-
-
-static UINT16 AssembleAddressFromIOShortAddress(UINT16 pp)
+#endif
+static UINT16 assemble_address_from_IO_short_address(UINT16 pp)
{
- UINT16 fullAddy = 0xffe0 ;
- fullAddy |= pp ;
- return fullAddy ;
+ UINT16 fullAddy = 0xffe0;
+ fullAddy |= pp;
+ return fullAddy;
}
-
-static UINT16 AssembleAddressFrom6BitSignedRelativeShortAddress(UINT16 srs)
+#ifdef UNUSED_FUNCTION
+static UINT16 assemble_address_from_6bit_signed_relative_short_address(UINT16 srs)
{
UINT16 fullAddy = srs ;
if (fullAddy & 0x0020) fullAddy |= 0xffc0 ;
return fullAddy ;
}
-
-static int DecodeccccTable(UINT16 cccc)
+#endif
+static void dsp56k_process_loop(void)
{
- int retVal = 0 ;
-
- // !!! go back and check me again someday - potential bugs !!!
- switch (cccc)
+ if (LF_bit())
{
- // Arranged according to mnemonic table - not decoding table...
- case 0x0: if( C_bit() == 0) retVal = 1 ; break ; // cc(hs)
- case 0x8: if( C_bit() == 1) retVal = 1 ; break ; // cs(lo)
- case 0x5: if( E_bit() == 0) retVal = 1 ; break ; // ec
- case 0xa: if( Z_bit() == 1) retVal = 1 ; break ; // eq
- case 0xd: if( E_bit() == 1) retVal = 1 ; break ; // es
- case 0x1: if((N_bit() ^ V_bit()) == 0) retVal = 1 ; break ; // ge
- case 0x7: if((Z_bit() + (N_bit() ^ V_bit())) == 0) retVal = 1 ; break ; // gt
- case 0x6: if( L_bit() == 0) retVal = 1 ; break ; // lc
- case 0xf: if((Z_bit() + (N_bit() ^ V_bit())) == 1) retVal = 1 ; break ; // le
- case 0xe: if( L_bit() == 1) retVal = 1 ; break ; // ls
- case 0x9: if((N_bit() ^ V_bit()) == 1) retVal = 1 ; break ; // lt
- case 0xb: if( N_bit() == 1) retVal = 1 ; break ; // mi
- case 0x2: if( Z_bit() == 0) retVal = 1 ; break ; // ne
- case 0xc: if((Z_bit() + ((!U_bit()) & (!E_bit()))) == 1) retVal = 1 ; break ; // nr
- case 0x3: if( N_bit() == 0) retVal = 1 ; break ; // pl
- case 0x4: if((Z_bit() + ((!U_bit()) & (!E_bit()))) == 0) retVal = 1 ; break ; // nn
+ if (PC == LA)
+ {
+ if (LC == 1)
+ {
+ /* End of loop processing */
+ SR = SSL; /* TODO: A-83. I believe only the Loop Flag comes back here. */
+ SP--;
+
+ LA = SSH;
+ LC = SSL;
+ SP--;
+ }
+ else
+ {
+ LC--;
+ PC = SSH;
+ change_pc(PC);
+ }
+ }
}
-
- return retVal ;
}
-static void Decodeh0hFTable(UINT16 h0h, UINT16 F,
- void **source, unsigned char *st,
- void **dest, unsigned char *dt)
+static void dsp56k_process_rep(size_t repSize)
{
- UINT16 switchVal = (h0h << 1) | F ;
-
- switch (switchVal)
+ if (core.repFlag)
{
- case 0x8: *source = &X0 ; *st = DT_WORD ; *dest = &A ; *dt = DT_LONG_WORD ; break ;
- case 0x9: *source = &X0 ; *st = DT_WORD ; *dest = &B ; *dt = DT_LONG_WORD ; break ;
- case 0xa: *source = &Y0 ; *st = DT_WORD ; *dest = &A ; *dt = DT_LONG_WORD ; break ;
- case 0xb: *source = &Y0 ; *st = DT_WORD ; *dest = &B ; *dt = DT_LONG_WORD ; break ;
- case 0x2: *source = &A ; *st = DT_LONG_WORD ; *dest = &A ; *dt = DT_LONG_WORD ; break ;
- case 0x1: *source = &A ; *st = DT_LONG_WORD ; *dest = &B ; *dt = DT_LONG_WORD ; break ;
- case 0x0: *source = &B ; *st = DT_LONG_WORD ; *dest = &A ; *dt = DT_LONG_WORD ; break ;
- case 0x3: *source = &B ; *st = DT_LONG_WORD ; *dest = &B ; *dt = DT_LONG_WORD ; break ;
+ if (PC == core.repAddr)
+ {
+ if (LC == 1)
+ {
+ /* End of rep processing */
+ LC = TEMP;
+ core.repFlag = 0;
+ core.repAddr = 0x0000;
+ }
+ else
+ {
+ LC--;
+ PC -= repSize; /* A little strange - rewind by the size of the rep'd op */
+ change_pc(PC);
+ }
+ }
}
}
-static void *DecodeFTable(UINT16 F, unsigned char *dt)
-{
- void *retAddress = 0x00 ;
-
- switch(F)
- {
- case 0x0: retAddress = &A ; *dt = DT_LONG_WORD ; break ;
- case 0x1: retAddress = &B ; *dt = DT_LONG_WORD ; break ;
- }
-
- return retAddress ;
-}
-static void DecodeJJJFTable(UINT16 JJJ, UINT16 F,
- void **source, unsigned char *st,
- void **dest, unsigned char *dt)
+/***************************************************************************
+ Parallel Memory Ops
+***************************************************************************/
+/* Register to Register Data Move : 0100 IIII ---- ---- */
+static void execute_register_to_register_data_move(const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value)
{
- UINT16 switchVal = (JJJ << 1) | F ;
+ typed_pointer S = {NULL, DT_BYTE};
+ typed_pointer D = {NULL, DT_BYTE};
- switch(switchVal)
- {
- case 0x0: *source = &B ; *st = DT_LONG_WORD ; *dest = &A ; *dt = DT_LONG_WORD ; break ;
- case 0x1: *source = &A ; *st = DT_LONG_WORD ; *dest = &B ; *dt = DT_LONG_WORD ; break ;
- case 0x4: *source = &X ; *st = DT_DOUBLE_WORD ; *dest = &A ; *dt = DT_LONG_WORD ; break ;
- case 0x5: *source = &X ; *st = DT_DOUBLE_WORD ; *dest = &B ; *dt = DT_LONG_WORD ; break ;
- case 0x6: *source = &Y ; *st = DT_DOUBLE_WORD ; *dest = &A ; *dt = DT_LONG_WORD ; break ;
- case 0x7: *source = &Y ; *st = DT_DOUBLE_WORD ; *dest = &B ; *dt = DT_LONG_WORD ; break ;
- case 0x8: *source = &X0 ; *st = DT_WORD ; *dest = &A ; *dt = DT_LONG_WORD ; break ;
- case 0x9: *source = &X0 ; *st = DT_WORD ; *dest = &B ; *dt = DT_LONG_WORD ; break ;
- case 0xa: *source = &Y0 ; *st = DT_WORD ; *dest = &A ; *dt = DT_LONG_WORD ; break ;
- case 0xb: *source = &Y0 ; *st = DT_WORD ; *dest = &B ; *dt = DT_LONG_WORD ; break ;
- case 0xc: *source = &X1 ; *st = DT_WORD ; *dest = &A ; *dt = DT_LONG_WORD ; break ;
- case 0xd: *source = &X1 ; *st = DT_WORD ; *dest = &B ; *dt = DT_LONG_WORD ; break ;
- case 0xe: *source = &Y1 ; *st = DT_WORD ; *dest = &A ; *dt = DT_LONG_WORD ; break ;
- case 0xf: *source = &Y1 ; *st = DT_WORD ; *dest = &B ; *dt = DT_LONG_WORD ; break ;
- }
-}
-
-static void DecodeJJFTable(UINT16 JJ, UINT16 F,
- void **source, unsigned char *st,
- void **dest, unsigned char *dt)
-{
- UINT16 switchVal = (JJ << 1) | F ;
+ decode_IIII_table(BITS(op,0x0f00), &S, &D, d_register->addr);
- switch (switchVal)
+ /* If the source is the same as the ALU destination, use the previous accumulator value */
+ if (d_register->addr == S.addr)
{
- case 0x0: *source = &X0 ; *st = DT_WORD ; *dest = &A ; *dt = DT_LONG_WORD ; break ;
- case 0x1: *source = &X0 ; *st = DT_WORD ; *dest = &B ; *dt = DT_LONG_WORD ; break ;
- case 0x2: *source = &Y0 ; *st = DT_WORD ; *dest = &A ; *dt = DT_LONG_WORD ; break ;
- case 0x3: *source = &Y0 ; *st = DT_WORD ; *dest = &B ; *dt = DT_LONG_WORD ; break ;
- case 0x4: *source = &X1 ; *st = DT_WORD ; *dest = &A ; *dt = DT_LONG_WORD ; break ;
- case 0x5: *source = &X1 ; *st = DT_WORD ; *dest = &B ; *dt = DT_LONG_WORD ; break ;
- case 0x6: *source = &Y1 ; *st = DT_WORD ; *dest = &A ; *dt = DT_LONG_WORD ; break ;
- case 0x7: *source = &Y1 ; *st = DT_WORD ; *dest = &B ; *dt = DT_LONG_WORD ; break ;
+ typed_pointer tempTP;
+ tempTP.addr = prev_accum_value;
+ tempTP.data_type = DT_LONG_WORD;
+ SetDestinationValue(tempTP, D);
}
-}
-
-// Types not necessary - we know what we are...
-static void DecodeQQFTableSp(UINT16 QQ, UINT16 F, void **S1, void **S2, void **D)
-{
- UINT16 switchVal = (QQ << 1) | F ;
-
- switch(switchVal)
+ else
{
- case 0x0: *S1 = &Y0 ; *S2 = &X0 ; *D = &A ; break ;
- case 0x1: *S1 = &Y0 ; *S2 = &X0 ; *D = &B ; break ;
- case 0x2: *S1 = &Y1 ; *S2 = &X0 ; *D = &A ; break ;
- case 0x3: *S1 = &Y1 ; *S2 = &X0 ; *D = &B ; break ;
- case 0x4: *S1 = &X1 ; *S2 = &Y0 ; *D = &A ; break ;
- case 0x5: *S1 = &X1 ; *S2 = &Y0 ; *D = &B ; break ;
- case 0x6: *S1 = &X1 ; *S2 = &Y1 ; *D = &A ; break ;
- case 0x7: *S1 = &X1 ; *S2 = &Y1 ; *D = &B ; break ;
+ SetDestinationValue(S, D);
}
}
-static void DecodeIIIITable(UINT16 IIII,
- void **source, unsigned char *st,
- void **dest, unsigned char *dt,
- void *working)
+/* X Memory Data Move : 1mRR HHHW ---- ---- : A-137 */
+static void execute_x_memory_data_move(const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value)
{
- void *opposite = 0x00 ;
+ UINT16 W;
+ typed_pointer R = {NULL, DT_BYTE};
+ typed_pointer SD = {NULL, DT_BYTE};
- if (working == &A) opposite = &B ;
- else opposite = &A ;
+ W = BITS(op,0x0100);
+ decode_HHH_table(BITS(op,0x0e00), &SD);
+ decode_RR_table(BITS(op,0x3000),&R);
- switch(IIII)
+ if (W)
{
- case 0x0: *source = &X0 ; *st = DT_WORD ; *dest = opposite ; *dt = DT_LONG_WORD ; break ;
- case 0x1: *source = &Y0 ; *st = DT_WORD ; *dest = opposite ; *dt = DT_LONG_WORD ; break ;
- case 0x2: *source = &X1 ; *st = DT_WORD ; *dest = opposite ; *dt = DT_LONG_WORD ; break ;
- case 0x3: *source = &Y1 ; *st = DT_WORD ; *dest = opposite ; *dt = DT_LONG_WORD ; break ;
- case 0x4: *source = &A ; *st = DT_LONG_WORD ; *dest = &X0 ; *dt = DT_WORD ; break ;
- case 0x5: *source = &B ; *st = DT_LONG_WORD ; *dest = &Y0 ; *dt = DT_WORD ; break ;
- case 0x6: *source = &A0 ; *st = DT_WORD ; *dest = &X0 ; *dt = DT_WORD ; break ;
- case 0x7: *source = &B0 ; *st = DT_WORD ; *dest = &Y0 ; *dt = DT_WORD ; break ;
- case 0x8: *source = working ; *st = DT_LONG_WORD ; *dest = opposite ; *dt = DT_LONG_WORD ; break ;
- case 0x9: *source = working ; *st = DT_LONG_WORD ; *dest = opposite ; *dt = DT_LONG_WORD ; break ;
- case 0xc: *source = &A ; *st = DT_LONG_WORD ; *dest = &X1 ; *dt = DT_WORD ; break ;
- case 0xd: *source = &B ; *st = DT_LONG_WORD ; *dest = &Y1 ; *dt = DT_WORD ; break ;
- case 0xe: *source = &A0 ; *st = DT_WORD ; *dest = &X1 ; *dt = DT_WORD ; break ;
- case 0xf: *source = &B0 ; *st = DT_WORD ; *dest = &Y1 ; *dt = DT_WORD ; break ;
- }
-}
-
-/*
-MEMORY OPS
-*/
-
-static void XMDMOperation(UINT16 parameters, void *working, UINT64 *pa)
-{
- UINT16 W ;
- unsigned char rdt = 0x00 ;
- void *R = 0x00 ;
-
- unsigned char sdt = 0x00 ;
- void *SD = 0x00 ;
-
- // Get the source
- SD = DecodeHHHTable(BITS(parameters,0x000e), &sdt) ;
-
- // Get the destination
- R = DecodeRRTable(BITS(parameters,0x0030), &rdt) ;
+ /* From X:<ea> to SD */
+ UINT16 data = data_read_word_16le(WORD(*((UINT16*)R.addr)));
- // Move the data
- W = BITS(parameters,0x0001) ;
+ typed_pointer tempTP;
+ tempTP.addr = &data;
+ tempTP.data_type = DT_WORD;
- if (W)
- {
- // from X:<ea> to SD...
- // !!! TODO : Fill in similar comments for other "if (W)'s" !!!
- UINT16 data = data_read_word_16le((*((UINT16*)R))<<1) ; // read the word out
- SetDestinationValue(&data, DT_WORD, SD, sdt) ;
+ SetDestinationValue(tempTP, SD);
}
else
{
- // from SD to X:<ea>...
-
- // If the source is the same as the ALU destination, use the Previous Accumulator value
- if (working == SD)
+ /* From SD to X:<ea> */
+ /* If the source is the same as the ALU destination, use the previous accumulator value */
+ if (d_register->addr == SD.addr)
{
- // the value before the ALU operation was executed...
- SetDataMemoryValue(pa, DT_LONG_WORD, (*((UINT16*)R))<<1) ;
+ typed_pointer tempTP;
+ tempTP.addr = prev_accum_value;
+ tempTP.data_type = DT_LONG_WORD;
+
+ SetDataMemoryValue(tempTP, WORD(*((UINT16*)R.addr))) ;
}
else
{
- // Expected memory move
- SetDataMemoryValue(SD, sdt, (*((UINT16*)R))<<1) ;
+ SetDataMemoryValue(SD, WORD(*((UINT16*)R.addr))) ;
}
}
- // Postincrement
- ExecutemTable(BITS(parameters,0x0030), BITS(parameters,0x0040)) ;
-}
-
-static void RRDMOperation(UINT16 parameters, void *working, UINT64 *pa)
-{
- unsigned char st = 0x00, dt = 0x00 ;
- void *S = 0x00, *D = 0x00;
-
- DecodeIIIITable(BITS(parameters,0x000f), &S, &st, &D, &dt, working) ;
-
- // If the source is what we're working with, use the old value
- if (S == working)
- SetDestinationValue(pa, DT_LONG_WORD, D, dt) ;
- else
- SetDestinationValue(S, st, D, dt) ;
+ execute_m_table(BITS(op,0x3000), BITS(op,0x4000));
}
-static void XMDMSpecialOperation(UINT16 parameters, void *working)
+/* X Memory Data Move : 0101 HHHW ---- ---- : A-137 */
+/* NOTE: previous accumulator value is not needed since ^F1 is always the opposite accumulator */
+static void execute_x_memory_data_move2(const UINT16 op, typed_pointer* d_register)
{
- UINT16 W ;
- UINT16 *dest = 0x00 ;
+ UINT16 W;
+ UINT16* mem_offset = NULL;
+ typed_pointer SD = {NULL, DT_BYTE};
- // Get the source/destination
- unsigned char sdt = 0x00 ;
- void *SD = 0x00 ;
- SD = DecodeHHHTable(BITS(parameters,0x000e), &sdt) ;
+ W = BITS(op,0x0100);
+ decode_HHH_table(BITS(op,0x0e000), &SD);
- // Get the opposite A/B depending on what was used before
- if (working == &A)
- dest = &B1 ;
- else if (working == &B)
- dest = &A1 ;
- else
- {
- mame_printf_debug("WTF MF\n") ;
- return ;
- }
-
- // Move the data
- W = BITS(parameters,0x0001) ;
+ if (d_register->addr == &A)
+ mem_offset = &B1;
+ else
+ mem_offset = &A1;
if (W)
{
- // from X:<ea> to SD...
- // !!! DOES THIS WORK ???
- UINT16 data = data_read_word_16le((*dest)<<1) ; // read the word out
- SetDestinationValue(&data, DT_WORD, SD, sdt) ;
+ /* Write D */
+ UINT16 value = data_read_word_16le(WORD(*mem_offset));
+ typed_pointer tempV = {&value, DT_WORD};
+ SetDestinationValue(tempV, SD);
}
else
{
- // Normal memory move
- SetDataMemoryValue(SD, sdt, (*dest)<<1) ;
+ /* Read S */
+ SetDataMemoryValue(SD, WORD(*mem_offset));
}
}
-static void ARUOperation(UINT16 parameters)
-{
- ExecutezTable(BITS(parameters, 0x0003), BITS(parameters, 0x0004)) ;
-}
-
-/*
-HELPERS
-*/
+/***************************************************************************
+ Helper Functions
+***************************************************************************/
static UINT16 Dsp56kOpMask(UINT16 cur, UINT16 mask)
{
int i ;
@@ -2516,93 +3341,90 @@ static UINT16 Dsp56kOpMask(UINT16 cur, UINT16 mask)
return temp ;
}
-
-static void SetDestinationValue(void *sourcePointer, unsigned char sourceType,
- void *destinationPointer, unsigned char destinationType)
+static void SetDestinationValue(typed_pointer source, typed_pointer dest)
{
UINT64 destinationValue = 0 ;
- switch(destinationType)
+ switch(dest.data_type)
{
+ /* Copying to an 8-bit value */
case DT_BYTE:
- switch(sourceType)
+ switch(source.data_type)
{
- case DT_BYTE: *((UINT8*)destinationPointer) = *((UINT8*) sourcePointer) ; break ;
- case DT_WORD: *((UINT8*)destinationPointer) = *((UINT16*)sourcePointer) ; break ;
- case DT_DOUBLE_WORD: *((UINT8*)destinationPointer) = *((UINT32*)sourcePointer) ; break ;
- case DT_LONG_WORD: *((UINT8*)destinationPointer) = *((UINT64*)sourcePointer) ; break ;
+ /* From a ? */
+ case DT_BYTE: *((UINT8*)dest.addr) = (*((UINT8*) source.addr)) & 0xff; break;
+ case DT_WORD: *((UINT8*)dest.addr) = (*((UINT16*)source.addr)) & 0x00ff; break;
+ case DT_DOUBLE_WORD: *((UINT8*)dest.addr) = (*((UINT32*)source.addr)) & 0x000000ff; break;
+ case DT_LONG_WORD: *((UINT8*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x00000000000000ff); break;
}
break ;
+ /* Copying to a 16-bit value */
case DT_WORD:
- switch(sourceType)
+ switch(source.data_type)
{
- case DT_BYTE: *((UINT16*)destinationPointer) = *((UINT8*) sourcePointer) ; break ;
- case DT_WORD: *((UINT16*)destinationPointer) = *((UINT16*)sourcePointer) ; break ;
- case DT_DOUBLE_WORD: *((UINT16*)destinationPointer) = *((UINT32*)sourcePointer) ; break ;
- // !!! This one is interesting too - shifter limiter action !!!
- case DT_LONG_WORD: *((UINT16*)destinationPointer) = *((UINT64*)sourcePointer) ; break ;
+ case DT_BYTE: *((UINT16*)dest.addr) = (*((UINT8*) source.addr)) & 0xff; break;
+ case DT_WORD: *((UINT16*)dest.addr) = (*((UINT16*)source.addr)) & 0xffff; break;
+ case DT_DOUBLE_WORD: *((UINT16*)dest.addr) = (*((UINT32*)source.addr)) & 0x0000ffff; break;
+ case DT_LONG_WORD: *((UINT16*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x000000000000ffff); break; /* Shift limiter action? */
}
break ;
+ /* Copying to a 32-bit value */
case DT_DOUBLE_WORD:
- switch(sourceType)
+ switch(source.data_type)
{
- case DT_BYTE: *((UINT32*)destinationPointer) = *((UINT8*) sourcePointer) ; break ;
- case DT_WORD: *((UINT32*)destinationPointer) = *((UINT16*)sourcePointer) ; break ;
- case DT_DOUBLE_WORD: *((UINT32*)destinationPointer) = *((UINT32*)sourcePointer) ; break ;
- case DT_LONG_WORD: *((UINT32*)destinationPointer) = *((UINT64*)sourcePointer) ; break ;
+ case DT_BYTE: *((UINT32*)dest.addr) = (*((UINT8*) source.addr)) & 0xff; break;
+ case DT_WORD: *((UINT32*)dest.addr) = (*((UINT16*)source.addr)) & 0xffff; break;
+ case DT_DOUBLE_WORD: *((UINT32*)dest.addr) = (*((UINT32*)source.addr)) & 0xffffffff; break;
+ case DT_LONG_WORD: *((UINT32*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x00000000ffffffff); break;
}
break ;
+ /* Copying to a 64-bit value */
case DT_LONG_WORD:
- switch(sourceType)
+ switch(source.data_type)
{
- case DT_BYTE: *((UINT64*)destinationPointer) = *((UINT8*) sourcePointer) ; break ;
+ case DT_BYTE: *((UINT64*)dest.addr) = (*((UINT8*)source.addr)) & 0xff; break;
- // !!! sign extending works on intel, others ???
- // !!! Need to check the shift limiter here too !!!
- case DT_WORD: destinationValue = (*((INT16*)sourcePointer)) << 16 ; // Insure sign extending
- destinationValue &= (UINT64)U64(0x000000ffffff0000) ;
- *((UINT64*)destinationPointer) = destinationValue ; break ;
+ case DT_WORD: destinationValue = (*((INT16*)source.addr)) << 16; /* Sign extend */
+ destinationValue &= U64(0x000000ffffff0000);
+ *((UINT64*)dest.addr) = destinationValue; break; /* Forget not, yon shift register */
- case DT_DOUBLE_WORD: *((UINT64*)destinationPointer) = *((UINT32*)sourcePointer) ; break ;
- case DT_LONG_WORD: *((UINT64*)destinationPointer) = *((UINT64*)sourcePointer) ; break ;
+ case DT_DOUBLE_WORD: *((UINT64*)dest.addr) = (*((UINT32*)source.addr)) & 0xffffffff; break;
+ case DT_LONG_WORD: *((UINT64*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x000000ffffffffff); break;
}
break ;
}
}
-// !! redundant functions (data and memory) can be handled with function pointers !!
-static void SetDataMemoryValue(void *sourcePointer, unsigned char sourceType, UINT32 destinationAddr)
+/* TODO: Wait-state timings! */
+static void SetDataMemoryValue(typed_pointer source, UINT32 destinationAddr)
{
- // mame_printf_debug("%d %x\n", sourceType, destinationAddr) ;
-
- // I wonder if this is how this should be done???
- switch(sourceType)
+ switch(source.data_type)
{
- case DT_BYTE: data_write_word_16le(destinationAddr, (UINT16)( (*((UINT8*) sourcePointer) & 0xff) ) ) ; break ;
- case DT_WORD: data_write_word_16le(destinationAddr, (UINT16)( (*((UINT16*)sourcePointer) & 0xffff) ) ) ; break ;
- case DT_DOUBLE_WORD: data_write_word_16le(destinationAddr, (UINT16)( (*((UINT32*)sourcePointer) & 0x0000ffff) ) ) ; break ;
+ case DT_BYTE: data_write_word_16le(destinationAddr, (UINT16)( (*((UINT8*) source.addr) & 0xff) ) ) ; break ;
+ case DT_WORD: data_write_word_16le(destinationAddr, (UINT16)( (*((UINT16*)source.addr) & 0xffff) ) ) ; break ;
+ case DT_DOUBLE_WORD: data_write_word_16le(destinationAddr, (UINT16)( (*((UINT32*)source.addr) & 0x0000ffff) ) ) ; break ;
// !!! Is this universal ???
// !!! Forget not, yon shift-limiter !!!
- case DT_LONG_WORD: data_write_word_16le(destinationAddr, (UINT16)( ((*((UINT64*)sourcePointer)) & (UINT64)U64(0x00000000ffff0000)) >> 16) ) ; break ;
+ case DT_LONG_WORD: data_write_word_16le(destinationAddr, (UINT16)( ((*((UINT64*)source.addr)) & U64(0x00000000ffff0000)) >> 16) ) ; break ;
}
}
-static void SetProgramMemoryValue(void *sourcePointer, unsigned char sourceType, UINT32 destinationAddr)
+/* TODO: Wait-state timings! */
+static void SetProgramMemoryValue(typed_pointer source, UINT32 destinationAddr)
{
- // I wonder if this is how this should be done???
- switch(sourceType)
+ switch(source.data_type)
{
- case DT_BYTE: program_write_word_16le(destinationAddr, (UINT16)( (*((UINT8*) sourcePointer) & 0xff) ) ) ; break ;
- case DT_WORD: program_write_word_16le(destinationAddr, (UINT16)( (*((UINT16*)sourcePointer) & 0xffff) ) ) ; break ;
- case DT_DOUBLE_WORD: program_write_word_16le(destinationAddr, (UINT16)( (*((UINT32*)sourcePointer) & 0x0000ffff) ) ) ; break ;
+ case DT_BYTE: program_write_word_16le(destinationAddr, (UINT16)( (*((UINT8*) source.addr) & 0xff) ) ) ; break ;
+ case DT_WORD: program_write_word_16le(destinationAddr, (UINT16)( (*((UINT16*)source.addr) & 0xffff) ) ) ; break ;
+ case DT_DOUBLE_WORD: program_write_word_16le(destinationAddr, (UINT16)( (*((UINT32*)source.addr) & 0x0000ffff) ) ) ; break ;
// !!! Is this universal ???
// !!! Forget not, yon shift-limiter !!!
- case DT_LONG_WORD: program_write_word_16le(destinationAddr, (UINT16)( ((*((UINT64*)sourcePointer)) & (UINT64)U64(0x00000000ffff0000)) >> 16) ) ; break ;
+ case DT_LONG_WORD: program_write_word_16le(destinationAddr, (UINT16)( ((*((UINT64*)source.addr)) & U64(0x00000000ffff0000)) >> 16) ) ; break ;
}
}
diff --git a/src/emu/cpu/dsp56k/dsp56pcu.c b/src/emu/cpu/dsp56k/dsp56pcu.c
index 8b2ff303173..a43188c5b50 100644
--- a/src/emu/cpu/dsp56k/dsp56pcu.c
+++ b/src/emu/cpu/dsp56k/dsp56pcu.c
@@ -211,8 +211,7 @@ static void pcu_reset(void)
IPR = 0x0000;
// FM.5-4
-// I_bits_set(0x03); This is what the manual says, but i'm dubious! Polygonet's HI interrupt wouldn't happen with the I bits set.
- I_bits_set(0x00);
+ I_bits_set(0x03);
S_bits_set(0);
L_bit_set(0);
S_bit_set(0);
@@ -287,7 +286,10 @@ static void pcu_service_interrupts(void)
{
// The host command input has a floating vector.
const UINT16 irq_vector = HV_bits() << 1;
+
+ core.ppc = PC;
PC = irq_vector;
+ change_pc(PC);
// TODO: 5-9 5-11 Gotta' Clear HC (HCP gets it too) when taking this exception!
HC_bit_set(0);