diff options
author | 2008-10-18 18:10:59 +0000 | |
---|---|---|
committer | 2008-10-18 18:10:59 +0000 | |
commit | e138837002fc37f58ea2f50023a44ce74b0f4dd0 (patch) | |
tree | bd75defa9c56f2e44f06e3768c162bf1b46e7df7 /src/emu/cpu/dsp56k | |
parent | 191767f62f4f1e6fa75e59065ce3d01ba198814e (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.c | 16 | ||||
-rw-r--r-- | src/emu/cpu/dsp56k/dsp56k.c | 4 | ||||
-rw-r--r-- | src/emu/cpu/dsp56k/dsp56ops.c | 4622 | ||||
-rw-r--r-- | src/emu/cpu/dsp56k/dsp56pcu.c | 6 |
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); |