DSP: Add txt file with luigi ucode comments (very basic). Rename some stuff. Remove function pointer in g_dsp structure, replace with a "Host" function call. Fix a problem where symbols weren't loaded into DSP debugger.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3563 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2009-06-28 10:00:25 +00:00
parent 7ea2bc5da9
commit 895b02f410
34 changed files with 2826 additions and 250 deletions

View File

@ -58,8 +58,7 @@
#include "WII_IPC_HLE_Device_net.h" #include "WII_IPC_HLE_Device_net.h"
#include <stdio.h> #include <stdio.h>
#ifdef _WIN32 #ifdef _WIN32
#include <winsock.h> #include <ws2tcpip.h>
typedef int socklen_t;
#else #else
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
@ -287,7 +286,7 @@ u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommand(u32 _Command, u32 _BufferIn,
// Clean the location of the output buffer to zeroes as a safety precaution */ // Clean the location of the output buffer to zeroes as a safety precaution */
Memory::Memset(BufferOut, 0, BufferOutSize); Memory::Memset(BufferOut, 0, BufferOutSize);
switch(_Command) switch (_Command)
{ {
case IOCTL_SO_STARTUP: case IOCTL_SO_STARTUP:
break; break;
@ -297,7 +296,7 @@ u32 CWII_IPC_HLE_Device_net_ip_top::ExecuteCommand(u32 _Command, u32 _BufferIn,
u32 TYPE = Memory::Read_U32(_BufferIn + 0x04); u32 TYPE = Memory::Read_U32(_BufferIn + 0x04);
u32 PROT = Memory::Read_U32(_BufferIn + 0x04 * 2); u32 PROT = Memory::Read_U32(_BufferIn + 0x04 * 2);
u32 Unk1 = Memory::Read_U32(_BufferIn + 0x04 * 3); u32 Unk1 = Memory::Read_U32(_BufferIn + 0x04 * 3);
u32 Socket = socket(AF,TYPE,PROT); u32 Socket = socket(AF, TYPE, PROT);
return Common::swap32(Socket); // So it doesn't get mangled later on return Common::swap32(Socket); // So it doesn't get mangled later on
} }
break; break;

View File

@ -413,6 +413,14 @@
RelativePath=".\Src\DspIntBranch.cpp" RelativePath=".\Src\DspIntBranch.cpp"
> >
</File> </File>
<File
RelativePath=".\Src\DSPIntExtOps.cpp"
>
</File>
<File
RelativePath=".\Src\DSPIntExtOps.h"
>
</File>
<File <File
RelativePath=".\Src\DspIntLoadStore.cpp" RelativePath=".\Src\DspIntLoadStore.cpp"
> >
@ -425,6 +433,10 @@
RelativePath=".\Src\DspIntMultiplier.cpp" RelativePath=".\Src\DspIntMultiplier.cpp"
> >
</File> </File>
<File
RelativePath=".\Src\DSPIntUtil.h"
>
</File>
</Filter> </Filter>
<Filter <Filter
Name="Debugger" Name="Debugger"
@ -446,6 +458,14 @@
RelativePath=".\Src\disassemble.h" RelativePath=".\Src\disassemble.h"
> >
</File> </File>
<File
RelativePath=".\Src\DSPAccelerator.cpp"
>
</File>
<File
RelativePath=".\Src\DSPAccelerator.h"
>
</File>
<File <File
RelativePath=".\Src\DSPAnalyzer.cpp" RelativePath=".\Src\DSPAnalyzer.cpp"
> >
@ -486,6 +506,14 @@
RelativePath=".\Src\DSPJit.h" RelativePath=".\Src\DSPJit.h"
> >
</File> </File>
<File
RelativePath=".\Src\DSPMemoryMap.cpp"
>
</File>
<File
RelativePath=".\Src\DSPMemoryMap.h"
>
</File>
<File <File
RelativePath=".\Src\DSPTables.cpp" RelativePath=".\Src\DSPTables.cpp"
> >
@ -494,14 +522,6 @@
RelativePath=".\Src\DSPTables.h" RelativePath=".\Src\DSPTables.h"
> >
</File> </File>
<File
RelativePath=".\Src\gdsp_aram.cpp"
>
</File>
<File
RelativePath=".\Src\gdsp_aram.h"
>
</File>
<File <File
RelativePath=".\Src\gdsp_condition_codes.cpp" RelativePath=".\Src\gdsp_condition_codes.cpp"
> >
@ -510,14 +530,6 @@
RelativePath=".\Src\gdsp_condition_codes.h" RelativePath=".\Src\gdsp_condition_codes.h"
> >
</File> </File>
<File
RelativePath=".\Src\gdsp_ext_op.cpp"
>
</File>
<File
RelativePath=".\Src\gdsp_ext_op.h"
>
</File>
<File <File
RelativePath=".\Src\gdsp_interface.cpp" RelativePath=".\Src\gdsp_interface.cpp"
> >
@ -534,18 +546,6 @@
RelativePath=".\Src\gdsp_interpreter.h" RelativePath=".\Src\gdsp_interpreter.h"
> >
</File> </File>
<File
RelativePath=".\Src\gdsp_memory.cpp"
>
</File>
<File
RelativePath=".\Src\gdsp_memory.h"
>
</File>
<File
RelativePath=".\Src\gdsp_opcodes_helper.h"
>
</File>
<File <File
RelativePath=".\Src\gdsp_registers.cpp" RelativePath=".\Src\gdsp_registers.cpp"
> >

View File

@ -15,8 +15,8 @@
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#ifndef _GDSP_ARAM_H #ifndef _DSP_ACCELERATOR_H
#define _GDSP_ARAM_H #define _DSP_ACCELERATOR_H
u16 dsp_read_accelerator(); u16 dsp_read_accelerator();

View File

@ -18,7 +18,7 @@
#include "DSPAnalyzer.h" #include "DSPAnalyzer.h"
#include "DSPInterpreter.h" #include "DSPInterpreter.h"
#include "DSPTables.h" #include "DSPTables.h"
#include "gdsp_memory.h" #include "DSPMemoryMap.h"
namespace DSPAnalyzer { namespace DSPAnalyzer {
@ -30,12 +30,13 @@ u8 code_flags[ISPACE];
// as well give up its time slice immediately, after executing once. // as well give up its time slice immediately, after executing once.
// Max signature length is 6. A 0 in a signature is ignored. // Max signature length is 6. A 0 in a signature is ignored.
#define NUM_IDLE_SIGS 4 #define NUM_IDLE_SIGS 5
#define MAX_IDLE_SIG_SIZE 6 #define MAX_IDLE_SIG_SIZE 6
// 0xFFFF means ignore. // 0xFFFF means ignore.
const u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] = const u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] =
{ {
// From AX:
{ 0x26fc, // LRS $30, @DMBH { 0x26fc, // LRS $30, @DMBH
0x02c0, 0x8000, // ANDCF $30, #0x8000 0x02c0, 0x8000, // ANDCF $30, #0x8000
0x029d, 0xFFFF, // JLZ 0x027a 0x029d, 0xFFFF, // JLZ 0x027a
@ -52,6 +53,12 @@ const u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] =
0x03c0, 0x8000, // ANDCF $31, #0x8000 0x03c0, 0x8000, // ANDCF $31, #0x8000
0x029c, 0xFFFF, // JLNZ 0x0280 0x029c, 0xFFFF, // JLNZ 0x0280
0, 0 }, // RET 0, 0 }, // RET
// From Zelda:
{ 0x00de, 0xFFFE, // LR $AC0.M, @CMBH
0x02c0, 0x8000, // ANDCF $AC0.M, #0x8000
0x029c, 0xFFFF, // JLNZ 0x05cf
0 }
}; };
void Reset() void Reset()

View File

@ -30,7 +30,7 @@
#include "gdsp_interface.h" #include "gdsp_interface.h"
#include "gdsp_registers.h" #include "gdsp_registers.h"
#include "gdsp_opcodes_helper.h" #include "DSPIntUtil.h"
SDSP g_dsp; SDSP g_dsp;
@ -156,8 +156,7 @@ void DSPCore_CheckExternalInterrupt()
// level 7 is the interrupt exception // level 7 is the interrupt exception
DSPCore_SetException(7); DSPCore_SetException(7);
// Uh, confusing. Can this really be right? g_dsp.cr &= ~CR_EXTERNAL_INT;
g_dsp.cr &= ~0x0002;
} }
} }
} }

View File

@ -59,23 +59,35 @@ struct SDSP
#if PROFILE #if PROFILE
u16 err_pc; u16 err_pc;
#endif #endif
u16 *iram;
u16 *dram; // This is NOT the same cr as r[DSP_REG_CR].
u16 *irom; // This register is shared with the main emulation, see DSP.cpp
u16 *coef; // The plugin has control over 0x0C07 of this reg.
u8 *cpu_ram; // Bits are defined in a struct in DSP.cpp.
u16 cr; u16 cr;
u8 reg_stack_ptr[4]; u8 reg_stack_ptr[4];
u8 exceptions; // pending exceptions? u8 exceptions; // pending exceptions?
bool exception_in_progress_hack; // is this the same as "exception enabled"? bool exception_in_progress_hack; // is this the same as "exception enabled"?
// lets make stack depth to 32 for now // Let's make stack depth 32 for now. The real DSP has different depths
// for the different stacks, but it would be strange if any ucode relied on stack
// overflows since on the DSP, when the stack overflows, you're screwed.
u16 reg_stack[4][DSP_STACK_DEPTH]; u16 reg_stack[4][DSP_STACK_DEPTH];
void (*irq_request)(void);
// for debugger only // For debugging.
u32 iram_crc; u32 iram_crc;
u64 step_counter; u64 step_counter;
// When state saving, all of the above can just be memcpy'd into the save state.
// The below needs special handling.
u16 *iram;
u16 *dram;
u16 *irom;
u16 *coef;
// This one doesn't really belong here.
u8 *cpu_ram;
}; };
extern SDSP g_dsp; extern SDSP g_dsp;

View File

@ -27,6 +27,7 @@ u8 DSPHost_ReadHostMemory(u32 addr);
void DSPHost_WriteHostMemory(u8 value, u32 addr); void DSPHost_WriteHostMemory(u8 value, u32 addr);
bool DSPHost_OnThread(); bool DSPHost_OnThread();
bool DSPHost_Running(); bool DSPHost_Running();
void DSPHost_InterruptRequest();
u32 DSPHost_CodeLoaded(const u8 *ptr, int size); u32 DSPHost_CodeLoaded(const u8 *ptr, int size);
#endif #endif

View File

@ -23,8 +23,8 @@
====================================================================*/ ====================================================================*/
#include "gdsp_opcodes_helper.h" #include "DSPIntUtil.h"
#include "gdsp_memory.h" #include "DSPMemoryMap.h"
// Extended opcodes do not exist on their own. These opcodes can only be // Extended opcodes do not exist on their own. These opcodes can only be
// attached to opcodes that allow extending (8 lower bits of opcode not used by // attached to opcodes that allow extending (8 lower bits of opcode not used by

View File

@ -23,19 +23,18 @@
====================================================================*/ ====================================================================*/
#ifndef _GDSP_OPCODES_HELPER_H #ifndef _DSP_INT_UTIL_H
#define _GDSP_OPCODES_HELPER_H #define _DSP_INT_UTIL_H
#include "Common.h" #include "Common.h"
#include "DSPInterpreter.h" #include "DSPInterpreter.h"
#include "DSPCore.h" #include "DSPCore.h"
#include "DSPMemoryMap.h"
#include "gdsp_memory.h"
#include "gdsp_interpreter.h" #include "gdsp_interpreter.h"
#include "gdsp_registers.h" #include "gdsp_registers.h"
#include "gdsp_ext_op.h" // #include "DSPIntExtOps.h"
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// --- SR // --- SR
@ -51,20 +50,8 @@ inline bool dsp_SR_is_flag_set(int flag)
} }
// See http://code.google.com/p/dolphin-emu/source/detail?r=3125
inline void dsp_decrement_addr_reg(int reg)
{
// This one was easy. increment is worse...
if ((g_dsp.r[reg] & g_dsp.r[DSP_REG_WR0 + reg]) == 0)
g_dsp.r[reg] |= g_dsp.r[DSP_REG_WR0 + reg];
else
g_dsp.r[reg]--;
}
// HORRIBLE UGLINESS, someone please fix. // HORRIBLE UGLINESS, someone please fix.
// See http://code.google.com/p/dolphin-emu/source/detail?r=3125 // See http://code.google.com/p/dolphin-emu/source/detail?r=3125
inline u16 ToMask(u16 a) inline u16 ToMask(u16 a)
{ {
a = a | (a >> 8); a = a | (a >> 8);
@ -82,6 +69,16 @@ inline void dsp_increment_addr_reg(int reg)
g_dsp.r[reg]++; g_dsp.r[reg]++;
} }
// See http://code.google.com/p/dolphin-emu/source/detail?r=3125
inline void dsp_decrement_addr_reg(int reg)
{
// This one is easy. Looks like a hw implementation. Increment is worse...
if ((g_dsp.r[reg] & g_dsp.r[DSP_REG_WR0 + reg]) == 0)
g_dsp.r[reg] |= g_dsp.r[DSP_REG_WR0 + reg];
else
g_dsp.r[reg]--;
}
inline void dsp_increase_addr_reg(int reg, s16 value) inline void dsp_increase_addr_reg(int reg, s16 value)
{ {
// TODO: DO RIGHT! // TODO: DO RIGHT!

View File

@ -26,20 +26,20 @@
#include <stdio.h> #include <stdio.h>
#include "gdsp_interpreter.h" #include "gdsp_interpreter.h"
#include "gdsp_memory.h"
#include "gdsp_interface.h" #include "gdsp_interface.h"
#include "DSPMemoryMap.h"
#include "DSPCore.h" #include "DSPCore.h"
u16 dsp_imem_read(u16 addr) u16 dsp_imem_read(u16 addr)
{ {
switch (addr >> 12) switch (addr >> 12)
{ {
case 0: case 0: // 0xxx IRAM
return g_dsp.iram[addr & DSP_IRAM_MASK]; return g_dsp.iram[addr & DSP_IRAM_MASK];
case 8: case 8: // 8xxx IROM - contains code to receive code for IRAM, and a bunch of mixing loops.
return g_dsp.irom[addr & DSP_IROM_MASK]; return g_dsp.irom[addr & DSP_IROM_MASK];
default: default: // Unmapped/non-existing memory
ERROR_LOG(DSPLLE, "%04x DSP ERROR: Executing from invalid (%04x) memory", g_dsp.pc, addr); ERROR_LOG(DSPLLE, "%04x DSP ERROR: Executing from invalid (%04x) memory", g_dsp.pc, addr);
return 0; return 0;
} }
@ -49,16 +49,17 @@ u16 dsp_dmem_read(u16 addr)
{ {
switch (addr >> 12) switch (addr >> 12)
{ {
case 0x0: // 0xxx DRAM case 0x0: // 0xxx DRAM
return g_dsp.dram[addr & DSP_DRAM_MASK]; return g_dsp.dram[addr & DSP_DRAM_MASK];
case 0x1: // 1xxx COEF case 0x1: // 1xxx COEF
// DEBUG_LOG(DSPLLE, "%04x : Coef Read @ %04x", g_dsp.pc, addr);
return g_dsp.coef[addr & DSP_COEF_MASK]; return g_dsp.coef[addr & DSP_COEF_MASK];
case 0xf: // Fxxx HW regs case 0xf: // Fxxx HW regs
return gdsp_ifx_read(addr); return gdsp_ifx_read(addr);
default: // error default: // Unmapped/non-existing memory
ERROR_LOG(DSPLLE, "%04x DSP ERROR: Read from UNKNOWN (%04x) memory", g_dsp.pc, addr); ERROR_LOG(DSPLLE, "%04x DSP ERROR: Read from UNKNOWN (%04x) memory", g_dsp.pc, addr);
return 0; return 0;
} }
@ -73,14 +74,14 @@ void dsp_dmem_write(u16 addr, u16 val)
break; break;
case 0x1: // 1xxx COEF case 0x1: // 1xxx COEF
ERROR_LOG(DSPLLE, "someone writes to COEF (pc = %02x)", g_dsp.pc); ERROR_LOG(DSPLLE, "Illegal write to COEF (pc = %02x)", g_dsp.pc);
break; break;
case 0xf: // Fxxx HW regs case 0xf: // Fxxx HW regs
gdsp_ifx_write(addr, val); gdsp_ifx_write(addr, val);
break; break;
default: // error default: // Unmapped/non-existing memory
ERROR_LOG(DSPLLE, "%04x DSP ERROR: Write to UNKNOWN (%04x) memory", g_dsp.pc, addr); ERROR_LOG(DSPLLE, "%04x DSP ERROR: Write to UNKNOWN (%04x) memory", g_dsp.pc, addr);
break; break;
} }

View File

@ -22,6 +22,7 @@
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
====================================================================*/ ====================================================================*/
#ifndef _GDSP_MEMORY_H #ifndef _GDSP_MEMORY_H
#define _GDSP_MEMORY_H #define _GDSP_MEMORY_H

View File

@ -53,7 +53,7 @@ jnz, ifs, retlnz
#include "DSPInterpreter.h" #include "DSPInterpreter.h"
#include "DSPJit.h" #include "DSPJit.h"
#include "gdsp_ext_op.h" #include "DSPIntExtOps.h"
void nop(const UDSPInstruction& opc) void nop(const UDSPInstruction& opc)
{ {

View File

@ -20,7 +20,7 @@
#include "DSPInterpreter.h" #include "DSPInterpreter.h"
#include "gdsp_condition_codes.h" #include "gdsp_condition_codes.h"
#include "gdsp_opcodes_helper.h" #include "DSPIntUtil.h"
// Arithmetic and accumulator control. // Arithmetic and accumulator control.

View File

@ -21,9 +21,8 @@
#include "DSPCore.h" #include "DSPCore.h"
#include "gdsp_condition_codes.h" #include "gdsp_condition_codes.h"
#include "gdsp_opcodes_helper.h" #include "DSPIntUtil.h"
#include "gdsp_memory.h" #include "DSPMemoryMap.h"
namespace DSPInterpreter { namespace DSPInterpreter {

View File

@ -19,8 +19,8 @@
#include "DSPInterpreter.h" #include "DSPInterpreter.h"
#include "gdsp_memory.h" #include "DSPMemoryMap.h"
#include "gdsp_opcodes_helper.h" #include "DSPIntUtil.h"
namespace DSPInterpreter { namespace DSPInterpreter {

View File

@ -23,7 +23,7 @@
#include "DSPCore.h" #include "DSPCore.h"
#include "gdsp_registers.h" #include "gdsp_registers.h"
#include "gdsp_opcodes_helper.h" #include "DSPIntUtil.h"
namespace DSPInterpreter { namespace DSPInterpreter {

View File

@ -23,7 +23,7 @@
#include "DSPInterpreter.h" #include "DSPInterpreter.h"
#include "gdsp_condition_codes.h" #include "gdsp_condition_codes.h"
#include "gdsp_opcodes_helper.h" #include "DSPIntUtil.h"
#include "gdsp_registers.h" #include "gdsp_registers.h"
namespace DSPInterpreter { namespace DSPInterpreter {

View File

@ -32,7 +32,7 @@
#include "DSPHost.h" #include "DSPHost.h"
#include "DSPTables.h" #include "DSPTables.h"
#include "DSPAnalyzer.h" #include "DSPAnalyzer.h"
#include "gdsp_aram.h" #include "DSPAccelerator.h"
#include "gdsp_interpreter.h" #include "gdsp_interpreter.h"
#include "gdsp_interface.h" #include "gdsp_interface.h"
@ -124,7 +124,7 @@ void gdsp_ifx_write(u16 addr, u16 val)
{ {
case 0xfb: // DIRQ case 0xfb: // DIRQ
if (val & 0x1) if (val & 0x1)
g_dsp.irq_request(); DSPHost_InterruptRequest();
break; break;
case 0xfc: // DMBH case 0xfc: // DMBH
@ -311,5 +311,3 @@ void gdsp_dma()
break; break;
} }
} }

View File

@ -32,12 +32,14 @@
#include "DSPAnalyzer.h" #include "DSPAnalyzer.h"
#include "gdsp_interface.h" #include "gdsp_interface.h"
#include "gdsp_opcodes_helper.h" #include "DSPIntUtil.h"
namespace DSPInterpreter { namespace DSPInterpreter {
volatile u32 gdsp_running; volatile u32 gdsp_running;
// NOTE: These have nothing to do with g_dsp.r[DSP_REG_CR].
// Hm, should instructions that change CR use this? Probably not (but they // Hm, should instructions that change CR use this? Probably not (but they
// should call UpdateCachedCR()) // should call UpdateCachedCR())
void WriteCR(u16 val) void WriteCR(u16 val)
@ -69,6 +71,8 @@ u16 ReadCR()
return g_dsp.cr; return g_dsp.cr;
} }
void HandleLoop() void HandleLoop()
{ {
// Handle looping hardware. // Handle looping hardware.

View File

@ -93,7 +93,8 @@
#define DSP_STACK_D 1 #define DSP_STACK_D 1
// CR bits // cr (Not g_dsp.r[CR]) bits
// See HW/DSP.cpp.
#define CR_HALT 0x0004 #define CR_HALT 0x0004
#define CR_EXTERNAL_INT 0x0002 #define CR_EXTERNAL_INT 0x0002

View File

@ -19,14 +19,13 @@
#include "FileUtil.h" #include "FileUtil.h"
#include "DSPCodeUtil.h" #include "DSPCodeUtil.h"
//#include "dsp_test.h"
// Stub out the dsplib host stuff, since this is just a simple cmdline tools. // Stub out the dsplib host stuff, since this is just a simple cmdline tools.
u8 DSPHost_ReadHostMemory(u32 addr) { return 0; } u8 DSPHost_ReadHostMemory(u32 addr) { return 0; }
void DSPHost_WriteHostMemory(u8 value, u32 addr) {} void DSPHost_WriteHostMemory(u8 value, u32 addr) {}
bool DSPHost_OnThread() { return false; } bool DSPHost_OnThread() { return false; }
bool DSPHost_Running() { return true; } bool DSPHost_Running() { return true; }
u32 DSPHost_CodeLoaded(const u8 *ptr, int size) {return 0x1337c0de;} u32 DSPHost_CodeLoaded(const u8 *ptr, int size) {return 0x1337c0de;}
void DSPHost_InterruptRequest() {}
// This test goes from text ASM to binary to text ASM and once again back to binary. // This test goes from text ASM to binary to text ASM and once again back to binary.
// Then the two binaries are compared. // Then the two binaries are compared.

View File

@ -54,8 +54,8 @@ IUCode* UCodeFactory(u32 _CRC, CMailHandler& _rMailHandler)
case 0x088e38a5: // IPL - JAP case 0x088e38a5: // IPL - JAP
case 0xd73338cf: // IPL case 0xd73338cf: // IPL
case 0x42f64ac4: // Luigi (after fix) case 0x42f64ac4: // Luigi
case 0x4be6a5cb: // AC, Pikmin (after fix) case 0x4be6a5cb: // AC, Pikmin
INFO_LOG(CONSOLE, "JAC (early Zelda) ucode chosen\n"); INFO_LOG(CONSOLE, "JAC (early Zelda) ucode chosen\n");
return new CUCode_Jac(_rMailHandler); return new CUCode_Jac(_rMailHandler);
// return new CUCode_Zelda(_rMailHandler, false); // return new CUCode_Zelda(_rMailHandler, false);

View File

@ -21,7 +21,7 @@
#include "disassemble.h" #include "disassemble.h"
#include "DSPSymbols.h" #include "DSPSymbols.h"
#include "gdsp_memory.h" #include "DSPMemoryMap.h"
void DSPDebugInterface::disasm(unsigned int address, char *dest, int max_size) void DSPDebugInterface::disasm(unsigned int address, char *dest, int max_size)
{ {

View File

@ -23,6 +23,14 @@
extern DSPInitialize g_dspInitialize; extern DSPInitialize g_dspInitialize;
#if defined(HAVE_WX) && HAVE_WX
#include "DSPConfigDlgLLE.h"
#include "Debugger/Debugger.h" // For the DSPDebuggerLLE class
extern DSPDebuggerLLE* m_DebuggerFrame;
#endif
// The user of the DSPCore library must supply a few functions so that the // The user of the DSPCore library must supply a few functions so that the
// emulation core can access the environment it runs in. If the emulation // emulation core can access the environment it runs in. If the emulation
// core isn't used, for example in an asm/disasm tool, then most of these // core isn't used, for example in an asm/disasm tool, then most of these
@ -48,6 +56,12 @@ bool DSPHost_Running()
return !(*g_dspInitialize.pEmulatorState); return !(*g_dspInitialize.pEmulatorState);
} }
void DSPHost_InterruptRequest()
{
// Fire an interrupt on the PPC ASAP.
g_dspInitialize.pGenerateDSPInterrupt();
}
u32 DSPHost_CodeLoaded(const u8 *ptr, int size) u32 DSPHost_CodeLoaded(const u8 *ptr, int size)
{ {
u32 crc = GenerateCRC(ptr, size); u32 crc = GenerateCRC(ptr, size);
@ -68,13 +82,22 @@ u32 DSPHost_CodeLoaded(const u8 *ptr, int size)
// TODO: Don't hardcode for Zelda. // TODO: Don't hardcode for Zelda.
NOTICE_LOG(DSPLLE, "CRC: %08x", ector_crc); NOTICE_LOG(DSPLLE, "CRC: %08x", ector_crc);
if (ector_crc != 0x86840740 || !DSPSymbols::ReadAnnotatedAssembly("../../Docs/DSP/DSP_UC_Zelda.txt"))
{ DSPSymbols::Clear();
DSPSymbols::Clear(); bool success = false;
switch (ector_crc) {
case 0x86840740: success = DSPSymbols::ReadAnnotatedAssembly("../../Docs/DSP/DSP_UC_Zelda.txt"); break;
case 0x42f64ac4: success = DSPSymbols::ReadAnnotatedAssembly("../../Docs/DSP/DSP_UC_Luigi.txt"); break;
default: success = false; break;
}
if (!success) {
DSPSymbols::AutoDisassembly(0x0, 0x1000); DSPSymbols::AutoDisassembly(0x0, 0x1000);
} }
// Always add the ROM. // Always add the ROM.
DSPSymbols::AutoDisassembly(0x8000, 0x9000); DSPSymbols::AutoDisassembly(0x8000, 0x9000);
m_DebuggerFrame->Refresh();
return crc; return crc;
} }

View File

@ -77,7 +77,7 @@ wxGridCellAttr *CRegTable::GetAttr(int row, int col, wxGridCellAttr::wxAttrKind)
} }
DSPRegisterView::DSPRegisterView(wxWindow *parent, wxWindowID id) DSPRegisterView::DSPRegisterView(wxWindow *parent, wxWindowID id)
: wxGrid(parent, id) : wxGrid(parent, id, wxDefaultPosition, wxSize(130, 120))
{ {
SetTable(new CRegTable(), true); SetTable(new CRegTable(), true);
SetRowLabelSize(0); SetRowLabelSize(0);

View File

@ -41,7 +41,6 @@ DSPDebuggerLLE::DSPDebuggerLLE(wxWindow *parent, wxWindowID id, const wxString &
, m_CachedStepCounter(-1) , m_CachedStepCounter(-1)
, m_CachedCR(-1) , m_CachedCR(-1)
, m_State(RUN) , m_State(RUN)
, m_CachedUCodeCRC(-1)
{ {
CreateGUIControls(); CreateGUIControls();
} }
@ -64,31 +63,27 @@ void DSPDebuggerLLE::CreateGUIControls()
m_Toolbar->AddTool(ID_JUMPTOTOOL, wxT("Jump"), wxNullBitmap, wxT("Jump to a specific Address"), wxITEM_NORMAL); m_Toolbar->AddTool(ID_JUMPTOTOOL, wxT("Jump"), wxNullBitmap, wxT("Jump to a specific Address"), wxITEM_NORMAL);
m_Toolbar->AddSeparator(); m_Toolbar->AddSeparator();
m_Toolbar->AddCheckTool(ID_CHECK_ASSERTINT, wxT("AssertInt"), wxNullBitmap, wxNullBitmap, wxEmptyString);
m_Toolbar->AddCheckTool(ID_CHECK_HALT, wxT("Halt"), wxNullBitmap, wxNullBitmap, wxEmptyString);
m_Toolbar->AddCheckTool(ID_CHECK_INIT, wxT("Init"), wxNullBitmap, wxNullBitmap, wxEmptyString);
m_Toolbar->AddSeparator();
m_Toolbar->AddControl(new wxTextCtrl(m_Toolbar, ID_ADDRBOX, _T(""))); m_Toolbar->AddControl(new wxTextCtrl(m_Toolbar, ID_ADDRBOX, _T("")));
m_Toolbar->Realize(); m_Toolbar->Realize();
wxBoxSizer* sMain = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* sMain = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* sizerLeft = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sizerLeft = new wxBoxSizer(wxVERTICAL);
sizerLeft->Add(m_SymbolList = new wxListBox(this, ID_SYMBOLLIST, wxDefaultPosition, wxSize(90, 100), 0, NULL, wxLB_SORT), 1, wxEXPAND); sizerLeft->Add(m_SymbolList = new wxListBox(this, ID_SYMBOLLIST, wxDefaultPosition, wxSize(140, 100), 0, NULL, wxLB_SORT),
1, wxEXPAND);
m_CodeView = new CCodeView(&debug_interface, &DSPSymbols::g_dsp_symbol_db, this, ID_CODEVIEW); m_CodeView = new CCodeView(&debug_interface, &DSPSymbols::g_dsp_symbol_db, this, ID_CODEVIEW);
m_CodeView->SetPlain(); m_CodeView->SetPlain();
sMain->Add(sizerLeft, 1, wxALL|wxEXPAND, 0); sMain->Add(sizerLeft, 0, wxEXPAND, 0);
sMain->Add(m_CodeView, 4, wxALL|wxEXPAND, 5); sMain->Add(m_CodeView, 4, wxEXPAND, 0);
wxStaticLine* m_staticline = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL); wxStaticLine* m_staticline = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL);
sMain->Add(m_staticline, 0, wxEXPAND|wxALL, 5); sMain->Add(m_staticline, 0, wxEXPAND|wxALL, 0);
m_Regs = new DSPRegisterView(this, ID_DSP_REGS); m_Regs = new DSPRegisterView(this, ID_DSP_REGS);
sMain->Add(m_Regs, 1, wxEXPAND|wxALL, 5); sMain->Add(m_Regs, 0, wxEXPAND|wxALL, 5);
this->SetSizer(sMain); this->SetSizer(sMain);
this->Layout(); this->Layout();
@ -165,28 +160,15 @@ void DSPDebuggerLLE::UpdateSymbolMap()
if (g_dsp.dram == NULL) if (g_dsp.dram == NULL)
return; return;
if (m_CachedUCodeCRC != g_dsp.iram_crc) m_SymbolList->Freeze(); // HyperIris: wx style fast filling
m_SymbolList->Clear();
for (SymbolDB::XFuncMap::iterator iter = DSPSymbols::g_dsp_symbol_db.GetIterator();
iter != DSPSymbols::g_dsp_symbol_db.End(); iter++)
{ {
// load symbol map (if there is one) int idx = m_SymbolList->Append(wxString::FromAscii(iter->second.name.c_str()));
m_CachedUCodeCRC = g_dsp.iram_crc; m_SymbolList->SetClientData(idx, (void*)&iter->second);
char FileName[256];
sprintf(FileName, "%sDSP_%08x.map", FULL_MAPS_DIR, m_CachedUCodeCRC);
// LoadSymbolMap(FileName);
m_SymbolList->Freeze(); // HyperIris: wx style fast filling
m_SymbolList->Clear();
for (SymbolDB::XFuncMap::iterator iter = DSPSymbols::g_dsp_symbol_db.GetIterator();
iter != DSPSymbols::g_dsp_symbol_db.End(); iter++)
{
int idx = m_SymbolList->Append(wxString::FromAscii(iter->second.name.c_str()));
m_SymbolList->SetClientData(idx, (void*)&iter->second);
}
m_SymbolList->Thaw();
// rebuild the disasm
// RebuildDisAsmListView();
} }
m_SymbolList->Thaw();
} }
void DSPDebuggerLLE::OnSymbolListChange(wxCommandEvent& event) void DSPDebuggerLLE::OnSymbolListChange(wxCommandEvent& event)
@ -209,9 +191,9 @@ void DSPDebuggerLLE::UpdateRegisterFlags()
if (m_CachedCR == g_dsp.cr) if (m_CachedCR == g_dsp.cr)
return; return;
m_Toolbar->ToggleTool(ID_CHECK_ASSERTINT, g_dsp.cr & 0x02 ? true : false); // m_Toolbar->ToggleTool(ID_CHECK_ASSERTINT, g_dsp.cr & 0x02 ? true : false);
m_Toolbar->ToggleTool(ID_CHECK_HALT, g_dsp.cr & 0x04 ? true : false); // m_Toolbar->ToggleTool(ID_CHECK_HALT, g_dsp.cr & 0x04 ? true : false);
m_Toolbar->ToggleTool(ID_CHECK_INIT, g_dsp.cr & 0x800 ? true : false); // m_Toolbar->ToggleTool(ID_CHECK_INIT, g_dsp.cr & 0x800 ? true : false);
m_CachedCR = g_dsp.cr; m_CachedCR = g_dsp.cr;
} }

View File

@ -36,7 +36,7 @@
#include "disassemble.h" #include "disassemble.h"
#include "gdsp_interpreter.h" #include "gdsp_interpreter.h"
#include "gdsp_memory.h" #include "DSPMemoryMap.h"
#include "../DSPDebugInterface.h" #include "../DSPDebugInterface.h"
class DSPRegisterView; class DSPRegisterView;
@ -107,7 +107,6 @@ private:
DSPDebugInterface debug_interface; DSPDebugInterface debug_interface;
u64 m_CachedStepCounter; u64 m_CachedStepCounter;
u16 m_CachedCR; u16 m_CachedCR;
u32 m_CachedUCodeCRC;
// GUI updaters // GUI updaters
void UpdateDisAsmListView(); void UpdateDisAsmListView();

View File

@ -26,18 +26,18 @@
// ======================================================================================= // =======================================================================================
// For PB address detection // For PB address detection
// -------------- // --------------
// This will only work on GC, not Wii.
u32 RAM_MASK = 0x1FFFFFF; u32 RAM_MASK = 0x1FFFFFF;
u16 Memory_Read_U16(u32 _uAddress) u16 Memory_Read_U16(u32 _uAddress)
{ {
_uAddress &= RAM_MASK; return Common::swap16(*(u16*)&g_dsp.cpu_ram[_uAddress & RAM_MASK]);
return Common::swap16(*(u16*)&g_dsp.cpu_ram[_uAddress]);
} }
u32 Memory_Read_U32(u32 _uAddress) u32 Memory_Read_U32(u32 _uAddress)
{ {
_uAddress &= RAM_MASK; return Common::swap32(*(u32*)&g_dsp.cpu_ram[_uAddress & RAM_MASK]);
return Common::swap32(*(u32*)&g_dsp.cpu_ram[_uAddress]);
} }
#if PROFILE #if PROFILE

View File

@ -193,13 +193,6 @@ void DSP_DebugBreak()
#endif #endif
} }
void dspi_req_dsp_irq()
{
// Fire an interrupt on the PPC ASAP.
g_dspInitialize.pGenerateDSPInterrupt();
}
void Initialize(void *init) void Initialize(void *init)
{ {
bCanWork = true; bCanWork = true;
@ -211,8 +204,6 @@ void Initialize(void *init)
std::string coef_filename = File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + DSP_COEF; std::string coef_filename = File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + DSP_COEF;
bCanWork = DSPCore_Init(irom_filename.c_str(), coef_filename.c_str()); bCanWork = DSPCore_Init(irom_filename.c_str(), coef_filename.c_str());
g_dsp.cpu_ram = g_dspInitialize.pGetMemoryPointer(0); g_dsp.cpu_ram = g_dspInitialize.pGetMemoryPointer(0);
g_dsp.irq_request = dspi_req_dsp_irq;
// g_dsp.exception_in_progress_hack = false;
DSPCore_Reset(); DSPCore_Reset();
if (!bCanWork) if (!bCanWork)

2496
docs/DSP/DSP_UC_Luigi.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,7 @@ can parse this file and auto read symbols using those.
BIG Questions: BIG Questions:
- Who resets the 0x0350 to the beginning of the command block? - Who resets the 0x0350 to the beginning of the command block? Wrap register?
- What does 00eb_Unk_BufferMultWithDest?? - What does 00eb_Unk_BufferMultWithDest??
- Why is a PB-Transfer from RAM to DMEM 0xC0 shorts long but DMEM to RAM just 0x80 - Why is a PB-Transfer from RAM to DMEM 0xC0 shorts long but DMEM to RAM just 0x80
@ -170,6 +170,7 @@ There's definitely a bunch of sample data stored in each PB but I don't know exa
000c 02ff rti 000c 02ff rti
000d 0000 nop 000d 0000 nop
000e 029f 05b8 jmp 0x05b8 -> 05b8_NewMail() 000e 029f 05b8 jmp 0x05b8 -> 05b8_NewMail()
0010 029f 004e jmp 0x004e -> 004e_ContinueUCode() ??? 0010 029f 004e jmp 0x004e -> 004e_ContinueUCode() ???
// reset vector // reset vector
@ -220,7 +221,7 @@ void 0012_ResetVector()
// 002a 00fe 034e sr @0x034e, $AC0.M // 002a 00fe 034e sr @0x034e, $AC0.M
*0x034e = 0x00 *0x034e = 0x00
# 002c 1305 sbset #0x05 002c 1305 sbset #0x05
// 002d 029f 06c5 jmp 0x06c5 // 002d 029f 06c5 jmp 0x06c5
@ -251,12 +252,10 @@ void 0012_ResetVector()
upperCommand = (upperCommand >> 7) & 0x7e // F|RES: i think duddy is wrong here ... a negative must be a shift right upperCommand = (upperCommand >> 7) & 0x7e // F|RES: i think duddy is wrong here ... a negative must be a shift right
*0x0343 = upperCommand *0x0343 = upperCommand
/* // 003f 0200 0075 addi $AC0.M, #0x0075
003f 0200 0075 addi $AC0.M, #0x0075 // 0041 1c1e mrr $AR0, $AC0.M
0041 1c1e mrr $AR0, $AC0.M // 0042 170f jmpr $AR0
0042 170f jmpr $AR0 // switch casement of the commands.. jump table is at 0075
switch casement of the commands.. jump table is at 0075
*/
switch (upperCommand >> 1) // command must be shift >> 1 in our source code because the jump table is aligned with 2 Bytes switch (upperCommand >> 1) // command must be shift >> 1 in our source code because the jump table is aligned with 2 Bytes
{ {
@ -319,14 +318,18 @@ void 0057_InitHardware()
005b 8e00 set16 005b 8e00 set16
005c 8c00 clr15 005c 8c00 clr15
005d 8b00 m0 005d 8b00 m0
// Set all indexing wrappers to max range.
005e 009e ffff lri $AC0.M, #0xffff 005e 009e ffff lri $AC0.M, #0xffff
0060 1d1e mrr $WR0, $AC0.M 0060 1d1e mrr $WR0, $AC0.M
0061 1d3e mrr $WR1, $AC0.M 0061 1d3e mrr $WR1, $AC0.M
0062 1d5e mrr $WR2, $AC0.M 0062 1d5e mrr $WR2, $AC0.M
0063 1d7e mrr $WR3, $AC0.M 0063 1d7e mrr $WR3, $AC0.M
// Have CR point to the HW interface.
0064 0092 00ff lri $CR, #0x00ff 0064 0092 00ff lri $CR, #0x00ff
0066 02df ret // 0066 02df ret
} }
void 0067_CopyCommand(_destAddr($AR0), _loopCount($AC0.M)) void 0067_CopyCommand(_destAddr($AR0), _loopCount($AC0.M))
{ {
@ -597,13 +600,16 @@ void 0127_Unk() {
0135 0508 addis $ACC1, #0x08 0135 0508 addis $ACC1, #0x08
0136 02bf 0525 call 0x0525 // 0525_CopyRAMtoDMEM 0136 02bf 0525 call 0x0525 // 0525_CopyRAMtoDMEM
// 0525_CopyRAMtoDMEM(... ,.. , 0x50) // 0525_CopyRAMtoDMEM(... ,.. , 0x50)
0138 00de 0390 lr $AC0.M, @0x0390
013a 02a0 0001 andf $AC0.M, #0x0001 // 0138 00de 0390 lr $AC0.M, @0x0390
013c 029d 0145 jlz 0x0145 // 013a 02a0 0001 andf $AC0.M, #0x0001
013e 0080 0398 lri $AR0, #0x0398 // 013c 029d 0145 jlz 0x0145
0140 0e08 lris $AC0.M, #0x08 if (*0x0390 & 1) {
0141 00c1 03a1 lr $AR1, @0x03a1 013e 0080 0398 lri $AR0, #0x0398
0143 02bf 0b2e call 0x0b2e // 0b2e_Unk_Multiply 0140 0e08 lris $AC0.M, #0x08
0141 00c1 03a1 lr $AR1, @0x03a1
0143 02bf 0b2e call 0x0b2e // 0b2e_Unk_Multiply
}
0145 0f50 lris $AC1.M, #0x50 0145 0f50 lris $AC1.M, #0x50
0146 00c0 03a1 lr $AR0, @0x03a1 0146 00c0 03a1 lr $AR0, @0x03a1
0148 00da 0394 lr $AX0.H, @0x0394 0148 00da 0394 lr $AX0.H, @0x0394
@ -619,12 +625,16 @@ void 0127_Unk() {
0155 00da 0396 lr $AX0.H, @0x0396 0155 00da 0396 lr $AX0.H, @0x0396
0157 8600 tstaxh $AX0.H 0157 8600 tstaxh $AX0.H
0158 0295 015f jz 0x015f 0158 0295 015f jz 0x015f
015a 1c7a mrr $AR3, $AX0.H 015a 1c7a mrr $AR3, $AX0.H
015b 00d8 0397 lr $AX0.L, @0x0397 015b 00d8 0397 lr $AX0.L, @0x0397
015d 02bf 00eb call 0x00eb // 00eb_Unk_BufferMultWithDest 015d 02bf 00eb call 0x00eb // 00eb_Unk_BufferMultWithDest
015f 00de 0390 lr $AC0.M, @0x0390
0161 02a0 0002 andf $AC0.M, #0x0002 // 015f 00de 0390 lr $AC0.M, @0x0390
0163 02dd retlz // 0161 02a0 0002 andf $AC0.M, #0x0002
// 0163 02dd retlz
if (*0x390 & 2)
return;
0164 0080 0398 lri $AR0, #0x0398 0164 0080 0398 lri $AR0, #0x0398
0166 0e08 lris $AC0.M, #0x08 0166 0e08 lris $AC0.M, #0x08
0167 00c1 03a1 lr $AR1, @0x03a1 0167 00c1 03a1 lr $AR1, @0x03a1
@ -1089,56 +1099,56 @@ void 0243_COMMAND_02() // sync frame
// A block of audio is now present at 0x520. // A block of audio is now present at 0x520.
ContinueWithBlock: ContinueWithBlock:
// 02d8 00da 04a8 lr $AX0.H, @0x04a8 // 02d8 00da 04a8 lr $AX0.H, @0x04a8
// 02da 8600 tstaxh $AX0.H // 02da 8600 tstaxh $AX0.H
// 02db 0295 02e1 jz 0x02e1 // 02db 0295 02e1 jz 0x02e1
// 02dd 0080 0520 lri $AR0, #0x0520 // 02dd 0080 0520 lri $AR0, #0x0520
// 02df 02bf 0c84 call 0x0c84 // 02df 02bf 0c84 call 0x0c84
if (0x04a8 != 0) if (0x04a8 != 0)
0c84_ModifySample(0x0520) 0c84_ModifySample(0x0520)
// 02e1 009e 0520 lri $AC0.M, #0x0520 // 02e1 009e 0520 lri $AC0.M, #0x0520
// 02e3 00fe 038f sr @0x038f, $AC0.M // 02e3 00fe 038f sr @0x038f, $AC0.M
*0x038f = 0x0520 *0x038f = 0x0520
// 02e5 8900 clr $ACC1 // 02e5 8900 clr $ACC1
// 02e6 00df 0484 lr $AC1.M, @0x0484 // 02e6 00df 0484 lr $AC1.M, @0x0484
// 02e8 0340 001f andi $AC1.M, #0x001f // 02e8 0340 001f andi $AC1.M, #0x001f
// 02ea b900 tst $ACC1 // 02ea b900 tst $ACC1
// 02eb 0295 0311 jz 0x0311 // 02eb 0295 0311 jz 0x0311
if ((*0x0484 & 0x1f) != 0x00) if ((*0x0484 & 0x1f) != 0x00)
{ {
// 02ed 00de 038f lr $AC0.M, @0x038f // 02ed 00de 038f lr $AC0.M, @0x038f
// 02ef 5c00 sub $ACC0, $AC1.L // 02ef 5c00 sub $ACC0, $AC1.L
// 02f0 00fe 038f sr @0x038f, $AC0.M // 02f0 00fe 038f sr @0x038f, $AC0.M
(*0x038f) -= AC1.L; // where did AC1.L get its value? should be 0, unless sub is wrong? (*0x038f) -= AC1.L; // where did AC1.L get its value? should be 0, unless sub is wrong?
// 02f2 1c7e mrr $AR3, $AC0.M // 02f2 1c7e mrr $AR3, $AC0.M
// 02f3 0080 0440 lri $AR0, #0x0440 // 02f3 0080 0440 lri $AR0, #0x0440
// 02f5 05fe addis $ACC1, #0xfe // 02f5 05fe addis $ACC1, #0xfe
// 02f6 02bf 00da call 0x00da // 02f6 02bf 00da call 0x00da
00da_CopyBuffer(0x0440, (*0x038f), (*0x0484) + 0xfe) 00da_CopyBuffer(0x0440, (*0x038f), (*0x0484) + 0xfe)
// 02f8 0080 0490 lri $AR0, #0x0490 // 02f8 0080 0490 lri $AR0, #0x0490
// 02fa 00c1 038f lr $AR1, @0x038f // 02fa 00c1 038f lr $AR1, @0x038f
// 02fc 8900 clr $ACC1 // 02fc 8900 clr $ACC1
// 02fd 00df 0484 lr $AC1.M, @0x0484 // 02fd 00df 0484 lr $AC1.M, @0x0484
// 02ff 0340 001f andi $AC1.M, #0x001f // 02ff 0340 001f andi $AC1.M, #0x001f
// 0301 02bf 0b4d call 0x0b4d // 0301 02bf 0b4d call 0x0b4d
0b4d_IIR_Filter(In(0x0490), Out(*0x038f), FilterLength(*0x0484 & 0x1f)) 0b4d_IIR_Filter(In(0x0490), Out(*0x038f), FilterLength(*0x0484 & 0x1f))
0303 00de 038f lr $AC0.M, @0x038f 0303 00de 038f lr $AC0.M, @0x038f
0305 0450 addis $ACC0, #0x50 0305 0450 addis $ACC0, #0x50
0306 1c1e mrr $AR0, $AC0.M 0306 1c1e mrr $AR0, $AC0.M
// 0307 0083 0440 lri $AR3, #0x0440 // 0307 0083 0440 lri $AR3, #0x0440
0309 8900 clr $ACC1 0309 8900 clr $ACC1
030a 00df 0484 lr $AC1.M, @0x0484 030a 00df 0484 lr $AC1.M, @0x0484
030c 0340 001f andi $AC1.M, #0x001f 030c 0340 001f andi $AC1.M, #0x001f
030e 05fe addis $ACC1, #0xfe 030e 05fe addis $ACC1, #0xfe
// 030f 02bf 00da call 0x00da // 030f 02bf 00da call 0x00da
00da_CopyBuffer(, 0x0440) 00da_CopyBuffer(, 0x0440)
} }
// 0311 00de 0484 lr $AC0.M, @0x0484 // 0311 00de 0484 lr $AC0.M, @0x0484
// 0313 0240 0020 andi $AC0.M, #0x0020 // 0313 0240 0020 andi $AC0.M, #0x0020
@ -2182,18 +2192,25 @@ void 0688_InitCommandBlock()
0694 00e8 03fc sr @0x03fc, $WR0 0694 00e8 03fc sr @0x03fc, $WR0
0696 00c0 0350 lr $AR0, @0x0350 0696 00c0 0350 lr $AR0, @0x0350
0698 0088 002f lri $WR0, #0x002f 0698 0088 002f lri $WR0, #0x002f
069a 1b1a srri @$AR0, $AX0.H
069b 00de fffe lr $AC0.M, @CMBH do {
069d 02c0 8000 andcf $AC0.M, #0x8000 069a 1b1a srri @$AR0, $AX0.H
069f 029c 069b jlnz 0x069b
06a1 00dc ffff lr $AC0.L, @CMBL // 069b 00de fffe lr $AC0.M, @CMBH
06a3 1b1e srri @$AR0, $AC0.M // 069d 02c0 8000 andcf $AC0.M, #0x8000
06a4 1b1c srri @$AR0, $AC0.L // 069f 029c 069b jlnz 0x069b
06a5 1fda mrr $AC0.M, $AX0.H while (!CMBH & 0x8000)
06a6 7800 decm $AC0.M ;
06a7 1f5e mrr $AX0.H, $AC0.M 06a1 00dc ffff lr $AC0.L, @CMBL
06a8 8600 tstaxh $AX0.H 06a3 1b1e srri @$AR0, $AC0.M
06a9 0294 069b jnz 0x069b 06a4 1b1c srri @$AR0, $AC0.L
06a5 1fda mrr $AC0.M, $AX0.H
06a6 7800 decm $AC0.M
06a7 1f5e mrr $AX0.H, $AC0.M
// 06a8 8600 tstaxh $AX0.H
// 06a9 0294 069b jnz 0x069b
} while (AX0.H);
/* /*
06ab 8100 clr $ACC0 06ab 8100 clr $ACC0
@ -2213,6 +2230,7 @@ void 0688_InitCommandBlock()
GOTO EndOfMailException // return values and leave exception GOTO EndOfMailException // return values and leave exception
// looks like a read from ring buffer [0x350, 0x37f] // looks like a read from ring buffer [0x350, 0x37f]
// note the use of the wrap register WR0.
06b9 00e0 03fb sr @0x03fb, $AR0 06b9 00e0 03fb sr @0x03fb, $AR0
06bb 00e8 03fc sr @0x03fc, $WR0 06bb 00e8 03fc sr @0x03fc, $WR0
06bd 00c0 0350 lr $AR0, @0x0350 06bd 00c0 0350 lr $AR0, @0x0350
@ -2260,16 +2278,14 @@ void 06c5_CopyCommandBlock()
// 06d6 0081 0356 lri $AR1, #0x0356 // 06d6 0081 0356 lri $AR1, #0x0356
short destCommandQueueAddr = 0x0356 short destCommandQueueAddr = 0x0356
/* // 06d8 191e lrri $AC0.M, @$AR0
06d8 191e lrri $AC0.M, @$AR0 // 06d9 02c0 8000 andcf $AC0.M, #0x8000
06d9 02c0 8000 andcf $AC0.M, #0x8000 // 06db 029d 06f1 jlz 0x06f1
06db 029d 06f1 jlz 0x06f1 // 06dd 1f5e mrr $AX0.H, $AC0.M
06dd 1f5e mrr $AX0.H, $AC0.M // 06de 8600 tstaxh $AX0.H
06de 8600 tstaxh $AX0.H // 06df 0295 06f5 jz 0x06f5
06df 0295 06f5 jz 0x06f5
// check if command is valid // check if command is valid
*/
short numCommands = *srcCommandQueueAddr++ short numCommands = *srcCommandQueueAddr++
numCommands &= 0x8000 numCommands &= 0x8000
@ -2333,8 +2349,11 @@ void 06f9_Unk_PrepareSampleDecode()
06f9 8100 clr $ACC0 06f9 8100 clr $ACC0
06fa 0e10 lris $AC0.M, #0x10 06fa 0e10 lris $AC0.M, #0x10
06fb 2232 lrs $AX0.H, @0x0032 06fb 2232 lrs $AX0.H, @0x0032
06fc 8600 tstaxh $AX0.H // 06fc 8600 tstaxh $AX0.H
06fd 02d5 retz // 06fd 02d5 retz
if (!*0x0432)
return;
06fe 5400 subr $ACC0, $AX0.H 06fe 5400 subr $ACC0, $AX0.H
06ff 0200 0458 addi $AC0.M, #0x0458 06ff 0200 0458 addi $AC0.M, #0x0458
0701 1c1e mrr $AR0, $AC0.M 0701 1c1e mrr $AR0, $AC0.M
@ -2342,18 +2361,21 @@ void 06f9_Unk_PrepareSampleDecode()
0703 04fe addis $ACC0, #0xfe 0703 04fe addis $ACC0, #0xfe
0704 1f1e mrr $AX0.L, $AC0.M 0704 1f1e mrr $AX0.L, $AC0.M
0705 191e lrri $AC0.M, @$AR0 0705 191e lrri $AC0.M, @$AR0
0706 0291 070c js 0x070c // 0706 0291 070c js 0x070c
0708 191a lrri $AX0.H, @$AR0 if ( .. ?? ..) {
0709 0058 loop $AX0.L 0708 191a lrri $AX0.H, @$AR0
070a 64a0 movr'ls $ACC0, $AX0.H : $AX0.H, $AC0.M // Copy-loop
070b 6433 movr's $ACC0, $AX0.H : @$AR3, $AC0.M 0709 0058 loop $AX0.L
070a 64a0 movr'ls $ACC0, $AX0.H : $AX0.H, $AC0.M
070b 6433 movr's $ACC0, $AX0.H : @$AR3, $AC0.M
}
070c 1b7e srri @$AR3, $AC0.M 070c 1b7e srri @$AR3, $AC0.M
070d 02df ret 070d 02df ret
} }
// early out for 073d_DECODE_0x05_0x09 // early out for 073d_DECODE_0x05_0x09
{ void EarlyOutFrom_073d_DECODE_0x05_0x09() {
//070e 02bf 06f9 call 0x06f9 //070e 02bf 06f9 call 0x06f9
06f9_Unk_PrepareSampleDecode() 06f9_Unk_PrepareSampleDecode()
0710 8100 clr $ACC0 0710 8100 clr $ACC0
@ -3501,7 +3523,7 @@ void 0af6_Unk() {
0b1d 0274 ifnz 0b1d 0274 ifnz
if (ACC1) { if (ACC1) {
0b1e 0008 iar $AR0 0b1e 0008 iar $AR0
} }
0b1f 8900 clr $ACC1 0b1f 8900 clr $ACC1
0b20 1fe1 mrr $AC1.M, $AR1 0b20 1fe1 mrr $AC1.M, $AR1
0b21 191e lrri $AC0.M, @$AR0 0b21 191e lrri $AC0.M, @$AR0
@ -3522,7 +3544,7 @@ void 0af6_Unk() {
} }
void 0b2e_Unk_Multiply() { void 0b2e_Unk_Multiply() { // ZWW: 01c2_Unk
0b2e 8a00 m2 0b2e 8a00 m2
0b2f 0083 03e8 lri $AR3, #0x03e8 0b2f 0083 03e8 lri $AR3, #0x03e8
0b31 191e lrri $AC0.M, @$AR0 0b31 191e lrri $AC0.M, @$AR0

View File

@ -0,0 +1,45 @@
# this can be used to upgrade disassemblies that aren't too annotated.
# won't do very well on the current zelda disasm.
import os
import sys
def GetPrefixLine(l, a):
for s in a:
if s[0:len(l)] == l:
return s
return ""
def GetComment(l):
comment_start = l.find("//")
if comment_start < 0:
comment_start = l.find("->")
if comment_start < 0:
return ""
while (l[comment_start-1] == ' ') or (l[comment_start-1] == '\t'):
comment_start -= 1
return l[comment_start:]
def main():
old_lines = open("DSP_UC_Zelda.txt", "r").readlines()
# for l in old_lines:
# print l
new_lines = open("zeldanew.txt", "r").readlines()
for i in range(0, len(old_lines)):
prefix = old_lines[i][0:14]
comment = GetComment(old_lines[i])
new_line = GetPrefixLine(prefix, new_lines)
if new_line:
old_lines[i] = new_line[:-1] + comment[:-1] + "\n"
for i in range(0, len(old_lines)):
print old_lines[i],
new_file = open("output.txt", "w")
new_file.writelines(old_lines)
main()