--- hatari/src/falcon/dsp.c 2019/04/09 08:54:35 1.1.1.10 +++ hatari/src/falcon/dsp.c 2019/04/09 08:57:00 1.1.1.12 @@ -67,20 +67,63 @@ static bool bDspDebugging; bool bDspEnabled = false; bool bDspHostInterruptPending = false; +Uint64 DSP_CyclesGlobalClockCounter = 0; /* Value of CyclesGlobalClockCounter when DSP_Run was last called */ + /** * Trigger HREQ interrupt at the host CPU. */ #if ENABLE_DSP_EMU -static void DSP_TriggerHostInterrupt(void) +static void DSP_TriggerHostInterrupt(int hreq) { - bDspHostInterruptPending = true; - M68000_SetSpecial(SPCFLAG_DSP); +//fprintf ( stderr, "DSP_TriggerHostInterrupt %d %x %x\n" , hreq , regs.sr , regs.intmask ); + if ( hreq ) + { + M68000_SetSpecial(SPCFLAG_DSP); // TODO for old cpu core, remove, use level 6 instead and M68000_Update_intlev() + bDspHostInterruptPending = true; + M68000_Update_intlev (); + } + else + { + M68000_UnsetSpecial(SPCFLAG_DSP); // TODO for old cpu core, remove, use level 6 instead and M68000_Update_intlev() + bDspHostInterruptPending = false; + M68000_Update_intlev (); + } } #endif /** + * Return the state of HREQ + */ +Uint8 DSP_GetHREQ ( void ) +{ + if ( bDspHostInterruptPending ) + return 1; + else + return 0; +} + + +/** + * Return the vector number associated to the HREQ interrupt. + * If this function is called when HREQ=0, then we return -1 to indicate + * a spurious interrupt. + */ +int DSP_ProcessIACK ( void ) +{ + int VecNr; + + if ( bDspHostInterruptPending ) + VecNr = IoMem_ReadByte ( 0xffa203 ); + else + VecNr = -1; + + return VecNr; +} + + +/** * This function is called from the CPU emulation part when SPCFLAG_DSP is set. * If the DSP's IRQ signal is set, we check that SR allows a level 6 interrupt, * and if so, we call M68000_Exception. @@ -90,9 +133,9 @@ bool DSP_ProcessIRQ(void) { if (bDspHostInterruptPending && regs.intmask < 6) { - M68000_Exception(IoMem_ReadByte(0xffa203)*4, M68000_EXC_SRC_INT_DSP); - bDspHostInterruptPending = false; - M68000_UnsetSpecial(SPCFLAG_DSP); + M68000_Exception(IoMem_ReadByte(0xffa203), M68000_EXC_SRC_INT_DSP); + bDspHostInterruptPending = false; // [NP] TODO : remove this line, should be cleared by DSP_TriggerHostInterrupt ? + M68000_UnsetSpecial(SPCFLAG_DSP); // [NP] TODO : remove this line, should be cleared by DSP_TriggerHostInterrupt ? return true; } @@ -102,29 +145,24 @@ bool DSP_ProcessIRQ(void) /** - * Initialize the DSP emulation + * Initialize the DSP emulation (should be called only once at start) */ void DSP_Init(void) { #if ENABLE_DSP_EMU - if (bDspEnabled || ConfigureParams.System.nDSPType != DSP_TYPE_EMU) - return; dsp_core_init(DSP_TriggerHostInterrupt); dsp56k_init_cpu(); - bDspEnabled = true; save_cycles = 0; #endif } /** - * Shut down the DSP emulation + * Shut down the DSP emulation (should be called only once at exit) */ void DSP_UnInit(void) { #if ENABLE_DSP_EMU - if (!bDspEnabled) - return; dsp_core_shutdown(); bDspEnabled = false; #endif @@ -138,24 +176,49 @@ void DSP_Reset(void) { #if ENABLE_DSP_EMU dsp_core_reset(); - bDspHostInterruptPending = false; + DSP_TriggerHostInterrupt ( 0 ); /* Clear HREQ */ save_cycles = 0; #endif } /** + * Enable the DSP emulation + */ +void DSP_Enable(void) +{ +#if ENABLE_DSP_EMU + bDspEnabled = true; + DSP_CyclesGlobalClockCounter = CyclesGlobalClockCounter; +#endif +} + + +/** + * Disable the DSP emulation + */ +void DSP_Disable(void) +{ +#if ENABLE_DSP_EMU + bDspEnabled = false; +#endif +} + + +/** * Save/Restore snapshot of CPU variables ('MemorySnapShot_Store' handles type) */ void DSP_MemorySnapShot_Capture(bool bSave) { #if ENABLE_DSP_EMU - if (!bSave) - DSP_Reset(); - MemorySnapShot_Store(&bDspEnabled, sizeof(bDspEnabled)); MemorySnapShot_Store(&dsp_core, sizeof(dsp_core)); MemorySnapShot_Store(&save_cycles, sizeof(save_cycles)); + + if ( bDspEnabled ) + DSP_Enable(); + else + DSP_Disable(); #endif } @@ -165,6 +228,11 @@ void DSP_MemorySnapShot_Capture(bool bSa void DSP_Run(int nHostCycles) { #if ENABLE_DSP_EMU + if ( nHostCycles == 0 ) + return; + + DSP_CyclesGlobalClockCounter = CyclesGlobalClockCounter; + save_cycles += nHostCycles * 2; if (dsp_core.running == 0) @@ -234,7 +302,7 @@ Uint16 DSP_GetNextPC(Uint16 pc) /* why dsp56k_execute_one_disasm_instruction() does "-1" * for this value, that doesn't seem right??? */ - instruction_length = dsp56k_disasm(DSP_DISASM_MODE); + instruction_length = dsp56k_disasm(DSP_DISASM_MODE, stderr); /* Restore DSP context */ memcpy(&dsp_core, &dsp_core_save, sizeof(dsp_core)); @@ -367,7 +435,7 @@ Uint32 DSP_ReadMemory(Uint16 address, ch * Output memory values between given addresses in given DSP address space. * Return next DSP address value. */ -Uint16 DSP_DisasmMemory(Uint16 dsp_memdump_addr, Uint16 dsp_memdump_upper, char space) +Uint16 DSP_DisasmMemory(FILE *fp, Uint16 dsp_memdump_addr, Uint16 dsp_memdump_upper, char space) { #if ENABLE_DSP_EMU Uint32 mem, mem2, value; @@ -377,16 +445,16 @@ Uint16 DSP_DisasmMemory(Uint16 dsp_memdu /* special printing of host communication/transmit registers */ if (space == 'X' && mem >= 0xffc0) { if (mem == 0xffeb) { - fprintf(stderr,"X periph:%04x HTX : %06x RTX:%06x\n", + fprintf(fp, "X periph:%04x HTX : %06x RTX:%06x\n", mem, dsp_core.dsp_host_htx, dsp_core.dsp_host_rtx); } else if (mem == 0xffef) { - fprintf(stderr,"X periph:%04x SSI TX : %06x SSI RX:%06x\n", + fprintf(fp, "X periph:%04x SSI TX : %06x SSI RX:%06x\n", mem, dsp_core.ssi.transmit_value, dsp_core.ssi.received_value); } else { value = DSP_ReadMemory(mem, space, &mem_str); - fprintf(stderr,"%s:%04x %06x\t%s\n", mem_str, mem, value, x_ext_memory_addr_name[mem-0xffc0]); + fprintf(fp, "%s:%04x %06x\t%s\n", mem_str, mem, value, x_ext_memory_addr_name[mem-0xffc0]); } continue; } @@ -397,12 +465,12 @@ Uint16 DSP_DisasmMemory(Uint16 dsp_memdu if (space == 'X') { mem2 += (DSP_RAMSIZE>>1); } - fprintf(stderr,"%c:%04x (P:%04x): %06x\n", space, + fprintf(fp, "%c:%04x (P:%04x): %06x\n", space, mem, mem2, dsp_core.ramext[mem2 & (DSP_RAMSIZE-1)]); continue; } value = DSP_ReadMemory(mem, space, &mem_str); - fprintf(stderr,"%s:%04x %06x\n", mem_str, mem, value); + fprintf(fp, "%s:%04x %06x\n", mem_str, mem, value); } #endif return dsp_memdump_upper+1; @@ -412,68 +480,68 @@ Uint16 DSP_DisasmMemory(Uint16 dsp_memdu * Show information on DSP core state which isn't * shown by any of the other commands (dd, dm, dr). */ -void DSP_Info(Uint32 dummy) +void DSP_Info(FILE *fp, Uint32 dummy) { #if ENABLE_DSP_EMU int i, j; const char *stackname[] = { "SSH", "SSL" }; - fputs("DSP core information:\n", stderr); + fputs("DSP core information:\n", fp); - for (i = 0; i < ARRAYSIZE(stackname); i++) { - fprintf(stderr, "- %s stack:", stackname[i]); - for (j = 0; j < ARRAYSIZE(dsp_core.stack[0]); j++) { - fprintf(stderr, " %04hx", dsp_core.stack[i][j]); + for (i = 0; i < ARRAY_SIZE(stackname); i++) { + fprintf(fp, "- %s stack:", stackname[i]); + for (j = 0; j < ARRAY_SIZE(dsp_core.stack[0]); j++) { + fprintf(fp, " %04hx", dsp_core.stack[i][j]); } - fputs("\n", stderr); + fputs("\n", fp); } - fprintf(stderr, "- Interrupt IPL:"); - for (i = 0; i < ARRAYSIZE(dsp_core.interrupt_ipl); i++) { - fprintf(stderr, " %04hx", dsp_core.interrupt_ipl[i]); + fprintf(fp, "- Interrupt IPL:"); + for (i = 0; i < ARRAY_SIZE(dsp_core.interrupt_ipl); i++) { + fprintf(fp, " %04hx", dsp_core.interrupt_ipl[i]); } - fputs("\n", stderr); + fputs("\n", fp); - fprintf(stderr, "- Pending ints: "); - for (i = 0; i < ARRAYSIZE(dsp_core.interrupt_isPending); i++) { - fprintf(stderr, " %04hx", dsp_core.interrupt_isPending[i]); + fprintf(fp, "- Pending ints: "); + for (i = 0; i < ARRAY_SIZE(dsp_core.interrupt_isPending); i++) { + fprintf(fp, " %04hx", dsp_core.interrupt_isPending[i]); } - fputs("\n", stderr); + fputs("\n", fp); - fprintf(stderr, "- Hostport:"); - for (i = 0; i < ARRAYSIZE(dsp_core.hostport); i++) { - fprintf(stderr, " %02x", dsp_core.hostport[i]); + fprintf(fp, "- Hostport:"); + for (i = 0; i < ARRAY_SIZE(dsp_core.hostport); i++) { + fprintf(fp, " %02x", dsp_core.hostport[i]); } - fputs("\n", stderr); + fputs("\n", fp); #endif } /** * Show DSP register contents */ -void DSP_DisasmRegisters(void) +void DSP_DisasmRegisters(FILE *fp) { #if ENABLE_DSP_EMU Uint32 i; - fprintf(stderr,"A: A2: %02x A1: %06x A0: %06x\n", + fprintf(fp, "A: A2: %02x A1: %06x A0: %06x\n", dsp_core.registers[DSP_REG_A2], dsp_core.registers[DSP_REG_A1], dsp_core.registers[DSP_REG_A0]); - fprintf(stderr,"B: B2: %02x B1: %06x B0: %06x\n", + fprintf(fp, "B: B2: %02x B1: %06x B0: %06x\n", dsp_core.registers[DSP_REG_B2], dsp_core.registers[DSP_REG_B1], dsp_core.registers[DSP_REG_B0]); - fprintf(stderr,"X: X1: %06x X0: %06x\n", dsp_core.registers[DSP_REG_X1], dsp_core.registers[DSP_REG_X0]); - fprintf(stderr,"Y: Y1: %06x Y0: %06x\n", dsp_core.registers[DSP_REG_Y1], dsp_core.registers[DSP_REG_Y0]); + fprintf(fp, "X: X1: %06x X0: %06x\n", dsp_core.registers[DSP_REG_X1], dsp_core.registers[DSP_REG_X0]); + fprintf(fp, "Y: Y1: %06x Y0: %06x\n", dsp_core.registers[DSP_REG_Y1], dsp_core.registers[DSP_REG_Y0]); for (i=0; i<8; i++) { - fprintf(stderr,"R%01x: %04x N%01x: %04x M%01x: %04x\n", + fprintf(fp, "R%01x: %04x N%01x: %04x M%01x: %04x\n", i, dsp_core.registers[DSP_REG_R0+i], i, dsp_core.registers[DSP_REG_N0+i], i, dsp_core.registers[DSP_REG_M0+i]); } - fprintf(stderr,"LA: %04x LC: %04x PC: %04x\n", dsp_core.registers[DSP_REG_LA], dsp_core.registers[DSP_REG_LC], dsp_core.pc); - fprintf(stderr,"SR: %04x OMR: %02x\n", dsp_core.registers[DSP_REG_SR], dsp_core.registers[DSP_REG_OMR]); - fprintf(stderr,"SP: %02x SSH: %04x SSL: %04x\n", + fprintf(fp, "LA: %04x LC: %04x PC: %04x\n", dsp_core.registers[DSP_REG_LA], dsp_core.registers[DSP_REG_LC], dsp_core.pc); + fprintf(fp, "SR: %04x OMR: %02x\n", dsp_core.registers[DSP_REG_SR], dsp_core.registers[DSP_REG_OMR]); + fprintf(fp, "SP: %02x SSH: %04x SSL: %04x\n", dsp_core.registers[DSP_REG_SP], dsp_core.registers[DSP_REG_SSH], dsp_core.registers[DSP_REG_SSL]); #endif } @@ -584,7 +652,7 @@ int DSP_GetRegisterAddress(const char *r /* bisect */ l = 0; - r = ARRAYSIZE(registers) - 1; + r = ARRAY_SIZE(registers) - 1; do { m = (l+r) >> 1; for (i = 0; i < len; i++) {