From 9490ae7e786ff6ef5307203eb5bc5d59b14fcbc7 Mon Sep 17 00:00:00 2001 From: espes Date: Thu, 11 Jun 2015 22:58:39 +1000 Subject: [PATCH] factor --- hw/xbox/dsp/Makefile.objs | 2 +- hw/xbox/dsp/dsp.c | 11 +- hw/xbox/dsp/dsp.h | 3 + hw/xbox/dsp/dsp_cpu.c | 8410 +-------------------- hw/xbox/dsp/dsp_cpu.h | 16 +- hw/xbox/dsp/{dsp_disasm.c => dsp_dis.inl} | 1175 ++- hw/xbox/dsp/dsp_disasm.h | 145 - hw/xbox/dsp/dsp_emu.inl | 7374 ++++++++++++++++++ hw/xbox/dsp/dsp_int.h | 55 +- 9 files changed, 8322 insertions(+), 8869 deletions(-) rename hw/xbox/dsp/{dsp_disasm.c => dsp_dis.inl} (50%) delete mode 100644 hw/xbox/dsp/dsp_disasm.h create mode 100644 hw/xbox/dsp/dsp_emu.inl diff --git a/hw/xbox/dsp/Makefile.objs b/hw/xbox/dsp/Makefile.objs index 073e7adb92..eb44da36e8 100644 --- a/hw/xbox/dsp/Makefile.objs +++ b/hw/xbox/dsp/Makefile.objs @@ -1 +1 @@ -obj-y += dsp.o dsp_cpu.o dsp_disasm.o +obj-y += dsp.o dsp_cpu.o diff --git a/hw/xbox/dsp/dsp.c b/hw/xbox/dsp/dsp.c index de0b991629..7809134735 100644 --- a/hw/xbox/dsp/dsp.c +++ b/hw/xbox/dsp/dsp.c @@ -27,7 +27,6 @@ #include #include "dsp_cpu.h" -#include "dsp_disasm.h" #include "dsp_int.h" #include "dsp.h" @@ -52,7 +51,7 @@ void dsp_init(void) memset(&dsp_core, 0, sizeof(dsp_core_t)); - dsp56k_init_cpu(); + dsp56k_init_cpu(&dsp_core); save_cycles = 0; } @@ -99,7 +98,7 @@ void dsp_run(int cycles) // fprintf(stderr, "--> %d\n", save_cycles); while (save_cycles > 0) { - dsp56k_execute_instruction(); + dsp56k_execute_instruction(&dsp_core); save_cycles -= dsp_core.instr_cycle; } @@ -157,7 +156,7 @@ uint32_t dsp_disasm_address(FILE *out, uint32_t lowerAdr, uint32_t UpperAdr) uint32_t dsp_pc; for (dsp_pc=lowerAdr; dsp_pc<=UpperAdr; dsp_pc++) { - dsp_pc += dsp56k_execute_one_disasm_instruction(out, dsp_pc); + dsp_pc += dsp56k_execute_one_disasm_instruction(&dsp_core, out, dsp_pc); } return dsp_pc; } @@ -197,7 +196,7 @@ uint32_t dsp_read_memory(uint32_t address, char space_id, const char **mem_str) assert(false); } - return dsp56k_read_memory(space, address); + return dsp56k_read_memory(&dsp_core, space, address); } @@ -504,5 +503,5 @@ void dsp_core_reset(void) dsp_core.loop_rep = 0; DPRINTF("Dsp: reset done\n"); - dsp56k_init_cpu(); + dsp56k_init_cpu(&dsp_core); } diff --git a/hw/xbox/dsp/dsp.h b/hw/xbox/dsp/dsp.h index 64e303b35f..fdc60c7389 100644 --- a/hw/xbox/dsp/dsp.h +++ b/hw/xbox/dsp/dsp.h @@ -27,6 +27,9 @@ #include #include +#include + +typedef struct dsp_core_s dsp_core_t; /* Dsp commands */ bool dsp_process_irq(void); diff --git a/hw/xbox/dsp/dsp_cpu.c b/hw/xbox/dsp/dsp_cpu.c index 5017343153..d0be870cc3 100644 --- a/hw/xbox/dsp/dsp_cpu.c +++ b/hw/xbox/dsp/dsp_cpu.c @@ -23,9 +23,8 @@ #include #include -#include "dsp_disasm.h" +#include "dsp.h" #include "dsp_int.h" - #include "dsp_cpu.h" #define TRACE_DSP_DISASM 1 @@ -47,466 +46,47 @@ #define SIGN_PLUS 0 #define SIGN_MINUS 1 -/********************************** - * Variables - **********************************/ - -/* Instructions per second */ -#ifdef DSP_COUNT_IPS -static uint32_t start_time; -#endif -static uint32_t num_inst; - -/* Length of current instruction */ -static uint32_t cur_inst_len; /* =0:jump, >0:increment */ - -/* Current instruction */ -static uint32_t cur_inst; - -/* DSP is in disasm mode ? */ -/* If yes, stack overflow, underflow and illegal instructions messages are not displayed */ -static bool is_dsp_in_disasm_mode; - -static char str_disasm_memory[2][50]; /* Buffer for memory change text in disasm mode */ -static uint32_t disasm_memory_ptr; /* Pointer for memory change in disasm mode */ - -static bool bExceptionDebugging = false; - /********************************** * Functions **********************************/ -static void dsp_postexecute_update_pc(void); -static void dsp_postexecute_interrupts(void); +static void dsp_postexecute_update_pc(dsp_core_t* dsp); +static void dsp_postexecute_interrupts(dsp_core_t* dsp); -static void dsp_ccr_update_e_u_n_z(uint32_t reg0, uint32_t reg1, uint32_t reg2); +static uint32_t read_memory_p(dsp_core_t* dsp, uint32_t address); +static uint32_t read_memory_disasm(dsp_core_t* dsp, int space, uint32_t address); -static uint32_t read_memory_p(uint32_t address); -static uint32_t read_memory_disasm(int space, uint32_t address); +static void write_memory_raw(dsp_core_t* dsp, int space, uint32_t address, uint32_t value); +static void write_memory_disasm(dsp_core_t* dsp, int space, uint32_t address, uint32_t value); -static void write_memory_raw(int space, uint32_t address, uint32_t value); -static void write_memory_disasm(int space, uint32_t address, uint32_t value); +static void dsp_write_reg(dsp_core_t* dsp, uint32_t numreg, uint32_t value); -static void dsp_write_reg(uint32_t numreg, uint32_t value); - -static void dsp_stack_push(uint32_t curpc, uint32_t cursr, uint16_t sshOnly); -static void dsp_stack_pop(uint32_t *curpc, uint32_t *cursr); -static void dsp_compute_ssh_ssl(void); - -static void dsp_update_rn(uint32_t numreg, int16_t modifier); -static void dsp_update_rn_bitreverse(uint32_t numreg); -static void dsp_update_rn_modulo(uint32_t numreg, int16_t modifier); -static int dsp_calc_ea(uint32_t ea_mode, uint32_t *dst_addr); -static int dsp_calc_cc(uint32_t cc_code); - -typedef void (*emu_func_t)(void); - -static void emu_undefined(void); - -/* Instructions without parallel moves */ -static void emu_add_long(void); -static void emu_andi(void); -static void emu_bcc_long(void); -static void emu_bcc_imm(void); -static void emu_bchg_aa(void); -static void emu_bchg_ea(void); -static void emu_bchg_pp(void); -static void emu_bchg_reg(void); -static void emu_bclr_aa(void); -static void emu_bclr_ea(void); -static void emu_bclr_pp(void); -static void emu_bclr_reg(void); -static void emu_bra_imm(void); -static void emu_bset_aa(void); -static void emu_bset_ea(void); -static void emu_bset_pp(void); -static void emu_bset_reg(void); -static void emu_btst_aa(void); -static void emu_btst_ea(void); -static void emu_btst_pp(void); -static void emu_btst_reg(void); -static void emu_cmpu(void); -static void emu_div(void); -static void emu_enddo(void); -static void emu_illegal(void); -static void emu_jcc_imm(void); -static void emu_jcc_ea(void); -static void emu_jclr_aa(void); -static void emu_jclr_ea(void); -static void emu_jclr_pp(void); -static void emu_jclr_reg(void); -static void emu_jmp_ea(void); -static void emu_jmp_imm(void); -static void emu_jscc_ea(void); -static void emu_jscc_imm(void); -static void emu_jsclr_aa(void); -static void emu_jsclr_ea(void); -static void emu_jsclr_pp(void); -static void emu_jsclr_reg(void); -static void emu_jset_aa(void); -static void emu_jset_ea(void); -static void emu_jset_pp(void); -static void emu_jset_reg(void); -static void emu_jsr_ea(void); -static void emu_jsr_imm(void); -static void emu_jsset_aa(void); -static void emu_jsset_ea(void); -static void emu_jsset_pp(void); -static void emu_jsset_reg(void); -static void emu_lua(void); -static void emu_movem_ea(void); -static void emu_movem_aa(void); -static void emu_nop(void); -static void emu_norm(void); -static void emu_ori(void); -static void emu_reset(void); -static void emu_rti(void); -static void emu_rts(void); -static void emu_stop(void); -static void emu_swi(void); -static void emu_tcc(void); -static void emu_wait(void); - -static void emu_do_ea(void); -static void emu_do_aa(void); -static void emu_do_imm(void); -static void emu_do_reg(void); -static void emu_dor_imm(void); -static void emu_rep_aa(void); -static void emu_rep_ea(void); -static void emu_rep_imm(void); -static void emu_rep_reg(void); -static void emu_movec_aa(void); -static void emu_movec_ea(void); -static void emu_movec_imm(void); -static void emu_movec_reg(void); -static void emu_movep_0(void); -static void emu_movep_1(void); -static void emu_movep_23(void); - -static void emu_movep_x_low(void); -static void emu_move_x_aa(void); - -/* Parallel move analyzer */ -static int emu_pm_read_accu24(int numreg, uint32_t *dest); -static void emu_pm_0(void); -static void emu_pm_1(void); -static void emu_pm_2(void); -static void emu_pm_2_2(void); -static void emu_pm_3(void); -static void emu_pm_4(void); -static void emu_pm_4x(void); -static void emu_pm_5(void); -static void emu_pm_8(void); +static void dsp_stack_push(dsp_core_t* dsp, uint32_t curpc, uint32_t cursr, uint16_t sshOnly); +static void dsp_stack_pop(dsp_core_t* dsp, uint32_t *curpc, uint32_t *cursr); +static void dsp_compute_ssh_ssl(dsp_core_t* dsp); /* 56bits arithmetic */ -static uint16_t dsp_abs56(uint32_t *dest); -static uint16_t dsp_asl56(uint32_t *dest); -static uint16_t dsp_asr56(uint32_t *dest); -static uint16_t dsp_add56(uint32_t *source, uint32_t *dest); -static uint16_t dsp_sub56(uint32_t *source, uint32_t *dest); -static void dsp_mul56(uint32_t source1, uint32_t source2, uint32_t *dest, uint8_t signe); -static void dsp_rnd56(uint32_t *dest); +static uint16_t dsp_abs56(dsp_core_t* dsp, uint32_t *dest); +static uint16_t dsp_asl56(dsp_core_t* dsp, uint32_t *dest); +static uint16_t dsp_asr56(dsp_core_t* dsp, uint32_t *dest); +static uint16_t dsp_add56(dsp_core_t* dsp, uint32_t *source, uint32_t *dest); +static uint16_t dsp_sub56(dsp_core_t* dsp, uint32_t *source, uint32_t *dest); +static void dsp_mul56(dsp_core_t* dsp, uint32_t source1, uint32_t source2, uint32_t *dest, uint8_t signe); +static void dsp_rnd56(dsp_core_t* dsp, uint32_t *dest); -/* Instructions with parallel moves */ -static void emu_abs_a(void); -static void emu_abs_b(void); -static void emu_adc_x_a(void); -static void emu_adc_x_b(void); -static void emu_adc_y_a(void); -static void emu_adc_y_b(void); -static void emu_add_b_a(void); -static void emu_add_a_b(void); -static void emu_add_x_a(void); -static void emu_add_x_b(void); -static void emu_add_y_a(void); -static void emu_add_y_b(void); -static void emu_add_x0_a(void); -static void emu_add_x0_b(void); -static void emu_add_y0_a(void); -static void emu_add_y0_b(void); -static void emu_add_x1_a(void); -static void emu_add_x1_b(void); -static void emu_add_y1_a(void); -static void emu_add_y1_b(void); -static void emu_addl_b_a(void); -static void emu_addl_b_a(void); -static void emu_addl_a_b(void); -static void emu_addr_b_a(void); -static void emu_addr_a_b(void); -static void emu_and_x0_a(void); -static void emu_and_x0_b(void); -static void emu_and_y0_a(void); -static void emu_and_y0_b(void); -static void emu_and_x1_a(void); -static void emu_and_x1_b(void); -static void emu_and_y1_a(void); -static void emu_and_y1_b(void); -static void emu_asl_a(void); -static void emu_asl_b(void); -static void emu_asr_a(void); -static void emu_asr_b(void); -static void emu_clr_a(void); -static void emu_clr_b(void); -static void emu_cmp_b_a(void); -static void emu_cmp_a_b(void); -static void emu_cmp_x0_a(void); -static void emu_cmp_x0_b(void); -static void emu_cmp_y0_a(void); -static void emu_cmp_y0_b(void); -static void emu_cmp_x1_a(void); -static void emu_cmp_x1_b(void); -static void emu_cmp_y1_a(void); -static void emu_cmp_y1_b(void); -static void emu_cmpm_b_a(void); -static void emu_cmpm_a_b(void); -static void emu_cmpm_x0_a(void); -static void emu_cmpm_x0_b(void); -static void emu_cmpm_y0_a(void); -static void emu_cmpm_y0_b(void); -static void emu_cmpm_x1_a(void); -static void emu_cmpm_x1_b(void); -static void emu_cmpm_y1_a(void); -static void emu_cmpm_y1_b(void); -static void emu_eor_x0_a(void); -static void emu_eor_x0_b(void); -static void emu_eor_y0_a(void); -static void emu_eor_y0_b(void); -static void emu_eor_x1_a(void); -static void emu_eor_x1_b(void); -static void emu_eor_y1_a(void); -static void emu_eor_y1_b(void); -static void emu_lsl_a(void); -static void emu_lsl_b(void); -static void emu_lsr_a(void); -static void emu_lsr_b(void); -static void emu_mac_p_x0_x0_a(void); -static void emu_mac_m_x0_x0_a(void); -static void emu_mac_p_x0_x0_b(void); -static void emu_mac_m_x0_x0_b(void); -static void emu_mac_p_y0_y0_a(void); -static void emu_mac_m_y0_y0_a(void); -static void emu_mac_p_y0_y0_b(void); -static void emu_mac_m_y0_y0_b(void); -static void emu_mac_p_x1_x0_a(void); -static void emu_mac_m_x1_x0_a(void); -static void emu_mac_p_x1_x0_b(void); -static void emu_mac_m_x1_x0_b(void); -static void emu_mac_p_y1_y0_a(void); -static void emu_mac_m_y1_y0_a(void); -static void emu_mac_p_y1_y0_b(void); -static void emu_mac_m_y1_y0_b(void); -static void emu_mac_p_x0_y1_a(void); -static void emu_mac_m_x0_y1_a(void); -static void emu_mac_p_x0_y1_b(void); -static void emu_mac_m_x0_y1_b(void); -static void emu_mac_p_y0_x0_a(void); -static void emu_mac_m_y0_x0_a(void); -static void emu_mac_p_y0_x0_b(void); -static void emu_mac_m_y0_x0_b(void); -static void emu_mac_p_x1_y0_a(void); -static void emu_mac_m_x1_y0_a(void); -static void emu_mac_p_x1_y0_b(void); -static void emu_mac_m_x1_y0_b(void); -static void emu_mac_p_y1_x1_a(void); -static void emu_mac_m_y1_x1_a(void); -static void emu_mac_p_y1_x1_b(void); -static void emu_mac_m_y1_x1_b(void); -static void emu_macr_p_x0_x0_a(void); -static void emu_macr_m_x0_x0_a(void); -static void emu_macr_p_x0_x0_b(void); -static void emu_macr_m_x0_x0_b(void); -static void emu_macr_p_y0_y0_a(void); -static void emu_macr_m_y0_y0_a(void); -static void emu_macr_p_y0_y0_b(void); -static void emu_macr_m_y0_y0_b(void); -static void emu_macr_p_x1_x0_a(void); -static void emu_macr_m_x1_x0_a(void); -static void emu_macr_p_x1_x0_b(void); -static void emu_macr_m_x1_x0_b(void); -static void emu_macr_p_y1_y0_a(void); -static void emu_macr_m_y1_y0_a(void); -static void emu_macr_p_y1_y0_b(void); -static void emu_macr_m_y1_y0_b(void); -static void emu_macr_p_x0_y1_a(void); -static void emu_macr_m_x0_y1_a(void); -static void emu_macr_p_x0_y1_b(void); -static void emu_macr_m_x0_y1_b(void); -static void emu_macr_p_y0_x0_a(void); -static void emu_macr_m_y0_x0_a(void); -static void emu_macr_p_y0_x0_b(void); -static void emu_macr_m_y0_x0_b(void); -static void emu_macr_p_x1_y0_a(void); -static void emu_macr_m_x1_y0_a(void); -static void emu_macr_p_x1_y0_b(void); -static void emu_macr_m_x1_y0_b(void); -static void emu_macr_p_y1_x1_a(void); -static void emu_macr_m_y1_x1_a(void); -static void emu_macr_p_y1_x1_b(void); -static void emu_macr_m_y1_x1_b(void); -static void emu_move(void); -static void emu_mpy_p_x0_x0_a(void); -static void emu_mpy_m_x0_x0_a(void); -static void emu_mpy_p_x0_x0_b(void); -static void emu_mpy_m_x0_x0_b(void); -static void emu_mpy_p_y0_y0_a(void); -static void emu_mpy_m_y0_y0_a(void); -static void emu_mpy_p_y0_y0_b(void); -static void emu_mpy_m_y0_y0_b(void); -static void emu_mpy_p_x1_x0_a(void); -static void emu_mpy_m_x1_x0_a(void); -static void emu_mpy_p_x1_x0_b(void); -static void emu_mpy_m_x1_x0_b(void); -static void emu_mpy_p_y1_y0_a(void); -static void emu_mpy_m_y1_y0_a(void); -static void emu_mpy_p_y1_y0_b(void); -static void emu_mpy_m_y1_y0_b(void); -static void emu_mpy_p_x0_y1_a(void); -static void emu_mpy_m_x0_y1_a(void); -static void emu_mpy_p_x0_y1_b(void); -static void emu_mpy_m_x0_y1_b(void); -static void emu_mpy_p_y0_x0_a(void); -static void emu_mpy_m_y0_x0_a(void); -static void emu_mpy_p_y0_x0_b(void); -static void emu_mpy_m_y0_x0_b(void); -static void emu_mpy_p_x1_y0_a(void); -static void emu_mpy_m_x1_y0_a(void); -static void emu_mpy_p_x1_y0_b(void); -static void emu_mpy_m_x1_y0_b(void); -static void emu_mpy_p_y1_x1_a(void); -static void emu_mpy_m_y1_x1_a(void); -static void emu_mpy_p_y1_x1_b(void); -static void emu_mpy_m_y1_x1_b(void); -static void emu_mpyr_p_x0_x0_a(void); -static void emu_mpyr_m_x0_x0_a(void); -static void emu_mpyr_p_x0_x0_b(void); -static void emu_mpyr_m_x0_x0_b(void); -static void emu_mpyr_p_y0_y0_a(void); -static void emu_mpyr_m_y0_y0_a(void); -static void emu_mpyr_p_y0_y0_b(void); -static void emu_mpyr_m_y0_y0_b(void); -static void emu_mpyr_p_x1_x0_a(void); -static void emu_mpyr_m_x1_x0_a(void); -static void emu_mpyr_p_x1_x0_b(void); -static void emu_mpyr_m_x1_x0_b(void); -static void emu_mpyr_p_y1_y0_a(void); -static void emu_mpyr_m_y1_y0_a(void); -static void emu_mpyr_p_y1_y0_b(void); -static void emu_mpyr_m_y1_y0_b(void); -static void emu_mpyr_p_x0_y1_a(void); -static void emu_mpyr_m_x0_y1_a(void); -static void emu_mpyr_p_x0_y1_b(void); -static void emu_mpyr_m_x0_y1_b(void); -static void emu_mpyr_p_y0_x0_a(void); -static void emu_mpyr_m_y0_x0_a(void); -static void emu_mpyr_p_y0_x0_b(void); -static void emu_mpyr_m_y0_x0_b(void); -static void emu_mpyr_p_x1_y0_a(void); -static void emu_mpyr_m_x1_y0_a(void); -static void emu_mpyr_p_x1_y0_b(void); -static void emu_mpyr_m_x1_y0_b(void); -static void emu_mpyr_p_y1_x1_a(void); -static void emu_mpyr_m_y1_x1_a(void); -static void emu_mpyr_p_y1_x1_b(void); -static void emu_mpyr_m_y1_x1_b(void); -static void emu_neg_a(void); -static void emu_neg_b(void); -static void emu_not_a(void); -static void emu_not_b(void); -static void emu_or_x0_a(void); -static void emu_or_x0_b(void); -static void emu_or_y0_a(void); -static void emu_or_y0_b(void); -static void emu_or_x1_a(void); -static void emu_or_x1_b(void); -static void emu_or_y1_a(void); -static void emu_or_y1_b(void); -static void emu_rnd_a(void); -static void emu_rnd_b(void); -static void emu_rol_a(void); -static void emu_rol_b(void); -static void emu_ror_a(void); -static void emu_ror_b(void); -static void emu_sbc_x_a(void); -static void emu_sbc_x_b(void); -static void emu_sbc_y_a(void); -static void emu_sbc_y_b(void); -static void emu_sub_b_a(void); -static void emu_sub_a_b(void); -static void emu_sub_x_a(void); -static void emu_sub_x_b(void); -static void emu_sub_y_a(void); -static void emu_sub_y_b(void); -static void emu_sub_x0_a(void); -static void emu_sub_x0_b(void); -static void emu_sub_y0_a(void); -static void emu_sub_y0_b(void); -static void emu_sub_x1_a(void); -static void emu_sub_x1_b(void); -static void emu_sub_y1_a(void); -static void emu_sub_y1_b(void); -static void emu_subl_a(void); -static void emu_subl_b(void); -static void emu_subr_a(void); -static void emu_subr_b(void); -static void emu_tfr_b_a(void); -static void emu_tfr_a_b(void); -static void emu_tfr_x0_a(void); -static void emu_tfr_x0_b(void); -static void emu_tfr_y0_a(void); -static void emu_tfr_y0_b(void); -static void emu_tfr_x1_a(void); -static void emu_tfr_x1_b(void); -static void emu_tfr_y1_a(void); -static void emu_tfr_y1_b(void); -static void emu_tst_a(void); -static void emu_tst_b(void); - -static const emu_func_t opcodes_parmove[16] = { - emu_pm_0, emu_pm_1, emu_pm_2, emu_pm_3, emu_pm_4, emu_pm_5, emu_pm_5, emu_pm_5, - emu_pm_8, emu_pm_8, emu_pm_8, emu_pm_8, emu_pm_8, emu_pm_8, emu_pm_8, emu_pm_8 -}; - -static const emu_func_t opcodes_alu[256] = { - /* 0x00 - 0x3f */ - emu_move , emu_tfr_b_a, emu_addr_b_a, emu_tst_a, emu_undefined, emu_cmp_b_a, emu_subr_a, emu_cmpm_b_a, - emu_undefined, emu_tfr_a_b, emu_addr_a_b, emu_tst_b, emu_undefined, emu_cmp_a_b, emu_subr_b, emu_cmpm_a_b, - emu_add_b_a, emu_rnd_a, emu_addl_b_a, emu_clr_a, emu_sub_b_a, emu_undefined, emu_subl_a, emu_not_a, - emu_add_a_b, emu_rnd_b, emu_addl_a_b, emu_clr_b, emu_sub_a_b, emu_undefined, emu_subl_b, emu_not_b, - emu_add_x_a, emu_adc_x_a, emu_asr_a, emu_lsr_a, emu_sub_x_a, emu_sbc_x_a, emu_abs_a, emu_ror_a, - emu_add_x_b, emu_adc_x_b, emu_asr_b, emu_lsr_b, emu_sub_x_b, emu_sbc_x_b, emu_abs_b, emu_ror_b, - emu_add_y_a, emu_adc_y_a, emu_asl_a, emu_lsl_a, emu_sub_y_a, emu_sbc_y_a, emu_neg_a, emu_rol_a, - emu_add_y_b, emu_adc_y_b, emu_asl_b, emu_lsl_b, emu_sub_y_b, emu_sbc_y_b, emu_neg_b, emu_rol_b, - - /* 0x40 - 0x7f */ - emu_add_x0_a, emu_tfr_x0_a, emu_or_x0_a, emu_eor_x0_a, emu_sub_x0_a, emu_cmp_x0_a, emu_and_x0_a, emu_cmpm_x0_a, - emu_add_x0_b, emu_tfr_x0_b, emu_or_x0_b, emu_eor_x0_b, emu_sub_x0_b, emu_cmp_x0_b, emu_and_x0_b, emu_cmpm_x0_b, - emu_add_y0_a, emu_tfr_y0_a, emu_or_y0_a, emu_eor_y0_a, emu_sub_y0_a, emu_cmp_y0_a, emu_and_y0_a, emu_cmpm_y0_a, - emu_add_y0_b, emu_tfr_y0_b, emu_or_y0_b, emu_eor_y0_b, emu_sub_y0_b, emu_cmp_y0_b, emu_and_y0_b, emu_cmpm_y0_b, - emu_add_x1_a, emu_tfr_x1_a, emu_or_x1_a, emu_eor_x1_a, emu_sub_x1_a, emu_cmp_x1_a, emu_and_x1_a, emu_cmpm_x1_a, - emu_add_x1_b, emu_tfr_x1_b, emu_or_x1_b, emu_eor_x1_b, emu_sub_x1_b, emu_cmp_x1_b, emu_and_x1_b, emu_cmpm_x1_b, - emu_add_y1_a, emu_tfr_y1_a, emu_or_y1_a, emu_eor_y1_a, emu_sub_y1_a, emu_cmp_y1_a, emu_and_y1_a, emu_cmpm_y1_a, - emu_add_y1_b, emu_tfr_y1_b, emu_or_y1_b, emu_eor_y1_b, emu_sub_y1_b, emu_cmp_y1_b, emu_and_y1_b, emu_cmpm_y1_b, - - /* 0x80 - 0xbf */ - emu_mpy_p_x0_x0_a, emu_mpyr_p_x0_x0_a, emu_mac_p_x0_x0_a, emu_macr_p_x0_x0_a, emu_mpy_m_x0_x0_a, emu_mpyr_m_x0_x0_a, emu_mac_m_x0_x0_a, emu_macr_m_x0_x0_a, - emu_mpy_p_x0_x0_b, emu_mpyr_p_x0_x0_b, emu_mac_p_x0_x0_b, emu_macr_p_x0_x0_b, emu_mpy_m_x0_x0_b, emu_mpyr_m_x0_x0_b, emu_mac_m_x0_x0_b, emu_macr_m_x0_x0_b, - emu_mpy_p_y0_y0_a, emu_mpyr_p_y0_y0_a, emu_mac_p_y0_y0_a, emu_macr_p_y0_y0_a, emu_mpy_m_y0_y0_a, emu_mpyr_m_y0_y0_a, emu_mac_m_y0_y0_a, emu_macr_m_y0_y0_a, - emu_mpy_p_y0_y0_b, emu_mpyr_p_y0_y0_b, emu_mac_p_y0_y0_b, emu_macr_p_y0_y0_b, emu_mpy_m_y0_y0_b, emu_mpyr_m_y0_y0_b, emu_mac_m_y0_y0_b, emu_macr_m_y0_y0_b, - emu_mpy_p_x1_x0_a, emu_mpyr_p_x1_x0_a, emu_mac_p_x1_x0_a, emu_macr_p_x1_x0_a, emu_mpy_m_x1_x0_a, emu_mpyr_m_x1_x0_a, emu_mac_m_x1_x0_a, emu_macr_m_x1_x0_a, - emu_mpy_p_x1_x0_b, emu_mpyr_p_x1_x0_b, emu_mac_p_x1_x0_b, emu_macr_p_x1_x0_b, emu_mpy_m_x1_x0_b, emu_mpyr_m_x1_x0_b, emu_mac_m_x1_x0_b, emu_macr_m_x1_x0_b, - emu_mpy_p_y1_y0_a, emu_mpyr_p_y1_y0_a, emu_mac_p_y1_y0_a, emu_macr_p_y1_y0_a, emu_mpy_m_y1_y0_a, emu_mpyr_m_y1_y0_a, emu_mac_m_y1_y0_a, emu_macr_m_y1_y0_a, - emu_mpy_p_y1_y0_b, emu_mpyr_p_y1_y0_b, emu_mac_p_y1_y0_b, emu_macr_p_y1_y0_b, emu_mpy_m_y1_y0_b, emu_mpyr_m_y1_y0_b, emu_mac_m_y1_y0_b, emu_macr_m_y1_y0_b, - - /* 0xc0_m_ 0xff */ - emu_mpy_p_x0_y1_a, emu_mpyr_p_x0_y1_a, emu_mac_p_x0_y1_a, emu_macr_p_x0_y1_a, emu_mpy_m_x0_y1_a, emu_mpyr_m_x0_y1_a, emu_mac_m_x0_y1_a, emu_macr_m_x0_y1_a, - emu_mpy_p_x0_y1_b, emu_mpyr_p_x0_y1_b, emu_mac_p_x0_y1_b, emu_macr_p_x0_y1_b, emu_mpy_m_x0_y1_b, emu_mpyr_m_x0_y1_b, emu_mac_m_x0_y1_b, emu_macr_m_x0_y1_b, - emu_mpy_p_y0_x0_a, emu_mpyr_p_y0_x0_a, emu_mac_p_y0_x0_a, emu_macr_p_y0_x0_a, emu_mpy_m_y0_x0_a, emu_mpyr_m_y0_x0_a, emu_mac_m_y0_x0_a, emu_macr_m_y0_x0_a, - emu_mpy_p_y0_x0_b, emu_mpyr_p_y0_x0_b, emu_mac_p_y0_x0_b, emu_macr_p_y0_x0_b, emu_mpy_m_y0_x0_b, emu_mpyr_m_y0_x0_b, emu_mac_m_y0_x0_b, emu_macr_m_y0_x0_b, - emu_mpy_p_x1_y0_a, emu_mpyr_p_x1_y0_a, emu_mac_p_x1_y0_a, emu_macr_p_x1_y0_a, emu_mpy_m_x1_y0_a, emu_mpyr_m_x1_y0_a, emu_mac_m_x1_y0_a, emu_macr_m_x1_y0_a, - emu_mpy_p_x1_y0_b, emu_mpyr_p_x1_y0_b, emu_mac_p_x1_y0_b, emu_macr_p_x1_y0_b, emu_mpy_m_x1_y0_b, emu_mpyr_m_x1_y0_b, emu_mac_m_x1_y0_b, emu_macr_m_x1_y0_b, - emu_mpy_p_y1_x1_a, emu_mpyr_p_y1_x1_a, emu_mac_p_y1_x1_a, emu_macr_p_y1_x1_a, emu_mpy_m_y1_x1_a, emu_mpyr_m_y1_x1_a, emu_mac_m_y1_x1_a, emu_macr_m_y1_x1_a, - emu_mpy_p_y1_x1_b, emu_mpyr_p_y1_x1_b, emu_mac_p_y1_x1_b, emu_macr_p_y1_x1_b, emu_mpy_m_y1_x1_b, emu_mpyr_m_y1_x1_b, emu_mac_m_y1_x1_b, emu_macr_m_y1_x1_b +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"} }; static const int registers_tcc[16][2] = { @@ -553,21 +133,9 @@ static const int registers_mask[64] = { 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"} -}; +#include "dsp_emu.inl" +#include "dsp_dis.inl" typedef struct OpcodeEntry { const char* template; @@ -772,7 +340,7 @@ static uint32_t nonparallel_matches[ARRAYSIZE(nonparallel_opcodes)][2]; * Emulator kernel **********************************/ -void dsp56k_init_cpu(void) +void dsp56k_init_cpu(dsp_core_t* dsp) { int i; for (i=0; iin_disasm_mode = false; // start_time = SDL_GetTicks(); - num_inst = 0; + dsp->num_inst = 0; } - -typedef enum { - DSP_TRACE_MODE, - DSP_DISASM_MODE -} dsp_trace_disasm_t; - static OpcodeEntry lookup_opcode(uint32_t op) { OpcodeEntry r = {0}; int i; @@ -817,141 +379,267 @@ static OpcodeEntry lookup_opcode(uint32_t op) { return r; } -static uint16_t dsp56k_disasm(dsp_trace_disasm_t mode) +typedef enum { + DSP_TRACE_MODE, + DSP_DISASM_MODE +} dsp_trace_disasm_t; + +static uint16_t disasm_instruction(dsp_core_t* dsp, dsp_trace_disasm_t mode) { uint32_t value; if (mode == DSP_TRACE_MODE) { - isInDisasmMode = false; - if (prev_inst_pc == dsp_core.pc) { - if (!isLooping) { - fprintf(stderr, "Looping on DSP instruction at PC = $%04x\n", prev_inst_pc); - isLooping = true; + dsp->isInDisasmMode = false; + if (dsp->disasm_prev_inst_pc == dsp->pc) { + if (!dsp->disasm_is_looping) { + fprintf(stderr, "Looping on DSP instruction at PC = $%04x\n", dsp->disasm_prev_inst_pc); + dsp->disasm_is_looping = true; } return 0; } } else { - isInDisasmMode = true; + dsp->isInDisasmMode = true; } - prev_inst_pc = dsp_core.pc; - isLooping = false; + dsp->disasm_prev_inst_pc = dsp->pc; + dsp->disasm_is_looping = false; - disasm_cur_inst = dsp56k_read_memory(DSP_SPACE_P, dsp_core.pc); - disasm_cur_inst_len = 1; + dsp->disasm_cur_inst = dsp56k_read_memory(dsp, DSP_SPACE_P, dsp->pc); + dsp->disasm_cur_inst_len = 1; - strcpy(parallelmove_name, ""); + dsp->disasm_parallelmove_name[0] = 0; - if (disasm_cur_inst < 0x100000) { - const OpcodeEntry op = lookup_opcode(disasm_cur_inst); + if (dsp->disasm_cur_inst < 0x100000) { + const OpcodeEntry op = lookup_opcode(dsp->disasm_cur_inst); if (op.template) { if (op.dis_func) { - op.dis_func(); + op.dis_func(dsp); } else { - sprintf(str_instr, "%s", op.name); + sprintf(dsp->disasm_str_instr, "%s", op.name); } } else { - dis_undefined(); + dis_undefined(dsp); } } else { - dis_pm_class2(); + dis_pm(dsp); + sprintf(dsp->disasm_str_instr, "%s %s", + disasm_opcodes_alu[dsp->disasm_cur_inst & BITMASK(8)], dsp->disasm_parallelmove_name); } - return disasm_cur_inst_len; + return dsp->disasm_cur_inst_len; } +static void disasm_reg_save(dsp_core_t* dsp) +{ + memcpy(dsp->disasm_registers_save, dsp->registers , sizeof(dsp->disasm_registers_save)); +#if DSP_DISASM_REG_PC + dsp->pc_save = dsp->pc; +#endif +} + +static void disasm_reg_compare(dsp_core_t* dsp) +{ + int i; + bool bRegA = false; + bool bRegB = false; + + for (i=4; i<64; i++) { + if (dsp->disasm_registers_save[i] == dsp->registers[i]) { + continue; + } + + switch(i) { + case DSP_REG_X0: + case DSP_REG_X1: + case DSP_REG_Y0: + case DSP_REG_Y1: + fprintf(stderr,"\tReg: %s $%06x -> $%06x\n", + registers_name[i], dsp->disasm_registers_save[i], dsp->registers[i]); + 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_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: + 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_SR: + case DSP_REG_LA: + case DSP_REG_LC: + fprintf(stderr,"\tReg: %s $%04x -> $%04x\n", + registers_name[i], dsp->disasm_registers_save[i], dsp->registers[i]); + break; + case DSP_REG_OMR: + case DSP_REG_SP: + case DSP_REG_SSH: + case DSP_REG_SSL: + fprintf(stderr,"\tReg: %s $%02x -> $%02x\n", + registers_name[i], dsp->disasm_registers_save[i], dsp->registers[i]); + break; + case DSP_REG_A0: + case DSP_REG_A1: + case DSP_REG_A2: + if (bRegA == false) { + fprintf(stderr,"\tReg: a $%02x:%06x:%06x -> $%02x:%06x:%06x\n", + dsp->disasm_registers_save[DSP_REG_A2], dsp->disasm_registers_save[DSP_REG_A1], dsp->disasm_registers_save[DSP_REG_A0], + dsp->registers[DSP_REG_A2], dsp->registers[DSP_REG_A1], dsp->registers[DSP_REG_A0] + ); + bRegA = true; + } + break; + case DSP_REG_B0: + case DSP_REG_B1: + case DSP_REG_B2: + if (bRegB == false) { + fprintf(stderr,"\tReg: b $%02x:%06x:%06x -> $%02x:%06x:%06x\n", + dsp->disasm_registers_save[DSP_REG_B2], dsp->disasm_registers_save[DSP_REG_B1], dsp->disasm_registers_save[DSP_REG_B0], + dsp->registers[DSP_REG_B2], dsp->registers[DSP_REG_B1], dsp->registers[DSP_REG_B0] + ); + bRegB = true; + } + break; + } + } + +#if DSP_DISASM_REG_PC + if (pc_save != dsp->pc) { + fprintf(stderr,"\tReg: pc $%04x -> $%04x\n", pc_save, dsp->pc); + } +#endif +} + +const char* disasm_get_instruction_text(dsp_core_t* dsp) +{ + const int len = sizeof(dsp->disasm_str_instr); + // uint64_t count, cycles; + // uint16_t cycle_diff; + // float percentage; + int offset; + + if (dsp->disasm_is_looping) { + dsp->disasm_str_instr2[0] = 0; + } + if (dsp->disasm_cur_inst_len == 1) { + offset = sprintf(dsp->disasm_str_instr2, "p:%04x %06x (%02d cyc) %-*s\n", dsp->disasm_prev_inst_pc, dsp->disasm_cur_inst, dsp->instr_cycle, len, dsp->disasm_str_instr); + } else { + offset = sprintf(dsp->disasm_str_instr2, "p:%04x %06x %06x (%02d cyc) %-*s\n", dsp->disasm_prev_inst_pc, dsp->disasm_cur_inst, read_memory_p(dsp, dsp->disasm_prev_inst_pc + 1), dsp->instr_cycle, len, dsp->disasm_str_instr); + } + // if (offset > 2 && Profile_DspAddressData(dsp->disasm_prev_inst_pc, &percentage, &count, &cycles, &cycle_diff)) { + // offset -= 2; + // sprintf(str_instr2+offset, "%5.2f%% (%"PRId64", %"PRId64", %d)\n", + // percentage, count, cycles, cycle_diff); + // } + return dsp->disasm_str_instr2; +} /** * Execute one instruction in trace mode at a given PC address. * */ -uint16_t dsp56k_execute_one_disasm_instruction(FILE *out, uint32_t pc) +uint16_t dsp56k_execute_one_disasm_instruction(dsp_core_t* dsp, FILE *out, uint32_t pc) { - dsp_core_t dsp_core_save; + // dsp_core_t dsp_core_save; /* Set DSP in disasm mode */ - is_dsp_in_disasm_mode = true; + dsp->in_disasm_mode = true; /* Save DSP context before executing instruction */ - memcpy(&dsp_core_save, &dsp_core, sizeof(dsp_core)); + // memcpy(&dsp_core_save, &dsp_core, sizeof(dsp_core)); /* execute and disasm instruction */ - dsp_core.pc = pc; + dsp->pc = pc; /* Disasm instruction */ - uint16_t instruction_length = dsp56k_disasm(DSP_DISASM_MODE) - 1; + uint16_t instruction_length = disasm_instruction(dsp, DSP_DISASM_MODE) - 1; /* Execute instruction at address given in parameter to get the number of cycles it takes */ - dsp56k_execute_instruction(); + dsp56k_execute_instruction(dsp); - fprintf(out, "%s", dsp56k_get_instruction_text()); + fprintf(out, "%s", disasm_get_instruction_text(dsp)); /* Restore DSP context after executing instruction */ - memcpy(&dsp_core, &dsp_core_save, sizeof(dsp_core)); + // memcpy(&dsp_core, &dsp_core_save, sizeof(dsp_core)); /* Unset DSP in disasm mode */ - is_dsp_in_disasm_mode = false; + dsp->in_disasm_mode = false; return instruction_length; } -void dsp56k_execute_instruction(void) +void dsp56k_execute_instruction(dsp_core_t* dsp) { uint32_t value; uint32_t disasm_return = 0; - disasm_memory_ptr = 0; + dsp->disasm_memory_ptr = 0; /* Decode and execute current instruction */ - cur_inst = read_memory_p(dsp_core.pc); + dsp->cur_inst = read_memory_p(dsp, dsp->pc); /* Initialize instruction size and cycle counter */ - cur_inst_len = 1; - dsp_core.instr_cycle = 2; + dsp->cur_inst_len = 1; + dsp->instr_cycle = 2; /* Disasm current instruction ? (trace mode only) */ if (TRACE_DSP_DISASM) { - /* Call dsp56k_disasm only when DSP is called in trace mode */ - if (is_dsp_in_disasm_mode == false) { - disasm_return = dsp56k_disasm(DSP_TRACE_MODE); + /* Call disasm_instruction only when DSP is called in trace mode */ + if (dsp->in_disasm_mode == false) { + disasm_return = disasm_instruction(dsp, DSP_TRACE_MODE); if (disasm_return != 0 && TRACE_DSP_DISASM_REG) { /* DSP regs trace enabled only if DSP DISASM is enabled */ - dsp56k_disasm_reg_save(); + disasm_reg_save(dsp); } } } - if (cur_inst < 0x100000) { - const OpcodeEntry op = lookup_opcode(cur_inst); + if (dsp->cur_inst < 0x100000) { + const OpcodeEntry op = lookup_opcode(dsp->cur_inst); if (op.emu_func) { - op.emu_func(); + op.emu_func(dsp); } else { - printf("%x - %s\n", cur_inst, op.name); - emu_undefined(); + printf("%x - %s\n", dsp->cur_inst, op.name); + emu_undefined(dsp); } } else { /* Do parallel move read */ - opcodes_parmove[(cur_inst>>20) & BITMASK(4)](); + opcodes_parmove[(dsp->cur_inst>>20) & BITMASK(4)](dsp); } /* Disasm current instruction ? (trace mode only) */ if (TRACE_DSP_DISASM) { /* Display only when DSP is called in trace mode */ - if (is_dsp_in_disasm_mode == false) { + if (dsp->in_disasm_mode == false) { if (disasm_return != 0) { - fprintf(stderr, "%s", dsp56k_get_instruction_text()); + fprintf(stderr, "%s", disasm_get_instruction_text(dsp)); /* DSP regs trace enabled only if DSP DISASM is enabled */ if (TRACE_DSP_DISASM_REG) - dsp56k_disasm_reg_compare(); + disasm_reg_compare(dsp); if (TRACE_DSP_DISASM_MEM) { /* 1 memory change to display ? */ - if (disasm_memory_ptr == 1) - fprintf(stderr, "\t%s\n", str_disasm_memory[0]); + if (dsp->disasm_memory_ptr == 1) + fprintf(stderr, "\t%s\n", dsp->str_disasm_memory[0]); /* 2 memory changes to display ? */ - else if (disasm_memory_ptr == 2) { - fprintf(stderr, "\t%s\n", str_disasm_memory[0]); - fprintf(stderr, "\t%s\n", str_disasm_memory[1]); + else if (dsp->disasm_memory_ptr == 2) { + fprintf(stderr, "\t%s\n", dsp->str_disasm_memory[0]); + fprintf(stderr, "\t%s\n", dsp->str_disasm_memory[1]); } } } @@ -959,20 +647,20 @@ void dsp56k_execute_instruction(void) } /* Process the PC */ - dsp_postexecute_update_pc(); + dsp_postexecute_update_pc(dsp); /* Process Interrupts */ - dsp_postexecute_interrupts(); + dsp_postexecute_interrupts(dsp); #ifdef DSP_COUNT_IPS - ++num_inst; - if ((num_inst & 63) == 0) { + ++dsp->num_inst; + if ((dsp->num_inst & 63) == 0) { /* Evaluate time after instructions have been executed to avoid asking too frequently */ uint32_t cur_time = SDL_GetTicks(); if (cur_time-start_time>1000) { - fprintf(stderr, "Dsp: %d i/s\n", (num_inst*1000)/(cur_time-start_time)); + fprintf(stderr, "Dsp: %d i/s\n", (dsp->num_inst*1000)/(cur_time-start_time)); start_time=cur_time; - num_inst=0; + dsp->num_inst=0; } } #endif @@ -982,53 +670,53 @@ void dsp56k_execute_instruction(void) * Update the PC **********************************/ -static void dsp_postexecute_update_pc(void) +static void dsp_postexecute_update_pc(dsp_core_t* dsp) { /* When running a REP, PC must stay on the current instruction */ - if (dsp_core.loop_rep) { + if (dsp->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->pc_on_rep==0) { + --dsp->registers[DSP_REG_LC]; + dsp->registers[DSP_REG_LC] &= BITMASK(16); - if (dsp_core.registers[DSP_REG_LC] > 0) { - cur_inst_len = 0; /* Stay on this instruction */ + if (dsp->registers[DSP_REG_LC] > 0) { + dsp->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->loop_rep = 0; + dsp->registers[DSP_REG_LC] = dsp->registers[DSP_REG_LCSAVE]; } } else { /* Init LC at right value */ - if (dsp_core.registers[DSP_REG_LC] == 0) { - dsp_core.registers[DSP_REG_LC] = 0x010000; + if (dsp->registers[DSP_REG_LC] == 0) { + dsp->registers[DSP_REG_LC] = 0x010000; } - dsp_core.pc_on_rep = 0; + dsp->pc_on_rep = 0; } } /* Normal execution, go to next instruction */ - dsp_core.pc += cur_inst_len; + dsp->pc += dsp->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<registers[DSP_REG_SR] & (1<pc == dsp->registers[DSP_REG_LA] + 1) { + --dsp->registers[DSP_REG_LC]; + dsp->registers[DSP_REG_LC] &= BITMASK(16); - if (dsp_core.registers[DSP_REG_LC] == 0) { + if (dsp->registers[DSP_REG_LC] == 0) { /* end of loop */ uint32_t saved_pc, saved_sr; - dsp_stack_pop(&saved_pc, &saved_sr); - dsp_core.registers[DSP_REG_SR] &= 0x7f; - dsp_core.registers[DSP_REG_SR] |= saved_sr & (1<registers[DSP_REG_SR] &= 0x7f; + dsp->registers[DSP_REG_SR] |= saved_sr & (1<registers[DSP_REG_LA], &dsp->registers[DSP_REG_LC]); } else { /* Loop one more time */ - dsp_core.pc = dsp_core.registers[DSP_REG_SSH]; + dsp->pc = dsp->registers[DSP_REG_SSH]; } } } @@ -1039,129 +727,129 @@ static void dsp_postexecute_update_pc(void) **********************************/ /* Post a new interrupt to the interrupt table */ -void dsp56k_add_interrupt(uint16_t inter) +void dsp56k_add_interrupt(dsp_core_t* dsp, uint16_t inter) { /* detect if this interrupt is used or not */ - if (dsp_core.interrupt_ipl[inter] == -1) + if (dsp->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 ++; + if (dsp->interrupt_isPending[inter] == 0) { + dsp->interrupt_isPending[inter] = 1; + dsp->interrupt_counter ++; } } -static void dsp_postexecute_interrupts(void) +static void dsp_postexecute_interrupts(dsp_core_t* dsp) { uint32_t index, instr, i; int32_t ipl_to_raise, ipl_sr; /* REP is not interruptible */ - if (dsp_core.loop_rep) { + if (dsp->loop_rep) { return; } /* A fast interrupt can not be interrupted. */ - if (dsp_core.interrupt_state == DSP_INTERRUPT_DISABLED) { + if (dsp->interrupt_state == DSP_INTERRUPT_DISABLED) { - switch (dsp_core.interrupt_pipeline_count) { + switch (dsp->interrupt_pipeline_count) { case 5: - dsp_core.interrupt_pipeline_count --; + dsp->interrupt_pipeline_count --; return; case 4: /* Prefetch interrupt instruction 1 */ - dsp_core.interrupt_save_pc = dsp_core.pc; - dsp_core.pc = dsp_core.interrupt_instr_fetch; + dsp->interrupt_save_pc = dsp->pc; + dsp->pc = dsp->interrupt_instr_fetch; /* is it a LONG interrupt ? */ - instr = read_memory_p(dsp_core.interrupt_instr_fetch); + instr = read_memory_p(dsp, dsp->interrupt_instr_fetch); if ( ((instr & 0xfff000) == 0x0d0000) || ((instr & 0xffc0ff) == 0x0bc080) ) { - dsp_core.interrupt_state = DSP_INTERRUPT_LONG; - dsp_stack_push(dsp_core.interrupt_save_pc, dsp_core.registers[DSP_REG_SR], 0); - dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<interrupt_state = DSP_INTERRUPT_LONG; + dsp_stack_push(dsp, dsp->interrupt_save_pc, dsp->registers[DSP_REG_SR], 0); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= dsp->interrupt_IplToRaise<interrupt_pipeline_count --; return; case 3: /* Prefetch interrupt instruction 2 */ - if (dsp_core.pc == dsp_core.interrupt_instr_fetch+1) { - instr = read_memory_p(dsp_core.pc); + if (dsp->pc == dsp->interrupt_instr_fetch+1) { + instr = read_memory_p(dsp, dsp->pc); if ( ((instr & 0xfff000) == 0x0d0000) || ((instr & 0xffc0ff) == 0x0bc080) ) { - dsp_core.interrupt_state = DSP_INTERRUPT_LONG; - dsp_stack_push(dsp_core.interrupt_save_pc, dsp_core.registers[DSP_REG_SR], 0); - dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<interrupt_state = DSP_INTERRUPT_LONG; + dsp_stack_push(dsp, dsp->interrupt_save_pc, dsp->registers[DSP_REG_SR], 0); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= dsp->interrupt_IplToRaise<interrupt_pipeline_count --; return; case 2: /* 1 instruction executed after interrupt */ /* before re enable interrupts */ /* Was it a FAST interrupt ? */ - if (dsp_core.pc == dsp_core.interrupt_instr_fetch+2) { - dsp_core.pc = dsp_core.interrupt_save_pc; + if (dsp->pc == dsp->interrupt_instr_fetch+2) { + dsp->pc = dsp->interrupt_save_pc; } - dsp_core.interrupt_pipeline_count --; + dsp->interrupt_pipeline_count --; return; case 1: /* Last instruction executed after interrupt */ /* before re enable interrupts */ - dsp_core.interrupt_pipeline_count --; + dsp->interrupt_pipeline_count --; return; case 0: /* Re enable interrupts */ /* All 6 instruction are done, Interrupts can be enabled again */ - dsp_core.interrupt_save_pc = -1; - dsp_core.interrupt_instr_fetch = -1; - dsp_core.interrupt_state = DSP_INTERRUPT_NONE; + dsp->interrupt_save_pc = -1; + dsp->interrupt_instr_fetch = -1; + dsp->interrupt_state = DSP_INTERRUPT_NONE; break; } } /* Trace Interrupt ? */ - if (dsp_core.registers[DSP_REG_SR] & (1<registers[DSP_REG_SR] & (1<interrupt_counter == 0) { return; } /* search for an interrupt */ - ipl_sr = (dsp_core.registers[DSP_REG_SR]>>DSP_SR_I0) & BITMASK(2); + ipl_sr = (dsp->registers[DSP_REG_SR]>>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) { + if (dsp->interrupt_isPending[i] == 1) { /* level 3 interrupt ? */ - if (dsp_core.interrupt_ipl[i] == 3) { + if (dsp->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) + if (dsp->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) + if (dsp->interrupt_ipl[i] <= ipl_to_raise) continue; /* save current arbitrated interrupt */ index = i; - ipl_to_raise = dsp_core.interrupt_ipl[i]; + ipl_to_raise = dsp->interrupt_ipl[i]; } } @@ -1171,122 +859,58 @@ static void dsp_postexecute_interrupts(void) } /* remove this interrupt from the pending interrupts table */ - dsp_core.interrupt_isPending[index] = 0; - dsp_core.interrupt_counter --; + dsp->interrupt_isPending[index] = 0; + dsp->interrupt_counter --; /* process arbritrated interrupt */ - ipl_to_raise = dsp_core.interrupt_ipl[index] + 1; + ipl_to_raise = dsp->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; + dsp->interrupt_instr_fetch = dsp_interrupt[index].vectorAddr; + dsp->interrupt_pipeline_count = 5; + dsp->interrupt_state = DSP_INTERRUPT_DISABLED; + dsp->interrupt_IplToRaise = ipl_to_raise; DPRINTF("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<interrupt_instr_fetch == 0xe) { + // dsp->periph[DSP_SPACE_X][DSP_SSI_SR] &= 0xff-(1<interrupt_instr_fetch == 0x12) { + // dsp->periph[DSP_SPACE_X][DSP_SSI_SR] &= 0xff-(1<interrupt_instr_fetch == 0xff) { /* Clear HC and HCP interrupt */ - // dsp_core.periph[DSP_SPACE_X][DSP_HOST_HSR] &= 0xff - (1<periph[DSP_SPACE_X][DSP_HOST_HSR] &= 0xff - (1<hostport[CPU_HOST_CVR] &= 0xff - (1<interrupt_instr_fetch = dsp->hostport[CPU_HOST_CVR] & BITMASK(5); + // dsp->interrupt_instr_fetch *= 2; assert(false); } } -/********************************** - * Set/clear ccr bits - **********************************/ - -/* reg0 has bits 55..48 */ -/* reg1 has bits 47..24 */ -/* reg2 has bits 23..0 */ - -static void dsp_ccr_update_e_u_n_z(uint32_t reg0, uint32_t reg1, uint32_t reg2) -{ - uint32_t scaling, value_e, value_u; - - /* Initialize SR register */ - dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>DSP_SR_S0) & BITMASK(2); - switch(scaling) { - case 0: - /* 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: - /* 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; - } - - /* 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; -} - /********************************** * Read/Write memory functions **********************************/ -static uint32_t read_memory_disasm(int space, uint32_t address) -{ - return dsp56k_read_memory(space, address); -} - -static uint32_t read_memory_p(uint32_t address) +static uint32_t read_memory_p(dsp_core_t* dsp, uint32_t address) { + assert((address & 0xFF000000) == 0); assert(address < DSP_PRAM_SIZE); - return dsp_core.pram[address]; + return dsp->pram[address]; } -uint32_t dsp56k_read_memory(int space, uint32_t address) +uint32_t dsp56k_read_memory(dsp_core_t* dsp, int space, uint32_t address) { assert((address & 0xFF000000) == 0); @@ -1296,67 +920,73 @@ uint32_t dsp56k_read_memory(int space, uint32_t address) return 0xababa; } assert(address < DSP_XRAM_SIZE); - return dsp_core.xram[address]; + return dsp->xram[address]; } else if (space == DSP_SPACE_Y) { assert(address < DSP_YRAM_SIZE); - return dsp_core.yram[address]; + return dsp->yram[address]; } else if (space == DSP_SPACE_P) { - return read_memory_p(address); + return read_memory_p(dsp, address); } else { assert(false); return 0; } } -void dsp56k_write_memory(int space, uint32_t address, uint32_t value) +void dsp56k_write_memory(dsp_core_t* dsp, int space, uint32_t address, uint32_t value) { assert((value & 0xFF000000) == 0); assert((address & 0xFF000000) == 0); if (TRACE_DSP_DISASM_MEM) - write_memory_disasm(space, address, value); + write_memory_disasm(dsp, space, address, value); else - write_memory_raw(space, address, value); + write_memory_raw(dsp, space, address, value); } -static void write_memory_peripheral(uint32_t address, uint32_t value) { +static void write_memory_peripheral(dsp_core_t* dsp, uint32_t address, uint32_t value) { assert((value & 0xFF000000) == 0); assert((address & 0xFF000000) == 0); // assert(false); } -static void write_memory_raw(int space, uint32_t address, uint32_t value) + +static void write_memory_raw(dsp_core_t* dsp, int space, uint32_t address, uint32_t value) { assert((value & 0xFF000000) == 0); assert((address & 0xFF000000) == 0); if (space == DSP_SPACE_X) { if (address >= DSP_PERIPH_BASE) { - write_memory_peripheral(address, value); + write_memory_peripheral(dsp, address, value); return; } assert(address < DSP_XRAM_SIZE); - dsp_core.xram[address] = value; + dsp->xram[address] = value; } else if (space == DSP_SPACE_Y) { assert(address < DSP_YRAM_SIZE); - dsp_core.yram[address] = value; + dsp->yram[address] = value; } else if (space == DSP_SPACE_P) { assert(address < DSP_PRAM_SIZE); - dsp_core.pram[address] = value; + dsp->pram[address] = value; } else { assert(false); } } -static void write_memory_disasm(int space, uint32_t address, uint32_t value) +static uint32_t read_memory_disasm(dsp_core_t* dsp, int space, uint32_t address) +{ + return dsp56k_read_memory(dsp, space, address); +} + +static void write_memory_disasm(dsp_core_t* dsp, int space, uint32_t address, uint32_t value) { uint32_t oldvalue, curvalue; char space_c; - oldvalue = read_memory_disasm(space, address); + oldvalue = read_memory_disasm(dsp, space, address); - write_memory_raw(space, address, value); + write_memory_raw(dsp, space, address, value); switch(space) { case DSP_SPACE_X: @@ -1372,61 +1002,63 @@ static void write_memory_disasm(int space, uint32_t address, uint32_t value) assert(false); } - 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 ++; + curvalue = read_memory_disasm(dsp, space, address); + sprintf(dsp->str_disasm_memory[dsp->disasm_memory_ptr],"Mem: %c:0x%04x 0x%06x -> 0x%06x", space_c, address, oldvalue, curvalue); + dsp->disasm_memory_ptr ++; } -static void dsp_write_reg(uint32_t numreg, uint32_t value) +static void dsp_write_reg(dsp_core_t* dsp, uint32_t numreg, uint32_t value) { uint32_t stack_error; switch (numreg) { case DSP_REG_A: - dsp_core.registers[DSP_REG_A0] = 0; - dsp_core.registers[DSP_REG_A1] = value; - dsp_core.registers[DSP_REG_A2] = value & (1<<23) ? 0xff : 0x0; + dsp->registers[DSP_REG_A0] = 0; + dsp->registers[DSP_REG_A1] = value; + dsp->registers[DSP_REG_A2] = value & (1<<23) ? 0xff : 0x0; break; case DSP_REG_B: - dsp_core.registers[DSP_REG_B0] = 0; - dsp_core.registers[DSP_REG_B1] = value; - dsp_core.registers[DSP_REG_B2] = value & (1<<23) ? 0xff : 0x0; + dsp->registers[DSP_REG_B0] = 0; + dsp->registers[DSP_REG_B1] = value; + dsp->registers[DSP_REG_B2] = value & (1<<23) ? 0xff : 0x0; break; case DSP_REG_OMR: - dsp_core.registers[DSP_REG_OMR] = value & 0xc7; + dsp->registers[DSP_REG_OMR] = value & 0xc7; break; case DSP_REG_SR: - dsp_core.registers[DSP_REG_SR] = value & 0xaf7f; + dsp->registers[DSP_REG_SR] = value & 0xaf7f; break; case DSP_REG_SP: - stack_error = dsp_core.registers[DSP_REG_SP] & (3<registers[DSP_REG_SP] & (3<registers[DSP_REG_SP] = value & (3<in_disasm_mode) { + fprintf(stderr, "Dsp: Stack Overflow or Underflow\n"); + } + if (dsp->exception_debugging) { assert(false); - } - else - dsp_core.registers[DSP_REG_SP] = value & BITMASK(6); - dsp_compute_ssh_ssl(); + } + } else { + dsp->registers[DSP_REG_SP] = value & BITMASK(6); + } + dsp_compute_ssh_ssl(dsp); break; case DSP_REG_SSH: - dsp_stack_push(value, 0, 1); + dsp_stack_push(dsp, value, 0, 1); break; case DSP_REG_SSL: - numreg = dsp_core.registers[DSP_REG_SP] & BITMASK(4); + numreg = dsp->registers[DSP_REG_SP] & BITMASK(4); if (numreg == 0) { value = 0; } - dsp_core.stack[1][numreg] = value & BITMASK(16); - dsp_core.registers[DSP_REG_SSL] = value & BITMASK(16); + dsp->stack[1][numreg] = value & BITMASK(16); + dsp->registers[DSP_REG_SSL] = value & BITMASK(16); break; default: - dsp_core.registers[numreg] = value; - dsp_core.registers[numreg] &= BITMASK(registers_mask[numreg]); + dsp->registers[numreg] = value; + dsp->registers[numreg] &= BITMASK(registers_mask[numreg]); break; } } @@ -1435,2610 +1067,81 @@ static void dsp_write_reg(uint32_t numreg, uint32_t value) * Stack push/pop **********************************/ -static void dsp_stack_push(uint32_t curpc, uint32_t cursr, uint16_t sshOnly) +static void dsp_stack_push(dsp_core_t* dsp, uint32_t curpc, uint32_t cursr, uint16_t sshOnly) { uint32_t stack_error, underflow, stack; - stack_error = dsp_core.registers[DSP_REG_SP] & (1<registers[DSP_REG_SP] & (1<registers[DSP_REG_SP] & (1<registers[DSP_REG_SP] & BITMASK(4)) + 1; if ((stack_error==0) && (stack & (1<in_disasm_mode) fprintf(stderr,"Dsp: Stack Overflow\n"); - if (bExceptionDebugging) + if (dsp->exception_debugging) assert(false); } - dsp_core.registers[DSP_REG_SP] = (underflow | stack_error | stack) & BITMASK(6); + dsp->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); + dsp->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); + dsp->stack[1][stack] = cursr & BITMASK(16); } } else { - dsp_core.stack[0][0] = 0; - dsp_core.stack[1][0] = 0; + dsp->stack[0][0] = 0; + dsp->stack[1][0] = 0; } /* 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]; + dsp->registers[DSP_REG_SSH] = dsp->stack[0][stack]; + dsp->registers[DSP_REG_SSL] = dsp->stack[1][stack]; } -static void dsp_stack_pop(uint32_t *newpc, uint32_t *newsr) +static void dsp_stack_pop(dsp_core_t* dsp, uint32_t *newpc, uint32_t *newsr) { uint32_t stack_error, underflow, stack; - stack_error = dsp_core.registers[DSP_REG_SP] & (1<registers[DSP_REG_SP] & (1<registers[DSP_REG_SP] & (1<registers[DSP_REG_SP] & BITMASK(4)) - 1; if ((stack_error==0) && (stack & (1<in_disasm_mode) fprintf(stderr,"Dsp: Stack underflow\n"); - if (bExceptionDebugging) + if (dsp->exception_debugging) assert(false); } - dsp_core.registers[DSP_REG_SP] = (underflow | stack_error | stack) & BITMASK(6); + dsp->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]; + *newpc = dsp->registers[DSP_REG_SSH]; + *newsr = dsp->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]; + dsp->registers[DSP_REG_SSH] = dsp->stack[0][stack]; + dsp->registers[DSP_REG_SSL] = dsp->stack[1][stack]; } -static void dsp_compute_ssh_ssl(void) +static void dsp_compute_ssh_ssl(dsp_core_t* dsp) { uint32_t stack; - stack = dsp_core.registers[DSP_REG_SP]; + stack = dsp->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]; + dsp->registers[DSP_REG_SSH] = dsp->stack[0][stack]; + dsp->registers[DSP_REG_SSL] = dsp->stack[1][stack]; } -/********************************** - * Effective address calculation - **********************************/ -static void dsp_update_rn(uint32_t numreg, int16_t modifier) -{ - int16_t value; - uint16_t m_reg; - - m_reg = (uint16_t) dsp_core.registers[DSP_REG_M0+numreg]; - if (m_reg == 65535) { - /* Linear addressing mode */ - value = (int16_t) dsp_core.registers[DSP_REG_R0+numreg]; - value += modifier; - dsp_core.registers[DSP_REG_R0+numreg] = ((uint32_t) value) & BITMASK(16); - } else if (m_reg == 0) { - /* Bit reversed carry update */ - dsp_update_rn_bitreverse(numreg); - } else if (m_reg<=32767) { - /* Modulo update */ - dsp_update_rn_modulo(numreg, modifier); - } else { - /* Undefined */ - } -} - -static void dsp_update_rn_bitreverse(uint32_t numreg) -{ - int revbits, i; - uint32_t value, r_reg; - - /* Check how many bits to reverse */ - value = dsp_core.registers[DSP_REG_N0+numreg]; - for (revbits=0;revbits<16;revbits++) { - if (value & (1<modulo) { - while (modifier>bufsize) { - r_reg += bufsize; - modifier -= bufsize; - } - while (modifier<-bufsize) { - r_reg -= bufsize; - modifier += bufsize; - } - } - - r_reg += modifier; - - if (orig_modifier!=modulo) { - if (r_reg>hibound) { - r_reg -= modulo; - } else if (r_reg> 3) & BITMASK(3); - numreg = ea_mode & BITMASK(3); - 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]); - 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]); - break; - case 2: - /* (Rx)- */ - *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); - break; - case 4: - /* (Rx) */ - *dst_addr = dsp_core.registers[DSP_REG_R0+numreg]; - break; - case 5: - /* (Rx+Nx) */ - 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 */ - dsp_core.instr_cycle += 2; - *dst_addr = read_memory_p(dsp_core.pc+1); - cur_inst_len++; - if (numreg != 0) { - return 1; /* immediate value */ - } - break; - case 7: - /* -(Rx) */ - dsp_core.instr_cycle += 2; - dsp_update_rn(numreg, -1); - *dst_addr = dsp_core.registers[DSP_REG_R0+numreg]; - break; - } - /* address */ - return 0; -} - -/********************************** - * Condition code test - **********************************/ - -static int dsp_calc_cc(uint32_t cc_code) -{ - uint16_t value1, value2, value3; - - 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; -} - -/********************************** - * Highbyte opcodes dispatchers - **********************************/ - -/********************************** - * Non-parallel moves instructions - **********************************/ - -static void emu_undefined(void) -{ - if (is_dsp_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 (bExceptionDebugging) { - assert(false); - } -} - -static void emu_add_long(void) -{ - uint32_t xxxx = read_memory_p(dsp_core.pc+1); - // QQQ - cur_inst_len++; -} - -static void emu_andi(void) -{ - uint32_t regnum, value; - - value = (cur_inst >> 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; - } -} - -static void emu_bcc_long(void) { - uint32_t xxxx = read_memory_p(dsp_core.pc+1); - cur_inst_len++; - //QQQ - dsp_core.instr_cycle += 2; //?? -} - -static void emu_bcc_imm(void) { - //QQQ - dsp_core.instr_cycle += 2; //?? -} - -static void emu_bchg_aa(void) -{ - uint32_t memspace, addr, value, newcarry, numbit; - - memspace = (cur_inst>>6) & 1; - value = (cur_inst>>8) & BITMASK(6); - numbit = cur_inst & BITMASK(5); - - addr = value; - value = dsp56k_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 = dsp56k_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); - - addr = 0xffffc0 + value; - value = dsp56k_read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - if (newcarry) { - value -= (1<>8) & BITMASK(6); - numbit = cur_inst & BITMASK(5); - - if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { - emu_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 = dsp56k_read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - value &= 0xffffffff-(1<>6) & 1; - value = (cur_inst>>8) & BITMASK(6); - numbit = cur_inst & BITMASK(5); - - dsp_calc_ea(value, &addr); - value = dsp56k_read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - value &= 0xffffffff-(1<>6) & 1; - value = (cur_inst>>8) & BITMASK(6); - numbit = cur_inst & BITMASK(5); - - addr = 0xffffc0 + value; - value = dsp56k_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)) { - emu_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); - - addr = value; - value = dsp56k_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 = dsp56k_read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - value |= (1<>6) & 1; - value = (cur_inst>>8) & BITMASK(6); - numbit = cur_inst & BITMASK(5); - addr = 0xffffc0 + value; - value = dsp56k_read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - value |= (1<>8) & BITMASK(6); - numbit = cur_inst & BITMASK(5); - - if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { - emu_pm_read_accu24(numreg, &value); - } else { - value = dsp_core.registers[numreg]; - } - - newcarry = (value>>numbit) & 1; - value |= (1<>6) & 1; - value = (cur_inst>>8) & BITMASK(6); - numbit = cur_inst & BITMASK(5); - - addr = value; - value = dsp56k_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); - - dsp_calc_ea(value, &addr); - value = dsp56k_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 = 0xffffc0 + value; - value = dsp56k_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)) { - emu_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<>4) & BITMASK(2)) { - case 0: srcreg = DSP_REG_X0; break; - case 1: srcreg = DSP_REG_Y0; break; - case 2: srcreg = DSP_REG_X1; break; - case 3: srcreg = DSP_REG_Y1; break; - } - source[2] = 0; - source[1] = dsp_core.registers[srcreg]; - source[0] = source[1] & (1<<23) ? 0xff : 0x0; - - 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 */ - newsr = dsp_asl56(dest); - dsp_add56(source, dest); - } else { - /* D -= S */ - newsr = dsp_asl56(dest); - dsp_sub56(source, dest); - } - - dest[2] |= (dsp_core.registers[DSP_REG_SR]>>DSP_SR_C) & 1; - - if (destreg == DSP_REG_A) { - dsp_core.registers[DSP_REG_A2] = dest[0]; - dsp_core.registers[DSP_REG_A1] = dest[1]; - dsp_core.registers[DSP_REG_A0] = dest[2]; - } - else { - 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<>7) & 1))<>6) & 1; - addr = (cur_inst>>8) & BITMASK(6); - dsp_core.registers[DSP_REG_LC] = dsp56k_read_memory(memspace, addr) & BITMASK(16); - - dsp_core.instr_cycle += 4; -} - -static void emu_do_imm(void) -{ - /* #xx */ - - 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 emu_do_ea(void) -{ - uint32_t 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] = dsp56k_read_memory(memspace, addr) & BITMASK(16); - - dsp_core.instr_cycle += 4; -} - -static void emu_do_reg(void) -{ - uint32_t 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)) { - emu_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] &= 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<>12) & BITMASK(4); - if (dsp_calc_cc(cc_code)) { - dsp_core.pc = newpc; - cur_inst_len = 0; - } - - dsp_core.instr_cycle += 2; -} - -static void emu_jcc_ea(void) -{ - uint32_t 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; - cur_inst_len = 0; - } - - dsp_core.instr_cycle += 2; -} - -static void emu_jclr_aa(void) -{ - uint32_t memspace, addr, value, numbit, newaddr; - - memspace = (cur_inst>>6) & 1; - addr = (cur_inst>>8) & BITMASK(6); - numbit = cur_inst & BITMASK(5); - value = dsp56k_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); - newaddr = read_memory_p(dsp_core.pc+1); - - dsp_calc_ea(value, &addr); - value = dsp56k_read_memory(memspace, addr); - - dsp_core.instr_cycle += 4; - - if ((value & (1<>6) & 1; - value = (cur_inst>>8) & BITMASK(6); - numbit = cur_inst & BITMASK(5); - addr = 0xffffc0 + value; - value = dsp56k_read_memory(memspace, addr); - newaddr = read_memory_p(dsp_core.pc+1); - - dsp_core.instr_cycle += 4; - - if ((value & (1<>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)) { - emu_pm_read_accu24(numreg, &value); - } else { - value = dsp_core.registers[numreg]; - } - - dsp_core.instr_cycle += 4; - - if ((value & (1<>8) & BITMASK(6), &newpc); - cur_inst_len = 0; - dsp_core.pc = newpc; - - dsp_core.instr_cycle += 2; -} - -static void emu_jmp_imm(void) -{ - uint32_t newpc; - - newpc = cur_inst & BITMASK(12); - cur_inst_len = 0; - dsp_core.pc = newpc; - - dsp_core.instr_cycle += 2; -} - -static void emu_jscc_ea(void) -{ - uint32_t 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_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 emu_jscc_imm(void) -{ - uint32_t 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], 0); - dsp_core.pc = newpc; - cur_inst_len = 0; - } - - dsp_core.instr_cycle += 2; -} - -static void emu_jsclr_aa(void) -{ - uint32_t memspace, addr, value, newpc, numbit, newaddr; - - memspace = (cur_inst>>6) & 1; - addr = (cur_inst>>8) & BITMASK(6); - numbit = cur_inst & BITMASK(5); - value = dsp56k_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 = dsp56k_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 = 0xffffc0 + value; - value = dsp56k_read_memory(memspace, addr); - newaddr = read_memory_p(dsp_core.pc+1); - - dsp_core.instr_cycle += 4; - - if ((value & (1<>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)) { - emu_pm_read_accu24(numreg, &value); - } else { - value = dsp_core.registers[numreg]; - } - - dsp_core.instr_cycle += 4; - - if ((value & (1<>6) & 1; - addr = (cur_inst>>8) & BITMASK(6); - numbit = cur_inst & BITMASK(5); - value = dsp56k_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 = dsp56k_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 = 0xffffc0 + value; - value = dsp56k_read_memory(memspace, addr); - newaddr = read_memory_p(dsp_core.pc+1); - - dsp_core.instr_cycle += 4; - - if (value & (1<>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)) { - emu_pm_read_accu24(numreg, &value); - } else { - value = dsp_core.registers[numreg]; - } - - dsp_core.instr_cycle += 4; - - if (value & (1<>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; - cur_inst_len = 0; - - dsp_core.instr_cycle += 2; -} - -static void emu_jsset_aa(void) -{ - uint32_t memspace, addr, value, newpc, numbit, newaddr; - - memspace = (cur_inst>>6) & 1; - addr = (cur_inst>>8) & BITMASK(6); - numbit = cur_inst & BITMASK(5); - value = dsp56k_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 = dsp56k_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 = 0xffffc0 + value; - value = dsp56k_read_memory(memspace, addr); - newaddr = read_memory_p(dsp_core.pc+1); - - dsp_core.instr_cycle += 4; - - if (value & (1<>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)) { - emu_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]; - 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; - - 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; - } - - dsp_core.instr_cycle += 2; -} - -static void emu_movec_reg(void) -{ - uint32_t numreg1, numreg2, value, dummy; - - /* S1,D2 */ - /* S2,D1 */ - - numreg2 = (cur_inst>>8) & BITMASK(6); - numreg1 = cur_inst & BITMASK(6); - - if (cur_inst & (1<<15)) { - /* Write D1 */ - - if ((numreg2 == DSP_REG_A) || (numreg2 == DSP_REG_B)) { - emu_pm_read_accu24(numreg2, &value); - } else { - value = dsp_core.registers[numreg2]; - } - value &= BITMASK(registers_mask[numreg1]); - dsp_write_reg(numreg1, value); - } else { - /* Read S1 */ - if (numreg1 == DSP_REG_SSH) { - dsp_stack_pop(&value, &dummy); - } - else { - value = dsp_core.registers[numreg1]; - } - - if (numreg2 == 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; - } - else if (numreg2 == 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; - } - else { - dsp_core.registers[numreg2] = value & BITMASK(registers_mask[numreg2]); - } - } -} - -static void emu_movec_aa(void) -{ - uint32_t numreg, addr, memspace, value, dummy; - - /* x:aa,D1 */ - /* S1,x:aa */ - /* y:aa,D1 */ - /* S1,y:aa */ - - numreg = cur_inst & BITMASK(6); - addr = (cur_inst>>8) & BITMASK(6); - memspace = (cur_inst>>6) & 1; - - if (cur_inst & (1<<15)) { - /* Write D1 */ - value = dsp56k_read_memory(memspace, addr); - value &= BITMASK(registers_mask[numreg]); - dsp_write_reg(numreg, value); - } else { - /* Read S1 */ - if (numreg == DSP_REG_SSH) { - dsp_stack_pop(&value, &dummy); - } - else { - value = dsp_core.registers[numreg]; - } - dsp56k_write_memory(memspace, addr, value); - } -} - -static void emu_movec_imm(void) -{ - uint32_t numreg, value; - - /* #xx,D1 */ - numreg = cur_inst & BITMASK(6); - value = (cur_inst>>8) & BITMASK(8); - value &= BITMASK(registers_mask[numreg]); - dsp_write_reg(numreg, value); -} - -static void emu_movec_ea(void) -{ - uint32_t numreg, addr, memspace, ea_mode, value, dummy; - int retour; - - /* x:ea,D1 */ - /* S1,x:ea */ - /* y:ea,D1 */ - /* S1,y:ea */ - /* #xxxx,D1 */ - - 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) { - value = addr; - } else { - value = dsp56k_read_memory(memspace, addr); - } - value &= BITMASK(registers_mask[numreg]); - dsp_write_reg(numreg, value); - } else { - /* Read S1 */ - dsp_calc_ea(ea_mode, &addr); - if (numreg == DSP_REG_SSH) { - dsp_stack_pop(&value, &dummy); - } - else { - value = dsp_core.registers[numreg]; - } - dsp56k_write_memory(memspace, addr, value); - } -} - -static void emu_movem_aa(void) -{ - uint32_t numreg, addr, value, dummy; - - numreg = cur_inst & BITMASK(6); - addr = (cur_inst>>8) & BITMASK(6); - - if (cur_inst & (1<<15)) { - /* Write D */ - value = read_memory_p(addr); - value &= BITMASK(registers_mask[numreg]); - 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)) { - emu_pm_read_accu24(numreg, &value); - } - else { - value = dsp_core.registers[numreg]; - } - dsp56k_write_memory(DSP_SPACE_P, addr, value); - } - - dsp_core.instr_cycle += 4; -} - -static void emu_movem_ea(void) -{ - uint32_t numreg, addr, ea_mode, value, dummy; - - 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); - value &= BITMASK(registers_mask[numreg]); - 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)) { - emu_pm_read_accu24(numreg, &value); - } - else { - value = dsp_core.registers[numreg]; - } - dsp56k_write_memory(DSP_SPACE_P, addr, value); - } - - dsp_core.instr_cycle += 4; -} - -static void emu_movep_0(void) -{ - /* S,x:pp */ - /* x:pp,D */ - /* S,y:pp */ - /* y:pp,D */ - - uint32_t addr, memspace, numreg, value, dummy; - - addr = 0xffffc0 + (cur_inst & BITMASK(6)); - memspace = (cur_inst>>16) & 1; - numreg = (cur_inst>>8) & BITMASK(6); - - if (cur_inst & (1<<15)) { - /* Write pp */ - if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - emu_pm_read_accu24(numreg, &value); - } - else if (numreg == DSP_REG_SSH) { - dsp_stack_pop(&value, &dummy); - } - else { - value = dsp_core.registers[numreg]; - } - dsp56k_write_memory(memspace, addr, value); - } else { - /* Read pp */ - value = dsp56k_read_memory(memspace, addr); - value &= BITMASK(registers_mask[numreg]); - dsp_write_reg(numreg, value); - } - - dsp_core.instr_cycle += 2; -} - -static void emu_movep_1(void) -{ - /* p:ea,x:pp */ - /* x:pp,p:ea */ - /* p:ea,y:pp */ - /* y:pp,p:ea */ - - uint32_t xyaddr, memspace, paddr; - - xyaddr = 0xffffc0 + (cur_inst & BITMASK(6)); - dsp_calc_ea((cur_inst>>8) & BITMASK(6), &paddr); - memspace = (cur_inst>>16) & 1; - - if (cur_inst & (1<<15)) { - /* Write pp */ - dsp56k_write_memory(memspace, xyaddr, read_memory_p(paddr)); - } else { - /* Read pp */ - dsp56k_write_memory(DSP_SPACE_P, paddr, dsp56k_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 emu_movep_23(void) -{ - /* x:ea,x:pp */ - /* y:ea,x:pp */ - /* #xxxxxx,x:pp */ - /* x:pp,x:ea */ - /* x:pp,y:pp */ - /* x:ea,y:pp */ - /* y:ea,y:pp */ - /* #xxxxxx,y:pp */ - /* y:pp,y:ea */ - /* y:pp,x:ea */ - - uint32_t addr, peraddr, easpace, perspace, ea_mode; - int retour; - - peraddr = 0xffffc0 + (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) { - dsp56k_write_memory(perspace, peraddr, addr); - } else { - dsp56k_write_memory(perspace, peraddr, dsp56k_read_memory(easpace, addr)); - } - } else { - /* Read pp */ - dsp56k_write_memory(easpace, addr, dsp56k_read_memory(perspace, peraddr)); - } - - dsp_core.instr_cycle += 2; -} - -static void emu_movep_x_low(void) { - // 00000111W1MMMRRR0sqqqqqq - - uint32_t addr, peraddr, easpace, ea_mode; - int retour; - - peraddr = 0xffff80 + (cur_inst & BITMASK(6)); - - ea_mode = (cur_inst>>8) & BITMASK(6); - easpace = (cur_inst>>6) & 1; - retour = dsp_calc_ea(ea_mode, &addr); - - // QQQ - - dsp_core.instr_cycle += 2; // ??? -} - -static void emu_move_x_aa(void) { - // 0000001aaaaaaRRR1a0WDDDD - int W = (cur_inst >> 4) & 1; - int a = (((cur_inst >> 11) & BITMASK(6)) << 1) - + ((cur_inst >> 6) & 1); - //QQQ - dsp_core.instr_cycle += 2; //??? -} - -static void emu_norm(void) -{ - uint32_t cursr,cur_e, cur_euz, dest[3], numreg, rreg; - uint16_t newsr; - - 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; - cur_euz &= ~((cursr>>DSP_SR_Z) & 1); - 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]; - 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); - } else if (cur_e) { - newsr = dsp_asr56(dest); - ++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_update_e_u_n_z(dest[0], dest[1], dest[2]); - - dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<> 8) & BITMASK(8); - regnum = cur_inst & BITMASK(2); - switch(regnum) { - case 0: - /* mr */ - dsp_core.registers[DSP_REG_SR] |= value<<8; - break; - case 1: - /* ccr */ - dsp_core.registers[DSP_REG_SR] |= value; - break; - case 2: - /* omr */ - dsp_core.registers[DSP_REG_OMR] |= value; - break; - } -} - -/* - REP instruction parameter encoding - - xxxxxxxx 00xxxxxx 0xxxxxxx aa - xxxxxxxx 01xxxxxx 0xxxxxxx ea - xxxxxxxx YYxxxxxx 1xxxxxxx imm - xxxxxxxx 11xxxxxx 0xxxxxxx reg -*/ - -static void emu_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]=dsp56k_read_memory((cur_inst>>6) & 1,(cur_inst>>8) & BITMASK(6)); - - dsp_core.instr_cycle += 2; -} - -static void emu_rep_imm(void) -{ - /* #xxx */ - - 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 emu_rep_ea(void) -{ - uint32_t 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]= dsp56k_read_memory((cur_inst>>6) & 1, value); - - dsp_core.instr_cycle += 2; -} - -static void emu_rep_reg(void) -{ - uint32_t 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)) { - emu_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] &= BITMASK(16); - - dsp_core.instr_cycle += 2; -} - -static void emu_reset(void) -{ - /* Reset external peripherals */ - dsp_core.instr_cycle += 2; -} - -static void emu_rti(void) -{ - uint32_t newpc = 0, newsr = 0; - - dsp_stack_pop(&newpc, &newsr); - dsp_core.pc = newpc; - dsp_core.registers[DSP_REG_SR] = newsr; - cur_inst_len = 0; - - dsp_core.instr_cycle += 2; -} - -static void emu_rts(void) -{ - uint32_t newpc = 0, newsr; - - dsp_stack_pop(&newpc, &newsr); - dsp_core.pc = newpc; - cur_inst_len = 0; - - dsp_core.instr_cycle += 2; -} - -static void emu_stop(void) -{ - DPRINTF("Dsp: STOP instruction\n"); -} - -static void emu_swi(void) -{ - /* Raise interrupt p:0x0006 */ - dsp_core.instr_cycle += 6; -} - -static void emu_tcc(void) -{ - uint32_t cc_code, regsrc1, regdest1; - uint32_t regsrc2, regdest2; - uint32_t val0, val1, val2; - - cc_code = (cur_inst>>12) & BITMASK(4); - - if (dsp_calc_cc(cc_code)) { - regsrc1 = registers_tcc[(cur_inst>>3) & BITMASK(4)][0]; - regdest1 = registers_tcc[(cur_inst>>3) & BITMASK(4)][1]; - - /* Read S1 */ - 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 */ - 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]; - } - } -} - -static void emu_wait(void) -{ - DPRINTF("Dsp: WAIT instruction\n"); -} - -static int emu_pm_read_accu24(int numreg, uint32_t *dest) -{ - uint32_t scaling, value, reg; - int got_limited = 0; - - /* Read an accumulator, stores it limited */ - - scaling = (dsp_core.registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); - reg = numreg & 1; - - value = (dsp_core.registers[DSP_REG_A2+reg]) << 24; - value += dsp_core.registers[DSP_REG_A1+reg]; - - switch(scaling) { - case 0: - /* No scaling */ - break; - case 1: - /* scaling down */ - value >>= 1; - break; - case 2: - /* scaling up */ - value <<= 1; - value |= (dsp_core.registers[DSP_REG_A0+reg]>>23) & 1; - break; - /* indeterminate */ - case 3: - break; - } - - /* 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<>15) & 1; - numreg = (cur_inst>>16) & 1; - dsp_calc_ea((cur_inst>>8) & BITMASK(6), &addr); - - /* Save A or B */ - emu_pm_read_accu24(numreg, &save_accu); - - /* Save X0 or Y0 */ - save_xy0 = dsp_core.registers[DSP_REG_X0+(memspace<<1)]; - - /* Execute parallel instruction */ - opcodes_alu[cur_inst & BITMASK(8)](); - - /* Move [A|B] to [x|y]:ea */ - dsp56k_write_memory(memspace, addr, save_accu); - - /* 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 emu_pm_1(void) -{ - uint32_t memspace, numreg1, numreg2, value, xy_addr, retour, save_1, save_2; -/* - 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 - S1,D1 S2,y:ea - S1,D1 #xxxxxx,D2 -*/ - value = (cur_inst>>8) & BITMASK(6); - retour = dsp_calc_ea(value, &xy_addr); - memspace = (cur_inst>>14) & 1; - numreg1 = numreg2 = DSP_REG_NULL; - - if (memspace) { - /* Y: */ - switch((cur_inst>>16) & BITMASK(2)) { - 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: 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) - save_1 = xy_addr; - else - save_1 = dsp56k_read_memory(memspace, xy_addr); - } else { - /* Read S1 */ - if ((numreg1==DSP_REG_A) || (numreg1==DSP_REG_B)) - emu_pm_read_accu24(numreg1, &save_1); - else - save_1 = dsp_core.registers[numreg1]; - } - - /* S2 */ - if (memspace) { - /* Y: */ - numreg2 = DSP_REG_A + ((cur_inst>>19) & 1); - } else { - /* X: */ - numreg2 = DSP_REG_A + ((cur_inst>>17) & 1); - } - emu_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 */ - if (numreg1 == DSP_REG_A) { - dsp_core.registers[DSP_REG_A0] = 0x0; - dsp_core.registers[DSP_REG_A1] = save_1; - dsp_core.registers[DSP_REG_A2] = save_1 & (1<<23) ? 0xff : 0x0; - } - else if (numreg1 == DSP_REG_B) { - dsp_core.registers[DSP_REG_B0] = 0x0; - dsp_core.registers[DSP_REG_B1] = save_1; - dsp_core.registers[DSP_REG_B2] = save_1 & (1<<23) ? 0xff : 0x0; - } - else { - } dsp_core.registers[numreg1] = save_1; - } else { - /* Read S1 */ - dsp56k_write_memory(memspace, xy_addr, save_1); - } - - /* S2 -> D2 */ - if (memspace) { - /* Y: */ - numreg2 = DSP_REG_X0 + ((cur_inst>>18) & 1); - } else { - /* X: */ - numreg2 = DSP_REG_Y0 + ((cur_inst>>16) & 1); - } - dsp_core.registers[numreg2] = save_2; -} - -static void emu_pm_2(void) -{ - uint32_t dummy; -/* - 0010 0000 0000 0000 nop - 0010 0000 010m mrrr R update - 0010 00ee eeed dddd S,D - 001d dddd iiii iiii #xx,D -*/ - if ((cur_inst & 0xffff00) == 0x200000) { - /* Execute parallel instruction */ - opcodes_alu[cur_inst & BITMASK(8)](); - return; - } - - 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 & 0xfc0000) == 0x200000) { - emu_pm_2_2(); - return; - } - - emu_pm_3(); -} - -static void emu_pm_2_2(void) -{ -/* - 0010 00ee eeed dddd S,D -*/ - uint32_t srcreg, dstreg, save_reg; - - srcreg = (cur_inst >> 13) & BITMASK(5); - dstreg = (cur_inst >> 8) & BITMASK(5); - - if ((srcreg == DSP_REG_A) || (srcreg == DSP_REG_B)) - /* Accu to register: limited 24 bits */ - emu_pm_read_accu24(srcreg, &save_reg); - else - save_reg = dsp_core.registers[srcreg]; - - /* Execute parallel instruction */ - opcodes_alu[cur_inst & BITMASK(8)](); - - /* Write reg */ - if (dstreg == DSP_REG_A) { - dsp_core.registers[DSP_REG_A0] = 0x0; - dsp_core.registers[DSP_REG_A1] = save_reg; - dsp_core.registers[DSP_REG_A2] = save_reg & (1<<23) ? 0xff : 0x0; - } - else if (dstreg == DSP_REG_B) { - dsp_core.registers[DSP_REG_B0] = 0x0; - dsp_core.registers[DSP_REG_B1] = save_reg; - dsp_core.registers[DSP_REG_B2] = save_reg & (1<<23) ? 0xff : 0x0; - } - else { - dsp_core.registers[dstreg] = save_reg & BITMASK(registers_mask[dstreg]); - } -} - -static void emu_pm_3(void) -{ - uint32_t dstreg, srcvalue; -/* - 001d dddd iiii iiii #xx,R -*/ - - /* Execute parallel instruction */ - opcodes_alu[cur_inst & BITMASK(8)](); - - /* Write reg */ - dstreg = (cur_inst >> 16) & BITMASK(5); - srcvalue = (cur_inst >> 8) & BITMASK(8); - - switch(dstreg) { - case DSP_REG_X0: - case DSP_REG_X1: - case DSP_REG_Y0: - case DSP_REG_Y1: - case DSP_REG_A: - case DSP_REG_B: - srcvalue <<= 16; - break; - } - - if (dstreg == DSP_REG_A) { - dsp_core.registers[DSP_REG_A0] = 0x0; - dsp_core.registers[DSP_REG_A1] = srcvalue; - dsp_core.registers[DSP_REG_A2] = srcvalue & (1<<23) ? 0xff : 0x0; - } - else if (dstreg == DSP_REG_B) { - dsp_core.registers[DSP_REG_B0] = 0x0; - dsp_core.registers[DSP_REG_B1] = srcvalue; - dsp_core.registers[DSP_REG_B2] = srcvalue & (1<<23) ? 0xff : 0x0; - } - else { - dsp_core.registers[dstreg] = srcvalue & BITMASK(registers_mask[dstreg]); - } -} - -static void emu_pm_4(void) -{ -/* - 0100 l0ll w0aa aaaa l:aa,D - S,l:aa - 0100 l0ll w1mm mrrr l:ea,D - S,l:ea - 01dd 0ddd w0aa aaaa x:aa,D - S,x:aa - 01dd 0ddd w1mm mrrr x:ea,D - S,x:ea - #xxxxxx,D - 01dd 1ddd w0aa aaaa y:aa,D - S,y:aa - 01dd 1ddd w1mm mrrr y:ea,D - S,y:ea - #xxxxxx,D -*/ - if ((cur_inst & 0xf40000)==0x400000) { - emu_pm_4x(); - return; - } - - emu_pm_5(); -} - -static void emu_pm_4x(void) -{ - uint32_t 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 -*/ - 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 */ - save_lx = dsp56k_read_memory(DSP_SPACE_X,l_addr); - save_ly = dsp56k_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 (emu_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 (emu_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 */ - emu_pm_read_accu24(DSP_REG_A, &save_lx); - emu_pm_read_accu24(DSP_REG_B, &save_ly); - break; - case 7: - /* BA */ - emu_pm_read_accu24(DSP_REG_B, &save_lx); - emu_pm_read_accu24(DSP_REG_A, &save_ly); - break; - } - } - - /* Execute parallel instruction */ - opcodes_alu[cur_inst & BITMASK(8)](); - - - 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 */ - dsp56k_write_memory(DSP_SPACE_X, l_addr, save_lx); - dsp56k_write_memory(DSP_SPACE_Y, l_addr, save_ly); - } -} - -static void emu_pm_5(void) -{ - uint32_t memspace, numreg, value, xy_addr, retour; -/* - 01dd 0ddd w0aa aaaa x:aa,D - S,x:aa - 01dd 0ddd w1mm mrrr x:ea,D - S,x:ea - #xxxxxx,D - 01dd 1ddd w0aa aaaa y:aa,D - S,y:aa - 01dd 1ddd w1mm mrrr y:ea,D - S,y:ea - #xxxxxx,D -*/ - - value = (cur_inst>>8) & BITMASK(6); - - if (cur_inst & (1<<14)) { - retour = dsp_calc_ea(value, &xy_addr); - } else { - xy_addr = value; - retour = 0; - } - - memspace = (cur_inst>>19) & 1; - numreg = (cur_inst>>16) & BITMASK(3); - numreg |= (cur_inst>>17) & (BITMASK(2)<<3); - - if (cur_inst & (1<<15)) { - /* Write D */ - if (retour) - value = xy_addr; - else - value = dsp56k_read_memory(memspace, xy_addr); - } - else { - /* Read S */ - if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) - emu_pm_read_accu24(numreg, &value); - else - value = dsp_core.registers[numreg]; - } - - - /* Execute parallel instruction */ - opcodes_alu[cur_inst & BITMASK(8)](); - - if (cur_inst & (1<<15)) { - /* Write D */ - if (numreg == DSP_REG_A) { - dsp_core.registers[DSP_REG_A0] = 0x0; - dsp_core.registers[DSP_REG_A1] = value; - dsp_core.registers[DSP_REG_A2] = value & (1<<23) ? 0xff : 0x0; - } - else if (numreg == DSP_REG_B) { - dsp_core.registers[DSP_REG_B0] = 0x0; - dsp_core.registers[DSP_REG_B1] = value; - dsp_core.registers[DSP_REG_B2] = value & (1<<23) ? 0xff : 0x0; - } - else { - dsp_core.registers[numreg] = value & BITMASK(registers_mask[numreg]); - } - } - else { - /* Read S */ - dsp56k_write_memory(memspace, xy_addr, value); - } -} - -static void emu_pm_8(void) -{ - uint32_t ea1, ea2; - uint32_t numreg1, numreg2; - uint32_t save_reg1, save_reg2, x_addr, y_addr; -/* - 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 -*/ - numreg1 = numreg2 = DSP_REG_NULL; - - ea1 = (cur_inst>>8) & BITMASK(5); - if ((ea1>>3) == 0) { - ea1 |= (1<<5); - } - ea2 = (cur_inst>>13) & BITMASK(2); - ea2 |= (cur_inst>>17) & (BITMASK(2)<<3); - if ((ea1 & (1<<2))==0) { - ea2 |= 1<<2; - } - if ((ea2>>3) == 0) { - ea2 |= (1<<5); - } - - 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; - case 1: numreg1=DSP_REG_X1; break; - case 2: numreg1=DSP_REG_A; break; - case 3: numreg1=DSP_REG_B; break; - } - switch((cur_inst>>16) & BITMASK(2)) { - case 0: numreg2=DSP_REG_Y0; break; - case 1: numreg2=DSP_REG_Y1; break; - case 2: numreg2=DSP_REG_A; break; - case 3: numreg2=DSP_REG_B; break; - } - - if (cur_inst & (1<<15)) { - /* Write D1 */ - save_reg1 = dsp56k_read_memory(DSP_SPACE_X, x_addr); - } else { - /* Read S1 */ - if ((numreg1==DSP_REG_A) || (numreg1==DSP_REG_B)) - emu_pm_read_accu24(numreg1, &save_reg1); - else - save_reg1 = dsp_core.registers[numreg1]; - } - - if (cur_inst & (1<<22)) { - /* Write D2 */ - save_reg2 = dsp56k_read_memory(DSP_SPACE_Y, y_addr); - } else { - /* Read S2 */ - if ((numreg2==DSP_REG_A) || (numreg2==DSP_REG_B)) - emu_pm_read_accu24(numreg2, &save_reg2); - else - save_reg2 = dsp_core.registers[numreg2]; - } - - - /* Execute parallel instruction */ - opcodes_alu[cur_inst & BITMASK(8)](); - - /* 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 */ - dsp56k_write_memory(DSP_SPACE_X, x_addr, save_reg1); - } - - /* Write second parallel move */ - if (cur_inst & (1<<22)) { - /* Write D2 */ - 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; - } - } else { - /* Read S2 */ - dsp56k_write_memory(DSP_SPACE_Y, y_addr, save_reg2); - } -} /********************************** * 56bit arithmetic @@ -4048,7 +1151,7 @@ static void emu_pm_8(void) /* source,dest[1] is 47:24 */ /* source,dest[2] is 23:00 */ -static uint16_t dsp_abs56(uint32_t *dest) +static uint16_t dsp_abs56(dsp_core_t* dsp, uint32_t *dest) { uint32_t zerodest[3]; uint16_t newsr; @@ -4058,7 +1161,7 @@ static uint16_t dsp_abs56(uint32_t *dest) if (dest[0] & (1<<7)) { zerodest[0] = zerodest[1] = zerodest[2] = 0; - newsr = dsp_sub56(dest, zerodest); + newsr = dsp_sub56(dsp, dest, zerodest); dest[0] = zerodest[0]; dest[1] = zerodest[1]; @@ -4070,7 +1173,7 @@ static uint16_t dsp_abs56(uint32_t *dest) return newsr; } -static uint16_t dsp_asl56(uint32_t *dest) +static uint16_t dsp_asl56(dsp_core_t* dsp, uint32_t *dest) { uint16_t overflow, carry; @@ -4094,7 +1197,7 @@ static uint16_t dsp_asl56(uint32_t *dest) return (overflow<registers[DSP_REG_SR] & (1<registers[DSP_REG_SR] & (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_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_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; - newsr |= dsp_add56(source, 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_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_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<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 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<>23) & 1)<>23) & 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] |= newcarry; - 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] |= 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<>= 1; - dsp_core.registers[DSP_REG_B1] |= newcarry<<23; - - 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_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_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; - newsr |= dsp_sub56(source, 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_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_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< #include -/* Functions */ -void dsp56k_init_cpu(void); /* Set dsp_core to use */ -void dsp56k_execute_instruction(void); /* Execute 1 instruction */ -uint16_t dsp56k_execute_one_disasm_instruction(FILE *out, uint32_t pc); /* Execute 1 instruction in disasm mode */ +#include "dsp.h" -uint32_t dsp56k_read_memory(int space, uint32_t address); -void dsp56k_write_memory(int space, uint32_t address, uint32_t value); +/* Functions */ +void dsp56k_init_cpu(dsp_core_t* dsp); /* Set dsp_core to use */ +void dsp56k_execute_instruction(dsp_core_t* dsp); /* Execute 1 instruction */ +uint16_t dsp56k_execute_one_disasm_instruction(dsp_core_t* dsp, FILE *out, uint32_t pc); /* Execute 1 instruction in disasm mode */ + +uint32_t dsp56k_read_memory(dsp_core_t* dsp, int space, uint32_t address); +void dsp56k_write_memory(dsp_core_t* dsp, int space, uint32_t address, uint32_t value); /* Interrupt relative functions */ -void dsp56k_add_interrupt(uint16_t inter); +void dsp56k_add_interrupt(dsp_core_t* dsp, uint16_t inter); #endif /* DSP_CPU_H */ diff --git a/hw/xbox/dsp/dsp_disasm.c b/hw/xbox/dsp/dsp_dis.inl similarity index 50% rename from hw/xbox/dsp/dsp_disasm.c rename to hw/xbox/dsp/dsp_dis.inl index 1ab4879839..7e37831095 100644 --- a/hw/xbox/dsp/dsp_disasm.c +++ b/hw/xbox/dsp/dsp_dis.inl @@ -1,70 +1,6 @@ -/* - DSP56300 Disassembler - Copyright (c) 2015 espes +typedef void (*dis_func_t)(dsp_core_t* dsp); - Adapted from Hatari DSP M56001 Disassembler - (C) 2003-2008 ARAnyM developer team - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include -#include -#include -#include - -#include "dsp_cpu.h" -#include "dsp_int.h" -#include "dsp_disasm.h" - -/* More disasm infos, if wanted */ -#define DSP_DISASM_REG_PC 0 - -/********************************** - * Defines - **********************************/ -#define BITMASK(x) ((1<<(x))-1) - -/********************************** - * Variables - **********************************/ - -/* Previous instruction */ -uint32_t prev_inst_pc; -bool isLooping; - -/* Used to display dc instead of unknown instruction for illegal opcodes */ -bool isInDisasmMode; - -uint32_t disasm_cur_inst; -uint16_t disasm_cur_inst_len; - -/* Current instruction */ -char str_instr[50]; -char str_instr2[120]; -char parallelmove_name[64]; - -/********************************** - * Register change - **********************************/ - -static uint32_t registers_save[64]; -#if DSP_DISASM_REG_PC -static uint32_t pc_save; -#endif static const char *registers_name[64]={ "","","","", @@ -88,16 +24,8 @@ static const char *registers_name[64]={ "ssh","ssl","la","lc" }; -/********************************** - * Opcode disassembler - **********************************/ -static uint32_t read_memory(uint32_t currPc); - -static int dis_calc_ea(uint32_t ea_mode, char *dest); -static void dis_calc_cc(uint32_t cc_mode, char *dest); - -static const char* opcodes_alu[256] = { +static const char* disasm_opcodes_alu[256] = { /* 0x00 - 0x3f */ "move" , "tfr b,a", "addr b,a", "tst a", "undefined", "cmp b,a" , "subr b,a", "cmpm b,a", "undefined", "tfr a,b", "addr a,b", "tst b", "undefined", "cmp a,b" , "subr a,b", "cmpm a,b", @@ -139,9 +67,13 @@ static const char* opcodes_alu[256] = { "mpy +y1,x1,b", "mpyr +y1,x1,b", "mac +y1,x1,b", "macr +y1,x1,b", "mpy -y1,x1,b", "mpyr -y1,x1,b", "mac -y1,x1,b", "macr -y1,x1,b" }; +static void dis_pm_0(dsp_core_t* dsp); +static void dis_pm_1(dsp_core_t* dsp); +static void dis_pm_2(dsp_core_t* dsp); +static void dis_pm_4(dsp_core_t* dsp); +static void dis_pm_8(dsp_core_t* dsp); - -static const dis_func_t opcodes_parmove[16] = { +static const dis_func_t disasm_opcodes_parmove[16] = { dis_pm_0, dis_pm_1, dis_pm_2, @@ -161,28 +93,6 @@ static const dis_func_t opcodes_parmove[16] = { dis_pm_8 }; -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}, - {DSP_REG_NULL,DSP_REG_NULL}, - - {DSP_REG_NULL,DSP_REG_NULL}, - {DSP_REG_NULL,DSP_REG_NULL}, - {DSP_REG_NULL,DSP_REG_NULL}, - {DSP_REG_NULL,DSP_REG_NULL}, - - {DSP_REG_X0,DSP_REG_A}, - {DSP_REG_X0,DSP_REG_B}, - {DSP_REG_Y0,DSP_REG_A}, - {DSP_REG_Y0,DSP_REG_B}, - - {DSP_REG_X1,DSP_REG_A}, - {DSP_REG_X1,DSP_REG_B}, - {DSP_REG_Y1,DSP_REG_A}, - {DSP_REG_Y1,DSP_REG_B} -}; - static const char *registers_lmove[8] = { "a10", "b10", @@ -226,141 +136,12 @@ static const char *cc_name[16] = { "le" }; -void dsp56k_disasm_reg_save(void) -{ - memcpy(registers_save, dsp_core.registers , sizeof(registers_save)); -#if DSP_DISASM_REG_PC - pc_save = dsp_core.pc; -#endif -} - -void dsp56k_disasm_reg_compare(void) -{ - int i; - bool bRegA = false; - bool bRegB = false; - - for (i=4; i<64; i++) { - if (registers_save[i] == dsp_core.registers[i]) { - continue; - } - - switch(i) { - case DSP_REG_X0: - case DSP_REG_X1: - case DSP_REG_Y0: - case DSP_REG_Y1: - fprintf(stderr,"\tReg: %s $%06x -> $%06x\n", registers_name[i], registers_save[i], dsp_core.registers[i]); - 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_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: - 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_SR: - case DSP_REG_LA: - case DSP_REG_LC: - fprintf(stderr,"\tReg: %s $%04x -> $%04x\n", registers_name[i], registers_save[i], dsp_core.registers[i]); - break; - case DSP_REG_OMR: - case DSP_REG_SP: - case DSP_REG_SSH: - case DSP_REG_SSL: - fprintf(stderr,"\tReg: %s $%02x -> $%02x\n", registers_name[i], registers_save[i], dsp_core.registers[i]); - break; - case DSP_REG_A0: - case DSP_REG_A1: - case DSP_REG_A2: - if (bRegA == false) { - fprintf(stderr,"\tReg: a $%02x:%06x:%06x -> $%02x:%06x:%06x\n", - registers_save[DSP_REG_A2], registers_save[DSP_REG_A1], registers_save[DSP_REG_A0], - dsp_core.registers[DSP_REG_A2], dsp_core.registers[DSP_REG_A1], dsp_core.registers[DSP_REG_A0] - ); - bRegA = true; - } - break; - case DSP_REG_B0: - case DSP_REG_B1: - case DSP_REG_B2: - if (bRegB == false) { - fprintf(stderr,"\tReg: b $%02x:%06x:%06x -> $%02x:%06x:%06x\n", - registers_save[DSP_REG_B2], registers_save[DSP_REG_B1], registers_save[DSP_REG_B0], - dsp_core.registers[DSP_REG_B2], dsp_core.registers[DSP_REG_B1], dsp_core.registers[DSP_REG_B0] - ); - bRegB = true; - } - break; - } - } - -#if DSP_DISASM_REG_PC - if (pc_save != dsp_core.pc) { - fprintf(stderr,"\tReg: pc $%04x -> $%04x\n", pc_save, dsp_core.pc); - } -#endif -} - -/** - * dsp56k_getInstrText : return the disasembled instructions - */ -const char* dsp56k_get_instruction_text(void) -{ - const int len = sizeof(str_instr); - // uint64_t count, cycles; - // uint16_t cycle_diff; - // float percentage; - int offset; - - if (isLooping) { - *str_instr2 = 0; - } - if (disasm_cur_inst_len == 1) { - offset = sprintf(str_instr2, "p:%04x %06x (%02d cyc) %-*s\n", prev_inst_pc, disasm_cur_inst, dsp_core.instr_cycle, len, str_instr); - } else { - offset = sprintf(str_instr2, "p:%04x %06x %06x (%02d cyc) %-*s\n", prev_inst_pc, disasm_cur_inst, read_memory(prev_inst_pc + 1), dsp_core.instr_cycle, len, str_instr); - } - // if (offset > 2 && Profile_DspAddressData(prev_inst_pc, &percentage, &count, &cycles, &cycle_diff)) { - // offset -= 2; - // sprintf(str_instr2+offset, "%5.2f%% (%"PRId64", %"PRId64", %d)\n", - // percentage, count, cycles, cycle_diff); - // } - return str_instr2; -} - -void dis_pm_class2(void) { - dis_pm(); - sprintf(str_instr, "%s %s", opcodes_alu[disasm_cur_inst & BITMASK(8)], parallelmove_name); -} - -static uint32_t read_memory(uint32_t currPc) -{ - return dsp56k_read_memory(DSP_SPACE_P, currPc); -} /********************************** * Conditions code calculation **********************************/ -void dis_calc_cc(uint32_t cc_mode, char *dest) +static void dis_calc_cc(dsp_core_t* dsp, uint32_t cc_mode, char *dest) { strcpy(dest, cc_name[cc_mode & BITMASK(4)]); } @@ -369,7 +150,7 @@ void dis_calc_cc(uint32_t cc_mode, char *dest) * Effective address calculation **********************************/ -static int dis_calc_ea(uint32_t ea_mode, char *dest) +static int dis_calc_ea(dsp_core_t* dsp, uint32_t ea_mode, char *dest) { int value, retour, numreg; @@ -406,15 +187,15 @@ static int dis_calc_ea(uint32_t ea_mode, char *dest) sprintf(dest, ea_names[value], numreg); break; case 6: - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; switch ((ea_mode >> 2) & 1) { case 0: /* Absolute address */ - sprintf(dest, ea_names[value], read_memory(dsp_core.pc+1)); + sprintf(dest, ea_names[value], read_memory_p(dsp, dsp->pc+1)); break; case 1: /* Immediate value */ - sprintf(dest, ea_names[8], read_memory(dsp_core.pc+1)); + sprintf(dest, ea_names[8], read_memory_p(dsp, dsp->pc+1)); retour = 1; break; } @@ -427,75 +208,75 @@ static int dis_calc_ea(uint32_t ea_mode, char *dest) * Non-parallel moves instructions **********************************/ -void dis_undefined(void) +static void dis_undefined(dsp_core_t* dsp) { /* In Disasm mode, display dc instruction_opcode */ - if (isInDisasmMode) - sprintf(str_instr, "dc $%06x", disasm_cur_inst); + if (dsp->isInDisasmMode) + sprintf(dsp->disasm_str_instr, "dc $%06x", dsp->disasm_cur_inst); /* In trace mode, display unknown instruction */ else - sprintf(str_instr, "$%06x unknown instruction", disasm_cur_inst); + sprintf(dsp->disasm_str_instr, "$%06x unknown instruction", dsp->disasm_cur_inst); } -void dis_add_long(void) +static void dis_add_long(dsp_core_t* dsp) { - disasm_cur_inst_len++; - uint32_t xxxx = read_memory(dsp_core.pc+1); - uint32_t accname = ((disasm_cur_inst >> 3) & 1) ? DSP_REG_B : DSP_REG_A; - sprintf(str_instr, "add #$%04x,%s", xxxx, registers_name[accname]); + dsp->disasm_cur_inst_len++; + uint32_t xxxx = read_memory_p(dsp, dsp->pc+1); + uint32_t accname = ((dsp->disasm_cur_inst >> 3) & 1) ? DSP_REG_B : DSP_REG_A; + sprintf(dsp->disasm_str_instr, "add #$%04x,%s", xxxx, registers_name[accname]); } -void dis_andi(void) +static void dis_andi(dsp_core_t* dsp) { - switch(disasm_cur_inst & BITMASK(2)) { + switch(dsp->disasm_cur_inst & BITMASK(2)) { case 0: - sprintf(str_instr, "andi #$%02x,mr", (disasm_cur_inst>>8) & BITMASK(8)); + sprintf(dsp->disasm_str_instr, "andi #$%02x,mr", (dsp->disasm_cur_inst>>8) & BITMASK(8)); break; case 1: - sprintf(str_instr, "andi #$%02x,ccr", (disasm_cur_inst>>8) & BITMASK(8)); + sprintf(dsp->disasm_str_instr, "andi #$%02x,ccr", (dsp->disasm_cur_inst>>8) & BITMASK(8)); break; case 2: - sprintf(str_instr, "andi #$%02x,omr", (disasm_cur_inst>>8) & BITMASK(8)); + sprintf(dsp->disasm_str_instr, "andi #$%02x,omr", (dsp->disasm_cur_inst>>8) & BITMASK(8)); break; default: break; } } -void dis_bcc_long(void) { - disasm_cur_inst_len++; +static void dis_bcc_long(dsp_core_t* dsp) { + dsp->disasm_cur_inst_len++; - uint32_t cc_code = disasm_cur_inst & BITMASK(4); - uint32_t xxxx = read_memory(dsp_core.pc+1); + uint32_t cc_code = dsp->disasm_cur_inst & BITMASK(4); + uint32_t xxxx = read_memory_p(dsp, dsp->pc+1); char cond_name[16]; - dis_calc_cc(cc_code, cond_name); + dis_calc_cc(dsp, cc_code, cond_name); - sprintf(str_instr, "b%s p:$%06x", cond_name, xxxx); + sprintf(dsp->disasm_str_instr, "b%s p:$%06x", cond_name, xxxx); } -void dis_bcc_imm(void) { +static void dis_bcc_imm(dsp_core_t* dsp) { char cond_name[16]; - uint32_t cc_code = (disasm_cur_inst >> 12) & BITMASK(4); - uint32_t xxx = (disasm_cur_inst & BITMASK(5)) - + ((disasm_cur_inst & (BITMASK(4) << 6)) >> 1); + uint32_t cc_code = (dsp->disasm_cur_inst >> 12) & BITMASK(4); + uint32_t xxx = (dsp->disasm_cur_inst & BITMASK(5)) + + ((dsp->disasm_cur_inst & (BITMASK(4) << 6)) >> 1); - dis_calc_cc(cc_code, cond_name); + dis_calc_cc(dsp, cc_code, cond_name); - sprintf(str_instr,"b%s p:$%04x", cond_name, xxx); + sprintf(dsp->disasm_str_instr,"b%s p:$%04x", cond_name, xxx); } -void dis_bchg_aa(void) +static void dis_bchg_aa(dsp_core_t* dsp) { /* bchg #n,x:aa */ /* bchg #n,y:aa */ char name[16]; uint32_t memspace, value, numbit; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); if (memspace) { sprintf(name,"y:$%04x",value); @@ -503,40 +284,40 @@ void dis_bchg_aa(void) sprintf(name,"x:$%04x",value); } - sprintf(str_instr,"bchg #%d,%s", numbit, name); + sprintf(dsp->disasm_str_instr,"bchg #%d,%s", numbit, name); } -void dis_bchg_ea(void) +static void dis_bchg_ea(dsp_core_t* dsp) { /* bchg #n,x:ea */ /* bchg #n,y:ea */ char name[16], addr_name[16]; uint32_t memspace, value, numbit; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - dis_calc_ea(value, addr_name); + dis_calc_ea(dsp, value, addr_name); if (memspace) { sprintf(name,"y:%s",addr_name); } else { sprintf(name,"x:%s",addr_name); } - sprintf(str_instr,"bchg #%d,%s", numbit, name); + sprintf(dsp->disasm_str_instr,"bchg #%d,%s", numbit, name); } -void dis_bchg_pp(void) +static void dis_bchg_pp(dsp_core_t* dsp) { /* bchg #n,x:pp */ /* bchg #n,y:pp */ char name[16]; uint32_t memspace, value, numbit; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); if (memspace) { sprintf(name,"y:$%06x",value+0xffffc0); @@ -544,30 +325,30 @@ void dis_bchg_pp(void) sprintf(name,"x:$%06x",value+0xffffc0); } - sprintf(str_instr,"bchg #%d,%s", numbit, name); + sprintf(dsp->disasm_str_instr,"bchg #%d,%s", numbit, name); } -void dis_bchg_reg(void) +static void dis_bchg_reg(dsp_core_t* dsp) { /* bchg #n,R */ uint32_t value, numbit; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - sprintf(str_instr,"bchg #%d,%s", numbit, registers_name[value]); + sprintf(dsp->disasm_str_instr,"bchg #%d,%s", numbit, registers_name[value]); } -void dis_bclr_aa(void) +static void dis_bclr_aa(dsp_core_t* dsp) { /* bclr #n,x:aa */ /* bclr #n,y:aa */ char name[16]; uint32_t memspace, value, numbit; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); if (memspace) { sprintf(name,"y:$%04x",value); @@ -575,40 +356,40 @@ void dis_bclr_aa(void) sprintf(name,"x:$%04x",value); } - sprintf(str_instr,"bclr #%d,%s", numbit, name); + sprintf(dsp->disasm_str_instr,"bclr #%d,%s", numbit, name); } -void dis_bclr_ea(void) +static void dis_bclr_ea(dsp_core_t* dsp) { /* bclr #n,x:ea */ /* bclr #n,y:ea */ char name[16], addr_name[16]; uint32_t memspace, value, numbit; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - dis_calc_ea(value, addr_name); + dis_calc_ea(dsp, value, addr_name); if (memspace) { sprintf(name,"y:%s",addr_name); } else { sprintf(name,"x:%s",addr_name); } - sprintf(str_instr,"bclr #%d,%s", numbit, name); + sprintf(dsp->disasm_str_instr,"bclr #%d,%s", numbit, name); } -void dis_bclr_pp(void) +static void dis_bclr_pp(dsp_core_t* dsp) { /* bclr #n,x:pp */ /* bclr #n,y:pp */ char name[16]; uint32_t memspace, value, numbit; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); if (memspace) { sprintf(name,"y:$%06x",value+0xffffc0); @@ -616,38 +397,38 @@ void dis_bclr_pp(void) sprintf(name,"x:$%06x",value+0xffffc0); } - sprintf(str_instr,"bclr #%d,%s", numbit, name); + sprintf(dsp->disasm_str_instr,"bclr #%d,%s", numbit, name); } -void dis_bclr_reg(void) +static void dis_bclr_reg(dsp_core_t* dsp) { /* bclr #n,R */ uint32_t value, numbit; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - sprintf(str_instr,"bclr #%d,%s", numbit, registers_name[value]); + sprintf(dsp->disasm_str_instr,"bclr #%d,%s", numbit, registers_name[value]); } -void dis_bra_imm(void) +static void dis_bra_imm(dsp_core_t* dsp) { // QQQ - sign-extend - uint32_t xxx = (disasm_cur_inst & BITMASK(5)) - + ((disasm_cur_inst & (BITMASK(4) << 6)) >> 1); - sprintf(str_instr, "bra p:$%04x", xxx); + uint32_t xxx = (dsp->disasm_cur_inst & BITMASK(5)) + + ((dsp->disasm_cur_inst & (BITMASK(4) << 6)) >> 1); + sprintf(dsp->disasm_str_instr, "bra p:$%04x", xxx); } -void dis_bset_aa(void) +static void dis_bset_aa(dsp_core_t* dsp) { /* bset #n,x:aa */ /* bset #n,y:aa */ char name[16]; uint32_t memspace, value, numbit; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); if (memspace) { sprintf(name,"y:$%04x",value); @@ -655,40 +436,40 @@ void dis_bset_aa(void) sprintf(name,"x:$%04x",value); } - sprintf(str_instr,"bset #%d,%s", numbit, name); + sprintf(dsp->disasm_str_instr,"bset #%d,%s", numbit, name); } -void dis_bset_ea(void) +static void dis_bset_ea(dsp_core_t* dsp) { /* bset #n,x:ea */ /* bset #n,y:ea */ char name[16], addr_name[16]; uint32_t memspace, value, numbit; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - dis_calc_ea(value, addr_name); + dis_calc_ea(dsp, value, addr_name); if (memspace) { sprintf(name,"y:%s",addr_name); } else { sprintf(name,"x:%s",addr_name); } - sprintf(str_instr,"bset #%d,%s", numbit, name); + sprintf(dsp->disasm_str_instr,"bset #%d,%s", numbit, name); } -void dis_bset_pp(void) +static void dis_bset_pp(dsp_core_t* dsp) { /* bset #n,x:pp */ /* bset #n,y:pp */ char name[16]; uint32_t memspace, value, numbit; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); if (memspace) { sprintf(name,"y:$%06x",value+0xffffc0); @@ -696,30 +477,30 @@ void dis_bset_pp(void) sprintf(name,"x:$%06x",value+0xffffc0); } - sprintf(str_instr,"bset #%d,%s", numbit, name); + sprintf(dsp->disasm_str_instr,"bset #%d,%s", numbit, name); } -void dis_bset_reg(void) +static void dis_bset_reg(dsp_core_t* dsp) { /* bset #n,R */ uint32_t value, numbit; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - sprintf(str_instr,"bset #%d,%s", numbit, registers_name[value]); + sprintf(dsp->disasm_str_instr,"bset #%d,%s", numbit, registers_name[value]); } -void dis_btst_aa(void) +static void dis_btst_aa(dsp_core_t* dsp) { /* btst #n,x:aa */ /* btst #n,y:aa */ char name[16]; uint32_t memspace, value, numbit; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); if (memspace) { sprintf(name,"y:$%04x",value); @@ -727,40 +508,40 @@ void dis_btst_aa(void) sprintf(name,"x:$%04x",value); } - sprintf(str_instr,"btst #%d,%s", numbit, name); + sprintf(dsp->disasm_str_instr,"btst #%d,%s", numbit, name); } -void dis_btst_ea(void) +static void dis_btst_ea(dsp_core_t* dsp) { /* btst #n,x:ea */ /* btst #n,y:ea */ char name[16], addr_name[16]; uint32_t memspace, value, numbit; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - dis_calc_ea(value, addr_name); + dis_calc_ea(dsp, value, addr_name); if (memspace) { sprintf(name,"y:%s",addr_name); } else { sprintf(name,"x:%s",addr_name); } - sprintf(str_instr,"btst #%d,%s", numbit, name); + sprintf(dsp->disasm_str_instr,"btst #%d,%s", numbit, name); } -void dis_btst_pp(void) +static void dis_btst_pp(dsp_core_t* dsp) { /* btst #n,x:pp */ /* btst #n,y:pp */ char name[16]; uint32_t memspace, value, numbit; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); if (memspace) { sprintf(name,"y:$%06x",value+0xffffc0); @@ -768,23 +549,23 @@ void dis_btst_pp(void) sprintf(name,"x:$%06x",value+0xffffc0); } - sprintf(str_instr,"btst #%d,%s", numbit, name); + sprintf(dsp->disasm_str_instr,"btst #%d,%s", numbit, name); } -void dis_btst_reg(void) +static void dis_btst_reg(dsp_core_t* dsp) { /* btst #n,R */ uint32_t value, numbit; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - sprintf(str_instr,"btst #%d,%s", numbit, registers_name[value]); + sprintf(dsp->disasm_str_instr,"btst #%d,%s", numbit, registers_name[value]); } -void dis_cmpu(void) { - uint32_t ggg = (disasm_cur_inst >> 1) & BITMASK(3); - uint32_t d = disasm_cur_inst & 1; +static void dis_cmpu(dsp_core_t* dsp) { + uint32_t ggg = (dsp->disasm_cur_inst >> 1) & BITMASK(3); + uint32_t d = dsp->disasm_cur_inst & 1; uint32_t srcreg = DSP_REG_NULL; uint32_t srcacc = d ? DSP_REG_B : DSP_REG_A; @@ -796,14 +577,14 @@ void dis_cmpu(void) { case 7: srcreg = DSP_REG_Y1; break; } - sprintf(str_instr, "cmpu %s,%s", registers_name[srcreg], registers_name[srcacc]); + sprintf(dsp->disasm_str_instr, "cmpu %s,%s", registers_name[srcreg], registers_name[srcacc]); } -void dis_div(void) +static void dis_div(dsp_core_t* dsp) { uint32_t srcreg=DSP_REG_NULL, destreg; - switch((disasm_cur_inst>>4) & BITMASK(2)) { + switch((dsp->disasm_cur_inst>>4) & BITMASK(2)) { case 0: srcreg = DSP_REG_X0; break; @@ -817,117 +598,117 @@ void dis_div(void) srcreg = DSP_REG_Y1; break; } - destreg = DSP_REG_A+((disasm_cur_inst>>3) & 1); + destreg = DSP_REG_A+((dsp->disasm_cur_inst>>3) & 1); - sprintf(str_instr,"div %s,%s", registers_name[srcreg],registers_name[destreg]); + sprintf(dsp->disasm_str_instr,"div %s,%s", registers_name[srcreg],registers_name[destreg]); } -void dis_do_aa(void) +static void dis_do_aa(dsp_core_t* dsp) { char name[16]; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - if (disasm_cur_inst & (1<<6)) { - sprintf(name, "y:$%04x", (disasm_cur_inst>>8) & BITMASK(6)); + if (dsp->disasm_cur_inst & (1<<6)) { + sprintf(name, "y:$%04x", (dsp->disasm_cur_inst>>8) & BITMASK(6)); } else { - sprintf(name, "x:$%04x", (disasm_cur_inst>>8) & BITMASK(6)); + sprintf(name, "x:$%04x", (dsp->disasm_cur_inst>>8) & BITMASK(6)); } - sprintf(str_instr,"do %s,p:$%04x", + sprintf(dsp->disasm_str_instr,"do %s,p:$%04x", name, - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_do_imm(void) +static void dis_do_imm(dsp_core_t* dsp) { - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - sprintf(str_instr,"do #$%04x,p:$%04x", - ((disasm_cur_inst>>8) & BITMASK(8))|((disasm_cur_inst & BITMASK(4))<<8), - read_memory(dsp_core.pc+1) + sprintf(dsp->disasm_str_instr,"do #$%04x,p:$%04x", + ((dsp->disasm_cur_inst>>8) & BITMASK(8))|((dsp->disasm_cur_inst & BITMASK(4))<<8), + read_memory_p(dsp, dsp->pc+1) ); } -void dis_do_ea(void) +static void dis_do_ea(dsp_core_t* dsp) { char addr_name[16], name[16]; uint32_t ea_mode; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - ea_mode = (disasm_cur_inst>>8) & BITMASK(6); - dis_calc_ea(ea_mode, addr_name); + ea_mode = (dsp->disasm_cur_inst>>8) & BITMASK(6); + dis_calc_ea(dsp, ea_mode, addr_name); - if (disasm_cur_inst & (1<<6)) { + if (dsp->disasm_cur_inst & (1<<6)) { sprintf(name, "y:%s", addr_name); } else { sprintf(name, "x:%s", addr_name); } - sprintf(str_instr,"do %s,p:$%04x", + sprintf(dsp->disasm_str_instr,"do %s,p:$%04x", name, - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_do_reg(void) +static void dis_do_reg(dsp_core_t* dsp) { - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - sprintf(str_instr,"do %s,p:$%04x", - registers_name[(disasm_cur_inst>>8) & BITMASK(6)], - read_memory(dsp_core.pc+1) + sprintf(dsp->disasm_str_instr,"do %s,p:$%04x", + registers_name[(dsp->disasm_cur_inst>>8) & BITMASK(6)], + read_memory_p(dsp, dsp->pc+1) ); } -void dis_dor_imm(void) +static void dis_dor_imm(dsp_core_t* dsp) { - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - sprintf(str_instr,"dor #$%04x,p:$%04x", - ((disasm_cur_inst>>8) & BITMASK(8))|((disasm_cur_inst & BITMASK(4))<<8), - read_memory(dsp_core.pc+1) + sprintf(dsp->disasm_str_instr,"dor #$%04x,p:$%04x", + ((dsp->disasm_cur_inst>>8) & BITMASK(8))|((dsp->disasm_cur_inst & BITMASK(4))<<8), + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jcc_ea(void) +static void dis_jcc_ea(dsp_core_t* dsp) { char cond_name[16], addr_name[16]; uint32_t cc_code=0; - dis_calc_ea((disasm_cur_inst >>8) & BITMASK(6), addr_name); - cc_code=disasm_cur_inst & BITMASK(4); - dis_calc_cc(cc_code, cond_name); + dis_calc_ea(dsp, (dsp->disasm_cur_inst >>8) & BITMASK(6), addr_name); + cc_code=dsp->disasm_cur_inst & BITMASK(4); + dis_calc_cc(dsp, cc_code, cond_name); - sprintf(str_instr,"j%s p:%s", cond_name, addr_name); + sprintf(dsp->disasm_str_instr,"j%s p:%s", cond_name, addr_name); } -void dis_jcc_imm(void) +static void dis_jcc_imm(dsp_core_t* dsp) { char cond_name[16], addr_name[16]; uint32_t cc_code=0; - sprintf(addr_name, "$%04x", disasm_cur_inst & BITMASK(12)); - cc_code=(disasm_cur_inst>>12) & BITMASK(4); - dis_calc_cc(cc_code, cond_name); + sprintf(addr_name, "$%04x", dsp->disasm_cur_inst & BITMASK(12)); + cc_code=(dsp->disasm_cur_inst>>12) & BITMASK(4); + dis_calc_cc(dsp, cc_code, cond_name); - sprintf(str_instr,"j%s p:%s", cond_name, addr_name); + sprintf(dsp->disasm_str_instr,"j%s p:%s", cond_name, addr_name); } -void dis_jclr_aa(void) +static void dis_jclr_aa(dsp_core_t* dsp) { /* jclr #n,x:aa,p:xx */ /* jclr #n,y:aa,p:xx */ char srcname[16]; uint32_t memspace, value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); if (memspace) { sprintf(srcname, "y:$%04x", value); @@ -935,52 +716,52 @@ void dis_jclr_aa(void) sprintf(srcname, "x:$%04x", value); } - sprintf(str_instr,"jclr #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jclr #%d,%s,p:$%04x", numbit, srcname, - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jclr_ea(void) +static void dis_jclr_ea(dsp_core_t* dsp) { /* jclr #n,x:ea,p:xx */ /* jclr #n,y:ea,p:xx */ char srcname[16], addr_name[16]; uint32_t memspace, value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - dis_calc_ea(value, addr_name); + dis_calc_ea(dsp, value, addr_name); if (memspace) { sprintf(srcname, "y:%s", addr_name); } else { sprintf(srcname, "x:%s", addr_name); } - sprintf(str_instr,"jclr #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jclr #%d,%s,p:$%04x", numbit, srcname, - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jclr_pp(void) +static void dis_jclr_pp(dsp_core_t* dsp) { /* jclr #n,x:pp,p:xx */ /* jclr #n,y:pp,p:xx */ char srcname[16]; uint32_t memspace, value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); value += 0xffffc0; if (memspace) { @@ -989,80 +770,80 @@ void dis_jclr_pp(void) sprintf(srcname, "x:$%06x", value); } - sprintf(str_instr,"jclr #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jclr #%d,%s,p:$%04x", numbit, srcname, - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jclr_reg(void) +static void dis_jclr_reg(dsp_core_t* dsp) { /* jclr #n,R,p:xx */ uint32_t value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - sprintf(str_instr,"jclr #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jclr #%d,%s,p:$%04x", numbit, registers_name[value], - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jmp_imm(void) +static void dis_jmp_imm(dsp_core_t* dsp) { - sprintf(str_instr,"jmp p:$%04x", disasm_cur_inst & BITMASK(12)); + sprintf(dsp->disasm_str_instr,"jmp p:$%04x", dsp->disasm_cur_inst & BITMASK(12)); } -void dis_jmp_ea(void) +static void dis_jmp_ea(dsp_core_t* dsp) { char dstname[16]; - dis_calc_ea((disasm_cur_inst >>8) & BITMASK(6), dstname); + dis_calc_ea(dsp, (dsp->disasm_cur_inst >>8) & BITMASK(6), dstname); - sprintf(str_instr,"jmp p:%s", dstname); + sprintf(dsp->disasm_str_instr,"jmp p:%s", dstname); } -void dis_jscc_ea(void) +static void dis_jscc_ea(dsp_core_t* dsp) { char cond_name[16], addr_name[16]; uint32_t cc_code=0; - dis_calc_ea((disasm_cur_inst>>8) & BITMASK(6), addr_name); - cc_code=disasm_cur_inst & BITMASK(4); - dis_calc_cc(cc_code, cond_name); + dis_calc_ea(dsp, (dsp->disasm_cur_inst>>8) & BITMASK(6), addr_name); + cc_code=dsp->disasm_cur_inst & BITMASK(4); + dis_calc_cc(dsp, cc_code, cond_name); - sprintf(str_instr,"js%s p:%s", cond_name, addr_name); + sprintf(dsp->disasm_str_instr,"js%s p:%s", cond_name, addr_name); } -void dis_jscc_imm(void) +static void dis_jscc_imm(dsp_core_t* dsp) { char cond_name[16], addr_name[16]; uint32_t cc_code=0; - sprintf(addr_name, "$%04x", disasm_cur_inst & BITMASK(12)); - cc_code=(disasm_cur_inst>>12) & BITMASK(4); - dis_calc_cc(cc_code, cond_name); + sprintf(addr_name, "$%04x", dsp->disasm_cur_inst & BITMASK(12)); + cc_code=(dsp->disasm_cur_inst>>12) & BITMASK(4); + dis_calc_cc(dsp, cc_code, cond_name); - sprintf(str_instr,"js%s p:%s", cond_name, addr_name); + sprintf(dsp->disasm_str_instr,"js%s p:%s", cond_name, addr_name); } -void dis_jsclr_aa(void) +static void dis_jsclr_aa(dsp_core_t* dsp) { /* jsclr #n,x:aa,p:xx */ /* jsclr #n,y:aa,p:xx */ char srcname[16]; uint32_t memspace, value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); if (memspace) { sprintf(srcname, "y:$%04x", value); @@ -1070,52 +851,52 @@ void dis_jsclr_aa(void) sprintf(srcname, "x:$%04x", value); } - sprintf(str_instr,"jsclr #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jsclr #%d,%s,p:$%04x", numbit, srcname, - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jsclr_ea(void) +static void dis_jsclr_ea(dsp_core_t* dsp) { /* jsclr #n,x:ea,p:xx */ /* jsclr #n,y:ea,p:xx */ char srcname[16], addr_name[16]; uint32_t memspace, value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - dis_calc_ea(value, addr_name); + dis_calc_ea(dsp, value, addr_name); if (memspace) { sprintf(srcname, "y:%s", addr_name); } else { sprintf(srcname, "x:%s", addr_name); } - sprintf(str_instr,"jsclr #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jsclr #%d,%s,p:$%04x", numbit, srcname, - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jsclr_pp(void) +static void dis_jsclr_pp(dsp_core_t* dsp) { /* jsclr #n,x:pp,p:xx */ /* jsclr #n,y:pp,p:xx */ char srcname[16]; uint32_t memspace, value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); value += 0xffffc0; if (memspace) { @@ -1124,42 +905,42 @@ void dis_jsclr_pp(void) sprintf(srcname, "x:$%06x", value); } - sprintf(str_instr,"jsclr #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jsclr #%d,%s,p:$%04x", numbit, srcname, - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jsclr_reg(void) +static void dis_jsclr_reg(dsp_core_t* dsp) { /* jsclr #n,R,p:xx */ uint32_t value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - sprintf(str_instr,"jsclr #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jsclr #%d,%s,p:$%04x", numbit, registers_name[value], - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jset_aa(void) +static void dis_jset_aa(dsp_core_t* dsp) { /* jset #n,x:aa,p:xx */ /* jset #n,y:aa,p:xx */ char srcname[16]; uint32_t memspace, value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); if (memspace) { sprintf(srcname, "y:$%04x", value); @@ -1167,52 +948,52 @@ void dis_jset_aa(void) sprintf(srcname, "x:$%04x", value); } - sprintf(str_instr,"jset #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jset #%d,%s,p:$%04x", numbit, srcname, - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jset_ea(void) +static void dis_jset_ea(dsp_core_t* dsp) { /* jset #n,x:ea,p:xx */ /* jset #n,y:ea,p:xx */ char srcname[16], addr_name[16]; uint32_t memspace, value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - dis_calc_ea(value, addr_name); + dis_calc_ea(dsp, value, addr_name); if (memspace) { sprintf(srcname, "y:%s", addr_name); } else { sprintf(srcname, "x:%s", addr_name); } - sprintf(str_instr,"jset #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jset #%d,%s,p:$%04x", numbit, srcname, - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jset_pp(void) +static void dis_jset_pp(dsp_core_t* dsp) { /* jset #n,x:pp,p:xx */ /* jset #n,y:pp,p:xx */ char srcname[16]; uint32_t memspace, value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); value += 0xffffc0; if (memspace) { @@ -1221,56 +1002,56 @@ void dis_jset_pp(void) sprintf(srcname, "x:$%06x", value); } - sprintf(str_instr,"jset #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jset #%d,%s,p:$%04x", numbit, srcname, - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jset_reg(void) +static void dis_jset_reg(dsp_core_t* dsp) { /* jset #n,R,p:xx */ uint32_t value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - sprintf(str_instr,"jset #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jset #%d,%s,p:$%04x", numbit, registers_name[value], - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jsr_imm(void) +static void dis_jsr_imm(dsp_core_t* dsp) { - sprintf(str_instr,"jsr p:$%04x", disasm_cur_inst & BITMASK(12)); + sprintf(dsp->disasm_str_instr,"jsr p:$%04x", dsp->disasm_cur_inst & BITMASK(12)); } -void dis_jsr_ea(void) +static void dis_jsr_ea(dsp_core_t* dsp) { char dstname[16]; - dis_calc_ea((disasm_cur_inst>>8) & BITMASK(6),dstname); + dis_calc_ea(dsp, (dsp->disasm_cur_inst>>8) & BITMASK(6),dstname); - sprintf(str_instr,"jsr p:%s", dstname); + sprintf(dsp->disasm_str_instr,"jsr p:%s", dstname); } -void dis_jsset_aa(void) +static void dis_jsset_aa(dsp_core_t* dsp) { /* jsset #n,x:aa,p:xx */ /* jsset #n,y:aa,p:xx */ char srcname[16]; uint32_t memspace, value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); if (memspace) { sprintf(srcname, "y:$%04x", value); @@ -1278,52 +1059,52 @@ void dis_jsset_aa(void) sprintf(srcname, "x:$%04x", value); } - sprintf(str_instr,"jsset #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jsset #%d,%s,p:$%04x", numbit, srcname, - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jsset_ea(void) +static void dis_jsset_ea(dsp_core_t* dsp) { /* jsset #n,x:ea,p:xx */ /* jsset #n,y:ea,p:xx */ char srcname[16], addr_name[16]; uint32_t memspace, value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - dis_calc_ea(value, addr_name); + dis_calc_ea(dsp, value, addr_name); if (memspace) { sprintf(srcname, "y:%s", addr_name); } else { sprintf(srcname, "x:%s", addr_name); } - sprintf(str_instr,"jsset #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jsset #%d,%s,p:$%04x", numbit, srcname, - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jsset_pp(void) +static void dis_jsset_pp(dsp_core_t* dsp) { /* jsset #n,x:pp,p:xx */ /* jsset #n,y:pp,p:xx */ char srcname[16]; uint32_t memspace, value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - memspace = (disasm_cur_inst>>6) & 1; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + memspace = (dsp->disasm_cur_inst>>6) & 1; + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); value += 0xffffc0; if (memspace) { @@ -1332,63 +1113,63 @@ void dis_jsset_pp(void) sprintf(srcname, "x:$%06x", value); } - sprintf(str_instr,"jsset #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jsset #%d,%s,p:$%04x", numbit, srcname, - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_jsset_reg(void) +static void dis_jsset_reg(dsp_core_t* dsp) { /* jsset #n,r,p:xx */ uint32_t value, numbit; - disasm_cur_inst_len++; + dsp->disasm_cur_inst_len++; - value = (disasm_cur_inst>>8) & BITMASK(6); - numbit = disasm_cur_inst & BITMASK(5); + value = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numbit = dsp->disasm_cur_inst & BITMASK(5); - sprintf(str_instr,"jsset #%d,%s,p:$%04x", + sprintf(dsp->disasm_str_instr,"jsset #%d,%s,p:$%04x", numbit, registers_name[value], - read_memory(dsp_core.pc+1) + read_memory_p(dsp, dsp->pc+1) ); } -void dis_lua(void) +static void dis_lua(dsp_core_t* dsp) { char addr_name[16], numreg; - dis_calc_ea((disasm_cur_inst>>8) & BITMASK(5), addr_name); - numreg = disasm_cur_inst & BITMASK(3); + dis_calc_ea(dsp, (dsp->disasm_cur_inst>>8) & BITMASK(5), addr_name); + numreg = dsp->disasm_cur_inst & BITMASK(3); - if (disasm_cur_inst & (1<<3)) - sprintf(str_instr,"lua %s,n%d", addr_name, numreg); + if (dsp->disasm_cur_inst & (1<<3)) + sprintf(dsp->disasm_str_instr,"lua %s,n%d", addr_name, numreg); else - sprintf(str_instr,"lua %s,r%d", addr_name, numreg); + sprintf(dsp->disasm_str_instr,"lua %s,r%d", addr_name, numreg); } -void dis_movec_reg(void) +static void dis_movec_reg(dsp_core_t* dsp) { uint32_t numreg1, numreg2; /* S1,D2 */ /* S2,D1 */ - numreg2 = (disasm_cur_inst>>8) & BITMASK(6); - numreg1 = disasm_cur_inst & BITMASK(6); + numreg2 = (dsp->disasm_cur_inst>>8) & BITMASK(6); + numreg1 = dsp->disasm_cur_inst & BITMASK(6); - if (disasm_cur_inst & (1<<15)) { + if (dsp->disasm_cur_inst & (1<<15)) { /* Write D1 */ - sprintf(str_instr,"movec %s,%s", registers_name[numreg2], registers_name[numreg1]); + sprintf(dsp->disasm_str_instr,"movec %s,%s", registers_name[numreg2], registers_name[numreg1]); } else { /* Read S1 */ - sprintf(str_instr,"movec %s,%s", registers_name[numreg1], registers_name[numreg2]); + sprintf(dsp->disasm_str_instr,"movec %s,%s", registers_name[numreg1], registers_name[numreg2]); } } -void dis_movec_aa(void) +static void dis_movec_aa(dsp_core_t* dsp) { const char *spacename; char srcname[16],dstname[16]; @@ -1399,16 +1180,16 @@ void dis_movec_aa(void) /* y:aa,D1 */ /* S1,y:aa */ - numreg = disasm_cur_inst & BITMASK(6); - addr = (disasm_cur_inst>>8) & BITMASK(6); + numreg = dsp->disasm_cur_inst & BITMASK(6); + addr = (dsp->disasm_cur_inst>>8) & BITMASK(6); - if (disasm_cur_inst & (1<<6)) { + if (dsp->disasm_cur_inst & (1<<6)) { spacename="y"; } else { spacename="x"; } - if (disasm_cur_inst & (1<<15)) { + if (dsp->disasm_cur_inst & (1<<15)) { /* Write D1 */ sprintf(srcname, "%s:$%04x", spacename, addr); strcpy(dstname, registers_name[numreg]); @@ -1418,21 +1199,21 @@ void dis_movec_aa(void) sprintf(dstname, "%s:$%04x", spacename, addr); } - sprintf(str_instr,"movec %s,%s", srcname, dstname); + sprintf(dsp->disasm_str_instr,"movec %s,%s", srcname, dstname); } -void dis_movec_imm(void) +static void dis_movec_imm(dsp_core_t* dsp) { uint32_t numreg; /* #xx,D1 */ - numreg = disasm_cur_inst & BITMASK(6); + numreg = dsp->disasm_cur_inst & BITMASK(6); - sprintf(str_instr,"movec #$%02x,%s", (disasm_cur_inst>>8) & BITMASK(8), registers_name[numreg]); + sprintf(dsp->disasm_str_instr,"movec #$%02x,%s", (dsp->disasm_cur_inst>>8) & BITMASK(8), registers_name[numreg]); } -void dis_movec_ea(void) +static void dis_movec_ea(dsp_core_t* dsp) { const char *spacename; char srcname[16], dstname[16], addr_name[16]; @@ -1445,17 +1226,17 @@ void dis_movec_ea(void) /* S1,y:ea */ /* #xxxx,D1 */ - numreg = disasm_cur_inst & BITMASK(6); - ea_mode = (disasm_cur_inst>>8) & BITMASK(6); - retour = dis_calc_ea(ea_mode, addr_name); + numreg = dsp->disasm_cur_inst & BITMASK(6); + ea_mode = (dsp->disasm_cur_inst>>8) & BITMASK(6); + retour = dis_calc_ea(dsp, ea_mode, addr_name); - if (disasm_cur_inst & (1<<6)) { + if (dsp->disasm_cur_inst & (1<<6)) { spacename="y"; } else { spacename="x"; } - if (disasm_cur_inst & (1<<15)) { + if (dsp->disasm_cur_inst & (1<<15)) { /* Write D1 */ if (retour) { sprintf(srcname, "#%s", addr_name); @@ -1469,19 +1250,19 @@ void dis_movec_ea(void) sprintf(dstname, "%s:%s", spacename, addr_name); } - sprintf(str_instr,"movec %s,%s", srcname, dstname); + sprintf(dsp->disasm_str_instr,"movec %s,%s", srcname, dstname); } -void dis_movem_aa(void) +static void dis_movem_aa(dsp_core_t* dsp) { /* S,p:aa */ /* p:aa,D */ char addr_name[16], srcname[16], dstname[16]; uint32_t numreg; - sprintf(addr_name, "$%04x",(disasm_cur_inst>>8) & BITMASK(6)); - numreg = disasm_cur_inst & BITMASK(6); - if (disasm_cur_inst & (1<<15)) { + sprintf(addr_name, "$%04x",(dsp->disasm_cur_inst>>8) & BITMASK(6)); + numreg = dsp->disasm_cur_inst & BITMASK(6); + if (dsp->disasm_cur_inst & (1<<15)) { /* Write D */ sprintf(srcname, "p:%s", addr_name); strcpy(dstname, registers_name[numreg]); @@ -1491,20 +1272,20 @@ void dis_movem_aa(void) sprintf(dstname, "p:%s", addr_name); } - sprintf(str_instr,"movem %s,%s", srcname, dstname); + sprintf(dsp->disasm_str_instr,"movem %s,%s", srcname, dstname); } -void dis_movem_ea(void) +static void dis_movem_ea(dsp_core_t* dsp) { /* S,p:ea */ /* p:ea,D */ char addr_name[16], srcname[16], dstname[16]; uint32_t ea_mode, numreg; - ea_mode = (disasm_cur_inst>>8) & BITMASK(6); - dis_calc_ea(ea_mode, addr_name); - numreg = disasm_cur_inst & BITMASK(6); - if (disasm_cur_inst & (1<<15)) { + ea_mode = (dsp->disasm_cur_inst>>8) & BITMASK(6); + dis_calc_ea(dsp, ea_mode, addr_name); + numreg = dsp->disasm_cur_inst & BITMASK(6); + if (dsp->disasm_cur_inst & (1<<15)) { /* Write D */ sprintf(srcname, "p:%s", addr_name); strcpy(dstname, registers_name[numreg]); @@ -1514,10 +1295,10 @@ void dis_movem_ea(void) sprintf(dstname, "p:%s", addr_name); } - sprintf(str_instr,"movem %s,%s", srcname, dstname); + sprintf(dsp->disasm_str_instr,"movem %s,%s", srcname, dstname); } -void dis_movep_0(void) +static void dis_movep_0(dsp_core_t* dsp) { char srcname[16]="",dstname[16]=""; uint32_t addr, memspace, numreg; @@ -1527,11 +1308,11 @@ void dis_movep_0(void) /* S,y:pp */ /* y:pp,D */ - addr = 0xffffc0 + (disasm_cur_inst & BITMASK(6)); - memspace = (disasm_cur_inst>>16) & 1; - numreg = (disasm_cur_inst>>8) & BITMASK(6); + addr = 0xffffc0 + (dsp->disasm_cur_inst & BITMASK(6)); + memspace = (dsp->disasm_cur_inst>>16) & 1; + numreg = (dsp->disasm_cur_inst>>8) & BITMASK(6); - if (disasm_cur_inst & (1<<15)) { + if (dsp->disasm_cur_inst & (1<<15)) { /* Write pp */ strcpy(srcname, registers_name[numreg]); @@ -1553,10 +1334,10 @@ void dis_movep_0(void) strcpy(dstname, registers_name[numreg]); } - sprintf(str_instr,"movep %s,%s", srcname, dstname); + sprintf(dsp->disasm_str_instr,"movep %s,%s", srcname, dstname); } -void dis_movep_1(void) +static void dis_movep_1(dsp_core_t* dsp) { char srcname[16]="",dstname[16]="",name[16]=""; uint32_t addr, memspace; @@ -1566,11 +1347,11 @@ void dis_movep_1(void) /* p:ea,y:pp */ /* y:pp,p:ea */ - addr = 0xffffc0 + (disasm_cur_inst & BITMASK(6)); - dis_calc_ea((disasm_cur_inst>>8) & BITMASK(6), name); - memspace = (disasm_cur_inst>>16) & 1; + addr = 0xffffc0 + (dsp->disasm_cur_inst & BITMASK(6)); + dis_calc_ea(dsp, (dsp->disasm_cur_inst>>8) & BITMASK(6), name); + memspace = (dsp->disasm_cur_inst>>16) & 1; - if (disasm_cur_inst & (1<<15)) { + if (dsp->disasm_cur_inst & (1<<15)) { /* Write pp */ sprintf(srcname, "p:%s", name); @@ -1592,10 +1373,10 @@ void dis_movep_1(void) sprintf(dstname, "p:%s", name); } - sprintf(str_instr,"movep %s,%s", srcname, dstname); + sprintf(dsp->disasm_str_instr,"movep %s,%s", srcname, dstname); } -void dis_movep_23(void) +static void dis_movep_23(dsp_core_t* dsp) { char srcname[16]="",dstname[16]="",name[16]=""; uint32_t addr, memspace, easpace, retour; @@ -1612,12 +1393,12 @@ void dis_movep_23(void) /* y:pp,y:ea */ /* y:pp,x:ea */ - addr = 0xffffc0 + (disasm_cur_inst & BITMASK(6)); - retour = dis_calc_ea((disasm_cur_inst>>8) & BITMASK(6), name); - memspace = (disasm_cur_inst>>16) & 1; - easpace = (disasm_cur_inst>>6) & 1; + addr = 0xffffc0 + (dsp->disasm_cur_inst & BITMASK(6)); + retour = dis_calc_ea(dsp, (dsp->disasm_cur_inst>>8) & BITMASK(6), name); + memspace = (dsp->disasm_cur_inst>>16) & 1; + easpace = (dsp->disasm_cur_inst>>6) & 1; - if (disasm_cur_inst & (1<<15)) { + if (dsp->disasm_cur_inst & (1<<15)) { /* Write pp */ if (retour) { @@ -1651,20 +1432,20 @@ void dis_movep_23(void) } } - sprintf(str_instr,"movep %s,%s", srcname, dstname); + sprintf(dsp->disasm_str_instr,"movep %s,%s", srcname, dstname); } -void dis_movep_x_low(void) { +static void dis_movep_x_low(dsp_core_t* dsp) { // 00000111W1MMMRRR0Sqqqqqq char srcname[16]="",dstname[16]="",name[16]=""; uint32_t addr, easpace, retour; - addr = 0xffff80 + (disasm_cur_inst & BITMASK(6)); - retour = dis_calc_ea((disasm_cur_inst>>8) & BITMASK(6), name); - easpace = (disasm_cur_inst>>6) & 1; + addr = 0xffff80 + (dsp->disasm_cur_inst & BITMASK(6)); + retour = dis_calc_ea(dsp, (dsp->disasm_cur_inst>>8) & BITMASK(6), name); + easpace = (dsp->disasm_cur_inst>>6) & 1; - if (disasm_cur_inst & (1<<15)) { + if (dsp->disasm_cur_inst & (1<<15)) { /* Write pp */ if (retour) { @@ -1690,43 +1471,43 @@ void dis_movep_x_low(void) { } } - sprintf(str_instr,"movep %s,%s", srcname, dstname); + sprintf(dsp->disasm_str_instr,"movep %s,%s", srcname, dstname); } -void dis_move_x_aa(void) { +static void dis_move_x_aa(dsp_core_t* dsp) { // 0000001aaaaaaRRR1a0WDDDD - int W = (disasm_cur_inst >> 4) & 1; - int a = (((disasm_cur_inst >> 11) & BITMASK(6)) << 1) - + ((disasm_cur_inst >> 6) & 1); + int W = (dsp->disasm_cur_inst >> 4) & 1; + int a = (((dsp->disasm_cur_inst >> 11) & BITMASK(6)) << 1) + + ((dsp->disasm_cur_inst >> 6) & 1); if (W) { - sprintf(str_instr, "move x:(?? + %d), ??", a); + sprintf(dsp->disasm_str_instr, "move x:(?? + %d), ??", a); } else { - sprintf(str_instr, "move ??, x:(?? + %d)", a); + sprintf(dsp->disasm_str_instr, "move ??, x:(?? + %d)", a); } } -void dis_norm(void) +static void dis_norm(dsp_core_t* dsp) { uint32_t srcreg, destreg; - srcreg = DSP_REG_R0+((disasm_cur_inst>>8) & BITMASK(3)); - destreg = DSP_REG_A+((disasm_cur_inst>>3) & 1); + srcreg = DSP_REG_R0+((dsp->disasm_cur_inst>>8) & BITMASK(3)); + destreg = DSP_REG_A+((dsp->disasm_cur_inst>>3) & 1); - sprintf(str_instr,"norm %s,%s", registers_name[srcreg], registers_name[destreg]); + sprintf(dsp->disasm_str_instr,"norm %s,%s", registers_name[srcreg], registers_name[destreg]); } -void dis_ori(void) +static void dis_ori(dsp_core_t* dsp) { - switch(disasm_cur_inst & BITMASK(2)) { + switch(dsp->disasm_cur_inst & BITMASK(2)) { case 0: - sprintf(str_instr,"ori #$%02x,mr", (disasm_cur_inst>>8) & BITMASK(8)); + sprintf(dsp->disasm_str_instr,"ori #$%02x,mr", (dsp->disasm_cur_inst>>8) & BITMASK(8)); break; case 1: - sprintf(str_instr,"ori #$%02x,ccr", (disasm_cur_inst>>8) & BITMASK(8)); + sprintf(dsp->disasm_str_instr,"ori #$%02x,ccr", (dsp->disasm_cur_inst>>8) & BITMASK(8)); break; case 2: - sprintf(str_instr,"ori #$%02x,omr", (disasm_cur_inst>>8) & BITMASK(8)); + sprintf(dsp->disasm_str_instr,"ori #$%02x,omr", (dsp->disasm_cur_inst>>8) & BITMASK(8)); break; default: break; @@ -1734,67 +1515,67 @@ void dis_ori(void) } -void dis_rep_aa(void) +static void dis_rep_aa(dsp_core_t* dsp) { char name[16]; /* x:aa */ /* y:aa */ - if (disasm_cur_inst & (1<<6)) { - sprintf(name, "y:$%04x",(disasm_cur_inst>>8) & BITMASK(6)); + if (dsp->disasm_cur_inst & (1<<6)) { + sprintf(name, "y:$%04x",(dsp->disasm_cur_inst>>8) & BITMASK(6)); } else { - sprintf(name, "x:$%04x",(disasm_cur_inst>>8) & BITMASK(6)); + sprintf(name, "x:$%04x",(dsp->disasm_cur_inst>>8) & BITMASK(6)); } - sprintf(str_instr,"rep %s", name); + sprintf(dsp->disasm_str_instr,"rep %s", name); } -void dis_rep_imm(void) +static void dis_rep_imm(dsp_core_t* dsp) { /* #xxx */ - sprintf(str_instr,"rep #$%02x", ((disasm_cur_inst>>8) & BITMASK(8)) - + ((disasm_cur_inst & BITMASK(4))<<8)); + sprintf(dsp->disasm_str_instr,"rep #$%02x", ((dsp->disasm_cur_inst>>8) & BITMASK(8)) + + ((dsp->disasm_cur_inst & BITMASK(4))<<8)); } -void dis_rep_ea(void) +static void dis_rep_ea(dsp_core_t* dsp) { char name[16],addr_name[16]; /* x:ea */ /* y:ea */ - dis_calc_ea((disasm_cur_inst>>8) & BITMASK(6), addr_name); - if (disasm_cur_inst & (1<<6)) { + dis_calc_ea(dsp, (dsp->disasm_cur_inst>>8) & BITMASK(6), addr_name); + if (dsp->disasm_cur_inst & (1<<6)) { sprintf(name, "y:%s",addr_name); } else { sprintf(name, "x:%s",addr_name); } - sprintf(str_instr,"rep %s", name); + sprintf(dsp->disasm_str_instr,"rep %s", name); } -void dis_rep_reg(void) +static void dis_rep_reg(dsp_core_t* dsp) { /* R */ - sprintf(str_instr,"rep %s", registers_name[(disasm_cur_inst>>8) & BITMASK(6)]); + sprintf(dsp->disasm_str_instr,"rep %s", registers_name[(dsp->disasm_cur_inst>>8) & BITMASK(6)]); } -void dis_tcc(void) +static void dis_tcc(dsp_core_t* dsp) { char ccname[16]; uint32_t src1reg, dst1reg, src2reg, dst2reg; - dis_calc_cc((disasm_cur_inst>>12) & BITMASK(4), ccname); - src1reg = registers_tcc[(disasm_cur_inst>>3) & BITMASK(4)][0]; - dst1reg = registers_tcc[(disasm_cur_inst>>3) & BITMASK(4)][1]; + dis_calc_cc(dsp, (dsp->disasm_cur_inst>>12) & BITMASK(4), ccname); + src1reg = registers_tcc[(dsp->disasm_cur_inst>>3) & BITMASK(4)][0]; + dst1reg = registers_tcc[(dsp->disasm_cur_inst>>3) & BITMASK(4)][1]; - if (disasm_cur_inst & (1<<16)) { - src2reg = DSP_REG_R0+((disasm_cur_inst>>8) & BITMASK(3)); - dst2reg = DSP_REG_R0+(disasm_cur_inst & BITMASK(3)); + if (dsp->disasm_cur_inst & (1<<16)) { + src2reg = DSP_REG_R0+((dsp->disasm_cur_inst>>8) & BITMASK(3)); + dst2reg = DSP_REG_R0+(dsp->disasm_cur_inst & BITMASK(3)); - sprintf(str_instr,"t%s %s,%s %s,%s", + sprintf(dsp->disasm_str_instr,"t%s %s,%s %s,%s", ccname, registers_name[src1reg], registers_name[dst1reg], @@ -1802,7 +1583,7 @@ void dis_tcc(void) registers_name[dst2reg] ); } else { - sprintf(str_instr,"t%s %s,%s", + sprintf(dsp->disasm_str_instr,"t%s %s,%s", ccname, registers_name[src1reg], registers_name[dst1reg] @@ -1815,15 +1596,13 @@ void dis_tcc(void) * Parallel moves **********************************/ -void dis_pm(void) +static void dis_pm(dsp_core_t* dsp) { - uint32_t value; - - value = (disasm_cur_inst >> 20) & BITMASK(4); - opcodes_parmove[value](); + uint32_t value = (dsp->disasm_cur_inst >> 20) & BITMASK(4); + disasm_opcodes_parmove[value](dsp); } -void dis_pm_0(void) +static void dis_pm_0(dsp_core_t* dsp) { char space_name[16], addr_name[16]; uint32_t memspace, numreg1, numreg2; @@ -1831,9 +1610,9 @@ void dis_pm_0(void) 0000 100d 00mm mrrr S,x:ea x0,D 0000 100d 10mm mrrr S,y:ea y0,D */ - memspace = (disasm_cur_inst>>15) & 1; - numreg1 = DSP_REG_A+((disasm_cur_inst>>16) & 1); - dis_calc_ea((disasm_cur_inst>>8) & BITMASK(6), addr_name); + memspace = (dsp->disasm_cur_inst>>15) & 1; + numreg1 = DSP_REG_A+((dsp->disasm_cur_inst>>16) & 1); + dis_calc_ea(dsp, (dsp->disasm_cur_inst>>8) & BITMASK(6), addr_name); if (memspace) { strcpy(space_name,"y"); @@ -1843,7 +1622,7 @@ void dis_pm_0(void) numreg2 = DSP_REG_X0; } - sprintf(parallelmove_name, + sprintf(dsp->disasm_parallelmove_name, "%s,%s:%s %s,%s", registers_name[numreg1], space_name, @@ -1853,7 +1632,7 @@ void dis_pm_0(void) ); } -void dis_pm_1(void) +static void dis_pm_1(dsp_core_t* dsp) { /* 0001 ffdf w0mm mrrr x:ea,D1 S2,D2 @@ -1867,34 +1646,34 @@ void dis_pm_1(void) char addr_name[16]; uint32_t memspace, write_flag, retour, s1reg, s2reg, d1reg, d2reg; - memspace = (disasm_cur_inst>>14) & 1; - write_flag = (disasm_cur_inst>>15) & 1; - retour = dis_calc_ea((disasm_cur_inst>>8) & BITMASK(6), addr_name); + memspace = (dsp->disasm_cur_inst>>14) & 1; + write_flag = (dsp->disasm_cur_inst>>15) & 1; + retour = dis_calc_ea(dsp, (dsp->disasm_cur_inst>>8) & BITMASK(6), addr_name); if (memspace==DSP_SPACE_Y) { s2reg = d2reg = DSP_REG_Y0; - switch((disasm_cur_inst>>16) & BITMASK(2)) { + switch((dsp->disasm_cur_inst>>16) & BITMASK(2)) { case 0: s2reg = d2reg = DSP_REG_Y0; break; case 1: s2reg = d2reg = DSP_REG_Y1; break; case 2: s2reg = d2reg = DSP_REG_A; break; case 3: s2reg = d2reg = DSP_REG_B; break; } - s1reg = DSP_REG_A+((disasm_cur_inst>>19) & 1); - d1reg = DSP_REG_X0+((disasm_cur_inst>>18) & 1); + s1reg = DSP_REG_A+((dsp->disasm_cur_inst>>19) & 1); + d1reg = DSP_REG_X0+((dsp->disasm_cur_inst>>18) & 1); if (write_flag) { /* Write D2 */ if (retour) { - sprintf(parallelmove_name,"%s,%s #%s,%s", + sprintf(dsp->disasm_parallelmove_name,"%s,%s #%s,%s", registers_name[s1reg], registers_name[d1reg], addr_name, registers_name[d2reg] ); } else { - sprintf(parallelmove_name,"%s,%s y:%s,%s", + sprintf(dsp->disasm_parallelmove_name,"%s,%s y:%s,%s", registers_name[s1reg], registers_name[d1reg], addr_name, @@ -1903,7 +1682,7 @@ void dis_pm_1(void) } } else { /* Read S2 */ - sprintf(parallelmove_name,"%s,%s %s,y:%s", + sprintf(dsp->disasm_parallelmove_name,"%s,%s %s,y:%s", registers_name[s1reg], registers_name[d1reg], registers_name[s2reg], @@ -1913,28 +1692,28 @@ void dis_pm_1(void) } else { s1reg = d1reg = DSP_REG_X0; - switch((disasm_cur_inst>>18) & BITMASK(2)) { + switch((dsp->disasm_cur_inst>>18) & BITMASK(2)) { case 0: s1reg = d1reg = DSP_REG_X0; break; case 1: s1reg = d1reg = DSP_REG_X1; break; case 2: s1reg = d1reg = DSP_REG_A; break; case 3: s1reg = d1reg = DSP_REG_B; break; } - s2reg = DSP_REG_A+((disasm_cur_inst>>17) & 1); - d2reg = DSP_REG_Y0+((disasm_cur_inst>>16) & 1); + s2reg = DSP_REG_A+((dsp->disasm_cur_inst>>17) & 1); + d2reg = DSP_REG_Y0+((dsp->disasm_cur_inst>>16) & 1); if (write_flag) { /* Write D1 */ if (retour) { - sprintf(parallelmove_name,"#%s,%s %s,%s", + sprintf(dsp->disasm_parallelmove_name,"#%s,%s %s,%s", addr_name, registers_name[d1reg], registers_name[s2reg], registers_name[d2reg] ); } else { - sprintf(parallelmove_name,"x:%s,%s %s,%s", + sprintf(dsp->disasm_parallelmove_name,"x:%s,%s %s,%s", addr_name, registers_name[d1reg], registers_name[s2reg], @@ -1943,7 +1722,7 @@ void dis_pm_1(void) } } else { /* Read S1 */ - sprintf(parallelmove_name,"%s,x:%s %s,%s", + sprintf(dsp->disasm_parallelmove_name,"%s,x:%s %s,%s", registers_name[s1reg], addr_name, registers_name[s2reg], @@ -1954,7 +1733,7 @@ void dis_pm_1(void) } } -void dis_pm_2(void) +static void dis_pm_2(dsp_core_t* dsp) { char addr_name[16]; uint32_t numreg1, numreg2; @@ -1964,28 +1743,28 @@ void dis_pm_2(void) 0010 00ee eeed dddd S,D 001d dddd iiii iiii #xx,D */ - if (((disasm_cur_inst >> 8) & 0xffff) == 0x2000) { + if (((dsp->disasm_cur_inst >> 8) & 0xffff) == 0x2000) { return; } - if (((disasm_cur_inst >> 8) & 0xffe0) == 0x2040) { - dis_calc_ea((disasm_cur_inst>>8) & BITMASK(5), addr_name); - sprintf(parallelmove_name, "%s,r%d",addr_name, (disasm_cur_inst>>8) & BITMASK(3)); + if (((dsp->disasm_cur_inst >> 8) & 0xffe0) == 0x2040) { + dis_calc_ea(dsp, (dsp->disasm_cur_inst>>8) & BITMASK(5), addr_name); + sprintf(dsp->disasm_parallelmove_name, "%s,r%d",addr_name, (dsp->disasm_cur_inst>>8) & BITMASK(3)); return; } - if (((disasm_cur_inst >> 8) & 0xfc00) == 0x2000) { - numreg1 = (disasm_cur_inst>>13) & BITMASK(5); - numreg2 = (disasm_cur_inst>>8) & BITMASK(5); - sprintf(parallelmove_name, "%s,%s", registers_name[numreg1], registers_name[numreg2]); + if (((dsp->disasm_cur_inst >> 8) & 0xfc00) == 0x2000) { + numreg1 = (dsp->disasm_cur_inst>>13) & BITMASK(5); + numreg2 = (dsp->disasm_cur_inst>>8) & BITMASK(5); + sprintf(dsp->disasm_parallelmove_name, "%s,%s", registers_name[numreg1], registers_name[numreg2]); return; } - numreg1 = (disasm_cur_inst>>16) & BITMASK(5); - sprintf(parallelmove_name, "#$%02x,%s", (disasm_cur_inst >> 8) & BITMASK(8), registers_name[numreg1]); + numreg1 = (dsp->disasm_cur_inst>>16) & BITMASK(5); + sprintf(dsp->disasm_parallelmove_name, "#$%02x,%s", (dsp->disasm_cur_inst >> 8) & BITMASK(8), registers_name[numreg1]); } -void dis_pm_4(void) +static void dis_pm_4(dsp_core_t* dsp) { char addr_name[16]; uint32_t value, retour, ea_mode, memspace; @@ -2005,42 +1784,42 @@ void dis_pm_4(void) S,y:ea #xxxxxx,D */ - value = (disasm_cur_inst>>16) & BITMASK(3); - value |= (disasm_cur_inst>>17) & (BITMASK(2)<<3); + value = (dsp->disasm_cur_inst>>16) & BITMASK(3); + value |= (dsp->disasm_cur_inst>>17) & (BITMASK(2)<<3); - ea_mode = (disasm_cur_inst>>8) & BITMASK(6); + ea_mode = (dsp->disasm_cur_inst>>8) & BITMASK(6); if ((value>>2)==0) { /* L: memory move */ - if (disasm_cur_inst & (1<<14)) { - retour = dis_calc_ea(ea_mode, addr_name); + if (dsp->disasm_cur_inst & (1<<14)) { + retour = dis_calc_ea(dsp, ea_mode, addr_name); } else { sprintf(addr_name,"$%04x", ea_mode); retour = 0; } - value = (disasm_cur_inst>>16) & BITMASK(2); - value |= (disasm_cur_inst>>17) & (1<<2); + value = (dsp->disasm_cur_inst>>16) & BITMASK(2); + value |= (dsp->disasm_cur_inst>>17) & (1<<2); - if (disasm_cur_inst & (1<<15)) { + if (dsp->disasm_cur_inst & (1<<15)) { /* Write D */ if (retour) { - sprintf(parallelmove_name, "#%s,%s", addr_name, registers_lmove[value]); + sprintf(dsp->disasm_parallelmove_name, "#%s,%s", addr_name, registers_lmove[value]); } else { - sprintf(parallelmove_name, "l:%s,%s", addr_name, registers_lmove[value]); + sprintf(dsp->disasm_parallelmove_name, "l:%s,%s", addr_name, registers_lmove[value]); } } else { /* Read S */ - sprintf(parallelmove_name, "%s,l:%s", registers_lmove[value], addr_name); + sprintf(dsp->disasm_parallelmove_name, "%s,l:%s", registers_lmove[value], addr_name); } return; } - memspace = (disasm_cur_inst>>19) & 1; - if (disasm_cur_inst & (1<<14)) { - retour = dis_calc_ea(ea_mode, addr_name); + memspace = (dsp->disasm_cur_inst>>19) & 1; + if (dsp->disasm_cur_inst & (1<<14)) { + retour = dis_calc_ea(dsp, ea_mode, addr_name); } else { sprintf(addr_name,"$%04x", ea_mode); retour = 0; @@ -2049,38 +1828,38 @@ void dis_pm_4(void) if (memspace) { /* Y: */ - if (disasm_cur_inst & (1<<15)) { + if (dsp->disasm_cur_inst & (1<<15)) { /* Write D */ if (retour) { - sprintf(parallelmove_name, "#%s,%s", addr_name, registers_name[value]); + sprintf(dsp->disasm_parallelmove_name, "#%s,%s", addr_name, registers_name[value]); } else { - sprintf(parallelmove_name, "y:%s,%s", addr_name, registers_name[value]); + sprintf(dsp->disasm_parallelmove_name, "y:%s,%s", addr_name, registers_name[value]); } } else { /* Read S */ - sprintf(parallelmove_name, "%s,y:%s", registers_name[value], addr_name); + sprintf(dsp->disasm_parallelmove_name, "%s,y:%s", registers_name[value], addr_name); } } else { /* X: */ - if (disasm_cur_inst & (1<<15)) { + if (dsp->disasm_cur_inst & (1<<15)) { /* Write D */ if (retour) { - sprintf(parallelmove_name, "#%s,%s", addr_name, registers_name[value]); + sprintf(dsp->disasm_parallelmove_name, "#%s,%s", addr_name, registers_name[value]); } else { - sprintf(parallelmove_name, "x:%s,%s", addr_name, registers_name[value]); + sprintf(dsp->disasm_parallelmove_name, "x:%s,%s", addr_name, registers_name[value]); } } else { /* Read S */ - sprintf(parallelmove_name, "%s,x:%s", registers_name[value], addr_name); + sprintf(dsp->disasm_parallelmove_name, "%s,x:%s", registers_name[value], addr_name); } } } -void dis_pm_8(void) +static void dis_pm_8(dsp_core_t* dsp) { char addr1_name[16], addr2_name[16]; uint32_t ea_mode1, ea_mode2, numreg1, numreg2; @@ -2091,7 +1870,7 @@ void dis_pm_8(void) S1,x:ea S2,y:ea */ numreg1 = DSP_REG_X0; - switch((disasm_cur_inst>>18) & BITMASK(2)) { + switch((dsp->disasm_cur_inst>>18) & BITMASK(2)) { case 0: numreg1 = DSP_REG_X0; break; case 1: numreg1 = DSP_REG_X1; break; case 2: numreg1 = DSP_REG_A; break; @@ -2099,19 +1878,19 @@ void dis_pm_8(void) } numreg2 = DSP_REG_Y0; - switch((disasm_cur_inst>>16) & BITMASK(2)) { + switch((dsp->disasm_cur_inst>>16) & BITMASK(2)) { case 0: numreg2 = DSP_REG_Y0; break; case 1: numreg2 = DSP_REG_Y1; break; case 2: numreg2 = DSP_REG_A; break; case 3: numreg2 = DSP_REG_B; break; } - ea_mode1 = (disasm_cur_inst>>8) & BITMASK(5); + ea_mode1 = (dsp->disasm_cur_inst>>8) & BITMASK(5); if ((ea_mode1>>3) == 0) { ea_mode1 |= (1<<5); } - ea_mode2 = (disasm_cur_inst>>13) & BITMASK(2); - ea_mode2 |= ((disasm_cur_inst>>20) & BITMASK(2))<<3; + ea_mode2 = (dsp->disasm_cur_inst>>13) & BITMASK(2); + ea_mode2 |= ((dsp->disasm_cur_inst>>20) & BITMASK(2))<<3; if ((ea_mode1 & (1<<2))==0) { ea_mode2 |= 1<<2; } @@ -2119,19 +1898,19 @@ void dis_pm_8(void) ea_mode2 |= (1<<5); } - dis_calc_ea(ea_mode1, addr1_name); - dis_calc_ea(ea_mode2, addr2_name); + dis_calc_ea(dsp, ea_mode1, addr1_name); + dis_calc_ea(dsp, ea_mode2, addr2_name); - if (disasm_cur_inst & (1<<15)) { - if (disasm_cur_inst & (1<<22)) { - sprintf(parallelmove_name, "x:%s,%s y:%s,%s", + if (dsp->disasm_cur_inst & (1<<15)) { + if (dsp->disasm_cur_inst & (1<<22)) { + sprintf(dsp->disasm_parallelmove_name, "x:%s,%s y:%s,%s", addr1_name, registers_name[numreg1], addr2_name, registers_name[numreg2] ); } else { - sprintf(parallelmove_name, "x:%s,%s %s,y:%s", + sprintf(dsp->disasm_parallelmove_name, "x:%s,%s %s,y:%s", addr1_name, registers_name[numreg1], registers_name[numreg2], @@ -2139,15 +1918,15 @@ void dis_pm_8(void) ); } } else { - if (disasm_cur_inst & (1<<22)) { - sprintf(parallelmove_name, "%s,x:%s y:%s,%s", + if (dsp->disasm_cur_inst & (1<<22)) { + sprintf(dsp->disasm_parallelmove_name, "%s,x:%s y:%s,%s", registers_name[numreg1], addr1_name, addr2_name, registers_name[numreg2] ); } else { - sprintf(parallelmove_name, "%s,x:%s %s,y:%s", + sprintf(dsp->disasm_parallelmove_name, "%s,x:%s %s,y:%s", registers_name[numreg1], addr1_name, registers_name[numreg2], diff --git a/hw/xbox/dsp/dsp_disasm.h b/hw/xbox/dsp/dsp_disasm.h deleted file mode 100644 index 0edcbeae3f..0000000000 --- a/hw/xbox/dsp/dsp_disasm.h +++ /dev/null @@ -1,145 +0,0 @@ -/* - DSP56300 Disassembler - - Copyright (c) 2015 espes - - Adapted from Hatari DSP M56001 Disassembler - (C) 2003-2008 ARAnyM developer team - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef DSP_DISASM_H -#define DSP_DISASM_H - -#include -#include - -extern uint32_t prev_inst_pc; -extern bool isLooping; - -/* Used to display dc instead of unknown instruction for illegal opcodes */ -extern bool isInDisasmMode; - -extern uint32_t disasm_cur_inst; -extern uint16_t disasm_cur_inst_len; -extern char str_instr[50]; -extern char parallelmove_name[64]; - - -/* Functions */ -const char* dsp56k_get_instruction_text(void); - -/* Registers change */ -void dsp56k_disasm_reg_save(void); -void dsp56k_disasm_reg_compare(void); - - -typedef void (*dis_func_t)(void); - -void dis_undefined(void); - -/* Instructions without parallel moves */ -void dis_add_long(void); -void dis_andi(void); -void dis_bcc_long(void); -void dis_bcc_imm(void); -void dis_bchg_aa(void); -void dis_bchg_ea(void); -void dis_bchg_pp(void); -void dis_bchg_reg(void); -void dis_bclr_aa(void); -void dis_bclr_ea(void); -void dis_bclr_pp(void); -void dis_bclr_reg(void); -void dis_bra_imm(void); -void dis_bset_aa(void); -void dis_bset_ea(void); -void dis_bset_pp(void); -void dis_bset_reg(void); -void dis_btst_aa(void); -void dis_btst_ea(void); -void dis_btst_pp(void); -void dis_btst_reg(void); -void dis_cmpu(void); -void dis_div(void); -void dis_enddo(void); -void dis_illegal(void); -void dis_jcc_imm(void); -void dis_jcc_ea(void); -void dis_jclr_aa(void); -void dis_jclr_ea(void); -void dis_jclr_pp(void); -void dis_jclr_reg(void); -void dis_jmp_ea(void); -void dis_jmp_imm(void); -void dis_jscc_ea(void); -void dis_jscc_imm(void); -void dis_jsclr_aa(void); -void dis_jsclr_ea(void); -void dis_jsclr_pp(void); -void dis_jsclr_reg(void); -void dis_jset_aa(void); -void dis_jset_ea(void); -void dis_jset_pp(void); -void dis_jset_reg(void); -void dis_jsr_ea(void); -void dis_jsr_imm(void); -void dis_jsset_aa(void); -void dis_jsset_ea(void); -void dis_jsset_pp(void); -void dis_jsset_reg(void); -void dis_lua(void); -void dis_movem_ea(void); -void dis_movem_aa(void); -void dis_norm(void); -void dis_ori(void); -void dis_reset(void); -void dis_rti(void); -void dis_rts(void); -void dis_stop(void); -void dis_swi(void); -void dis_tcc(void); -void dis_wait(void); -void dis_do_ea(void); -void dis_do_aa(void); -void dis_do_imm(void); -void dis_do_reg(void); -void dis_dor_imm(void); -void dis_rep_aa(void); -void dis_rep_ea(void); -void dis_rep_imm(void); -void dis_rep_reg(void); -void dis_movec_aa(void); -void dis_movec_ea(void); -void dis_movec_imm(void); -void dis_movec_reg(void); -void dis_movep_0(void); -void dis_movep_1(void); -void dis_movep_23(void); - -void dis_movep_x_low(void); -void dis_move_x_aa(void); - -/* Parallel moves */ -void dis_pm_class2(void); -void dis_pm(void); -void dis_pm_0(void); -void dis_pm_1(void); -void dis_pm_2(void); -void dis_pm_4(void); -void dis_pm_8(void); - -#endif /* DSP_DISASM_H */ diff --git a/hw/xbox/dsp/dsp_emu.inl b/hw/xbox/dsp/dsp_emu.inl new file mode 100644 index 0000000000..5f4504858c --- /dev/null +++ b/hw/xbox/dsp/dsp_emu.inl @@ -0,0 +1,7374 @@ + +typedef void (*emu_func_t)(dsp_core_t* dsp); + + +static void emu_undefined(dsp_core_t* dsp) +{ + if (!dsp->in_disasm_mode) { + dsp->cur_inst_len = 0; + fprintf(stderr, "Dsp: 0x%04x: 0x%06x Illegal instruction\n",dsp->pc, dsp->cur_inst); + /* Add some artificial CPU cycles to avoid being stuck in an infinite loop */ + dsp->instr_cycle += 100; + } else { + dsp->cur_inst_len = 1; + dsp->instr_cycle = 0; + } + if (dsp->exception_debugging) { + assert(false); + } +} + + +/********************************** + * Effective address calculation + **********************************/ + + +static void emu_update_rn_bitreverse(dsp_core_t* dsp, uint32_t numreg) +{ + int revbits, i; + uint32_t value, r_reg; + + /* Check how many bits to reverse */ + value = dsp->registers[DSP_REG_N0+numreg]; + for (revbits=0;revbits<16;revbits++) { + if (value & (1<registers[DSP_REG_R0+numreg]; + value = r_reg & (BITMASK(16)-BITMASK(revbits)); + for (i=0;iregisters[DSP_REG_R0+numreg] = value; +} + +static void emu_update_rn_modulo(dsp_core_t* dsp, uint32_t numreg, int16_t modifier) +{ + uint16_t bufsize, modulo, lobound, hibound, bufmask; + int16_t r_reg, orig_modifier=modifier; + + modulo = dsp->registers[DSP_REG_M0+numreg]+1; + bufsize = 1; + bufmask = BITMASK(16); + while (bufsize < modulo) { + bufsize <<= 1; + bufmask <<= 1; + } + + lobound = dsp->registers[DSP_REG_R0+numreg] & bufmask; + hibound = lobound + modulo - 1; + + r_reg = (int16_t) dsp->registers[DSP_REG_R0+numreg]; + + if (orig_modifier>modulo) { + while (modifier>bufsize) { + r_reg += bufsize; + modifier -= bufsize; + } + while (modifier<-bufsize) { + r_reg -= bufsize; + modifier += bufsize; + } + } + + r_reg += modifier; + + if (orig_modifier!=modulo) { + if (r_reg>hibound) { + r_reg -= modulo; + } else if (r_regregisters[DSP_REG_R0+numreg] = ((uint32_t) r_reg) & BITMASK(16); +} + +static void emu_update_rn(dsp_core_t* dsp, uint32_t numreg, int16_t modifier) +{ + int16_t value; + uint16_t m_reg; + + m_reg = (uint16_t) dsp->registers[DSP_REG_M0+numreg]; + if (m_reg == 65535) { + /* Linear addressing mode */ + value = (int16_t) dsp->registers[DSP_REG_R0+numreg]; + value += modifier; + dsp->registers[DSP_REG_R0+numreg] = ((uint32_t) value) & BITMASK(16); + } else if (m_reg == 0) { + /* Bit reversed carry update */ + emu_update_rn_bitreverse(dsp, numreg); + } else if (m_reg<=32767) { + /* Modulo update */ + emu_update_rn_modulo(dsp, numreg, modifier); + } else { + /* Undefined */ + } +} + +static int emu_calc_ea(dsp_core_t* dsp, uint32_t ea_mode, uint32_t *dst_addr) +{ + uint32_t value, numreg, curreg; + + value = (ea_mode >> 3) & BITMASK(3); + numreg = ea_mode & BITMASK(3); + switch (value) { + case 0: + /* (Rx)-Nx */ + *dst_addr = dsp->registers[DSP_REG_R0+numreg]; + emu_update_rn(dsp, numreg, -dsp->registers[DSP_REG_N0+numreg]); + break; + case 1: + /* (Rx)+Nx */ + *dst_addr = dsp->registers[DSP_REG_R0+numreg]; + emu_update_rn(dsp, numreg, dsp->registers[DSP_REG_N0+numreg]); + break; + case 2: + /* (Rx)- */ + *dst_addr = dsp->registers[DSP_REG_R0+numreg]; + emu_update_rn(dsp, numreg, -1); + break; + case 3: + /* (Rx)+ */ + *dst_addr = dsp->registers[DSP_REG_R0+numreg]; + emu_update_rn(dsp, numreg, +1); + break; + case 4: + /* (Rx) */ + *dst_addr = dsp->registers[DSP_REG_R0+numreg]; + break; + case 5: + /* (Rx+Nx) */ + dsp->instr_cycle += 2; + curreg = dsp->registers[DSP_REG_R0+numreg]; + emu_update_rn(dsp, numreg, dsp->registers[DSP_REG_N0+numreg]); + *dst_addr = dsp->registers[DSP_REG_R0+numreg]; + dsp->registers[DSP_REG_R0+numreg] = curreg; + break; + case 6: + /* aa */ + dsp->instr_cycle += 2; + *dst_addr = read_memory_p(dsp, dsp->pc+1); + dsp->cur_inst_len++; + if (numreg != 0) { + return 1; /* immediate value */ + } + break; + case 7: + /* -(Rx) */ + dsp->instr_cycle += 2; + emu_update_rn(dsp, numreg, -1); + *dst_addr = dsp->registers[DSP_REG_R0+numreg]; + break; + } + /* address */ + return 0; +} + +/********************************** + * Condition code test + **********************************/ + +static int emu_calc_cc(dsp_core_t* dsp, uint32_t cc_code) +{ + uint16_t value1, value2, value3; + + switch (cc_code) { + case 0: /* CC (HS) */ + value1 = dsp->registers[DSP_REG_SR] & (1<registers[DSP_REG_SR] >> DSP_SR_N) & 1; + value2 = (dsp->registers[DSP_REG_SR] >> DSP_SR_V) & 1; + return ((value1 ^ value2) == 0); + case 2: /* NE */ + value1 = dsp->registers[DSP_REG_SR] & (1<registers[DSP_REG_SR] & (1<registers[DSP_REG_SR] >> DSP_SR_Z) & 1; + value2 = (~(dsp->registers[DSP_REG_SR] >> DSP_SR_U)) & 1; + value3 = (~(dsp->registers[DSP_REG_SR] >> DSP_SR_E)) & 1; + return ((value1 | (value2 & value3)) == 0); + case 5: /* EC */ + value1 = dsp->registers[DSP_REG_SR] & (1<registers[DSP_REG_SR] & (1<registers[DSP_REG_SR] >> DSP_SR_N) & 1; + value2 = (dsp->registers[DSP_REG_SR] >> DSP_SR_V) & 1; + value3 = (dsp->registers[DSP_REG_SR] >> DSP_SR_Z) & 1; + return ((value3 | (value1 ^ value2)) == 0); + case 8: /* CS (LO) */ + value1 = dsp->registers[DSP_REG_SR] & (1<registers[DSP_REG_SR] >> DSP_SR_N) & 1; + value2 = (dsp->registers[DSP_REG_SR] >> DSP_SR_V) & 1; + return ((value1 ^ value2) == 1); + case 10: /* EQ */ + value1 = (dsp->registers[DSP_REG_SR] >> DSP_SR_Z) & 1; + return (value1==1); + case 11: /* MI */ + value1 = (dsp->registers[DSP_REG_SR] >> DSP_SR_N) & 1; + return (value1==1); + case 12: /* NR */ + value1 = (dsp->registers[DSP_REG_SR] >> DSP_SR_Z) & 1; + value2 = (~(dsp->registers[DSP_REG_SR] >> DSP_SR_U)) & 1; + value3 = (~(dsp->registers[DSP_REG_SR] >> DSP_SR_E)) & 1; + return ((value1 | (value2 & value3)) == 1); + case 13: /* ES */ + value1 = (dsp->registers[DSP_REG_SR] >> DSP_SR_E) & 1; + return (value1==1); + case 14: /* LS */ + value1 = (dsp->registers[DSP_REG_SR] >> DSP_SR_L) & 1; + return (value1==1); + case 15: /* LE */ + value1 = (dsp->registers[DSP_REG_SR] >> DSP_SR_N) & 1; + value2 = (dsp->registers[DSP_REG_SR] >> DSP_SR_V) & 1; + value3 = (dsp->registers[DSP_REG_SR] >> DSP_SR_Z) & 1; + return ((value3 | (value1 ^ value2)) == 1); + } + return 0; +} + +/********************************** + * Set/clear ccr bits + **********************************/ + +/* reg0 has bits 55..48 */ +/* reg1 has bits 47..24 */ +/* reg2 has bits 23..0 */ + +static void emu_ccr_update_e_u_n_z(dsp_core_t* dsp, uint32_t reg0, uint32_t reg1, uint32_t reg2) +{ + uint32_t scaling, value_e, value_u; + + /* Initialize SR register */ + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); + switch(scaling) { + case 0: + /* Extension Bit (E) */ + value_e = (reg0<<1) + (reg1>>23); + if ((value_e != 0) && (value_e != BITMASK(9))) + dsp->registers[DSP_REG_SR] |= 1 << DSP_SR_E; + + /* Unnormalized bit (U) */ + if ((reg1 & 0xc00000) == 0 || (reg1 & 0xc00000) == 0xc00000) + dsp->registers[DSP_REG_SR] |= 1 << DSP_SR_U; + break; + case 1: + /* Extension Bit (E) */ + if ((reg0 != 0) && (reg0 != BITMASK(8))) + dsp->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->registers[DSP_REG_SR] |= 1 << DSP_SR_U; + break; + case 2: + /* Extension Bit (E) */ + value_e = (reg0<<2) + (reg1>>22); + if ((value_e != 0) && (value_e != BITMASK(10))) + dsp->registers[DSP_REG_SR] |= 1 << DSP_SR_E; + + /* Unnormalized bit (U) */ + if ((reg1 & 0x600000) == 0 || (reg1 & 0x600000) == 0x600000) + dsp->registers[DSP_REG_SR] |= 1 << DSP_SR_U; + break; + default: + return; + break; + } + + /* Zero Flag (Z) */ + if ((reg1 == 0) && (reg2 == 0) && (reg0 == 0)) + dsp->registers[DSP_REG_SR] |= 1 << DSP_SR_Z; + + /* Negative Flag (N) */ + dsp->registers[DSP_REG_SR] |= (reg0>>4) & 0x8; +} + +/********************************** + * ALU instructions + **********************************/ + +static void emu_abs_a(dsp_core_t* dsp) +{ + uint32_t dest[3], overflowed; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + + overflowed = ((dest[2]==0) && (dest[1]==0) && (dest[0]==0x80)); + + dsp_abs56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= (overflowed<registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + overflowed = ((dest[2]==0) && (dest[1]==0) && (dest[0]==0x80)); + + dsp_abs56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= (overflowed<registers[DSP_REG_SR]>>DSP_SR_C) & 1; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + + source[2] = dsp->registers[DSP_REG_X0]; + source[1] = dsp->registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_add56(dsp, source, dest); + } + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_adc_x_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3], curcarry; + uint16_t newsr; + + curcarry = (dsp->registers[DSP_REG_SR]>>DSP_SR_C) & 1; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + source[2] = dsp->registers[DSP_REG_X0]; + source[1] = dsp->registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_add56(dsp, source, dest); + } + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_adc_y_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3], curcarry; + uint16_t newsr; + + curcarry = (dsp->registers[DSP_REG_SR]>>DSP_SR_C) & 1; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + + source[2] = dsp->registers[DSP_REG_Y0]; + source[1] = dsp->registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_add56(dsp, source, dest); + } + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_adc_y_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3], curcarry; + uint16_t newsr; + + curcarry = (dsp->registers[DSP_REG_SR]>>DSP_SR_C) & 1; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + source[2] = dsp->registers[DSP_REG_Y0]; + source[1] = dsp->registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_add56(dsp, source, dest); + } + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_add_b_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + + source[0] = dsp->registers[DSP_REG_B2]; + source[1] = dsp->registers[DSP_REG_B1]; + source[2] = dsp->registers[DSP_REG_B0]; + + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_add_a_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + source[0] = dsp->registers[DSP_REG_A2]; + source[1] = dsp->registers[DSP_REG_A1]; + source[2] = dsp->registers[DSP_REG_A0]; + + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_add_x_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + + source[1] = dsp->registers[DSP_REG_X1]; + source[2] = dsp->registers[DSP_REG_X0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_add_x_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + source[1] = dsp->registers[DSP_REG_X1]; + source[2] = dsp->registers[DSP_REG_X0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_add_y_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + + source[1] = dsp->registers[DSP_REG_Y1]; + source[2] = dsp->registers[DSP_REG_Y0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_add_y_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + source[1] = dsp->registers[DSP_REG_Y1]; + source[2] = dsp->registers[DSP_REG_Y0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_add_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_add_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_add_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_add_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_add_x1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_add_x1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_add_y1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_add_y1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_addl_b_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_asl56(dsp, dest); + + source[0] = dsp->registers[DSP_REG_B2]; + source[1] = dsp->registers[DSP_REG_B1]; + source[2] = dsp->registers[DSP_REG_B0]; + newsr |= dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_addl_a_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_asl56(dsp, dest); + + source[0] = dsp->registers[DSP_REG_A2]; + source[1] = dsp->registers[DSP_REG_A1]; + source[2] = dsp->registers[DSP_REG_A0]; + newsr |= dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_addr_b_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_asr56(dsp, dest); + + source[0] = dsp->registers[DSP_REG_B2]; + source[1] = dsp->registers[DSP_REG_B1]; + source[2] = dsp->registers[DSP_REG_B0]; + newsr |= dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_addr_a_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_asr56(dsp, dest); + + source[0] = dsp->registers[DSP_REG_A2]; + source[1] = dsp->registers[DSP_REG_A1]; + source[2] = dsp->registers[DSP_REG_A0]; + newsr |= dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_and_x0_a(dsp_core_t* dsp) +{ + dsp->registers[DSP_REG_A1] &= dsp->registers[DSP_REG_X0]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_A1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1] &= dsp->registers[DSP_REG_X0]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_B1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_A1] &= dsp->registers[DSP_REG_Y0]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_A1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1] &= dsp->registers[DSP_REG_Y0]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_B1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_A1] &= dsp->registers[DSP_REG_X1]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_A1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1] &= dsp->registers[DSP_REG_X1]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_B1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_A1] &= dsp->registers[DSP_REG_Y1]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_A1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1] &= dsp->registers[DSP_REG_Y1]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_B1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + + newsr = dsp_asl56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); +} + +static void emu_asl_b(dsp_core_t* dsp) +{ + uint32_t dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + newsr = dsp_asl56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); +} + +static void emu_asr_a(dsp_core_t* dsp) +{ + uint32_t dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + + newsr = dsp_asr56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); +} + +static void emu_asr_b(dsp_core_t* dsp) +{ + uint32_t dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + newsr = dsp_asr56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); +} + +static void emu_clr_a(dsp_core_t* dsp) +{ + dsp->registers[DSP_REG_A2] = 0; + dsp->registers[DSP_REG_A1] = 0; + dsp->registers[DSP_REG_A0] = 0; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= (1<registers[DSP_REG_B2] = 0; + dsp->registers[DSP_REG_B1] = 0; + dsp->registers[DSP_REG_B0] = 0; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= (1<registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + + source[0] = dsp->registers[DSP_REG_B2]; + source[1] = dsp->registers[DSP_REG_B1]; + source[2] = dsp->registers[DSP_REG_B0]; + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmp_a_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + source[0] = dsp->registers[DSP_REG_A2]; + source[1] = dsp->registers[DSP_REG_A1]; + source[2] = dsp->registers[DSP_REG_A0]; + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmp_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmp_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmp_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmp_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} +static void emu_cmp_x1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmp_x1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmp_y1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmp_y1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmpm_b_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + dsp_abs56(dsp, dest); + + source[0] = dsp->registers[DSP_REG_B2]; + source[1] = dsp->registers[DSP_REG_B1]; + source[2] = dsp->registers[DSP_REG_B0]; + dsp_abs56(dsp, source); + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmpm_a_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + dsp_abs56(dsp, dest); + + source[0] = dsp->registers[DSP_REG_A2]; + source[1] = dsp->registers[DSP_REG_A1]; + source[2] = dsp->registers[DSP_REG_A0]; + dsp_abs56(dsp, source); + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmpm_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + dsp_abs56(dsp, dest); + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + dsp_abs56(dsp, source); + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmpm_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + dsp_abs56(dsp, dest); + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + dsp_abs56(dsp, source); + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmpm_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + dsp_abs56(dsp, dest); + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + dsp_abs56(dsp, source); + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmpm_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + dsp_abs56(dsp, dest); + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + dsp_abs56(dsp, source); + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmpm_x1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + dsp_abs56(dsp, dest); + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + dsp_abs56(dsp, source); + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmpm_x1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + dsp_abs56(dsp, dest); + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + dsp_abs56(dsp, source); + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmpm_y1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + dsp_abs56(dsp, dest); + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + dsp_abs56(dsp, source); + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_cmpm_y1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + dsp_abs56(dsp, dest); + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + dsp_abs56(dsp, source); + + newsr = dsp_sub56(dsp, source, dest); + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_eor_x0_a(dsp_core_t* dsp) +{ + dsp->registers[DSP_REG_A1] ^= dsp->registers[DSP_REG_X0]; + dsp->registers[DSP_REG_A1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_A1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1] ^= dsp->registers[DSP_REG_X0]; + dsp->registers[DSP_REG_B1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_B1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_A1] ^= dsp->registers[DSP_REG_Y0]; + dsp->registers[DSP_REG_A1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_A1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1] ^= dsp->registers[DSP_REG_Y0]; + dsp->registers[DSP_REG_B1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_B1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_A1] ^= dsp->registers[DSP_REG_X1]; + dsp->registers[DSP_REG_A1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_A1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1] ^= dsp->registers[DSP_REG_X1]; + dsp->registers[DSP_REG_B1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_B1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_A1] ^= dsp->registers[DSP_REG_Y1]; + dsp->registers[DSP_REG_A1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_A1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1] ^= dsp->registers[DSP_REG_Y1]; + dsp->registers[DSP_REG_B1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_B1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_A1]>>23) & 1; + + dsp->registers[DSP_REG_A1] <<= 1; + dsp->registers[DSP_REG_A1] &= BITMASK(24); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; + dsp->registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_A1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1]>>23) & 1; + + dsp->registers[DSP_REG_B1] <<= 1; + dsp->registers[DSP_REG_B1] &= BITMASK(24); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; + dsp->registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_B1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_A1] & 1; + dsp->registers[DSP_REG_A1] >>= 1; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; + dsp->registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1] & 1; + dsp->registers[DSP_REG_B1] >>= 1; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; + dsp->registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_x0_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} +static void emu_mac_p_x0_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_x0_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_p_y0_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_y0_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} +static void emu_mac_p_y0_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_y0_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_p_x1_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_x1_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_p_x1_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_x1_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_p_y1_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_y1_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_p_y1_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_y1_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_p_x0_y1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_x0_y1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_p_x0_y1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_x0_y1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_p_y0_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_y0_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_p_y0_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_y0_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_p_x1_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_x1_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_p_x1_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_x1_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_p_y1_x1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_y1_x1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_p_y1_x1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_mac_m_y1_x1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_p_x0_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_x0_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} +static void emu_macr_p_x0_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_x0_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_p_y0_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_y0_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} +static void emu_macr_p_y0_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_y0_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_p_x1_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_x1_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_p_x1_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_x1_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_p_y1_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_y1_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_p_y1_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_y1_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_p_x0_y1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_x0_y1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_p_x0_y1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_x0_y1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_p_y0_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_y0_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_p_y0_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_y0_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_p_x1_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_x1_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_p_x1_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dsp_rnd56(dsp, dest); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_x1_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_p_y1_x1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_y1_x1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_p_y1_x1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_PLUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + +static void emu_macr_m_y1_x1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dsp_mul56(dsp, dsp->registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_MINUS); + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_add56(dsp, source, dest); + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; +} + + +static void emu_move(dsp_core_t* dsp) +{ + /* move instruction inside alu opcodes + taken care of by parallel move dispatcher */ +} + +static void emu_mpy_p_x0_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3]; + + dsp_mul56(dsp, dsp->registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_PLUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_MINUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_PLUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_MINUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_PLUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_MINUS); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_PLUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_MINUS); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X0], dsp->registers[DSP_REG_Y1], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y0], dsp->registers[DSP_REG_X0], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_X1], dsp->registers[DSP_REG_Y0], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_A2] = source[0]; + dsp->registers[DSP_REG_A1] = source[1]; + dsp->registers[DSP_REG_A0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_PLUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_Y1], dsp->registers[DSP_REG_X1], source, SIGN_MINUS); + dsp_rnd56(dsp, source); + + dsp->registers[DSP_REG_B2] = source[0]; + dsp->registers[DSP_REG_B1] = source[1]; + dsp->registers[DSP_REG_B0] = source[2]; + + emu_ccr_update_e_u_n_z(dsp, source[0], source[1], source[2]); + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_A2]; + source[1] = dsp->registers[DSP_REG_A1]; + source[2] = dsp->registers[DSP_REG_A0]; + + overflowed = ((source[2]==0) && (source[1]==0) && (source[0]==0x80)); + + dest[0] = dest[1] = dest[2] = 0; + + dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= (overflowed<registers[DSP_REG_B2]; + source[1] = dsp->registers[DSP_REG_B1]; + source[2] = dsp->registers[DSP_REG_B0]; + + overflowed = ((source[2]==0) && (source[1]==0) && (source[0]==0x80)); + + dest[0] = dest[1] = dest[2] = 0; + + dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= (overflowed<registers[DSP_REG_A1] = ~dsp->registers[DSP_REG_A1]; + dsp->registers[DSP_REG_A1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_A1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1] = ~dsp->registers[DSP_REG_B1]; + dsp->registers[DSP_REG_B1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_B1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_A1] |= dsp->registers[DSP_REG_X0]; + dsp->registers[DSP_REG_A1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_A1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1] |= dsp->registers[DSP_REG_X0]; + dsp->registers[DSP_REG_B1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_B1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_A1] |= dsp->registers[DSP_REG_Y0]; + dsp->registers[DSP_REG_A1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_A1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1] |= dsp->registers[DSP_REG_Y0]; + dsp->registers[DSP_REG_B1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_B1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_A1] |= dsp->registers[DSP_REG_X1]; + dsp->registers[DSP_REG_A1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_A1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1] |= dsp->registers[DSP_REG_X1]; + dsp->registers[DSP_REG_B1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_B1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_A1] |= dsp->registers[DSP_REG_Y1]; + dsp->registers[DSP_REG_A1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_A1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1] |= dsp->registers[DSP_REG_Y1]; + dsp->registers[DSP_REG_B1] &= BITMASK(24); /* FIXME: useless ? */ + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_B1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); +} + +static void emu_rnd_b(dsp_core_t* dsp) +{ + uint32_t dest[3]; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + dsp_rnd56(dsp, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); +} + +static void emu_rol_a(dsp_core_t* dsp) +{ + uint32_t newcarry; + + newcarry = (dsp->registers[DSP_REG_A1]>>23) & 1; + + dsp->registers[DSP_REG_A1] <<= 1; + dsp->registers[DSP_REG_A1] |= newcarry; + dsp->registers[DSP_REG_A1] &= BITMASK(24); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; + dsp->registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_A1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1]>>23) & 1; + + dsp->registers[DSP_REG_B1] <<= 1; + dsp->registers[DSP_REG_B1] |= newcarry; + dsp->registers[DSP_REG_B1] &= BITMASK(24); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; + dsp->registers[DSP_REG_SR] |= ((dsp->registers[DSP_REG_B1]>>23) & 1)<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_A1] & 1; + + dsp->registers[DSP_REG_A1] >>= 1; + dsp->registers[DSP_REG_A1] |= newcarry<<23; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; + dsp->registers[DSP_REG_SR] |= newcarry<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_A1]==0)<registers[DSP_REG_B1] & 1; + + dsp->registers[DSP_REG_B1] >>= 1; + dsp->registers[DSP_REG_B1] |= newcarry<<23; + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; + dsp->registers[DSP_REG_SR] |= newcarry<registers[DSP_REG_SR] |= (dsp->registers[DSP_REG_B1]==0)<registers[DSP_REG_SR]>>(DSP_SR_C)) & 1; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + + source[2] = dsp->registers[DSP_REG_X0]; + source[1] = dsp->registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_sub56(dsp, source, dest); + } + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sbc_x_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3], curcarry; + uint16_t newsr; + + curcarry = (dsp->registers[DSP_REG_SR]>>(DSP_SR_C)) & 1; + + dest[2] = dsp->registers[DSP_REG_B0]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[0] = dsp->registers[DSP_REG_B2]; + + source[2] = dsp->registers[DSP_REG_X0]; + source[1] = dsp->registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_sub56(dsp, source, dest); + } + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sbc_y_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3], curcarry; + uint16_t newsr; + + curcarry = (dsp->registers[DSP_REG_SR]>>(DSP_SR_C)) & 1; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + + source[2] = dsp->registers[DSP_REG_Y0]; + source[1] = dsp->registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_sub56(dsp, source, dest); + } + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sbc_y_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3], curcarry; + uint16_t newsr; + + curcarry = (dsp->registers[DSP_REG_SR]>>(DSP_SR_C)) & 1; + + dest[2] = dsp->registers[DSP_REG_B0]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[0] = dsp->registers[DSP_REG_B2]; + + source[2] = dsp->registers[DSP_REG_Y0]; + source[1] = dsp->registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_sub56(dsp, source, dest); + } + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sub_b_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + + source[2] = dsp->registers[DSP_REG_B0]; + source[1] = dsp->registers[DSP_REG_B1]; + source[0] = dsp->registers[DSP_REG_B2]; + + newsr = dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sub_a_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_B0]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[0] = dsp->registers[DSP_REG_B2]; + + source[2] = dsp->registers[DSP_REG_A0]; + source[1] = dsp->registers[DSP_REG_A1]; + source[0] = dsp->registers[DSP_REG_A2]; + + newsr = dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sub_x_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + + source[2] = dsp->registers[DSP_REG_X0]; + source[1] = dsp->registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sub_x_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_B0]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[0] = dsp->registers[DSP_REG_B2]; + + source[2] = dsp->registers[DSP_REG_X0]; + source[1] = dsp->registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sub_y_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + + source[2] = dsp->registers[DSP_REG_Y0]; + source[1] = dsp->registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sub_y_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_B0]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[0] = dsp->registers[DSP_REG_B2]; + + source[2] = dsp->registers[DSP_REG_Y0]; + source[1] = dsp->registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sub_x0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sub_x0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_B0]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[0] = dsp->registers[DSP_REG_B2]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sub_y0_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sub_y0_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_B0]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[0] = dsp->registers[DSP_REG_B2]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sub_x1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sub_x1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_B0]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[0] = dsp->registers[DSP_REG_B2]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sub_y1_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_A0]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[0] = dsp->registers[DSP_REG_A2]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_sub_y1_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[2] = dsp->registers[DSP_REG_B0]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[0] = dsp->registers[DSP_REG_B2]; + + source[2] = 0; + source[1] = dsp->registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_subl_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + newsr = dsp_asl56(dsp, dest); + + source[0] = dsp->registers[DSP_REG_B2]; + source[1] = dsp->registers[DSP_REG_B1]; + source[2] = dsp->registers[DSP_REG_B0]; + newsr |= dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_subl_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + newsr = dsp_asl56(dsp, dest); + + source[0] = dsp->registers[DSP_REG_A2]; + source[1] = dsp->registers[DSP_REG_A1]; + source[2] = dsp->registers[DSP_REG_A0]; + newsr |= dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_subr_a(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + + newsr = dsp_asr56(dsp, dest); + + source[0] = dsp->registers[DSP_REG_B2]; + source[1] = dsp->registers[DSP_REG_B1]; + source[2] = dsp->registers[DSP_REG_B0]; + + newsr |= dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_subr_b(dsp_core_t* dsp) +{ + uint32_t source[3], dest[3]; + uint16_t newsr; + + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + + newsr = dsp_asr56(dsp, dest); + + source[0] = dsp->registers[DSP_REG_A2]; + source[1] = dsp->registers[DSP_REG_A1]; + source[2] = dsp->registers[DSP_REG_A0]; + + newsr |= dsp_sub56(dsp, source, dest); + + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_tfr_b_a(dsp_core_t* dsp) +{ + dsp->registers[DSP_REG_A0] = dsp->registers[DSP_REG_B0]; + dsp->registers[DSP_REG_A1] = dsp->registers[DSP_REG_B1]; + dsp->registers[DSP_REG_A2] = dsp->registers[DSP_REG_B2]; +} + +static void emu_tfr_a_b(dsp_core_t* dsp) +{ + dsp->registers[DSP_REG_B0] = dsp->registers[DSP_REG_A0]; + dsp->registers[DSP_REG_B1] = dsp->registers[DSP_REG_A1]; + dsp->registers[DSP_REG_B2] = dsp->registers[DSP_REG_A2]; +} + +static void emu_tfr_x0_a(dsp_core_t* dsp) +{ + dsp->registers[DSP_REG_A0] = 0; + dsp->registers[DSP_REG_A1] = dsp->registers[DSP_REG_X0]; + if (dsp->registers[DSP_REG_A1] & (1<<23)) + dsp->registers[DSP_REG_A2] = 0xff; + else + dsp->registers[DSP_REG_A2] = 0x0; +} + +static void emu_tfr_x0_b(dsp_core_t* dsp) +{ + dsp->registers[DSP_REG_B0] = 0; + dsp->registers[DSP_REG_B1] = dsp->registers[DSP_REG_X0]; + if (dsp->registers[DSP_REG_B1] & (1<<23)) + dsp->registers[DSP_REG_B2] = 0xff; + else + dsp->registers[DSP_REG_B2] = 0x0; +} + +static void emu_tfr_y0_a(dsp_core_t* dsp) +{ + dsp->registers[DSP_REG_A0] = 0; + dsp->registers[DSP_REG_A1] = dsp->registers[DSP_REG_Y0]; + if (dsp->registers[DSP_REG_A1] & (1<<23)) + dsp->registers[DSP_REG_A2] = 0xff; + else + dsp->registers[DSP_REG_A2] = 0x0; +} + +static void emu_tfr_y0_b(dsp_core_t* dsp) +{ + dsp->registers[DSP_REG_B0] = 0; + dsp->registers[DSP_REG_B1] = dsp->registers[DSP_REG_Y0]; + if (dsp->registers[DSP_REG_B1] & (1<<23)) + dsp->registers[DSP_REG_B2] = 0xff; + else + dsp->registers[DSP_REG_B2] = 0x0; +} + +static void emu_tfr_x1_a(dsp_core_t* dsp) +{ + dsp->registers[DSP_REG_A0] = 0; + dsp->registers[DSP_REG_A1] = dsp->registers[DSP_REG_X1]; + if (dsp->registers[DSP_REG_A1] & (1<<23)) + dsp->registers[DSP_REG_A2] = 0xff; + else + dsp->registers[DSP_REG_A2] = 0x0; +} + +static void emu_tfr_x1_b(dsp_core_t* dsp) +{ + dsp->registers[DSP_REG_B0] = 0; + dsp->registers[DSP_REG_B1] = dsp->registers[DSP_REG_X1]; + if (dsp->registers[DSP_REG_B1] & (1<<23)) + dsp->registers[DSP_REG_B2] = 0xff; + else + dsp->registers[DSP_REG_B2] = 0x0; +} + +static void emu_tfr_y1_a(dsp_core_t* dsp) +{ + dsp->registers[DSP_REG_A0] = 0; + dsp->registers[DSP_REG_A1] = dsp->registers[DSP_REG_Y1]; + if (dsp->registers[DSP_REG_A1] & (1<<23)) + dsp->registers[DSP_REG_A2] = 0xff; + else + dsp->registers[DSP_REG_A2] = 0x0; +} + +static void emu_tfr_y1_b(dsp_core_t* dsp) +{ + dsp->registers[DSP_REG_B0] = 0; + dsp->registers[DSP_REG_B1] = dsp->registers[DSP_REG_Y1]; + if (dsp->registers[DSP_REG_B1] & (1<<23)) + dsp->registers[DSP_REG_B2] = 0xff; + else + dsp->registers[DSP_REG_B2] = 0x0; +} + +static void emu_tst_a(dsp_core_t* dsp) +{ + emu_ccr_update_e_u_n_z(dsp, dsp->registers[DSP_REG_A2], + dsp->registers[DSP_REG_A1], + dsp->registers[DSP_REG_A0]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_B2], + dsp->registers[DSP_REG_B1], + dsp->registers[DSP_REG_B0]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); + reg = numreg & 1; + + value = (dsp->registers[DSP_REG_A2+reg]) << 24; + value += dsp->registers[DSP_REG_A1+reg]; + + switch(scaling) { + case 0: + /* No scaling */ + break; + case 1: + /* scaling down */ + value >>= 1; + break; + case 2: + /* scaling up */ + value <<= 1; + value |= (dsp->registers[DSP_REG_A0+reg]>>23) & 1; + break; + /* indeterminate */ + case 3: + break; + } + + /* limiting ? */ + value &= BITMASK(24); + + if (dsp->registers[DSP_REG_A2+reg] == 0) { + if (value <= 0x007fffff) { + /* No limiting */ + *dest=value; + return 0; + } + } + + if (dsp->registers[DSP_REG_A2+reg] == 0xff) { + if (value >= 0x00800000) { + /* No limiting */ + *dest=value; + return 0; + } + } + + if (dsp->registers[DSP_REG_A2+reg] & (1<<7)) { + /* Limited to maximum negative value */ + *dest=0x00800000; + dsp->registers[DSP_REG_SR] |= (1<registers[DSP_REG_SR] |= (1<cur_inst>>15) & 1; + numreg = (dsp->cur_inst>>16) & 1; + emu_calc_ea(dsp, (dsp->cur_inst>>8) & BITMASK(6), &addr); + + /* Save A or B */ + emu_pm_read_accu24(dsp, numreg, &save_accu); + + /* Save X0 or Y0 */ + save_xy0 = dsp->registers[DSP_REG_X0+(memspace<<1)]; + + /* Execute parallel instruction */ + opcodes_alu[dsp->cur_inst & BITMASK(8)](dsp); + + /* Move [A|B] to [x|y]:ea */ + dsp56k_write_memory(dsp, memspace, addr, save_accu); + + /* Move [x|y]0 to [A|B] */ + dsp->registers[DSP_REG_A0+numreg] = 0; + dsp->registers[DSP_REG_A1+numreg] = save_xy0; + dsp->registers[DSP_REG_A2+numreg] = save_xy0 & (1<<23) ? 0xff : 0x0; +} + +static void emu_pm_1(dsp_core_t* dsp) +{ + uint32_t memspace, numreg1, numreg2, value, xy_addr, retour, save_1, save_2; +/* + 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 + S1,D1 S2,y:ea + S1,D1 #xxxxxx,D2 +*/ + value = (dsp->cur_inst>>8) & BITMASK(6); + retour = emu_calc_ea(dsp, value, &xy_addr); + memspace = (dsp->cur_inst>>14) & 1; + numreg1 = numreg2 = DSP_REG_NULL; + + if (memspace) { + /* Y: */ + switch((dsp->cur_inst>>16) & BITMASK(2)) { + 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((dsp->cur_inst>>18) & BITMASK(2)) { + 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 (dsp->cur_inst & (1<<15)) { + /* Write D1 */ + if (retour) + save_1 = xy_addr; + else + save_1 = dsp56k_read_memory(dsp, memspace, xy_addr); + } else { + /* Read S1 */ + if ((numreg1==DSP_REG_A) || (numreg1==DSP_REG_B)) + emu_pm_read_accu24(dsp, numreg1, &save_1); + else + save_1 = dsp->registers[numreg1]; + } + + /* S2 */ + if (memspace) { + /* Y: */ + numreg2 = DSP_REG_A + ((dsp->cur_inst>>19) & 1); + } else { + /* X: */ + numreg2 = DSP_REG_A + ((dsp->cur_inst>>17) & 1); + } + emu_pm_read_accu24(dsp, numreg2, &save_2); + + + /* Execute parallel instruction */ + opcodes_alu[dsp->cur_inst & BITMASK(8)](dsp); + + + /* Write parallel move values */ + if (dsp->cur_inst & (1<<15)) { + /* Write D1 */ + if (numreg1 == DSP_REG_A) { + dsp->registers[DSP_REG_A0] = 0x0; + dsp->registers[DSP_REG_A1] = save_1; + dsp->registers[DSP_REG_A2] = save_1 & (1<<23) ? 0xff : 0x0; + } + else if (numreg1 == DSP_REG_B) { + dsp->registers[DSP_REG_B0] = 0x0; + dsp->registers[DSP_REG_B1] = save_1; + dsp->registers[DSP_REG_B2] = save_1 & (1<<23) ? 0xff : 0x0; + } + else { + } dsp->registers[numreg1] = save_1; + } else { + /* Read S1 */ + dsp56k_write_memory(dsp, memspace, xy_addr, save_1); + } + + /* S2 -> D2 */ + if (memspace) { + /* Y: */ + numreg2 = DSP_REG_X0 + ((dsp->cur_inst>>18) & 1); + } else { + /* X: */ + numreg2 = DSP_REG_Y0 + ((dsp->cur_inst>>16) & 1); + } + dsp->registers[numreg2] = save_2; +} + +static void emu_pm_2_2(dsp_core_t* dsp); + +static void emu_pm_2(dsp_core_t* dsp) +{ + uint32_t dummy; +/* + 0010 0000 0000 0000 nop + 0010 0000 010m mrrr R update + 0010 00ee eeed dddd S,D + 001d dddd iiii iiii #xx,D +*/ + if ((dsp->cur_inst & 0xffff00) == 0x200000) { + /* Execute parallel instruction */ + opcodes_alu[dsp->cur_inst & BITMASK(8)](dsp); + return; + } + + if ((dsp->cur_inst & 0xffe000) == 0x204000) { + emu_calc_ea(dsp, (dsp->cur_inst>>8) & BITMASK(5), &dummy); + /* Execute parallel instruction */ + opcodes_alu[dsp->cur_inst & BITMASK(8)](dsp); + return; + } + + if ((dsp->cur_inst & 0xfc0000) == 0x200000) { + emu_pm_2_2(dsp); + return; + } + + emu_pm_3(dsp); +} + +static void emu_pm_2_2(dsp_core_t* dsp) +{ +/* + 0010 00ee eeed dddd S,D +*/ + uint32_t srcreg, dstreg, save_reg; + + srcreg = (dsp->cur_inst >> 13) & BITMASK(5); + dstreg = (dsp->cur_inst >> 8) & BITMASK(5); + + if ((srcreg == DSP_REG_A) || (srcreg == DSP_REG_B)) + /* Accu to register: limited 24 bits */ + emu_pm_read_accu24(dsp, srcreg, &save_reg); + else + save_reg = dsp->registers[srcreg]; + + /* Execute parallel instruction */ + opcodes_alu[dsp->cur_inst & BITMASK(8)](dsp); + + /* Write reg */ + if (dstreg == DSP_REG_A) { + dsp->registers[DSP_REG_A0] = 0x0; + dsp->registers[DSP_REG_A1] = save_reg; + dsp->registers[DSP_REG_A2] = save_reg & (1<<23) ? 0xff : 0x0; + } + else if (dstreg == DSP_REG_B) { + dsp->registers[DSP_REG_B0] = 0x0; + dsp->registers[DSP_REG_B1] = save_reg; + dsp->registers[DSP_REG_B2] = save_reg & (1<<23) ? 0xff : 0x0; + } + else { + dsp->registers[dstreg] = save_reg & BITMASK(registers_mask[dstreg]); + } +} + +static void emu_pm_3(dsp_core_t* dsp) +{ + uint32_t dstreg, srcvalue; +/* + 001d dddd iiii iiii #xx,R +*/ + + /* Execute parallel instruction */ + opcodes_alu[dsp->cur_inst & BITMASK(8)](dsp); + + /* Write reg */ + dstreg = (dsp->cur_inst >> 16) & BITMASK(5); + srcvalue = (dsp->cur_inst >> 8) & BITMASK(8); + + switch(dstreg) { + case DSP_REG_X0: + case DSP_REG_X1: + case DSP_REG_Y0: + case DSP_REG_Y1: + case DSP_REG_A: + case DSP_REG_B: + srcvalue <<= 16; + break; + } + + if (dstreg == DSP_REG_A) { + dsp->registers[DSP_REG_A0] = 0x0; + dsp->registers[DSP_REG_A1] = srcvalue; + dsp->registers[DSP_REG_A2] = srcvalue & (1<<23) ? 0xff : 0x0; + } + else if (dstreg == DSP_REG_B) { + dsp->registers[DSP_REG_B0] = 0x0; + dsp->registers[DSP_REG_B1] = srcvalue; + dsp->registers[DSP_REG_B2] = srcvalue & (1<<23) ? 0xff : 0x0; + } + else { + dsp->registers[dstreg] = srcvalue & BITMASK(registers_mask[dstreg]); + } +} + +static void emu_pm_4(dsp_core_t* dsp) +{ +/* + 0100 l0ll w0aa aaaa l:aa,D + S,l:aa + 0100 l0ll w1mm mrrr l:ea,D + S,l:ea + 01dd 0ddd w0aa aaaa x:aa,D + S,x:aa + 01dd 0ddd w1mm mrrr x:ea,D + S,x:ea + #xxxxxx,D + 01dd 1ddd w0aa aaaa y:aa,D + S,y:aa + 01dd 1ddd w1mm mrrr y:ea,D + S,y:ea + #xxxxxx,D +*/ + if ((dsp->cur_inst & 0xf40000)==0x400000) { + emu_pm_4x(dsp); + return; + } + + emu_pm_5(dsp); +} + +static void emu_pm_4x(dsp_core_t* dsp) +{ + uint32_t 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 +*/ + value = (dsp->cur_inst>>8) & BITMASK(6); + if (dsp->cur_inst & (1<<14)) { + emu_calc_ea(dsp, value, &l_addr); + } else { + l_addr = value; + } + + numreg = (dsp->cur_inst>>16) & BITMASK(2); + numreg |= (dsp->cur_inst>>17) & (1<<2); + + if (dsp->cur_inst & (1<<15)) { + /* Write D */ + save_lx = dsp56k_read_memory(dsp, DSP_SPACE_X,l_addr); + save_ly = dsp56k_read_memory(dsp, DSP_SPACE_Y,l_addr); + } + else { + /* Read S */ + switch(numreg) { + case 0: + /* A10 */ + save_lx = dsp->registers[DSP_REG_A1]; + save_ly = dsp->registers[DSP_REG_A0]; + break; + case 1: + /* B10 */ + save_lx = dsp->registers[DSP_REG_B1]; + save_ly = dsp->registers[DSP_REG_B0]; + break; + case 2: + /* X */ + save_lx = dsp->registers[DSP_REG_X1]; + save_ly = dsp->registers[DSP_REG_X0]; + break; + case 3: + /* Y */ + save_lx = dsp->registers[DSP_REG_Y1]; + save_ly = dsp->registers[DSP_REG_Y0]; + break; + case 4: + /* A */ + if (emu_pm_read_accu24(dsp, DSP_REG_A, &save_lx)) { + /* Was limited, set lower part */ + save_ly = (save_lx & (1<<23) ? 0 : 0xffffff); + } else { + /* Not limited */ + save_ly = dsp->registers[DSP_REG_A0]; + } + break; + case 5: + /* B */ + if (emu_pm_read_accu24(dsp, DSP_REG_B, &save_lx)) { + /* Was limited, set lower part */ + save_ly = (save_lx & (1<<23) ? 0 : 0xffffff); + } else { + /* Not limited */ + save_ly = dsp->registers[DSP_REG_B0]; + } + break; + case 6: + /* AB */ + emu_pm_read_accu24(dsp, DSP_REG_A, &save_lx); + emu_pm_read_accu24(dsp, DSP_REG_B, &save_ly); + break; + case 7: + /* BA */ + emu_pm_read_accu24(dsp, DSP_REG_B, &save_lx); + emu_pm_read_accu24(dsp, DSP_REG_A, &save_ly); + break; + } + } + + /* Execute parallel instruction */ + opcodes_alu[dsp->cur_inst & BITMASK(8)](dsp); + + + if (dsp->cur_inst & (1<<15)) { + /* Write D */ + switch(numreg) { + case 0: /* A10 */ + dsp->registers[DSP_REG_A1] = save_lx; + dsp->registers[DSP_REG_A0] = save_ly; + break; + case 1: /* B10 */ + dsp->registers[DSP_REG_B1] = save_lx; + dsp->registers[DSP_REG_B0] = save_ly; + break; + case 2: /* X */ + dsp->registers[DSP_REG_X1] = save_lx; + dsp->registers[DSP_REG_X0] = save_ly; + break; + case 3: /* Y */ + dsp->registers[DSP_REG_Y1] = save_lx; + dsp->registers[DSP_REG_Y0] = save_ly; + break; + case 4: /* A */ + dsp->registers[DSP_REG_A0] = save_ly; + dsp->registers[DSP_REG_A1] = save_lx; + dsp->registers[DSP_REG_A2] = save_lx & (1<<23) ? 0xff : 0; + break; + case 5: /* B */ + dsp->registers[DSP_REG_B0] = save_ly; + dsp->registers[DSP_REG_B1] = save_lx; + dsp->registers[DSP_REG_B2] = save_lx & (1<<23) ? 0xff : 0; + break; + case 6: /* AB */ + dsp->registers[DSP_REG_A0] = 0; + dsp->registers[DSP_REG_A1] = save_lx; + dsp->registers[DSP_REG_A2] = save_lx & (1<<23) ? 0xff : 0; + dsp->registers[DSP_REG_B0] = 0; + dsp->registers[DSP_REG_B1] = save_ly; + dsp->registers[DSP_REG_B2] = save_ly & (1<<23) ? 0xff : 0; + break; + case 7: /* BA */ + dsp->registers[DSP_REG_B0] = 0; + dsp->registers[DSP_REG_B1] = save_lx; + dsp->registers[DSP_REG_B2] = save_lx & (1<<23) ? 0xff : 0; + dsp->registers[DSP_REG_A0] = 0; + dsp->registers[DSP_REG_A1] = save_ly; + dsp->registers[DSP_REG_A2] = save_ly & (1<<23) ? 0xff : 0; + break; + } + } + else { + /* Read S */ + dsp56k_write_memory(dsp, DSP_SPACE_X, l_addr, save_lx); + dsp56k_write_memory(dsp, DSP_SPACE_Y, l_addr, save_ly); + } +} + +static void emu_pm_5(dsp_core_t* dsp) +{ + uint32_t memspace, numreg, value, xy_addr, retour; +/* + 01dd 0ddd w0aa aaaa x:aa,D + S,x:aa + 01dd 0ddd w1mm mrrr x:ea,D + S,x:ea + #xxxxxx,D + 01dd 1ddd w0aa aaaa y:aa,D + S,y:aa + 01dd 1ddd w1mm mrrr y:ea,D + S,y:ea + #xxxxxx,D +*/ + + value = (dsp->cur_inst>>8) & BITMASK(6); + + if (dsp->cur_inst & (1<<14)) { + retour = emu_calc_ea(dsp, value, &xy_addr); + } else { + xy_addr = value; + retour = 0; + } + + memspace = (dsp->cur_inst>>19) & 1; + numreg = (dsp->cur_inst>>16) & BITMASK(3); + numreg |= (dsp->cur_inst>>17) & (BITMASK(2)<<3); + + if (dsp->cur_inst & (1<<15)) { + /* Write D */ + if (retour) + value = xy_addr; + else + value = dsp56k_read_memory(dsp, memspace, xy_addr); + } + else { + /* Read S */ + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) + emu_pm_read_accu24(dsp, numreg, &value); + else + value = dsp->registers[numreg]; + } + + + /* Execute parallel instruction */ + opcodes_alu[dsp->cur_inst & BITMASK(8)](dsp); + + if (dsp->cur_inst & (1<<15)) { + /* Write D */ + if (numreg == DSP_REG_A) { + dsp->registers[DSP_REG_A0] = 0x0; + dsp->registers[DSP_REG_A1] = value; + dsp->registers[DSP_REG_A2] = value & (1<<23) ? 0xff : 0x0; + } + else if (numreg == DSP_REG_B) { + dsp->registers[DSP_REG_B0] = 0x0; + dsp->registers[DSP_REG_B1] = value; + dsp->registers[DSP_REG_B2] = value & (1<<23) ? 0xff : 0x0; + } + else { + dsp->registers[numreg] = value & BITMASK(registers_mask[numreg]); + } + } + else { + /* Read S */ + dsp56k_write_memory(dsp, memspace, xy_addr, value); + } +} + +static void emu_pm_8(dsp_core_t* dsp) +{ + uint32_t ea1, ea2; + uint32_t numreg1, numreg2; + uint32_t save_reg1, save_reg2, x_addr, y_addr; +/* + 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 +*/ + numreg1 = numreg2 = DSP_REG_NULL; + + ea1 = (dsp->cur_inst>>8) & BITMASK(5); + if ((ea1>>3) == 0) { + ea1 |= (1<<5); + } + ea2 = (dsp->cur_inst>>13) & BITMASK(2); + ea2 |= (dsp->cur_inst>>17) & (BITMASK(2)<<3); + if ((ea1 & (1<<2))==0) { + ea2 |= 1<<2; + } + if ((ea2>>3) == 0) { + ea2 |= (1<<5); + } + + emu_calc_ea(dsp, ea1, &x_addr); + emu_calc_ea(dsp, ea2, &y_addr); + + switch((dsp->cur_inst>>18) & BITMASK(2)) { + 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; + } + switch((dsp->cur_inst>>16) & BITMASK(2)) { + case 0: numreg2=DSP_REG_Y0; break; + case 1: numreg2=DSP_REG_Y1; break; + case 2: numreg2=DSP_REG_A; break; + case 3: numreg2=DSP_REG_B; break; + } + + if (dsp->cur_inst & (1<<15)) { + /* Write D1 */ + save_reg1 = dsp56k_read_memory(dsp, DSP_SPACE_X, x_addr); + } else { + /* Read S1 */ + if ((numreg1==DSP_REG_A) || (numreg1==DSP_REG_B)) + emu_pm_read_accu24(dsp, numreg1, &save_reg1); + else + save_reg1 = dsp->registers[numreg1]; + } + + if (dsp->cur_inst & (1<<22)) { + /* Write D2 */ + save_reg2 = dsp56k_read_memory(dsp, DSP_SPACE_Y, y_addr); + } else { + /* Read S2 */ + if ((numreg2==DSP_REG_A) || (numreg2==DSP_REG_B)) + emu_pm_read_accu24(dsp, numreg2, &save_reg2); + else + save_reg2 = dsp->registers[numreg2]; + } + + + /* Execute parallel instruction */ + opcodes_alu[dsp->cur_inst & BITMASK(8)](dsp); + + /* Write first parallel move */ + if (dsp->cur_inst & (1<<15)) { + /* Write D1 */ + if (numreg1 == DSP_REG_A) { + dsp->registers[DSP_REG_A0] = 0x0; + dsp->registers[DSP_REG_A1] = save_reg1; + dsp->registers[DSP_REG_A2] = save_reg1 & (1<<23) ? 0xff : 0x0; + } + else if (numreg1 == DSP_REG_B) { + dsp->registers[DSP_REG_B0] = 0x0; + dsp->registers[DSP_REG_B1] = save_reg1; + dsp->registers[DSP_REG_B2] = save_reg1 & (1<<23) ? 0xff : 0x0; + } + else { + dsp->registers[numreg1] = save_reg1; + } + } else { + /* Read S1 */ + dsp56k_write_memory(dsp, DSP_SPACE_X, x_addr, save_reg1); + } + + /* Write second parallel move */ + if (dsp->cur_inst & (1<<22)) { + /* Write D2 */ + if (numreg2 == DSP_REG_A) { + dsp->registers[DSP_REG_A0] = 0x0; + dsp->registers[DSP_REG_A1] = save_reg2; + dsp->registers[DSP_REG_A2] = save_reg2 & (1<<23) ? 0xff : 0x0; + } + else if (numreg2 == DSP_REG_B) { + dsp->registers[DSP_REG_B0] = 0x0; + dsp->registers[DSP_REG_B1] = save_reg2; + dsp->registers[DSP_REG_B2] = save_reg2 & (1<<23) ? 0xff : 0x0; + } + else { + dsp->registers[numreg2] = save_reg2; + } + } else { + /* Read S2 */ + dsp56k_write_memory(dsp, DSP_SPACE_Y, y_addr, save_reg2); + } +} + +static const emu_func_t opcodes_parmove[16] = { + emu_pm_0, emu_pm_1, emu_pm_2, emu_pm_3, emu_pm_4, emu_pm_5, emu_pm_5, emu_pm_5, + emu_pm_8, emu_pm_8, emu_pm_8, emu_pm_8, emu_pm_8, emu_pm_8, emu_pm_8, emu_pm_8 +}; + + +/********************************** + * Non-parallel moves instructions + **********************************/ + +static void emu_add_long(dsp_core_t* dsp) +{ + uint32_t xxxx = read_memory_p(dsp, dsp->pc+1); + // QQQ + dsp->cur_inst_len++; +} + +static void emu_andi(dsp_core_t* dsp) +{ + uint32_t regnum, value; + + value = (dsp->cur_inst >> 8) & BITMASK(8); + regnum = dsp->cur_inst & BITMASK(2); + switch(regnum) { + case 0: + /* mr */ + dsp->registers[DSP_REG_SR] &= (value<<8)|BITMASK(8); + break; + case 1: + /* ccr */ + dsp->registers[DSP_REG_SR] &= (BITMASK(8)<<8)|value; + break; + case 2: + /* omr */ + dsp->registers[DSP_REG_OMR] &= value; + break; + } +} + +static void emu_bcc_long(dsp_core_t* dsp) { + uint32_t xxxx = read_memory_p(dsp, dsp->pc+1); + dsp->cur_inst_len++; + //QQQ + dsp->instr_cycle += 2; //?? +} + +static void emu_bcc_imm(dsp_core_t* dsp) { + //QQQ + dsp->instr_cycle += 2; //?? +} + +static void emu_bchg_aa(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newcarry, numbit; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + + addr = value; + value = dsp56k_read_memory(dsp, memspace, addr); + newcarry = (value>>numbit) & 1; + if (newcarry) { + value -= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_bchg_ea(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newcarry, numbit; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + + emu_calc_ea(dsp, value, &addr); + value = dsp56k_read_memory(dsp, memspace, addr); + newcarry = (value>>numbit) & 1; + if (newcarry) { + value -= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_bchg_pp(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newcarry, numbit; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + + addr = 0xffffc0 + value; + value = dsp56k_read_memory(dsp, memspace, addr); + newcarry = (value>>numbit) & 1; + if (newcarry) { + value -= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_bchg_reg(dsp_core_t* dsp) +{ + uint32_t value, numreg, newcarry, numbit; + + numreg = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + emu_pm_read_accu24(dsp, numreg, &value); + } else { + value = dsp->registers[numreg]; + } + + newcarry = (value>>numbit) & 1; + if (newcarry) { + value -= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_bclr_aa(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newcarry, numbit; + + memspace = (dsp->cur_inst>>6) & 1; + addr = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + + value = dsp56k_read_memory(dsp, memspace, addr); + newcarry = (value>>numbit) & 1; + value &= 0xffffffff-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_bclr_ea(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newcarry, numbit; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + + emu_calc_ea(dsp, value, &addr); + value = dsp56k_read_memory(dsp, memspace, addr); + newcarry = (value>>numbit) & 1; + value &= 0xffffffff-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_bclr_pp(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newcarry, numbit; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + + addr = 0xffffc0 + value; + value = dsp56k_read_memory(dsp, memspace, addr); + newcarry = (value>>numbit) & 1; + value &= 0xffffffff-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_bclr_reg(dsp_core_t* dsp) +{ + uint32_t value, numreg, newcarry, numbit; + + numreg = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + emu_pm_read_accu24(dsp, numreg, &value); + } else { + value = dsp->registers[numreg]; + } + + newcarry = (value>>numbit) & 1; + value &= 0xffffffff-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_bra_imm(dsp_core_t* dsp) { + // QQQ + dsp->instr_cycle += 2; +} + +static void emu_bset_aa(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newcarry, numbit; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + + addr = value; + value = dsp56k_read_memory(dsp, memspace, addr); + newcarry = (value>>numbit) & 1; + value |= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_bset_ea(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newcarry, numbit; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + + emu_calc_ea(dsp, value, &addr); + value = dsp56k_read_memory(dsp, memspace, addr); + newcarry = (value>>numbit) & 1; + value |= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_bset_pp(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newcarry, numbit; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + addr = 0xffffc0 + value; + value = dsp56k_read_memory(dsp, memspace, addr); + newcarry = (value>>numbit) & 1; + value |= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_bset_reg(dsp_core_t* dsp) +{ + uint32_t value, numreg, newcarry, numbit; + + numreg = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + emu_pm_read_accu24(dsp, numreg, &value); + } else { + value = dsp->registers[numreg]; + } + + newcarry = (value>>numbit) & 1; + value |= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_btst_aa(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newcarry, numbit; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + + addr = value; + value = dsp56k_read_memory(dsp, memspace, addr); + newcarry = (value>>numbit) & 1; + + /* Set carry */ + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_btst_ea(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newcarry, numbit; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + + emu_calc_ea(dsp, value, &addr); + value = dsp56k_read_memory(dsp, memspace, addr); + newcarry = (value>>numbit) & 1; + + /* Set carry */ + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_btst_pp(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newcarry, numbit; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + + addr = 0xffffc0 + value; + value = dsp56k_read_memory(dsp, memspace, addr); + newcarry = (value>>numbit) & 1; + + /* Set carry */ + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_btst_reg(dsp_core_t* dsp) +{ + uint32_t value, numreg, newcarry, numbit; + + numreg = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + emu_pm_read_accu24(dsp, numreg, &value); + } else { + value = dsp->registers[numreg]; + } + + newcarry = (value>>numbit) & 1; + + /* Set carry */ + dsp->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void emu_cmpu(dsp_core_t* dsp) { + // QQQ +} + +static void emu_div(dsp_core_t* dsp) +{ + uint32_t srcreg, destreg, source[3], dest[3]; + uint16_t newsr; + + srcreg = DSP_REG_NULL; + switch((dsp->cur_inst>>4) & BITMASK(2)) { + case 0: srcreg = DSP_REG_X0; break; + case 1: srcreg = DSP_REG_Y0; break; + case 2: srcreg = DSP_REG_X1; break; + case 3: srcreg = DSP_REG_Y1; break; + } + source[2] = 0; + source[1] = dsp->registers[srcreg]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + destreg = DSP_REG_A + ((dsp->cur_inst>>3) & 1); + if (destreg == DSP_REG_A) { + dest[0] = dsp->registers[DSP_REG_A2]; + dest[1] = dsp->registers[DSP_REG_A1]; + dest[2] = dsp->registers[DSP_REG_A0]; + } + else { + dest[0] = dsp->registers[DSP_REG_B2]; + dest[1] = dsp->registers[DSP_REG_B1]; + dest[2] = dsp->registers[DSP_REG_B0]; + } + + if (((dest[0]>>7) & 1) ^ ((source[1]>>23) & 1)) { + /* D += S */ + newsr = dsp_asl56(dsp, dest); + dsp_add56(dsp, source, dest); + } else { + /* D -= S */ + newsr = dsp_asl56(dsp, dest); + dsp_sub56(dsp, source, dest); + } + + dest[2] |= (dsp->registers[DSP_REG_SR]>>DSP_SR_C) & 1; + + if (destreg == DSP_REG_A) { + dsp->registers[DSP_REG_A2] = dest[0]; + dsp->registers[DSP_REG_A1] = dest[1]; + dsp->registers[DSP_REG_A0] = dest[2]; + } + else { + dsp->registers[DSP_REG_B2] = dest[0]; + dsp->registers[DSP_REG_B1] = dest[1]; + dsp->registers[DSP_REG_B0] = dest[2]; + } + + dsp->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<registers[DSP_REG_LA], dsp->registers[DSP_REG_LC], 0); + dsp->registers[DSP_REG_LA] = read_memory_p(dsp, dsp->pc+1) & BITMASK(16); + dsp->cur_inst_len++; + dsp_stack_push(dsp, dsp->pc+dsp->cur_inst_len, dsp->registers[DSP_REG_SR], 0); + dsp->registers[DSP_REG_SR] |= (1<cur_inst>>6) & 1; + addr = (dsp->cur_inst>>8) & BITMASK(6); + dsp->registers[DSP_REG_LC] = dsp56k_read_memory(dsp, memspace, addr) & BITMASK(16); + + dsp->instr_cycle += 4; +} + +static void emu_do_imm(dsp_core_t* dsp) +{ + /* #xx */ + + dsp_stack_push(dsp, dsp->registers[DSP_REG_LA], dsp->registers[DSP_REG_LC], 0); + dsp->registers[DSP_REG_LA] = read_memory_p(dsp, dsp->pc+1) & BITMASK(16); + dsp->cur_inst_len++; + dsp_stack_push(dsp, dsp->pc+dsp->cur_inst_len, dsp->registers[DSP_REG_SR], 0); + dsp->registers[DSP_REG_SR] |= (1<registers[DSP_REG_LC] = ((dsp->cur_inst>>8) & BITMASK(8)) + + ((dsp->cur_inst & BITMASK(4))<<8); + + dsp->instr_cycle += 4; +} + +static void emu_do_ea(dsp_core_t* dsp) +{ + uint32_t memspace, ea_mode, addr; + + /* x:ea */ + /* y:ea */ + + dsp_stack_push(dsp, dsp->registers[DSP_REG_LA], dsp->registers[DSP_REG_LC], 0); + dsp->registers[DSP_REG_LA] = read_memory_p(dsp, dsp->pc+1) & BITMASK(16); + dsp->cur_inst_len++; + dsp_stack_push(dsp, dsp->pc+dsp->cur_inst_len, dsp->registers[DSP_REG_SR], 0); + dsp->registers[DSP_REG_SR] |= (1<cur_inst>>6) & 1; + ea_mode = (dsp->cur_inst>>8) & BITMASK(6); + emu_calc_ea(dsp, ea_mode, &addr); + dsp->registers[DSP_REG_LC] = dsp56k_read_memory(dsp, memspace, addr) & BITMASK(16); + + dsp->instr_cycle += 4; +} + +static void emu_do_reg(dsp_core_t* dsp) +{ + uint32_t numreg; + + /* S */ + + dsp_stack_push(dsp, dsp->registers[DSP_REG_LA], dsp->registers[DSP_REG_LC], 0); + dsp->registers[DSP_REG_LA] = read_memory_p(dsp, dsp->pc+1) & BITMASK(16); + dsp->cur_inst_len++; + + numreg = (dsp->cur_inst>>8) & BITMASK(6); + if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { + emu_pm_read_accu24(dsp, numreg, &dsp->registers[DSP_REG_LC]); + } else { + dsp->registers[DSP_REG_LC] = dsp->registers[numreg]; + } + dsp->registers[DSP_REG_LC] &= BITMASK(16); + + dsp_stack_push(dsp, dsp->pc+dsp->cur_inst_len, dsp->registers[DSP_REG_SR], 0); + dsp->registers[DSP_REG_SR] |= (1<instr_cycle += 4; +} + +static void emu_dor_imm(dsp_core_t* dsp) +{ + //QQQ + + dsp->instr_cycle += 4; +} + +static void emu_enddo(dsp_core_t* dsp) +{ + uint32_t saved_pc, saved_sr; + + dsp_stack_pop(dsp, &saved_pc, &saved_sr); + dsp->registers[DSP_REG_SR] &= 0x7f; + dsp->registers[DSP_REG_SR] |= saved_sr & (1<registers[DSP_REG_LA], &dsp->registers[DSP_REG_LC]); +} + +static void emu_illegal(dsp_core_t* dsp) +{ + /* Raise interrupt p:0x003e */ + dsp56k_add_interrupt(dsp, DSP_INTER_ILLEGAL); + if (dsp->exception_debugging) { + assert(false); + } +} + +static void emu_jcc_imm(dsp_core_t* dsp) +{ + uint32_t cc_code, newpc; + + newpc = dsp->cur_inst & BITMASK(12); + cc_code=(dsp->cur_inst>>12) & BITMASK(4); + if (emu_calc_cc(dsp, cc_code)) { + dsp->pc = newpc; + dsp->cur_inst_len = 0; + } + + dsp->instr_cycle += 2; +} + +static void emu_jcc_ea(dsp_core_t* dsp) +{ + uint32_t newpc, cc_code; + + emu_calc_ea(dsp, (dsp->cur_inst >>8) & BITMASK(6), &newpc); + cc_code=dsp->cur_inst & BITMASK(4); + + if (emu_calc_cc(dsp, cc_code)) { + dsp->pc = newpc; + dsp->cur_inst_len = 0; + } + + dsp->instr_cycle += 2; +} + +static void emu_jclr_aa(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, numbit, newaddr; + + memspace = (dsp->cur_inst>>6) & 1; + addr = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + value = dsp56k_read_memory(dsp, memspace, addr); + newaddr = read_memory_p(dsp, dsp->pc+1); + + dsp->instr_cycle += 4; + + if ((value & (1<pc = newaddr; + dsp->cur_inst_len = 0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_jclr_ea(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, numbit, newaddr; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + newaddr = read_memory_p(dsp, dsp->pc+1); + + emu_calc_ea(dsp, value, &addr); + value = dsp56k_read_memory(dsp, memspace, addr); + + dsp->instr_cycle += 4; + + if ((value & (1<pc = newaddr; + dsp->cur_inst_len = 0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_jclr_pp(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, numbit, newaddr; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + addr = 0xffffc0 + value; + value = dsp56k_read_memory(dsp, memspace, addr); + newaddr = read_memory_p(dsp, dsp->pc+1); + + dsp->instr_cycle += 4; + + if ((value & (1<pc = newaddr; + dsp->cur_inst_len = 0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_jclr_reg(dsp_core_t* dsp) +{ + uint32_t value, numreg, numbit, newaddr; + + numreg = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + newaddr = read_memory_p(dsp, dsp->pc+1); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + emu_pm_read_accu24(dsp, numreg, &value); + } else { + value = dsp->registers[numreg]; + } + + dsp->instr_cycle += 4; + + if ((value & (1<pc = newaddr; + dsp->cur_inst_len = 0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_jmp_ea(dsp_core_t* dsp) +{ + uint32_t newpc; + + emu_calc_ea(dsp, (dsp->cur_inst>>8) & BITMASK(6), &newpc); + dsp->cur_inst_len = 0; + dsp->pc = newpc; + + dsp->instr_cycle += 2; +} + +static void emu_jmp_imm(dsp_core_t* dsp) +{ + uint32_t newpc; + + newpc = dsp->cur_inst & BITMASK(12); + dsp->cur_inst_len = 0; + dsp->pc = newpc; + + dsp->instr_cycle += 2; +} + +static void emu_jscc_ea(dsp_core_t* dsp) +{ + uint32_t newpc, cc_code; + + emu_calc_ea(dsp, (dsp->cur_inst >>8) & BITMASK(6), &newpc); + cc_code=dsp->cur_inst & BITMASK(4); + + if (emu_calc_cc(dsp, cc_code)) { + dsp_stack_push(dsp, dsp->pc+dsp->cur_inst_len, dsp->registers[DSP_REG_SR], 0); + dsp->pc = newpc; + dsp->cur_inst_len = 0; + } + + dsp->instr_cycle += 2; +} + +static void emu_jscc_imm(dsp_core_t* dsp) +{ + uint32_t cc_code, newpc; + + newpc = dsp->cur_inst & BITMASK(12); + cc_code=(dsp->cur_inst>>12) & BITMASK(4); + if (emu_calc_cc(dsp, cc_code)) { + dsp_stack_push(dsp, dsp->pc+dsp->cur_inst_len, dsp->registers[DSP_REG_SR], 0); + dsp->pc = newpc; + dsp->cur_inst_len = 0; + } + + dsp->instr_cycle += 2; +} + +static void emu_jsclr_aa(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newpc, numbit, newaddr; + + memspace = (dsp->cur_inst>>6) & 1; + addr = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + value = dsp56k_read_memory(dsp, memspace, addr); + newaddr = read_memory_p(dsp, dsp->pc+1); + + dsp->instr_cycle += 4; + + if ((value & (1<pc+2, dsp->registers[DSP_REG_SR], 0); + newpc = newaddr; + dsp->pc = newpc; + dsp->cur_inst_len = 0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_jsclr_ea(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newpc, numbit, newaddr; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + emu_calc_ea(dsp, value, &addr); + value = dsp56k_read_memory(dsp, memspace, addr); + newaddr = read_memory_p(dsp, dsp->pc+1); + + dsp->instr_cycle += 4; + + if ((value & (1<pc+2, dsp->registers[DSP_REG_SR], 0); + newpc = newaddr; + dsp->pc = newpc; + dsp->cur_inst_len = 0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_jsclr_pp(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newpc, numbit, newaddr; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + addr = 0xffffc0 + value; + value = dsp56k_read_memory(dsp, memspace, addr); + newaddr = read_memory_p(dsp, dsp->pc+1); + + dsp->instr_cycle += 4; + + if ((value & (1<pc+2, dsp->registers[DSP_REG_SR], 0); + newpc = newaddr; + dsp->pc = newpc; + dsp->cur_inst_len = 0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_jsclr_reg(dsp_core_t* dsp) +{ + uint32_t value, numreg, newpc, numbit, newaddr; + + numreg = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + newaddr = read_memory_p(dsp, dsp->pc+1); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + emu_pm_read_accu24(dsp, numreg, &value); + } else { + value = dsp->registers[numreg]; + } + + dsp->instr_cycle += 4; + + if ((value & (1<pc+2, dsp->registers[DSP_REG_SR], 0); + newpc = newaddr; + dsp->pc = newpc; + dsp->cur_inst_len = 0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_jset_aa(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, numbit, newpc, newaddr; + + memspace = (dsp->cur_inst>>6) & 1; + addr = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + value = dsp56k_read_memory(dsp, memspace, addr); + newaddr = read_memory_p(dsp, dsp->pc+1); + + dsp->instr_cycle += 4; + + if (value & (1<pc = newpc; + dsp->cur_inst_len=0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_jset_ea(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, numbit, newpc, newaddr; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + emu_calc_ea(dsp, value, &addr); + value = dsp56k_read_memory(dsp, memspace, addr); + newaddr = read_memory_p(dsp, dsp->pc+1); + + dsp->instr_cycle += 4; + + if (value & (1<pc = newpc; + dsp->cur_inst_len=0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_jset_pp(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, numbit, newpc, newaddr; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + addr = 0xffffc0 + value; + value = dsp56k_read_memory(dsp, memspace, addr); + newaddr = read_memory_p(dsp, dsp->pc+1); + + dsp->instr_cycle += 4; + + if (value & (1<pc = newpc; + dsp->cur_inst_len=0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_jset_reg(dsp_core_t* dsp) +{ + uint32_t value, numreg, numbit, newpc, newaddr; + + numreg = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + newaddr = read_memory_p(dsp, dsp->pc+1); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + emu_pm_read_accu24(dsp, numreg, &value); + } else { + value = dsp->registers[numreg]; + } + + dsp->instr_cycle += 4; + + if (value & (1<pc = newpc; + dsp->cur_inst_len=0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_jsr_imm(dsp_core_t* dsp) +{ + uint32_t newpc; + + newpc = dsp->cur_inst & BITMASK(12); + + if (dsp->interrupt_state != DSP_INTERRUPT_LONG){ + dsp_stack_push(dsp, dsp->pc+dsp->cur_inst_len, dsp->registers[DSP_REG_SR], 0); + } + else { + dsp->interrupt_state = DSP_INTERRUPT_DISABLED; + } + + dsp->pc = newpc; + dsp->cur_inst_len = 0; + + dsp->instr_cycle += 2; +} + +static void emu_jsr_ea(dsp_core_t* dsp) +{ + uint32_t newpc; + + emu_calc_ea(dsp, (dsp->cur_inst>>8) & BITMASK(6),&newpc); + + if (dsp->interrupt_state != DSP_INTERRUPT_LONG){ + dsp_stack_push(dsp, dsp->pc+dsp->cur_inst_len, dsp->registers[DSP_REG_SR], 0); + } + else { + dsp->interrupt_state = DSP_INTERRUPT_DISABLED; + } + + dsp->pc = newpc; + dsp->cur_inst_len = 0; + + dsp->instr_cycle += 2; +} + +static void emu_jsset_aa(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newpc, numbit, newaddr; + + memspace = (dsp->cur_inst>>6) & 1; + addr = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + value = dsp56k_read_memory(dsp, memspace, addr); + newaddr = read_memory_p(dsp, dsp->pc+1); + + dsp->instr_cycle += 4; + + if (value & (1<pc+2, dsp->registers[DSP_REG_SR], 0); + newpc = newaddr; + dsp->pc = newpc; + dsp->cur_inst_len = 0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_jsset_ea(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newpc, numbit, newaddr; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + emu_calc_ea(dsp, value, &addr); + value = dsp56k_read_memory(dsp, memspace, addr); + newaddr = read_memory_p(dsp, dsp->pc+1); + + dsp->instr_cycle += 4; + + if (value & (1<pc+2, dsp->registers[DSP_REG_SR], 0); + newpc = newaddr; + dsp->pc = newpc; + dsp->cur_inst_len = 0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_jsset_pp(dsp_core_t* dsp) +{ + uint32_t memspace, addr, value, newpc, numbit, newaddr; + + memspace = (dsp->cur_inst>>6) & 1; + value = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + addr = 0xffffc0 + value; + value = dsp56k_read_memory(dsp, memspace, addr); + newaddr = read_memory_p(dsp, dsp->pc+1); + + dsp->instr_cycle += 4; + + if (value & (1<pc+2, dsp->registers[DSP_REG_SR], 0); + newpc = newaddr; + dsp->pc = newpc; + dsp->cur_inst_len = 0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_jsset_reg(dsp_core_t* dsp) +{ + uint32_t value, numreg, newpc, numbit, newaddr; + + numreg = (dsp->cur_inst>>8) & BITMASK(6); + numbit = dsp->cur_inst & BITMASK(5); + newaddr = read_memory_p(dsp, dsp->pc+1); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + emu_pm_read_accu24(dsp, numreg, &value); + } else { + value = dsp->registers[numreg]; + } + + dsp->instr_cycle += 4; + + if (value & (1<pc+2, dsp->registers[DSP_REG_SR], 0); + newpc = newaddr; + dsp->pc = newpc; + dsp->cur_inst_len = 0; + return; + } + ++dsp->cur_inst_len; +} + +static void emu_lua(dsp_core_t* dsp) +{ + uint32_t value, srcreg, dstreg, srcsave, srcnew; + + srcreg = (dsp->cur_inst>>8) & BITMASK(3); + + srcsave = dsp->registers[DSP_REG_R0+srcreg]; + emu_calc_ea(dsp, (dsp->cur_inst>>8) & BITMASK(5), &value); + srcnew = dsp->registers[DSP_REG_R0+srcreg]; + dsp->registers[DSP_REG_R0+srcreg] = srcsave; + + dstreg = dsp->cur_inst & BITMASK(3); + + if (dsp->cur_inst & (1<<3)) { + dsp->registers[DSP_REG_N0+dstreg] = srcnew; + } else { + dsp->registers[DSP_REG_R0+dstreg] = srcnew; + } + + dsp->instr_cycle += 2; +} + +static void emu_movec_reg(dsp_core_t* dsp) +{ + uint32_t numreg1, numreg2, value, dummy; + + /* S1,D2 */ + /* S2,D1 */ + + numreg2 = (dsp->cur_inst>>8) & BITMASK(6); + numreg1 = dsp->cur_inst & BITMASK(6); + + if (dsp->cur_inst & (1<<15)) { + /* Write D1 */ + + if ((numreg2 == DSP_REG_A) || (numreg2 == DSP_REG_B)) { + emu_pm_read_accu24(dsp, numreg2, &value); + } else { + value = dsp->registers[numreg2]; + } + value &= BITMASK(registers_mask[numreg1]); + dsp_write_reg(dsp, numreg1, value); + } else { + /* Read S1 */ + if (numreg1 == DSP_REG_SSH) { + dsp_stack_pop(dsp, &value, &dummy); + } + else { + value = dsp->registers[numreg1]; + } + + if (numreg2 == DSP_REG_A) { + dsp->registers[DSP_REG_A0] = 0; + dsp->registers[DSP_REG_A1] = value & BITMASK(24); + dsp->registers[DSP_REG_A2] = value & (1<<23) ? 0xff : 0x0; + } + else if (numreg2 == DSP_REG_B) { + dsp->registers[DSP_REG_B0] = 0; + dsp->registers[DSP_REG_B1] = value & BITMASK(24); + dsp->registers[DSP_REG_B2] = value & (1<<23) ? 0xff : 0x0; + } + else { + dsp->registers[numreg2] = value & BITMASK(registers_mask[numreg2]); + } + } +} + +static void emu_movec_aa(dsp_core_t* dsp) +{ + uint32_t numreg, addr, memspace, value, dummy; + + /* x:aa,D1 */ + /* S1,x:aa */ + /* y:aa,D1 */ + /* S1,y:aa */ + + numreg = dsp->cur_inst & BITMASK(6); + addr = (dsp->cur_inst>>8) & BITMASK(6); + memspace = (dsp->cur_inst>>6) & 1; + + if (dsp->cur_inst & (1<<15)) { + /* Write D1 */ + value = dsp56k_read_memory(dsp, memspace, addr); + value &= BITMASK(registers_mask[numreg]); + dsp_write_reg(dsp, numreg, value); + } else { + /* Read S1 */ + if (numreg == DSP_REG_SSH) { + dsp_stack_pop(dsp, &value, &dummy); + } + else { + value = dsp->registers[numreg]; + } + dsp56k_write_memory(dsp, memspace, addr, value); + } +} + +static void emu_movec_imm(dsp_core_t* dsp) +{ + uint32_t numreg, value; + + /* #xx,D1 */ + numreg = dsp->cur_inst & BITMASK(6); + value = (dsp->cur_inst>>8) & BITMASK(8); + value &= BITMASK(registers_mask[numreg]); + dsp_write_reg(dsp, numreg, value); +} + +static void emu_movec_ea(dsp_core_t* dsp) +{ + uint32_t numreg, addr, memspace, ea_mode, value, dummy; + int retour; + + /* x:ea,D1 */ + /* S1,x:ea */ + /* y:ea,D1 */ + /* S1,y:ea */ + /* #xxxx,D1 */ + + numreg = dsp->cur_inst & BITMASK(6); + ea_mode = (dsp->cur_inst>>8) & BITMASK(6); + memspace = (dsp->cur_inst>>6) & 1; + + if (dsp->cur_inst & (1<<15)) { + /* Write D1 */ + retour = emu_calc_ea(dsp, ea_mode, &addr); + if (retour) { + value = addr; + } else { + value = dsp56k_read_memory(dsp, memspace, addr); + } + value &= BITMASK(registers_mask[numreg]); + dsp_write_reg(dsp, numreg, value); + } else { + /* Read S1 */ + emu_calc_ea(dsp, ea_mode, &addr); + if (numreg == DSP_REG_SSH) { + dsp_stack_pop(dsp, &value, &dummy); + } + else { + value = dsp->registers[numreg]; + } + dsp56k_write_memory(dsp, memspace, addr, value); + } +} + +static void emu_movem_aa(dsp_core_t* dsp) +{ + uint32_t numreg, addr, value, dummy; + + numreg = dsp->cur_inst & BITMASK(6); + addr = (dsp->cur_inst>>8) & BITMASK(6); + + if (dsp->cur_inst & (1<<15)) { + /* Write D */ + value = read_memory_p(dsp, addr); + value &= BITMASK(registers_mask[numreg]); + dsp_write_reg(dsp, numreg, value); + } else { + /* Read S */ + if (numreg == DSP_REG_SSH) { + dsp_stack_pop(dsp, &value, &dummy); + } + else if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { + emu_pm_read_accu24(dsp, numreg, &value); + } + else { + value = dsp->registers[numreg]; + } + dsp56k_write_memory(dsp, DSP_SPACE_P, addr, value); + } + + dsp->instr_cycle += 4; +} + +static void emu_movem_ea(dsp_core_t* dsp) +{ + uint32_t numreg, addr, ea_mode, value, dummy; + + numreg = dsp->cur_inst & BITMASK(6); + ea_mode = (dsp->cur_inst>>8) & BITMASK(6); + emu_calc_ea(dsp, ea_mode, &addr); + + if (dsp->cur_inst & (1<<15)) { + /* Write D */ + value = read_memory_p(dsp, addr); + value &= BITMASK(registers_mask[numreg]); + dsp_write_reg(dsp, numreg, value); + } else { + /* Read S */ + if (numreg == DSP_REG_SSH) { + dsp_stack_pop(dsp, &value, &dummy); + } + else if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { + emu_pm_read_accu24(dsp, numreg, &value); + } + else { + value = dsp->registers[numreg]; + } + dsp56k_write_memory(dsp, DSP_SPACE_P, addr, value); + } + + dsp->instr_cycle += 4; +} + +static void emu_movep_0(dsp_core_t* dsp) +{ + /* S,x:pp */ + /* x:pp,D */ + /* S,y:pp */ + /* y:pp,D */ + + uint32_t addr, memspace, numreg, value, dummy; + + addr = 0xffffc0 + (dsp->cur_inst & BITMASK(6)); + memspace = (dsp->cur_inst>>16) & 1; + numreg = (dsp->cur_inst>>8) & BITMASK(6); + + if (dsp->cur_inst & (1<<15)) { + /* Write pp */ + if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { + emu_pm_read_accu24(dsp, numreg, &value); + } + else if (numreg == DSP_REG_SSH) { + dsp_stack_pop(dsp, &value, &dummy); + } + else { + value = dsp->registers[numreg]; + } + dsp56k_write_memory(dsp, memspace, addr, value); + } else { + /* Read pp */ + value = dsp56k_read_memory(dsp, memspace, addr); + value &= BITMASK(registers_mask[numreg]); + dsp_write_reg(dsp, numreg, value); + } + + dsp->instr_cycle += 2; +} + +static void emu_movep_1(dsp_core_t* dsp) +{ + /* p:ea,x:pp */ + /* x:pp,p:ea */ + /* p:ea,y:pp */ + /* y:pp,p:ea */ + + uint32_t xyaddr, memspace, paddr; + + xyaddr = 0xffffc0 + (dsp->cur_inst & BITMASK(6)); + emu_calc_ea(dsp, (dsp->cur_inst>>8) & BITMASK(6), &paddr); + memspace = (dsp->cur_inst>>16) & 1; + + if (dsp->cur_inst & (1<<15)) { + /* Write pp */ + dsp56k_write_memory(dsp, memspace, xyaddr, read_memory_p(dsp, paddr)); + } else { + /* Read pp */ + dsp56k_write_memory(dsp, DSP_SPACE_P, paddr, dsp56k_read_memory(dsp, 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->instr_cycle += 4; +} + +static void emu_movep_23(dsp_core_t* dsp) +{ + /* x:ea,x:pp */ + /* y:ea,x:pp */ + /* #xxxxxx,x:pp */ + /* x:pp,x:ea */ + /* x:pp,y:pp */ + /* x:ea,y:pp */ + /* y:ea,y:pp */ + /* #xxxxxx,y:pp */ + /* y:pp,y:ea */ + /* y:pp,x:ea */ + + uint32_t addr, peraddr, easpace, perspace, ea_mode; + int retour; + + peraddr = 0xffffc0 + (dsp->cur_inst & BITMASK(6)); + perspace = (dsp->cur_inst>>16) & 1; + + ea_mode = (dsp->cur_inst>>8) & BITMASK(6); + easpace = (dsp->cur_inst>>6) & 1; + retour = emu_calc_ea(dsp, ea_mode, &addr); + + if (dsp->cur_inst & (1<<15)) { + /* Write pp */ + + if (retour) { + dsp56k_write_memory(dsp, perspace, peraddr, addr); + } else { + dsp56k_write_memory(dsp, perspace, peraddr, dsp56k_read_memory(dsp, easpace, addr)); + } + } else { + /* Read pp */ + dsp56k_write_memory(dsp, easpace, addr, dsp56k_read_memory(dsp, perspace, peraddr)); + } + + dsp->instr_cycle += 2; +} + +static void emu_movep_x_low(dsp_core_t* dsp) { + // 00000111W1MMMRRR0sqqqqqq + + uint32_t addr, peraddr, easpace, ea_mode; + int retour; + + peraddr = 0xffff80 + (dsp->cur_inst & BITMASK(6)); + + ea_mode = (dsp->cur_inst>>8) & BITMASK(6); + easpace = (dsp->cur_inst>>6) & 1; + retour = emu_calc_ea(dsp, ea_mode, &addr); + + // QQQ + + dsp->instr_cycle += 2; // ??? +} + +static void emu_move_x_aa(dsp_core_t* dsp) { + // 0000001aaaaaaRRR1a0WDDDD + int W = (dsp->cur_inst >> 4) & 1; + int a = (((dsp->cur_inst >> 11) & BITMASK(6)) << 1) + + ((dsp->cur_inst >> 6) & 1); + //QQQ + dsp->instr_cycle += 2; //??? +} + +static void emu_norm(dsp_core_t* dsp) +{ + uint32_t cursr,cur_e, cur_euz, dest[3], numreg, rreg; + uint16_t newsr; + + cursr = dsp->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; + cur_euz &= ~((cursr>>DSP_SR_Z) & 1); + cur_euz &= 1; + + numreg = (dsp->cur_inst>>3) & 1; + dest[0] = dsp->registers[DSP_REG_A2+numreg]; + dest[1] = dsp->registers[DSP_REG_A1+numreg]; + dest[2] = dsp->registers[DSP_REG_A0+numreg]; + rreg = DSP_REG_R0+((dsp->cur_inst>>8) & BITMASK(3)); + + if (cur_euz) { + newsr = dsp_asl56(dsp, dest); + --dsp->registers[rreg]; + dsp->registers[rreg] &= BITMASK(16); + } else if (cur_e) { + newsr = dsp_asr56(dsp, dest); + ++dsp->registers[rreg]; + dsp->registers[rreg] &= BITMASK(16); + } else { + newsr = 0; + } + + dsp->registers[DSP_REG_A2+numreg] = dest[0]; + dsp->registers[DSP_REG_A1+numreg] = dest[1]; + dsp->registers[DSP_REG_A0+numreg] = dest[2]; + + emu_ccr_update_e_u_n_z(dsp, dest[0], dest[1], dest[2]); + + dsp->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; +} + +static void emu_ori(dsp_core_t* dsp) +{ + uint32_t regnum, value; + + value = (dsp->cur_inst >> 8) & BITMASK(8); + regnum = dsp->cur_inst & BITMASK(2); + switch(regnum) { + case 0: + /* mr */ + dsp->registers[DSP_REG_SR] |= value<<8; + break; + case 1: + /* ccr */ + dsp->registers[DSP_REG_SR] |= value; + break; + case 2: + /* omr */ + dsp->registers[DSP_REG_OMR] |= value; + break; + } +} + +/* + REP instruction parameter encoding + + xxxxxxxx 00xxxxxx 0xxxxxxx aa + xxxxxxxx 01xxxxxx 0xxxxxxx ea + xxxxxxxx YYxxxxxx 1xxxxxxx imm + xxxxxxxx 11xxxxxx 0xxxxxxx reg +*/ + +static void emu_rep_aa(dsp_core_t* dsp) +{ + /* x:aa */ + /* y:aa */ + dsp->registers[DSP_REG_LCSAVE] = dsp->registers[DSP_REG_LC]; + dsp->pc_on_rep = 1; /* Not decrement LC at first time */ + dsp->loop_rep = 1; /* We are now running rep */ + + dsp->registers[DSP_REG_LC]=dsp56k_read_memory(dsp, (dsp->cur_inst>>6) & 1,(dsp->cur_inst>>8) & BITMASK(6)); + + dsp->instr_cycle += 2; +} + +static void emu_rep_imm(dsp_core_t* dsp) +{ + /* #xxx */ + + dsp->registers[DSP_REG_LCSAVE] = dsp->registers[DSP_REG_LC]; + dsp->pc_on_rep = 1; /* Not decrement LC at first time */ + dsp->loop_rep = 1; /* We are now running rep */ + + dsp->registers[DSP_REG_LC] = ((dsp->cur_inst>>8) & BITMASK(8)) + + ((dsp->cur_inst & BITMASK(4))<<8); + + dsp->instr_cycle += 2; +} + +static void emu_rep_ea(dsp_core_t* dsp) +{ + uint32_t value; + + /* x:ea */ + /* y:ea */ + + dsp->registers[DSP_REG_LCSAVE] = dsp->registers[DSP_REG_LC]; + dsp->pc_on_rep = 1; /* Not decrement LC at first time */ + dsp->loop_rep = 1; /* We are now running rep */ + + emu_calc_ea(dsp, (dsp->cur_inst>>8) & BITMASK(6),&value); + dsp->registers[DSP_REG_LC]= dsp56k_read_memory(dsp, (dsp->cur_inst>>6) & 1, value); + + dsp->instr_cycle += 2; +} + +static void emu_rep_reg(dsp_core_t* dsp) +{ + uint32_t numreg; + + /* R */ + + dsp->registers[DSP_REG_LCSAVE] = dsp->registers[DSP_REG_LC]; + dsp->pc_on_rep = 1; /* Not decrement LC at first time */ + dsp->loop_rep = 1; /* We are now running rep */ + + numreg = (dsp->cur_inst>>8) & BITMASK(6); + if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { + emu_pm_read_accu24(dsp, numreg, &dsp->registers[DSP_REG_LC]); + } else { + dsp->registers[DSP_REG_LC] = dsp->registers[numreg]; + } + dsp->registers[DSP_REG_LC] &= BITMASK(16); + + dsp->instr_cycle += 2; +} + +static void emu_reset(dsp_core_t* dsp) +{ + /* Reset external peripherals */ + dsp->instr_cycle += 2; +} + +static void emu_rti(dsp_core_t* dsp) +{ + uint32_t newpc = 0, newsr = 0; + + dsp_stack_pop(dsp, &newpc, &newsr); + dsp->pc = newpc; + dsp->registers[DSP_REG_SR] = newsr; + dsp->cur_inst_len = 0; + + dsp->instr_cycle += 2; +} + +static void emu_rts(dsp_core_t* dsp) +{ + uint32_t newpc = 0, newsr; + + dsp_stack_pop(dsp, &newpc, &newsr); + dsp->pc = newpc; + dsp->cur_inst_len = 0; + + dsp->instr_cycle += 2; +} + +static void emu_stop(dsp_core_t* dsp) +{ + DPRINTF("Dsp: STOP instruction\n"); +} + +static void emu_swi(dsp_core_t* dsp) +{ + /* Raise interrupt p:0x0006 */ + dsp->instr_cycle += 6; +} + +static void emu_tcc(dsp_core_t* dsp) +{ + uint32_t cc_code, regsrc1, regdest1; + uint32_t regsrc2, regdest2; + uint32_t val0, val1, val2; + + cc_code = (dsp->cur_inst>>12) & BITMASK(4); + + if (emu_calc_cc(dsp, cc_code)) { + regsrc1 = registers_tcc[(dsp->cur_inst>>3) & BITMASK(4)][0]; + regdest1 = registers_tcc[(dsp->cur_inst>>3) & BITMASK(4)][1]; + + /* Read S1 */ + if (regsrc1 == DSP_REG_A) { + val0 = dsp->registers[DSP_REG_A0]; + val1 = dsp->registers[DSP_REG_A1]; + val2 = dsp->registers[DSP_REG_A2]; + } + else if (regsrc1 == DSP_REG_B) { + val0 = dsp->registers[DSP_REG_B0]; + val1 = dsp->registers[DSP_REG_B1]; + val2 = dsp->registers[DSP_REG_B2]; + } + else { + val0 = 0; + val1 = dsp->registers[regsrc1]; + val2 = val1 & (1<<23) ? 0xff : 0x0; + } + + /* Write D1 */ + if (regdest1 == DSP_REG_A) { + dsp->registers[DSP_REG_A2] = val2; + dsp->registers[DSP_REG_A1] = val1; + dsp->registers[DSP_REG_A0] = val0; + } + else { + dsp->registers[DSP_REG_B2] = val2; + dsp->registers[DSP_REG_B1] = val1; + dsp->registers[DSP_REG_B0] = val0; + } + + /* S2,D2 transfer */ + if (dsp->cur_inst & (1<<16)) { + regsrc2 = DSP_REG_R0+((dsp->cur_inst>>8) & BITMASK(3)); + regdest2 = DSP_REG_R0+(dsp->cur_inst & BITMASK(3)); + + dsp->registers[regdest2] = dsp->registers[regsrc2]; + } + } +} + +static void emu_wait(dsp_core_t* dsp) +{ + DPRINTF("Dsp: WAIT instruction\n"); +} + + diff --git a/hw/xbox/dsp/dsp_int.h b/hw/xbox/dsp/dsp_int.h index eecabde226..61fc1af929 100644 --- a/hw/xbox/dsp/dsp_int.h +++ b/hw/xbox/dsp/dsp_int.h @@ -142,7 +142,7 @@ typedef struct dsp_interrupt_s { const char *name; } dsp_interrupt_t; -typedef struct dsp_core_s { +struct dsp_core_s { /* DSP executing instructions ? */ int running; @@ -176,7 +176,58 @@ typedef struct dsp_core_s { uint16_t interrupt_pipeline_count; /* used to prefetch correctly the 2 inter instructions */ int16_t interrupt_ipl[12]; /* store the current IPL for each interrupt */ uint16_t interrupt_isPending[12]; /* store if interrupt is pending for each interrupt */ -} dsp_core_t; + + + /* runtime data */ + + /* Instructions per second */ +#ifdef DSP_COUNT_IPS + uint32_t start_time; +#endif + uint32_t num_inst; + +/* Length of current instruction */ + uint32_t cur_inst_len; /* =0:jump, >0:increment */ +/* Current instruction */ + uint32_t cur_inst; + + /* DSP is in disasm mode ? */ + /* If yes, stack overflow, underflow and illegal instructions messages are not displayed */ + bool in_disasm_mode; + + char str_disasm_memory[2][50]; /* Buffer for memory change text in disasm mode */ + uint32_t disasm_memory_ptr; /* Pointer for memory change in disasm mode */ + + bool exception_debugging; + + + /* disasm data */ + + /* Previous instruction */ + uint32_t disasm_prev_inst_pc; + bool disasm_is_looping; + + /* Used to display dc instead of unknown instruction for illegal opcodes */ + bool isInDisasmMode; + + uint32_t disasm_cur_inst; + uint16_t disasm_cur_inst_len; + + /* Current instruction */ + char disasm_str_instr[50]; + char disasm_str_instr2[120]; + char disasm_parallelmove_name[64]; + + /********************************** + * Register change + **********************************/ + + uint32_t disasm_registers_save[64]; +#if DSP_DISASM_REG_PC + uint32_t pc_save; +#endif + +}; /* DSP */ extern dsp_core_t dsp_core;