--- hatari/src/falcon/dsp_cpu.c 2019/04/01 07:14:55 1.1.1.2 +++ hatari/src/falcon/dsp_cpu.c 2019/04/09 08:57:02 1.1.1.12 @@ -1,6 +1,6 @@ /* DSP M56001 emulation - Instructions interpreter, execution thread + Instructions interpreter (C) 2003-2008 ARAnyM developer team @@ -19,64 +19,109 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* + DSP memory mapping + ------------------ + + The memory map is configured as follows : + Program space P is one contiguous block of 32K dsp Words + X and Y data space are each separate 16K dsp Word blocks. + Both X and Y can be accessed as blocks starting at 0 or 16K. + Program space physically overlaps both X and Y data spaces. + Y: memory is mapped at address $0 in P memory + X: memory is mapped at address $4000 in P memory + + The DSP external RAM is zero waitstate, but there is a penalty for + accessing it twice or more in a single instruction, because there is only + one external data bus. The extra access costs 2 cycles penalty. + + The internal buses are all separate (0 waitstate) + + + X: Y: P: + $ffff |--------------+--------------+--------------| + | Int. I/O | Ext. I/O | | + $ffc0 |--------------+--------------+ | + | | | | + | Reserved | Reserved | Reserved | + | | | | + | | | | + | | | | + $8000 |--------------+--------------+--------------| + | | | | + | 16k Shadow | 16k Shadow | | + | | | 32K | + $4000 |--------------+--------------| Program | + | 16K | 16K | RAM | + | External | External | | + | RAM | RAM | | + $0200 |--------------+--------------+--------------| + | Log table or | Sin table or | | + | external mem | external mem | Internal | + $0100 |--------------+--------------+ program | + | Internal X | Internal Y | memory | + | memory | memory | | + $0000 |--------------+--------------+--------------| + + + Special Note : As the Falcon DSP is a 0 waitstate access memory, I've simplified a little the cycle counting. + If this DSP emulator code is used in another project, one should take into account the bus control register (BCR) waitstates. +*/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif +#include + +#include "main.h" #include "dsp_core.h" #include "dsp_cpu.h" -#ifdef DSP_DISASM #include "dsp_disasm.h" -#endif - -#define DEBUG 0 - -/* More disasm infos, if wanted */ -#define DSP_DISASM_INST 0 /* Instructions */ -#define DSP_DISASM_REG 0 /* Registers changes */ -#define DSP_DISASM_MEM 0 /* Memory changes */ -#define DSP_DISASM_INTER 0 /* Interrupts */ -#define DSP_DISASM_STATE 0 /* State change */ +#include "log.h" +#include "debugui.h" #define DSP_COUNT_IPS 0 /* Count instruction per seconds */ -#if defined(DSP_DISASM) && (DSP_DISASM_MEM==1) -# define write_memory(x,y,z) write_memory_disasm(x,y,z) -#else -# define write_memory(x,y,z) write_memory_raw(x,y,z) -#endif /********************************** * Defines **********************************/ -#define BITMASK(x) ((1<<(x))-1) +#define SIGN_PLUS 0 +#define SIGN_MINUS 1 + +/* Defines some bits values for access to external memory (X, Y, P) */ +/* These values will set/unset the corresponding bits in the variable access_to_ext_memory */ +/* to detect how many access to the external memory were done for a single instruction */ +#define EXT_X_MEMORY 0 +#define EXT_Y_MEMORY 1 +#define EXT_P_MEMORY 2 + /********************************** * Variables **********************************/ +/* Instructions per second */ +static Uint32 start_time; +static Uint32 num_inst; + /* Length of current instruction */ static Uint32 cur_inst_len; /* =0:jump, >0:increment */ /* Current instruction */ -static Uint32 cur_inst; +static Uint32 cur_inst; + +/* Counts the number of access to the external memory for one instruction */ +static Uint16 access_to_ext_memory; -/* Parallel move temp data */ -typedef union { - Uint32 *host_pointer; - Uint32 dsp_address; -} parmove_dest_u; - -static Uint32 tmp_parmove_src[2][3]; /* What to read */ -static parmove_dest_u tmp_parmove_dest[2][3]; /* Where to write */ -static Uint32 tmp_parmove_start[2]; /* From where to read/write */ -static Uint32 tmp_parmove_len[2]; /* How many to read/write */ -static Uint32 tmp_parmove_type[2]; /* 0=register, 1=memory */ -static Uint32 tmp_parmove_space[2]; /* Memory space to write to */ +/* DSP is in disasm mode ? */ +/* If yes, stack overflow, underflow and illegal instructions messages are not displayed */ +static bool isDsp_in_disasm_mode; -/* PC on Rep instruction ? */ -static Uint32 pc_on_rep; +static char str_disasm_memory[2][50]; /* Buffer for memory change text in disasm mode */ +static Uint16 disasm_memory_ptr; /* Pointer for memory change in disasm mode */ /********************************** * Functions @@ -84,32 +129,28 @@ static Uint32 pc_on_rep; typedef void (*dsp_emul_t)(void); -static void dsp_execute_instruction(void); static void dsp_postexecute_update_pc(void); static void dsp_postexecute_interrupts(void); -static void dsp_ccr_extension(Uint32 *reg0, Uint32 *reg1); -static void dsp_ccr_unnormalized(Uint32 *reg0, Uint32 *reg1); -static void dsp_ccr_negative(Uint32 *reg0); -static void dsp_ccr_zero(Uint32 *reg0, Uint32 *reg1, Uint32 *reg2); +static void dsp_setInterruptIPL(Uint32 value); + +static void dsp_ccr_update_e_u_n_z(Uint32 reg0, Uint32 reg1, Uint32 reg2); static Uint32 read_memory(int space, Uint16 address); -static void write_memory_raw(int space, Uint32 address, Uint32 value); -#if defined(DSP_DISASM) && (DSP_DISASM_MEM==1) +static inline Uint32 read_memory_p(Uint16 address); static Uint32 read_memory_disasm(int space, Uint16 address); -static void write_memory_disasm(int space, Uint32 address, Uint32 value); -#endif -static void dsp_stack_push(Uint32 curpc, Uint32 cursr); +static inline void write_memory(int space, Uint16 address, Uint32 value); +static void write_memory_raw(int space, Uint16 address, Uint32 value); +static void write_memory_disasm(int space, Uint16 address, Uint32 value); + +static void dsp_write_reg(Uint32 numreg, Uint32 value); + +static void dsp_stack_push(Uint32 curpc, Uint32 cursr, Uint16 sshOnly); static void dsp_stack_pop(Uint32 *curpc, Uint32 *cursr); +static void dsp_compute_ssh_ssl(void); static void opcode8h_0(void); -static void opcode8h_1(void); -static void opcode8h_4(void); -static void opcode8h_6(void); -static void opcode8h_8(void); -static void opcode8h_a(void); -static void opcode8h_b(void); static void dsp_update_rn(Uint32 numreg, Sint16 modifier); static void dsp_update_rn_bitreverse(Uint32 numreg); @@ -121,30 +162,55 @@ static void dsp_undefined(void); /* Instructions without parallel moves */ static void dsp_andi(void); -static void dsp_bchg(void); -static void dsp_bclr(void); -static void dsp_bset(void); -static void dsp_btst(void); +static void dsp_bchg_aa(void); +static void dsp_bchg_ea(void); +static void dsp_bchg_pp(void); +static void dsp_bchg_reg(void); +static void dsp_bclr_aa(void); +static void dsp_bclr_ea(void); +static void dsp_bclr_pp(void); +static void dsp_bclr_reg(void); +static void dsp_bset_aa(void); +static void dsp_bset_ea(void); +static void dsp_bset_pp(void); +static void dsp_bset_reg(void); +static void dsp_btst_aa(void); +static void dsp_btst_ea(void); +static void dsp_btst_pp(void); +static void dsp_btst_reg(void); static void dsp_div(void); -static void dsp_do(void); static void dsp_enddo(void); static void dsp_illegal(void); -static void dsp_jcc(void); -static void dsp_jclr(void); -static void dsp_jmp(void); -static void dsp_jscc(void); -static void dsp_jsclr(void); -static void dsp_jset(void); -static void dsp_jsr(void); -static void dsp_jsset(void); +static void dsp_jcc_imm(void); +static void dsp_jcc_ea(void); +static void dsp_jclr_aa(void); +static void dsp_jclr_ea(void); +static void dsp_jclr_pp(void); +static void dsp_jclr_reg(void); +static void dsp_jmp_ea(void); +static void dsp_jmp_imm(void); +static void dsp_jscc_ea(void); +static void dsp_jscc_imm(void); +static void dsp_jsclr_aa(void); +static void dsp_jsclr_ea(void); +static void dsp_jsclr_pp(void); +static void dsp_jsclr_reg(void); +static void dsp_jset_aa(void); +static void dsp_jset_ea(void); +static void dsp_jset_pp(void); +static void dsp_jset_reg(void); +static void dsp_jsr_ea(void); +static void dsp_jsr_imm(void); +static void dsp_jsset_aa(void); +static void dsp_jsset_ea(void); +static void dsp_jsset_pp(void); +static void dsp_jsset_reg(void); static void dsp_lua(void); -static void dsp_movec(void); -static void dsp_movem(void); -static void dsp_movep(void); +static void dsp_movem_ea(void); +static void dsp_movem_aa(void); static void dsp_nop(void); static void dsp_norm(void); static void dsp_ori(void); -static void dsp_rep(void); static void dsp_reset(void); static void dsp_rti(void); static void dsp_rts(void); @@ -153,36 +219,31 @@ static void dsp_swi(void); static void dsp_tcc(void); static void dsp_wait(void); -static void dsp_do_0(void); -static void dsp_do_2(void); -static void dsp_do_4(void); -static void dsp_do_c(void); -static void dsp_rep_1(void); -static void dsp_rep_3(void); -static void dsp_rep_5(void); -static void dsp_rep_d(void); -static void dsp_movec_7(void); -static void dsp_movec_9(void); -static void dsp_movec_b(void); -static void dsp_movec_d(void); +static void dsp_do_ea(void); +static void dsp_do_aa(void); +static void dsp_do_imm(void); +static void dsp_do_reg(void); +static void dsp_rep_aa(void); +static void dsp_rep_ea(void); +static void dsp_rep_imm(void); +static void dsp_rep_reg(void); +static void dsp_movec_aa(void); +static void dsp_movec_ea(void); +static void dsp_movec_imm(void); +static void dsp_movec_reg(void); static void dsp_movep_0(void); static void dsp_movep_1(void); -static void dsp_movep_2(void); +static void dsp_movep_23(void); /* Parallel move analyzer */ -static void dsp_parmove_read(void); -static void dsp_parmove_write(void); - static int dsp_pm_read_accu24(int numreg, Uint32 *dest); -static void dsp_pm_writereg(int numreg, int position); - static void dsp_pm_0(void); static void dsp_pm_1(void); static void dsp_pm_2(void); static void dsp_pm_2_2(void); static void dsp_pm_3(void); static void dsp_pm_4(void); -static void dsp_pm_4x(int immediat, Uint32 l_addr); +static void dsp_pm_4x(void); static void dsp_pm_5(void); static void dsp_pm_8(void); @@ -192,366 +253,392 @@ static Uint16 dsp_asl56(Uint32 *dest); static Uint16 dsp_asr56(Uint32 *dest); static Uint16 dsp_add56(Uint32 *source, Uint32 *dest); static Uint16 dsp_sub56(Uint32 *source, Uint32 *dest); -static void dsp_mul56(Uint32 source1, Uint32 source2, Uint32 *dest); +static void dsp_mul56(Uint32 source1, Uint32 source2, Uint32 *dest, Uint8 signe); static void dsp_rnd56(Uint32 *dest); /* Instructions with parallel moves */ -static void dsp_abs(void); -static void dsp_adc(void); -static void dsp_add(void); -static void dsp_addl(void); -static void dsp_addr(void); -static void dsp_and(void); -static void dsp_asl(void); -static void dsp_asr(void); -static void dsp_clr(void); -static void dsp_cmp(void); -static void dsp_cmpm(void); -static void dsp_eor(void); -static void dsp_lsl(void); -static void dsp_lsr(void); -static void dsp_mac(void); -static void dsp_macr(void); +static void dsp_abs_a(void); +static void dsp_abs_b(void); +static void dsp_adc_x_a(void); +static void dsp_adc_x_b(void); +static void dsp_adc_y_a(void); +static void dsp_adc_y_b(void); +static void dsp_add_b_a(void); +static void dsp_add_a_b(void); +static void dsp_add_x_a(void); +static void dsp_add_x_b(void); +static void dsp_add_y_a(void); +static void dsp_add_y_b(void); +static void dsp_add_x0_a(void); +static void dsp_add_x0_b(void); +static void dsp_add_y0_a(void); +static void dsp_add_y0_b(void); +static void dsp_add_x1_a(void); +static void dsp_add_x1_b(void); +static void dsp_add_y1_a(void); +static void dsp_add_y1_b(void); +static void dsp_addl_b_a(void); +static void dsp_addl_a_b(void); +static void dsp_addr_b_a(void); +static void dsp_addr_a_b(void); +static void dsp_and_x0_a(void); +static void dsp_and_x0_b(void); +static void dsp_and_y0_a(void); +static void dsp_and_y0_b(void); +static void dsp_and_x1_a(void); +static void dsp_and_x1_b(void); +static void dsp_and_y1_a(void); +static void dsp_and_y1_b(void); +static void dsp_asl_a(void); +static void dsp_asl_b(void); +static void dsp_asr_a(void); +static void dsp_asr_b(void); +static void dsp_clr_a(void); +static void dsp_clr_b(void); +static void dsp_cmp_b_a(void); +static void dsp_cmp_a_b(void); +static void dsp_cmp_x0_a(void); +static void dsp_cmp_x0_b(void); +static void dsp_cmp_y0_a(void); +static void dsp_cmp_y0_b(void); +static void dsp_cmp_x1_a(void); +static void dsp_cmp_x1_b(void); +static void dsp_cmp_y1_a(void); +static void dsp_cmp_y1_b(void); +static void dsp_cmpm_b_a(void); +static void dsp_cmpm_a_b(void); +static void dsp_cmpm_x0_a(void); +static void dsp_cmpm_x0_b(void); +static void dsp_cmpm_y0_a(void); +static void dsp_cmpm_y0_b(void); +static void dsp_cmpm_x1_a(void); +static void dsp_cmpm_x1_b(void); +static void dsp_cmpm_y1_a(void); +static void dsp_cmpm_y1_b(void); +static void dsp_eor_x0_a(void); +static void dsp_eor_x0_b(void); +static void dsp_eor_y0_a(void); +static void dsp_eor_y0_b(void); +static void dsp_eor_x1_a(void); +static void dsp_eor_x1_b(void); +static void dsp_eor_y1_a(void); +static void dsp_eor_y1_b(void); +static void dsp_lsl_a(void); +static void dsp_lsl_b(void); +static void dsp_lsr_a(void); +static void dsp_lsr_b(void); +static void dsp_mac_p_x0_x0_a(void); +static void dsp_mac_m_x0_x0_a(void); +static void dsp_mac_p_x0_x0_b(void); +static void dsp_mac_m_x0_x0_b(void); +static void dsp_mac_p_y0_y0_a(void); +static void dsp_mac_m_y0_y0_a(void); +static void dsp_mac_p_y0_y0_b(void); +static void dsp_mac_m_y0_y0_b(void); +static void dsp_mac_p_x1_x0_a(void); +static void dsp_mac_m_x1_x0_a(void); +static void dsp_mac_p_x1_x0_b(void); +static void dsp_mac_m_x1_x0_b(void); +static void dsp_mac_p_y1_y0_a(void); +static void dsp_mac_m_y1_y0_a(void); +static void dsp_mac_p_y1_y0_b(void); +static void dsp_mac_m_y1_y0_b(void); +static void dsp_mac_p_x0_y1_a(void); +static void dsp_mac_m_x0_y1_a(void); +static void dsp_mac_p_x0_y1_b(void); +static void dsp_mac_m_x0_y1_b(void); +static void dsp_mac_p_y0_x0_a(void); +static void dsp_mac_m_y0_x0_a(void); +static void dsp_mac_p_y0_x0_b(void); +static void dsp_mac_m_y0_x0_b(void); +static void dsp_mac_p_x1_y0_a(void); +static void dsp_mac_m_x1_y0_a(void); +static void dsp_mac_p_x1_y0_b(void); +static void dsp_mac_m_x1_y0_b(void); +static void dsp_mac_p_y1_x1_a(void); +static void dsp_mac_m_y1_x1_a(void); +static void dsp_mac_p_y1_x1_b(void); +static void dsp_mac_m_y1_x1_b(void); +static void dsp_macr_p_x0_x0_a(void); +static void dsp_macr_m_x0_x0_a(void); +static void dsp_macr_p_x0_x0_b(void); +static void dsp_macr_m_x0_x0_b(void); +static void dsp_macr_p_y0_y0_a(void); +static void dsp_macr_m_y0_y0_a(void); +static void dsp_macr_p_y0_y0_b(void); +static void dsp_macr_m_y0_y0_b(void); +static void dsp_macr_p_x1_x0_a(void); +static void dsp_macr_m_x1_x0_a(void); +static void dsp_macr_p_x1_x0_b(void); +static void dsp_macr_m_x1_x0_b(void); +static void dsp_macr_p_y1_y0_a(void); +static void dsp_macr_m_y1_y0_a(void); +static void dsp_macr_p_y1_y0_b(void); +static void dsp_macr_m_y1_y0_b(void); +static void dsp_macr_p_x0_y1_a(void); +static void dsp_macr_m_x0_y1_a(void); +static void dsp_macr_p_x0_y1_b(void); +static void dsp_macr_m_x0_y1_b(void); +static void dsp_macr_p_y0_x0_a(void); +static void dsp_macr_m_y0_x0_a(void); +static void dsp_macr_p_y0_x0_b(void); +static void dsp_macr_m_y0_x0_b(void); +static void dsp_macr_p_x1_y0_a(void); +static void dsp_macr_m_x1_y0_a(void); +static void dsp_macr_p_x1_y0_b(void); +static void dsp_macr_m_x1_y0_b(void); +static void dsp_macr_p_y1_x1_a(void); +static void dsp_macr_m_y1_x1_a(void); +static void dsp_macr_p_y1_x1_b(void); +static void dsp_macr_m_y1_x1_b(void); static void dsp_move(void); -static void dsp_mpy(void); -static void dsp_mpyr(void); -static void dsp_neg(void); -static void dsp_not(void); -static void dsp_or(void); -static void dsp_rnd(void); -static void dsp_rol(void); -static void dsp_ror(void); -static void dsp_sbc(void); -static void dsp_sub(void); -static void dsp_subl(void); -static void dsp_subr(void); -static void dsp_tfr(void); -static void dsp_tst(void); - -static void dsp_move_pm(void); - -static dsp_emul_t opcodes8h[16]={ - opcode8h_0, - opcode8h_1, - dsp_tcc, - dsp_tcc, - opcode8h_4, - dsp_movec, - opcode8h_6, - dsp_movem, - opcode8h_8, - opcode8h_8, - opcode8h_a, - opcode8h_b, - dsp_jmp, - dsp_jsr, - dsp_jcc, - dsp_jscc -}; - -static dsp_emul_t opcodes_0809[16]={ - dsp_move_pm, - dsp_move_pm, - dsp_move_pm, - dsp_move_pm, - - dsp_movep, - dsp_movep, - dsp_movep, - dsp_movep, - - dsp_move_pm, - dsp_move_pm, - dsp_move_pm, - dsp_move_pm, - - dsp_movep, - dsp_movep, - dsp_movep, - dsp_movep -}; - -static dsp_emul_t opcodes_0a[32]={ - /* 00 000 */ dsp_bclr, - /* 00 001 */ dsp_bset, - /* 00 010 */ dsp_bclr, - /* 00 011 */ dsp_bset, - /* 00 100 */ dsp_jclr, - /* 00 101 */ dsp_jset, - /* 00 110 */ dsp_jclr, - /* 00 111 */ dsp_jset, - - /* 01 000 */ dsp_bclr, - /* 01 001 */ dsp_bset, - /* 01 010 */ dsp_bclr, - /* 01 011 */ dsp_bset, - /* 01 100 */ dsp_jclr, - /* 01 101 */ dsp_jset, - /* 01 110 */ dsp_jclr, - /* 01 111 */ dsp_jset, - - /* 10 000 */ dsp_bclr, - /* 10 001 */ dsp_bset, - /* 10 010 */ dsp_bclr, - /* 10 011 */ dsp_bset, - /* 10 100 */ dsp_jclr, - /* 10 101 */ dsp_jset, - /* 10 110 */ dsp_jclr, - /* 10 111 */ dsp_jset, - - /* 11 000 */ dsp_jclr, - /* 11 001 */ dsp_jset, - /* 11 010 */ dsp_bclr, - /* 11 011 */ dsp_bset, - /* 11 100 */ dsp_jmp, - /* 11 101 */ dsp_jcc, - /* 11 110 */ dsp_undefined, - /* 11 111 */ dsp_undefined +static void dsp_mpy_p_x0_x0_a(void); +static void dsp_mpy_m_x0_x0_a(void); +static void dsp_mpy_p_x0_x0_b(void); +static void dsp_mpy_m_x0_x0_b(void); +static void dsp_mpy_p_y0_y0_a(void); +static void dsp_mpy_m_y0_y0_a(void); +static void dsp_mpy_p_y0_y0_b(void); +static void dsp_mpy_m_y0_y0_b(void); +static void dsp_mpy_p_x1_x0_a(void); +static void dsp_mpy_m_x1_x0_a(void); +static void dsp_mpy_p_x1_x0_b(void); +static void dsp_mpy_m_x1_x0_b(void); +static void dsp_mpy_p_y1_y0_a(void); +static void dsp_mpy_m_y1_y0_a(void); +static void dsp_mpy_p_y1_y0_b(void); +static void dsp_mpy_m_y1_y0_b(void); +static void dsp_mpy_p_x0_y1_a(void); +static void dsp_mpy_m_x0_y1_a(void); +static void dsp_mpy_p_x0_y1_b(void); +static void dsp_mpy_m_x0_y1_b(void); +static void dsp_mpy_p_y0_x0_a(void); +static void dsp_mpy_m_y0_x0_a(void); +static void dsp_mpy_p_y0_x0_b(void); +static void dsp_mpy_m_y0_x0_b(void); +static void dsp_mpy_p_x1_y0_a(void); +static void dsp_mpy_m_x1_y0_a(void); +static void dsp_mpy_p_x1_y0_b(void); +static void dsp_mpy_m_x1_y0_b(void); +static void dsp_mpy_p_y1_x1_a(void); +static void dsp_mpy_m_y1_x1_a(void); +static void dsp_mpy_p_y1_x1_b(void); +static void dsp_mpy_m_y1_x1_b(void); +static void dsp_mpyr_p_x0_x0_a(void); +static void dsp_mpyr_m_x0_x0_a(void); +static void dsp_mpyr_p_x0_x0_b(void); +static void dsp_mpyr_m_x0_x0_b(void); +static void dsp_mpyr_p_y0_y0_a(void); +static void dsp_mpyr_m_y0_y0_a(void); +static void dsp_mpyr_p_y0_y0_b(void); +static void dsp_mpyr_m_y0_y0_b(void); +static void dsp_mpyr_p_x1_x0_a(void); +static void dsp_mpyr_m_x1_x0_a(void); +static void dsp_mpyr_p_x1_x0_b(void); +static void dsp_mpyr_m_x1_x0_b(void); +static void dsp_mpyr_p_y1_y0_a(void); +static void dsp_mpyr_m_y1_y0_a(void); +static void dsp_mpyr_p_y1_y0_b(void); +static void dsp_mpyr_m_y1_y0_b(void); +static void dsp_mpyr_p_x0_y1_a(void); +static void dsp_mpyr_m_x0_y1_a(void); +static void dsp_mpyr_p_x0_y1_b(void); +static void dsp_mpyr_m_x0_y1_b(void); +static void dsp_mpyr_p_y0_x0_a(void); +static void dsp_mpyr_m_y0_x0_a(void); +static void dsp_mpyr_p_y0_x0_b(void); +static void dsp_mpyr_m_y0_x0_b(void); +static void dsp_mpyr_p_x1_y0_a(void); +static void dsp_mpyr_m_x1_y0_a(void); +static void dsp_mpyr_p_x1_y0_b(void); +static void dsp_mpyr_m_x1_y0_b(void); +static void dsp_mpyr_p_y1_x1_a(void); +static void dsp_mpyr_m_y1_x1_a(void); +static void dsp_mpyr_p_y1_x1_b(void); +static void dsp_mpyr_m_y1_x1_b(void); +static void dsp_neg_a(void); +static void dsp_neg_b(void); +static void dsp_not_a(void); +static void dsp_not_b(void); +static void dsp_or_x0_a(void); +static void dsp_or_x0_b(void); +static void dsp_or_y0_a(void); +static void dsp_or_y0_b(void); +static void dsp_or_x1_a(void); +static void dsp_or_x1_b(void); +static void dsp_or_y1_a(void); +static void dsp_or_y1_b(void); +static void dsp_rnd_a(void); +static void dsp_rnd_b(void); +static void dsp_rol_a(void); +static void dsp_rol_b(void); +static void dsp_ror_a(void); +static void dsp_ror_b(void); +static void dsp_sbc_x_a(void); +static void dsp_sbc_x_b(void); +static void dsp_sbc_y_a(void); +static void dsp_sbc_y_b(void); +static void dsp_sub_b_a(void); +static void dsp_sub_a_b(void); +static void dsp_sub_x_a(void); +static void dsp_sub_x_b(void); +static void dsp_sub_y_a(void); +static void dsp_sub_y_b(void); +static void dsp_sub_x0_a(void); +static void dsp_sub_x0_b(void); +static void dsp_sub_y0_a(void); +static void dsp_sub_y0_b(void); +static void dsp_sub_x1_a(void); +static void dsp_sub_x1_b(void); +static void dsp_sub_y1_a(void); +static void dsp_sub_y1_b(void); +static void dsp_subl_a(void); +static void dsp_subl_b(void); +static void dsp_subr_a(void); +static void dsp_subr_b(void); +static void dsp_tfr_b_a(void); +static void dsp_tfr_a_b(void); +static void dsp_tfr_x0_a(void); +static void dsp_tfr_x0_b(void); +static void dsp_tfr_y0_a(void); +static void dsp_tfr_y0_b(void); +static void dsp_tfr_x1_a(void); +static void dsp_tfr_x1_b(void); +static void dsp_tfr_y1_a(void); +static void dsp_tfr_y1_b(void); +static void dsp_tst_a(void); +static void dsp_tst_b(void); + +static const dsp_emul_t opcodes8h[512] = { + /* 0x00 - 0x3f */ + opcode8h_0, dsp_undefined, dsp_undefined, dsp_undefined, opcode8h_0, dsp_andi, dsp_undefined, dsp_ori, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_andi, dsp_undefined, dsp_ori, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_andi, dsp_undefined, dsp_ori, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_andi, dsp_undefined, dsp_ori, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_div, dsp_div, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_norm, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + + /* 0x40 - 0x7f */ + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + + /* 0x80 - 0xbf */ + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_lua, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_reg, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_reg, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, + + /* 0xc0 - 0xff */ + dsp_do_aa, dsp_rep_aa, dsp_do_aa, dsp_rep_aa, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_do_ea, dsp_rep_ea, dsp_do_ea, dsp_rep_ea, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_do_reg, dsp_rep_reg, dsp_undefined, dsp_undefined, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_movem_aa, dsp_movem_aa, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movem_ea, dsp_movem_ea, dsp_undefined, dsp_undefined, + dsp_movem_aa, dsp_movem_aa, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movem_ea, dsp_movem_ea, dsp_undefined, dsp_undefined, + + /* 0x100 - 0x13f */ + dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, + dsp_movep_0, dsp_movep_0, dsp_movep_1, dsp_movep_1, dsp_movep_23, dsp_movep_23, dsp_movep_23, dsp_movep_23, + dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, + dsp_movep_0, dsp_movep_0, dsp_movep_1, dsp_movep_1, dsp_movep_23, dsp_movep_23, dsp_movep_23, dsp_movep_23, + dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, + dsp_movep_0, dsp_movep_0, dsp_movep_1, dsp_movep_1, dsp_movep_23, dsp_movep_23, dsp_movep_23, dsp_movep_23, + dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, + dsp_movep_0, dsp_movep_0, dsp_movep_1, dsp_movep_1, dsp_movep_23, dsp_movep_23, dsp_movep_23, dsp_movep_23, + + /* 0x140 - 0x17f */ + dsp_bclr_aa, dsp_bset_aa, dsp_bclr_aa, dsp_bset_aa, dsp_jclr_aa, dsp_jset_aa, dsp_jclr_aa, dsp_jset_aa, + dsp_bclr_ea, dsp_bset_ea, dsp_bclr_ea, dsp_bset_ea, dsp_jclr_ea, dsp_jset_ea, dsp_jclr_ea, dsp_jset_ea, + dsp_bclr_pp, dsp_bset_pp, dsp_bclr_pp, dsp_bset_pp, dsp_jclr_pp, dsp_jset_pp, dsp_jclr_pp, dsp_jset_pp, + dsp_jclr_reg, dsp_jset_reg, dsp_bclr_reg, dsp_bset_reg, dsp_jmp_ea, dsp_jcc_ea, dsp_undefined, dsp_undefined, + dsp_bchg_aa, dsp_btst_aa, dsp_bchg_aa, dsp_btst_aa, dsp_jsclr_aa, dsp_jsset_aa, dsp_jsclr_aa, dsp_jsset_aa, + dsp_bchg_ea, dsp_btst_ea, dsp_bchg_ea, dsp_btst_ea, dsp_jsclr_ea, dsp_jsset_ea, dsp_jsclr_ea, dsp_jsset_ea, + dsp_bchg_pp, dsp_btst_pp, dsp_bchg_pp, dsp_btst_pp, dsp_jsclr_pp, dsp_jsset_pp, dsp_jsclr_pp, dsp_jsset_pp, + dsp_jsclr_reg, dsp_jsset_reg, dsp_bchg_reg, dsp_btst_reg, dsp_jsr_ea, dsp_jscc_ea, dsp_undefined, dsp_undefined, + + /* 0x180 - 0x1bf */ + dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + + /* 0x1c0 - 0x1ff */ + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, }; -static dsp_emul_t opcodes_0b[32]={ - /* 00 000 */ dsp_bchg, - /* 00 001 */ dsp_btst, - /* 00 010 */ dsp_bchg, - /* 00 011 */ dsp_btst, - /* 00 100 */ dsp_jsclr, - /* 00 101 */ dsp_jsset, - /* 00 110 */ dsp_jsclr, - /* 00 111 */ dsp_jsset, - - /* 01 000 */ dsp_bchg, - /* 01 001 */ dsp_btst, - /* 01 010 */ dsp_bchg, - /* 01 011 */ dsp_btst, - /* 01 100 */ dsp_jsclr, - /* 01 101 */ dsp_jsset, - /* 01 110 */ dsp_jsclr, - /* 01 111 */ dsp_jsset, - - /* 10 000 */ dsp_bchg, - /* 10 001 */ dsp_btst, - /* 10 010 */ dsp_bchg, - /* 10 011 */ dsp_btst, - /* 10 100 */ dsp_jsclr, - /* 10 101 */ dsp_jsset, - /* 10 110 */ dsp_jsclr, - /* 10 111 */ dsp_jsset, - - /* 11 000 */ dsp_jsclr, - /* 11 001 */ dsp_jsclr, - /* 11 010 */ dsp_bchg, - /* 11 011 */ dsp_btst, - /* 11 100 */ dsp_jsr, - /* 11 101 */ dsp_jscc, - /* 11 110 */ dsp_undefined, - /* 11 111 */ dsp_undefined +static const dsp_emul_t opcodes_parmove[16] = { + dsp_pm_0, dsp_pm_1, dsp_pm_2, dsp_pm_3, dsp_pm_4, dsp_pm_5, dsp_pm_5, dsp_pm_5, + dsp_pm_8, dsp_pm_8, dsp_pm_8, dsp_pm_8, dsp_pm_8, dsp_pm_8, dsp_pm_8, dsp_pm_8 }; -static dsp_emul_t opcodes_parmove[16]={ - dsp_pm_0, - dsp_pm_1, - dsp_pm_2, - dsp_pm_3, - dsp_pm_4, - dsp_pm_5, - dsp_pm_5, - dsp_pm_5, - - dsp_pm_8, - dsp_pm_8, - dsp_pm_8, - dsp_pm_8, - dsp_pm_8, - dsp_pm_8, - dsp_pm_8, - dsp_pm_8 +static const dsp_emul_t opcodes_alu[256] = { + /* 0x00 - 0x3f */ + dsp_move , dsp_tfr_b_a, dsp_addr_b_a, dsp_tst_a, dsp_undefined, dsp_cmp_b_a, dsp_subr_a, dsp_cmpm_b_a, + dsp_undefined, dsp_tfr_a_b, dsp_addr_a_b, dsp_tst_b, dsp_undefined, dsp_cmp_a_b, dsp_subr_b, dsp_cmpm_a_b, + dsp_add_b_a, dsp_rnd_a, dsp_addl_b_a, dsp_clr_a, dsp_sub_b_a, dsp_undefined, dsp_subl_a, dsp_not_a, + dsp_add_a_b, dsp_rnd_b, dsp_addl_a_b, dsp_clr_b, dsp_sub_a_b, dsp_undefined, dsp_subl_b, dsp_not_b, + dsp_add_x_a, dsp_adc_x_a, dsp_asr_a, dsp_lsr_a, dsp_sub_x_a, dsp_sbc_x_a, dsp_abs_a, dsp_ror_a, + dsp_add_x_b, dsp_adc_x_b, dsp_asr_b, dsp_lsr_b, dsp_sub_x_b, dsp_sbc_x_b, dsp_abs_b, dsp_ror_b, + dsp_add_y_a, dsp_adc_y_a, dsp_asl_a, dsp_lsl_a, dsp_sub_y_a, dsp_sbc_y_a, dsp_neg_a, dsp_rol_a, + dsp_add_y_b, dsp_adc_y_b, dsp_asl_b, dsp_lsl_b, dsp_sub_y_b, dsp_sbc_y_b, dsp_neg_b, dsp_rol_b, + + /* 0x40 - 0x7f */ + dsp_add_x0_a, dsp_tfr_x0_a, dsp_or_x0_a, dsp_eor_x0_a, dsp_sub_x0_a, dsp_cmp_x0_a, dsp_and_x0_a, dsp_cmpm_x0_a, + dsp_add_x0_b, dsp_tfr_x0_b, dsp_or_x0_b, dsp_eor_x0_b, dsp_sub_x0_b, dsp_cmp_x0_b, dsp_and_x0_b, dsp_cmpm_x0_b, + dsp_add_y0_a, dsp_tfr_y0_a, dsp_or_y0_a, dsp_eor_y0_a, dsp_sub_y0_a, dsp_cmp_y0_a, dsp_and_y0_a, dsp_cmpm_y0_a, + dsp_add_y0_b, dsp_tfr_y0_b, dsp_or_y0_b, dsp_eor_y0_b, dsp_sub_y0_b, dsp_cmp_y0_b, dsp_and_y0_b, dsp_cmpm_y0_b, + dsp_add_x1_a, dsp_tfr_x1_a, dsp_or_x1_a, dsp_eor_x1_a, dsp_sub_x1_a, dsp_cmp_x1_a, dsp_and_x1_a, dsp_cmpm_x1_a, + dsp_add_x1_b, dsp_tfr_x1_b, dsp_or_x1_b, dsp_eor_x1_b, dsp_sub_x1_b, dsp_cmp_x1_b, dsp_and_x1_b, dsp_cmpm_x1_b, + dsp_add_y1_a, dsp_tfr_y1_a, dsp_or_y1_a, dsp_eor_y1_a, dsp_sub_y1_a, dsp_cmp_y1_a, dsp_and_y1_a, dsp_cmpm_y1_a, + dsp_add_y1_b, dsp_tfr_y1_b, dsp_or_y1_b, dsp_eor_y1_b, dsp_sub_y1_b, dsp_cmp_y1_b, dsp_and_y1_b, dsp_cmpm_y1_b, + + /* 0x80 - 0xbf */ + dsp_mpy_p_x0_x0_a, dsp_mpyr_p_x0_x0_a, dsp_mac_p_x0_x0_a, dsp_macr_p_x0_x0_a, dsp_mpy_m_x0_x0_a, dsp_mpyr_m_x0_x0_a, dsp_mac_m_x0_x0_a, dsp_macr_m_x0_x0_a, + dsp_mpy_p_x0_x0_b, dsp_mpyr_p_x0_x0_b, dsp_mac_p_x0_x0_b, dsp_macr_p_x0_x0_b, dsp_mpy_m_x0_x0_b, dsp_mpyr_m_x0_x0_b, dsp_mac_m_x0_x0_b, dsp_macr_m_x0_x0_b, + dsp_mpy_p_y0_y0_a, dsp_mpyr_p_y0_y0_a, dsp_mac_p_y0_y0_a, dsp_macr_p_y0_y0_a, dsp_mpy_m_y0_y0_a, dsp_mpyr_m_y0_y0_a, dsp_mac_m_y0_y0_a, dsp_macr_m_y0_y0_a, + dsp_mpy_p_y0_y0_b, dsp_mpyr_p_y0_y0_b, dsp_mac_p_y0_y0_b, dsp_macr_p_y0_y0_b, dsp_mpy_m_y0_y0_b, dsp_mpyr_m_y0_y0_b, dsp_mac_m_y0_y0_b, dsp_macr_m_y0_y0_b, + dsp_mpy_p_x1_x0_a, dsp_mpyr_p_x1_x0_a, dsp_mac_p_x1_x0_a, dsp_macr_p_x1_x0_a, dsp_mpy_m_x1_x0_a, dsp_mpyr_m_x1_x0_a, dsp_mac_m_x1_x0_a, dsp_macr_m_x1_x0_a, + dsp_mpy_p_x1_x0_b, dsp_mpyr_p_x1_x0_b, dsp_mac_p_x1_x0_b, dsp_macr_p_x1_x0_b, dsp_mpy_m_x1_x0_b, dsp_mpyr_m_x1_x0_b, dsp_mac_m_x1_x0_b, dsp_macr_m_x1_x0_b, + dsp_mpy_p_y1_y0_a, dsp_mpyr_p_y1_y0_a, dsp_mac_p_y1_y0_a, dsp_macr_p_y1_y0_a, dsp_mpy_m_y1_y0_a, dsp_mpyr_m_y1_y0_a, dsp_mac_m_y1_y0_a, dsp_macr_m_y1_y0_a, + dsp_mpy_p_y1_y0_b, dsp_mpyr_p_y1_y0_b, dsp_mac_p_y1_y0_b, dsp_macr_p_y1_y0_b, dsp_mpy_m_y1_y0_b, dsp_mpyr_m_y1_y0_b, dsp_mac_m_y1_y0_b, dsp_macr_m_y1_y0_b, + + /* 0xc0_m_ 0xff */ + dsp_mpy_p_x0_y1_a, dsp_mpyr_p_x0_y1_a, dsp_mac_p_x0_y1_a, dsp_macr_p_x0_y1_a, dsp_mpy_m_x0_y1_a, dsp_mpyr_m_x0_y1_a, dsp_mac_m_x0_y1_a, dsp_macr_m_x0_y1_a, + dsp_mpy_p_x0_y1_b, dsp_mpyr_p_x0_y1_b, dsp_mac_p_x0_y1_b, dsp_macr_p_x0_y1_b, dsp_mpy_m_x0_y1_b, dsp_mpyr_m_x0_y1_b, dsp_mac_m_x0_y1_b, dsp_macr_m_x0_y1_b, + dsp_mpy_p_y0_x0_a, dsp_mpyr_p_y0_x0_a, dsp_mac_p_y0_x0_a, dsp_macr_p_y0_x0_a, dsp_mpy_m_y0_x0_a, dsp_mpyr_m_y0_x0_a, dsp_mac_m_y0_x0_a, dsp_macr_m_y0_x0_a, + dsp_mpy_p_y0_x0_b, dsp_mpyr_p_y0_x0_b, dsp_mac_p_y0_x0_b, dsp_macr_p_y0_x0_b, dsp_mpy_m_y0_x0_b, dsp_mpyr_m_y0_x0_b, dsp_mac_m_y0_x0_b, dsp_macr_m_y0_x0_b, + dsp_mpy_p_x1_y0_a, dsp_mpyr_p_x1_y0_a, dsp_mac_p_x1_y0_a, dsp_macr_p_x1_y0_a, dsp_mpy_m_x1_y0_a, dsp_mpyr_m_x1_y0_a, dsp_mac_m_x1_y0_a, dsp_macr_m_x1_y0_a, + dsp_mpy_p_x1_y0_b, dsp_mpyr_p_x1_y0_b, dsp_mac_p_x1_y0_b, dsp_macr_p_x1_y0_b, dsp_mpy_m_x1_y0_b, dsp_mpyr_m_x1_y0_b, dsp_mac_m_x1_y0_b, dsp_macr_m_x1_y0_b, + dsp_mpy_p_y1_x1_a, dsp_mpyr_p_y1_x1_a, dsp_mac_p_y1_x1_a, dsp_macr_p_y1_x1_a, dsp_mpy_m_y1_x1_a, dsp_mpyr_m_y1_x1_a, dsp_mac_m_y1_x1_a, dsp_macr_m_y1_x1_a, + dsp_mpy_p_y1_x1_b, dsp_mpyr_p_y1_x1_b, dsp_mac_p_y1_x1_b, dsp_macr_p_y1_x1_b, dsp_mpy_m_y1_x1_b, dsp_mpyr_m_y1_x1_b, dsp_mac_m_y1_x1_b, dsp_macr_m_y1_x1_b }; -static dsp_emul_t opcodes_alu003f[64]={ - /* 0x00 - 0x0f */ - dsp_move, - dsp_tfr, - dsp_addr, - dsp_tst, - dsp_undefined, - dsp_cmp, - dsp_subr, - dsp_cmpm, - dsp_undefined, - dsp_tfr, - dsp_addr, - dsp_tst, - dsp_undefined, - dsp_cmp, - dsp_subr, - dsp_cmpm, - - /* 0x10 - 0x1f */ - dsp_add, - dsp_rnd, - dsp_addl, - dsp_clr, - dsp_sub, - dsp_undefined, - dsp_subl, - dsp_not, - dsp_add, - dsp_rnd, - dsp_addl, - dsp_clr, - dsp_sub, - dsp_undefined, - dsp_subl, - dsp_not, - - /* 0x20 - 0x2f */ - dsp_add, - dsp_adc, - dsp_asr, - dsp_lsr, - dsp_sub, - dsp_sbc, - dsp_abs, - dsp_ror, - dsp_add, - dsp_adc, - dsp_asr, - dsp_lsr, - dsp_sub, - dsp_sbc, - dsp_abs, - dsp_ror, - - /* 0x30 - 0x3f */ - dsp_add, - dsp_adc, - dsp_asl, - dsp_lsl, - dsp_sub, - dsp_sbc, - dsp_neg, - dsp_rol, - dsp_add, - dsp_adc, - dsp_asl, - dsp_lsl, - dsp_sub, - dsp_sbc, - dsp_neg, - dsp_rol -}; - -static dsp_emul_t opcodes_alu407f[16]={ - dsp_add, - dsp_tfr, - dsp_or, - dsp_eor, - dsp_sub, - dsp_cmp, - dsp_and, - dsp_cmpm, - dsp_add, - dsp_tfr, - dsp_or, - dsp_eor, - dsp_sub, - dsp_cmp, - dsp_and, - dsp_cmpm -}; - -static dsp_emul_t opcodes_alu80ff[4]={ - dsp_mpy, - dsp_mpyr, - dsp_mac, - dsp_macr -}; - -static dsp_emul_t opcodes_do[16]={ - dsp_do_0, - dsp_undefined, - dsp_do_2, - dsp_undefined, - - dsp_do_4, - dsp_undefined, - dsp_do_2, - dsp_undefined, - - dsp_undefined, - dsp_undefined, - dsp_do_2, - dsp_undefined, - - dsp_do_c, - dsp_undefined, - dsp_do_2, - dsp_undefined -}; - -static dsp_emul_t opcodes_rep[16]={ - dsp_undefined, - dsp_rep_1, - dsp_undefined, - dsp_rep_3, - - dsp_undefined, - dsp_rep_5, - dsp_undefined, - dsp_rep_3, - - dsp_undefined, - dsp_undefined, - dsp_undefined, - dsp_rep_3, - - dsp_undefined, - dsp_rep_d, - dsp_undefined, - dsp_rep_3 -}; - -static dsp_emul_t opcodes_movec[16]={ - dsp_undefined, - dsp_undefined, - dsp_undefined, - dsp_undefined, - - dsp_undefined, - dsp_undefined, - dsp_undefined, - dsp_movec_7, - - dsp_undefined, - dsp_movec_9, - dsp_undefined, - dsp_movec_b, - - dsp_undefined, - dsp_movec_d, - dsp_undefined, - dsp_movec_b -}; - -static dsp_emul_t opcodes_movep[4]={ - dsp_movep_0, - dsp_movep_1, - dsp_movep_2, - dsp_movep_2 -}; - -static int registers_lmove[8][2]={ - {DSP_REG_A1,DSP_REG_A0}, /* A10 */ - {DSP_REG_B1,DSP_REG_B0}, /* B10 */ - {DSP_REG_X1,DSP_REG_X0}, /* X */ - {DSP_REG_Y1,DSP_REG_Y0}, /* Y */ - {DSP_REG_A,DSP_REG_A}, /* A */ - {DSP_REG_B,DSP_REG_B}, /* B */ - {DSP_REG_A,DSP_REG_B}, /* AB */ - {DSP_REG_B,DSP_REG_A} /* BA */ -}; - -static int registers_tcc[16][2]={ +static const int registers_tcc[16][2] = { {DSP_REG_B,DSP_REG_A}, {DSP_REG_A,DSP_REG_B}, {DSP_REG_NULL,DSP_REG_NULL}, @@ -573,29 +660,17 @@ static int registers_tcc[16][2]={ {DSP_REG_Y1,DSP_REG_B} }; -static int registers_mpy[8][2]={ - {DSP_REG_X0,DSP_REG_X0}, - {DSP_REG_Y0,DSP_REG_Y0}, - {DSP_REG_X1,DSP_REG_X0}, - {DSP_REG_Y1,DSP_REG_Y0}, - - {DSP_REG_X0,DSP_REG_Y1}, - {DSP_REG_Y0,DSP_REG_X0}, - {DSP_REG_X1,DSP_REG_Y0}, - {DSP_REG_Y1,DSP_REG_X1} -}; - -static int registers_mask[64]={ +static const int registers_mask[64] = { 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 8, 8, 24, 24, 24, 24, - + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - + 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, @@ -604,101 +679,169 @@ static int registers_mask[64]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 8, 6, - 6, 6, 16, 16 + 16, 16, 16, 16 +}; + +static const dsp_interrupt_t dsp_interrupt[12] = { + {DSP_INTER_RESET , 0x00, 0, "Reset"}, + {DSP_INTER_ILLEGAL , 0x3e, 0, "Illegal"}, + {DSP_INTER_STACK_ERROR , 0x02, 0, "Stack Error"}, + {DSP_INTER_TRACE , 0x04, 0, "Trace"}, + {DSP_INTER_SWI , 0x06, 0, "Swi"}, + {DSP_INTER_HOST_COMMAND , 0xff, 1, "Host Command"}, + {DSP_INTER_HOST_RCV_DATA, 0x20, 1, "Host receive"}, + {DSP_INTER_HOST_TRX_DATA, 0x22, 1, "Host transmit"}, + {DSP_INTER_SSI_RCV_DATA_E, 0x0e, 2, "SSI receive with exception"}, + {DSP_INTER_SSI_RCV_DATA , 0x0c, 2, "SSI receive"}, + {DSP_INTER_SSI_TRX_DATA_E, 0x12, 2, "SSI transmit with exception"}, + {DSP_INTER_SSI_TRX_DATA , 0x10, 2, "SSI tramsmit"} }; + /********************************** * Emulator kernel **********************************/ -/* Yep, feel lazy, so put it there */ -static dsp_core_t *dsp_core; +void dsp56k_init_cpu(void) +{ + dsp56k_disasm_init(); + isDsp_in_disasm_mode = false; + start_time = SDL_GetTicks(); + num_inst = 0; +} -int dsp56k_do_execute(void *th_dsp_core) +/** + * Execute one instruction in trace mode at a given PC address. + * */ +Uint16 dsp56k_execute_one_disasm_instruction(FILE *out, Uint16 pc) { - Uint32 start_time, num_inst; + dsp_core_t *ptr1, *ptr2; + static dsp_core_t dsp_core_save; + Uint16 instruction_length; - dsp_core = th_dsp_core; -#ifdef DSP_DISASM - dsp56k_disasm_init(dsp_core); -#endif + ptr1 = &dsp_core; + ptr2 = &dsp_core_save; -#if DSP_DISASM_STATE - fprintf(stderr, "Dsp: WAIT_BOOTSTRAP\n"); -#endif - SDL_SemWait(dsp_core->semaphore); + /* Set DSP in disasm mode */ + isDsp_in_disasm_mode = true; - start_time = SDL_GetTicks(); - num_inst = 0; - while(dsp_core->running) { - dsp_execute_instruction(); -#if DSP_COUNT_IPS - ++num_inst; - if ((num_inst & 63) == 0) { - /* Evaluate time after instructions have been executed to avoid asking too frequently */ - Uint32 cur_time = SDL_GetTicks(); - if (cur_time-start_time>1000) { - fprintf(stderr, "Dsp: %d i/s\n", (num_inst*1000)/(cur_time-start_time)); - start_time=cur_time; - num_inst=0; - } - } -#endif - } + /* Save DSP context before executing instruction */ + memcpy(ptr2, ptr1, sizeof(dsp_core)); -#if DSP_DISASM_STATE - fprintf(stderr, "Dsp: SHUTDOWN\n"); -#endif - return 0; + /* execute and disasm instruction */ + dsp_core.pc = pc; + + /* Disasm instruction */ + instruction_length = dsp56k_disasm(DSP_DISASM_MODE, out) - 1; + + /* Execute instruction at address given in parameter to get the number of cycles it takes */ + dsp56k_execute_instruction(); + + fprintf(out, "%s", dsp56k_getInstructionText()); + + /* Restore DSP context after executing instruction */ + memcpy(ptr1, ptr2, sizeof(dsp_core)); + + /* Unset DSP in disasm mode */ + isDsp_in_disasm_mode = false; + + return instruction_length; } -static void dsp_execute_instruction(void) +void dsp56k_execute_instruction(void) { Uint32 value; + Uint32 disasm_return = 0; + disasm_memory_ptr = 0; -#ifdef DSP_DISASM -#if DSP_DISASM_REG - dsp56k_disasm_reg_read(); -#endif -#if DSP_DISASM_INST - dsp56k_disasm(); -#endif -#endif + /* Initialise the number of access to the external memory for this instruction */ + access_to_ext_memory = 0; + + /* Init the indirect AGU move instruction flag */ + dsp_core.agu_move_indirect_instr = 0; /* Decode and execute current instruction */ - cur_inst = read_memory(DSP_SPACE_P, dsp_core->pc); + cur_inst = read_memory_p(dsp_core.pc); + + /* Initialize instruction size and cycle counter */ cur_inst_len = 1; + dsp_core.instr_cycle = 2; + + /* Disasm current instruction ? (trace mode only) */ + if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM)) { + /* Call dsp56k_disasm only when DSP is called in trace mode */ + if (isDsp_in_disasm_mode == false) { + disasm_return = dsp56k_disasm(DSP_TRACE_MODE, TraceFile); - value = (cur_inst >> 16) & BITMASK(8); - if (value< 0x10) { + if (disasm_return != 0 && LOG_TRACE_LEVEL(TRACE_DSP_DISASM_REG)) { + /* DSP regs trace enabled only if DSP DISASM is enabled */ + dsp56k_disasm_reg_save(); + } + } + } + + if (cur_inst < 0x100000) { + value = (cur_inst >> 11) & (BITMASK(6) << 3); + value += (cur_inst >> 5) & BITMASK(3); opcodes8h[value](); } else { - dsp_parmove_read(); - value = cur_inst & BITMASK(8); - if (value < 0x40) { - opcodes_alu003f[value](); - } else if (value < 0x80) { - value &= BITMASK(4); - opcodes_alu407f[value](); - } else { - value &= BITMASK(2); - opcodes_alu80ff[value](); - } - dsp_parmove_write(); + /* Do parallel move read */ + opcodes_parmove[(cur_inst>>20) & BITMASK(4)](); } - /* Don't update the PC if we are halted */ - /*if (dsp_core->state == DSP_RUNNING)*/ { - dsp_postexecute_update_pc(); + /* Add the waitstate due to external memory access */ + /* (2 extra cycles per extra access to the external memory after the first one */ + if (access_to_ext_memory != 0) { + value = access_to_ext_memory & 1; + value += (access_to_ext_memory & 2) >> 1; + value += (access_to_ext_memory & 4) >> 2; + + if (value > 1) + dsp_core.instr_cycle += (value - 1) * 2; + } + + /* Disasm current instruction ? (trace mode only) */ + if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM)) { + /* Display only when DSP is called in trace mode */ + if (isDsp_in_disasm_mode == false) { + if (disasm_return != 0) { + fprintf(TraceFile, "%s", dsp56k_getInstructionText()); + + /* DSP regs trace enabled only if DSP DISASM is enabled */ + if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM_REG)) + dsp56k_disasm_reg_compare(TraceFile); + + if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM_MEM)) { + /* 1 memory change to display ? */ + if (disasm_memory_ptr == 1) + fprintf(TraceFile, "\t%s\n", str_disasm_memory[0]); + /* 2 memory changes to display ? */ + else if (disasm_memory_ptr == 2) { + fprintf(TraceFile, "\t%s\n", str_disasm_memory[0]); + fprintf(TraceFile, "\t%s\n", str_disasm_memory[1]); + } + } + } + } } - /* Interrupts ? */ + /* Process the PC */ + dsp_postexecute_update_pc(); + + /* Process Interrupts */ dsp_postexecute_interrupts(); -#ifdef DSP_DISASM -#if DSP_DISASM_REG - dsp56k_disasm_reg_compare(); -#endif +#if DSP_COUNT_IPS + ++num_inst; + if ((num_inst & 63) == 0) { + /* Evaluate time after instructions have been executed to avoid asking too frequently */ + Uint32 cur_time = SDL_GetTicks(); + if (cur_time-start_time>1000) { + fprintf(stderr, "Dsp: %d i/s\n", (num_inst*1000)/(cur_time-start_time)); + start_time=cur_time; + num_inst=0; + } + } #endif } @@ -709,60 +852,50 @@ static void dsp_execute_instruction(void static void dsp_postexecute_update_pc(void) { /* When running a REP, PC must stay on the current instruction */ - if (dsp_core->loop_rep) { - /* Is PC on the instruction to repeat ? */ - if (pc_on_rep==0) { - --dsp_core->registers[DSP_REG_LC]; - dsp_core->registers[DSP_REG_LC] &= BITMASK(16); + if (dsp_core.loop_rep) { + /* Is PC on the instruction to repeat ? */ + if (dsp_core.pc_on_rep==0) { + --dsp_core.registers[DSP_REG_LC]; + dsp_core.registers[DSP_REG_LC] &= BITMASK(16); - if (dsp_core->registers[DSP_REG_LC] > 0) { - cur_inst_len=0; /* Stay on this instruction */ + if (dsp_core.registers[DSP_REG_LC] > 0) { + cur_inst_len = 0; /* Stay on this instruction */ } else { - dsp_core->loop_rep = 0; - dsp_core->registers[DSP_REG_LC] = dsp_core->registers[DSP_REG_LCSAVE]; + dsp_core.loop_rep = 0; + dsp_core.registers[DSP_REG_LC] = dsp_core.registers[DSP_REG_LCSAVE]; } -#ifdef DSP_DISASM - dsp56k_disasm_force_reg_changed(DSP_REG_LC); -#endif } else { /* Init LC at right value */ - if (dsp_core->registers[DSP_REG_LC] == 0) { - dsp_core->registers[DSP_REG_LC] = 0x010000; -#ifdef DSP_DISASM - dsp56k_disasm_force_reg_changed(DSP_REG_LC); -#endif + if (dsp_core.registers[DSP_REG_LC] == 0) { + dsp_core.registers[DSP_REG_LC] = 0x010000; } - pc_on_rep = 0; + dsp_core.pc_on_rep = 0; } } /* Normal execution, go to next instruction */ - if (cur_inst_len>0) { - dsp_core->pc += cur_inst_len; - } + dsp_core.pc += cur_inst_len; /* When running a DO loop, we test the end of loop with the */ /* updated PC, pointing to last instruction of the loop */ - if (dsp_core->registers[DSP_REG_SR] & (1<pc == dsp_core->registers[DSP_REG_LA]+1) { - --dsp_core->registers[DSP_REG_LC]; - dsp_core->registers[DSP_REG_LC] &= BITMASK(16); - - if (dsp_core->registers[DSP_REG_LC]==0) { - /* end of loop */ - Uint32 newpc; - - dsp_stack_pop(&newpc, &dsp_core->registers[DSP_REG_SR]); - dsp_stack_pop(&dsp_core->registers[DSP_REG_LA], &dsp_core->registers[DSP_REG_LC]); + if (dsp_core.pc == dsp_core.registers[DSP_REG_LA] + 1) { + if (dsp_core.registers[DSP_REG_LC] == 1) { + /* end of the loop */ + Uint32 saved_pc, saved_sr; + + dsp_stack_pop(&saved_pc, &saved_sr); + dsp_core.registers[DSP_REG_SR] &= 0x7fff; + dsp_core.registers[DSP_REG_SR] |= saved_sr & (1<pc = dsp_core->stack[0][dsp_core->registers[DSP_REG_SSH]]; + --dsp_core.registers[DSP_REG_LC]; + dsp_core.registers[DSP_REG_LC] &= BITMASK(16); + dsp_core.pc = dsp_core.registers[DSP_REG_SSH]; } -#ifdef DSP_DISASM - dsp56k_disasm_force_reg_changed(DSP_REG_LC); -#endif } } } @@ -771,57 +904,194 @@ static void dsp_postexecute_update_pc(vo * Interrupts **********************************/ +/* Post a new interrupt to the interrupt table */ +void dsp_add_interrupt(Uint16 inter) +{ + /* detect if this interrupt is used or not */ + if (dsp_core.interrupt_ipl[inter] == -1) + return; + + /* add this interrupt to the pending interrupts table */ + if (dsp_core.interrupt_isPending[inter] == 0) { + dsp_core.interrupt_isPending[inter] = 1; + dsp_core.interrupt_counter ++; + } +} + +static void dsp_setInterruptIPL(Uint32 value) +{ + Uint32 ipl_ssi, ipl_hi, i; + + ipl_ssi = ((value >> 12) & 3) - 1; + ipl_hi = ((value >> 10) & 3) - 1; + + /* set IPL_HI */ + for (i=5; i<8; i++) { + dsp_core.interrupt_ipl[i] = ipl_hi; + } + + /* set IPL_SSI */ + for (i=8; i<12; i++) { + dsp_core.interrupt_ipl[i] = ipl_ssi; + } +} + static void dsp_postexecute_interrupts(void) { - Uint32 ipl, ipl_hi; - - ipl = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_I0) & BITMASK(2); - ipl_hi = (dsp_core->periph[DSP_SPACE_X][DSP_IPR]>>10) & BITMASK(2); - - /* Trace, level 3 */ - if (dsp_core->registers[DSP_REG_SR] & (1<0) && ((ipl_hi-1)>=ipl)) { + /* A fast interrupt can not be interrupted. */ + if (dsp_core.interrupt_state == DSP_INTERRUPT_DISABLED) { - /* Host transmit */ - if ( - (dsp_core->periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<periph[DSP_SPACE_X][DSP_HOST_HSR] & (1<periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<periph[DSP_SPACE_X][DSP_HOST_HSR] & (1<periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<periph[DSP_SPACE_X][DSP_HOST_HSR] & (1<>DSP_SR_I0) & BITMASK(2); + index = 0xffff; + ipl_to_raise = -1; + + /* Arbitrate between all pending interrupts */ + for (i=0; i<12; i++) { + if (dsp_core.interrupt_isPending[i] == 1) { + + /* level 3 interrupt ? */ + if (dsp_core.interrupt_ipl[i] == 3) { + index = i; + break; + } + + /* level 0, 1 ,2 interrupt ? */ + /* if interrupt is masked in SR, don't process it */ + if (dsp_core.interrupt_ipl[i] < ipl_sr) + continue; + + /* if interrupt is lower or equal than current arbitrated interrupt */ + if (dsp_core.interrupt_ipl[i] <= ipl_to_raise) + continue; + + /* save current arbitrated interrupt */ + index = i; + ipl_to_raise = dsp_core.interrupt_ipl[i]; } } + + /* If there's no interrupt to process, return */ + if (index == 0xffff) { + return; + } + + /* remove this interrupt from the pending interrupts table */ + dsp_core.interrupt_isPending[index] = 0; + dsp_core.interrupt_counter --; + + /* process arbritrated interrupt */ + ipl_to_raise = dsp_core.interrupt_ipl[index] + 1; + if (ipl_to_raise > 3) { + ipl_to_raise = 3; + } + + dsp_core.interrupt_instr_fetch = dsp_interrupt[index].vectorAddr; + dsp_core.interrupt_pipeline_count = 5; + dsp_core.interrupt_state = DSP_INTERRUPT_DISABLED; + dsp_core.interrupt_IplToRaise = ipl_to_raise; + + LOG_TRACE(TRACE_DSP_INTERRUPT, "Dsp interrupt: %s\n", dsp_interrupt[index].name); + + /* SSI receive data with exception ? */ + if (dsp_core.interrupt_instr_fetch == 0xe) { + dsp_core.periph[DSP_SPACE_X][DSP_SSI_SR] &= 0xff-(1<registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); - value = (*reg0) & 0xff; - numbits = 8; + scaling = (dsp_core.registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); switch(scaling) { case 0: - value <<=1; - value |= ((*reg1)>>23) & 1; - numbits=9; + /* Extension Bit (E) */ + value_e = (reg0<<1) + (reg1>>23); + if ((value_e != 0) && (value_e != BITMASK(9))) + dsp_core.registers[DSP_REG_SR] |= 1 << DSP_SR_E; + + /* Unnormalized bit (U) */ + if ((reg1 & 0xc00000) == 0 || (reg1 & 0xc00000) == 0xc00000) + dsp_core.registers[DSP_REG_SR] |= 1 << DSP_SR_U; break; case 1: + /* Extension Bit (E) */ + if ((reg0 != 0) && (reg0 != BITMASK(8))) + dsp_core.registers[DSP_REG_SR] |= 1 << DSP_SR_E; + + /* Unnormalized bit (U) */ + value_u = ((reg0<<1) + (reg1>>23)) & 3; + if (value_u == 0 || value_u == 3) + dsp_core.registers[DSP_REG_SR] |= 1 << DSP_SR_U; break; case 2: - value <<=2; - value |= ((*reg1)>>22) & 3; - numbits=10; + /* Extension Bit (E) */ + value_e = (reg0<<2) + (reg1>>22); + if ((value_e != 0) && (value_e != BITMASK(10))) + dsp_core.registers[DSP_REG_SR] |= 1 << DSP_SR_E; + + /* Unnormalized bit (U) */ + if ((reg1 & 0x600000) == 0 || (reg1 & 0x600000) == 0x600000) + dsp_core.registers[DSP_REG_SR] |= 1 << DSP_SR_U; break; default: return; break; } - if ((value==0) || (value==(Uint32)BITMASK(numbits))) { - sr_extension = 0; - } - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= sr_extension; + /* Zero Flag (Z) */ + if ((reg1 == 0) && (reg2 == 0) && (reg0 == 0)) + dsp_core.registers[DSP_REG_SR] |= 1 << DSP_SR_Z; + + /* Negative Flag (N) */ + dsp_core.registers[DSP_REG_SR] |= (reg0>>4) & 0x8; } -static void dsp_ccr_unnormalized(Uint32 *reg0, Uint32 *reg1) +/********************************** + * Read/Write memory functions + **********************************/ + +static Uint32 read_memory_disasm(int space, Uint16 address) { - Uint32 scaling, value; + /* Internal RAM ? */ + if (address<0x100) { + return dsp_core.ramint[space][address] & BITMASK(24); + } - scaling = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); + if (space==DSP_SPACE_P) { + return read_memory_p(address); + } - switch(scaling) { - case 0: - value = ((*reg1)>>22) & 3; - break; - case 1: - value = ((*reg0)<<1) & 2; - value |= ((*reg1)>>23) & 1; - break; - case 2: - value = ((*reg1)>>21) & 3; - break; - default: - return; - break; + /* Internal ROM? */ + if ((dsp_core.registers[DSP_REG_OMR] & (1<= 0xffc0) { + if ((space==DSP_SPACE_X) && (address==0xffc0+DSP_HOST_HTX)) { + return dsp_core.dsp_host_htx; + } + if ((space==DSP_SPACE_X) && (address==0xffc0+DSP_SSI_TX)) { + return dsp_core.ssi.transmit_value; + } + return dsp_core.periph[space][address-0xffc0] & BITMASK(24); + } + + /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ + address &= (DSP_RAMSIZE>>1) - 1; + if (space == DSP_SPACE_X) { + address += DSP_RAMSIZE>>1; } - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= ((value==0) || (value==BITMASK(2)))<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= (((*reg0)>>7) & 1)<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= zeroed<ramint[space][address] & BITMASK(24); - } - /* Internal ROM? */ - if ((dsp_core->registers[DSP_REG_OMR] & (1<rom[space][address] & BITMASK(24); - } - /* Peripheral address ? */ - if (address >= 0xffc0) { - return dsp_core->periph[space][address-0xffc0] & BITMASK(24); + /* Peripheral address ? */ + if (address >= 0xffc0) { + value = dsp_core.periph[space][address-0xffc0] & BITMASK(24); + if (space == DSP_SPACE_X) { + if (address == 0xffc0+DSP_HOST_HRX) { + value = dsp_core.dsp_host_rtx; + dsp_core_hostport_dspread(); } - /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ - if (space == DSP_SPACE_X) { - address += DSP_RAMSIZE>>1; + else if (address == 0xffc0+DSP_SSI_RX) { + value = dsp_core_ssi_readRX(); } - /* Falcon: External RAM, map X,Y to P */ - space = DSP_SPACE_P; - break; - case DSP_SPACE_P: - /* Internal RAM? */ - if (address<0x200) { - return dsp_core->ramint[space][address] & BITMASK(24); - } - break; + } + return value; } - /* External RAM, mask address to available ram size */ - return dsp_core->ram[space][address & (DSP_RAMSIZE-1)] & BITMASK(24); + /* Falcon: External X or Y RAM access */ + address &= (DSP_RAMSIZE>>1) - 1; + + if (space == DSP_SPACE_X) { + /* Map X to upper 16K of matching space in Y,P */ + address += DSP_RAMSIZE>>1; + + /* Set one access to the X external memory */ + access_to_ext_memory |= 1 << EXT_X_MEMORY; + } + else { + /* Access to the Y external memory */ + access_to_ext_memory |= 1 << EXT_Y_MEMORY; + } + + + /* Falcon: External RAM, finally map X,Y to P */ + return dsp_core.ramext[address & (DSP_RAMSIZE-1)] & BITMASK(24); } -#endif -static Uint32 read_memory(int space, Uint16 address) +static inline void write_memory(int space, Uint16 address, Uint32 value) { - address &= BITMASK(16); + if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM_MEM)) + write_memory_disasm(space, address, value); + else + write_memory_raw(space, address, value); +} - switch(space) { - case DSP_SPACE_X: - case DSP_SPACE_Y: - /* Internal RAM ?*/ - if (address<0x100) { - return dsp_core->ramint[space][address] & BITMASK(24); - } - /* Internal ROM ?*/ - if ((dsp_core->registers[DSP_REG_OMR] & (1<rom[space][address] & BITMASK(24); - } - /* Peripheral address ? */ - if (address >= 0xffc0) { - Uint32 value; - - SDL_LockMutex(dsp_core->mutex); - if ((space==DSP_SPACE_X) && (address==0xffc0+DSP_HOST_HRX)) { - dsp_core_hostport_dspread(dsp_core); - } - value = dsp_core->periph[space][address-0xffc0] & BITMASK(24); - SDL_UnlockMutex(dsp_core->mutex); +static void write_memory_raw(int space, Uint16 address, Uint32 value) +{ + value &= BITMASK(24); - return value; - } - /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ - if (space == DSP_SPACE_X) { - address += DSP_RAMSIZE>>1; + /* Peripheral address ? */ + if (address >= 0xffc0) { + if (space == DSP_SPACE_X) { + switch(address-0xffc0) { + case DSP_HOST_HTX: + dsp_core.dsp_host_htx = value; + dsp_core_hostport_dspwrite(); + break; + case DSP_HOST_HCR: + dsp_core.periph[DSP_SPACE_X][DSP_HOST_HCR] = value; + /* Set HF3 and HF2 accordingly on the host side */ + dsp_core.hostport[CPU_HOST_ISR] &= + BITMASK(8)-((1<ramint[space][address] & BITMASK(24); + return; + } + else if (space == DSP_SPACE_Y) { + dsp_core.periph[DSP_SPACE_Y][address-0xffc0] = value; + return; + } + } + + /* Internal RAM ? */ + if (address < 0x100) { + dsp_core.ramint[space][address] = value; + return; + } + + /* Internal ROM ? */ + if (address < 0x200) { + if (space != DSP_SPACE_P) { + if (dsp_core.registers[DSP_REG_OMR] & (1<ram[space][address & (DSP_RAMSIZE-1)] & BITMASK(24); + /* Access to X, Y or P external RAM */ + + if (space == DSP_SPACE_P) { + /* Access to the P external RAM */ + access_to_ext_memory |= 1 << EXT_P_MEMORY; + } + else { + address &= (DSP_RAMSIZE>>1) - 1; + + if (space == DSP_SPACE_X) { + /* Access to the X external RAM */ + /* map X to upper 16K of matching space in Y,P */ + address += DSP_RAMSIZE>>1; + access_to_ext_memory |= 1; + } + else { + /* Access to the Y external RAM */ + access_to_ext_memory |= 1 << EXT_Y_MEMORY; + } + } + + /* Falcon: External RAM, map X,Y to P */ + dsp_core.ramext[address & (DSP_RAMSIZE-1)] = value; } -/* Note: MACRO write_memory defined to either write_memory_raw or write_memory_disasm */ -static void write_memory_raw(int space, Uint32 address, Uint32 value) +static void write_memory_disasm(int space, Uint16 address, Uint32 value) { - address &= BITMASK(16); + Uint32 oldvalue, curvalue; + Uint8 space_c = 'p'; + value &= BITMASK(24); + oldvalue = read_memory_disasm(space, address); + + write_memory_raw(space,address,value); switch(space) { case DSP_SPACE_X: - /* Internal RAM ? */ - if (address<0x100) { - dsp_core->ramint[space][address] = value; - return; - } - /* Internal ROM ?*/ - if ((dsp_core->registers[DSP_REG_OMR] & (1<= 0xffc0) && (address <= 0xffff)) { - SDL_LockMutex(dsp_core->mutex); - switch(address-0xffc0) { - case DSP_HOST_HTX: - dsp_core->periph[space][DSP_HOST_HTX] = value; - - dsp_core_hostport_dspwrite(dsp_core); - break; - case DSP_HOST_HCR: - dsp_core->periph[space][DSP_HOST_HCR] = value; - /* Set HF3 and HF2 accordingly on the host side */ - dsp_core->hostport[CPU_HOST_ISR] &= - BITMASK(8)-((1<hostport[CPU_HOST_ISR] |= - dsp_core->periph[DSP_SPACE_X][DSP_HOST_HCR] & ((1<periph[space][address-0xffc0] = value; - break; - } - SDL_UnlockMutex(dsp_core->mutex); - return; - } - /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ - if (space == DSP_SPACE_X) { - address += DSP_RAMSIZE>>1; - } - /* Falcon: External RAM, map X to P */ - space = DSP_SPACE_P; + space_c = 'x'; break; case DSP_SPACE_Y: - /* Internal RAM ? */ - if (address<0x100) { - dsp_core->ramint[space][address] = value; - return; - } - /* Internal ROM ?*/ - if ((dsp_core->registers[DSP_REG_OMR] & (1<= 0xffc0) && (address <= 0xffff)) { - dsp_core->periph[space][address-0xffc0] = value; - return; - } - /* Falcon: External RAM, map Y to P */ - space = DSP_SPACE_P; + space_c = 'y'; break; - case DSP_SPACE_P: - /* Internal RAM ?*/ - if (address<0x200) { - dsp_core->ramint[space][address] = value; - return; - } + default: break; } - /* External RAM, mask address to available ram size */ - dsp_core->ram[space][address & (DSP_RAMSIZE-1)] = value; + curvalue = read_memory_disasm(space, address); + sprintf(str_disasm_memory[disasm_memory_ptr],"Mem: %c:0x%04x 0x%06x -> 0x%06x", space_c, address, oldvalue, curvalue); + disasm_memory_ptr ++; } -#if defined(DSP_DISASM) && (DSP_DISASM_MEM==1) -static void write_memory_disasm(int space, Uint32 address, Uint32 value) +static void dsp_write_reg(Uint32 numreg, Uint32 value) { - address &= BITMASK(16); - value &= BITMASK(24); - - Uint32 curvalue = read_memory_disasm(space, address); + Uint32 stack_error; - write_memory_raw(space,address,value); - - switch(space) { - case DSP_SPACE_P: - fprintf(stderr,"Dsp: Mem: p:0x%04x:0x%06x -> 0x%06x\n", address, curvalue, read_memory_disasm(space, address)); + switch (numreg) { + case DSP_REG_A: + dsp_core.registers[DSP_REG_A0] = 0; + dsp_core.registers[DSP_REG_A1] = value & BITMASK(24); + dsp_core.registers[DSP_REG_A2] = value & (1<<23) ? 0xff : 0x0; break; - case DSP_SPACE_X: - fprintf(stderr,"Dsp: Mem: x:0x%04x:0x%06x -> 0x%06x\n", address, curvalue, read_memory_disasm(space, address)); + case DSP_REG_B: + dsp_core.registers[DSP_REG_B0] = 0; + dsp_core.registers[DSP_REG_B1] = value & BITMASK(24); + dsp_core.registers[DSP_REG_B2] = value & (1<<23) ? 0xff : 0x0; + break; + case DSP_REG_R0: + case DSP_REG_R1: + case DSP_REG_R2: + case DSP_REG_R3: + case DSP_REG_R4: + case DSP_REG_R5: + case DSP_REG_R6: + case DSP_REG_R7: + case DSP_REG_N0: + case DSP_REG_N1: + case DSP_REG_N2: + case DSP_REG_N3: + case DSP_REG_N4: + case DSP_REG_N5: + case DSP_REG_N6: + case DSP_REG_N7: + case DSP_REG_M0: + case DSP_REG_M1: + case DSP_REG_M2: + case DSP_REG_M3: + case DSP_REG_M4: + case DSP_REG_M5: + case DSP_REG_M6: + case DSP_REG_M7: + dsp_core.registers[numreg] = value & BITMASK(16); + break; + case DSP_REG_OMR: + dsp_core.registers[DSP_REG_OMR] = value & 0xc7; + break; + case DSP_REG_SR: + dsp_core.registers[DSP_REG_SR] = value & 0xaf7f; + break; + case DSP_REG_SP: + stack_error = dsp_core.registers[DSP_REG_SP] & (3< 0x%06x\n", address, curvalue, read_memory_disasm(space, address)); + default: + dsp_core.registers[numreg] = value; + dsp_core.registers[numreg] &= BITMASK(registers_mask[numreg]); break; } } -#endif /********************************** * Stack push/pop **********************************/ -static void dsp_stack_push(Uint32 curpc, Uint32 cursr) +static void dsp_stack_push(Uint32 curpc, Uint32 cursr, Uint16 sshOnly) { - if (dsp_core->registers[DSP_REG_SP]==0x0f) { + Uint32 stack_error, underflow, stack; + + stack_error = dsp_core.registers[DSP_REG_SP] & (1<semaphore); - return; + dsp_add_interrupt(DSP_INTER_STACK_ERROR); + if (!isDsp_in_disasm_mode) + fprintf(stderr,"Dsp: Stack Overflow\n"); + if (ExceptionDebugMask & EXCEPT_DSP) + DebugUI(REASON_DSP_EXCEPTION); + } + + dsp_core.registers[DSP_REG_SP] = (underflow | stack_error | stack) & BITMASK(6); + stack &= BITMASK(4); + + if (stack) { + /* SSH part */ + dsp_core.stack[0][stack] = curpc & BITMASK(16); + /* SSL part, if instruction is not like "MOVEC xx, SSH" */ + if (sshOnly == 0) { + dsp_core.stack[1][stack] = cursr & BITMASK(16); + } + } else { + dsp_core.stack[0][0] = 0; + dsp_core.stack[1][0] = 0; } - dsp_core->registers[DSP_REG_SP]++; - dsp_core->registers[DSP_REG_SSH]++; - dsp_core->registers[DSP_REG_SSL]++; - - dsp_core->stack[0][dsp_core->registers[DSP_REG_SSH]]=curpc; - dsp_core->stack[1][dsp_core->registers[DSP_REG_SSL]]=cursr; + /* Update SSH and SSL registers */ + dsp_core.registers[DSP_REG_SSH] = dsp_core.stack[0][stack]; + dsp_core.registers[DSP_REG_SSL] = dsp_core.stack[1][stack]; } static void dsp_stack_pop(Uint32 *newpc, Uint32 *newsr) { - if (dsp_core->registers[DSP_REG_SP]==0x00) { - /* Stack empty, raise interrupt */ -#if DSP_DISASM_STATE - fprintf(stderr, "Dsp: Stack error (underflow)\n"); -#endif - SDL_SemWait(dsp_core->semaphore); - return; + Uint32 stack_error, underflow, stack; + + stack_error = dsp_core.registers[DSP_REG_SP] & (1<stack[0][dsp_core->registers[DSP_REG_SSH]]; - *newsr = dsp_core->stack[1][dsp_core->registers[DSP_REG_SSL]]; + dsp_core.registers[DSP_REG_SP] = (underflow | stack_error | stack) & BITMASK(6); + stack &= BITMASK(4); + *newpc = dsp_core.registers[DSP_REG_SSH]; + *newsr = dsp_core.registers[DSP_REG_SSL]; + + dsp_core.registers[DSP_REG_SSH] = dsp_core.stack[0][stack]; + dsp_core.registers[DSP_REG_SSL] = dsp_core.stack[1][stack]; +} + +static void dsp_compute_ssh_ssl(void) +{ + Uint32 stack; - --dsp_core->registers[DSP_REG_SP]; - --dsp_core->registers[DSP_REG_SSH]; - --dsp_core->registers[DSP_REG_SSL]; + stack = dsp_core.registers[DSP_REG_SP]; + stack &= BITMASK(4); + dsp_core.registers[DSP_REG_SSH] = dsp_core.stack[0][stack]; + dsp_core.registers[DSP_REG_SSL] = dsp_core.stack[1][stack]; } /********************************** @@ -1165,21 +1563,21 @@ static void dsp_stack_pop(Uint32 *newpc, static void dsp_update_rn(Uint32 numreg, Sint16 modifier) { - Sint16 value; + Uint32 value; Uint16 m_reg; - m_reg = (Uint16) dsp_core->registers[DSP_REG_M0+numreg]; - if (m_reg == 0) { + m_reg = (Uint16) dsp_core.registers[DSP_REG_M0+numreg]; + if (m_reg == 65535) { + /* Linear addressing mode */ + value = dsp_core.registers[DSP_REG_R0+numreg]|0x10000; + value += modifier; + dsp_core.registers[DSP_REG_R0+numreg] = value & BITMASK(16); + } else if (m_reg == 0) { /* Bit reversed carry update */ dsp_update_rn_bitreverse(numreg); - } else if ((m_reg>=1) && (m_reg<=32767)) { + } else if (m_reg<=32767) { /* Modulo update */ dsp_update_rn_modulo(numreg, modifier); - } else if (m_reg == 65535) { - /* Linear addressing mode */ - value = (Sint16) dsp_core->registers[DSP_REG_R0+numreg]; - value += modifier; - dsp_core->registers[DSP_REG_R0+numreg] = ((Uint32) value) & BITMASK(16); } else { /* Undefined */ } @@ -1191,16 +1589,16 @@ static void dsp_update_rn_bitreverse(Uin Uint32 value, r_reg; /* Check how many bits to reverse */ - value = dsp_core->registers[DSP_REG_N0+numreg]; + value = dsp_core.registers[DSP_REG_N0+numreg]; for (revbits=0;revbits<16;revbits++) { if (value & (1<registers[DSP_REG_R0+numreg]; + r_reg = dsp_core.registers[DSP_REG_R0+numreg]; value = r_reg & (BITMASK(16)-BITMASK(revbits)); for (i=0;iregisters[DSP_REG_R0+numreg] = value; + dsp_core.registers[DSP_REG_R0+numreg] = value; } static void dsp_update_rn_modulo(Uint32 numreg, Sint16 modifier) { - Uint16 bufsize, modulo, lobound, hibound, bufmask; - Sint16 r_reg; + Uint16 bufsize, bufmask, modulo, abs_modifier; + Uint32 r_reg, lobound, hibound; + + r_reg = dsp_core.registers[DSP_REG_R0+numreg]|0x10000; + modulo = dsp_core.registers[DSP_REG_M0+numreg]+1; + - modulo = (dsp_core->registers[DSP_REG_M0+numreg]+1) & BITMASK(16); bufsize = 1; - bufmask = BITMASK(16); while (bufsize < modulo) { bufsize <<= 1; - bufmask <<= 1; } - bufmask &= BITMASK(16); - - lobound = dsp_core->registers[DSP_REG_R0+numreg] & bufmask; + bufmask = bufsize - 1; + + + lobound = r_reg - (r_reg&bufmask); hibound = lobound + modulo - 1; - r_reg = (Sint16) (dsp_core->registers[DSP_REG_R0+numreg] & BITMASK(16)); - while (modifier>=bufsize) { - r_reg += bufsize; - modifier -= bufsize; - } - while (modifier<=-bufsize) { - r_reg -= bufsize; - modifier += bufsize; - } - r_reg += modifier; - if (r_reg>hibound) { - r_reg -= modulo; - } else if (r_regmodulo) { + if (abs_modifier&bufmask) { + fprintf(stderr,"Dsp: Modulo addressing result unpredictable\n"); + } else { + r_reg += modifier; + } + } else { + r_reg += modifier; + + + if (r_reg>hibound) { + r_reg -= modulo; + } else if (r_regregisters[DSP_REG_R0+numreg] = ((Uint32) r_reg) & BITMASK(16); + dsp_core.registers[DSP_REG_R0+numreg] = r_reg & BITMASK(16); } static int dsp_calc_ea(Uint32 ea_mode, Uint32 *dst_addr) @@ -1271,38 +1680,40 @@ static int dsp_calc_ea(Uint32 ea_mode, U switch (value) { case 0: /* (Rx)-Nx */ - *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; - dsp_update_rn(numreg, -dsp_core->registers[DSP_REG_N0+numreg]); + *dst_addr = dsp_core.registers[DSP_REG_R0+numreg]; + dsp_update_rn(numreg, -dsp_core.registers[DSP_REG_N0+numreg]); break; case 1: /* (Rx)+Nx */ - *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; - dsp_update_rn(numreg, dsp_core->registers[DSP_REG_N0+numreg]); + *dst_addr = dsp_core.registers[DSP_REG_R0+numreg]; + dsp_update_rn(numreg, dsp_core.registers[DSP_REG_N0+numreg]); break; case 2: /* (Rx)- */ - *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; + *dst_addr = dsp_core.registers[DSP_REG_R0+numreg]; dsp_update_rn(numreg, -1); break; case 3: /* (Rx)+ */ - *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; - dsp_update_rn(numreg, +1); + *dst_addr = dsp_core.registers[DSP_REG_R0+numreg]; + dsp_update_rn(numreg, 1); break; case 4: /* (Rx) */ - *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; + *dst_addr = dsp_core.registers[DSP_REG_R0+numreg]; break; case 5: /* (Rx+Nx) */ - curreg = dsp_core->registers[DSP_REG_R0+numreg]; - dsp_update_rn(numreg, dsp_core->registers[DSP_REG_N0+numreg]); - *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; - dsp_core->registers[DSP_REG_R0+numreg] = curreg; + dsp_core.instr_cycle += 2; + curreg = dsp_core.registers[DSP_REG_R0+numreg]; + dsp_update_rn(numreg, dsp_core.registers[DSP_REG_N0+numreg]); + *dst_addr = dsp_core.registers[DSP_REG_R0+numreg]; + dsp_core.registers[DSP_REG_R0+numreg] = curreg; break; case 6: /* aa */ - *dst_addr = read_memory(DSP_SPACE_P,dsp_core->pc+1); + dsp_core.instr_cycle += 2; + *dst_addr = read_memory_p(dsp_core.pc+1); cur_inst_len++; if (numreg != 0) { return 1; /* immediate value */ @@ -1310,8 +1721,9 @@ static int dsp_calc_ea(Uint32 ea_mode, U break; case 7: /* -(Rx) */ + dsp_core.instr_cycle += 2; dsp_update_rn(numreg, -1); - *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; + *dst_addr = dsp_core.registers[DSP_REG_R0+numreg]; break; } /* address */ @@ -1322,34 +1734,71 @@ static int dsp_calc_ea(Uint32 ea_mode, U * Condition code test **********************************/ -#define DSP_SR_NV 8 /* N xor V */ -#define DSP_SR_ZUE 9 /* Z or ((not U) and (not E)) */ -#define DSP_SR_ZNV 10 /* Z or (N xor V) */ - -#define CCR_BIT(x,y) \ - (((x) >> (y)) & 1) - -static int cc_code_map[8]={ - DSP_SR_C, - DSP_SR_NV, - DSP_SR_Z, - DSP_SR_N, - DSP_SR_ZUE, - DSP_SR_E, - DSP_SR_L, - DSP_SR_ZNV -}; - static int dsp_calc_cc(Uint32 cc_code) { - Uint16 value; + Uint16 value1, value2, value3; - value = dsp_core->registers[DSP_REG_SR] & BITMASK(8); - value |= (CCR_BIT(value,DSP_SR_N) ^ CCR_BIT(value, DSP_SR_V))<>3) & 1); + switch (cc_code) { + case 0: /* CC (HS) */ + value1 = dsp_core.registers[DSP_REG_SR] & (1<> DSP_SR_N) & 1; + value2 = (dsp_core.registers[DSP_REG_SR] >> DSP_SR_V) & 1; + return ((value1 ^ value2) == 0); + case 2: /* NE */ + value1 = dsp_core.registers[DSP_REG_SR] & (1<> DSP_SR_Z) & 1; + value2 = (~(dsp_core.registers[DSP_REG_SR] >> DSP_SR_U)) & 1; + value3 = (~(dsp_core.registers[DSP_REG_SR] >> DSP_SR_E)) & 1; + return ((value1 | (value2 & value3)) == 0); + case 5: /* EC */ + value1 = dsp_core.registers[DSP_REG_SR] & (1<> DSP_SR_N) & 1; + value2 = (dsp_core.registers[DSP_REG_SR] >> DSP_SR_V) & 1; + value3 = (dsp_core.registers[DSP_REG_SR] >> DSP_SR_Z) & 1; + return ((value3 | (value1 ^ value2)) == 0); + case 8: /* CS (LO) */ + value1 = dsp_core.registers[DSP_REG_SR] & (1<> DSP_SR_N) & 1; + value2 = (dsp_core.registers[DSP_REG_SR] >> DSP_SR_V) & 1; + return ((value1 ^ value2) == 1); + case 10: /* EQ */ + value1 = (dsp_core.registers[DSP_REG_SR] >> DSP_SR_Z) & 1; + return (value1==1); + case 11: /* MI */ + value1 = (dsp_core.registers[DSP_REG_SR] >> DSP_SR_N) & 1; + return (value1==1); + case 12: /* NR */ + value1 = (dsp_core.registers[DSP_REG_SR] >> DSP_SR_Z) & 1; + value2 = (~(dsp_core.registers[DSP_REG_SR] >> DSP_SR_U)) & 1; + value3 = (~(dsp_core.registers[DSP_REG_SR] >> DSP_SR_E)) & 1; + return ((value1 | (value2 & value3)) == 1); + case 13: /* ES */ + value1 = (dsp_core.registers[DSP_REG_SR] >> DSP_SR_E) & 1; + return (value1==1); + case 14: /* LS */ + value1 = (dsp_core.registers[DSP_REG_SR] >> DSP_SR_L) & 1; + return (value1==1); + case 15: /* LE */ + value1 = (dsp_core.registers[DSP_REG_SR] >> DSP_SR_N) & 1; + value2 = (dsp_core.registers[DSP_REG_SR] >> DSP_SR_V) & 1; + value3 = (dsp_core.registers[DSP_REG_SR] >> DSP_SR_Z) & 1; + return ((value3 | (value1 ^ value2)) == 1); + } + return 0; } /********************************** @@ -1358,376 +1807,438 @@ static int dsp_calc_cc(Uint32 cc_code) static void opcode8h_0(void) { - if (cur_inst <= 0x00008c) { - switch(cur_inst) { - case 0x000000: - dsp_nop(); - break; - case 0x000004: - dsp_rti(); - break; - case 0x000005: - dsp_illegal(); - break; - case 0x000006: - dsp_swi(); - break; - case 0x00000c: - dsp_rts(); - break; - case 0x000084: - dsp_reset(); - break; - case 0x000086: - dsp_wait(); - break; - case 0x000087: - dsp_stop(); - break; - case 0x00008c: - dsp_enddo(); - break; - } - } else { - switch (cur_inst & 0xf8) { - case 0x0000b8: - dsp_andi(); - break; - case 0x0000f8: - dsp_ori(); - break; - } + switch(cur_inst) { + case 0x000000: + dsp_nop(); + break; + case 0x000004: + dsp_rti(); + break; + case 0x000005: + dsp_illegal(); + break; + case 0x000006: + dsp_swi(); + break; + case 0x00000c: + dsp_rts(); + break; + case 0x000084: + dsp_reset(); + break; + case 0x000086: + dsp_wait(); + break; + case 0x000087: + dsp_stop(); + break; + case 0x00008c: + dsp_enddo(); + break; + default: + dsp_undefined(); + break; } } -static void opcode8h_1(void) +/********************************** + * Non-parallel moves instructions + **********************************/ + +static void dsp_undefined(void) { - switch(cur_inst & 0xfff8c7) { - case 0x018040: - dsp_div(); - break; - case 0x01c805: - dsp_norm(); - break; + if (isDsp_in_disasm_mode == false) { + cur_inst_len = 0; + fprintf(stderr, "Dsp: 0x%04x: 0x%06x Illegal instruction\n",dsp_core.pc, cur_inst); + /* Add some artificial CPU cycles to avoid being stuck in an infinite loop */ + dsp_core.instr_cycle += 100; + } + else { + cur_inst_len = 1; + dsp_core.instr_cycle = 0; + } + if (ExceptionDebugMask & EXCEPT_DSP) { + DebugUI(REASON_DSP_EXCEPTION); } } -static void opcode8h_4(void) +static void dsp_andi(void) { - switch((cur_inst>>5) & BITMASK(3)) { + Uint32 regnum, value; + + value = (cur_inst >> 8) & BITMASK(8); + regnum = cur_inst & BITMASK(2); + switch(regnum) { case 0: - dsp_lua(); + /* mr */ + dsp_core.registers[DSP_REG_SR] &= (value<<8)|BITMASK(8); break; - case 5: - dsp_movec(); + case 1: + /* ccr */ + dsp_core.registers[DSP_REG_SR] &= (BITMASK(8)<<8)|value; + break; + case 2: + /* omr */ + dsp_core.registers[DSP_REG_OMR] &= value; break; } } -static void opcode8h_6(void) +static void dsp_bchg_aa(void) { - if (cur_inst & (1<<5)) { - dsp_rep(); + Uint32 memspace, addr, value, newcarry, numbit; + + memspace = (cur_inst>>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + + addr = value; + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + if (newcarry) { + value -= (1<>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + + dsp_calc_ea(value, &addr); + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + if (newcarry) { + value -= (1<> 12) & BITMASK(4); - opcodes_0809[value](); + dsp_core.instr_cycle += 2; } -static void opcode8h_a(void) +static void dsp_bchg_pp(void) { - Uint32 value; - - value = (cur_inst >> 11) & (BITMASK(2)<<3); - value |= (cur_inst >> 5) & BITMASK(3); + Uint32 memspace, addr, value, newcarry, numbit; + + memspace = (cur_inst>>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); - opcodes_0a[value](); + addr = 0xffc0 + value; + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + if (newcarry) { + value -= (1<> 11) & (BITMASK(2)<<3); - value |= (cur_inst >> 5) & BITMASK(3); + Uint32 value, numreg, newcarry, numbit; - opcodes_0b[value](); + numreg = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); + } else { + value = dsp_core.registers[numreg]; + } + + newcarry = (value>>numbit) & 1; + if (newcarry) { + value -= (1<>6) & 1; + addr = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + value &= 0xffffffff-(1<pc, cur_inst); + Uint32 memspace, addr, value, newcarry, numbit; + + memspace = (cur_inst>>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + + dsp_calc_ea(value, &addr); + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + value &= 0xffffffff-(1<> 8) & BITMASK(8); - regnum = cur_inst & BITMASK(2); - switch(regnum) { - case 0: - /* mr */ - dsp_core->registers[DSP_REG_SR] &= (value<<8)|BITMASK(8); - break; - case 1: - /* ccr */ - dsp_core->registers[DSP_REG_SR] &= (BITMASK(8)<<8)|value; - break; - case 2: - /* omr */ - dsp_core->registers[DSP_REG_OMR] &= value; - break; + memspace = (cur_inst>>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + + addr = 0xffc0 + value; + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + value &= 0xffffffff-(1<>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); + } else { + value = dsp_core.registers[numreg]; } + + newcarry = (value>>numbit) & 1; + value &= 0xffffffff-(1<>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); - newcarry = 0; - switch((cur_inst>>14) & BITMASK(2)) { - case 0: - /* bchg #n,x:aa */ - /* bchg #n,y:aa */ - addr = value; - value = read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - if (newcarry) { - value -= (1<>numbit) & 1; - if (newcarry) { - value -= (1<>numbit) & 1; - if (newcarry) { - value -= (1<registers[numreg]; - newcarry = (value>>numbit) & 1; - if (newcarry) { - value -= (1<registers[numreg] = value; - if (((srcreg==DSP_REG_A) || (srcreg==DSP_REG_B)) && (numbit==23)) { - dsp_core->registers[DSP_REG_A2+(srcreg & 1)]= (newcarry ? 0x00 : 0xff); - } - break; - } + addr = value; + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + value |= (1<>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + + dsp_calc_ea(value, &addr); + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + value |= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); - newcarry = 0; + addr = 0xffc0 + value; + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + value |= (1<>14) & BITMASK(2)) { - case 0: - /* bclr #n,x:aa */ - /* bclr #n,y:aa */ - addr = value; - value = read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - value &= 0xffffffff-(1<>numbit) & 1; - value &= 0xffffffff-(1<>numbit) & 1; - value &= 0xffffffff-(1<registers[numreg]; - newcarry = (value>>numbit) & 1; - value &= 0xffffffff-(1<registers[numreg] = value; - if (((srcreg==DSP_REG_A) || (srcreg==DSP_REG_B)) && (numbit==23)) { - dsp_core->registers[DSP_REG_A2+(srcreg & 1)]=0x00; - } - break; + /* Set carry */ + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); + } else { + value = dsp_core.registers[numreg]; } + newcarry = (value>>numbit) & 1; + value |= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); - newcarry = 0; - switch((cur_inst>>14) & BITMASK(2)) { - case 0: - /* bset #n,x:aa */ - /* bset #n,y:aa */ - addr = value; - value = read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - value |= (1<>numbit) & 1; - value |= (1<>numbit) & 1; - value |= (1<registers[numreg]; - newcarry = (value>>numbit) & 1; - value |= (1<registers[numreg] = value; - if (((srcreg==DSP_REG_A) || (srcreg==DSP_REG_B)) && (numbit==23)) { - dsp_core->registers[DSP_REG_A2+(srcreg & 1)]=0xff; - } - break; - } + addr = value; + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); - newcarry = 0; - switch((cur_inst>>14) & BITMASK(2)) { - case 0: - /* btst #n,x:aa */ - /* btst #n,y:aa */ - addr = value; - value = read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - break; - case 1: - /* btst #n,x:ea */ - /* btst #n,y:ea */ - dsp_calc_ea(value, &addr); - value = read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - break; - case 2: - /* btst #n,x:pp */ - /* btst #n,y:pp */ - addr = 0xffc0 + value; - value = read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - break; - case 3: - /* btst #n,R */ - numreg = value; - if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { - numreg = DSP_REG_A1+(numreg & 1); - } - value = dsp_core->registers[numreg]; - newcarry = (value>>numbit) & 1; - break; + dsp_calc_ea(value, &addr); + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + + /* Set carry */ + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + + addr = 0xffc0 + value; + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + + /* Set carry */ + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); + } else { + value = dsp_core.registers[numreg]; } + newcarry = (value>>numbit) & 1; + /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<>3) & 1); - - source[0] = 0; - source[1] = dsp_core->registers[srcreg]; - if (source[1] & (1<<23)) { - source[0] = 0xff; - } source[2] = 0; + source[1] = dsp_core.registers[srcreg]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; - dest[0] = dsp_core->registers[DSP_REG_A2+(destreg & 1)]; - dest[1] = dsp_core->registers[DSP_REG_A1+(destreg & 1)]; - dest[2] = dsp_core->registers[DSP_REG_A0+(destreg & 1)]; + destreg = DSP_REG_A + ((cur_inst>>3) & 1); + if (destreg == DSP_REG_A) { + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + } + else { + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + } if (((dest[0]>>7) & 1) ^ ((source[1]>>23) & 1)) { /* D += S */ @@ -1765,408 +2279,617 @@ static void dsp_div(void) dsp_sub56(source, dest); } - dest[2] |= (dsp_core->registers[DSP_REG_SR]>>DSP_SR_C) & 1; + dest[2] |= (dsp_core.registers[DSP_REG_SR]>>DSP_SR_C) & 1; - dsp_core->registers[DSP_REG_A2+(destreg & 1)] = dest[0]; - dsp_core->registers[DSP_REG_A1+(destreg & 1)] = dest[1]; - dsp_core->registers[DSP_REG_A0+(destreg & 1)] = dest[2]; - - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= (1-((dest[0]>>7) & 1))<registers[DSP_REG_SR] |= newsr & (1<registers[DSP_REG_SR] |= newsr & (1<>7) & 1))<registers[DSP_REG_LA], dsp_core->registers[DSP_REG_LC]); - - dsp_core->registers[DSP_REG_LA] = read_memory(DSP_SPACE_P, dsp_core->pc+1) & BITMASK(16); - cur_inst_len++; - - dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR]); - - dsp_core->registers[DSP_REG_SR] |= (1<>12) & (BITMASK(2)<<2); - value |= (cur_inst>>6) & 1<<1; - value |= (cur_inst>>5) & 1; +/* + DO instruction parameter encoding - opcodes_do[value](); -} + xxxxxxxx 00xxxxxx 0xxxxxxx aa + xxxxxxxx 01xxxxxx 0xxxxxxx ea + xxxxxxxx YYxxxxxx 1xxxxxxx imm + xxxxxxxx 11xxxxxx 0xxxxxxx reg +*/ -static void dsp_do_0(void) +static void dsp_do_aa(void) { Uint32 memspace, addr; /* x:aa */ /* y:aa */ + dsp_stack_push(dsp_core.registers[DSP_REG_LA], dsp_core.registers[DSP_REG_LC], 0); + dsp_core.registers[DSP_REG_LA] = read_memory_p(dsp_core.pc+1) & BITMASK(16); + cur_inst_len++; + dsp_stack_push(dsp_core.pc+cur_inst_len, dsp_core.registers[DSP_REG_SR], 0); + dsp_core.registers[DSP_REG_SR] |= (1<>6) & 1; addr = (cur_inst>>8) & BITMASK(6); - dsp_core->registers[DSP_REG_LC] = read_memory(memspace, addr) & BITMASK(16); + dsp_core.registers[DSP_REG_LC] = read_memory(memspace, addr) & BITMASK(16); + + dsp_core.instr_cycle += 4; } -static void dsp_do_2(void) +static void dsp_do_imm(void) { /* #xx */ - dsp_core->registers[DSP_REG_LC] = (cur_inst>>8) & BITMASK(8); - dsp_core->registers[DSP_REG_LC] |= (cur_inst & BITMASK(4))<<8; + + dsp_stack_push(dsp_core.registers[DSP_REG_LA], dsp_core.registers[DSP_REG_LC], 0); + dsp_core.registers[DSP_REG_LA] = read_memory_p(dsp_core.pc+1) & BITMASK(16); + cur_inst_len++; + dsp_stack_push(dsp_core.pc+cur_inst_len, dsp_core.registers[DSP_REG_SR], 0); + dsp_core.registers[DSP_REG_SR] |= (1<>8) & BITMASK(8)) + + ((cur_inst & BITMASK(4))<<8); + + dsp_core.instr_cycle += 4; } -static void dsp_do_4(void) +static void dsp_do_ea(void) { Uint32 memspace, ea_mode, addr; /* x:ea */ /* y:ea */ + dsp_stack_push(dsp_core.registers[DSP_REG_LA], dsp_core.registers[DSP_REG_LC], 0); + dsp_core.registers[DSP_REG_LA] = read_memory_p(dsp_core.pc+1) & BITMASK(16); + cur_inst_len++; + dsp_stack_push(dsp_core.pc+cur_inst_len, dsp_core.registers[DSP_REG_SR], 0); + dsp_core.registers[DSP_REG_SR] |= (1<>6) & 1; ea_mode = (cur_inst>>8) & BITMASK(6); dsp_calc_ea(ea_mode, &addr); - dsp_core->registers[DSP_REG_LC] = read_memory(memspace, addr) & BITMASK(16); + dsp_core.registers[DSP_REG_LC] = read_memory(memspace, addr) & BITMASK(16); + + dsp_core.instr_cycle += 4; } -static void dsp_do_c(void) +static void dsp_do_reg(void) { Uint32 numreg; /* S */ + dsp_stack_push(dsp_core.registers[DSP_REG_LA], dsp_core.registers[DSP_REG_LC], 0); + dsp_core.registers[DSP_REG_LA] = read_memory_p(dsp_core.pc+1) & BITMASK(16); + cur_inst_len++; + numreg = (cur_inst>>8) & BITMASK(6); if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &dsp_core->registers[DSP_REG_LC]); + dsp_pm_read_accu24(numreg, &dsp_core.registers[DSP_REG_LC]); } else { - dsp_core->registers[DSP_REG_LC] = dsp_core->registers[numreg]; + dsp_core.registers[DSP_REG_LC] = dsp_core.registers[numreg]; } - dsp_core->registers[DSP_REG_LC] &= BITMASK(16); + dsp_core.registers[DSP_REG_LC] &= BITMASK(16); + + dsp_stack_push(dsp_core.pc+cur_inst_len, dsp_core.registers[DSP_REG_SR], 0); + dsp_core.registers[DSP_REG_SR] |= (1<registers[DSP_REG_SR]); - dsp_stack_pop(&dsp_core->registers[DSP_REG_LA], &dsp_core->registers[DSP_REG_LC]); + dsp_stack_pop(&saved_pc, &saved_sr); + dsp_core.registers[DSP_REG_SR] &= 0x7f; + dsp_core.registers[DSP_REG_SR] |= saved_sr & (1<> 16) & BITMASK(8)) { - case 0x0a: - dsp_calc_ea((cur_inst >>8) & BITMASK(6), &newpc); - cc_code=cur_inst & BITMASK(4); - break; - case 0x0e: - newpc = cur_inst & BITMASK(12); - cc_code=(cur_inst>>12) & BITMASK(4); - break; + newpc = cur_inst & BITMASK(12); + cc_code=(cur_inst>>12) & BITMASK(4); + if (dsp_calc_cc(cc_code)) { + dsp_core.pc = newpc; + cur_inst_len = 0; } + dsp_core.instr_cycle += 2; +} + +static void dsp_jcc_ea(void) +{ + Uint32 newpc, cc_code; + + dsp_calc_ea((cur_inst >>8) & BITMASK(6), &newpc); + cc_code=cur_inst & BITMASK(4); + if (dsp_calc_cc(cc_code)) { - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; } + + dsp_core.instr_cycle += 2; } -static void dsp_jclr(void) +static void dsp_jclr_aa(void) { - Uint32 memspace, addr, value, numreg, newpc, numbit; - + Uint32 memspace, addr, value, numbit, newaddr; + memspace = (cur_inst>>6) & 1; - value = (cur_inst>>8) & BITMASK(6); + addr = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); + value = read_memory(memspace, addr); + newaddr = read_memory_p(dsp_core.pc+1); - switch((cur_inst>>14) & BITMASK(2)) { - case 0: - /* jclr #n,x:aa,p:xx */ - /* jclr #n,y:aa,p:xx */ - addr = value; - value = read_memory(memspace, addr); - break; - case 1: - /* jclr #n,x:ea,p:xx */ - /* jclr #n,y:ea,p:xx */ - dsp_calc_ea(value, &addr); - value = read_memory(memspace, addr); - break; - case 2: - /* jclr #n,x:pp,p:xx */ - /* jclr #n,y:pp,p:xx */ - addr = 0xffc0 + value; - value = read_memory(memspace, addr); - break; - case 3: - /* jclr #n,R,p:xx */ - numreg = value; - value = dsp_core->registers[numreg]; - addr = 0xffff0000; /* invalid address */ - memspace = 0xffff0000; /* invalid memspace */ - break; - } + dsp_core.instr_cycle += 4; + if ((value & (1<pc+1); + memspace = (cur_inst>>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + newaddr = read_memory_p(dsp_core.pc+1); - /* Polling loop if jump to same PC as current JCLR instruction */ - pollingLoop = (newpc == dsp_core->pc); - if (!pollingLoop && (newpcpc)) { - /* or if only NOPs from jump address to current JCLR instruction */ - pollingLoop = 1; - for (i=newpc; ipc; i++) { - if (read_memory(DSP_SPACE_P, i) != 0) { - pollingLoop=0; - break; - } - } - } - if (!pollingLoop && (newpc+2 == dsp_core->pc)) { - /* or programs that re-set host port operation (Papa was a bladerunner/Eko) */ - pollingLoop = (read_memory(DSP_SPACE_P, newpc) == 0x08f4a0) /* movep #0x000001,x:0xffe0 */ - && (read_memory(DSP_SPACE_P, newpc+1) == 0x000001); - } + dsp_calc_ea(value, &addr); + value = read_memory(memspace, addr); - if (pollingLoop) { - /* Are we waiting for host port ? */ - if ((memspace==DSP_SPACE_X) && (addr==0xffc0+DSP_HOST_HSR)) { - /* Wait for host to write */ - if (numbit==DSP_HOST_HSR_HRDF) { -#if DSP_DISASM_STATE - fprintf(stderr, "Dsp: WAIT_HOSTWRITE\n"); -#endif - SDL_SemWait(dsp_core->semaphore); - } + dsp_core.instr_cycle += 4; - /* Wait for host to read */ - if (numbit==DSP_HOST_HSR_HTDE) { -#if DSP_DISASM_STATE - fprintf(stderr, "Dsp: WAIT_HOSTREAD\n"); -#endif - SDL_SemWait(dsp_core->semaphore); - } - } - } + if ((value & (1<pc = newpc; +static void dsp_jclr_pp(void) +{ + Uint32 memspace, addr, value, numbit, newaddr; + + memspace = (cur_inst>>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + addr = 0xffc0 + value; + value = read_memory(memspace, addr); + newaddr = read_memory_p(dsp_core.pc+1); + + dsp_core.instr_cycle += 4; + + if ((value & (1<> 16) & BITMASK(8)) { - case 0x0a: - dsp_calc_ea((cur_inst >>8) & BITMASK(6), &newpc); - break; - case 0x0c: - newpc = cur_inst & BITMASK(12); - break; + numreg = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + newaddr = read_memory_p(dsp_core.pc+1); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); + } else { + value = dsp_core.registers[numreg]; } - cur_inst_len = 0; + dsp_core.instr_cycle += 4; - /* Infinite loop ? */ - if (newpc == dsp_core->pc) { -#if DSP_DISASM_STATE - fprintf(stderr, "Dsp: JMP instruction, infinite loop\n"); -#endif - SDL_SemWait(dsp_core->semaphore); + if ((value & (1<>8) & BITMASK(6), &newpc); + cur_inst_len = 0; + dsp_core.pc = newpc; - dsp_core->pc = newpc; + dsp_core.instr_cycle += 2; } -static void dsp_jscc(void) +static void dsp_jmp_imm(void) +{ + Uint32 newpc; + + newpc = cur_inst & BITMASK(12); + cur_inst_len = 0; + dsp_core.pc = newpc; + + dsp_core.instr_cycle += 2; +} + +static void dsp_jscc_ea(void) { Uint32 newpc, cc_code; - cc_code = 0; - switch((cur_inst >> 16) & BITMASK(8)) { - case 0x0b: - dsp_calc_ea((cur_inst >>8) & BITMASK(6), &newpc); - cc_code=cur_inst & BITMASK(4); - break; - case 0x0f: - newpc = cur_inst & BITMASK(12); - cc_code=(cur_inst>>12) & BITMASK(4); - break; + dsp_calc_ea((cur_inst >>8) & BITMASK(6), &newpc); + cc_code=cur_inst & BITMASK(4); + + if (dsp_calc_cc(cc_code)) { + dsp_stack_push(dsp_core.pc+cur_inst_len, dsp_core.registers[DSP_REG_SR], 0); + dsp_core.pc = newpc; + cur_inst_len = 0; } + dsp_core.instr_cycle += 2; +} + +static void dsp_jscc_imm(void) +{ + Uint32 cc_code, newpc; + + newpc = cur_inst & BITMASK(12); + cc_code=(cur_inst>>12) & BITMASK(4); if (dsp_calc_cc(cc_code)) { - dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR]); + dsp_stack_push(dsp_core.pc+cur_inst_len, dsp_core.registers[DSP_REG_SR], 0); + dsp_core.pc = newpc; + cur_inst_len = 0; + } + + dsp_core.instr_cycle += 2; +} + +static void dsp_jsclr_aa(void) +{ + Uint32 memspace, addr, value, newpc, numbit, newaddr; - dsp_core->pc = newpc; + memspace = (cur_inst>>6) & 1; + addr = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + value = read_memory(memspace, addr); + newaddr = read_memory_p(dsp_core.pc+1); + + dsp_core.instr_cycle += 4; + + if ((value & (1<>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); + dsp_calc_ea(value, &addr); + value = read_memory(memspace, addr); + newaddr = read_memory_p(dsp_core.pc+1); - switch((cur_inst>>14) & BITMASK(2)) { - case 0: - /* jsclr #n,x:aa,p:xx */ - /* jsclr #n,y:aa,p:xx */ - addr = value; - value = read_memory(memspace, addr); - break; - case 1: - /* jsclr #n,x:ea,p:xx */ - /* jsclr #n,y:ea,p:xx */ - dsp_calc_ea(value, &addr); - value = read_memory(memspace, addr); - break; - case 2: - /* jsclr #n,x:pp,p:xx */ - /* jsclr #n,y:pp,p:xx */ - addr = 0xffc0 + value; - value = read_memory(memspace, addr); - break; - case 3: - /* jsclr #n,R,p:xx */ - numreg = value; - value = dsp_core->registers[numreg]; - break; - } + dsp_core.instr_cycle += 4; + if ((value & (1<>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + addr = 0xffc0 + value; + value = read_memory(memspace, addr); + newaddr = read_memory_p(dsp_core.pc+1); + + dsp_core.instr_cycle += 4; + if ((value & (1<pc+cur_inst_len, dsp_core->registers[DSP_REG_SR]); + dsp_stack_push(dsp_core.pc+2, dsp_core.registers[DSP_REG_SR], 0); + newpc = newaddr; + dsp_core.pc = newpc; + cur_inst_len = 0; + return; + } + ++cur_inst_len; +} + +static void dsp_jsclr_reg(void) +{ + Uint32 value, numreg, newpc, numbit, newaddr; + + numreg = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + newaddr = read_memory_p(dsp_core.pc+1); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); + } else { + value = dsp_core.registers[numreg]; + } + + dsp_core.instr_cycle += 4; - newpc = read_memory(DSP_SPACE_P, dsp_core->pc+1); - dsp_core->pc = newpc; + if ((value & (1<>6) & 1; - value = (cur_inst>>8) & BITMASK(6); + addr = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); + value = read_memory(memspace, addr); + newaddr = read_memory_p(dsp_core.pc+1); - switch((cur_inst>>14) & BITMASK(2)) { - case 0: - /* jset #n,x:aa,p:xx */ - /* jset #n,y:aa,p:xx */ - addr = value; - value = read_memory(memspace, addr); - break; - case 1: - /* jset #n,x:ea,p:xx */ - /* jset #n,y:ea,p:xx */ - dsp_calc_ea(value, &addr); - value = read_memory(memspace, addr); - break; - case 2: - /* jset #n,x:pp,p:xx */ - /* jset #n,y:pp,p:xx */ - addr = 0xffc0 + value; - value = read_memory(memspace, addr); - break; - case 3: - /* jset #n,R,p:xx */ - numreg = value; - value = dsp_core->registers[numreg]; - break; + dsp_core.instr_cycle += 4; + + if (value & (1<>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + dsp_calc_ea(value, &addr); + value = read_memory(memspace, addr); + newaddr = read_memory_p(dsp_core.pc+1); + + dsp_core.instr_cycle += 4; + + if (value & (1<>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + addr = 0xffc0 + value; + value = read_memory(memspace, addr); + newaddr = read_memory_p(dsp_core.pc+1); + + dsp_core.instr_cycle += 4; + if (value & (1<pc+1); + newpc = newaddr; + dsp_core.pc = newpc; + cur_inst_len=0; + return; + } + ++cur_inst_len; +} - dsp_core->pc = newpc; +static void dsp_jset_reg(void) +{ + Uint32 value, numreg, numbit, newpc, newaddr; + + numreg = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + newaddr = read_memory_p(dsp_core.pc+1); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); + } else { + value = dsp_core.registers[numreg]; + } + + dsp_core.instr_cycle += 4; + + if (value & (1<>12) & BITMASK(4))==0) { - newpc = cur_inst & BITMASK(12); - } else { - dsp_calc_ea((cur_inst>>8) & BITMASK(6),&newpc); + newpc = cur_inst & BITMASK(12); + + if (dsp_core.interrupt_state != DSP_INTERRUPT_LONG){ + dsp_stack_push(dsp_core.pc+cur_inst_len, dsp_core.registers[DSP_REG_SR], 0); + } + else { + dsp_core.interrupt_state = DSP_INTERRUPT_DISABLED; } - dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR]); + dsp_core.pc = newpc; + cur_inst_len = 0; + + dsp_core.instr_cycle += 2; +} + +static void dsp_jsr_ea(void) +{ + Uint32 newpc; + + dsp_calc_ea((cur_inst>>8) & BITMASK(6),&newpc); + + if (dsp_core.interrupt_state != DSP_INTERRUPT_LONG){ + dsp_stack_push(dsp_core.pc+cur_inst_len, dsp_core.registers[DSP_REG_SR], 0); + } + else { + dsp_core.interrupt_state = DSP_INTERRUPT_DISABLED; + } - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; + + dsp_core.instr_cycle += 2; } -static void dsp_jsset(void) +static void dsp_jsset_aa(void) { - Uint32 memspace, addr, value, numreg, newpc, numbit; - + Uint32 memspace, addr, value, newpc, numbit, newaddr; + memspace = (cur_inst>>6) & 1; - value = (cur_inst>>8) & BITMASK(6); + addr = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); + value = read_memory(memspace, addr); + newaddr = read_memory_p(dsp_core.pc+1); - switch((cur_inst>>14) & BITMASK(2)) { - case 0: - /* jsset #n,x:aa,p:xx */ - /* jsset #n,y:aa,p:xx */ - addr = value; - value = read_memory(memspace, addr); - break; - case 1: - /* jsset #n,x:ea,p:xx */ - /* jsset #n,y:ea,p:xx */ - dsp_calc_ea(value, &addr); - value = read_memory(memspace, addr); - break; - case 2: - /* jsset #n,x:pp,p:xx */ - /* jsset #n,y:pp,p:xx */ - addr = 0xffc0 + value; - value = read_memory(memspace, addr); - break; - case 3: - /* jsset #n,R,p:xx */ - numreg = value; - value = dsp_core->registers[numreg]; - break; + dsp_core.instr_cycle += 4; + + if (value & (1<>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + dsp_calc_ea(value, &addr); + value = read_memory(memspace, addr); + newaddr = read_memory_p(dsp_core.pc+1); + + dsp_core.instr_cycle += 4; + if (value & (1<>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + addr = 0xffc0 + value; + value = read_memory(memspace, addr); + newaddr = read_memory_p(dsp_core.pc+1); + + dsp_core.instr_cycle += 4; + if (value & (1<pc+cur_inst_len, dsp_core->registers[DSP_REG_SR]); + dsp_stack_push(dsp_core.pc+2, dsp_core.registers[DSP_REG_SR], 0); + newpc = newaddr; + dsp_core.pc = newpc; + cur_inst_len = 0; + return; + } + ++cur_inst_len; +} - newpc = read_memory(DSP_SPACE_P, dsp_core->pc+1); - dsp_core->pc = newpc; +static void dsp_jsset_reg(void) +{ + Uint32 value, numreg, newpc, numbit, newaddr; + + numreg = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + newaddr = read_memory_p(dsp_core.pc+1); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); + } else { + value = dsp_core.registers[numreg]; + } + + dsp_core.instr_cycle += 4; + + if (value & (1<>8) & BITMASK(3); - srcsave = dsp_core->registers[DSP_REG_R0+srcreg]; + srcsave = dsp_core.registers[DSP_REG_R0+srcreg]; dsp_calc_ea((cur_inst>>8) & BITMASK(5), &value); - srcnew = dsp_core->registers[DSP_REG_R0+srcreg]; - dsp_core->registers[DSP_REG_R0+srcreg] = srcsave; + srcnew = dsp_core.registers[DSP_REG_R0+srcreg]; + dsp_core.registers[DSP_REG_R0+srcreg] = srcsave; - dstreg = cur_inst & BITMASK(3); - - if (cur_inst & (1<<3)) { - dsp_core->registers[DSP_REG_N0+dstreg] = srcnew; - } else { - dsp_core->registers[DSP_REG_R0+dstreg] = srcnew; - } -} + if (cur_inst & (1<<3)) + dstreg = DSP_REG_N0 + (cur_inst & BITMASK(3)); + else + dstreg = DSP_REG_R0 + (cur_inst & BITMASK(3)); -static void dsp_movec(void) -{ - Uint32 value; - - value = (cur_inst>>13) & (1<<3); - value |= (cur_inst>>12) & (1<<2); - value |= (cur_inst>>6) & (1<<1); - value |= (cur_inst>>5) & 1; - - opcodes_movec[value](); + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(dstreg, srcnew); + dsp_core.instr_cycle += 2; } -static void dsp_movec_7(void) +static void dsp_movec_reg(void) { - Uint32 numreg1, numreg2, value; + Uint32 numreg1, numreg2, value, dummy; /* S1,D2 */ /* S2,D1 */ numreg2 = (cur_inst>>8) & BITMASK(6); - numreg1 = (cur_inst & BITMASK(5))|0x20; + numreg1 = cur_inst & BITMASK(6); + + dsp_core.agu_move_indirect_instr = 1; if (cur_inst & (1<<15)) { /* Write D1 */ if ((numreg2 == DSP_REG_A) || (numreg2 == DSP_REG_B)) { - dsp_pm_read_accu24(numreg2, &dsp_core->registers[numreg1]); + dsp_pm_read_accu24(numreg2, &value); } else { - dsp_core->registers[numreg1] = dsp_core->registers[numreg2]; + value = dsp_core.registers[numreg2]; } - dsp_core->registers[numreg1] &= BITMASK(registers_mask[numreg1]); + dsp_write_reg(numreg1, value); } else { /* Read S1 */ - - if ((numreg2 == DSP_REG_A) || (numreg2 == DSP_REG_B)) { - value = dsp_core->registers[numreg1]; - dsp_core->registers[DSP_REG_A2+(numreg2 & 1)] = 0; - if (value & (1<<23)) { - dsp_core->registers[DSP_REG_A2+(numreg2 & 1)] = 0xff; - } - dsp_core->registers[DSP_REG_A1+(numreg2 & 1)] = value & BITMASK(24); - dsp_core->registers[DSP_REG_A0+(numreg2 & 1)] = 0; - } else { - dsp_core->registers[numreg2] = dsp_core->registers[numreg1]; - dsp_core->registers[numreg2] &= BITMASK(registers_mask[numreg2]); + if (numreg1 == DSP_REG_SSH) { + dsp_stack_pop(&value, &dummy); + } + else { + value = dsp_core.registers[numreg1]; } + + dsp_write_reg(numreg2, value); } } -static void dsp_movec_9(void) +static void dsp_movec_aa(void) { - Uint32 numreg, addr, memspace; + Uint32 numreg, addr, memspace, value, dummy; /* x:aa,D1 */ /* S1,x:aa */ /* y:aa,D1 */ /* S1,y:aa */ - numreg = (cur_inst & BITMASK(5))|0x20; + numreg = cur_inst & BITMASK(6); addr = (cur_inst>>8) & BITMASK(6); memspace = (cur_inst>>6) & 1; if (cur_inst & (1<<15)) { /* Write D1 */ - - dsp_core->registers[numreg] = read_memory(memspace, addr); - dsp_core->registers[numreg] &= BITMASK(registers_mask[numreg]); + value = read_memory(memspace, addr); + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(numreg, value); } else { /* Read S1 */ - - write_memory(memspace, addr, dsp_core->registers[numreg]); + if (numreg == DSP_REG_SSH) { + dsp_stack_pop(&value, &dummy); + } + else { + value = dsp_core.registers[numreg]; + } + write_memory(memspace, addr, value); } } -static void dsp_movec_b(void) +static void dsp_movec_imm(void) { - Uint32 numreg; + Uint32 numreg, value; /* #xx,D1 */ - - numreg = (cur_inst & BITMASK(5))|0x20; - dsp_core->registers[numreg] = (cur_inst>>8) & BITMASK(8); + numreg = cur_inst & BITMASK(6); + value = (cur_inst>>8) & BITMASK(8); + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(numreg, value); } -static void dsp_movec_d(void) +static void dsp_movec_ea(void) { - Uint32 numreg, addr, memspace, ea_mode; + Uint32 numreg, addr, memspace, ea_mode, value, dummy; int retour; /* x:ea,D1 */ @@ -2284,82 +2999,90 @@ static void dsp_movec_d(void) /* S1,y:ea */ /* #xxxx,D1 */ - numreg = (cur_inst & BITMASK(5))|0x20; + numreg = cur_inst & BITMASK(6); ea_mode = (cur_inst>>8) & BITMASK(6); memspace = (cur_inst>>6) & 1; if (cur_inst & (1<<15)) { /* Write D1 */ - retour = dsp_calc_ea(ea_mode, &addr); if (retour) { - dsp_core->registers[numreg] = addr; + value = addr; } else { - dsp_core->registers[numreg] = read_memory(memspace, addr); + value = read_memory(memspace, addr); } - dsp_core->registers[numreg] &= BITMASK(registers_mask[numreg]); + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(numreg, value); } else { /* Read S1 */ - - retour = dsp_calc_ea(ea_mode, &addr); - - write_memory(memspace, addr, dsp_core->registers[numreg]); + dsp_calc_ea(ea_mode, &addr); + if (numreg == DSP_REG_SSH) { + dsp_stack_pop(&value, &dummy); + } + else { + value = dsp_core.registers[numreg]; + } + write_memory(memspace, addr, value); } } -static void dsp_movem(void) +static void dsp_movem_aa(void) { - Uint32 numreg, addr, ea_mode, value; + Uint32 numreg, addr, value, dummy; numreg = cur_inst & BITMASK(6); - - if (cur_inst & (1<<14)) { - /* S,p:ea */ - /* p:ea,D */ - - ea_mode = (cur_inst>>8) & BITMASK(6); - dsp_calc_ea(ea_mode, &addr); - } else { - /* S,p:aa */ - /* p:aa,D */ - - addr = (cur_inst>>8) & BITMASK(6); - } + addr = (cur_inst>>8) & BITMASK(6); if (cur_inst & (1<<15)) { /* Write D */ - - if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - value = read_memory(DSP_SPACE_P, addr); - dsp_core->registers[DSP_REG_A2+(numreg & 1)] = 0; - if (value & (1<<23)) { - dsp_core->registers[DSP_REG_A2+(numreg & 1)] = 0xff; - } - dsp_core->registers[DSP_REG_A1+(numreg & 1)] = value & BITMASK(24); - dsp_core->registers[DSP_REG_A0+(numreg & 1)] = 0; - } else { - dsp_core->registers[numreg] = read_memory(DSP_SPACE_P, addr); - dsp_core->registers[numreg] &= BITMASK(registers_mask[numreg]); - } + value = read_memory_p(addr); + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(numreg, value); } else { /* Read S */ - - if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &value); - } else { - value = dsp_core->registers[numreg]; + if (numreg == DSP_REG_SSH) { + dsp_stack_pop(&value, &dummy); + } + else if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); + } + else { + value = dsp_core.registers[numreg]; } write_memory(DSP_SPACE_P, addr, value); } + + dsp_core.instr_cycle += 4; } -static void dsp_movep(void) +static void dsp_movem_ea(void) { - Uint32 value; - - value = (cur_inst>>6) & BITMASK(2); + Uint32 numreg, addr, ea_mode, value, dummy; - opcodes_movep[value](); + numreg = cur_inst & BITMASK(6); + ea_mode = (cur_inst>>8) & BITMASK(6); + dsp_calc_ea(ea_mode, &addr); + + if (cur_inst & (1<<15)) { + /* Write D */ + value = read_memory_p(addr); + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(numreg, value); + } else { + /* Read S */ + if (numreg == DSP_REG_SSH) { + dsp_stack_pop(&value, &dummy); + } + else if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); + } + else { + value = dsp_core.registers[numreg]; + } + write_memory(DSP_SPACE_P, addr, value); + } + + dsp_core.instr_cycle += 4; } static void dsp_movep_0(void) @@ -2368,8 +3091,8 @@ static void dsp_movep_0(void) /* x:pp,D */ /* S,y:pp */ /* y:pp,D */ - - Uint32 addr, memspace, numreg, value; + + Uint32 addr, memspace, numreg, value, dummy; addr = 0xffc0 + (cur_inst & BITMASK(6)); memspace = (cur_inst>>16) & 1; @@ -2377,30 +3100,24 @@ static void dsp_movep_0(void) if (cur_inst & (1<<15)) { /* Write pp */ - if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &value); - } else { - value = dsp_core->registers[numreg]; + dsp_pm_read_accu24(numreg, &value); + } + else if (numreg == DSP_REG_SSH) { + dsp_stack_pop(&value, &dummy); + } + else { + value = dsp_core.registers[numreg]; } write_memory(memspace, addr, value); } else { /* Read pp */ - value = read_memory(memspace, addr); - - if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_core->registers[DSP_REG_A2+(numreg & 1)] = 0; - if (value & (1<<23)) { - dsp_core->registers[DSP_REG_A2+(numreg & 1)] = 0xff; - } - dsp_core->registers[DSP_REG_A1+(numreg & 1)] = value & BITMASK(24); - dsp_core->registers[DSP_REG_A0+(numreg & 1)] = 0; - } else { - dsp_core->registers[numreg] = value; - dsp_core->registers[numreg] &= BITMASK(registers_mask[numreg]); - } + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(numreg, value); } + + dsp_core.instr_cycle += 2; } static void dsp_movep_1(void) @@ -2418,14 +3135,19 @@ static void dsp_movep_1(void) if (cur_inst & (1<<15)) { /* Write pp */ - write_memory(memspace, xyaddr, read_memory(DSP_SPACE_P, paddr)); + write_memory(memspace, xyaddr, read_memory_p(paddr)); } else { /* Read pp */ write_memory(DSP_SPACE_P, paddr, read_memory(memspace, xyaddr)); } + + /* Movep is 4 cycles, but according to the motorola doc, */ + /* movep from p memory to x or y peripheral memory takes */ + /* 2 more cycles, so +4 cycles at total */ + dsp_core.instr_cycle += 4; } -static void dsp_movep_2(void) +static void dsp_movep_23(void) { /* x:ea,x:pp */ /* y:ea,x:pp */ @@ -2443,14 +3165,14 @@ static void dsp_movep_2(void) peraddr = 0xffc0 + (cur_inst & BITMASK(6)); perspace = (cur_inst>>16) & 1; - + ea_mode = (cur_inst>>8) & BITMASK(6); easpace = (cur_inst>>6) & 1; retour = dsp_calc_ea(ea_mode, &addr); if (cur_inst & (1<<15)) { /* Write pp */ - + if (retour) { write_memory(perspace, peraddr, addr); } else { @@ -2458,9 +3180,10 @@ static void dsp_movep_2(void) } } else { /* Read pp */ - write_memory(easpace, addr, read_memory(perspace, peraddr)); } + + dsp_core.instr_cycle += 2; } static void dsp_norm(void) @@ -2468,7 +3191,7 @@ static void dsp_norm(void) Uint32 cursr,cur_e, cur_euz, dest[3], numreg, rreg; Uint16 newsr; - cursr = dsp_core->registers[DSP_REG_SR]; + cursr = dsp_core.registers[DSP_REG_SR]; cur_e = (cursr>>DSP_SR_E) & 1; /* E */ cur_euz = ~cur_e; /* (not E) and U and (not Z) */ cur_euz &= (cursr>>DSP_SR_U) & 1; @@ -2476,34 +3199,31 @@ static void dsp_norm(void) cur_euz &= 1; numreg = (cur_inst>>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; + dest[0] = dsp_core.registers[DSP_REG_A2+numreg]; + dest[1] = dsp_core.registers[DSP_REG_A1+numreg]; + dest[2] = dsp_core.registers[DSP_REG_A0+numreg]; rreg = DSP_REG_R0+((cur_inst>>8) & BITMASK(3)); if (cur_euz) { newsr = dsp_asl56(dest); - --dsp_core->registers[rreg]; - dsp_core->registers[rreg] &= BITMASK(16); + --dsp_core.registers[rreg]; + dsp_core.registers[rreg] &= BITMASK(16); } else if (cur_e) { newsr = dsp_asr56(dest); - ++dsp_core->registers[rreg]; - dsp_core->registers[rreg] &= BITMASK(16); + ++dsp_core.registers[rreg]; + dsp_core.registers[rreg] &= BITMASK(16); } else { newsr = 0; } - dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; - - dsp_ccr_extension(&dest[0], &dest[1]); - dsp_ccr_unnormalized(&dest[0], &dest[1]); - dsp_ccr_negative(&dest[0]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_core.registers[DSP_REG_A2+numreg] = dest[0]; + dsp_core.registers[DSP_REG_A1+numreg] = dest[1]; + dsp_core.registers[DSP_REG_A0+numreg] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= value<<8; + dsp_core.registers[DSP_REG_SR] |= value<<8; break; case 1: /* ccr */ - dsp_core->registers[DSP_REG_SR] |= value; + dsp_core.registers[DSP_REG_SR] |= value; break; case 2: /* omr */ - dsp_core->registers[DSP_REG_OMR] |= value; + dsp_core.registers[DSP_REG_OMR] |= value; break; } } -static void dsp_rep(void) -{ - Uint32 value; - - dsp_core->registers[DSP_REG_LCSAVE] = dsp_core->registers[DSP_REG_LC]; - - value = (cur_inst>>12) & (BITMASK(2)<<2); - value |= (cur_inst>>6) & (1<<1); - value |= (cur_inst>>5) & 1; +/* + REP instruction parameter encoding - opcodes_rep[value](); - pc_on_rep = 1; /* Not decrement LC at first time */ - dsp_core->loop_rep = 1; /* We are now running rep */ -} + xxxxxxxx 00xxxxxx 0xxxxxxx aa + xxxxxxxx 01xxxxxx 0xxxxxxx ea + xxxxxxxx YYxxxxxx 1xxxxxxx imm + xxxxxxxx 11xxxxxx 0xxxxxxx reg +*/ -static void dsp_rep_1(void) +static void dsp_rep_aa(void) { /* x:aa */ /* y:aa */ + dsp_core.registers[DSP_REG_LCSAVE] = dsp_core.registers[DSP_REG_LC]; + dsp_core.pc_on_rep = 1; /* Not decrement LC at first time */ + dsp_core.loop_rep = 1; /* We are now running rep */ + + dsp_core.registers[DSP_REG_LC]=read_memory((cur_inst>>6) & 1,(cur_inst>>8) & BITMASK(6)); - dsp_core->registers[DSP_REG_LC]=read_memory((cur_inst>>6) & 1,(cur_inst>>8) & BITMASK(6)); + dsp_core.instr_cycle += 2; } -static void dsp_rep_3(void) +static void dsp_rep_imm(void) { /* #xxx */ - dsp_core->registers[DSP_REG_LC]= (cur_inst>>8) & BITMASK(8); + dsp_core.registers[DSP_REG_LCSAVE] = dsp_core.registers[DSP_REG_LC]; + dsp_core.pc_on_rep = 1; /* Not decrement LC at first time */ + dsp_core.loop_rep = 1; /* We are now running rep */ + + dsp_core.registers[DSP_REG_LC] = ((cur_inst>>8) & BITMASK(8)) + + ((cur_inst & BITMASK(4))<<8); + + dsp_core.instr_cycle += 2; } -static void dsp_rep_5(void) +static void dsp_rep_ea(void) { Uint32 value; /* x:ea */ /* y:ea */ + dsp_core.registers[DSP_REG_LCSAVE] = dsp_core.registers[DSP_REG_LC]; + dsp_core.pc_on_rep = 1; /* Not decrement LC at first time */ + dsp_core.loop_rep = 1; /* We are now running rep */ + dsp_calc_ea((cur_inst>>8) & BITMASK(6),&value); - dsp_core->registers[DSP_REG_LC]= read_memory((cur_inst>>6) & 1, value); + dsp_core.registers[DSP_REG_LC]= read_memory((cur_inst>>6) & 1, value); + + dsp_core.instr_cycle += 2; } -static void dsp_rep_d(void) +static void dsp_rep_reg(void) { Uint32 numreg; /* R */ + dsp_core.registers[DSP_REG_LCSAVE] = dsp_core.registers[DSP_REG_LC]; + dsp_core.pc_on_rep = 1; /* Not decrement LC at first time */ + dsp_core.loop_rep = 1; /* We are now running rep */ + numreg = (cur_inst>>8) & BITMASK(6); if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &dsp_core->registers[DSP_REG_LC]); + dsp_pm_read_accu24(numreg, &dsp_core.registers[DSP_REG_LC]); } else { - dsp_core->registers[DSP_REG_LC] = dsp_core->registers[numreg]; + dsp_core.registers[DSP_REG_LC] = dsp_core.registers[numreg]; } - dsp_core->registers[DSP_REG_LC] &= BITMASK(16); + dsp_core.registers[DSP_REG_LC] &= BITMASK(16); + + dsp_core.instr_cycle += 2; } static void dsp_reset(void) { /* Reset external peripherals */ + dsp_core.instr_cycle += 2; } static void dsp_rti(void) @@ -2594,11 +3333,11 @@ static void dsp_rti(void) Uint32 newpc = 0, newsr = 0; dsp_stack_pop(&newpc, &newsr); - - dsp_core->pc = newpc; - dsp_core->registers[DSP_REG_SR] = newsr; - + dsp_core.pc = newpc; + dsp_core.registers[DSP_REG_SR] = newsr; cur_inst_len = 0; + + dsp_core.instr_cycle += 2; } static void dsp_rts(void) @@ -2606,31 +3345,28 @@ static void dsp_rts(void) Uint32 newpc = 0, newsr; dsp_stack_pop(&newpc, &newsr); - - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; + + dsp_core.instr_cycle += 2; } static void dsp_stop(void) { -#if DSP_DISASM_STATE - fprintf(stderr, "Dsp: STOP instruction\n"); -#endif - SDL_SemWait(dsp_core->semaphore); + LOG_TRACE(TRACE_DSP_STATE, "Dsp: STOP instruction\n"); } static void dsp_swi(void) { /* Raise interrupt p:0x0006 */ -#if DSP_DISASM_INTER - fprintf(stderr, "Dsp: Interrupt: Swi\n"); -#endif + dsp_core.instr_cycle += 6; } static void dsp_tcc(void) { - Uint32 cc_code, regsrc1, regdest1, value; + Uint32 cc_code, regsrc1, regdest1; Uint32 regsrc2, regdest2; + Uint32 val0, val1, val2; cc_code = (cur_inst>>12) & BITMASK(4); @@ -2639,285 +3375,225 @@ static void dsp_tcc(void) regdest1 = registers_tcc[(cur_inst>>3) & BITMASK(4)][1]; /* Read S1 */ - if ((regsrc1 == DSP_REG_A) || (regsrc1 == DSP_REG_B)) { - tmp_parmove_src[0][0]=dsp_core->registers[DSP_REG_A2+(regsrc1 & 1)]; - tmp_parmove_src[0][1]=dsp_core->registers[DSP_REG_A1+(regsrc1 & 1)]; - tmp_parmove_src[0][2]=dsp_core->registers[DSP_REG_A0+(regsrc1 & 1)]; - } else { - value = dsp_core->registers[regsrc1]; - tmp_parmove_src[0][0]=0; - if (value & (1<<23)) { - tmp_parmove_src[0][0]=0x0000ff; - } - tmp_parmove_src[0][1]=value; - tmp_parmove_src[0][2]=0; + if (regsrc1 == DSP_REG_A) { + val0 = dsp_core.registers[DSP_REG_A0]; + val1 = dsp_core.registers[DSP_REG_A1]; + val2 = dsp_core.registers[DSP_REG_A2]; + } + else if (regsrc1 == DSP_REG_B) { + val0 = dsp_core.registers[DSP_REG_B0]; + val1 = dsp_core.registers[DSP_REG_B1]; + val2 = dsp_core.registers[DSP_REG_B2]; + } + else { + val0 = 0; + val1 = dsp_core.registers[regsrc1]; + val2 = val1 & (1<<23) ? 0xff : 0x0; } - + /* Write D1 */ - dsp_core->registers[DSP_REG_A2+(regdest1 & 1)]=tmp_parmove_src[0][0]; - dsp_core->registers[DSP_REG_A1+(regdest1 & 1)]=tmp_parmove_src[0][1]; - dsp_core->registers[DSP_REG_A0+(regdest1 & 1)]=tmp_parmove_src[0][2]; + if (regdest1 == DSP_REG_A) { + dsp_core.registers[DSP_REG_A2] = val2; + dsp_core.registers[DSP_REG_A1] = val1; + dsp_core.registers[DSP_REG_A0] = val0; + } + else { + dsp_core.registers[DSP_REG_B2] = val2; + dsp_core.registers[DSP_REG_B1] = val1; + dsp_core.registers[DSP_REG_B0] = val0; + } /* S2,D2 transfer */ if (cur_inst & (1<<16)) { regsrc2 = DSP_REG_R0+((cur_inst>>8) & BITMASK(3)); regdest2 = DSP_REG_R0+(cur_inst & BITMASK(3)); - dsp_core->registers[regdest2] = dsp_core->registers[regsrc2]; + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(regdest2, dsp_core.registers[regsrc2]); } } } static void dsp_wait(void) { -#if DSP_DISASM_STATE - fprintf(stderr, "Dsp: WAIT instruction\n"); -#endif - SDL_SemWait(dsp_core->semaphore); -} - -/********************************** - * Parallel moves instructions dispatcher - **********************************/ - -static void dsp_parmove_read(void) -{ - Uint32 value; - - tmp_parmove_len[0] = tmp_parmove_len[1] = 0; - - /* Calculate needed parallel moves */ - value = (cur_inst >> 20) & BITMASK(4); - - /* Do parallel move read */ - opcodes_parmove[value](); -} - -static void dsp_parmove_write(void) -{ - Uint32 i,j; - - for(i=0;i<2;i++) { - if (tmp_parmove_len[i]==0) { - continue; - } - - /* Do parallel move write */ - for ( - j=tmp_parmove_start[i]; - jregisters[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); - numreg &= 1; + scaling = (dsp_core.registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); + reg = numreg & 1; - /* scaling==1 */ - value = dsp_core->registers[DSP_REG_A2+numreg] & 0xff; - numbits = 8; + value = (dsp_core.registers[DSP_REG_A2+reg]) << 24; + value += dsp_core.registers[DSP_REG_A1+reg]; switch(scaling) { case 0: - value <<=1; - value |= (dsp_core->registers[DSP_REG_A1+numreg]>>23) & 1; - numbits=9; + /* No scaling */ + break; + case 1: + /* scaling down */ + value >>= 1; break; case 2: - value <<=2; - value |= (dsp_core->registers[DSP_REG_A1+numreg]>>22) & 3; - numbits=10; + /* scaling up */ + value <<= 1; + value |= (dsp_core.registers[DSP_REG_A0+reg]>>23) & 1; + break; + /* indeterminate */ + case 3: break; } - if ((value==0) || (value==(Uint32)(BITMASK(numbits)))) { - /* No limiting */ - *dest=dsp_core->registers[DSP_REG_A1+numreg]; - } else if (dsp_core->registers[DSP_REG_A2+numreg] & (1<<7)) { + /* limiting ? */ + value &= BITMASK(24); + + if (dsp_core.registers[DSP_REG_A2+reg] == 0) { + if (value <= 0x007fffff) { + /* No limiting */ + *dest=value; + return 0; + } + } + + if (dsp_core.registers[DSP_REG_A2+reg] == 0xff) { + if (value >= 0x00800000) { + /* No limiting */ + *dest=value; + return 0; + } + } + + if (dsp_core.registers[DSP_REG_A2+reg] & (1<<7)) { /* Limited to maximum negative value */ *dest=0x00800000; - dsp_core->registers[DSP_REG_SR] |= (1<registers[DSP_REG_SR] |= (1<registers[DSP_REG_A2+(numreg & 1)]; - tmp_parmove_dest[position][1].host_pointer=&dsp_core->registers[DSP_REG_A1+(numreg & 1)]; - tmp_parmove_dest[position][2].host_pointer=&dsp_core->registers[DSP_REG_A0+(numreg & 1)]; - - tmp_parmove_start[position]=0; - tmp_parmove_len[position]=3; - } else { - tmp_parmove_dest[position][1].host_pointer=&dsp_core->registers[numreg]; - - tmp_parmove_start[position]=1; - tmp_parmove_len[position]=1; - } -} - static void dsp_pm_0(void) { - Uint32 memspace, dummy, numreg, value; + Uint32 memspace, numreg, addr, save_accu, save_xy0; /* 0000 100d 00mm mrrr S,x:ea x0,D 0000 100d 10mm mrrr S,y:ea y0,D */ memspace = (cur_inst>>15) & 1; numreg = (cur_inst>>16) & 1; - dsp_calc_ea((cur_inst>>8) & BITMASK(6), &dummy); + dsp_calc_ea((cur_inst>>8) & BITMASK(6), &addr); - /* [A|B] to [x|y]:ea */ - dsp_pm_read_accu24(numreg, &tmp_parmove_src[0][1]); - tmp_parmove_dest[0][1].dsp_address=dummy; + /* Save A or B */ + dsp_pm_read_accu24(numreg, &save_accu); - tmp_parmove_start[0] = 1; - tmp_parmove_len[0] = 1; + /* Save X0 or Y0 */ + save_xy0 = dsp_core.registers[DSP_REG_X0+(memspace<<1)]; - tmp_parmove_type[0]=1; - tmp_parmove_space[0]=memspace; + /* Execute parallel instruction */ + opcodes_alu[cur_inst & BITMASK(8)](); - /* [x|y]0 to [A|B] */ - value = dsp_core->registers[DSP_REG_X0+(memspace<<1)]; - if (value & (1<<23)) { - tmp_parmove_src[1][0]=0x0000ff; - } else { - tmp_parmove_src[1][0]=0x000000; - } - tmp_parmove_src[1][1]=value; - tmp_parmove_src[1][2]=0x000000; - tmp_parmove_dest[1][0].host_pointer=&dsp_core->registers[DSP_REG_A2+numreg]; - tmp_parmove_dest[1][1].host_pointer=&dsp_core->registers[DSP_REG_A1+numreg]; - tmp_parmove_dest[1][2].host_pointer=&dsp_core->registers[DSP_REG_A0+numreg]; + /* Move [A|B] to [x|y]:ea */ + write_memory(memspace, addr, save_accu); - tmp_parmove_start[1] = 0; - tmp_parmove_len[1] = 3; + /* Move [x|y]0 to [A|B] */ + dsp_core.registers[DSP_REG_A0+numreg] = 0; + dsp_core.registers[DSP_REG_A1+numreg] = save_xy0; + dsp_core.registers[DSP_REG_A2+numreg] = save_xy0 & (1<<23) ? 0xff : 0x0; } static void dsp_pm_1(void) { - Uint32 memspace, numreg, value, xy_addr, retour; + Uint32 memspace, numreg1, numreg2, value, xy_addr, retour, save_1, save_2; /* - 0001 ffdf w0mm mrrr x:ea,D1 S2,D2 + 0001 ffdf w0mm mrrr x:ea,D1 S2,D2 S1,x:ea S2,D2 #xxxxxx,D1 S2,D2 - 0001 deff w1mm mrrr S1,D1 y:ea,D2 + 0001 deff w1mm mrrr S1,D1 y:ea,D2 S1,D1 S2,y:ea S1,D1 #xxxxxx,D2 */ value = (cur_inst>>8) & BITMASK(6); - - retour = dsp_calc_ea(value, &xy_addr); - + retour = dsp_calc_ea(value, &xy_addr); memspace = (cur_inst>>14) & 1; - numreg = DSP_REG_NULL; + numreg1 = numreg2 = DSP_REG_NULL; if (memspace) { /* Y: */ switch((cur_inst>>16) & BITMASK(2)) { - case 0: numreg = DSP_REG_Y0; break; - case 1: numreg = DSP_REG_Y1; break; - case 2: numreg = DSP_REG_A; break; - case 3: numreg = DSP_REG_B; break; + case 0: numreg1 = DSP_REG_Y0; break; + case 1: numreg1 = DSP_REG_Y1; break; + case 2: numreg1 = DSP_REG_A; break; + case 3: numreg1 = DSP_REG_B; break; } } else { /* X: */ switch((cur_inst>>18) & BITMASK(2)) { - case 0: numreg = DSP_REG_X0; break; - case 1: numreg = DSP_REG_X1; break; - case 2: numreg = DSP_REG_A; break; - case 3: numreg = DSP_REG_B; break; + case 0: numreg1 = DSP_REG_X0; break; + case 1: numreg1 = DSP_REG_X1; break; + case 2: numreg1 = DSP_REG_A; break; + case 3: numreg1 = DSP_REG_B; break; } } if (cur_inst & (1<<15)) { /* Write D1 */ - - if (retour) { - value = xy_addr; - } else { - value = read_memory(memspace, xy_addr); - } - tmp_parmove_src[0][0]= 0x000000; - if (value & (1<<23)) { - tmp_parmove_src[0][0]= 0x0000ff; - } - tmp_parmove_src[0][1]= value & BITMASK(registers_mask[numreg]); - tmp_parmove_src[0][2]= 0x000000; - - dsp_pm_writereg(numreg, 0); - tmp_parmove_type[0]=0; + if (retour) + save_1 = xy_addr; + else + save_1 = read_memory(memspace, xy_addr); } else { /* Read S1 */ - - if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &tmp_parmove_src[0][1]); - } else { - tmp_parmove_src[0][1]=dsp_core->registers[numreg]; - } - - tmp_parmove_dest[0][1].dsp_address=xy_addr; - - tmp_parmove_start[0]=1; - tmp_parmove_len[0]=1; - - tmp_parmove_type[0]=1; - tmp_parmove_space[0]=memspace; + if ((numreg1==DSP_REG_A) || (numreg1==DSP_REG_B)) + dsp_pm_read_accu24(numreg1, &save_1); + else + save_1 = dsp_core.registers[numreg1]; } /* S2 */ if (memspace) { /* Y: */ - numreg = DSP_REG_A + ((cur_inst>>19) & 1); + numreg2 = DSP_REG_A + ((cur_inst>>19) & 1); } else { /* X: */ - numreg = DSP_REG_A + ((cur_inst>>17) & 1); - } - dsp_pm_read_accu24(numreg, &tmp_parmove_src[1][1]); - - /* D2 */ + numreg2 = DSP_REG_A + ((cur_inst>>17) & 1); + } + dsp_pm_read_accu24(numreg2, &save_2); + + + /* Execute parallel instruction */ + opcodes_alu[cur_inst & BITMASK(8)](); + + + /* Write parallel move values */ + if (cur_inst & (1<<15)) { + /* Write D1 */ + dsp_write_reg(numreg1, save_1); + } else { + /* Read S1 */ + write_memory(memspace, xy_addr, save_1); + } + + /* S2 -> D2 */ if (memspace) { /* Y: */ - numreg = DSP_REG_X0 + ((cur_inst>>18) & 1); + numreg2 = DSP_REG_X0 + ((cur_inst>>18) & 1); } else { /* X: */ - numreg = DSP_REG_Y0 + ((cur_inst>>16) & 1); - } - tmp_parmove_src[1][1] &= BITMASK(registers_mask[numreg]); - tmp_parmove_dest[1][1].host_pointer=&dsp_core->registers[numreg]; - - tmp_parmove_start[1]=1; - tmp_parmove_len[1]=1; - - tmp_parmove_type[1]=0; + numreg2 = DSP_REG_Y0 + ((cur_inst>>16) & 1); + } + dsp_core.registers[numreg2] = save_2; } static void dsp_pm_2(void) @@ -2929,16 +3605,20 @@ static void dsp_pm_2(void) 0010 00ee eeed dddd S,D 001d dddd iiii iiii #xx,D */ - if (((cur_inst >> 8) & 0xffff) == 0x2000) { + if ((cur_inst & 0xffff00) == 0x200000) { + /* Execute parallel instruction */ + opcodes_alu[cur_inst & BITMASK(8)](); return; } - if (((cur_inst >> 8) & 0xffe0) == 0x2040) { + if ((cur_inst & 0xffe000) == 0x204000) { dsp_calc_ea((cur_inst>>8) & BITMASK(5), &dummy); + /* Execute parallel instruction */ + opcodes_alu[cur_inst & BITMASK(8)](); return; } - if (((cur_inst >> 8) & 0xfc00) == 0x2000) { + if ((cur_inst & 0xfc0000) == 0x200000) { dsp_pm_2_2(); return; } @@ -2951,48 +3631,40 @@ static void dsp_pm_2_2(void) /* 0010 00ee eeed dddd S,D */ - Uint32 srcreg, dstreg; - + Uint32 srcreg, dstreg, save_reg; + srcreg = (cur_inst >> 13) & BITMASK(5); dstreg = (cur_inst >> 8) & BITMASK(5); - tmp_parmove_src[0][0]= - tmp_parmove_src[0][1]= - tmp_parmove_src[0][2]= 0x000000; - - if ((srcreg == DSP_REG_A) || (srcreg == DSP_REG_B)) { - /* Accu to register or accu: limited 24 bits */ - dsp_pm_read_accu24(srcreg, &tmp_parmove_src[0][1]); - if (tmp_parmove_src[0][1] & (1<<23)) { - tmp_parmove_src[0][0]=0x0000ff; - } - } else { - if ((dstreg == DSP_REG_A) || (dstreg == DSP_REG_B)) { - /* Register to accu: sign extended to 56 bits */ - tmp_parmove_src[0][1]=dsp_core->registers[srcreg] & BITMASK(registers_mask[srcreg]); - if (tmp_parmove_src[0][1] & (1<<23)) { - tmp_parmove_src[0][0]=0x0000ff; - } - } else { - /* Register to register: n bits */ - tmp_parmove_src[0][1]=dsp_core->registers[srcreg] & BITMASK(registers_mask[srcreg]); - } - } - - dsp_pm_writereg(dstreg, 0); - tmp_parmove_type[0]=0; + if ((srcreg == DSP_REG_A) || (srcreg == DSP_REG_B)) + /* Accu to register: limited 24 bits */ + dsp_pm_read_accu24(srcreg, &save_reg); + else + save_reg = dsp_core.registers[srcreg]; + + /* Execute parallel instruction */ + opcodes_alu[cur_inst & BITMASK(8)](); + + /* Write reg */ + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(dstreg, save_reg); } static void dsp_pm_3(void) { - Uint32 dest, srcvalue; + Uint32 dstreg, srcvalue; /* 001d dddd iiii iiii #xx,R */ - dest = (cur_inst >> 16) & BITMASK(5); + + /* Execute parallel instruction */ + opcodes_alu[cur_inst & BITMASK(8)](); + + /* Write reg */ + dstreg = (cur_inst >> 16) & BITMASK(5); srcvalue = (cur_inst >> 8) & BITMASK(8); - switch(dest) { + switch(dstreg) { case DSP_REG_X0: case DSP_REG_X1: case DSP_REG_Y0: @@ -3003,139 +3675,171 @@ static void dsp_pm_3(void) break; } - tmp_parmove_src[0][0]=0x000000; - if ((dest == DSP_REG_A) || (dest == DSP_REG_B)) { - if (srcvalue & (1<<23)) { - tmp_parmove_src[0][0]=0x0000ff; - } - } - tmp_parmove_src[0][1]=srcvalue & BITMASK(registers_mask[dest]); - tmp_parmove_src[0][2]=0x000000; - - dsp_pm_writereg(dest, 0); - tmp_parmove_type[0]=0; + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(dstreg, srcvalue); } static void dsp_pm_4(void) { - Uint32 l_addr, value; - int retour; /* - 0100 l0ll w0aa aaaa l:aa,D + 0100 l0ll w0aa aaaa l:aa,D S,l:aa - 0100 l0ll w1mm mrrr l:ea,D + 0100 l0ll w1mm mrrr l:ea,D S,l:ea - 01dd 0ddd w0aa aaaa x:aa,D + 01dd 0ddd w0aa aaaa x:aa,D S,x:aa - 01dd 0ddd w1mm mrrr x:ea,D + 01dd 0ddd w1mm mrrr x:ea,D S,x:ea #xxxxxx,D - 01dd 1ddd w0aa aaaa y:aa,D + 01dd 1ddd w0aa aaaa y:aa,D S,y:aa - 01dd 1ddd w1mm mrrr y:ea,D + 01dd 1ddd w1mm mrrr y:ea,D S,y:ea #xxxxxx,D */ - value = (cur_inst>>16) & BITMASK(3); - value |= (cur_inst>>17) & (BITMASK(2)<<3); - - if ((value>>2)==0) { - value = (cur_inst>>8) & BITMASK(6); - if (cur_inst & (1<<14)) { - retour = dsp_calc_ea(value, &l_addr); - } else { - l_addr = value; - retour = 0; - } - dsp_pm_4x(retour, l_addr); + if ((cur_inst & 0xf40000)==0x400000) { + dsp_pm_4x(); return; } dsp_pm_5(); } -static void dsp_pm_4x(int immediat, Uint32 l_addr) +static void dsp_pm_4x(void) { - Uint32 value, numreg, numreg2; - immediat = 0; /* UNUSED */ + Uint32 value, numreg, l_addr, save_lx, save_ly; /* - 0100 l0ll w0aa aaaa l:aa,D - S,l:aa - 0100 l0ll w1mm mrrr l:ea,D - S,l:ea + 0100 l0ll w0aa aaaa l:aa,D + S,l:aa + 0100 l0ll w1mm mrrr l:ea,D + S,l:ea */ - l_addr &= BITMASK(16); + value = (cur_inst>>8) & BITMASK(6); + if (cur_inst & (1<<14)) { + dsp_calc_ea(value, &l_addr); + } else { + l_addr = value; + } + numreg = (cur_inst>>16) & BITMASK(2); numreg |= (cur_inst>>17) & (1<<2); if (cur_inst & (1<<15)) { /* Write D */ - - /* Sources */ - value = read_memory(DSP_SPACE_X,l_addr); - tmp_parmove_src[0][0] = (value & (1<<23) ? 0xff : 0); - tmp_parmove_src[0][1] = value & BITMASK(registers_mask[registers_lmove[numreg][0]]); - tmp_parmove_src[0][2] = 0x000000; - value = read_memory(DSP_SPACE_Y,l_addr); - - if (registers_lmove[numreg][0]==registers_lmove[numreg][1]) { - /* Write to 56bit accumulator, setup a single transfer as 56 bit */ - tmp_parmove_src[0][2] = value & BITMASK(registers_mask[registers_lmove[numreg][1]]); - } else { - /* Writes to 24bit registers, setup second 24 bit transfer */ - tmp_parmove_src[1][0] = (value & (1<<23) ? 0xff : 0); - tmp_parmove_src[1][1] = value & BITMASK(registers_mask[registers_lmove[numreg][1]]); - tmp_parmove_src[1][2] = 0x000000; + save_lx = read_memory(DSP_SPACE_X,l_addr); + save_ly = read_memory(DSP_SPACE_Y,l_addr); + } + else { + /* Read S */ + switch(numreg) { + case 0: + /* A10 */ + save_lx = dsp_core.registers[DSP_REG_A1]; + save_ly = dsp_core.registers[DSP_REG_A0]; + break; + case 1: + /* B10 */ + save_lx = dsp_core.registers[DSP_REG_B1]; + save_ly = dsp_core.registers[DSP_REG_B0]; + break; + case 2: + /* X */ + save_lx = dsp_core.registers[DSP_REG_X1]; + save_ly = dsp_core.registers[DSP_REG_X0]; + break; + case 3: + /* Y */ + save_lx = dsp_core.registers[DSP_REG_Y1]; + save_ly = dsp_core.registers[DSP_REG_Y0]; + break; + case 4: + /* A */ + if (dsp_pm_read_accu24(DSP_REG_A, &save_lx)) { + /* Was limited, set lower part */ + save_ly = (save_lx & (1<<23) ? 0 : 0xffffff); + } else { + /* Not limited */ + save_ly = dsp_core.registers[DSP_REG_A0]; + } + break; + case 5: + /* B */ + if (dsp_pm_read_accu24(DSP_REG_B, &save_lx)) { + /* Was limited, set lower part */ + save_ly = (save_lx & (1<<23) ? 0 : 0xffffff); + } else { + /* Not limited */ + save_ly = dsp_core.registers[DSP_REG_B0]; + } + break; + case 6: + /* AB */ + dsp_pm_read_accu24(DSP_REG_A, &save_lx); + dsp_pm_read_accu24(DSP_REG_B, &save_ly); + break; + case 7: + /* BA */ + dsp_pm_read_accu24(DSP_REG_B, &save_lx); + dsp_pm_read_accu24(DSP_REG_A, &save_ly); + break; } + } - /* Destinations */ - dsp_pm_writereg(registers_lmove[numreg][0], 0); - tmp_parmove_type[0]=0; - - if (registers_lmove[numreg][0]!=registers_lmove[numreg][1]) { - /* Two 24 or 56 bits registers */ - dsp_pm_writereg(registers_lmove[numreg][1], 1); - tmp_parmove_type[1]=0; - } - } else { - /* Read S */ + /* Execute parallel instruction */ + opcodes_alu[cur_inst & BITMASK(8)](); - /* Sources */ - if (numreg<4) { - /* Two 24 bits tranfers */ - tmp_parmove_src[0][1] = dsp_core->registers[registers_lmove[numreg][0]]; - tmp_parmove_src[1][1] = dsp_core->registers[registers_lmove[numreg][1]]; - } else if (numreg<6) { - /* Single accumulator transfer */ - numreg2 = registers_lmove[numreg][0]; - if (dsp_pm_read_accu24(numreg2, &tmp_parmove_src[0][1])) { - /* Was limited, set lower part */ - tmp_parmove_src[1][1] = (tmp_parmove_src[0][1] & (1<<23) ? 0 : 0xffffff); - } else { - /* Not limited */ - tmp_parmove_src[1][1] = dsp_core->registers[DSP_REG_A0+(numreg2 & 1)]; - } - } else { - /* Two accumulators tranfers */ - dsp_pm_read_accu24(registers_lmove[numreg][0], &tmp_parmove_src[0][1]); - dsp_pm_read_accu24(registers_lmove[numreg][1], &tmp_parmove_src[1][1]); - } - - /* D1 */ - tmp_parmove_dest[0][1].dsp_address=l_addr; - tmp_parmove_start[0]=1; - tmp_parmove_len[0]=1; - - tmp_parmove_type[0]=1; - tmp_parmove_space[0]=DSP_SPACE_X; - - /* D2 */ - tmp_parmove_dest[1][1].dsp_address=l_addr; - tmp_parmove_start[1]=1; - tmp_parmove_len[1]=1; - tmp_parmove_type[1]=1; - tmp_parmove_space[1]=DSP_SPACE_Y; + if (cur_inst & (1<<15)) { + /* Write D */ + switch(numreg) { + case 0: /* A10 */ + dsp_core.registers[DSP_REG_A1] = save_lx; + dsp_core.registers[DSP_REG_A0] = save_ly; + break; + case 1: /* B10 */ + dsp_core.registers[DSP_REG_B1] = save_lx; + dsp_core.registers[DSP_REG_B0] = save_ly; + break; + case 2: /* X */ + dsp_core.registers[DSP_REG_X1] = save_lx; + dsp_core.registers[DSP_REG_X0] = save_ly; + break; + case 3: /* Y */ + dsp_core.registers[DSP_REG_Y1] = save_lx; + dsp_core.registers[DSP_REG_Y0] = save_ly; + break; + case 4: /* A */ + dsp_core.registers[DSP_REG_A0] = save_ly; + dsp_core.registers[DSP_REG_A1] = save_lx; + dsp_core.registers[DSP_REG_A2] = save_lx & (1<<23) ? 0xff : 0; + break; + case 5: /* B */ + dsp_core.registers[DSP_REG_B0] = save_ly; + dsp_core.registers[DSP_REG_B1] = save_lx; + dsp_core.registers[DSP_REG_B2] = save_lx & (1<<23) ? 0xff : 0; + break; + case 6: /* AB */ + dsp_core.registers[DSP_REG_A0] = 0; + dsp_core.registers[DSP_REG_A1] = save_lx; + dsp_core.registers[DSP_REG_A2] = save_lx & (1<<23) ? 0xff : 0; + dsp_core.registers[DSP_REG_B0] = 0; + dsp_core.registers[DSP_REG_B1] = save_ly; + dsp_core.registers[DSP_REG_B2] = save_ly & (1<<23) ? 0xff : 0; + break; + case 7: /* BA */ + dsp_core.registers[DSP_REG_B0] = 0; + dsp_core.registers[DSP_REG_B1] = save_lx; + dsp_core.registers[DSP_REG_B2] = save_lx & (1<<23) ? 0xff : 0; + dsp_core.registers[DSP_REG_A0] = 0; + dsp_core.registers[DSP_REG_A1] = save_ly; + dsp_core.registers[DSP_REG_A2] = save_ly & (1<<23) ? 0xff : 0; + break; + } + } + else { + /* Read S */ + write_memory(DSP_SPACE_X, l_addr, save_lx); + write_memory(DSP_SPACE_Y, l_addr, save_ly); } } @@ -3143,14 +3847,14 @@ static void dsp_pm_5(void) { Uint32 memspace, numreg, value, xy_addr, retour; /* - 01dd 0ddd w0aa aaaa x:aa,D + 01dd 0ddd w0aa aaaa x:aa,D S,x:aa - 01dd 0ddd w1mm mrrr x:ea,D + 01dd 0ddd w1mm mrrr x:ea,D S,x:ea #xxxxxx,D - 01dd 1ddd w0aa aaaa y:aa,D + 01dd 1ddd w0aa aaaa y:aa,D S,y:aa - 01dd 1ddd w1mm mrrr y:ea,D + 01dd 1ddd w1mm mrrr y:ea,D S,y:ea #xxxxxx,D */ @@ -3158,7 +3862,7 @@ static void dsp_pm_5(void) value = (cur_inst>>8) & BITMASK(6); if (cur_inst & (1<<14)) { - retour = dsp_calc_ea(value, &xy_addr); + retour = dsp_calc_ea(value, &xy_addr); } else { xy_addr = value; retour = 0; @@ -3170,37 +3874,31 @@ static void dsp_pm_5(void) if (cur_inst & (1<<15)) { /* Write D */ - - if (retour) { + if (retour) value = xy_addr; - } else { + else value = read_memory(memspace, xy_addr); - } - tmp_parmove_src[0][0]= 0x000000; - if (value & (1<<23)) { - tmp_parmove_src[0][0]= 0x0000ff; - } - tmp_parmove_src[0][1]= value & BITMASK(registers_mask[numreg]); - tmp_parmove_src[0][2]= 0x000000; - - dsp_pm_writereg(numreg, 0); - tmp_parmove_type[0]=0; - } else { + } + else { /* Read S */ + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) + dsp_pm_read_accu24(numreg, &value); + else + value = dsp_core.registers[numreg]; + } - if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &tmp_parmove_src[0][1]); - } else { - tmp_parmove_src[0][1]=dsp_core->registers[numreg]; - } - - tmp_parmove_dest[0][1].dsp_address=xy_addr; - tmp_parmove_start[0]=1; - tmp_parmove_len[0]=1; + /* Execute parallel instruction */ + opcodes_alu[cur_inst & BITMASK(8)](); - tmp_parmove_type[0]=1; - tmp_parmove_space[0]=memspace; + if (cur_inst & (1<<15)) { + /* Write D */ + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(numreg, value); + } + else { + /* Read S */ + write_memory(memspace, xy_addr, value); } } @@ -3208,9 +3906,9 @@ static void dsp_pm_8(void) { Uint32 ea1, ea2; Uint32 numreg1, numreg2; - Uint32 value, dummy1, dummy2; + Uint32 save_reg1, save_reg2, x_addr, y_addr; /* - 1wmm eeff WrrM MRRR x:ea,D1 y:ea,D2 + 1wmm eeff WrrM MRRR x:ea,D1 y:ea,D2 x:ea,D1 S2,y:ea S1,x:ea y:ea,D2 S1,x:ea S2,y:ea @@ -3230,8 +3928,8 @@ static void dsp_pm_8(void) ea2 |= (1<<5); } - dsp_calc_ea(ea1, &dummy1); - dsp_calc_ea(ea2, &dummy2); + dsp_calc_ea(ea1, &x_addr); + dsp_calc_ea(ea2, &y_addr); switch((cur_inst>>18) & BITMASK(2)) { case 0: numreg1=DSP_REG_X0; break; @@ -3245,66 +3943,73 @@ static void dsp_pm_8(void) case 2: numreg2=DSP_REG_A; break; case 3: numreg2=DSP_REG_B; break; } - + if (cur_inst & (1<<15)) { /* Write D1 */ - - value = read_memory(DSP_SPACE_X, dummy1); - tmp_parmove_src[0][0]= 0x000000; - if (value & (1<<23)) { - tmp_parmove_src[0][0]= 0x0000ff; - } - tmp_parmove_src[0][1]= value & BITMASK(registers_mask[numreg1]); - tmp_parmove_src[0][2]= 0x000000; - - dsp_pm_writereg(numreg1, 0); - tmp_parmove_type[0]=0; + save_reg1 = read_memory(DSP_SPACE_X, x_addr); } else { /* Read S1 */ + if ((numreg1==DSP_REG_A) || (numreg1==DSP_REG_B)) + dsp_pm_read_accu24(numreg1, &save_reg1); + else + save_reg1 = dsp_core.registers[numreg1]; + } - if ((numreg1==DSP_REG_A) || (numreg1==DSP_REG_B)) { - dsp_pm_read_accu24(numreg1, &tmp_parmove_src[0][1]); - } else { - tmp_parmove_src[0][1]=dsp_core->registers[numreg1]; - } + if (cur_inst & (1<<22)) { + /* Write D2 */ + save_reg2 = read_memory(DSP_SPACE_Y, y_addr); + } else { + /* Read S2 */ + if ((numreg2==DSP_REG_A) || (numreg2==DSP_REG_B)) + dsp_pm_read_accu24(numreg2, &save_reg2); + else + save_reg2 = dsp_core.registers[numreg2]; + } - tmp_parmove_dest[0][1].dsp_address=dummy1; - tmp_parmove_start[0]=1; - tmp_parmove_len[0]=1; + /* Execute parallel instruction */ + opcodes_alu[cur_inst & BITMASK(8)](); - tmp_parmove_type[0]=1; - tmp_parmove_space[0]=DSP_SPACE_X; + /* Write first parallel move */ + if (cur_inst & (1<<15)) { + /* Write D1 */ + if (numreg1 == DSP_REG_A) { + dsp_core.registers[DSP_REG_A0] = 0x0; + dsp_core.registers[DSP_REG_A1] = save_reg1; + dsp_core.registers[DSP_REG_A2] = save_reg1 & (1<<23) ? 0xff : 0x0; + } + else if (numreg1 == DSP_REG_B) { + dsp_core.registers[DSP_REG_B0] = 0x0; + dsp_core.registers[DSP_REG_B1] = save_reg1; + dsp_core.registers[DSP_REG_B2] = save_reg1 & (1<<23) ? 0xff : 0x0; + } + else { + dsp_core.registers[numreg1] = save_reg1; + } + } else { + /* Read S1 */ + write_memory(DSP_SPACE_X, x_addr, save_reg1); } + /* Write second parallel move */ if (cur_inst & (1<<22)) { /* Write D2 */ - - value = read_memory(DSP_SPACE_Y, dummy2); - tmp_parmove_src[1][0]= 0x000000; - if (value & (1<<23)) { - tmp_parmove_src[1][0]= 0x0000ff; + if (numreg2 == DSP_REG_A) { + dsp_core.registers[DSP_REG_A0] = 0x0; + dsp_core.registers[DSP_REG_A1] = save_reg2; + dsp_core.registers[DSP_REG_A2] = save_reg2 & (1<<23) ? 0xff : 0x0; + } + else if (numreg2 == DSP_REG_B) { + dsp_core.registers[DSP_REG_B0] = 0x0; + dsp_core.registers[DSP_REG_B1] = save_reg2; + dsp_core.registers[DSP_REG_B2] = save_reg2 & (1<<23) ? 0xff : 0x0; + } + else { + dsp_core.registers[numreg2] = save_reg2; } - tmp_parmove_src[1][1]= value & BITMASK(registers_mask[numreg2]); - tmp_parmove_src[1][2]= 0x000000; - - dsp_pm_writereg(numreg2, 1); - tmp_parmove_type[1]=0; } else { /* Read S2 */ - if ((numreg1==DSP_REG_A) || (numreg1==DSP_REG_B)) { - dsp_pm_read_accu24(numreg1, &tmp_parmove_src[1][1]); - } else { - tmp_parmove_src[1][1]=dsp_core->registers[numreg1]; - } - - tmp_parmove_dest[1][1].dsp_address=dummy2; - - tmp_parmove_start[1]=1; - tmp_parmove_len[1]=1; - - tmp_parmove_type[1]=1; - tmp_parmove_space[1]=DSP_SPACE_Y; + write_memory(DSP_SPACE_Y, y_addr, save_reg2); } } @@ -3353,7 +4058,7 @@ static Uint16 dsp_asl56(Uint32 *dest) dest[1] <<= 1; dest[1] |= (dest[2]>>23) & 1; dest[1] &= BITMASK(24); - + dest[2] <<= 1; dest[2] &= BITMASK(24); @@ -3371,15 +4076,12 @@ static Uint16 dsp_asr56(Uint32 *dest) carry = dest[2] & 1; dest[2] >>= 1; - dest[2] &= BITMASK(23); dest[2] |= (dest[1] & 1)<<23; dest[1] >>= 1; - dest[1] &= BITMASK(23); dest[1] |= (dest[0] & 1)<<23; dest[0] >>= 1; - dest[0] &= BITMASK(7); dest[0] |= (dest[0] & (1<<6))<<1; return (carry<>7) & 1; + flg_d = (dest[0]>>7) & 1; /* Add source to dest: D = D+S */ dest[2] += source[2]; dest[1] += source[1]+((dest[2]>>24) & 1); dest[0] += source[0]+((dest[1]>>24) & 1); - /* overflow if we go below -256.0 or above +256.0 */ - overflow = (((dest[0] & 0xff)!=0) && ((dest[0] & 0xff)!=0xff)); - - /* set carry from the virtual 56th bit */ carry = (dest[0]>>8) & 1; dest[2] &= BITMASK(24); dest[1] &= BITMASK(24); dest[0] &= BITMASK(8); + flg_r = (dest[0]>>7) & 1; + + /*set overflow*/ + overflow = (flg_s ^ flg_r) & (flg_d ^ flg_r); + return (overflow<>24) & 1); dest[0] -= source[0]+((dest[1]>>24) & 1); - /* overflow if we go below -256.0 or above +256.0 */ - overflow = (((dest[0] & 0xff)!=0) && ((dest[0] & 0xff)!=0xff)); - - /* set carry from the virtual 56th bit */ carry = (dest[0]>>8) & 1; dest[2] &= BITMASK(24); dest[1] &= BITMASK(24); dest[0] &= BITMASK(8); + flg_s = (source[0]>>7) & 1; + flg_d = (dest_save>>7) & 1; + flg_r = (dest[0]>>7) & 1; + + /* set overflow */ + overflow = (flg_s ^ flg_d) & (flg_r ^ flg_d); + return (overflow<>24) & BITMASK(8)) { - ++dest[0]; - dest[0] &= BITMASK(8); - dest[1] &= BITMASK(24); - } + /* Scaling mode S0 */ + if (dsp_core.registers[DSP_REG_SR] & (1<0x800000) { - ++dest[1]; - if ((dest[1]>>24) & BITMASK(8)) { - ++dest[0]; - dest[0] &= BITMASK(8); - dest[1] &= BITMASK(24); + dest[1] &= 0xfffffe; + dest[2]=0; + } + /* Scaling mode S1 */ + else if (dsp_core.registers[DSP_REG_SR] & (1<>3) & 1; + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + + overflowed = ((dest[2]==0) && (dest[1]==0) && (dest[0]==0x80)); + + dsp_abs56(dest); + + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; overflowed = ((dest[2]==0) && (dest[1]==0) && (dest[0]==0x80)); dsp_abs56(dest); - dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= (overflowed<registers[DSP_REG_SR]>>DSP_SR_C) & 1; + curcarry = (dsp_core.registers[DSP_REG_SR]>>DSP_SR_C) & 1; - destreg = (cur_inst>>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + + source[2] = dsp_core.registers[DSP_REG_X0]; + source[1] = dsp_core.registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; - srcreg = (cur_inst>>4) & 1; - if (srcreg == 0) { /* X */ - source[1] = dsp_core->registers[DSP_REG_X1]; - source[2] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } + newsr = dsp_add56(source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_add56(source, dest); } - else { /* Y */ - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[2] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } + + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>DSP_SR_C) & 1; + + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + + source[2] = dsp_core.registers[DSP_REG_X0]; + source[1] = dsp_core.registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_add56(source, dest); } + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>DSP_SR_C) & 1; + + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + + source[2] = dsp_core.registers[DSP_REG_Y0]; + source[1] = dsp_core.registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + newsr = dsp_add56(source, dest); - + if (curcarry) { - source[0]=0; - source[1]=0; - source[2]=1; + source[0]=0; source[1]=0; source[2]=1; newsr |= dsp_add56(source, dest); } - dsp_core->registers[DSP_REG_A2+destreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+destreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+destreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_extension(&dest[0], &dest[1]); - dsp_ccr_unnormalized(&dest[0], &dest[1]); - dsp_ccr_negative(&dest[0]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; - - srcreg = (cur_inst>>4) & BITMASK(3); - switch(srcreg) { - case 1: /* A or B */ - srcreg = destreg ^ 1; - source[0] = dsp_core->registers[DSP_REG_A2+srcreg]; - source[1] = dsp_core->registers[DSP_REG_A1+srcreg]; - source[2] = dsp_core->registers[DSP_REG_A0+srcreg]; - break; - case 2: /* X */ - source[1] = dsp_core->registers[DSP_REG_X1]; - source[2] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 3: /* Y */ - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[2] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 4: /* X0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 5: /* Y0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 6: /* X1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 7: /* Y1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - default: - fprintf(stderr, "Dsp: source register undefined! dsp_cpu.cpp: %d\n", __LINE__); - return; + curcarry = (dsp_core.registers[DSP_REG_SR]>>DSP_SR_C) & 1; + + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + + source[2] = dsp_core.registers[DSP_REG_Y0]; + source[1] = dsp_core.registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_add56(source, dest); } + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+destreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+destreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+destreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_extension(&dest[0], &dest[1]); - dsp_ccr_unnormalized(&dest[0], &dest[1]); - dsp_ccr_negative(&dest[0]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + + source[0] = dsp_core.registers[DSP_REG_A2]; + source[1] = dsp_core.registers[DSP_REG_A1]; + source[2] = dsp_core.registers[DSP_REG_A0]; + + newsr = dsp_add56(source, dest); + + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; + newsr = dsp_add56(source, dest); + + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+(numreg ^ 1)]; - source[1] = dsp_core->registers[DSP_REG_A1+(numreg ^ 1)]; - source[2] = dsp_core->registers[DSP_REG_A0+(numreg ^ 1)]; + source[0] = dsp_core.registers[DSP_REG_B2]; + source[1] = dsp_core.registers[DSP_REG_B1]; + source[2] = dsp_core.registers[DSP_REG_B0]; newsr |= dsp_add56(source, dest); - dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_extension(&dest[0], &dest[1]); - dsp_ccr_unnormalized(&dest[0], &dest[1]); - dsp_ccr_negative(&dest[0]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + newsr = dsp_asl56(dest); + + source[0] = dsp_core.registers[DSP_REG_A2]; + source[1] = dsp_core.registers[DSP_REG_A1]; + source[2] = dsp_core.registers[DSP_REG_A0]; + newsr |= dsp_add56(source, dest); + + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; - dest[0] = dsp_core->registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+(numreg ^ 1)]; - source[1] = dsp_core->registers[DSP_REG_A1+(numreg ^ 1)]; - source[2] = dsp_core->registers[DSP_REG_A0+(numreg ^ 1)]; + source[0] = dsp_core.registers[DSP_REG_B2]; + source[1] = dsp_core.registers[DSP_REG_B1]; + source[2] = dsp_core.registers[DSP_REG_B0]; newsr |= dsp_add56(source, dest); - dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_extension(&dest[0], &dest[1]); - dsp_ccr_unnormalized(&dest[0], &dest[1]); - dsp_ccr_negative(&dest[0]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>4) & BITMASK(2)) { - case 1: - srcreg=DSP_REG_Y0; - break; - case 2: - srcreg=DSP_REG_X1; - break; - case 3: - srcreg=DSP_REG_Y1; - break; - case 0: - default: - srcreg=DSP_REG_X0; - } - dstreg = DSP_REG_A1+((cur_inst>>3) & 1); + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + newsr = dsp_asr56(dest); - dsp_core->registers[dstreg] &= dsp_core->registers[srcreg]; - dsp_core->registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */ + source[0] = dsp_core.registers[DSP_REG_A2]; + source[1] = dsp_core.registers[DSP_REG_A1]; + source[2] = dsp_core.registers[DSP_REG_A0]; + newsr |= dsp_add56(source, dest); + + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<>23) & 1)<>23) & 1)<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>3) & 1; + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + + newsr = dsp_asl56(dest); + + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; newsr = dsp_asl56(dest); - dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + + newsr = dsp_asr56(dest); + + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; newsr = dsp_asr56(dest); - dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+numreg]=0; - dsp_core->registers[DSP_REG_A1+numreg]=0; - dsp_core->registers[DSP_REG_A0+numreg]=0; +static void dsp_clr_b(void) +{ + dsp_core.registers[DSP_REG_B2] = 0; + dsp_core.registers[DSP_REG_B1] = 0; + dsp_core.registers[DSP_REG_B0] = 0; - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= (1<>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; - - srcreg = (cur_inst>>4) & BITMASK(3); - switch(srcreg) { - case 0: /* A or B */ - srcreg = destreg ^ 1; - source[0] = dsp_core->registers[DSP_REG_A2+srcreg]; - source[1] = dsp_core->registers[DSP_REG_A1+srcreg]; - source[2] = dsp_core->registers[DSP_REG_A0+srcreg]; - break; - case 4: /* X0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 5: /* Y0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 6: /* X1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 7: /* Y1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - default: - fprintf(stderr, "source register undefined! dsp_cpu.cpp: %d\n", __LINE__); - return; - } + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + + source[0] = dsp_core.registers[DSP_REG_B2]; + source[1] = dsp_core.registers[DSP_REG_B1]; + source[2] = dsp_core.registers[DSP_REG_B0]; newsr = dsp_sub56(source, dest); - dsp_ccr_extension(&dest[0], &dest[1]); - dsp_ccr_unnormalized(&dest[0], &dest[1]); - dsp_ccr_negative(&dest[0]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + + source[2] = 0; + source[1] = dsp_core.registers[DSP_REG_X0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(source, dest); + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>4) & BITMASK(3); - switch(srcreg) { - case 0: /* A or B */ - srcreg = destreg ^ 1; - source[0] = dsp_core->registers[DSP_REG_A2+srcreg]; - source[1] = dsp_core->registers[DSP_REG_A1+srcreg]; - source[2] = dsp_core->registers[DSP_REG_A0+srcreg]; - break; - case 4: /* X0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 5: /* Y0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 6: /* X1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 7: /* Y1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - default: - fprintf(stderr, "source register undefined! dsp_cpu.cpp: %d\n", __LINE__); - return; - } + source[0] = dsp_core.registers[DSP_REG_B2]; + source[1] = dsp_core.registers[DSP_REG_B1]; + source[2] = dsp_core.registers[DSP_REG_B0]; + dsp_abs56(source); + + newsr = dsp_sub56(source, dest); + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>4) & BITMASK(2)) { - case 1: - srcreg=DSP_REG_Y0; - break; - case 2: - srcreg=DSP_REG_X1; - break; - case 3: - srcreg=DSP_REG_Y1; - break; - case 0: - default: - srcreg=DSP_REG_X0; - } - dstreg = DSP_REG_A1+((cur_inst>>3) & 1); + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + dsp_abs56(dest); - dsp_core->registers[dstreg] ^= dsp_core->registers[srcreg]; - dsp_core->registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */ + source[2] = 0; + source[1] = dsp_core.registers[DSP_REG_X0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + dsp_abs56(source); + + newsr = dsp_sub56(source, dest); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<>3) & 1); + dest[2] = dsp_core.registers[DSP_REG_A0]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[0] = dsp_core.registers[DSP_REG_A2]; + dsp_abs56(dest); - newcarry = (dsp_core->registers[numreg]>>23) & 1; + source[2] = 0; + source[1] = dsp_core.registers[DSP_REG_Y0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + dsp_abs56(source); + + newsr = dsp_sub56(source, dest); - dsp_core->registers[numreg] <<= 1; - dsp_core->registers[numreg] &= BITMASK(24); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; - dsp_core->registers[DSP_REG_SR] |= ((dsp_core->registers[numreg]>>23) & 1)<registers[DSP_REG_SR] |= (dsp_core->registers[numreg]==0)<>3) & 1); + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + dsp_abs56(dest); - newcarry = dsp_core->registers[numreg] & 1; + source[2] = 0; + source[1] = dsp_core.registers[DSP_REG_Y0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + dsp_abs56(source); + + newsr = dsp_sub56(source, dest); - dsp_core->registers[numreg] >>= 1; - /*dsp_core->registers[numreg] &= BITMASK(24);*/ + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; - dsp_core->registers[DSP_REG_SR] |= (dsp_core->registers[numreg]==0)<>4) & BITMASK(3); - srcreg1 = registers_mpy[value][0]; - srcreg2 = registers_mpy[value][1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[0] = dsp_core.registers[DSP_REG_A2]; + dsp_abs56(dest); - dsp_mul56(dsp_core->registers[srcreg1], dsp_core->registers[srcreg2], source); + source[2] = 0; + source[1] = dsp_core.registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + dsp_abs56(source); - if (cur_inst & (1<<2)) { - dest[0] = dest[1] = dest[2] = 0; + newsr = dsp_sub56(source, dest); - dsp_sub56(source, dest); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - source[0] = dest[0]; - source[1] = dest[1]; - source[2] = dest[2]; - } + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; +static void dsp_cmpm_x1_b(void) +{ + Uint32 source[3], dest[3]; + Uint16 newsr; + + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + dsp_abs56(dest); + + source[2] = 0; + source[1] = dsp_core.registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + dsp_abs56(source); + + newsr = dsp_sub56(source, dest); + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1; + + dsp_core.registers[DSP_REG_A1] <<= 1; + dsp_core.registers[DSP_REG_A1] &= BITMASK(24); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<>23) & 1; + + dsp_core.registers[DSP_REG_B1] <<= 1; + dsp_core.registers[DSP_REG_B1] &= BITMASK(24); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<>= 1; + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>= 1; + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+destreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+destreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+destreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_extension(&dest[0], &dest[1]); - dsp_ccr_unnormalized(&dest[0], &dest[1]); - dsp_ccr_negative(&dest[0]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<>4) & BITMASK(3); - srcreg1 = registers_mpy[value][0]; - srcreg2 = registers_mpy[value][1]; + dsp_mul56(dsp_core.registers[DSP_REG_X0], dsp_core.registers[DSP_REG_X0], source, SIGN_MINUS); + + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + newsr = dsp_add56(source, dest); - dsp_mul56(dsp_core->registers[srcreg1], dsp_core->registers[srcreg2], source); + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - if (cur_inst & (1<<2)) { - dest[0] = dest[1] = dest[2] = 0; + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_sub56(source, dest); + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + newsr = dsp_add56(source, dest); + + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_A2+destreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+destreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+destreg] = dest[2]; - - dsp_ccr_extension(&dest[0], &dest[1]); - dsp_ccr_unnormalized(&dest[0], &dest[1]); - dsp_ccr_negative(&dest[0]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<>4) & BITMASK(3); - srcreg1 = registers_mpy[value][0]; - srcreg2 = registers_mpy[value][1]; + dsp_mul56(dsp_core.registers[DSP_REG_X0], dsp_core.registers[DSP_REG_X0], source, SIGN_MINUS); - dsp_mul56(dsp_core->registers[srcreg1], dsp_core->registers[srcreg2], source); + dsp_core.registers[DSP_REG_A2] = source[0]; + dsp_core.registers[DSP_REG_A1] = source[1]; + dsp_core.registers[DSP_REG_A0] = source[2]; - destreg = (cur_inst>>3) & 1; - if (cur_inst & (1<<2)) { - dest[0] = dest[1] = dest[2] = 0; + dsp_ccr_update_e_u_n_z(source[0], source[1], source[2]); + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_A2+destreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+destreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+destreg] = dest[2]; - } else { - dsp_core->registers[DSP_REG_A2+destreg] = source[0]; - dsp_core->registers[DSP_REG_A1+destreg] = source[1]; - dsp_core->registers[DSP_REG_A0+destreg] = source[2]; - } + dsp_mul56(dsp_core.registers[DSP_REG_X0], dsp_core.registers[DSP_REG_X0], source, SIGN_PLUS); - dsp_ccr_extension(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg]); - dsp_ccr_unnormalized(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg]); - dsp_ccr_negative(&dsp_core->registers[DSP_REG_A2+destreg]); - dsp_ccr_zero(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg], &dsp_core->registers[DSP_REG_A0+destreg]); + dsp_core.registers[DSP_REG_B2] = source[0]; + dsp_core.registers[DSP_REG_B1] = source[1]; + dsp_core.registers[DSP_REG_B0] = source[2]; - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<>4) & BITMASK(3); - srcreg1 = registers_mpy[value][0]; - srcreg2 = registers_mpy[value][1]; - dsp_mul56(dsp_core->registers[srcreg1], dsp_core->registers[srcreg2], source); + dsp_mul56(dsp_core.registers[DSP_REG_X0], dsp_core.registers[DSP_REG_X0], source, SIGN_MINUS); - destreg = (cur_inst>>3) & 1; - if (cur_inst & (1<<2)) { - dest[0] = dest[1] = dest[2] = 0; + dsp_core.registers[DSP_REG_B2] = source[0]; + dsp_core.registers[DSP_REG_B1] = source[1]; + dsp_core.registers[DSP_REG_B0] = source[2]; - dsp_sub56(source, dest); - } else { - dest[0] = source[0]; - dest[1] = source[1]; - dest[2] = source[2]; - } + dsp_ccr_update_e_u_n_z(source[0], source[1], source[2]); + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_A2+destreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+destreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+destreg] = dest[2]; +static void dsp_mpyr_m_y0_x0_b(void) +{ + Uint32 source[3]; + + dsp_mul56(dsp_core.registers[DSP_REG_Y0], dsp_core.registers[DSP_REG_X0], source, SIGN_MINUS); + dsp_rnd56(source); + + dsp_core.registers[DSP_REG_B2] = source[0]; + dsp_core.registers[DSP_REG_B1] = source[1]; + dsp_core.registers[DSP_REG_B0] = source[2]; + + dsp_ccr_update_e_u_n_z(source[0], source[1], source[2]); + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<>3) & 1; - source[0] = dsp_core->registers[DSP_REG_A2+srcreg]; - source[1] = dsp_core->registers[DSP_REG_A1+srcreg]; - source[2] = dsp_core->registers[DSP_REG_A0+srcreg]; + source[0] = dsp_core.registers[DSP_REG_A2]; + source[1] = dsp_core.registers[DSP_REG_A1]; + source[2] = dsp_core.registers[DSP_REG_A0]; overflowed = ((source[2]==0) && (source[1]==0) && (source[0]==0x80)); @@ -4216,390 +8030,892 @@ static void dsp_neg(void) dsp_sub56(source, dest); - dsp_core->registers[DSP_REG_A2+srcreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+srcreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+srcreg] = dest[2]; - - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= (overflowed<>3) & 1); + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<registers[dstreg] = ~dsp_core->registers[dstreg]; - dsp_core->registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */ +static void dsp_not_b(void) +{ + dsp_core.registers[DSP_REG_B1] = ~dsp_core.registers[DSP_REG_B1]; + dsp_core.registers[DSP_REG_B1] &= BITMASK(24); /* FIXME: useless ? */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<>23) & 1)<>4) & BITMASK(2)) { - case 1: - srcreg=DSP_REG_Y0; - break; - case 2: - srcreg=DSP_REG_X1; - break; - case 3: - srcreg=DSP_REG_Y1; - break; - case 0: - default: - srcreg=DSP_REG_X0; - } - dstreg = DSP_REG_A1+((cur_inst>>3) & 1); + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<registers[dstreg] |= dsp_core->registers[srcreg]; - dsp_core->registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */ +static void dsp_or_x0_b(void) +{ + dsp_core.registers[DSP_REG_B1] |= dsp_core.registers[DSP_REG_X0]; + dsp_core.registers[DSP_REG_B1] &= BITMASK(24); /* FIXME: useless ? */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<>23) & 1)<>3) & 1; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<>3) & 1); + newcarry = (dsp_core.registers[DSP_REG_A1]>>23) & 1; - newcarry = (dsp_core->registers[dstreg]>>23) & 1; + dsp_core.registers[DSP_REG_A1] <<= 1; + dsp_core.registers[DSP_REG_A1] |= newcarry; + dsp_core.registers[DSP_REG_A1] &= BITMASK(24); - dsp_core->registers[dstreg] <<= 1; - dsp_core->registers[dstreg] |= newcarry; - dsp_core->registers[dstreg] &= BITMASK(24); + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; - dsp_core->registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<>23) & 1; + + dsp_core.registers[DSP_REG_B1] <<= 1; + dsp_core.registers[DSP_REG_B1] |= newcarry; + dsp_core.registers[DSP_REG_B1] &= BITMASK(24); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<>= 1; + dsp_core.registers[DSP_REG_A1] |= newcarry<<23; + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1); +static void dsp_ror_b(void) +{ + Uint32 newcarry; - newcarry = dsp_core->registers[dstreg] & 1; + newcarry = dsp_core.registers[DSP_REG_B1] & 1; - dsp_core->registers[dstreg] >>= 1; - dsp_core->registers[dstreg] |= newcarry<<23; - dsp_core->registers[dstreg] &= BITMASK(24); + dsp_core.registers[DSP_REG_B1] >>= 1; + dsp_core.registers[DSP_REG_B1] |= newcarry<<23; - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; - dsp_core->registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<registers[DSP_REG_SR]>>(DSP_SR_C)) & 1; + curcarry = (dsp_core.registers[DSP_REG_SR]>>(DSP_SR_C)) & 1; - destreg = (cur_inst>>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[0] = dsp_core.registers[DSP_REG_A2]; + + source[2] = dsp_core.registers[DSP_REG_X0]; + source[1] = dsp_core.registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; - srcreg = (cur_inst>>4) & 1; - if (srcreg == 0) { /* X */ - source[1] = dsp_core->registers[DSP_REG_X1]; - source[2] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } + newsr = dsp_sub56(source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_sub56(source, dest); } - else { /* Y */ - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[2] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } + + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>(DSP_SR_C)) & 1; + + dest[2] = dsp_core.registers[DSP_REG_B0]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[0] = dsp_core.registers[DSP_REG_B2]; + + source[2] = dsp_core.registers[DSP_REG_X0]; + source[1] = dsp_core.registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_sub56(source, dest); } + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>(DSP_SR_C)) & 1; + + dest[2] = dsp_core.registers[DSP_REG_A0]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[0] = dsp_core.registers[DSP_REG_A2]; + + source[2] = dsp_core.registers[DSP_REG_Y0]; + source[1] = dsp_core.registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + newsr = dsp_sub56(source, dest); - + if (curcarry) { - source[0]=0; - source[1]=0; - source[2]=1; + source[0]=0; source[1]=0; source[2]=1; newsr |= dsp_sub56(source, dest); } - dsp_core->registers[DSP_REG_A2+destreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+destreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+destreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_extension(&dest[0], &dest[1]); - dsp_ccr_unnormalized(&dest[0], &dest[1]); - dsp_ccr_negative(&dest[0]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; - - srcreg = (cur_inst>>4) & BITMASK(3); - switch(srcreg) { - case 1: /* A or B */ - srcreg = destreg ^ 1; - source[0] = dsp_core->registers[DSP_REG_A2+srcreg]; - source[1] = dsp_core->registers[DSP_REG_A1+srcreg]; - source[2] = dsp_core->registers[DSP_REG_A0+srcreg]; - break; - case 2: /* X */ - source[1] = dsp_core->registers[DSP_REG_X1]; - source[2] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 3: /* Y */ - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[2] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 4: /* X0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 5: /* Y0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 6: /* X1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 7: /* Y1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - default: - fprintf(stderr, "Dsp: source register undefined! dsp_cpu.cpp: %d\n", __LINE__); - return; + curcarry = (dsp_core.registers[DSP_REG_SR]>>(DSP_SR_C)) & 1; + + dest[2] = dsp_core.registers[DSP_REG_B0]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[0] = dsp_core.registers[DSP_REG_B2]; + + source[2] = dsp_core.registers[DSP_REG_Y0]; + source[1] = dsp_core.registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_sub56(source, dest); } + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+destreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+destreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+destreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_extension(&dest[0], &dest[1]); - dsp_ccr_unnormalized(&dest[0], &dest[1]); - dsp_ccr_negative(&dest[0]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; + dest[2] = dsp_core.registers[DSP_REG_B0]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[0] = dsp_core.registers[DSP_REG_B2]; + + source[2] = dsp_core.registers[DSP_REG_A0]; + source[1] = dsp_core.registers[DSP_REG_A1]; + source[0] = dsp_core.registers[DSP_REG_A2]; + + newsr = dsp_sub56(source, dest); + + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; +static void dsp_subl_a(void) +{ + Uint32 source[3], dest[3]; + Uint16 newsr; + + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; newsr = dsp_asl56(dest); - source[0] = dsp_core->registers[DSP_REG_A2+(numreg ^ 1)]; - source[1] = dsp_core->registers[DSP_REG_A1+(numreg ^ 1)]; - source[2] = dsp_core->registers[DSP_REG_A0+(numreg ^ 1)]; + source[0] = dsp_core.registers[DSP_REG_B2]; + source[1] = dsp_core.registers[DSP_REG_B1]; + source[2] = dsp_core.registers[DSP_REG_B0]; newsr |= dsp_sub56(source, dest); - dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_extension(&dest[0], &dest[1]); - dsp_ccr_unnormalized(&dest[0], &dest[1]); - dsp_ccr_negative(&dest[0]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + newsr = dsp_asl56(dest); + + source[0] = dsp_core.registers[DSP_REG_A2]; + source[1] = dsp_core.registers[DSP_REG_A1]; + source[2] = dsp_core.registers[DSP_REG_A0]; + newsr |= dsp_sub56(source, dest); + + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; newsr = dsp_asr56(dest); - source[0] = dsp_core->registers[DSP_REG_A2+(numreg ^ 1)]; - source[1] = dsp_core->registers[DSP_REG_A1+(numreg ^ 1)]; - source[2] = dsp_core->registers[DSP_REG_A0+(numreg ^ 1)]; + source[0] = dsp_core.registers[DSP_REG_B2]; + source[1] = dsp_core.registers[DSP_REG_B1]; + source[2] = dsp_core.registers[DSP_REG_B0]; + newsr |= dsp_sub56(source, dest); - dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; - - dsp_ccr_extension(&dest[0], &dest[1]); - dsp_ccr_unnormalized(&dest[0], &dest[1]); - dsp_ccr_negative(&dest[0]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); - - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; -} - -static void dsp_tfr(void) -{ - Uint32 srcreg, destreg, source[3]; - - destreg = (cur_inst>>3) & 1; - - srcreg = (cur_inst>>4) & BITMASK(3); - switch(srcreg) { - case 0: /* A or B */ - srcreg = destreg ^ 1; - source[0] = dsp_core->registers[DSP_REG_A2+srcreg]; - source[1] = dsp_core->registers[DSP_REG_A1+srcreg]; - source[2] = dsp_core->registers[DSP_REG_A0+srcreg]; - break; - case 4: /* X0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 5: /* Y0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 6: /* X1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 7: /* Y1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - default: - return; - } + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_core->registers[DSP_REG_A2+destreg] = source[0]; - dsp_core->registers[DSP_REG_A1+destreg] = source[1]; - dsp_core->registers[DSP_REG_A0+destreg] = source[2]; + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; + Uint32 source[3], dest[3]; + Uint16 newsr; + + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + + newsr = dsp_asr56(dest); - dsp_ccr_extension(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg]); - dsp_ccr_unnormalized(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg]); - dsp_ccr_negative(&dsp_core->registers[DSP_REG_A2+destreg]); - dsp_ccr_zero(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg], &dsp_core->registers[DSP_REG_A0+destreg]); + source[0] = dsp_core.registers[DSP_REG_A2]; + source[1] = dsp_core.registers[DSP_REG_A1]; + source[2] = dsp_core.registers[DSP_REG_A0]; + + newsr |= dsp_sub56(source, dest); + + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-(1<