--- hatari/src/falcon/dsp_cpu.c 2019/04/09 08:52:11 1.1.1.8 +++ hatari/src/falcon/dsp_cpu.c 2019/04/09 08:58:17 1.1.1.13 @@ -15,25 +15,26 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + along with this program; if not, write to the Free Software Foundation, + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ /* DSP memory mapping ------------------ - + The memory map is configured as follows : Program space P is one contiguous block of 32K dsp Words - X and Y data space are each separate 16K dsp Word blocks. + X and Y data space are each separate 16K dsp Word blocks. Both X and Y can be accessed as blocks starting at 0 or 16K. Program space physically overlaps both X and Y data spaces. Y: memory is mapped at address $0 in P memory - X: memory is mapped at address $4000 in P memory + X: memory is mapped at address $4000 in P memory The DSP external RAM is zero waitstate, but there is a penalty for - accessing it twice in a single instruction, because there is only - one external data bus. + accessing it twice or more in a single instruction, because there is only + one external data bus. The extra access costs 2 cycles penalty. + The internal buses are all separate (0 waitstate) @@ -73,12 +74,12 @@ #include +#include "main.h" #include "dsp_core.h" #include "dsp_cpu.h" #include "dsp_disasm.h" #include "log.h" -# include "main.h" - +#include "debugui.h" #define DSP_COUNT_IPS 0 /* Count instruction per seconds */ @@ -90,6 +91,14 @@ #define SIGN_PLUS 0 #define SIGN_MINUS 1 +/* Defines some bits values for access to external memory (X, Y, P) */ +/* These values will set/unset the corresponding bits in the variable access_to_ext_memory */ +/* to detect how many access to the external memory were done for a single instruction */ +#define EXT_X_MEMORY 0 +#define EXT_Y_MEMORY 1 +#define EXT_P_MEMORY 2 + + /********************************** * Variables **********************************/ @@ -105,7 +114,7 @@ static Uint32 cur_inst_len; /* =0:jump, static Uint32 cur_inst; /* Counts the number of access to the external memory for one instruction */ -static Uint16 nb_access_to_extMemory; +static Uint16 access_to_ext_memory; /* DSP is in disasm mode ? */ /* If yes, stack overflow, underflow and illegal instructions messages are not displayed */ @@ -135,7 +144,7 @@ static inline void write_memory(int spac static void write_memory_raw(int space, Uint16 address, Uint32 value); static void write_memory_disasm(int space, Uint16 address, Uint32 value); -static void dsp_write_reg(Uint32 numreg, Uint32 value); +static void dsp_write_reg(Uint32 numreg, Uint32 value); static void dsp_stack_push(Uint32 curpc, Uint32 cursr, Uint16 sshOnly); static void dsp_stack_pop(Uint32 *curpc, Uint32 *cursr); @@ -269,7 +278,6 @@ static void dsp_add_x1_b(void); static void dsp_add_y1_a(void); static void dsp_add_y1_b(void); static void dsp_addl_b_a(void); -static void dsp_addl_b_a(void); static void dsp_addl_a_b(void); static void dsp_addr_b_a(void); static void dsp_addr_a_b(void); @@ -511,7 +519,7 @@ static const dsp_emul_t opcodes8h[512] = dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_div, dsp_div, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_norm, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - + /* 0x40 - 0x7f */ dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_tcc, dsp_tcc, dsp_tcc, dsp_tcc, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, @@ -524,23 +532,23 @@ static const dsp_emul_t opcodes8h[512] = /* 0x80 - 0xbf */ dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_lua, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_reg, dsp_undefined, dsp_undefined, + dsp_lua, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_reg, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_reg, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_reg, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_aa, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_ea, dsp_undefined, dsp_movec_imm, dsp_undefined, dsp_undefined, - + /* 0xc0 - 0xff */ - dsp_do_aa, dsp_rep_aa, dsp_do_aa, dsp_rep_aa, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, - dsp_do_ea, dsp_rep_ea, dsp_do_ea, dsp_rep_ea, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, - dsp_do_reg, dsp_rep_reg, dsp_undefined, dsp_undefined, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, - dsp_movem_aa, dsp_movem_aa, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movem_ea, dsp_movem_ea, dsp_undefined, dsp_undefined, - dsp_movem_aa, dsp_movem_aa, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movem_ea, dsp_movem_ea, dsp_undefined, dsp_undefined, + dsp_do_aa, dsp_rep_aa, dsp_do_aa, dsp_rep_aa, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_do_ea, dsp_rep_ea, dsp_do_ea, dsp_rep_ea, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_do_reg, dsp_rep_reg, dsp_undefined, dsp_undefined, dsp_do_imm, dsp_rep_imm, dsp_undefined, dsp_undefined, + dsp_movem_aa, dsp_movem_aa, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movem_ea, dsp_movem_ea, dsp_undefined, dsp_undefined, + dsp_movem_aa, dsp_movem_aa, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_movem_ea, dsp_movem_ea, dsp_undefined, dsp_undefined, /* 0x100 - 0x13f */ dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, dsp_pm_0, @@ -564,23 +572,23 @@ static const dsp_emul_t opcodes8h[512] = /* 0x180 - 0x1bf */ dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, dsp_jmp_imm, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, - dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, dsp_jsr_imm, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, + dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, dsp_undefined, /* 0x1c0 - 0x1ff */ - dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, - dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, - dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, - dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, - dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, - dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, - dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, - dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, dsp_jcc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, + dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, dsp_jscc_imm, }; static const dsp_emul_t opcodes_parmove[16] = { @@ -598,7 +606,7 @@ static const dsp_emul_t opcodes_alu[256] dsp_add_x_b, dsp_adc_x_b, dsp_asr_b, dsp_lsr_b, dsp_sub_x_b, dsp_sbc_x_b, dsp_abs_b, dsp_ror_b, dsp_add_y_a, dsp_adc_y_a, dsp_asl_a, dsp_lsl_a, dsp_sub_y_a, dsp_sbc_y_a, dsp_neg_a, dsp_rol_a, dsp_add_y_b, dsp_adc_y_b, dsp_asl_b, dsp_lsl_b, dsp_sub_y_b, dsp_sbc_y_b, dsp_neg_b, dsp_rol_b, - + /* 0x40 - 0x7f */ dsp_add_x0_a, dsp_tfr_x0_a, dsp_or_x0_a, dsp_eor_x0_a, dsp_sub_x0_a, dsp_cmp_x0_a, dsp_and_x0_a, dsp_cmpm_x0_a, dsp_add_x0_b, dsp_tfr_x0_b, dsp_or_x0_b, dsp_eor_x0_b, dsp_sub_x0_b, dsp_cmp_x0_b, dsp_and_x0_b, dsp_cmpm_x0_b, @@ -657,12 +665,12 @@ static const int registers_mask[64] = { 24, 24, 24, 24, 24, 24, 8, 8, 24, 24, 24, 24, - + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - + 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, @@ -689,6 +697,13 @@ static const dsp_interrupt_t dsp_interru {DSP_INTER_SSI_TRX_DATA , 0x10, 2, "SSI tramsmit"} }; +static struct { + int limit; + int count; + Uint32 inst; + Uint16 pc; +} dsp_error; + /********************************** * Emulator kernel @@ -699,13 +714,15 @@ void dsp56k_init_cpu(void) dsp56k_disasm_init(); isDsp_in_disasm_mode = false; start_time = SDL_GetTicks(); + memset(&dsp_error, 0, sizeof(dsp_error)); + dsp_error.limit = 1; num_inst = 0; } /** * Execute one instruction in trace mode at a given PC address. * */ -Uint16 dsp56k_execute_one_disasm_instruction(Uint16 pc) +Uint16 dsp56k_execute_one_disasm_instruction(FILE *out, Uint16 pc) { dsp_core_t *ptr1, *ptr2; static dsp_core_t dsp_core_save; @@ -724,16 +741,16 @@ Uint16 dsp56k_execute_one_disasm_instruc dsp_core.pc = pc; /* Disasm instruction */ - instruction_length = dsp56k_disasm(DSP_DISASM_MODE) - 1; + instruction_length = dsp56k_disasm(DSP_DISASM_MODE, out) - 1; /* Execute instruction at address given in parameter to get the number of cycles it takes */ dsp56k_execute_instruction(); - fprintf(stderr, "%s", dsp56k_getInstructionText()); + fprintf(out, "%s", dsp56k_getInstructionText()); /* Restore DSP context after executing instruction */ memcpy(ptr1, ptr2, sizeof(dsp_core)); - + /* Unset DSP in disasm mode */ isDsp_in_disasm_mode = false; @@ -747,28 +764,31 @@ void dsp56k_execute_instruction(void) disasm_memory_ptr = 0; /* Initialise the number of access to the external memory for this instruction */ - nb_access_to_extMemory = 0; - + access_to_ext_memory = 0; + + /* Init the indirect AGU move instruction flag */ + dsp_core.agu_move_indirect_instr = 0; + /* Decode and execute current instruction */ cur_inst = read_memory_p(dsp_core.pc); - + /* Initialize instruction size and cycle counter */ cur_inst_len = 1; dsp_core.instr_cycle = 2; /* Disasm current instruction ? (trace mode only) */ - if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM)) { + if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM)) { /* Call dsp56k_disasm only when DSP is called in trace mode */ if (isDsp_in_disasm_mode == false) { - disasm_return = dsp56k_disasm(DSP_TRACE_MODE); - + disasm_return = dsp56k_disasm(DSP_TRACE_MODE, TraceFile); + if (disasm_return != 0 && LOG_TRACE_LEVEL(TRACE_DSP_DISASM_REG)) { /* DSP regs trace enabled only if DSP DISASM is enabled */ dsp56k_disasm_reg_save(); } } } - + if (cur_inst < 0x100000) { value = (cur_inst >> 11) & (BITMASK(6) << 3); value += (cur_inst >> 5) & BITMASK(3); @@ -779,28 +799,35 @@ void dsp56k_execute_instruction(void) } /* Add the waitstate due to external memory access */ - if (nb_access_to_extMemory > 1) - dsp_core.instr_cycle += nb_access_to_extMemory - 1; - + /* (2 extra cycles per extra access to the external memory after the first one */ + if (access_to_ext_memory != 0) { + value = access_to_ext_memory & 1; + value += (access_to_ext_memory & 2) >> 1; + value += (access_to_ext_memory & 4) >> 2; + + if (value > 1) + dsp_core.instr_cycle += (value - 1) * 2; + } + /* Disasm current instruction ? (trace mode only) */ if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM)) { /* Display only when DSP is called in trace mode */ if (isDsp_in_disasm_mode == false) { if (disasm_return != 0) { - fprintf(stderr, "%s", dsp56k_getInstructionText()); - + fprintf(TraceFile, "%s", dsp56k_getInstructionText()); + /* DSP regs trace enabled only if DSP DISASM is enabled */ if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM_REG)) - dsp56k_disasm_reg_compare(); + dsp56k_disasm_reg_compare(TraceFile); if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM_MEM)) { /* 1 memory change to display ? */ if (disasm_memory_ptr == 1) - fprintf(stderr, "\t%s\n", str_disasm_memory[0]); + fprintf(TraceFile, "\t%s\n", str_disasm_memory[0]); /* 2 memory changes to display ? */ else if (disasm_memory_ptr == 2) { - fprintf(stderr, "\t%s\n", str_disasm_memory[0]); - fprintf(stderr, "\t%s\n", str_disasm_memory[1]); + fprintf(TraceFile, "\t%s\n", str_disasm_memory[0]); + fprintf(TraceFile, "\t%s\n", str_disasm_memory[1]); } } } @@ -835,7 +862,7 @@ static void dsp_postexecute_update_pc(vo { /* When running a REP, PC must stay on the current instruction */ if (dsp_core.loop_rep) { - /* Is PC on the instruction to repeat ? */ + /* Is PC on the instruction to repeat ? */ if (dsp_core.pc_on_rep==0) { --dsp_core.registers[DSP_REG_LC]; dsp_core.registers[DSP_REG_LC] &= BITMASK(16); @@ -863,20 +890,19 @@ static void dsp_postexecute_update_pc(vo if (dsp_core.registers[DSP_REG_SR] & (1<>23)) & 3; - if (value_u == 0 || value_u == 3) + if (value_u == 0 || value_u == 3) dsp_core.registers[DSP_REG_SR] |= 1 << DSP_SR_U; break; case 2: @@ -1119,7 +1147,7 @@ static void dsp_ccr_update_e_u_n_z(Uint3 dsp_core.registers[DSP_REG_SR] |= 1 << DSP_SR_E; /* Unnormalized bit (U) */ - if ((reg1 & 0x600000) == 0 || (reg1 & 0x600000) == 0x600000) + if ((reg1 & 0x600000) == 0 || (reg1 & 0x600000) == 0x600000) dsp_core.registers[DSP_REG_SR] |= 1 << DSP_SR_U; break; default: @@ -1184,8 +1212,8 @@ static inline Uint32 read_memory_p(Uint1 return dsp_core.ramint[DSP_SPACE_P][address] & BITMASK(24); } - /* Access to the external memory */ - nb_access_to_extMemory ++; + /* Access to the external P memory */ + access_to_ext_memory |= 1 << EXT_P_MEMORY; /* External RAM, mask address to available ram size */ return dsp_core.ramext[address & (DSP_RAMSIZE-1)] & BITMASK(24); @@ -1218,7 +1246,7 @@ static Uint32 read_memory(int space, Uin if (address == 0xffc0+DSP_HOST_HRX) { value = dsp_core.dsp_host_rtx; dsp_core_hostport_dspread(); - } + } else if (address == 0xffc0+DSP_SSI_RX) { value = dsp_core_ssi_readRX(); } @@ -1226,25 +1254,31 @@ static Uint32 read_memory(int space, Uin return value; } - /* Access to the external memory */ - nb_access_to_extMemory ++; - - /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ + /* Falcon: External X or Y RAM access */ address &= (DSP_RAMSIZE>>1) - 1; if (space == DSP_SPACE_X) { + /* Map X to upper 16K of matching space in Y,P */ address += DSP_RAMSIZE>>1; + + /* Set one access to the X external memory */ + access_to_ext_memory |= 1 << EXT_X_MEMORY; + } + else { + /* Access to the Y external memory */ + access_to_ext_memory |= 1 << EXT_Y_MEMORY; } + /* Falcon: External RAM, finally map X,Y to P */ return dsp_core.ramext[address & (DSP_RAMSIZE-1)] & BITMASK(24); } static inline void write_memory(int space, Uint16 address, Uint32 value) { - if (unlikely(LOG_TRACE_LEVEL(TRACE_DSP_DISASM_MEM))) + if (LOG_TRACE_LEVEL(TRACE_DSP_DISASM_MEM)) write_memory_disasm(space, address, value); - else + else write_memory_raw(space, address, value); } @@ -1261,7 +1295,7 @@ static void write_memory_raw(int space, dsp_core_hostport_dspwrite(); break; case DSP_HOST_HCR: - dsp_core.periph[DSP_SPACE_X][DSP_HOST_HCR] = value; + dsp_core.periph[DSP_SPACE_X][DSP_HOST_HCR] = value & 0x1f; /* Set HF3 and HF2 accordingly on the host side */ dsp_core.hostport[CPU_HOST_ISR] &= BITMASK(8)-((1<>1) - 1; - } - if (space == DSP_SPACE_X) { - address += DSP_RAMSIZE>>1; + if (space == DSP_SPACE_X) { + /* Access to the X external RAM */ + /* map X to upper 16K of matching space in Y,P */ + address += DSP_RAMSIZE>>1; + access_to_ext_memory |= 1; + } + else { + /* Access to the Y external RAM */ + access_to_ext_memory |= 1 << EXT_Y_MEMORY; + } } /* Falcon: External RAM, map X,Y to P */ @@ -1372,14 +1415,40 @@ static void dsp_write_reg(Uint32 numreg, switch (numreg) { case DSP_REG_A: dsp_core.registers[DSP_REG_A0] = 0; - dsp_core.registers[DSP_REG_A1] = value; + dsp_core.registers[DSP_REG_A1] = value & BITMASK(24); dsp_core.registers[DSP_REG_A2] = value & (1<<23) ? 0xff : 0x0; break; case DSP_REG_B: dsp_core.registers[DSP_REG_B0] = 0; - dsp_core.registers[DSP_REG_B1] = value; + dsp_core.registers[DSP_REG_B1] = value & BITMASK(24); dsp_core.registers[DSP_REG_B2] = value & (1<<23) ? 0xff : 0x0; break; + case DSP_REG_R0: + case DSP_REG_R1: + case DSP_REG_R2: + case DSP_REG_R3: + case DSP_REG_R4: + case DSP_REG_R5: + case DSP_REG_R6: + case DSP_REG_R7: + case DSP_REG_N0: + case DSP_REG_N1: + case DSP_REG_N2: + case DSP_REG_N3: + case DSP_REG_N4: + case DSP_REG_N5: + case DSP_REG_N6: + case DSP_REG_N7: + case DSP_REG_M0: + case DSP_REG_M1: + case DSP_REG_M2: + case DSP_REG_M3: + case DSP_REG_M4: + case DSP_REG_M5: + case DSP_REG_M6: + case DSP_REG_M7: + dsp_core.registers[numreg] = value & BITMASK(16); + break; case DSP_REG_OMR: dsp_core.registers[DSP_REG_OMR] = value & 0xc7; break; @@ -1391,12 +1460,14 @@ static void dsp_write_reg(Uint32 numreg, if ((stack_error==0) && (value & (3<modulo) { - while (modifier>bufsize) { - r_reg += bufsize; - modifier -= bufsize; - } - while (modifier<-bufsize) { - r_reg -= bufsize; - modifier += bufsize; - } + if (modifier<0) { + abs_modifier = -modifier; + } else { + abs_modifier = modifier; } - r_reg += modifier; - if (orig_modifier!=modulo) { + if (abs_modifier>modulo) { + if (abs_modifier&bufmask) { + fprintf(stderr,"Dsp: Modulo addressing result unpredictable\n"); + } else { + r_reg += modifier; + } + } else { + r_reg += modifier; + + if (r_reg>hibound) { r_reg -= modulo; } else if (r_reg> DSP_SR_N) & 1; value2 = (dsp_core.registers[DSP_REG_SR] >> DSP_SR_V) & 1; value3 = (dsp_core.registers[DSP_REG_SR] >> DSP_SR_Z) & 1; @@ -1764,6 +1844,9 @@ static void opcode8h_0(void) case 0x00008c: dsp_enddo(); break; + default: + dsp_undefined(); + break; } } @@ -1775,14 +1858,34 @@ static void dsp_undefined(void) { if (isDsp_in_disasm_mode == false) { cur_inst_len = 0; - fprintf(stderr, "Dsp: 0x%04x: 0x%06x Illegal instruction\n",dsp_core.pc, cur_inst); /* Add some artificial CPU cycles to avoid being stuck in an infinite loop */ dsp_core.instr_cycle += 100; - } - else { + + /* Rate limit identical messages. Required to make + * "Terrorize your soul" demo run at usable speed + */ + dsp_error.count++; + if (cur_inst != dsp_error.inst || dsp_core.pc != dsp_error.pc || + dsp_error.count >= dsp_error.limit) { + dsp_error.inst = cur_inst; + dsp_error.pc = dsp_core.pc; + fprintf(stderr, "Dsp: 0x%04hx: 0x%06x Illegal instruction (%dx times)\n", + dsp_error.pc, dsp_error.inst, dsp_error.count); + if (dsp_error.count >= dsp_error.limit) { + /* next message after 2x more hits */ + dsp_error.limit *= 2; + } else { + dsp_error.limit = 1; + } + dsp_error.count = 0; + } + } else { cur_inst_len = 1; dsp_core.instr_cycle = 0; } + if (ExceptionDebugMask & EXCEPT_DSP) { + DebugUI(REASON_DSP_EXCEPTION); + } } static void dsp_andi(void) @@ -1810,7 +1913,7 @@ static void dsp_andi(void) static void dsp_bchg_aa(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1835,7 +1938,7 @@ static void dsp_bchg_aa(void) static void dsp_bchg_ea(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1860,7 +1963,7 @@ static void dsp_bchg_ea(void) static void dsp_bchg_pp(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1885,7 +1988,7 @@ static void dsp_bchg_pp(void) static void dsp_bchg_reg(void) { Uint32 value, numreg, newcarry, numbit; - + numreg = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1914,7 +2017,7 @@ static void dsp_bchg_reg(void) static void dsp_bclr_aa(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; addr = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1934,7 +2037,7 @@ static void dsp_bclr_aa(void) static void dsp_bclr_ea(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1955,7 +2058,7 @@ static void dsp_bclr_ea(void) static void dsp_bclr_pp(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -1976,7 +2079,7 @@ static void dsp_bclr_pp(void) static void dsp_bclr_reg(void) { Uint32 value, numreg, newcarry, numbit; - + numreg = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2001,7 +2104,7 @@ static void dsp_bclr_reg(void) static void dsp_bset_aa(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2022,7 +2125,7 @@ static void dsp_bset_aa(void) static void dsp_bset_ea(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2043,7 +2146,7 @@ static void dsp_bset_ea(void) static void dsp_bset_pp(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2063,7 +2166,7 @@ static void dsp_bset_pp(void) static void dsp_bset_reg(void) { Uint32 value, numreg, newcarry, numbit; - + numreg = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2088,7 +2191,7 @@ static void dsp_bset_reg(void) static void dsp_btst_aa(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2107,7 +2210,7 @@ static void dsp_btst_aa(void) static void dsp_btst_ea(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2126,7 +2229,7 @@ static void dsp_btst_ea(void) static void dsp_btst_pp(void) { Uint32 memspace, addr, value, newcarry, numbit; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2145,7 +2248,7 @@ static void dsp_btst_pp(void) static void dsp_btst_reg(void) { Uint32 value, numreg, newcarry, numbit; - + numreg = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2214,7 +2317,7 @@ static void dsp_div(void) dsp_core.registers[DSP_REG_B1] = dest[1]; dsp_core.registers[DSP_REG_B0] = dest[2]; } - + dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>7) & 1))<>8) & BITMASK(6); if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &dsp_core.registers[DSP_REG_LC]); + dsp_pm_read_accu24(numreg, &dsp_core.registers[DSP_REG_LC]); } else { dsp_core.registers[DSP_REG_LC] = dsp_core.registers[numreg]; } @@ -2325,6 +2428,9 @@ static void dsp_illegal(void) { /* Raise interrupt p:0x003e */ dsp_add_interrupt(DSP_INTER_ILLEGAL); + if (ExceptionDebugMask & EXCEPT_DSP) { + DebugUI(REASON_DSP_EXCEPTION); + } } static void dsp_jcc_imm(void) @@ -2359,7 +2465,7 @@ static void dsp_jcc_ea(void) static void dsp_jclr_aa(void) { Uint32 memspace, addr, value, numbit, newaddr; - + memspace = (cur_inst>>6) & 1; addr = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2372,19 +2478,19 @@ static void dsp_jclr_aa(void) dsp_core.pc = newaddr; cur_inst_len = 0; return; - } + } ++cur_inst_len; } static void dsp_jclr_ea(void) { Uint32 memspace, addr, value, numbit, newaddr; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); newaddr = read_memory_p(dsp_core.pc+1); - + dsp_calc_ea(value, &addr); value = read_memory(memspace, addr); @@ -2394,14 +2500,14 @@ static void dsp_jclr_ea(void) dsp_core.pc = newaddr; cur_inst_len = 0; return; - } + } ++cur_inst_len; } static void dsp_jclr_pp(void) { Uint32 memspace, addr, value, numbit, newaddr; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2415,14 +2521,14 @@ static void dsp_jclr_pp(void) dsp_core.pc = newaddr; cur_inst_len = 0; return; - } + } ++cur_inst_len; } static void dsp_jclr_reg(void) { Uint32 value, numreg, numbit, newaddr; - + numreg = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); newaddr = read_memory_p(dsp_core.pc+1); @@ -2439,7 +2545,7 @@ static void dsp_jclr_reg(void) dsp_core.pc = newaddr; cur_inst_len = 0; return; - } + } ++cur_inst_len; } @@ -2476,7 +2582,7 @@ static void dsp_jscc_ea(void) dsp_stack_push(dsp_core.pc+cur_inst_len, dsp_core.registers[DSP_REG_SR], 0); dsp_core.pc = newpc; cur_inst_len = 0; - } + } dsp_core.instr_cycle += 2; } @@ -2491,7 +2597,7 @@ static void dsp_jscc_imm(void) dsp_stack_push(dsp_core.pc+cur_inst_len, dsp_core.registers[DSP_REG_SR], 0); dsp_core.pc = newpc; cur_inst_len = 0; - } + } dsp_core.instr_cycle += 2; } @@ -2499,29 +2605,29 @@ static void dsp_jscc_imm(void) static void dsp_jsclr_aa(void) { Uint32 memspace, addr, value, newpc, numbit, newaddr; - + memspace = (cur_inst>>6) & 1; addr = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); value = read_memory(memspace, addr); newaddr = read_memory_p(dsp_core.pc+1); - + dsp_core.instr_cycle += 4; - + if ((value & (1<>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2530,21 +2636,21 @@ static void dsp_jsclr_ea(void) newaddr = read_memory_p(dsp_core.pc+1); dsp_core.instr_cycle += 4; - + if ((value & (1<>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2553,21 +2659,21 @@ static void dsp_jsclr_pp(void) newaddr = read_memory_p(dsp_core.pc+1); dsp_core.instr_cycle += 4; - + if ((value & (1<>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); newaddr = read_memory_p(dsp_core.pc+1); @@ -2579,21 +2685,21 @@ static void dsp_jsclr_reg(void) } dsp_core.instr_cycle += 4; - + if ((value & (1<>6) & 1; addr = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2601,20 +2707,20 @@ static void dsp_jset_aa(void) newaddr = read_memory_p(dsp_core.pc+1); dsp_core.instr_cycle += 4; - + if (value & (1<>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2629,14 +2735,14 @@ static void dsp_jset_ea(void) dsp_core.pc = newpc; cur_inst_len=0; return; - } + } ++cur_inst_len; } static void dsp_jset_pp(void) { Uint32 memspace, addr, value, numbit, newpc, newaddr; - + memspace = (cur_inst>>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2645,24 +2751,24 @@ static void dsp_jset_pp(void) newaddr = read_memory_p(dsp_core.pc+1); dsp_core.instr_cycle += 4; - + if (value & (1<>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); newaddr = read_memory_p(dsp_core.pc+1); - + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { dsp_pm_read_accu24(numreg, &value); } else { @@ -2670,13 +2776,13 @@ static void dsp_jset_reg(void) } dsp_core.instr_cycle += 4; - + if (value & (1<>6) & 1; addr = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); value = read_memory(memspace, addr); newaddr = read_memory_p(dsp_core.pc+1); - + dsp_core.instr_cycle += 4; if (value & (1<>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); dsp_calc_ea(value, &addr); value = read_memory(memspace, addr); newaddr = read_memory_p(dsp_core.pc+1); - + dsp_core.instr_cycle += 4; if (value & (1<>6) & 1; value = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); @@ -2782,18 +2888,18 @@ static void dsp_jsset_pp(void) dsp_core.pc = newpc; cur_inst_len = 0; return; - } + } ++cur_inst_len; } static void dsp_jsset_reg(void) { Uint32 value, numreg, newpc, numbit, newaddr; - + numreg = (cur_inst>>8) & BITMASK(6); numbit = cur_inst & BITMASK(5); newaddr = read_memory_p(dsp_core.pc+1); - + if ((numreg==DSP_REG_A) || (numreg==DSP_REG_B)) { dsp_pm_read_accu24(numreg, &value); } else { @@ -2808,7 +2914,7 @@ static void dsp_jsset_reg(void) dsp_core.pc = newpc; cur_inst_len = 0; return; - } + } ++cur_inst_len; } @@ -2823,14 +2929,13 @@ static void dsp_lua(void) srcnew = dsp_core.registers[DSP_REG_R0+srcreg]; dsp_core.registers[DSP_REG_R0+srcreg] = srcsave; - dstreg = cur_inst & BITMASK(3); - - if (cur_inst & (1<<3)) { - dsp_core.registers[DSP_REG_N0+dstreg] = srcnew; - } else { - dsp_core.registers[DSP_REG_R0+dstreg] = srcnew; - } + if (cur_inst & (1<<3)) + dstreg = DSP_REG_N0 + (cur_inst & BITMASK(3)); + else + dstreg = DSP_REG_R0 + (cur_inst & BITMASK(3)); + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(dstreg, srcnew); dsp_core.instr_cycle += 2; } @@ -2844,38 +2949,27 @@ static void dsp_movec_reg(void) numreg2 = (cur_inst>>8) & BITMASK(6); numreg1 = cur_inst & BITMASK(6); + dsp_core.agu_move_indirect_instr = 1; + if (cur_inst & (1<<15)) { /* Write D1 */ if ((numreg2 == DSP_REG_A) || (numreg2 == DSP_REG_B)) { - dsp_pm_read_accu24(numreg2, &value); + dsp_pm_read_accu24(numreg2, &value); } else { value = dsp_core.registers[numreg2]; } - value &= BITMASK(registers_mask[numreg1]); dsp_write_reg(numreg1, value); } else { /* Read S1 */ if (numreg1 == DSP_REG_SSH) { dsp_stack_pop(&value, &dummy); - } + } else { value = dsp_core.registers[numreg1]; } - if (numreg2 == DSP_REG_A) { - dsp_core.registers[DSP_REG_A0] = 0; - dsp_core.registers[DSP_REG_A1] = value & BITMASK(24); - dsp_core.registers[DSP_REG_A2] = value & (1<<23) ? 0xff : 0x0; - } - else if (numreg2 == DSP_REG_B) { - dsp_core.registers[DSP_REG_B0] = 0; - dsp_core.registers[DSP_REG_B1] = value & BITMASK(24); - dsp_core.registers[DSP_REG_B2] = value & (1<<23) ? 0xff : 0x0; - } - else { - dsp_core.registers[numreg2] = value & BITMASK(registers_mask[numreg2]); - } + dsp_write_reg(numreg2, value); } } @@ -2895,13 +2989,13 @@ static void dsp_movec_aa(void) if (cur_inst & (1<<15)) { /* Write D1 */ value = read_memory(memspace, addr); - value &= BITMASK(registers_mask[numreg]); + dsp_core.agu_move_indirect_instr = 1; dsp_write_reg(numreg, value); } else { /* Read S1 */ if (numreg == DSP_REG_SSH) { dsp_stack_pop(&value, &dummy); - } + } else { value = dsp_core.registers[numreg]; } @@ -2916,7 +3010,7 @@ static void dsp_movec_imm(void) /* #xx,D1 */ numreg = cur_inst & BITMASK(6); value = (cur_inst>>8) & BITMASK(8); - value &= BITMASK(registers_mask[numreg]); + dsp_core.agu_move_indirect_instr = 1; dsp_write_reg(numreg, value); } @@ -2943,14 +3037,14 @@ static void dsp_movec_ea(void) } else { value = read_memory(memspace, addr); } - value &= BITMASK(registers_mask[numreg]); + dsp_core.agu_move_indirect_instr = 1; dsp_write_reg(numreg, value); } else { /* Read S1 */ dsp_calc_ea(ea_mode, &addr); if (numreg == DSP_REG_SSH) { dsp_stack_pop(&value, &dummy); - } + } else { value = dsp_core.registers[numreg]; } @@ -2968,16 +3062,16 @@ static void dsp_movem_aa(void) if (cur_inst & (1<<15)) { /* Write D */ value = read_memory_p(addr); - value &= BITMASK(registers_mask[numreg]); + dsp_core.agu_move_indirect_instr = 1; dsp_write_reg(numreg, value); } else { /* Read S */ if (numreg == DSP_REG_SSH) { dsp_stack_pop(&value, &dummy); - } + } else if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &value); - } + dsp_pm_read_accu24(numreg, &value); + } else { value = dsp_core.registers[numreg]; } @@ -2998,16 +3092,16 @@ static void dsp_movem_ea(void) if (cur_inst & (1<<15)) { /* Write D */ value = read_memory_p(addr); - value &= BITMASK(registers_mask[numreg]); + dsp_core.agu_move_indirect_instr = 1; dsp_write_reg(numreg, value); } else { /* Read S */ if (numreg == DSP_REG_SSH) { dsp_stack_pop(&value, &dummy); - } + } else if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &value); - } + dsp_pm_read_accu24(numreg, &value); + } else { value = dsp_core.registers[numreg]; } @@ -3023,7 +3117,7 @@ static void dsp_movep_0(void) /* x:pp,D */ /* S,y:pp */ /* y:pp,D */ - + Uint32 addr, memspace, numreg, value, dummy; addr = 0xffc0 + (cur_inst & BITMASK(6)); @@ -3033,7 +3127,7 @@ static void dsp_movep_0(void) if (cur_inst & (1<<15)) { /* Write pp */ if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &value); + dsp_pm_read_accu24(numreg, &value); } else if (numreg == DSP_REG_SSH) { dsp_stack_pop(&value, &dummy); @@ -3045,7 +3139,7 @@ static void dsp_movep_0(void) } else { /* Read pp */ value = read_memory(memspace, addr); - value &= BITMASK(registers_mask[numreg]); + dsp_core.agu_move_indirect_instr = 1; dsp_write_reg(numreg, value); } @@ -3097,14 +3191,14 @@ static void dsp_movep_23(void) peraddr = 0xffc0 + (cur_inst & BITMASK(6)); perspace = (cur_inst>>16) & 1; - + ea_mode = (cur_inst>>8) & BITMASK(6); easpace = (cur_inst>>6) & 1; retour = dsp_calc_ea(ea_mode, &addr); if (cur_inst & (1<<15)) { /* Write pp */ - + if (retour) { write_memory(perspace, peraddr, addr); } else { @@ -3245,7 +3339,7 @@ static void dsp_rep_reg(void) numreg = (cur_inst>>8) & BITMASK(6); if ((numreg == DSP_REG_A) || (numreg == DSP_REG_B)) { - dsp_pm_read_accu24(numreg, &dsp_core.registers[DSP_REG_LC]); + dsp_pm_read_accu24(numreg, &dsp_core.registers[DSP_REG_LC]); } else { dsp_core.registers[DSP_REG_LC] = dsp_core.registers[numreg]; } @@ -3256,7 +3350,44 @@ static void dsp_rep_reg(void) static void dsp_reset(void) { - /* Reset external peripherals */ + /* Clear the IPR register */ + write_memory(DSP_SPACE_X, 0xffc0 + DSP_IPR, 0); + + /* Software reset all on-chip peripherals */ + + /* HOST_HCR x:$FFE8 : clear the full register */ + write_memory(DSP_SPACE_X, 0xffc0 + DSP_HOST_HCR, 0); + + /* HOST_ICR $0 : clear the full register */ + dsp_core_write_host(CPU_HOST_ICR, 0); + + /* HOST_CVR $1 : set the register to $12 */ + dsp_core_write_host(CPU_HOST_CVR, 0x12); + + /* HOST_ISR $2 : set the bits TRDY and TXDE 1, other bits to 0 */ + dsp_core.hostport[CPU_HOST_ISR] = (1<>12) & BITMASK(4); if (dsp_calc_cc(cc_code)) { @@ -3322,7 +3453,7 @@ static void dsp_tcc(void) val1 = dsp_core.registers[regsrc1]; val2 = val1 & (1<<23) ? 0xff : 0x0; } - + /* Write D1 */ if (regdest1 == DSP_REG_A) { dsp_core.registers[DSP_REG_A2] = val2; @@ -3340,7 +3471,8 @@ static void dsp_tcc(void) regsrc2 = DSP_REG_R0+((cur_inst>>8) & BITMASK(3)); regdest2 = DSP_REG_R0+(cur_inst & BITMASK(3)); - dsp_core.registers[regdest2] = dsp_core.registers[regsrc2]; + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(regdest2, dsp_core.registers[regsrc2]); } } } @@ -3377,7 +3509,7 @@ static int dsp_pm_read_accu24(int numreg value |= (dsp_core.registers[DSP_REG_A0+reg]>>23) & 1; break; /* indeterminate */ - case 3: + case 3: break; } @@ -3389,7 +3521,7 @@ static int dsp_pm_read_accu24(int numreg /* No limiting */ *dest=value; return 0; - } + } } if (dsp_core.registers[DSP_REG_A2+reg] == 0xff) { @@ -3397,7 +3529,7 @@ static int dsp_pm_read_accu24(int numreg /* No limiting */ *dest=value; return 0; - } + } } if (dsp_core.registers[DSP_REG_A2+reg] & (1<<7)) { @@ -3410,7 +3542,7 @@ static int dsp_pm_read_accu24(int numreg *dest=0x007fffff; dsp_core.registers[DSP_REG_SR] |= (1<>16) & 1; dsp_calc_ea((cur_inst>>8) & BITMASK(6), &addr); - /* Save A or B */ + /* Save A or B */ dsp_pm_read_accu24(numreg, &save_accu); /* Save X0 or Y0 */ @@ -3435,7 +3567,7 @@ static void dsp_pm_0(void) /* Execute parallel instruction */ opcodes_alu[cur_inst & BITMASK(8)](); - /* Move [A|B] to [x|y]:ea */ + /* Move [A|B] to [x|y]:ea */ write_memory(memspace, addr, save_accu); /* Move [x|y]0 to [A|B] */ @@ -3448,15 +3580,15 @@ static void dsp_pm_1(void) { Uint32 memspace, numreg1, numreg2, value, xy_addr, retour, save_1, save_2; /* - 0001 ffdf w0mm mrrr x:ea,D1 S2,D2 + 0001 ffdf w0mm mrrr x:ea,D1 S2,D2 S1,x:ea S2,D2 #xxxxxx,D1 S2,D2 - 0001 deff w1mm mrrr S1,D1 y:ea,D2 + 0001 deff w1mm mrrr S1,D1 y:ea,D2 S1,D1 S2,y:ea S1,D1 #xxxxxx,D2 */ value = (cur_inst>>8) & BITMASK(6); - retour = dsp_calc_ea(value, &xy_addr); + retour = dsp_calc_ea(value, &xy_addr); memspace = (cur_inst>>14) & 1; numreg1 = numreg2 = DSP_REG_NULL; @@ -3491,7 +3623,7 @@ static void dsp_pm_1(void) else save_1 = dsp_core.registers[numreg1]; } - + /* S2 */ if (memspace) { /* Y: */ @@ -3499,9 +3631,9 @@ static void dsp_pm_1(void) } else { /* X: */ numreg2 = DSP_REG_A + ((cur_inst>>17) & 1); - } + } dsp_pm_read_accu24(numreg2, &save_2); - + /* Execute parallel instruction */ opcodes_alu[cur_inst & BITMASK(8)](); @@ -3510,18 +3642,7 @@ static void dsp_pm_1(void) /* Write parallel move values */ if (cur_inst & (1<<15)) { /* Write D1 */ - if (numreg1 == DSP_REG_A) { - dsp_core.registers[DSP_REG_A0] = 0x0; - dsp_core.registers[DSP_REG_A1] = save_1; - dsp_core.registers[DSP_REG_A2] = save_1 & (1<<23) ? 0xff : 0x0; - } - else if (numreg1 == DSP_REG_B) { - dsp_core.registers[DSP_REG_B0] = 0x0; - dsp_core.registers[DSP_REG_B1] = save_1; - dsp_core.registers[DSP_REG_B2] = save_1 & (1<<23) ? 0xff : 0x0; - } - else { - } dsp_core.registers[numreg1] = save_1; + dsp_write_reg(numreg1, save_1); } else { /* Read S1 */ write_memory(memspace, xy_addr, save_1); @@ -3534,7 +3655,7 @@ static void dsp_pm_1(void) } else { /* X: */ numreg2 = DSP_REG_Y0 + ((cur_inst>>16) & 1); - } + } dsp_core.registers[numreg2] = save_2; } @@ -3574,7 +3695,7 @@ static void dsp_pm_2_2(void) 0010 00ee eeed dddd S,D */ Uint32 srcreg, dstreg, save_reg; - + srcreg = (cur_inst >> 13) & BITMASK(5); dstreg = (cur_inst >> 8) & BITMASK(5); @@ -3588,19 +3709,8 @@ static void dsp_pm_2_2(void) opcodes_alu[cur_inst & BITMASK(8)](); /* Write reg */ - if (dstreg == DSP_REG_A) { - dsp_core.registers[DSP_REG_A0] = 0x0; - dsp_core.registers[DSP_REG_A1] = save_reg; - dsp_core.registers[DSP_REG_A2] = save_reg & (1<<23) ? 0xff : 0x0; - } - else if (dstreg == DSP_REG_B) { - dsp_core.registers[DSP_REG_B0] = 0x0; - dsp_core.registers[DSP_REG_B1] = save_reg; - dsp_core.registers[DSP_REG_B2] = save_reg & (1<<23) ? 0xff : 0x0; - } - else { - dsp_core.registers[dstreg] = save_reg & BITMASK(registers_mask[dstreg]); - } + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(dstreg, save_reg); } static void dsp_pm_3(void) @@ -3628,19 +3738,8 @@ static void dsp_pm_3(void) break; } - if (dstreg == DSP_REG_A) { - dsp_core.registers[DSP_REG_A0] = 0x0; - dsp_core.registers[DSP_REG_A1] = srcvalue; - dsp_core.registers[DSP_REG_A2] = srcvalue & (1<<23) ? 0xff : 0x0; - } - else if (dstreg == DSP_REG_B) { - dsp_core.registers[DSP_REG_B0] = 0x0; - dsp_core.registers[DSP_REG_B1] = srcvalue; - dsp_core.registers[DSP_REG_B2] = srcvalue & (1<<23) ? 0xff : 0x0; - } - else { - dsp_core.registers[dstreg] = srcvalue & BITMASK(registers_mask[dstreg]); - } + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(dstreg, srcvalue); } static void dsp_pm_4(void) @@ -3680,7 +3779,7 @@ static void dsp_pm_4x(void) */ value = (cur_inst>>8) & BITMASK(6); if (cur_inst & (1<<14)) { - dsp_calc_ea(value, &l_addr); + dsp_calc_ea(value, &l_addr); } else { l_addr = value; } @@ -3688,11 +3787,6 @@ static void dsp_pm_4x(void) numreg = (cur_inst>>16) & BITMASK(2); numreg |= (cur_inst>>17) & (1<<2); - /* 2 more cycles are needed if address is in external memory */ - if (l_addr>=0x200) { - dsp_core.instr_cycle += 2; - } - if (cur_inst & (1<<15)) { /* Write D */ save_lx = read_memory(DSP_SPACE_X,l_addr); @@ -3743,13 +3837,13 @@ static void dsp_pm_4x(void) break; case 6: /* AB */ - dsp_pm_read_accu24(DSP_REG_A, &save_lx); - dsp_pm_read_accu24(DSP_REG_B, &save_ly); + dsp_pm_read_accu24(DSP_REG_A, &save_lx); + dsp_pm_read_accu24(DSP_REG_B, &save_ly); break; case 7: /* BA */ - dsp_pm_read_accu24(DSP_REG_B, &save_lx); - dsp_pm_read_accu24(DSP_REG_A, &save_ly); + dsp_pm_read_accu24(DSP_REG_B, &save_lx); + dsp_pm_read_accu24(DSP_REG_A, &save_ly); break; } } @@ -3831,7 +3925,7 @@ static void dsp_pm_5(void) value = (cur_inst>>8) & BITMASK(6); if (cur_inst & (1<<14)) { - retour = dsp_calc_ea(value, &xy_addr); + retour = dsp_calc_ea(value, &xy_addr); } else { xy_addr = value; retour = 0; @@ -3862,19 +3956,8 @@ static void dsp_pm_5(void) if (cur_inst & (1<<15)) { /* Write D */ - if (numreg == DSP_REG_A) { - dsp_core.registers[DSP_REG_A0] = 0x0; - dsp_core.registers[DSP_REG_A1] = value; - dsp_core.registers[DSP_REG_A2] = value & (1<<23) ? 0xff : 0x0; - } - else if (numreg == DSP_REG_B) { - dsp_core.registers[DSP_REG_B0] = 0x0; - dsp_core.registers[DSP_REG_B1] = value; - dsp_core.registers[DSP_REG_B2] = value & (1<<23) ? 0xff : 0x0; - } - else { - dsp_core.registers[numreg] = value & BITMASK(registers_mask[numreg]); - } + dsp_core.agu_move_indirect_instr = 1; + dsp_write_reg(numreg, value); } else { /* Read S */ @@ -3888,7 +3971,7 @@ static void dsp_pm_8(void) Uint32 numreg1, numreg2; Uint32 save_reg1, save_reg2, x_addr, y_addr; /* - 1wmm eeff WrrM MRRR x:ea,D1 y:ea,D2 + 1wmm eeff WrrM MRRR x:ea,D1 y:ea,D2 x:ea,D1 S2,y:ea S1,x:ea y:ea,D2 S1,x:ea S2,y:ea @@ -3911,11 +3994,6 @@ static void dsp_pm_8(void) dsp_calc_ea(ea1, &x_addr); dsp_calc_ea(ea2, &y_addr); - /* 2 more cycles are needed if X:address1 and Y:address2 are both in external memory */ - if ((x_addr>=0x200) && (y_addr>=0x200)) { - dsp_core.instr_cycle += 2; - } - switch((cur_inst>>18) & BITMASK(2)) { case 0: numreg1=DSP_REG_X0; break; case 1: numreg1=DSP_REG_X1; break; @@ -3928,7 +4006,7 @@ static void dsp_pm_8(void) case 2: numreg2=DSP_REG_A; break; case 3: numreg2=DSP_REG_B; break; } - + if (cur_inst & (1<<15)) { /* Write D1 */ save_reg1 = read_memory(DSP_SPACE_X, x_addr); @@ -4043,7 +4121,7 @@ static Uint16 dsp_asl56(Uint32 *dest) dest[1] <<= 1; dest[1] |= (dest[2]>>23) & 1; dest[1] &= BITMASK(24); - + dest[2] <<= 1; dest[2] &= BITMASK(24); @@ -4104,7 +4182,7 @@ static Uint16 dsp_sub56(Uint32 *source, dest_save = dest[0]; - /* Substract source from dest: D = D-S */ + /* Subtract source from dest: D = D-S */ dest[2] -= source[2]; dest[1] -= source[1]+((dest[2]>>24) & 1); dest[0] -= source[0]+((dest[1]>>24) & 1); @@ -4210,7 +4288,7 @@ static void dsp_rnd56(Uint32 *dest) rnd_const[1] = 0; rnd_const[2] = (1<<22); dsp_add56(rnd_const, dest); - + if ((dest[2] & 0x7fffff) == 0){ dest[2] = 0; } @@ -4293,7 +4371,7 @@ static void dsp_adc_x_a(void) source[0] = source[1] & (1<<23) ? 0xff : 0x0; newsr = dsp_add56(source, dest); - + if (curcarry) { source[0]=0; source[1]=0; source[2]=1; newsr |= dsp_add56(source, dest); @@ -4325,7 +4403,7 @@ static void dsp_adc_x_b(void) source[0] = source[1] & (1<<23) ? 0xff : 0x0; newsr = dsp_add56(source, dest); - + if (curcarry) { source[0]=0; source[1]=0; source[2]=1; newsr |= dsp_add56(source, dest); @@ -4357,7 +4435,7 @@ static void dsp_adc_y_a(void) source[0] = source[1] & (1<<23) ? 0xff : 0x0; newsr = dsp_add56(source, dest); - + if (curcarry) { source[0]=0; source[1]=0; source[2]=1; newsr |= dsp_add56(source, dest); @@ -4389,7 +4467,7 @@ static void dsp_adc_y_b(void) source[0] = source[1] & (1<<23) ? 0xff : 0x0; newsr = dsp_add56(source, dest); - + if (curcarry) { source[0]=0; source[1]=0; source[2]=1; newsr |= dsp_add56(source, dest); @@ -6927,13 +7005,13 @@ static void dsp_macr_p_x1_y0_b(void) dsp_mul56(dsp_core.registers[DSP_REG_X1], dsp_core.registers[DSP_REG_Y0], source, SIGN_PLUS); - dsp_rnd56(dest); - dest[0] = dsp_core.registers[DSP_REG_B2]; dest[1] = dsp_core.registers[DSP_REG_B1]; dest[2] = dsp_core.registers[DSP_REG_B0]; newsr = dsp_add56(source, dest); + dsp_rnd56(dest); + dsp_core.registers[DSP_REG_B2] = dest[0]; dsp_core.registers[DSP_REG_B1] = dest[1]; dsp_core.registers[DSP_REG_B0] = dest[2]; @@ -8265,7 +8343,7 @@ static void dsp_sbc_x_a(void) source[0] = source[1] & (1<<23) ? 0xff : 0x0; newsr = dsp_sub56(source, dest); - + if (curcarry) { source[0]=0; source[1]=0; source[2]=1; newsr |= dsp_sub56(source, dest); @@ -8297,7 +8375,7 @@ static void dsp_sbc_x_b(void) source[0] = source[1] & (1<<23) ? 0xff : 0x0; newsr = dsp_sub56(source, dest); - + if (curcarry) { source[0]=0; source[1]=0; source[2]=1; newsr |= dsp_sub56(source, dest); @@ -8329,7 +8407,7 @@ static void dsp_sbc_y_a(void) source[0] = source[1] & (1<<23) ? 0xff : 0x0; newsr = dsp_sub56(source, dest); - + if (curcarry) { source[0]=0; source[1]=0; source[2]=1; newsr |= dsp_sub56(source, dest); @@ -8361,7 +8439,7 @@ static void dsp_sbc_y_b(void) source[0] = source[1] & (1<<23) ? 0xff : 0x0; newsr = dsp_sub56(source, dest); - + if (curcarry) { source[0]=0; source[1]=0; source[2]=1; newsr |= dsp_sub56(source, dest); @@ -8785,13 +8863,13 @@ static void dsp_subr_a(void) dest[0] = dsp_core.registers[DSP_REG_A2]; dest[1] = dsp_core.registers[DSP_REG_A1]; dest[2] = dsp_core.registers[DSP_REG_A0]; - + newsr = dsp_asr56(dest); source[0] = dsp_core.registers[DSP_REG_B2]; source[1] = dsp_core.registers[DSP_REG_B1]; source[2] = dsp_core.registers[DSP_REG_B0]; - + newsr |= dsp_sub56(source, dest); dsp_core.registers[DSP_REG_A2] = dest[0]; @@ -8812,13 +8890,13 @@ static void dsp_subr_b(void) dest[0] = dsp_core.registers[DSP_REG_B2]; dest[1] = dsp_core.registers[DSP_REG_B1]; dest[2] = dsp_core.registers[DSP_REG_B0]; - + newsr = dsp_asr56(dest); source[0] = dsp_core.registers[DSP_REG_A2]; source[1] = dsp_core.registers[DSP_REG_A1]; source[2] = dsp_core.registers[DSP_REG_A0]; - + newsr |= dsp_sub56(source, dest); dsp_core.registers[DSP_REG_B2] = dest[0]; @@ -8847,82 +8925,42 @@ static void dsp_tfr_a_b(void) static void dsp_tfr_x0_a(void) { - dsp_core.registers[DSP_REG_A0] = 0; - dsp_core.registers[DSP_REG_A1] = dsp_core.registers[DSP_REG_X0]; - if (dsp_core.registers[DSP_REG_A1] & (1<<23)) - dsp_core.registers[DSP_REG_A2] = 0xff; - else - dsp_core.registers[DSP_REG_A2] = 0x0; + dsp_write_reg(DSP_REG_A, dsp_core.registers[DSP_REG_X0]); } static void dsp_tfr_x0_b(void) { - dsp_core.registers[DSP_REG_B0] = 0; - dsp_core.registers[DSP_REG_B1] = dsp_core.registers[DSP_REG_X0]; - if (dsp_core.registers[DSP_REG_B1] & (1<<23)) - dsp_core.registers[DSP_REG_B2] = 0xff; - else - dsp_core.registers[DSP_REG_B2] = 0x0; + dsp_write_reg(DSP_REG_B, dsp_core.registers[DSP_REG_X0]); } static void dsp_tfr_y0_a(void) { - dsp_core.registers[DSP_REG_A0] = 0; - dsp_core.registers[DSP_REG_A1] = dsp_core.registers[DSP_REG_Y0]; - if (dsp_core.registers[DSP_REG_A1] & (1<<23)) - dsp_core.registers[DSP_REG_A2] = 0xff; - else - dsp_core.registers[DSP_REG_A2] = 0x0; + dsp_write_reg(DSP_REG_A, dsp_core.registers[DSP_REG_Y0]); } static void dsp_tfr_y0_b(void) { - dsp_core.registers[DSP_REG_B0] = 0; - dsp_core.registers[DSP_REG_B1] = dsp_core.registers[DSP_REG_Y0]; - if (dsp_core.registers[DSP_REG_B1] & (1<<23)) - dsp_core.registers[DSP_REG_B2] = 0xff; - else - dsp_core.registers[DSP_REG_B2] = 0x0; + dsp_write_reg(DSP_REG_B, dsp_core.registers[DSP_REG_Y0]); } static void dsp_tfr_x1_a(void) { - dsp_core.registers[DSP_REG_A0] = 0; - dsp_core.registers[DSP_REG_A1] = dsp_core.registers[DSP_REG_X1]; - if (dsp_core.registers[DSP_REG_A1] & (1<<23)) - dsp_core.registers[DSP_REG_A2] = 0xff; - else - dsp_core.registers[DSP_REG_A2] = 0x0; + dsp_write_reg(DSP_REG_A, dsp_core.registers[DSP_REG_X1]); } static void dsp_tfr_x1_b(void) { - dsp_core.registers[DSP_REG_B0] = 0; - dsp_core.registers[DSP_REG_B1] = dsp_core.registers[DSP_REG_X1]; - if (dsp_core.registers[DSP_REG_B1] & (1<<23)) - dsp_core.registers[DSP_REG_B2] = 0xff; - else - dsp_core.registers[DSP_REG_B2] = 0x0; + dsp_write_reg(DSP_REG_B, dsp_core.registers[DSP_REG_X1]); } static void dsp_tfr_y1_a(void) { - dsp_core.registers[DSP_REG_A0] = 0; - dsp_core.registers[DSP_REG_A1] = dsp_core.registers[DSP_REG_Y1]; - if (dsp_core.registers[DSP_REG_A1] & (1<<23)) - dsp_core.registers[DSP_REG_A2] = 0xff; - else - dsp_core.registers[DSP_REG_A2] = 0x0; + dsp_write_reg(DSP_REG_A, dsp_core.registers[DSP_REG_Y1]); } static void dsp_tfr_y1_b(void) { - dsp_core.registers[DSP_REG_B0] = 0; - dsp_core.registers[DSP_REG_B1] = dsp_core.registers[DSP_REG_Y1]; - if (dsp_core.registers[DSP_REG_B1] & (1<<23)) - dsp_core.registers[DSP_REG_B2] = 0xff; - else - dsp_core.registers[DSP_REG_B2] = 0x0; + dsp_write_reg(DSP_REG_B, dsp_core.registers[DSP_REG_Y1]); } static void dsp_tst_a(void)