--- hatari/src/falcon/dsp_cpu.c 2019/04/09 08:48:48 1.1.1.5 +++ hatari/src/falcon/dsp_cpu.c 2019/04/09 08:58:17 1.1.1.13 @@ -15,46 +15,89 @@ 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 + along with this program; if not, write to the Free Software Foundation, + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA +*/ + +/* + DSP memory mapping + ------------------ + + The memory map is configured as follows : + Program space P is one contiguous block of 32K dsp Words + X and Y data space are each separate 16K dsp Word blocks. + Both X and Y can be accessed as blocks starting at 0 or 16K. + Program space physically overlaps both X and Y data spaces. + Y: memory is mapped at address $0 in P memory + X: memory is mapped at address $4000 in P memory + + The DSP external RAM is zero waitstate, but there is a penalty for + accessing it twice or more in a single instruction, because there is only + one external data bus. The extra access costs 2 cycles penalty. + + The internal buses are all separate (0 waitstate) + + + X: Y: P: + $ffff |--------------+--------------+--------------| + | Int. I/O | Ext. I/O | | + $ffc0 |--------------+--------------+ | + | | | | + | Reserved | Reserved | Reserved | + | | | | + | | | | + | | | | + $8000 |--------------+--------------+--------------| + | | | | + | 16k Shadow | 16k Shadow | | + | | | 32K | + $4000 |--------------+--------------| Program | + | 16K | 16K | RAM | + | External | External | | + | RAM | RAM | | + $0200 |--------------+--------------+--------------| + | Log table or | Sin table or | | + | external mem | external mem | Internal | + $0100 |--------------+--------------+ program | + | Internal X | Internal Y | memory | + | memory | memory | | + $0000 |--------------+--------------+--------------| + + + Special Note : As the Falcon DSP is a 0 waitstate access memory, I've simplified a little the cycle counting. + If this DSP emulator code is used in another project, one should take into account the bus control register (BCR) waitstates. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#include + +#include "main.h" #include "dsp_core.h" #include "dsp_cpu.h" #include "dsp_disasm.h" - - -/* More disasm infos, if wanted */ -#define DSP_DISASM 0 /* Main DSP disassembler switch */ -#define DSP_DISASM_INST 0 /* Instructions */ -#define DSP_DISASM_REG 0 /* Registers changes */ -#define DSP_DISASM_MEM 0 /* Memory changes */ -#define DSP_DISASM_INTER 0 /* Interrupts */ -#define DSP_DISASM_STATE 0 /* State change */ +#include "log.h" +#include "debugui.h" #define DSP_COUNT_IPS 0 /* Count instruction per seconds */ -#if defined(DSP_DISASM) && (DSP_DISASM_MEM==1) -# define write_memory(x,y,z) write_memory_disasm(x,y,z) -#else -# define write_memory(x,y,z) write_memory_raw(x,y,z) -#endif /********************************** * Defines **********************************/ -#define BITMASK(x) ((1<<(x))-1) +#define SIGN_PLUS 0 +#define SIGN_MINUS 1 + +/* Defines some bits values for access to external memory (X, Y, P) */ +/* These values will set/unset the corresponding bits in the variable access_to_ext_memory */ +/* to detect how many access to the external memory were done for a single instruction */ +#define EXT_X_MEMORY 0 +#define EXT_Y_MEMORY 1 +#define EXT_P_MEMORY 2 -/* cycle counter wait state time when access to external memory */ -#define XY_WAITSTATE 1 -#define P_WAITSTATE 1 -#define XP_WAITSTATE 1 /* X Peripheral WaitState */ -#define YP_WAITSTATE 1 /* Y Peripheral WaitState */ /********************************** * Variables @@ -70,23 +113,15 @@ static Uint32 cur_inst_len; /* =0:jump, /* Current instruction */ static Uint32 cur_inst; -/* Parallel move temp data */ -typedef union { - Uint32 *host_pointer; - Uint32 dsp_address; -} parmove_dest_u; - -static Uint32 tmp_parmove_src[2][3]; /* What to read */ -static parmove_dest_u tmp_parmove_dest[2][3]; /* Where to write */ -static Uint32 tmp_parmove_start[2]; /* From where to read/write */ -static Uint32 tmp_parmove_len[2]; /* How many to read/write */ -static Uint32 tmp_parmove_type[2]; /* 0=register, 1=memory */ -static Uint32 tmp_parmove_space[2]; /* Memory space to write to */ +/* Counts the number of access to the external memory for one instruction */ +static Uint16 access_to_ext_memory; + +/* DSP is in disasm mode ? */ +/* If yes, stack overflow, underflow and illegal instructions messages are not displayed */ +static bool isDsp_in_disasm_mode; -#if defined(DSP_DISASM) && (DSP_DISASM_MEM==1) -static char str_disasm_memory[2][50]; /* Buffer for memory change text in disasm mode */ +static char str_disasm_memory[2][50]; /* Buffer for memory change text in disasm mode */ static Uint16 disasm_memory_ptr; /* Pointer for memory change in disasm mode */ -#endif /********************************** * Functions @@ -99,16 +134,17 @@ static void dsp_postexecute_interrupts(v static void dsp_setInterruptIPL(Uint32 value); -static void dsp_ccr_update_e_u_n_z(Uint32 *reg0, Uint32 *reg1, Uint32 *reg2); +static void dsp_ccr_update_e_u_n_z(Uint32 reg0, Uint32 reg1, Uint32 reg2); -static inline Uint32 read_memory_p(Uint16 address); static Uint32 read_memory(int space, Uint16 address); -static void write_memory_raw(int space, Uint16 address, Uint32 value); -#if defined(DSP_DISASM) && (DSP_DISASM_MEM==1) +static inline Uint32 read_memory_p(Uint16 address); static Uint32 read_memory_disasm(int space, Uint16 address); + +static inline void write_memory(int space, Uint16 address, Uint32 value); +static void write_memory_raw(int space, Uint16 address, Uint32 value); static void write_memory_disasm(int space, Uint16 address, Uint32 value); -#endif -static void dsp_write_reg(Uint32 numreg, Uint32 value); + +static void dsp_write_reg(Uint32 numreg, Uint32 value); static void dsp_stack_push(Uint32 curpc, Uint32 cursr, Uint16 sshOnly); static void dsp_stack_pop(Uint32 *curpc, Uint32 *cursr); @@ -200,13 +236,7 @@ static void dsp_movep_1(void); static void dsp_movep_23(void); /* Parallel move analyzer */ -static void dsp_parmove_read(void); -static void dsp_parmove_write(void); -static void dsp_pm_class2(void); - static int dsp_pm_read_accu24(int numreg, Uint32 *dest); -static void dsp_pm_writereg(int numreg, int position); - static void dsp_pm_0(void); static void dsp_pm_1(void); static void dsp_pm_2(void); @@ -227,39 +257,259 @@ static void dsp_mul56(Uint32 source1, Ui static void dsp_rnd56(Uint32 *dest); /* Instructions with parallel moves */ -static void dsp_abs(void); -static void dsp_adc(void); -static void dsp_add(void); -static void dsp_addl(void); -static void dsp_addr(void); -static void dsp_and(void); -static void dsp_asl(void); -static void dsp_asr(void); -static void dsp_clr(void); -static void dsp_cmp(void); -static void dsp_cmpm(void); -static void dsp_eor(void); -static void dsp_lsl(void); -static void dsp_lsr(void); -static void dsp_mac(void); -static void dsp_macr(void); +static void dsp_abs_a(void); +static void dsp_abs_b(void); +static void dsp_adc_x_a(void); +static void dsp_adc_x_b(void); +static void dsp_adc_y_a(void); +static void dsp_adc_y_b(void); +static void dsp_add_b_a(void); +static void dsp_add_a_b(void); +static void dsp_add_x_a(void); +static void dsp_add_x_b(void); +static void dsp_add_y_a(void); +static void dsp_add_y_b(void); +static void dsp_add_x0_a(void); +static void dsp_add_x0_b(void); +static void dsp_add_y0_a(void); +static void dsp_add_y0_b(void); +static void dsp_add_x1_a(void); +static void dsp_add_x1_b(void); +static void dsp_add_y1_a(void); +static void dsp_add_y1_b(void); +static void dsp_addl_b_a(void); +static void dsp_addl_a_b(void); +static void dsp_addr_b_a(void); +static void dsp_addr_a_b(void); +static void dsp_and_x0_a(void); +static void dsp_and_x0_b(void); +static void dsp_and_y0_a(void); +static void dsp_and_y0_b(void); +static void dsp_and_x1_a(void); +static void dsp_and_x1_b(void); +static void dsp_and_y1_a(void); +static void dsp_and_y1_b(void); +static void dsp_asl_a(void); +static void dsp_asl_b(void); +static void dsp_asr_a(void); +static void dsp_asr_b(void); +static void dsp_clr_a(void); +static void dsp_clr_b(void); +static void dsp_cmp_b_a(void); +static void dsp_cmp_a_b(void); +static void dsp_cmp_x0_a(void); +static void dsp_cmp_x0_b(void); +static void dsp_cmp_y0_a(void); +static void dsp_cmp_y0_b(void); +static void dsp_cmp_x1_a(void); +static void dsp_cmp_x1_b(void); +static void dsp_cmp_y1_a(void); +static void dsp_cmp_y1_b(void); +static void dsp_cmpm_b_a(void); +static void dsp_cmpm_a_b(void); +static void dsp_cmpm_x0_a(void); +static void dsp_cmpm_x0_b(void); +static void dsp_cmpm_y0_a(void); +static void dsp_cmpm_y0_b(void); +static void dsp_cmpm_x1_a(void); +static void dsp_cmpm_x1_b(void); +static void dsp_cmpm_y1_a(void); +static void dsp_cmpm_y1_b(void); +static void dsp_eor_x0_a(void); +static void dsp_eor_x0_b(void); +static void dsp_eor_y0_a(void); +static void dsp_eor_y0_b(void); +static void dsp_eor_x1_a(void); +static void dsp_eor_x1_b(void); +static void dsp_eor_y1_a(void); +static void dsp_eor_y1_b(void); +static void dsp_lsl_a(void); +static void dsp_lsl_b(void); +static void dsp_lsr_a(void); +static void dsp_lsr_b(void); +static void dsp_mac_p_x0_x0_a(void); +static void dsp_mac_m_x0_x0_a(void); +static void dsp_mac_p_x0_x0_b(void); +static void dsp_mac_m_x0_x0_b(void); +static void dsp_mac_p_y0_y0_a(void); +static void dsp_mac_m_y0_y0_a(void); +static void dsp_mac_p_y0_y0_b(void); +static void dsp_mac_m_y0_y0_b(void); +static void dsp_mac_p_x1_x0_a(void); +static void dsp_mac_m_x1_x0_a(void); +static void dsp_mac_p_x1_x0_b(void); +static void dsp_mac_m_x1_x0_b(void); +static void dsp_mac_p_y1_y0_a(void); +static void dsp_mac_m_y1_y0_a(void); +static void dsp_mac_p_y1_y0_b(void); +static void dsp_mac_m_y1_y0_b(void); +static void dsp_mac_p_x0_y1_a(void); +static void dsp_mac_m_x0_y1_a(void); +static void dsp_mac_p_x0_y1_b(void); +static void dsp_mac_m_x0_y1_b(void); +static void dsp_mac_p_y0_x0_a(void); +static void dsp_mac_m_y0_x0_a(void); +static void dsp_mac_p_y0_x0_b(void); +static void dsp_mac_m_y0_x0_b(void); +static void dsp_mac_p_x1_y0_a(void); +static void dsp_mac_m_x1_y0_a(void); +static void dsp_mac_p_x1_y0_b(void); +static void dsp_mac_m_x1_y0_b(void); +static void dsp_mac_p_y1_x1_a(void); +static void dsp_mac_m_y1_x1_a(void); +static void dsp_mac_p_y1_x1_b(void); +static void dsp_mac_m_y1_x1_b(void); +static void dsp_macr_p_x0_x0_a(void); +static void dsp_macr_m_x0_x0_a(void); +static void dsp_macr_p_x0_x0_b(void); +static void dsp_macr_m_x0_x0_b(void); +static void dsp_macr_p_y0_y0_a(void); +static void dsp_macr_m_y0_y0_a(void); +static void dsp_macr_p_y0_y0_b(void); +static void dsp_macr_m_y0_y0_b(void); +static void dsp_macr_p_x1_x0_a(void); +static void dsp_macr_m_x1_x0_a(void); +static void dsp_macr_p_x1_x0_b(void); +static void dsp_macr_m_x1_x0_b(void); +static void dsp_macr_p_y1_y0_a(void); +static void dsp_macr_m_y1_y0_a(void); +static void dsp_macr_p_y1_y0_b(void); +static void dsp_macr_m_y1_y0_b(void); +static void dsp_macr_p_x0_y1_a(void); +static void dsp_macr_m_x0_y1_a(void); +static void dsp_macr_p_x0_y1_b(void); +static void dsp_macr_m_x0_y1_b(void); +static void dsp_macr_p_y0_x0_a(void); +static void dsp_macr_m_y0_x0_a(void); +static void dsp_macr_p_y0_x0_b(void); +static void dsp_macr_m_y0_x0_b(void); +static void dsp_macr_p_x1_y0_a(void); +static void dsp_macr_m_x1_y0_a(void); +static void dsp_macr_p_x1_y0_b(void); +static void dsp_macr_m_x1_y0_b(void); +static void dsp_macr_p_y1_x1_a(void); +static void dsp_macr_m_y1_x1_a(void); +static void dsp_macr_p_y1_x1_b(void); +static void dsp_macr_m_y1_x1_b(void); static void dsp_move(void); -static void dsp_mpy(void); -static void dsp_mpyr(void); -static void dsp_neg(void); -static void dsp_not(void); -static void dsp_or(void); -static void dsp_rnd(void); -static void dsp_rol(void); -static void dsp_ror(void); -static void dsp_sbc(void); -static void dsp_sub(void); -static void dsp_subl(void); -static void dsp_subr(void); -static void dsp_tfr(void); -static void dsp_tst(void); +static void dsp_mpy_p_x0_x0_a(void); +static void dsp_mpy_m_x0_x0_a(void); +static void dsp_mpy_p_x0_x0_b(void); +static void dsp_mpy_m_x0_x0_b(void); +static void dsp_mpy_p_y0_y0_a(void); +static void dsp_mpy_m_y0_y0_a(void); +static void dsp_mpy_p_y0_y0_b(void); +static void dsp_mpy_m_y0_y0_b(void); +static void dsp_mpy_p_x1_x0_a(void); +static void dsp_mpy_m_x1_x0_a(void); +static void dsp_mpy_p_x1_x0_b(void); +static void dsp_mpy_m_x1_x0_b(void); +static void dsp_mpy_p_y1_y0_a(void); +static void dsp_mpy_m_y1_y0_a(void); +static void dsp_mpy_p_y1_y0_b(void); +static void dsp_mpy_m_y1_y0_b(void); +static void dsp_mpy_p_x0_y1_a(void); +static void dsp_mpy_m_x0_y1_a(void); +static void dsp_mpy_p_x0_y1_b(void); +static void dsp_mpy_m_x0_y1_b(void); +static void dsp_mpy_p_y0_x0_a(void); +static void dsp_mpy_m_y0_x0_a(void); +static void dsp_mpy_p_y0_x0_b(void); +static void dsp_mpy_m_y0_x0_b(void); +static void dsp_mpy_p_x1_y0_a(void); +static void dsp_mpy_m_x1_y0_a(void); +static void dsp_mpy_p_x1_y0_b(void); +static void dsp_mpy_m_x1_y0_b(void); +static void dsp_mpy_p_y1_x1_a(void); +static void dsp_mpy_m_y1_x1_a(void); +static void dsp_mpy_p_y1_x1_b(void); +static void dsp_mpy_m_y1_x1_b(void); +static void dsp_mpyr_p_x0_x0_a(void); +static void dsp_mpyr_m_x0_x0_a(void); +static void dsp_mpyr_p_x0_x0_b(void); +static void dsp_mpyr_m_x0_x0_b(void); +static void dsp_mpyr_p_y0_y0_a(void); +static void dsp_mpyr_m_y0_y0_a(void); +static void dsp_mpyr_p_y0_y0_b(void); +static void dsp_mpyr_m_y0_y0_b(void); +static void dsp_mpyr_p_x1_x0_a(void); +static void dsp_mpyr_m_x1_x0_a(void); +static void dsp_mpyr_p_x1_x0_b(void); +static void dsp_mpyr_m_x1_x0_b(void); +static void dsp_mpyr_p_y1_y0_a(void); +static void dsp_mpyr_m_y1_y0_a(void); +static void dsp_mpyr_p_y1_y0_b(void); +static void dsp_mpyr_m_y1_y0_b(void); +static void dsp_mpyr_p_x0_y1_a(void); +static void dsp_mpyr_m_x0_y1_a(void); +static void dsp_mpyr_p_x0_y1_b(void); +static void dsp_mpyr_m_x0_y1_b(void); +static void dsp_mpyr_p_y0_x0_a(void); +static void dsp_mpyr_m_y0_x0_a(void); +static void dsp_mpyr_p_y0_x0_b(void); +static void dsp_mpyr_m_y0_x0_b(void); +static void dsp_mpyr_p_x1_y0_a(void); +static void dsp_mpyr_m_x1_y0_a(void); +static void dsp_mpyr_p_x1_y0_b(void); +static void dsp_mpyr_m_x1_y0_b(void); +static void dsp_mpyr_p_y1_x1_a(void); +static void dsp_mpyr_m_y1_x1_a(void); +static void dsp_mpyr_p_y1_x1_b(void); +static void dsp_mpyr_m_y1_x1_b(void); +static void dsp_neg_a(void); +static void dsp_neg_b(void); +static void dsp_not_a(void); +static void dsp_not_b(void); +static void dsp_or_x0_a(void); +static void dsp_or_x0_b(void); +static void dsp_or_y0_a(void); +static void dsp_or_y0_b(void); +static void dsp_or_x1_a(void); +static void dsp_or_x1_b(void); +static void dsp_or_y1_a(void); +static void dsp_or_y1_b(void); +static void dsp_rnd_a(void); +static void dsp_rnd_b(void); +static void dsp_rol_a(void); +static void dsp_rol_b(void); +static void dsp_ror_a(void); +static void dsp_ror_b(void); +static void dsp_sbc_x_a(void); +static void dsp_sbc_x_b(void); +static void dsp_sbc_y_a(void); +static void dsp_sbc_y_b(void); +static void dsp_sub_b_a(void); +static void dsp_sub_a_b(void); +static void dsp_sub_x_a(void); +static void dsp_sub_x_b(void); +static void dsp_sub_y_a(void); +static void dsp_sub_y_b(void); +static void dsp_sub_x0_a(void); +static void dsp_sub_x0_b(void); +static void dsp_sub_y0_a(void); +static void dsp_sub_y0_b(void); +static void dsp_sub_x1_a(void); +static void dsp_sub_x1_b(void); +static void dsp_sub_y1_a(void); +static void dsp_sub_y1_b(void); +static void dsp_subl_a(void); +static void dsp_subl_b(void); +static void dsp_subr_a(void); +static void dsp_subr_b(void); +static void dsp_tfr_b_a(void); +static void dsp_tfr_a_b(void); +static void dsp_tfr_x0_a(void); +static void dsp_tfr_x0_b(void); +static void dsp_tfr_y0_a(void); +static void dsp_tfr_y0_b(void); +static void dsp_tfr_x1_a(void); +static void dsp_tfr_x1_b(void); +static void dsp_tfr_y1_a(void); +static void dsp_tfr_y1_b(void); +static void dsp_tst_a(void); +static void dsp_tst_b(void); -static dsp_emul_t opcodes8h[512]={ +static const dsp_emul_t opcodes8h[512] = { /* 0x00 - 0x3f */ opcode8h_0, dsp_undefined, dsp_undefined, dsp_undefined, opcode8h_0, dsp_andi, dsp_undefined, dsp_ori, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_andi, dsp_undefined, dsp_ori, @@ -269,7 +519,7 @@ static dsp_emul_t opcodes8h[512]={ dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_div, dsp_div, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_norm, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - + /* 0x40 - 0x7f */ dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, @@ -282,32 +532,32 @@ static dsp_emul_t opcodes8h[512]={ /* 0x80 - 0xbf */ dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_lua, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_reg, dsp_undefined, dsp_undefined, + dsp_lua, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_reg, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_reg, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_reg, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, - + /* 0xc0 - 0xff */ - dsp_do_aa, dsp_rep_aa, dsp_do_aa, dsp_rep_aa, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, - dsp_do_ea, dsp_rep_ea, dsp_do_ea, dsp_rep_ea, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, - dsp_do_reg, dsp_rep_reg, dsp_undefined, dsp_undefined, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, - dsp_movem_aa, dsp_movem_aa, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movem_ea, dsp_movem_ea, dsp_undefined, dsp_undefined, - dsp_movem_aa, dsp_movem_aa, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movem_ea, dsp_movem_ea, dsp_undefined, dsp_undefined, + dsp_do_aa, dsp_rep_aa, dsp_do_aa, dsp_rep_aa, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_do_ea, dsp_rep_ea, dsp_do_ea, dsp_rep_ea, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_do_reg, dsp_rep_reg, dsp_undefined, dsp_undefined, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_movem_aa, dsp_movem_aa, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movem_ea, dsp_movem_ea, dsp_undefined, dsp_undefined, + dsp_movem_aa, dsp_movem_aa, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movem_ea, dsp_movem_ea, dsp_undefined, dsp_undefined, /* 0x100 - 0x13f */ - dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, + dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_movep_0, dsp_movep_0, dsp_movep_1, dsp_movep_1, dsp_movep_23, dsp_movep_23, dsp_movep_23, dsp_movep_23, - dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, + dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_movep_0, dsp_movep_0, dsp_movep_1, dsp_movep_1, dsp_movep_23, dsp_movep_23, dsp_movep_23, dsp_movep_23, - dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, + dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_movep_0, dsp_movep_0, dsp_movep_1, dsp_movep_1, dsp_movep_23, dsp_movep_23, dsp_movep_23, dsp_movep_23, - dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, + dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_movep_0, dsp_movep_0, dsp_movep_1, dsp_movep_1, dsp_movep_23, dsp_movep_23, dsp_movep_23, dsp_movep_23, /* 0x140 - 0x17f */ @@ -322,88 +572,73 @@ static dsp_emul_t opcodes8h[512]={ /* 0x180 - 0x1bf */ dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, /* 0x1c0 - 0x1ff */ - dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, - dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, - dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, - dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, - dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, - dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, - dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, - dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, }; -static dsp_emul_t opcodes_parmove[16]={ - dsp_pm_0, - dsp_pm_1, - dsp_pm_2, - dsp_pm_3, - dsp_pm_4, - dsp_pm_5, - dsp_pm_5, - dsp_pm_5, - - dsp_pm_8, - dsp_pm_8, - dsp_pm_8, - dsp_pm_8, - dsp_pm_8, - dsp_pm_8, - dsp_pm_8, - dsp_pm_8 +static const dsp_emul_t opcodes_parmove[16] = { + dsp_pm_0, dsp_pm_1, dsp_pm_2, dsp_pm_3, dsp_pm_4, dsp_pm_5, dsp_pm_5, dsp_pm_5, + dsp_pm_8, dsp_pm_8, dsp_pm_8, dsp_pm_8, dsp_pm_8, dsp_pm_8, dsp_pm_8, dsp_pm_8 }; -static dsp_emul_t opcodes_alu[256]={ +static const dsp_emul_t opcodes_alu[256] = { /* 0x00 - 0x3f */ - dsp_move, dsp_tfr, dsp_addr, dsp_tst, dsp_undefined, dsp_cmp, dsp_subr, dsp_cmpm, - dsp_undefined, dsp_tfr, dsp_addr, dsp_tst, dsp_undefined, dsp_cmp, dsp_subr, dsp_cmpm, - dsp_add, dsp_rnd, dsp_addl, dsp_clr, dsp_sub, dsp_undefined, dsp_subl, dsp_not, - dsp_add, dsp_rnd, dsp_addl, dsp_clr, dsp_sub, dsp_undefined, dsp_subl, dsp_not, - dsp_add, dsp_adc, dsp_asr, dsp_lsr, dsp_sub, dsp_sbc, dsp_abs, dsp_ror, - dsp_add, dsp_adc, dsp_asr, dsp_lsr, dsp_sub, dsp_sbc, dsp_abs, dsp_ror, - dsp_add, dsp_adc, dsp_asl, dsp_lsl, dsp_sub, dsp_sbc, dsp_neg, dsp_rol, - dsp_add, dsp_adc, dsp_asl, dsp_lsl, dsp_sub, dsp_sbc, dsp_neg, dsp_rol, - + dsp_move , dsp_tfr_b_a, dsp_addr_b_a, dsp_tst_a, dsp_undefined, dsp_cmp_b_a, dsp_subr_a, dsp_cmpm_b_a, + dsp_undefined, dsp_tfr_a_b, dsp_addr_a_b, dsp_tst_b, dsp_undefined, dsp_cmp_a_b, dsp_subr_b, dsp_cmpm_a_b, + dsp_add_b_a, dsp_rnd_a, dsp_addl_b_a, dsp_clr_a, dsp_sub_b_a, dsp_undefined, dsp_subl_a, dsp_not_a, + dsp_add_a_b, dsp_rnd_b, dsp_addl_a_b, dsp_clr_b, dsp_sub_a_b, dsp_undefined, dsp_subl_b, dsp_not_b, + dsp_add_x_a, dsp_adc_x_a, dsp_asr_a, dsp_lsr_a, dsp_sub_x_a, dsp_sbc_x_a, dsp_abs_a, dsp_ror_a, + dsp_add_x_b, dsp_adc_x_b, dsp_asr_b, dsp_lsr_b, dsp_sub_x_b, dsp_sbc_x_b, dsp_abs_b, dsp_ror_b, + dsp_add_y_a, dsp_adc_y_a, dsp_asl_a, dsp_lsl_a, dsp_sub_y_a, dsp_sbc_y_a, dsp_neg_a, dsp_rol_a, + dsp_add_y_b, dsp_adc_y_b, dsp_asl_b, dsp_lsl_b, dsp_sub_y_b, dsp_sbc_y_b, dsp_neg_b, dsp_rol_b, + /* 0x40 - 0x7f */ - dsp_add, dsp_tfr, dsp_or, dsp_eor, dsp_sub, dsp_cmp, dsp_and, dsp_cmpm, - dsp_add, dsp_tfr, dsp_or, dsp_eor, dsp_sub, dsp_cmp, dsp_and, dsp_cmpm, - dsp_add, dsp_tfr, dsp_or, dsp_eor, dsp_sub, dsp_cmp, dsp_and, dsp_cmpm, - dsp_add, dsp_tfr, dsp_or, dsp_eor, dsp_sub, dsp_cmp, dsp_and, dsp_cmpm, - dsp_add, dsp_tfr, dsp_or, dsp_eor, dsp_sub, dsp_cmp, dsp_and, dsp_cmpm, - dsp_add, dsp_tfr, dsp_or, dsp_eor, dsp_sub, dsp_cmp, dsp_and, dsp_cmpm, - dsp_add, dsp_tfr, dsp_or, dsp_eor, dsp_sub, dsp_cmp, dsp_and, dsp_cmpm, - dsp_add, dsp_tfr, dsp_or, dsp_eor, dsp_sub, dsp_cmp, dsp_and, dsp_cmpm, + dsp_add_x0_a, dsp_tfr_x0_a, dsp_or_x0_a, dsp_eor_x0_a, dsp_sub_x0_a, dsp_cmp_x0_a, dsp_and_x0_a, dsp_cmpm_x0_a, + dsp_add_x0_b, dsp_tfr_x0_b, dsp_or_x0_b, dsp_eor_x0_b, dsp_sub_x0_b, dsp_cmp_x0_b, dsp_and_x0_b, dsp_cmpm_x0_b, + dsp_add_y0_a, dsp_tfr_y0_a, dsp_or_y0_a, dsp_eor_y0_a, dsp_sub_y0_a, dsp_cmp_y0_a, dsp_and_y0_a, dsp_cmpm_y0_a, + dsp_add_y0_b, dsp_tfr_y0_b, dsp_or_y0_b, dsp_eor_y0_b, dsp_sub_y0_b, dsp_cmp_y0_b, dsp_and_y0_b, dsp_cmpm_y0_b, + dsp_add_x1_a, dsp_tfr_x1_a, dsp_or_x1_a, dsp_eor_x1_a, dsp_sub_x1_a, dsp_cmp_x1_a, dsp_and_x1_a, dsp_cmpm_x1_a, + dsp_add_x1_b, dsp_tfr_x1_b, dsp_or_x1_b, dsp_eor_x1_b, dsp_sub_x1_b, dsp_cmp_x1_b, dsp_and_x1_b, dsp_cmpm_x1_b, + dsp_add_y1_a, dsp_tfr_y1_a, dsp_or_y1_a, dsp_eor_y1_a, dsp_sub_y1_a, dsp_cmp_y1_a, dsp_and_y1_a, dsp_cmpm_y1_a, + dsp_add_y1_b, dsp_tfr_y1_b, dsp_or_y1_b, dsp_eor_y1_b, dsp_sub_y1_b, dsp_cmp_y1_b, dsp_and_y1_b, dsp_cmpm_y1_b, /* 0x80 - 0xbf */ - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, - - /* 0xc0 - 0xff */ - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, - dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr, dsp_mpy, dsp_mpyr, dsp_mac, dsp_macr + dsp_mpy_p_x0_x0_a, dsp_mpyr_p_x0_x0_a, dsp_mac_p_x0_x0_a, dsp_macr_p_x0_x0_a, dsp_mpy_m_x0_x0_a, dsp_mpyr_m_x0_x0_a, dsp_mac_m_x0_x0_a, dsp_macr_m_x0_x0_a, + dsp_mpy_p_x0_x0_b, dsp_mpyr_p_x0_x0_b, dsp_mac_p_x0_x0_b, dsp_macr_p_x0_x0_b, dsp_mpy_m_x0_x0_b, dsp_mpyr_m_x0_x0_b, dsp_mac_m_x0_x0_b, dsp_macr_m_x0_x0_b, + dsp_mpy_p_y0_y0_a, dsp_mpyr_p_y0_y0_a, dsp_mac_p_y0_y0_a, dsp_macr_p_y0_y0_a, dsp_mpy_m_y0_y0_a, dsp_mpyr_m_y0_y0_a, dsp_mac_m_y0_y0_a, dsp_macr_m_y0_y0_a, + dsp_mpy_p_y0_y0_b, dsp_mpyr_p_y0_y0_b, dsp_mac_p_y0_y0_b, dsp_macr_p_y0_y0_b, dsp_mpy_m_y0_y0_b, dsp_mpyr_m_y0_y0_b, dsp_mac_m_y0_y0_b, dsp_macr_m_y0_y0_b, + dsp_mpy_p_x1_x0_a, dsp_mpyr_p_x1_x0_a, dsp_mac_p_x1_x0_a, dsp_macr_p_x1_x0_a, dsp_mpy_m_x1_x0_a, dsp_mpyr_m_x1_x0_a, dsp_mac_m_x1_x0_a, dsp_macr_m_x1_x0_a, + dsp_mpy_p_x1_x0_b, dsp_mpyr_p_x1_x0_b, dsp_mac_p_x1_x0_b, dsp_macr_p_x1_x0_b, dsp_mpy_m_x1_x0_b, dsp_mpyr_m_x1_x0_b, dsp_mac_m_x1_x0_b, dsp_macr_m_x1_x0_b, + dsp_mpy_p_y1_y0_a, dsp_mpyr_p_y1_y0_a, dsp_mac_p_y1_y0_a, dsp_macr_p_y1_y0_a, dsp_mpy_m_y1_y0_a, dsp_mpyr_m_y1_y0_a, dsp_mac_m_y1_y0_a, dsp_macr_m_y1_y0_a, + dsp_mpy_p_y1_y0_b, dsp_mpyr_p_y1_y0_b, dsp_mac_p_y1_y0_b, dsp_macr_p_y1_y0_b, dsp_mpy_m_y1_y0_b, dsp_mpyr_m_y1_y0_b, dsp_mac_m_y1_y0_b, dsp_macr_m_y1_y0_b, + + /* 0xc0_m_ 0xff */ + dsp_mpy_p_x0_y1_a, dsp_mpyr_p_x0_y1_a, dsp_mac_p_x0_y1_a, dsp_macr_p_x0_y1_a, dsp_mpy_m_x0_y1_a, dsp_mpyr_m_x0_y1_a, dsp_mac_m_x0_y1_a, dsp_macr_m_x0_y1_a, + dsp_mpy_p_x0_y1_b, dsp_mpyr_p_x0_y1_b, dsp_mac_p_x0_y1_b, dsp_macr_p_x0_y1_b, dsp_mpy_m_x0_y1_b, dsp_mpyr_m_x0_y1_b, dsp_mac_m_x0_y1_b, dsp_macr_m_x0_y1_b, + dsp_mpy_p_y0_x0_a, dsp_mpyr_p_y0_x0_a, dsp_mac_p_y0_x0_a, dsp_macr_p_y0_x0_a, dsp_mpy_m_y0_x0_a, dsp_mpyr_m_y0_x0_a, dsp_mac_m_y0_x0_a, dsp_macr_m_y0_x0_a, + dsp_mpy_p_y0_x0_b, dsp_mpyr_p_y0_x0_b, dsp_mac_p_y0_x0_b, dsp_macr_p_y0_x0_b, dsp_mpy_m_y0_x0_b, dsp_mpyr_m_y0_x0_b, dsp_mac_m_y0_x0_b, dsp_macr_m_y0_x0_b, + dsp_mpy_p_x1_y0_a, dsp_mpyr_p_x1_y0_a, dsp_mac_p_x1_y0_a, dsp_macr_p_x1_y0_a, dsp_mpy_m_x1_y0_a, dsp_mpyr_m_x1_y0_a, dsp_mac_m_x1_y0_a, dsp_macr_m_x1_y0_a, + dsp_mpy_p_x1_y0_b, dsp_mpyr_p_x1_y0_b, dsp_mac_p_x1_y0_b, dsp_macr_p_x1_y0_b, dsp_mpy_m_x1_y0_b, dsp_mpyr_m_x1_y0_b, dsp_mac_m_x1_y0_b, dsp_macr_m_x1_y0_b, + dsp_mpy_p_y1_x1_a, dsp_mpyr_p_y1_x1_a, dsp_mac_p_y1_x1_a, dsp_macr_p_y1_x1_a, dsp_mpy_m_y1_x1_a, dsp_mpyr_m_y1_x1_a, dsp_mac_m_y1_x1_a, dsp_macr_m_y1_x1_a, + dsp_mpy_p_y1_x1_b, dsp_mpyr_p_y1_x1_b, dsp_mac_p_y1_x1_b, dsp_macr_p_y1_x1_b, dsp_mpy_m_y1_x1_b, dsp_mpyr_m_y1_x1_b, dsp_mac_m_y1_x1_b, dsp_macr_m_y1_x1_b }; -static int registers_tcc[16][2]={ +static const int registers_tcc[16][2] = { {DSP_REG_B,DSP_REG_A}, {DSP_REG_A,DSP_REG_B}, {DSP_REG_NULL,DSP_REG_NULL}, @@ -425,29 +660,17 @@ static int registers_tcc[16][2]={ {DSP_REG_Y1,DSP_REG_B} }; -static int registers_mpy[8][2]={ - {DSP_REG_X0,DSP_REG_X0}, - {DSP_REG_Y0,DSP_REG_Y0}, - {DSP_REG_X1,DSP_REG_X0}, - {DSP_REG_Y1,DSP_REG_Y0}, - - {DSP_REG_X0,DSP_REG_Y1}, - {DSP_REG_Y0,DSP_REG_X0}, - {DSP_REG_X1,DSP_REG_Y0}, - {DSP_REG_Y1,DSP_REG_X1} -}; - -static int registers_mask[64]={ +static const int registers_mask[64] = { 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 8, 8, 24, 24, 24, 24, - + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - + 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, @@ -459,7 +682,7 @@ static int registers_mask[64]={ 16, 16, 16, 16 }; -static dsp_interrupt_t dsp_interrupt[12] = { +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"}, @@ -474,56 +697,141 @@ static dsp_interrupt_t dsp_interrupt[12] {DSP_INTER_SSI_TRX_DATA , 0x10, 2, "SSI tramsmit"} }; +static struct { + int limit; + int count; + Uint32 inst; + Uint16 pc; +} dsp_error; + /********************************** * Emulator kernel **********************************/ -/* Yep, feel lazy, so put it there */ -static dsp_core_t *dsp_core; - -void dsp56k_init_cpu(void *th_dsp_core) +void dsp56k_init_cpu(void) { - dsp_core = th_dsp_core; -#ifdef DSP_DISASM - dsp56k_disasm_init(dsp_core); -#endif + dsp56k_disasm_init(); + isDsp_in_disasm_mode = false; start_time = SDL_GetTicks(); + memset(&dsp_error, 0, sizeof(dsp_error)); + dsp_error.limit = 1; num_inst = 0; } +/** + * Execute one instruction in trace mode at a given PC address. + * */ +Uint16 dsp56k_execute_one_disasm_instruction(FILE *out, Uint16 pc) +{ + dsp_core_t *ptr1, *ptr2; + static dsp_core_t dsp_core_save; + Uint16 instruction_length; + + ptr1 = &dsp_core; + ptr2 = &dsp_core_save; + + /* Set DSP in disasm mode */ + isDsp_in_disasm_mode = true; + + /* Save DSP context before executing instruction */ + memcpy(ptr2, ptr1, sizeof(dsp_core)); + + /* execute and disasm instruction */ + dsp_core.pc = pc; + + /* Disasm instruction */ + instruction_length = dsp56k_disasm(DSP_DISASM_MODE, out) - 1; + + /* Execute instruction at address given in parameter to get the number of cycles it takes */ + dsp56k_execute_instruction(); + + fprintf(out, "%s", dsp56k_getInstructionText()); + + /* Restore DSP context after executing instruction */ + memcpy(ptr1, ptr2, sizeof(dsp_core)); + + /* Unset DSP in disasm mode */ + isDsp_in_disasm_mode = false; + + return instruction_length; +} + void dsp56k_execute_instruction(void) { Uint32 value; - -#ifdef DSP_DISASM -#if DSP_DISASM_REG - dsp56k_disasm_reg_save(); -#endif -#if DSP_DISASM_INST - dsp56k_disasm(); -#endif -#if DSP_DISASM_MEM + Uint32 disasm_return = 0; disasm_memory_ptr = 0; -#endif -#endif + + /* Initialise the number of access to the external memory for this instruction */ + access_to_ext_memory = 0; + + /* Init the indirect AGU move instruction flag */ + dsp_core.agu_move_indirect_instr = 0; /* Decode and execute current instruction */ - cur_inst = read_memory_p(dsp_core->pc); + cur_inst = read_memory_p(dsp_core.pc); + + /* Initialize instruction size and cycle counter */ cur_inst_len = 1; - - /* Initialize instruction cycle counter */ - dsp_core->instr_cycle = 2; + dsp_core.instr_cycle = 2; + + /* Disasm current instruction ? (trace mode only) */ + if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM)) { + /* Call dsp56k_disasm only when DSP is called in trace mode */ + if (isDsp_in_disasm_mode == false) { + disasm_return = dsp56k_disasm(DSP_TRACE_MODE, TraceFile); + + if (disasm_return != 0 && LOG_TRACE_LEVEL(TRACE_DSP_DISASM_REG)) { + /* DSP regs trace enabled only if DSP DISASM is enabled */ + dsp56k_disasm_reg_save(); + } + } + } if (cur_inst < 0x100000) { value = (cur_inst >> 11) & (BITMASK(6) << 3); value += (cur_inst >> 5) & BITMASK(3); opcodes8h[value](); } else { - dsp_parmove_read(); - value = cur_inst & BITMASK(8); - opcodes_alu[value](); - dsp_parmove_write(); + /* Do parallel move read */ + opcodes_parmove[(cur_inst>>20) & BITMASK(4)](); + } + + /* Add the waitstate due to external memory access */ + /* (2 extra cycles per extra access to the external memory after the first one */ + if (access_to_ext_memory != 0) { + value = access_to_ext_memory & 1; + value += (access_to_ext_memory & 2) >> 1; + value += (access_to_ext_memory & 4) >> 2; + + if (value > 1) + dsp_core.instr_cycle += (value - 1) * 2; + } + + /* Disasm current instruction ? (trace mode only) */ + if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM)) { + /* Display only when DSP is called in trace mode */ + if (isDsp_in_disasm_mode == false) { + if (disasm_return != 0) { + fprintf(TraceFile, "%s", dsp56k_getInstructionText()); + + /* DSP regs trace enabled only if DSP DISASM is enabled */ + if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM_REG)) + dsp56k_disasm_reg_compare(TraceFile); + + if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM_MEM)) { + /* 1 memory change to display ? */ + if (disasm_memory_ptr == 1) + fprintf(TraceFile, "\t%s\n", str_disasm_memory[0]); + /* 2 memory changes to display ? */ + else if (disasm_memory_ptr == 2) { + fprintf(TraceFile, "\t%s\n", str_disasm_memory[0]); + fprintf(TraceFile, "\t%s\n", str_disasm_memory[1]); + } + } + } + } } /* Process the PC */ @@ -544,25 +852,6 @@ void dsp56k_execute_instruction(void) } } #endif - -#ifdef DSP_DISASM -#if DSP_DISASM_INST - fprintf(stderr, "%s", dsp56k_getInstructionText()); -#endif -#if DSP_DISASM_REG - dsp56k_disasm_reg_compare(); -#endif -#if DSP_DISASM_MEM - /* 1 memory change to display ? */ - if (disasm_memory_ptr == 1) - fprintf(stderr, "\t%s\n", 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]); - } -#endif -#endif } /********************************** @@ -572,50 +861,49 @@ void dsp56k_execute_instruction(void) static void dsp_postexecute_update_pc(void) { /* When running a REP, PC must stay on the current instruction */ - if (dsp_core->loop_rep) { - /* Is PC on the instruction to repeat ? */ - if (dsp_core->pc_on_rep==0) { - --dsp_core->registers[DSP_REG_LC]; - dsp_core->registers[DSP_REG_LC] &= BITMASK(16); + if (dsp_core.loop_rep) { + /* Is PC on the instruction to repeat ? */ + if (dsp_core.pc_on_rep==0) { + --dsp_core.registers[DSP_REG_LC]; + dsp_core.registers[DSP_REG_LC] &= BITMASK(16); - if (dsp_core->registers[DSP_REG_LC] > 0) { - cur_inst_len=0; /* Stay on this instruction */ + if (dsp_core.registers[DSP_REG_LC] > 0) { + cur_inst_len = 0; /* Stay on this instruction */ } else { - dsp_core->loop_rep = 0; - dsp_core->registers[DSP_REG_LC] = dsp_core->registers[DSP_REG_LCSAVE]; + dsp_core.loop_rep = 0; + dsp_core.registers[DSP_REG_LC] = dsp_core.registers[DSP_REG_LCSAVE]; } } else { /* Init LC at right value */ - if (dsp_core->registers[DSP_REG_LC] == 0) { - dsp_core->registers[DSP_REG_LC] = 0x010000; + if (dsp_core.registers[DSP_REG_LC] == 0) { + dsp_core.registers[DSP_REG_LC] = 0x010000; } - dsp_core->pc_on_rep = 0; + dsp_core.pc_on_rep = 0; } } /* Normal execution, go to next instruction */ - dsp_core->pc += cur_inst_len; + dsp_core.pc += cur_inst_len; /* When running a DO loop, we test the end of loop with the */ /* updated PC, pointing to last instruction of the loop */ - if (dsp_core->registers[DSP_REG_SR] & (1<pc == dsp_core->registers[DSP_REG_LA]+1) { - --dsp_core->registers[DSP_REG_LC]; - dsp_core->registers[DSP_REG_LC] &= BITMASK(16); - - if (dsp_core->registers[DSP_REG_LC]==0) { - /* end of loop */ + if (dsp_core.pc == dsp_core.registers[DSP_REG_LA] + 1) { + if (dsp_core.registers[DSP_REG_LC] == 1) { + /* end of the loop */ Uint32 saved_pc, saved_sr; dsp_stack_pop(&saved_pc, &saved_sr); - dsp_core->registers[DSP_REG_SR] &= 0x7f; - dsp_core->registers[DSP_REG_SR] |= saved_sr & (1<registers[DSP_REG_LA], &dsp_core->registers[DSP_REG_LC]); + dsp_core.registers[DSP_REG_SR] &= 0x7fff; + dsp_core.registers[DSP_REG_SR] |= saved_sr & (1<pc = dsp_core->registers[DSP_REG_SSH]; + --dsp_core.registers[DSP_REG_LC]; + dsp_core.registers[DSP_REG_LC] &= BITMASK(16); + dsp_core.pc = dsp_core.registers[DSP_REG_SSH]; } } } @@ -629,13 +917,13 @@ static void dsp_postexecute_update_pc(vo void dsp_add_interrupt(Uint16 inter) { /* detect if this interrupt is used or not */ - if (dsp_core->interrupt_ipl[inter] == -1) + if (dsp_core.interrupt_ipl[inter] == -1) return; /* add this interrupt to the pending interrupts table */ - if (dsp_core->interrupt_isPending[inter] == 0) { - dsp_core->interrupt_isPending[inter] = 1; - dsp_core->interrupt_counter ++; + if (dsp_core.interrupt_isPending[inter] == 0) { + dsp_core.interrupt_isPending[inter] = 1; + dsp_core.interrupt_counter ++; } } @@ -647,13 +935,13 @@ static void dsp_setInterruptIPL(Uint32 v ipl_hi = ((value >> 10) & 3) - 1; /* set IPL_HI */ - for (i=5;i<8;i++) { - dsp_core->interrupt_ipl[i] = ipl_hi; + for (i=5; i<8; i++) { + dsp_core.interrupt_ipl[i] = ipl_hi; } /* set IPL_SSI */ - for (i=8;i<12;i++) { - dsp_core->interrupt_ipl[i] = ipl_ssi; + for (i=8; i<12; i++) { + dsp_core.interrupt_ipl[i] = ipl_ssi; } } @@ -663,109 +951,112 @@ static void dsp_postexecute_interrupts(v Sint32 ipl_to_raise, ipl_sr; /* REP is not interruptible */ - if (dsp_core->loop_rep) { + if (dsp_core.loop_rep) { return; } /* A fast interrupt can not be interrupted. */ - if (dsp_core->interrupt_state == DSP_INTERRUPT_DISABLED) { + if (dsp_core.interrupt_state == DSP_INTERRUPT_DISABLED) { - switch (dsp_core->interrupt_pipeline_count) { + switch (dsp_core.interrupt_pipeline_count) { case 5: - dsp_core->interrupt_pipeline_count --; + dsp_core.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_core.interrupt_save_pc = dsp_core.pc; + dsp_core.pc = dsp_core.interrupt_instr_fetch; /* is it a LONG interrupt ? */ - instr = read_memory_p(dsp_core->interrupt_instr_fetch); + instr = read_memory_p(dsp_core.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<registers[DSP_REG_SR] |= dsp_core->interrupt_IplToRaise<interrupt_pipeline_count --; + dsp_core.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); + /* Prefetch interrupt instruction 2, if first one was single word */ + if (dsp_core.pc == dsp_core.interrupt_instr_fetch+1) { + instr = read_memory_p(dsp_core.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<registers[DSP_REG_SR] |= dsp_core->interrupt_IplToRaise<interrupt_pipeline_count --; - return; + dsp_core.interrupt_pipeline_count --; + return; + } + dsp_core.interrupt_pipeline_count --; + /* First instruction was 2 word. Fall through */ 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_core.pc == dsp_core.interrupt_instr_fetch+2) { + dsp_core.pc = dsp_core.interrupt_save_pc; } - dsp_core->interrupt_pipeline_count --; + dsp_core.interrupt_pipeline_count --; return; case 1: /* Last instruction executed after interrupt */ /* before re enable interrupts */ - dsp_core->interrupt_pipeline_count --; + dsp_core.interrupt_pipeline_count --; return; case 0: /* Re enable interrupts */ - dsp_core->interrupt_save_pc = -1; - dsp_core->interrupt_instr_fetch = -1; - dsp_core->interrupt_state = DSP_INTERRUPT_NONE; - return; + /* 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; + break; } } /* Trace Interrupt ? */ - if (dsp_core->registers[DSP_REG_SR] & (1<interrupt_counter == 0) { + if (dsp_core.interrupt_counter == 0) { return; } /* search for an interrupt */ - ipl_sr = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_I0) & BITMASK(2); + ipl_sr = (dsp_core.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_core.interrupt_isPending[i] == 1) { /* level 3 interrupt ? */ - if (dsp_core->interrupt_ipl[i] == 3) { + if (dsp_core.interrupt_ipl[i] == 3) { index = i; break; } /* level 0, 1 ,2 interrupt ? */ /* if interrupt is masked in SR, don't process it */ - if (dsp_core->interrupt_ipl[i] < ipl_sr) + if (dsp_core.interrupt_ipl[i] < ipl_sr) continue; /* if interrupt is lower or equal than current arbitrated interrupt */ - if (dsp_core->interrupt_ipl[i] <= ipl_to_raise) + if (dsp_core.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_core.interrupt_ipl[i]; } } @@ -775,42 +1066,40 @@ static void dsp_postexecute_interrupts(v } /* remove this interrupt from the pending interrupts table */ - dsp_core->interrupt_isPending[index] = 0; - dsp_core->interrupt_counter --; + dsp_core.interrupt_isPending[index] = 0; + dsp_core.interrupt_counter --; /* process arbritrated interrupt */ - ipl_to_raise = dsp_core->interrupt_ipl[index] + 1; + ipl_to_raise = dsp_core.interrupt_ipl[index] + 1; if (ipl_to_raise > 3) { ipl_to_raise = 3; } - dsp_core->interrupt_instr_fetch = dsp_interrupt[index].vectorAddr; - dsp_core->interrupt_pipeline_count = 5; - dsp_core->interrupt_state = DSP_INTERRUPT_DISABLED; - dsp_core->interrupt_IplToRaise = ipl_to_raise; - -#if DSP_DISASM_INTER - fprintf(stderr, "Dsp: Interrupt: %s\n", dsp_interrupt[index].name); -#endif + dsp_core.interrupt_instr_fetch = dsp_interrupt[index].vectorAddr; + dsp_core.interrupt_pipeline_count = 5; + dsp_core.interrupt_state = DSP_INTERRUPT_DISABLED; + dsp_core.interrupt_IplToRaise = ipl_to_raise; + + LOG_TRACE(TRACE_DSP_INTERRUPT, "Dsp interrupt: %s\n", dsp_interrupt[index].name); /* SSI receive data with exception ? */ - if (dsp_core->interrupt_instr_fetch == 0xe) { - dsp_core->periph[DSP_SPACE_X][DSP_SSI_SR] &= 0xff-(1<interrupt_instr_fetch == 0x12) { - dsp_core->periph[DSP_SPACE_X][DSP_SSI_SR] &= 0xff-(1<interrupt_instr_fetch == 0xff) { + else if (dsp_core.interrupt_instr_fetch == 0xff) { /* Clear HC and HCP interrupt */ - dsp_core->periph[DSP_SPACE_X][DSP_HOST_HSR] &= 0xff - (1<hostport[CPU_HOST_CVR] &= 0xff - (1<interrupt_instr_fetch = dsp_core->hostport[CPU_HOST_CVR] & BITMASK(5); - dsp_core->interrupt_instr_fetch *= 2; + dsp_core.interrupt_instr_fetch = dsp_core.hostport[CPU_HOST_CVR] & BITMASK(5); + dsp_core.interrupt_instr_fetch *= 2; } } @@ -822,71 +1111,67 @@ static void dsp_postexecute_interrupts(v /* reg1 has bits 47..24 */ /* reg2 has bits 23..0 */ -static void dsp_ccr_update_e_u_n_z(Uint32 *reg0, Uint32 *reg1, Uint32 *reg2) { - Uint32 scaling, value_e, value_u, numbits; +static void dsp_ccr_update_e_u_n_z(Uint32 reg0, Uint32 reg1, Uint32 reg2) +{ + Uint32 scaling, value_e, value_u; - int sr_extension = 1 << DSP_SR_E; - int sr_unnormalized; - int sr_negative = (((*reg0)>>7) & 1) << DSP_SR_N; - int sr_zero = 1 << DSP_SR_Z; - - scaling = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); - value_e = (*reg0) & 0xff; - numbits = 8; + /* Initialize SR register */ + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>DSP_SR_S0) & BITMASK(2); switch(scaling) { case 0: - value_e <<=1; - value_e |= ((*reg1)>>23) & 1; - numbits=9; - value_u = ((*reg1)>>22) & 3; + /* 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: - value_u = ((*reg0)<<1) & 2; - value_u |= ((*reg1)>>23) & 1; + /* Extension Bit (E) */ + if ((reg0 != 0) && (reg0 != BITMASK(8))) + dsp_core.registers[DSP_REG_SR] |= 1 << DSP_SR_E; + + /* Unnormalized bit (U) */ + value_u = ((reg0<<1) + (reg1>>23)) & 3; + if (value_u == 0 || value_u == 3) + dsp_core.registers[DSP_REG_SR] |= 1 << DSP_SR_U; break; case 2: - value_e <<=2; - value_e |= ((*reg1)>>22) & 3; - numbits=10; - value_u = ((*reg1)>>21) & 3; + /* Extension Bit (E) */ + value_e = (reg0<<2) + (reg1>>22); + if ((value_e != 0) && (value_e != BITMASK(10))) + dsp_core.registers[DSP_REG_SR] |= 1 << DSP_SR_E; + + /* Unnormalized bit (U) */ + if ((reg1 & 0x600000) == 0 || (reg1 & 0x600000) == 0x600000) + dsp_core.registers[DSP_REG_SR] |= 1 << DSP_SR_U; break; default: return; break; } - if ((value_e==0) || (value_e==(Uint32)BITMASK(numbits))) { - sr_extension = 0; - } + /* Zero Flag (Z) */ + if ((reg1 == 0) && (reg2 == 0) && (reg0 == 0)) + dsp_core.registers[DSP_REG_SR] |= 1 << DSP_SR_Z; - sr_unnormalized = ((value_u==0) || (value_u==BITMASK(2))) << DSP_SR_U; - if (((*reg2) & BITMASK(24))!=0) { - sr_zero = 0; - } else if (((*reg1) & BITMASK(24))!=0) { - sr_zero = 0; - } else if (((*reg0) & BITMASK(8))!=0) { - sr_zero = 0; - } - - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= sr_extension; - dsp_core->registers[DSP_REG_SR] |= sr_unnormalized; - dsp_core->registers[DSP_REG_SR] |= sr_negative; - dsp_core->registers[DSP_REG_SR] |= sr_zero; + /* Negative Flag (N) */ + dsp_core.registers[DSP_REG_SR] |= (reg0>>4) & 0x8; } /********************************** * Read/Write memory functions **********************************/ -#if defined(DSP_DISASM) && (DSP_DISASM_MEM==1) static Uint32 read_memory_disasm(int space, Uint16 address) { /* Internal RAM ? */ if (address<0x100) { - return dsp_core->ramint[space][address] & BITMASK(24); + return dsp_core.ramint[space][address] & BITMASK(24); } if (space==DSP_SPACE_P) { @@ -894,20 +1179,20 @@ static Uint32 read_memory_disasm(int spa } /* Internal ROM? */ - if ((dsp_core->registers[DSP_REG_OMR] & (1<rom[space][address] & BITMASK(24); + return dsp_core.rom[space][address] & BITMASK(24); } /* Peripheral address ? */ if (address >= 0xffc0) { - if ((space==DSP_SPACE_X) && (address==0xffc0+DSP_HOST_HRX)) { - return dsp_core->dsp_host_rtx; + if ((space==DSP_SPACE_X) && (address==0xffc0+DSP_HOST_HTX)) { + return dsp_core.dsp_host_htx; } if ((space==DSP_SPACE_X) && (address==0xffc0+DSP_SSI_TX)) { - return dsp_core->ssi.transmit_value; + return dsp_core.ssi.transmit_value; } - return dsp_core->periph[space][address-0xffc0] & BITMASK(24); + return dsp_core.periph[space][address-0xffc0] & BITMASK(24); } /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ @@ -917,20 +1202,21 @@ static Uint32 read_memory_disasm(int spa } /* Falcon: External RAM, finally map X,Y to P */ - return dsp_core->ramext[address & (DSP_RAMSIZE-1)] & BITMASK(24); + return dsp_core.ramext[address & (DSP_RAMSIZE-1)] & BITMASK(24); } -#endif static inline Uint32 read_memory_p(Uint16 address) { /* Internal RAM ? */ - if (address<0x200) { - return dsp_core->ramint[DSP_SPACE_P][address] & BITMASK(24); + if (address < 0x200) { + return dsp_core.ramint[DSP_SPACE_P][address] & BITMASK(24); } + /* Access to the external P memory */ + access_to_ext_memory |= 1 << EXT_P_MEMORY; + /* External RAM, mask address to available ram size */ -// dsp_core->instr_cycle += P_WAITSTATE; - return dsp_core->ramext[address & (DSP_RAMSIZE-1)] & BITMASK(24); + return dsp_core.ramext[address & (DSP_RAMSIZE-1)] & BITMASK(24); } static Uint32 read_memory(int space, Uint16 address) @@ -939,7 +1225,7 @@ static Uint32 read_memory(int space, Uin /* Internal RAM ? */ if (address < 0x100) { - return dsp_core->ramint[space][address] & BITMASK(24); + return dsp_core.ramint[space][address] & BITMASK(24); } if (space == DSP_SPACE_P) { @@ -948,45 +1234,54 @@ static Uint32 read_memory(int space, Uin /* Internal ROM ? */ if (address < 0x200) { - if (dsp_core->registers[DSP_REG_OMR] & (1<rom[space][address] & BITMASK(24); + if (dsp_core.registers[DSP_REG_OMR] & (1<= 0xffc0) { - value = dsp_core->periph[space][address-0xffc0] & BITMASK(24); + value = dsp_core.periph[space][address-0xffc0] & BITMASK(24); if (space == DSP_SPACE_X) { if (address == 0xffc0+DSP_HOST_HRX) { - value = dsp_core->dsp_host_rtx; - dsp_core_hostport_dspread(dsp_core); - } + value = dsp_core.dsp_host_rtx; + dsp_core_hostport_dspread(); + } else if (address == 0xffc0+DSP_SSI_RX) { - value = dsp_core_ssi_readRX(dsp_core); + value = dsp_core_ssi_readRX(); } - dsp_core->instr_cycle += XP_WAITSTATE; - } - else { - dsp_core->instr_cycle += YP_WAITSTATE; } return value; } - /* 1 more cycle for external RAM access */ - dsp_core->instr_cycle += XY_WAITSTATE; - - /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ + /* Falcon: External X or Y RAM access */ address &= (DSP_RAMSIZE>>1) - 1; if (space == DSP_SPACE_X) { + /* Map X to upper 16K of matching space in Y,P */ address += DSP_RAMSIZE>>1; + + /* Set one access to the X external memory */ + access_to_ext_memory |= 1 << EXT_X_MEMORY; } + else { + /* Access to the Y external memory */ + access_to_ext_memory |= 1 << EXT_Y_MEMORY; + } + /* Falcon: External RAM, finally map X,Y to P */ - return dsp_core->ramext[address & (DSP_RAMSIZE-1)] & BITMASK(24); + return dsp_core.ramext[address & (DSP_RAMSIZE-1)] & BITMASK(24); +} + +static inline void write_memory(int space, Uint16 address, Uint32 value) +{ + if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM_MEM)) + write_memory_disasm(space, address, value); + else + write_memory_raw(space, address, value); } -/* Note: MACRO write_memory defined to either write_memory_raw or write_memory_disasm */ static void write_memory_raw(int space, Uint16 address, Uint32 value) { value &= BITMASK(24); @@ -996,103 +1291,104 @@ static void write_memory_raw(int space, if (space == DSP_SPACE_X) { switch(address-0xffc0) { case DSP_HOST_HTX: - dsp_core->dsp_host_htx = value; - dsp_core_hostport_dspwrite(dsp_core); + dsp_core.dsp_host_htx = value; + dsp_core_hostport_dspwrite(); break; case DSP_HOST_HCR: - dsp_core->periph[DSP_SPACE_X][DSP_HOST_HCR] = value; + dsp_core.periph[DSP_SPACE_X][DSP_HOST_HCR] = value & 0x1f; /* Set HF3 and HF2 accordingly on the host side */ - dsp_core->hostport[CPU_HOST_ISR] &= + dsp_core.hostport[CPU_HOST_ISR] &= BITMASK(8)-((1<hostport[CPU_HOST_ISR] |= - dsp_core->periph[DSP_SPACE_X][DSP_HOST_HCR] & ((1<periph[DSP_SPACE_X][address-0xffc0] = value; - dsp_core_ssi_configure(dsp_core, address-0xffc0, value); + dsp_core.periph[DSP_SPACE_X][address-0xffc0] = value; + dsp_core_ssi_configure(address-0xffc0, value); break; case DSP_SSI_TSR: - dsp_core_ssi_writeTSR(dsp_core); + dsp_core_ssi_writeTSR(); break; case DSP_SSI_TX: - dsp_core_ssi_writeTX(dsp_core, value); + dsp_core_ssi_writeTX(value); break; case DSP_IPR: - dsp_core->periph[DSP_SPACE_X][DSP_IPR] = value; + dsp_core.periph[DSP_SPACE_X][DSP_IPR] = value; dsp_setInterruptIPL(value); break; case DSP_PCD: - dsp_core->periph[DSP_SPACE_X][DSP_PCD] = value; - dsp_core_setPortCDataRegister(dsp_core, value); + dsp_core.periph[DSP_SPACE_X][DSP_PCD] = value; + dsp_core_setPortCDataRegister(value); break; default: - dsp_core->periph[DSP_SPACE_X][address-0xffc0] = value; + dsp_core.periph[DSP_SPACE_X][address-0xffc0] = value; break; } - dsp_core->instr_cycle += XP_WAITSTATE; return; - } + } else if (space == DSP_SPACE_Y) { - dsp_core->periph[DSP_SPACE_Y][address-0xffc0] = value; - dsp_core->instr_cycle += YP_WAITSTATE; + dsp_core.periph[DSP_SPACE_Y][address-0xffc0] = value; return; } } - + /* Internal RAM ? */ if (address < 0x100) { - dsp_core->ramint[space][address] = value; + dsp_core.ramint[space][address] = value; return; } /* Internal ROM ? */ if (address < 0x200) { if (space != DSP_SPACE_P) { - if (dsp_core->registers[DSP_REG_OMR] & (1<ramint[DSP_SPACE_P][address] = value; + dsp_core.ramint[DSP_SPACE_P][address] = value; return; } } - /* 1 more cycle for external RAM access */ - dsp_core->instr_cycle += XY_WAITSTATE; + /* Access to X, Y or P external RAM */ - /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ - if (space != DSP_SPACE_P) { + if (space == DSP_SPACE_P) { + /* Access to the P external RAM */ + access_to_ext_memory |= 1 << EXT_P_MEMORY; + } + else { address &= (DSP_RAMSIZE>>1) - 1; - } - if (space == DSP_SPACE_X) { - address += DSP_RAMSIZE>>1; + if (space == DSP_SPACE_X) { + /* Access to the X external RAM */ + /* map X to upper 16K of matching space in Y,P */ + address += DSP_RAMSIZE>>1; + access_to_ext_memory |= 1; + } + else { + /* Access to the Y external RAM */ + access_to_ext_memory |= 1 << EXT_Y_MEMORY; + } } /* Falcon: External RAM, map X,Y to P */ - dsp_core->ramext[address & (DSP_RAMSIZE-1)] = value; + dsp_core.ramext[address & (DSP_RAMSIZE-1)] = value; } -#if defined(DSP_DISASM) && (DSP_DISASM_MEM==1) static void write_memory_disasm(int space, Uint16 address, Uint32 value) { Uint32 oldvalue, curvalue; Uint8 space_c = 'p'; value &= BITMASK(24); - - if ((address == 0xffeb) && (space == DSP_SPACE_X) ) { - oldvalue = dsp_core->dsp_host_htx; - } else { - oldvalue = read_memory_disasm(space, address); - } + oldvalue = read_memory_disasm(space, address); write_memory_raw(space,address,value); @@ -1107,62 +1403,88 @@ static void write_memory_disasm(int spac break; } - if ((address == 0xffeb) && (space == DSP_SPACE_X) ) { - curvalue = dsp_core->dsp_host_htx; - } else { - curvalue = read_memory_disasm(space, address); - } + 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 ++; } -#endif static void dsp_write_reg(Uint32 numreg, Uint32 value) { Uint32 stack_error; - if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { - numreg &= 1; - dsp_core->registers[DSP_REG_A0+numreg]= 0; - dsp_core->registers[DSP_REG_A1+numreg]= value; - dsp_core->registers[DSP_REG_A2+numreg]= 0; - if (value & (1<<23)) { - dsp_core->registers[DSP_REG_A2+numreg]= 0xff; - } - } else { - switch (numreg) { - case DSP_REG_OMR: - dsp_core->registers[DSP_REG_OMR] = value & 0xc7; - break; - case DSP_REG_SR: - dsp_core->registers[DSP_REG_SR] = value & 0xaf7f; - break; - case DSP_REG_SP: - stack_error = dsp_core->registers[DSP_REG_SP] & (1<registers[DSP_REG_SP] = value & BITMASK(6); - dsp_compute_ssh_ssl(); - break; - case DSP_REG_SSH: - dsp_stack_push(value, 0, 1); - break; - case DSP_REG_SSL: - numreg = dsp_core->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); - break; - default: - dsp_core->registers[numreg] = value; - dsp_core->registers[numreg] &= BITMASK(registers_mask[numreg]); - break; - } + switch (numreg) { + case DSP_REG_A: + dsp_core.registers[DSP_REG_A0] = 0; + dsp_core.registers[DSP_REG_A1] = value & BITMASK(24); + dsp_core.registers[DSP_REG_A2] = value & (1<<23) ? 0xff : 0x0; + break; + case DSP_REG_B: + dsp_core.registers[DSP_REG_B0] = 0; + dsp_core.registers[DSP_REG_B1] = value & BITMASK(24); + dsp_core.registers[DSP_REG_B2] = value & (1<<23) ? 0xff : 0x0; + break; + case DSP_REG_R0: + case DSP_REG_R1: + case DSP_REG_R2: + case DSP_REG_R3: + case DSP_REG_R4: + case DSP_REG_R5: + case DSP_REG_R6: + case DSP_REG_R7: + case DSP_REG_N0: + case DSP_REG_N1: + case DSP_REG_N2: + case DSP_REG_N3: + case DSP_REG_N4: + case DSP_REG_N5: + case DSP_REG_N6: + case DSP_REG_N7: + case DSP_REG_M0: + case DSP_REG_M1: + case DSP_REG_M2: + case DSP_REG_M3: + case DSP_REG_M4: + case DSP_REG_M5: + case DSP_REG_M6: + case DSP_REG_M7: + dsp_core.registers[numreg] = value & BITMASK(16); + break; + case DSP_REG_OMR: + dsp_core.registers[DSP_REG_OMR] = value & 0xc7; + break; + case DSP_REG_SR: + dsp_core.registers[DSP_REG_SR] = value & 0xaf7f; + break; + case DSP_REG_SP: + stack_error = dsp_core.registers[DSP_REG_SP] & (3<registers[DSP_REG_SP] & (1<registers[DSP_REG_SP] & (1<registers[DSP_REG_SP] & BITMASK(4)) + 1; + stack_error = dsp_core.registers[DSP_REG_SP] & (1<registers[DSP_REG_SP] = (underflow | stack_error | stack) & BITMASK(6); + + dsp_core.registers[DSP_REG_SP] = (underflow | stack_error | stack) & BITMASK(6); stack &= BITMASK(4); if (stack) { /* SSH part */ - dsp_core->stack[0][stack] = curpc & BITMASK(16); + dsp_core.stack[0][stack] = curpc & BITMASK(16); /* SSL part, if instruction is not like "MOVEC xx, SSH" */ if (sshOnly == 0) { - dsp_core->stack[1][stack] = cursr & BITMASK(16); + dsp_core.stack[1][stack] = cursr & BITMASK(16); } } else { - dsp_core->stack[0][0] = 0; - dsp_core->stack[1][0] = 0; + dsp_core.stack[0][0] = 0; + dsp_core.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_core.registers[DSP_REG_SSH] = dsp_core.stack[0][stack]; + dsp_core.registers[DSP_REG_SSL] = dsp_core.stack[1][stack]; } static void dsp_stack_pop(Uint32 *newpc, Uint32 *newsr) { Uint32 stack_error, underflow, stack; - stack_error = dsp_core->registers[DSP_REG_SP] & (1<registers[DSP_REG_SP] & (1<registers[DSP_REG_SP] & BITMASK(4)) - 1; + stack_error = dsp_core.registers[DSP_REG_SP] & (1<registers[DSP_REG_SP] = (underflow | stack_error | stack) & BITMASK(6); + dsp_core.registers[DSP_REG_SP] = (underflow | stack_error | stack) & BITMASK(6); stack &= BITMASK(4); - *newpc = dsp_core->registers[DSP_REG_SSH]; - *newsr = dsp_core->registers[DSP_REG_SSL]; + *newpc = dsp_core.registers[DSP_REG_SSH]; + *newsr = dsp_core.registers[DSP_REG_SSL]; - dsp_core->registers[DSP_REG_SSH] = dsp_core->stack[0][stack]; - dsp_core->registers[DSP_REG_SSL] = dsp_core->stack[1][stack]; + dsp_core.registers[DSP_REG_SSH] = dsp_core.stack[0][stack]; + dsp_core.registers[DSP_REG_SSL] = dsp_core.stack[1][stack]; } static void dsp_compute_ssh_ssl(void) { Uint32 stack; - stack = dsp_core->registers[DSP_REG_SP]; + stack = dsp_core.registers[DSP_REG_SP]; stack &= BITMASK(4); - dsp_core->registers[DSP_REG_SSH] = dsp_core->stack[0][stack]; - dsp_core->registers[DSP_REG_SSL] = dsp_core->stack[1][stack]; + dsp_core.registers[DSP_REG_SSH] = dsp_core.stack[0][stack]; + dsp_core.registers[DSP_REG_SSL] = dsp_core.stack[1][stack]; } /********************************** @@ -1244,21 +1572,21 @@ static void dsp_compute_ssh_ssl(void) static void dsp_update_rn(Uint32 numreg, Sint16 modifier) { - Sint16 value; + Uint32 value; Uint16 m_reg; - m_reg = (Uint16) dsp_core->registers[DSP_REG_M0+numreg]; - if (m_reg == 0) { + m_reg = (Uint16) dsp_core.registers[DSP_REG_M0+numreg]; + if (m_reg == 65535) { + /* Linear addressing mode */ + value = dsp_core.registers[DSP_REG_R0+numreg]|0x10000; + value += modifier; + dsp_core.registers[DSP_REG_R0+numreg] = value & BITMASK(16); + } else if (m_reg == 0) { /* Bit reversed carry update */ dsp_update_rn_bitreverse(numreg); } else if (m_reg<=32767) { /* Modulo update */ dsp_update_rn_modulo(numreg, modifier); - } else if (m_reg == 65535) { - /* Linear addressing mode */ - value = (Sint16) dsp_core->registers[DSP_REG_R0+numreg]; - value += modifier; - dsp_core->registers[DSP_REG_R0+numreg] = ((Uint32) value) & BITMASK(16); } else { /* Undefined */ } @@ -1270,16 +1598,16 @@ static void dsp_update_rn_bitreverse(Uin Uint32 value, r_reg; /* Check how many bits to reverse */ - value = dsp_core->registers[DSP_REG_N0+numreg]; + value = dsp_core.registers[DSP_REG_N0+numreg]; for (revbits=0;revbits<16;revbits++) { if (value & (1<registers[DSP_REG_R0+numreg]; + r_reg = dsp_core.registers[DSP_REG_R0+numreg]; value = r_reg & (BITMASK(16)-BITMASK(revbits)); for (i=0;iregisters[DSP_REG_R0+numreg] = value; + dsp_core.registers[DSP_REG_R0+numreg] = value; } static void dsp_update_rn_modulo(Uint32 numreg, Sint16 modifier) { - Uint16 bufsize, modulo, lobound, hibound, bufmask; - Sint16 r_reg, orig_modifier=modifier; + Uint16 bufsize, bufmask, modulo, abs_modifier; + Uint32 r_reg, lobound, hibound; + + r_reg = dsp_core.registers[DSP_REG_R0+numreg]|0x10000; + modulo = dsp_core.registers[DSP_REG_M0+numreg]+1; + - modulo = dsp_core->registers[DSP_REG_M0+numreg]+1; bufsize = 1; - bufmask = BITMASK(16); while (bufsize < modulo) { bufsize <<= 1; - bufmask <<= 1; } - - lobound = dsp_core->registers[DSP_REG_R0+numreg] & bufmask; + bufmask = bufsize - 1; + + + lobound = r_reg - (r_reg&bufmask); hibound = lobound + modulo - 1; - r_reg = (Sint16) dsp_core->registers[DSP_REG_R0+numreg]; - if (orig_modifier>modulo) { - while (modifier>bufsize) { - r_reg += bufsize; - modifier -= bufsize; - } - while (modifier<-bufsize) { - r_reg -= bufsize; - modifier += bufsize; - } + if (modifier<0) { + abs_modifier = -modifier; + } else { + abs_modifier = modifier; } - r_reg += modifier; - if (orig_modifier!=modulo) { + if (abs_modifier>modulo) { + if (abs_modifier&bufmask) { + fprintf(stderr,"Dsp: Modulo addressing result unpredictable\n"); + } else { + r_reg += modifier; + } + } else { + r_reg += modifier; + + if (r_reg>hibound) { r_reg -= modulo; } else if (r_regregisters[DSP_REG_R0+numreg] = ((Uint32) r_reg) & BITMASK(16); + dsp_core.registers[DSP_REG_R0+numreg] = r_reg & BITMASK(16); } static int dsp_calc_ea(Uint32 ea_mode, Uint32 *dst_addr) @@ -1356,40 +1689,40 @@ static int dsp_calc_ea(Uint32 ea_mode, U switch (value) { case 0: /* (Rx)-Nx */ - *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; - dsp_update_rn(numreg, -dsp_core->registers[DSP_REG_N0+numreg]); + *dst_addr = dsp_core.registers[DSP_REG_R0+numreg]; + dsp_update_rn(numreg, -dsp_core.registers[DSP_REG_N0+numreg]); break; case 1: /* (Rx)+Nx */ - *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; - dsp_update_rn(numreg, dsp_core->registers[DSP_REG_N0+numreg]); + *dst_addr = dsp_core.registers[DSP_REG_R0+numreg]; + dsp_update_rn(numreg, dsp_core.registers[DSP_REG_N0+numreg]); break; case 2: /* (Rx)- */ - *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; + *dst_addr = dsp_core.registers[DSP_REG_R0+numreg]; dsp_update_rn(numreg, -1); break; case 3: /* (Rx)+ */ - *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; - dsp_update_rn(numreg, +1); + *dst_addr = dsp_core.registers[DSP_REG_R0+numreg]; + dsp_update_rn(numreg, 1); break; case 4: /* (Rx) */ - *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; + *dst_addr = dsp_core.registers[DSP_REG_R0+numreg]; break; case 5: /* (Rx+Nx) */ - 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; + 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); + dsp_core.instr_cycle += 2; + *dst_addr = read_memory_p(dsp_core.pc+1); cur_inst_len++; if (numreg != 0) { return 1; /* immediate value */ @@ -1397,9 +1730,9 @@ static int dsp_calc_ea(Uint32 ea_mode, U break; case 7: /* -(Rx) */ - dsp_core->instr_cycle += 2; + dsp_core.instr_cycle += 2; dsp_update_rn(numreg, -1); - *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; + *dst_addr = dsp_core.registers[DSP_REG_R0+numreg]; break; } /* address */ @@ -1416,62 +1749,62 @@ static int dsp_calc_cc(Uint32 cc_code) switch (cc_code) { case 0: /* CC (HS) */ - value1 = dsp_core->registers[DSP_REG_SR] & (1<registers[DSP_REG_SR] >> DSP_SR_N) & 1; - value2 = (dsp_core->registers[DSP_REG_SR] >> DSP_SR_V) & 1; + value1 = (dsp_core.registers[DSP_REG_SR] >> 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<registers[DSP_REG_SR] & (1<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; + 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)) == 0); case 5: /* EC */ - value1 = dsp_core->registers[DSP_REG_SR] & (1<registers[DSP_REG_SR] & (1<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; + case 7: /* GT */ + 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)) == 0); case 8: /* CS (LO) */ - value1 = dsp_core->registers[DSP_REG_SR] & (1<registers[DSP_REG_SR] >> DSP_SR_N) & 1; - value2 = (dsp_core->registers[DSP_REG_SR] >> DSP_SR_V) & 1; + value1 = (dsp_core.registers[DSP_REG_SR] >> 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; + 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; + 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; + 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; + 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; + 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; + 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; @@ -1511,6 +1844,9 @@ static void opcode8h_0(void) case 0x00008c: dsp_enddo(); break; + default: + dsp_undefined(); + break; } } @@ -1520,8 +1856,36 @@ static void opcode8h_0(void) static void dsp_undefined(void) { - cur_inst_len = 0; - fprintf(stderr, "Dsp: 0x%04x: 0x%06x unknown instruction\n",dsp_core->pc, cur_inst); + if (isDsp_in_disasm_mode == false) { + cur_inst_len = 0; + /* Add some artificial CPU cycles to avoid being stuck in an infinite loop */ + dsp_core.instr_cycle += 100; + + /* Rate limit identical messages. Required to make + * "Terrorize your soul" demo run at usable speed + */ + dsp_error.count++; + if (cur_inst != dsp_error.inst || dsp_core.pc != dsp_error.pc || + dsp_error.count >= dsp_error.limit) { + dsp_error.inst = cur_inst; + dsp_error.pc = dsp_core.pc; + fprintf(stderr, "Dsp: 0x%04hx: 0x%06x Illegal instruction (%dx times)\n", + dsp_error.pc, dsp_error.inst, dsp_error.count); + if (dsp_error.count >= dsp_error.limit) { + /* next message after 2x more hits */ + dsp_error.limit *= 2; + } else { + dsp_error.limit = 1; + } + dsp_error.count = 0; + } + } else { + cur_inst_len = 1; + dsp_core.instr_cycle = 0; + } + if (ExceptionDebugMask & EXCEPT_DSP) { + DebugUI(REASON_DSP_EXCEPTION); + } } static void dsp_andi(void) @@ -1533,15 +1897,15 @@ static void dsp_andi(void) switch(regnum) { case 0: /* mr */ - dsp_core->registers[DSP_REG_SR] &= (value<<8)|BITMASK(8); + dsp_core.registers[DSP_REG_SR] &= (value<<8)|BITMASK(8); break; case 1: /* ccr */ - dsp_core->registers[DSP_REG_SR] &= (BITMASK(8)<<8)|value; + dsp_core.registers[DSP_REG_SR] &= (BITMASK(8)<<8)|value; break; case 2: /* omr */ - dsp_core->registers[DSP_REG_OMR] &= value; + dsp_core.registers[DSP_REG_OMR] &= value; break; } } @@ -1549,7 +1913,7 @@ static void dsp_andi(void) static void dsp_bchg_aa(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1565,19 +1929,16 @@ static void dsp_bchg_aa(void) write_memory(memspace, addr, value); /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; - if (addr>=0x200) { - dsp_core->instr_cycle += XY_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_bchg_ea(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1593,19 +1954,16 @@ static void dsp_bchg_ea(void) write_memory(memspace, addr, value); /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; - if (addr>=0x200) { - dsp_core->instr_cycle += XY_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_bchg_pp(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1621,28 +1979,23 @@ static void dsp_bchg_pp(void) write_memory(memspace, addr, value); /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; - if (memspace == DSP_SPACE_X) { - dsp_core->instr_cycle += XP_WAITSTATE; - } else { - dsp_core->instr_cycle += YP_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_bchg_reg(void) { Uint32 value, numreg, newcarry, numbit; - + numreg = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { dsp_pm_read_accu24(numreg, &value); } else { - value = dsp_core->registers[numreg]; + value = dsp_core.registers[numreg]; } newcarry = (value>>numbit) & 1; @@ -1655,16 +2008,16 @@ static void dsp_bchg_reg(void) dsp_write_reg(numreg, value); /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; + dsp_core.instr_cycle += 2; } static void dsp_bclr_aa(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; addr = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1675,19 +2028,16 @@ static void dsp_bclr_aa(void) write_memory(memspace, addr, value); /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; - if (addr>=0x200) { - dsp_core->instr_cycle += XY_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_bclr_ea(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1699,19 +2049,16 @@ static void dsp_bclr_ea(void) write_memory(memspace, addr, value); /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; - if (addr>=0x200) { - dsp_core->instr_cycle += XY_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_bclr_pp(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1723,28 +2070,23 @@ static void dsp_bclr_pp(void) write_memory(memspace, addr, value); /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; - if (memspace == DSP_SPACE_X) { - dsp_core->instr_cycle += XP_WAITSTATE; - } else { - dsp_core->instr_cycle += YP_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_bclr_reg(void) { Uint32 value, numreg, newcarry, numbit; - + numreg = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { dsp_pm_read_accu24(numreg, &value); } else { - value = dsp_core->registers[numreg]; + value = dsp_core.registers[numreg]; } newcarry = (value>>numbit) & 1; @@ -1753,16 +2095,16 @@ static void dsp_bclr_reg(void) dsp_write_reg(numreg, value); /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; + dsp_core.instr_cycle += 2; } static void dsp_bset_aa(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1774,19 +2116,16 @@ static void dsp_bset_aa(void) write_memory(memspace, addr, value); /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; - if (addr>=0x200) { - dsp_core->instr_cycle += XY_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_bset_ea(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1798,19 +2137,16 @@ static void dsp_bset_ea(void) write_memory(memspace, addr, value); /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; - if (addr>=0x200) { - dsp_core->instr_cycle += XY_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_bset_pp(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1821,28 +2157,23 @@ static void dsp_bset_pp(void) write_memory(memspace, addr, value); /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; - if (memspace == DSP_SPACE_X) { - dsp_core->instr_cycle += XP_WAITSTATE; - } else { - dsp_core->instr_cycle += YP_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_bset_reg(void) { Uint32 value, numreg, newcarry, numbit; - + numreg = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { dsp_pm_read_accu24(numreg, &value); } else { - value = dsp_core->registers[numreg]; + value = dsp_core.registers[numreg]; } newcarry = (value>>numbit) & 1; @@ -1851,16 +2182,16 @@ static void dsp_bset_reg(void) dsp_write_reg(numreg, value); /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; + dsp_core.instr_cycle += 2; } static void dsp_btst_aa(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1870,16 +2201,16 @@ static void dsp_btst_aa(void) newcarry = (value>>numbit) & 1; /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; + dsp_core.instr_cycle += 2; } static void dsp_btst_ea(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1889,16 +2220,16 @@ static void dsp_btst_ea(void) newcarry = (value>>numbit) & 1; /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; + dsp_core.instr_cycle += 2; } static void dsp_btst_pp(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1908,32 +2239,32 @@ static void dsp_btst_pp(void) newcarry = (value>>numbit) & 1; /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; + dsp_core.instr_cycle += 2; } static void dsp_btst_reg(void) { Uint32 value, numreg, newcarry, numbit; - + numreg = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { dsp_pm_read_accu24(numreg, &value); } else { - value = dsp_core->registers[numreg]; + value = dsp_core.registers[numreg]; } newcarry = (value>>numbit) & 1; /* Set carry */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; + dsp_core.instr_cycle += 2; } static void dsp_div(void) @@ -1948,18 +2279,21 @@ static void dsp_div(void) case 2: srcreg = DSP_REG_X1; break; case 3: srcreg = DSP_REG_Y1; break; } - destreg = DSP_REG_A+((cur_inst>>3) & 1); - - source[0] = 0; - source[1] = dsp_core->registers[srcreg]; - if (source[1] & (1<<23)) { - source[0] = 0xff; - } - source[2] = 0; - - dest[0] = dsp_core->registers[DSP_REG_A2+(destreg & 1)]; - dest[1] = dsp_core->registers[DSP_REG_A1+(destreg & 1)]; - dest[2] = dsp_core->registers[DSP_REG_A0+(destreg & 1)]; + 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 */ @@ -1971,16 +2305,23 @@ static void dsp_div(void) dsp_sub56(source, dest); } - dest[2] |= (dsp_core->registers[DSP_REG_SR]>>DSP_SR_C) & 1; + dest[2] |= (dsp_core.registers[DSP_REG_SR]>>DSP_SR_C) & 1; + + 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_A2+(destreg & 1)] = dest[0]; - dsp_core->registers[DSP_REG_A1+(destreg & 1)] = dest[1]; - dsp_core->registers[DSP_REG_A0+(destreg & 1)] = dest[2]; - - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= (1-((dest[0]>>7) & 1))<registers[DSP_REG_SR] |= newsr & (1<registers[DSP_REG_SR] |= newsr & (1<>7) & 1))<registers[DSP_REG_LA], dsp_core->registers[DSP_REG_LC], 0); - dsp_core->registers[DSP_REG_LA] = read_memory_p(dsp_core->pc+1) & BITMASK(16); + dsp_stack_push(dsp_core.registers[DSP_REG_LA], dsp_core.registers[DSP_REG_LC], 0); + dsp_core.registers[DSP_REG_LA] = read_memory_p(dsp_core.pc+1) & BITMASK(16); cur_inst_len++; - dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR], 0); - dsp_core->registers[DSP_REG_SR] |= (1<>6) & 1; addr = (cur_inst>>8) & BITMASK(6); - dsp_core->registers[DSP_REG_LC] = read_memory(memspace, addr) & BITMASK(16); + dsp_core.registers[DSP_REG_LC] = read_memory(memspace, addr) & BITMASK(16); - dsp_core->instr_cycle += 4; + dsp_core.instr_cycle += 4; } static void dsp_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); + 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<registers[DSP_REG_LC] = ((cur_inst>>8) & BITMASK(8)) + dsp_core.registers[DSP_REG_LC] = ((cur_inst>>8) & BITMASK(8)) + ((cur_inst & BITMASK(4))<<8); - dsp_core->instr_cycle += 4; + dsp_core.instr_cycle += 4; } static void dsp_do_ea(void) @@ -2035,18 +2376,18 @@ static void dsp_do_ea(void) /* 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); + dsp_stack_push(dsp_core.registers[DSP_REG_LA], dsp_core.registers[DSP_REG_LC], 0); + dsp_core.registers[DSP_REG_LA] = read_memory_p(dsp_core.pc+1) & BITMASK(16); cur_inst_len++; - dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR], 0); - dsp_core->registers[DSP_REG_SR] |= (1<>6) & 1; ea_mode = (cur_inst>>8) & BITMASK(6); dsp_calc_ea(ea_mode, &addr); - dsp_core->registers[DSP_REG_LC] = read_memory(memspace, addr) & BITMASK(16); + dsp_core.registers[DSP_REG_LC] = read_memory(memspace, addr) & BITMASK(16); - dsp_core->instr_cycle += 4; + dsp_core.instr_cycle += 4; } static void dsp_do_reg(void) @@ -2055,22 +2396,22 @@ static void dsp_do_reg(void) /* 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); + dsp_stack_push(dsp_core.registers[DSP_REG_LA], dsp_core.registers[DSP_REG_LC], 0); + dsp_core.registers[DSP_REG_LA] = read_memory_p(dsp_core.pc+1) & BITMASK(16); cur_inst_len++; numreg = (cur_inst>>8) & BITMASK(6); if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &dsp_core->registers[DSP_REG_LC]); + dsp_pm_read_accu24(numreg, &dsp_core.registers[DSP_REG_LC]); } else { - dsp_core->registers[DSP_REG_LC] = dsp_core->registers[numreg]; + dsp_core.registers[DSP_REG_LC] = dsp_core.registers[numreg]; } - dsp_core->registers[DSP_REG_LC] &= BITMASK(16); + dsp_core.registers[DSP_REG_LC] &= BITMASK(16); - dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR], 0); - dsp_core->registers[DSP_REG_SR] |= (1<instr_cycle += 4; + dsp_core.instr_cycle += 4; } static void dsp_enddo(void) @@ -2078,15 +2419,18 @@ static void dsp_enddo(void) Uint32 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_LA], &dsp_core->registers[DSP_REG_LC]); + dsp_core.registers[DSP_REG_SR] &= 0x7f; + dsp_core.registers[DSP_REG_SR] |= saved_sr & (1<>12) & BITMASK(4); if (dsp_calc_cc(cc_code)) { - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; } - dsp_core->instr_cycle += 2; - if (newpc >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_jcc_ea(void) @@ -2114,112 +2455,97 @@ static void dsp_jcc_ea(void) cc_code=cur_inst & BITMASK(4); if (dsp_calc_cc(cc_code)) { - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; } - dsp_core->instr_cycle += 2; - if (newpc >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_jclr_aa(void) { Uint32 memspace, addr, value, numbit, newaddr; - + memspace = (cur_inst>>6) & 1; addr = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); value = read_memory(memspace, addr); - newaddr = read_memory_p(dsp_core->pc+1); + newaddr = read_memory_p(dsp_core.pc+1); - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + dsp_core.instr_cycle += 4; if ((value & (1<pc = newaddr; + dsp_core.pc = newaddr; cur_inst_len = 0; return; - } + } ++cur_inst_len; } static void dsp_jclr_ea(void) { Uint32 memspace, addr, value, numbit, newaddr; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); - newaddr = read_memory_p(dsp_core->pc+1); - + newaddr = read_memory_p(dsp_core.pc+1); + dsp_calc_ea(value, &addr); value = read_memory(memspace, addr); - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + dsp_core.instr_cycle += 4; if ((value & (1<pc = newaddr; + dsp_core.pc = newaddr; cur_inst_len = 0; return; - } + } ++cur_inst_len; } static void dsp_jclr_pp(void) { Uint32 memspace, addr, value, numbit, newaddr; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); addr = 0xffc0 + value; value = read_memory(memspace, addr); - newaddr = read_memory_p(dsp_core->pc+1); + newaddr = read_memory_p(dsp_core.pc+1); - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + dsp_core.instr_cycle += 4; if ((value & (1<pc = newaddr; + dsp_core.pc = newaddr; cur_inst_len = 0; return; - } + } ++cur_inst_len; } static void dsp_jclr_reg(void) { Uint32 value, numreg, numbit, newaddr; - + numreg = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); - newaddr = read_memory_p(dsp_core->pc+1); + newaddr = read_memory_p(dsp_core.pc+1); if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { dsp_pm_read_accu24(numreg, &value); } else { - value = dsp_core->registers[numreg]; + value = dsp_core.registers[numreg]; } - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + dsp_core.instr_cycle += 4; if ((value & (1<pc = newaddr; + dsp_core.pc = newaddr; cur_inst_len = 0; return; - } + } ++cur_inst_len; } @@ -2229,12 +2555,9 @@ static void dsp_jmp_ea(void) dsp_calc_ea((cur_inst>>8) & BITMASK(6), &newpc); cur_inst_len = 0; - dsp_core->pc = newpc; + dsp_core.pc = newpc; - dsp_core->instr_cycle += 2; - if (newpc >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_jmp_imm(void) @@ -2243,12 +2566,9 @@ static void dsp_jmp_imm(void) newpc = cur_inst & BITMASK(12); cur_inst_len = 0; - dsp_core->pc = newpc; + dsp_core.pc = newpc; - dsp_core->instr_cycle += 2; - if (newpc >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_jscc_ea(void) @@ -2259,15 +2579,12 @@ static void dsp_jscc_ea(void) 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; + 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; - if (newpc >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; } + + dsp_core.instr_cycle += 2; } static void dsp_jscc_imm(void) @@ -2277,222 +2594,195 @@ static void dsp_jscc_imm(void) 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; + 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; - if (newpc >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; } + + dsp_core.instr_cycle += 2; } static void dsp_jsclr_aa(void) { Uint32 memspace, addr, value, newpc, numbit, newaddr; - + memspace = (cur_inst>>6) & 1; addr = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); value = read_memory(memspace, addr); - newaddr = read_memory_p(dsp_core->pc+1); - - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } - + newaddr = read_memory_p(dsp_core.pc+1); + + dsp_core.instr_cycle += 4; + if ((value & (1<pc+2, dsp_core->registers[DSP_REG_SR], 0); + dsp_stack_push(dsp_core.pc+2, dsp_core.registers[DSP_REG_SR], 0); newpc = newaddr; - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; return; - } + } ++cur_inst_len; } static void dsp_jsclr_ea(void) { Uint32 memspace, addr, value, newpc, numbit, newaddr; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); dsp_calc_ea(value, &addr); value = read_memory(memspace, addr); - newaddr = read_memory_p(dsp_core->pc+1); + newaddr = read_memory_p(dsp_core.pc+1); + + dsp_core.instr_cycle += 4; - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } - if ((value & (1<pc+2, dsp_core->registers[DSP_REG_SR], 0); + dsp_stack_push(dsp_core.pc+2, dsp_core.registers[DSP_REG_SR], 0); newpc = newaddr; - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; return; - } + } ++cur_inst_len; } static void dsp_jsclr_pp(void) { Uint32 memspace, addr, value, newpc, numbit, newaddr; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); addr = 0xffc0 + value; value = read_memory(memspace, addr); - newaddr = read_memory_p(dsp_core->pc+1); + newaddr = read_memory_p(dsp_core.pc+1); + + dsp_core.instr_cycle += 4; - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } - if ((value & (1<pc+2, dsp_core->registers[DSP_REG_SR], 0); + dsp_stack_push(dsp_core.pc+2, dsp_core.registers[DSP_REG_SR], 0); newpc = newaddr; - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; return; - } + } ++cur_inst_len; } static void dsp_jsclr_reg(void) { Uint32 value, numreg, newpc, numbit, newaddr; - + numreg = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); - newaddr = read_memory_p(dsp_core->pc+1); + newaddr = read_memory_p(dsp_core.pc+1); if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { dsp_pm_read_accu24(numreg, &value); } else { - value = dsp_core->registers[numreg]; + value = dsp_core.registers[numreg]; } - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } - + dsp_core.instr_cycle += 4; + if ((value & (1<pc+2, dsp_core->registers[DSP_REG_SR], 0); + dsp_stack_push(dsp_core.pc+2, dsp_core.registers[DSP_REG_SR], 0); newpc = newaddr; - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; return; - } + } ++cur_inst_len; } static void dsp_jset_aa(void) { Uint32 memspace, addr, value, numbit, newpc, newaddr; - + memspace = (cur_inst>>6) & 1; addr = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); value = read_memory(memspace, addr); - newaddr = read_memory_p(dsp_core->pc+1); + newaddr = read_memory_p(dsp_core.pc+1); + + dsp_core.instr_cycle += 4; - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } - if (value & (1<pc = newpc; + dsp_core.pc = newpc; cur_inst_len=0; return; - } + } ++cur_inst_len; } static void dsp_jset_ea(void) { Uint32 memspace, addr, value, numbit, newpc, newaddr; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); dsp_calc_ea(value, &addr); value = read_memory(memspace, addr); - newaddr = read_memory_p(dsp_core->pc+1); + newaddr = read_memory_p(dsp_core.pc+1); + + dsp_core.instr_cycle += 4; - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } - if (value & (1<pc = newpc; + dsp_core.pc = newpc; cur_inst_len=0; return; - } + } ++cur_inst_len; } static void dsp_jset_pp(void) { Uint32 memspace, addr, value, numbit, newpc, newaddr; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); addr = 0xffc0 + value; value = read_memory(memspace, addr); - newaddr = read_memory_p(dsp_core->pc+1); + newaddr = read_memory_p(dsp_core.pc+1); + + dsp_core.instr_cycle += 4; - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } - if (value & (1<pc = newpc; + dsp_core.pc = newpc; cur_inst_len=0; return; - } + } ++cur_inst_len; } static void dsp_jset_reg(void) { Uint32 value, numreg, numbit, newpc, newaddr; - + numreg = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); - newaddr = read_memory_p(dsp_core->pc+1); - + newaddr = read_memory_p(dsp_core.pc+1); + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { dsp_pm_read_accu24(numreg, &value); } else { - value = dsp_core->registers[numreg]; + value = dsp_core.registers[numreg]; } - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } - + dsp_core.instr_cycle += 4; + if (value & (1<pc = newpc; + dsp_core.pc = newpc; cur_inst_len=0; return; - } + } ++cur_inst_len; } @@ -2502,20 +2792,17 @@ static void dsp_jsr_imm(void) newpc = cur_inst & BITMASK(12); - if (dsp_core->interrupt_state != DSP_INTERRUPT_LONG){ - dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR], 0); + 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.interrupt_state = DSP_INTERRUPT_DISABLED; } - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; - dsp_core->instr_cycle += 2; - if (newpc >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_jsr_ea(void) @@ -2524,125 +2811,110 @@ static void dsp_jsr_ea(void) dsp_calc_ea((cur_inst>>8) & BITMASK(6),&newpc); - if (dsp_core->interrupt_state != DSP_INTERRUPT_LONG){ - dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR], 0); + 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.interrupt_state = DSP_INTERRUPT_DISABLED; } - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; - dsp_core->instr_cycle += 2; - if (newpc >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_jsset_aa(void) { Uint32 memspace, addr, value, newpc, numbit, newaddr; - + memspace = (cur_inst>>6) & 1; addr = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); value = read_memory(memspace, addr); - newaddr = read_memory_p(dsp_core->pc+1); - - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + newaddr = read_memory_p(dsp_core.pc+1); + + dsp_core.instr_cycle += 4; if (value & (1<pc+2, dsp_core->registers[DSP_REG_SR], 0); + dsp_stack_push(dsp_core.pc+2, dsp_core.registers[DSP_REG_SR], 0); newpc = newaddr; - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; return; - } + } ++cur_inst_len; } static void dsp_jsset_ea(void) { Uint32 memspace, addr, value, newpc, numbit, newaddr; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); dsp_calc_ea(value, &addr); value = read_memory(memspace, addr); - newaddr = read_memory_p(dsp_core->pc+1); - - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + newaddr = read_memory_p(dsp_core.pc+1); + + dsp_core.instr_cycle += 4; if (value & (1<pc+2, dsp_core->registers[DSP_REG_SR], 0); + dsp_stack_push(dsp_core.pc+2, dsp_core.registers[DSP_REG_SR], 0); newpc = newaddr; - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; return; - } + } ++cur_inst_len; } static void dsp_jsset_pp(void) { Uint32 memspace, addr, value, newpc, numbit, newaddr; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); addr = 0xffc0 + value; value = read_memory(memspace, addr); - newaddr = read_memory_p(dsp_core->pc+1); + newaddr = read_memory_p(dsp_core.pc+1); - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + dsp_core.instr_cycle += 4; if (value & (1<pc+2, dsp_core->registers[DSP_REG_SR], 0); + dsp_stack_push(dsp_core.pc+2, dsp_core.registers[DSP_REG_SR], 0); newpc = newaddr; - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; return; - } + } ++cur_inst_len; } static void dsp_jsset_reg(void) { Uint32 value, numreg, newpc, numbit, newaddr; - + numreg = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); - newaddr = read_memory_p(dsp_core->pc+1); - + newaddr = read_memory_p(dsp_core.pc+1); + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { dsp_pm_read_accu24(numreg, &value); } else { - value = dsp_core->registers[numreg]; + value = dsp_core.registers[numreg]; } - dsp_core->instr_cycle += 4; - if (newaddr >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + dsp_core.instr_cycle += 4; if (value & (1<pc+2, dsp_core->registers[DSP_REG_SR], 0); + dsp_stack_push(dsp_core.pc+2, dsp_core.registers[DSP_REG_SR], 0); newpc = newaddr; - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; return; - } + } ++cur_inst_len; } @@ -2652,20 +2924,19 @@ static void dsp_lua(void) srcreg = (cur_inst>>8) & BITMASK(3); - srcsave = dsp_core->registers[DSP_REG_R0+srcreg]; + srcsave = dsp_core.registers[DSP_REG_R0+srcreg]; dsp_calc_ea((cur_inst>>8) & BITMASK(5), &value); - srcnew = dsp_core->registers[DSP_REG_R0+srcreg]; - dsp_core->registers[DSP_REG_R0+srcreg] = srcsave; + srcnew = dsp_core.registers[DSP_REG_R0+srcreg]; + dsp_core.registers[DSP_REG_R0+srcreg] = srcsave; - dstreg = cur_inst & BITMASK(3); - - if (cur_inst & (1<<3)) { - dsp_core->registers[DSP_REG_N0+dstreg] = srcnew; - } else { - dsp_core->registers[DSP_REG_R0+dstreg] = srcnew; - } - - dsp_core->instr_cycle += 2; + if (cur_inst & (1<<3)) + dstreg = DSP_REG_N0 + (cur_inst & BITMASK(3)); + else + dstreg = DSP_REG_R0 + (cur_inst & BITMASK(3)); + + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(dstreg, srcnew); + dsp_core.instr_cycle += 2; } static void dsp_movec_reg(void) @@ -2678,35 +2949,27 @@ static void dsp_movec_reg(void) numreg2 = (cur_inst>>8) & BITMASK(6); numreg1 = cur_inst & BITMASK(6); + dsp_core.agu_move_indirect_instr = 1; + if (cur_inst & (1<<15)) { /* Write D1 */ if ((numreg2 == DSP_REG_A) || (numreg2 == DSP_REG_B)) { - dsp_pm_read_accu24(numreg2, &value); + dsp_pm_read_accu24(numreg2, &value); } else { - value = dsp_core->registers[numreg2]; + 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]; + value = dsp_core.registers[numreg1]; } - if ((numreg2 == DSP_REG_A) || (numreg2 == DSP_REG_B)) { - dsp_core->registers[DSP_REG_A2+(numreg2 & 1)] = 0; - if (value & (1<<23)) { - dsp_core->registers[DSP_REG_A2+(numreg2 & 1)] = 0xff; - } - dsp_core->registers[DSP_REG_A1+(numreg2 & 1)] = value & BITMASK(24); - dsp_core->registers[DSP_REG_A0+(numreg2 & 1)] = 0; - } else { - dsp_core->registers[numreg2] = value & BITMASK(registers_mask[numreg2]); - } + dsp_write_reg(numreg2, value); } } @@ -2726,15 +2989,15 @@ static void dsp_movec_aa(void) if (cur_inst & (1<<15)) { /* Write D1 */ value = read_memory(memspace, addr); - value &= BITMASK(registers_mask[numreg]); + dsp_core.agu_move_indirect_instr = 1; dsp_write_reg(numreg, value); } else { /* Read S1 */ if (numreg == DSP_REG_SSH) { dsp_stack_pop(&value, &dummy); - } + } else { - value = dsp_core->registers[numreg]; + value = dsp_core.registers[numreg]; } write_memory(memspace, addr, value); } @@ -2747,7 +3010,7 @@ static void dsp_movec_imm(void) /* #xx,D1 */ numreg = cur_inst & BITMASK(6); value = (cur_inst>>8) & BITMASK(8); - value &= BITMASK(registers_mask[numreg]); + dsp_core.agu_move_indirect_instr = 1; dsp_write_reg(numreg, value); } @@ -2774,16 +3037,16 @@ static void dsp_movec_ea(void) } else { value = read_memory(memspace, addr); } - value &= BITMASK(registers_mask[numreg]); + dsp_core.agu_move_indirect_instr = 1; 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]; + value = dsp_core.registers[numreg]; } write_memory(memspace, addr, value); } @@ -2799,26 +3062,23 @@ static void dsp_movem_aa(void) if (cur_inst & (1<<15)) { /* Write D */ value = read_memory_p(addr); - value &= BITMASK(registers_mask[numreg]); + dsp_core.agu_move_indirect_instr = 1; dsp_write_reg(numreg, value); } else { /* Read S */ if (numreg == DSP_REG_SSH) { dsp_stack_pop(&value, &dummy); - } + } else if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &value); - } + dsp_pm_read_accu24(numreg, &value); + } else { - value = dsp_core->registers[numreg]; + value = dsp_core.registers[numreg]; } write_memory(DSP_SPACE_P, addr, value); } - dsp_core->instr_cycle += 4; - if (addr>=0x200) { - dsp_core->instr_cycle += P_WAITSTATE; - } + dsp_core.instr_cycle += 4; } static void dsp_movem_ea(void) @@ -2832,26 +3092,23 @@ static void dsp_movem_ea(void) if (cur_inst & (1<<15)) { /* Write D */ value = read_memory_p(addr); - value &= BITMASK(registers_mask[numreg]); + dsp_core.agu_move_indirect_instr = 1; dsp_write_reg(numreg, value); } else { /* Read S */ if (numreg == DSP_REG_SSH) { dsp_stack_pop(&value, &dummy); - } + } else if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &value); - } + dsp_pm_read_accu24(numreg, &value); + } else { - value = dsp_core->registers[numreg]; + value = dsp_core.registers[numreg]; } write_memory(DSP_SPACE_P, addr, value); } - dsp_core->instr_cycle += 4; - if (addr>=0x200) { - dsp_core->instr_cycle += P_WAITSTATE; - } + dsp_core.instr_cycle += 4; } static void dsp_movep_0(void) @@ -2860,7 +3117,7 @@ static void dsp_movep_0(void) /* x:pp,D */ /* S,y:pp */ /* y:pp,D */ - + Uint32 addr, memspace, numreg, value, dummy; addr = 0xffc0 + (cur_inst & BITMASK(6)); @@ -2870,23 +3127,23 @@ static void dsp_movep_0(void) if (cur_inst & (1<<15)) { /* Write pp */ if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &value); + dsp_pm_read_accu24(numreg, &value); } else if (numreg == DSP_REG_SSH) { dsp_stack_pop(&value, &dummy); } else { - value = dsp_core->registers[numreg]; + value = dsp_core.registers[numreg]; } write_memory(memspace, addr, value); } else { /* Read pp */ value = read_memory(memspace, addr); - value &= BITMASK(registers_mask[numreg]); + dsp_core.agu_move_indirect_instr = 1; dsp_write_reg(numreg, value); } - dsp_core->instr_cycle += 2; + dsp_core.instr_cycle += 2; } static void dsp_movep_1(void) @@ -2910,7 +3167,10 @@ static void dsp_movep_1(void) write_memory(DSP_SPACE_P, paddr, read_memory(memspace, xyaddr)); } - dsp_core->instr_cycle += 2; + /* Movep is 4 cycles, but according to the motorola doc, */ + /* movep from p memory to x or y peripheral memory takes */ + /* 2 more cycles, so +4 cycles at total */ + dsp_core.instr_cycle += 4; } static void dsp_movep_23(void) @@ -2931,31 +3191,25 @@ static void dsp_movep_23(void) peraddr = 0xffc0 + (cur_inst & BITMASK(6)); perspace = (cur_inst>>16) & 1; - + ea_mode = (cur_inst>>8) & BITMASK(6); easpace = (cur_inst>>6) & 1; retour = dsp_calc_ea(ea_mode, &addr); if (cur_inst & (1<<15)) { /* Write pp */ - + if (retour) { write_memory(perspace, peraddr, addr); } else { - if (peraddr>=0x200) { - dsp_core->instr_cycle += P_WAITSTATE; - } write_memory(perspace, peraddr, read_memory(easpace, addr)); } } else { /* Read pp */ - if (peraddr>=0x200) { - dsp_core->instr_cycle += P_WAITSTATE; - } write_memory(easpace, addr, read_memory(perspace, peraddr)); } - dsp_core->instr_cycle += 4; + dsp_core.instr_cycle += 2; } static void dsp_norm(void) @@ -2963,7 +3217,7 @@ static void dsp_norm(void) Uint32 cursr,cur_e, cur_euz, dest[3], numreg, rreg; Uint16 newsr; - cursr = dsp_core->registers[DSP_REG_SR]; + cursr = dsp_core.registers[DSP_REG_SR]; cur_e = (cursr>>DSP_SR_E) & 1; /* E */ cur_euz = ~cur_e; /* (not E) and U and (not Z) */ cur_euz &= (cursr>>DSP_SR_U) & 1; @@ -2971,31 +3225,31 @@ static void dsp_norm(void) cur_euz &= 1; numreg = (cur_inst>>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; + dest[0] = dsp_core.registers[DSP_REG_A2+numreg]; + dest[1] = dsp_core.registers[DSP_REG_A1+numreg]; + dest[2] = dsp_core.registers[DSP_REG_A0+numreg]; rreg = DSP_REG_R0+((cur_inst>>8) & BITMASK(3)); if (cur_euz) { newsr = dsp_asl56(dest); - --dsp_core->registers[rreg]; - dsp_core->registers[rreg] &= BITMASK(16); + --dsp_core.registers[rreg]; + dsp_core.registers[rreg] &= BITMASK(16); } else if (cur_e) { newsr = dsp_asr56(dest); - ++dsp_core->registers[rreg]; - dsp_core->registers[rreg] &= BITMASK(16); + ++dsp_core.registers[rreg]; + dsp_core.registers[rreg] &= BITMASK(16); } else { newsr = 0; } - dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_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_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= value<<8; + dsp_core.registers[DSP_REG_SR] |= value<<8; break; case 1: /* ccr */ - dsp_core->registers[DSP_REG_SR] |= value; + dsp_core.registers[DSP_REG_SR] |= value; break; case 2: /* omr */ - dsp_core->registers[DSP_REG_OMR] |= value; + dsp_core.registers[DSP_REG_OMR] |= value; break; } } @@ -3033,27 +3287,27 @@ static void dsp_rep_aa(void) { /* x:aa */ /* y:aa */ - dsp_core->registers[DSP_REG_LCSAVE] = dsp_core->registers[DSP_REG_LC]; - dsp_core->pc_on_rep = 1; /* Not decrement LC at first time */ - dsp_core->loop_rep = 1; /* We are now running rep */ + dsp_core.registers[DSP_REG_LCSAVE] = dsp_core.registers[DSP_REG_LC]; + dsp_core.pc_on_rep = 1; /* Not decrement LC at first time */ + dsp_core.loop_rep = 1; /* We are now running rep */ - dsp_core->registers[DSP_REG_LC]=read_memory((cur_inst>>6) & 1,(cur_inst>>8) & BITMASK(6)); + dsp_core.registers[DSP_REG_LC]=read_memory((cur_inst>>6) & 1,(cur_inst>>8) & BITMASK(6)); - dsp_core->instr_cycle += 2; + dsp_core.instr_cycle += 2; } static void dsp_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_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)) + dsp_core.registers[DSP_REG_LC] = ((cur_inst>>8) & BITMASK(8)) + ((cur_inst & BITMASK(4))<<8); - dsp_core->instr_cycle += 2; + dsp_core.instr_cycle += 2; } static void dsp_rep_ea(void) @@ -3063,14 +3317,14 @@ static void dsp_rep_ea(void) /* 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_core.registers[DSP_REG_LCSAVE] = dsp_core.registers[DSP_REG_LC]; + dsp_core.pc_on_rep = 1; /* Not decrement LC at first time */ + dsp_core.loop_rep = 1; /* We are now running rep */ dsp_calc_ea((cur_inst>>8) & BITMASK(6),&value); - dsp_core->registers[DSP_REG_LC]= read_memory((cur_inst>>6) & 1, value); + dsp_core.registers[DSP_REG_LC]= read_memory((cur_inst>>6) & 1, value); - dsp_core->instr_cycle += 2; + dsp_core.instr_cycle += 2; } static void dsp_rep_reg(void) @@ -3079,25 +3333,62 @@ static void dsp_rep_reg(void) /* 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 */ + dsp_core.registers[DSP_REG_LCSAVE] = dsp_core.registers[DSP_REG_LC]; + dsp_core.pc_on_rep = 1; /* Not decrement LC at first time */ + dsp_core.loop_rep = 1; /* We are now running rep */ numreg = (cur_inst>>8) & BITMASK(6); if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &dsp_core->registers[DSP_REG_LC]); + dsp_pm_read_accu24(numreg, &dsp_core.registers[DSP_REG_LC]); } else { - dsp_core->registers[DSP_REG_LC] = dsp_core->registers[numreg]; + dsp_core.registers[DSP_REG_LC] = dsp_core.registers[numreg]; } - dsp_core->registers[DSP_REG_LC] &= BITMASK(16); + dsp_core.registers[DSP_REG_LC] &= BITMASK(16); - dsp_core->instr_cycle += 2; + dsp_core.instr_cycle += 2; } static void dsp_reset(void) { - /* Reset external peripherals */ - dsp_core->instr_cycle += 2; + /* Clear the IPR register */ + write_memory(DSP_SPACE_X, 0xffc0 + DSP_IPR, 0); + + /* Software reset all on-chip peripherals */ + + /* HOST_HCR x:$FFE8 : clear the full register */ + write_memory(DSP_SPACE_X, 0xffc0 + DSP_HOST_HCR, 0); + + /* HOST_ICR $0 : clear the full register */ + dsp_core_write_host(CPU_HOST_ICR, 0); + + /* HOST_CVR $1 : set the register to $12 */ + dsp_core_write_host(CPU_HOST_CVR, 0x12); + + /* HOST_ISR $2 : set the bits TRDY and TXDE 1, other bits to 0 */ + dsp_core.hostport[CPU_HOST_ISR] = (1<pc = newpc; - dsp_core->registers[DSP_REG_SR] = newsr; + dsp_core.pc = newpc; + dsp_core.registers[DSP_REG_SR] = newsr; cur_inst_len = 0; - dsp_core->instr_cycle += 2; - if (newpc >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_rts(void) @@ -3120,32 +3408,28 @@ static void dsp_rts(void) Uint32 newpc = 0, newsr; dsp_stack_pop(&newpc, &newsr); - dsp_core->pc = newpc; + dsp_core.pc = newpc; cur_inst_len = 0; - dsp_core->instr_cycle += 2; - if (newpc >= 0x200) { - dsp_core->instr_cycle += 2*P_WAITSTATE; - } + dsp_core.instr_cycle += 2; } static void dsp_stop(void) { -#if DSP_DISASM_STATE - fprintf(stderr, "Dsp: STOP instruction\n"); -#endif + LOG_TRACE(TRACE_DSP_STATE, "Dsp: STOP instruction\n"); } static void dsp_swi(void) { /* Raise interrupt p:0x0006 */ - dsp_core->instr_cycle += 6; + dsp_core.instr_cycle += 6; } static void dsp_tcc(void) { - Uint32 cc_code, regsrc1, regdest1, value; + Uint32 cc_code, regsrc1, regdest1; Uint32 regsrc2, regdest2; + Uint32 val0, val1, val2; cc_code = (cur_inst>>12) & BITMASK(4); @@ -3154,109 +3438,62 @@ static void dsp_tcc(void) regdest1 = registers_tcc[(cur_inst>>3) & BITMASK(4)][1]; /* Read S1 */ - if ((regsrc1 == DSP_REG_A) || (regsrc1 == DSP_REG_B)) { - tmp_parmove_src[0][0]=dsp_core->registers[DSP_REG_A2+(regsrc1 & 1)]; - tmp_parmove_src[0][1]=dsp_core->registers[DSP_REG_A1+(regsrc1 & 1)]; - tmp_parmove_src[0][2]=dsp_core->registers[DSP_REG_A0+(regsrc1 & 1)]; - } else { - value = dsp_core->registers[regsrc1]; - tmp_parmove_src[0][0]=0; - if (value & (1<<23)) { - tmp_parmove_src[0][0]=0x0000ff; - } - tmp_parmove_src[0][1]=value; - tmp_parmove_src[0][2]=0; + if (regsrc1 == DSP_REG_A) { + val0 = dsp_core.registers[DSP_REG_A0]; + val1 = dsp_core.registers[DSP_REG_A1]; + val2 = dsp_core.registers[DSP_REG_A2]; + } + else if (regsrc1 == DSP_REG_B) { + val0 = dsp_core.registers[DSP_REG_B0]; + val1 = dsp_core.registers[DSP_REG_B1]; + val2 = dsp_core.registers[DSP_REG_B2]; + } + else { + val0 = 0; + val1 = dsp_core.registers[regsrc1]; + val2 = val1 & (1<<23) ? 0xff : 0x0; } - + /* Write D1 */ - dsp_core->registers[DSP_REG_A2+(regdest1 & 1)]=tmp_parmove_src[0][0]; - dsp_core->registers[DSP_REG_A1+(regdest1 & 1)]=tmp_parmove_src[0][1]; - dsp_core->registers[DSP_REG_A0+(regdest1 & 1)]=tmp_parmove_src[0][2]; + if (regdest1 == DSP_REG_A) { + dsp_core.registers[DSP_REG_A2] = val2; + dsp_core.registers[DSP_REG_A1] = val1; + dsp_core.registers[DSP_REG_A0] = val0; + } + else { + dsp_core.registers[DSP_REG_B2] = val2; + dsp_core.registers[DSP_REG_B1] = val1; + dsp_core.registers[DSP_REG_B0] = val0; + } /* S2,D2 transfer */ if (cur_inst & (1<<16)) { regsrc2 = DSP_REG_R0+((cur_inst>>8) & BITMASK(3)); regdest2 = DSP_REG_R0+(cur_inst & BITMASK(3)); - dsp_core->registers[regdest2] = dsp_core->registers[regsrc2]; + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(regdest2, dsp_core.registers[regsrc2]); } } } static void dsp_wait(void) { -#if DSP_DISASM_STATE - fprintf(stderr, "Dsp: WAIT instruction\n"); -#endif -} - -/********************************** - * Parallel moves instructions dispatcher - **********************************/ - -static void dsp_parmove_read(void) -{ - Uint32 value; - - tmp_parmove_len[0] = tmp_parmove_len[1] = 0; - - /* Calculate needed parallel moves */ - value = (cur_inst >> 20) & BITMASK(4); - - /* Do parallel move read */ - opcodes_parmove[value](); -} - -static void dsp_pm_class2(void) { - Uint32 value; - - dsp_pm_0(); - value = cur_inst & BITMASK(8); - opcodes_alu[value](); - dsp_parmove_write(); -} - -static void dsp_parmove_write(void) -{ - Uint32 i,j; - - for(i=0;i<2;i++) { - if (tmp_parmove_len[i]==0) { - continue; - } - - /* Do parallel move write */ - for ( - j=tmp_parmove_start[i]; - jregisters[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); + 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]; + value = (dsp_core.registers[DSP_REG_A2+reg]) << 24; + value += dsp_core.registers[DSP_REG_A1+reg]; switch(scaling) { case 0: @@ -3269,199 +3506,157 @@ static int dsp_pm_read_accu24(int numreg case 2: /* scaling up */ value <<= 1; - value |= (dsp_core->registers[DSP_REG_A0+reg]>>23) & 1; + value |= (dsp_core.registers[DSP_REG_A0+reg]>>23) & 1; break; /* indeterminate */ - case 3: + case 3: break; } /* limiting ? */ value &= BITMASK(24); - if (dsp_core->registers[DSP_REG_A2+reg] == 0) { + 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 (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)) { + if (dsp_core.registers[DSP_REG_A2+reg] & (1<<7)) { /* Limited to maximum negative value */ *dest=0x00800000; - dsp_core->registers[DSP_REG_SR] |= (1<registers[DSP_REG_SR] |= (1<registers[DSP_REG_A2+(numreg & 1)]; - tmp_parmove_dest[position][1].host_pointer=&dsp_core->registers[DSP_REG_A1+(numreg & 1)]; - tmp_parmove_dest[position][2].host_pointer=&dsp_core->registers[DSP_REG_A0+(numreg & 1)]; - - tmp_parmove_start[position]=0; - tmp_parmove_len[position]=3; - } else { - tmp_parmove_dest[position][1].host_pointer=&dsp_core->registers[numreg]; - - tmp_parmove_start[position]=1; - tmp_parmove_len[position]=1; - } -} - static void dsp_pm_0(void) { - Uint32 memspace, dummy, numreg, value; + Uint32 memspace, numreg, addr, save_accu, save_xy0; /* 0000 100d 00mm mrrr S,x:ea x0,D 0000 100d 10mm mrrr S,y:ea y0,D */ memspace = (cur_inst>>15) & 1; numreg = (cur_inst>>16) & 1; - dsp_calc_ea((cur_inst>>8) & BITMASK(6), &dummy); + dsp_calc_ea((cur_inst>>8) & BITMASK(6), &addr); + + /* Save A or B */ + dsp_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 */ + write_memory(memspace, addr, save_accu); - /* [A|B] to [x|y]:ea */ - dsp_pm_read_accu24(numreg, &tmp_parmove_src[0][1]); - tmp_parmove_dest[0][1].dsp_address=dummy; - - tmp_parmove_start[0] = 1; - tmp_parmove_len[0] = 1; - - tmp_parmove_type[0]=1; - tmp_parmove_space[0]=memspace; - - /* [x|y]0 to [A|B] */ - value = dsp_core->registers[DSP_REG_X0+(memspace<<1)]; - if (value & (1<<23)) { - tmp_parmove_src[1][0]=0x0000ff; - } else { - tmp_parmove_src[1][0]=0x000000; - } - tmp_parmove_src[1][1]=value; - tmp_parmove_src[1][2]=0x000000; - tmp_parmove_dest[1][0].host_pointer=&dsp_core->registers[DSP_REG_A2+numreg]; - tmp_parmove_dest[1][1].host_pointer=&dsp_core->registers[DSP_REG_A1+numreg]; - tmp_parmove_dest[1][2].host_pointer=&dsp_core->registers[DSP_REG_A0+numreg]; - - tmp_parmove_start[1]=0; - tmp_parmove_len[1]=3; - tmp_parmove_type[1]=0; + /* Move [x|y]0 to [A|B] */ + dsp_core.registers[DSP_REG_A0+numreg] = 0; + dsp_core.registers[DSP_REG_A1+numreg] = save_xy0; + dsp_core.registers[DSP_REG_A2+numreg] = save_xy0 & (1<<23) ? 0xff : 0x0; } static void dsp_pm_1(void) { - Uint32 memspace, numreg, value, xy_addr, retour; + Uint32 memspace, numreg1, numreg2, value, xy_addr, retour, save_1, save_2; /* - 0001 ffdf w0mm mrrr x:ea,D1 S2,D2 + 0001 ffdf w0mm mrrr x:ea,D1 S2,D2 S1,x:ea S2,D2 #xxxxxx,D1 S2,D2 - 0001 deff w1mm mrrr S1,D1 y:ea,D2 + 0001 deff w1mm mrrr S1,D1 y:ea,D2 S1,D1 S2,y:ea S1,D1 #xxxxxx,D2 */ value = (cur_inst>>8) & BITMASK(6); - - retour = dsp_calc_ea(value, &xy_addr); - + retour = dsp_calc_ea(value, &xy_addr); memspace = (cur_inst>>14) & 1; - numreg = DSP_REG_NULL; + numreg1 = numreg2 = DSP_REG_NULL; if (memspace) { /* Y: */ switch((cur_inst>>16) & BITMASK(2)) { - case 0: numreg = DSP_REG_Y0; break; - case 1: numreg = DSP_REG_Y1; break; - case 2: numreg = DSP_REG_A; break; - case 3: numreg = DSP_REG_B; break; + case 0: numreg1 = DSP_REG_Y0; break; + case 1: numreg1 = DSP_REG_Y1; break; + case 2: numreg1 = DSP_REG_A; break; + case 3: numreg1 = DSP_REG_B; break; } } else { /* X: */ switch((cur_inst>>18) & BITMASK(2)) { - case 0: numreg = DSP_REG_X0; break; - case 1: numreg = DSP_REG_X1; break; - case 2: numreg = DSP_REG_A; break; - case 3: numreg = DSP_REG_B; break; + case 0: numreg1 = DSP_REG_X0; break; + case 1: numreg1 = DSP_REG_X1; break; + case 2: numreg1 = DSP_REG_A; break; + case 3: numreg1 = DSP_REG_B; break; } } if (cur_inst & (1<<15)) { /* Write D1 */ - - if (retour) { - value = xy_addr; - } else { - value = read_memory(memspace, xy_addr); - } - tmp_parmove_src[0][0]= 0x000000; - if (value & (1<<23)) { - tmp_parmove_src[0][0]= 0x0000ff; - } - tmp_parmove_src[0][1]= value & BITMASK(registers_mask[numreg]); - tmp_parmove_src[0][2]= 0x000000; - - dsp_pm_writereg(numreg, 0); - tmp_parmove_type[0]=0; + if (retour) + save_1 = xy_addr; + else + save_1 = read_memory(memspace, xy_addr); } else { /* Read S1 */ - - if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &tmp_parmove_src[0][1]); - } else { - tmp_parmove_src[0][1]=dsp_core->registers[numreg]; - } - - tmp_parmove_dest[0][1].dsp_address=xy_addr; - - tmp_parmove_start[0]=1; - tmp_parmove_len[0]=1; - - tmp_parmove_type[0]=1; - tmp_parmove_space[0]=memspace; + if ((numreg1==DSP_REG_A) || (numreg1==DSP_REG_B)) + dsp_pm_read_accu24(numreg1, &save_1); + else + save_1 = dsp_core.registers[numreg1]; } /* S2 */ if (memspace) { /* Y: */ - numreg = DSP_REG_A + ((cur_inst>>19) & 1); + numreg2 = DSP_REG_A + ((cur_inst>>19) & 1); } else { /* X: */ - numreg = DSP_REG_A + ((cur_inst>>17) & 1); - } - dsp_pm_read_accu24(numreg, &tmp_parmove_src[1][1]); - - /* D2 */ + numreg2 = DSP_REG_A + ((cur_inst>>17) & 1); + } + dsp_pm_read_accu24(numreg2, &save_2); + + + /* Execute parallel instruction */ + opcodes_alu[cur_inst & BITMASK(8)](); + + + /* Write parallel move values */ + if (cur_inst & (1<<15)) { + /* Write D1 */ + dsp_write_reg(numreg1, save_1); + } else { + /* Read S1 */ + write_memory(memspace, xy_addr, save_1); + } + + /* S2 -> D2 */ if (memspace) { /* Y: */ - numreg = DSP_REG_X0 + ((cur_inst>>18) & 1); + numreg2 = DSP_REG_X0 + ((cur_inst>>18) & 1); } else { /* X: */ - numreg = DSP_REG_Y0 + ((cur_inst>>16) & 1); - } - tmp_parmove_src[1][1] &= BITMASK(registers_mask[numreg]); - tmp_parmove_dest[1][1].host_pointer=&dsp_core->registers[numreg]; - - tmp_parmove_start[1]=1; - tmp_parmove_len[1]=1; - - tmp_parmove_type[1]=0; + numreg2 = DSP_REG_Y0 + ((cur_inst>>16) & 1); + } + dsp_core.registers[numreg2] = save_2; } static void dsp_pm_2(void) @@ -3474,11 +3669,15 @@ static void dsp_pm_2(void) 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; } @@ -3495,49 +3694,40 @@ static void dsp_pm_2_2(void) /* 0010 00ee eeed dddd S,D */ - Uint32 srcreg, dstreg; - + Uint32 srcreg, dstreg, save_reg; + srcreg = (cur_inst >> 13) & BITMASK(5); dstreg = (cur_inst >> 8) & BITMASK(5); - tmp_parmove_src[0][0]= - tmp_parmove_src[0][1]= - tmp_parmove_src[0][2]= 0x000000; - - if ((srcreg == DSP_REG_A) || (srcreg == DSP_REG_B)) { - /* Accu to register or accu: limited 24 bits */ - dsp_pm_read_accu24(srcreg, &tmp_parmove_src[0][1]); - tmp_parmove_src[0][1] &= BITMASK(registers_mask[dstreg]); - if (tmp_parmove_src[0][1] & (1<<23)) { - tmp_parmove_src[0][0]=0x0000ff; - } - } else { - if ((dstreg == DSP_REG_A) || (dstreg == DSP_REG_B)) { - /* Register to accu: sign extended to 56 bits */ - tmp_parmove_src[0][1]=dsp_core->registers[srcreg] & BITMASK(registers_mask[dstreg]); - if (tmp_parmove_src[0][1] & (1<<23)) { - tmp_parmove_src[0][0]=0x0000ff; - } - } else { - /* Register to register: n bits */ - tmp_parmove_src[0][1]=dsp_core->registers[srcreg] & BITMASK(registers_mask[dstreg]); - } - } - - dsp_pm_writereg(dstreg, 0); - tmp_parmove_type[0]=0; + if ((srcreg == DSP_REG_A) || (srcreg == DSP_REG_B)) + /* Accu to register: limited 24 bits */ + dsp_pm_read_accu24(srcreg, &save_reg); + else + save_reg = dsp_core.registers[srcreg]; + + /* Execute parallel instruction */ + opcodes_alu[cur_inst & BITMASK(8)](); + + /* Write reg */ + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(dstreg, save_reg); } static void dsp_pm_3(void) { - Uint32 dest, srcvalue; + Uint32 dstreg, srcvalue; /* 001d dddd iiii iiii #xx,R */ - dest = (cur_inst >> 16) & BITMASK(5); + + /* Execute parallel instruction */ + opcodes_alu[cur_inst & BITMASK(8)](); + + /* Write reg */ + dstreg = (cur_inst >> 16) & BITMASK(5); srcvalue = (cur_inst >> 8) & BITMASK(8); - switch(dest) { + switch(dstreg) { case DSP_REG_X0: case DSP_REG_X1: case DSP_REG_Y0: @@ -3548,17 +3738,8 @@ static void dsp_pm_3(void) break; } - tmp_parmove_src[0][0]=0x000000; - if ((dest == DSP_REG_A) || (dest == DSP_REG_B)) { - if (srcvalue & (1<<23)) { - tmp_parmove_src[0][0]=0x0000ff; - } - } - tmp_parmove_src[0][1]=srcvalue & BITMASK(registers_mask[dest]); - tmp_parmove_src[0][2]=0x000000; - - dsp_pm_writereg(dest, 0); - tmp_parmove_type[0]=0; + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(dstreg, srcvalue); } static void dsp_pm_4(void) @@ -3589,7 +3770,7 @@ static void dsp_pm_4(void) static void dsp_pm_4x(void) { - Uint32 value, numreg, l_addr; + Uint32 value, numreg, l_addr, save_lx, save_ly; /* 0100 l0ll w0aa aaaa l:aa,D S,l:aa @@ -3598,7 +3779,7 @@ static void dsp_pm_4x(void) */ value = (cur_inst>>8) & BITMASK(6); if (cur_inst & (1<<14)) { - dsp_calc_ea(value, &l_addr); + dsp_calc_ea(value, &l_addr); } else { l_addr = value; } @@ -3606,145 +3787,122 @@ static void dsp_pm_4x(void) numreg = (cur_inst>>16) & BITMASK(2); numreg |= (cur_inst>>17) & (1<<2); - /* 2 more cycles are needed if address is in external memory */ - if (l_addr>=0x200) { - dsp_core->instr_cycle += 2; - } - if (cur_inst & (1<<15)) { /* Write D */ - tmp_parmove_src[0][1] = read_memory(DSP_SPACE_X,l_addr); - + save_lx = read_memory(DSP_SPACE_X,l_addr); + save_ly = read_memory(DSP_SPACE_Y,l_addr); + } + else { + /* Read S */ switch(numreg) { case 0: /* A10 */ - tmp_parmove_src[1][1] = read_memory(DSP_SPACE_Y,l_addr); - dsp_pm_writereg(DSP_REG_A1, 0); - dsp_pm_writereg(DSP_REG_A0, 1); + save_lx = dsp_core.registers[DSP_REG_A1]; + save_ly = dsp_core.registers[DSP_REG_A0]; break; case 1: /* B10 */ - tmp_parmove_src[1][1] = read_memory(DSP_SPACE_Y,l_addr); - dsp_pm_writereg(DSP_REG_B1, 0); - dsp_pm_writereg(DSP_REG_B0, 1); + save_lx = dsp_core.registers[DSP_REG_B1]; + save_ly = dsp_core.registers[DSP_REG_B0]; break; case 2: /* X */ - tmp_parmove_src[1][1] = read_memory(DSP_SPACE_Y,l_addr); - dsp_pm_writereg(DSP_REG_X1, 0); - dsp_pm_writereg(DSP_REG_X0, 1); + save_lx = dsp_core.registers[DSP_REG_X1]; + save_ly = dsp_core.registers[DSP_REG_X0]; break; case 3: /* Y */ - tmp_parmove_src[1][1] = read_memory(DSP_SPACE_Y,l_addr); - dsp_pm_writereg(DSP_REG_Y1, 0); - dsp_pm_writereg(DSP_REG_Y0, 1); + save_lx = dsp_core.registers[DSP_REG_Y1]; + save_ly = dsp_core.registers[DSP_REG_Y0]; break; case 4: /* A */ - tmp_parmove_src[0][0] = (tmp_parmove_src[0][1] & (1<<23) ? 0xff : 0); - tmp_parmove_src[0][2] = read_memory(DSP_SPACE_Y,l_addr); - dsp_pm_writereg(DSP_REG_A, 0); + if (dsp_pm_read_accu24(DSP_REG_A, &save_lx)) { + /* Was limited, set lower part */ + save_ly = (save_lx & (1<<23) ? 0 : 0xffffff); + } else { + /* Not limited */ + save_ly = dsp_core.registers[DSP_REG_A0]; + } break; case 5: /* B */ - tmp_parmove_src[0][0] = (tmp_parmove_src[0][1] & (1<<23) ? 0xff : 0); - tmp_parmove_src[0][2] = read_memory(DSP_SPACE_Y,l_addr); - dsp_pm_writereg(DSP_REG_B, 0); + if (dsp_pm_read_accu24(DSP_REG_B, &save_lx)) { + /* Was limited, set lower part */ + save_ly = (save_lx & (1<<23) ? 0 : 0xffffff); + } else { + /* Not limited */ + save_ly = dsp_core.registers[DSP_REG_B0]; + } break; case 6: /* AB */ - tmp_parmove_src[0][0] = (tmp_parmove_src[0][1] & (1<<23) ? 0xff : 0); - tmp_parmove_src[0][2] = 0; - tmp_parmove_src[1][1] = read_memory(DSP_SPACE_Y,l_addr); - tmp_parmove_src[1][0] = (tmp_parmove_src[1][1] & (1<<23) ? 0xff : 0); - tmp_parmove_src[1][2] = 0; - dsp_pm_writereg(DSP_REG_A, 0); - dsp_pm_writereg(DSP_REG_B, 1); + dsp_pm_read_accu24(DSP_REG_A, &save_lx); + dsp_pm_read_accu24(DSP_REG_B, &save_ly); break; case 7: /* BA */ - tmp_parmove_src[0][0] = (tmp_parmove_src[0][1] & (1<<23) ? 0xff : 0); - tmp_parmove_src[0][2] = 0; - tmp_parmove_src[1][1] = read_memory(DSP_SPACE_Y,l_addr); - tmp_parmove_src[1][0] = (tmp_parmove_src[1][1] & (1<<23) ? 0xff : 0); - tmp_parmove_src[1][2] = 0; - dsp_pm_writereg(DSP_REG_B, 0); - dsp_pm_writereg(DSP_REG_A, 1); + dsp_pm_read_accu24(DSP_REG_B, &save_lx); + dsp_pm_read_accu24(DSP_REG_A, &save_ly); break; } + } - tmp_parmove_type[0]=0; - tmp_parmove_type[1]=0; - } else { - /* Read S */ + /* Execute parallel instruction */ + opcodes_alu[cur_inst & BITMASK(8)](); + + if (cur_inst & (1<<15)) { + /* Write D */ switch(numreg) { - case 0: - /* A10 */ - tmp_parmove_src[0][1] = dsp_core->registers[DSP_REG_A1]; - tmp_parmove_src[1][1] = dsp_core->registers[DSP_REG_A0]; + case 0: /* A10 */ + dsp_core.registers[DSP_REG_A1] = save_lx; + dsp_core.registers[DSP_REG_A0] = save_ly; break; - case 1: - /* B10 */ - tmp_parmove_src[0][1] = dsp_core->registers[DSP_REG_B1]; - tmp_parmove_src[1][1] = dsp_core->registers[DSP_REG_B0]; + case 1: /* B10 */ + dsp_core.registers[DSP_REG_B1] = save_lx; + dsp_core.registers[DSP_REG_B0] = save_ly; break; - case 2: - /* X */ - tmp_parmove_src[0][1] = dsp_core->registers[DSP_REG_X1]; - tmp_parmove_src[1][1] = dsp_core->registers[DSP_REG_X0]; + case 2: /* X */ + dsp_core.registers[DSP_REG_X1] = save_lx; + dsp_core.registers[DSP_REG_X0] = save_ly; break; - case 3: - /* Y */ - tmp_parmove_src[0][1] = dsp_core->registers[DSP_REG_Y1]; - tmp_parmove_src[1][1] = dsp_core->registers[DSP_REG_Y0]; + case 3: /* Y */ + dsp_core.registers[DSP_REG_Y1] = save_lx; + dsp_core.registers[DSP_REG_Y0] = save_ly; break; - case 4: - /* A */ - if (dsp_pm_read_accu24(DSP_REG_A, &tmp_parmove_src[0][1])) { - /* Was limited, set lower part */ - tmp_parmove_src[1][1] = (tmp_parmove_src[0][1] & (1<<23) ? 0 : 0xffffff); - } else { - /* Not limited */ - tmp_parmove_src[1][1] = dsp_core->registers[DSP_REG_A0]; - } + 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 */ - if (dsp_pm_read_accu24(DSP_REG_B, &tmp_parmove_src[0][1])) { - /* Was limited, set lower part */ - tmp_parmove_src[1][1] = (tmp_parmove_src[0][1] & (1<<23) ? 0 : 0xffffff); - } else { - /* Not limited */ - tmp_parmove_src[1][1] = dsp_core->registers[DSP_REG_B0]; - } + 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_pm_read_accu24(DSP_REG_A, &tmp_parmove_src[0][1]); - dsp_pm_read_accu24(DSP_REG_B, &tmp_parmove_src[1][1]); + 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_pm_read_accu24(DSP_REG_B, &tmp_parmove_src[0][1]); - dsp_pm_read_accu24(DSP_REG_A, &tmp_parmove_src[1][1]); + 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; } - - /* D1 */ - tmp_parmove_dest[0][1].dsp_address=l_addr; - tmp_parmove_start[0]=1; - tmp_parmove_len[0]=1; - tmp_parmove_type[0]=1; - tmp_parmove_space[0]=DSP_SPACE_X; - - /* D2 */ - tmp_parmove_dest[1][1].dsp_address=l_addr; - tmp_parmove_start[1]=1; - tmp_parmove_len[1]=1; - tmp_parmove_type[1]=1; - tmp_parmove_space[1]=DSP_SPACE_Y; + } + else { + /* Read S */ + write_memory(DSP_SPACE_X, l_addr, save_lx); + write_memory(DSP_SPACE_Y, l_addr, save_ly); } } @@ -3767,7 +3925,7 @@ static void dsp_pm_5(void) value = (cur_inst>>8) & BITMASK(6); if (cur_inst & (1<<14)) { - retour = dsp_calc_ea(value, &xy_addr); + retour = dsp_calc_ea(value, &xy_addr); } else { xy_addr = value; retour = 0; @@ -3779,37 +3937,31 @@ static void dsp_pm_5(void) if (cur_inst & (1<<15)) { /* Write D */ - - if (retour) { + if (retour) value = xy_addr; - } else { + else value = read_memory(memspace, xy_addr); - } - tmp_parmove_src[0][1]= value & BITMASK(registers_mask[numreg]); - tmp_parmove_src[0][2]= 0x000000; - tmp_parmove_src[0][0]= 0x000000; - if (value & (1<<23)) { - tmp_parmove_src[0][0]= 0x0000ff; - } - - dsp_pm_writereg(numreg, 0); - tmp_parmove_type[0]=0; - } else { + } + else { /* Read S */ + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) + dsp_pm_read_accu24(numreg, &value); + else + value = dsp_core.registers[numreg]; + } - if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &tmp_parmove_src[0][1]); - } else { - tmp_parmove_src[0][1]=dsp_core->registers[numreg]; - } - - tmp_parmove_dest[0][1].dsp_address=xy_addr; - tmp_parmove_start[0]=1; - tmp_parmove_len[0]=1; + /* Execute parallel instruction */ + opcodes_alu[cur_inst & BITMASK(8)](); - tmp_parmove_type[0]=1; - tmp_parmove_space[0]=memspace; + if (cur_inst & (1<<15)) { + /* Write D */ + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(numreg, value); + } + else { + /* Read S */ + write_memory(memspace, xy_addr, value); } } @@ -3817,9 +3969,9 @@ static void dsp_pm_8(void) { Uint32 ea1, ea2; Uint32 numreg1, numreg2; - Uint32 value, x_addr, y_addr; + Uint32 save_reg1, save_reg2, x_addr, y_addr; /* - 1wmm eeff WrrM MRRR x:ea,D1 y:ea,D2 + 1wmm eeff WrrM MRRR x:ea,D1 y:ea,D2 x:ea,D1 S2,y:ea S1,x:ea y:ea,D2 S1,x:ea S2,y:ea @@ -3842,11 +3994,6 @@ static void dsp_pm_8(void) dsp_calc_ea(ea1, &x_addr); dsp_calc_ea(ea2, &y_addr); - /* 2 more cycles are needed if X:address1 and Y:address2 are both in external memory */ - if ((x_addr>=0x200) && (y_addr>=0x200)) { - dsp_core->instr_cycle += 2; - } - switch((cur_inst>>18) & BITMASK(2)) { case 0: numreg1=DSP_REG_X0; break; case 1: numreg1=DSP_REG_X1; break; @@ -3859,59 +4006,73 @@ static void dsp_pm_8(void) case 2: numreg2=DSP_REG_A; break; case 3: numreg2=DSP_REG_B; break; } - + if (cur_inst & (1<<15)) { /* Write D1 */ - - value = read_memory(DSP_SPACE_X, x_addr); - tmp_parmove_src[0][0]= 0x000000; - if (value & (1<<23)) { - tmp_parmove_src[0][0]= 0x0000ff; - } - tmp_parmove_src[0][1]= value & BITMASK(registers_mask[numreg1]); - tmp_parmove_src[0][2]= 0x000000; - dsp_pm_writereg(numreg1, 0); - tmp_parmove_type[0]=0; + save_reg1 = read_memory(DSP_SPACE_X, x_addr); } else { /* Read S1 */ - - if ((numreg1==DSP_REG_A) || (numreg1==DSP_REG_B)) { - dsp_pm_read_accu24(numreg1, &tmp_parmove_src[0][1]); - } else { - tmp_parmove_src[0][1]=dsp_core->registers[numreg1]; - } - tmp_parmove_dest[0][1].dsp_address=x_addr; - tmp_parmove_start[0]=1; - tmp_parmove_len[0]=1; - tmp_parmove_type[0]=1; - tmp_parmove_space[0]=DSP_SPACE_X; + if ((numreg1==DSP_REG_A) || (numreg1==DSP_REG_B)) + dsp_pm_read_accu24(numreg1, &save_reg1); + else + save_reg1 = dsp_core.registers[numreg1]; } if (cur_inst & (1<<22)) { /* Write D2 */ - - value = read_memory(DSP_SPACE_Y, y_addr); - tmp_parmove_src[1][0]= 0x000000; - if (value & (1<<23)) { - tmp_parmove_src[1][0]= 0x0000ff; - } - tmp_parmove_src[1][1]= value & BITMASK(registers_mask[numreg2]); - tmp_parmove_src[1][2]= 0x000000; - dsp_pm_writereg(numreg2, 1); - tmp_parmove_type[1]=0; + save_reg2 = read_memory(DSP_SPACE_Y, y_addr); } else { /* Read S2 */ - if ((numreg2==DSP_REG_A) || (numreg2==DSP_REG_B)) { - dsp_pm_read_accu24(numreg2, &tmp_parmove_src[1][1]); - } else { - tmp_parmove_src[1][1]=dsp_core->registers[numreg2]; + if ((numreg2==DSP_REG_A) || (numreg2==DSP_REG_B)) + dsp_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 */ + write_memory(DSP_SPACE_X, x_addr, save_reg1); + } - tmp_parmove_dest[1][1].dsp_address=y_addr; - tmp_parmove_start[1]=1; - tmp_parmove_len[1]=1; - tmp_parmove_type[1]=1; - tmp_parmove_space[1]=DSP_SPACE_Y; + /* 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 */ + write_memory(DSP_SPACE_Y, y_addr, save_reg2); } } @@ -3960,7 +4121,7 @@ static Uint16 dsp_asl56(Uint32 *dest) dest[1] <<= 1; dest[1] |= (dest[2]>>23) & 1; dest[1] &= BITMASK(24); - + dest[2] <<= 1; dest[2] &= BITMASK(24); @@ -3978,15 +4139,12 @@ static Uint16 dsp_asr56(Uint32 *dest) carry = dest[2] & 1; dest[2] >>= 1; - dest[2] &= BITMASK(23); dest[2] |= (dest[1] & 1)<<23; dest[1] >>= 1; - dest[1] &= BITMASK(23); dest[1] |= (dest[0] & 1)<<23; dest[0] >>= 1; - dest[0] &= BITMASK(7); dest[0] |= (dest[0] & (1<<6))<<1; return (carry<>24) & 1); dest[0] -= source[0]+((dest[1]>>24) & 1); @@ -4052,11 +4210,11 @@ static void dsp_mul56(Uint32 source1, Ui /* Multiply: D = S1*S2 */ if (source1 & (1<<23)) { signe ^= 1; - source1 = (1<<24) - (source1 & BITMASK(24)); + source1 = (1<<24) - source1; } if (source2 & (1<<23)) { signe ^= 1; - source2 = (1<<24) - (source2 & BITMASK(24)); + source2 = (1<<24) - source2; } /* bits 0-11 * bits 0-11 */ @@ -4114,7 +4272,7 @@ static void dsp_rnd56(Uint32 *dest) rnd_const[0] = 0; /* Scaling mode S0 */ - if (dsp_core->registers[DSP_REG_SR] & (1<registers[DSP_REG_SR] & (1<>3) & 1; + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; - 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]; + overflowed = ((dest[2]==0) && (dest[1]==0) && (dest[0]==0x80)); + + dsp_abs56(dest); + + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= (overflowed<registers[DSP_REG_SR]>>DSP_SR_C) & 1; + curcarry = (dsp_core.registers[DSP_REG_SR]>>DSP_SR_C) & 1; - destreg = (cur_inst>>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + + source[2] = dsp_core.registers[DSP_REG_X0]; + source[1] = dsp_core.registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; - srcreg = (cur_inst>>4) & 1; - if (srcreg == 0) { /* X */ - source[1] = dsp_core->registers[DSP_REG_X1]; - source[2] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } + newsr = dsp_add56(source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_add56(source, dest); } - else { /* Y */ - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[2] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } + + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>DSP_SR_C) & 1; + + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + + source[2] = dsp_core.registers[DSP_REG_X0]; + source[1] = dsp_core.registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_add56(source, dest); } + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>DSP_SR_C) & 1; + + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + + source[2] = dsp_core.registers[DSP_REG_Y0]; + source[1] = dsp_core.registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + newsr = dsp_add56(source, dest); - + if (curcarry) { - source[0]=0; - source[1]=0; - source[2]=1; + source[0]=0; source[1]=0; source[2]=1; newsr |= dsp_add56(source, dest); } - dsp_core->registers[DSP_REG_A2+destreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+destreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+destreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; - - srcreg = (cur_inst>>4) & BITMASK(3); - switch(srcreg) { - case 1: /* A or B */ - srcreg = destreg ^ 1; - source[0] = dsp_core->registers[DSP_REG_A2+srcreg]; - source[1] = dsp_core->registers[DSP_REG_A1+srcreg]; - source[2] = dsp_core->registers[DSP_REG_A0+srcreg]; - break; - case 2: /* X */ - source[1] = dsp_core->registers[DSP_REG_X1]; - source[2] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 3: /* Y */ - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[2] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 4: /* X0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 5: /* Y0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 6: /* X1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 7: /* Y1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - default: - fprintf(stderr, "Dsp: source register undefined! dsp_cpu.cpp: %d\n", __LINE__); - return; + curcarry = (dsp_core.registers[DSP_REG_SR]>>DSP_SR_C) & 1; + + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + + source[2] = dsp_core.registers[DSP_REG_Y0]; + source[1] = dsp_core.registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_add56(source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_add56(source, dest); } + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+destreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+destreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+destreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + + source[0] = dsp_core.registers[DSP_REG_A2]; + source[1] = dsp_core.registers[DSP_REG_A1]; + source[2] = dsp_core.registers[DSP_REG_A0]; + + newsr = dsp_add56(source, dest); + + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; + newsr = dsp_add56(source, dest); + + dsp_core.registers[DSP_REG_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<registers[DSP_REG_A2+(numreg ^ 1)]; - source[1] = dsp_core->registers[DSP_REG_A1+(numreg ^ 1)]; - source[2] = dsp_core->registers[DSP_REG_A0+(numreg ^ 1)]; + source[0] = dsp_core.registers[DSP_REG_B2]; + source[1] = dsp_core.registers[DSP_REG_B1]; + source[2] = dsp_core.registers[DSP_REG_B0]; newsr |= dsp_add56(source, dest); - dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + newsr = dsp_asl56(dest); + + source[0] = dsp_core.registers[DSP_REG_A2]; + source[1] = dsp_core.registers[DSP_REG_A1]; + source[2] = dsp_core.registers[DSP_REG_A0]; + newsr |= dsp_add56(source, dest); + + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; - dest[0] = dsp_core->registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+(numreg ^ 1)]; - source[1] = dsp_core->registers[DSP_REG_A1+(numreg ^ 1)]; - source[2] = dsp_core->registers[DSP_REG_A0+(numreg ^ 1)]; + source[0] = dsp_core.registers[DSP_REG_B2]; + source[1] = dsp_core.registers[DSP_REG_B1]; + source[2] = dsp_core.registers[DSP_REG_B0]; newsr |= dsp_add56(source, dest); - dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>4) & BITMASK(2)) { - case 1: - srcreg=DSP_REG_Y0; - break; - case 2: - srcreg=DSP_REG_X1; - break; - case 3: - srcreg=DSP_REG_Y1; - break; - case 0: - default: - srcreg=DSP_REG_X0; - } - dstreg = DSP_REG_A1+((cur_inst>>3) & 1); + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + newsr = dsp_asr56(dest); + + source[0] = dsp_core.registers[DSP_REG_A2]; + source[1] = dsp_core.registers[DSP_REG_A1]; + source[2] = dsp_core.registers[DSP_REG_A0]; + newsr |= dsp_add56(source, dest); + + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<registers[dstreg] &= dsp_core->registers[srcreg]; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<>23) & 1)<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<>23) & 1)<>3) & 1; + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + + newsr = dsp_asl56(dest); - dest[0] = dsp_core->registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; - 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]; + newsr = dsp_asr56(dest); + + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+numreg]=0; - dsp_core->registers[DSP_REG_A1+numreg]=0; - dsp_core->registers[DSP_REG_A0+numreg]=0; +static void dsp_clr_b(void) +{ + dsp_core.registers[DSP_REG_B2] = 0; + dsp_core.registers[DSP_REG_B1] = 0; + dsp_core.registers[DSP_REG_B0] = 0; - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= (1<>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; - - srcreg = (cur_inst>>4) & BITMASK(3); - switch(srcreg) { - case 0: /* A or B */ - srcreg = destreg ^ 1; - source[0] = dsp_core->registers[DSP_REG_A2+srcreg]; - source[1] = dsp_core->registers[DSP_REG_A1+srcreg]; - source[2] = dsp_core->registers[DSP_REG_A0+srcreg]; - break; - case 4: /* X0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 5: /* Y0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 6: /* X1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 7: /* Y1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - default: - fprintf(stderr, "source register undefined! dsp_cpu.cpp: %d\n", __LINE__); - return; - } + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + + source[0] = dsp_core.registers[DSP_REG_B2]; + source[1] = dsp_core.registers[DSP_REG_B1]; + source[2] = dsp_core.registers[DSP_REG_B0]; newsr = dsp_sub56(source, dest); - dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + + source[2] = 0; + source[1] = dsp_core.registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(source, dest); + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>4) & BITMASK(3); - switch(srcreg) { - case 0: /* A or B */ - srcreg = destreg ^ 1; - source[0] = dsp_core->registers[DSP_REG_A2+srcreg]; - source[1] = dsp_core->registers[DSP_REG_A1+srcreg]; - source[2] = dsp_core->registers[DSP_REG_A0+srcreg]; - break; - case 4: /* X0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 5: /* Y0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 6: /* X1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 7: /* Y1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - default: - fprintf(stderr, "source register undefined! dsp_cpu.cpp: %d\n", __LINE__); - return; - } + source[0] = dsp_core.registers[DSP_REG_B2]; + source[1] = dsp_core.registers[DSP_REG_B1]; + source[2] = dsp_core.registers[DSP_REG_B0]; + dsp_abs56(source); + + newsr = dsp_sub56(source, dest); + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>4) & BITMASK(2)) { - case 1: - srcreg=DSP_REG_Y0; - break; - case 2: - srcreg=DSP_REG_X1; - break; - case 3: - srcreg=DSP_REG_Y1; - break; - case 0: - default: - srcreg=DSP_REG_X0; - } - dstreg = DSP_REG_A1+((cur_inst>>3) & 1); + dest[2] = dsp_core.registers[DSP_REG_A0]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[0] = dsp_core.registers[DSP_REG_A2]; + dsp_abs56(dest); + + source[2] = 0; + source[1] = dsp_core.registers[DSP_REG_X0]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + dsp_abs56(source); + + newsr = dsp_sub56(source, dest); + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1; + + dsp_core.registers[DSP_REG_A1] <<= 1; + dsp_core.registers[DSP_REG_A1] &= BITMASK(24); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<>23) & 1; + + dsp_core.registers[DSP_REG_B1] <<= 1; + dsp_core.registers[DSP_REG_B1] &= BITMASK(24); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<>= 1; + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>= 1; + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[dstreg] ^= dsp_core->registers[srcreg]; - dsp_core->registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */ + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + newsr = dsp_add56(source, dest); + + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<>3) & 1); + dsp_mul56(dsp_core.registers[DSP_REG_Y0], dsp_core.registers[DSP_REG_X0], source, SIGN_PLUS); - newcarry = (dsp_core->registers[numreg]>>23) & 1; + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + newsr = dsp_add56(source, dest); - dsp_core->registers[numreg] <<= 1; - dsp_core->registers[numreg] &= BITMASK(24); + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; - dsp_core->registers[DSP_REG_SR] |= ((dsp_core->registers[numreg]>>23) & 1)<registers[DSP_REG_SR] |= (dsp_core->registers[numreg]==0)<>3) & 1); + dsp_mul56(dsp_core.registers[DSP_REG_Y0], dsp_core.registers[DSP_REG_X0], source, SIGN_MINUS); - newcarry = dsp_core->registers[numreg] & 1; + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + newsr = dsp_add56(source, dest); - dsp_core->registers[numreg] >>= 1; - /*dsp_core->registers[numreg] &= BITMASK(24);*/ + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; - dsp_core->registers[DSP_REG_SR] |= (dsp_core->registers[numreg]==0)<>4) & BITMASK(3); - srcreg1 = registers_mpy[value][0]; - srcreg2 = registers_mpy[value][1]; + dsp_mul56(dsp_core.registers[DSP_REG_Y0], dsp_core.registers[DSP_REG_X0], source, SIGN_PLUS); + + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + newsr = dsp_add56(source, dest); + + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[srcreg1], dsp_core->registers[srcreg2], source, (cur_inst >> 2) & 1); +static void dsp_mac_m_y0_x0_b(void) +{ + Uint32 source[3], dest[3]; + Uint16 newsr; - destreg = (cur_inst>>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; + dsp_mul56(dsp_core.registers[DSP_REG_Y0], dsp_core.registers[DSP_REG_X0], source, SIGN_MINUS); + + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; newsr = dsp_add56(source, dest); - dsp_core->registers[DSP_REG_A2+destreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+destreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+destreg] = dest[2]; + dsp_core.registers[DSP_REG_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_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<>4) & BITMASK(3); - srcreg1 = registers_mpy[value][0]; - srcreg2 = registers_mpy[value][1]; + dsp_mul56(dsp_core.registers[DSP_REG_X1], dsp_core.registers[DSP_REG_Y0], source, SIGN_PLUS); + + dest[0] = dsp_core.registers[DSP_REG_A2]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + newsr = dsp_add56(source, dest); + + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_mul56(dsp_core->registers[srcreg1], dsp_core->registers[srcreg2], source, (cur_inst >> 2) & 1); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - destreg = (cur_inst>>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_A2+destreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+destreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+destreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<>4) & BITMASK(3); - srcreg1 = registers_mpy[value][0]; - srcreg2 = registers_mpy[value][1]; + dsp_mul56(dsp_core.registers[DSP_REG_X0], dsp_core.registers[DSP_REG_X0], source, SIGN_PLUS); - dsp_mul56(dsp_core->registers[srcreg1], dsp_core->registers[srcreg2], source, (cur_inst >> 2) & 1); + dsp_core.registers[DSP_REG_A2] = source[0]; + dsp_core.registers[DSP_REG_A1] = source[1]; + dsp_core.registers[DSP_REG_A0] = source[2]; - destreg = (cur_inst>>3) & 1; + dsp_ccr_update_e_u_n_z(source[0], source[1], source[2]); + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_A2+destreg] = source[0]; - dsp_core->registers[DSP_REG_A1+destreg] = source[1]; - dsp_core->registers[DSP_REG_A0+destreg] = source[2]; +static void dsp_mpy_m_x0_x0_a(void) +{ + Uint32 source[3]; - dsp_ccr_update_e_u_n_z( &dsp_core->registers[DSP_REG_A2+destreg], - &dsp_core->registers[DSP_REG_A1+destreg], - &dsp_core->registers[DSP_REG_A0+destreg]); + dsp_mul56(dsp_core.registers[DSP_REG_X0], dsp_core.registers[DSP_REG_X0], source, SIGN_MINUS); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<>4) & BITMASK(3); - srcreg1 = registers_mpy[value][0]; - srcreg2 = registers_mpy[value][1]; + dsp_mul56(dsp_core.registers[DSP_REG_X0], dsp_core.registers[DSP_REG_X0], source, SIGN_PLUS); - dsp_mul56(dsp_core->registers[srcreg1], dsp_core->registers[srcreg2], source, (cur_inst >> 2) & 1); + dsp_core.registers[DSP_REG_B2] = source[0]; + dsp_core.registers[DSP_REG_B1] = source[1]; + dsp_core.registers[DSP_REG_B0] = source[2]; - destreg = (cur_inst>>3) & 1; + dsp_ccr_update_e_u_n_z(source[0], source[1], source[2]); + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_A2+destreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+destreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+destreg] = dest[2]; + dsp_mul56(dsp_core.registers[DSP_REG_X0], dsp_core.registers[DSP_REG_X0], source, SIGN_MINUS); + + dsp_core.registers[DSP_REG_B2] = source[0]; + dsp_core.registers[DSP_REG_B1] = source[1]; + dsp_core.registers[DSP_REG_B0] = source[2]; + + dsp_ccr_update_e_u_n_z(source[0], source[1], source[2]); + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<>3) & 1; - source[0] = dsp_core->registers[DSP_REG_A2+srcreg]; - source[1] = dsp_core->registers[DSP_REG_A1+srcreg]; - source[2] = dsp_core->registers[DSP_REG_A0+srcreg]; + dsp_mul56(dsp_core.registers[DSP_REG_X0], dsp_core.registers[DSP_REG_Y1], source, SIGN_PLUS); + + dsp_core.registers[DSP_REG_B2] = source[0]; + dsp_core.registers[DSP_REG_B1] = source[1]; + dsp_core.registers[DSP_REG_B0] = source[2]; + + dsp_ccr_update_e_u_n_z(source[0], source[1], source[2]); + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_A2+srcreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+srcreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+srcreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= (overflowed<>3) & 1); + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<registers[dstreg] = ~dsp_core->registers[dstreg]; - dsp_core->registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */ +static void dsp_not_b(void) +{ + dsp_core.registers[DSP_REG_B1] = ~dsp_core.registers[DSP_REG_B1]; + dsp_core.registers[DSP_REG_B1] &= BITMASK(24); /* FIXME: useless ? */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<>23) & 1)<>4) & BITMASK(2)) { - case 1: - srcreg=DSP_REG_Y0; - break; - case 2: - srcreg=DSP_REG_X1; - break; - case 3: - srcreg=DSP_REG_Y1; - break; - case 0: - default: - srcreg=DSP_REG_X0; - } - dstreg = DSP_REG_A1+((cur_inst>>3) & 1); + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<registers[dstreg] |= dsp_core->registers[srcreg]; - dsp_core->registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */ +static void dsp_or_x0_b(void) +{ + dsp_core.registers[DSP_REG_B1] |= dsp_core.registers[DSP_REG_X0]; + dsp_core.registers[DSP_REG_B1] &= BITMASK(24); /* FIXME: useless ? */ - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<>23) & 1)<>3) & 1; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<>23) & 1)<registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); } -static void dsp_rol(void) +static void dsp_rnd_b(void) { - Uint32 dstreg, newcarry; + Uint32 dest[3]; - dstreg = DSP_REG_A1+((cur_inst>>3) & 1); + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; - newcarry = (dsp_core->registers[dstreg]>>23) & 1; + dsp_rnd56(dest); - dsp_core->registers[dstreg] <<= 1; - dsp_core->registers[dstreg] |= newcarry; - dsp_core->registers[dstreg] &= BITMASK(24); + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; - dsp_core->registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<>3) & 1); + newcarry = (dsp_core.registers[DSP_REG_A1]>>23) & 1; - newcarry = dsp_core->registers[dstreg] & 1; + dsp_core.registers[DSP_REG_A1] <<= 1; + dsp_core.registers[DSP_REG_A1] |= newcarry; + dsp_core.registers[DSP_REG_A1] &= BITMASK(24); - dsp_core->registers[dstreg] >>= 1; - dsp_core->registers[dstreg] |= newcarry<<23; - dsp_core->registers[dstreg] &= 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<registers[DSP_REG_SR] |= newcarry; - dsp_core->registers[DSP_REG_SR] |= ((dsp_core->registers[dstreg]>>23) & 1)<registers[DSP_REG_SR] |= (dsp_core->registers[dstreg]==0)<>23) & 1)<>= 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<registers[DSP_REG_SR]>>(DSP_SR_C)) & 1; + curcarry = (dsp_core.registers[DSP_REG_SR]>>(DSP_SR_C)) & 1; - destreg = (cur_inst>>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; + dest[2] = dsp_core.registers[DSP_REG_A0]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[0] = dsp_core.registers[DSP_REG_A2]; + + source[2] = dsp_core.registers[DSP_REG_X0]; + source[1] = dsp_core.registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; - srcreg = (cur_inst>>4) & 1; - if (srcreg == 0) { /* X */ - source[1] = dsp_core->registers[DSP_REG_X1]; - source[2] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } + newsr = dsp_sub56(source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_sub56(source, dest); } - else { /* Y */ - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[2] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } + + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>(DSP_SR_C)) & 1; + + dest[2] = dsp_core.registers[DSP_REG_B0]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[0] = dsp_core.registers[DSP_REG_B2]; + + source[2] = dsp_core.registers[DSP_REG_X0]; + source[1] = dsp_core.registers[DSP_REG_X1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_sub56(source, dest); } + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>(DSP_SR_C)) & 1; + + dest[2] = dsp_core.registers[DSP_REG_A0]; + dest[1] = dsp_core.registers[DSP_REG_A1]; + dest[0] = dsp_core.registers[DSP_REG_A2]; + + source[2] = dsp_core.registers[DSP_REG_Y0]; + source[1] = dsp_core.registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + newsr = dsp_sub56(source, dest); - + if (curcarry) { - source[0]=0; - source[1]=0; - source[2]=1; + source[0]=0; source[1]=0; source[2]=1; newsr |= dsp_sub56(source, dest); } - dsp_core->registers[DSP_REG_A2+destreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+destreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+destreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; - dest[0] = dsp_core->registers[DSP_REG_A2+destreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+destreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+destreg]; - - srcreg = (cur_inst>>4) & BITMASK(3); - switch(srcreg) { - case 1: /* A or B */ - srcreg = destreg ^ 1; - source[0] = dsp_core->registers[DSP_REG_A2+srcreg]; - source[1] = dsp_core->registers[DSP_REG_A1+srcreg]; - source[2] = dsp_core->registers[DSP_REG_A0+srcreg]; - break; - case 2: /* X */ - source[1] = dsp_core->registers[DSP_REG_X1]; - source[2] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 3: /* Y */ - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[2] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 4: /* X0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 5: /* Y0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 6: /* X1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 7: /* Y1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - default: - fprintf(stderr, "Dsp: source register undefined! dsp_cpu.cpp: %d\n", __LINE__); - return; + curcarry = (dsp_core.registers[DSP_REG_SR]>>(DSP_SR_C)) & 1; + + dest[2] = dsp_core.registers[DSP_REG_B0]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[0] = dsp_core.registers[DSP_REG_B2]; + + source[2] = dsp_core.registers[DSP_REG_Y0]; + source[1] = dsp_core.registers[DSP_REG_Y1]; + source[0] = source[1] & (1<<23) ? 0xff : 0x0; + + newsr = dsp_sub56(source, dest); + + if (curcarry) { + source[0]=0; source[1]=0; source[2]=1; + newsr |= dsp_sub56(source, dest); } + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+destreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+destreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+destreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; + dest[2] = dsp_core.registers[DSP_REG_B0]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[0] = dsp_core.registers[DSP_REG_B2]; + + source[2] = dsp_core.registers[DSP_REG_A0]; + source[1] = dsp_core.registers[DSP_REG_A1]; + source[0] = dsp_core.registers[DSP_REG_A2]; + + newsr = dsp_sub56(source, dest); + + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+(numreg ^ 1)]; - source[1] = dsp_core->registers[DSP_REG_A1+(numreg ^ 1)]; - source[2] = dsp_core->registers[DSP_REG_A0+(numreg ^ 1)]; + source[0] = dsp_core.registers[DSP_REG_B2]; + source[1] = dsp_core.registers[DSP_REG_B1]; + source[2] = dsp_core.registers[DSP_REG_B0]; newsr |= dsp_sub56(source, dest); - dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_core.registers[DSP_REG_A2] = dest[0]; + dsp_core.registers[DSP_REG_A1] = dest[1]; + dsp_core.registers[DSP_REG_A0] = dest[2]; - dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; + newsr = dsp_asl56(dest); + + source[0] = dsp_core.registers[DSP_REG_A2]; + source[1] = dsp_core.registers[DSP_REG_A1]; + source[2] = dsp_core.registers[DSP_REG_A0]; + newsr |= dsp_sub56(source, dest); + + dsp_core.registers[DSP_REG_B2] = dest[0]; + dsp_core.registers[DSP_REG_B1] = dest[1]; + dsp_core.registers[DSP_REG_B0] = dest[2]; + + dsp_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_A2+numreg]; - dest[1] = dsp_core->registers[DSP_REG_A1+numreg]; - dest[2] = dsp_core->registers[DSP_REG_A0+numreg]; newsr = dsp_asr56(dest); - source[0] = dsp_core->registers[DSP_REG_A2+(numreg ^ 1)]; - source[1] = dsp_core->registers[DSP_REG_A1+(numreg ^ 1)]; - source[2] = dsp_core->registers[DSP_REG_A0+(numreg ^ 1)]; + source[0] = dsp_core.registers[DSP_REG_B2]; + source[1] = dsp_core.registers[DSP_REG_B1]; + source[2] = dsp_core.registers[DSP_REG_B0]; + newsr |= dsp_sub56(source, dest); - dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; - dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; - dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + dsp_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_ccr_update_e_u_n_z(dest[0], dest[1], dest[2]); - dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>3) & 1; + dest[0] = dsp_core.registers[DSP_REG_B2]; + dest[1] = dsp_core.registers[DSP_REG_B1]; + dest[2] = dsp_core.registers[DSP_REG_B0]; - srcreg = (cur_inst>>4) & BITMASK(3); - switch(srcreg) { - case 0: /* A or B */ - srcreg = destreg ^ 1; - source[0] = dsp_core->registers[DSP_REG_A2+srcreg]; - source[1] = dsp_core->registers[DSP_REG_A1+srcreg]; - source[2] = dsp_core->registers[DSP_REG_A0+srcreg]; - break; - case 4: /* X0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 5: /* Y0 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 6: /* X1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_X1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 7: /* Y1 */ - source[2] = 0; - source[1] = dsp_core->registers[DSP_REG_Y1]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - default: - return; - } + newsr = dsp_asr56(dest); + + source[0] = dsp_core.registers[DSP_REG_A2]; + source[1] = dsp_core.registers[DSP_REG_A1]; + source[2] = dsp_core.registers[DSP_REG_A0]; - dsp_core->registers[DSP_REG_A2+destreg] = source[0]; - dsp_core->registers[DSP_REG_A1+destreg] = source[1]; - dsp_core->registers[DSP_REG_A0+destreg] = source[2]; + 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<>3) & 1; + dsp_core.registers[DSP_REG_B0] = dsp_core.registers[DSP_REG_A0]; + dsp_core.registers[DSP_REG_B1] = dsp_core.registers[DSP_REG_A1]; + dsp_core.registers[DSP_REG_B2] = dsp_core.registers[DSP_REG_A2]; +} - dsp_ccr_update_e_u_n_z( &dsp_core->registers[DSP_REG_A2+destreg], - &dsp_core->registers[DSP_REG_A1+destreg], - &dsp_core->registers[DSP_REG_A0+destreg]); +static void dsp_tfr_x0_a(void) +{ + dsp_write_reg(DSP_REG_A, dsp_core.registers[DSP_REG_X0]); +} + +static void dsp_tfr_x0_b(void) +{ + dsp_write_reg(DSP_REG_B, dsp_core.registers[DSP_REG_X0]); +} + +static void dsp_tfr_y0_a(void) +{ + dsp_write_reg(DSP_REG_A, dsp_core.registers[DSP_REG_Y0]); +} + +static void dsp_tfr_y0_b(void) +{ + dsp_write_reg(DSP_REG_B, dsp_core.registers[DSP_REG_Y0]); +} + +static void dsp_tfr_x1_a(void) +{ + dsp_write_reg(DSP_REG_A, dsp_core.registers[DSP_REG_X1]); +} + +static void dsp_tfr_x1_b(void) +{ + dsp_write_reg(DSP_REG_B, dsp_core.registers[DSP_REG_X1]); +} + +static void dsp_tfr_y1_a(void) +{ + dsp_write_reg(DSP_REG_A, dsp_core.registers[DSP_REG_Y1]); +} + +static void dsp_tfr_y1_b(void) +{ + dsp_write_reg(DSP_REG_B, dsp_core.registers[DSP_REG_Y1]); +} + +static void dsp_tst_a(void) +{ + dsp_ccr_update_e_u_n_z( dsp_core.registers[DSP_REG_A2], + dsp_core.registers[DSP_REG_A1], + dsp_core.registers[DSP_REG_A0]); + + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<