--- 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:54:36 1.1.1.10 @@ -32,8 +32,9 @@ 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 */ @@ -705,7 +714,7 @@ void dsp56k_init_cpu(void) /** * 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; @@ -729,7 +738,7 @@ Uint16 dsp56k_execute_one_disasm_instruc /* 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)); @@ -747,7 +756,7 @@ 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; /* Decode and execute current instruction */ cur_inst = read_memory_p(dsp_core.pc); @@ -779,9 +788,16 @@ 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 */ @@ -872,7 +888,7 @@ static void dsp_postexecute_update_pc(vo Uint32 saved_pc, saved_sr; dsp_stack_pop(&saved_pc, &saved_sr); - dsp_core.registers[DSP_REG_SR] &= 0x7f; + dsp_core.registers[DSP_REG_SR] &= 0x7fff; dsp_core.registers[DSP_REG_SR] |= saved_sr & (1<>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); } @@ -1323,16 +1345,25 @@ static void write_memory_raw(int space, } } - /* Access to the external memory */ - nb_access_to_extMemory ++; + /* Access to X, Y or P external RAM */ - /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ - if (space != DSP_SPACE_P) { + if (space == DSP_SPACE_P) { + /* Access to the P external RAM */ + access_to_ext_memory |= 1 << EXT_P_MEMORY; + } + else { address &= (DSP_RAMSIZE>>1) - 1; - } - if (space == DSP_SPACE_X) { - address += DSP_RAMSIZE>>1; + if (space == DSP_SPACE_X) { + /* Access to the X external RAM */ + /* map X to upper 16K of matching space in Y,P */ + address += DSP_RAMSIZE>>1; + access_to_ext_memory |= 1; + } + else { + /* Access to the Y external RAM */ + access_to_ext_memory |= 1 << EXT_Y_MEMORY; + } } /* Falcon: External RAM, map X,Y to P */ @@ -1391,9 +1422,11 @@ static void dsp_write_reg(Uint32 numreg, if ((stack_error==0) && (value & (3<>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); @@ -3911,11 +3952,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; @@ -4104,7 +4140,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); @@ -6927,13 +6963,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];