--- hatari/src/falcon/dsp.c 2019/04/01 07:13:46 1.1 +++ hatari/src/falcon/dsp.c 2019/04/09 08:52:10 1.1.1.8 @@ -1,586 +1,707 @@ /* - * dsp.c - Atari DSP56001 emulation code - * - * Copyright (c) 2001-2004 Petr Stehlik of ARAnyM dev team - * 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 ARAnyM; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ + DSP M56001 emulation + Dummy emulation, Hatari glue + + (C) 2001-2008 ARAnyM developer team + Adaption to Hatari (C) 2008 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 "main.h" #include "sysdeps.h" +#include "newcpu.h" +#include "memorySnapShot.h" #include "ioMem.h" #include "dsp.h" +#include "crossbar.h" +#include "configuration.h" +#include "cycInt.h" + +#if ENABLE_DSP_EMU +#include "m68000.h" +#include "debugdsp.h" #include "dsp_cpu.h" +#include "dsp_disasm.h" +#endif -#define DSP_EMULATION 1 -#define DEBUG 1 - +#define DEBUG 0 #if DEBUG -#define D(x) x +#define Dprintf(a) printf a #else -#define D(x) +#define Dprintf(a) #endif -#include +#define DSP_HW_OFFSET 0xFFA200 -#include -#include -#ifndef M_PI -#define M_PI 3.141592653589793238462643383279502 +#if ENABLE_DSP_EMU +static Sint32 save_cycles; #endif +static bool bDspDebugging; +bool bDspEnabled = false; +bool bDspHostInterruptPending = false; -/* DSP state */ -uint8 dsp_state; +static const char* x_ext_memory_addr_name[] = { + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "PBC", "PCC", "PBDDR", "PCDDR", "PBD", "PCD", "", "", + "HCR", "HSR", "", "HRX/HTX", "CRA", "CRB", "SSISR/TSR", "RX/TX", + "SCR", "SSR", "SCCR", "STXA", "SRX/STX", "SRX/STX", "SRX/STX", "", + "", "", "", "", "", "", "BCR", "IPR" +}; -/* Registers */ -uint16 dsp_pc; -uint32 dsp_registers[64]; -/* stack[0=ssh], stack[1=ssl] */ -uint16 dsp_stack[2][15]; +/** + * Trigger HREQ interrupt at the host CPU. + */ +#if ENABLE_DSP_EMU +static void DSP_TriggerHostInterrupt(void) +{ + bDspHostInterruptPending = true; -/* ram[0] is x:, ram[1] is y:, ram[2] is p: */ -uint32 dsp_ram[3][DSP_RAMSIZE]; + /* Note: The DSP interrupt is not wired to the MFP on a real Falcon + * (but to the COMBEL chip). But in Hatari we still handle it with + * the SPCFLAG_MFP to avoid taking care of another special flag in + * the CPU core! */ + M68000_SetSpecial(SPCFLAG_MFP); +} +#endif -/* rom[0] is x:, rom[1] is y: */ -uint32 dsp_rom[2][512]; -/* peripheral space, [x|y]:0xffc0-0xffff */ -uint32 dsp_periph[2][64]; +/** + * Initialize the DSP emulation + */ +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 +} -/* host port, CPU side */ -uint8 dsp_hostport[8]; -/* Misc */ -uint32 dsp_loop_rep; /* executing rep ? */ -uint32 dsp_last_loop_inst; /* executing the last instruction in DO ? */ -uint32 dsp_first_host_write; /* first byte written to host port */ +/** + * Shut down the DSP emulation + */ +void DSP_UnInit(void) +{ +#if ENABLE_DSP_EMU + if (!bDspEnabled) + return; + dsp_core_shutdown(); + bDspEnabled = false; +#endif +} + -SDL_sem *dsp56k_sem; +/** + * Reset the DSP emulation + */ +void DSP_Reset(void) +{ +#if ENABLE_DSP_EMU + dsp_core_reset(); + bDspHostInterruptPending = false; + save_cycles = 0; +#endif +} -/* For bootstrap routine */ -static uint16 bootstrap_pos; -static uint32 bootstrap_accum; +/** + * Save/Restore snapshot of CPU variables ('MemorySnapShot_Store' handles type) + */ +void DSP_MemorySnapShot_Capture(bool bSave) +{ +#if ENABLE_DSP_EMU + if (!bSave) + DSP_Reset(); -static SDL_Thread *dsp56k_thread; + MemorySnapShot_Store(&bDspEnabled, sizeof(bDspEnabled)); + MemorySnapShot_Store(&dsp_core, sizeof(dsp_core)); + MemorySnapShot_Store(&save_cycles, sizeof(save_cycles)); +#endif +} +/** + * Run DSP for certain cycles + */ +void DSP_Run(int nHostCycles) +{ +#if ENABLE_DSP_EMU + save_cycles += nHostCycles * 2; + if (dsp_core.running == 0) + return; -#if DSP_EMULATION + if (save_cycles <= 0) + return; + + if (unlikely(bDspDebugging)) { + while (save_cycles > 0) + { + DebugDsp_Check(); + dsp56k_execute_instruction(); + save_cycles -= dsp_core.instr_cycle; + } + } else { + // fprintf(stderr, "--> %d\n", save_cycles); + while (save_cycles > 0) + { + dsp56k_execute_instruction(); + save_cycles -= dsp_core.instr_cycle; + } + } -/* More disasm infos, if wanted */ -#define DSP_DISASM_HOSTREAD 0 /* Dsp->Host transfer */ -#define DSP_DISASM_HOSTWRITE 0 /* Host->Dsp transfer */ -#define DSP_DISASM_STATE 0 /* State changes */ +#endif +} -/* Execute DSP instructions till the DSP waits for a read/write */ -#define DSP_HOST_FORCEEXEC 0 +/** + * Enable/disable DSP debugging mode + */ +void DSP_SetDebugging(bool enabled) +{ + bDspDebugging = enabled; +} +/** + * Get DSP program counter (for debugging) + */ +Uint16 DSP_GetPC(void) +{ +#if ENABLE_DSP_EMU + if (bDspEnabled) + return dsp_core.pc; + else +#endif + return 0; +} -static inline Uint32 getHWoffset(void) +/** + * Get current DSP instruction cycles (for profiling) + */ +Uint16 DSP_GetInstrCycles(void) { - return 0xFFA200; +#if ENABLE_DSP_EMU + if (bDspEnabled) + return dsp_core.instr_cycle; + else +#endif + return 0; } -/* Constructor and destructor for DSP class */ -void DSP_Init(void) +/** + * Disassemble DSP code between given addresses, return next PC address + */ +Uint16 DSP_DisasmAddress(Uint16 lowerAdr, Uint16 UpperAdr) { - int i; +#if ENABLE_DSP_EMU + Uint16 dsp_pc; - memset(dsp_ram, 0,sizeof(dsp_ram)); + for (dsp_pc=lowerAdr; dsp_pc<=UpperAdr; dsp_pc++) { + dsp_pc += dsp56k_execute_one_disasm_instruction(dsp_pc); + } + return dsp_pc; +#else + return 0; +#endif +} - /* Initialize Y:rom[0x0100-0x01ff] with a sin table */ - { - float src; - int32 dest; - for (i=0;i<256;i++) { - src = (((float) i)*M_PI)/128.0; - dest = (int32) (sin(src) * 8388608.0); /* 1<<23 */ - if (dest>8388607) { - dest = 8388607; - } else if (dest<-8388608) { - dest = -8388608; - } - dsp_rom[DSP_SPACE_Y][0x100+i]=dest & 0x00ffffff; +/** + * Get the value from the given (16-bit) DSP memory address / space + * exactly the same way as in dsp_cpu.c::read_memory() (except for + * the host/transmit peripheral register values which access has + * side-effects). Set the mem_str to suitable string for that + * address / space. + * Return the value at given address. For valid values AND the return + * value with BITMASK(24). + */ +Uint32 DSP_ReadMemory(Uint16 address, char space_id, const char **mem_str) +{ +#if ENABLE_DSP_EMU + static const char *spaces[3][4] = { + { "X ram", "X rom", "X", "X periph" }, + { "Y ram", "Y rom", "Y", "Y periph" }, + { "P ram", "P ram", "P ext memory", "P ext memory" } + }; + int idx, space; + + switch (space_id) { + case 'X': + space = DSP_SPACE_X; + idx = 0; + break; + case 'Y': + space = DSP_SPACE_Y; + idx = 1; + break; + case 'P': + space = DSP_SPACE_P; + idx = 2; + break; + default: + space = DSP_SPACE_X; + idx = 0; + } + address &= 0xFFFF; + + /* Internal RAM ? */ + if (address < 0x100) { + *mem_str = spaces[idx][0]; + return dsp_core.ramint[space][address]; + } + + if (space == DSP_SPACE_P) { + /* Internal RAM ? */ + if (address < 0x200) { + *mem_str = spaces[idx][0]; + return dsp_core.ramint[DSP_SPACE_P][address]; } + /* External RAM, mask address to available ram size */ + *mem_str = spaces[idx][2]; + return dsp_core.ramext[address & (DSP_RAMSIZE-1)]; } - /* Initialize X:rom[0x0100-0x017f] with a mu-law table */ - { - const uint16 mulaw_base[8]={ - 0x7d7c, 0x3e7c, 0x1efc, 0x0f3c, 0x075c, 0x036c, 0x0174, 0x0078 - }; - - uint32 value, offset, position; - int j; - - position = 0x0100; - offset = 0x040000; - for(i=0;i<8;i++) { - value = mulaw_base[i]<<8; - - for (j=0;j<16;j++) { - dsp_rom[DSP_SPACE_X][position++]=value; - value -= offset; - } - - offset >>= 1; + /* Internal ROM ? */ + if (address < 0x200) { + if (dsp_core.registers[DSP_REG_OMR] & (1<= 0xffc0) { + *mem_str = spaces[idx][3]; + /* reading host/transmit regs has side-effects, + * so just give the memory value. + */ + return dsp_core.periph[space][address-0xffc0]; + } + + /* Falcon: External RAM, map X to upper 16K of matching space in Y,P */ + address &= (DSP_RAMSIZE>>1) - 1; + if (space == DSP_SPACE_X) { + address += DSP_RAMSIZE>>1; + } - for (k=0;k<4;k++) { - int32 alawbase2; + /* Falcon: External RAM, finally map X,Y to P */ + *mem_str = spaces[idx][2]; + return dsp_core.ramext[address & (DSP_RAMSIZE-1)]; +#endif + return 0; +} - alawbase2 = alawbase1 + ((base_values[k]*multiply_col[i & 3])<<12); - dsp_rom[DSP_SPACE_X][pos++]=alawbase2; - } +/** + * 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) +{ +#if ENABLE_DSP_EMU + Uint32 mem, mem2, value; + const char *mem_str; + + for (mem = dsp_memdump_addr; mem <= dsp_memdump_upper; mem++) { + /* 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", + 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", + 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]); } + continue; } + /* special printing of X & Y external RAM values */ + if ((space == 'X' || space == 'Y') && + mem >= 0x200 && mem < 0xffc0) { + mem2 = mem & ((DSP_RAMSIZE>>1)-1); + if (space == 'X') { + mem2 += (DSP_RAMSIZE>>1); + } + fprintf(stderr,"%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); } - - D(bug("Dsp: power-on done")); - - dsp56k_thread = NULL; - dsp56k_sem = NULL; - - dsp_state = DSP_HALT; -#if DSP_DISASM_STATE - D(bug("Dsp: state = HALT")); #endif + return dsp_memdump_upper+1; } -void DSP_UnInit(void) -{ - DSP_shutdown(); -} -/* Other functions to init/shutdown dsp emulation */ -void DSP_Reset(void) +void DSP_DisasmRegisters(void) { - int i; - - /* Kill existing thread and semaphore */ - DSP_shutdown(); - - /* Pause thread */ - dsp_state = DSP_BOOTING; -#if DSP_DISASM_STATE - D(bug("Dsp: state = BOOTING")); -#endif +#if ENABLE_DSP_EMU + Uint32 i; - /* Memory */ - memset(dsp_periph, 0,sizeof(dsp_periph)); - memset(dsp_stack, 0,sizeof(dsp_stack)); - memset(dsp_registers, 0,sizeof(dsp_registers)); - - bootstrap_pos = bootstrap_accum = 0; + fprintf(stderr,"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", + dsp_core.registers[DSP_REG_B2], dsp_core.registers[DSP_REG_B1], dsp_core.registers[DSP_REG_B0]); - /* Registers */ - dsp_pc = 0x0000; - dsp_registers[DSP_REG_OMR]=0x02; - for (i=0;i<8;i++) { - dsp_registers[DSP_REG_M0+i]=0x00ffff; - } - - /* host port init, dsp side */ - dsp_periph[DSP_SPACE_X][DSP_HOST_HSR]=(1<> 1; + for (i = 0; i < len; i++) { + dir = (int)reg[i] - registers[m].name[i]; + if (dir) { + break; + } } - - /* Wait for the thread to finish */ - while (dsp_state != DSP_STOPPEDTHREAD) { - SDL_Delay(1); + if (dir == 0) { + *addr = registers[m].addr; + *mask = registers[m].mask; + return registers[m].bits; } - - dsp56k_thread = NULL; - } - - /* Destroy the semaphore */ - if (dsp56k_sem != NULL) { - SDL_DestroySemaphore(dsp56k_sem); - dsp56k_sem = NULL; - } -} - -/********************************** - * Force execution of DSP, till something - * to read from/write to host port - **********************************/ - -static inline void DSP_force_exec(void) -{ -#if DSP_HOST_FORCEEXEC - while (state == DSP_RUNNING) { - } -#endif -} - -#endif /* DSP_EMULATION */ - -/********************************** - * Hardware address read/write by CPU - **********************************/ - -static uint8 DSP_handleRead(Uint32 addr) -{ -#if DSP_EMULATION - uint8 value=0; - - addr -= getHWoffset(); - -/* D(bug("HWget_b(0x%08x)=0x%02x at 0x%08x", addr+HW_DSP, value, showPC()));*/ - - /* Whenever the host want to read something on host port, we test if a - transfer is needed */ - DSP_dsp2host(); - - switch(addr) { - case CPU_HOST_ICR: - value = dsp_hostport[CPU_HOST_ICR]; - break; - case CPU_HOST_CVR: - value = dsp_hostport[CPU_HOST_CVR]; - break; - case CPU_HOST_ISR: - value = dsp_hostport[CPU_HOST_ISR]; - break; - case CPU_HOST_IVR: - value = dsp_hostport[CPU_HOST_IVR]; - break; - case CPU_HOST_RX0: - DSP_force_exec(); - value = 0; - break; - case CPU_HOST_RXH: - DSP_force_exec(); - value = dsp_hostport[CPU_HOST_RXH]; - break; - case CPU_HOST_RXM: - DSP_force_exec(); - value = dsp_hostport[CPU_HOST_RXM]; - break; - case CPU_HOST_RXL: - DSP_force_exec(); - value = dsp_hostport[CPU_HOST_RXL]; - - if (dsp_state!=DSP_BOOTING) { - /* Clear RXDF bit to say that CPU has read */ - dsp_hostport[CPU_HOST_ISR] &= 0xff-(1<H): Host RXDF cleared")); + if (dir < 0) { + r = m-1; + } else { + l = m+1; + } + } while (l <= r); +#undef MAX_REGNAME_LEN #endif - } + return 0; +} - /* Wake up DSP if it was waiting our read */ - if (dsp_state==DSP_WAITHOSTREAD) { -#if DSP_DISASM_STATE - D(bug("Dsp: state = DSP_RUNNING")); -#endif - dsp_state = DSP_RUNNING; - if (SDL_SemValue(dsp56k_sem)==0) { - SDL_SemPost(dsp56k_sem); +/** + * Set given DSP register value, return false if unknown register given + */ +bool DSP_Disasm_SetRegister(const char *arg, Uint32 value) +{ +#if ENABLE_DSP_EMU + Uint32 *addr, mask, sp_value; + int bits; + + /* first check registers needing special handling... */ + if (arg[0]=='S' || arg[0]=='s') { + if (arg[1]=='P' || arg[1]=='p') { + dsp_core.registers[DSP_REG_SP] = value & BITMASK(6); + value &= BITMASK(4); + dsp_core.registers[DSP_REG_SSH] = dsp_core.stack[0][value]; + dsp_core.registers[DSP_REG_SSL] = dsp_core.stack[1][value]; + return true; + } + if (arg[1]=='S' || arg[1]=='s') { + sp_value = dsp_core.registers[DSP_REG_SP] & BITMASK(4); + if (arg[2]=='H' || arg[2]=='h') { + if (sp_value == 0) { + dsp_core.registers[DSP_REG_SSH] = 0; + dsp_core.stack[0][sp_value] = 0; + } else { + dsp_core.registers[DSP_REG_SSH] = value & BITMASK(16); + dsp_core.stack[0][sp_value] = value & BITMASK(16); } + return true; } - - break; + if (arg[2]=='L' || arg[2]=='l') { + if (sp_value == 0) { + dsp_core.registers[DSP_REG_SSL] = 0; + dsp_core.stack[1][sp_value] = 0; + } else { + dsp_core.registers[DSP_REG_SSL] = value & BITMASK(16); + dsp_core.stack[1][sp_value] = value & BITMASK(16); + } + return true; + } + } } - return value; -#else - return 0xff; // this value prevents TOS from hanging in the DSP init code */ -#endif /* DSP_EMULATION */ + /* ...then registers where address & mask are enough */ + bits = DSP_GetRegisterAddress(arg, &addr, &mask); + switch (bits) { + case 32: + *addr = value & mask; + return true; + case 16: + *(Uint16*)addr = value & mask; + return true; + } +#endif + return false; } -void DSP_HandleReadAccess(void) +/** + * Read SSI transmit value + */ +Uint32 DSP_SsiReadTxValue(void) { - Uint32 a; - Uint8 v; - for (a = IoAccessBaseAddress; a < IoAccessBaseAddress+nIoMemAccessSize; a++) - { - v = DSP_handleRead(a); - IoMem_WriteByte(a, v); - } +#if ENABLE_DSP_EMU + return dsp_core.ssi.transmit_value; +#else + return 0; +#endif } -static void DSP_handleWrite(Uint32 addr, uint8 value) +/** + * Write SSI receive value + */ +void DSP_SsiWriteRxValue(Uint32 value) { -#if DSP_EMULATION - addr -= getHWoffset(); - -/* D(bug("HWput_b(0x%08x,0x%02x) at 0x%08x", addr+HW_DSP, value, showPC()));*/ - - switch(addr) { - case CPU_HOST_ICR: - dsp_hostport[CPU_HOST_ICR]=value & 0xfb; - /* Set HF1 and HF0 accordingly on the host side */ - dsp_periph[DSP_SPACE_X][DSP_HOST_HSR] &= - 0xff-((1<D): Host TXDE cleared")); +#if ENABLE_DSP_EMU + dsp_core.ssi.received_value = value & 0xffffff; #endif +} - DSP_host2dsp(); - } - - switch(dsp_state) { - case DSP_BOOTING: - dsp_ram[DSP_SPACE_P][bootstrap_pos] = bootstrap_accum; -/* D(bug("Dsp: bootstrap: p:0x%04x: 0x%06x written", bootstrap_pos, bootstrap_accum));*/ - bootstrap_pos++; - if (bootstrap_pos == 0x200) { -#if DSP_DISASM_STATE - D(bug("Dsp: bootstrap done")); -#endif - dsp_state = DSP_RUNNING; - - SDL_SemPost(dsp56k_sem); - } - bootstrap_accum = 0; - break; - case DSP_WAITHOSTWRITE: - /* Wake up DSP if it was waiting our write */ -#if DSP_DISASM_STATE - D(bug("Dsp: state = DSP_RUNNING")); -#endif - dsp_state = DSP_RUNNING; - - if (SDL_SemValue(dsp56k_sem)==0) { - SDL_SemPost(dsp56k_sem); - } - break; - } +/** + * Signal SSI clock tick to DSP + */ - break; - } -#endif /* DSP_EMULATION */ +void DSP_SsiReceive_SC0(void) +{ +#if ENABLE_DSP_EMU + dsp_core_ssi_Receive_SC0(); +#endif } -void DSP_HandleWriteAccess(void) +void DSP_SsiTransmit_SC0(void) { - Uint32 a; - Uint8 v; - for (a = IoAccessBaseAddress; a < IoAccessBaseAddress+nIoMemAccessSize; a++) - { - v = IoMem_ReadByte(a); - DSP_handleWrite(a,v); - } +#if ENABLE_DSP_EMU +#endif } - -#if DSP_EMULATION - -/********************************** - * Host transfer - **********************************/ - -void DSP_host2dsp(void) +void DSP_SsiReceive_SC1(Uint32 FrameCounter) { - int trdy; - - /* Host port transfer ? (host->dsp) */ - if ( - ((dsp_hostport[CPU_HOST_ISR] & (1<D): Transfer 0x%06x",dsp_periph[DSP_SPACE_X][DSP_HOST_HRX])); +#if ENABLE_DSP_EMU + dsp_core_ssi_Receive_SC1(FrameCounter); #endif +} - /* Set HRDF bit to say that DSP can read */ - dsp_periph[DSP_SPACE_X][DSP_HOST_HSR] |= 1<D): Dsp HRDF set")); +void DSP_SsiTransmit_SC1(void) +{ +#if ENABLE_DSP_EMU + Crossbar_DmaPlayInHandShakeMode(); #endif +} - /* Set TXDE bit to say that host can write */ - dsp_hostport[CPU_HOST_ISR] |= 1<D): Host TXDE set")); +void DSP_SsiReceive_SC2(Uint32 FrameCounter) +{ +#if ENABLE_DSP_EMU + dsp_core_ssi_Receive_SC2(FrameCounter); #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; - } } -void DSP_dsp2host(void) +void DSP_SsiTransmit_SC2(Uint32 frame) { - /* Host port transfer ? (dsp->host) */ - if ( - ((dsp_hostport[CPU_HOST_ISR] & (1<>8; - dsp_hostport[CPU_HOST_RXH] = dsp_periph[DSP_SPACE_X][DSP_HOST_HTX]>>16; +#if ENABLE_DSP_EMU + Crossbar_DmaRecordInHandShakeMode_Frame(frame); +#endif +} -#if DSP_DISASM_HOSTWRITE - D(bug("Dsp: (D->H): Transfer 0x%06x",dsp_periph[DSP_SPACE_X][DSP_HOST_HTX])); +void DSP_SsiReceive_SCK(void) +{ +#if ENABLE_DSP_EMU + dsp_core_ssi_Receive_SCK(); #endif +} - /* Set HTDE bit to say that DSP can write */ - dsp_periph[DSP_SPACE_X][DSP_HOST_HSR] |= 1<H): Dsp HTDE set")); +void DSP_SsiTransmit_SCK(void) +{ +#if ENABLE_DSP_EMU #endif +} - /* Set RXDF bit to say that host can read */ - dsp_hostport[CPU_HOST_ISR] |= 1<H): Host RXDF set")); +/** + * Read access wrapper for ioMemTabFalcon (DSP Host port) + * DSP Host interface port is accessed by the 68030 in Byte mode. + * A move.w value,$ffA206 results in 2 bus access for the 68030. + */ +void DSP_HandleReadAccess(void) +{ + Uint32 addr; + Uint8 value; + bool multi_access = false; + + for (addr = IoAccessBaseAddress; addr < IoAccessBaseAddress+nIoMemAccessSize; addr++) + { +#if ENABLE_DSP_EMU + value = dsp_core_read_host(addr-DSP_HW_OFFSET); + if (multi_access == true) + M68000_AddCycles(4); + multi_access = true; +#else + /* this value prevents TOS from hanging in the DSP init code */ + value = 0xff; #endif + + Dprintf(("HWget_b(0x%08x)=0x%02x at 0x%08x\n", addr, value, m68k_getpc())); + IoMem_WriteByte(addr, value); } } -#endif /* DSP_EMULATION */ +/** + * Write access wrapper for ioMemTabFalcon (DSP Host port) + * DSP Host interface port is accessed by the 68030 in Byte mode. + * A move.w value,$ffA206 results in 2 bus access for the 68030. + */ +void DSP_HandleWriteAccess(void) +{ + Uint32 addr; + Uint8 value; + bool multi_access = false; + for (addr = IoAccessBaseAddress; addr < IoAccessBaseAddress+nIoMemAccessSize; addr++) + { + value = IoMem_ReadByte(addr); + Dprintf(("HWput_b(0x%08x,0x%02x) at 0x%08x\n", addr, value, m68k_getpc())); +#if ENABLE_DSP_EMU + dsp_core_write_host(addr-DSP_HW_OFFSET, value); + if (multi_access == true) + M68000_AddCycles(4); + multi_access = true; +#endif + } +}