diff --git a/Source/Core/Common/Src/MemoryUtil.h b/Source/Core/Common/Src/MemoryUtil.h index 29bd911c9d..7f568d3701 100644 --- a/Source/Core/Common/Src/MemoryUtil.h +++ b/Source/Core/Common/Src/MemoryUtil.h @@ -22,10 +22,8 @@ void* AllocateExecutableMemory(size_t size, bool low = true); void* AllocateMemoryPages(size_t size); void FreeMemoryPages(void* ptr, size_t size); void WriteProtectMemory(void* ptr, size_t size, bool executable = false); -void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute); - - -inline int GetPageSize() {return 4096;} +void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute = false); +inline int GetPageSize() { return 4096; } #endif diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h index a50ce13e98..0842e14fb2 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h @@ -54,11 +54,18 @@ public: virtual bool Open(u32 _CommandAddress, u32 _Mode) { - ERROR_LOG(WII_IPC_SD, "STM: Open"); + ERROR_LOG(WII_IPC_SD, "STM immediate: Open"); Memory::Write_U32(GetDeviceID(), _CommandAddress+4); return true; } + virtual bool Close(u32 _CommandAddress) + { + ERROR_LOG(WII_IPC_SD, "STM immediate: Close"); + Memory::Write_U32(0, _CommandAddress+4); + return true; + } + virtual bool IOCtl(u32 _CommandAddress) { u32 Parameter = Memory::Read_U32(_CommandAddress +0x0C); @@ -141,6 +148,13 @@ public: return true; } + virtual bool Close(u32 _CommandAddress) + { + INFO_LOG(WII_IPC_SD, "STM eventhook: Close"); + Memory::Write_U32(0, _CommandAddress+4); + return true; + } + virtual bool IOCtl(u32 _CommandAddress) { u32 Parameter = Memory::Read_U32(_CommandAddress +0x0C); diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.h index ab76a47482..9d2f1f2c6a 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.h +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/Config.h @@ -26,7 +26,6 @@ struct CConfig CConfig(); void Load(); - void Save(); }; diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp index 7b1d6701d9..4156b587c5 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.cpp @@ -288,6 +288,7 @@ void srr(const UDSPInstruction& opc) u16 val = dsp_op_read_reg(sreg); dsp_dmem_write(g_dsp.r[dreg], val); } + // SRRD @$D, $S // 0001 1010 1dds ssss // Store value from source register $S to a memory location pointed by diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.h index 012bb23275..3241736403 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.h +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPInterpreter.h @@ -114,6 +114,7 @@ void msubc(const UDSPInstruction& opc); void srs(const UDSPInstruction& opc); void lrs(const UDSPInstruction& opc); void nx(const UDSPInstruction& opc); +void cmpi(const UDSPInstruction& opc); // FIXME inside void rti(const UDSPInstruction& opc); @@ -122,7 +123,6 @@ void srbith(const UDSPInstruction& opc); void andfc(const UDSPInstruction& opc); void andf(const UDSPInstruction& opc); -void cmpi(const UDSPInstruction& opc); void xori(const UDSPInstruction& opc); void andi(const UDSPInstruction& opc); void ori(const UDSPInstruction& opc); @@ -130,11 +130,14 @@ void ori(const UDSPInstruction& opc); // TODO: PENDING IMPLEMENTATION / UNIMPLEMENTED +// The mysterious a100 + // END OF UNIMPLEMENTED // Helpers inline void tsta(int reg); -}; + +} // namespace #endif // _DSPINTERPRETER_H diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.cpp index 178d9e06bd..dbc3729fa6 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.cpp @@ -336,9 +336,27 @@ dspInstFunc opTable[OPTABLE_SIZE]; dspInstFunc prologueTable[OPTABLE_SIZE]; dspInstFunc epilogueTable[OPTABLE_SIZE]; +const DSPOPCTemplate *GetOpTemplate(const UDSPInstruction &inst) +{ + for (int i = 0; i < opcodes_size; i++) + { + u16 mask = opcodes[i].opcode_mask; + if (opcodes[i].size & P_EXT) { + // Ignore extension bits. + mask &= 0xFF00; + } + if ((mask & inst.hex) == opcodes[i].opcode) + return &opcodes[i]; + } + return NULL; +} + + +// This function could use the above GetOpTemplate, but then we'd lose the +// nice property that it catches colliding op masks. void InitInstructionTable() { - for (u32 i = 0; i < OPTABLE_SIZE; i++) + for (int i = 0; i < OPTABLE_SIZE; i++) { opTable[i] = DSPInterpreter::unknown; prologueTable[i] = NULL; @@ -346,7 +364,7 @@ void InitInstructionTable() opSize[i] = 0; } - for (u32 i = 0; i < OPTABLE_SIZE; i++) + for (int i = 0; i < OPTABLE_SIZE; i++) { for (u32 j = 0; j < opcodes_size; j++) { diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.h index 309cd9bad5..4805f1cbd4 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.h +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/DSPTables.h @@ -118,4 +118,8 @@ void InitInstructionTable(); void ComputeInstruction(const UDSPInstruction& inst); +// This one's pretty slow, try to use it only at init or seldomly. +// returns NULL if no matching instruction. +const DSPOPCTemplate *GetOpTemplate(const UDSPInstruction &inst); + #endif // _DSPTABLES_H diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interface.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interface.cpp index d38f9ec910..ec9b5af594 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interface.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interface.cpp @@ -24,8 +24,10 @@ ====================================================================*/ #include + #include "Globals.h" #include "Thread.h" +#include "MemoryUtil.h" #include "gdsp_aram.h" #include "gdsp_interpreter.h" @@ -163,11 +165,8 @@ void gdsp_ifx_write(u16 addr, u16 val) switch (addr & 0xff) { case 0xfb: // DIRQ - if (val & 0x1) - { g_dsp.irq_request(); - } break; @@ -246,13 +245,15 @@ u16 gdsp_ifx_read(u16 addr) void gdsp_idma_in(u16 dsp_addr, u32 addr, u32 size) { - u8* dst = ((u8*)g_dsp.iram); + UnWriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); + u8* dst = ((u8*)g_dsp.iram); for (u32 i = 0; i < size; i += 2) { // TODO : this may be different on Wii. *(u16*)&dst[dsp_addr + i] = *(u16*)&g_dsp.cpu_ram[(addr + i) & 0x0fffffff]; } + WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); g_dsp.iram_crc = GenerateCRC(g_dsp.cpu_ram + (addr & 0x0fffffff), size); INFO_LOG(DSPLLE, "*** Copy new UCode from 0x%08x to 0x%04x (crc: %8x)\n", addr, dsp_addr, g_dsp.iram_crc); diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp index 6ccd1ec611..76228191fd 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.cpp @@ -31,34 +31,12 @@ #include "gdsp_interface.h" #include "gdsp_opcodes_helper.h" #include "Tools.h" +#include "MemoryUtil.h" //------------------------------------------------------------------------------- SDSP g_dsp; -u16 SDSP::r[32]; -u16 SDSP::pc = 0; -u16 SDSP::err_pc = 0; -u16* SDSP::iram = 0; -u16* SDSP::dram = 0; -u16* SDSP::irom = 0; -u16* SDSP::drom = 0; -u16* SDSP::coef = 0; -u8* SDSP::cpu_ram = 0; -u16 SDSP::cr = 0; -u8 SDSP::reg_stack_ptr[4]; -u8 SDSP::exceptions; - -// lets make stack depth to 32 for now -u16 SDSP::reg_stack[4][DSP_STACK_DEPTH]; -void (*SDSP::irq_request)() = NULL; -bool SDSP::exception_in_progress_hack = false; // should be replaced with bit9 in SR? - -// for debugger only -bool SDSP::dump_imem = true; -u32 SDSP::iram_crc = 0; -u64 SDSP::step_counter = 0; - bool gdsp_running; extern volatile u32 dsp_running; @@ -75,28 +53,17 @@ void UpdateCachedCR() void gdsp_init() { - // Why do we have DROM? Does it exist? Has it been dumped? - g_dsp.irom = (u16*)malloc(DSP_IROM_SIZE * sizeof(u16)); - g_dsp.iram = (u16*)malloc(DSP_IRAM_SIZE * sizeof(u16)); - g_dsp.drom = (u16*)malloc(DSP_DROM_SIZE * sizeof(u16)); - g_dsp.dram = (u16*)malloc(DSP_DRAM_SIZE * sizeof(u16)); - g_dsp.coef = (u16*)malloc(DSP_COEF_SIZE * sizeof(u16)); + // Dump IMEM when ucodes get uploaded. Why not... still a plugin heavily in dev. + g_dsp.dump_imem = true; - // Fill memories with junk. - for (int i = 0; i < DSP_IRAM_SIZE; i++) - { - g_dsp.iram[i] = 0x0021; // HALT opcode - } - - for (int i = 0; i < DSP_DRAM_SIZE; i++) - { - g_dsp.dram[i] = 0x0021; // HALT opcode - } + g_dsp.irom = (u16*)AllocateMemoryPages(DSP_IROM_BYTE_SIZE); + g_dsp.iram = (u16*)AllocateMemoryPages(DSP_IRAM_BYTE_SIZE); + g_dsp.dram = (u16*)AllocateMemoryPages(DSP_DRAM_BYTE_SIZE); + g_dsp.coef = (u16*)AllocateMemoryPages(DSP_COEF_BYTE_SIZE); // Fill roms with zeros. - memset(g_dsp.irom, 0, DSP_IROM_SIZE * sizeof(u16)); - memset(g_dsp.drom, 0, DSP_DROM_SIZE * sizeof(u16)); - memset(g_dsp.coef, 0, DSP_COEF_SIZE * sizeof(u16)); + memset(g_dsp.irom, 0, DSP_IROM_BYTE_SIZE); + memset(g_dsp.coef, 0, DSP_COEF_BYTE_SIZE); for (int i = 0; i < 32; i++) { @@ -113,6 +80,17 @@ void gdsp_init() } } + // Fill memories with junk. + for (int i = 0; i < DSP_IRAM_SIZE; i++) + { + g_dsp.iram[i] = 0x0021; // HALT opcode + } + + for (int i = 0; i < DSP_DRAM_SIZE; i++) + { + g_dsp.dram[i] = 0x0021; // HALT opcode + } + // copied from a real console after the custom UCode has been loaded g_dsp.r[0x08] = 0xffff; g_dsp.r[0x09] = 0xffff; @@ -123,12 +101,23 @@ void gdsp_init() gdsp_ifx_init(); UpdateCachedCR(); + + // Mostly keep IRAM write protected. We unprotect only when DMA-ing + // in new ucodes. + WriteProtectMemory(g_dsp.iram, DSP_IRAM_BYTE_SIZE, false); +} + +void gdsp_shutdown() +{ + FreeMemoryPages(g_dsp.irom, DSP_IROM_BYTE_SIZE); + FreeMemoryPages(g_dsp.iram, DSP_IRAM_BYTE_SIZE); + FreeMemoryPages(g_dsp.dram, DSP_DRAM_BYTE_SIZE); + FreeMemoryPages(g_dsp.coef, DSP_COEF_BYTE_SIZE); } void gdsp_reset() { -// _assert_msg_(0, "gdsp_reset()"); _assert_msg_(MASTER_LOG, !g_dsp.exception_in_progress_hack, "reset while exception"); g_dsp.pc = DSP_RESET_VECTOR; g_dsp.exception_in_progress_hack = false; @@ -140,11 +129,9 @@ void gdsp_generate_exception(u8 level) g_dsp.exceptions |= 1 << level; } - -bool gdsp_load_rom(const char *fname) +bool gdsp_load_irom(const char *fname) { FILE *pFile = fopen(fname, "rb"); - if (pFile) { size_t size_in_bytes = DSP_IROM_SIZE * sizeof(u16); @@ -158,15 +145,14 @@ bool gdsp_load_rom(const char *fname) fclose(pFile); return true; } - + // Always keep IROM write protected. + WriteProtectMemory(g_dsp.irom, DSP_IROM_BYTE_SIZE, false); return false; } - bool gdsp_load_coef(const char *fname) { FILE *pFile = fopen(fname, "rb"); - if (pFile) { size_t size_in_bytes = DSP_COEF_SIZE * sizeof(u16); @@ -180,7 +166,8 @@ bool gdsp_load_coef(const char *fname) fclose(pFile); return true; } - + // Always keep COEF write protected. We unprotect only when DMA-ing + WriteProtectMemory(g_dsp.coef, DSP_COEF_BYTE_SIZE, false); return false; } diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.h b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.h index 6a7891b0cb..4c614397e8 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.h +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_interpreter.h @@ -45,55 +45,60 @@ #include "Globals.h" -// Are these in bytes or 16-bit words? Probably 16-bit words. -#define DSP_IRAM_SIZE (0x1000) -#define DSP_IRAM_MASK (0x0fff) -#define DSP_IROM_SIZE (0x1000) -#define DSP_IROM_MASK (0x0fff) -#define DSP_DRAM_SIZE (0x1000) -#define DSP_DRAM_MASK (0x0fff) -#define DSP_DROM_SIZE (0x1000) -#define DSP_DROM_MASK (0x0fff) -#define DSP_COEF_SIZE (0x1000) -#define DSP_COEF_MASK (0x0fff) +#define DSP_IRAM_BYTE_SIZE 0x2000 +#define DSP_IRAM_SIZE 0x1000 +#define DSP_IRAM_MASK 0x0fff -#define DSP_RESET_VECTOR (0x8000) +#define DSP_IROM_BYTE_SIZE 0x2000 +#define DSP_IROM_SIZE 0x1000 +#define DSP_IROM_MASK 0x0fff + +#define DSP_DRAM_BYTE_SIZE 0x2000 +#define DSP_DRAM_SIZE 0x1000 +#define DSP_DRAM_MASK 0x0fff + +#define DSP_COEF_BYTE_SIZE 0x2000 +#define DSP_COEF_SIZE 0x1000 +#define DSP_COEF_MASK 0x0fff + +#define DSP_RESET_VECTOR 0x8000 #define DSP_STACK_DEPTH 0x20 #define DSP_STACK_MASK 0x1f struct SDSP { - static u16 r[32]; - static u16 pc; - static u16 err_pc; - static u16* iram; - static u16* dram; - static u16* irom; - static u16* drom; - static u16* coef; - static u8* cpu_ram; - static u16 cr; - static u8 reg_stack_ptr[4]; - static u8 exceptions; // pending exceptiosn? + u16 r[32]; + u16 pc; + u16 err_pc; + u16* iram; + u16* dram; + u16* irom; + u16* coef; + u8* cpu_ram; + u16 cr; + u8 reg_stack_ptr[4]; + u8 exceptions; // pending exceptiosn? // lets make stack depth to 32 for now - static u16 reg_stack[4][DSP_STACK_DEPTH]; - static void (* irq_request)(void); + u16 reg_stack[4][DSP_STACK_DEPTH]; + void (* irq_request)(void); // for debugger only - static bool dump_imem; - static u32 iram_crc; - static u64 step_counter; - static bool exception_in_progress_hack; + bool dump_imem; + u32 iram_crc; + u64 step_counter; + bool exception_in_progress_hack; }; extern SDSP g_dsp; -void gdsp_init(void); -void gdsp_reset(void); -bool gdsp_load_rom(const char *fname); +void gdsp_init(); +void gdsp_reset(); +void gdsp_shutdown(); + +bool gdsp_load_irom(const char *fname); bool gdsp_load_coef(const char *fname); diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_memory.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_memory.cpp index 233b1cecb8..055af25534 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_memory.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/gdsp_memory.cpp @@ -37,15 +37,22 @@ u16 dsp_swap16(u16 x) u16 dsp_imem_read(u16 addr) { - if (g_dsp.pc & 0x8000) - return dsp_swap16(g_dsp.irom[addr & DSP_IROM_MASK]); - else + switch (addr >> 12) + { + case 0: return dsp_swap16(g_dsp.iram[addr & DSP_IRAM_MASK]); + case 8: + return dsp_swap16(g_dsp.irom[addr & DSP_IROM_MASK]); + default: + ERROR_LOG(DSPLLE, "%04x DSP ERROR: Executing from invalid (%04x) memory", g_dsp.pc, addr); + return 0; + } } u16 dsp_dmem_read(u16 addr) { - switch (addr >> 12) { + switch (addr >> 12) + { case 0x0: // 0xxx DRAM return dsp_swap16(g_dsp.dram[addr & DSP_DRAM_MASK]); @@ -58,10 +65,6 @@ u16 dsp_dmem_read(u16 addr) case 0x4: break;*/ - case 0x8: // 8xxx DROM - ERROR_LOG(DSPLLE, "someone reads from ROM"); - return dsp_swap16(g_dsp.drom[addr & DSP_DROM_MASK]); - case 0xf: // Fxxx HW regs return gdsp_ifx_read(addr); @@ -84,12 +87,6 @@ void dsp_dmem_write(u16 addr, u16 val) ERROR_LOG(DSPLLE, "someone writes to COEF"); break; - case 0x8: // 8xxx DROM - ERROR_LOG(DSPLLE, "someone writes to DROM"); - /* val = dsp_swap16(val); - g_dsp.drom[addr & DSP_DROM_MASK] = val;*/ - break; - case 0xf: // Fxxx HW regs gdsp_ifx_write(addr, val); break; diff --git a/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp b/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp index 8f001dc156..08af7d09da 100644 --- a/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp +++ b/Source/Plugins/Plugin_DSP_LLE-testing/Src/main.cpp @@ -231,14 +231,17 @@ void Initialize(void *init) g_dsp.step_counter = 0; g_dsp.cpu_ram = g_dspInitialize.pGetMemoryPointer(0); g_dsp.irq_request = dspi_req_dsp_irq; +// g_dsp.exception_in_progress_hack = false; gdsp_reset(); - if (!gdsp_load_rom(DSP_IROM_FILE)) { + if (!gdsp_load_irom(DSP_IROM_FILE)) + { bCanWork = false; PanicAlert("Failed loading DSP ROM from " DSP_IROM_FILE); } - if (!gdsp_load_coef(DSP_COEF_FILE)) { + if (!gdsp_load_coef(DSP_COEF_FILE)) + { bCanWork = false; PanicAlert("Failed loading DSP COEF from " DSP_COEF_FILE); } @@ -248,10 +251,10 @@ void Initialize(void *init) bIsRunning = true; + InitInstructionTable(); + g_hDSPThread = new Common::Thread(dsp_thread, NULL); soundStream = AudioCommon::InitSoundStream(); - - InitInstructionTable(); } void DSP_StopSoundStream() @@ -262,9 +265,10 @@ void DSP_StopSoundStream() g_hDSPThread = NULL; } -void Shutdown(void) +void Shutdown() { AudioCommon::ShutdownSoundStream(); + gdsp_shutdown(); } u16 DSP_WriteControlRegister(u16 _uFlag)