--- hatari/src/falcon/dsp_cpu.c 2019/04/01 07:13:46 1.1.1.1 +++ hatari/src/falcon/dsp_cpu.c 2019/04/01 07:15:35 1.1.1.3 @@ -1,31 +1,29 @@ /* - * 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" + DSP M56001 emulation + Instructions interpreter, execution thread + + (C) 2003-2008 ARAnyM developer team + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "dsp_core.h" #include "dsp_cpu.h" #ifdef DSP_DISASM #include "dsp_disasm.h" @@ -33,23 +31,20 @@ #define DEBUG 0 -#if DEBUG -#define D(x) x -#else -#define D(x) -#endif - /* 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_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 @@ -62,26 +57,26 @@ **********************************/ /* 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; +static Uint32 pc_on_rep; /********************************** * Functions @@ -92,23 +87,21 @@ 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_extension(Uint32 *reg0, Uint32 *reg1); +static void dsp_ccr_unnormalized(Uint32 *reg0, Uint32 *reg1); +static void dsp_ccr_negative(Uint32 *reg0); +static void dsp_ccr_zero(Uint32 *reg0, Uint32 *reg1, Uint32 *reg2); + +static Uint32 read_memory(int space, Uint16 address); +static void write_memory_raw(int space, Uint32 address, Uint32 value); +#if defined(DSP_DISASM) && (DSP_DISASM_MEM==1) +static Uint32 read_memory_disasm(int space, Uint16 address); +static void write_memory_disasm(int space, Uint32 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_stack_push(uint32 curpc, uint32 cursr); -static void dsp_stack_pop(uint32 *curpc, uint32 *cursr); +static void dsp_stack_push(Uint32 curpc, Uint32 cursr); +static void dsp_stack_pop(Uint32 *curpc, Uint32 *cursr); static void opcode8h_0(void); static void opcode8h_1(void); @@ -118,11 +111,11 @@ 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); @@ -160,18 +153,18 @@ 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); @@ -180,7 +173,7 @@ static void dsp_movep_2(void); static void dsp_parmove_read(void); 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); static void dsp_pm_writereg(int numreg, int position); static void dsp_pm_0(void); @@ -189,18 +182,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(int immediat, Uint32 l_addr); 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); @@ -474,70 +467,40 @@ static dsp_emul_t opcodes_alu80ff[4]={ dsp_macr }; -static dsp_emul_t opcodes_do[16]={ - dsp_do_0, - dsp_undefined, - dsp_do_2, - dsp_undefined, +static dsp_emul_t opcodes_do[8]={ + dsp_do_aa, + dsp_do_imm, + dsp_do_ea, + dsp_do_imm, - 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 + dsp_do_imm, + dsp_do_reg, + dsp_do_imm }; -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, +static dsp_emul_t opcodes_rep[8]={ + dsp_rep_aa, + dsp_rep_imm, + dsp_rep_ea, + dsp_rep_imm, dsp_undefined, - dsp_undefined, - dsp_undefined, - dsp_rep_3, - - dsp_undefined, - dsp_rep_d, - dsp_undefined, - dsp_rep_3 + dsp_rep_imm, + dsp_rep_reg, + dsp_rep_imm }; -static dsp_emul_t opcodes_movec[16]={ +static dsp_emul_t opcodes_movec[8]={ dsp_undefined, dsp_undefined, dsp_undefined, - dsp_undefined, - - dsp_undefined, - dsp_undefined, - dsp_undefined, - dsp_movec_7, + dsp_movec_reg, - dsp_undefined, - dsp_movec_9, - dsp_undefined, - dsp_movec_b, - - dsp_undefined, - dsp_movec_d, - dsp_undefined, - dsp_movec_b + dsp_movec_aa, + dsp_movec_imm, + dsp_movec_ea, + dsp_movec_imm }; static dsp_emul_t opcodes_movep[4]={ @@ -571,11 +534,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} }; @@ -618,22 +581,50 @@ static int registers_mask[64]={ * Emulator kernel **********************************/ -int dsp56k_do_execute(void *arg) +/* Yep, feel lazy, so put it there */ +static dsp_core_t *dsp_core; + +int dsp56k_do_execute(void *th_dsp_core) { - /* Wait upload of bootstrap code */ - SDL_SemWait(dsp56k_sem); + Uint32 start_time, num_inst; + + dsp_core = th_dsp_core; +#ifdef DSP_DISASM + dsp56k_disasm_init(dsp_core); +#endif + +#if DSP_DISASM_STATE + fprintf(stderr, "Dsp: WAIT_BOOTSTRAP\n"); +#endif + SDL_SemWait(dsp_core->semaphore); - while(dsp_state != DSP_STOPTHREAD) { + start_time = SDL_GetTicks(); + num_inst = 0; + while(dsp_core->running) { dsp_execute_instruction(); +#if DSP_COUNT_IPS + ++num_inst; + if ((num_inst & 63) == 0) { + /* Evaluate time after instructions have been executed to avoid asking too frequently */ + Uint32 cur_time = SDL_GetTicks(); + if (cur_time-start_time>1000) { + fprintf(stderr, "Dsp: %d i/s\n", (num_inst*1000)/(cur_time-start_time)); + start_time=cur_time; + num_inst=0; + } + } +#endif } - dsp_state = DSP_STOPPEDTHREAD; +#if DSP_DISASM_STATE + fprintf(stderr, "Dsp: SHUTDOWN\n"); +#endif return 0; } static void dsp_execute_instruction(void) { - uint32 value; + Uint32 value; #ifdef DSP_DISASM #if DSP_DISASM_REG @@ -645,7 +636,7 @@ static void dsp_execute_instruction(void #endif /* Decode and execute current instruction */ - cur_inst = read_memory(DSP_SPACE_P,dsp_pc); + cur_inst = read_memory(DSP_SPACE_P, dsp_core->pc); cur_inst_len = 1; value = (cur_inst >> 16) & BITMASK(8); @@ -667,7 +658,7 @@ static void dsp_execute_instruction(void } /* Don't update the PC if we are halted */ - if (dsp_state == DSP_RUNNING) { + /*if (dsp_core->state == DSP_RUNNING)*/ { dsp_postexecute_update_pc(); } @@ -688,22 +679,28 @@ 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); + --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; } @@ -711,35 +708,31 @@ static void dsp_postexecute_update_pc(vo /* 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); - --dsp_registers[DSP_REG_LC]; - dsp_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; + Uint32 newpc; - dsp_stack_pop(&newpc, &dsp_registers[DSP_REG_SR]); - dsp_stack_pop(&dsp_registers[DSP_REG_LA], &dsp_registers[DSP_REG_LC]); + dsp_stack_pop(&newpc, &dsp_core->registers[DSP_REG_SR]); + dsp_stack_pop(&dsp_core->registers[DSP_REG_LA], &dsp_core->registers[DSP_REG_LC]); } else { /* Loop one more time */ - dsp_pc = dsp_stack[0][dsp_registers[DSP_REG_SSH]]; + dsp_core->pc = dsp_core->stack[0][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,16 +743,16 @@ static void dsp_postexecute_update_pc(vo static void dsp_postexecute_interrupts(void) { - uint32 ipl, ipl_hi; + 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); + ipl = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_I0) & BITMASK(2); + ipl_hi = (dsp_core->periph[DSP_SPACE_X][DSP_IPR]>>10) & BITMASK(2); /* Trace, level 3 */ - if (dsp_registers[DSP_REG_SR] & (1<registers[DSP_REG_SR] & (1<periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<periph[DSP_SPACE_X][DSP_HOST_HSR] & (1<periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<periph[DSP_SPACE_X][DSP_HOST_HSR] & (1<periph[DSP_SPACE_X][DSP_HOST_HCR] & (1<periph[DSP_SPACE_X][DSP_HOST_HSR] & (1<>DSP_SR_S0) & BITMASK(2); + scaling = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); value = (*reg0) & 0xff; numbits = 8; switch(scaling) { @@ -833,17 +827,19 @@ static void dsp_ccr_extension(uint32 *re return; break; } + if ((value==0) || (value==(Uint32)BITMASK(numbits))) { + sr_extension = 0; + } - dsp_registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= sr_extension; } -static void dsp_ccr_unnormalized(uint32 *reg0, uint32 *reg1, uint32 *reg2) +static void dsp_ccr_unnormalized(Uint32 *reg0, Uint32 *reg1) { - DUNUSED(reg2); - uint32 scaling, value; + Uint32 scaling, value; - scaling = (dsp_registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); + scaling = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); switch(scaling) { case 0: @@ -861,21 +857,19 @@ static void dsp_ccr_unnormalized(uint32 break; } - dsp_registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= ((value==0) || (value==BITMASK(2)))<>7) & 1)<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= (((*reg0)>>7) & 1)<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= zeroed<=0x100) && (address<0x200)) { - return dsp_rom[space][address] & BITMASK(24); + /* Internal RAM? */ + if (address<0x100) { + return dsp_core->ramint[space][address] & BITMASK(24); + } + /* Internal ROM? */ + if ((dsp_core->registers[DSP_REG_OMR] & (1<rom[space][address] & BITMASK(24); } - /* Peripheral address ? */ if (address >= 0xffc0) { - return dsp_periph[space][address-0xffc0] & BITMASK(24); + return dsp_core->periph[space][address-0xffc0] & BITMASK(24); } - - /* Now continue with common code, no break here */ + /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ + if (space == DSP_SPACE_X) { + address += DSP_RAMSIZE>>1; + } + /* Falcon: External RAM, map X,Y to P */ + space = DSP_SPACE_P; + break; case DSP_SPACE_P: - if (address<=0x8000) { - return dsp_ram[space][address] & BITMASK(24); + /* Internal RAM? */ + if (address<0x200) { + return dsp_core->ramint[space][address] & BITMASK(24); } break; } - return 0xdead; + /* External RAM, mask address to available ram size */ + return dsp_core->ram[space][address & (DSP_RAMSIZE-1)] & BITMASK(24); } #endif -static uint32 read_memory(int space, uint16 address) +static Uint32 read_memory(int space, Uint16 address) { address &= BITMASK(16); 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); + /* Internal RAM ?*/ + if (address<0x100) { + return dsp_core->ramint[space][address] & BITMASK(24); + } + /* Internal ROM ?*/ + if ((dsp_core->registers[DSP_REG_OMR] & (1<rom[space][address] & BITMASK(24); } - /* Peripheral address ? */ if (address >= 0xffc0) { + Uint32 value; + SDL_LockMutex(dsp_core->mutex); if ((space==DSP_SPACE_X) && (address==0xffc0+DSP_HOST_HRX)) { - int trdy; - - /* Read available data from host for the DSP */ - DSP_host2dsp(); - - /* 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; + dsp_core_hostport_dspread(dsp_core); } + value = dsp_core->periph[space][address-0xffc0] & BITMASK(24); + SDL_UnlockMutex(dsp_core->mutex); - return dsp_periph[space][address-0xffc0] & BITMASK(24); + return value; } - - /* Now continue with common code, no break here */ + /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ + if (space == DSP_SPACE_X) { + address += DSP_RAMSIZE>>1; + } + /* Falcon: External RAM, map X,Y to P */ + space = DSP_SPACE_P; + break; 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; - - SDL_SemWait(dsp56k_sem); - - return 0xdead; -#endif /* DSP_CHECK_MEM_ACCESS */ + /* Internal RAM ?*/ + if (address<0x200) { + return dsp_core->ramint[space][address] & BITMASK(24); } break; } - return 0xdead; + /* External RAM, mask address to available ram size */ + return dsp_core->ram[space][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, Uint32 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<ramint[space][address] = value; + return; + } + /* Internal ROM ?*/ + if ((dsp_core->registers[DSP_REG_OMR] & (1<= 0xffc0) && (address <= 0xffff)) { + SDL_LockMutex(dsp_core->mutex); switch(address-0xffc0) { case DSP_HOST_HTX: - dsp_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(); + dsp_core->periph[space][DSP_HOST_HTX] = value; + + dsp_core_hostport_dspwrite(dsp_core); break; case DSP_HOST_HCR: - dsp_periph[space][DSP_HOST_HCR] = value; + dsp_core->periph[space][DSP_HOST_HCR] = value; /* Set HF3 and HF2 accordingly on the host side */ - dsp_hostport[CPU_HOST_ISR] &= + dsp_core->hostport[CPU_HOST_ISR] &= BITMASK(8)-((1<hostport[CPU_HOST_ISR] |= + dsp_core->periph[DSP_SPACE_X][DSP_HOST_HCR] & ((1<periph[space][address-0xffc0] = value; break; } - } - -#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); + SDL_UnlockMutex(dsp_core->mutex); return; -#endif } - /* x:0x0000-0x01ff is internal ram/rom */ - /* x:0x0200-0x3fff = p:0x4200-0x7fff */ - if ((address >= 0x200) && (address <= 0x3fff)) { - dsp_ram[DSP_SPACE_P][address+0x4000] = value; + /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ + if (space == DSP_SPACE_X) { + address += DSP_RAMSIZE>>1; } + /* Falcon: External RAM, map X to P */ + space = DSP_SPACE_P; break; case DSP_SPACE_Y: - if ((address >= 0x100) && (address <= 0x200)) { - if (dsp_registers[DSP_REG_OMR] & (1<= 0xffc0) && (address <= 0xffff)) { - dsp_periph[space][address-0xffc0] = value; + /* 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 ((dsp_core->registers[DSP_REG_OMR] & (1<= 0x200) && (address <= 0x3fff)) { - dsp_ram[DSP_SPACE_P][address] = value; + /* Peripheral space ? */ + if ((address >= 0xffc0) && (address <= 0xffff)) { + dsp_core->periph[space][address-0xffc0] = value; + return; } + /* Falcon: External RAM, map Y to P */ + space = DSP_SPACE_P; 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); + /* Internal RAM ?*/ + if (address<0x200) { + dsp_core->ramint[space][address] = value; 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; } -#ifdef DSP_DISASM -#if DSP_DISASM_MEM + /* External RAM, mask address to available ram size */ + dsp_core->ram[space][address & (DSP_RAMSIZE-1)] = value; +} + +#if defined(DSP_DISASM) && (DSP_DISASM_MEM==1) +static void write_memory_disasm(int space, Uint32 address, Uint32 value) +{ + address &= BITMASK(16); + value &= BITMASK(24); + + Uint32 curvalue = 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)); @@ -1135,66 +1084,61 @@ static void write_memory(int space, uint fprintf(stderr,"Dsp: Mem: y:0x%04x:0x%06x -> 0x%06x\n", address, curvalue, read_memory_disasm(space, address)); break; } -#endif -#endif } +#endif /********************************** * Stack push/pop **********************************/ -static void dsp_stack_push(uint32 curpc, uint32 cursr) +static void dsp_stack_push(Uint32 curpc, Uint32 cursr) { - if (dsp_registers[DSP_REG_SP]==0x0f) { + if (dsp_core->registers[DSP_REG_SP]==0x0f) { /* Stack full, raise interrupt */ - D(bug("Dsp: Interrupt: Stack error (overflow)")); #if DSP_DISASM_STATE - D(bug("Dsp: state = DSP_HALT")); + fprintf(stderr, "Dsp: Stack error (overflow)\n"); #endif - dsp_state = DSP_HALT; - SDL_SemWait(dsp56k_sem); + SDL_SemWait(dsp_core->semaphore); return; } - dsp_registers[DSP_REG_SP]++; - dsp_registers[DSP_REG_SSH]++; - dsp_registers[DSP_REG_SSL]++; + dsp_core->registers[DSP_REG_SP]++; + dsp_core->registers[DSP_REG_SSH]++; + dsp_core->registers[DSP_REG_SSL]++; - dsp_stack[0][dsp_registers[DSP_REG_SSH]]=curpc; - dsp_stack[1][dsp_registers[DSP_REG_SSL]]=cursr; + dsp_core->stack[0][dsp_core->registers[DSP_REG_SSH]]=curpc; + dsp_core->stack[1][dsp_core->registers[DSP_REG_SSL]]=cursr; } -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) { + if (dsp_core->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")); + fprintf(stderr, "Dsp: Stack error (underflow)\n"); #endif - dsp_state = DSP_HALT; - SDL_SemWait(dsp56k_sem); + SDL_SemWait(dsp_core->semaphore); return; } - *newpc = dsp_stack[0][dsp_registers[DSP_REG_SSH]]; - *newsr = dsp_stack[1][dsp_registers[DSP_REG_SSL]]; + *newpc = dsp_core->stack[0][dsp_core->registers[DSP_REG_SSH]]; + *newsr = dsp_core->stack[1][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_SP]; + --dsp_core->registers[DSP_REG_SSH]; + --dsp_core->registers[DSP_REG_SSL]; } /********************************** * 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); @@ -1203,21 +1147,21 @@ static void dsp_update_rn(uint32 numreg, 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; - modulo = (dsp_registers[DSP_REG_M0+numreg]+1) & BITMASK(16); + modulo = (dsp_core->registers[DSP_REG_M0+numreg]+1) & BITMASK(16); bufsize = 1; + bufmask = BITMASK(16); while (bufsize < modulo) { bufsize <<= 1; + bufmask <<= 1; } + bufmask &= BITMASK(16); - /* lobound 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; - hibound = lobound + modulo-1; - - r_reg = (int16) (dsp_registers[DSP_REG_R0+numreg] & BITMASK(16)); + r_reg = (Sint16) (dsp_core->registers[DSP_REG_R0+numreg] & BITMASK(16)); + while (modifier>=bufsize) { + r_reg += bufsize; + modifier -= bufsize; + } + while (modifier<=-bufsize) { + r_reg -= bufsize; + modifier += bufsize; + } r_reg += modifier; if (r_reg>hibound) { - r_reg -= hibound; - r_reg += lobound; + 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; + 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); + *dst_addr = read_memory(DSP_SPACE_P,dsp_core->pc+1); cur_inst_len++; if (numreg != 0) { return 1; /* immediate value */ @@ -1332,7 +1281,7 @@ static int dsp_calc_ea(uint32 ea_mode, u case 7: /* -(Rx) */ dsp_update_rn(numreg, -1); - *dst_addr = dsp_registers[DSP_REG_R0+numreg]; + *dst_addr = dsp_core->registers[DSP_REG_R0+numreg]; break; } /* address */ @@ -1361,16 +1310,16 @@ static int cc_code_map[8]={ DSP_SR_ZNV }; -static int dsp_calc_cc(uint32 cc_code) +static int dsp_calc_cc(Uint32 cc_code) { - uint16 value; + Uint16 value; - value = dsp_registers[DSP_REG_SR] & BITMASK(8); + value = dsp_core->registers[DSP_REG_SR] & BITMASK(8); value |= (CCR_BIT(value,DSP_SR_N) ^ CCR_BIT(value, DSP_SR_V))<>3) & 1); + return (Uint32)(CCR_BIT(value,cc_code_map[cc_code & BITMASK(3)]))==((cc_code>>3) & 1); } /********************************** @@ -1423,11 +1372,11 @@ static void opcode8h_0(void) static void opcode8h_1(void) { - switch(cur_inst & 0xfff8c7) { - case 0x018040: + switch(cur_inst & 0xfff000) { + case 0x018000: dsp_div(); break; - case 0x01c805: + case 0x01d000: dsp_norm(); break; } @@ -1456,7 +1405,7 @@ static void opcode8h_6(void) static void opcode8h_8(void) { - uint32 value; + Uint32 value; value = (cur_inst >> 12) & BITMASK(4); opcodes_0809[value](); @@ -1464,7 +1413,7 @@ static void opcode8h_8(void) static void opcode8h_a(void) { - uint32 value; + Uint32 value; value = (cur_inst >> 11) & (BITMASK(2)<<3); value |= (cur_inst >> 5) & BITMASK(3); @@ -1474,7 +1423,7 @@ static void opcode8h_a(void) static void opcode8h_b(void) { - uint32 value; + Uint32 value; value = (cur_inst >> 11) & (BITMASK(2)<<3); value |= (cur_inst >> 5) & BITMASK(3); @@ -1489,34 +1438,34 @@ static void opcode8h_b(void) static void dsp_undefined(void) { cur_inst_len = 0; - D(bug("Dsp: 0x%04x: 0x%06x unknown instruction",dsp_pc, cur_inst)); + fprintf(stderr, "Dsp: 0x%04x: 0x%06x unknown instruction\n",dsp_core->pc, cur_inst); } static void dsp_andi(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)|BITMASK(8); + dsp_core->registers[DSP_REG_SR] &= (value<<8)|BITMASK(8); break; case 1: /* ccr */ - dsp_registers[DSP_REG_SR] &= (BITMASK(8)<<8)|value; + dsp_core->registers[DSP_REG_SR] &= (BITMASK(8)<<8)|value; break; case 2: /* omr */ - dsp_registers[DSP_REG_OMR] &= value; + dsp_core->registers[DSP_REG_OMR] &= value; break; } } static void dsp_bchg(void) { - uint32 memspace, addr, value, numreg, newcarry, numbit; + Uint32 memspace, addr, value, numreg, newcarry, numbit, srcreg; memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); @@ -1565,36 +1514,32 @@ static void dsp_bchg(void) break; case 3: /* bchg #n,R */ - numreg = value; + srcreg = numreg = value; if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { numreg = DSP_REG_A1+(numreg & 1); } - value = dsp_registers[numreg]; + value = dsp_core->registers[numreg]; newcarry = (value>>numbit) & 1; if (newcarry) { value -= (1<registers[numreg] = value; + if (((srcreg==DSP_REG_A) || (srcreg==DSP_REG_B)) && (numbit==23)) { + dsp_core->registers[DSP_REG_A2+(srcreg & 1)]= (newcarry ? 0x00 : 0xff); } break; } /* Set carry */ - dsp_registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<>6) & 1; value = (cur_inst>>8) & BITMASK(6); @@ -1631,28 +1576,28 @@ static void dsp_bclr(void) break; case 3: /* bclr #n,R */ - numreg = value; + srcreg = numreg = value; if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { numreg = DSP_REG_A1+(numreg & 1); } - value = dsp_registers[numreg]; + value = dsp_core->registers[numreg]; newcarry = (value>>numbit) & 1; value &= 0xffffffff-(1<registers[numreg] = value; + if (((srcreg==DSP_REG_A) || (srcreg==DSP_REG_B)) && (numbit==23)) { + dsp_core->registers[DSP_REG_A2+(srcreg & 1)]=0x00; } break; } /* Set carry */ - dsp_registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<>6) & 1; value = (cur_inst>>8) & BITMASK(6); @@ -1689,28 +1634,28 @@ static void dsp_bset(void) break; case 3: /* bset #n,R */ - numreg = value; + srcreg = numreg = value; if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { numreg = DSP_REG_A1+(numreg & 1); } - value = dsp_registers[numreg]; + value = dsp_core->registers[numreg]; newcarry = (value>>numbit) & 1; value |= (1<registers[numreg] = value; + if (((srcreg==DSP_REG_A) || (srcreg==DSP_REG_B)) && (numbit==23)) { + dsp_core->registers[DSP_REG_A2+(srcreg & 1)]=0xff; } break; } /* Set carry */ - dsp_registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<>6) & 1; value = (cur_inst>>8) & BITMASK(6); @@ -1745,20 +1690,20 @@ static void dsp_btst(void) if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { numreg = DSP_REG_A1+(numreg & 1); } - value = dsp_registers[numreg]; + value = dsp_core->registers[numreg]; newcarry = (value>>numbit) & 1; break; } /* Set carry */ - dsp_registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] |= newcarry<>4) & BITMASK(2)) { @@ -1769,91 +1714,90 @@ 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<registers[DSP_REG_LA], dsp_core->registers[DSP_REG_LC]); - dsp_registers[DSP_REG_LA] = read_memory(DSP_SPACE_P, dsp_pc+1) & BITMASK(16); + dsp_core->registers[DSP_REG_LA] = read_memory(DSP_SPACE_P, dsp_core->pc+1) & BITMASK(16); cur_inst_len++; - 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]); - dsp_registers[DSP_REG_SR] |= (1<registers[DSP_REG_SR] |= (1<>12) & (BITMASK(2)<<2); - value |= (cur_inst>>6) & 1<<1; - value |= (cur_inst>>5) & 1; + value = ((cur_inst>>14) & BITMASK(2))<<1; + value |= (cur_inst>>7) & 1; opcodes_do[value](); } -static void dsp_do_0(void) +static void dsp_do_aa(void) { - uint32 memspace, addr; + Uint32 memspace, addr; /* x:aa */ /* y:aa */ memspace = (cur_inst>>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); } -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_core->registers[DSP_REG_LC] = ((cur_inst>>8) & BITMASK(8)) + + ((cur_inst & BITMASK(4))<<8); } -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 */ @@ -1861,46 +1805,43 @@ static void dsp_do_4(void) memspace = (cur_inst>>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); } -static void dsp_do_c(void) +static void dsp_do_reg(void) { - uint32 numreg; + Uint32 numreg; /* S */ 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); } static void dsp_enddo(void) { - uint32 newpc; + Uint32 newpc; - dsp_stack_pop(&newpc, &dsp_registers[DSP_REG_SR]); - dsp_pc = dsp_registers[DSP_REG_LA]; - cur_inst_len = 0; - - dsp_stack_pop(&dsp_registers[DSP_REG_LA], &dsp_registers[DSP_REG_LC]); + dsp_stack_pop(&newpc, &dsp_core->registers[DSP_REG_SR]); + dsp_stack_pop(&dsp_core->registers[DSP_REG_LA], &dsp_core->registers[DSP_REG_LC]); } static void dsp_illegal(void) { /* Raise interrupt p:0x003e */ #if DSP_DISASM_INTER - D(bug("Dsp: Interrupt: Illegal")); + fprintf(stderr, "Dsp: Interrupt: Illegal\n"); #endif } static void dsp_jcc(void) { - uint32 newpc, cc_code; + Uint32 newpc, cc_code; cc_code = 0; switch((cur_inst >> 16) & BITMASK(8)) { @@ -1915,14 +1856,14 @@ static void dsp_jcc(void) } if (dsp_calc_cc(cc_code)) { - dsp_pc = newpc; + dsp_core->pc = newpc; cur_inst_len = 0; } } static void dsp_jclr(void) { - uint32 memspace, addr, value, numreg, newpc, numbit; + Uint32 memspace, addr, value, numreg, newpc, numbit; memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); @@ -1950,43 +1891,59 @@ static void dsp_jclr(void) case 3: /* jclr #n,R,p:xx */ numreg = value; - value = dsp_registers[numreg]; + value = dsp_core->registers[numreg]; addr = 0xffff0000; /* invalid address */ memspace = 0xffff0000; /* invalid memspace */ break; } - cur_inst_len++; + ++cur_inst_len; if ((value & (1<pc+1); + + /* Polling loop if jump to same PC as current JCLR instruction */ + pollingLoop = (newpc == dsp_core->pc); + if (!pollingLoop && (newpcpc)) { + /* or if only NOPs from jump address to current JCLR instruction */ + pollingLoop = 1; + for (i=newpc; ipc; i++) { + if (read_memory(DSP_SPACE_P, i) != 0) { + pollingLoop=0; + break; + } + } + } + if (!pollingLoop && (newpc+2 == dsp_core->pc)) { + /* or programs that re-set host port operation (Papa was a bladerunner/Eko) */ + pollingLoop = (read_memory(DSP_SPACE_P, newpc) == 0x08f4a0) /* movep #0x000001,x:0xffe0 */ + && (read_memory(DSP_SPACE_P, newpc+1) == 0x000001); + } + if (pollingLoop) { /* Are we waiting for host port ? */ if ((memspace==DSP_SPACE_X) && (addr==0xffc0+DSP_HOST_HSR)) { /* Wait for host to write */ if (numbit==DSP_HOST_HSR_HRDF) { #if DSP_DISASM_STATE - D(bug("Dsp: state = DSP_WAITHOSTWRITE")); + fprintf(stderr, "Dsp: WAIT_HOSTWRITE\n"); #endif - dsp_state = DSP_WAITHOSTWRITE; - SDL_SemWait(dsp56k_sem); + SDL_SemWait(dsp_core->semaphore); } /* Wait for host to read */ if (numbit==DSP_HOST_HSR_HTDE) { #if DSP_DISASM_STATE - D(bug("Dsp: state = DSP_WAITHOSTREAD")); + fprintf(stderr, "Dsp: WAIT_HOSTREAD\n"); #endif - dsp_state = DSP_WAITHOSTREAD; - SDL_SemWait(dsp56k_sem); + SDL_SemWait(dsp_core->semaphore); } } } - dsp_pc = newpc; + dsp_core->pc = newpc; cur_inst_len = 0; return; } @@ -1994,7 +1951,7 @@ static void dsp_jclr(void) static void dsp_jmp(void) { - uint32 newpc; + Uint32 newpc; switch((cur_inst >> 16) & BITMASK(8)) { case 0x0a: @@ -2008,21 +1965,20 @@ static void dsp_jmp(void) cur_inst_len = 0; /* Infinite loop ? */ - if (newpc == dsp_pc) { + if (newpc == dsp_core->pc) { #if DSP_DISASM_STATE - D(bug("Dsp: state = DSP_HALT")); + fprintf(stderr, "Dsp: JMP instruction, infinite loop\n"); #endif - dsp_state = DSP_HALT; - SDL_SemWait(dsp56k_sem); + SDL_SemWait(dsp_core->semaphore); return; } - dsp_pc = newpc; + dsp_core->pc = newpc; } static void dsp_jscc(void) { - uint32 newpc, cc_code; + Uint32 newpc, cc_code; cc_code = 0; switch((cur_inst >> 16) & BITMASK(8)) { @@ -2037,16 +1993,16 @@ static void dsp_jscc(void) } 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]); - dsp_pc = newpc; + dsp_core->pc = newpc; cur_inst_len = 0; } } static void dsp_jsclr(void) { - uint32 memspace, addr, value, numreg, newpc, numbit; + Uint32 memspace, addr, value, numreg, newpc, numbit; memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); @@ -2074,24 +2030,24 @@ static void dsp_jsclr(void) case 3: /* jsclr #n,R,p:xx */ numreg = value; - value = dsp_registers[numreg]; + value = dsp_core->registers[numreg]; break; } - cur_inst_len++; + ++cur_inst_len; if ((value & (1<pc+cur_inst_len, dsp_core->registers[DSP_REG_SR]); - newpc = read_memory(DSP_SPACE_P, dsp_pc+1); - dsp_pc = newpc; + newpc = read_memory(DSP_SPACE_P, dsp_core->pc+1); + dsp_core->pc = newpc; cur_inst_len = 0; } } static void dsp_jset(void) { - uint32 memspace, addr, value, numreg, numbit; - uint32 newpc; + Uint32 memspace, addr, value, numreg, numbit; + Uint32 newpc; memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); @@ -2119,22 +2075,22 @@ static void dsp_jset(void) case 3: /* jset #n,R,p:xx */ numreg = value; - value = dsp_registers[numreg]; + value = dsp_core->registers[numreg]; break; } - cur_inst_len++; + ++cur_inst_len; if (value & (1<pc+1); - dsp_pc = newpc; + dsp_core->pc = newpc; cur_inst_len=0; } } static void dsp_jsr(void) { - uint32 newpc; + Uint32 newpc; if (((cur_inst>>12) & BITMASK(4))==0) { newpc = cur_inst & BITMASK(12); @@ -2142,15 +2098,15 @@ static void dsp_jsr(void) dsp_calc_ea((cur_inst>>8) & BITMASK(6),&newpc); } - 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]); - dsp_pc = newpc; + dsp_core->pc = newpc; cur_inst_len = 0; } static void dsp_jsset(void) { - uint32 memspace, addr, value, numreg, newpc, numbit; + Uint32 memspace, addr, value, numreg, newpc, numbit; memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); @@ -2178,50 +2134,62 @@ static void dsp_jsset(void) case 3: /* jsset #n,R,p:xx */ numreg = value; - value = dsp_registers[numreg]; + value = dsp_core->registers[numreg]; break; } - cur_inst_len++; + ++cur_inst_len; if (value & (1<pc+cur_inst_len, dsp_core->registers[DSP_REG_SR]); - newpc = read_memory(DSP_SPACE_P, dsp_pc+1); - dsp_pc = newpc; + newpc = read_memory(DSP_SPACE_P, dsp_core->pc+1); + dsp_core->pc = newpc; cur_inst_len = 0; } } static void dsp_lua(void) { - uint32 value, srcreg, dstreg; - - dsp_calc_ea((cur_inst>>8) & BITMASK(5), &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); if (cur_inst & (1<<3)) { - dsp_registers[DSP_REG_N0+dstreg] = dsp_registers[DSP_REG_N0+srcreg]; + dsp_core->registers[DSP_REG_N0+dstreg] = srcnew; } else { - dsp_registers[DSP_REG_R0+dstreg] = dsp_registers[DSP_REG_R0+srcreg]; + dsp_core->registers[DSP_REG_R0+dstreg] = srcnew; } } +/* + MOVEC instruction parameter encoding + + xxxxxxx0 x1xxxxxx 1xxxxxxx reg + xxxxxxx1 x0xxxxxx 0xxxxxxx aa + xxxxxxx1 x1xxxxxx 0xxxxxxx ea + xxxxxxx1 xYxxxxxx 1xxxxxxx #xx +*/ static void dsp_movec(void) { - uint32 value; - - value = (cur_inst>>13) & (1<<3); - value |= (cur_inst>>12) & (1<<2); - value |= (cur_inst>>6) & (1<<1); - value |= (cur_inst>>5) & 1; + Uint32 value; + + value = ((cur_inst>>16) & 1)<<2; + value |= ((cur_inst>>14) & 1)<<1; + value |= (cur_inst>>7) & 1; opcodes_movec[value](); } -static void dsp_movec_7(void) +static void dsp_movec_reg(void) { - uint32 numreg1, numreg2, value; + Uint32 numreg1, numreg2, value; /* S1,D2 */ /* S2,D1 */ @@ -2233,32 +2201,32 @@ static void dsp_movec_7(void) /* Write D1 */ if ((numreg2 == DSP_REG_A) || (numreg2 == DSP_REG_B)) { - dsp_pm_read_accu24(numreg2, &dsp_registers[numreg1]); + dsp_pm_read_accu24(numreg2, &dsp_core->registers[numreg1]); } else { - dsp_registers[numreg1] = dsp_registers[numreg2]; + dsp_core->registers[numreg1] = dsp_core->registers[numreg2]; } - dsp_registers[numreg1] &= BITMASK(registers_mask[numreg1]); + dsp_core->registers[numreg1] &= BITMASK(registers_mask[numreg1]); } else { /* Read S1 */ if ((numreg2 == DSP_REG_A) || (numreg2 == DSP_REG_B)) { - value = dsp_registers[numreg1]; - dsp_registers[DSP_REG_A2+(numreg2 & 1)] = 0; + value = dsp_core->registers[numreg1]; + 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] = dsp_core->registers[numreg1]; + dsp_core->registers[numreg2] &= BITMASK(registers_mask[numreg2]); } } } -static void dsp_movec_9(void) +static void dsp_movec_aa(void) { - uint32 numreg, addr, memspace; + Uint32 numreg, addr, memspace; /* x:aa,D1 */ /* S1,x:aa */ @@ -2272,28 +2240,28 @@ static void dsp_movec_9(void) if (cur_inst & (1<<15)) { /* Write D1 */ - dsp_registers[numreg] = read_memory(memspace, addr); - dsp_registers[numreg] &= BITMASK(registers_mask[numreg]); + dsp_core->registers[numreg] = read_memory(memspace, addr); + dsp_core->registers[numreg] &= BITMASK(registers_mask[numreg]); } else { /* Read S1 */ - write_memory(memspace, addr, dsp_registers[numreg]); + write_memory(memspace, addr, dsp_core->registers[numreg]); } } -static void dsp_movec_b(void) +static void dsp_movec_imm(void) { - uint32 numreg; + Uint32 numreg; /* #xx,D1 */ numreg = (cur_inst & BITMASK(5))|0x20; - dsp_registers[numreg] = (cur_inst>>8) & BITMASK(8); + dsp_core->registers[numreg] = (cur_inst>>8) & BITMASK(8); } -static void dsp_movec_d(void) +static void dsp_movec_ea(void) { - uint32 numreg, addr, memspace, ea_mode; + Uint32 numreg, addr, memspace, ea_mode; int retour; /* x:ea,D1 */ @@ -2311,23 +2279,23 @@ static void dsp_movec_d(void) retour = dsp_calc_ea(ea_mode, &addr); if (retour) { - dsp_registers[numreg] = addr; + dsp_core->registers[numreg] = addr; } else { - dsp_registers[numreg] = read_memory(memspace, addr); + dsp_core->registers[numreg] = read_memory(memspace, addr); } - dsp_registers[numreg] &= BITMASK(registers_mask[numreg]); + dsp_core->registers[numreg] &= BITMASK(registers_mask[numreg]); } else { /* Read S1 */ retour = dsp_calc_ea(ea_mode, &addr); - write_memory(memspace, addr, dsp_registers[numreg]); + write_memory(memspace, addr, dsp_core->registers[numreg]); } } static void dsp_movem(void) { - uint32 numreg, addr, ea_mode, value; + Uint32 numreg, addr, ea_mode, value; numreg = cur_inst & BITMASK(6); @@ -2349,15 +2317,15 @@ static void dsp_movem(void) if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { value = read_memory(DSP_SPACE_P, addr); - dsp_registers[DSP_REG_A2+(numreg & 1)] = 0; + dsp_core->registers[DSP_REG_A2+(numreg & 1)] = 0; if (value & (1<<23)) { - dsp_registers[DSP_REG_A2+(numreg & 1)] = 0xff; + dsp_core->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; + dsp_core->registers[DSP_REG_A1+(numreg & 1)] = value & BITMASK(24); + dsp_core->registers[DSP_REG_A0+(numreg & 1)] = 0; } else { - dsp_registers[numreg] = read_memory(DSP_SPACE_P, addr); - dsp_registers[numreg] &= BITMASK(registers_mask[numreg]); + dsp_core->registers[numreg] = read_memory(DSP_SPACE_P, addr); + dsp_core->registers[numreg] &= BITMASK(registers_mask[numreg]); } } else { /* Read S */ @@ -2365,7 +2333,7 @@ static void dsp_movem(void) if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { dsp_pm_read_accu24(numreg, &value); } else { - value = dsp_registers[numreg]; + value = dsp_core->registers[numreg]; } write_memory(DSP_SPACE_P, addr, value); } @@ -2373,7 +2341,7 @@ static void dsp_movem(void) static void dsp_movep(void) { - uint32 value; + Uint32 value; value = (cur_inst>>6) & BITMASK(2); @@ -2387,7 +2355,7 @@ static void dsp_movep_0(void) /* S,y:pp */ /* y:pp,D */ - uint32 addr, memspace, numreg, value; + Uint32 addr, memspace, numreg, value; addr = 0xffc0 + (cur_inst & BITMASK(6)); memspace = (cur_inst>>16) & 1; @@ -2399,7 +2367,7 @@ static void dsp_movep_0(void) if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { dsp_pm_read_accu24(numreg, &value); } else { - value = dsp_registers[numreg]; + value = dsp_core->registers[numreg]; } write_memory(memspace, addr, value); } else { @@ -2408,15 +2376,15 @@ static void dsp_movep_0(void) value = read_memory(memspace, addr); if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_registers[DSP_REG_A2+(numreg & 1)] = 0; + dsp_core->registers[DSP_REG_A2+(numreg & 1)] = 0; if (value & (1<<23)) { - dsp_registers[DSP_REG_A2+(numreg & 1)] = 0xff; + dsp_core->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; + dsp_core->registers[DSP_REG_A1+(numreg & 1)] = value & BITMASK(24); + dsp_core->registers[DSP_REG_A0+(numreg & 1)] = 0; } else { - dsp_registers[numreg] = value; - dsp_registers[numreg] &= BITMASK(registers_mask[numreg]); + dsp_core->registers[numreg] = value; + dsp_core->registers[numreg] &= BITMASK(registers_mask[numreg]); } } } @@ -2428,7 +2396,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); @@ -2456,7 +2424,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)); @@ -2483,10 +2451,10 @@ static void dsp_movep_2(void) 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,112 +2462,121 @@ 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_core->registers[DSP_REG_A2+numreg] = dest[0]; + dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; + dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + + dsp_ccr_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); - dsp_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; } } +/* + REP instruction parameter encoding + + xxxxxxxx 00xxxxxx 0xxxxxxx aa + xxxxxxxx 01xxxxxx 0xxxxxxx ea + xxxxxxxx YYxxxxxx 1xxxxxxx imm + xxxxxxxx 11xxxxxx 0xxxxxxx reg +*/ + static void dsp_rep(void) { - uint32 value; + Uint32 value; - dsp_registers[DSP_REG_LCSAVE] = dsp_registers[DSP_REG_LC]; + dsp_core->registers[DSP_REG_LCSAVE] = dsp_core->registers[DSP_REG_LC]; - value = (cur_inst>>12) & (BITMASK(2)<<2); - value |= (cur_inst>>6) & (1<<1); - value |= (cur_inst>>5) & 1; + value = ((cur_inst>>14) & BITMASK(2))<<1; + value |= (cur_inst>>7) & 1; opcodes_rep[value](); pc_on_rep = 1; /* Not decrement LC at first time */ - dsp_loop_rep = 1; /* We are now running rep */ + dsp_core->loop_rep = 1; /* We are now running rep */ } -static void dsp_rep_1(void) +static void dsp_rep_aa(void) { /* x:aa */ /* y:aa */ - dsp_registers[DSP_REG_LC]=read_memory((cur_inst>>6) & 1,(cur_inst>>8) & BITMASK(6)); + dsp_core->registers[DSP_REG_LC]=read_memory((cur_inst>>6) & 1,(cur_inst>>8) & BITMASK(6)); } -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_LC] = ((cur_inst>>8) & BITMASK(8)) + + ((cur_inst & BITMASK(4))<<8); } -static void dsp_rep_5(void) +static void dsp_rep_ea(void) { - uint32 value; + Uint32 value; /* x:ea */ /* y:ea */ 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); } -static void dsp_rep_d(void) +static void dsp_rep_reg(void) { - uint32 numreg; + Uint32 numreg; /* R */ 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); } static void dsp_reset(void) @@ -2609,58 +2586,60 @@ static void dsp_reset(void) 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; } 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; } static void dsp_stop(void) { - dsp_state = DSP_HALT; - SDL_SemWait(dsp56k_sem); +#if DSP_DISASM_STATE + fprintf(stderr, "Dsp: STOP instruction\n"); +#endif + SDL_SemWait(dsp_core->semaphore); } static void dsp_swi(void) { /* Raise interrupt p:0x0006 */ #if DSP_DISASM_INTER - D(bug("Dsp: Interrupt: Swi")); + fprintf(stderr, "Dsp: Interrupt: Swi\n"); #endif } 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 +2649,26 @@ 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 + SDL_SemWait(dsp_core->semaphore); } /********************************** @@ -2696,7 +2677,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; @@ -2709,7 +2690,7 @@ static void dsp_parmove_read(void) 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 +2707,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 +2717,62 @@ 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, numbits; + int got_limited=0; /* Read an accumulator, stores it limited */ - scaling = (dsp_registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); + scaling = (dsp_core->registers[DSP_REG_SR]>>DSP_SR_S0) & BITMASK(2); numreg &= 1; /* scaling==1 */ - value = dsp_registers[DSP_REG_A2+numreg] & 0xff; + value = dsp_core->registers[DSP_REG_A2+numreg] & 0xff; numbits = 8; switch(scaling) { case 0: value <<=1; - value |= (dsp_registers[DSP_REG_A1+numreg]>>23) & 1; + value |= (dsp_core->registers[DSP_REG_A1+numreg]>>23) & 1; numbits=9; break; case 2: value <<=2; - value |= (dsp_registers[DSP_REG_A1+numreg]>>22) & 3; + value |= (dsp_core->registers[DSP_REG_A1+numreg]>>22) & 3; numbits=10; break; } - if ((value==0) || (value==(uint32)(BITMASK(numbits)))) { + 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)) { + *dest=dsp_core->registers[DSP_REG_A1+numreg]; + } else if (dsp_core->registers[DSP_REG_A2+numreg] & (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 +2781,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 +2801,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 +2809,17 @@ 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_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[0]=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 +2876,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,23 +2901,23 @@ 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 @@ -2962,7 +2946,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 +2956,21 @@ 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]); + 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[srcreg]); if (tmp_parmove_src[0][1] & (1<<23)) { tmp_parmove_src[0][0]=0x0000ff; } } else { /* Register to register: n bits */ - tmp_parmove_src[0][1]=dsp_registers[srcreg] & BITMASK(registers_mask[srcreg]); + tmp_parmove_src[0][1]=dsp_core->registers[srcreg] & BITMASK(registers_mask[srcreg]); } } @@ -3003,7 +2980,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,7 +3013,7 @@ static void dsp_pm_3(void) static void dsp_pm_4(void) { - uint32 l_addr, value; + Uint32 l_addr, value; int retour; /* 0100 l0ll w0aa aaaa l:aa,D @@ -3072,9 +3049,10 @@ static void dsp_pm_4(void) dsp_pm_5(); } -static void dsp_pm_4x(int immediat, uint32 l_addr) +static void dsp_pm_4x(int immediat, Uint32 l_addr) { - uint32 value, numreg, numreg2; + Uint32 value, numreg, numreg2; + immediat = 0; /* UNUSED */ /* 0100 l0ll w0aa aaaa l:aa,D S,l:aa @@ -3088,94 +3066,58 @@ static void dsp_pm_4x(int immediat, uint if (cur_inst & (1<<15)) { /* Write D */ - /* S1 */ + /* Sources */ 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][0] = (value & (1<<23) ? 0xff : 0); tmp_parmove_src[0][1] = value & BITMASK(registers_mask[registers_lmove[numreg][0]]); tmp_parmove_src[0][2] = 0x000000; - - /* 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)]; + if (registers_lmove[numreg][0]==registers_lmove[numreg][1]) { + /* Write to 56bit accumulator, setup a single transfer as 56 bit */ + tmp_parmove_src[0][2] = value & BITMASK(registers_mask[registers_lmove[numreg][1]]); } else { - 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; + /* Writes to 24bit registers, setup second 24 bit transfer */ + tmp_parmove_src[1][0] = (value & (1<<23) ? 0xff : 0); + tmp_parmove_src[1][1] = value & BITMASK(registers_mask[registers_lmove[numreg][1]]); + tmp_parmove_src[1][2] = 0x000000; } + /* Destinations */ + dsp_pm_writereg(registers_lmove[numreg][0], 0); 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; + if (registers_lmove[numreg][0]!=registers_lmove[numreg][1]) { + /* Two 24 or 56 bits registers */ + dsp_pm_writereg(registers_lmove[numreg][1], 1); + tmp_parmove_type[1]=0; } - 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]); + /* Sources */ + if (numreg<4) { + /* Two 24 bits tranfers */ + tmp_parmove_src[0][1] = dsp_core->registers[registers_lmove[numreg][0]]; + tmp_parmove_src[1][1] = dsp_core->registers[registers_lmove[numreg][1]]; + } else if (numreg<6) { + /* Single accumulator transfer */ + numreg2 = registers_lmove[numreg][0]; + if (dsp_pm_read_accu24(numreg2, &tmp_parmove_src[0][1])) { + /* Was limited, set lower part */ + tmp_parmove_src[1][1] = (tmp_parmove_src[0][1] & (1<<23) ? 0 : 0xffffff); + } else { + /* Not limited */ + tmp_parmove_src[1][1] = dsp_core->registers[DSP_REG_A0+(numreg2 & 1)]; + } } else { - tmp_parmove_src[1][1] = dsp_registers[numreg2]; + /* Two accumulators tranfers */ + dsp_pm_read_accu24(registers_lmove[numreg][0], &tmp_parmove_src[0][1]); + dsp_pm_read_accu24(registers_lmove[numreg][1], &tmp_parmove_src[1][1]); } - + /* D1 */ tmp_parmove_dest[0][1].dsp_address=l_addr; - tmp_parmove_start[0]=1; tmp_parmove_len[0]=1; @@ -3184,7 +3126,6 @@ static void dsp_pm_4x(int immediat, uint /* D2 */ tmp_parmove_dest[1][1].dsp_address=l_addr; - tmp_parmove_start[1]=1; tmp_parmove_len[1]=1; @@ -3195,7 +3136,7 @@ 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 S,x:aa @@ -3245,7 +3186,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,9 +3201,9 @@ 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, dummy1, dummy2; /* 1wmm eeff WrrM MRRR x:ea,D1 y:ea,D2 x:ea,D1 S2,y:ea @@ -3319,7 +3260,7 @@ 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; @@ -3349,7 +3290,7 @@ static void dsp_pm_8(void) if ((numreg1==DSP_REG_A) || (numreg1==DSP_REG_B)) { dsp_pm_read_accu24(numreg1, &tmp_parmove_src[1][1]); } else { - tmp_parmove_src[1][1]=dsp_registers[numreg1]; + tmp_parmove_src[1][1]=dsp_core->registers[numreg1]; } tmp_parmove_dest[1][1].dsp_address=dummy2; @@ -3370,10 +3311,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 +3333,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 +3357,9 @@ static uint16 dsp_asl56(uint32 *dest) return (overflow<>=1 */ @@ -3439,52 +3380,20 @@ static uint16 dsp_asr56(uint32 *dest) return (carry<>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]++; - } - - src = source[0] & BITMASK(8); - if (src & (1<<7)) { - src |= 0xffffff00; - } - dest[0] += src; - if ((dest[1]>>24) & BITMASK(8)) { - dest[0]++; - } + dest[2] += source[2]; + dest[1] += source[1]+((dest[2]>>24) & 1); + dest[0] += source[0]+((dest[1]>>24) & 1); /* overflow if we go below -256.0 or above +256.0 */ - overflow = (((dest[0] & 0xffffff00)!=0) && ((dest[0] & 0xffffff00)!=0xffffff00)); + overflow = (((dest[0] & 0xff)!=0) && ((dest[0] & 0xff)!=0xff)); - if (overflow) { - 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); - } - } + /* set carry from the virtual 56th bit */ + carry = (dest[0]>>8) & 1; dest[2] &= BITMASK(24); dest[1] &= BITMASK(24); @@ -3493,53 +3402,20 @@ static uint16 dsp_add56(uint32 *source, return (overflow<>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]--; - } - - src = source[0] & BITMASK(8); - if (src & (1<<7)) { - src |= 0xffffff00; - } - dest[0] -= src; - if ((dest[1]>>24) & BITMASK(8)) { - dest[0]--; - } + dest[2] -= source[2]; + dest[1] -= source[1]+((dest[2]>>24) & 1); + dest[0] -= source[0]+((dest[1]>>24) & 1); /* overflow if we go below -256.0 or above +256.0 */ - overflow = (((dest[0] & 0xffffff00)!=0) && ((dest[0] & 0xffffff00)!=0xffffff00)); + overflow = (((dest[0] & 0xff)!=0) && ((dest[0] & 0xff)!=0xff)); - if (overflow) { - 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); - } - } + /* set carry from the virtual 56th bit */ + carry = (dest[0]>>8) & 1; dest[2] &= BITMASK(24); dest[1] &= BITMASK(24); @@ -3548,10 +3424,10 @@ static uint16 dsp_sub56(uint32 *source, return (overflow<>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 +3586,48 @@ 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_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_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); - dsp_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 +3635,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 +3643,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 +3651,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 +3659,206 @@ 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_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_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); - dsp_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_core->registers[DSP_REG_A2+numreg] = dest[0]; + dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; + dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + + dsp_ccr_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); - dsp_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_core->registers[DSP_REG_A2+numreg] = dest[0]; + dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; + dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + + dsp_ccr_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); - dsp_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_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]; 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_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); } 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_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); } 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 +3866,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 +3874,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 +3882,50 @@ 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_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); - dsp_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 +3933,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 +3941,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 +3949,100 @@ 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_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); - dsp_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 +4055,34 @@ 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_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_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); - dsp_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 +4095,24 @@ 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_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_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); - dsp_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) @@ -4221,13 +4130,13 @@ static void dsp_move_pm(void) 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 +4144,32 @@ 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_extension(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg]); + dsp_ccr_unnormalized(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg]); + dsp_ccr_negative(&dsp_core->registers[DSP_REG_A2+destreg]); + dsp_ccr_zero(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg], &dsp_core->registers[DSP_REG_A0+destreg]); - dsp_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 +4184,26 @@ 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_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_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); - dsp_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,16 +4211,16 @@ 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_core->registers[DSP_REG_SR] &= BITMASK(16)-(1<>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 +4369,48 @@ 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_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_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); - dsp_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 +4418,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 +4426,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 +4434,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 +4442,95 @@ 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_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_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); - dsp_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_core->registers[DSP_REG_A2+numreg] = dest[0]; + dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; + dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + + dsp_ccr_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); - dsp_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_core->registers[DSP_REG_A2+numreg] = dest[0]; + dsp_core->registers[DSP_REG_A1+numreg] = dest[1]; + dsp_core->registers[DSP_REG_A0+numreg] = dest[2]; + + dsp_ccr_extension(&dest[0], &dest[1]); + dsp_ccr_unnormalized(&dest[0], &dest[1]); + dsp_ccr_negative(&dest[0]); dsp_ccr_zero(&dest[0], &dest[1], &dest[2]); - dsp_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 +4538,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 +4552,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 +4560,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 +4568,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 +4578,25 @@ 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_extension(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg]); + dsp_ccr_unnormalized(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg]); + dsp_ccr_negative(&dsp_core->registers[DSP_REG_A2+destreg]); + dsp_ccr_zero(&dsp_core->registers[DSP_REG_A2+destreg], &dsp_core->registers[DSP_REG_A1+destreg], &dsp_core->registers[DSP_REG_A0+destreg]); - dsp_registers[DSP_REG_SR] &= BITMASK(16)-(1<registers[DSP_REG_SR] &= BITMASK(16)-(1<