--- hatari/src/falcon/dsp_cpu.c 2019/04/01 07:13:46 1.1.1.1 +++ hatari/src/falcon/dsp_cpu.c 2019/04/09 08:47:23 1.1.1.4 @@ -1,55 +1,48 @@ /* - * Dsp56K emulation kernel - * - * ARAnyM (C) 2003 Patrice Mandin - * Adaption to Hatari (C) 2006 by Thomas Huth - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include - -#include "main.h" -#include "sysdeps.h" -#include "ioMem.h" -#include "dsp.h" -#include "dsp_cpu.h" -#ifdef DSP_DISASM -#include "dsp_disasm.h" -#endif + DSP M56001 emulation + Instructions interpreter -#define DEBUG 0 + (C) 2003-2008 ARAnyM developer team -#if DEBUG -#define D(x) x -#else -#define D(x) + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" #endif +#include "dsp_core.h" +#include "dsp_cpu.h" +#include "dsp_disasm.h" + + /* More disasm infos, if wanted */ -#define DSP_DISASM_INST 0 /* Instructions */ -#define DSP_DISASM_REG 0 /* Registers changes */ -#define DSP_DISASM_MEM 0 /* Memory changes */ -#define DSP_DISASM_STATE 0 /* State changes */ -#define DSP_DISASM_HOSTREAD 0 /* Host port read */ -#define DSP_DISASM_HOSTWRITE 0 /* Host port write */ -#define DSP_DISASM_INTER 0 /* Interrupts */ +#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 */ -/* Prevent DSP from accessing non-present memory */ -#define DSP_CHECK_MEM_ACCESS 1 +#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 @@ -57,31 +50,39 @@ #define BITMASK(x) ((1<<(x))-1) +/* 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 **********************************/ +/* Instructions per second */ +static Uint32 start_time; +static Uint32 num_inst; + /* Length of current instruction */ -static uint32 cur_inst_len; /* =0:jump, >0:increment */ +static Uint32 cur_inst_len; /* =0:jump, >0:increment */ /* Current instruction */ -static uint32 cur_inst; +static Uint32 cur_inst; /* Parallel move temp data */ -typedef union { - uint32 *host_pointer; - uint32 dsp_address; +typedef union { + Uint32 *host_pointer; + Uint32 dsp_address; } parmove_dest_u; -static uint32 tmp_parmove_src[2][3]; /* What to read */ +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 */ +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 */ -/* PC on Rep instruction ? */ -static uint32 pc_on_rep; /********************************** * Functions @@ -89,69 +90,85 @@ static uint32 pc_on_rep; typedef void (*dsp_emul_t)(void); -static void dsp_execute_instruction(void); static void dsp_postexecute_update_pc(void); static void dsp_postexecute_interrupts(void); -/* -static void dsp_host2dsp(void); -static void dsp_dsp2host(void); -*/ -static void dsp_ccr_extension(uint32 *reg0, uint32 *reg1, uint32 *reg2); -static void dsp_ccr_unnormalized(uint32 *reg0, uint32 *reg1, uint32 *reg2); -static void dsp_ccr_negative(uint32 *reg0, uint32 *reg1, uint32 *reg2); -static void dsp_ccr_zero(uint32 *reg0, uint32 *reg1, uint32 *reg2); -#if DSP_DISASM_MEM -static uint32 read_memory_disasm(int space, uint16 address); +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 Uint32 read_memory_disasm(int space, Uint16 address); +static void write_memory_disasm(int space, Uint16 address, Uint32 value); #endif -static uint32 read_memory(int space, uint16 address); -static void write_memory(int space, uint32 address, uint32 value); +static void dsp_write_reg(Uint32 numreg, Uint32 value); -static void dsp_stack_push(uint32 curpc, uint32 cursr); -static void dsp_stack_pop(uint32 *curpc, uint32 *cursr); +static void dsp_stack_push(Uint32 curpc, Uint32 cursr, Uint16 sshOnly); +static void dsp_stack_pop(Uint32 *curpc, Uint32 *cursr); +static void dsp_compute_ssh_ssl(void); static void opcode8h_0(void); -static void opcode8h_1(void); -static void opcode8h_4(void); -static void opcode8h_6(void); -static void opcode8h_8(void); -static void opcode8h_a(void); -static void opcode8h_b(void); - -static void dsp_update_rn(uint32 numreg, int16 modifier); -static void dsp_update_rn_bitreverse(uint32 numreg); -static void dsp_update_rn_modulo(uint32 numreg, int16 modifier); -static int dsp_calc_ea(uint32 ea_mode, uint32 *dst_addr); -static int dsp_calc_cc(uint32 cc_code); + +static void dsp_update_rn(Uint32 numreg, Sint16 modifier); +static void dsp_update_rn_bitreverse(Uint32 numreg); +static void dsp_update_rn_modulo(Uint32 numreg, Sint16 modifier); +static int dsp_calc_ea(Uint32 ea_mode, Uint32 *dst_addr); +static int dsp_calc_cc(Uint32 cc_code); static void dsp_undefined(void); /* Instructions without parallel moves */ static void dsp_andi(void); -static void dsp_bchg(void); -static void dsp_bclr(void); -static void dsp_bset(void); -static void dsp_btst(void); +static void dsp_bchg_aa(void); +static void dsp_bchg_ea(void); +static void dsp_bchg_pp(void); +static void dsp_bchg_reg(void); +static void dsp_bclr_aa(void); +static void dsp_bclr_ea(void); +static void dsp_bclr_pp(void); +static void dsp_bclr_reg(void); +static void dsp_bset_aa(void); +static void dsp_bset_ea(void); +static void dsp_bset_pp(void); +static void dsp_bset_reg(void); +static void dsp_btst_aa(void); +static void dsp_btst_ea(void); +static void dsp_btst_pp(void); +static void dsp_btst_reg(void); static void dsp_div(void); -static void dsp_do(void); static void dsp_enddo(void); static void dsp_illegal(void); -static void dsp_jcc(void); -static void dsp_jclr(void); -static void dsp_jmp(void); -static void dsp_jscc(void); -static void dsp_jsclr(void); -static void dsp_jset(void); -static void dsp_jsr(void); -static void dsp_jsset(void); +static void dsp_jcc_imm(void); +static void dsp_jcc_ea(void); +static void dsp_jclr_aa(void); +static void dsp_jclr_ea(void); +static void dsp_jclr_pp(void); +static void dsp_jclr_reg(void); +static void dsp_jmp_ea(void); +static void dsp_jmp_imm(void); +static void dsp_jscc_ea(void); +static void dsp_jscc_imm(void); +static void dsp_jsclr_aa(void); +static void dsp_jsclr_ea(void); +static void dsp_jsclr_pp(void); +static void dsp_jsclr_reg(void); +static void dsp_jset_aa(void); +static void dsp_jset_ea(void); +static void dsp_jset_pp(void); +static void dsp_jset_reg(void); +static void dsp_jsr_ea(void); +static void dsp_jsr_imm(void); +static void dsp_jsset_aa(void); +static void dsp_jsset_ea(void); +static void dsp_jsset_pp(void); +static void dsp_jsset_reg(void); static void dsp_lua(void); -static void dsp_movec(void); -static void dsp_movem(void); -static void dsp_movep(void); +static void dsp_movem_ea(void); +static void dsp_movem_aa(void); static void dsp_nop(void); static void dsp_norm(void); static void dsp_ori(void); -static void dsp_rep(void); static void dsp_reset(void); static void dsp_rti(void); static void dsp_rts(void); @@ -160,27 +177,28 @@ static void dsp_swi(void); static void dsp_tcc(void); static void dsp_wait(void); -static void dsp_do_0(void); -static void dsp_do_2(void); -static void dsp_do_4(void); -static void dsp_do_c(void); -static void dsp_rep_1(void); -static void dsp_rep_3(void); -static void dsp_rep_5(void); -static void dsp_rep_d(void); -static void dsp_movec_7(void); -static void dsp_movec_9(void); -static void dsp_movec_b(void); -static void dsp_movec_d(void); +static void dsp_do_ea(void); +static void dsp_do_aa(void); +static void dsp_do_imm(void); +static void dsp_do_reg(void); +static void dsp_rep_aa(void); +static void dsp_rep_ea(void); +static void dsp_rep_imm(void); +static void dsp_rep_reg(void); +static void dsp_movec_aa(void); +static void dsp_movec_ea(void); +static void dsp_movec_imm(void); +static void dsp_movec_reg(void); static void dsp_movep_0(void); static void dsp_movep_1(void); -static void dsp_movep_2(void); +static void dsp_movep_23(void); /* Parallel move analyzer */ static void dsp_parmove_read(void); static void dsp_parmove_write(void); +static void dsp_pm_class2(void); -static void dsp_pm_read_accu24(int numreg, uint32 *dest); +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); @@ -189,18 +207,18 @@ static void dsp_pm_2(void); static void dsp_pm_2_2(void); static void dsp_pm_3(void); static void dsp_pm_4(void); -static void dsp_pm_4x(int immediat, uint32 l_addr); +static void dsp_pm_4x(void); static void dsp_pm_5(void); static void dsp_pm_8(void); /* 56bits arithmetic */ -static uint16 dsp_abs56(uint32 *dest); -static uint16 dsp_asl56(uint32 *dest); -static uint16 dsp_asr56(uint32 *dest); -static uint16 dsp_add56(uint32 *source, uint32 *dest); -static uint16 dsp_sub56(uint32 *source, uint32 *dest); -static void dsp_mul56(uint32 source1, uint32 source2, uint32 *dest); -static void dsp_rnd56(uint32 *dest); +static Uint16 dsp_abs56(Uint32 *dest); +static Uint16 dsp_asl56(Uint32 *dest); +static Uint16 dsp_asr56(Uint32 *dest); +static Uint16 dsp_add56(Uint32 *source, Uint32 *dest); +static Uint16 dsp_sub56(Uint32 *source, Uint32 *dest); +static void dsp_mul56(Uint32 source1, Uint32 source2, Uint32 *dest); +static void dsp_rnd56(Uint32 *dest); /* Instructions with parallel moves */ static void dsp_abs(void); @@ -235,123 +253,86 @@ static void dsp_subr(void); static void dsp_tfr(void); static void dsp_tst(void); -static void dsp_move_pm(void); - -static dsp_emul_t opcodes8h[16]={ - opcode8h_0, - opcode8h_1, - dsp_tcc, - dsp_tcc, - opcode8h_4, - dsp_movec, - opcode8h_6, - dsp_movem, - opcode8h_8, - opcode8h_8, - opcode8h_a, - opcode8h_b, - dsp_jmp, - dsp_jsr, - dsp_jcc, - dsp_jscc -}; - -static dsp_emul_t opcodes_0809[16]={ - dsp_move_pm, - dsp_move_pm, - dsp_move_pm, - dsp_move_pm, - - dsp_movep, - dsp_movep, - dsp_movep, - dsp_movep, - - dsp_move_pm, - dsp_move_pm, - dsp_move_pm, - dsp_move_pm, - - dsp_movep, - dsp_movep, - dsp_movep, - dsp_movep -}; - -static dsp_emul_t opcodes_0a[32]={ - /* 00 000 */ dsp_bclr, - /* 00 001 */ dsp_bset, - /* 00 010 */ dsp_bclr, - /* 00 011 */ dsp_bset, - /* 00 100 */ dsp_jclr, - /* 00 101 */ dsp_jset, - /* 00 110 */ dsp_jclr, - /* 00 111 */ dsp_jset, - - /* 01 000 */ dsp_bclr, - /* 01 001 */ dsp_bset, - /* 01 010 */ dsp_bclr, - /* 01 011 */ dsp_bset, - /* 01 100 */ dsp_jclr, - /* 01 101 */ dsp_jset, - /* 01 110 */ dsp_jclr, - /* 01 111 */ dsp_jset, - - /* 10 000 */ dsp_bclr, - /* 10 001 */ dsp_bset, - /* 10 010 */ dsp_bclr, - /* 10 011 */ dsp_bset, - /* 10 100 */ dsp_jclr, - /* 10 101 */ dsp_jset, - /* 10 110 */ dsp_jclr, - /* 10 111 */ dsp_jset, - - /* 11 000 */ dsp_jclr, - /* 11 001 */ dsp_jset, - /* 11 010 */ dsp_bclr, - /* 11 011 */ dsp_bset, - /* 11 100 */ dsp_jmp, - /* 11 101 */ dsp_jcc, - /* 11 110 */ dsp_undefined, - /* 11 111 */ dsp_undefined -}; - -static dsp_emul_t opcodes_0b[32]={ - /* 00 000 */ dsp_bchg, - /* 00 001 */ dsp_btst, - /* 00 010 */ dsp_bchg, - /* 00 011 */ dsp_btst, - /* 00 100 */ dsp_jsclr, - /* 00 101 */ dsp_jsset, - /* 00 110 */ dsp_jsclr, - /* 00 111 */ dsp_jsset, - - /* 01 000 */ dsp_bchg, - /* 01 001 */ dsp_btst, - /* 01 010 */ dsp_bchg, - /* 01 011 */ dsp_btst, - /* 01 100 */ dsp_jsclr, - /* 01 101 */ dsp_jsset, - /* 01 110 */ dsp_jsclr, - /* 01 111 */ dsp_jsset, - - /* 10 000 */ dsp_bchg, - /* 10 001 */ dsp_btst, - /* 10 010 */ dsp_bchg, - /* 10 011 */ dsp_btst, - /* 10 100 */ dsp_jsclr, - /* 10 101 */ dsp_jsset, - /* 10 110 */ dsp_jsclr, - /* 10 111 */ dsp_jsset, - - /* 11 000 */ dsp_jsclr, - /* 11 001 */ dsp_jsclr, - /* 11 010 */ dsp_bchg, - /* 11 011 */ dsp_btst, - /* 11 100 */ dsp_jsr, - /* 11 101 */ dsp_jscc, - /* 11 110 */ dsp_undefined, - /* 11 111 */ dsp_undefined +static dsp_emul_t opcodes8h[512]={ + /* 0x00 - 0x3f */ + opcode8h_0, dsp_undefined, dsp_undefined, dsp_undefined, opcode8h_0, dsp_andi, dsp_undefined, dsp_ori, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_andi, dsp_undefined, dsp_ori, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_andi, dsp_undefined, dsp_ori, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_andi, dsp_undefined, dsp_ori, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_div, dsp_div, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_norm, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + + /* 0x40 - 0x7f */ + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + + /* 0x80 - 0xbf */ + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_lua, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_reg, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_reg, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, + + /* 0xc0 - 0xff */ + dsp_do_aa, dsp_rep_aa, dsp_do_aa, dsp_rep_aa, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_do_ea, dsp_rep_ea, dsp_do_ea, dsp_rep_ea, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_do_reg, dsp_rep_reg, dsp_undefined, dsp_undefined, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_movem_aa, dsp_movem_aa, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movem_ea, dsp_movem_ea, dsp_undefined, dsp_undefined, + dsp_movem_aa, dsp_movem_aa, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movem_ea, dsp_movem_ea, dsp_undefined, dsp_undefined, + + /* 0x100 - 0x13f */ + dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, dsp_pm_class2, + 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_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_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_movep_0, dsp_movep_0, dsp_movep_1, dsp_movep_1, dsp_movep_23, dsp_movep_23, dsp_movep_23, dsp_movep_23, + + /* 0x140 - 0x17f */ + dsp_bclr_aa, dsp_bset_aa, dsp_bclr_aa, dsp_bset_aa, dsp_jclr_aa, dsp_jset_aa, dsp_jclr_aa, dsp_jset_aa, + dsp_bclr_ea, dsp_bset_ea, dsp_bclr_ea, dsp_bset_ea, dsp_jclr_ea, dsp_jset_ea, dsp_jclr_ea, dsp_jset_ea, + dsp_bclr_pp, dsp_bset_pp, dsp_bclr_pp, dsp_bset_pp, dsp_jclr_pp, dsp_jset_pp, dsp_jclr_pp, dsp_jset_pp, + dsp_jclr_reg, dsp_jset_reg, dsp_bclr_reg, dsp_bset_reg, dsp_jmp_ea, dsp_jcc_ea, dsp_undefined, dsp_undefined, + dsp_bchg_aa, dsp_btst_aa, dsp_bchg_aa, dsp_btst_aa, dsp_jsclr_aa, dsp_jsset_aa, dsp_jsclr_aa, dsp_jsset_aa, + dsp_bchg_ea, dsp_btst_ea, dsp_bchg_ea, dsp_btst_ea, dsp_jsclr_ea, dsp_jsset_ea, dsp_jsclr_ea, dsp_jsset_ea, + dsp_bchg_pp, dsp_btst_pp, dsp_bchg_pp, dsp_btst_pp, dsp_jsclr_pp, dsp_jsset_pp, dsp_jsclr_pp, dsp_jsset_pp, + dsp_jsclr_reg, dsp_jsset_reg, dsp_bchg_reg, dsp_btst_reg, dsp_jsr_ea, dsp_jscc_ea, dsp_undefined, dsp_undefined, + + /* 0x180 - 0x1bf */ + dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + + /* 0x1c0 - 0x1ff */ + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, }; static dsp_emul_t opcodes_parmove[16]={ @@ -374,188 +355,46 @@ static dsp_emul_t opcodes_parmove[16]={ dsp_pm_8 }; -static dsp_emul_t opcodes_alu003f[64]={ - /* 0x00 - 0x0f */ - dsp_move, - dsp_tfr, - dsp_addr, - dsp_tst, - dsp_undefined, - dsp_cmp, - dsp_subr, - dsp_cmpm, - dsp_undefined, - dsp_tfr, - dsp_addr, - dsp_tst, - dsp_undefined, - dsp_cmp, - dsp_subr, - dsp_cmpm, - - /* 0x10 - 0x1f */ - dsp_add, - dsp_rnd, - dsp_addl, - dsp_clr, - dsp_sub, - dsp_undefined, - dsp_subl, - dsp_not, - dsp_add, - dsp_rnd, - dsp_addl, - dsp_clr, - dsp_sub, - dsp_undefined, - dsp_subl, - dsp_not, - - /* 0x20 - 0x2f */ - dsp_add, - dsp_adc, - dsp_asr, - dsp_lsr, - dsp_sub, - dsp_sbc, - dsp_abs, - dsp_ror, - dsp_add, - dsp_adc, - dsp_asr, - dsp_lsr, - dsp_sub, - dsp_sbc, - dsp_abs, - dsp_ror, - - /* 0x30 - 0x3f */ - dsp_add, - dsp_adc, - dsp_asl, - dsp_lsl, - dsp_sub, - dsp_sbc, - dsp_neg, - dsp_rol, - dsp_add, - dsp_adc, - dsp_asl, - dsp_lsl, - dsp_sub, - dsp_sbc, - dsp_neg, - dsp_rol -}; - -static dsp_emul_t opcodes_alu407f[16]={ - dsp_add, - dsp_tfr, - dsp_or, - dsp_eor, - dsp_sub, - dsp_cmp, - dsp_and, - dsp_cmpm, - dsp_add, - dsp_tfr, - dsp_or, - dsp_eor, - dsp_sub, - dsp_cmp, - dsp_and, - dsp_cmpm -}; - -static dsp_emul_t opcodes_alu80ff[4]={ - dsp_mpy, - dsp_mpyr, - dsp_mac, - dsp_macr -}; - -static dsp_emul_t opcodes_do[16]={ - dsp_do_0, - dsp_undefined, - dsp_do_2, - dsp_undefined, - - dsp_do_4, - dsp_undefined, - dsp_do_2, - dsp_undefined, - - dsp_undefined, - dsp_undefined, - dsp_do_2, - dsp_undefined, - - dsp_do_c, - dsp_undefined, - dsp_do_2, - dsp_undefined -}; - -static dsp_emul_t opcodes_rep[16]={ - dsp_undefined, - dsp_rep_1, - dsp_undefined, - dsp_rep_3, - - dsp_undefined, - dsp_rep_5, - dsp_undefined, - dsp_rep_3, - - dsp_undefined, - dsp_undefined, - dsp_undefined, - dsp_rep_3, - - dsp_undefined, - dsp_rep_d, - dsp_undefined, - dsp_rep_3 -}; - -static dsp_emul_t opcodes_movec[16]={ - dsp_undefined, - dsp_undefined, - dsp_undefined, - dsp_undefined, - - dsp_undefined, - dsp_undefined, - dsp_undefined, - dsp_movec_7, - - dsp_undefined, - dsp_movec_9, - dsp_undefined, - dsp_movec_b, - - dsp_undefined, - dsp_movec_d, - dsp_undefined, - dsp_movec_b -}; - -static dsp_emul_t opcodes_movep[4]={ - dsp_movep_0, - dsp_movep_1, - dsp_movep_2, - dsp_movep_2 -}; - -static int registers_lmove[8][2]={ - {DSP_REG_A1,DSP_REG_A0}, /* A10 */ - {DSP_REG_B1,DSP_REG_B0}, /* B10 */ - {DSP_REG_X1,DSP_REG_X0}, /* X */ - {DSP_REG_Y1,DSP_REG_Y0}, /* Y */ - {DSP_REG_A,DSP_REG_A}, /* A */ - {DSP_REG_B,DSP_REG_B}, /* B */ - {DSP_REG_A,DSP_REG_B}, /* AB */ - {DSP_REG_B,DSP_REG_A} /* BA */ +static 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, + + /* 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, + + /* 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 }; static int registers_tcc[16][2]={ @@ -571,11 +410,11 @@ static int registers_tcc[16][2]={ {DSP_REG_X0,DSP_REG_A}, {DSP_REG_X0,DSP_REG_B}, - {DSP_REG_X1,DSP_REG_A}, - {DSP_REG_X1,DSP_REG_B}, - {DSP_REG_Y0,DSP_REG_A}, {DSP_REG_Y0,DSP_REG_B}, + + {DSP_REG_X1,DSP_REG_A}, + {DSP_REG_X1,DSP_REG_B}, {DSP_REG_Y1,DSP_REG_A}, {DSP_REG_Y1,DSP_REG_B} }; @@ -611,29 +450,43 @@ static int registers_mask[64]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 8, 6, - 6, 6, 16, 16 + 16, 16, 16, 16 +}; + +static int interrupt_adress[13]={ + 0x0, 0x3e, 0x2, 0x4, + 0x6, 0xff, 0x20, 0x22, 0x0, + 0xe, 0xc, 0x12, 0x10 }; +#if DSP_DISASM_INTER +static const char *interrupt_label[13]={ + "Reset", "Illegal", "Stack Error", "Trace", + "Swi", "Host Command", "Host receive", "Host transmit", "", + "SSI receive with exception", "SSI receive", "SSI transmit with exception", "SSI tramsmit" +}; +#endif + /********************************** * Emulator kernel **********************************/ -int dsp56k_do_execute(void *arg) -{ - /* Wait upload of bootstrap code */ - SDL_SemWait(dsp56k_sem); - - while(dsp_state != DSP_STOPTHREAD) { - dsp_execute_instruction(); - } +/* Yep, feel lazy, so put it there */ +static dsp_core_t *dsp_core; - dsp_state = DSP_STOPPEDTHREAD; - return 0; +void dsp56k_init_cpu(void *th_dsp_core) +{ + dsp_core = th_dsp_core; +#ifdef DSP_DISASM + dsp56k_disasm_init(dsp_core); +#endif + start_time = SDL_GetTicks(); + num_inst = 0; } -static void dsp_execute_instruction(void) +void dsp56k_execute_instruction(void) { - uint32 value; + Uint32 value; #ifdef DSP_DISASM #if DSP_DISASM_REG @@ -643,37 +496,47 @@ static void dsp_execute_instruction(void dsp56k_disasm(); #endif #endif - /* Decode and execute current instruction */ - cur_inst = read_memory(DSP_SPACE_P,dsp_pc); + cur_inst = read_memory_p(dsp_core->pc); cur_inst_len = 1; + + /* Initialize instruction cycle counter */ + dsp_core->instr_cycle = 2; - value = (cur_inst >> 16) & BITMASK(8); - if (value< 0x10) { + if (cur_inst < 0x100000) { + value = (cur_inst >> 11) & (BITMASK(6) << 3); + value += (cur_inst >> 5) & BITMASK(3); opcodes8h[value](); } else { dsp_parmove_read(); value = cur_inst & BITMASK(8); - if (value < 0x40) { - opcodes_alu003f[value](); - } else if (value < 0x80) { - value &= BITMASK(4); - opcodes_alu407f[value](); - } else { - value &= BITMASK(2); - opcodes_alu80ff[value](); - } + opcodes_alu[value](); dsp_parmove_write(); } - /* Don't update the PC if we are halted */ - if (dsp_state == DSP_RUNNING) { - dsp_postexecute_update_pc(); - } + /* Process the PC */ + dsp_postexecute_update_pc(); - /* Interrupts ? */ + /* Process Interrupts */ dsp_postexecute_interrupts(); + /* process peripherals On Chip components */ + dsp_core_process_host_interface(dsp_core); + dsp_core_process_ssi_interface(dsp_core); + +#if DSP_COUNT_IPS + ++num_inst; + if ((num_inst & 63) == 0) { + /* Evaluate time after instructions have been executed to avoid asking too frequently */ + Uint32 cur_time = SDL_GetTicks(); + if (cur_time-start_time>1000) { + fprintf(stderr, "Dsp: %d i/s\n", (num_inst*1000)/(cur_time-start_time)); + start_time=cur_time; + num_inst=0; + } + } +#endif + #ifdef DSP_DISASM #if DSP_DISASM_REG dsp56k_disasm_reg_compare(); @@ -688,58 +551,62 @@ static void dsp_execute_instruction(void static void dsp_postexecute_update_pc(void) { /* When running a REP, PC must stay on the current instruction */ - if (dsp_loop_rep) { + if (dsp_core->loop_rep) { /* Is PC on the instruction to repeat ? */ - if (pc_on_rep==0) { - --dsp_registers[DSP_REG_LC]; - dsp_registers[DSP_REG_LC] &= BITMASK(16); + if (dsp_core->pc_on_rep==0) { + --dsp_core->registers[DSP_REG_LC]; + dsp_core->registers[DSP_REG_LC] &= BITMASK(16); - if (dsp_registers[DSP_REG_LC] > 0) { + if (dsp_core->registers[DSP_REG_LC] > 0) { cur_inst_len=0; /* Stay on this instruction */ } else { - dsp_loop_rep = 0; - dsp_registers[DSP_REG_LC] = dsp_registers[DSP_REG_LCSAVE]; + dsp_core->loop_rep = 0; + dsp_core->registers[DSP_REG_LC] = dsp_core->registers[DSP_REG_LCSAVE]; } +#ifdef DSP_DISASM + dsp56k_disasm_force_reg_changed(DSP_REG_LC); +#endif } else { /* Init LC at right value */ - if (dsp_registers[DSP_REG_LC] == 0) { - dsp_registers[DSP_REG_LC] = 0x010000; + if (dsp_core->registers[DSP_REG_LC] == 0) { + dsp_core->registers[DSP_REG_LC] = 0x010000; +#ifdef DSP_DISASM + dsp56k_disasm_force_reg_changed(DSP_REG_LC); +#endif } - pc_on_rep = 0; + dsp_core->pc_on_rep = 0; } } /* Normal execution, go to next instruction */ if (cur_inst_len>0) { - dsp_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_registers[DSP_REG_SR] & (1<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_registers[DSP_REG_LC]==0) { + if (dsp_core->registers[DSP_REG_LC]==0) { /* end of loop */ - uint32 newpc; - - dsp_stack_pop(&newpc, &dsp_registers[DSP_REG_SR]); - dsp_stack_pop(&dsp_registers[DSP_REG_LA], &dsp_registers[DSP_REG_LC]); + 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]); } else { /* Loop one more time */ - dsp_pc = dsp_stack[0][dsp_registers[DSP_REG_SSH]]; + dsp_core->pc = dsp_core->registers[DSP_REG_SSH]; } - } - - if (dsp_pc == dsp_registers[DSP_REG_LA]) { - /* We are executing the last loop instruction */ - dsp_last_loop_inst = 1; +#ifdef DSP_DISASM + dsp56k_disasm_force_reg_changed(DSP_REG_LC); +#endif } } } @@ -750,55 +617,164 @@ static void dsp_postexecute_update_pc(vo static void dsp_postexecute_interrupts(void) { - uint32 ipl, ipl_hi; - - ipl = (dsp_registers[DSP_REG_SR]>>DSP_SR_I0) & BITMASK(2); - ipl_hi = (dsp_periph[DSP_SPACE_X][DSP_IPR]>>10) & BITMASK(2); + Uint32 ipl, ipl_to_raise, ipl_hi, ipl_ssi, instr1, instr2, i, count1, count2, ipl1, ipl2; - /* Trace, level 3 */ - if (dsp_registers[DSP_REG_SR] & (1<loop_rep) { + return; } - /* Host interface interrupts */ - if ((ipl_hi>0) && ((ipl_hi-1)>=ipl)) { + /* A fast interrupt can not be interrupted. */ + if (dsp_core->interrupt_state == DSP_INTERRUPT_FAST) { + /* Did we execute the 2-inst interrupt of the vector ? */ + if (dsp_core->pc >= dsp_core->interrupt_instr_fetch+2) { + if (dsp_core->pc == dsp_core->interrupt_instr_fetch+2) { + dsp_core->pc = dsp_core->interrupt_save_pc; + } + dsp_core->interrupt_save_pc = -1; + dsp_core->interrupt_instr_fetch = -1; + dsp_core->interrupt_state = DSP_INTERRUPT_NONE; + } + return; + } + + /* Trace Interrupt ? */ + if (dsp_core->registers[DSP_REG_SR] & (1<interrupt_counter == 0) { + return; + } + + ipl_to_raise = 99; + + /* level 3 interrupt ? */ + for (i=0; i<5; i++) { + if (dsp_core->interrupt_table[i] != 0) { + ipl_to_raise = 3; + dsp_core->interrupt_instr_fetch = interrupt_adress[i]; + dsp_core->interrupt_table[i] = 0; + dsp_core->interrupt_counter --; #if DSP_DISASM_INTER - D(bug("Dsp: Interrupt: Host transmit")); + fprintf(stderr, "Dsp: Interrupt: %s\n", interrupt_label[i]); #endif + break; + } + } + + /* Level 2 and above interrupt ? */ + ipl = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_I0) & BITMASK(2); + if ((ipl_to_raise==99) && (ipl<3)) { + ipl_hi = (dsp_core->periph[DSP_SPACE_X][DSP_IPR]>>10) & BITMASK(2); + ipl_ssi = (dsp_core->periph[DSP_SPACE_X][DSP_IPR]>>12) & BITMASK(2); + + /* Determine the order of the peripheral interrupt to test . + If 2 or more peripharal have the same interrupt level, + the order is (high priority) : HI, SSI, SCI (low priority) */ + if (ipl_hi >= ipl_ssi) { + ipl1 = ipl_hi; + ipl2 = ipl_ssi; + count1 = 5; + count2 = 9; + } else { + ipl1 = ipl_ssi; + ipl2 = ipl_hi; + count1 = 9; + count2 = 5; } - /* Host receive */ - if ( - (dsp_periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<= ipl) { + for (i=count1; iinterrupt_table[i] != 0) { + ipl_to_raise = ipl1; + dsp_core->interrupt_instr_fetch = interrupt_adress[i]; + dsp_core->interrupt_table[i] = 0; + dsp_core->interrupt_counter --; #if DSP_DISASM_INTER - D(bug("Dsp: Interrupt: Host receive")); + fprintf(stderr, "Dsp: Interrupt: %s\n", interrupt_label[i]); #endif + break; + } + } } - - /* Host command */ - if ( - (dsp_periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<=ipl) { + for (i=count2; iinterrupt_table[i] != 0) { + ipl_to_raise = ipl2; + dsp_core->interrupt_instr_fetch = interrupt_adress[i]; + dsp_core->interrupt_table[i] = 0; + dsp_core->interrupt_counter --; #if DSP_DISASM_INTER - D(bug("Dsp: Interrupt: Host command")); + fprintf(stderr, "Dsp: Interrupt: %s\n", interrupt_label[i]); #endif + break; + } + } + } } } + + if (ipl_to_raise == 99) { + return; + } + + /* 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) { + /* 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; + } + + /* Read the 2 vectored instructions to search a "JSR" (long interrupt) or not (fast interrupt) */ + instr1 = read_memory_p(dsp_core->interrupt_instr_fetch); + instr2 = read_memory_p(dsp_core->interrupt_instr_fetch+1); + dsp_core->interrupt_state = DSP_INTERRUPT_FAST; + + if ( ((instr1 & 0xfff000) == 0x0d0000) || ((instr1 & 0xffc0ff) == 0x0bc080) ){ + dsp_core->interrupt_state = DSP_INTERRUPT_LONG; + } + + else if ( ((instr2 & 0xfff000) == 0x0d0000) || ((instr2 & 0xffc0ff) == 0x0bc080) ){ + dsp_core->interrupt_state = DSP_INTERRUPT_LONG; + } + + if (dsp_core->interrupt_state == DSP_INTERRUPT_FAST){ + /* Execute a fast interrupt */ + dsp_core->interrupt_save_pc = dsp_core->pc; + dsp_core->pc = dsp_core->interrupt_instr_fetch; +#if DSP_DISASM_INTER + fprintf(stderr, "Dsp: Fast Interrupt: %06x\n", dsp_core->pc); +#endif + } else { + /* Execute a long interrupt */ + dsp_stack_push(dsp_core->pc, dsp_core->registers[DSP_REG_SR], 0); + dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= ipl_to_raise<pc = dsp_core->interrupt_instr_fetch; + dsp_core->interrupt_instr_fetch = -1; + dsp_core->interrupt_save_pc = -1; +#if DSP_DISASM_INTER + fprintf(stderr, "Dsp: Long Interrupt: %06x\n", dsp_core->pc); +#endif + } } /********************************** @@ -809,415 +785,440 @@ static void dsp_postexecute_interrupts(v /* reg1 has bits 47..24 */ /* reg2 has bits 23..0 */ -static void dsp_ccr_extension(uint32 *reg0, uint32 *reg1, uint32 * reg2) -{ - uint32 scaling, value, numbits; +static void dsp_ccr_update_e_u_n_z(Uint32 *reg0, Uint32 *reg1, Uint32 *reg2) { + Uint32 scaling, value_e, value_u, numbits; + + 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_registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); - value = (*reg0) & 0xff; + scaling = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); + value_e = (*reg0) & 0xff; numbits = 8; + switch(scaling) { case 0: - value <<=1; - value |= ((*reg1)>>23) & 1; + value_e <<=1; + value_e |= ((*reg1)>>23) & 1; numbits=9; + value_u = ((*reg1)>>22) & 3; break; case 1: + value_u = ((*reg0)<<1) & 2; + value_u |= ((*reg1)>>23) & 1; break; case 2: - value <<=2; - value |= ((*reg1)>>22) & 3; + value_e <<=2; + value_e |= ((*reg1)>>22) & 3; numbits=10; + value_u = ((*reg1)>>21) & 3; break; default: return; break; } - dsp_registers[DSP_REG_SR] &= BITMASK(16)-(1<>DSP_SR_S0) & BITMASK(2); - - switch(scaling) { - case 0: - value = ((*reg1)>>22) & 3; - break; - case 1: - value = ((*reg0)<<1) & 2; - value |= ((*reg1)>>23) & 1; - break; - case 2: - value = ((*reg1)>>21) & 3; - break; - default: - return; - break; + if ((value_e==0) || (value_e==(Uint32)BITMASK(numbits))) { + sr_extension = 0; } - dsp_registers[DSP_REG_SR] &= BITMASK(16)-(1<>7) & 1)<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; } /********************************** * Read/Write memory functions **********************************/ -#if DSP_DISASM_MEM -static uint32 read_memory_disasm(int space, uint16 address) +#if defined(DSP_DISASM) && (DSP_DISASM_MEM==1) +static Uint32 read_memory_disasm(int space, Uint16 address) { - address &= BITMASK(16); + /* Internal RAM ? */ + if (address<0x100) { + return dsp_core->ramint[space][address] & BITMASK(24); + } - switch(space) { - case DSP_SPACE_X: - case DSP_SPACE_Y: - /* Internal RAM or ROM ? */ - if ((dsp_registers[DSP_REG_OMR] & (1<=0x100) && (address<0x200)) { - return dsp_rom[space][address] & BITMASK(24); - } - - /* Peripheral address ? */ - if (address >= 0xffc0) { - return dsp_periph[space][address-0xffc0] & BITMASK(24); - } + if (space==DSP_SPACE_P) { + return read_memory_p(address); + } - /* Now continue with common code, no break here */ - case DSP_SPACE_P: - if (address<=0x8000) { - return dsp_ram[space][address] & BITMASK(24); - } - break; + /* Internal ROM? */ + if ((dsp_core->registers[DSP_REG_OMR] & (1<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_SSI_TX)) { + return dsp_core->ssi.transmit_value; + } + return dsp_core->periph[space][address-0xffc0] & BITMASK(24); } - return 0xdead; + /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ + address &= (DSP_RAMSIZE>>1) - 1; + if (space == DSP_SPACE_X) { + address += DSP_RAMSIZE>>1; + } + + /* Falcon: External RAM, finally map X,Y to P */ + return dsp_core->ramext[address & (DSP_RAMSIZE-1)] & BITMASK(24); } #endif -static uint32 read_memory(int space, uint16 address) +static inline Uint32 read_memory_p(Uint16 address) { - address &= BITMASK(16); + /* Internal RAM ? */ + if (address<0x200) { + return dsp_core->ramint[DSP_SPACE_P][address] & BITMASK(24); + } - switch(space) { - case DSP_SPACE_X: - case DSP_SPACE_Y: - /* Internal RAM or ROM ? */ - if ((dsp_registers[DSP_REG_OMR] & (1<=0x100) && (address<0x200)) { - return dsp_rom[space][address] & BITMASK(24); - } - - /* Peripheral address ? */ - if (address >= 0xffc0) { + /* External RAM, mask address to available ram size */ +// dsp_core->instr_cycle += P_WAITSTATE; + return dsp_core->ramext[address & (DSP_RAMSIZE-1)] & BITMASK(24); +} - if ((space==DSP_SPACE_X) && (address==0xffc0+DSP_HOST_HRX)) { - int trdy; +static Uint32 read_memory(int space, Uint16 address) +{ + Uint32 value; - /* Read available data from host for the DSP */ - DSP_host2dsp(); + /* Internal RAM ? */ + if (address < 0x100) { + return dsp_core->ramint[space][address] & BITMASK(24); + } - /* Clear HRDF bit to say that DSP has read */ - dsp_periph[DSP_SPACE_X][DSP_HOST_HSR] &= BITMASK(8)-(1<D): Dsp HRDF cleared")); -#endif - /* Clear/set TRDY bit */ - dsp_hostport[CPU_HOST_ISR] &= 0xff-(1<>CPU_HOST_ISR_TXDE) & 1; - trdy &= !((dsp_periph[DSP_SPACE_X][DSP_HOST_HSR]>>DSP_HOST_HSR_HRDF) & 1); - dsp_hostport[CPU_HOST_ISR] |= (trdy & 1)<< CPU_HOST_ISR_TRDY; - } + if (space == DSP_SPACE_P) { + return read_memory_p(address); + } - return dsp_periph[space][address-0xffc0] & BITMASK(24); - } + /* Internal ROM ? */ + if (address < 0x200) { + if (dsp_core->registers[DSP_REG_OMR] & (1<rom[space][address] & BITMASK(24); + } + } - /* Now continue with common code, no break here */ - case DSP_SPACE_P: -#if DSP_CHECK_MEM_ACCESS - if (address<0x8000) { -#endif - return dsp_ram[space][address] & BITMASK(24); -#if DSP_CHECK_MEM_ACCESS - } else { - D(bug("Dsp: Read at 0x%04x without mapped memory",address)); -#if DSP_DISASM_STATE - D(bug("Dsp: state = DSP_HALT")); -#endif - dsp_state = DSP_HALT; + /* Peripheral address ? */ + if (address >= 0xffc0) { + value = dsp_core->periph[space][address-0xffc0] & BITMASK(24); + if (space == DSP_SPACE_X) { + if (address == 0xffc0+DSP_HOST_HRX) { + value = dsp_core->dsp_host_rtx; + dsp_core_hostport_dspread(dsp_core); + } + else if (address == 0xffc0+DSP_SSI_RX) { + value = dsp_core_ssi_readRX(dsp_core); + } + dsp_core->instr_cycle += XP_WAITSTATE; + } + else { + dsp_core->instr_cycle += YP_WAITSTATE; + } + return value; + } - SDL_SemWait(dsp56k_sem); + /* 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 */ + address &= (DSP_RAMSIZE>>1) - 1; - return 0xdead; -#endif /* DSP_CHECK_MEM_ACCESS */ - } - break; + if (space == DSP_SPACE_X) { + address += DSP_RAMSIZE>>1; } - return 0xdead; + /* Falcon: External RAM, finally map X,Y to P */ + return dsp_core->ramext[address & (DSP_RAMSIZE-1)] & BITMASK(24); } -static void write_memory(int space, uint32 address, uint32 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) { -#ifdef DSP_DISASM -#if DSP_DISASM_MEM - uint32 curvalue; -#endif -#endif - - address &= BITMASK(16); value &= BITMASK(24); -#ifdef DSP_DISASM -#if DSP_DISASM_MEM - curvalue = read_memory_disasm(space, address); -#endif -#endif - - switch(space) { - case DSP_SPACE_X: - /* Internal RAM or ROM ? */ - if ((address >= 0x100) && (address <= 0x200)) { - if (dsp_registers[DSP_REG_OMR] & (1<= 0xffc0) && (address <= 0xffff)) { - switch(address-0xffc0) { - case DSP_HOST_HTX: - dsp_periph[space][DSP_HOST_HTX] = value; - /* Clear HTDE bit to say that DSP has written */ - dsp_periph[DSP_SPACE_X][DSP_HOST_HSR] &= BITMASK(8)-(1<H): Dsp HTDE cleared")); -#endif - /* Write available data from DSP for the host */ - DSP_dsp2host(); - break; - case DSP_HOST_HCR: - dsp_periph[space][DSP_HOST_HCR] = value; - /* Set HF3 and HF2 accordingly on the host side */ - dsp_hostport[CPU_HOST_ISR] &= - BITMASK(8)-((1<= 0xffc0) { + if (space == DSP_SPACE_X) { + switch(address-0xffc0) { + case DSP_HOST_HTX: + dsp_core->dsp_host_htx = value; + dsp_core_hostport_dspwrite(dsp_core); + break; + case DSP_HOST_HCR: + dsp_core->periph[DSP_SPACE_X][DSP_HOST_HCR] = value; + /* Set HF3 and HF2 accordingly on the host side */ + dsp_core->hostport[CPU_HOST_ISR] &= + BITMASK(8)-((1<hostport[CPU_HOST_ISR] |= + dsp_core->periph[DSP_SPACE_X][DSP_HOST_HCR] & ((1<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; + return; + } + } + + /* Internal RAM ? */ + if (address < 0x100) { + dsp_core->ramint[space][address] = value; + return; + } -#if DSP_CHECK_MEM_ACCESS - if ((address<0x8000) || (address>=0xffc0)) { -#endif - dsp_ram[space][address] = value; -#if DSP_CHECK_MEM_ACCESS - } else { - D(bug("Dsp: Write at 0x%04x without mapped memory",address)); -#if DSP_DISASM_STATE - D(bug("Dsp: state = DSP_HALT")); -#endif - dsp_state = DSP_HALT; - SDL_SemWait(dsp56k_sem); + /* Internal ROM ? */ + if (address < 0x200) { + if (space != DSP_SPACE_P) { + if (dsp_core->registers[DSP_REG_OMR] & (1<= 0x200) && (address <= 0x3fff)) { - dsp_ram[DSP_SPACE_P][address+0x4000] = value; - } - break; - case DSP_SPACE_Y: - if ((address >= 0x100) && (address <= 0x200)) { - if (dsp_registers[DSP_REG_OMR] & (1<ramint[DSP_SPACE_P][address] = value; + return; + } + } - if ((address >= 0xffc0) && (address <= 0xffff)) { - dsp_periph[space][address-0xffc0] = value; - } + /* 1 more cycle for external RAM access */ + dsp_core->instr_cycle += XY_WAITSTATE; -#if DSP_CHECK_MEM_ACCESS - if ((address<0x8000) || (address>=0xffc0)) { -#endif - dsp_ram[space][address] = value; -#if DSP_CHECK_MEM_ACCESS - } else { - D(bug("Dsp: Write at 0x%04x without mapped memory",address)); -#if DSP_DISASM_STATE - D(bug("Dsp: state = DSP_HALT")); -#endif - dsp_state = DSP_HALT; - SDL_SemWait(dsp56k_sem); - return; -#endif - } - /* y:0x0000-0x01ff is internal ram/rom */ - /* y:0x0200-0x3fff = p:0x0200-0x3fff */ - if ((address >= 0x200) && (address <= 0x3fff)) { - dsp_ram[DSP_SPACE_P][address] = value; - } - break; - case DSP_SPACE_P: - dsp_ram[space][address] = value; -#if DSP_CHECK_MEM_ACCESS - if (address>=0x8000) { - D(bug("Dsp: Write at 0x%04x without mapped memory",address)); -#if DSP_DISASM_STATE - D(bug("Dsp: state = DSP_HALT")); -#endif - dsp_state = DSP_HALT; - SDL_SemWait(dsp56k_sem); - return; - } -#endif - /* p:0x0000-0x01ff is internal ram */ - /* p:0x0200-0x3fff = y:0x200-0x3fff */ - /* p:0x4200-0x7fff = x:0x200-0x3fff */ - if ((address >= 0x200) && (address <= 0x3fff)) { - dsp_ram[DSP_SPACE_Y][address] = value; - } else if ((address >= 0x4200) && (address <= 0x7fff)) { - dsp_ram[DSP_SPACE_X][address-0x4000] = value; - } - break; + /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ + if (space != DSP_SPACE_P) { + address &= (DSP_RAMSIZE>>1) - 1; + } + + if (space == DSP_SPACE_X) { + address += DSP_RAMSIZE>>1; } -#ifdef DSP_DISASM -#if DSP_DISASM_MEM + /* Falcon: External RAM, map X,Y to P */ + 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); + } + + write_memory_raw(space,address,value); + switch(space) { - case DSP_SPACE_P: - fprintf(stderr,"Dsp: Mem: p:0x%04x:0x%06x -> 0x%06x\n", address, curvalue, read_memory_disasm(space, address)); - break; case DSP_SPACE_X: - fprintf(stderr,"Dsp: Mem: x:0x%04x:0x%06x -> 0x%06x\n", address, curvalue, read_memory_disasm(space, address)); + space_c = 'x'; break; case DSP_SPACE_Y: - fprintf(stderr,"Dsp: Mem: y:0x%04x:0x%06x -> 0x%06x\n", address, curvalue, read_memory_disasm(space, address)); + space_c = 'y'; + break; + default: break; } + + if ((address == 0xffeb) && (space == DSP_SPACE_X) ) { + curvalue = dsp_core->dsp_host_htx; + } else { + curvalue = read_memory_disasm(space, address); + } + + fprintf(stderr,"Dsp: Mem: %c:0x%04x:0x%06x -> 0x%06x\n", space_c, address, oldvalue, curvalue); +} #endif -#endif + +static void dsp_write_reg(Uint32 numreg, Uint32 value) +{ + Uint32 reg = numreg; + + if ((reg==DSP_REG_A) || (reg==DSP_REG_B)) { + reg &= 1; + dsp_core->registers[DSP_REG_A0+reg]= 0; + dsp_core->registers[DSP_REG_A1+reg]= value; + dsp_core->registers[DSP_REG_A2+reg]= 0; + if (value & (1<<23)) { + dsp_core->registers[DSP_REG_A2+reg]= 0xff; + } + } else { + switch (reg) { + 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: + dsp_core->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: + reg = dsp_core->registers[DSP_REG_SP] & BITMASK(4); + if (reg == 0) { + value = 0; + } + dsp_core->stack[1][reg] = value & BITMASK(16); + dsp_core->registers[DSP_REG_SSL] = value & BITMASK(16); + break; + default: + dsp_core->registers[reg] = value; + dsp_core->registers[reg] &= BITMASK(registers_mask[reg]); + break; + } + } } /********************************** * Stack push/pop **********************************/ -static void dsp_stack_push(uint32 curpc, uint32 cursr) +static void dsp_stack_push(Uint32 curpc, Uint32 cursr, Uint16 sshOnly) { - if (dsp_registers[DSP_REG_SP]==0x0f) { + 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; + + + if ((stack_error==0) && (stack & (1<registers[DSP_REG_SP] = (underflow | stack_error | stack) & BITMASK(6); + stack &= BITMASK(4); - dsp_registers[DSP_REG_SP]++; - dsp_registers[DSP_REG_SSH]++; - dsp_registers[DSP_REG_SSL]++; + if (stack) { + /* SSH part */ + dsp_core->stack[0][stack] = curpc & BITMASK(16); + /* SSL part, if instruction is not like "MOVEC xx, SSH" */ + if (sshOnly == 0) { + dsp_core->stack[1][stack] = cursr & BITMASK(16); + } + } else { + dsp_core->stack[0][0] = 0; + dsp_core->stack[1][0] = 0; + } - dsp_stack[0][dsp_registers[DSP_REG_SSH]]=curpc; - dsp_stack[1][dsp_registers[DSP_REG_SSL]]=cursr; + /* Update SSH and SSL registers */ + dsp_core->registers[DSP_REG_SSH] = dsp_core->stack[0][stack]; + dsp_core->registers[DSP_REG_SSL] = dsp_core->stack[1][stack]; } -static void dsp_stack_pop(uint32 *newpc, uint32 *newsr) +static void dsp_stack_pop(Uint32 *newpc, Uint32 *newsr) { - if (dsp_registers[DSP_REG_SP]==0x00) { - /* Stack empty, raise interrupt */ - D(bug("Dsp: Interrupt: Stack error (underflow)")); -#if DSP_DISASM_STATE - D(bug("Dsp: state = DSP_HALT")); -#endif - dsp_state = DSP_HALT; - SDL_SemWait(dsp56k_sem); - return; + 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; + + if ((stack_error==0) && (stack & (1<registers[DSP_REG_SP] = (underflow | stack_error | stack) & BITMASK(6); + stack &= BITMASK(4); + *newpc = dsp_core->registers[DSP_REG_SSH]; + *newsr = dsp_core->registers[DSP_REG_SSL]; - --dsp_registers[DSP_REG_SP]; - --dsp_registers[DSP_REG_SSH]; - --dsp_registers[DSP_REG_SSL]; + dsp_core->registers[DSP_REG_SSH] = dsp_core->stack[0][stack]; + dsp_core->registers[DSP_REG_SSL] = dsp_core->stack[1][stack]; +} + +static void dsp_compute_ssh_ssl(void) +{ + Uint32 stack; + + 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]; } /********************************** * Effective address calculation **********************************/ -static void dsp_update_rn(uint32 numreg, int16 modifier) +static void dsp_update_rn(Uint32 numreg, Sint16 modifier) { - int16 value; - uint16 m_reg; + Sint16 value; + Uint16 m_reg; - m_reg = (uint16) dsp_registers[DSP_REG_M0+numreg]; + m_reg = (Uint16) dsp_core->registers[DSP_REG_M0+numreg]; if (m_reg == 0) { /* Bit reversed carry update */ dsp_update_rn_bitreverse(numreg); - } else if ((m_reg>=1) && (m_reg<=32767)) { + } else if (m_reg<=32767) { /* Modulo update */ dsp_update_rn_modulo(numreg, modifier); } else if (m_reg == 65535) { /* Linear addressing mode */ - value = (int16) dsp_registers[DSP_REG_R0+numreg]; + value = (Sint16) dsp_core->registers[DSP_REG_R0+numreg]; value += modifier; - dsp_registers[DSP_REG_R0+numreg] = ((uint32) value) & BITMASK(16); + dsp_core->registers[DSP_REG_R0+numreg] = ((Uint32) value) & BITMASK(16); } else { /* Undefined */ } } -static void dsp_update_rn_bitreverse(uint32 numreg) +static void dsp_update_rn_bitreverse(Uint32 numreg) { int revbits, i; - uint32 value, r_reg; + Uint32 value, r_reg; /* Check how many bits to reverse */ - value = dsp_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]; value = r_reg & (BITMASK(16)-BITMASK(revbits)); for (i=0;iregisters[DSP_REG_R0+numreg] = value; } -static void dsp_update_rn_modulo(uint32 numreg, int16 modifier) +static void dsp_update_rn_modulo(Uint32 numreg, Sint16 modifier) { - uint16 bufsize, modulo, lobound, hibound, value; - int16 r_reg; + Uint16 bufsize, modulo, lobound, hibound, bufmask; + Sint16 r_reg, orig_modifier=modifier; - modulo = (dsp_registers[DSP_REG_M0+numreg]+1) & BITMASK(16); + modulo = dsp_core->registers[DSP_REG_M0+numreg]+1; bufsize = 1; + bufmask = BITMASK(16); while (bufsize < modulo) { bufsize <<= 1; + bufmask <<= 1; } - /* lobound is the highest multiple of bufsize<= Rn */ - value = dsp_registers[DSP_REG_R0+numreg] & BITMASK(16); - value /= bufsize; - lobound = value*bufsize; + lobound = dsp_core->registers[DSP_REG_R0+numreg] & bufmask; + hibound = lobound + modulo - 1; + + r_reg = (Sint16) dsp_core->registers[DSP_REG_R0+numreg]; - hibound = lobound + modulo-1; + if (orig_modifier>modulo) { + while (modifier>bufsize) { + r_reg += bufsize; + modifier -= bufsize; + } + while (modifier<-bufsize) { + r_reg -= bufsize; + modifier += bufsize; + } + } - r_reg = (int16) (dsp_registers[DSP_REG_R0+numreg] & BITMASK(16)); r_reg += modifier; - if (r_reg>hibound) { - r_reg -= hibound; - r_reg += lobound; - } else if (r_reghibound) { + r_reg -= modulo; + } else if (r_regregisters[DSP_REG_R0+numreg] = ((Uint32) r_reg) & BITMASK(16); } -static int dsp_calc_ea(uint32 ea_mode, uint32 *dst_addr) +static int dsp_calc_ea(Uint32 ea_mode, Uint32 *dst_addr) { - uint32 value, numreg, curreg; + Uint32 value, numreg, curreg; value = (ea_mode >> 3) & BITMASK(3); numreg = ea_mode & BITMASK(3); switch (value) { case 0: /* (Rx)-Nx */ - *dst_addr = dsp_registers[DSP_REG_R0+numreg]; - dsp_update_rn(numreg, -dsp_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_registers[DSP_REG_R0+numreg]; - dsp_update_rn(numreg, dsp_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_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_registers[DSP_REG_R0+numreg]; + *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; dsp_update_rn(numreg, +1); break; case 4: /* (Rx) */ - *dst_addr = dsp_registers[DSP_REG_R0+numreg]; + *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; break; case 5: /* (Rx+Nx) */ - curreg = dsp_registers[DSP_REG_R0+numreg]; - dsp_update_rn(numreg, dsp_registers[DSP_REG_N0+numreg]); - *dst_addr = dsp_registers[DSP_REG_R0+numreg]; - dsp_registers[DSP_REG_R0+numreg] = curreg; + dsp_core->instr_cycle += 2; + curreg = dsp_core->registers[DSP_REG_R0+numreg]; + dsp_update_rn(numreg, dsp_core->registers[DSP_REG_N0+numreg]); + *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; + dsp_core->registers[DSP_REG_R0+numreg] = curreg; break; case 6: /* aa */ - *dst_addr = read_memory(DSP_SPACE_P,dsp_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 */ @@ -1331,8 +1345,9 @@ static int dsp_calc_ea(uint32 ea_mode, u break; case 7: /* -(Rx) */ + dsp_core->instr_cycle += 2; dsp_update_rn(numreg, -1); - *dst_addr = dsp_registers[DSP_REG_R0+numreg]; + *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; break; } /* address */ @@ -1343,34 +1358,71 @@ static int dsp_calc_ea(uint32 ea_mode, u * Condition code test **********************************/ -#define DSP_SR_NV 8 /* N xor V */ -#define DSP_SR_ZUE 9 /* Z or ((not U) and (not E)) */ -#define DSP_SR_ZNV 10 /* Z or (N xor V) */ - -#define CCR_BIT(x,y) \ - (((x) >> (y)) & 1) - -static int cc_code_map[8]={ - DSP_SR_C, - DSP_SR_NV, - DSP_SR_Z, - DSP_SR_N, - DSP_SR_ZUE, - DSP_SR_E, - DSP_SR_L, - DSP_SR_ZNV -}; - -static int dsp_calc_cc(uint32 cc_code) +static int dsp_calc_cc(Uint32 cc_code) { - uint16 value; + Uint16 value1, value2, value3; - value = dsp_registers[DSP_REG_SR] & BITMASK(8); - value |= (CCR_BIT(value,DSP_SR_N) ^ CCR_BIT(value, DSP_SR_V))<>3) & 1); + switch (cc_code) { + case 0: /* CC (HS) */ + value1 = dsp_core->registers[DSP_REG_SR] & (1<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; + 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; + 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; + return ((value1 ^ value2) == 1); + case 10: /* EQ */ + value1 = (dsp_core->registers[DSP_REG_SR] >> DSP_SR_Z) & 1; + return (value1==1); + case 11: /* MI */ + value1 = (dsp_core->registers[DSP_REG_SR] >> DSP_SR_N) & 1; + return (value1==1); + case 12: /* NR */ + value1 = (dsp_core->registers[DSP_REG_SR] >> DSP_SR_Z) & 1; + value2 = (~(dsp_core->registers[DSP_REG_SR] >> DSP_SR_U)) & 1; + value3 = (~(dsp_core->registers[DSP_REG_SR] >> DSP_SR_E)) & 1; + return ((value1 | (value2 & value3)) == 1); + case 13: /* ES */ + value1 = (dsp_core->registers[DSP_REG_SR] >> DSP_SR_E) & 1; + return (value1==1); + case 14: /* LS */ + value1 = (dsp_core->registers[DSP_REG_SR] >> DSP_SR_L) & 1; + return (value1==1); + case 15: /* LE */ + value1 = (dsp_core->registers[DSP_REG_SR] >> DSP_SR_N) & 1; + value2 = (dsp_core->registers[DSP_REG_SR] >> DSP_SR_V) & 1; + value3 = (dsp_core->registers[DSP_REG_SR] >> DSP_SR_Z) & 1; + return ((value3 | (value1 ^ value2)) == 1); + } + return 0; } /********************************** @@ -1379,386 +1431,463 @@ static int dsp_calc_cc(uint32 cc_code) static void opcode8h_0(void) { - if (cur_inst <= 0x00008c) { - switch(cur_inst) { - case 0x000000: - dsp_nop(); - break; - case 0x000004: - dsp_rti(); - break; - case 0x000005: - dsp_illegal(); - break; - case 0x000006: - dsp_swi(); - break; - case 0x00000c: - dsp_rts(); - break; - case 0x000084: - dsp_reset(); - break; - case 0x000086: - dsp_wait(); - break; - case 0x000087: - dsp_stop(); - break; - case 0x00008c: - dsp_enddo(); - break; - } - } else { - switch (cur_inst & 0xf8) { - case 0x0000b8: - dsp_andi(); - break; - case 0x0000f8: - dsp_ori(); - break; - } + switch(cur_inst) { + case 0x000000: + dsp_nop(); + break; + case 0x000004: + dsp_rti(); + break; + case 0x000005: + dsp_illegal(); + break; + case 0x000006: + dsp_swi(); + break; + case 0x00000c: + dsp_rts(); + break; + case 0x000084: + dsp_reset(); + break; + case 0x000086: + dsp_wait(); + break; + case 0x000087: + dsp_stop(); + break; + case 0x00008c: + dsp_enddo(); + break; } } -static void opcode8h_1(void) +/********************************** + * Non-parallel moves instructions + **********************************/ + +static void dsp_undefined(void) { - switch(cur_inst & 0xfff8c7) { - case 0x018040: - dsp_div(); - break; - case 0x01c805: - dsp_norm(); - break; - } + cur_inst_len = 0; + fprintf(stderr, "Dsp: 0x%04x: 0x%06x unknown instruction\n",dsp_core->pc, cur_inst); } -static void opcode8h_4(void) +static void dsp_andi(void) { - switch((cur_inst>>5) & BITMASK(3)) { + Uint32 regnum, value; + + value = (cur_inst >> 8) & BITMASK(8); + regnum = cur_inst & BITMASK(2); + switch(regnum) { case 0: - dsp_lua(); + /* mr */ + dsp_core->registers[DSP_REG_SR] &= (value<<8)|BITMASK(8); break; - case 5: - dsp_movec(); + case 1: + /* ccr */ + dsp_core->registers[DSP_REG_SR] &= (BITMASK(8)<<8)|value; + break; + case 2: + /* omr */ + dsp_core->registers[DSP_REG_OMR] &= value; break; } } -static void opcode8h_6(void) +static void dsp_bchg_aa(void) { - if (cur_inst & (1<<5)) { - dsp_rep(); + Uint32 memspace, addr, value, newcarry, numbit; + + memspace = (cur_inst>>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + + addr = value; + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + if (newcarry) { + value -= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; + if (addr>=0x200) { + dsp_core->instr_cycle += XY_WAITSTATE; } } -static void opcode8h_8(void) +static void dsp_bchg_ea(void) { - uint32 value; + Uint32 memspace, addr, value, newcarry, numbit; + + memspace = (cur_inst>>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); - value = (cur_inst >> 12) & BITMASK(4); - opcodes_0809[value](); + dsp_calc_ea(value, &addr); + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + if (newcarry) { + value -= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; + if (addr>=0x200) { + dsp_core->instr_cycle += XY_WAITSTATE; + } } -static void opcode8h_a(void) +static void dsp_bchg_pp(void) { - uint32 value; + Uint32 memspace, addr, value, newcarry, numbit; - value = (cur_inst >> 11) & (BITMASK(2)<<3); - value |= (cur_inst >> 5) & BITMASK(3); + memspace = (cur_inst>>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); - opcodes_0a[value](); + addr = 0xffc0 + value; + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + if (newcarry) { + value -= (1<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; + } } -static void opcode8h_b(void) +static void dsp_bchg_reg(void) { - uint32 value; + Uint32 value, numreg, newcarry, numbit; - value = (cur_inst >> 11) & (BITMASK(2)<<3); - value |= (cur_inst >> 5) & BITMASK(3); + numreg = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); - opcodes_0b[value](); -} + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); + } else { + value = dsp_core->registers[numreg]; + } -/********************************** - * Non-parallel moves instructions - **********************************/ + newcarry = (value>>numbit) & 1; + if (newcarry) { + value -= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; +} + +static void dsp_bclr_aa(void) { - cur_inst_len = 0; - D(bug("Dsp: 0x%04x: 0x%06x unknown instruction",dsp_pc, cur_inst)); + Uint32 memspace, addr, value, newcarry, numbit; + + memspace = (cur_inst>>6) & 1; + addr = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + value &= 0xffffffff-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; + if (addr>=0x200) { + dsp_core->instr_cycle += XY_WAITSTATE; + } } -static void dsp_andi(void) +static void dsp_bclr_ea(void) { - uint32 regnum, value; + Uint32 memspace, addr, value, newcarry, numbit; + + memspace = (cur_inst>>6) & 1; + value = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); - value = (cur_inst >> 8) & BITMASK(8); - regnum = cur_inst & BITMASK(2); - switch(regnum) { - case 0: - /* mr */ - dsp_registers[DSP_REG_SR] &= (value<<8)|BITMASK(8); - break; - case 1: - /* ccr */ - dsp_registers[DSP_REG_SR] &= (BITMASK(8)<<8)|value; - break; - case 2: - /* omr */ - dsp_registers[DSP_REG_OMR] &= value; - break; + dsp_calc_ea(value, &addr); + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + value &= 0xffffffff-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; + if (addr>=0x200) { + dsp_core->instr_cycle += XY_WAITSTATE; } } -static void dsp_bchg(void) +static void dsp_bclr_pp(void) { - uint32 memspace, addr, value, numreg, newcarry, numbit; + Uint32 memspace, addr, value, newcarry, numbit; memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); - newcarry = 0; - switch((cur_inst>>14) & BITMASK(2)) { - case 0: - /* bchg #n,x:aa */ - /* bchg #n,y:aa */ - addr = value; - value = read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - if (newcarry) { - value -= (1<>numbit) & 1; - if (newcarry) { - value -= (1<>numbit) & 1; - if (newcarry) { - value -= (1<>numbit) & 1; - if (newcarry) { - value -= (1<>numbit) & 1; + value &= 0xffffffff-(1<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; + } +} + +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]; } + newcarry = (value>>numbit) & 1; + value &= 0xffffffff-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; } -static void dsp_bclr(void) +static void dsp_bset_aa(void) { - uint32 memspace, addr, value, numreg, newcarry, numbit; + Uint32 memspace, addr, value, newcarry, numbit; memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); - newcarry = 0; - switch((cur_inst>>14) & BITMASK(2)) { - case 0: - /* bclr #n,x:aa */ - /* bclr #n,y:aa */ - addr = value; - value = read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - value &= 0xffffffff-(1<>numbit) & 1; - value &= 0xffffffff-(1<>numbit) & 1; - value &= 0xffffffff-(1<>numbit) & 1; - value &= 0xffffffff-(1<>numbit) & 1; + value |= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; + if (addr>=0x200) { + dsp_core->instr_cycle += XY_WAITSTATE; } +} + +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); + + dsp_calc_ea(value, &addr); + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + value |= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; + if (addr>=0x200) { + dsp_core->instr_cycle += XY_WAITSTATE; + } } -static void dsp_bset(void) +static void dsp_bset_pp(void) { - uint32 memspace, addr, value, numreg, newcarry, numbit; + Uint32 memspace, addr, value, newcarry, numbit; memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); - newcarry = 0; + addr = 0xffc0 + value; + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + value |= (1<>14) & BITMASK(2)) { - case 0: - /* bset #n,x:aa */ - /* bset #n,y:aa */ - addr = value; - value = read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - value |= (1<>numbit) & 1; - value |= (1<>numbit) & 1; - value |= (1<>numbit) & 1; - value |= (1<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; + } +} + +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]; } + newcarry = (value>>numbit) & 1; + value |= (1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; } -static void dsp_btst(void) +static void dsp_btst_aa(void) { - uint32 memspace, addr, value, numreg, newcarry, numbit; + Uint32 memspace, addr, value, newcarry, numbit; memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); - newcarry = 0; - switch((cur_inst>>14) & BITMASK(2)) { - case 0: - /* btst #n,x:aa */ - /* btst #n,y:aa */ - addr = value; - value = read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - break; - case 1: - /* btst #n,x:ea */ - /* btst #n,y:ea */ - dsp_calc_ea(value, &addr); - value = read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - break; - case 2: - /* btst #n,x:pp */ - /* btst #n,y:pp */ - addr = 0xffc0 + value; - value = read_memory(memspace, addr); - newcarry = (value>>numbit) & 1; - break; - case 3: - /* btst #n,R */ - numreg = value; - if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { - numreg = DSP_REG_A1+(numreg & 1); - } - value = dsp_registers[numreg]; - newcarry = (value>>numbit) & 1; - break; + addr = value; + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + + /* Set carry */ + dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<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); + + dsp_calc_ea(value, &addr); + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + + /* Set carry */ + dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<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); + + addr = 0xffc0 + value; + value = read_memory(memspace, addr); + newcarry = (value>>numbit) & 1; + + /* Set carry */ + dsp_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<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]; } + newcarry = (value>>numbit) & 1; + /* Set carry */ - dsp_registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<instr_cycle += 2; } static void dsp_div(void) { - uint32 srcreg, destreg, source, dest[3], newcarry, cursign; - uint16 newsr; + Uint32 srcreg, destreg, source[3], dest[3]; + Uint16 newsr; srcreg = DSP_REG_NULL; switch((cur_inst>>4) & BITMASK(2)) { @@ -1769,531 +1898,810 @@ static void dsp_div(void) } destreg = DSP_REG_A+((cur_inst>>3) & 1); - source = dsp_registers[srcreg]; - dest[0] = dsp_registers[DSP_REG_A2+(destreg & 1)]; - dest[1] = dsp_registers[DSP_REG_A1+(destreg & 1)]; - dest[2] = dsp_registers[DSP_REG_A0+(destreg & 1)]; - newcarry = 0; - - newsr = dsp_asl56(dest); - dest[2] |= (dsp_registers[DSP_REG_SR]>>DSP_SR_C) & 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)]; - if (((dest[0]>>7) & 1) ^ ((source>>23) & 1)) { + if (((dest[0]>>7) & 1) ^ ((source[1]>>23) & 1)) { /* D += S */ - dest[1] += source; - if ((dest[1]>>24) & BITMASK(8)) { - cursign = (dest[0]>>7) & 1; - - ++dest[0]; - dest[1] &= BITMASK(24); - - newcarry =(cursign != ((dest[0]>>7) & 1)) && (cursign==1); - } + newsr = dsp_asl56(dest); + dsp_add56(source, dest); } else { /* D -= S */ - dest[1] -= source; - if ((dest[1]>>24) & BITMASK(8)) { - cursign = (dest[0]>>7) & 1; - - --dest[0]; - dest[1] &= BITMASK(24); - - newcarry =(cursign != ((dest[0]>>7) & 1)) && (cursign==0); - } + newsr = dsp_asl56(dest); + dsp_sub56(source, dest); } - dsp_registers[DSP_REG_A2+(destreg & 1)] = dest[0]; - dsp_registers[DSP_REG_A1+(destreg & 1)] = dest[1]; - dsp_registers[DSP_REG_A0+(destreg & 1)] = dest[2]; + dest[2] |= (dsp_core->registers[DSP_REG_SR]>>DSP_SR_C) & 1; - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<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<>12) & (BITMASK(2)<<2); - value |= (cur_inst>>6) & 1<<1; - value |= (cur_inst>>5) & 1; +/* + DO instruction parameter encoding - opcodes_do[value](); -} + xxxxxxxx 00xxxxxx 0xxxxxxx aa + xxxxxxxx 01xxxxxx 0xxxxxxx ea + xxxxxxxx YYxxxxxx 1xxxxxxx imm + xxxxxxxx 11xxxxxx 0xxxxxxx reg +*/ -static void dsp_do_0(void) +static void dsp_do_aa(void) { - uint32 memspace, addr; + Uint32 memspace, addr; /* x:aa */ /* y:aa */ + dsp_stack_push(dsp_core->registers[DSP_REG_LA], dsp_core->registers[DSP_REG_LC], 0); + dsp_core->registers[DSP_REG_LA] = read_memory_p(dsp_core->pc+1) & BITMASK(16); + cur_inst_len++; + dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR], 0); + dsp_core->registers[DSP_REG_SR] |= (1<>6) & 1; addr = (cur_inst>>8) & BITMASK(6); - dsp_registers[DSP_REG_LC] = read_memory(memspace, addr) & BITMASK(16); + dsp_core->registers[DSP_REG_LC] = read_memory(memspace, addr) & BITMASK(16); + + dsp_core->instr_cycle += 4; } -static void dsp_do_2(void) +static void dsp_do_imm(void) { /* #xx */ - dsp_registers[DSP_REG_LC] = (cur_inst>>8) & BITMASK(8); - dsp_registers[DSP_REG_LC] |= (cur_inst & BITMASK(4))<<8; + + dsp_stack_push(dsp_core->registers[DSP_REG_LA], dsp_core->registers[DSP_REG_LC], 0); + dsp_core->registers[DSP_REG_LA] = read_memory_p(dsp_core->pc+1) & BITMASK(16); + cur_inst_len++; + dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR], 0); + dsp_core->registers[DSP_REG_SR] |= (1<registers[DSP_REG_LC] = ((cur_inst>>8) & BITMASK(8)) + + ((cur_inst & BITMASK(4))<<8); + + dsp_core->instr_cycle += 4; } -static void dsp_do_4(void) +static void dsp_do_ea(void) { - uint32 memspace, ea_mode, addr; + Uint32 memspace, ea_mode, addr; /* x:ea */ /* y:ea */ + dsp_stack_push(dsp_core->registers[DSP_REG_LA], dsp_core->registers[DSP_REG_LC], 0); + dsp_core->registers[DSP_REG_LA] = read_memory_p(dsp_core->pc+1) & BITMASK(16); + cur_inst_len++; + dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR], 0); + dsp_core->registers[DSP_REG_SR] |= (1<>6) & 1; ea_mode = (cur_inst>>8) & BITMASK(6); dsp_calc_ea(ea_mode, &addr); - dsp_registers[DSP_REG_LC] = read_memory(memspace, addr) & BITMASK(16); + dsp_core->registers[DSP_REG_LC] = read_memory(memspace, addr) & BITMASK(16); + + dsp_core->instr_cycle += 4; } -static void dsp_do_c(void) +static void dsp_do_reg(void) { - uint32 numreg; + Uint32 numreg; /* S */ + dsp_stack_push(dsp_core->registers[DSP_REG_LA], dsp_core->registers[DSP_REG_LC], 0); + dsp_core->registers[DSP_REG_LA] = read_memory_p(dsp_core->pc+1) & BITMASK(16); + cur_inst_len++; + numreg = (cur_inst>>8) & BITMASK(6); if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &dsp_registers[DSP_REG_LC]); + dsp_pm_read_accu24(numreg, &dsp_core->registers[DSP_REG_LC]); } else { - dsp_registers[DSP_REG_LC] = dsp_registers[numreg]; + dsp_core->registers[DSP_REG_LC] = dsp_core->registers[numreg]; } - dsp_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; } static void dsp_enddo(void) { - uint32 newpc; - - dsp_stack_pop(&newpc, &dsp_registers[DSP_REG_SR]); - dsp_pc = dsp_registers[DSP_REG_LA]; - cur_inst_len = 0; + Uint32 saved_pc, saved_sr; - dsp_stack_pop(&dsp_registers[DSP_REG_LA], &dsp_registers[DSP_REG_LC]); + dsp_stack_pop(&saved_pc, &saved_sr); + dsp_core->registers[DSP_REG_SR] &= 0x7f; + dsp_core->registers[DSP_REG_SR] |= saved_sr & (1<registers[DSP_REG_LA], &dsp_core->registers[DSP_REG_LC]); } static void dsp_illegal(void) { /* Raise interrupt p:0x003e */ -#if DSP_DISASM_INTER - D(bug("Dsp: Interrupt: Illegal")); -#endif + dsp_core_add_interrupt(dsp_core, DSP_INTER_ILLEGAL); } -static void dsp_jcc(void) +static void dsp_jcc_imm(void) { - uint32 newpc, cc_code; + Uint32 cc_code, newpc; - cc_code = 0; - switch((cur_inst >> 16) & BITMASK(8)) { - case 0x0a: - dsp_calc_ea((cur_inst >>8) & BITMASK(6), &newpc); - cc_code=cur_inst & BITMASK(4); - break; - case 0x0e: - newpc = cur_inst & BITMASK(12); - cc_code=(cur_inst>>12) & BITMASK(4); - break; + newpc = cur_inst & BITMASK(12); + cc_code=(cur_inst>>12) & BITMASK(4); + if (dsp_calc_cc(cc_code)) { + dsp_core->pc = newpc; + cur_inst_len = 0; + } + + dsp_core->instr_cycle += 2; + if (newpc >= 0x200) { + dsp_core->instr_cycle += 2*P_WAITSTATE; } +} + +static void dsp_jcc_ea(void) +{ + Uint32 newpc, cc_code; + + dsp_calc_ea((cur_inst >>8) & BITMASK(6), &newpc); + cc_code=cur_inst & BITMASK(4); if (dsp_calc_cc(cc_code)) { - dsp_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; + } } -static void dsp_jclr(void) +static void dsp_jclr_aa(void) { - uint32 memspace, addr, value, numreg, newpc, numbit; + Uint32 memspace, addr, value, numbit, newaddr; + + memspace = (cur_inst>>6) & 1; + 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; + } + + if ((value & (1<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); + + dsp_calc_ea(value, &addr); + value = read_memory(memspace, addr); - switch((cur_inst>>14) & BITMASK(2)) { - case 0: - /* jclr #n,x:aa,p:xx */ - /* jclr #n,y:aa,p:xx */ - addr = value; - value = read_memory(memspace, addr); - break; - case 1: - /* jclr #n,x:ea,p:xx */ - /* jclr #n,y:ea,p:xx */ - dsp_calc_ea(value, &addr); - value = read_memory(memspace, addr); - break; - case 2: - /* jclr #n,x:pp,p:xx */ - /* jclr #n,y:pp,p:xx */ - addr = 0xffc0 + value; - value = read_memory(memspace, addr); - break; - case 3: - /* jclr #n,R,p:xx */ - numreg = value; - value = dsp_registers[numreg]; - addr = 0xffff0000; /* invalid address */ - memspace = 0xffff0000; /* invalid memspace */ - break; + dsp_core->instr_cycle += 4; + if (newaddr >= 0x200) { + dsp_core->instr_cycle += 2*P_WAITSTATE; } - cur_inst_len++; + if ((value & (1<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); + + dsp_core->instr_cycle += 4; + if (newaddr >= 0x200) { + dsp_core->instr_cycle += 2*P_WAITSTATE; + } if ((value & (1<pc = newaddr; + cur_inst_len = 0; + return; + } + ++cur_inst_len; +} - /* Polling loop ? */ - if (newpc == dsp_pc) { +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); - /* Are we waiting for host port ? */ - if ((memspace==DSP_SPACE_X) && (addr==0xffc0+DSP_HOST_HSR)) { - /* Wait for host to write */ - if (numbit==DSP_HOST_HSR_HRDF) { -#if DSP_DISASM_STATE - D(bug("Dsp: state = DSP_WAITHOSTWRITE")); -#endif - dsp_state = DSP_WAITHOSTWRITE; - SDL_SemWait(dsp56k_sem); - } + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); + } else { + value = dsp_core->registers[numreg]; + } - /* Wait for host to read */ - if (numbit==DSP_HOST_HSR_HTDE) { -#if DSP_DISASM_STATE - D(bug("Dsp: state = DSP_WAITHOSTREAD")); -#endif - dsp_state = DSP_WAITHOSTREAD; - SDL_SemWait(dsp56k_sem); - } - } - } + dsp_core->instr_cycle += 4; + if (newaddr >= 0x200) { + dsp_core->instr_cycle += 2*P_WAITSTATE; + } - dsp_pc = newpc; + if ((value & (1<pc = newaddr; cur_inst_len = 0; return; } + ++cur_inst_len; } -static void dsp_jmp(void) +static void dsp_jmp_ea(void) { - uint32 newpc; + Uint32 newpc; - switch((cur_inst >> 16) & BITMASK(8)) { - case 0x0a: - dsp_calc_ea((cur_inst >>8) & BITMASK(6), &newpc); - break; - case 0x0c: - newpc = cur_inst & BITMASK(12); - break; + dsp_calc_ea((cur_inst>>8) & BITMASK(6), &newpc); + cur_inst_len = 0; + dsp_core->pc = newpc; + + dsp_core->instr_cycle += 2; + if (newpc >= 0x200) { + dsp_core->instr_cycle += 2*P_WAITSTATE; } +} +static void dsp_jmp_imm(void) +{ + Uint32 newpc; + + newpc = cur_inst & BITMASK(12); cur_inst_len = 0; + dsp_core->pc = newpc; - /* Infinite loop ? */ - if (newpc == dsp_pc) { -#if DSP_DISASM_STATE - D(bug("Dsp: state = DSP_HALT")); -#endif - dsp_state = DSP_HALT; - SDL_SemWait(dsp56k_sem); - return; + dsp_core->instr_cycle += 2; + if (newpc >= 0x200) { + dsp_core->instr_cycle += 2*P_WAITSTATE; } - - dsp_pc = newpc; } -static void dsp_jscc(void) +static void dsp_jscc_ea(void) { - uint32 newpc, cc_code; + Uint32 newpc, cc_code; - cc_code = 0; - switch((cur_inst >> 16) & BITMASK(8)) { - case 0x0b: - dsp_calc_ea((cur_inst >>8) & BITMASK(6), &newpc); - cc_code=cur_inst & BITMASK(4); - break; - case 0x0f: - newpc = cur_inst & BITMASK(12); - cc_code=(cur_inst>>12) & BITMASK(4); - break; + dsp_calc_ea((cur_inst >>8) & BITMASK(6), &newpc); + cc_code=cur_inst & BITMASK(4); + + if (dsp_calc_cc(cc_code)) { + dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR], 0); + dsp_core->pc = newpc; + cur_inst_len = 0; + } + + dsp_core->instr_cycle += 2; + if (newpc >= 0x200) { + dsp_core->instr_cycle += 2*P_WAITSTATE; } +} +static void dsp_jscc_imm(void) +{ + Uint32 cc_code, newpc; + + newpc = cur_inst & BITMASK(12); + cc_code=(cur_inst>>12) & BITMASK(4); if (dsp_calc_cc(cc_code)) { - dsp_stack_push(dsp_pc+cur_inst_len, dsp_registers[DSP_REG_SR]); + dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR], 0); + dsp_core->pc = newpc; + cur_inst_len = 0; + } + + dsp_core->instr_cycle += 2; + if (newpc >= 0x200) { + dsp_core->instr_cycle += 2*P_WAITSTATE; + } +} - dsp_pc = newpc; +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; + } + + if ((value & (1<pc+2, dsp_core->registers[DSP_REG_SR], 0); + newpc = newaddr; + dsp_core->pc = newpc; cur_inst_len = 0; + return; } + ++cur_inst_len; } -static void dsp_jsclr(void) +static void dsp_jsclr_ea(void) { - uint32 memspace, addr, value, numreg, newpc, numbit; + Uint32 memspace, addr, value, newpc, numbit, newaddr; memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); - - switch((cur_inst>>14) & BITMASK(2)) { - case 0: - /* jsclr #n,x:aa,p:xx */ - /* jsclr #n,y:aa,p:xx */ - addr = value; - value = read_memory(memspace, addr); - break; - case 1: - /* jsclr #n,x:ea,p:xx */ - /* jsclr #n,y:ea,p:xx */ - dsp_calc_ea(value, &addr); - value = read_memory(memspace, addr); - break; - case 2: - /* jsclr #n,x:pp,p:xx */ - /* jsclr #n,y:pp,p:xx */ - addr = 0xffc0 + value; - value = read_memory(memspace, addr); - break; - case 3: - /* jsclr #n,R,p:xx */ - numreg = value; - value = dsp_registers[numreg]; - break; + 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; } - - cur_inst_len++; + if ((value & (1<pc+2, dsp_core->registers[DSP_REG_SR], 0); + newpc = newaddr; + dsp_core->pc = newpc; cur_inst_len = 0; + return; } + ++cur_inst_len; } -static void dsp_jset(void) +static void dsp_jsclr_pp(void) { - uint32 memspace, addr, value, numreg, numbit; - uint32 newpc; + 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); + + 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); + newpc = newaddr; + dsp_core->pc = newpc; + cur_inst_len = 0; + return; + } + ++cur_inst_len; +} - switch((cur_inst>>14) & BITMASK(2)) { - case 0: - /* jset #n,x:aa,p:xx */ - /* jset #n,y:aa,p:xx */ - addr = value; - value = read_memory(memspace, addr); - break; - case 1: - /* jset #n,x:ea,p:xx */ - /* jset #n,y:ea,p:xx */ - dsp_calc_ea(value, &addr); - value = read_memory(memspace, addr); - break; - case 2: - /* jset #n,x:pp,p:xx */ - /* jset #n,y:pp,p:xx */ - addr = 0xffc0 + value; - value = read_memory(memspace, addr); - break; - case 3: - /* jset #n,R,p:xx */ - numreg = value; - value = dsp_registers[numreg]; - break; +static void dsp_jsclr_reg(void) +{ + Uint32 value, numreg, newpc, numbit, newaddr; + + numreg = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + newaddr = read_memory_p(dsp_core->pc+1); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); + } else { + value = dsp_core->registers[numreg]; } - cur_inst_len++; + 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); + newpc = newaddr; + 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); + + dsp_core->instr_cycle += 4; + if (newaddr >= 0x200) { + dsp_core->instr_cycle += 2*P_WAITSTATE; + } + if (value & (1<pc = newpc; + cur_inst_len=0; + return; + } + ++cur_inst_len; +} - dsp_pc = newpc; +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); + + dsp_core->instr_cycle += 4; + if (newaddr >= 0x200) { + dsp_core->instr_cycle += 2*P_WAITSTATE; + } + + if (value & (1<pc = newpc; cur_inst_len=0; + return; } + ++cur_inst_len; } -static void dsp_jsr(void) +static void dsp_jset_pp(void) { - uint32 newpc; + 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); + + dsp_core->instr_cycle += 4; + if (newaddr >= 0x200) { + dsp_core->instr_cycle += 2*P_WAITSTATE; + } + + if (value & (1<pc = newpc; + cur_inst_len=0; + return; + } + ++cur_inst_len; +} - if (((cur_inst>>12) & BITMASK(4))==0) { - newpc = cur_inst & BITMASK(12); +static void dsp_jset_reg(void) +{ + Uint32 value, numreg, numbit, newpc, newaddr; + + numreg = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + newaddr = read_memory_p(dsp_core->pc+1); + + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); } else { - dsp_calc_ea((cur_inst>>8) & BITMASK(6),&newpc); + value = dsp_core->registers[numreg]; } - dsp_stack_push(dsp_pc+cur_inst_len, dsp_registers[DSP_REG_SR]); + dsp_core->instr_cycle += 4; + if (newaddr >= 0x200) { + dsp_core->instr_cycle += 2*P_WAITSTATE; + } + + if (value & (1<pc = newpc; + cur_inst_len=0; + return; + } + ++cur_inst_len; +} + +static void dsp_jsr_imm(void) +{ + Uint32 newpc; + + newpc = cur_inst & BITMASK(12); + + if (dsp_core->interrupt_state != DSP_INTERRUPT_LONG){ + dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR], 0); + } + else { + dsp_core->interrupt_state = DSP_INTERRUPT_NONE; + } + + dsp_core->pc = newpc; + cur_inst_len = 0; + + dsp_core->instr_cycle += 2; + if (newpc >= 0x200) { + dsp_core->instr_cycle += 2*P_WAITSTATE; + } +} + +static void dsp_jsr_ea(void) +{ + Uint32 newpc; + + dsp_calc_ea((cur_inst>>8) & BITMASK(6),&newpc); - dsp_pc = newpc; + if (dsp_core->interrupt_state != DSP_INTERRUPT_LONG){ + dsp_stack_push(dsp_core->pc+cur_inst_len, dsp_core->registers[DSP_REG_SR], 0); + } + else { + dsp_core->interrupt_state = DSP_INTERRUPT_NONE; + } + + dsp_core->pc = newpc; cur_inst_len = 0; + + dsp_core->instr_cycle += 2; + if (newpc >= 0x200) { + dsp_core->instr_cycle += 2*P_WAITSTATE; + } } -static void dsp_jsset(void) +static void dsp_jsset_aa(void) { - uint32 memspace, addr, value, numreg, newpc, numbit; + Uint32 memspace, addr, value, newpc, numbit, newaddr; memspace = (cur_inst>>6) & 1; - value = (cur_inst>>8) & BITMASK(6); + addr = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); + value = read_memory(memspace, addr); + newaddr = read_memory_p(dsp_core->pc+1); + + dsp_core->instr_cycle += 4; + if (newaddr >= 0x200) { + dsp_core->instr_cycle += 2*P_WAITSTATE; + } - switch((cur_inst>>14) & BITMASK(2)) { - case 0: - /* jsset #n,x:aa,p:xx */ - /* jsset #n,y:aa,p:xx */ - addr = value; - value = read_memory(memspace, addr); - break; - case 1: - /* jsset #n,x:ea,p:xx */ - /* jsset #n,y:ea,p:xx */ - dsp_calc_ea(value, &addr); - value = read_memory(memspace, addr); - break; - case 2: - /* jsset #n,x:pp,p:xx */ - /* jsset #n,y:pp,p:xx */ - addr = 0xffc0 + value; - value = read_memory(memspace, addr); - break; - case 3: - /* jsset #n,R,p:xx */ - numreg = value; - value = dsp_registers[numreg]; - break; + if (value & (1<pc+2, dsp_core->registers[DSP_REG_SR], 0); + newpc = newaddr; + dsp_core->pc = newpc; + cur_inst_len = 0; + return; + } + ++cur_inst_len; +} + +static void dsp_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; } - cur_inst_len++; if (value & (1<pc+2, dsp_core->registers[DSP_REG_SR], 0); + newpc = newaddr; + dsp_core->pc = newpc; + cur_inst_len = 0; + return; + } + ++cur_inst_len; +} - newpc = read_memory(DSP_SPACE_P, dsp_pc+1); - dsp_pc = newpc; +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); + + 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); + newpc = newaddr; + dsp_core->pc = newpc; cur_inst_len = 0; + return; } + ++cur_inst_len; } -static void dsp_lua(void) +static void dsp_jsset_reg(void) { - uint32 value, srcreg, dstreg; + Uint32 value, numreg, newpc, numbit, newaddr; - dsp_calc_ea((cur_inst>>8) & BITMASK(5), &value); - srcreg = (cur_inst>>8) & BITMASK(3); - dstreg = cur_inst & BITMASK(3); + numreg = (cur_inst>>8) & BITMASK(6); + numbit = cur_inst & BITMASK(5); + newaddr = read_memory_p(dsp_core->pc+1); - if (cur_inst & (1<<3)) { - dsp_registers[DSP_REG_N0+dstreg] = dsp_registers[DSP_REG_N0+srcreg]; + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); } else { - dsp_registers[DSP_REG_R0+dstreg] = dsp_registers[DSP_REG_R0+srcreg]; + value = dsp_core->registers[numreg]; } + + 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); + newpc = newaddr; + dsp_core->pc = newpc; + cur_inst_len = 0; + return; + } + ++cur_inst_len; } -static void dsp_movec(void) +static void dsp_lua(void) { - uint32 value; + Uint32 value, srcreg, dstreg, srcsave, srcnew; + + srcreg = (cur_inst>>8) & BITMASK(3); + + srcsave = dsp_core->registers[DSP_REG_R0+srcreg]; + dsp_calc_ea((cur_inst>>8) & BITMASK(5), &value); + srcnew = dsp_core->registers[DSP_REG_R0+srcreg]; + dsp_core->registers[DSP_REG_R0+srcreg] = srcsave; + + dstreg = cur_inst & BITMASK(3); - value = (cur_inst>>13) & (1<<3); - value |= (cur_inst>>12) & (1<<2); - value |= (cur_inst>>6) & (1<<1); - value |= (cur_inst>>5) & 1; + if (cur_inst & (1<<3)) { + dsp_core->registers[DSP_REG_N0+dstreg] = srcnew; + } else { + dsp_core->registers[DSP_REG_R0+dstreg] = srcnew; + } - opcodes_movec[value](); + dsp_core->instr_cycle += 2; } -static void dsp_movec_7(void) +static void dsp_movec_reg(void) { - uint32 numreg1, numreg2, value; + Uint32 numreg1, numreg2, value, dummy; /* S1,D2 */ /* S2,D1 */ numreg2 = (cur_inst>>8) & BITMASK(6); - numreg1 = (cur_inst & BITMASK(5))|0x20; + numreg1 = cur_inst & BITMASK(6); if (cur_inst & (1<<15)) { /* Write D1 */ if ((numreg2 == DSP_REG_A) || (numreg2 == DSP_REG_B)) { - dsp_pm_read_accu24(numreg2, &dsp_registers[numreg1]); + dsp_pm_read_accu24(numreg2, &value); } else { - dsp_registers[numreg1] = dsp_registers[numreg2]; + value = dsp_core->registers[numreg2]; } - dsp_registers[numreg1] &= BITMASK(registers_mask[numreg1]); + value &= BITMASK(registers_mask[numreg1]); + dsp_write_reg(numreg1, value); } else { /* Read S1 */ + if (numreg1 == DSP_REG_SSH) { + dsp_stack_pop(&value, &dummy); + } + else { + value = dsp_core->registers[numreg1]; + } if ((numreg2 == DSP_REG_A) || (numreg2 == DSP_REG_B)) { - value = dsp_registers[numreg1]; - dsp_registers[DSP_REG_A2+(numreg2 & 1)] = 0; + dsp_core->registers[DSP_REG_A2+(numreg2 & 1)] = 0; if (value & (1<<23)) { - dsp_registers[DSP_REG_A2+(numreg2 & 1)] = 0xff; + dsp_core->registers[DSP_REG_A2+(numreg2 & 1)] = 0xff; } - dsp_registers[DSP_REG_A1+(numreg2 & 1)] = value & BITMASK(24); - dsp_registers[DSP_REG_A0+(numreg2 & 1)] = 0; + dsp_core->registers[DSP_REG_A1+(numreg2 & 1)] = value & BITMASK(24); + dsp_core->registers[DSP_REG_A0+(numreg2 & 1)] = 0; } else { - dsp_registers[numreg2] = dsp_registers[numreg1]; - dsp_registers[numreg2] &= BITMASK(registers_mask[numreg2]); + dsp_core->registers[numreg2] = value & BITMASK(registers_mask[numreg2]); } } } -static void dsp_movec_9(void) +static void dsp_movec_aa(void) { - uint32 numreg, addr, memspace; + Uint32 numreg, addr, memspace, value, dummy; /* x:aa,D1 */ /* S1,x:aa */ /* y:aa,D1 */ /* S1,y:aa */ - numreg = (cur_inst & BITMASK(5))|0x20; + numreg = cur_inst & BITMASK(6); addr = (cur_inst>>8) & BITMASK(6); memspace = (cur_inst>>6) & 1; if (cur_inst & (1<<15)) { /* Write D1 */ - - dsp_registers[numreg] = read_memory(memspace, addr); - dsp_registers[numreg] &= BITMASK(registers_mask[numreg]); + value = read_memory(memspace, addr); + value &= BITMASK(registers_mask[numreg]); + dsp_write_reg(numreg, value); } else { /* Read S1 */ - - write_memory(memspace, addr, dsp_registers[numreg]); + if (numreg == DSP_REG_SSH) { + dsp_stack_pop(&value, &dummy); + } + else { + value = dsp_core->registers[numreg]; + } + write_memory(memspace, addr, value); } } -static void dsp_movec_b(void) +static void dsp_movec_imm(void) { - uint32 numreg; + Uint32 numreg, value; /* #xx,D1 */ - - numreg = (cur_inst & BITMASK(5))|0x20; - dsp_registers[numreg] = (cur_inst>>8) & BITMASK(8); + numreg = cur_inst & BITMASK(6); + value = (cur_inst>>8) & BITMASK(8); + value &= BITMASK(registers_mask[numreg]); + dsp_write_reg(numreg, value); } -static void dsp_movec_d(void) +static void dsp_movec_ea(void) { - uint32 numreg, addr, memspace, ea_mode; + Uint32 numreg, addr, memspace, ea_mode, value, dummy; int retour; /* x:ea,D1 */ @@ -2302,82 +2710,96 @@ static void dsp_movec_d(void) /* S1,y:ea */ /* #xxxx,D1 */ - numreg = (cur_inst & BITMASK(5))|0x20; + numreg = cur_inst & BITMASK(6); ea_mode = (cur_inst>>8) & BITMASK(6); memspace = (cur_inst>>6) & 1; if (cur_inst & (1<<15)) { /* Write D1 */ - retour = dsp_calc_ea(ea_mode, &addr); if (retour) { - dsp_registers[numreg] = addr; + value = addr; } else { - dsp_registers[numreg] = read_memory(memspace, addr); + value = read_memory(memspace, addr); } - dsp_registers[numreg] &= BITMASK(registers_mask[numreg]); + value &= BITMASK(registers_mask[numreg]); + dsp_write_reg(numreg, value); } else { /* Read S1 */ - - retour = dsp_calc_ea(ea_mode, &addr); - - write_memory(memspace, addr, dsp_registers[numreg]); + dsp_calc_ea(ea_mode, &addr); + if (numreg == DSP_REG_SSH) { + dsp_stack_pop(&value, &dummy); + } + else { + value = dsp_core->registers[numreg]; + } + write_memory(memspace, addr, value); } } -static void dsp_movem(void) +static void dsp_movem_aa(void) { - uint32 numreg, addr, ea_mode, value; + Uint32 numreg, addr, value, dummy; numreg = cur_inst & BITMASK(6); + addr = (cur_inst>>8) & BITMASK(6); - if (cur_inst & (1<<14)) { - /* S,p:ea */ - /* p:ea,D */ - - ea_mode = (cur_inst>>8) & BITMASK(6); - dsp_calc_ea(ea_mode, &addr); + if (cur_inst & (1<<15)) { + /* Write D */ + value = read_memory_p(addr); + value &= BITMASK(registers_mask[numreg]); + dsp_write_reg(numreg, value); } else { - /* S,p:aa */ - /* p:aa,D */ + /* Read S */ + if (numreg == DSP_REG_SSH) { + dsp_stack_pop(&value, &dummy); + } + else if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { + dsp_pm_read_accu24(numreg, &value); + } + else { + value = dsp_core->registers[numreg]; + } + write_memory(DSP_SPACE_P, addr, value); + } - addr = (cur_inst>>8) & BITMASK(6); + dsp_core->instr_cycle += 4; + if (addr>=0x200) { + dsp_core->instr_cycle += P_WAITSTATE; } +} + +static void dsp_movem_ea(void) +{ + Uint32 numreg, addr, ea_mode, value, dummy; + + numreg = cur_inst & BITMASK(6); + ea_mode = (cur_inst>>8) & BITMASK(6); + dsp_calc_ea(ea_mode, &addr); if (cur_inst & (1<<15)) { /* Write D */ - - if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - value = read_memory(DSP_SPACE_P, addr); - dsp_registers[DSP_REG_A2+(numreg & 1)] = 0; - if (value & (1<<23)) { - dsp_registers[DSP_REG_A2+(numreg & 1)] = 0xff; - } - dsp_registers[DSP_REG_A1+(numreg & 1)] = value & BITMASK(24); - dsp_registers[DSP_REG_A0+(numreg & 1)] = 0; - } else { - dsp_registers[numreg] = read_memory(DSP_SPACE_P, addr); - dsp_registers[numreg] &= BITMASK(registers_mask[numreg]); - } + value = read_memory_p(addr); + value &= BITMASK(registers_mask[numreg]); + dsp_write_reg(numreg, value); } else { /* Read S */ - - if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { + if (numreg == DSP_REG_SSH) { + dsp_stack_pop(&value, &dummy); + } + else if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { dsp_pm_read_accu24(numreg, &value); - } else { - value = dsp_registers[numreg]; + } + else { + value = dsp_core->registers[numreg]; } write_memory(DSP_SPACE_P, addr, value); } -} -static void dsp_movep(void) -{ - uint32 value; - - value = (cur_inst>>6) & BITMASK(2); - - opcodes_movep[value](); + dsp_core->instr_cycle += 4; + if (addr>=0x200) { + dsp_core->instr_cycle += P_WAITSTATE; + } } static void dsp_movep_0(void) @@ -2387,7 +2809,7 @@ static void dsp_movep_0(void) /* S,y:pp */ /* y:pp,D */ - uint32 addr, memspace, numreg, value; + Uint32 addr, memspace, numreg, value, dummy; addr = 0xffc0 + (cur_inst & BITMASK(6)); memspace = (cur_inst>>16) & 1; @@ -2395,30 +2817,24 @@ static void dsp_movep_0(void) if (cur_inst & (1<<15)) { /* Write pp */ - if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { dsp_pm_read_accu24(numreg, &value); - } else { - value = dsp_registers[numreg]; + } + else if (numreg == DSP_REG_SSH) { + dsp_stack_pop(&value, &dummy); + } + else { + value = dsp_core->registers[numreg]; } write_memory(memspace, addr, value); } else { /* Read pp */ - value = read_memory(memspace, addr); - - if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_registers[DSP_REG_A2+(numreg & 1)] = 0; - if (value & (1<<23)) { - dsp_registers[DSP_REG_A2+(numreg & 1)] = 0xff; - } - dsp_registers[DSP_REG_A1+(numreg & 1)] = value & BITMASK(24); - dsp_registers[DSP_REG_A0+(numreg & 1)] = 0; - } else { - dsp_registers[numreg] = value; - dsp_registers[numreg] &= BITMASK(registers_mask[numreg]); - } + value &= BITMASK(registers_mask[numreg]); + dsp_write_reg(numreg, value); } + + dsp_core->instr_cycle += 2; } static void dsp_movep_1(void) @@ -2428,7 +2844,7 @@ static void dsp_movep_1(void) /* p:ea,y:pp */ /* y:pp,p:ea */ - uint32 xyaddr, memspace, paddr; + Uint32 xyaddr, memspace, paddr; xyaddr = 0xffc0 + (cur_inst & BITMASK(6)); dsp_calc_ea((cur_inst>>8) & BITMASK(6), &paddr); @@ -2436,14 +2852,16 @@ static void dsp_movep_1(void) if (cur_inst & (1<<15)) { /* Write pp */ - write_memory(memspace, xyaddr, read_memory(DSP_SPACE_P, paddr)); + write_memory(memspace, xyaddr, read_memory_p(paddr)); } else { /* Read pp */ write_memory(DSP_SPACE_P, paddr, read_memory(memspace, xyaddr)); } + + dsp_core->instr_cycle += 2; } -static void dsp_movep_2(void) +static void dsp_movep_23(void) { /* x:ea,x:pp */ /* y:ea,x:pp */ @@ -2456,7 +2874,7 @@ static void dsp_movep_2(void) /* y:pp,y:ea */ /* y:pp,x:ea */ - uint32 addr, peraddr, easpace, perspace, ea_mode; + Uint32 addr, peraddr, easpace, perspace, ea_mode; int retour; peraddr = 0xffc0 + (cur_inst & BITMASK(6)); @@ -2472,21 +2890,28 @@ static void dsp_movep_2(void) 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; } static void dsp_norm(void) { - uint32 cursr,cur_e, cur_euz, dest[3], numreg, rreg; - uint16 newsr; + Uint32 cursr,cur_e, cur_euz, dest[3], numreg, rreg; + Uint16 newsr; - cursr = dsp_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; @@ -2494,173 +2919,197 @@ static void dsp_norm(void) cur_euz &= 1; numreg = (cur_inst>>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+numreg]; - dest[1] = dsp_registers[DSP_REG_A1+numreg]; - dest[2] = dsp_registers[DSP_REG_A0+numreg]; + 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_registers[rreg]; - dsp_registers[rreg] &= BITMASK(16); + --dsp_core->registers[rreg]; + dsp_core->registers[rreg] &= BITMASK(16); } else if (cur_e) { newsr = dsp_asr56(dest); - ++dsp_registers[rreg]; - dsp_registers[rreg] &= BITMASK(16); + ++dsp_core->registers[rreg]; + dsp_core->registers[rreg] &= BITMASK(16); } else { newsr = 0; } - dsp_registers[DSP_REG_A2+numreg] = dest[0]; - dsp_registers[DSP_REG_A1+numreg] = dest[1]; - dsp_registers[DSP_REG_A0+numreg] = dest[2]; - - dsp_ccr_extension(&dest[0], &dest[1], &dest[2]); - dsp_ccr_unnormalized(&dest[0], &dest[1], &dest[2]); - dsp_ccr_negative(&dest[0], &dest[1], &dest[2]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; + dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; + dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + + dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; } static void dsp_ori(void) { - uint32 regnum, value; + Uint32 regnum, value; value = (cur_inst >> 8) & BITMASK(8); regnum = cur_inst & BITMASK(2); switch(regnum) { case 0: /* mr */ - dsp_registers[DSP_REG_SR] |= value<<8; + dsp_core->registers[DSP_REG_SR] |= value<<8; break; case 1: /* ccr */ - dsp_registers[DSP_REG_SR] |= value; + dsp_core->registers[DSP_REG_SR] |= value; break; case 2: /* omr */ - dsp_registers[DSP_REG_OMR] |= value; + dsp_core->registers[DSP_REG_OMR] |= value; break; } } -static void dsp_rep(void) -{ - uint32 value; - - dsp_registers[DSP_REG_LCSAVE] = dsp_registers[DSP_REG_LC]; - - value = (cur_inst>>12) & (BITMASK(2)<<2); - value |= (cur_inst>>6) & (1<<1); - value |= (cur_inst>>5) & 1; +/* + REP instruction parameter encoding - opcodes_rep[value](); - pc_on_rep = 1; /* Not decrement LC at first time */ - dsp_loop_rep = 1; /* We are now running rep */ -} + xxxxxxxx 00xxxxxx 0xxxxxxx aa + xxxxxxxx 01xxxxxx 0xxxxxxx ea + xxxxxxxx YYxxxxxx 1xxxxxxx imm + xxxxxxxx 11xxxxxx 0xxxxxxx reg +*/ -static void dsp_rep_1(void) +static void dsp_rep_aa(void) { /* x:aa */ /* y:aa */ + dsp_core->registers[DSP_REG_LCSAVE] = dsp_core->registers[DSP_REG_LC]; + dsp_core->pc_on_rep = 1; /* Not decrement LC at first time */ + dsp_core->loop_rep = 1; /* We are now running rep */ + + dsp_core->registers[DSP_REG_LC]=read_memory((cur_inst>>6) & 1,(cur_inst>>8) & BITMASK(6)); - dsp_registers[DSP_REG_LC]=read_memory((cur_inst>>6) & 1,(cur_inst>>8) & BITMASK(6)); + dsp_core->instr_cycle += 2; } -static void dsp_rep_3(void) +static void dsp_rep_imm(void) { /* #xxx */ - dsp_registers[DSP_REG_LC]= (cur_inst>>8) & BITMASK(8); + dsp_core->registers[DSP_REG_LCSAVE] = dsp_core->registers[DSP_REG_LC]; + dsp_core->pc_on_rep = 1; /* Not decrement LC at first time */ + dsp_core->loop_rep = 1; /* We are now running rep */ + + dsp_core->registers[DSP_REG_LC] = ((cur_inst>>8) & BITMASK(8)) + + ((cur_inst & BITMASK(4))<<8); + + dsp_core->instr_cycle += 2; } -static void dsp_rep_5(void) +static void dsp_rep_ea(void) { - uint32 value; + Uint32 value; /* x:ea */ /* y:ea */ + dsp_core->registers[DSP_REG_LCSAVE] = dsp_core->registers[DSP_REG_LC]; + dsp_core->pc_on_rep = 1; /* Not decrement LC at first time */ + dsp_core->loop_rep = 1; /* We are now running rep */ + dsp_calc_ea((cur_inst>>8) & BITMASK(6),&value); - dsp_registers[DSP_REG_LC]= value; + dsp_core->registers[DSP_REG_LC]= read_memory((cur_inst>>6) & 1, value); + + dsp_core->instr_cycle += 2; } -static void dsp_rep_d(void) +static void dsp_rep_reg(void) { - uint32 numreg; + Uint32 numreg; /* R */ + dsp_core->registers[DSP_REG_LCSAVE] = dsp_core->registers[DSP_REG_LC]; + dsp_core->pc_on_rep = 1; /* Not decrement LC at first time */ + dsp_core->loop_rep = 1; /* We are now running rep */ + numreg = (cur_inst>>8) & BITMASK(6); if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &dsp_registers[DSP_REG_LC]); + dsp_pm_read_accu24(numreg, &dsp_core->registers[DSP_REG_LC]); } else { - dsp_registers[DSP_REG_LC] = dsp_registers[numreg]; + dsp_core->registers[DSP_REG_LC] = dsp_core->registers[numreg]; } - dsp_registers[DSP_REG_LC] &= BITMASK(16); + dsp_core->registers[DSP_REG_LC] &= BITMASK(16); + + dsp_core->instr_cycle += 2; } static void dsp_reset(void) { /* Reset external peripherals */ + dsp_core->instr_cycle += 2; } static void dsp_rti(void) { - uint32 newpc, newsr; + Uint32 newpc = 0, newsr = 0; dsp_stack_pop(&newpc, &newsr); - - dsp_pc = newpc; - dsp_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; + } } static void dsp_rts(void) { - uint32 newpc, newsr; + Uint32 newpc = 0, newsr; dsp_stack_pop(&newpc, &newsr); - - dsp_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; + } } static void dsp_stop(void) { - dsp_state = DSP_HALT; - SDL_SemWait(dsp56k_sem); +#if DSP_DISASM_STATE + fprintf(stderr, "Dsp: STOP instruction\n"); +#endif } static void dsp_swi(void) { /* Raise interrupt p:0x0006 */ -#if DSP_DISASM_INTER - D(bug("Dsp: Interrupt: Swi")); -#endif + dsp_core_add_interrupt(dsp_core, DSP_INTER_SWI); + + dsp_core->instr_cycle += 6; } static void dsp_tcc(void) { - uint32 cc_code, regsrc1, regdest1, value; - uint32 regsrc2, regdest2; + Uint32 cc_code, regsrc1, regdest1, value; + Uint32 regsrc2, regdest2; cc_code = (cur_inst>>12) & BITMASK(4); if (dsp_calc_cc(cc_code)) { regsrc1 = registers_tcc[(cur_inst>>3) & BITMASK(4)][0]; - regdest1 = registers_tcc[(cur_inst>>3) & BITMASK(4)][0]; + 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_registers[DSP_REG_A2+(regsrc1 & 1)]; - tmp_parmove_src[0][1]=dsp_registers[DSP_REG_A1+(regsrc1 & 1)]; - tmp_parmove_src[0][2]=dsp_registers[DSP_REG_A0+(regsrc1 & 1)]; + 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_registers[regsrc1]; + value = dsp_core->registers[regsrc1]; tmp_parmove_src[0][0]=0; if (value & (1<<23)) { tmp_parmove_src[0][0]=0x0000ff; @@ -2670,24 +3119,25 @@ static void dsp_tcc(void) } /* Write D1 */ - dsp_registers[DSP_REG_A2+(regdest1 & 1)]=tmp_parmove_src[0][0]; - dsp_registers[DSP_REG_A1+(regdest1 & 1)]=tmp_parmove_src[0][1]; - dsp_registers[DSP_REG_A0+(regdest1 & 1)]=tmp_parmove_src[0][2]; + 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]; /* S2,D2 transfer */ if (cur_inst & (1<<16)) { - regsrc2 = DSP_REG_R0+(cur_inst & BITMASK(3)); - regdest2 = DSP_REG_R0+((cur_inst>>8) & BITMASK(3)); + regsrc2 = DSP_REG_R0+((cur_inst>>8) & BITMASK(3)); + regdest2 = DSP_REG_R0+(cur_inst & BITMASK(3)); - dsp_registers[regdest2] = dsp_registers[regsrc2]; + dsp_core->registers[regdest2] = dsp_core->registers[regsrc2]; } } } static void dsp_wait(void) { - dsp_state = DSP_HALT; - SDL_SemWait(dsp56k_sem); +#if DSP_DISASM_STATE + fprintf(stderr, "Dsp: WAIT instruction\n"); +#endif } /********************************** @@ -2696,7 +3146,7 @@ static void dsp_wait(void) static void dsp_parmove_read(void) { - uint32 value; + Uint32 value; tmp_parmove_len[0] = tmp_parmove_len[1] = 0; @@ -2707,9 +3157,18 @@ static void dsp_parmove_read(void) 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; + Uint32 i,j; for(i=0;i<2;i++) { if (tmp_parmove_len[i]==0) { @@ -2726,7 +3185,7 @@ static void dsp_parmove_write(void) /* Write to memory */ write_memory(tmp_parmove_space[i], tmp_parmove_dest[i][j].dsp_address, tmp_parmove_src[i][j]); } else { - uint32 *dest; + Uint32 *dest; /* Write to register */ dest=tmp_parmove_dest[i][j].host_pointer; @@ -2736,57 +3195,82 @@ static void dsp_parmove_write(void) } } -static void dsp_pm_read_accu24(int numreg, uint32 *dest) +static int dsp_pm_read_accu24(int numreg, Uint32 *dest) { - uint32 scaling, value, numbits; + Uint32 scaling, value, reg; + int got_limited=0; /* Read an accumulator, stores it limited */ - scaling = (dsp_registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); - numreg &= 1; + scaling = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); + reg = numreg & 1; - /* scaling==1 */ - value = dsp_registers[DSP_REG_A2+numreg] & 0xff; - numbits = 8; + value = (dsp_core->registers[DSP_REG_A2+reg]) << 24; + value += dsp_core->registers[DSP_REG_A1+reg]; switch(scaling) { case 0: - value <<=1; - value |= (dsp_registers[DSP_REG_A1+numreg]>>23) & 1; - numbits=9; + /* No scaling */ + break; + case 1: + /* scaling down */ + value >>= 1; break; case 2: - value <<=2; - value |= (dsp_registers[DSP_REG_A1+numreg]>>22) & 3; - numbits=10; + /* scaling up */ + value <<= 1; + value |= (dsp_core->registers[DSP_REG_A0+reg]>>23) & 1; break; + /* indeterminate */ + case 3: + break; + } + + /* limiting ? */ + value &= BITMASK(24); + + if (dsp_core->registers[DSP_REG_A2+reg] == 0) { + if (value <= 0x007fffff) { + /* No limiting */ + *dest=value; + return 0; + } + } + + if (dsp_core->registers[DSP_REG_A2+reg] == 0xff) { + if (value >= 0x00800000) { + /* No limiting */ + *dest=value; + return 0; + } } - if ((value==0) || (value==(uint32)(BITMASK(numbits)))) { - /* No limiting */ - *dest=dsp_registers[DSP_REG_A1+numreg]; - } else if (dsp_registers[DSP_REG_A2+numreg] & (1<<7)) { + if (dsp_core->registers[DSP_REG_A2+reg] & (1<<7)) { /* Limited to maximum negative value */ *dest=0x00800000; - dsp_registers[DSP_REG_SR] |= (1<registers[DSP_REG_SR] |= (1<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_registers[numreg]; + tmp_parmove_dest[position][1].host_pointer=&dsp_core->registers[numreg]; tmp_parmove_start[position]=1; tmp_parmove_len[position]=1; @@ -2795,7 +3279,7 @@ static void dsp_pm_writereg(int numreg, static void dsp_pm_0(void) { - uint32 memspace, dummy, numreg, value; + Uint32 memspace, dummy, numreg, value; /* 0000 100d 00mm mrrr S,x:ea x0,D 0000 100d 10mm mrrr S,y:ea y0,D @@ -2815,7 +3299,7 @@ static void dsp_pm_0(void) tmp_parmove_space[0]=memspace; /* [x|y]0 to [A|B] */ - value = dsp_registers[DSP_REG_X0+(memspace<<1)]; + value = dsp_core->registers[DSP_REG_X0+(memspace<<1)]; if (value & (1<<23)) { tmp_parmove_src[1][0]=0x0000ff; } else { @@ -2823,19 +3307,18 @@ static void dsp_pm_0(void) } tmp_parmove_src[1][1]=value; tmp_parmove_src[1][2]=0x000000; - tmp_parmove_dest[1][0].host_pointer=&dsp_registers[DSP_REG_A2+numreg]; - tmp_parmove_dest[1][1].host_pointer=&dsp_registers[DSP_REG_A1+numreg]; - tmp_parmove_dest[1][2].host_pointer=&dsp_registers[DSP_REG_A0+numreg]; - - tmp_parmove_start[1] = 0; - tmp_parmove_len[1] = 3; - - tmp_parmove_type[0]=0; + 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; } static void dsp_pm_1(void) { - uint32 memspace, numreg, value, xy_addr, retour; + Uint32 memspace, numreg, value, xy_addr, retour; /* 0001 ffdf w0mm mrrr x:ea,D1 S2,D2 S1,x:ea S2,D2 @@ -2892,7 +3375,7 @@ static void dsp_pm_1(void) 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_registers[numreg]; + tmp_parmove_src[0][1]=dsp_core->registers[numreg]; } tmp_parmove_dest[0][1].dsp_address=xy_addr; @@ -2917,39 +3400,39 @@ static void dsp_pm_1(void) /* D2 */ if (memspace) { /* Y: */ - numreg = DSP_REG_Y0 + ((cur_inst>>18) & 1); + numreg = DSP_REG_X0 + ((cur_inst>>18) & 1); } else { /* X: */ - numreg = DSP_REG_X0 + ((cur_inst>>16) & 1); + 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_registers[numreg]; + tmp_parmove_dest[1][1].host_pointer=&dsp_core->registers[numreg]; - tmp_parmove_start[0]=1; - tmp_parmove_len[0]=1; + tmp_parmove_start[1]=1; + tmp_parmove_len[1]=1; - tmp_parmove_type[0]=0; + tmp_parmove_type[1]=0; } static void dsp_pm_2(void) { - uint32 dummy; + Uint32 dummy; /* 0010 0000 0000 0000 nop 0010 0000 010m mrrr R update 0010 00ee eeed dddd S,D 001d dddd iiii iiii #xx,D */ - if (((cur_inst >> 8) & 0xffff) == 0x2000) { + if ((cur_inst & 0xffff00) == 0x200000) { return; } - if (((cur_inst >> 8) & 0xffe0) == 0x2040) { + if ((cur_inst & 0xffe000) == 0x204000) { dsp_calc_ea((cur_inst>>8) & BITMASK(5), &dummy); return; } - if (((cur_inst >> 8) & 0xfc00) == 0x2000) { + if ((cur_inst & 0xfc0000) == 0x200000) { dsp_pm_2_2(); return; } @@ -2962,7 +3445,7 @@ static void dsp_pm_2_2(void) /* 0010 00ee eeed dddd S,D */ - uint32 srcreg, dstreg; + Uint32 srcreg, dstreg; srcreg = (cur_inst >> 13) & BITMASK(5); dstreg = (cur_inst >> 8) & BITMASK(5); @@ -2972,28 +3455,22 @@ static void dsp_pm_2_2(void) tmp_parmove_src[0][2]= 0x000000; if ((srcreg == DSP_REG_A) || (srcreg == DSP_REG_B)) { - if ((dstreg == DSP_REG_A) || (dstreg == DSP_REG_B)) { - /* Accu to accu: full 56 bits */ - tmp_parmove_src[0][0]=dsp_registers[DSP_REG_A2+(srcreg & 1)] & BITMASK(8); - tmp_parmove_src[0][1]=dsp_registers[DSP_REG_A1+(srcreg & 1)] & BITMASK(24); - tmp_parmove_src[0][2]=dsp_registers[DSP_REG_A0+(srcreg & 1)] & BITMASK(24); - } else { - /* Accu to register: limited 24 bits */ - dsp_pm_read_accu24(srcreg, &tmp_parmove_src[0][1]); - if (tmp_parmove_src[0][1] & (1<<23)) { - tmp_parmove_src[0][0]=0x0000ff; - } + /* 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_registers[srcreg] & BITMASK(registers_mask[srcreg]); + 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_registers[srcreg] & BITMASK(registers_mask[srcreg]); + tmp_parmove_src[0][1]=dsp_core->registers[srcreg] & BITMASK(registers_mask[dstreg]); } } @@ -3003,7 +3480,7 @@ static void dsp_pm_2_2(void) static void dsp_pm_3(void) { - uint32 dest, srcvalue; + Uint32 dest, srcvalue; /* 001d dddd iiii iiii #xx,R */ @@ -3036,158 +3513,186 @@ static void dsp_pm_3(void) static void dsp_pm_4(void) { - uint32 l_addr, value; - int retour; /* - 0100 l0ll w0aa aaaa l:aa,D + 0100 l0ll w0aa aaaa l:aa,D S,l:aa - 0100 l0ll w1mm mrrr l:ea,D + 0100 l0ll w1mm mrrr l:ea,D S,l:ea - 01dd 0ddd w0aa aaaa x:aa,D + 01dd 0ddd w0aa aaaa x:aa,D S,x:aa - 01dd 0ddd w1mm mrrr x:ea,D + 01dd 0ddd w1mm mrrr x:ea,D S,x:ea #xxxxxx,D - 01dd 1ddd w0aa aaaa y:aa,D + 01dd 1ddd w0aa aaaa y:aa,D S,y:aa - 01dd 1ddd w1mm mrrr y:ea,D + 01dd 1ddd w1mm mrrr y:ea,D S,y:ea #xxxxxx,D */ - value = (cur_inst>>16) & BITMASK(3); - value |= (cur_inst>>17) & (BITMASK(2)<<3); - - if ((value>>2)==0) { - value = (cur_inst>>8) & BITMASK(6); - if (cur_inst & (1<<14)) { - retour = dsp_calc_ea(value, &l_addr); - } else { - l_addr = value; - retour = 0; - } - dsp_pm_4x(retour, l_addr); + if ((cur_inst & 0xf40000)==0x400000) { + dsp_pm_4x(); return; } dsp_pm_5(); } -static void dsp_pm_4x(int immediat, uint32 l_addr) +static void dsp_pm_4x(void) { - uint32 value, numreg, numreg2; + Uint32 value, numreg, l_addr; /* - 0100 l0ll w0aa aaaa l:aa,D - S,l:aa - 0100 l0ll w1mm mrrr l:ea,D - S,l:ea + 0100 l0ll w0aa aaaa l:aa,D + S,l:aa + 0100 l0ll w1mm mrrr l:ea,D + S,l:ea */ - l_addr &= BITMASK(16); + value = (cur_inst>>8) & BITMASK(6); + if (cur_inst & (1<<14)) { + dsp_calc_ea(value, &l_addr); + } else { + l_addr = value; + } + numreg = (cur_inst>>16) & BITMASK(2); numreg |= (cur_inst>>17) & (1<<2); + /* 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); - /* S1 */ - value = read_memory(DSP_SPACE_X,l_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[registers_lmove[numreg][0]]); - tmp_parmove_src[0][2] = 0x000000; - - /* S2 */ - value = read_memory(DSP_SPACE_Y,l_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[registers_lmove[numreg][1]]); - tmp_parmove_src[1][2] = 0x000000; - - /* D1 */ - tmp_parmove_dest[0][0].host_pointer = NULL; - tmp_parmove_start[0]=1; - tmp_parmove_len[0]=1; - if (numreg >= 4) { - tmp_parmove_dest[0][0].host_pointer = &dsp_registers[DSP_REG_A2+(numreg & 1)]; - tmp_parmove_start[0]=0; - tmp_parmove_len[0]=2; - } - numreg2 = registers_lmove[numreg][0]; - if ((numreg2 == DSP_REG_A) || (numreg2 == DSP_REG_B)) { - tmp_parmove_dest[0][1].host_pointer = &dsp_registers[DSP_REG_A1+(numreg2 & 1)]; - } else { - tmp_parmove_dest[0][1].host_pointer = &dsp_registers[numreg2]; - } - if (numreg >= 6) { - tmp_parmove_dest[0][2].host_pointer = &dsp_registers[DSP_REG_A0+(numreg & 1)]; - tmp_parmove_start[0]=0; - tmp_parmove_len[0]=3; + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + break; } tmp_parmove_type[0]=0; - - /* D2 */ - tmp_parmove_dest[1][0].host_pointer = NULL; - tmp_parmove_start[1]=1; - tmp_parmove_len[1]=1; - if (numreg >= 4) { - tmp_parmove_dest[1][0].host_pointer = &dsp_registers[DSP_REG_A2+(numreg & 1)]; - tmp_parmove_start[1]=0; - tmp_parmove_len[1]=2; - } - numreg2 = registers_lmove[numreg][1]; - if ((numreg2 == DSP_REG_A) || (numreg2 == DSP_REG_B)) { - tmp_parmove_dest[1][1].host_pointer = &dsp_registers[DSP_REG_A1+(numreg2 & 1)]; - } else { - tmp_parmove_dest[1][1].host_pointer = &dsp_registers[numreg2]; - } - if (numreg >= 6) { - tmp_parmove_dest[1][2].host_pointer = &dsp_registers[DSP_REG_A0+(numreg & 1)]; - tmp_parmove_start[1]=0; - tmp_parmove_len[1]=3; - } - tmp_parmove_len[0]=1; - tmp_parmove_type[1]=0; } else { /* Read S */ - /* S1 */ - numreg2 = registers_lmove[numreg][0]; - if (numreg>=4) { - /* A, B, AB, BA */ - dsp_pm_read_accu24(numreg2, &tmp_parmove_src[0][1]); - } else { - tmp_parmove_src[0][1] = dsp_registers[numreg2]; - } - - /* S2 */ - numreg2 = registers_lmove[numreg][1]; - if (numreg>=4) { - /* A, B, AB, BA */ - dsp_pm_read_accu24(numreg2, &tmp_parmove_src[1][1]); - } else { - tmp_parmove_src[1][1] = dsp_registers[numreg2]; + 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]; + 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]; + 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]; + 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]; + 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]; + } + 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]; + } + 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]); + 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]); + 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; } @@ -3195,16 +3700,16 @@ static void dsp_pm_4x(int immediat, uint static void dsp_pm_5(void) { - uint32 memspace, numreg, value, xy_addr, retour; + Uint32 memspace, numreg, value, xy_addr, retour; /* - 01dd 0ddd w0aa aaaa x:aa,D + 01dd 0ddd w0aa aaaa x:aa,D S,x:aa - 01dd 0ddd w1mm mrrr x:ea,D + 01dd 0ddd w1mm mrrr x:ea,D S,x:ea #xxxxxx,D - 01dd 1ddd w0aa aaaa y:aa,D + 01dd 1ddd w0aa aaaa y:aa,D S,y:aa - 01dd 1ddd w1mm mrrr y:ea,D + 01dd 1ddd w1mm mrrr y:ea,D S,y:ea #xxxxxx,D */ @@ -3230,12 +3735,12 @@ static void dsp_pm_5(void) } 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; } - 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; @@ -3245,7 +3750,7 @@ static void dsp_pm_5(void) 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_registers[numreg]; + tmp_parmove_src[0][1]=dsp_core->registers[numreg]; } tmp_parmove_dest[0][1].dsp_address=xy_addr; @@ -3260,11 +3765,11 @@ static void dsp_pm_5(void) static void dsp_pm_8(void) { - uint32 ea1, ea2; - uint32 numreg1, numreg2; - uint32 value, dummy1, dummy2; + Uint32 ea1, ea2; + Uint32 numreg1, numreg2; + Uint32 value, 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 @@ -3284,8 +3789,13 @@ static void dsp_pm_8(void) ea2 |= (1<<5); } - dsp_calc_ea(ea1, &dummy1); - dsp_calc_ea(ea2, &dummy2); + dsp_calc_ea(ea1, &x_addr); + dsp_calc_ea(ea2, &y_addr); + + /* 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; @@ -3303,14 +3813,13 @@ static void dsp_pm_8(void) if (cur_inst & (1<<15)) { /* Write D1 */ - value = read_memory(DSP_SPACE_X, dummy1); + 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; } else { @@ -3319,14 +3828,11 @@ static void dsp_pm_8(void) 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_registers[numreg1]; + tmp_parmove_src[0][1]=dsp_core->registers[numreg1]; } - - tmp_parmove_dest[0][1].dsp_address=dummy1; - + 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; } @@ -3334,29 +3840,26 @@ static void dsp_pm_8(void) if (cur_inst & (1<<22)) { /* Write D2 */ - value = read_memory(DSP_SPACE_Y, dummy2); + 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; } else { /* Read S2 */ - if ((numreg1==DSP_REG_A) || (numreg1==DSP_REG_B)) { - dsp_pm_read_accu24(numreg1, &tmp_parmove_src[1][1]); + 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_registers[numreg1]; + tmp_parmove_src[1][1]=dsp_core->registers[numreg2]; } - tmp_parmove_dest[1][1].dsp_address=dummy2; - + 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; } @@ -3370,10 +3873,10 @@ static void dsp_pm_8(void) /* source,dest[1] is 47:24 */ /* source,dest[2] is 23:00 */ -static uint16 dsp_abs56(uint32 *dest) +static Uint16 dsp_abs56(Uint32 *dest) { - uint32 zerodest[3]; - uint16 newsr; + Uint32 zerodest[3]; + Uint16 newsr; /* D=|D| */ @@ -3392,9 +3895,9 @@ static uint16 dsp_abs56(uint32 *dest) return newsr; } -static uint16 dsp_asl56(uint32 *dest) +static Uint16 dsp_asl56(Uint32 *dest) { - uint16 overflow, carry; + Uint16 overflow, carry; /* Shift left dest 1 bit: D<<=1 */ @@ -3416,9 +3919,9 @@ static uint16 dsp_asl56(uint32 *dest) return (overflow<>=1 */ @@ -3439,119 +3942,97 @@ static uint16 dsp_asr56(uint32 *dest) return (carry<>7) & 1; + flg_d = (dest[0]>>7) & 1; + + not_dest[2] = ((Uint32)(~dest[2])) & BITMASK(24); + not_dest[1] = ((Uint32)(~dest[1])) & BITMASK(24); + not_dest[0] = ((Uint32)(~dest[0])) & BITMASK(8); /* Add source to dest: D = D+S */ + dest[2] += source[2]; + dest[1] += source[1]+((dest[2]>>24) & 1); + dest[0] += source[0]+((dest[1]>>24) & 1); + dest[2] &= BITMASK(24); dest[1] &= BITMASK(24); dest[0] &= BITMASK(8); - carry = (dest[0]>>7) & 1; - - if (dest[0] & (1<<7)) { - dest[0] |= 0xffffff00; - } - - dest[2] += source[2] & BITMASK(24); - - dest[1] += source[1] & BITMASK(24); - if ((dest[2]>>24) & BITMASK(8)) { - dest[1]++; - } + flg_r = (dest[0]>>7) & 1; - src = source[0] & BITMASK(8); - if (src & (1<<7)) { - src |= 0xffffff00; - } - dest[0] += src; - if ((dest[1]>>24) & BITMASK(8)) { - dest[0]++; - } + /*set overflow*/ + overflow = (flg_s ^ flg_r) & (flg_d ^ flg_r); - /* overflow if we go below -256.0 or above +256.0 */ - overflow = (((dest[0] & 0xffffff00)!=0) && ((dest[0] & 0xffffff00)!=0xffffff00)); + /* set carry : carry (for a add) = ~dest < source */ + carry = 0; - if (overflow) { + if (not_dest[0] < source[0]) { carry = 1; - } else { - if (carry) { - /* Carry set if we go from negative to positive value */ - carry = ( ((dest[0]>>7) & 1)==0); - } else { - /* Carry set if we go from positive to negative value */ - carry = ( ((dest[0]>>7) & 1)==1); + } else if (not_dest[0] == source[0]) { + if (not_dest[1] < source[1]) { + carry = 1; + } else if (not_dest[1] == source[1]) { + if (not_dest[2] < source[2]) { + carry = 1; + } } } - dest[2] &= BITMASK(24); - dest[1] &= BITMASK(24); - dest[0] &= BITMASK(8); - return (overflow<>24) & 1); + dest[0] -= source[0]+((dest[1]>>24) & 1); dest[2] &= BITMASK(24); dest[1] &= BITMASK(24); dest[0] &= BITMASK(8); - carry = (dest[0]>>7) & 1; + flg_s = (source[0]>>7) & 1; + flg_d = (dest_save[0]>>7) & 1; + flg_r = (dest[0]>>7) & 1; - if (dest[0] & (1<<7)) { - dest[0] |= 0xffffff00; - } - - dest[2] -= source[2] & BITMASK(24); - - dest[1] -= source[1] & BITMASK(24); - if ((dest[2]>>24) & BITMASK(8)) { - dest[1]--; - } + /* set overflow */ + overflow = (flg_s ^ flg_d) & (flg_r ^ flg_d); - src = source[0] & BITMASK(8); - if (src & (1<<7)) { - src |= 0xffffff00; - } - dest[0] -= src; - if ((dest[1]>>24) & BITMASK(8)) { - dest[0]--; - } - - /* overflow if we go below -256.0 or above +256.0 */ - overflow = (((dest[0] & 0xffffff00)!=0) && ((dest[0] & 0xffffff00)!=0xffffff00)); + /* set carry : carry (for a sub) = dest < source */ + carry = 0; - if (overflow) { + if (dest_save[0] < source[0]) { carry = 1; - } else { - if (carry) { - /* Carry set if we go from negative to positive value */ - carry = ( ((dest[0]>>7) & 1)==0); - } else { - /* Carry set if we go from positive to negative value */ - carry = ( ((dest[0]>>7) & 1)==1); + } else if (dest_save[0] == source[0]) { + if (dest_save[1] < source[1]) { + carry = 1; + } else if (dest_save[1] == source[1]) { + if (dest_save[2] < source[2]) { + carry = 1; + } } } - dest[2] &= BITMASK(24); - dest[1] &= BITMASK(24); - dest[0] &= BITMASK(8); - return (overflow<>24) & BITMASK(8)) { - ++dest[0]; - dest[0] &= BITMASK(8); - dest[1] &= BITMASK(24); - } + /* Scaling mode S0 */ + if (dsp_core->registers[DSP_REG_SR] & (1<0x800000) { - ++dest[1]; - if ((dest[1]>>24) & BITMASK(8)) { - ++dest[0]; - dest[0] &= BITMASK(8); - dest[1] &= BITMASK(24); + dest[1] &= 0xfffffe; + dest[2]=0; + } + /* Scaling mode S1 */ + else if (dsp_core->registers[DSP_REG_SR] & (1<>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+numreg]; - dest[1] = dsp_registers[DSP_REG_A1+numreg]; - dest[2] = dsp_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]; overflowed = ((dest[2]==0) && (dest[1]==0) && (dest[0]==0x80)); dsp_abs56(dest); - dsp_registers[DSP_REG_A2+numreg] = dest[0]; - dsp_registers[DSP_REG_A1+numreg] = dest[1]; - dsp_registers[DSP_REG_A0+numreg] = dest[2]; - - dsp_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_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= (overflowed<>DSP_SR_C) & 1; + curcarry = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_C) & 1; destreg = (cur_inst>>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+destreg]; - dest[1] = dsp_registers[DSP_REG_A1+destreg]; - dest[2] = dsp_registers[DSP_REG_A0+destreg]; + 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) & 1; - switch(srcreg) { - case 0: /* X */ - source[1] = dsp_registers[DSP_REG_X1]; - source[2] = dsp_registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 1: /* Y */ - source[1] = dsp_registers[DSP_REG_Y1]; - source[2] = dsp_registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; + 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; + } + } + 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; + } } newsr = dsp_add56(source, dest); @@ -3712,48 +4202,45 @@ static void dsp_adc(void) newsr |= dsp_add56(source, dest); } - dsp_registers[DSP_REG_A2+destreg] = dest[0]; - dsp_registers[DSP_REG_A1+destreg] = dest[1]; - dsp_registers[DSP_REG_A0+destreg] = dest[2]; - - dsp_ccr_extension(&dest[0], &dest[1], &dest[2]); - dsp_ccr_unnormalized(&dest[0], &dest[1], &dest[2]); - dsp_ccr_negative(&dest[0], &dest[1], &dest[2]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + 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_registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; } static void dsp_add(void) { - uint32 srcreg, destreg, source[3], dest[3]; - uint16 newsr; + Uint32 srcreg, destreg, source[3], dest[3]; + Uint16 newsr; destreg = (cur_inst>>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+destreg]; - dest[1] = dsp_registers[DSP_REG_A1+destreg]; - dest[2] = dsp_registers[DSP_REG_A0+destreg]; + 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_registers[DSP_REG_A2+srcreg]; - source[1] = dsp_registers[DSP_REG_A1+srcreg]; - source[2] = dsp_registers[DSP_REG_A0+srcreg]; + 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_registers[DSP_REG_X1]; - source[2] = dsp_registers[DSP_REG_X0]; + 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_registers[DSP_REG_Y1]; - source[2] = dsp_registers[DSP_REG_Y0]; + 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; @@ -3761,7 +4248,7 @@ static void dsp_add(void) break; case 4: /* X0 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_X0]; + source[1] = dsp_core->registers[DSP_REG_X0]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -3769,7 +4256,7 @@ static void dsp_add(void) break; case 5: /* Y0 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_Y0]; + source[1] = dsp_core->registers[DSP_REG_Y0]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -3777,7 +4264,7 @@ static void dsp_add(void) break; case 6: /* X1 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_X1]; + source[1] = dsp_core->registers[DSP_REG_X1]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -3785,190 +4272,190 @@ static void dsp_add(void) break; case 7: /* Y1 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_Y1]; + 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; } newsr = dsp_add56(source, dest); - dsp_registers[DSP_REG_A2+destreg] = dest[0]; - dsp_registers[DSP_REG_A1+destreg] = dest[1]; - dsp_registers[DSP_REG_A0+destreg] = dest[2]; - - dsp_ccr_extension(&dest[0], &dest[1], &dest[2]); - dsp_ccr_unnormalized(&dest[0], &dest[1], &dest[2]); - dsp_ccr_negative(&dest[0], &dest[1], &dest[2]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + 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_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; } static void dsp_addl(void) { - uint32 numreg, source[3], dest[3]; - uint16 newsr; + Uint32 numreg, source[3], dest[3]; + Uint16 newsr; numreg = (cur_inst>>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+numreg]; - dest[1] = dsp_registers[DSP_REG_A1+numreg]; - dest[2] = dsp_registers[DSP_REG_A0+numreg]; + 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_asl56(dest); - source[0] = dsp_registers[DSP_REG_A2+(numreg ^ 1)]; - source[1] = dsp_registers[DSP_REG_A1+(numreg ^ 1)]; - source[2] = dsp_registers[DSP_REG_A0+(numreg ^ 1)]; + 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)]; newsr |= dsp_add56(source, dest); - dsp_registers[DSP_REG_A2+numreg] = dest[0]; - dsp_registers[DSP_REG_A1+numreg] = dest[1]; - dsp_registers[DSP_REG_A0+numreg] = dest[2]; - - dsp_ccr_extension(&dest[0], &dest[1], &dest[2]); - dsp_ccr_unnormalized(&dest[0], &dest[1], &dest[2]); - dsp_ccr_negative(&dest[0], &dest[1], &dest[2]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; + dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; + dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + + dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; } static void dsp_addr(void) { - uint32 numreg, source[3], dest[3]; - uint16 newsr; + Uint32 numreg, source[3], dest[3]; + Uint16 newsr; numreg = (cur_inst>>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+numreg]; - dest[1] = dsp_registers[DSP_REG_A1+numreg]; - dest[2] = dsp_registers[DSP_REG_A0+numreg]; + 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); - source[0] = dsp_registers[DSP_REG_A2+(numreg ^ 1)]; - source[1] = dsp_registers[DSP_REG_A1+(numreg ^ 1)]; - source[2] = dsp_registers[DSP_REG_A0+(numreg ^ 1)]; + 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)]; newsr |= dsp_add56(source, dest); - dsp_registers[DSP_REG_A2+numreg] = dest[0]; - dsp_registers[DSP_REG_A1+numreg] = dest[1]; - dsp_registers[DSP_REG_A0+numreg] = dest[2]; - - dsp_ccr_extension(&dest[0], &dest[1], &dest[2]); - dsp_ccr_unnormalized(&dest[0], &dest[1], &dest[2]); - dsp_ccr_negative(&dest[0], &dest[1], &dest[2]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; + dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; + dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; } static void dsp_and(void) { - uint32 srcreg, dstreg; + Uint32 srcreg, dstreg; - srcreg = DSP_REG_X0+((cur_inst>>4) & BITMASK(2)); + switch((cur_inst>>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_registers[dstreg] &= dsp_registers[srcreg]; - dsp_registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */ + dsp_core->registers[dstreg] &= dsp_core->registers[srcreg]; - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((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)<>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+numreg]; - dest[1] = dsp_registers[DSP_REG_A1+numreg]; - dest[2] = dsp_registers[DSP_REG_A0+numreg]; + 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_asl56(dest); - dsp_registers[DSP_REG_A2+numreg] = dest[0]; - dsp_registers[DSP_REG_A1+numreg] = dest[1]; - dsp_registers[DSP_REG_A0+numreg] = dest[2]; - - dsp_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_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + + dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); } static void dsp_asr(void) { - uint32 numreg, newsr, dest[3]; + Uint32 numreg, newsr, dest[3]; numreg = (cur_inst>>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+numreg]; - dest[1] = dsp_registers[DSP_REG_A1+numreg]; - dest[2] = dsp_registers[DSP_REG_A0+numreg]; + 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_registers[DSP_REG_A2+numreg] = dest[0]; - dsp_registers[DSP_REG_A1+numreg] = dest[1]; - dsp_registers[DSP_REG_A0+numreg] = dest[2]; - - dsp_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_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; + + dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); } static void dsp_clr(void) { - uint32 numreg; + Uint32 numreg; numreg = (cur_inst>>3) & 1; - dsp_registers[DSP_REG_A2+numreg]=0; - dsp_registers[DSP_REG_A1+numreg]=0; - dsp_registers[DSP_REG_A0+numreg]=0; + dsp_core->registers[DSP_REG_A2+numreg]=0; + dsp_core->registers[DSP_REG_A1+numreg]=0; + dsp_core->registers[DSP_REG_A0+numreg]=0; - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= (1<>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+destreg]; - dest[1] = dsp_registers[DSP_REG_A1+destreg]; - dest[2] = dsp_registers[DSP_REG_A0+destreg]; + 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_registers[DSP_REG_A2+srcreg]; - source[1] = dsp_registers[DSP_REG_A1+srcreg]; - source[2] = dsp_registers[DSP_REG_A0+srcreg]; + 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_registers[DSP_REG_X0]; + source[1] = dsp_core->registers[DSP_REG_X0]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -3976,7 +4463,7 @@ static void dsp_cmp(void) break; case 5: /* Y0 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_Y0]; + source[1] = dsp_core->registers[DSP_REG_Y0]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -3984,7 +4471,7 @@ static void dsp_cmp(void) break; case 6: /* X1 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_X1]; + source[1] = dsp_core->registers[DSP_REG_X1]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -3992,47 +4479,47 @@ static void dsp_cmp(void) break; case 7: /* Y1 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_Y1]; + 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; } newsr = dsp_sub56(source, dest); - dsp_ccr_extension(&dest[0], &dest[1], &dest[2]); - dsp_ccr_unnormalized(&dest[0], &dest[1], &dest[2]); - dsp_ccr_negative(&dest[0], &dest[1], &dest[2]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; } static void dsp_cmpm(void) { - uint32 srcreg, destreg, source[3], dest[3]; - uint16 newsr; + Uint32 srcreg, destreg, source[3], dest[3]; + Uint16 newsr; destreg = (cur_inst>>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+destreg]; - dest[1] = dsp_registers[DSP_REG_A1+destreg]; - dest[2] = dsp_registers[DSP_REG_A0+destreg]; + 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_abs56(dest); srcreg = (cur_inst>>4) & BITMASK(3); switch(srcreg) { case 0: /* A or B */ srcreg = destreg ^ 1; - source[0] = dsp_registers[DSP_REG_A2+srcreg]; - source[1] = dsp_registers[DSP_REG_A1+srcreg]; - source[2] = dsp_registers[DSP_REG_A0+srcreg]; + 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_registers[DSP_REG_X0]; + source[1] = dsp_core->registers[DSP_REG_X0]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -4040,7 +4527,7 @@ static void dsp_cmpm(void) break; case 5: /* Y0 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_Y0]; + source[1] = dsp_core->registers[DSP_REG_Y0]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -4048,7 +4535,7 @@ static void dsp_cmpm(void) break; case 6: /* X1 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_X1]; + source[1] = dsp_core->registers[DSP_REG_X1]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -4056,84 +4543,97 @@ static void dsp_cmpm(void) break; case 7: /* Y1 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_Y1]; + 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; } dsp_abs56(source); newsr = dsp_sub56(source, dest); - dsp_ccr_extension(&dest[0], &dest[1], &dest[2]); - dsp_ccr_unnormalized(&dest[0], &dest[1], &dest[2]); - dsp_ccr_negative(&dest[0], &dest[1], &dest[2]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; } static void dsp_eor(void) { - uint32 srcreg, dstreg; + Uint32 srcreg, dstreg; - srcreg = DSP_REG_X0+((cur_inst>>4) & BITMASK(2)); + switch((cur_inst>>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_registers[dstreg] ^= dsp_registers[srcreg]; - dsp_registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */ + dsp_core->registers[dstreg] ^= dsp_core->registers[srcreg]; + dsp_core->registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */ - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((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)<>3) & 1; + numreg = DSP_REG_A1+((cur_inst>>3) & 1); - newcarry = (dsp_registers[DSP_REG_A1+numreg]>>23) & 1; + newcarry = (dsp_core->registers[numreg]>>23) & 1; - dsp_registers[DSP_REG_A1+numreg] &= BITMASK(24); - dsp_registers[DSP_REG_A1+numreg] <<= 1; + dsp_core->registers[numreg] <<= 1; + dsp_core->registers[numreg] &= BITMASK(24); - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newcarry; + dsp_core->registers[DSP_REG_SR] |= ((dsp_core->registers[numreg]>>23) & 1)<registers[DSP_REG_SR] |= (dsp_core->registers[numreg]==0)<>3) & 1; + numreg = DSP_REG_A1+((cur_inst>>3) & 1); - newcarry = dsp_registers[DSP_REG_A1+numreg] & 1; + newcarry = dsp_core->registers[numreg] & 1; - dsp_registers[DSP_REG_A1+numreg] &= BITMASK(24); - dsp_registers[DSP_REG_A1+numreg] >>= 1; + dsp_core->registers[numreg] >>= 1; + /*dsp_core->registers[numreg] &= BITMASK(24);*/ - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<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_registers[srcreg1], dsp_registers[srcreg2], source); + dsp_mul56(dsp_core->registers[srcreg1], dsp_core->registers[srcreg2], source); if (cur_inst & (1<<2)) { dest[0] = dest[1] = dest[2] = 0; @@ -4146,34 +4646,31 @@ static void dsp_mac(void) } destreg = (cur_inst>>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+destreg]; - dest[1] = dsp_registers[DSP_REG_A1+destreg]; - dest[2] = dsp_registers[DSP_REG_A0+destreg]; + 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]; newsr = dsp_add56(source, dest); - dsp_registers[DSP_REG_A2+destreg] = dest[0]; - dsp_registers[DSP_REG_A1+destreg] = dest[1]; - dsp_registers[DSP_REG_A0+destreg] = dest[2]; - - dsp_ccr_extension(&dest[0], &dest[1], &dest[2]); - dsp_ccr_unnormalized(&dest[0], &dest[1], &dest[2]); - dsp_ccr_negative(&dest[0], &dest[1], &dest[2]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + 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_registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; } static void dsp_macr(void) { - uint32 srcreg1, srcreg2, destreg, value, source[3], dest[3]; - uint16 newsr; + Uint32 srcreg1, srcreg2, destreg, value, source[3], dest[3]; + Uint16 newsr; value = (cur_inst>>4) & BITMASK(3); srcreg1 = registers_mpy[value][0]; srcreg2 = registers_mpy[value][1]; - dsp_mul56(dsp_registers[srcreg1], dsp_registers[srcreg2], source); + dsp_mul56(dsp_core->registers[srcreg1], dsp_core->registers[srcreg2], source); if (cur_inst & (1<<2)) { dest[0] = dest[1] = dest[2] = 0; @@ -4186,24 +4683,21 @@ static void dsp_macr(void) } destreg = (cur_inst>>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+destreg]; - dest[1] = dsp_registers[DSP_REG_A1+destreg]; - dest[2] = dsp_registers[DSP_REG_A0+destreg]; + 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]; newsr = dsp_add56(source, dest); dsp_rnd56(dest); - dsp_registers[DSP_REG_A2+destreg] = dest[0]; - dsp_registers[DSP_REG_A1+destreg] = dest[1]; - dsp_registers[DSP_REG_A0+destreg] = dest[2]; - - dsp_ccr_extension(&dest[0], &dest[1], &dest[2]); - dsp_ccr_unnormalized(&dest[0], &dest[1], &dest[2]); - dsp_ccr_negative(&dest[0], &dest[1], &dest[2]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + 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_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newsr & 0xfe; } static void dsp_move(void) @@ -4212,22 +4706,15 @@ static void dsp_move(void) taken care of by parallel move dispatcher */ } -static void dsp_move_pm(void) -{ - /* move instruction outside alu opcodes */ - dsp_parmove_read(); - dsp_parmove_write(); -} - static void dsp_mpy(void) { - uint32 srcreg1, srcreg2, destreg, value, dest[3], source[3]; + Uint32 srcreg1, srcreg2, destreg, value, dest[3], source[3]; value = (cur_inst>>4) & BITMASK(3); srcreg1 = registers_mpy[value][0]; srcreg2 = registers_mpy[value][1]; - dsp_mul56(dsp_registers[srcreg1], dsp_registers[srcreg2], source); + dsp_mul56(dsp_core->registers[srcreg1], dsp_core->registers[srcreg2], source); destreg = (cur_inst>>3) & 1; if (cur_inst & (1<<2)) { @@ -4235,32 +4722,31 @@ static void dsp_mpy(void) dsp_sub56(source, dest); - dsp_registers[DSP_REG_A2+destreg] = dest[0]; - dsp_registers[DSP_REG_A1+destreg] = dest[1]; - dsp_registers[DSP_REG_A0+destreg] = dest[2]; + 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]; } else { - dsp_registers[DSP_REG_A2+destreg] = source[0]; - dsp_registers[DSP_REG_A1+destreg] = source[1]; - dsp_registers[DSP_REG_A0+destreg] = source[2]; + dsp_core->registers[DSP_REG_A2+destreg] = source[0]; + dsp_core->registers[DSP_REG_A1+destreg] = source[1]; + dsp_core->registers[DSP_REG_A0+destreg] = source[2]; } - dsp_ccr_extension(&dsp_registers[DSP_REG_A2+destreg], &dsp_registers[DSP_REG_A1+destreg], &dsp_registers[DSP_REG_A0+destreg]); - dsp_ccr_unnormalized(&dsp_registers[DSP_REG_A2+destreg], &dsp_registers[DSP_REG_A1+destreg], &dsp_registers[DSP_REG_A0+destreg]); - dsp_ccr_negative(&dsp_registers[DSP_REG_A2+destreg], &dsp_registers[DSP_REG_A1+destreg], &dsp_registers[DSP_REG_A0+destreg]); - dsp_ccr_zero(&dsp_registers[DSP_REG_A2+destreg], &dsp_registers[DSP_REG_A1+destreg], &dsp_registers[DSP_REG_A0+destreg]); + 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_registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<>4) & BITMASK(3); srcreg1 = registers_mpy[value][0]; srcreg2 = registers_mpy[value][1]; - dsp_mul56(dsp_registers[srcreg1], dsp_registers[srcreg2], source); + dsp_mul56(dsp_core->registers[srcreg1], dsp_core->registers[srcreg2], source); destreg = (cur_inst>>3) & 1; if (cur_inst & (1<<2)) { @@ -4275,26 +4761,23 @@ static void dsp_mpyr(void) dsp_rnd56(dest); - dsp_registers[DSP_REG_A2+destreg] = dest[0]; - dsp_registers[DSP_REG_A1+destreg] = dest[1]; - dsp_registers[DSP_REG_A0+destreg] = dest[2]; - - dsp_ccr_extension(&dest[0], &dest[1], &dest[2]); - dsp_ccr_unnormalized(&dest[0], &dest[1], &dest[2]); - dsp_ccr_negative(&dest[0], &dest[1], &dest[2]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + 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_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); - dsp_registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<>3) & 1; - source[0] = dsp_registers[DSP_REG_A2+srcreg]; - source[1] = dsp_registers[DSP_REG_A1+srcreg]; - source[2] = dsp_registers[DSP_REG_A0+srcreg]; + 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]; overflowed = ((source[2]==0) && (source[1]==0) && (source[0]==0x80)); @@ -4302,17 +4785,14 @@ static void dsp_neg(void) dsp_sub56(source, dest); - dsp_registers[DSP_REG_A2+srcreg] = dest[0]; - dsp_registers[DSP_REG_A1+srcreg] = dest[1]; - dsp_registers[DSP_REG_A0+srcreg] = dest[2]; - - dsp_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_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= (overflowed<>3) & 1); - dsp_registers[dstreg] = ~dsp_registers[dstreg]; - dsp_registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */ + dsp_core->registers[dstreg] = ~dsp_core->registers[dstreg]; + dsp_core->registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */ - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((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)<>4) & BITMASK(2)); + switch((cur_inst>>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_registers[dstreg] |= dsp_registers[srcreg]; - dsp_registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */ + dsp_core->registers[dstreg] |= dsp_core->registers[srcreg]; + dsp_core->registers[dstreg] &= BITMASK(24); /* FIXME: useless ? */ - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((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)<>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+numreg]; - dest[1] = dsp_registers[DSP_REG_A1+numreg]; - dest[2] = dsp_registers[DSP_REG_A0+numreg]; + 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_rnd56(dest); - dsp_registers[DSP_REG_A2+numreg] = dest[0]; - dsp_registers[DSP_REG_A1+numreg] = dest[1]; - dsp_registers[DSP_REG_A0+numreg] = dest[2]; - - dsp_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_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); } static void dsp_rol(void) { - uint32 dstreg, newcarry; + Uint32 dstreg, newcarry; dstreg = DSP_REG_A1+((cur_inst>>3) & 1); - newcarry = (dsp_registers[dstreg]>>23) & 1; + newcarry = (dsp_core->registers[dstreg]>>23) & 1; - dsp_registers[dstreg] <<= 1; - dsp_registers[dstreg] |= newcarry; - dsp_registers[dstreg] &= BITMASK(24); - - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<registers[dstreg] <<= 1; + dsp_core->registers[dstreg] |= newcarry; + dsp_core->registers[dstreg] &= 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)<>3) & 1); - newcarry = dsp_registers[dstreg] & 1; + newcarry = dsp_core->registers[dstreg] & 1; - dsp_registers[dstreg] >>= 1; - dsp_registers[dstreg] |= newcarry<<23; - dsp_registers[dstreg] &= BITMASK(24); - - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1)<registers[dstreg] >>= 1; + dsp_core->registers[dstreg] |= newcarry<<23; + dsp_core->registers[dstreg] &= 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)<>(DSP_SR_C)) & 1; + curcarry = (dsp_core->registers[DSP_REG_SR]>>(DSP_SR_C)) & 1; destreg = (cur_inst>>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+destreg]; - dest[1] = dsp_registers[DSP_REG_A1+destreg]; - dest[2] = dsp_registers[DSP_REG_A0+destreg]; + 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) & 1; - switch(srcreg) { - case 0: /* X */ - source[1] = dsp_registers[DSP_REG_X1]; - source[2] = dsp_registers[DSP_REG_X0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; - case 1: /* Y */ - source[1] = dsp_registers[DSP_REG_Y1]; - source[2] = dsp_registers[DSP_REG_Y0]; - source[0] = 0; - if (source[1] & (1<<23)) { - source[0] = 0x0000ff; - } - break; + 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; + } + } + 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; + } } newsr = dsp_sub56(source, dest); @@ -4449,48 +4935,45 @@ static void dsp_sbc(void) newsr |= dsp_sub56(source, dest); } - dsp_registers[DSP_REG_A2+destreg] = dest[0]; - dsp_registers[DSP_REG_A1+destreg] = dest[1]; - dsp_registers[DSP_REG_A0+destreg] = dest[2]; - - dsp_ccr_extension(&dest[0], &dest[1], &dest[2]); - dsp_ccr_unnormalized(&dest[0], &dest[1], &dest[2]); - dsp_ccr_negative(&dest[0], &dest[1], &dest[2]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + 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_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; } static void dsp_sub(void) { - uint32 srcreg, destreg, source[3], dest[3]; - uint16 newsr; + Uint32 srcreg, destreg, source[3], dest[3]; + Uint16 newsr; destreg = (cur_inst>>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+destreg]; - dest[1] = dsp_registers[DSP_REG_A1+destreg]; - dest[2] = dsp_registers[DSP_REG_A0+destreg]; + 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_registers[DSP_REG_A2+srcreg]; - source[1] = dsp_registers[DSP_REG_A1+srcreg]; - source[2] = dsp_registers[DSP_REG_A0+srcreg]; + 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_registers[DSP_REG_X1]; - source[2] = dsp_registers[DSP_REG_X0]; + 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_registers[DSP_REG_Y1]; - source[2] = dsp_registers[DSP_REG_Y0]; + 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; @@ -4498,7 +4981,7 @@ static void dsp_sub(void) break; case 4: /* X0 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_X0]; + source[1] = dsp_core->registers[DSP_REG_X0]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -4506,7 +4989,7 @@ static void dsp_sub(void) break; case 5: /* Y0 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_Y0]; + source[1] = dsp_core->registers[DSP_REG_Y0]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -4514,7 +4997,7 @@ static void dsp_sub(void) break; case 6: /* X1 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_X1]; + source[1] = dsp_core->registers[DSP_REG_X1]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -4522,92 +5005,86 @@ static void dsp_sub(void) break; case 7: /* Y1 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_Y1]; + 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; } newsr = dsp_sub56(source, dest); - dsp_registers[DSP_REG_A2+destreg] = dest[0]; - dsp_registers[DSP_REG_A1+destreg] = dest[1]; - dsp_registers[DSP_REG_A0+destreg] = dest[2]; - - dsp_ccr_extension(&dest[0], &dest[1], &dest[2]); - dsp_ccr_unnormalized(&dest[0], &dest[1], &dest[2]); - dsp_ccr_negative(&dest[0], &dest[1], &dest[2]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + 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_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; } static void dsp_subl(void) { - uint32 numreg, source[3], dest[3]; - uint16 newsr; + Uint32 numreg, source[3], dest[3]; + Uint16 newsr; numreg = (cur_inst>>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+numreg]; - dest[1] = dsp_registers[DSP_REG_A1+numreg]; - dest[2] = dsp_registers[DSP_REG_A0+numreg]; + 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_asl56(dest); - source[0] = dsp_registers[DSP_REG_A2+(numreg ^ 1)]; - source[1] = dsp_registers[DSP_REG_A1+(numreg ^ 1)]; - source[2] = dsp_registers[DSP_REG_A0+(numreg ^ 1)]; + 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)]; newsr |= dsp_sub56(source, dest); - dsp_registers[DSP_REG_A2+numreg] = dest[0]; - dsp_registers[DSP_REG_A1+numreg] = dest[1]; - dsp_registers[DSP_REG_A0+numreg] = dest[2]; - - dsp_ccr_extension(&dest[0], &dest[1], &dest[2]); - dsp_ccr_unnormalized(&dest[0], &dest[1], &dest[2]); - dsp_ccr_negative(&dest[0], &dest[1], &dest[2]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; + dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; + dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; } static void dsp_subr(void) { - uint32 numreg, source[3], dest[3]; - uint16 newsr; + Uint32 numreg, source[3], dest[3]; + Uint16 newsr; numreg = (cur_inst>>3) & 1; - dest[0] = dsp_registers[DSP_REG_A2+numreg]; - dest[1] = dsp_registers[DSP_REG_A1+numreg]; - dest[2] = dsp_registers[DSP_REG_A0+numreg]; + 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); - source[0] = dsp_registers[DSP_REG_A2+(numreg ^ 1)]; - source[1] = dsp_registers[DSP_REG_A1+(numreg ^ 1)]; - source[2] = dsp_registers[DSP_REG_A0+(numreg ^ 1)]; + 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)]; newsr |= dsp_sub56(source, dest); - dsp_registers[DSP_REG_A2+numreg] = dest[0]; - dsp_registers[DSP_REG_A1+numreg] = dest[1]; - dsp_registers[DSP_REG_A0+numreg] = dest[2]; - - dsp_ccr_extension(&dest[0], &dest[1], &dest[2]); - dsp_ccr_unnormalized(&dest[0], &dest[1], &dest[2]); - dsp_ccr_negative(&dest[0], &dest[1], &dest[2]); - dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); + dsp_core->registers[DSP_REG_A2+numreg] = dest[0]; + dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; + dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + + dsp_ccr_update_e_u_n_z(&dest[0], &dest[1], &dest[2]); - dsp_registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] &= BITMASK(16)-((1<registers[DSP_REG_SR] |= newsr; } static void dsp_tfr(void) { - uint32 srcreg, destreg, source[3]; + Uint32 srcreg, destreg, source[3]; destreg = (cur_inst>>3) & 1; @@ -4615,13 +5092,13 @@ static void dsp_tfr(void) switch(srcreg) { case 0: /* A or B */ srcreg = destreg ^ 1; - source[0] = dsp_registers[DSP_REG_A2+srcreg]; - source[1] = dsp_registers[DSP_REG_A1+srcreg]; - source[2] = dsp_registers[DSP_REG_A0+srcreg]; + 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_registers[DSP_REG_X0]; + source[1] = dsp_core->registers[DSP_REG_X0]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -4629,7 +5106,7 @@ static void dsp_tfr(void) break; case 5: /* Y0 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_Y0]; + source[1] = dsp_core->registers[DSP_REG_Y0]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -4637,7 +5114,7 @@ static void dsp_tfr(void) break; case 6: /* X1 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_X1]; + source[1] = dsp_core->registers[DSP_REG_X1]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -4645,7 +5122,7 @@ static void dsp_tfr(void) break; case 7: /* Y1 */ source[2] = 0; - source[1] = dsp_registers[DSP_REG_Y1]; + source[1] = dsp_core->registers[DSP_REG_Y1]; source[0] = 0; if (source[1] & (1<<23)) { source[0] = 0x0000ff; @@ -4655,22 +5132,24 @@ static void dsp_tfr(void) return; } - dsp_registers[DSP_REG_A2+destreg] = source[0]; - dsp_registers[DSP_REG_A1+destreg] = source[1]; - dsp_registers[DSP_REG_A0+destreg] = source[2]; + dsp_core->registers[DSP_REG_A2+destreg] = source[0]; + dsp_core->registers[DSP_REG_A1+destreg] = source[1]; + dsp_core->registers[DSP_REG_A0+destreg] = source[2]; } static void dsp_tst(void) { - uint32 destreg; + Uint32 destreg; destreg = (cur_inst>>3) & 1; - dsp_ccr_extension(&dsp_registers[DSP_REG_A2+destreg], &dsp_registers[DSP_REG_A1+destreg], &dsp_registers[DSP_REG_A0+destreg]); - dsp_ccr_unnormalized(&dsp_registers[DSP_REG_A2+destreg], &dsp_registers[DSP_REG_A1+destreg], &dsp_registers[DSP_REG_A0+destreg]); - dsp_ccr_negative(&dsp_registers[DSP_REG_A2+destreg], &dsp_registers[DSP_REG_A1+destreg], &dsp_registers[DSP_REG_A0+destreg]); - dsp_ccr_zero(&dsp_registers[DSP_REG_A2+destreg], &dsp_registers[DSP_REG_A1+destreg], &dsp_registers[DSP_REG_A0+destreg]); + 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_registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<