diff --git a/.gitattributes b/.gitattributes index 760fdda6900..7e64e0183b5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -94,6 +94,14 @@ src/emu/cpu/dsp56k/dsp56k.h svneol=native#text/plain src/emu/cpu/dsp56k/dsp56mem.c svneol=native#text/plain src/emu/cpu/dsp56k/dsp56ops.c svneol=native#text/plain src/emu/cpu/dsp56k/dsp56pcu.c svneol=native#text/plain +src/emu/cpu/dsp56k/inst.c svneol=native#text/plain +src/emu/cpu/dsp56k/inst.h svneol=native#text/plain +src/emu/cpu/dsp56k/opcode.c svneol=native#text/plain +src/emu/cpu/dsp56k/opcode.h svneol=native#text/plain +src/emu/cpu/dsp56k/pmove.c svneol=native#text/plain +src/emu/cpu/dsp56k/pmove.h svneol=native#text/plain +src/emu/cpu/dsp56k/tables.c svneol=native#text/plain +src/emu/cpu/dsp56k/tables.h svneol=native#text/plain src/emu/cpu/e132xs/32xsdasm.c svneol=native#text/plain src/emu/cpu/e132xs/e132xs.c svneol=native#text/plain src/emu/cpu/e132xs/e132xs.h svneol=native#text/plain diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak index 4bb106f2255..28b92f1d338 100644 --- a/src/emu/cpu/cpu.mak +++ b/src/emu/cpu/cpu.mak @@ -1054,14 +1054,30 @@ ifneq ($(filter DSP56156,$(CPUS)),) OBJDIRS += $(CPUOBJ)/dsp56k CPUOBJS += $(CPUOBJ)/dsp56k/dsp56k.o DASMOBJS += $(CPUOBJ)/dsp56k/dsp56dsm.o +DASMOBJS += $(CPUOBJ)/dsp56k/opcode.o +DASMOBJS += $(CPUOBJ)/dsp56k/inst.o +DASMOBJS += $(CPUOBJ)/dsp56k/pmove.o +DASMOBJS += $(CPUOBJ)/dsp56k/tables.o endif $(CPUOBJ)/dsp56k/dsp56k.o: $(CPUSRC)/dsp56k/dsp56k.c \ + $(CPUSRC)/dsp56k/opcode.c \ + $(CPUSRC)/dsp56k/inst.c \ + $(CPUSRC)/dsp56k/pmove.c \ + $(CPUSRC)/dsp56k/tables.c \ $(CPUSRC)/dsp56k/dsp56ops.c \ $(CPUSRC)/dsp56k/dsp56mem.c \ $(CPUSRC)/dsp56k/dsp56pcu.c \ $(CPUSRC)/dsp56k/dsp56k.h +$(CPUOBJ)/dsp56k/dsp56dsm.o: $(CPUSRC)/dsp56k/opcode.c \ + $(CPUSRC)/dsp56k/opcode.h \ + $(CPUSRC)/dsp56k/inst.c \ + $(CPUSRC)/dsp56k/inst.h \ + $(CPUSRC)/dsp56k/pmove.c \ + $(CPUSRC)/dsp56k/pmove.h \ + $(CPUSRC)/dsp56k/tables.c \ + $(CPUSRC)/dsp56k/tables.h #------------------------------------------------- diff --git a/src/emu/cpu/dsp56k/dsp56dsm.c b/src/emu/cpu/dsp56k/dsp56dsm.c index 80537190db7..8cc109c2dc4 100644 --- a/src/emu/cpu/dsp56k/dsp56dsm.c +++ b/src/emu/cpu/dsp56k/dsp56dsm.c @@ -1,3271 +1,28 @@ /*************************************************************************** - dsp56dsm.c - Disassembler for the portable Motorola/Freescale dsp56k emulator. - Written by Andrew Gardner + dsp56dsm.c + Disassembler for the portable Motorola/Freescale dsp56k emulator. + Written by Andrew Gardner ***************************************************************************/ -/* - This disassembler has been 95% verified against the docs and a different disassembler. - The docs list some conflicting and confusing behaviors. These are mareked with an asterisk - and need to be tested on real hardware before this disassembler is considered 100% complete. -*/ +#include "opcode.h" #include "emu.h" #include "dsp56k.h" -/*******************/ -/* Dasm prototypes */ -/*******************/ -static size_t dsp56k_dasm_addsub_2 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_mac_1 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_macr_1 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_tfr_2 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_move_1 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_mpy_1 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_mpyr_1 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_mpy_2 (const UINT16 op_byte, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_mac_2 (const UINT16 op_byte, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_clr (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_add (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_move (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_tfr (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_rnd (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_tst (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_inc (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_inc24 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_or (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_asr (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_asl (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_lsr (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_lsl (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -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_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); -static size_t dsp56k_dasm_not (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_dec (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_dec24 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_and (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_abs (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_ror (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_rol (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_cmpm (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_mpy (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_mpyr (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_mac (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_macr (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); -static size_t dsp56k_dasm_adc (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_andi (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_asl4 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_asr4 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_asr16 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_bfop (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_bcc (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc); -static size_t dsp56k_dasm_bcc_1 (const UINT16 op, char* opcode_str, char* arg_str, const offs_t pc); -static size_t dsp56k_dasm_bcc_2 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_bra (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc); -static size_t dsp56k_dasm_bra_1 (const UINT16 op, char* opcode_str, char* arg_str, const offs_t pc); -static size_t dsp56k_dasm_bra_2 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_brkcc (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_bscc (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc); -static size_t dsp56k_dasm_bscc_1 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_bsr (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc); -static size_t dsp56k_dasm_bsr_1 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_chkaau (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_debug (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_debugcc (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_div (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_dmac (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_do (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc); -static size_t dsp56k_dasm_do_1 (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc); -static size_t dsp56k_dasm_do_2 (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc); -static size_t dsp56k_dasm_doforever (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc); -static size_t dsp56k_dasm_enddo (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_ext (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_illegal (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_imac (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_impy (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_jcc (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_jcc_1 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_jmp (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_jmp_1 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_jscc (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_jscc_1 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_jsr (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_jsr_1 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_jsr_2 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_lea (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_lea_1 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_macsuuu (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_move_2 (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_movec (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_movec_1 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_movec_2 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_movec_3 (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_movec_4 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_movec_5 (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_movei (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_movem (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_movem_1 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_movem_2 (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_movep (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_movep_1 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_moves (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_mpysuuu (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_negc (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_nop (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_norm (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_ori (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_rep (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_rep_1 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_rep_2 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_repcc (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_reset (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_rti (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_rts (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_stop (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_swap (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_swi (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_tcc (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_tfr2 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_tfr3 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_tst2 (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_wait (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_zero (const UINT16 op, char* opcode_str, char* arg_str); - - -/***************************/ -/* Table decoder functions */ -/***************************/ -static int decode_BBB_table (UINT16 BBB); -static void decode_cccc_table (UINT16 cccc, char *mnemonic); -static void decode_DDDDD_table(UINT16 DDDDD, char *SD); -static void decode_DD_table (UINT16 DD, char *SD); -static void decode_DDF_table (UINT16 DD, UINT16 F, char *S, char *D); -static void decode_EE_table (UINT16 EE, char *D); -static void decode_F_table (UINT16 F, char *SD); -static void decode_h0hF_table (UINT16 h0h, UINT16 F, char *S, char *D); -static void decode_HH_table (UINT16 HH, char *SD); -static void decode_HHH_table (UINT16 HHH, char *SD); -static void decode_IIII_table (UINT16 IIII, char *S, char *D); -static void decode_JJJF_table (UINT16 JJJ, UINT16 F, char *S, char *D); -static void decode_JJF_table (UINT16 JJ, UINT16 F, char *S, char *D); -static void decode_JF_table (UINT16 J, UINT16 F, char *S, char *D); -static void decode_k_table (UINT16 k, char *Dnot); -static void decode_kSign_table(UINT16 k, char *plusMinus); -static void decode_KKK_table (UINT16 KKK, char *D1, char *D2); -static int decode_NN_table (UINT16 NN); -static int decode_TT_table (UINT16 TT); -static void decode_QQF_table (UINT16 QQ, UINT16 F, char *S1, char *S2, char *D); -static void decode_QQF_special_table(UINT16 QQ, UINT16 F, char *S1, char *S2, char *D); -static void decode_QQQF_table (UINT16 QQQ, UINT16 F, char *S1, char *S2, char *D); -static int decode_RR_table (UINT16 RR); -static int decode_rr_table (UINT16 rr); -static void decode_s_table (UINT16 s, char *arithmetic); -static void decode_ss_table (UINT16 ss, char *arithmetic); -static void decode_uuuuF_table(UINT16 uuuu, UINT16 F, char *arg, char *S, char *D); -static void decode_Z_table (UINT16 Z, char *ea); - -static void assemble_ea_from_m_table (UINT16 m, int n, char *ea); -static void assemble_eas_from_m_table(UINT16 mm, int n1, int n2, char *ea1, char *ea2); -static void assemble_ea_from_MM_table(UINT16 MM, int n, char *ea); -static void assemble_ea_from_t_table (UINT16 t, UINT16 val, char *ea); -static void assemble_ea_from_q_table (UINT16 q, int n, char *ea); -static void assemble_ea_from_z_table (UINT16 z, int n, char *ea); - -static void assemble_D_from_P_table(UINT16 P, UINT16 ppppp, char *D); -static void assemble_arguments_from_W_table(UINT16 W, char *args, char ma, char *SD, char *ea); -static void assemble_reg_from_W_table(UINT16 W, char *args, char ma, char *SD, INT8 xx); - -static void assemble_address_from_IO_short_address(UINT16 pp, char *ea); -static INT8 get_6_bit_signed_value(UINT16 bits); - - -/**********************************/ -/* Parallel memory move functions */ -/**********************************/ -static void decode_x_memory_data_move(const UINT16 op, char* parallel_move_str); -static void decode_x_memory_data_move2(const UINT16 op, char* parallel_move_str, char* d_register); -static void decode_dual_x_memory_data_read(const UINT16 op, char* parallel_move_str, char* parallel_move_str2, char* d_register); -static void decode_register_to_register_data_move(const UINT16 op, char* parallel_move_str, char* d_register); -static void decode_x_memory_data_write_and_register_data_move(const UINT16 op, char* parallel_move_str, char* parallel_move_str2); -static void decode_address_register_update(const UINT16 op, char* parallel_move_str); -static void decode_x_memory_data_move_with_short_displacement(const UINT16 op, const UINT16 op2, char* parallel_move_str); - - -/********************/ -/* Helper functions */ -/********************/ -#define BITS(CUR,MASK) (dsp56k_op_mask(CUR,MASK)) -static UINT16 dsp56k_op_mask(UINT16 op, UINT16 mask); -static void pad_string(const int dest_length, char* string); - -enum bbbType { BBB_UPPER, BBB_MIDDLE, BBB_LOWER, BBB_INVALID }; - - - /*****************************/ /* Main disassembly function */ /*****************************/ CPU_DISASSEMBLE( dsp56k ) { - /* ORDER: Handle parallel types in the ALU */ - /* Handle the rest */ - unsigned size = 0; + const UINT16 w0 = oprom[0] | (oprom[1] << 8); + const UINT16 w1 = oprom[2] | (oprom[3] << 8); - char arg_str[128] = ""; - char opcode_str[128] = ""; - char parallel_move_str[128] = ""; - char parallel_move_str2[128] = ""; - - const UINT16 op = oprom[0] | (oprom[1] << 8); - const UINT16 op2 = oprom[2] | (oprom[3] << 8); - - /* Dual X Memory Data Read : 011m mKKK .rr. .... : A-142*/ - if ((op & 0xe000) == 0x6000) - { - char d_register[32] = ""; - - /* Quote: (MOVE, MAC(R), MPY(R), ADD, SUB, TFR) */ - UINT16 op_byte = op & 0x00ff; - - /* ADD : 011m mKKK 0rru Fuuu : A-22 */ - /* SUB : 011m mKKK 0rru Fuuu : A-202 */ - /* Note: 0x0094 check allows command to drop through to MOVE and TFR */ - if (((op & 0xe080) == 0x6000) && ((op & 0x0094) != 0x0010)) - { - size = dsp56k_dasm_addsub_2(op_byte, opcode_str, arg_str, d_register); - } - /* MAC : 011m mKKK 1xx0 F1QQ : A-122 */ - else if ((op & 0xe094) == 0x6084) - { - size = dsp56k_dasm_mac_1(op_byte, opcode_str, arg_str, d_register); - } - /* MACR: 011m mKKK 1--1 F1QQ : A-124 */ - else if ((op & 0xe094) == 0x6094) - { - size = dsp56k_dasm_macr_1(op_byte, opcode_str, arg_str, d_register); - } - /* TFR : 011m mKKK 0rr1 F0DD : A-212 */ - else if ((op & 0xe094) == 0x6010) - { - size = dsp56k_dasm_tfr_2(op_byte, opcode_str, arg_str, d_register); - } - /* MOVE : 011m mKKK 0rr1 0000 : A-128 */ - else if ((op & 0xe09f) == 0x6010) - { - /* Note: The opcode encoding : 011x xxxx 0xx1 0000 (move + double memory read) - is .identical. to (tfr X0,A + two parallel reads). This sparks the notion - that these 'move' opcodes don't actually exist and are just there as - documentation. Real-world examples would need to be examined to come - to a satisfactory conclusion, but as it stands, tfr will override this - move operation. */ - size = dsp56k_dasm_move_1(op_byte, opcode_str, arg_str, d_register); - } - /* MPY : 011m mKKK 1xx0 F0QQ : A-160 */ - else if ((op & 0xe094) == 0x6080) - { - size = dsp56k_dasm_mpy_1(op_byte, opcode_str, arg_str, d_register); - } - /* MPYR : 011m mKKK 1--1 F0QQ : A-162 */ - else if ((op & 0xe094) == 0x6090) - { - size = dsp56k_dasm_mpyr_1(op_byte, opcode_str, arg_str, d_register); - } - - /* Now evaluate the parallel data move */ - decode_dual_x_memory_data_read(op, parallel_move_str, parallel_move_str2, d_register); - } - /* X Memory Data Write and Register Data Move : 0001 011k RRDD .... : A-140 */ - else if ((op & 0xfe00) == 0x1600) - { - /* Quote: (MPY or MAC) */ - UINT16 op_byte = op & 0x00ff; - - /* MPY : 0001 0110 RRDD FQQQ : A-160 */ - if ((op & 0xff00) == 0x1600) - { - size = dsp56k_dasm_mpy_2(op_byte, opcode_str, arg_str); - } - /* MAC : 0001 0111 RRDD FQQQ : A-122 */ - else if ((op & 0xff00) == 0x1700) - { - size = dsp56k_dasm_mac_2(op_byte, opcode_str, arg_str); - } - - /* Now evaluate the parallel data move */ - 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 }; - - UINT16 op_byte = 0x0000; - char d_register[32] = ""; - int parallelType = -1; - - /* 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) - { - /* Now check it against all the other potential collisions */ - /* This is necessary because "don't care bits" get in the way. */ - /* - MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 - MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 - MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 - */ - if (((op2 & 0xfe20) != 0x0200) && - ((op2 & 0xf810) != 0x3800) && - ((op2 & 0x00ff) != 0x0011)) - { - op_byte = op2 & 0x00ff; - parallelType = kXMemoryDataMoveWithDisp; - } - } - - - if (parallelType != -1) - { - /* 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) - { - size = dsp56k_dasm_clr(op_byte, opcode_str, arg_str, d_register); - } - /* ADD : .... .... 0000 FJJJ : A-22 */ - else if ((op_byte & 0x00f0) == 0x0000) - { - size = dsp56k_dasm_add(op_byte, opcode_str, arg_str, d_register); - } - - - /* MOVE : .... .... 0001 0001 : A-128 */ - else if ((op_byte & 0x00ff) == 0x0011) - { - size = dsp56k_dasm_move(op_byte, opcode_str, arg_str, d_register); - } - /* TFR : .... .... 0001 FJJJ : A-212 */ - else if ((op_byte & 0x00f0) == 0x0010) - { - size = dsp56k_dasm_tfr(op_byte, opcode_str, arg_str, d_register); - } - - - /* RND : .... .... 0010 F000 : A-188 */ - else if ((op_byte & 0x00f7) == 0x0020) - { - size = dsp56k_dasm_rnd(op_byte, opcode_str, arg_str, d_register); - } - /* TST : .... .... 0010 F001 : A-218 */ - else if ((op_byte & 0x00f7) == 0x0021) - { - size = dsp56k_dasm_tst(op_byte, opcode_str, arg_str, d_register); - } - /* INC : .... .... 0010 F010 : A-104 */ - else if ((op_byte & 0x00f7) == 0x0022) - { - size = dsp56k_dasm_inc(op_byte, opcode_str, arg_str, d_register); - } - /* INC24 : .... .... 0010 F011 : A-106 */ - else if ((op_byte & 0x00f7) == 0x0023) - { - size = dsp56k_dasm_inc24(op_byte, opcode_str, arg_str, d_register); - } - /* OR : .... .... 0010 F1JJ : A-176 */ - else if ((op_byte & 0x00f4) == 0x0024) - { - size = dsp56k_dasm_or(op_byte, opcode_str, arg_str, d_register); - } - - - /* ASR : .... .... 0011 F000 : A-32 */ - else if ((op_byte & 0x00f7) == 0x0030) - { - size = dsp56k_dasm_asr(op_byte, opcode_str, arg_str, d_register); - } - /* ASL : .... .... 0011 F001 : A-28 */ - else if ((op_byte & 0x00f7) == 0x0031) - { - size = dsp56k_dasm_asl(op_byte, opcode_str, arg_str, d_register); - } - /* LSR : .... .... 0011 F010 : A-120 */ - else if ((op_byte & 0x00f7) == 0x0032) - { - size = dsp56k_dasm_lsr(op_byte, opcode_str, arg_str, d_register); - } - /* LSL : .... .... 0011 F011 : A-118 */ - else if ((op_byte & 0x00f7) == 0x0033) - { - size = dsp56k_dasm_lsl(op_byte, opcode_str, arg_str, d_register); - } - /* EOR : .... .... 0011 F1JJ : A-94 */ - else if ((op_byte & 0x00f4) == 0x0034) - { - size = dsp56k_dasm_eor(op_byte, opcode_str, arg_str, d_register); - } - - - /* SUBL : .... .... 0100 F001 : A-204 */ - else if ((op_byte & 0x00f7) == 0x0041) - { - size = dsp56k_dasm_subl(op_byte, opcode_str, arg_str, d_register); - } - /* SUB : .... .... 0100 FJJJ : A-202 */ - else if ((op_byte & 0x00f0) == 0x0040) - { - size = dsp56k_dasm_sub(op_byte, opcode_str, arg_str, d_register); - } - - - /* CLR24 : .... .... 0101 F001 : A-62 */ - else if ((op_byte & 0x00f7) == 0x0051) - { - size = dsp56k_dasm_clr24(op_byte, opcode_str, arg_str, d_register); - } - /* SBC : .... .... 0101 F01J : A-198 */ - else if ((op_byte & 0x00f6) == 0x0052) - { - size = dsp56k_dasm_sbc(op_byte, opcode_str, arg_str, d_register); - } - /* CMP : .... .... 0101 FJJJ : A-64 */ - else if ((op_byte & 0x00f0) == 0x0050) - { - size = dsp56k_dasm_cmp(op_byte, opcode_str, arg_str, d_register); - } - - - /* NEG : .... .... 0110 F000 : A-166 */ - else if ((op_byte & 0x00f7) == 0x0060) - { - size = dsp56k_dasm_neg(op_byte, opcode_str, arg_str, d_register); - } - /* NOT : .... .... 0110 F001 : A-174 */ - else if ((op_byte & 0x00f7) == 0x0061) - { - size = dsp56k_dasm_not(op_byte, opcode_str, arg_str, d_register); - } - /* DEC : .... .... 0110 F010 : A-72 */ - else if ((op_byte & 0x00f7) == 0x0062) - { - size = dsp56k_dasm_dec(op_byte, opcode_str, arg_str, d_register); - } - /* DEC24 : .... .... 0110 F011 : A-74 */ - else if ((op_byte & 0x00f7) == 0x0063) - { - size = dsp56k_dasm_dec24(op_byte, opcode_str, arg_str, d_register); - } - /* AND : .... .... 0110 F1JJ : A-24 */ - else if ((op_byte & 0x00f4) == 0x0064) - { - size = dsp56k_dasm_and(op_byte, opcode_str, arg_str, d_register); - } - - - /* ABS : .... .... 0111 F001 : A-18 */ - if ((op_byte & 0x00f7) == 0x0071) - { - size = dsp56k_dasm_abs(op_byte, opcode_str, arg_str, d_register); - } - /* ROR : .... .... 0111 F010 : A-192 */ - else if ((op_byte & 0x00f7) == 0x0072) - { - size = dsp56k_dasm_ror(op_byte, opcode_str, arg_str, d_register); - } - /* ROL : .... .... 0111 F011 : A-190 */ - else if ((op_byte & 0x00f7) == 0x0073) - { - size = dsp56k_dasm_rol(op_byte, opcode_str, arg_str, d_register); - } - /* CMPM : .... .... 0111 FJJJ : A-66 */ - else if ((op_byte & 0x00f0) == 0x0070) - { - size = dsp56k_dasm_cmpm(op_byte, opcode_str, arg_str, d_register); - } - - - /* MPY : .... .... 1k00 FQQQ : A-160 -- CONFIRMED TYPO IN DOCS (HHHH vs HHHW) */ - else if ((op_byte & 0x00b0) == 0x0080) - { - size = dsp56k_dasm_mpy(op_byte, opcode_str, arg_str, d_register); - } - /* MPYR : .... .... 1k01 FQQQ : A-162 */ - else if ((op_byte & 0x00b0) == 0x0090) - { - size = dsp56k_dasm_mpyr(op_byte, opcode_str, arg_str, d_register); - } - /* MAC : .... .... 1k10 FQQQ : A-122 */ - else if ((op_byte & 0x00b0) == 0x00a0) - { - size = dsp56k_dasm_mac(op_byte, opcode_str, arg_str, d_register); - } - /* MACR : .... .... 1k11 FQQQ : A-124 -- DRAMA - rr vs xx (805) */ - else if ((op_byte & 0x00b0) == 0x00b0) - { - size = dsp56k_dasm_macr(op_byte, opcode_str, arg_str, d_register); - } - - - /* Now evaluate the parallel data move */ - switch (parallelType) - { - case kNoParallelDataMove: - /* DO NOTHING */ - size = 1; - break; - case kRegisterToRegister: - decode_register_to_register_data_move(op, parallel_move_str, d_register); - size = 1; - break; - case kAddressRegister: - decode_address_register_update(op, parallel_move_str); - size = 1; - break; - case kXMemoryDataMove: - decode_x_memory_data_move(op, parallel_move_str); - size = 1; - break; - case kXMemoryDataMove2: - decode_x_memory_data_move2(op, parallel_move_str, d_register); - size = 1; - break; - case kXMemoryDataMoveWithDisp: - decode_x_memory_data_move_with_short_displacement(op, op2, parallel_move_str); - size = 2; - break; - } - } - } - - /* Assemble and return parallel move operation */ - if (size > 0) - { - char space[32] = ""; - - pad_string(11, opcode_str); - if (strlen(parallel_move_str) != 0) - pad_string(15, arg_str); - if (strlen(parallel_move_str2) != 0) - sprintf(space, " "); - - sprintf(buffer, "%s%s%s%s%s", opcode_str, arg_str, parallel_move_str, space, parallel_move_str2); - - return (size | DASMFLAG_SUPPORTED); - } - - - /******************************/ - /* Remaining non-parallel ops */ - /******************************/ - - /* ADC : 0001 0101 0000 F01J : A-20 */ - if ((op & 0xfff6) == 0x1502) - { - size = dsp56k_dasm_adc(op, opcode_str, arg_str); - } - /* 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)) - { - size = dsp56k_dasm_andi(op, opcode_str, arg_str); - } - /* ASL4 : 0001 0101 0011 F001 : A-30 */ - else if ((op & 0xfff7) == 0x1531) - { - size = dsp56k_dasm_asl4(op, opcode_str, arg_str); - } - /* ASR4 : 0001 0101 0011 F000 : A-34 */ - else if ((op & 0xfff7) == 0x1530) - { - size = dsp56k_dasm_asr4(op, opcode_str, arg_str); - } - /* ASR16 : 0001 0101 0111 F000 : A-36 */ - else if ((op & 0xfff7) == 0x1570) - { - size = dsp56k_dasm_asr16(op, opcode_str, arg_str); - } - /* BFCHG : 0001 0100 11Pp pppp BBB1 0010 iiii iiii : A-38 */ - else if (((op & 0xffc0) == 0x14c0) && ((op2 & 0x1f00) == 0x1200)) - { - size = dsp56k_dasm_bfop(op, op2, opcode_str, arg_str); - } - /* BFCHG : 0001 0100 101- --RR BBB1 0010 iiii iiii : A-38 */ - else if (((op & 0xffe0) == 0x14a0) && ((op2 & 0x1f00) == 0x1200)) - { - size = dsp56k_dasm_bfop(op, op2, opcode_str, arg_str); - } - /* BFCHG : 0001 0100 100D DDDD BBB1 0010 iiii iiii : A-38 */ - else if (((op & 0xffe0) == 0x1480) && ((op2 & 0x1f00) == 0x1200)) - { - size = dsp56k_dasm_bfop(op, op2, opcode_str, arg_str); - } - /* BFCLR : 0001 0100 11Pp pppp BBB0 0100 iiii iiii : A-40 */ - else if (((op & 0xffc0) == 0x14c0) && ((op2 & 0x1f00) == 0x0400)) - { - size = dsp56k_dasm_bfop(op, op2, opcode_str, arg_str); - } - /* BFCLR : 0001 0100 101- --RR BBB0 0100 iiii iiii : A-40 */ - else if (((op & 0xffe0) == 0x14a0) && ((op2 & 0x1f00) == 0x0400)) - { - size = dsp56k_dasm_bfop(op, op2, opcode_str, arg_str); - } - /* BFCLR : 0001 0100 100D DDDD BBB0 0100 iiii iiii : A-40 */ - else if (((op & 0xffe0) == 0x1480) && ((op2 & 0x1f00) == 0x0400)) - { - size = dsp56k_dasm_bfop(op, op2, opcode_str, arg_str); - } - /* BFSET : 0001 0100 11Pp pppp BBB1 1000 iiii iiii : A-42 */ - else if (((op & 0xffc0) == 0x14c0) && ((op2 & 0x1f00) == 0x1800)) - { - size = dsp56k_dasm_bfop(op, op2, opcode_str, arg_str); - } - /* BFSET : 0001 0100 101- --RR BBB1 1000 iiii iiii : A-42 */ - else if (((op & 0xffe0) == 0x14a0) && ((op2 & 0x1f00) == 0x1800)) - { - size = dsp56k_dasm_bfop(op, op2, opcode_str, arg_str); - } - /* BFSET : 0001 0100 100D DDDD BBB1 1000 iiii iiii : A-42 */ - else if (((op & 0xffe0) == 0x1480) && ((op2 & 0x1f00) == 0x1800)) - { - size = dsp56k_dasm_bfop(op, op2, opcode_str, arg_str); - } - /* BFTSTH : 0001 0100 01Pp pppp BBB1 0000 iiii iiii : A-44 */ - else if (((op & 0xffc0) == 0x1440) && ((op2 & 0x1f00) == 0x1000)) - { - size = dsp56k_dasm_bfop(op, op2, opcode_str, arg_str); - } - /* BFTSTH : 0001 0100 001- --RR BBB1 0000 iiii iiii : A-44 */ - else if (((op & 0xffe0) == 0x1420) && ((op2 & 0x1f00) == 0x1000)) - { - size = dsp56k_dasm_bfop(op, op2, opcode_str, arg_str); - } - /* BFTSTH : 0001 0100 000D DDDD BBB1 0000 iiii iiii : A-44 */ - else if (((op & 0xffe0) == 0x1400) && ((op2 & 0x1f00) == 0x1000)) - { - size = dsp56k_dasm_bfop(op, op2, opcode_str, arg_str); - } - /* BFTSTL : 0001 0100 01Pp pppp BBB0 0000 iiii iiii : A-46 */ - else if (((op & 0xffc0) == 0x1440) && ((op2 & 0x1f00) == 0x0000)) - { - size = dsp56k_dasm_bfop(op, op2, opcode_str, arg_str); - } - /* BFTSTL : 0001 0100 001- --RR BBB0 0000 iiii iiii : A-46 */ - else if (((op & 0xffe0) == 0x1420) && ((op2 & 0x1f00) == 0x0000)) - { - size = dsp56k_dasm_bfop(op, op2, opcode_str, arg_str); - } - /* BFTSTL : 0001 0100 000D DDDD BBB0 0000 iiii iiii : A-46 */ - else if (((op & 0xffe0) == 0x1400) && ((op2 & 0x1f00) == 0x0000)) - { - size = dsp56k_dasm_bfop(op, op2, opcode_str, arg_str); - } - /* Bcc : 0000 0111 --11 cccc xxxx xxxx xxxx xxxx : A-48 */ - else if (((op & 0xff30) == 0x0730) && ((op2 & 0x0000) == 0x0000)) - { - size = dsp56k_dasm_bcc(op, op2, opcode_str, arg_str, pc); - } - /* Bcc : 0010 11cc ccee eeee : A-48 */ - else if ((op & 0xfc00) == 0x2c00) - { - size = dsp56k_dasm_bcc_1(op, opcode_str, arg_str, pc); - } - /* Bcc : 0000 0111 RR10 cccc : A-48 */ - else if ((op & 0xff30) == 0x0720) - { - size = dsp56k_dasm_bcc_2(op, opcode_str, arg_str); - } - /* BRA : 0000 0001 0011 11-- xxxx xxxx xxxx xxxx : A-50 */ - else if (((op & 0xfffc) == 0x013c) && ((op2 & 0x0000) == 0x0000)) - { - size = dsp56k_dasm_bra(op, op2, opcode_str, arg_str, pc); - } - /* BRA : 0000 1011 aaaa aaaa : A-50 */ - else if ((op & 0xff00) == 0x0b00) - { - size = dsp56k_dasm_bra_1(op, opcode_str, arg_str, pc); - } - /* BRA : 0000 0001 0010 11RR : A-50 */ - else if ((op & 0xfffc) == 0x012c) - { - size = dsp56k_dasm_bra_2(op, opcode_str, arg_str); - } - /* BRKc : 0000 0001 0001 cccc : A-52 */ - else if ((op & 0xfff0) == 0x0110) - { - size = dsp56k_dasm_brkcc(op, opcode_str, arg_str); - } - /* BScc : 0000 0111 --01 cccc xxxx xxxx xxxx xxxx : A-54 */ - else if (((op & 0xff30) == 0x0710) && ((op2 & 0x0000) == 0x0000)) - { - size = dsp56k_dasm_bscc(op, op2, opcode_str, arg_str, pc); - } - /* BScc : 0000 0111 RR00 cccc : A-54 */ - else if ((op & 0xff30) == 0x0700) - { - size = dsp56k_dasm_bscc_1(op, opcode_str, arg_str); - } - /* BSR : 0000 0001 0011 10-- xxxx xxxx xxxx xxxx : A-56 */ - else if (((op & 0xfffc) == 0x0138) && ((op2 & 0x0000) == 0x0000)) - { - size = dsp56k_dasm_bsr(op, op2, opcode_str, arg_str, pc); - } - /* BSR : 0000 0001 0010 10RR : A-56 */ - else if ((op & 0xfffc) == 0x0128) - { - size = dsp56k_dasm_bsr_1(op, opcode_str, arg_str); - } - /* CHKAAU : 0000 0000 0000 0100 : A-58 */ - else if ((op & 0xffff) == 0x0004) - { - size = dsp56k_dasm_chkaau(op, opcode_str, arg_str); - } - /* DEBUG : 0000 0000 0000 0001 : A-68 */ - else if ((op & 0xffff) == 0x0001) - { - size = dsp56k_dasm_debug(op, opcode_str, arg_str); - } - /* DEBUGcc : 0000 0000 0101 cccc : A-70 */ - else if ((op & 0xfff0) == 0x0050) - { - size = dsp56k_dasm_debugcc(op, opcode_str, arg_str); - } - /* DIV : 0001 0101 0--0 F1DD : A-76 */ - else if ((op & 0xff94) == 0x1504) - { - size = dsp56k_dasm_div(op, opcode_str, arg_str); - } - /* DMAC : 0001 0101 10s1 FsQQ : A-80 */ - else if ((op & 0xffd0) == 0x1590) - { - size = dsp56k_dasm_dmac(op, opcode_str, arg_str); - } - /* DO : 0000 0000 110- --RR xxxx xxxx xxxx xxxx : A-82 */ - else if (((op & 0xffe0) == 0x00c0) && ((op2 & 0x0000) == 0x0000)) - { - size = dsp56k_dasm_do(op, op2, opcode_str, arg_str, pc); - } - /* DO : 0000 1110 iiii iiii xxxx xxxx xxxx xxxx : A-82 */ - else if (((op & 0xff00) == 0x0e00) && ((op2 & 0x0000) == 0x0000)) - { - size = dsp56k_dasm_do_1(op, op2, opcode_str, arg_str, pc); - } - /* DO : 0000 0100 000D DDDD xxxx xxxx xxxx xxxx : A-82 */ - else if (((op & 0xffe0) == 0x0400) && ((op2 & 0x0000) == 0x0000)) - { - size = dsp56k_dasm_do_2(op, op2, opcode_str, arg_str, pc); - } - /* DO FOREVER : 0000 0000 0000 0010 xxxx xxxx xxxx xxxx : A-88 */ - else if (((op & 0xffff) == 0x0002) && ((op2 & 0x0000) == 0x0000)) - { - size = dsp56k_dasm_doforever(op, op2, opcode_str, arg_str, pc); - } - /* ENDDO : 0000 0000 0000 1001 : A-92 */ - else if ((op & 0xffff) == 0x0009) - { - size = dsp56k_dasm_enddo(op, opcode_str, arg_str); - } - /* EXT : 0001 0101 0101 F010 : A-96 */ - else if ((op & 0xfff7) == 0x1552) - { - size = dsp56k_dasm_ext(op, opcode_str, arg_str); - } - /* ILLEGAL : 0000 0000 0000 1111 : A-98 */ - else if ((op & 0xffff) == 0x000f) - { - size = dsp56k_dasm_illegal(op, opcode_str, arg_str); - } - /* IMAC : 0001 0101 1010 FQQQ : A-100 */ - else if ((op & 0xfff0) == 0x15a0) - { - size = dsp56k_dasm_imac(op, opcode_str, arg_str); - } - /* IMPY : 0001 0101 1000 FQQQ : A-102 */ - else if ((op & 0xfff0) == 0x1580) - { - size = dsp56k_dasm_impy(op, opcode_str, arg_str); - } - /* Jcc : 0000 0110 --11 cccc xxxx xxxx xxxx xxxx : A-108 */ - else if (((op & 0xff30) == 0x0630) && ((op2 & 0x0000) == 0x0000)) - { - size = dsp56k_dasm_jcc(op, op2, opcode_str, arg_str); - } - /* Jcc : 0000 0110 RR10 cccc : A-108 */ - else if ((op & 0xff30) == 0x0620 ) - { - size = dsp56k_dasm_jcc_1(op, opcode_str, arg_str); - } - /* JMP : 0000 0001 0011 01-- xxxx xxxx xxxx xxxx : A-110 */ - else if (((op & 0xfffc) == 0x0134) && ((op2 & 0x0000) == 0x0000)) - { - size = dsp56k_dasm_jmp(op, op2, opcode_str, arg_str); - } - /* JMP : 0000 0001 0010 01RR : A-110 */ - else if ((op & 0xfffc) == 0x0124) - { - size = dsp56k_dasm_jmp_1(op, opcode_str, arg_str); - } - /* JScc : 0000 0110 --01 cccc xxxx xxxx xxxx xxxx : A-112 */ - else if (((op & 0xff30) == 0x0610) && ((op2 & 0x0000) == 0x0000)) - { - size = dsp56k_dasm_jscc(op, op2, opcode_str, arg_str); - } - /* JScc : 0000 0110 RR00 cccc : A-112 */ - else if ((op & 0xff30) == 0x0600) - { - size = dsp56k_dasm_jscc_1(op, opcode_str, arg_str); - } - /* JSR : 0000 0001 0011 00-- xxxx xxxx xxxx xxxx : A-114 */ - else if (((op & 0xfffc) == 0x0130) && ((op2 & 0x0000) == 0x0000)) - { - size = dsp56k_dasm_jsr(op, op2, opcode_str, arg_str); - } - /* JSR : 0000 1010 AAAA AAAA : A-114 */ - else if ((op & 0xff00) == 0x0a00) - { - size = dsp56k_dasm_jsr_1(op, opcode_str, arg_str); - } - /* JSR : 0000 0001 0010 00RR : A-114 */ - else if ((op & 0xfffc) == 0x0120) - { - size = dsp56k_dasm_jsr_2(op, opcode_str, arg_str); - } - /* LEA : 0000 0001 11TT MMRR : A-116 */ - else if ((op & 0xffc0) == 0x01c0) - { - size = dsp56k_dasm_lea(op, opcode_str, arg_str); - } - /* LEA : 0000 0001 10NN MMRR : A-116 */ - else if ((op & 0xffc0) == 0x0180) - { - size = dsp56k_dasm_lea_1(op, opcode_str, arg_str); - } - /* MAC(su,uu) : 0001 0101 1110 FsQQ : A-126 */ - else if ((op & 0xfff0) == 0x15e0) - { - size = dsp56k_dasm_macsuuu(op, opcode_str, arg_str); - } - /* MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 */ - else if (((op & 0xff00) == 0x0500) && ((op2 & 0x00ff) == 0x0011)) - { - size = dsp56k_dasm_move_2(op, op2, opcode_str, arg_str); - } - /* MOVE(C) : 0011 1WDD DDD0 MMRR : A-144 */ - else if ((op & 0xf810) == 0x3800) - { - size = dsp56k_dasm_movec(op, opcode_str, arg_str); - } - /* MOVE(C) : 0011 1WDD DDD1 q0RR : A-144 */ - else if ((op & 0xf814) == 0x3810) - { - size = dsp56k_dasm_movec_1(op, opcode_str, arg_str); - } - /* MOVE(C) : 0011 1WDD DDD1 Z11- : A-144 */ - else if ((op & 0xf816) == 0x3816) - { - size = dsp56k_dasm_movec_2(op, opcode_str, arg_str); - } - /* MOVE(C) : 0011 1WDD DDD1 t10- xxxx xxxx xxxx xxxx : A-144 */ - else if (((op & 0xf816) == 0x3814) && ((op2 & 0x0000) == 0x0000)) - { - size = dsp56k_dasm_movec_3(op, op2, opcode_str, arg_str); - } - /* MOVE(C) : 0010 10dd dddD DDDD : A-144 */ - else if ((op & 0xfc00) == 0x2800) - { - size = dsp56k_dasm_movec_4(op, opcode_str, arg_str); - } - /* MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 */ - else if (((op & 0xff00) == 0x0500) && ((op2 & 0xf810) == 0x3800)) - { - size = dsp56k_dasm_movec_5(op, op2, opcode_str, arg_str); - } - /* MOVE(I) : 0010 00DD BBBB BBBB : A-150 */ - else if ((op & 0xfc00) == 0x2000) - { - size = dsp56k_dasm_movei(op, opcode_str, arg_str); - } - /* MOVE(M) : 0000 001W RR0M MHHH : A-152 */ - else if ((op & 0xfe20) == 0x0200) - { - size = dsp56k_dasm_movem(op, opcode_str, arg_str); - } - /* MOVE(M) : 0000 001W RR11 mmRR : A-152 */ - else if ((op & 0xfe30) == 0x0230) - { - size = dsp56k_dasm_movem_1(op, opcode_str, arg_str); - } - /* MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 */ - else if (((op & 0xff00) == 0x0500) && ((op2 & 0xfe20) == 0x0200)) - { - size = dsp56k_dasm_movem_2(op, op2, opcode_str, arg_str); - } - /* MOVE(P) : 0001 100W HH1p pppp : A-156 */ - else if ((op & 0xfe20) == 0x1820) - { - size = dsp56k_dasm_movep(op, opcode_str, arg_str); - } - /* MOVE(P) : 0000 110W RRmp pppp : A-156 */ - else if ((op & 0xfe00) == 0x0c00) - { - size = dsp56k_dasm_movep_1(op, opcode_str, arg_str); - } - /* MOVE(S) : 0001 100W HH0a aaaa : A-158 */ - else if ((op & 0xfe20) == 0x1800) - { - size = dsp56k_dasm_moves(op, opcode_str, arg_str); - } - /* MPY(su,uu) : 0001 0101 1100 FsQQ : A-164 */ - else if ((op & 0xfff0) == 0x15c0) - { - size = dsp56k_dasm_mpysuuu(op, opcode_str, arg_str); - } - /* NEGC : 0001 0101 0110 F000 : A-168 */ - else if ((op & 0xfff7) == 0x1560) - { - size = dsp56k_dasm_negc(op, opcode_str, arg_str); - } - /* NOP : 0000 0000 0000 0000 : A-170 */ - else if ((op & 0xffff) == 0x0000) - { - size = dsp56k_dasm_nop(op, opcode_str, arg_str); - } - /* NORM : 0001 0101 0010 F0RR : A-172 */ - else if ((op & 0xfff4) == 0x1520) - { - size = dsp56k_dasm_norm(op, opcode_str, arg_str); - } - /* ORI : 0001 1EE1 iiii iiii : A-178 */ - else if ((op & 0xf900) == 0x1900) - { - size = dsp56k_dasm_ori(op, opcode_str, arg_str); - } - /* REP : 0000 0000 111- --RR : A-180 */ - else if ((op & 0xffe0) == 0x00e0) - { - size = dsp56k_dasm_rep(op, opcode_str, arg_str); - } - /* REP : 0000 1111 iiii iiii : A-180 */ - else if ((op & 0xff00) == 0x0f00) - { - size = dsp56k_dasm_rep_1(op, opcode_str, arg_str); - } - /* REP : 0000 0100 001D DDDD : A-180 */ - else if ((op & 0xffe0) == 0x0420) - { - size = dsp56k_dasm_rep_2(op, opcode_str, arg_str); - } - /* REPcc : 0000 0001 0101 cccc : A-184 */ - else if ((op & 0xfff0) == 0x0150) - { - size = dsp56k_dasm_repcc(op, opcode_str, arg_str); - } - /* RESET : 0000 0000 0000 1000 : A-186 */ - else if ((op & 0xffff) == 0x0008) - { - size = dsp56k_dasm_reset(op, opcode_str, arg_str); - } - /* RTI : 0000 0000 0000 0111 : A-194 */ - else if ((op & 0xffff) == 0x0007) - { - size = dsp56k_dasm_rti(op, opcode_str, arg_str); - } - /* RTS : 0000 0000 0000 0110 : A-196 */ - else if ((op & 0xffff) == 0x0006) - { - size = dsp56k_dasm_rts(op, opcode_str, arg_str); - } - /* STOP : 0000 0000 0000 1010 : A-200 */ - else if ((op & 0xffff) == 0x000a) - { - size = dsp56k_dasm_stop(op, opcode_str, arg_str); - } - /* SWAP : 0001 0101 0111 F001 : A-206 */ - else if ((op & 0xfff7) == 0x1571) - { - size = dsp56k_dasm_swap(op, opcode_str, arg_str); - } - /* SWI : 0000 0000 0000 0101 : A-208 */ - else if ((op & 0xffff) == 0x0005) - { - size = dsp56k_dasm_swi(op, opcode_str, arg_str); - } - /* Tcc : 0001 00cc ccTT Fh0h : A-210 */ - else if ((op & 0xfc02) == 0x1000) - { - size = dsp56k_dasm_tcc(op, opcode_str, arg_str); - } - /* TFR(2) : 0001 0101 0000 F00J : A-214 */ - else if ((op & 0xfff6) == 0x1500) - { - size = dsp56k_dasm_tfr2(op, opcode_str, arg_str); - } - /* TFR(3) : 0010 01mW RRDD FHHH : A-216 */ - else if ((op & 0xfc00) == 0x2400) - { - size = dsp56k_dasm_tfr3(op, opcode_str, arg_str); - } - /* TST(2) : 0001 0101 0001 -1DD : A-220 */ - else if ((op & 0xfff4) == 0x1514) - { - size = dsp56k_dasm_tst2(op, opcode_str, arg_str); - } - /* WAIT : 0000 0000 0000 1011 : A-222 */ - else if ((op & 0xffff) == 0x000b) - { - size = dsp56k_dasm_wait(op, opcode_str, arg_str); - } - /* ZERO : 0001 0101 0101 F000 : A-224 */ - else if ((op & 0xfff7) == 0x1550) - { - size = dsp56k_dasm_zero(op, opcode_str, arg_str); - } - - - /* Assemble opcode string buffer */ - if (size >= 1) - { - pad_string(11, opcode_str); - sprintf(buffer, "%s%s", opcode_str, arg_str); - } - /* Not recognized? Nudge debugger onto the next word */ - else if (size == 0) - { - sprintf(buffer, "unknown"); - size = 1; - } + // Decode and disassemble. + DSP56K::Opcode op(w0, w1); + sprintf(buffer, "%s", op.disassemble().c_str()); + const unsigned size = op.size(); return (size | DASMFLAG_SUPPORTED); } - - -/*******************************/ -/* 32 Parallel move operations */ -/*******************************/ - -/* ADD : 011m mKKK 0rru Fuuu : A-22 */ -/* SUB : 011m mKKK 0rru Fuuu : A-202 */ -static size_t dsp56k_dasm_addsub_2(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - /* TODO: How strange. Same as SUB? Investigate */ - char D[32]; - char S1[32]; - char arg[32]; - decode_uuuuF_table(BITS(op_byte,0x17), BITS(op_byte,0x08), arg, S1, D); - sprintf(opcode_str, "%s", arg); - sprintf(arg_str, "%s,%s", S1, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* MAC : 011m mKKK 1xx0 F1QQ : A-122 */ -static size_t dsp56k_dasm_mac_1(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - char S1[32]; - char S2[32]; - decode_QQF_table(BITS(op_byte,0x03), BITS(op_byte,0x08), S1, S2, D); - sprintf(opcode_str, "mac"); - sprintf(arg_str, "%s,%s,%s", S1, S2, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* MACR: 011m mKKK 1--1 F1QQ : A-124 */ -static size_t dsp56k_dasm_macr_1(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - char S1[32]; - char S2[32]; - decode_QQF_table(BITS(op_byte,0x03), BITS(op_byte,0x08), S1, S2, D); - sprintf(opcode_str, "macr"); - sprintf(arg_str, "%s,%s,%s", S1, S2, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* TFR : 011m mKKK 0rr1 F0DD : A-212 */ -static size_t dsp56k_dasm_tfr_2(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - /* Note: This opcode collides with move_1 when F0DD is 0000. Needs verifying on a real CPU. */ - char D[32]; - char S1[32]; - decode_DDF_table(BITS(op_byte,0x03), BITS(op_byte,0x08), S1, D); - sprintf(opcode_str, "tfr"); - if (BITS(op_byte,0x0f) == 0x00) - strcat(opcode_str, "*"); /* This asterisk is to denote that this opcode may have an error with its disassembly */ - sprintf(arg_str, "%s,%s", S1, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* MOVE : 011m mKKK 0rr1 0000 : A-128 */ -static size_t dsp56k_dasm_move_1(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - /* Note: This opcode collides with tfr_2 & will never be disassembled. Needs verifying on a real CPU. */ - char D[32]; - char S1[32]; - decode_DDF_table(BITS(op_byte,0x03), BITS(op_byte,0x08), S1, D); - sprintf(opcode_str, "tfr"); - sprintf(arg_str, "%s,%s", S1, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* MPY : 011m mKKK 1xx0 F0QQ : A-160 */ -static size_t dsp56k_dasm_mpy_1(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - char S1[32]; - char S2[32]; - decode_QQF_table(BITS(op_byte,0x03), BITS(op_byte,0x08), S1, S2, D); - sprintf(opcode_str, "mpy"); - sprintf(arg_str, "%s,%s,%s", S1, S2, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* MPYR : 011m mKKK 1--1 F0QQ : A-162 */ -static size_t dsp56k_dasm_mpyr_1(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - char S1[32]; - char S2[32]; - decode_QQF_table(BITS(op_byte,0x03), BITS(op_byte,0x08), S1, S2, D); - sprintf(opcode_str, "mpyr"); - sprintf(arg_str, "%s,%s,%s", S1, S2, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* MPY : 0001 0110 RRDD FQQQ : A-160 */ -static size_t dsp56k_dasm_mpy_2(const UINT16 op_byte, char* opcode_str, char* arg_str) -{ - char D[32]; - char S1[32]; - char S2[32]; - decode_QQQF_table(BITS(op_byte,0x0007), BITS(op_byte,0x0008), S1, S2, D); - sprintf(opcode_str, "mpy"); - sprintf(arg_str, "%s,%s,%s", S1, S2, D); - return 1; -} - -/* MAC : 0001 0111 RRDD FQQQ : A-122 */ -static size_t dsp56k_dasm_mac_2(const UINT16 op_byte, char* opcode_str, char* arg_str) -{ - char D[32]; - char S1[32]; - char S2[32]; - decode_QQQF_table(BITS(op_byte,0x0007), BITS(op_byte,0x0008), S1, S2, D); - sprintf(opcode_str, "mac"); - sprintf(arg_str, "%s,%s,%s", S1, S2, D); - return 1; -} - -/* CLR : .... .... 0000 F001 : A-60 */ -static size_t dsp56k_dasm_clr(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "clr"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* ADD : .... .... 0000 FJJJ : A-22 */ -static size_t dsp56k_dasm_add(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - char S1[32]; - decode_JJJF_table(BITS(op_byte,0x07), BITS(op_byte,0x08), S1, D); - sprintf(opcode_str, "add"); - sprintf(arg_str, "%s,%s", S1, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* MOVE : .... .... 0001 0001 : A-128 */ -static size_t dsp56k_dasm_move(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - /* Equivalent to a NOP (+ parallel move) */ - sprintf(opcode_str, "move"); - sprintf(arg_str, " "); - sprintf(d_register, " "); - return 1; -} - -/* TFR : .... .... 0001 FJJJ : A-212 */ -static size_t dsp56k_dasm_tfr(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - char S1[32]; - decode_JJJF_table(BITS(op_byte,0x07), BITS(op_byte,0x08), S1, D); - sprintf(opcode_str, "tfr"); - sprintf(arg_str, "%s,%s", S1, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* RND : .... .... 0010 F000 : A-188 */ -static size_t dsp56k_dasm_rnd(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "rnd"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* TST : .... .... 0010 F001 : A-218 */ -static size_t dsp56k_dasm_tst(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "tst"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* INC : .... .... 0010 F010 : A-104 */ -static size_t dsp56k_dasm_inc(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "inc"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* INC24 : .... .... 0010 F011 : A-106 */ -static size_t dsp56k_dasm_inc24(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "inc24"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* OR : .... .... 0010 F1JJ : A-176 */ -static size_t dsp56k_dasm_or(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - char S1[32]; - decode_JJF_table(BITS(op_byte,0x03),BITS(op_byte,0x08), S1, D); - sprintf(opcode_str, "or"); - sprintf(arg_str, "%s,%s", S1, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* ASR : .... .... 0011 F000 : A-32 */ -static size_t dsp56k_dasm_asr(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "asr"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* ASL : .... .... 0011 F001 : A-28 */ -static size_t dsp56k_dasm_asl(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "asl"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* LSR : .... .... 0011 F010 : A-120 */ -static size_t dsp56k_dasm_lsr(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "lsr"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* LSL : .... .... 0011 F011 : A-118 */ -static size_t dsp56k_dasm_lsl(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "lsl"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* EOR : .... .... 0011 F1JJ : A-94 */ -static size_t dsp56k_dasm_eor(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - char S1[32]; - decode_JJF_table(BITS(op_byte,0x03),BITS(op_byte,0x08), S1, D); - sprintf(opcode_str, "eor"); - sprintf(arg_str, "%s,%s", S1, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* SUBL : .... .... 0100 F001 : A-204 */ -static size_t dsp56k_dasm_subl(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - sprintf(opcode_str, "subl"); - - /* There is only one option for the F table. This is a very strange opcode. */ - if (!BITS(op_byte,0x08)) - { - sprintf(arg_str, "B,A"); - sprintf(d_register, "A"); - } - else - { - sprintf(arg_str, "!,!"); - sprintf(d_register, "!"); - } - - return 1; -} - -/* SUB : .... .... 0100 FJJJ : A-202 */ -static size_t dsp56k_dasm_sub(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - char S1[32]; - decode_JJJF_table(BITS(op_byte,0x07), BITS(op_byte,0x08), S1, D); - sprintf(opcode_str, "sub"); - sprintf(arg_str, "%s,%s", S1, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* CLR24 : .... .... 0101 F001 : A-62 */ -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); - sprintf(opcode_str, "clr24"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* SBC : .... .... 0101 F01J : A-198 */ -static size_t dsp56k_dasm_sbc(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - char S1[32]; - decode_JF_table(BITS(op_byte,0x01), BITS(op_byte,0x08), S1, D); - sprintf(opcode_str, "sbc"); - sprintf(arg_str, "%s,%s", S1, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* CMP : .... .... 0101 FJJJ : A-64 */ -static size_t dsp56k_dasm_cmp(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - char S1[32]; - /* Note: This is a JJJF limited in the docs, but other opcodes sneak - in before cmp, so the same decode function can be used. */ - decode_JJJF_table(BITS(op_byte,0x07), BITS(op_byte,0x08), S1, D); - sprintf(opcode_str, "cmp"); - sprintf(arg_str, "%s,%s", S1, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* NEG : .... .... 0110 F000 : A-166 */ -static size_t dsp56k_dasm_neg(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "neg"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* NOT : .... .... 0110 F001 : A-174 */ -static size_t dsp56k_dasm_not(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "not"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* DEC : .... .... 0110 F010 : A-72 */ -static size_t dsp56k_dasm_dec(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "dec"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* DEC24 : .... .... 0110 F011 : A-74 */ -static size_t dsp56k_dasm_dec24(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "dec24"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* AND : .... .... 0110 F1JJ : A-24 */ -static size_t dsp56k_dasm_and(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - char S1[32]; - decode_JJF_table(BITS(op_byte,0x03),BITS(op_byte,0x08), S1, D); - sprintf(opcode_str, "and"); - sprintf(arg_str, "%s,%s", S1, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* ABS : .... .... 0111 F001 : A-18 */ -static size_t dsp56k_dasm_abs(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "abs"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* ROR : .... .... 0111 F010 : A-192 */ -static size_t dsp56k_dasm_ror(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "ror"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* ROL : .... .... 0111 F011 : A-190 */ -static size_t dsp56k_dasm_rol(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - decode_F_table(BITS(op_byte,0x08), D); - sprintf(opcode_str, "rol"); - sprintf(arg_str, "%s", D); - sprintf(d_register, "%s", D); - return 1; -} - -/* CMPM : .... .... 0111 FJJJ : A-66 */ -static size_t dsp56k_dasm_cmpm(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - char S1[32]; - /* Note: This is a JJJF limited in the docs, but other opcodes sneak - in before cmp, so the same decode function can be used. */ - decode_JJJF_table(BITS(op_byte,0x07), BITS(op_byte,0x08), S1, D); - sprintf(opcode_str, "cmpm"); - sprintf(arg_str, "%s,%s", S1, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* MPY : .... .... 1k00 FQQQ : A-160 -- CONFIRMED TYPO IN DOCS (HHHH vs HHHW) */ -static size_t dsp56k_dasm_mpy(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - /* There are inconsistencies with the S1 & S2 operand ordering in the docs, - but since it's a multiply it doesn't matter */ - char D[32]; - char S1[32]; - char S2[32]; - char sign[32]; - decode_QQQF_table(BITS(op_byte,0x07), BITS(op_byte,0x08), S1, S2, D); - decode_kSign_table(BITS(op_byte,0x40), sign); - sprintf(opcode_str, "mpy"); - if (sign[0] == '-') - sprintf(arg_str, "-%s,%s,%s", S1, S2, D); - else - sprintf(arg_str, "%s,%s,%s", S1, S2, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* MPYR : .... .... 1k01 FQQQ : A-162 */ -static size_t dsp56k_dasm_mpyr(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - /* There are inconsistencies with the S1 & S2 operand ordering in the docs, - but since it's a multiply it doesn't matter */ - char D[32]; - char S1[32]; - char S2[32]; - char sign[32]; - decode_QQQF_table(BITS(op_byte,0x07), BITS(op_byte,0x08), S1, S2, D); - decode_kSign_table(BITS(op_byte,0x40), sign); - sprintf(opcode_str, "mpyr"); - if (sign[0] == '-') - sprintf(arg_str, "-%s,%s,%s", S1, S2, D); - else - sprintf(arg_str, "%s,%s,%s", S1, S2, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* MAC : .... .... 1k10 FQQQ : A-122 */ -static size_t dsp56k_dasm_mac(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - char D[32]; - char S1[32]; - char S2[32]; - char sign[32]; - decode_QQQF_table(BITS(op_byte,0x07), BITS(op_byte,0x08), S1, S2, D); - decode_kSign_table(BITS(op_byte,0x40), sign); - sprintf(opcode_str, "mac"); - if (sign[0] == '-') - sprintf(arg_str, "-%s,%s,%s", S1, S2, D); - else - sprintf(arg_str, "%s,%s,%s", S1, S2, D); - sprintf(d_register, "%s", D); - return 1; -} - -/* MACR : .... .... 1k11 FQQQ : A-124 -- DRAMA - rr vs xx (805) */ -static size_t dsp56k_dasm_macr(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) -{ - /* There are inconsistencies with the S1 & S2 operand ordering in the docs, - but since it's a multiply it doesn't matter */ - char D[32]; - char S1[32]; - char S2[32]; - char sign[32]; - decode_QQQF_table(BITS(op_byte,0x07), BITS(op_byte,0x08), S1, S2, D); - decode_kSign_table(BITS(op_byte,0x40), sign); - sprintf(opcode_str, "macr"); - if (sign[0] == '-') - sprintf(arg_str, "-%s,%s,%s", S1, S2, D); - else - sprintf(arg_str, "%s,%s,%s", S1, S2, D); - sprintf(d_register, "%s", D); - return 1; -} - - -/******************************/ -/* Remaining non-parallel ops */ -/******************************/ - -/* ADC : 0001 0101 0000 F01J : A-20 */ -static size_t dsp56k_dasm_adc(const UINT16 op, char* opcode_str, char* arg_str) -{ - char D[32]; - char S1[32]; - decode_JF_table(BITS(op,0x0001), BITS(op,0x0008), S1, D); - sprintf(opcode_str, "adc"); - sprintf(arg_str, "%s,%s", S1, D); - return 1; -} - -/* ANDI : 0001 1EE0 iiii iiii : A-26 */ -static size_t dsp56k_dasm_andi(const UINT16 op, char* opcode_str, char* arg_str) -{ - char D[32]; - decode_EE_table(BITS(op,0x0600), D); - sprintf(opcode_str, "and(i)"); - sprintf(arg_str, "#$%02x,%s", BITS(op,0x00ff), D); - return 1; -} - -/* ASL4 : 0001 0101 0011 F001 : A-30 */ -static size_t dsp56k_dasm_asl4(const UINT16 op, char* opcode_str, char* arg_str) -{ - char D[32]; - decode_F_table(BITS(op,0x0008), D); - sprintf(opcode_str, "asl4"); - sprintf(arg_str, "%s", D); - return 1; -} - -/* ASR4 : 0001 0101 0011 F000 : A-34 */ -static size_t dsp56k_dasm_asr4(const UINT16 op, char* opcode_str, char* arg_str) -{ - char D[32]; - decode_F_table(BITS(op,0x0008), D); - sprintf(opcode_str, "asr4"); - sprintf(arg_str, "%s", D); - return 1; -} - -/* ASR16 : 0001 0101 0111 F000 : A-36 */ -static size_t dsp56k_dasm_asr16(const UINT16 op, char* opcode_str, char* arg_str) -{ - char D[32]; - decode_F_table(BITS(op,0x0008), D); - sprintf(opcode_str, "asr16"); - sprintf(arg_str, "%s", D); - return 1; -} - -/* BFCHG : 0001 0100 11Pp pppp BBB1 0010 iiii iiii : A-38 */ -/* BFCHG : 0001 0100 101- --RR BBB1 0010 iiii iiii : A-38 */ -/* BFCHG : 0001 0100 100D DDDD BBB1 0010 iiii iiii : A-38 */ -/* BFCLR : 0001 0100 11Pp pppp BBB0 0100 iiii iiii : A-40 */ -/* BFCLR : 0001 0100 101- --RR BBB0 0100 iiii iiii : A-40 */ -/* BFCLR : 0001 0100 100D DDDD BBB0 0100 iiii iiii : A-40 */ -/* BFSET : 0001 0100 11Pp pppp BBB1 1000 iiii iiii : A-42 */ -/* BFSET : 0001 0100 101- --RR BBB1 1000 iiii iiii : A-42 */ -/* BFSET : 0001 0100 100D DDDD BBB1 1000 iiii iiii : A-42 */ -/* BFTSTH : 0001 0100 01Pp pppp BBB1 0000 iiii iiii : A-44 */ -/* BFTSTH : 0001 0100 001- --RR BBB1 0000 iiii iiii : A-44 */ -/* BFTSTH : 0001 0100 000D DDDD BBB1 0000 iiii iiii : A-44 */ -/* BFTSTL : 0001 0100 01Pp pppp BBB0 0000 iiii iiii : A-46 */ -/* BFTSTL : 0001 0100 001- --RR BBB0 0000 iiii iiii : A-46 */ -/* BFTSTL : 0001 0100 000D DDDD BBB0 0000 iiii iiii : A-46 */ -static size_t dsp56k_dasm_bfop(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) -{ - char D[32]; - int upperMiddleLower = -1; - UINT16 iVal = 0x0000; - UINT16 rVal = 0x0000; - - /* Decode the common parts */ - upperMiddleLower = decode_BBB_table(BITS(op2,0xe000)); - iVal = BITS(op2,0x00ff); - - switch(upperMiddleLower) - { - case BBB_UPPER: iVal <<= 8; break; - case BBB_MIDDLE: iVal <<= 4; break; - case BBB_LOWER: iVal <<= 0; break; - } - - switch(BITS(op,0x00e0)) - { - case 0x6: case 0x7: case 0x2: case 0x3: - assemble_D_from_P_table(BITS(op,0x0020), BITS(op,0x001f), D); - break; - - case 0x5: case 0x1: - rVal = decode_RR_table(BITS(op,0x0003)); - sprintf(D, "X:(R%d)", rVal); - break; - - case 0x4: case 0x0: - decode_DDDDD_table(BITS(op,0x001f), D); - break; - } - - if (upperMiddleLower != BBB_INVALID) - { - sprintf(arg_str, "#$%04x,%s", iVal, D); - } - else - { - sprintf(arg_str, "[[invalid]],%s", D); - } - - switch(BITS(op2,0x1f00)) - { - case 0x12: sprintf(opcode_str, "bfchg"); break; - case 0x04: sprintf(opcode_str, "bfclr"); break; - case 0x18: sprintf(opcode_str, "bfset"); break; - case 0x10: sprintf(opcode_str, "bftsth"); break; - case 0x00: sprintf(opcode_str, "bftstl"); break; - } - - return 2; -} - -/* Bcc : 0000 0111 --11 cccc xxxx xxxx xxxx xxxx : A-48 */ -static size_t dsp56k_dasm_bcc(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc) -{ - char M[32]; - decode_cccc_table(BITS(op,0x000f), M); - sprintf(opcode_str, "b.%s", M); - sprintf(arg_str, "$%04x (%d)", pc + 2 + (INT16)op2, (INT16)op2); - return 2; -} - -/* Bcc : 0010 11cc ccee eeee : A-48 */ -static size_t dsp56k_dasm_bcc_1(const UINT16 op, char* opcode_str, char* arg_str, const offs_t pc) -{ - char M[32]; - INT8 relativeInt; - decode_cccc_table(BITS(op,0x3c0), M); - relativeInt = get_6_bit_signed_value(BITS(op,0x003f)); - sprintf(opcode_str, "b.%s", M); - sprintf(arg_str, "$%04x (%d)", pc + 1 + relativeInt, relativeInt); - return 1; -} - -/* Bcc : 0000 0111 RR10 cccc : A-48 */ -static size_t dsp56k_dasm_bcc_2(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - char M[32]; - decode_cccc_table(BITS(op,0x000f), M); - Rnum = decode_RR_table(BITS(op,0x00c0)); - sprintf(opcode_str, "b.%s", M); - sprintf(arg_str, "R%d", Rnum); - return 1; -} - -/* BRA : 0000 0001 0011 11-- xxxx xxxx xxxx xxxx : A-50 */ -static size_t dsp56k_dasm_bra(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc) -{ - sprintf(opcode_str, "bra"); - sprintf(arg_str, "$%04x (%d)", pc + 2 + op2, (INT16)op2); - return 2; -} - -/* BRA : 0000 1011 aaaa aaaa : A-50 */ -static size_t dsp56k_dasm_bra_1(const UINT16 op, char* opcode_str, char* arg_str, const offs_t pc) -{ - INT8 iVal = (INT8)BITS(op,0x00ff); - sprintf(opcode_str, "bra"); - sprintf(arg_str, "$%04x (%d)", pc + 1 + iVal, iVal); - return 1; -} - -/* BRA : 0000 0001 0010 11RR : A-50 */ -static size_t dsp56k_dasm_bra_2(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - Rnum = decode_RR_table(BITS(op,0x0003)); - sprintf(opcode_str, "bra"); - sprintf(arg_str, "R%d", Rnum); - return 1; -} - -/* BRKc : 0000 0001 0001 cccc : A-52 */ -static size_t dsp56k_dasm_brkcc(const UINT16 op, char* opcode_str, char* arg_str) -{ - char M[32]; - decode_cccc_table(BITS(op,0x000f), M); - sprintf(opcode_str, "brk.%s", M); - sprintf(arg_str, " "); - return 1; -} - -/* BScc : 0000 0111 --01 cccc xxxx xxxx xxxx xxxx : A-54 */ -static size_t dsp56k_dasm_bscc(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc) -{ - char M[32]; - decode_cccc_table(BITS(op,0x000f), M); - sprintf(opcode_str, "bs.%s", M); - sprintf(arg_str, "$%04x (%d)", pc + 2 + (INT16)op2, (INT16)op2); - return (2 | DASMFLAG_STEP_OVER); -} - -/* BScc: 0000 0111 RR00 cccc : A-54 */ -static size_t dsp56k_dasm_bscc_1(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - char M[32]; - decode_cccc_table(BITS(op,0x000f), M); - Rnum = decode_RR_table(BITS(op,0x00c0)); - sprintf(opcode_str, "bs.%s", M); - sprintf(arg_str, "R%d", Rnum); - return (1 | DASMFLAG_STEP_OVER); -} - -/* BSR : 0000 0001 0011 10-- xxxx xxxx xxxx xxxx : A-56 */ -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, "$%04x (%d)", pc + 2 + (INT16)op2, (INT16)op2); - return (2 | DASMFLAG_STEP_OVER); -} - -/* BSR : 0000 0001 0010 10RR : A-56 */ -static size_t dsp56k_dasm_bsr_1(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - Rnum = decode_RR_table(BITS(op,0x0003)); - sprintf(opcode_str, "bsr"); - sprintf(arg_str, "R%d", Rnum); - return (1 | DASMFLAG_STEP_OVER); -} - -/* CHKAAU : 0000 0000 0000 0100 : A-58 */ -static size_t dsp56k_dasm_chkaau(const UINT16 op, char* opcode_str, char* arg_str) -{ - sprintf(opcode_str, "chkaau"); - sprintf(arg_str, " "); - return 1; -} - -/* DEBUG : 0000 0000 0000 0001 : A-68 */ -static size_t dsp56k_dasm_debug(const UINT16 op, char* opcode_str, char* arg_str) -{ - sprintf(opcode_str, "debug"); - sprintf(arg_str, " "); - return 1; -} - -/* DEBUGcc : 0000 0000 0101 cccc : A-70 */ -static size_t dsp56k_dasm_debugcc(const UINT16 op, char* opcode_str, char* arg_str) -{ - char M[32]; - decode_cccc_table(BITS(op,0x000f), M); - sprintf(opcode_str, "debug.%s", M); - sprintf(arg_str, " "); - return 1; -} - -/* DIV : 0001 0101 0--0 F1DD : A-76 */ -static size_t dsp56k_dasm_div(const UINT16 op, char* opcode_str, char* arg_str) -{ - /* The docs on page A-76 claim there is potential for a parallel move here, - but various other sources (including elsewhere in the family manual) disagree */ - char D[32]; - char S1[32]; - decode_DDF_table(BITS(op,0x0003), BITS(op,0x0008), S1, D); - sprintf(opcode_str, "div"); - sprintf(arg_str, "%s,%s", S1, D); - return 1; -} - -/* DMAC : 0001 0101 10s1 FsQQ : A-80 */ -static size_t dsp56k_dasm_dmac(const UINT16 op, char* opcode_str, char* arg_str) -{ - char A[32]; - char D[32]; - char S1[32]; - char S2[32]; - decode_ss_table(BITS(op,0x0024), A); - decode_QQF_special_table(BITS(op,0x0003), BITS(op,0x0008), S1, S2, D); /* Special QQF */ - sprintf(opcode_str, "dmac(%s)", A); - sprintf(arg_str, "%s,%s,%s", S1, S2, D); - return 1; -} - -/* DO : 0000 0000 110- --RR xxxx xxxx xxxx xxxx : A-82 */ -static size_t dsp56k_dasm_do(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc) -{ - int Rnum; - Rnum = decode_RR_table(BITS(op,0x0003)); - sprintf(opcode_str, "do"); - sprintf(arg_str, "X:(R%d),$%02x", Rnum, pc + 2 + op2); - return 2; -} - -/* DO : 0000 1110 iiii iiii xxxx xxxx xxxx xxxx : A-82 */ -static size_t dsp56k_dasm_do_1(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc) -{ - sprintf(opcode_str, "do"); - sprintf(arg_str, "#$%02x,$%04x", BITS(op,0x00ff), pc + 2 + op2); - return 2; -} - -/* DO : 0000 0100 000D DDDD xxxx xxxx xxxx xxxx : A-82 */ -static size_t dsp56k_dasm_do_2(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc) -{ - char S1[32]; - decode_DDDDD_table(BITS(op,0x001f), S1); - sprintf(opcode_str, "do"); - sprintf(arg_str, "%s,$%04x", S1, pc + 2 + op2); - return 2; -} - -/* DO FOREVER : 0000 0000 0000 0010 xxxx xxxx xxxx xxxx : A-88 */ -static size_t dsp56k_dasm_doforever(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc) -{ - sprintf(opcode_str, "do forever"); - sprintf(arg_str, "$%04x", pc + 2 + op2); - return 2; -} - -/* ENDDO : 0000 0000 0000 1001 : A-92 */ -static size_t dsp56k_dasm_enddo(const UINT16 op, char* opcode_str, char* arg_str) -{ - sprintf(opcode_str, "enddo"); - sprintf(arg_str, " "); - return 1; -} - -/* EXT : 0001 0101 0101 F010 : A-96 */ -static size_t dsp56k_dasm_ext(const UINT16 op, char* opcode_str, char* arg_str) -{ - char D[32]; - decode_F_table(BITS(op,0x0008), D); - sprintf(opcode_str, "ext"); - sprintf(arg_str, "%s", D); - return 1; -} - -/* ILLEGAL : 0000 0000 0000 1111 : A-98 */ -static size_t dsp56k_dasm_illegal(const UINT16 op, char* opcode_str, char* arg_str) -{ - sprintf(opcode_str, "illegal"); - sprintf(arg_str, " "); - return 1; -} - -/* IMAC : 0001 0101 1010 FQQQ : A-100 */ -static size_t dsp56k_dasm_imac(const UINT16 op, char* opcode_str, char* arg_str) -{ - char D[32]; - char S1[32]; - char S2[32]; - decode_QQQF_table(BITS(op,0x0007), BITS(op,0x0008), S1, S2, D); - sprintf(opcode_str, "imac"); - sprintf(arg_str, "%s,%s,%s", S1, S2, D); - return 1; -} - -/* IMPY : 0001 0101 1000 FQQQ : A-102 */ -static size_t dsp56k_dasm_impy(const UINT16 op, char* opcode_str, char* arg_str) -{ - char D[32]; - char S1[32]; - char S2[32]; - decode_QQQF_table(BITS(op,0x0007), BITS(op,0x0008), S1, S2, D); - sprintf(opcode_str, "impy"); - sprintf(arg_str, "%s,%s,%s", S1, S2, D); - return 1; -} - -/* Jcc : 0000 0110 --11 cccc xxxx xxxx xxxx xxxx : A-108 */ -static size_t dsp56k_dasm_jcc(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) -{ - char M[32]; - decode_cccc_table(BITS(op,0x000f), M); - sprintf(opcode_str, "j.%s", M); - sprintf(arg_str, "$%04x", op2); - return 2; -} - -/* Jcc : 0000 0110 RR10 cccc : A-108 */ -static size_t dsp56k_dasm_jcc_1(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - char M[32]; - decode_cccc_table(BITS(op,0x000f), M); - Rnum = decode_RR_table(BITS(op,0x00c0)); - sprintf(opcode_str, "j.%s", M); - sprintf(arg_str, "R%d", Rnum); - return 1; -} - -/* JMP : 0000 0001 0011 01-- xxxx xxxx xxxx xxxx : A-110 */ -static size_t dsp56k_dasm_jmp(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) -{ - sprintf(opcode_str, "jmp"); - sprintf(arg_str, "$%04x", op2); - return 2; -} - -/* JMP : 0000 0001 0010 01RR : A-110 */ -static size_t dsp56k_dasm_jmp_1(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - Rnum = decode_RR_table(BITS(op,0x0003)); - sprintf(opcode_str, "jmp"); - sprintf(arg_str, "R%d", Rnum); - return 1; -} - -/* JScc : 0000 0110 --01 cccc xxxx xxxx xxxx xxxx : A-112 */ -static size_t dsp56k_dasm_jscc(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) -{ - char M[32]; - decode_cccc_table(BITS(op,0x000f), M); - sprintf(opcode_str, "js.%s", M); - sprintf(arg_str, "$%04x", op2); - return (2 | DASMFLAG_STEP_OVER); -} - -/* JScc : 0000 0110 RR00 cccc : A-112 */ -static size_t dsp56k_dasm_jscc_1(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - char M[32]; - decode_cccc_table(BITS(op,0x000f), M); - Rnum = decode_RR_table(BITS(op,0x00c0)); - sprintf(opcode_str, "js.%s", M); - sprintf(arg_str, "R%d", Rnum); - return (1 | DASMFLAG_STEP_OVER); -} - -/* JSR : 0000 0001 0011 00-- xxxx xxxx xxxx xxxx : A-114 */ -static size_t dsp56k_dasm_jsr(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) -{ - sprintf(opcode_str, "jsr"); - sprintf(arg_str, "$%04x", op2); - return (2 | DASMFLAG_STEP_OVER); -} - -/* JSR : 0000 1010 AAAA AAAA : A-114 */ -static size_t dsp56k_dasm_jsr_1(const UINT16 op, char* opcode_str, char* arg_str) -{ - sprintf(opcode_str, "jsr"); - sprintf(arg_str, "#$%02x", BITS(op,0x00ff)); - return (1 | DASMFLAG_STEP_OVER); -} - -/* JSR : 0000 0001 0010 00RR : A-114 */ -static size_t dsp56k_dasm_jsr_2(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - Rnum = decode_RR_table(BITS(op,0x0003)); - sprintf(opcode_str, "jsr"); - sprintf(arg_str, "R%d", Rnum); - return (1 | DASMFLAG_STEP_OVER); -} - -/* LEA : 0000 0001 11TT MMRR : A-116 */ -static size_t dsp56k_dasm_lea(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - int Tnum; - char ea[32]; - Tnum = decode_TT_table(BITS(op,0x0030)); - Rnum = decode_RR_table(BITS(op,0x0003)); - assemble_ea_from_MM_table(BITS(op,0x000c), Rnum, ea); - sprintf(opcode_str, "lea"); - sprintf(arg_str, "%s,R%d", ea, Tnum); - return 1; -} - -/* LEA : 0000 0001 10NN MMRR : A-116 */ -static size_t dsp56k_dasm_lea_1(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Nnum; - int Rnum; - char ea[32]; - Nnum = decode_NN_table(BITS(op,0x0030)); - Rnum = decode_RR_table(BITS(op,0x0003)); - assemble_ea_from_MM_table(BITS(op,0x000c), Rnum, ea); - sprintf(opcode_str, "lea"); - sprintf(arg_str, "%s,N%d", ea, Nnum); - return 1; -} - -/* MAC(su,uu) : 0001 0101 1110 FsQQ : A-126 */ -static size_t dsp56k_dasm_macsuuu(const UINT16 op, char* opcode_str, char* arg_str) -{ - char A[32]; - char D[32]; - char S1[32]; - char S2[32]; - decode_s_table(BITS(op,0x0004), A); - decode_QQF_special_table(BITS(op,0x0003), BITS(op,0x0008), S1, S2, D); /* Special QQF */ - sprintf(opcode_str, "mac(%s)", A); - sprintf(arg_str, "%s,%s,%s", S1, S2, D); - return 1; -} - -/* MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 */ -static size_t dsp56k_dasm_move_2(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) -{ - INT8 B; - char SD[32]; - char args[32]; - B = BITS(op,0x00ff); - decode_HHH_table(BITS(op2,0x0e00), SD); - assemble_reg_from_W_table(BITS(op2,0x0100), args, 'X', SD, B); - sprintf(opcode_str, "move"); - sprintf(arg_str, "%s", args); - return 2; -} - -/* MOVE(C) : 0011 1WDD DDD0 MMRR : A-144 */ -static size_t dsp56k_dasm_movec(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - char ea[32]; - char SD[32]; - char args[32]; - decode_DDDDD_table(BITS(op,0x03e0), SD); - Rnum = decode_RR_table(BITS(op,0x0003)); - assemble_ea_from_MM_table(BITS(op,0x000c), Rnum, ea); - assemble_arguments_from_W_table(BITS(op,0x0400), args, 'X', SD, ea); - sprintf(opcode_str, "move(c)"); - sprintf(arg_str, "%s", args); - return 1; -} - -/* MOVE(C) : 0011 1WDD DDD1 q0RR : A-144 */ -static size_t dsp56k_dasm_movec_1(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - char ea[32]; - char SD[32]; - char args[32]; - decode_DDDDD_table(BITS(op,0x03e0), SD); - Rnum = decode_RR_table(BITS(op,0x0003)); - assemble_ea_from_q_table(BITS(op,0x0008), Rnum, ea); - assemble_arguments_from_W_table(BITS(op,0x0400), args, 'X', SD, ea); - sprintf(opcode_str, "move(c)"); - sprintf(arg_str, "%s", args); - return 1; -} - -/* MOVE(C) : 0011 1WDD DDD1 Z11- : A-144 */ -static size_t dsp56k_dasm_movec_2(const UINT16 op, char* opcode_str, char* arg_str) -{ - char ea[32]; - char SD[32]; - char args[32]; - decode_DDDDD_table(BITS(op,0x03e0), SD); - decode_Z_table(BITS(op,0x0008), ea); - assemble_arguments_from_W_table(BITS(op,0x0400), args, 'X', SD, ea); - sprintf(opcode_str, "move(c)"); - sprintf(arg_str, "%s", args); - return 1; -} - -/* MOVE(C) : 0011 1WDD DDD1 t10- xxxx xxxx xxxx xxxx : A-144 */ -static size_t dsp56k_dasm_movec_3(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) -{ - char ea[32]; - char SD[32]; - char args[32]; - decode_DDDDD_table(BITS(op,0x03e0), SD); - assemble_ea_from_t_table(BITS(op,0x0008), op2, ea); - if (BITS(op,0x0400)) /* order fixed - 02/03/05 */ - sprintf(args, "%s,%s", ea, SD); - else - sprintf(args, "%s,%s", SD, ea); - sprintf(opcode_str, "move(c)"); - sprintf(arg_str, "%s", args); - return 2; -} - -/* MOVE(C) : 0010 10dd dddD DDDD : A-144 */ -static size_t dsp56k_dasm_movec_4(const UINT16 op, char* opcode_str, char* arg_str) -{ - char D1[32]; - char S1[32]; - decode_DDDDD_table(BITS(op,0x03e0), S1); - decode_DDDDD_table(BITS(op,0x001f), D1); - sprintf(opcode_str, "move(c)"); - sprintf(arg_str, "%s,%s", S1, D1); - return 1; -} - -/* MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 */ -static size_t dsp56k_dasm_movec_5(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) -{ - INT8 B; - char SD[32]; - char args[32]; - B = BITS(op,0x00ff); - decode_DDDDD_table(BITS(op2,0x03e0), SD); - assemble_reg_from_W_table(BITS(op2,0x0400), args, 'X', SD, B); - sprintf(opcode_str, "move(c)"); - sprintf(arg_str, "%s", args); - return 2; -} - -/* MOVE(I) : 0010 00DD BBBB BBBB : A-150 */ -static size_t dsp56k_dasm_movei(const UINT16 op, char* opcode_str, char* arg_str) -{ - char D1[32]; - decode_DD_table(BITS(op,0x0300), D1); - sprintf(opcode_str, "move(i)"); - sprintf(arg_str, "#$%02x,%s", BITS(op,0x00ff), D1); - return 1; -} - -/* MOVE(M) : 0000 001W RR0M MHHH : A-152 */ -static size_t dsp56k_dasm_movem(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - char ea[32]; - char SD[32]; - char args[32]; - Rnum = decode_RR_table(BITS(op,0x00c0)); - decode_HHH_table(BITS(op,0x0007), SD); - assemble_ea_from_MM_table(BITS(op,0x0018), Rnum, ea); - assemble_arguments_from_W_table(BITS(op,0x0100), args, 'P', SD, ea); - sprintf(opcode_str, "move(m)"); - sprintf(arg_str, "%s", args); - return 1; -} - -/* MOVE(M) : 0000 001W RR11 mmRR : A-152 */ -static size_t dsp56k_dasm_movem_1(const UINT16 op, char* opcode_str, char* arg_str) -{ - char ea[32]; - char SD[32]; - char ea2[32]; - char args[32]; - assemble_eas_from_m_table(BITS(op,0x000c), BITS(op,0x00c0), BITS(op,0x0003), ea, ea2); - sprintf(SD, "P:%s", ea); - assemble_arguments_from_W_table(BITS(op,0x0100), args, 'X', SD, ea2); - sprintf(opcode_str, "move(m)*"); /* This asterisk is to denote that this opcode may have an error with its disassembly */ - sprintf(arg_str, "%s", args); - return 1; -} - -/* MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 */ -static size_t dsp56k_dasm_movem_2(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) -{ - INT8 B; - char SD[32]; - char args[32]; - B = BITS(op,0x00ff); - decode_HHH_table(BITS(op2,0x0007), SD); - assemble_reg_from_W_table(BITS(op2,0x0100), args, 'P', SD, B); - sprintf(opcode_str, "move(m)"); - sprintf(arg_str, "%s", args); - return 2; -} - -/* MOVE(P) : 0001 100W HH1p pppp : A-156 */ -static size_t dsp56k_dasm_movep(const UINT16 op, char* opcode_str, char* arg_str) -{ - char A[32]; - char SD[32]; - char args[32]; - char fullAddy[128]; /* Convert Short Absolute Address to full 16-bit */ - decode_HH_table(BITS(op,0x00c0), SD); - assemble_address_from_IO_short_address(BITS(op,0x001f), fullAddy); - sprintf(A, "$%s", fullAddy); - assemble_arguments_from_W_table(BITS(op,0x0100), args, 'X', SD, A); - sprintf(opcode_str, "move(p)"); - sprintf(arg_str, "%s", args); - return 1; -} - -/* MOVE(P) : 0000 110W RRmp pppp : A-156 */ -static size_t dsp56k_dasm_movep_1(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - char ea[32]; - char SD[32]; - char args[32]; - char fullAddy[128]; /* Convert Short Absolute Address to full 16-bit */ - Rnum = decode_RR_table(BITS(op,0x00c0)); - assemble_ea_from_m_table(BITS(op,0x0020), Rnum, ea); - assemble_address_from_IO_short_address(BITS(op,0x001f), fullAddy); - sprintf(SD, "X:$%s", fullAddy); - assemble_arguments_from_W_table(BITS(op,0x0100), args, 'X', SD, ea); - sprintf(opcode_str, "move(p)*"); /* This asterisk is to denote that this opcode may have an error with its disassembly */ - sprintf(arg_str, "%s", args); - return 1; -} - -/* MOVE(S) : 0001 100W HH0a aaaa : A-158 */ -static size_t dsp56k_dasm_moves(const UINT16 op, char* opcode_str, char* arg_str) -{ - char A[32]; - char SD[32]; - char args[32]; - decode_HH_table(BITS(op,0x00c0), SD); - sprintf(A, "$%02x", BITS(op,0x001f)); - assemble_arguments_from_W_table(BITS(op,0x0100), args, 'X', SD, A); - sprintf(opcode_str, "move(s)"); - sprintf(arg_str, "%s", args); - return 1; -} - -/* MPY(su,uu) : 0001 0101 1100 FsQQ : A-164 */ -static size_t dsp56k_dasm_mpysuuu(const UINT16 op, char* opcode_str, char* arg_str) -{ - char A[32]; - char D[32]; - char S1[32]; - char S2[32]; - decode_s_table(BITS(op,0x0004), A); - decode_QQF_special_table(BITS(op,0x0003), BITS(op,0x0008), S1, S2, D); /* Special QQF */ - sprintf(opcode_str, "mpy(%s)", A); - sprintf(arg_str, "%s,%s,%s", S1, S2, D); - return 1; -} - -/* NEGC : 0001 0101 0110 F000 : A-168 */ -static size_t dsp56k_dasm_negc(const UINT16 op, char* opcode_str, char* arg_str) -{ - char D[32]; - decode_F_table(BITS(op,0x0008), D); - sprintf(opcode_str, "negc"); - sprintf(arg_str, "%s", D); - return 1; -} - -/* NOP : 0000 0000 0000 0000 : A-170 */ -static size_t dsp56k_dasm_nop(const UINT16 op, char* opcode_str, char* arg_str) -{ - sprintf(opcode_str, "nop"); - sprintf(arg_str, " "); - return 1; -} - -/* NORM : 0001 0101 0010 F0RR : A-172 */ -static size_t dsp56k_dasm_norm(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - char D[32]; - decode_F_table(BITS(op,0x0008), D); - Rnum = decode_RR_table(BITS(op,0x0003)); - sprintf(opcode_str, "norm"); - sprintf(arg_str, "R%d,%s", Rnum, D); - return 1; -} - -/* ORI : 0001 1EE1 iiii iiii : A-178 */ -static size_t dsp56k_dasm_ori(const UINT16 op, char* opcode_str, char* arg_str) -{ - char D[32]; - decode_EE_table(BITS(op,0x0600), D); - sprintf(opcode_str, "or(i)"); - sprintf(arg_str, "#$%02x,%s", BITS(op,0x00ff), D); - return 1; -} - -/* REP : 0000 0000 111- --RR : A-180 */ -static size_t dsp56k_dasm_rep(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - Rnum = decode_RR_table(BITS(op,0x0003)); - sprintf(opcode_str, "rep"); - sprintf(arg_str, "X:(R%d)", Rnum); - return 1; -} - -/* REP : 0000 1111 iiii iiii : A-180 */ -static size_t dsp56k_dasm_rep_1(const UINT16 op, char* opcode_str, char* arg_str) -{ - sprintf(opcode_str, "rep"); - sprintf(arg_str, "#$%02x (%d)", BITS(op,0x00ff), BITS(op,0x00ff)); - return 1; -} - -/* REP : 0000 0100 001D DDDD : A-180 */ -static size_t dsp56k_dasm_rep_2(const UINT16 op, char* opcode_str, char* arg_str) -{ - char S1[32]; - decode_DDDDD_table(BITS(op,0x001f), S1); - sprintf(opcode_str, "rep"); - sprintf(arg_str, "%s", S1); - return 1; -} - -/* REPcc : 0000 0001 0101 cccc : A-184 */ -static size_t dsp56k_dasm_repcc(const UINT16 op, char* opcode_str, char* arg_str) -{ - char M[32]; - decode_cccc_table(BITS(op,0x000f), M); - sprintf(opcode_str, "rep.%s", M); - sprintf(arg_str, " "); - return 1; -} - -/* RESET : 0000 0000 0000 1000 : A-186 */ -static size_t dsp56k_dasm_reset(const UINT16 op, char* opcode_str, char* arg_str) -{ - sprintf(opcode_str, "reset"); - sprintf(arg_str, " "); - return 1; -} - -/* RTI : 0000 0000 0000 0111 : A-194 */ -static size_t dsp56k_dasm_rti(const UINT16 op, char* opcode_str, char* arg_str) -{ - sprintf(opcode_str, "rti"); - sprintf(arg_str, " "); - return (1 | DASMFLAG_STEP_OUT); -} - -/* RTS : 0000 0000 0000 0110 : A-196 */ -static size_t dsp56k_dasm_rts(const UINT16 op, char* opcode_str, char* arg_str) -{ - sprintf(opcode_str, "rts"); - sprintf(arg_str, " "); - return (1 | DASMFLAG_STEP_OUT); -} - -/* STOP : 0000 0000 0000 1010 : A-200 */ -static size_t dsp56k_dasm_stop(const UINT16 op, char* opcode_str, char* arg_str) -{ - sprintf(opcode_str, "stop"); - sprintf(arg_str, " "); - return 1; -} - -/* SWAP : 0001 0101 0111 F001 : A-206 */ -static size_t dsp56k_dasm_swap(const UINT16 op, char* opcode_str, char* arg_str) -{ - char D[32]; - decode_F_table(BITS(op,0x0008), D); - sprintf(opcode_str, "swap"); - sprintf(arg_str, "%s", D); - return 1; -} - -/* SWI : 0000 0000 0000 0101 : A-208 */ -static size_t dsp56k_dasm_swi(const UINT16 op, char* opcode_str, char* arg_str) -{ - sprintf(opcode_str, "swi"); - sprintf(arg_str, " "); - return 1; -} - -/* Tcc : 0001 00cc ccTT Fh0h : A-210 */ -static size_t dsp56k_dasm_tcc(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum = -1; - char M[32]; - char D[32]; - char S[32]; - - decode_cccc_table(BITS(op,0x03c0), M); - sprintf(opcode_str, "t.%s", M); - - Rnum = decode_RR_table(BITS(op,0x0030)); - decode_h0hF_table(BITS(op,0x0007),BITS(op,0x0008), S, D); - sprintf(arg_str, "%s,%s R0,R%d", S, D, Rnum); - - /* Note: S == 'A' && D == 'A' is used by the assembler when "no Data ALU - transfer is specified in the instruction." The Data ALU contains the - X,Y,A,B registers. The AGU holds the R registers. This comment means - the assembler will create Tcc A,A when it wants to conditionally transfer - only a R register to another R register. */ - return 1; -} - -/* TFR(2) : 0001 0101 0000 F00J : A-214 */ -static size_t dsp56k_dasm_tfr2(const UINT16 op, char* opcode_str, char* arg_str) -{ - char D[32]; - char S1[32]; - decode_JF_table(BITS(op,0x0001),BITS(op,0x0008), D, S1); - sprintf(opcode_str, "tfr2"); - sprintf(arg_str, "%s,%s", S1, D); - return 1; -} - -/* TFR(3) : 0010 01mW RRDD FHHH : A-216 */ -static size_t dsp56k_dasm_tfr3(const UINT16 op, char* opcode_str, char* arg_str) -{ - int Rnum; - char ea[32]; - char D1[32]; - char S1[32]; - char SD[32]; - char args[32]; - decode_DDF_table(BITS(op,0x0030), BITS(op,0x0008), D1, S1); /* Intentionally switched */ - decode_HHH_table(BITS(op,0x0007), SD); - Rnum = decode_RR_table(BITS(op,0x00c0)); - assemble_ea_from_m_table(BITS(op,0x0200), Rnum, ea); - assemble_arguments_from_W_table(BITS(op,0x0100), args, 'X', SD, ea); - sprintf(opcode_str, "tfr3"); - sprintf(arg_str, "%s,%s %s", S1, D1, args); - return 1; -} - -/* TST(2) : 0001 0101 0001 -1DD : A-220 */ -static size_t dsp56k_dasm_tst2(const UINT16 op, char* opcode_str, char* arg_str) -{ - char S1[32]; - decode_DD_table(BITS(op,0x0003), S1); - sprintf(opcode_str, "tst2"); - sprintf(arg_str, "%s", S1); - return 1; -} - -/* WAIT : 0000 0000 0000 1011 : A-222 */ -static size_t dsp56k_dasm_wait(const UINT16 op, char* opcode_str, char* arg_str) -{ - sprintf(opcode_str, "wait"); - sprintf(arg_str, " "); - return 1; -} - -/* ZERO : 0001 0101 0101 F000 : A-224 */ -static size_t dsp56k_dasm_zero(const UINT16 op, char* opcode_str, char* arg_str) -{ - char D[32]; - decode_F_table(BITS(op,0x0008), D); - sprintf(opcode_str, "zero"); - sprintf(arg_str, "%s", D); - return 1; -} - - - -/**********************************/ -/* Parallel memory move functions */ -/**********************************/ -/* X Memory Data Move : 1mRR HHHW ---- ---- : A-137 */ -static void decode_x_memory_data_move(const UINT16 op, char* parallel_move_str) -{ - int Rnum; - char SD[32]; - char ea[32]; - char args[32]; - - Rnum = decode_RR_table(BITS(op,0x3000)); - decode_HHH_table(BITS(op,0x0e00), SD); - assemble_ea_from_m_table(BITS(op,0x4000), Rnum, ea); - assemble_arguments_from_W_table(BITS(op,0x0100), args, 'X', SD, ea); - - sprintf(parallel_move_str, "%s", args); -} - -/* X Memory Data Move : 0101 HHHW ---- ---- : A-137 */ -static void decode_x_memory_data_move2(const UINT16 op, char* parallel_move_str, char* d_register) -{ - char SD[32] ; - char args[32] ; - char dest[32] ; - - if (d_register[0] == 'B') - sprintf(dest, "(A1)"); - else if (d_register[0] == 'A') - sprintf(dest, "(B1)"); - else - sprintf(dest, "(A1)"); - - decode_HHH_table(BITS(op,0x0e00), SD) ; - assemble_arguments_from_W_table(BITS(op,0x0100), args, 'X', SD, dest) ; - - sprintf(parallel_move_str, "%s", args); -} - -/* Dual X Memory Data Read : 011m mKKK -rr- ---- : A-142*/ -static void decode_dual_x_memory_data_read(const UINT16 op, char* parallel_move_str, char* parallel_move_str2, char* d_register) -{ - int Rnum; - char D1[32] = ""; - char D2[32] = ""; - char ea1[32] = ""; - char ea2[32] = ""; - - Rnum = decode_rr_table(BITS(op,0x0060)); - decode_KKK_table(BITS(op,0x0700), D1, D2); - assemble_eas_from_m_table(BITS(op,0x1800), Rnum, 3, ea1, ea2); - - /* Not documented, but extrapolated from docs on page A-133 */ - if (D1[0] == '^' && D1[1] == 'F') - { - if (d_register[0] == 'B') - sprintf(D1, "A"); - else if (d_register[0] == 'A') - sprintf(D1, "B"); - else - sprintf(D1, "A"); /* In the case of no data ALU operation */ - } - - /* D1 and D2 may not specify the same register : A-142 */ - if (Rnum == 3) - { - /* Replace the R3 with !! */ - ea1[1] = ea1[2] = '!'; - } - - sprintf(parallel_move_str, "X:%s,%s", ea1, D1); - sprintf(parallel_move_str2, "X:%s,%s", ea2, D2); -} - -/* Register to Register Data Move : 0100 IIII ---- ---- : A-133 */ -static void decode_register_to_register_data_move(const UINT16 op, char* parallel_move_str, char* d_register) -{ - char S[32]; - char D[32]; - - 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') - sprintf(D, "A"); - else if (d_register[0] == 'A') - sprintf(D, "B"); - else - sprintf(D, "A"); /* In the case of no data ALU operation */ - } - - sprintf(parallel_move_str, "%s,%s", S, D); -} - -/* Address Register Update : 0011 0zRR ---- ---- : A-135 */ -static void decode_address_register_update(const UINT16 op, char* parallel_move_str) -{ - char ea[32]; - int Rnum; - Rnum = decode_RR_table(BITS(op,0x0300)); - assemble_ea_from_z_table(BITS(op,0x0400), Rnum, ea); - sprintf(parallel_move_str, "%s", ea); -} - -/* X Memory Data Write and Register Data Move : 0001 011k RRDD ---- : A-140 */ -static void decode_x_memory_data_write_and_register_data_move(const UINT16 op, char* parallel_move_str, char* parallel_move_str2) -{ - int Rnum; - char S[32]; - char Dnot[32]; - - decode_k_table(BITS(op,0x0100), Dnot); - Rnum = decode_RR_table(BITS(op,0x00c0)); - decode_DD_table(BITS(op,0x0030), S); - - sprintf(parallel_move_str, "%s,X:(R%d)+N%d", Dnot, Rnum, Rnum); - sprintf(parallel_move_str2, "%s,%s", S, Dnot); -} - -/* X Memory Data Move with short displacement : 0000 0101 BBBB BBBB ---- HHHW ---- ---- : A-139 */ -static void decode_x_memory_data_move_with_short_displacement(const UINT16 op, const UINT16 op2, char* parallel_move_str) -{ - INT8 B; - char SD[32]; - char args[32]; - - B = (char)(op & 0x00ff); - decode_HHH_table(BITS(op2,0x0e00), SD); - assemble_reg_from_W_table(BITS(op2,0x0100), args, 'X', SD, B); - sprintf(parallel_move_str, "%s", args); -} - - -/******************/ -/* Table decoding */ -/******************/ - -static int decode_BBB_table(UINT16 BBB) -{ - switch(BBB) - { - case 0x4: return BBB_UPPER; - case 0x2: return BBB_MIDDLE; - case 0x1: return BBB_LOWER; - } - - return BBB_INVALID; -} - -static void decode_cccc_table(UINT16 cccc, char *mnemonic) -{ - switch (cccc) - { - case 0x0: sprintf(mnemonic, "cc(hs)"); break; - case 0x1: sprintf(mnemonic, "ge "); break; - case 0x2: sprintf(mnemonic, "ne "); break; - case 0x3: sprintf(mnemonic, "pl "); break; - case 0x4: sprintf(mnemonic, "nn "); break; - case 0x5: sprintf(mnemonic, "ec "); break; - case 0x6: sprintf(mnemonic, "lc "); break; - case 0x7: sprintf(mnemonic, "gt "); break; - case 0x8: sprintf(mnemonic, "cs(lo)"); break; - case 0x9: sprintf(mnemonic, "lt "); break; - case 0xa: sprintf(mnemonic, "eq "); break; - case 0xb: sprintf(mnemonic, "mi "); break; - case 0xc: sprintf(mnemonic, "nr "); break; - case 0xd: sprintf(mnemonic, "es "); break; - case 0xe: sprintf(mnemonic, "ls "); break; - case 0xf: sprintf(mnemonic, "le "); break; - } -} - -static void decode_DDDDD_table(UINT16 DDDDD, char *SD) -{ - switch(DDDDD) - { - case 0x00: sprintf(SD, "X0"); break; - case 0x01: sprintf(SD, "Y0"); break; - case 0x02: sprintf(SD, "X1"); break; - case 0x03: sprintf(SD, "Y1"); break; - case 0x04: sprintf(SD, "A"); break; - case 0x05: sprintf(SD, "B"); break; - case 0x06: sprintf(SD, "A0"); break; - case 0x07: sprintf(SD, "B0"); break; - case 0x08: sprintf(SD, "LC"); break; - case 0x09: sprintf(SD, "SR"); break; - case 0x0a: sprintf(SD, "OMR"); break; - case 0x0b: sprintf(SD, "SP"); break; - case 0x0c: sprintf(SD, "A1"); break; - case 0x0d: sprintf(SD, "B1"); break; - case 0x0e: sprintf(SD, "A2"); break; - case 0x0f: sprintf(SD, "B2"); break; - - case 0x10: sprintf(SD, "R0"); break; - case 0x11: sprintf(SD, "R1"); break; - case 0x12: sprintf(SD, "R2"); break; - case 0x13: sprintf(SD, "R3"); break; - case 0x14: sprintf(SD, "M0"); break; - case 0x15: sprintf(SD, "M1"); break; - case 0x16: sprintf(SD, "M2"); break; - case 0x17: sprintf(SD, "M3"); break; - case 0x18: sprintf(SD, "SSH"); break; - case 0x19: sprintf(SD, "SSL"); break; - case 0x1a: sprintf(SD, "LA"); break; - case 0x1b: sprintf(SD, "!!"); break; /* no 0x1b */ - case 0x1c: sprintf(SD, "N0"); break; - case 0x1d: sprintf(SD, "N1"); break; - case 0x1e: sprintf(SD, "N2"); break; - case 0x1f: sprintf(SD, "N3"); break; - } -} - -static void decode_DD_table(UINT16 DD, char *SD) -{ - switch (DD) - { - case 0x0: sprintf(SD, "X0"); break; - case 0x1: sprintf(SD, "Y0"); break; - case 0x2: sprintf(SD, "X1"); break; - case 0x3: sprintf(SD, "Y1"); break; - } -} - -static void decode_DDF_table(UINT16 DD, UINT16 F, char *S, char *D) -{ - UINT16 switchVal = (DD << 1) | F; - - switch (switchVal) - { - case 0x0: sprintf(S, "X0"); sprintf(D, "A"); break; - case 0x1: sprintf(S, "X0"); sprintf(D, "B"); break; - case 0x2: sprintf(S, "Y0"); sprintf(D, "A"); break; - case 0x3: sprintf(S, "Y0"); sprintf(D, "B"); break; - case 0x4: sprintf(S, "X1"); sprintf(D, "A"); break; - case 0x5: sprintf(S, "X1"); sprintf(D, "B"); break; - case 0x6: sprintf(S, "Y1"); sprintf(D, "A"); break; - case 0x7: sprintf(S, "Y1"); sprintf(D, "B"); break; - } -} - -static void decode_EE_table(UINT16 EE, char *D) -{ - switch(EE) - { - case 0x1: sprintf(D, "MR"); break; - case 0x3: sprintf(D, "CCR"); break; - case 0x2: sprintf(D, "OMR"); break; - } -} - -static void decode_F_table(UINT16 F, char *SD) -{ - switch(F) - { - case 0x0: sprintf(SD, "A"); break; - case 0x1: sprintf(SD, "B"); break; - } -} - -static void decode_h0hF_table(UINT16 h0h, UINT16 F, char *S, char *D) -{ - UINT16 switchVal = (h0h << 1) | F; - - switch (switchVal) - { - case 0x8: sprintf(S, "X0"); sprintf(D, "A"); break; - case 0x9: sprintf(S, "X0"); sprintf(D, "B"); break; - case 0xa: sprintf(S, "Y0"); sprintf(D, "A"); break; - case 0xb: sprintf(S, "Y0"); sprintf(D, "B"); break; - case 0x2: sprintf(S, "A") ; sprintf(D, "A"); break; - case 0x1: sprintf(S, "A") ; sprintf(D, "B"); break; - case 0x0: sprintf(S, "B") ; sprintf(D, "A"); break; - case 0x3: sprintf(S, "B") ; sprintf(D, "B"); break; - } -} - -static void decode_HH_table(UINT16 HH, char *SD) -{ - switch(HH) - { - case 0x0: sprintf(SD, "X0"); break; - case 0x1: sprintf(SD, "Y0"); break; - case 0x2: sprintf(SD, "A") ; break; - case 0x3: sprintf(SD, "B") ; break; - } -} - -static void decode_HHH_table(UINT16 HHH, char *SD) -{ - switch(HHH) - { - case 0x0: sprintf(SD, "X0"); break; - case 0x1: sprintf(SD, "Y0"); break; - case 0x2: sprintf(SD, "X1"); break; - case 0x3: sprintf(SD, "Y1"); break; - case 0x4: sprintf(SD, "A") ; break; - case 0x5: sprintf(SD, "B") ; break; - case 0x6: sprintf(SD, "A0"); break; - case 0x7: sprintf(SD, "B0"); break; - } -} - -static void decode_IIII_table(UINT16 IIII, char *S, char *D) -{ - switch(IIII) - { - case 0x0: sprintf(S, "X0"); sprintf(D, "^F"); break; - case 0x1: sprintf(S, "Y0"); sprintf(D, "^F"); break; - case 0x2: sprintf(S, "X1"); sprintf(D, "^F"); break; - case 0x3: sprintf(S, "Y1"); sprintf(D, "^F"); break; - case 0x4: sprintf(S, "A"); sprintf(D, "X0"); break; - case 0x5: sprintf(S, "B"); sprintf(D, "Y0"); break; - case 0x6: sprintf(S, "A0"); sprintf(D, "X0"); break; - case 0x7: sprintf(S, "B0"); sprintf(D, "Y0"); break; - case 0x8: sprintf(S, "F"); sprintf(D, "^F"); break; - case 0x9: sprintf(S, "F"); sprintf(D, "^F"); break; - case 0xa: sprintf(S, "?"); sprintf(D, "?"); break; - case 0xb: sprintf(S, "?"); sprintf(D, "?"); break; - case 0xc: sprintf(S, "A"); sprintf(D, "X1"); break; - case 0xd: sprintf(S, "B"); sprintf(D, "Y1"); break; - case 0xe: sprintf(S, "A0"); sprintf(D, "X1"); break; - case 0xf: sprintf(S, "B0"); sprintf(D, "Y1"); break; - } -} - -static void decode_JJJF_table(UINT16 JJJ, UINT16 F, char *S, char *D) -{ - UINT16 switchVal = (JJJ << 1) | F; - - switch(switchVal) - { - case 0x0: sprintf(S, "B") ; sprintf(D, "A"); break; - case 0x1: sprintf(S, "A") ; sprintf(D, "B"); break; - case 0x2: sprintf(S, "!") ; sprintf(D, "!"); break; - case 0x3: sprintf(S, "!") ; sprintf(D, "!"); break; - case 0x4: sprintf(S, "X") ; sprintf(D, "A"); break; - case 0x5: sprintf(S, "X") ; sprintf(D, "B"); break; - case 0x6: sprintf(S, "Y") ; sprintf(D, "A"); break; - case 0x7: sprintf(S, "Y") ; sprintf(D, "B"); break; - case 0x8: sprintf(S, "X0"); sprintf(D, "A"); break; - case 0x9: sprintf(S, "X0"); sprintf(D, "B"); break; - case 0xa: sprintf(S, "Y0"); sprintf(D, "A"); break; - case 0xb: sprintf(S, "Y0"); sprintf(D, "B"); break; - case 0xc: sprintf(S, "X1"); sprintf(D, "A"); break; - case 0xd: sprintf(S, "X1"); sprintf(D, "B"); break; - case 0xe: sprintf(S, "Y1"); sprintf(D, "A"); break; - case 0xf: sprintf(S, "Y1"); sprintf(D, "B"); break; - } -} - -static void decode_JJF_table(UINT16 JJ, UINT16 F, char *S, char *D) -{ - UINT16 switchVal = (JJ << 1) | F; - - switch (switchVal) - { - case 0x0: sprintf(S, "X0"); sprintf(D, "A"); break; - case 0x1: sprintf(S, "X0"); sprintf(D, "B"); break; - case 0x2: sprintf(S, "Y0"); sprintf(D, "A"); break; - case 0x3: sprintf(S, "Y0"); sprintf(D, "B"); break; - case 0x4: sprintf(S, "X1"); sprintf(D, "A"); break; - case 0x5: sprintf(S, "X1"); sprintf(D, "B"); break; - case 0x6: sprintf(S, "Y1"); sprintf(D, "A"); break; - case 0x7: sprintf(S, "Y1"); sprintf(D, "B"); break; - } -} - -static void decode_JF_table(UINT16 J, UINT16 F, char *S, char *D) -{ - UINT16 switchVal = (J << 1) | F; - - switch(switchVal) - { - case 0x0: sprintf(S, "X"); sprintf(D, "A"); break; - case 0x1: sprintf(S, "X"); sprintf(D, "B"); break; - case 0x2: sprintf(S, "Y"); sprintf(D, "A"); break; - case 0x3: sprintf(S, "Y"); sprintf(D, "B"); break; - } -} - -static void decode_k_table(UINT16 k, char *Dnot) -{ - switch(k) - { - case 0x0: sprintf(Dnot, "B"); break; - case 0x1: sprintf(Dnot, "A"); break; - } -} - -static void decode_kSign_table(UINT16 k, char *plusMinus) -{ - switch(k) - { - case 0x0: sprintf(plusMinus, "+"); break; - case 0x1: sprintf(plusMinus, "-"); break; - } -} - -static void decode_KKK_table(UINT16 KKK, char *D1, char *D2) -{ - switch(KKK) - { - case 0x0: sprintf(D1, "^F"); sprintf(D2, "X0"); break; - case 0x1: sprintf(D1, "Y0"); sprintf(D2, "X0"); break; - case 0x2: sprintf(D1, "X1"); sprintf(D2, "X0"); break; - case 0x3: sprintf(D1, "Y1"); sprintf(D2, "X0"); break; - case 0x4: sprintf(D1, "X0"); sprintf(D2, "X1"); break; - case 0x5: sprintf(D1, "Y0"); sprintf(D2, "X1"); break; - case 0x6: sprintf(D1, "^F"); sprintf(D2, "Y0"); break; - case 0x7: sprintf(D1, "Y1"); sprintf(D2, "X1"); break; - } -} - -static int decode_NN_table(UINT16 NN) -{ - return NN; -} - -static int decode_TT_table(UINT16 TT) -{ - return TT; -} - -static void decode_QQF_table(UINT16 QQ, UINT16 F, char *S1, char *S2, char *D) -{ - UINT16 switchVal = (QQ << 1) | F; - - switch(switchVal) - { - case 0x0: sprintf(S1, "X0"); sprintf(S2, "Y0"); sprintf(D, "A"); break; - case 0x1: sprintf(S1, "X0"); sprintf(S2, "Y0"); sprintf(D, "B"); break; - case 0x2: sprintf(S1, "X0"); sprintf(S2, "Y1"); sprintf(D, "A"); break; - case 0x3: sprintf(S1, "X0"); sprintf(S2, "Y1"); sprintf(D, "B"); break; - case 0x4: sprintf(S1, "X1"); sprintf(S2, "Y0"); sprintf(D, "A"); break; - case 0x5: sprintf(S1, "X1"); sprintf(S2, "Y0"); sprintf(D, "B"); break; - case 0x6: sprintf(S1, "X1"); sprintf(S2, "Y1"); sprintf(D, "A"); break; - case 0x7: sprintf(S1, "X1"); sprintf(S2, "Y1"); sprintf(D, "B"); break; - } -} - -static void decode_QQF_special_table(UINT16 QQ, UINT16 F, char *S1, char *S2, char *D) -{ - UINT16 switchVal = (QQ << 1) | F; - - switch(switchVal) - { - case 0x0: sprintf(S1, "Y0"); sprintf(S2, "X0"); sprintf(D, "A"); break; - case 0x1: sprintf(S1, "Y0"); sprintf(S2, "X0"); sprintf(D, "B"); break; - case 0x2: sprintf(S1, "Y1"); sprintf(S2, "X0"); sprintf(D, "A"); break; - case 0x3: sprintf(S1, "Y1"); sprintf(S2, "X0"); sprintf(D, "B"); break; - case 0x4: sprintf(S1, "X1"); sprintf(S2, "Y0"); sprintf(D, "A"); break; - case 0x5: sprintf(S1, "X1"); sprintf(S2, "Y0"); sprintf(D, "B"); break; - case 0x6: sprintf(S1, "X1"); sprintf(S2, "Y1"); sprintf(D, "A"); break; - case 0x7: sprintf(S1, "X1"); sprintf(S2, "Y1"); sprintf(D, "B"); break; - } -} - -static void decode_QQQF_table(UINT16 QQQ, UINT16 F, char *S1, char *S2, char *D) -{ - UINT16 switchVal = (QQQ << 1) | F; - - switch(switchVal) - { - case 0x0: sprintf(S1, "X0"); sprintf(S2, "X0"); sprintf(D, "A"); break; - case 0x1: sprintf(S1, "X0"); sprintf(S2, "X0"); sprintf(D, "B"); break; - case 0x2: sprintf(S1, "X1"); sprintf(S2, "X0"); sprintf(D, "A"); break; - case 0x3: sprintf(S1, "X1"); sprintf(S2, "X0"); sprintf(D, "B"); break; - case 0x4: sprintf(S1, "A1"); sprintf(S2, "Y0"); sprintf(D, "A"); break; - case 0x5: sprintf(S1, "A1"); sprintf(S2, "Y0"); sprintf(D, "B"); break; - case 0x6: sprintf(S1, "B1"); sprintf(S2, "X0"); sprintf(D, "A"); break; - case 0x7: sprintf(S1, "B1"); sprintf(S2, "X0"); sprintf(D, "B"); break; - case 0x8: sprintf(S1, "Y0"); sprintf(S2, "X0"); sprintf(D, "A"); break; - case 0x9: sprintf(S1, "Y0"); sprintf(S2, "X0"); sprintf(D, "B"); break; - case 0xa: sprintf(S1, "Y1"); sprintf(S2, "X0"); sprintf(D, "A"); break; - case 0xb: sprintf(S1, "Y1"); sprintf(S2, "X0"); sprintf(D, "B"); break; - case 0xc: sprintf(S1, "Y0"); sprintf(S2, "X1"); sprintf(D, "A"); break; - case 0xd: sprintf(S1, "Y0"); sprintf(S2, "X1"); sprintf(D, "B"); break; - case 0xe: sprintf(S1, "Y1"); sprintf(S2, "X1"); sprintf(D, "A"); break; - case 0xf: sprintf(S1, "Y1"); sprintf(S2, "X1"); sprintf(D, "B"); break; - } -} - -static int decode_RR_table(UINT16 RR) -{ - return RR; -} - -static int decode_rr_table(UINT16 rr) -{ - return rr; -} - -static void decode_s_table(UINT16 s, char *arithmetic) -{ - switch(s) - { - case 0x0: sprintf(arithmetic, "su"); break; - case 0x1: sprintf(arithmetic, "uu"); break; - } -} - -static void decode_ss_table(UINT16 ss, char *arithmetic) -{ - switch(ss) - { - case 0x0: sprintf(arithmetic, "ss"); break; - case 0x1: sprintf(arithmetic, "ss"); break; - case 0x2: sprintf(arithmetic, "su"); break; - case 0x3: sprintf(arithmetic, "uu"); break; - } -} - -static void decode_uuuuF_table(UINT16 uuuu, UINT16 F, char *arg, char *S, char *D) -{ - UINT16 switchVal = (uuuu << 1) | F; - - sprintf(D, "sub?"); - sprintf(S, "add"); - sprintf(arg, "invalid"); - - switch(switchVal) - { - case 0x00: sprintf(arg, "add"); sprintf(S, "X0"); sprintf(D, "A"); break; - case 0x08: sprintf(arg, "sub"); sprintf(S, "X0"); sprintf(D, "A"); break; - case 0x01: sprintf(arg, "add"); sprintf(S, "X0"); sprintf(D, "B"); break; - case 0x09: sprintf(arg, "sub"); sprintf(S, "X0"); sprintf(D, "B"); break; - case 0x02: sprintf(arg, "add"); sprintf(S, "Y0"); sprintf(D, "A"); break; - case 0x0a: sprintf(arg, "sub"); sprintf(S, "Y0"); sprintf(D, "A"); break; - case 0x03: sprintf(arg, "add"); sprintf(S, "Y0"); sprintf(D, "B"); break; - case 0x0b: sprintf(arg, "sub"); sprintf(S, "Y0"); sprintf(D, "B"); break; - case 0x04: sprintf(arg, "add"); sprintf(S, "X1"); sprintf(D, "A"); break; - case 0x0c: sprintf(arg, "sub"); sprintf(S, "X1"); sprintf(D, "A"); break; - case 0x05: sprintf(arg, "add"); sprintf(S, "X1"); sprintf(D, "B"); break; - case 0x0d: sprintf(arg, "sub"); sprintf(S, "X1"); sprintf(D, "B"); break; - case 0x06: sprintf(arg, "add"); sprintf(S, "Y1"); sprintf(D, "A"); break; - case 0x0e: sprintf(arg, "sub"); sprintf(S, "Y1"); sprintf(D, "A"); break; - case 0x07: sprintf(arg, "add"); sprintf(S, "Y1"); sprintf(D, "B"); break; - case 0x0f: sprintf(arg, "sub"); sprintf(S, "Y1"); sprintf(D, "B"); break; - case 0x18: sprintf(arg, "add"); sprintf(S, "B") ; sprintf(D, "A"); break; - case 0x1a: sprintf(arg, "sub"); sprintf(S, "B") ; sprintf(D, "A"); break; - case 0x19: sprintf(arg, "add"); sprintf(S, "A") ; sprintf(D, "B"); break; - case 0x1b: sprintf(arg, "sub"); sprintf(S, "A") ; sprintf(D, "B"); break; - } -} - -static void decode_Z_table(UINT16 Z, char *ea) -{ - /* This is fixed as per the Family Manual errata addendum */ - switch(Z) - { - case 0x1: sprintf(ea, "(A1)"); break; - case 0x0: sprintf(ea, "(B1)"); break; - } -} - -static void assemble_ea_from_m_table(UINT16 m, int n, char *ea) -{ - switch(m) - { - case 0x0: sprintf(ea, "(R%d)+",n) ; break; - case 0x1: sprintf(ea, "(R%d)+N%d", n, n); break; - } -} - -static void assemble_eas_from_m_table(UINT16 mm, int n1, int n2, char *ea1, char *ea2) -{ - switch(mm) - { - case 0x0: sprintf(ea1, "(R%d)+", n1) ; - sprintf(ea2, "(R%d)+", n2) ; break; - case 0x1: sprintf(ea1, "(R%d)+", n1) ; - sprintf(ea2, "(R%d)+N%d", n2, n2); break; - case 0x2: sprintf(ea1, "(R%d)+N%d", n1, n1); - sprintf(ea2, "(R%d)+", n2) ; break; - case 0x3: sprintf(ea1, "(R%d)+N%d", n1, n1); - sprintf(ea2, "(R%d)+N%d", n2, n2); break; - } -} - -static void assemble_ea_from_MM_table(UINT16 MM, int n, char *ea) -{ - switch(MM) - { - case 0x0: sprintf(ea, "(R%d)", n) ; break; - case 0x1: sprintf(ea, "(R%d)+", n) ; break; - case 0x2: sprintf(ea, "(R%d)-", n) ; break; - case 0x3: sprintf(ea, "(R%d)+N%d", n, n); break; - } -} - -static void assemble_ea_from_q_table(UINT16 q, int n, char *ea) -{ - switch(q) - { - case 0x0: sprintf(ea, "(R%d+N%d)", n, n); break; - case 0x1: sprintf(ea, "-(R%d)", n) ; break; - } -} - -static void assemble_ea_from_t_table(UINT16 t, UINT16 val, char *ea) -{ - switch(t) - { - case 0x0: sprintf(ea, "X:$%04x", val); break; - case 0x1: sprintf(ea, "#$%04x", val); break; - } -} - -static void assemble_ea_from_z_table(UINT16 z, int n, char *ea) -{ - switch(z) - { - case 0x0: sprintf(ea, "(R%d)-", n) ; break; - case 0x1: sprintf(ea, "(R%d)+N%d", n, n); break; - } -} - -static void assemble_D_from_P_table(UINT16 P, UINT16 ppppp, char *D) -{ - char fullAddy[128]; /* Convert Short Absolute Address to full 16-bit */ - - switch(P) - { - case 0x0: sprintf(D, "X:$%02x", ppppp); break; - case 0x1: - assemble_address_from_IO_short_address(ppppp, fullAddy); - sprintf(D, "X:$%s", fullAddy); - break; - } -} - -static void assemble_arguments_from_W_table(UINT16 W, char *args, char ma, char *SD, char *ea) -{ - switch(W) - { - case 0x0: sprintf(args, "%s,%c:%s", SD, ma, ea); break; - case 0x1: sprintf(args, "%c:%s,%s", ma, ea, SD); break; - } -} - -static void assemble_reg_from_W_table(UINT16 W, char *args, char ma, char *SD, INT8 xx) -{ - UINT8 abs_xx; - char operation[32]; - - if(xx < 0) - sprintf(operation,"-"); - else - sprintf(operation,"+"); - - abs_xx = abs(xx); - - switch(W) - { - case 0x0: sprintf(args, "%s,%c:(R2%s$%02x)", SD, ma, operation, abs_xx); break; - case 0x1: sprintf(args, "%c:(R2%s$%02x),%s", ma, operation, abs_xx, SD); break; - } -} - -static void assemble_address_from_IO_short_address(UINT16 pp, char *ea) -{ - UINT16 fullAddy = 0xffe0; - fullAddy |= pp; - - sprintf(ea, "%.04x", fullAddy); -} - -static INT8 get_6_bit_signed_value(UINT16 bits) -{ - UINT16 fullAddy = bits; - if (fullAddy & 0x0020) - fullAddy |= 0xffc0; - - return (INT8)fullAddy; -} - - -/********************/ -/* HELPER FUNCTIONS */ -/********************/ - -static UINT16 dsp56k_op_mask(UINT16 cur, UINT16 mask) -{ - int i; - - UINT16 retVal = (cur & mask); - UINT16 temp = 0x0000; - int offsetCount = 0; - - /* Shift everything right, eliminating 'whitespace'... */ - for (i = 0; i < 16; i++) - { - if (mask & (0x1<> i) & 0x1) << offsetCount); - offsetCount++; - } - } - - return temp; -} - -static void pad_string(const int dest_length, char* string) -{ - while (strlen(string) < dest_length) - { - strcat(string, " "); - } -} diff --git a/src/emu/cpu/dsp56k/inst.c b/src/emu/cpu/dsp56k/inst.c new file mode 100644 index 00000000000..dcc6b53747a --- /dev/null +++ b/src/emu/cpu/dsp56k/inst.c @@ -0,0 +1,783 @@ +#include "inst.h" +#include "emu.h" + +namespace DSP56K +{ + +// Factory +Instruction* Instruction::decodeInstruction(const Opcode* opc, + const UINT16 word0, + const UINT16 word1, + bool shifted) +{ + UINT16 w0 = word0; + UINT16 w1 = word1; + + if (shifted) + { + w0 = w1; + w1 = 0x0000; + } + + /**************************************************************************/ + /* The very funky case of the XMemoryDataMoveWithShortDisplacement */ + /**************************************************************************/ + if ((w0 & 0xff00) == 0x0500) + { + // Avoid "05-- 05--" recursion + if (shifted) return NULL; + + Instruction* op = decodeInstruction(opc, w0, w1, true); + if (op) + { + // This parallel move only works for certain trailing instructions. + if (dynamic_cast(op) || + dynamic_cast(op) || + dynamic_cast(op) || + dynamic_cast(op) || + dynamic_cast(op) || + dynamic_cast(op) || + dynamic_cast(op) || + dynamic_cast(op) || + dynamic_cast(op) || + dynamic_cast(op)) + { + op->m_sizeIncrement = 1; + return op; + } + } + + global_free(op); + //return NULL; + } + + + /**************************************************************************/ + /* Dual X Memory Data Read : 011m mKKK .rr. .... : A-142 */ + /* Quote: (MOVE, MAC(R), MPY(R), ADD, SUB, TFR) */ + /**************************************************************************/ + /* TFR : 011m mKKK 0rr1 F0DD : A-212 */ + if ((w0 & 0xe094) == 0x6010) + { + return global_alloc(Tfr_2(opc, w0, w1)); + } + /* MOVE : 011m mKKK 0rr1 0000 : A-128 */ + if ((w0 & 0xe097) == 0x6017) + { + return global_alloc(Move_2(opc, w0, w1)); + } + /* MAC : 011m mKKK 1xx0 F1QQ : A-122 */ + else if ((w0 & 0xe094) == 0x6084) + { + return global_alloc(Mac_3(opc, w0, w1)); + } + /* MACR: 011m mKKK 1--1 F1QQ : A-124 */ + else if ((w0 & 0xe094) == 0x6094) + { + return global_alloc(Macr_2(opc, w0, w1)); + } + /* MPY : 011m mKKK 1xx0 F0QQ : A-160 */ + else if ((w0 & 0xe094) == 0x6080) + { + return global_alloc(Mpy_2(opc, w0, w1)); + } + /* MPYR : 011m mKKK 1--1 F0QQ : A-162 */ + else if ((w0 & 0xe094) == 0x6090) + { + return global_alloc(Mpyr_2(opc, w0, w1)); + } + /* ADD : 011m mKKK 0rru Fuuu : A-22 */ + /* SUB : 011m mKKK 0rru Fuuu : A-202 */ + else if ((w0 & 0xe080) == 0x6000) + { + return global_alloc(Add_2(opc, w0, w1)); + } + + /****************************************************************************/ + /* X Memory Data Write and Register Data Move : 0001 011k RRDD .... : A-140 */ + /* Quote: (MPY or MAC) */ + /****************************************************************************/ + /* MPY : 0001 0110 RRDD FQQQ : A-160 */ + else if ((w0 & 0xff00) == 0x1600) + { + return global_alloc(Mpy_3(opc, w0, w1)); + } + /* MAC : 0001 0111 RRDD FQQQ : A-122 */ + else if ((w0 & 0xff00) == 0x1700) + { + return global_alloc(Mac_3(opc, w0, w1)); + } + + /****************************************************************/ + /* No Parallel Data Move : 0100 1010 .... .... : A-131 */ + /* Register to Register Data Move : 0100 IIII .... .... : A-133 */ + /* Address Register Update : 0011 0zRR .... .... : A-135 */ + /* X Memory Data Move : 1mRR HHHW .... .... : A-137 */ + /* X Memory Data Move : 0101 HHHW .... .... : A-137 */ + /* Quote: (32 General parallel move instructions) */ + /****************************************************************/ + else if (((w0 & 0xff00) == 0x4a00) || + ((w0 & 0xf000) == 0x4000) || + ((w0 & 0xf800) == 0x3000) || + ((w0 & 0x8000) == 0x8000) || + ((w0 & 0xf000) == 0x5000)) + { + /* Note: There is much overlap down here, so certain ops must come before others */ + + /* CLR : .... .... 0000 F001 : A-60 */ + if ((w0 & 0x00f7) == 0x0001) + { + return global_alloc(Clr(opc, w0, w1)); + } + /* ADD : .... .... 0000 FJJJ : A-22 */ + else if ((w0 & 0x00f0) == 0x0000) + { + return global_alloc(Add(opc, w0, w1)); + } + + /* MOVE : .... .... 0001 0001 : A-128 */ + else if ((w0 & 0x00ff) == 0x0011 || (w0 & 0x00ff) == 0x0019) + // NEW // else if ((w0 & 0x00ff) == 0x0011) + { + return global_alloc(Move(opc, w0, w1)); + } + /* TFR : .... .... 0001 FJJJ : A-212 */ + else if ((w0 & 0x00f0) == 0x0010) + { + return global_alloc(Tfr(opc, w0, w1)); + } + + /* RND : .... .... 0010 F000 : A-188 */ + else if ((w0 & 0x00f7) == 0x0020) + { + return global_alloc(Rnd(opc, w0, w1)); + } + /* TST : .... .... 0010 F001 : A-218 */ + else if ((w0 & 0x00f7) == 0x0021) + { + return global_alloc(Tst(opc, w0, w1)); + } + /* INC : .... .... 0010 F010 : A-104 */ + else if ((w0 & 0x00f7) == 0x0022) + { + return global_alloc(Inc(opc, w0, w1)); + } + /* INC24 : .... .... 0010 F011 : A-106 */ + else if ((w0 & 0x00f7) == 0x0023) + { + return global_alloc(Inc24(opc, w0, w1)); + } + /* OR : .... .... 0010 F1JJ : A-176 */ + else if ((w0 & 0x00f4) == 0x0024) + { + return global_alloc(Or(opc, w0, w1)); + } + + /* ASR : .... .... 0011 F000 : A-32 */ + else if ((w0 & 0x00f7) == 0x0030) + { + return global_alloc(Asr(opc, w0, w1)); + } + /* ASL : .... .... 0011 F001 : A-28 */ + else if ((w0 & 0x00f7) == 0x0031) + { + return global_alloc(Asl(opc, w0, w1)); + } + /* LSR : .... .... 0011 F010 : A-120 */ + else if ((w0 & 0x00f7) == 0x0032) + { + return global_alloc(Lsr(opc, w0, w1)); + } + /* LSL : .... .... 0011 F011 : A-118 */ + else if ((w0 & 0x00f7) == 0x0033) + { + return global_alloc(Lsl(opc, w0, w1)); + } + /* EOR : .... .... 0011 F1JJ : A-94 */ + else if ((w0 & 0x00f4) == 0x0034) + { + return global_alloc(Eor(opc, w0, w1)); + } + + /* SUBL : .... .... 0100 F001 : A-204 */ + else if ((w0 & 0x00f7) == 0x0041) + { + return global_alloc(Subl(opc, w0, w1)); + } + /* SUB : .... .... 0100 FJJJ : A-202 */ + else if ((w0 & 0x00f0) == 0x0040) + { + return global_alloc(Sub(opc, w0, w1)); + } + + /* CLR24 : .... .... 0101 F001 : A-62 */ + else if ((w0 & 0x00f7) == 0x0051) + { + return global_alloc(Clr24(opc, w0, w1)); + } + /* SBC : .... .... 0101 F01J : A-198 */ + else if ((w0 & 0x00f6) == 0x0052) + { + return global_alloc(Sbc(opc, w0, w1)); + } + /* CMP : .... .... 0101 FJJJ : A-64 */ + else if ((w0 & 0x00f0) == 0x0050) + { + return global_alloc(Cmp(opc, w0, w1)); + } + + /* NEG : .... .... 0110 F000 : A-166 */ + else if ((w0 & 0x00f7) == 0x0060) + { + return global_alloc(Neg(opc, w0, w1)); + } + /* NOT : .... .... 0110 F001 : A-174 */ + else if ((w0 & 0x00f7) == 0x0061) + { + return global_alloc(Not(opc, w0, w1)); + } + /* DEC : .... .... 0110 F010 : A-72 */ + else if ((w0 & 0x00f7) == 0x0062) + { + return global_alloc(Dec(opc, w0, w1)); + } + /* DEC24 : .... .... 0110 F011 : A-74 */ + else if ((w0 & 0x00f7) == 0x0063) + { + return global_alloc(Dec24(opc, w0, w1)); + } + /* AND : .... .... 0110 F1JJ : A-24 */ + else if ((w0 & 0x00f4) == 0x0064) + { + return global_alloc(And(opc, w0, w1)); + } + + /* ABS : .... .... 0111 F001 : A-18 */ + if ((w0 & 0x00f7) == 0x0071) + { + return global_alloc(Abs(opc, w0, w1)); + } + /* ROR : .... .... 0111 F010 : A-192 */ + else if ((w0 & 0x00f7) == 0x0072) + { + return global_alloc(Ror(opc, w0, w1)); + } + /* ROL : .... .... 0111 F011 : A-190 */ + else if ((w0 & 0x00f7) == 0x0073) + { + return global_alloc(Rol(opc, w0, w1)); + } + /* CMPM : .... .... 0111 FJJJ : A-66 */ + else if ((w0 & 0x00f0) == 0x0070) + { + return global_alloc(Cmpm(opc, w0, w1)); + } + + /* MPY : .... .... 1k00 FQQQ : A-160 */ + else if ((w0 & 0x00b0) == 0x0080) + { + return global_alloc(Mpy(opc, w0, w1)); + } + /* MPYR : .... .... 1k01 FQQQ : A-162 */ + else if ((w0 & 0x00b0) == 0x0090) + { + return global_alloc(Mpyr(opc, w0, w1)); + } + /* MAC : .... .... 1k10 FQQQ : A-122 */ + else if ((w0 & 0x00b0) == 0x00a0) + { + return global_alloc(Mac(opc, w0, w1)); + } + /* MACR : .... .... 1k11 FQQQ : A-124 */ + else if ((w0 & 0x00b0) == 0x00b0) + { + return global_alloc(Macr(opc, w0, w1)); + } + } + + /******************************/ + /* Remaining non-parallel ops */ + /******************************/ + /* ADC : 0001 0101 0000 F01J : A-20 */ + else if ((w0 & 0xfff6) == 0x1502) + { + return global_alloc(Adc(opc, w0, w1)); + } + /* ANDI : 0001 1EE0 iiii iiii : A-26 */ + /* Note: MoveP sneaks in here if you don't check 0x0600 */ + else if (((w0 & 0xf900) == 0x1800) & ((w0 & 0x0600) != 0x0000)) + { + return global_alloc(Andi(opc, w0, w1)); + } + /* ASL4 : 0001 0101 0011 F001 : A-30 */ + else if ((w0 & 0xfff7) == 0x1531) + { + return global_alloc(Asl4(opc, w0, w1)); + } + /* ASR4 : 0001 0101 0011 F000 : A-34 */ + else if ((w0 & 0xfff7) == 0x1530) + { + return global_alloc(Asr4(opc, w0, w1)); + } + /* ASR16 : 0001 0101 0111 F000 : A-36 */ + else if ((w0 & 0xfff7) == 0x1570) + { + return global_alloc(Asr16(opc, w0, w1)); + } + /* BFCHG : 0001 0100 11Pp pppp BBB1 0010 iiii iiii : A-38 */ + else if (((w0 & 0xffc0) == 0x14c0) && ((w1 & 0x1f00) == 0x1200)) + { + return global_alloc(BfInstruction(opc, w0, w1)); + } + /* BFCHG : 0001 0100 101- --RR BBB1 0010 iiii iiii : A-38 */ + else if (((w0 & 0xfff0) == 0x14b0) && ((w1 & 0x1f00) == 0x1200)) + // NEW // else if (((w0 & 0xffe0) == 0x14a0) && ((w1 & 0x1f00) == 0x1200)) + { + return global_alloc(BfInstruction(opc, w0, w1)); + } + /* BFCHG : 0001 0100 100D DDDD BBB1 0010 iiii iiii : A-38 */ + else if (((w0 & 0xffe0) == 0x1480) && ((w1 & 0x1f00) == 0x1200)) + { + return global_alloc(BfInstruction(opc, w0, w1)); + } + /* BFCLR : 0001 0100 11Pp pppp BBB0 0100 iiii iiii : A-40 */ + else if (((w0 & 0xffc0) == 0x14c0) && ((w1 & 0x1f00) == 0x0400)) + { + return global_alloc(BfInstruction(opc, w0, w1)); + } + /* BFCLR : 0001 0100 101- --RR BBB0 0100 iiii iiii : A-40 */ + else if (((w0 & 0xfff0) == 0x14b0) && ((w1 & 0x1f00) == 0x0400)) + // NEW // else if (((w0 & 0xffe0) == 0x14a0) && ((w1 & 0x1f00) == 0x0400)) + { + return global_alloc(BfInstruction(opc, w0, w1)); + } + /* BFCLR : 0001 0100 100D DDDD BBB0 0100 iiii iiii : A-40 */ + else if (((w0 & 0xffe0) == 0x1480) && ((w1 & 0x1f00) == 0x0400)) + { + return global_alloc(BfInstruction(opc, w0, w1)); + } + /* BFSET : 0001 0100 11Pp pppp BBB1 1000 iiii iiii : A-42 */ + else if (((w0 & 0xffc0) == 0x14c0) && ((w1 & 0x1f00) == 0x1800)) + { + return global_alloc(BfInstruction(opc, w0, w1)); + } + /* BFSET : 0001 0100 101- --RR BBB1 1000 iiii iiii : A-42 */ + else if (((w0 & 0xfff0) == 0x14b0) && ((w1 & 0x1f00) == 0x1800)) + // NEW // else if (((w0 & 0xffe0) == 0x14a0) && ((w1 & 0x1f00) == 0x1800)) + { + return global_alloc(BfInstruction(opc, w0, w1)); + } + /* BFSET : 0001 0100 100D DDDD BBB1 1000 iiii iiii : A-42 */ + else if (((w0 & 0xffe0) == 0x1480) && ((w1 & 0x1f00) == 0x1800)) + { + return global_alloc(BfInstruction(opc, w0, w1)); + } + /* BFTSTH : 0001 0100 01Pp pppp BBB1 0000 iiii iiii : A-44 */ + else if (((w0 & 0xffc0) == 0x1440) && ((w1 & 0x1f00) == 0x1000)) + { + return global_alloc(BfInstruction(opc, w0, w1)); + } + /* BFTSTH : 0001 0100 001- --RR BBB1 0000 iiii iiii : A-44 */ + else if (((w0 & 0xfff0) == 0x1430) && ((w1 & 0x1f00) == 0x1000)) + // NEW // else if (((w0 & 0xffe0) == 0x1420) && ((w1 & 0x1f00) == 0x1000)) + { + return global_alloc(BfInstruction(opc, w0, w1)); + } + /* BFTSTH : 0001 0100 000D DDDD BBB1 0000 iiii iiii : A-44 */ + else if (((w0 & 0xffe0) == 0x1400) && ((w1 & 0x1f00) == 0x1000)) + { + return global_alloc(BfInstruction(opc, w0, w1)); + } + /* BFTSTL : 0001 0100 01Pp pppp BBB0 0000 iiii iiii : A-46 */ + else if (((w0 & 0xffc0) == 0x1440) && ((w1 & 0x1f00) == 0x0000)) + { + return global_alloc(BfInstruction(opc, w0, w1)); + } + /* BFTSTL : 0001 0100 001- --RR BBB0 0000 iiii iiii : A-46 */ + else if (((w0 & 0xfff0) == 0x1430) && ((w1 & 0x1f00) == 0x0000)) + // NEW // else if (((w0 & 0xffe0) == 0x1420) && ((w1 & 0x1f00) == 0x0000)) + { + return global_alloc(BfInstruction(opc, w0, w1)); + } + /* BFTSTL : 0001 0100 000D DDDD BBB0 0000 iiii iiii : A-46 */ + else if (((w0 & 0xffe0) == 0x1400) && ((w1 & 0x1f00) == 0x0000)) + { + return global_alloc(BfInstruction(opc, w0, w1)); + } + /* Bcc : 0000 0111 --11 cccc xxxx xxxx xxxx xxxx : A-48 */ + else if (((w0 & 0xff30) == 0x0730) && ((w1 & 0x0000) == 0x0000)) + { + return global_alloc(Bcc(opc, w0, w1)); + } + /* Bcc : 0010 11cc ccee eeee : A-48 */ + else if ((w0 & 0xfc00) == 0x2c00) + { + return global_alloc(Bcc_2(opc, w0, w1)); + } + /* Bcc : 0000 0111 RR10 cccc : A-48 */ + else if ((w0 & 0xff30) == 0x0720) + { + return global_alloc(Bcc_3(opc, w0, w1)); + } + /* BRA : 0000 0001 0011 11-- xxxx xxxx xxxx xxxx : A-50 */ + else if (((w0 & 0xfffc) == 0x013c) && ((w1 & 0x0000) == 0x0000)) + { + return global_alloc(Bra(opc, w0, w1)); + } + /* BRA : 0000 1011 aaaa aaaa : A-50 */ + else if ((w0 & 0xff00) == 0x0b00) + { + return global_alloc(Bra_2(opc, w0, w1)); + } + /* BRA : 0000 0001 0010 11RR : A-50 */ + else if ((w0 & 0xfffc) == 0x012c) + { + return global_alloc(Bra_3(opc, w0, w1)); + } + /* BRKc : 0000 0001 0001 cccc : A-52 */ + else if ((w0 & 0xfff0) == 0x0110) + { + return global_alloc(Brkcc(opc, w0, w1)); + } + /* BScc : 0000 0111 --01 cccc xxxx xxxx xxxx xxxx : A-54 */ + else if (((w0 & 0xff30) == 0x0710) && ((w1 & 0x0000) == 0x0000)) + { + return global_alloc(Bscc(opc, w0, w1)); + } + /* BScc : 0000 0111 RR00 cccc : A-54 */ + else if ((w0 & 0xff30) == 0x0700) + { + return global_alloc(Bscc_2(opc, w0, w1)); + } + /* BSR : 0000 0001 0011 10-- xxxx xxxx xxxx xxxx : A-56 */ + else if (((w0 & 0xfffc) == 0x0138) && ((w1 & 0x0000) == 0x0000)) + { + return global_alloc(Bsr(opc, w0, w1)); + } + /* BSR : 0000 0001 0010 10RR : A-56 */ + else if ((w0 & 0xfffc) == 0x0128) + { + return global_alloc(Bsr_2(opc, w0, w1)); + } + /* CHKAAU : 0000 0000 0000 0100 : A-58 */ + else if ((w0 & 0xffff) == 0x0004) + { + return global_alloc(Chkaau(opc, w0, w1)); + } + /* DEBUG : 0000 0000 0000 0001 : A-68 */ + else if ((w0 & 0xffff) == 0x0001) + { + return global_alloc(Debug(opc, w0, w1)); + } + /* DEBUGcc : 0000 0000 0101 cccc : A-70 */ + else if ((w0 & 0xfff0) == 0x0050) + { + return global_alloc(Debugcc(opc, w0, w1)); + } + /* DIV : 0001 0101 0--0 F1DD : A-76 */ + else if ((w0 & 0xfff4) == 0x1504) + // NEW // else if ((w0 & 0xff94) == 0x1504) + { + return global_alloc(Div(opc, w0, w1)); + } + /* DMAC : 0001 0101 10s1 FsQQ : A-80 */ + else if ((w0 & 0xffd0) == 0x1590) + { + return global_alloc(Dmac(opc, w0, w1)); + } + /* DO : 0000 0000 110- --RR xxxx xxxx xxxx xxxx : A-82 */ + else if (((w0 & 0xffe0) == 0x00c0) && ((w1 & 0x0000) == 0x0000)) // Wait. Huh? + { + return global_alloc(Do(opc, w0, w1)); + } + /* DO : 0000 1110 iiii iiii xxxx xxxx xxxx xxxx : A-82 */ + else if (((w0 & 0xff00) == 0x0e00) && ((w1 & 0x0000) == 0x0000)) // Wait. Huh? + { + return global_alloc(Do_2(opc, w0, w1)); + } + /* DO : 0000 0100 000D DDDD xxxx xxxx xxxx xxxx : A-82 */ + else if (((w0 & 0xffe0) == 0x0400) && ((w1 & 0x0000) == 0x0000)) // Wait. Huh? + { + return global_alloc(Do_3(opc, w0, w1)); + } + /* DO FOREVER : 0000 0000 0000 0010 xxxx xxxx xxxx xxxx : A-88 */ + else if (((w0 & 0xffff) == 0x0002) && ((w1 & 0x0000) == 0x0000)) // Wait. Huh? + { + return global_alloc(DoForever(opc, w0, w1)); + } + /* ENDDO : 0000 0000 0000 1001 : A-92 */ + else if ((w0 & 0xffff) == 0x0009) + { + return global_alloc(Enddo(opc, w0, w1)); + } + /* EXT : 0001 0101 0101 F010 : A-96 */ + else if ((w0 & 0xfff7) == 0x1552) + { + return global_alloc(Ext(opc, w0, w1)); + } + /* ILLEGAL : 0000 0000 0000 1111 : A-98 */ + else if ((w0 & 0xffff) == 0x000f) + { + return global_alloc(Illegal(opc, w0, w1)); + } + /* IMAC : 0001 0101 1010 FQQQ : A-100 */ + else if ((w0 & 0xfff0) == 0x15a0) + { + return global_alloc(Imac(opc, w0, w1)); + } + /* IMPY : 0001 0101 1000 FQQQ : A-102 */ + else if ((w0 & 0xfff0) == 0x1580) + { + return global_alloc(Impy(opc, w0, w1)); + } + /* Jcc : 0000 0110 --11 cccc xxxx xxxx xxxx xxxx : A-108 */ + else if (((w0 & 0xff30) == 0x0630) && ((w1 & 0x0000) == 0x0000)) + { + return global_alloc(Jcc(opc, w0, w1)); + } + /* Jcc : 0000 0110 RR10 cccc : A-108 */ + else if ((w0 & 0xff30) == 0x0620 ) + { + return global_alloc(Jcc_2(opc, w0, w1)); + } + /* JMP : 0000 0001 0011 01-- xxxx xxxx xxxx xxxx : A-110 */ + else if (((w0 & 0xfffc) == 0x0134) && ((w1 & 0x0000) == 0x0000)) + { + return global_alloc(Jmp(opc, w0, w1)); + } + /* JMP : 0000 0001 0010 01RR : A-110 */ + else if ((w0 & 0xfffc) == 0x0124) + { + return global_alloc(Jmp_2(opc, w0, w1)); + } + /* JScc : 0000 0110 --01 cccc xxxx xxxx xxxx xxxx : A-112 */ + else if (((w0 & 0xff30) == 0x0610) && ((w1 & 0x0000) == 0x0000)) + { + return global_alloc(Jscc(opc, w0, w1)); + } + /* JScc : 0000 0110 RR00 cccc : A-112 */ + else if ((w0 & 0xff30) == 0x0600) + { + return global_alloc(Jscc_2(opc, w0, w1)); + } + /* JSR : 0000 0001 0011 00-- xxxx xxxx xxxx xxxx : A-114 */ + else if (((w0 & 0xfffc) == 0x0130) && ((w1 & 0x0000) == 0x0000)) + { + return global_alloc(Jsr(opc, w0, w1)); + } + /* JSR : 0000 1010 AAAA AAAA : A-114 */ + else if ((w0 & 0xff00) == 0x0a00) + { + return global_alloc(Jsr_2(opc, w0, w1)); + } + /* JSR : 0000 0001 0010 00RR : A-114 */ + else if ((w0 & 0xfffc) == 0x0120) + { + return global_alloc(Jsr_3(opc, w0, w1)); + } + /* LEA : 0000 0001 11TT MMRR : A-116 */ + else if ((w0 & 0xffc0) == 0x01c0) + { + return global_alloc(Lea(opc, w0, w1)); + } + /* LEA : 0000 0001 10NN MMRR : A-116 */ + else if ((w0 & 0xffc0) == 0x0180) + { + return global_alloc(Lea_2(opc, w0, w1)); + } + /* MAC(su,uu) : 0001 0101 1110 FsQQ : A-126 */ + else if ((w0 & 0xfff0) == 0x15e0) + { + return global_alloc(Macsuuu(opc, w0, w1)); + } + /* MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 */ +// NEW // else if (((w0 & 0xff00) == 0x0500) && ((w1 & 0x00ff) == 0x0011)) +// NEW // { +// NEW // return global_alloc(Move_3(opc, w0, w1)); +// NEW // } + /* MOVE(C) : 0011 1WDD DDD0 MMRR : A-144 */ + else if ((w0 & 0xf810) == 0x3800) + { + return global_alloc(Movec(opc, w0, w1)); + } + /* MOVE(C) : 0011 1WDD DDD1 q0RR : A-144 */ + else if ((w0 & 0xf814) == 0x3810) + { + return global_alloc(Movec_2(opc, w0, w1)); + } + /* MOVE(C) : 0011 1WDD DDD1 Z11- : A-144 */ + else if ((w0 & 0xf816) == 0x3816) + { + return global_alloc(Movec_3(opc, w0, w1)); + } + /* MOVE(C) : 0011 1WDD DDD1 t10- xxxx xxxx xxxx xxxx : A-144 */ + else if (((w0 & 0xf816) == 0x3814) && ((w1 & 0x0000) == 0x0000)) + { + return global_alloc(Movec_4(opc, w0, w1)); + } + /* MOVE(C) : 0010 10dd dddD DDDD : A-144 */ + else if ((w0 & 0xfc00) == 0x2800) + { + return global_alloc(Movec_5(opc, w0, w1)); + } + /* MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 */ + else if (((w0 & 0xff00) == 0x0500) && ((w1 & 0xf810) == 0x3800)) + { + return global_alloc(Movec_6(opc, w0, w1)); + } + /* MOVE(I) : 0010 00DD BBBB BBBB : A-150 */ + else if ((w0 & 0xfc00) == 0x2000) + { + return global_alloc(Movei(opc, w0, w1)); + } + /* MOVE(M) : 0000 001W RR0M MHHH : A-152 */ + else if ((w0 & 0xfe20) == 0x0200) + { + return global_alloc(Movem(opc, w0, w1)); + } + /* MOVE(M) : 0000 001W RR11 mmRR : A-152 */ + else if ((w0 & 0xfe30) == 0x0230) + { + return global_alloc(Movem_2(opc, w0, w1)); + } + /* MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 */ + else if (((w0 & 0xff00) == 0x0500) && ((w1 & 0xfe20) == 0x0200)) + { + return global_alloc(Movem_3(opc, w0, w1)); + } + /* MOVE(P) : 0001 100W HH1p pppp : A-156 */ + else if ((w0 & 0xfe20) == 0x1820) + { + return global_alloc(Movep(opc, w0, w1)); + } + /* MOVE(P) : 0000 110W RRmp pppp : A-156 */ + else if ((w0 & 0xfe00) == 0x0c00) + { + return global_alloc(Movep_2(opc, w0, w1)); + } + /* MOVE(S) : 0001 100W HH0a aaaa : A-158 */ + else if ((w0 & 0xfe20) == 0x1800) + { + return global_alloc(Moves(opc, w0, w1)); + } + /* MPY(su,uu) : 0001 0101 1100 FsQQ : A-164 */ + else if ((w0 & 0xfff0) == 0x15c0) + { + return global_alloc(Mpysuuu(opc, w0, w1)); + } + /* NEGC : 0001 0101 0110 F000 : A-168 */ + else if ((w0 & 0xfff7) == 0x1560) + { + return global_alloc(Negc(opc, w0, w1)); + } + /* NOP : 0000 0000 0000 0000 : A-170 */ + else if ((w0 & 0xffff) == 0x0000) + { + return global_alloc(Nop(opc, w0, w1)); + } + /* NORM : 0001 0101 0010 F0RR : A-172 */ + else if ((w0 & 0xfff4) == 0x1520) + { + return global_alloc(Norm(opc, w0, w1)); + } + /* ORI : 0001 1EE1 iiii iiii : A-178 */ + else if ((w0 & 0xf900) == 0x1900) + { + return global_alloc(Ori(opc, w0, w1)); + } + /* REP : 0000 0000 111- --RR : A-180 */ + else if ((w0 & 0xffe0) == 0x00e0) + { + return global_alloc(Rep(opc, w0, w1)); + } + /* REP : 0000 1111 iiii iiii : A-180 */ + else if ((w0 & 0xff00) == 0x0f00) + { + return global_alloc(Rep_2(opc, w0, w1)); + } + /* REP : 0000 0100 001D DDDD : A-180 */ + else if ((w0 & 0xffe0) == 0x0420) + { + return global_alloc(Rep_3(opc, w0, w1)); + } + /* REPcc : 0000 0001 0101 cccc : A-184 */ + else if ((w0 & 0xfff0) == 0x0150) + { + return global_alloc(Repcc(opc, w0, w1)); + } + /* RESET : 0000 0000 0000 1000 : A-186 */ + else if ((w0 & 0xffff) == 0x0008) + { + return global_alloc(Reset(opc, w0, w1)); + } + /* RTI : 0000 0000 0000 0111 : A-194 */ + else if ((w0 & 0xffff) == 0x0007) + { + return global_alloc(Rti(opc, w0, w1)); + } + /* RTS : 0000 0000 0000 0110 : A-196 */ + else if ((w0 & 0xffff) == 0x0006) + { + return global_alloc(Rts(opc, w0, w1)); + } + /* STOP : 0000 0000 0000 1010 : A-200 */ + else if ((w0 & 0xffff) == 0x000a) + { + return global_alloc(Stop(opc, w0, w1)); + } + /* SWAP : 0001 0101 0111 F001 : A-206 */ + else if ((w0 & 0xfff7) == 0x1571) + { + return global_alloc(Swap(opc, w0, w1)); + } + /* SWI : 0000 0000 0000 0101 : A-208 */ + else if ((w0 & 0xffff) == 0x0005) + { + return global_alloc(Swi(opc, w0, w1)); + } + /* Tcc : 0001 00cc ccTT Fh0h : A-210 */ + else if ((w0 & 0xfc02) == 0x1000) + { + return global_alloc(Tcc(opc, w0, w1)); + } + /* TFR(2) : 0001 0101 0000 F00J : A-214 */ + else if ((w0 & 0xfff6) == 0x1500) + { + return global_alloc(Tfr2(opc, w0, w1)); + } + /* TFR(3) : 0010 01mW RRDD FHHH : A-216 */ + else if ((w0 & 0xfc00) == 0x2400) + { + return global_alloc(Tfr3(opc, w0, w1)); + } + /* TST(2) : 0001 0101 0001 -1DD : A-220 */ + else if ((w0 & 0xfffc) == 0x1514) + // NEW // else if ((w0 & 0xfff4) == 0x1514) + { + return global_alloc(Tst2(opc, w0, w1)); + } + /* WAIT : 0000 0000 0000 1011 : A-222 */ + else if ((w0 & 0xffff) == 0x000b) + { + return global_alloc(Wait(opc, w0, w1)); + } + /* ZERO : 0001 0101 0101 F000 : A-224 */ + else if ((w0 & 0xfff7) == 0x1550) + { + return global_alloc(Zero(opc, w0, w1)); + } + /* SHFL : 0001 0101 1101 FQQQ : !!UNDOCUMENTED!! */ + else if ((w0 & 0xfff0) == 0x15d0) + { + return global_alloc(Shfl(opc, w0, w1)); + } + /* SHFR : 0001 0101 1111 FQQQ : !!UNDOCUMENTED!! */ + else if ((w0 & 0xfff0) == 0x15f0) + { + return global_alloc(Shfr(opc, w0, w1)); + } + + return NULL; +} + +} diff --git a/src/emu/cpu/dsp56k/inst.h b/src/emu/cpu/dsp56k/inst.h new file mode 100644 index 00000000000..f20e37532df --- /dev/null +++ b/src/emu/cpu/dsp56k/inst.h @@ -0,0 +1,3702 @@ +#ifndef __DSP56K_INSTRUCTION_H__ +#define __DSP56K_INSTRUCTION_H__ + +#include + +#include "opcode.h" +#include "tables.h" + +// +// An Instruction is the base class all regular ops inherit from. +// +namespace DSP56K +{ + +class Opcode; + +class Instruction +{ +public: + Instruction(const Opcode* oco) : m_valid(false), + m_oco(oco), + m_sizeIncrement(0), + m_opcode(""), + m_source(""), + m_destination("") { } + virtual ~Instruction() {} + + virtual bool decode(const UINT16 word0, const UINT16 word1) = 0; + virtual void disassemble(std::string& retString) const = 0; + virtual void evaluate() = 0; + + virtual size_t size() const = 0; + virtual size_t accumulatorBitsModified() const = 0; // Potentially make this always return ALL (like flags) + virtual size_t flags() const { return 0; } + + static Instruction* decodeInstruction(const Opcode* opc, + const UINT16 word0, + const UINT16 word1, + bool shifted=false); + + const bool valid() const { return m_valid; } + + const std::string& opcode() const { return m_opcode; } + const std::string& source() const { return m_source; } + const std::string& destination() const { return m_destination; } + + size_t sizeIncrement() const { return m_sizeIncrement; } + +protected: + bool m_valid; + const Opcode* m_oco; + size_t m_sizeIncrement; + + // Parameters nearly everyone has + std::string m_opcode; + std::string m_source; + std::string m_destination; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// OPS //////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +// ABS : .... .... 0111 F001 : A-18 //////////////////////////////////////////// +class Abs: public Instruction +{ +public: + Abs(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + m_opcode = "abs"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// ADC : 0001 0101 0000 F01J : A-20 //////////////////////////////////////////// +class Adc: public Instruction +{ +public: + Adc(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_JF_table(BITSn(word0,0x0001), BITSn(word0,0x0008), + m_source, m_destination); + m_opcode = "adc"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// ADD : .... .... 0000 FJJJ : A-22 //////////////////////////////////////////// +class Add: public Instruction +{ +public: + Add(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_JJJF_table(BITSn(word0,0x07), BITSn(word0,0x08), + m_source, m_destination); + m_opcode = "add"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// ??? Odd that i should put the 011m mKKK everywhere ??? TODO +// ADD : 011m mKKK 0rru Fuuu : A-22 //////////////////////////////////////////// +class Add_2: public Instruction +{ +public: + Add_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_arg = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_uuuuF_table(BITSn(word0,0x17), BITSn(word0,0x08), + m_opcode, m_source, m_destination); + // TODO: m_opcode = "add"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_arg; // TODO: get rid of this Add|Sub thing. +}; + +// AND : .... .... 0110 F1JJ : A-24 //////////////////////////////////////////// +class And: public Instruction +{ +public: + And(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_JJF_table(BITSn(word0,0x03),BITSn(word0,0x08), + m_source, m_destination); + m_opcode = "and"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE; } +}; + +// ANDI : 0001 1EE0 iiii iiii : A-26 /////////////////////////////////////////// +class Andi: public Instruction +{ +public: + Andi(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_immediate = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_immediate = BITSn(word0,0x00ff); + decode_EE_table(BITSn(word0,0x0600), m_destination); + + m_opcode = "andi"; + // NEW // sprintf(opcode_str, "and(i)"); + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + sprintf(temp, "#$%x,%s", m_immediate, m_destination.c_str()); + retString = m_opcode + " " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + UINT8 m_immediate; +}; + +// ASL : .... .... 0011 F001 : A-28 //////////////////////////////////////////// +class Asl: public Instruction +{ +public: + Asl(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + m_opcode = "asl"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// ASL4 : 0001 0101 0011 F001 : A-30 /////////////////////////////////////////// +class Asl4: public Instruction +{ +public: + Asl4(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x0008), m_destination); + m_opcode = "asl4"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// ASR : .... .... 0011 F000 : A-32 //////////////////////////////////////////// +class Asr: public Instruction +{ +public: + Asr(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + m_opcode = "asr"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// ASR4 : 0001 0101 0011 F000 : A-34 /////////////////////////////////////////// +class Asr4: public Instruction +{ +public: + Asr4(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x0008), m_destination); + m_opcode = "asr4"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// ASR16 : 0001 0101 0111 F000 : A-36 ////////////////////////////////////////// +class Asr16: public Instruction +{ +public: + Asr16(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x0008), m_destination); + m_opcode = "asr16"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +/* BFCHG : 0001 0100 11Pp pppp BBB1 0010 iiii iiii : A-38 */ +/* BFCHG : 0001 0100 101- --RR BBB1 0010 iiii iiii : A-38 */ +/* BFCHG : 0001 0100 100D DDDD BBB1 0010 iiii iiii : A-38 */ +/* BFCLR : 0001 0100 11Pp pppp BBB0 0100 iiii iiii : A-40 */ +/* BFCLR : 0001 0100 101- --RR BBB0 0100 iiii iiii : A-40 */ +/* BFCLR : 0001 0100 100D DDDD BBB0 0100 iiii iiii : A-40 */ +/* BFSET : 0001 0100 11Pp pppp BBB1 1000 iiii iiii : A-42 */ +/* BFSET : 0001 0100 101- --RR BBB1 1000 iiii iiii : A-42 */ +/* BFSET : 0001 0100 100D DDDD BBB1 1000 iiii iiii : A-42 */ +/* BFTSTH : 0001 0100 01Pp pppp BBB1 0000 iiii iiii : A-44 */ +/* BFTSTH : 0001 0100 001- --RR BBB1 0000 iiii iiii : A-44 */ +/* BFTSTH : 0001 0100 000D DDDD BBB1 0000 iiii iiii : A-44 */ +/* BFTSTL : 0001 0100 01Pp pppp BBB0 0000 iiii iiii : A-46 */ +/* BFTSTL : 0001 0100 001- --RR BBB0 0000 iiii iiii : A-46 */ +/* BFTSTL : 0001 0100 000D DDDD BBB0 0000 iiii iiii : A-46 */ +class BfInstruction: public Instruction +{ +public: + BfInstruction(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + /* Decode the common parts */ + UINT16 iVal = 0x0000; + iVal = BITSn(word1,0x00ff); + + int upperMiddleLower = -1; + upperMiddleLower = decode_BBB_table(BITSn(word1,0xe000)); + + switch(upperMiddleLower) + { + case BBB_UPPER: iVal <<= 8; break; + case BBB_MIDDLE: iVal <<= 4; break; + case BBB_LOWER: iVal <<= 0; break; + + case BBB_INVALID: return false; break; + } + + switch(BITSn(word0,0x00e0)) + { + case 0x6: case 0x7: case 0x2: case 0x3: + assemble_D_from_P_table(BITSn(word0,0x0020), BITSn(word0,0x001f), m_destination); + break; + case 0x5: case 0x1: + INT8 rNum; + char temp[32]; + decode_RR_table(BITSn(word0,0x0003), rNum); + sprintf(temp, "X:(R%d)", rNum); + m_destination = temp; + break; + case 0x4: case 0x0: + decode_DDDDD_table(BITSn(word0,0x001f), m_destination); + break; + } + + if (m_destination == "!!") + return false; + + char temp[32]; + sprintf(temp, "#$%x", iVal); + // NEW // sprintf(temp, "#$%04x", iVal); + m_source = temp; + + switch(BITSn(word1,0x1f00)) + { + case 0x12: m_opcode = "bfchg"; break; + case 0x04: m_opcode = "bfclr"; break; + case 0x18: m_opcode = "bfset"; break; + case 0x10: m_opcode = "bftsth"; break; + case 0x00: m_opcode = "bftstl"; break; + } + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// Bcc : 0000 0111 --11 cccc xxxx xxxx xxxx xxxx : A-48 //////////////////////// +class Bcc: public Instruction +{ +public: + Bcc(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_immediate = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_immediate = (INT16)word1; + + std::string M; + decode_cccc_table(BITSn(word0,0x000f), M); + m_opcode = "b" + M; + // NEW // sprintf(opcode_str, "b.%s", M); + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + sprintf(temp, ">*+$%x", 2 + m_immediate); + // NEW // sprintf(temp, "$%04x (%d)", pc + 2 + (INT16)word1, (INT16)word1); + retString = m_opcode + " " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + INT16 m_immediate; +}; + +// Bcc : 0010 11cc ccee eeee : A-48 //////////////////////////////////////////// +class Bcc_2: public Instruction +{ +public: + Bcc_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_immediate = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + std::string M; + decode_cccc_table(BITSn(word0,0x3c0), M); + m_immediate = get_6_bit_signed_value(BITSn(word0,0x003f)); + m_opcode = "b" + M; + // NEW // sprintf(opcode_str, "b.%s", M); + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + if (m_immediate >= 0) sprintf(temp, "<*+$%x", m_immediate + 1); + else sprintf(temp, "<*-$%x", 1 - m_immediate - 2); + // NEW // sprintf(temp, "$%04x (%d)", pc + 1 + relativeInt, relativeInt); + retString = m_opcode + " " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + INT8 m_immediate; +}; + +// Bcc : 0000 0111 RR10 cccc : A-48 //////////////////////////////////////////// +class Bcc_3: public Instruction +{ +public: + Bcc_3(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + char temp[32]; + decode_RR_table(BITSn(word0,0x00c0), rNum); + sprintf(temp, "R%d", rNum); + m_destination = temp; + + std::string M; + decode_cccc_table(BITSn(word0,0x000f), M); + m_opcode = "b" + M; + // NEW // sprintf(opcode_str, "b.%s", M); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// BRA : 0000 0001 0011 11-- xxxx xxxx xxxx xxxx : A-50 //////////////////////// +class Bra: public Instruction +{ +public: + Bra(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_immediate = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_immediate = (INT16)word1; + + m_opcode = "bra"; + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + sprintf(temp, ">*+$%x", 2 + m_immediate); + // NEW // sprintf(temp, "$%04x (%d)", pc + 2 + word1, (INT16)word1); + retString = m_opcode + " " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + INT16 m_immediate; +}; + +// BRA : 0000 1011 aaaa aaaa : A-50 //////////////////////////////////////////// +class Bra_2: public Instruction +{ +public: + Bra_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_immediate = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_immediate = (INT8)BITSn(word0,0x00ff); + m_opcode = "bra"; + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + if (m_immediate >= 0) sprintf(temp, "<*+$%x", 1 + m_immediate); + else sprintf(temp, "<*-$%x", 1 - m_immediate - 2); + // NEW // sprintf(temp, "$%04x (%d)", pc + 1 + iVal, iVal); + retString = m_opcode + " " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + INT8 m_immediate; +}; + +// BRA : 0000 0001 0010 11RR : A-50 //////////////////////////////////////////// +class Bra_3: public Instruction +{ +public: + Bra_3(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + char temp[32]; + decode_RR_table(BITSn(word0,0x0003), rNum); + sprintf(temp, "R%d", rNum); + m_destination = temp; + + m_opcode = "bra"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// BRKcc : 0000 0001 0001 cccc : A-52 ////////////////////////////////////////// +class Brkcc: public Instruction +{ +public: + Brkcc(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + std::string M; + decode_cccc_table(BITSn(word0,0x000f), M); + m_opcode = "brk" + M; + // NEW // sprintf(opcode_str, "brk.%s", M); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// BScc : 0000 0111 --01 cccc xxxx xxxx xxxx xxxx : A-54 /////////////////////// +class Bscc: public Instruction +{ +public: + Bscc(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_immediate = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_immediate = (INT16)word1; + + std::string M; + decode_cccc_table(BITSn(word0,0x000f), M); + m_opcode = "bs" + M; + // NEW // sprintf(opcode_str, "bs.%s", M); + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + if (m_immediate >= 0) sprintf(temp, ">*+$%x", 2 + m_immediate); + else sprintf(temp, ">*-$%x", 1 - m_immediate - 1 - 2); + //sprintf(temp, ">*+$%x", 2 + m_immediate); + // NEW // sprintf(temp, "$%04x (%d)", pc + 2 + (INT16)word1, (INT16)word1); + retString = m_opcode + " " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + size_t flags() { return DASMFLAG_STEP_OVER; } + +private: + INT16 m_immediate; +}; + +// BScc : 0000 0111 RR00 cccc : A-54 /////////////////////////////////////////// +class Bscc_2: public Instruction +{ +public: + Bscc_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + char temp[32]; + decode_RR_table(BITSn(word0,0x00c0), rNum); + sprintf(temp, "R%d", rNum); + + std::string M; + decode_cccc_table(BITSn(word0,0x000f), M); + m_destination = temp; + + m_opcode = "bs" + M; + // NEW // sprintf(opcode_str, "bs.%s", M); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + size_t flags() { return DASMFLAG_STEP_OVER; } +}; + +// BSR : 0000 0001 0011 10-- xxxx xxxx xxxx xxxx : A-56 //////////////////////// +class Bsr: public Instruction +{ +public: + Bsr(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_immediate = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_immediate = (INT16)word1; + + m_opcode = "bsr"; + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + if (m_immediate >= 0) sprintf(temp, ">*+$%x", 2 + m_immediate); + else sprintf(temp, ">*-$%x", 1 - m_immediate - 1 - 2); + // NEW // sprintf(temp, "$%04x (%d)", pc + 2 + (INT16)word1, (INT16)word1); + retString = m_opcode + " " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + size_t flags() { return DASMFLAG_STEP_OVER; } + +private: + INT16 m_immediate; +}; + +// BSR : 0000 0001 0010 10RR : A-56 //////////////////////////////////////////// +class Bsr_2: public Instruction +{ +public: + Bsr_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + char temp[32]; + decode_RR_table(BITSn(word0,0x0003), rNum); + sprintf(temp, "R%d", rNum); + m_destination = temp; + + m_opcode = "bsr"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + size_t flags() { return DASMFLAG_STEP_OVER; } +}; + +// CHKAAU : 0000 0000 0000 0100 : A-58 ///////////////////////////////////////// +class Chkaau: public Instruction +{ +public: + Chkaau(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_opcode = "chkaau"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// CLR : .... .... 0000 F001 : A-60 //////////////////////////////////////////// +class Clr: public Instruction +{ +public: + Clr(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + m_opcode = "clr"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// CLR24 : .... .... 0101 F001 : A-62 ////////////////////////////////////////// +class Clr24: public Instruction +{ +public: + Clr24(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + m_opcode = "clr24"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE; } +}; + +// CMP : .... .... 0101 FJJJ : A-64 //////////////////////////////////////////// +class Cmp: public Instruction +{ +public: + Cmp(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + /* Note: This is a JJJF limited in the docs, but other opcodes sneak + in before cmp, so the same decode function can be used. */ + decode_JJJF_table(BITSn(word0,0x07), BITSn(word0,0x08), + m_source, m_destination); + m_opcode = "cmp"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_NONE; } +}; + +// CMPM : .... .... 0111 FJJJ : A-66 /////////////////////////////////////////// +class Cmpm: public Instruction +{ +public: + Cmpm(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + /* Note: This is a JJJF limited in the docs, but other opcodes sneak + in before cmp, so the same decode function can be used. */ + decode_JJJF_table(BITSn(word0,0x07), BITSn(word0,0x08), + m_source, m_destination); + m_opcode = "cmpm"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_NONE; } +}; + +// DEBUG : 0000 0000 0000 0001 : A-68 ////////////////////////////////////////// +class Debug: public Instruction +{ +public: + Debug(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_opcode = "debug"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// DEBUGcc : 0000 0000 0101 cccc : A-70 //////////////////////////////////////// +class Debugcc: public Instruction +{ +public: + Debugcc(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + std::string M; + decode_cccc_table(BITSn(word0,0x000f), M); + m_opcode = "debug" + M; + // NEW // sprintf(opcode_str, "debug.%s", M); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// DEC : .... .... 0110 F010 : A-72 //////////////////////////////////////////// +class Dec: public Instruction +{ +public: + Dec(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + m_opcode = "dec"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// DEC24 : .... .... 0110 F011 : A-74 ////////////////////////////////////////// +class Dec24: public Instruction +{ +public: + Dec24(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + m_opcode = "dec24"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE; } +}; + +// DIV : 0001 0101 0--0 F1DD : A-76 //////////////////////////////////////////// +class Div: public Instruction +{ +public: + Div(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_DDF_table(BITSn(word0,0x0003), BITSn(word0,0x0008), + m_source, m_destination); + m_opcode = "div"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// DMAC : 0001 0101 10s1 FsQQ : A-80 /////////////////////////////////////////// +class Dmac: public Instruction +{ +public: + Dmac(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_QQF_special_table(BITSn(word0,0x0003), BITSn(word0,0x0008), + m_source, m_source2, m_destination); + + std::string A; + decode_ss_table(BITSn(word0,0x0024), A); + if (A == "!!") return false; + + m_opcode = "dmac" + A; + // NEW // sprintf(opcode_str, "dmac(%s)", A); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// DO : 0000 0000 110- --RR xxxx xxxx xxxx xxxx : A-82 ///////////////////////// +class Do: public Instruction +{ +public: + Do(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_immediate = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_immediate = word1; + + INT8 rNum; + char temp[32]; + decode_RR_table(BITSn(word0,0x0003), rNum); + sprintf(temp, "X:(R%d)", rNum); + m_source = temp; + + m_opcode = "do"; + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + sprintf(temp, "*+$%x", 2 + m_immediate); + // NEW // sprintf(temp, "X:(R%d),$%02x", Rnum, pc + 2 + word1); + retString = m_opcode + " " + m_source + "," + std::string(temp); + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + UINT16 m_immediate; +}; + +// DO : 0000 1110 iiii iiii xxxx xxxx xxxx xxxx : A-82 ///////////////////////// +class Do_2: public Instruction +{ +public: + Do_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_immediate = 0; + m_displacement = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_immediate = BITSn(word0,0x00ff); + m_displacement = word1; + + m_opcode = "do"; + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + sprintf(temp, "#<$%x,*+$%x", m_immediate, 2 + m_displacement); + // NEW // sprintf(temp, "#$%02x,$%04x", BITSn(word0,0x00ff), pc + 2 + word1); + retString = m_opcode + " " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + UINT8 m_immediate; + UINT16 m_displacement; +}; + +// DO : 0000 0100 000D DDDD xxxx xxxx xxxx xxxx : A-82 ///////////////////////// +class Do_3: public Instruction +{ +public: + Do_3(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_displacement = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_displacement = word1; + + decode_DDDDD_table(BITSn(word0,0x001f), m_source); + if (m_source == "SSH") return false; // NEW // + if (m_source == "!!") return false; // NEW // + m_opcode = "do"; + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + sprintf(temp, "*+$%x", 2 + m_displacement); + // NEW // sprintf(temp, "%s,$%04x", S1, pc + 2 + word1); + retString = m_opcode + " " + m_source + "," + std::string(temp); + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + UINT16 m_displacement; +}; + +// DO FOREVER : 0000 0000 0000 0010 xxxx xxxx xxxx xxxx : A-88 ///////////////// +class DoForever: public Instruction +{ +public: + DoForever(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_displacement = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_displacement = word1; + m_opcode = "do forever"; + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + sprintf(temp, "*+$%x", m_displacement + 2); + // NEW // sprintf(temp, "*+$%x", pc + word1); + // NEW // sprintf(temp, "$%04x", pc + 2 + word1); + retString = m_opcode + ", " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + UINT16 m_displacement; +}; + +// ENDDO : 0000 0000 0000 1001 : A-92 ////////////////////////////////////////// +class Enddo: public Instruction +{ +public: + Enddo(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_opcode = "enddo"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// EOR : .... .... 0011 F1JJ : A-94 //////////////////////////////////////////// +class Eor: public Instruction +{ +public: + Eor(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_JJF_table(BITSn(word0,0x03),BITSn(word0,0x08), + m_source, m_destination); + m_opcode = "eor"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE; } +}; + +// EXT : 0001 0101 0101 F010 : A-96 //////////////////////////////////////////// +class Ext: public Instruction +{ +public: + Ext(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x0008), m_destination); + m_opcode = "ext"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// ILLEGAL : 0000 0000 0000 1111 : A-98 //////////////////////////////////////// +class Illegal: public Instruction +{ +public: + Illegal(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_opcode = "illegal"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// IMAC : 0001 0101 1010 FQQQ : A-100 ////////////////////////////////////////// +class Imac: public Instruction +{ +public: + Imac(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_QQQF_table(BITSn(word0,0x0007), BITSn(word0,0x0008), + m_source, m_source2, m_destination); + m_opcode = "imac"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// IMPY : 0001 0101 1000 FQQQ : A-102 ////////////////////////////////////////// +class Impy: public Instruction +{ +public: + Impy(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_QQQF_table(BITSn(word0,0x0007), BITSn(word0,0x0008), + m_source, m_source2, m_destination); + m_opcode = "impy"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// INC : .... .... 0010 F010 : A-104 /////////////////////////////////////////// +class Inc: public Instruction +{ +public: + Inc(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + m_opcode = "inc"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// INC24 : .... .... 0010 F011 : A-106 ///////////////////////////////////////// +class Inc24: public Instruction +{ +public: + Inc24(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + m_opcode = "inc24"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE; } +}; + +// Jcc : 0000 0110 --11 cccc xxxx xxxx xxxx xxxx : A-108 /////////////////////// +class Jcc: public Instruction +{ +public: + Jcc(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_displacement = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_displacement = word1; + + std::string M; + decode_cccc_table(BITSn(word0,0x000f), M); + m_opcode = "j" + M; + // NEW // sprintf(opcode_str, "j.%s", M); + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + sprintf(temp, ">$%x", m_displacement); + // NEW // sprintf(temp, "$%04x", word1); + retString = m_opcode + " " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + UINT16 m_displacement; +}; + +// Jcc : 0000 0110 RR10 cccc : A-108 /////////////////////////////////////////// +class Jcc_2: public Instruction +{ +public: + Jcc_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + char temp[32]; + decode_RR_table(BITSn(word0,0x00c0), rNum); + sprintf(temp, "R%d", rNum); + m_destination = temp; + + std::string M; + decode_cccc_table(BITSn(word0,0x000f), M); + m_opcode = "j" + M; + // NEW // sprintf(opcode_str, "j.%s", M); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// JMP : 0000 0001 0011 01-- xxxx xxxx xxxx xxxx : A-110 /////////////////////// +class Jmp: public Instruction +{ +public: + Jmp(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_displacement = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_displacement = word1; + + m_opcode = "jmp"; + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + sprintf(temp, ">$%x", m_displacement); + // NEW // sprintf(temp, "$%04x", word1); + retString = m_opcode + " " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + UINT16 m_displacement; +}; + +// JMP : 0000 0001 0010 01RR : A-110 /////////////////////////////////////////// +class Jmp_2: public Instruction +{ +public: + Jmp_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + char temp[32]; + decode_RR_table(BITSn(word0,0x0003), rNum); + sprintf(temp, "R%d", rNum); + m_destination = temp; + + m_opcode = "jmp"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// JScc : 0000 0110 --01 cccc xxxx xxxx xxxx xxxx : A-112 ////////////////////// +class Jscc: public Instruction +{ +public: + Jscc(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_displacement = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_displacement = word1; + + std::string M; + decode_cccc_table(BITSn(word0,0x000f), M); + m_opcode = "js" + M; + // NEW // sprintf(opcode_str, "js.%s", M); + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + sprintf(temp, ">$%x", m_displacement); + // NEW // sprintf(temp, "$%04x", word1); + retString = m_opcode + " " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + size_t flags() { return DASMFLAG_STEP_OVER; } + +private: + UINT16 m_displacement; +}; + +// JScc : 0000 0110 RR00 cccc : A-112 ////////////////////////////////////////// +class Jscc_2: public Instruction +{ +public: + Jscc_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + char temp[32]; + decode_RR_table(BITSn(word0,0x00c0), rNum); + sprintf(temp, "R%d", rNum); + m_destination = temp; + + std::string M; + decode_cccc_table(BITSn(word0,0x000f), M); + m_opcode = "js" + M; + // NEW // sprintf(opcode_str, "js.%s", M); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + size_t flags() { return DASMFLAG_STEP_OVER; } +}; + +// JSR : 0000 0001 0011 00-- xxxx xxxx xxxx xxxx : A-114 /////////////////////// +class Jsr: public Instruction +{ +public: + Jsr(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_displacement = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_displacement = word1; + + m_opcode = "jsr"; + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + sprintf(temp, ">$%x", m_displacement); + // NEW // sprintf(temp, "$%04x", word1); + retString = m_opcode + " " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + size_t flags() { return DASMFLAG_STEP_OVER; } + +private: + UINT16 m_displacement; +}; + +// JSR : 0000 1010 AAAA AAAA : A-114 /////////////////////////////////////////// +class Jsr_2: public Instruction +{ +public: + Jsr_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_bAddr = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_bAddr = BITSn(word0,0x00ff); + + m_opcode = "jsr"; + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + sprintf(temp, "<$%x", m_bAddr); + // NEW // sprintf(temp, "#$%02x", BITSn(word0,0x00ff)); + retString = m_opcode + " " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + size_t flags() { return DASMFLAG_STEP_OVER; } + +private: + UINT8 m_bAddr; +}; + +// JSR : 0000 0001 0010 00RR : A-114 /////////////////////////////////////////// +class Jsr_3: public Instruction +{ +public: + Jsr_3(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + char temp[32]; + decode_RR_table(BITSn(word0,0x0003), rNum); + sprintf(temp, "R%d", rNum); + m_destination = temp; + + m_opcode = "jsr"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + size_t flags() { return DASMFLAG_STEP_OVER; } +}; + +// LEA : 0000 0001 11TT MMRR : A-116 /////////////////////////////////////////// +class Lea: public Instruction +{ +public: + Lea(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + if ((word0 & 0x000c) == 0) return false; // NEW TODO // + + char temp[32]; + + INT8 tNum; + decode_TT_table(BITSn(word0,0x0030), tNum); + sprintf(temp, "R%d", tNum); + m_destination = temp; + + INT8 rNum; + std::string ea; + decode_RR_table(BITSn(word0,0x0003), rNum); + assemble_ea_from_MM_table(BITSn(word0,0x000c), rNum, ea); + m_source = ea; + + m_opcode = "lea"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// LEA : 0000 0001 10NN MMRR : A-116 /////////////////////////////////////////// +class Lea_2: public Instruction +{ +public: + Lea_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + if ((word0 & 0x000c) == 0) return false; // NEW TODO // + + char temp[32]; + + INT8 nNum; + decode_NN_table(BITSn(word0,0x0030), nNum); + sprintf(temp, "N%d", nNum); + m_destination = temp; + + INT8 rNum; + decode_RR_table(BITSn(word0,0x0003), rNum); + + std::string ea; + assemble_ea_from_MM_table(BITSn(word0,0x000c), rNum, ea); + m_source = ea; + + m_opcode = "lea"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// LSL : .... .... 0011 F011 : A-118 /////////////////////////////////////////// +class Lsl: public Instruction +{ +public: + Lsl(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + m_opcode = "lsl"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE; } +}; + +// LSR : .... .... 0011 F010 : A-120 /////////////////////////////////////////// +class Lsr: public Instruction +{ +public: + Lsr(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + m_opcode = "lsr"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE; } +}; + +// MAC : .... .... 1k10 FQQQ : A-122 /////////////////////////////////////////// +class Mac: public Instruction +{ +public: + Mac(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_QQQF_table(BITSn(word0,0x07), BITSn(word0,0x08), + m_source, m_source2, m_destination); + + std::string sign; + decode_kSign_table(BITSn(word0,0x40), sign); + if (sign == "-") + m_source = sign + m_source; // TODO: Probably silly for Instruction + + m_opcode = "mac"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// MAC : 011m mKKK 1xx0 F1QQ : A-122 /////////////////////////////////////////// +class Mac_2: public Instruction +{ +public: + Mac_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_QQF_table(BITSn(word0,0x03), BITSn(word0,0x08), + m_source, m_source2, m_destination); + + m_opcode = "mac"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// MAC : 0001 0111 RRDD FQQQ : A-122 /////////////////////////////////////////// +class Mac_3: public Instruction +{ +public: + Mac_3(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_QQQF_table(BITSn(word0,0x0007), BITSn(word0,0x0008), + m_source, m_source2, m_destination); + m_opcode = "mac"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// MACR : .... .... 1k11 FQQQ : A-124 ////////////////////////////////////////// +class Macr: public Instruction +{ +public: + Macr(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_QQQF_table(BITSn(word0,0x07), BITSn(word0,0x08), + m_source, m_source2, m_destination); + + std::string sign; + decode_kSign_table(BITSn(word0,0x40), sign); + if (sign == "-") + m_source = sign + m_source; // TODO: Probably silly for Instruction + + m_opcode = "macr"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// MACR : 011m mKKK 1--1 F1QQ : A-124 ////////////////////////////////////////// +class Macr_2: public Instruction +{ +public: + Macr_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_QQF_table(BITSn(word0,0x03), BITSn(word0,0x08), + m_source, m_source2, m_destination); + m_opcode = "macr"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// MAC(su,uu) : 0001 0101 1110 FsQQ : A-126 //////////////////////////////////// +class Macsuuu: public Instruction +{ +public: + Macsuuu(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + // Special QQF + decode_QQF_special_table(BITSn(word0,0x0003), BITSn(word0,0x0008), + m_source, m_source2, m_destination); + + std::string A; + decode_s_table(BITSn(word0,0x0004), A); + m_opcode = "mac" + A; + // NEW // sprintf(opcode_str, "mac(%s)", A); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// MOVE : .... .... 0001 0001 : A-128 ////////////////////////////////////////// +class Move: public Instruction +{ +public: + Move(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_isNop = false; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + // Equivalent to a NOP (+ parallel move) + + // This insures the debugger matches the reference disassembler + // for the undocumented .... .... 0001 1001 Instruction. + if(BITSn(word0, 0x000f) == 0x0001) + m_destination = "A"; + else + m_destination = "B"; + + // Hack to match reference disassembler + UINT8 BITSn = (word0 & 0xff00) >> 8; + if (BITSn == 0x4a || BITSn == 0x4b) + m_isNop = true; + + m_opcode = "move"; + return true; + } + void disassemble(std::string& retString) const + { + if (m_isNop) + retString = "nop"; + else + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_NONE; } + +private: + bool m_isNop; +}; + +// MOVE : 011m mKKK 0rr1 0000 : A-128 ////////////////////////////////////////// +class Move_2: public Instruction +{ +public: + Move_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + // Amounts to a nop with two parallel moves. + // This insures the debugger matches the reference disassembler + if((word0 & 0x0008) == 0x0008) + m_destination = "B"; + else + m_destination = "A"; + + m_opcode = "move"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 ////////////////////// +class Move_3: public Instruction +{ +public: + Move_3(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_b = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_b = BITSn(word0,0x00ff); + + std::string SD; + decode_HHH_table(BITSn(word1,0x0e00), SD); + assemble_reg_from_W_table(BITSn(word1,0x0100), 'X', SD, m_b, + m_source, m_destination); + + m_opcode = "move"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + INT8 m_b; +}; + +// MOVE(C) : 0011 1WDD DDD0 MMRR : A-144 /////////////////////////////////////// +class Movec: public Instruction +{ +public: + Movec(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + std::string ea; + decode_RR_table(BITSn(word0,0x0003), rNum); + assemble_ea_from_MM_table(BITSn(word0,0x000c), rNum, ea); + + std::string SD; + decode_DDDDD_table(BITSn(word0,0x03e0), SD); + assemble_arguments_from_W_table(BITSn(word0,0x0400), 'X', SD, ea, + m_source, m_destination); + + if (SD == "!!") return false; + + m_opcode = "move"; + // NEW // sprintf(opcode_str, "move(c)"); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// MOVE(C) : 0011 1WDD DDD1 q0RR : A-144 /////////////////////////////////////// +class Movec_2: public Instruction +{ +public: + Movec_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + std::string ea; + decode_RR_table(BITSn(word0,0x0003), rNum); + assemble_ea_from_q_table(BITSn(word0,0x0008), rNum, ea); + + std::string SD; + decode_DDDDD_table(BITSn(word0,0x03e0), SD); + assemble_arguments_from_W_table(BITSn(word0,0x0400), 'X', SD, ea, + m_source, m_destination); + + if (SD == "!!") return false; + + m_opcode = "move"; + // NEW // sprintf(opcode_str, "move(c)"); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// MOVE(C) : 0011 1WDD DDD1 Z11- : A-144 /////////////////////////////////////// +class Movec_3: public Instruction +{ +public: + Movec_3(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + std::string ea; + decode_Z_table(BITSn(word0,0x0008), ea); + + std::string SD; + decode_DDDDD_table(BITSn(word0,0x03e0), SD); + assemble_arguments_from_W_table(BITSn(word0,0x0400), 'X', SD, ea, + m_source, m_destination); + + if (SD == "!!") return false; + + m_opcode = "move"; + // NEW // sprintf(opcode_str, "move(c)"); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// MOVE(C) : 0011 1WDD DDD1 t10- xxxx xxxx xxxx xxxx : A-144 /////////////////// +class Movec_4: public Instruction +{ +public: + Movec_4(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_args = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + char temp[128]; + std::string SD; + decode_DDDDD_table(BITSn(word0,0x03e0), SD); + if (SD == "!!") return false; + + std::string ea; + assemble_ea_from_t_table(BITSn(word0,0x0008), word1, ea); + + // TODO: Figure out what this means, exactly. + if ((word0 & 0x000c) == 0x000c && (word0 & 0x0400) == 0x0000) + return false; + + if (BITSn(word0,0x0400)) + sprintf(temp, "%s,%s", ea.c_str(), SD.c_str()); + else + sprintf(temp, "%s,%s", SD.c_str(), ea.c_str()); + m_args = temp; // TODO + + m_opcode = "move"; + // NEW // sprintf(opcode_str, "move(c)"); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_args; // TODO + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_args; +}; + +// MOVE(C) : 0010 10dd dddD DDDD : A-144 /////////////////////////////////////// +class Movec_5: public Instruction +{ +public: + Movec_5(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_DDDDD_table(BITSn(word0,0x03e0), m_source); + decode_DDDDD_table(BITSn(word0,0x001f), m_destination); + + if (m_source == "!!" || m_destination == "!!") return false; + if (m_source == "SSH" && m_destination == "SSH") return false; + + m_opcode = "move"; + // NEW // sprintf(opcode_str, "move(c)"); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 /////////////////// +class Movec_6: public Instruction +{ +public: + Movec_6(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_b = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_b = BITSn(word0,0x00ff); + + std::string SD; + decode_DDDDD_table(BITSn(word1,0x03e0), SD); + assemble_reg_from_W_table(BITSn(word1,0x0400), 'X', SD, m_b, + m_source, m_destination); + + m_opcode = "move"; + // NEW // m_opcode = "move(c)"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + INT8 m_b; +}; + +// MOVE(I) : 0010 00DD BBBB BBBB : A-150 /////////////////////////////////////// +class Movei: public Instruction +{ +public: + Movei(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_immediate = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_immediate = (INT8)BITSn(word0,0x00ff); + + decode_DD_table(BITSn(word0,0x0300), m_destination); + + m_opcode = "move"; + // NEW // sprintf(opcode_str, "move(i)"); + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + if (m_immediate >= 0) sprintf(temp, "#<+$%x", m_immediate); + else sprintf(temp, "#<-$%x", 1 - m_immediate - 1); + // NEW // sprintf(temp, "#$%02x,%s", BITSn(word0,0x00ff), D1); + + retString = m_opcode + " " + + std::string(temp) + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + INT8 m_immediate; +}; + +// MOVE(M) : 0000 001W RR0M MHHH : A-152 /////////////////////////////////////// +class Movem: public Instruction +{ +public: + Movem(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + decode_RR_table(BITSn(word0,0x00c0), rNum); + + std::string SD; + std::string ea; + decode_HHH_table(BITSn(word0,0x0007), SD); + assemble_ea_from_MM_table(BITSn(word0,0x0018), rNum, ea); + assemble_arguments_from_W_table(BITSn(word0,0x0100), 'P', SD, ea, + m_source, m_destination); + + m_opcode = "move"; + // NEW // sprintf(opcode_str, "move(m)"); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// MOVE(M) : 0000 001W RR11 mmRR : A-152 /////////////////////////////////////// +class Movem_2: public Instruction +{ +public: + Movem_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + std::string ea; + std::string ea2; + assemble_eas_from_mm_table(BITSn(word0,0x000c), BITSn(word0,0x00c0), BITSn(word0,0x0003), ea, ea2); + if (BITSn(word0,0x0100)) + { + m_source = "X:" + ea; + m_destination = "P:" + ea2; + } + else + { + m_source = "P:" + ea; + m_destination = "X:" + ea2; + } + + m_opcode = "move"; + // NEW // sprintf(opcode_str, "move(m)*"); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 /////////////////// +class Movem_3: public Instruction +{ +public: + Movem_3(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 B; + B = BITSn(word0,0x00ff); + + std::string SD; + decode_HHH_table(BITSn(word1,0x0007), SD); + assemble_reg_from_W_table(BITSn(word1,0x0100), 'P', SD, B, + m_source, m_destination); + + m_opcode = "move"; + // NEW // m_opcode = "move(m)"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 2; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// MOVE(P) : 0001 100W HH1p pppp : A-156 /////////////////////////////////////// +class Movep: public Instruction +{ +public: + Movep(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + std::string SD; + decode_HH_table(BITSn(word0,0x00c0), SD); + + std::string fullAddy; + assemble_address_from_IO_short_address(BITSn(word0,0x001f), fullAddy); + fullAddy = "<<$" + fullAddy; + + assemble_arguments_from_W_table(BITSn(word0,0x0100), 'X', SD, fullAddy, + m_source, m_destination); + + m_opcode = "movep"; + // NEW // sprintf(opcode_str, "move(p)"); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// MOVE(P) : 0000 110W RRmp pppp : A-156 /////////////////////////////////////// +class Movep_2: public Instruction +{ +public: + Movep_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + decode_RR_table(BITSn(word0,0x00c0), rNum); + + std::string ea; + assemble_ea_from_m_table(BITSn(word0,0x0020), rNum, ea); + + std::string fullAddy; /* Convert Short Absolute Address to full 16-bit */ + assemble_address_from_IO_short_address(BITSn(word0,0x001f), fullAddy); + + std::string SD; + SD = "X:<<$" + fullAddy; + // NEW // sprintf(SD, "X:$%s", fullAddy); + + assemble_arguments_from_W_table(BITSn(word0,0x0100), 'X', SD, ea, + m_source, m_destination); + + m_opcode = "movep"; + // NEW // sprintf(opcode_str, "move(p)*"); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// MOVE(S) : 0001 100W HH0a aaaa : A-158 /////////////////////////////////////// +class Moves: public Instruction +{ +public: + Moves(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + std::string SD; + decode_HH_table(BITSn(word0,0x00c0), SD); + + char temp[32]; + std::string A; + sprintf(temp, "<$%x", BITSn(word0,0x001f)); + A = temp; + + assemble_arguments_from_W_table(BITSn(word0,0x0100), 'X', SD, A, + m_source, m_destination); + + m_opcode = "moves"; + // NEW // sprintf(opcode_str, "move(s)"); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// MPY : .... .... 1k00 FQQQ : A-160 /////////////////////////////////////////// +class Mpy: public Instruction +{ +public: + Mpy(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + /* There are inconsistencies with the S1 & S2 operand ordering in the docs, + but since it's a multiply it doesn't matter */ + decode_QQQF_table(BITSn(word0,0x07), BITSn(word0,0x08), + m_source, m_source2, m_destination); + + std::string sign; + decode_kSign_table(BITSn(word0,0x40), sign); + if (sign == "-") + m_source = sign + m_source; // TODO: Probably silly for Instruction + + m_opcode = "mpy"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// MPY : 011m mKKK 1xx0 F0QQ : A-160 /////////////////////////////////////////// +class Mpy_2: public Instruction +{ +public: + Mpy_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_QQF_table(BITSn(word0,0x03), BITSn(word0,0x08), + m_source, m_source2, m_destination); + + m_opcode = "mpy"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// MPY : 0001 0110 RRDD FQQQ : A-160 /////////////////////////////////////////// +class Mpy_3: public Instruction +{ +public: + Mpy_3(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_QQQF_table(BITSn(word0,0x0007), BITSn(word0,0x0008), + m_source, m_source2, m_destination); + + m_opcode = "mpy"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// MPYR : .... .... 1k01 FQQQ : A-162 ////////////////////////////////////////// +class Mpyr: public Instruction +{ +public: + Mpyr(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + /* There are inconsistencies with the S1 & S2 operand ordering in the docs, + but since it's a multiply it doesn't matter */ + decode_QQQF_table(BITSn(word0,0x07), BITSn(word0,0x08), + m_source, m_source2, m_destination); + + std::string sign; + decode_kSign_table(BITSn(word0,0x40), sign); + if (sign == "-") + m_source = sign + m_source; // TODO: Probably silly for Instruction + + m_opcode = "mpyr"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// MPYR : 011m mKKK 1--1 F0QQ : A-162 ////////////////////////////////////////// +class Mpyr_2: public Instruction +{ +public: + Mpyr_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_QQF_table(BITSn(word0,0x03), BITSn(word0,0x08), + m_source, m_source2, m_destination); + + m_opcode = "mpyr"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// MPY(su,uu) : 0001 0101 1100 FsQQ : A-164 //////////////////////////////////// +class Mpysuuu: public Instruction +{ +public: + Mpysuuu(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_QQF_special_table(BITSn(word0,0x0003), BITSn(word0,0x0008), + m_source, m_source2, m_destination); + + std::string A; + decode_s_table(BITSn(word0,0x0004), A); + m_opcode = "mpy" + A; + // NEW // sprintf(opcode_str, "mpy(%s)", A); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// NEG : .... .... 0110 F000 : A-166 /////////////////////////////////////////// +class Neg: public Instruction +{ +public: + Neg(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + + m_opcode = "neg"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// NEGC : 0001 0101 0110 F000 : A-168 ////////////////////////////////////////// +class Negc: public Instruction +{ +public: + Negc(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x0008), m_destination); + m_opcode = "negc"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// NOP : 0000 0000 0000 0000 : A-170 /////////////////////////////////////////// +class Nop: public Instruction +{ +public: + Nop(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_opcode = "nop"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// NORM : 0001 0101 0010 F0RR : A-172 ////////////////////////////////////////// +class Norm: public Instruction +{ +public: + Norm(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x0008), m_destination); + + INT8 rNum; + char temp[32]; + decode_RR_table(BITSn(word0,0x0003), rNum); + sprintf(temp, "R%d", rNum); + m_source = temp; + + m_opcode = "norm"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// NOT : .... .... 0110 F001 : A-174 /////////////////////////////////////////// +class Not: public Instruction +{ +public: + Not(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + + m_opcode = "not"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE; } +}; + +// OR : .... .... 0010 F1JJ : A-176 //////////////////////////////////////////// +class Or: public Instruction +{ +public: + Or(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_JJF_table(BITSn(word0,0x03),BITSn(word0,0x08), + m_source, m_destination); + m_opcode = "or"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE; } +}; + +// ORI : 0001 1EE1 iiii iiii : A-178 /////////////////////////////////////////// +class Ori: public Instruction +{ +public: + Ori(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_immediate = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_immediate = BITSn(word0,0x00ff); + + decode_EE_table(BITSn(word0,0x0600), m_destination); + m_opcode = "ori"; + // NEW // sprintf(opcode_str, "or(i)"); + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + sprintf(temp, "#$%x", m_immediate); + // NEW // sprintf(temp, "#$%02x", BITSn(word0,0x00ff)); + retString = m_opcode + " " + std::string(temp) + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + UINT8 m_immediate; +}; + +// REP : 0000 0000 111- --RR : A-180 /////////////////////////////////////////// +class Rep: public Instruction +{ +public: + Rep(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + char temp[32]; + decode_RR_table(BITSn(word0,0x0003), rNum); + sprintf(temp, "R%d", rNum); + m_source = temp; + + m_opcode = "rep"; + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + sprintf(temp, "X:(%s)", m_source.c_str()); + retString = m_opcode + " " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// REP : 0000 1111 iiii iiii : A-180 /////////////////////////////////////////// +class Rep_2: public Instruction +{ +public: + Rep_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_immediate = 0; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_immediate = BITSn(word0,0x00ff); + m_opcode = "rep"; + return true; + } + void disassemble(std::string& retString) const + { + char temp[32]; + sprintf(temp, "#$%x", m_immediate); + // NEW // sprintf(temp, "#$%02x (%d)", BITSn(word0,0x00ff), BITSn(word0,0x00ff)); + retString = m_opcode + " " + std::string(temp); + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + UINT8 m_immediate; +}; + +// REP : 0000 0100 001D DDDD : A-180 /////////////////////////////////////////// +class Rep_3: public Instruction +{ +public: + Rep_3(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_DDDDD_table(BITSn(word0,0x001f), m_source); + if (m_source == "!!") return false; + + m_opcode = "rep"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// REPcc : 0000 0001 0101 cccc : A-184 ///////////////////////////////////////// +class Repcc: public Instruction +{ +public: + Repcc(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + std::string M; + decode_cccc_table(BITSn(word0,0x000f), M); + m_opcode = "rep" + M; + // NEW // sprintf(opcode_str, "rep.%s", M); + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// RESET : 0000 0000 0000 1000 : A-186 ///////////////////////////////////////// +class Reset: public Instruction +{ +public: + Reset(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_opcode = "reset"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// RND : .... .... 0010 F000 : A-188 /////////////////////////////////////////// +class Rnd: public Instruction +{ +public: + Rnd(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + + m_opcode = "rnd"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// ROL : .... .... 0111 F011 : A-190 /////////////////////////////////////////// +class Rol: public Instruction +{ +public: + Rol(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + + m_opcode = "rol"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE; } +}; + +// ROR : .... .... 0111 F010 : A-192 /////////////////////////////////////////// +class Ror: public Instruction +{ +public: + Ror(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + + m_opcode = "ror"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE; } +}; + +// RTI : 0000 0000 0000 0111 : A-194 /////////////////////////////////////////// +class Rti: public Instruction +{ +public: + Rti(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_opcode = "rti"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + size_t flags() { return DASMFLAG_STEP_OUT; } +}; + +// RTS : 0000 0000 0000 0110 : A-196 /////////////////////////////////////////// +class Rts: public Instruction +{ +public: + Rts(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_opcode = "rts"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + size_t flags() { return DASMFLAG_STEP_OUT; } +}; + +// SBC : .... .... 0101 F01J : A-198 /////////////////////////////////////////// +class Sbc: public Instruction +{ +public: + Sbc(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_JF_table(BITSn(word0,0x01), BITSn(word0,0x08), + m_source, m_destination); + + m_opcode = "sbc"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// STOP : 0000 0000 0000 1010 : A-200 ////////////////////////////////////////// +class Stop: public Instruction +{ +public: + Stop(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_opcode = "stop"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// SUB : .... .... 0100 FJJJ : A-202 /////////////////////////////////////////// +class Sub: public Instruction +{ +public: + Sub(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_JJJF_table(BITSn(word0,0x07), BITSn(word0,0x08), + m_source, m_destination); + m_opcode = "sub"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// SUB : 011m mKKK 0rru Fuuu : A-202 /////////////////////////////////////////// +class Sub_2: public Instruction +{ +public: + Sub_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_uuuuF_table(BITSn(word0,0x17), BITSn(word0,0x08), + m_opcode, m_source, m_destination); + + // TODO // m_opcode = "sub"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// SUBL : .... .... 0100 F001 : A-204 ////////////////////////////////////////// +class Subl: public Instruction +{ +public: + Subl(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + /* There is only one option for the F table. This is a very strange opcode. */ + if (!BITSn(word0,0x0008)) + { + m_source = "B"; + m_destination = "A"; + } + else + { + m_source = "A"; + m_destination = "B"; + } + + m_opcode = "subl"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// SWAP : 0001 0101 0111 F001 : A-206 ////////////////////////////////////////// +class Swap: public Instruction +{ +public: + Swap(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x0008), m_destination); + + m_opcode = "swap"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// SWI : 0000 0000 0000 0101 : A-208 /////////////////////////////////////////// +class Swi: public Instruction +{ +public: + Swi(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_opcode = "swi"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// Tcc : 0001 00cc ccTT Fh0h : A-210 /////////////////////////////////////////// +class Tcc: public Instruction +{ +public: + Tcc(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_destination2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_h0hF_table(BITSn(word0,0x0007),BITSn(word0,0x0008), + m_source, m_destination); + + INT8 rNum; + char temp[32]; + decode_RR_table(BITSn(word0,0x0030), rNum); + sprintf(temp, "R%d", rNum); + m_destination2 = temp; + + std::string M; + decode_cccc_table(BITSn(word0,0x03c0), M); + m_opcode = "t" + M; + // NEW // sprintf(opcode_str, "t.%s", M); + if (m_source != m_destination) + return true; + if (m_destination2 != "R0") + return true; + + return false; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + if (m_source != m_destination) + retString += std::string(" ") + m_source + "," + m_destination; + + if (m_destination2 != "R0") + retString += std::string(" R0,") + m_destination2; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_destination2; +}; + +// TFR : .... .... 0001 FJJJ : A-212 /////////////////////////////////////////// +class Tfr: public Instruction +{ +public: + Tfr(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_JJJF_table(BITSn(word0,0x07), BITSn(word0,0x08), + m_source, m_destination); + + m_opcode = "tfr"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// TFR : 011m mKKK 0rr1 F0DD : A-212 /////////////////////////////////////////// +class Tfr_2: public Instruction +{ +public: + Tfr_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_DDF_table(BITSn(word0,0x03), BITSn(word0,0x08), + m_source, m_destination); + + m_opcode = "tfr"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// TFR(2) : 0001 0101 0000 F00J : A-214 //////////////////////////////////////// +class Tfr2: public Instruction +{ +public: + Tfr2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_JF_table(BITSn(word0,0x0001),BITSn(word0,0x0008), + m_destination, m_source); + + m_opcode = "tfr2"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// TFR(3) : 0010 01mW RRDD FHHH : A-216 //////////////////////////////////////// +class Tfr3: public Instruction +{ +public: + Tfr3(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_destination2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_DDF_table(BITSn(word0,0x0030), BITSn(word0,0x0008), + m_destination, m_source); + + std::string SD; + decode_HHH_table(BITSn(word0,0x0007), SD); + // If the destination of the second move is the same as the first, you're invalid + if (SD == m_destination && BITSn(word0,0x100)) return false; + + INT8 rNum; + decode_RR_table(BITSn(word0,0x00c0), rNum); + + std::string ea; + assemble_ea_from_m_table(BITSn(word0,0x0200), rNum, ea); + + assemble_arguments_from_W_table(BITSn(word0,0x0100), 'X', SD, ea, + m_source2, m_destination2); + + m_opcode = "tfr3"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_destination + " " + + m_source2 + "," + m_destination2; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; + std::string m_destination2; +}; + +// TST : .... .... 0010 F001 : A-218 /////////////////////////////////////////// +class Tst: public Instruction +{ +public: + Tst(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x08), m_destination); + + m_opcode = "tst"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_NONE; } +}; + +// TST(2) : 0001 0101 0001 -1DD : A-220 //////////////////////////////////////// +class Tst2: public Instruction +{ +public: + Tst2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_DD_table(BITSn(word0,0x0003), m_source); + + m_opcode = "tst2"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_source; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// WAIT : 0000 0000 0000 1011 : A-222 ////////////////////////////////////////// +class Wait: public Instruction +{ +public: + Wait(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + m_opcode = "wait"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// ZERO : 0001 0101 0101 F000 : A-224 ////////////////////////////////////////// +class Zero: public Instruction +{ +public: + Zero(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_F_table(BITSn(word0,0x0008), m_destination); + + m_opcode = "zero"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } +}; + +// SHFL : 0001 0101 1101 FQQQ : !!UNDOCUMENTED!! /////////////////////////////// +class Shfl: public Instruction +{ +public: + Shfl(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_QQQF_table(BITSn(word0,0x0007), BITSn(word0,0x0008), + m_source, m_source2, m_destination); + + // This hackery amounts to a very strange QQQF table... + if (m_source == "X0" && m_source2 == "X0") return false; + if (m_source == "X1" && m_source2 == "X0") return false; + + if (m_source == "Y0" && m_source2 == "X1") + { + m_source = "X1"; + m_source2 = "Y0"; + } + if (m_source == "Y1" && m_source2 == "X1") + { + m_source = "X1"; + m_source2 = "Y1"; + } + + m_opcode = "shfl"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +// SHFR : 0001 0101 1111 FQQQ : !!UNDOCUMENTED!! /////////////////////////////// +class Shfr: public Instruction +{ +public: + Shfr(const Opcode* oco, const UINT16 word0, const UINT16 word1) : Instruction(oco) + { + m_source2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_QQQF_table(BITSn(word0,0x0007), BITSn(word0,0x0008), + m_source, m_source2, m_destination); + + // This hackery amounts to a very strange QQQF table... + if (m_source == "X0" && m_source2 == "X0") return false; + if (m_source == "X1" && m_source2 == "X0") return false; + + if (m_source == "Y0" && m_source2 == "X1") + { + m_source = "X1"; + m_source2 = "Y0"; + } + if (m_source == "Y1" && m_source2 == "X1") + { + m_source = "X1"; + m_source2 = "Y1"; + } + + m_opcode = "shfr"; + return true; + } + void disassemble(std::string& retString) const + { + retString = m_opcode + " " + + m_source + "," + + m_source2 + "," + m_destination; + } + void evaluate() {} + size_t size() const { return 1; } + size_t accumulatorBitsModified() const { return BM_HIGH | BM_MIDDLE | BM_LOW; } + +private: + std::string m_source2; +}; + +} +#endif diff --git a/src/emu/cpu/dsp56k/opcode.c b/src/emu/cpu/dsp56k/opcode.c new file mode 100644 index 00000000000..398673becb5 --- /dev/null +++ b/src/emu/cpu/dsp56k/opcode.c @@ -0,0 +1,71 @@ +#include + +#include "opcode.h" + +namespace DSP56K +{ + +Opcode::Opcode(UINT16 w0, UINT16 w1) : m_word0(w0), m_word1(w1) +{ + m_instruction = Instruction::decodeInstruction(this, w0, w1); + m_parallelMove = ParallelMove::decodeParallelMove(this, w0, w1); +} + + +Opcode::~Opcode() +{ + global_free(m_instruction); + global_free(m_parallelMove); +} + + +std::string Opcode::disassemble() const +{ + // Duck out early if there isn't a valid op + if (!m_instruction) + return dcString(); + + // Duck out if either has had an explicit error. + if (m_instruction && !m_instruction->valid()) + return dcString(); + if (m_parallelMove && !m_parallelMove->valid()) + return dcString(); + + // Disassemble what you can. + std::string opString = ""; + std::string pmString = ""; + if (m_instruction) m_instruction->disassemble(opString); + if (m_parallelMove) m_parallelMove->disassemble(pmString); + + return opString + " " + pmString; +} + + +void Opcode::evaluate() const +{ + if (m_instruction) m_instruction->evaluate(); + if (m_parallelMove) m_parallelMove->evaluate(); +} + + +size_t Opcode::size() const +{ + if (m_instruction && m_instruction->valid()) + return m_instruction->size() + m_instruction->sizeIncrement(); + + // Opcode failed to decode, so push it past dc + return 1; +} + +const std::string& Opcode::instSource() const { return m_instruction->source(); } +const std::string& Opcode::instDestination() const { return m_instruction->destination(); } +const size_t Opcode::instAccumulatorBitsModified() const { return m_instruction->accumulatorBitsModified(); } + +std::string Opcode::dcString() const +{ + char tempStr[1024]; + sprintf(tempStr, "dc $%x", m_word0); + return std::string(tempStr); +} + +} diff --git a/src/emu/cpu/dsp56k/opcode.h b/src/emu/cpu/dsp56k/opcode.h new file mode 100644 index 00000000000..a5feaf4f45f --- /dev/null +++ b/src/emu/cpu/dsp56k/opcode.h @@ -0,0 +1,45 @@ +#ifndef __DSP56K_OPCODE_H__ +#define __DSP56K_OPCODE_H__ + +#include + +#include "emu.h" +#include "inst.h" +#include "pmove.h" + +// +// An Opcode contains an instruction and a parallel move operation. +// +namespace DSP56K +{ + +class Instruction; +class ParallelMove; + +class Opcode +{ +public: + Opcode(UINT16 w0, UINT16 w1); + virtual ~Opcode(); + + std::string disassemble() const; + void evaluate() const; + size_t size() const; + + // Peek through to the instruction + const std::string& instSource() const; + const std::string& instDestination() const; + const size_t instAccumulatorBitsModified() const; + +private: + Instruction* m_instruction; + ParallelMove* m_parallelMove; + + UINT16 m_word0; + UINT16 m_word1; + + std::string dcString() const; +}; + +} +#endif diff --git a/src/emu/cpu/dsp56k/pmove.c b/src/emu/cpu/dsp56k/pmove.c new file mode 100644 index 00000000000..05af4a33e73 --- /dev/null +++ b/src/emu/cpu/dsp56k/pmove.c @@ -0,0 +1,78 @@ +#include "pmove.h" + +namespace DSP56K +{ + +const std::string& ParallelMove::opSource() const { return m_oco->instSource(); } +const std::string& ParallelMove::opDestination() const { return m_oco->instDestination(); } +const size_t ParallelMove::opAccumulatorBitsModified() const { return m_oco->instAccumulatorBitsModified(); } + + +ParallelMove* ParallelMove::decodeParallelMove(const Opcode* opc, const UINT16 word0, const UINT16 word1) +{ + const UINT16 w0 = word0; + const UINT16 w1 = word1; + + /* Dual X Memory Data Read : 011m mKKK .rr. .... : A-142*/ + if ((w0 & 0xe000) == 0x6000) + { + return global_alloc(DualXMemoryDataRead(opc, w0, w1)); + } + /* X Memory Data Write and Register Data Move : 0001 011k RRDD .... : A-140 */ + else if ((w0 & 0xfe00) == 0x1600) + { + return global_alloc(XMemoryDataWriteAndRegisterDataMove(opc, w0, w1)); + } + else + { + /* 32 General parallel move operations */ + /* Note: It's important that NPDM comes before RtRDM */ + + /* No Parallel Data Move : 0100 1010 .... .... : A-131 */ + if ((w0 & 0xff00) == 0x4a00) + { + return NULL; + } + /* Register to Register Data Move : 0100 IIII .... .... : A-133 */ + else if ((w0 & 0xf000) == 0x4000) + { + return global_alloc(RegisterToRegisterDataMove(opc, w0, w1)); + } + /* Address Register Update : 0011 0zRR .... .... : A-135 */ + else if ((w0 & 0xf800) == 0x3000) + { + return global_alloc(AddressRegisterUpdate(opc, w0, w1)); + } + /* X Memory Data Move : 1mRR HHHW .... .... : A-137 */ + else if ((w0 & 0x8000) == 0x8000) + { + return global_alloc(XMemoryDataMove(opc, w0, w1)); + } + /* X Memory Data Move : 0101 HHHW .... .... : A-137 */ + else if ((w0 & 0xf000) == 0x5000) + { + return global_alloc(XMemoryDataMove_2(opc, w0, w1)); + } + /* X Memory Data Move with short displacement : 0000 0101 BBBB BBBB ---- HHHW .... .... : A-139 */ + else if ((w0 & 0xff00) == 0x0500) + { + // Now check it against all potential double-ups. + // These operations can't have an additional parallel move. + // + // MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 + // MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 + // MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 + // + if (((w1 & 0xfe20) != 0x0200) && + ((w1 & 0xf810) != 0x3800) && + ((w1 & 0x00ff) != 0x0011)) + { + return global_alloc(XMemoryDataMoveWithShortDisplacement(opc, w0, w1)); + } + } + } + + return NULL; +} + +} diff --git a/src/emu/cpu/dsp56k/pmove.h b/src/emu/cpu/dsp56k/pmove.h new file mode 100644 index 00000000000..1a3d83c8133 --- /dev/null +++ b/src/emu/cpu/dsp56k/pmove.h @@ -0,0 +1,339 @@ +#ifndef __DSP56K_PARALLEL_MOVE_H__ +#define __DSP56K_PARALLEL_MOVE_H__ + +#include + +#include "emu.h" +#include "opcode.h" +#include "tables.h" + +// +// A ParallelMove Object is what all parallel move classes inherit from. +// +namespace DSP56K +{ + +class Opcode; + +class ParallelMove +{ +public: + ParallelMove(const Opcode* oco) : m_valid(false), m_oco(oco) { } + virtual ~ParallelMove() {} + + virtual bool decode(const UINT16 word0, const UINT16 word1) = 0; + virtual void disassemble(std::string& retString) const = 0; + virtual void evaluate() = 0; + + static ParallelMove* decodeParallelMove(const Opcode* opc, const UINT16 word0, const UINT16 word1); + + const bool valid() const { return m_valid; } + + // Peek through the opcode to see the instruction + const std::string& opSource() const; + const std::string& opDestination() const; + const size_t opAccumulatorBitsModified() const; + +protected: + bool m_valid; + const Opcode* m_oco; +}; + + +//////////////////////////////////////////////////////////////////////////////// +// PARALLEL MOVES //////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +/* X Memory Data Move : 1mRR HHHW .... .... : A-137 */ +class XMemoryDataMove: public ParallelMove +{ +public: + XMemoryDataMove(const Opcode* oco, const UINT16 word0, const UINT16 word1) : ParallelMove(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + decode_RR_table(BITSn(word0,0x3000), rNum); + + std::string SD; + decode_HHH_table(BITSn(word0,0x0e00), SD); + + std::string ea; + assemble_ea_from_m_table(BITSn(word0,0x4000), rNum, ea); + + assemble_arguments_from_W_table(BITSn(word0,0x0100), 'X', SD, ea, + m_source, m_destination); + + // If the destination of the instruction overlaps with our destination, abort. + if (registerOverlap(opDestination(), opAccumulatorBitsModified(), m_destination)) + return false; + + return true; + } + void disassemble(std::string& retString) const + { + retString = m_source + "," + m_destination; + } + void evaluate() {} + +private: + std::string m_source; + std::string m_destination; +}; + + +/* X Memory Data Move : 0101 HHHW .... .... : A-137 */ +class XMemoryDataMove_2: public ParallelMove +{ +public: + XMemoryDataMove_2(const Opcode* oco, const UINT16 word0, const UINT16 word1) : ParallelMove(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + std::string ea; + if (opDestination() == "B") + ea = "(A1)"; + else if (opDestination() == "A") + ea = "(B1)"; + else + ea = "(A1)"; + + std::string SD; + decode_HHH_table(BITSn(word0,0x0e00), SD); + + assemble_arguments_from_W_table(BITSn(word0,0x0100), 'X', SD, ea, + m_source, m_destination); + + // If the destination of the instruction overlaps with our destination, abort. + if (registerOverlap(opDestination(), opAccumulatorBitsModified(), m_destination)) + return false; + + return true; + } + void disassemble(std::string& retString) const + { + retString = m_source + "," + m_destination; + } + void evaluate() {} + +private: + std::string m_source; + std::string m_destination; +}; + + +/* Dual X Memory Data Read : 011m mKKK .rr. .... : A-142*/ +class DualXMemoryDataRead: public ParallelMove +{ +public: + DualXMemoryDataRead(const Opcode* oco, const UINT16 word0, const UINT16 word1) : ParallelMove(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + std::string D1 = ""; + std::string D2 = ""; + std::string ea1 = ""; + std::string ea2 = ""; + + decode_rr_table(BITSn(word0,0x0060), rNum); + decode_KKK_table(BITSn(word0,0x0700), D1, D2); + assemble_eas_from_mm_table(BITSn(word0,0x1800), rNum, 3, ea1, ea2); + + /* Not documented, but extrapolated from docs on page A-133 */ + if (D1 == "^F") + { + if (opDestination() == "B") + D1 = "A"; + else if (opDestination() == "A") + D1 = "B"; + else + D1 = "A"; /* In the case of no data ALU instruction */ + } + + /* D1 and D2 may not specify the same register : A-142 */ + if (rNum == 3) return false; + + char temp[32]; + sprintf(temp, "X:%s,%s", ea1.c_str(), D1.c_str()); + parallelMove = temp; + sprintf(temp, "X:%s,%s", ea2.c_str(), D2.c_str()); + parallelMove2 = temp; + + return true; + } + void disassemble(std::string& retString) const + { + retString = parallelMove + " " + parallelMove2; + } + void evaluate() {} + +private: + std::string parallelMove; + std::string parallelMove2; +}; + + +/* Register to Register Data Move : 0100 IIII .... .... : A-133 */ +class RegisterToRegisterDataMove: public ParallelMove +{ +public: + RegisterToRegisterDataMove(const Opcode* oco, const UINT16 word0, const UINT16 word1) : ParallelMove(oco) + { + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + decode_IIIIx_table(BITSn(word0,0x0f00), BITSn(word0,0x0008), + m_source, m_destination); + + if (m_source == "!") + return false; + + if (m_source == "F") + m_source = opDestination(); + + if (m_destination == "^F") + { + if (opDestination() == "B") + m_destination = "A"; + else if (opDestination() == "A") + m_destination = "B"; + else + m_destination = "A"; /* In the case of no data ALU instruction */ + } + + // Don't return a failure, just let everything fall through (nop). + //if (m_source == "?" && m_destination == "?") + // return false; + + return true; + } + void disassemble(std::string& retString) const + { + // (?,?) is a parallel nop + if (m_source == "?" && m_destination == "?") + retString = ""; + else + retString = m_source + "," + m_destination; + } + void evaluate() {} + +private: + std::string m_source; + std::string m_destination; +}; + + +/* X Memory Data Write and Register Data Move : 0001 011k RRDD .... : A-140 */ +class XMemoryDataWriteAndRegisterDataMove: public ParallelMove +{ +public: + XMemoryDataWriteAndRegisterDataMove(const Opcode* oco, const UINT16 word0, const UINT16 word1) : ParallelMove(oco) + { + pms = ""; + pms2 = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + std::string S; + std::string Dnot; + char parallel_move_str[128]; + char parallel_move_str2[128]; + + if (opDestination() == "A") Dnot = "B"; + else Dnot = "A"; + + // NEW // decode_k_table(BITSn(word0,0x0100), Dnot); + decode_RR_table(BITSn(word0,0x00c0), rNum); + decode_DD_table(BITSn(word0,0x0030), S); + + sprintf(parallel_move_str, "%s,X:(R%d)+N%d", Dnot.c_str(), rNum, rNum); + sprintf(parallel_move_str2, "%s,%s", S.c_str(), Dnot.c_str()); + pms = parallel_move_str; + pms2 = parallel_move_str2; + return true; + } + void disassemble(std::string& retString) const + { + retString = pms + " " + pms2; + } + void evaluate() {} + +private: + std::string pms; // TODO + std::string pms2; +}; + + +/* Address Register Update : 0011 0zRR .... .... : A-135 */ +class AddressRegisterUpdate: public ParallelMove +{ +public: + AddressRegisterUpdate(const Opcode* oco, const UINT16 word0, const UINT16 word1) : ParallelMove(oco) + { + m_ea = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 rNum; + decode_RR_table(BITSn(word0,0x0300), rNum); + assemble_ea_from_z_table(BITSn(word0,0x0400), rNum, m_ea); + + return true; + } + void disassemble(std::string& retString) const + { + retString = m_ea; + } + void evaluate() {} + +private: + std::string m_ea; +}; + + +/* X Memory Data Move with short displacement : 0000 0101 BBBB BBBB ---- HHHW .... .... : A-139 */ +class XMemoryDataMoveWithShortDisplacement: public ParallelMove +{ +public: + XMemoryDataMoveWithShortDisplacement(const Opcode* oco, const UINT16 word0, const UINT16 word1) : ParallelMove(oco) + { + m_source = ""; + m_destination = ""; + m_valid = decode(word0, word1); + } + bool decode(const UINT16 word0, const UINT16 word1) + { + INT8 B; + std::string SD; + std::string args; + + B = (char)(word0 & 0x00ff); + decode_HHH_table(BITSn(word1,0x0e00), SD); + assemble_reg_from_W_table(BITSn(word1,0x0100), 'X', SD, B, m_source, m_destination); + + return true; + } + void disassemble(std::string& retString) const + { + retString = m_source + "," + m_destination; + } + void evaluate() {} + +private: + std::string m_source; + std::string m_destination; +}; + +} +#endif diff --git a/src/emu/cpu/dsp56k/tables.c b/src/emu/cpu/dsp56k/tables.c new file mode 100644 index 00000000000..5da910323ac --- /dev/null +++ b/src/emu/cpu/dsp56k/tables.c @@ -0,0 +1,661 @@ +#include +#include +#include +#include + +#include "tables.h" + +namespace DSP56K +{ + +/******************/ +/* Table decoding */ +/******************/ +int decode_BBB_table(UINT16 BBB) +{ + switch(BBB) + { + case 0x4: return BBB_UPPER; + case 0x2: return BBB_MIDDLE; + case 0x1: return BBB_LOWER; + } + + return BBB_INVALID; +} + +void decode_cccc_table(const UINT16 cccc, std::string& mnemonic) +{ + switch (cccc) + { + case 0x0: mnemonic = "cc"; break; + case 0x1: mnemonic = "ge"; break; + case 0x2: mnemonic = "ne"; break; + case 0x3: mnemonic = "pl"; break; + case 0x4: mnemonic = "nn"; break; + case 0x5: mnemonic = "ec"; break; + case 0x6: mnemonic = "lc"; break; + case 0x7: mnemonic = "gt"; break; + case 0x8: mnemonic = "cs"; break; + case 0x9: mnemonic = "lt"; break; + case 0xa: mnemonic = "eq"; break; + case 0xb: mnemonic = "mi"; break; + case 0xc: mnemonic = "nr"; break; + case 0xd: mnemonic = "es"; break; + case 0xe: mnemonic = "ls"; break; + case 0xf: mnemonic = "le"; break; + } + +// NEW // switch (cccc) +// NEW // { +// NEW // case 0x0: sprintf(mnemonic, "cc(hs)"); break; +// NEW // case 0x1: sprintf(mnemonic, "ge "); break; +// NEW // case 0x2: sprintf(mnemonic, "ne "); break; +// NEW // case 0x3: sprintf(mnemonic, "pl "); break; +// NEW // case 0x4: sprintf(mnemonic, "nn "); break; +// NEW // case 0x5: sprintf(mnemonic, "ec "); break; +// NEW // case 0x6: sprintf(mnemonic, "lc "); break; +// NEW // case 0x7: sprintf(mnemonic, "gt "); break; +// NEW // case 0x8: sprintf(mnemonic, "cs(lo)"); break; +// NEW // case 0x9: sprintf(mnemonic, "lt "); break; +// NEW // case 0xa: sprintf(mnemonic, "eq "); break; +// NEW // case 0xb: sprintf(mnemonic, "mi "); break; +// NEW // case 0xc: sprintf(mnemonic, "nr "); break; +// NEW // case 0xd: sprintf(mnemonic, "es "); break; +// NEW // case 0xe: sprintf(mnemonic, "ls "); break; +// NEW // case 0xf: sprintf(mnemonic, "le "); break; +// NEW // } +} + +void decode_DDDDD_table(const UINT16 DDDDD, std::string& SD) +{ + switch(DDDDD) + { + case 0x00: SD = "X0"; break; + case 0x01: SD = "Y0"; break; + case 0x02: SD = "X1"; break; + case 0x03: SD = "Y1"; break; + case 0x04: SD = "A"; break; + case 0x05: SD = "B"; break; + case 0x06: SD = "A0"; break; + case 0x07: SD = "B0"; break; + case 0x08: SD = "LC"; break; + case 0x09: SD = "SR"; break; + case 0x0a: SD = "OMR"; break; + case 0x0b: SD = "SP"; break; + case 0x0c: SD = "A1"; break; + case 0x0d: SD = "B1"; break; + case 0x0e: SD = "A2"; break; + case 0x0f: SD = "B2"; break; + + case 0x10: SD = "R0"; break; + case 0x11: SD = "R1"; break; + case 0x12: SD = "R2"; break; + case 0x13: SD = "R3"; break; + case 0x14: SD = "M0"; break; + case 0x15: SD = "M1"; break; + case 0x16: SD = "M2"; break; + case 0x17: SD = "M3"; break; + case 0x18: SD = "SSH"; break; + case 0x19: SD = "SSL"; break; + case 0x1a: SD = "LA"; break; + case 0x1b: SD = "!!"; break; /* no 0x1b */ + case 0x1c: SD = "N0"; break; + case 0x1d: SD = "N1"; break; + case 0x1e: SD = "N2"; break; + case 0x1f: SD = "N3"; break; + } +} + +void decode_DD_table(const UINT16 DD, std::string& SD) +{ + switch (DD) + { + case 0x0: SD = "X0"; break; + case 0x1: SD = "Y0"; break; + case 0x2: SD = "X1"; break; + case 0x3: SD = "Y1"; break; + } +} + +void decode_DDF_table(const UINT16 DD, const UINT16 F, std::string& S, std::string& D) +{ + const UINT16 switchVal = (DD << 1) | F; + + switch (switchVal) + { + case 0x0: S = "X0"; D = "A"; break; + case 0x1: S = "X0"; D = "B"; break; + case 0x2: S = "Y0"; D = "A"; break; + case 0x3: S = "Y0"; D = "B"; break; + case 0x4: S = "X1"; D = "A"; break; + case 0x5: S = "X1"; D = "B"; break; + case 0x6: S = "Y1"; D = "A"; break; + case 0x7: S = "Y1"; D = "B"; break; + } +} + +void decode_EE_table(const UINT16 EE, std::string& D) +{ + switch(EE) + { + case 0x1: D = "MR"; break; + case 0x3: D = "CCR"; break; + case 0x2: D = "OMR"; break; + } +} + +void decode_F_table(const UINT16 F, std::string& SD) +{ + switch(F) + { + case 0x0: SD = "A"; break; + case 0x1: SD = "B"; break; + } +} + +void decode_h0hF_table(const UINT16 h0h, UINT16 F, std::string& S, std::string& D) +{ + const UINT16 switchVal = (h0h << 1) | F; + + switch (switchVal) + { + case 0x8: S = "X0"; D = "A"; break; + case 0x9: S = "X0"; D = "B"; break; + case 0xa: S = "Y0"; D = "A"; break; + case 0xb: S = "Y0"; D = "B"; break; + case 0x2: S = "A"; D = "A"; break; + case 0x1: S = "A"; D = "B"; break; + case 0x0: S = "B"; D = "A"; break; + case 0x3: S = "B"; D = "B"; break; + } +} + +void decode_HH_table(const UINT16 HH, std::string& SD) +{ + switch(HH) + { + case 0x0: SD = "X0"; break; + case 0x1: SD = "Y0"; break; + case 0x2: SD = "A"; break; + case 0x3: SD = "B"; break; + } +} + +void decode_HHH_table(const UINT16 HHH, std::string& SD) +{ + switch(HHH) + { + case 0x0: SD = "X0"; break; + case 0x1: SD = "Y0"; break; + case 0x2: SD = "X1"; break; + case 0x3: SD = "Y1"; break; + case 0x4: SD = "A"; break; + case 0x5: SD = "B"; break; + case 0x6: SD = "A0"; break; + case 0x7: SD = "B0"; break; + } +} + +void decode_IIIIx_table(const UINT16 IIII, const UINT16 x, std::string& S, std::string& D) +{ + S = D = "!"; + switch(IIII) + { + case 0x0: S = "X0"; D = "^F"; break; + case 0x1: S = "Y0"; D = "^F"; break; + case 0x2: S = "X1"; D = "^F"; break; + case 0x3: S = "Y1"; D = "^F"; break; + case 0x4: S = "A"; D = "X0"; break; + case 0x5: S = "B"; D = "Y0"; break; + case 0x6: S = "A0"; D = "X0"; break; + case 0x7: S = "B0"; D = "Y0"; break; + case 0x8: if ( x) S = "F"; D = "^F"; break; + case 0x9: if (!x) S = "F"; D = "^F"; break; + case 0xa: S = "?"; D = "?"; break; + case 0xb: S = "?"; D = "?"; break; + case 0xc: S = "A"; D = "X1"; break; + case 0xd: S = "B"; D = "Y1"; break; + case 0xe: S = "A0"; D = "X1"; break; + case 0xf: S = "B0"; D = "Y1"; break; + } +} + +void decode_JJJF_table(const UINT16 JJJ, const UINT16 F, std::string& S, std::string& D) +{ + const UINT16 switchVal = (JJJ << 1) | F; + + switch(switchVal) + { + case 0x0: S = "B"; D = "A"; break; + case 0x1: S = "A"; D = "B"; break; + case 0x2: S = "!"; D = "!"; break; + case 0x3: S = "!"; D = "!"; break; + case 0x4: S = "X"; D = "A"; break; + case 0x5: S = "X"; D = "B"; break; + case 0x6: S = "Y"; D = "A"; break; + case 0x7: S = "Y"; D = "B"; break; + case 0x8: S = "X0"; D = "A"; break; + case 0x9: S = "X0"; D = "B"; break; + case 0xa: S = "Y0"; D = "A"; break; + case 0xb: S = "Y0"; D = "B"; break; + case 0xc: S = "X1"; D = "A"; break; + case 0xd: S = "X1"; D = "B"; break; + case 0xe: S = "Y1"; D = "A"; break; + case 0xf: S = "Y1"; D = "B"; break; + } +} + +void decode_JJF_table(const UINT16 JJ, const UINT16 F, std::string& S, std::string& D) +{ + const UINT16 switchVal = (JJ << 1) | F; + + switch (switchVal) + { + case 0x0: S = "X0"; D = "A"; break; + case 0x1: S = "X0"; D = "B"; break; + case 0x2: S = "Y0"; D = "A"; break; + case 0x3: S = "Y0"; D = "B"; break; + case 0x4: S = "X1"; D = "A"; break; + case 0x5: S = "X1"; D = "B"; break; + case 0x6: S = "Y1"; D = "A"; break; + case 0x7: S = "Y1"; D = "B"; break; + } +} + +void decode_JF_table(const UINT16 J, const UINT16 F, std::string& S, std::string& D) +{ + const UINT16 switchVal = (J << 1) | F; + + switch(switchVal) + { + case 0x0: S = "X"; D = "A"; break; + case 0x1: S = "X"; D = "B"; break; + case 0x2: S = "Y"; D = "A"; break; + case 0x3: S = "Y"; D = "B"; break; + } +} + +// NEW // void decode_k_table(UINT16 k, char *Dnot) +// NEW // { +// NEW // switch(k) +// NEW // { +// NEW // case 0x0: sprintf(Dnot, "B"); break; +// NEW // case 0x1: sprintf(Dnot, "A"); break; +// NEW // } +// NEW // } + +void decode_kSign_table(const UINT16 k, std::string& plusMinus) +{ + switch(k) + { + case 0x0: plusMinus = "+"; break; + case 0x1: plusMinus = "-"; break; + } +} + +void decode_KKK_table(const UINT16 KKK, std::string& D1, std::string& D2) +{ + switch(KKK) + { + case 0x0: D1 = "^F"; D2 = "X0"; break; + case 0x1: D1 = "Y0"; D2 = "X0"; break; + case 0x2: D1 = "X1"; D2 = "X0"; break; + case 0x3: D1 = "Y1"; D2 = "X0"; break; + case 0x4: D1 = "X0"; D2 = "X1"; break; + case 0x5: D1 = "Y0"; D2 = "X1"; break; + case 0x6: D1 = "^F"; D2 = "Y0"; break; + case 0x7: D1 = "Y1"; D2 = "X1"; break; + } +} + +void decode_NN_table(UINT16 NN, INT8& ret) +{ + ret = NN; +} + +void decode_TT_table(UINT16 TT, INT8& ret) +{ + ret = TT; +} + +void decode_QQF_table(const UINT16 QQ, const UINT16 F, std::string& S1, std::string& S2, std::string& D) +{ + const UINT16 switchVal = (QQ << 1) | F; + + 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 = "Y0"; S2 = "X1"; D = "A"; break; + case 0x5: S1 = "Y0"; S2 = "X1"; D = "B"; break; + case 0x6: S1 = "Y1"; S2 = "X1"; D = "A"; break; + case 0x7: S1 = "Y1"; S2 = "X1"; D = "B"; break; + } +} + +void decode_QQF_special_table(const UINT16 QQ, const UINT16 F, std::string& S1, std::string& S2, std::string& D) +{ + const UINT16 switchVal = (QQ << 1) | F; + + 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; + } +} + +void decode_QQQF_table(const UINT16 QQQ, const UINT16 F, std::string& S1, std::string& S2, std::string& D) +{ + const UINT16 switchVal = (QQQ << 1) | F; + + switch(switchVal) + { + case 0x0: S1 = "X0"; S2 = "X0"; D = "A"; break; + case 0x1: S1 = "X0"; S2 = "X0"; D = "B"; break; + case 0x2: S1 = "X1"; S2 = "X0"; D = "A"; break; + case 0x3: S1 = "X1"; S2 = "X0"; D = "B"; break; + case 0x4: S1 = "A1"; S2 = "Y0"; D = "A"; break; + case 0x5: S1 = "A1"; S2 = "Y0"; D = "B"; break; + case 0x6: S1 = "B1"; S2 = "X0"; D = "A"; break; + case 0x7: S1 = "B1"; S2 = "X0"; D = "B"; break; + case 0x8: S1 = "Y0"; S2 = "X0"; D = "A"; break; + case 0x9: S1 = "Y0"; S2 = "X0"; D = "B"; break; + case 0xa: S1 = "Y1"; S2 = "X0"; D = "A"; break; + case 0xb: S1 = "Y1"; S2 = "X0"; D = "B"; break; + case 0xc: S1 = "Y0"; S2 = "X1"; D = "A"; break; + case 0xd: S1 = "Y0"; S2 = "X1"; D = "B"; break; + case 0xe: S1 = "Y1"; S2 = "X1"; D = "A"; break; + case 0xf: S1 = "Y1"; S2 = "X1"; D = "B"; break; + } +} + +void decode_RR_table(UINT16 RR, INT8& ret) +{ + ret = RR; +} + +void decode_rr_table(UINT16 rr, INT8& ret) +{ + ret = rr; +} + +void decode_s_table(const UINT16 s, std::string& arithmetic) +{ + switch(s) + { + case 0x0: arithmetic = "su"; break; + case 0x1: arithmetic = "uu"; break; + } +} + +void decode_ss_table(const UINT16 ss, std::string& arithmetic) +{ + switch(ss) + { + case 0x0: arithmetic = "ss"; break; + case 0x1: arithmetic = "!!"; break; + //case 0x1: arithmetic = "ss"; break; + case 0x2: arithmetic = "su"; break; + case 0x3: arithmetic = "uu"; break; + } +} + +void decode_uuuuF_table(const UINT16 uuuu, const UINT16 F, std::string& arg, std::string& S, std::string& D) +{ + const UINT16 switchVal = (uuuu << 1) | F; + + D = "sub?"; + S = "add"; + arg = "invalid"; + + switch(switchVal) + { + case 0x00: arg = "add"; S = "X0"; D = "A"; break; + case 0x01: arg = "add"; S = "X0"; D = "B"; break; + case 0x02: arg = "add"; S = "Y0"; D = "A"; break; + case 0x03: arg = "add"; S = "Y0"; D = "B"; break; + case 0x04: arg = "add"; S = "X1"; D = "A"; break; + case 0x05: arg = "add"; S = "X1"; D = "B"; break; + case 0x06: arg = "add"; S = "Y1"; D = "A"; break; + case 0x07: arg = "add"; S = "Y1"; D = "B"; break; + + case 0x08: arg = "sub"; S = "X0"; D = "A"; break; + case 0x09: arg = "sub"; S = "X0"; D = "B"; break; + case 0x0a: arg = "sub"; S = "Y0"; D = "A"; break; + case 0x0b: arg = "sub"; S = "Y0"; D = "B"; break; + case 0x0c: arg = "sub"; S = "X1"; D = "A"; break; + case 0x0d: arg = "sub"; S = "X1"; D = "B"; break; + case 0x0e: arg = "sub"; S = "Y1"; D = "A"; break; + case 0x0f: arg = "sub"; S = "Y1"; D = "B"; break; + + case 0x18: arg = "add"; S = "B"; D = "A"; break; + case 0x19: arg = "add"; S = "A"; D = "B"; break; + + case 0x1a: arg = "sub"; S = "B"; D = "A"; break; + case 0x1b: arg = "sub"; S = "A"; D = "B"; break; + + case 0x1c: arg = "tfr"; S = "B"; D = "A"; break; + case 0x1d: arg = "tfr"; S = "A"; D = "B"; break; + + case 0x1e: arg = "move"; S = ""; D = ""; break; + case 0x1f: arg = "move"; S = ""; D = ""; break; + } +} + +void decode_Z_table(const UINT16 Z, std::string& ea) +{ + /* This is fixed as per the Family Manual errata addendum */ + switch(Z) + { + case 0x1: ea = "(A1)"; break; + case 0x0: ea = "(B1)"; break; + } +} + +void assemble_ea_from_m_table(const UINT16 m, const int n, std::string& ea) +{ + char temp[32]; + switch(m) + { + case 0x0: sprintf(temp, "(R%d)+",n) ; break; + case 0x1: sprintf(temp, "(R%d)+N%d", n, n); break; + } + ea = temp; +} + +void assemble_eas_from_mm_table(UINT16 mm, int n1, int n2, std::string& ea1, std::string& ea2) +{ + char temp1[32]; + char temp2[32]; + switch(mm) + { + case 0x0: sprintf(temp1, "(R%d)+", n1) ; + sprintf(temp2, "(R%d)+", n2) ; break; + case 0x1: sprintf(temp1, "(R%d)+", n1) ; + sprintf(temp2, "(R%d)+N%d", n2, n2); break; + case 0x2: sprintf(temp1, "(R%d)+N%d", n1, n1); + sprintf(temp2, "(R%d)+", n2) ; break; + case 0x3: sprintf(temp1, "(R%d)+N%d", n1, n1); + sprintf(temp2, "(R%d)+N%d", n2, n2); break; + } + ea1 = temp1; + ea2 = temp2; +} + +void assemble_ea_from_MM_table(UINT16 MM, int n, std::string& ea) +{ + char temp[32]; + switch(MM) + { + case 0x0: sprintf(temp, "(R%d)", n) ; break; + case 0x1: sprintf(temp, "(R%d)+", n) ; break; + case 0x2: sprintf(temp, "(R%d)-", n) ; break; + case 0x3: sprintf(temp, "(R%d)+N%d", n, n); break; + } + ea = temp; +} + +void assemble_ea_from_q_table(UINT16 q, int n, std::string& ea) +{ + char temp[32]; + switch(q) + { + case 0x0: sprintf(temp, "(R%d+N%d)", n, n); break; + case 0x1: sprintf(temp, "-(R%d)", n) ; break; + } + ea = temp; +} + +void assemble_ea_from_t_table(UINT16 t, UINT16 val, std::string& ea) +{ + char temp[32]; + switch(t) + { + case 0x0: sprintf(temp, "X:>$%x", val); break; + case 0x1: sprintf(temp, "#>$%x", val); break; + // NEW // case 0x0: sprintf(ea, "X:$%04x", val); break; + // NEW // case 0x1: sprintf(ea, "#$%04x", val); break; + } + ea = temp; +} + +void assemble_ea_from_z_table(UINT16 z, int n, std::string& ea) +{ + char temp[32]; + switch(z) + { + case 0x0: sprintf(temp, "(R%d)-", n) ; break; + case 0x1: sprintf(temp, "(R%d)+N%d", n, n); break; + } + ea = temp; +} + +void assemble_D_from_P_table(UINT16 P, UINT16 ppppp, std::string& D) +{ + char temp[32]; + std::string fullAddy; /* Convert Short Absolute Address to full 16-bit */ + + switch(P) + { + case 0x0: + sprintf(temp, "X:<$%x", ppppp); + // NEW // sprintf(temp, "X:$%02x", ppppp); + break; + case 0x1: + assemble_address_from_IO_short_address(ppppp, fullAddy); + sprintf(temp, "X:<<$%s", fullAddy.c_str()); + // NEW // sprintf(temp, "X:$%s", fullAddy.c_str()); + break; + } + D = temp; +} + +void assemble_arguments_from_W_table(UINT16 W, char ma, const std::string& SD, const std::string& ea, + std::string& source, std::string& destination) +{ + char temp[32]; + sprintf(temp, "%c:%s", ma, ea.c_str()); + switch(W) + { + case 0x0: source = SD; destination = temp; break; + case 0x1: source = temp; destination = SD; break; + } +} + +void assemble_reg_from_W_table(UINT16 W, char ma, const std::string& SD, const INT8 xx, std::string& S, std::string& D) +{ + UINT8 abs_xx; + char temp[32]; + char operation[32]; + + if(xx < 0) + sprintf(operation,"-"); + else + sprintf(operation,"+"); + + abs_xx = abs(xx); + + sprintf(temp, "%c:(R2%s$%x)", ma, operation, abs_xx); + // NEW // sprintf(temp, "%c:(R2%s$%02x)", ma, operation, abs_xx); + switch(W) + { + case 0x0: S = SD; D = temp; break; + case 0x1: S = temp; D = SD; break; + } +} + +void assemble_address_from_IO_short_address(UINT16 pp, std::string& ea) +{ + char temp[32]; + + UINT16 fullAddy = 0xffe0; + fullAddy |= pp; + + sprintf(temp, "%.04x", fullAddy); + ea = temp; +} + +INT8 get_6_bit_signed_value(UINT16 bits) +{ + UINT16 fullAddy = bits; + if (fullAddy & 0x0020) + fullAddy |= 0xffc0; + + return (INT8)fullAddy; +} + + +/*******************/ +/* HELPER FUNCTION */ +/*******************/ + +UINT16 dsp56k_op_maskn(UINT16 cur, UINT16 mask) +{ + int i; + + UINT16 retVal = (cur & mask); + UINT16 temp = 0x0000; + int offsetCount = 0; + + /* Shift everything right, eliminating 'whitespace'... */ + for (i = 0; i < 16; i++) + { + if (mask & (0x1<> i) & 0x1) << offsetCount); + offsetCount++; + } + } + + return temp; +} + +bool registerOverlap(const std::string& r0, const size_t bmd, const std::string& r1) +{ + if (bmd == BM_NONE) + return false; + + if (r0 == r1) + return true; + + if (r0 == "A" && (bmd & BM_LOW) && r1 == "A0") return true; + if (r0 == "A" && (bmd & BM_MIDDLE) && r1 == "A1") return true; + if (r0 == "A" && (bmd & BM_HIGH) && r1 == "A2") return true; + + if (r0 == "B" && (bmd & BM_LOW) && r1 == "B0") return true; + if (r0 == "B" && (bmd & BM_MIDDLE) && r1 == "B1") return true; + if (r0 == "B" && (bmd & BM_HIGH) && r1 == "B2") return true; + + return false; +} + +} + diff --git a/src/emu/cpu/dsp56k/tables.h b/src/emu/cpu/dsp56k/tables.h new file mode 100644 index 00000000000..00d5e507251 --- /dev/null +++ b/src/emu/cpu/dsp56k/tables.h @@ -0,0 +1,68 @@ +#ifndef __DSP56K_OPS_H__ +#define __DSP56K_OPS_H__ + +#include +#include +#include + +#include "emu.h" + +namespace DSP56K +{ + +#define BITSn(CUR,MASK) (dsp56k_op_maskn(CUR,MASK)) + +enum bbbType {BBB_UPPER, BBB_MIDDLE, BBB_LOWER, BBB_INVALID}; +enum bitsModified {BM_NONE = 0x0, + BM_LOW = 0x1, + BM_MIDDLE = 0x2, + BM_HIGH = 0x4}; + +int decode_BBB_table(UINT16 BBB); +void decode_cccc_table(const UINT16 cccc, std::string& mnemonic); +void decode_DDDDD_table(const UINT16 DDDDD, std::string& SD); +void decode_DD_table(const UINT16 DD, std::string& SD); +void decode_DDF_table(const UINT16 DD, const UINT16 F, std::string& S, std::string& D); +void decode_EE_table(const UINT16 EE, std::string& D); +void decode_F_table(const UINT16 F, std::string& SD); +void decode_h0hF_table(const UINT16 h0h, UINT16 F, std::string& S, std::string& D); +void decode_HH_table(const UINT16 HH, std::string& SD); +void decode_HHH_table(const UINT16 HHH, std::string& SD); +void decode_IIIIx_table(const UINT16 IIII, const UINT16 x, std::string& S, std::string& D); +void decode_JJJF_table(const UINT16 JJJ, const UINT16 F, std::string& S, std::string& D); +void decode_JJF_table(const UINT16 JJ, const UINT16 F, std::string& S, std::string& D); +void decode_JF_table(const UINT16 J, const UINT16 F, std::string& S, std::string& D); +void decode_kSign_table(const UINT16 k, std::string& plusMinus); +void decode_KKK_table(const UINT16 KKK, std::string& D1, std::string& D2); +void decode_NN_table(UINT16 NN, INT8& ret); +void decode_TT_table(UINT16 TT, INT8& ret); +void decode_QQF_table(const UINT16 QQ, const UINT16 F, std::string& S1, std::string& S2, std::string& D); +void decode_QQF_special_table(const UINT16 QQ, const UINT16 F, std::string& S1, std::string& S2, std::string& D); +void decode_QQQF_table(const UINT16 QQQ, const UINT16 F, std::string& S1, std::string& S2, std::string& D); +void decode_RR_table(UINT16 RR, INT8& ret); +void decode_rr_table(UINT16 rr, INT8& ret); +void decode_s_table(const UINT16 s, std::string& arithmetic); +void decode_ss_table(const UINT16 ss, std::string& arithmetic); +void decode_uuuuF_table(const UINT16 uuuu, const UINT16 F, std::string& arg, std::string& S, std::string& D); +void decode_Z_table(const UINT16 Z, std::string& ea); + +void assemble_ea_from_m_table(const UINT16 m, const int n, std::string& ea); +void assemble_eas_from_mm_table(UINT16 mm, int n1, int n2, std::string& ea1, std::string& ea2); +void assemble_ea_from_MM_table(UINT16 MM, int n, std::string& ea); +void assemble_ea_from_q_table(UINT16 q, int n, std::string& ea); +void assemble_ea_from_t_table(UINT16 t, UINT16 val, std::string& ea); +void assemble_ea_from_z_table(UINT16 z, int n, std::string& ea); +void assemble_D_from_P_table(UINT16 P, UINT16 ppppp, std::string& D); +void assemble_arguments_from_W_table(UINT16 W, char ma, const std::string& SD, const std::string& ea, std::string& S, std::string& D); +void assemble_reg_from_W_table(UINT16 W, char ma, const std::string& SD, const INT8 xx, std::string& S, std::string& D); +void assemble_address_from_IO_short_address(UINT16 pp, std::string& ea); + +INT8 get_6_bit_signed_value(UINT16 bits); + +// Helpers +UINT16 dsp56k_op_maskn(UINT16 cur, UINT16 mask); + +bool registerOverlap(const std::string& r0, const size_t bmd, const std::string& r1); + +} +#endif diff --git a/src/tools/tools.mak b/src/tools/tools.mak index 43092a0f8a0..8adb4c73165 100644 --- a/src/tools/tools.mak +++ b/src/tools/tools.mak @@ -111,7 +111,7 @@ jedutil$(EXE): $(JEDUTILOBJS) $(LIBUTIL) $(LIBOCORE) $(ZLIB) $(EXPAT) UNIDASMOBJS = \ $(TOOLSOBJ)/unidasm.o \ -unidasm$(EXE): $(UNIDASMOBJS) $(LIBDASM) $(LIBUTIL) $(LIBOCORE) $(ZLIB) $(EXPAT) +unidasm$(EXE): $(UNIDASMOBJS) $(LIBDASM) $(LIBEMU) $(LIBUTIL) $(LIBOCORE) $(ZLIB) $(EXPAT) @echo Linking $@... $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ diff --git a/src/tools/unidasm.c b/src/tools/unidasm.c index 89f7fa471ca..f8fdfaea45d 100644 --- a/src/tools/unidasm.c +++ b/src/tools/unidasm.c @@ -333,18 +333,6 @@ static const dasm_table_entry dasm_table[] = { "z8", _8bit, 0, CPU_DISASSEMBLE_NAME(z8) }, }; -void *malloc_file_line(size_t size, const char *file, int line) -{ - void *result = malloc(size); - return result; -} - - -void free_file_line(void *memory, const char *file, int line) -{ - free(memory); -} - void CLIB_DECL logerror(const char *format, ...) { /* silent logerrors are allowed in disassemblers */