--- hatari/src/falcon/dsp_cpu.c 2019/04/09 08:55:50 1.1.1.11 +++ hatari/src/falcon/dsp_cpu.c 2019/04/09 08:59:33 1.1.1.14 @@ -15,8 +15,8 @@ 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 */ /* @@ -83,6 +83,12 @@ #define DSP_COUNT_IPS 0 /* Count instruction per seconds */ +#if DSP_COUNT_IPS +/* For counting instructions per second */ +#include +static Uint32 start_time; +static Uint32 num_inst; +#endif /********************************** * Defines @@ -103,10 +109,6 @@ * Variables **********************************/ -/* Instructions per second */ -static Uint32 start_time; -static Uint32 num_inst; - /* Length of current instruction */ static Uint32 cur_inst_len; /* =0:jump, >0:increment */ @@ -278,7 +280,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); @@ -698,6 +699,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 @@ -707,8 +715,12 @@ void dsp56k_init_cpu(void) { dsp56k_disasm_init(); isDsp_in_disasm_mode = false; + memset(&dsp_error, 0, sizeof(dsp_error)); + dsp_error.limit = 1; +#if DSP_COUNT_IPS start_time = SDL_GetTicks(); num_inst = 0; +#endif } /** @@ -733,7 +745,7 @@ 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(); @@ -772,7 +784,7 @@ void dsp56k_execute_instruction(void) 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 */ @@ -806,20 +818,20 @@ void dsp56k_execute_instruction(void) /* 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]); } } } @@ -1268,7 +1280,7 @@ static Uint32 read_memory(int space, Uin 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 write_memory_raw(space, address, value); @@ -1287,7 +1299,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<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_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; } @@ -3320,7 +3354,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<>23) & 1; dsp_core.registers[DSP_REG_A1] <<= 1; - dsp_core.registers[DSP_REG_A1] |= newcarry; + dsp_core.registers[DSP_REG_A1] |= dsp_core.registers[DSP_REG_SR] & 1; dsp_core.registers[DSP_REG_A1] &= BITMASK(24); dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>23) & 1; dsp_core.registers[DSP_REG_B1] <<= 1; - dsp_core.registers[DSP_REG_B1] |= newcarry; + dsp_core.registers[DSP_REG_B1] |= dsp_core.registers[DSP_REG_SR] & 1; dsp_core.registers[DSP_REG_B1] &= BITMASK(24); dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>= 1; - dsp_core.registers[DSP_REG_A1] |= newcarry<<23; + dsp_core.registers[DSP_REG_A1] |= (dsp_core.registers[DSP_REG_SR] & 1)<<23; dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<>= 1; - dsp_core.registers[DSP_REG_B1] |= newcarry<<23; + dsp_core.registers[DSP_REG_B1] |= (dsp_core.registers[DSP_REG_SR] & 1)<<23; dsp_core.registers[DSP_REG_SR] &= BITMASK(16)-((1<