Merge branch 'master' into cartdom2addr2

This commit is contained in:
KrimtonZ 2019-12-27 07:34:11 -06:00
commit 6ebad8292e
61 changed files with 2678 additions and 2121 deletions

View File

@ -250,13 +250,13 @@ R4300iOp::Func * R4300iOp::BuildInterpreter()
Jump_Special[45] = SPECIAL_DADDU;
Jump_Special[46] = SPECIAL_DSUB;
Jump_Special[47] = SPECIAL_DSUBU;
Jump_Special[48] = UnknownOpcode;
Jump_Special[49] = UnknownOpcode;
Jump_Special[50] = UnknownOpcode;
Jump_Special[51] = UnknownOpcode;
Jump_Special[48] = SPECIAL_TGE;
Jump_Special[49] = SPECIAL_TGEU;
Jump_Special[50] = SPECIAL_TLT;
Jump_Special[51] = SPECIAL_TLTU;
Jump_Special[52] = SPECIAL_TEQ;
Jump_Special[53] = UnknownOpcode;
Jump_Special[54] = UnknownOpcode;
Jump_Special[54] = SPECIAL_TNE;
Jump_Special[55] = UnknownOpcode;
Jump_Special[56] = SPECIAL_DSLL;
Jump_Special[57] = UnknownOpcode;
@ -275,13 +275,13 @@ R4300iOp::Func * R4300iOp::BuildInterpreter()
Jump_Regimm[5] = UnknownOpcode;
Jump_Regimm[6] = UnknownOpcode;
Jump_Regimm[7] = UnknownOpcode;
Jump_Regimm[8] = UnknownOpcode;
Jump_Regimm[9] = UnknownOpcode;
Jump_Regimm[10] = UnknownOpcode;
Jump_Regimm[11] = UnknownOpcode;
Jump_Regimm[12] = UnknownOpcode;
Jump_Regimm[8] = REGIMM_TGEI;
Jump_Regimm[9] = REGIMM_TGEIU;
Jump_Regimm[10] = REGIMM_TLTI;
Jump_Regimm[11] = REGIMM_TLTIU;
Jump_Regimm[12] = REGIMM_TEQI;
Jump_Regimm[13] = UnknownOpcode;
Jump_Regimm[14] = UnknownOpcode;
Jump_Regimm[14] = REGIMM_TNEI;
Jump_Regimm[15] = UnknownOpcode;
Jump_Regimm[16] = REGIMM_BLTZAL;
Jump_Regimm[17] = REGIMM_BGEZAL;
@ -2048,9 +2048,49 @@ void R4300iOp::SPECIAL_DSUBU()
void R4300iOp::SPECIAL_TEQ()
{
if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW && HaveDebugger())
if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW)
{
g_Notify->DisplayError("Should trap this ???");
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
}
void R4300iOp::SPECIAL_TGE()
{
if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW)
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
}
void R4300iOp::SPECIAL_TGEU()
{
if (_GPR[m_Opcode.rs].UDW >= _GPR[m_Opcode.rt].UDW)
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
}
void R4300iOp::SPECIAL_TLT()
{
if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW)
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
}
void R4300iOp::SPECIAL_TLTU()
{
if (_GPR[m_Opcode.rs].UDW < _GPR[m_Opcode.rt].UDW)
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
}
void R4300iOp::SPECIAL_TNE()
{
if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW)
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
}
@ -2220,6 +2260,63 @@ void R4300iOp::REGIMM_BGEZAL()
}
_GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8);
}
void R4300iOp::REGIMM_TEQI()
{
if (_GPR[m_Opcode.rs].DW == (int64_t)((int16_t)m_Opcode.immediate))
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
}
void R4300iOp::REGIMM_TGEI()
{
if (_GPR[m_Opcode.rs].DW >= (int64_t)((int16_t)m_Opcode.immediate))
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
}
void R4300iOp::REGIMM_TGEIU()
{
int32_t imm32 = (int16_t)m_Opcode.immediate;
int64_t imm64;
imm64 = imm32;
if (_GPR[m_Opcode.rs].DW >= (uint64_t)imm64)
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
}
void R4300iOp::REGIMM_TLTI()
{
if (_GPR[m_Opcode.rs].DW < (int64_t)((int16_t)m_Opcode.immediate))
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
}
void R4300iOp::REGIMM_TLTIU()
{
int32_t imm32 = (int16_t)m_Opcode.immediate;
int64_t imm64;
imm64 = imm32;
if (_GPR[m_Opcode.rs].DW < (uint64_t)imm64)
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
}
void R4300iOp::REGIMM_TNEI()
{
if (_GPR[m_Opcode.rs].DW != (int64_t)((int16_t)m_Opcode.immediate))
{
g_Reg->DoTrapException(m_NextInstruction == JUMP);
}
}
/************************** COP0 functions **************************/
void R4300iOp::COP0_MF()
{

View File

@ -110,7 +110,12 @@ public:
static void SPECIAL_DADDU();
static void SPECIAL_DSUB();
static void SPECIAL_DSUBU();
static void SPECIAL_TGE();
static void SPECIAL_TGEU();
static void SPECIAL_TLT();
static void SPECIAL_TLTU();
static void SPECIAL_TEQ();
static void SPECIAL_TNE();
static void SPECIAL_DSLL();
static void SPECIAL_DSRL();
static void SPECIAL_DSRA();
@ -125,6 +130,12 @@ public:
static void REGIMM_BGEZL();
static void REGIMM_BLTZAL();
static void REGIMM_BGEZAL();
static void REGIMM_TEQI();
static void REGIMM_TGEI();
static void REGIMM_TGEIU();
static void REGIMM_TLTI();
static void REGIMM_TLTIU();
static void REGIMM_TNEI();
/************************** COP0 functions **************************/
static void COP0_MF();

View File

@ -155,13 +155,13 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter()
Jump_Special[45] = R4300iOp::SPECIAL_DADDU;
Jump_Special[46] = R4300iOp::SPECIAL_DSUB;
Jump_Special[47] = R4300iOp::SPECIAL_DSUBU;
Jump_Special[48] = R4300iOp::UnknownOpcode;
Jump_Special[49] = R4300iOp::UnknownOpcode;
Jump_Special[50] = R4300iOp::UnknownOpcode;
Jump_Special[51] = R4300iOp::UnknownOpcode;
Jump_Special[48] = R4300iOp::SPECIAL_TGE;
Jump_Special[49] = R4300iOp::SPECIAL_TGEU;
Jump_Special[50] = R4300iOp::SPECIAL_TLT;
Jump_Special[51] = R4300iOp::SPECIAL_TLTU;
Jump_Special[52] = R4300iOp::SPECIAL_TEQ;
Jump_Special[53] = R4300iOp::UnknownOpcode;
Jump_Special[54] = R4300iOp::UnknownOpcode;
Jump_Special[54] = R4300iOp::SPECIAL_TNE;
Jump_Special[55] = R4300iOp::UnknownOpcode;
Jump_Special[56] = R4300iOp::SPECIAL_DSLL;
Jump_Special[57] = R4300iOp::UnknownOpcode;
@ -180,13 +180,13 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter()
Jump_Regimm[5] = R4300iOp::UnknownOpcode;
Jump_Regimm[6] = R4300iOp::UnknownOpcode;
Jump_Regimm[7] = R4300iOp::UnknownOpcode;
Jump_Regimm[8] = R4300iOp::UnknownOpcode;
Jump_Regimm[9] = R4300iOp::UnknownOpcode;
Jump_Regimm[10] = R4300iOp::UnknownOpcode;
Jump_Regimm[11] = R4300iOp::UnknownOpcode;
Jump_Regimm[12] = R4300iOp::UnknownOpcode;
Jump_Regimm[8] = R4300iOp::REGIMM_TGEI;
Jump_Regimm[9] = R4300iOp::REGIMM_TGEIU;
Jump_Regimm[10] = R4300iOp::REGIMM_TLTI;
Jump_Regimm[11] = R4300iOp::REGIMM_TLTIU;
Jump_Regimm[12] = R4300iOp::REGIMM_TEQI;
Jump_Regimm[13] = R4300iOp::UnknownOpcode;
Jump_Regimm[14] = R4300iOp::UnknownOpcode;
Jump_Regimm[14] = R4300iOp::REGIMM_TNEI;
Jump_Regimm[15] = R4300iOp::UnknownOpcode;
Jump_Regimm[16] = REGIMM_BLTZAL;
Jump_Regimm[17] = REGIMM_BGEZAL;

View File

@ -438,6 +438,22 @@ void CRegisters::DoBreakException(bool DelaySlot)
m_PROGRAM_COUNTER = 0x80000180;
}
void CRegisters::DoTrapException(bool DelaySlot)
{
CAUSE_REGISTER = EXC_TRAP;
if (DelaySlot)
{
EPC_REGISTER = m_PROGRAM_COUNTER - 4;
CAUSE_REGISTER |= CAUSE_BD;
}
else
{
EPC_REGISTER = m_PROGRAM_COUNTER;
}
m_PROGRAM_COUNTER = 0x80000180;
}
void CRegisters::DoCopUnusableException(bool DelaySlot, int Coprocessor)
{
if (HaveDebugger())

View File

@ -631,6 +631,7 @@ public:
void CheckInterrupts ();
void DoAddressError ( bool DelaySlot, uint32_t BadVaddr, bool FromRead );
void DoBreakException ( bool DelaySlot );
void DoTrapException ( bool DelaySlot );
void DoCopUnusableException ( bool DelaySlot, int32_t Coprocessor );
bool DoIntrException ( bool DelaySlot );
void DoTLBReadMiss ( bool DelaySlot, uint32_t BadVaddr );

View File

@ -105,6 +105,77 @@ CArmRecompilerOps::CArmRecompilerOps() :
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
void CArmRecompilerOps::Compile_TrapCompare(TRAP_COMPARE CompareType)
{
void *FunctAddress = NULL;
const char *FunctName = NULL;
switch (CompareType)
{
case CompareTypeTEQ:
FunctAddress = (void*)R4300iOp::SPECIAL_TEQ;
FunctName = "R4300iOp::SPECIAL_TEQ";
break;
case CompareTypeTNE:
FunctAddress = (void*)R4300iOp::SPECIAL_TNE;
FunctName = "R4300iOp::SPECIAL_TNE";
break;
case CompareTypeTGE:
FunctAddress = (void*)R4300iOp::SPECIAL_TGE;
FunctName = "R4300iOp::SPECIAL_TGE";
break;
case CompareTypeTGEU:
FunctAddress = (void*)R4300iOp::SPECIAL_TGEU;
FunctName = "R4300iOp::SPECIAL_TGEU";
break;
case CompareTypeTLT:
FunctAddress = (void*)R4300iOp::SPECIAL_TLT;
FunctName = "R4300iOp::SPECIAL_TLT";
break;
case CompareTypeTLTU:
FunctAddress = (void*)R4300iOp::SPECIAL_TLTU;
FunctName = "R4300iOp::SPECIAL_TLTU";
break;
case CompareTypeTEQI:
FunctAddress = (void*)R4300iOp::REGIMM_TEQI;
FunctName = "R4300iOp::REGIMM_TEQI";
break;
case CompareTypeTNEI:
FunctAddress = (void*)R4300iOp::REGIMM_TNEI;
FunctName = "R4300iOp::REGIMM_TNEI";
break;
case CompareTypeTGEI:
FunctAddress = (void*)R4300iOp::REGIMM_TGEI;
FunctName = "R4300iOp::REGIMM_TGEI";
break;
case CompareTypeTGEIU:
FunctAddress = (void*)R4300iOp::REGIMM_TGEIU;
FunctName = "R4300iOp::REGIMM_TGEIU";
break;
case CompareTypeTLTI:
FunctAddress = (void*)R4300iOp::REGIMM_TLTI;
FunctName = "R4300iOp::REGIMM_TLTI";
break;
case CompareTypeTLTIU:
FunctAddress = (void*)R4300iOp::REGIMM_TLTIU;
FunctName = "R4300iOp::REGIMM_TLTIU";
break;
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (FunctName != NULL && FunctAddress != NULL)
{
if (m_Opcode.rs != 0) { WriteBack_GPR(m_Opcode.rs, false); }
if (m_Opcode.rt != 0) { WriteBack_GPR(m_Opcode.rt, false); }
CompileInterpterCall(FunctAddress, FunctName);
}
else
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
}
/************************** Branch functions ************************/
void CArmRecompilerOps::Compile_BranchCompare(BRANCH_COMPARE CompareType)
{

View File

@ -22,6 +22,9 @@ class CArmRecompilerOps :
public:
CArmRecompilerOps();
/*************************** Trap functions *************************/
void Compile_TrapCompare(TRAP_COMPARE CompareType);
/************************** Branch functions ************************/
void Compile_BranchCompare(BRANCH_COMPARE CompareType);
void Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link);

View File

@ -475,7 +475,9 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t &
case R4300i_SPECIAL_DSLL32: case R4300i_SPECIAL_DSRL32: case R4300i_SPECIAL_DSRA32:
case R4300i_SPECIAL_MULT: case R4300i_SPECIAL_MULTU: case R4300i_SPECIAL_DIV:
case R4300i_SPECIAL_DIVU: case R4300i_SPECIAL_DMULT: case R4300i_SPECIAL_DMULTU:
case R4300i_SPECIAL_DDIV: case R4300i_SPECIAL_DDIVU:
case R4300i_SPECIAL_DDIV: case R4300i_SPECIAL_DDIVU: case R4300i_SPECIAL_TEQ:
case R4300i_SPECIAL_TNE: case R4300i_SPECIAL_TGE: case R4300i_SPECIAL_TGEU:
case R4300i_SPECIAL_TLT: case R4300i_SPECIAL_TLTU:
break;
case R4300i_SPECIAL_JALR:
case R4300i_SPECIAL_JR:
@ -556,6 +558,9 @@ bool CCodeBlock::AnalyzeInstruction(uint32_t PC, uint32_t & TargetPC, uint32_t &
LikelyBranch = true;
IncludeDelaySlot = true;
break;
case R4300i_REGIMM_TEQI: case R4300i_REGIMM_TNEI: case R4300i_REGIMM_TGEI:
case R4300i_REGIMM_TGEIU: case R4300i_REGIMM_TLTI: case R4300i_REGIMM_TLTIU:
break;
default:
if (Command.Hex == 0x0407000D)
{

View File

@ -583,6 +583,13 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
case R4300i_SPECIAL_DSLL32: m_RecompilerOps->SPECIAL_DSLL32(); break;
case R4300i_SPECIAL_DSRL32: m_RecompilerOps->SPECIAL_DSRL32(); break;
case R4300i_SPECIAL_DSRA32: m_RecompilerOps->SPECIAL_DSRA32(); break;
case R4300i_SPECIAL_TEQ: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTEQ); break;
case R4300i_SPECIAL_TNE: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTNE); break;
case R4300i_SPECIAL_TGE: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTGE); break;
case R4300i_SPECIAL_TGEU: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTGEU); break;
case R4300i_SPECIAL_TLT: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTLT); break;
case R4300i_SPECIAL_TLTU: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTLTU); break;
break;
default:
m_RecompilerOps->UnknownOpcode(); break;
}
@ -596,6 +603,12 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
case R4300i_REGIMM_BGEZL: m_RecompilerOps->Compile_BranchLikely(CRecompilerOps::CompareTypeBGEZ, false); break;
case R4300i_REGIMM_BLTZAL: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBLTZ, CRecompilerOps::BranchTypeRs, true); break;
case R4300i_REGIMM_BGEZAL: m_RecompilerOps->Compile_Branch(CRecompilerOps::CompareTypeBGEZ, CRecompilerOps::BranchTypeRs, true); break;
case R4300i_REGIMM_TEQI: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTEQI); break;
case R4300i_REGIMM_TNEI: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTNEI); break;
case R4300i_REGIMM_TGEI: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTGEI); break;
case R4300i_REGIMM_TGEIU: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTGEIU); break;
case R4300i_REGIMM_TLTI: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTLTI); break;
case R4300i_REGIMM_TLTIU: m_RecompilerOps->Compile_TrapCompare(CRecompilerOps::TRAP_COMPARE::CompareTypeTLTIU); break;
default:
m_RecompilerOps->UnknownOpcode(); break;
}

View File

@ -238,6 +238,9 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
case R4300i_SPECIAL_DSLL32: SPECIAL_DSLL32(); break;
case R4300i_SPECIAL_DSRL32: SPECIAL_DSRL32(); break;
case R4300i_SPECIAL_DSRA32: SPECIAL_DSRA32(); break;
case R4300i_SPECIAL_TEQ: case R4300i_SPECIAL_TNE: case R4300i_SPECIAL_TGE:
case R4300i_SPECIAL_TGEU: case R4300i_SPECIAL_TLT: case R4300i_SPECIAL_TLTU:
break;
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
#ifdef legacycode
@ -252,6 +255,9 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
case R4300i_REGIMM:
switch (m_Command.rt)
{
case R4300i_REGIMM_TEQI: case R4300i_REGIMM_TNEI: case R4300i_REGIMM_TGEI:
case R4300i_REGIMM_TGEIU: case R4300i_REGIMM_TLTI: case R4300i_REGIMM_TLTIU:
break;
case R4300i_REGIMM_BLTZ:
case R4300i_REGIMM_BGEZ:
m_NextInstruction = DELAY_SLOT;

View File

@ -35,6 +35,24 @@ public:
CompareTypeCOP1BCF,
CompareTypeCOP1BCT,
};
enum TRAP_COMPARE
{
CompareTypeTEQ,
CompareTypeTNE,
CompareTypeTGE,
CompareTypeTGEU,
CompareTypeTLT,
CompareTypeTLTU,
CompareTypeTEQI,
CompareTypeTNEI,
CompareTypeTGEI,
CompareTypeTGEIU,
CompareTypeTLTI,
CompareTypeTLTIU,
};
/*************************** Trap functions *************************/
virtual void Compile_TrapCompare(TRAP_COMPARE CompareType) = 0;
/************************** Branch functions ************************/
virtual void Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link) = 0;

View File

@ -361,6 +361,84 @@ void CX86RecompilerOps::CompileWriteTLBMiss(x86Reg AddressReg, x86Reg LookUpReg)
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
/*************************** Trap functions *************************/
void CX86RecompilerOps::Compile_TrapCompare(TRAP_COMPARE CompareType)
{
void *FunctAddress = NULL;
const char *FunctName = NULL;
switch (CompareType)
{
case CompareTypeTEQ:
FunctAddress = (void*)R4300iOp::SPECIAL_TEQ;
FunctName = "R4300iOp::SPECIAL_TEQ";
break;
case CompareTypeTNE:
FunctAddress = (void*)R4300iOp::SPECIAL_TNE;
FunctName = "R4300iOp::SPECIAL_TNE";
break;
case CompareTypeTGE:
FunctAddress = (void*)R4300iOp::SPECIAL_TGE;
FunctName = "R4300iOp::SPECIAL_TGE";
break;
case CompareTypeTGEU:
FunctAddress = (void*)R4300iOp::SPECIAL_TGEU;
FunctName = "R4300iOp::SPECIAL_TGEU";
break;
case CompareTypeTLT:
FunctAddress = (void*)R4300iOp::SPECIAL_TLT;
FunctName = "R4300iOp::SPECIAL_TLT";
break;
case CompareTypeTLTU:
FunctAddress = (void*)R4300iOp::SPECIAL_TLTU;
FunctName = "R4300iOp::SPECIAL_TLTU";
break;
case CompareTypeTEQI:
FunctAddress = (void*)R4300iOp::REGIMM_TEQI;
FunctName = "R4300iOp::REGIMM_TEQI";
break;
case CompareTypeTNEI:
FunctAddress = (void*)R4300iOp::REGIMM_TNEI;
FunctName = "R4300iOp::REGIMM_TNEI";
break;
case CompareTypeTGEI:
FunctAddress = (void*)R4300iOp::REGIMM_TGEI;
FunctName = "R4300iOp::REGIMM_TGEI";
break;
case CompareTypeTGEIU:
FunctAddress = (void*)R4300iOp::REGIMM_TGEIU;
FunctName = "R4300iOp::REGIMM_TGEIU";
break;
case CompareTypeTLTI:
FunctAddress = (void*)R4300iOp::REGIMM_TLTI;
FunctName = "R4300iOp::REGIMM_TLTI";
break;
case CompareTypeTLTIU:
FunctAddress = (void*)R4300iOp::REGIMM_TLTIU;
FunctName = "R4300iOp::REGIMM_TLTIU";
break;
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if (FunctName != NULL && FunctAddress != NULL)
{
if (IsMapped(m_Opcode.rs)) {
UnMap_GPR(m_Opcode.rs, true);
}
if (IsMapped(m_Opcode.rt)) {
UnMap_GPR(m_Opcode.rt, true);
}
m_RegWorkingSet.BeforeCallDirect();
MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex");
Call_Direct(FunctAddress, FunctName);
m_RegWorkingSet.AfterCallDirect();
}
else
{
g_Notify->BreakPoint(__FILE__, __LINE__);
}
}
/************************** Branch functions ************************/
void CX86RecompilerOps::Compile_BranchCompare(BRANCH_COMPARE CompareType)
{

View File

@ -33,6 +33,9 @@ class CX86RecompilerOps :
protected CRecompilerSettings
{
public:
/*************************** Trap functions *************************/
void Compile_TrapCompare(TRAP_COMPARE CompareType);
/************************** Branch functions ************************/
void Compile_BranchCompare(BRANCH_COMPARE CompareType);
void Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE BranchType, bool Link);

View File

@ -1,4 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -122,70 +131,70 @@ void CAssembler::StrToLower(char* str)
uint32_t CAssembler::pop_reg()
{
char* r = strtok_s(NULL, " \t,()", &m_TokContext);
char* r = strtok_s(NULL, " \t,()", &m_TokContext);
if (r == NULL)
{
m_ParseError = ERR_EXPECTED_REG;
return 0;
}
if (r == NULL)
{
m_ParseError = ERR_EXPECTED_REG;
return 0;
}
const ASM_REGISTER* reg = LookupRegister(r);
const ASM_REGISTER* reg = LookupRegister(r);
if (reg == NULL)
{
m_ParseError = ERR_INVALID_REG;
return 0;
}
if (reg == NULL)
{
m_ParseError = ERR_INVALID_REG;
return 0;
}
return reg->val;
return reg->val;
}
uint32_t CAssembler::pop_val()
{
char* v = strtok_s(NULL, " \t,()", &m_TokContext);
char* v = strtok_s(NULL, " \t,()", &m_TokContext);
if (v == NULL)
{
if (v == NULL)
{
m_ParseError = ERR_EXPECTED_VAL;
return 0;
}
return 0;
}
//if (isalpha(*v))
//{
// // todo lookup label value
// return 0;
//}
//if (isalpha(*v))
//{
// // todo lookup label value
// return 0;
//}
int base = 0; // hex or dec
int base = 0; // hex or dec
if (*v == '$')
{
base = 16; // hex
v++;
}
if (*v == '$')
{
base = 16; // hex
v++;
}
char* endptr;
char* endptr;
uint32_t val = strtoul(v, &endptr, base);
uint32_t val = strtoul(v, &endptr, base);
if (*endptr != '\0')
{
if (*endptr != '\0')
{
m_ParseError = ERR_EXPECTED_VAL;
return 0;
}
return 0;
}
return val;
return val;
}
uint32_t CAssembler::base_op(uint32_t val)
{
return val << 26;
return val << 26;
}
uint32_t CAssembler::base_spec(uint32_t val)
{
return val;
return val;
}
uint32_t CAssembler::base_spec_jalr_ra(uint32_t val)
@ -195,7 +204,7 @@ uint32_t CAssembler::base_spec_jalr_ra(uint32_t val)
uint32_t CAssembler::base_regimm(uint32_t val)
{
return (R4300i_REGIMM << 26) | (val << 16);
return (R4300i_REGIMM << 26) | (val << 16);
}
uint32_t CAssembler::base_cop0_co(uint32_t val)
@ -235,12 +244,12 @@ void CAssembler::arg_reg_t(uint32_t* opcode)
void CAssembler::arg_reg_s(uint32_t* opcode)
{
*opcode |= pop_reg() << 21;
*opcode |= pop_reg() << 21;
}
void CAssembler::arg_reg_d(uint32_t* opcode)
{
*opcode |= pop_reg() << 11;
*opcode |= pop_reg() << 11;
}
void CAssembler::arg_reg_ft(uint32_t* opcode)
@ -260,23 +269,23 @@ void CAssembler::arg_reg_fd(uint32_t* opcode)
void CAssembler::arg_jump(uint32_t* opcode)
{
*opcode |= (pop_val() / 4) & 0x3FFFFFF;
*opcode |= (pop_val() / 4) & 0x3FFFFFF;
}
void CAssembler::arg_imm16(uint32_t* opcode)
{
*opcode |= (pop_val() & 0xFFFF);
*opcode |= (pop_val() & 0xFFFF);
}
void CAssembler::arg_bra_target(uint32_t* opcode)
{
uint16_t relTarget = (((pop_val() - m_Address) / 4) & 0xFFFF) - 1;
*opcode |= relTarget;
uint16_t relTarget = (((pop_val() - m_Address) / 4) & 0xFFFF) - 1;
*opcode |= relTarget;
}
void CAssembler::arg_shamt(uint32_t* opcode)
{
*opcode |= (pop_val() & 0x1F) << 6;
*opcode |= (pop_val() & 0x1F) << 6;
}
void CAssembler::arg_cache_op(uint32_t* opcode)

View File

@ -1,3 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once
#include <stdint.h>
@ -175,20 +185,20 @@ private:
{ "dmultu", R4300i_SPECIAL_DMULTU, base_spec, syn_arith2 },
{ "ddiv", R4300i_SPECIAL_DDIV, base_spec, syn_arith2 },
{ "ddivu", R4300i_SPECIAL_DDIVU, base_spec, syn_arith2 },
{ "add", R4300i_SPECIAL_ADD, base_spec, syn_arith },
{ "addu", R4300i_SPECIAL_ADDU, base_spec, syn_arith },
{ "sub", R4300i_SPECIAL_SUB, base_spec, syn_arith },
{ "subu", R4300i_SPECIAL_SUBU, base_spec, syn_arith },
{ "and", R4300i_SPECIAL_AND, base_spec, syn_arith },
{ "or", R4300i_SPECIAL_OR, base_spec, syn_arith },
{ "xor", R4300i_SPECIAL_XOR, base_spec, syn_arith },
{ "nor", R4300i_SPECIAL_NOR, base_spec, syn_arith },
{ "slt", R4300i_SPECIAL_SLT, base_spec, syn_arith },
{ "sltu", R4300i_SPECIAL_SLTU, base_spec, syn_arith },
{ "dadd", R4300i_SPECIAL_DADD, base_spec, syn_arith },
{ "daddu", R4300i_SPECIAL_DADDU, base_spec, syn_arith },
{ "dsub", R4300i_SPECIAL_DSUB, base_spec, syn_arith },
{ "dsubu", R4300i_SPECIAL_DSUBU, base_spec, syn_arith },
{ "add", R4300i_SPECIAL_ADD, base_spec, syn_arith },
{ "addu", R4300i_SPECIAL_ADDU, base_spec, syn_arith },
{ "sub", R4300i_SPECIAL_SUB, base_spec, syn_arith },
{ "subu", R4300i_SPECIAL_SUBU, base_spec, syn_arith },
{ "and", R4300i_SPECIAL_AND, base_spec, syn_arith },
{ "or", R4300i_SPECIAL_OR, base_spec, syn_arith },
{ "xor", R4300i_SPECIAL_XOR, base_spec, syn_arith },
{ "nor", R4300i_SPECIAL_NOR, base_spec, syn_arith },
{ "slt", R4300i_SPECIAL_SLT, base_spec, syn_arith },
{ "sltu", R4300i_SPECIAL_SLTU, base_spec, syn_arith },
{ "dadd", R4300i_SPECIAL_DADD, base_spec, syn_arith },
{ "daddu", R4300i_SPECIAL_DADDU, base_spec, syn_arith },
{ "dsub", R4300i_SPECIAL_DSUB, base_spec, syn_arith },
{ "dsubu", R4300i_SPECIAL_DSUBU, base_spec, syn_arith },
{ "tge", R4300i_SPECIAL_TGE, base_spec, syn_arith2 }, // note: no code field
{ "tgeu", R4300i_SPECIAL_TGEU, base_spec, syn_arith2 }, //
{ "tlt", R4300i_SPECIAL_TLT, base_spec, syn_arith2 }, //

View File

@ -1,390 +1,389 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include "stdafx.h"
#include "Breakpoints.h"
#include <Project64-core/N64System/Mips/RegisterClass.h>
#include <Project64-core/N64System/SystemGlobals.h>
#include <Project64-core/N64System/Mips/OpcodeName.h>
#include <Project64-core/N64System/N64Class.h>
CBreakpoints::CBreakpoints() :
m_bHaveRegBP(false),
m_GPRWriteBP(0),
m_GPRReadBP(0),
m_HIWriteBP(false),
m_HIReadBP(false),
m_LOWriteBP(false),
m_LOReadBP(false)
{
}
bool CBreakpoints::RBPAdd(uint32_t address)
{
if (!ReadBPExists8(address))
{
PreUpdateBP();
m_ReadMem.insert(breakpoints_t::value_type(address, false));
UpdateAlignedReadBP();
if (!HaveReadBP())
{
g_Settings->SaveBool(Debugger_ReadBPExists, true);
}
PostUpdateBP();
return true;
}
return false;
}
bool CBreakpoints::WBPAdd(uint32_t address)
{
if (!WriteBPExists8(address))
{
PreUpdateBP();
m_WriteMem.insert(breakpoints_t::value_type(address, false));
UpdateAlignedWriteBP();
if (!HaveWriteBP())
{
g_Settings->SaveBool(Debugger_WriteBPExists, true);
}
PostUpdateBP();
return true;
}
return false;
}
bool CBreakpoints::AddExecution(uint32_t address, bool bTemporary)
{
PreUpdateBP();
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include "stdafx.h"
#include "Breakpoints.h"
#include <Project64-core/N64System/Mips/RegisterClass.h>
#include <Project64-core/N64System/SystemGlobals.h>
#include <Project64-core/N64System/Mips/OpcodeName.h>
#include <Project64-core/N64System/N64Class.h>
CBreakpoints::CBreakpoints() :
m_bHaveRegBP(false),
m_GPRWriteBP(0),
m_GPRReadBP(0),
m_HIWriteBP(false),
m_HIReadBP(false),
m_LOWriteBP(false),
m_LOReadBP(false)
{
}
bool CBreakpoints::RBPAdd(uint32_t address)
{
if (!ReadBPExists8(address))
{
PreUpdateBP();
m_ReadMem.insert(breakpoints_t::value_type(address, false));
UpdateAlignedReadBP();
if (!HaveReadBP())
{
g_Settings->SaveBool(Debugger_ReadBPExists, true);
}
PostUpdateBP();
return true;
}
return false;
}
bool CBreakpoints::WBPAdd(uint32_t address)
{
if (!WriteBPExists8(address))
{
PreUpdateBP();
m_WriteMem.insert(breakpoints_t::value_type(address, false));
UpdateAlignedWriteBP();
if (!HaveWriteBP())
{
g_Settings->SaveBool(Debugger_WriteBPExists, true);
}
PostUpdateBP();
return true;
}
return false;
}
bool CBreakpoints::AddExecution(uint32_t address, bool bTemporary)
{
PreUpdateBP();
#if _MSC_VER >= 1920 // Visual Studio 2019 deprecates _Pairib
auto res = m_Execution.insert(breakpoint_t::value_type(address, bTemporary));
auto res = m_Execution.insert(breakpoint_t::value_type(address, bTemporary));
#else
breakpoints_t::_Pairib res = m_Execution.insert(breakpoint_t::value_type(address, bTemporary));
#endif // _MSC_VER
if (!res.second && !bTemporary)
{
res.first->second = true;
}
if (!HaveExecutionBP())
{
g_Settings->SaveBool(Debugger_HaveExecutionBP, true);
}
PostUpdateBP();
return !res.second;
}
void CBreakpoints::RBPRemove(uint32_t address)
{
PreUpdateBP();
breakpoints_t::iterator itr = m_ReadMem.find(address);
if (itr != m_ReadMem.end())
{
m_ReadMem.erase(itr);
UpdateAlignedWriteBP();
if (m_ReadMem.size() == 0)
{
g_Settings->SaveBool(Debugger_ReadBPExists, false);
}
}
PostUpdateBP();
}
void CBreakpoints::WBPRemove(uint32_t address)
{
PreUpdateBP();
breakpoints_t::iterator itr = m_WriteMem.find(address);
if (itr != m_WriteMem.end())
{
m_WriteMem.erase(itr);
UpdateAlignedWriteBP();
if (m_WriteMem.size() == 0)
{
g_Settings->SaveBool(Debugger_WriteBPExists, false);
}
}
PostUpdateBP();
}
void CBreakpoints::RemoveExecution(uint32_t address)
{
PreUpdateBP();
breakpoints_t::iterator itr = m_Execution.find(address);
if (itr != m_Execution.end())
{
m_Execution.erase(itr);
if (m_Execution.size() == 0)
{
g_Settings->SaveBool(Debugger_HaveExecutionBP, false);
}
}
PostUpdateBP();
}
void CBreakpoints::RBPToggle(uint32_t address)
{
if (RBPAdd(address) == false)
{
RBPRemove(address);
}
}
void CBreakpoints::WBPToggle(uint32_t address)
{
if (WBPAdd(address) == false)
{
WBPRemove(address);
}
}
void CBreakpoints::EBPToggle(uint32_t address, bool bTemporary)
{
if (AddExecution(address, bTemporary) == false)
{
RemoveExecution(address);
}
}
void CBreakpoints::RBPClear()
{
PreUpdateBP();
m_ReadMem.clear();
UpdateAlignedReadBP();
g_Settings->SaveBool(Debugger_ReadBPExists, false);
PostUpdateBP();
}
void CBreakpoints::WBPClear()
{
PreUpdateBP();
m_WriteMem.clear();
UpdateAlignedWriteBP();
g_Settings->SaveBool(Debugger_WriteBPExists, false);
PostUpdateBP();
}
void CBreakpoints::EBPClear()
{
PreUpdateBP();
m_Execution.clear();
g_Settings->SaveBool(Debugger_HaveExecutionBP, false);
PostUpdateBP();
}
void CBreakpoints::BPClear()
{
RBPClear();
WBPClear();
EBPClear();
}
CBreakpoints::BPSTATE CBreakpoints::ReadBPExists8(uint32_t address)
{
breakpoints_t::const_iterator itr = m_ReadMem.find(address);
if (itr != m_ReadMem.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::ReadBPExists16(uint32_t address)
{
breakpoints_t::const_iterator itr = m_ReadMem16.find(address);
if (itr != m_ReadMem16.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::ReadBPExists32(uint32_t address)
{
breakpoints_t::const_iterator itr = m_ReadMem32.find(address);
if (itr != m_ReadMem32.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::ReadBPExists64(uint32_t address)
{
breakpoints_t::const_iterator itr = m_ReadMem64.find(address);
if (itr != m_ReadMem64.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::WriteBPExists8(uint32_t address)
{
breakpoints_t::const_iterator itr = m_WriteMem.find(address);
if (itr != m_WriteMem.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::WriteBPExists16(uint32_t address)
{
breakpoints_t::const_iterator itr = m_WriteMem16.find(address);
if (itr != m_WriteMem16.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::WriteBPExists32(uint32_t address)
{
breakpoints_t::const_iterator itr = m_WriteMem32.find(address);
if (itr != m_WriteMem32.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::WriteBPExists64(uint32_t address)
{
breakpoints_t::const_iterator itr = m_WriteMem64.find(address);
if (itr != m_WriteMem64.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::WriteBPExistsInChunk(uint32_t address, uint32_t nBytes)
{
uint32_t endAddr = address + nBytes;
for (breakpoints_t::iterator breakpoint = m_WriteMem.begin(); breakpoint != m_WriteMem.end(); breakpoint++)
{
uint32_t wbpAddr = breakpoint->first;
if (wbpAddr >= address && wbpAddr < endAddr)
{
return BP_SET;
}
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::ExecutionBPExists(uint32_t address, bool bRemoveTemp)
{
breakpoints_t::const_iterator itr = m_Execution.find(address);
if (itr != m_Execution.end())
{
if (itr->second)
{
if (bRemoveTemp)
{
m_Execution.erase(itr);
}
return BP_SET_TEMP;
}
return BP_SET;
}
return BP_NOT_SET;
}
void CBreakpoints::UpdateAlignedReadBP()
{
m_ReadMem16.clear();
m_ReadMem32.clear();
m_ReadMem64.clear();
for (breakpoints_t::const_iterator itr = m_ReadMem.begin(); itr != m_ReadMem.end(); itr++)
{
m_ReadMem16.insert(breakpoints_t::value_type((itr->first & ~0x1), false));
m_ReadMem32.insert(breakpoints_t::value_type((itr->first & ~0x3), false));
m_ReadMem64.insert(breakpoints_t::value_type((itr->first & ~0x7), false));
}
}
void CBreakpoints::UpdateAlignedWriteBP()
{
m_WriteMem16.clear();
m_WriteMem32.clear();
m_WriteMem64.clear();
for (breakpoints_t::const_iterator itr = m_WriteMem.begin(); itr != m_WriteMem.end(); itr++)
{
m_WriteMem16.insert(breakpoints_t::value_type((itr->first & ~0x1), false));
m_WriteMem32.insert(breakpoints_t::value_type((itr->first & ~0x3), false));
m_WriteMem64.insert(breakpoints_t::value_type((itr->first & ~0x7), false));
}
}
void CBreakpoints::ToggleMemLock(uint32_t address)
{
if (m_MemLocks.count(address) == 0)
{
m_MemLocks.insert(address);
return;
}
m_MemLocks.erase(address);
}
bool CBreakpoints::MemLockExists(uint32_t address, int nBytes)
{
for (memlocks_t::const_iterator itr = m_MemLocks.begin(); itr != m_MemLocks.end(); itr++)
{
if (*itr >= address && *itr < (address + nBytes))
{
return true;
}
}
return false;
}
void CBreakpoints::ClearMemLocks()
{
m_MemLocks.clear();
}
size_t CBreakpoints::NumMemLocks()
{
return m_MemLocks.size();
}
void CBreakpoints::UpdateHaveRegBP(void)
{
m_bHaveRegBP = HaveAnyGPRWriteBP() || HaveAnyGPRReadBP() || HaveHIWriteBP() || HaveHIReadBP() || HaveLOWriteBP() || HaveLOReadBP();
}
void CBreakpoints::ToggleGPRWriteBP(int nReg) { m_GPRWriteBP ^= (1 << nReg); UpdateHaveRegBP(); }
void CBreakpoints::ToggleGPRReadBP(int nReg) { m_GPRReadBP ^= (1 << nReg); UpdateHaveRegBP(); }
void CBreakpoints::ToggleHIWriteBP(void) { m_HIWriteBP = !m_HIWriteBP; UpdateHaveRegBP(); }
void CBreakpoints::ToggleHIReadBP(void) { m_HIReadBP = !m_HIReadBP; UpdateHaveRegBP(); }
void CBreakpoints::ToggleLOWriteBP(void) { m_LOWriteBP = !m_LOWriteBP; UpdateHaveRegBP(); }
void CBreakpoints::ToggleLOReadBP(void) { m_LOReadBP = !m_LOReadBP; UpdateHaveRegBP(); }
void CBreakpoints::PreUpdateBP()
{
if (g_BaseSystem)
{
g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_ChangingBPs);
}
}
void CBreakpoints::PostUpdateBP()
{
if (g_BaseSystem)
{
g_BaseSystem->ExternalEvent(SysEvent_ResetRecompilerCode);
g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_ChangingBPs);
}
}
if (!res.second && !bTemporary)
{
res.first->second = true;
}
if (!HaveExecutionBP())
{
g_Settings->SaveBool(Debugger_HaveExecutionBP, true);
}
PostUpdateBP();
return !res.second;
}
void CBreakpoints::RBPRemove(uint32_t address)
{
PreUpdateBP();
breakpoints_t::iterator itr = m_ReadMem.find(address);
if (itr != m_ReadMem.end())
{
m_ReadMem.erase(itr);
UpdateAlignedWriteBP();
if (m_ReadMem.size() == 0)
{
g_Settings->SaveBool(Debugger_ReadBPExists, false);
}
}
PostUpdateBP();
}
void CBreakpoints::WBPRemove(uint32_t address)
{
PreUpdateBP();
breakpoints_t::iterator itr = m_WriteMem.find(address);
if (itr != m_WriteMem.end())
{
m_WriteMem.erase(itr);
UpdateAlignedWriteBP();
if (m_WriteMem.size() == 0)
{
g_Settings->SaveBool(Debugger_WriteBPExists, false);
}
}
PostUpdateBP();
}
void CBreakpoints::RemoveExecution(uint32_t address)
{
PreUpdateBP();
breakpoints_t::iterator itr = m_Execution.find(address);
if (itr != m_Execution.end())
{
m_Execution.erase(itr);
if (m_Execution.size() == 0)
{
g_Settings->SaveBool(Debugger_HaveExecutionBP, false);
}
}
PostUpdateBP();
}
void CBreakpoints::RBPToggle(uint32_t address)
{
if (RBPAdd(address) == false)
{
RBPRemove(address);
}
}
void CBreakpoints::WBPToggle(uint32_t address)
{
if (WBPAdd(address) == false)
{
WBPRemove(address);
}
}
void CBreakpoints::EBPToggle(uint32_t address, bool bTemporary)
{
if (AddExecution(address, bTemporary) == false)
{
RemoveExecution(address);
}
}
void CBreakpoints::RBPClear()
{
PreUpdateBP();
m_ReadMem.clear();
UpdateAlignedReadBP();
g_Settings->SaveBool(Debugger_ReadBPExists, false);
PostUpdateBP();
}
void CBreakpoints::WBPClear()
{
PreUpdateBP();
m_WriteMem.clear();
UpdateAlignedWriteBP();
g_Settings->SaveBool(Debugger_WriteBPExists, false);
PostUpdateBP();
}
void CBreakpoints::EBPClear()
{
PreUpdateBP();
m_Execution.clear();
g_Settings->SaveBool(Debugger_HaveExecutionBP, false);
PostUpdateBP();
}
void CBreakpoints::BPClear()
{
RBPClear();
WBPClear();
EBPClear();
}
CBreakpoints::BPSTATE CBreakpoints::ReadBPExists8(uint32_t address)
{
breakpoints_t::const_iterator itr = m_ReadMem.find(address);
if (itr != m_ReadMem.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::ReadBPExists16(uint32_t address)
{
breakpoints_t::const_iterator itr = m_ReadMem16.find(address);
if (itr != m_ReadMem16.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::ReadBPExists32(uint32_t address)
{
breakpoints_t::const_iterator itr = m_ReadMem32.find(address);
if (itr != m_ReadMem32.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::ReadBPExists64(uint32_t address)
{
breakpoints_t::const_iterator itr = m_ReadMem64.find(address);
if (itr != m_ReadMem64.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::WriteBPExists8(uint32_t address)
{
breakpoints_t::const_iterator itr = m_WriteMem.find(address);
if (itr != m_WriteMem.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::WriteBPExists16(uint32_t address)
{
breakpoints_t::const_iterator itr = m_WriteMem16.find(address);
if (itr != m_WriteMem16.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::WriteBPExists32(uint32_t address)
{
breakpoints_t::const_iterator itr = m_WriteMem32.find(address);
if (itr != m_WriteMem32.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::WriteBPExists64(uint32_t address)
{
breakpoints_t::const_iterator itr = m_WriteMem64.find(address);
if (itr != m_WriteMem64.end())
{
return BP_SET;
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::WriteBPExistsInChunk(uint32_t address, uint32_t nBytes)
{
uint32_t endAddr = address + nBytes;
for (breakpoints_t::iterator breakpoint = m_WriteMem.begin(); breakpoint != m_WriteMem.end(); breakpoint++)
{
uint32_t wbpAddr = breakpoint->first;
if (wbpAddr >= address && wbpAddr < endAddr)
{
return BP_SET;
}
}
return BP_NOT_SET;
}
CBreakpoints::BPSTATE CBreakpoints::ExecutionBPExists(uint32_t address, bool bRemoveTemp)
{
breakpoints_t::const_iterator itr = m_Execution.find(address);
if (itr != m_Execution.end())
{
if (itr->second)
{
if (bRemoveTemp)
{
m_Execution.erase(itr);
}
return BP_SET_TEMP;
}
return BP_SET;
}
return BP_NOT_SET;
}
void CBreakpoints::UpdateAlignedReadBP()
{
m_ReadMem16.clear();
m_ReadMem32.clear();
m_ReadMem64.clear();
for (breakpoints_t::const_iterator itr = m_ReadMem.begin(); itr != m_ReadMem.end(); itr++)
{
m_ReadMem16.insert(breakpoints_t::value_type((itr->first & ~0x1), false));
m_ReadMem32.insert(breakpoints_t::value_type((itr->first & ~0x3), false));
m_ReadMem64.insert(breakpoints_t::value_type((itr->first & ~0x7), false));
}
}
void CBreakpoints::UpdateAlignedWriteBP()
{
m_WriteMem16.clear();
m_WriteMem32.clear();
m_WriteMem64.clear();
for (breakpoints_t::const_iterator itr = m_WriteMem.begin(); itr != m_WriteMem.end(); itr++)
{
m_WriteMem16.insert(breakpoints_t::value_type((itr->first & ~0x1), false));
m_WriteMem32.insert(breakpoints_t::value_type((itr->first & ~0x3), false));
m_WriteMem64.insert(breakpoints_t::value_type((itr->first & ~0x7), false));
}
}
void CBreakpoints::ToggleMemLock(uint32_t address)
{
if (m_MemLocks.count(address) == 0)
{
m_MemLocks.insert(address);
return;
}
m_MemLocks.erase(address);
}
bool CBreakpoints::MemLockExists(uint32_t address, int nBytes)
{
for (memlocks_t::const_iterator itr = m_MemLocks.begin(); itr != m_MemLocks.end(); itr++)
{
if (*itr >= address && *itr < (address + nBytes))
{
return true;
}
}
return false;
}
void CBreakpoints::ClearMemLocks()
{
m_MemLocks.clear();
}
size_t CBreakpoints::NumMemLocks()
{
return m_MemLocks.size();
}
void CBreakpoints::UpdateHaveRegBP(void)
{
m_bHaveRegBP = HaveAnyGPRWriteBP() || HaveAnyGPRReadBP() || HaveHIWriteBP() || HaveHIReadBP() || HaveLOWriteBP() || HaveLOReadBP();
}
void CBreakpoints::ToggleGPRWriteBP(int nReg) { m_GPRWriteBP ^= (1 << nReg); UpdateHaveRegBP(); }
void CBreakpoints::ToggleGPRReadBP(int nReg) { m_GPRReadBP ^= (1 << nReg); UpdateHaveRegBP(); }
void CBreakpoints::ToggleHIWriteBP(void) { m_HIWriteBP = !m_HIWriteBP; UpdateHaveRegBP(); }
void CBreakpoints::ToggleHIReadBP(void) { m_HIReadBP = !m_HIReadBP; UpdateHaveRegBP(); }
void CBreakpoints::ToggleLOWriteBP(void) { m_LOWriteBP = !m_LOWriteBP; UpdateHaveRegBP(); }
void CBreakpoints::ToggleLOReadBP(void) { m_LOReadBP = !m_LOReadBP; UpdateHaveRegBP(); }
void CBreakpoints::PreUpdateBP()
{
if (g_BaseSystem)
{
g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_ChangingBPs);
}
}
void CBreakpoints::PostUpdateBP()
{
if (g_BaseSystem)
{
g_BaseSystem->ExternalEvent(SysEvent_ResetRecompilerCode);
g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_ChangingBPs);
}
}

View File

@ -1,7 +1,15 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include "stdafx.h"
#include "CPULog.h"
#include <Project64-core/N64System/Mips/OpCodeName.h>
CCPULog::CCPULog(size_t size) :

View File

@ -1,3 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once
#include <stdafx.h>

View File

@ -13,99 +13,99 @@
void CDMALog::AddEntry(uint32_t romAddr, uint32_t ramAddr, uint32_t length)
{
DMALOGENTRY entry = { romAddr, ramAddr, length };
m_Log.push_back(entry);
DMALOGENTRY entry = { romAddr, ramAddr, length };
m_Log.push_back(entry);
}
void CDMALog::ClearEntries()
{
m_Log.clear();
m_Log.clear();
}
size_t CDMALog::GetNumEntries()
{
return m_Log.size();
return m_Log.size();
}
DMALOGENTRY* CDMALog::GetEntryByIndex(uint32_t index)
{
if (index < m_Log.size())
{
return &m_Log[index];
}
return NULL;
if (index < m_Log.size())
{
return &m_Log[index];
}
return NULL;
}
DMALOGENTRY* CDMALog::GetEntryByRamAddress(uint32_t ramAddr)
{
uint32_t nEntries = GetNumEntries();
uint32_t nEntries = GetNumEntries();
if (nEntries == 0)
{
return NULL;
}
if (nEntries == 0)
{
return NULL;
}
for (uint32_t i = nEntries - 1; i-- > 0;)
{
uint32_t min = m_Log[i].ramAddr;
uint32_t max = min + m_Log[i].length - 1;
for (uint32_t i = nEntries - 1; i-- > 0;)
{
uint32_t min = m_Log[i].ramAddr;
uint32_t max = min + m_Log[i].length - 1;
if (ramAddr >= min && ramAddr <= max)
{
return &m_Log[i];
}
}
return NULL;
if (ramAddr >= min && ramAddr <= max)
{
return &m_Log[i];
}
}
return NULL;
}
DMALOGENTRY* CDMALog::GetEntryByRamAddress(uint32_t ramAddr, uint32_t* lpRomAddr, uint32_t* lpOffset)
{
DMALOGENTRY* lpEntry = GetEntryByRamAddress(ramAddr);
DMALOGENTRY* lpEntry = GetEntryByRamAddress(ramAddr);
if (lpEntry == NULL)
{
return NULL;
}
if (lpEntry == NULL)
{
return NULL;
}
*lpOffset = ramAddr - lpEntry->ramAddr;
*lpRomAddr = lpEntry->romAddr + *lpOffset;
*lpOffset = ramAddr - lpEntry->ramAddr;
*lpRomAddr = lpEntry->romAddr + *lpOffset;
return lpEntry;
return lpEntry;
}
DMALOGENTRY* CDMALog::GetEntryByRomAddress(uint32_t romAddr)
{
uint32_t nEntries = GetNumEntries();
uint32_t nEntries = GetNumEntries();
if (nEntries == 0)
{
return NULL;
}
if (nEntries == 0)
{
return NULL;
}
for (uint32_t i = nEntries - 1; i-- > 0; )
{
uint32_t min = m_Log[i].romAddr;
uint32_t max = min + m_Log[i].length - 1;
for (uint32_t i = nEntries - 1; i-- > 0; )
{
uint32_t min = m_Log[i].romAddr;
uint32_t max = min + m_Log[i].length - 1;
if (romAddr >= min && romAddr <= max)
{
return &m_Log[i];
}
}
return NULL;
if (romAddr >= min && romAddr <= max)
{
return &m_Log[i];
}
}
return NULL;
}
DMALOGENTRY* CDMALog::GetEntryByRomAddress(uint32_t romAddr, uint32_t* lpRamAddr, uint32_t* lpOffset)
{
DMALOGENTRY* lpEntry = GetEntryByRomAddress(romAddr);
DMALOGENTRY* lpEntry = GetEntryByRomAddress(romAddr);
if (lpEntry == NULL)
{
return NULL;
}
if (lpEntry == NULL)
{
return NULL;
}
*lpOffset = romAddr - lpEntry->romAddr;
*lpRamAddr = lpEntry->ramAddr + *lpOffset;
*lpOffset = romAddr - lpEntry->romAddr;
*lpRamAddr = lpEntry->ramAddr + *lpOffset;
return lpEntry;
return lpEntry;
}

View File

@ -1,3 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once
#include <Project64-core/Settings/SettingType/SettingsType-Application.h>
@ -30,8 +40,8 @@ protected:
m_bInitialized = true;
}
void LoadWindowPos()
{
void LoadWindowPos()
{
if (!m_bInitialized)
{
@ -51,10 +61,10 @@ protected:
pT->SetWindowPos(NULL, left, top, width, height, 1);
pT->RedrawWindow();
}
}
}
void SaveWindowPos(bool bSaveSize)
{
void SaveWindowPos(bool bSaveSize)
{
if (!m_bInitialized)
{
return;
@ -69,7 +79,7 @@ protected:
else {
UISettingsSaveString(m_UISettingID, stdstr_f("%d,%d,%d,%d", rect.left, rect.top, rect.Width(), rect.Height()).c_str());
}
}
}
public:
CDebugDialog(CDebuggerUI * debugger) :

View File

@ -1,304 +1,339 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include <stdafx.h>
#include "DebugMMU.h"
#include <Common/MemoryManagement.h>
#include <Project64-core/N64System/N64DiskClass.h>
uint32_t* CDebugMMU::PAddrWordPtr(uint32_t paddr)
#define PJMEM_CARTROM 1
uint8_t* CDebugMMU::GetPhysicalPtr(uint32_t paddr, WORD* flags)
{
if (g_MMU == NULL)
{
return NULL;
}
uint8_t* ptr = NULL;
int nbyte = paddr & 3;
paddr = paddr & ~3;
// RDRAM & DMEM/IMEM
if ((paddr < g_MMU->RdramSize()) ||
(paddr >= 0x04000000 && paddr <= 0x04001FFF))
{
return (uint32_t*)(g_MMU->Rdram() + paddr);
}
bool bBigEndian = false;
bool bCartRom = false;
// 64DD buffer
if (paddr >= 0x05000000 && paddr <= 0x050004FF)
if ((paddr < g_MMU->RdramSize()) ||
(paddr >= 0x04000000 && paddr <= 0x04001FFF)) // RDRAM & DMEM/IMEM
{
ptr = (uint8_t*)(g_MMU->Rdram() + paddr);
}
else if (paddr >= 0x05000000 && paddr <= 0x050004FF) // 64DD buffer
{
// todo
return NULL;
}
// Cartridge Domain 1 (Address 1) (64DD IPL ROM)
if (paddr >= 0x06000000 && paddr <= 0x06FFFFFF)
else if (paddr >= 0x06000000 && paddr <= 0x06FFFFFF) // Cartridge Domain 1 (Address 1) (64DD IPL ROM)
{
uint32_t iplRomOffset = paddr - 0x06000000;
if (g_DDRom != NULL && iplRomOffset < g_DDRom->GetRomSize())
{
return (uint32_t*)(g_MMU->Rdram() + paddr);
ptr = (uint8_t*)(g_MMU->Rdram() + paddr);
}
return NULL;
}
// Cartridge Domain 2 (Address 2) (SRAM/FlashRAM)
if (paddr >= 0x08000000 && paddr < 0x08FFFFFF)
{
// stored in a file
return NULL;
}
// Cartridge ROM
if (paddr >= 0x10000000 && paddr <= 0x15FFFFFF)
else if (paddr >= 0x10000000 && paddr <= 0x1FBFFFFF) // Cartridge ROM
{
uint32_t cartRomOffset = paddr - 0x10000000;
if (g_Rom != NULL && cartRomOffset < g_Rom->GetRomSize())
{
return (uint32_t*)(g_Rom->GetRomAddress() + cartRomOffset);
ptr = (uint8_t*)(g_Rom->GetRomAddress() + cartRomOffset);
bCartRom = true;
}
}
else if (paddr >= 0x1FC007C0 && paddr <= 0x1FC007FF) // PIF RAM
{
uint32_t pifRamOffset = paddr - 0x1FC007C0;
ptr = (uint8_t*)(g_MMU->PifRam() + pifRamOffset);
bBigEndian = true;
}
else
{
// note: write-only registers are excluded
switch (paddr)
{
case 0x03F00000: ptr = (uint8_t*)&g_Reg->RDRAM_CONFIG_REG; break;
case 0x03F00004: ptr = (uint8_t*)&g_Reg->RDRAM_DEVICE_ID_REG; break;
case 0x03F00008: ptr = (uint8_t*)&g_Reg->RDRAM_DELAY_REG; break;
case 0x03F0000C: ptr = (uint8_t*)&g_Reg->RDRAM_MODE_REG; break;
case 0x03F00010: ptr = (uint8_t*)&g_Reg->RDRAM_REF_INTERVAL_REG; break;
case 0x03F00014: ptr = (uint8_t*)&g_Reg->RDRAM_REF_ROW_REG; break;
case 0x03F00018: ptr = (uint8_t*)&g_Reg->RDRAM_RAS_INTERVAL_REG; break;
case 0x03F0001C: ptr = (uint8_t*)&g_Reg->RDRAM_MIN_INTERVAL_REG; break;
case 0x03F00020: ptr = (uint8_t*)&g_Reg->RDRAM_ADDR_SELECT_REG; break;
case 0x03F00024: ptr = (uint8_t*)&g_Reg->RDRAM_DEVICE_MANUF_REG; break;
case 0x04040010: ptr = (uint8_t*)&g_Reg->SP_STATUS_REG; break;
case 0x04040014: ptr = (uint8_t*)&g_Reg->SP_DMA_FULL_REG; break;
case 0x04040018: ptr = (uint8_t*)&g_Reg->SP_DMA_BUSY_REG; break;
case 0x0404001C: ptr = (uint8_t*)&g_Reg->SP_SEMAPHORE_REG; break;
case 0x04080000: ptr = (uint8_t*)&g_Reg->SP_PC_REG; break;
case 0x0410000C: ptr = (uint8_t*)&g_Reg->DPC_STATUS_REG; break;
case 0x04100010: ptr = (uint8_t*)&g_Reg->DPC_CLOCK_REG; break;
case 0x04100014: ptr = (uint8_t*)&g_Reg->DPC_BUFBUSY_REG; break;
case 0x04100018: ptr = (uint8_t*)&g_Reg->DPC_PIPEBUSY_REG; break;
case 0x0410001C: ptr = (uint8_t*)&g_Reg->DPC_TMEM_REG; break;
case 0x04300000: ptr = (uint8_t*)&g_Reg->MI_MODE_REG; break;
case 0x04300004: ptr = (uint8_t*)&g_Reg->MI_VERSION_REG; break;
case 0x04300008: ptr = (uint8_t*)&g_Reg->MI_INTR_REG; break;
case 0x0430000C: ptr = (uint8_t*)&g_Reg->MI_INTR_MASK_REG; break;
case 0x04400000: ptr = (uint8_t*)&g_Reg->VI_STATUS_REG; break;
case 0x04400004: ptr = (uint8_t*)&g_Reg->VI_ORIGIN_REG; break;
case 0x04400008: ptr = (uint8_t*)&g_Reg->VI_WIDTH_REG; break;
case 0x0440000C: ptr = (uint8_t*)&g_Reg->VI_INTR_REG; break;
case 0x04400010: ptr = (uint8_t*)&g_Reg->VI_V_CURRENT_LINE_REG; break;
case 0x04400014: ptr = (uint8_t*)&g_Reg->VI_BURST_REG; break;
case 0x04400018: ptr = (uint8_t*)&g_Reg->VI_V_SYNC_REG; break;
case 0x0440001C: ptr = (uint8_t*)&g_Reg->VI_H_SYNC_REG; break;
case 0x04400020: ptr = (uint8_t*)&g_Reg->VI_LEAP_REG; break;
case 0x04400024: ptr = (uint8_t*)&g_Reg->VI_H_START_REG; break;
case 0x04400028: ptr = (uint8_t*)&g_Reg->VI_V_START_REG; break;
case 0x0440002C: ptr = (uint8_t*)&g_Reg->VI_V_BURST_REG; break;
case 0x04400030: ptr = (uint8_t*)&g_Reg->VI_X_SCALE_REG; break;
case 0x04400034: ptr = (uint8_t*)&g_Reg->VI_Y_SCALE_REG; break;
case 0x04600000: ptr = (uint8_t*)&g_Reg->PI_DRAM_ADDR_REG; break;
case 0x04600004: ptr = (uint8_t*)&g_Reg->PI_CART_ADDR_REG; break;
case 0x04600008: ptr = (uint8_t*)&g_Reg->PI_RD_LEN_REG; break;
case 0x0460000C: ptr = (uint8_t*)&g_Reg->PI_WR_LEN_REG; break;
case 0x04600010: ptr = (uint8_t*)&g_Reg->PI_STATUS_REG; break;
case 0x04600014: ptr = (uint8_t*)&g_Reg->PI_DOMAIN1_REG; break;
case 0x04600018: ptr = (uint8_t*)&g_Reg->PI_BSD_DOM1_PWD_REG; break;
case 0x0460001C: ptr = (uint8_t*)&g_Reg->PI_BSD_DOM1_PGS_REG; break;
case 0x04600020: ptr = (uint8_t*)&g_Reg->PI_BSD_DOM1_RLS_REG; break;
case 0x04600024: ptr = (uint8_t*)&g_Reg->PI_DOMAIN2_REG; break;
case 0x04600028: ptr = (uint8_t*)&g_Reg->PI_BSD_DOM2_PWD_REG; break;
case 0x0460002C: ptr = (uint8_t*)&g_Reg->PI_BSD_DOM2_PGS_REG; break;
case 0x04600030: ptr = (uint8_t*)&g_Reg->PI_BSD_DOM2_RLS_REG; break;
case 0x04700000: ptr = (uint8_t*)&g_Reg->RI_MODE_REG; break;
case 0x04700004: ptr = (uint8_t*)&g_Reg->RI_CONFIG_REG; break;
case 0x04700008: ptr = (uint8_t*)&g_Reg->RI_CURRENT_LOAD_REG; break;
case 0x0470000C: ptr = (uint8_t*)&g_Reg->RI_SELECT_REG; break;
case 0x04700010: ptr = (uint8_t*)&g_Reg->RI_REFRESH_REG; break;
case 0x04700014: ptr = (uint8_t*)&g_Reg->RI_LATENCY_REG; break;
case 0x04700018: ptr = (uint8_t*)&g_Reg->RI_RERROR_REG; break;
case 0x0470001C: ptr = (uint8_t*)&g_Reg->RI_WERROR_REG; break;
case 0x04800018: ptr = (uint8_t*)&g_Reg->SI_STATUS_REG; break;
case 0x05000500: ptr = (uint8_t*)&g_Reg->ASIC_DATA; break;
case 0x05000504: ptr = (uint8_t*)&g_Reg->ASIC_MISC_REG; break;
case 0x05000508: ptr = (uint8_t*)&g_Reg->ASIC_STATUS; break;
case 0x0500050C: ptr = (uint8_t*)&g_Reg->ASIC_CUR_TK; break;
case 0x05000510: ptr = (uint8_t*)&g_Reg->ASIC_BM_STATUS; break;
case 0x05000514: ptr = (uint8_t*)&g_Reg->ASIC_ERR_SECTOR; break;
case 0x05000518: ptr = (uint8_t*)&g_Reg->ASIC_SEQ_STATUS; break;
case 0x0500051C: ptr = (uint8_t*)&g_Reg->ASIC_CUR_SECTOR; break;
case 0x05000520: ptr = (uint8_t*)&g_Reg->ASIC_HARD_RESET; break;
case 0x05000524: ptr = (uint8_t*)&g_Reg->ASIC_C1_S0; break;
case 0x05000528: ptr = (uint8_t*)&g_Reg->ASIC_HOST_SECBYTE; break;
case 0x0500052C: ptr = (uint8_t*)&g_Reg->ASIC_C1_S2; break;
case 0x05000530: ptr = (uint8_t*)&g_Reg->ASIC_SEC_BYTE; break;
case 0x05000534: ptr = (uint8_t*)&g_Reg->ASIC_C1_S4; break;
case 0x05000538: ptr = (uint8_t*)&g_Reg->ASIC_C1_S6; break;
case 0x0500053C: ptr = (uint8_t*)&g_Reg->ASIC_CUR_ADDR; break;
case 0x05000540: ptr = (uint8_t*)&g_Reg->ASIC_ID_REG; break;
case 0x05000544: ptr = (uint8_t*)&g_Reg->ASIC_TEST_REG; break;
case 0x05000548: ptr = (uint8_t*)&g_Reg->ASIC_TEST_PIN_SEL; break;
}
return false;
}
// PIF ROM
if (paddr >= 0x1FC00000 && paddr <= 0x1FC007BF)
if (ptr == NULL)
{
return NULL;
}
// PIF RAM
if (paddr >= 0x1FC007C0 && paddr <= 0x1FC007FF)
if (flags != NULL)
{
uint32_t pifRamOffset = paddr - 0x1FC007C0;
return (uint32_t*)(g_MMU->PifRam() + pifRamOffset);
*flags = (bCartRom ? PJMEM_CARTROM : 0);
}
switch (paddr)
if (bBigEndian)
{
case 0x03F00000: return &g_Reg->RDRAM_CONFIG_REG;
case 0x03F00004: return &g_Reg->RDRAM_DEVICE_ID_REG;
case 0x03F00008: return &g_Reg->RDRAM_DELAY_REG;
case 0x03F0000C: return &g_Reg->RDRAM_MODE_REG;
case 0x03F00010: return &g_Reg->RDRAM_REF_INTERVAL_REG;
case 0x03F00014: return &g_Reg->RDRAM_REF_ROW_REG;
case 0x03F00018: return &g_Reg->RDRAM_RAS_INTERVAL_REG;
case 0x03F0001C: return &g_Reg->RDRAM_MIN_INTERVAL_REG;
case 0x03F00020: return &g_Reg->RDRAM_ADDR_SELECT_REG;
case 0x03F00024: return &g_Reg->RDRAM_DEVICE_MANUF_REG;
case 0x04040010: return &g_Reg->SP_STATUS_REG;
case 0x04040014: return &g_Reg->SP_DMA_FULL_REG;
case 0x04040018: return &g_Reg->SP_DMA_BUSY_REG;
case 0x0404001C: return &g_Reg->SP_SEMAPHORE_REG;
case 0x04080000: return &g_Reg->SP_PC_REG;
case 0x0410000C: return &g_Reg->DPC_STATUS_REG;
case 0x04100010: return &g_Reg->DPC_CLOCK_REG;
case 0x04100014: return &g_Reg->DPC_BUFBUSY_REG;
case 0x04100018: return &g_Reg->DPC_PIPEBUSY_REG;
case 0x0410001C: return &g_Reg->DPC_TMEM_REG;
case 0x04300000: return &g_Reg->MI_MODE_REG;
case 0x04300004: return &g_Reg->MI_VERSION_REG;
case 0x04300008: return &g_Reg->MI_INTR_REG;
case 0x0430000C: return &g_Reg->MI_INTR_MASK_REG;
case 0x04400000: return &g_Reg->VI_STATUS_REG;
case 0x04400004: return &g_Reg->VI_ORIGIN_REG;
case 0x04400008: return &g_Reg->VI_WIDTH_REG;
case 0x0440000C: return &g_Reg->VI_INTR_REG;
case 0x04400010: return &g_Reg->VI_V_CURRENT_LINE_REG;
case 0x04400014: return &g_Reg->VI_BURST_REG;
case 0x04400018: return &g_Reg->VI_V_SYNC_REG;
case 0x0440001C: return &g_Reg->VI_H_SYNC_REG;
case 0x04400020: return &g_Reg->VI_LEAP_REG;
case 0x04400024: return &g_Reg->VI_H_START_REG;
case 0x04400028: return &g_Reg->VI_V_START_REG;
case 0x0440002C: return &g_Reg->VI_V_BURST_REG;
case 0x04400030: return &g_Reg->VI_X_SCALE_REG;
case 0x04400034: return &g_Reg->VI_Y_SCALE_REG;
case 0x04600000: return &g_Reg->PI_DRAM_ADDR_REG;
case 0x04600004: return &g_Reg->PI_CART_ADDR_REG;
case 0x04600008: return &g_Reg->PI_RD_LEN_REG;
case 0x0460000C: return &g_Reg->PI_WR_LEN_REG;
case 0x04600010: return &g_Reg->PI_STATUS_REG;
case 0x04600014: return &g_Reg->PI_DOMAIN1_REG;
case 0x04600018: return &g_Reg->PI_BSD_DOM1_PWD_REG;
case 0x0460001C: return &g_Reg->PI_BSD_DOM1_PGS_REG;
case 0x04600020: return &g_Reg->PI_BSD_DOM1_RLS_REG;
case 0x04600024: return &g_Reg->PI_DOMAIN2_REG;
case 0x04600028: return &g_Reg->PI_BSD_DOM2_PWD_REG;
case 0x0460002C: return &g_Reg->PI_BSD_DOM2_PGS_REG;
case 0x04600030: return &g_Reg->PI_BSD_DOM2_RLS_REG;
case 0x04700000: return &g_Reg->RI_MODE_REG;
case 0x04700004: return &g_Reg->RI_CONFIG_REG;
case 0x04700008: return &g_Reg->RI_CURRENT_LOAD_REG;
case 0x0470000C: return &g_Reg->RI_SELECT_REG;
case 0x04700010: return &g_Reg->RI_REFRESH_REG;
case 0x04700014: return &g_Reg->RI_LATENCY_REG;
case 0x04700018: return &g_Reg->RI_RERROR_REG;
case 0x0470001C: return &g_Reg->RI_WERROR_REG;
case 0x04800018: return &g_Reg->SI_STATUS_REG;
case 0x05000500: return &g_Reg->ASIC_DATA;
case 0x05000504: return &g_Reg->ASIC_MISC_REG;
case 0x05000508: return &g_Reg->ASIC_STATUS;
case 0x0500050C: return &g_Reg->ASIC_CUR_TK;
case 0x05000510: return &g_Reg->ASIC_BM_STATUS;
case 0x05000514: return &g_Reg->ASIC_ERR_SECTOR;
case 0x05000518: return &g_Reg->ASIC_SEQ_STATUS;
case 0x0500051C: return &g_Reg->ASIC_CUR_SECTOR;
case 0x05000520: return &g_Reg->ASIC_HARD_RESET;
case 0x05000524: return &g_Reg->ASIC_C1_S0;
case 0x05000528: return &g_Reg->ASIC_HOST_SECBYTE;
case 0x0500052C: return &g_Reg->ASIC_C1_S2;
case 0x05000530: return &g_Reg->ASIC_SEC_BYTE;
case 0x05000534: return &g_Reg->ASIC_C1_S4;
case 0x05000538: return &g_Reg->ASIC_C1_S6;
case 0x0500053C: return &g_Reg->ASIC_CUR_ADDR;
case 0x05000540: return &g_Reg->ASIC_ID_REG;
case 0x05000544: return &g_Reg->ASIC_TEST_REG;
case 0x05000548: return &g_Reg->ASIC_TEST_PIN_SEL;
return &ptr[nbyte];
}
else
{
return &ptr[nbyte ^ 3];
}
return NULL;
}
bool CDebugMMU::DebugLW_PAddr(uint32_t paddr, uint32_t& value)
bool CDebugMMU::GetPhysicalByte(uint32_t paddr, uint8_t* value)
{
if (g_MMU == NULL)
{
return false;
}
uint32_t* ptr = PAddrWordPtr(paddr);
uint8_t* ptr = GetPhysicalPtr(paddr, NULL);
if (ptr != NULL)
{
value = *ptr;
*value = *ptr;
return true;
}
if (paddr >= 0x08000000 && paddr < 0x08FFFFFF) // Cartridge Domain 2 (Address 2)
int nByte = paddr & 3;
if (paddr >= 0x08000000 && paddr <= 0x08FFFFFF) // Cartridge Domain 2 (Address 2)
{
uint32_t saveOffset = paddr & 0x000FFFFF;
if (g_System->m_SaveUsing == SaveChip_Sram && saveOffset <= 0x7FFF) // sram
{
uint8_t tmp[4] = "";
uint32_t wordpaddr = paddr & ~3;
uint8_t data[4];
CSram *sram = g_MMU->GetSram();
sram->DmaFromSram(tmp, paddr - 0x08000000, 4);
value = tmp[3] << 24 | tmp[2] << 16 | tmp[1] << 8 | tmp[0];
sram->DmaFromSram(data, wordpaddr - 0x08000000, 4);
*value = data[nByte ^ 3];
return true;
}
else if (g_System->m_SaveUsing == SaveChip_FlashRam && saveOffset == 0) // flash ram status
else if (g_System->m_SaveUsing == SaveChip_FlashRam && saveOffset <= 3) // flash ram status
{
CFlashram* flashRam = g_MMU->GetFlashram();
value = flashRam->ReadFromFlashStatus(0x08000000);
uint32_t flashStatus = flashRam->ReadFromFlashStatus(0x08000000);
*value = (flashStatus >> (24 - nByte * 8)) & 0xFF;
return true;
}
}
if (paddr == 0x04500004)
if (paddr >= 0x04500004 && paddr <= 0x04500007)
{
uint32_t audioLength;
if (g_System->bFixedAudio())
{
value = g_Audio->GetLength();
audioLength = g_Audio->GetLength();
}
else
{
CAudioPlugin* audioPlg = g_Plugins->Audio();
value = (audioPlg->AiReadLength != NULL) ? audioPlg->AiReadLength() : 0;
audioLength = audioPlg->AiReadLength != NULL ? audioPlg->AiReadLength() : 0;
}
*value = (audioLength >> (24 - nByte * 8)) & 0xFF;
return true;
}
if (paddr == 0x0450000C)
if (paddr >= 0x0450000C && paddr <= 0x0450000F)
{
value = g_System->bFixedAudio() ? g_Audio->GetStatus() : g_Reg->AI_STATUS_REG;
uint32_t audioStatus = g_System->bFixedAudio() ? g_Audio->GetStatus() : g_Reg->AI_STATUS_REG;
*value = (audioStatus >> (24 - nByte * 8)) & 0xFF;
return true;
}
return false;
}
bool CDebugMMU::DebugLW_VAddr(uint32_t vaddr, uint32_t& value)
bool CDebugMMU::SetPhysicalByte(uint32_t paddr, uint8_t value)
{
if (vaddr <= 0x7FFFFFFF || vaddr >= 0xC0000000) // KUSEG, KSEG2 (TLB)
WORD flags;
uint8_t* ptr = GetPhysicalPtr(paddr, &flags);
bool bCartRom = flags & PJMEM_CARTROM;
if (ptr != NULL)
{
if (g_MMU == NULL)
if (!bCartRom)
{
return false;
*ptr = value;
}
return g_MMU->LW_VAddr(vaddr, value);
}
uint32_t paddr = vaddr & 0x1FFFFFFF;
return DebugLW_PAddr(paddr, value);
}
bool CDebugMMU::DebugLB_PAddr(uint32_t vaddr, uint8_t& value)
{
uint32_t word;
if (!DebugLW_PAddr(vaddr & ~3, word))
{
return false;
}
value = (word >> (24 - (vaddr & 3) * 8)) & 0xFF;
return true;
}
bool CDebugMMU::DebugLB_VAddr(uint32_t vaddr, uint8_t& value)
{
uint32_t word;
if (!DebugLW_VAddr(vaddr & ~3, word))
{
return false;
}
value = (word >> (24 - (vaddr & 3) * 8)) & 0xFF;
return true;
}
bool CDebugMMU::DebugSB_PAddr(uint32_t paddr, uint8_t value)
{
bool bWriteToRom = false;
if (paddr >= 0x10000000 && paddr <= 0x1FBFFFFF)
{
uint32_t romOffset = paddr - 0x10000000;
if (romOffset > g_Rom->GetRomSize())
else
{
return false;
ProtectMemory(g_Rom->GetRomAddress(), g_Rom->GetRomSize(), MEM_READWRITE);
*ptr = value;
ProtectMemory(g_Rom->GetRomAddress(), g_Rom->GetRomSize(), MEM_READONLY);
}
bWriteToRom = true;
return true;
}
int nbyte = 3 - (paddr & 3);
uint8_t* ptr = (uint8_t*)PAddrWordPtr(paddr & ~3);
int nByte = paddr & 3;
if (ptr == NULL)
if (paddr >= 0x08000000 && paddr <= 0x08FFFFFF) // Cartridge Domain 2 (Address 2)
{
return false;
}
uint32_t saveOffset = paddr & 0x000FFFFF;
if (bWriteToRom)
{
ProtectMemory(g_Rom->GetRomAddress(), g_Rom->GetRomSize(), MEM_READWRITE);
}
ptr[nbyte] = value;
if (bWriteToRom)
{
ProtectMemory(g_Rom->GetRomAddress(), g_Rom->GetRomSize(), MEM_READONLY);
}
return true;
}
bool CDebugMMU::DebugSB_VAddr(uint32_t vaddr, uint8_t value)
{
if (vaddr <= 0x7FFFFFFF || vaddr >= 0xC0000000) // KUSEG, KSEG2 (TLB)
{
if (g_MMU == NULL)
if (g_System->m_SaveUsing == SaveChip_Sram && saveOffset <= 0x7FFF)
{
return false;
}
uint32_t wordpaddr = paddr & ~3;
uint8_t data[4];
return g_MMU->SB_VAddr(vaddr, value);
CSram *sram = g_MMU->GetSram();
sram->DmaFromSram(data, wordpaddr - 0x08000000, sizeof(data));
data[nByte ^ 3] = value;
sram->DmaToSram(data, wordpaddr - 0x08000000, sizeof(data));
return true;
}
}
uint32_t paddr = vaddr & 0x1FFFFFFF;
return DebugSB_PAddr(paddr, value);
return false;
}
size_t CDebugMMU::ReadPhysical(uint32_t paddr, size_t length, uint8_t* buffer)
{
size_t nByte;
for (nByte = 0; nByte < length; nByte++)
{
if (!GetPhysicalByte(paddr + nByte, &buffer[nByte]))
{
return nByte;
}
}
return nByte;
}
size_t CDebugMMU::ReadVirtual(uint32_t vaddr, size_t length, uint8_t* buffer)
{
size_t nByte;
for (nByte = 0; nByte < length; nByte++)
{
uint32_t paddr;
if (!g_MMU || !g_MMU->TranslateVaddr(vaddr + nByte, paddr))
{
return nByte;
}
if (!GetPhysicalByte(paddr, &buffer[nByte]))
{
return nByte;
}
}
return nByte;
}
size_t CDebugMMU::WritePhysical(uint32_t paddr, size_t length, uint8_t* buffer)
{
size_t nByte;
for (nByte = 0; nByte < length; nByte++)
{
if (!SetPhysicalByte(paddr + nByte, buffer[nByte]))
{
return nByte;
}
}
return nByte;
}
size_t CDebugMMU::WriteVirtual(uint32_t vaddr, size_t length, uint8_t* buffer)
{
size_t nByte;
for (nByte = 0; nByte < length; nByte++)
{
uint32_t paddr;
if (!g_MMU || !g_MMU->TranslateVaddr(vaddr + nByte, paddr))
{
return nByte;
}
if (!SetPhysicalByte(paddr, buffer[nByte]))
{
return nByte;
}
}
return nByte;
}

View File

@ -1,15 +1,115 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once
#include <stdafx.h>
class CDebugMMU
{
private:
uint32_t* PAddrWordPtr(uint32_t paddr);
public:
bool DebugLW_PAddr(uint32_t paddr, uint32_t& value);
bool DebugLW_VAddr(uint32_t vaddr, uint32_t& value);
bool DebugLB_PAddr(uint32_t paddr, uint8_t& value);
bool DebugLB_VAddr(uint32_t vaddr, uint8_t& value);
bool DebugSB_PAddr(uint32_t paddr, uint8_t value);
bool DebugSB_VAddr(uint32_t vaddr, uint8_t value);
};
size_t ReadPhysical(uint32_t paddr, size_t length, uint8_t* buffer);
size_t ReadVirtual(uint32_t vaddr, size_t length, uint8_t* buffer);
size_t WritePhysical(uint32_t paddr, size_t length, uint8_t* buffer);
size_t WriteVirtual(uint32_t vaddr, size_t length, uint8_t* buffer);
template<typename T>
bool DebugLoad_PAddr(uint32_t paddr, T& value)
{
union {
T word;
uint8_t bytes[sizeof(T)];
} buffer;
if (ReadPhysical(paddr, sizeof(buffer), buffer.bytes) == sizeof(buffer))
{
value = ByteSwap<T>(buffer.word);
return true;
}
return false;
}
template<typename T>
bool DebugLoad_VAddr(uint32_t vaddr, T& value)
{
union {
T word;
uint8_t bytes[sizeof(T)];
} buffer;
if (ReadVirtual(vaddr, sizeof(buffer), buffer.bytes) == sizeof(buffer))
{
value = ByteSwap<T>(buffer.word);
return true;
}
return false;
}
template<typename T>
bool DebugStore_PAddr(uint32_t paddr, T value)
{
union {
T word;
uint8_t bytes[sizeof(T)];
} buffer = { ByteSwap<T>(value) };
return (WritePhysical(paddr, sizeof(buffer), buffer.bytes) == sizeof(buffer));
}
template<typename T>
bool DebugStore_VAddr(uint32_t vaddr, T value)
{
union {
T word;
uint8_t bytes[sizeof(T)];
} buffer = { ByteSwap<T>(value) };
return (WriteVirtual(vaddr, sizeof(buffer), buffer.bytes) == sizeof(buffer));
}
private:
uint8_t* GetPhysicalPtr(uint32_t paddr, WORD* flags = NULL);
bool GetPhysicalByte(uint32_t paddr, uint8_t* value);
bool SetPhysicalByte(uint32_t paddr, uint8_t value);
template<typename T>
T ByteSwap(T value)
{
union
{
T value;
uint16_t u16;
uint32_t u32;
uint64_t u64;
} bytes;
bytes.value = value;
switch (sizeof(T))
{
case sizeof(uint8_t) :
break;
case sizeof(uint16_t) :
bytes.u16 = _byteswap_ushort(bytes.u16);
break;
case sizeof(uint32_t) :
bytes.u32 = _byteswap_ulong(bytes.u32);
break;
case sizeof(uint64_t) :
bytes.u64 = _byteswap_uint64(bytes.u64);
break;
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
}
return bytes.value;
}
};

View File

@ -13,7 +13,7 @@
#include "DebuggerUI.h"
LRESULT CAddBreakpointDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
LRESULT CAddBreakpointDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
CenterWindow();
m_AddressEdit.Attach(GetDlgItem(IDC_ADDR_EDIT));

View File

@ -32,8 +32,8 @@ private:
CButton m_ExecuteCheck;
CEdit m_AddressEdit;
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
LRESULT OnDestroy(void)
{
return 0;

View File

@ -14,118 +14,116 @@
#include "DebuggerUI.h"
#include "Symbols.h"
LRESULT CAddSymbolDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
LRESULT CAddSymbolDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
CenterWindow();
CenterWindow();
m_AddressEdit.Attach(GetDlgItem(IDC_ADDR_EDIT));
m_AddressEdit.SetDisplayType(CEditNumber32::DisplayHex);
m_TypeComboBox.Attach(GetDlgItem(IDC_TYPE_COMBOBOX));
m_NameEdit.Attach(GetDlgItem(IDC_NAME_EDIT));
m_DescriptionEdit.Attach(GetDlgItem(IDC_DESC_EDIT));
m_AddressEdit.Attach(GetDlgItem(IDC_ADDR_EDIT));
m_AddressEdit.SetDisplayType(CEditNumber32::DisplayHex);
m_TypeComboBox.Attach(GetDlgItem(IDC_TYPE_COMBOBOX));
m_NameEdit.Attach(GetDlgItem(IDC_NAME_EDIT));
m_DescriptionEdit.Attach(GetDlgItem(IDC_DESC_EDIT));
for (int i = 0;; i++)
{
char* type = CSymbols::SymbolTypes[i];
if (type == NULL)
{
break;
}
m_TypeComboBox.AddString(type);
}
m_AddressEdit.SetWindowTextA("");
m_AddressEdit.SetFocus();
for (int i = 0;; i++)
{
const char* typeName = CSymbolTable::m_SymbolTypes[i].name;
if (typeName == NULL)
{
break;
}
m_TypeComboBox.AddString(typeName);
}
m_AddressEdit.SetWindowTextA("");
m_AddressEdit.SetFocus();
if (m_bHaveAddress)
{
m_AddressEdit.SetValue(m_InitAddress, false, true);
m_TypeComboBox.SetFocus();
}
if (m_bHaveAddress)
{
m_AddressEdit.SetValue(m_InitAddress, false, true);
m_TypeComboBox.SetFocus();
}
if(m_bHaveType)
{
m_TypeComboBox.SetCurSel(m_InitType);
m_NameEdit.SetFocus();
}
else
{
m_TypeComboBox.SetCurSel(CSymbols::TYPE_DATA);
}
return FALSE;
if(m_bHaveType)
{
m_TypeComboBox.SetCurSel(m_InitType);
m_NameEdit.SetFocus();
}
else
{
m_TypeComboBox.SetCurSel(SYM_DATA);
}
return FALSE;
}
LRESULT CAddSymbolDlg::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
switch (wID)
{
case IDCANCEL:
EndDialog(0);
break;
case IDOK:
int addrLen = m_AddressEdit.GetWindowTextLengthA();
switch (wID)
{
case IDCANCEL:
EndDialog(0);
break;
case IDOK:
int addrLen = m_AddressEdit.GetWindowTextLengthA();
if (!addrLen)
{
MessageBox("Address required", "Error", MB_OK);
return 0;
}
if (!addrLen)
{
MessageBox("Address required", "Error", MB_OK);
return 0;
}
uint32_t address = m_AddressEdit.GetValue();
int type = m_TypeComboBox.GetCurSel();
uint32_t address = m_AddressEdit.GetValue();
int type = m_TypeComboBox.GetCurSel();
int nameLen = m_NameEdit.GetWindowTextLengthA();
int descLen = m_DescriptionEdit.GetWindowTextLengthA();
if (!nameLen && !descLen)
{
MessageBox("Name and/or description required", "Error", MB_OK);
return 0;
}
int nameLen = m_NameEdit.GetWindowTextLengthA();
int descLen = m_DescriptionEdit.GetWindowTextLengthA();
if (!nameLen && !descLen)
{
MessageBox("Name and/or description required", "Error", MB_OK);
return 0;
}
char name[128];
char description[256];
char name[128];
char description[256];
m_NameEdit.GetWindowTextA(name, nameLen + 1);
m_DescriptionEdit.GetWindowTextA(description, descLen + 1);
CSymbols::EnterCriticalSection();
CSymbols::Add(type, address, name, description);
CSymbols::Save();
CSymbols::LeaveCriticalSection();
m_NameEdit.GetWindowTextA(name, nameLen + 1);
m_DescriptionEdit.GetWindowTextA(description, descLen + 1);
m_Debugger->SymbolTable()->AddSymbol(type, address, name, description);
m_Debugger->SymbolTable()->Save();
m_Debugger->Debug_RefreshSymbolsWindow();
m_Debugger->Debug_RefreshSymbolsWindow();
EndDialog(0);
break;
}
return 0;
EndDialog(0);
break;
}
return 0;
}
INT_PTR CAddSymbolDlg::DoModal(CDebuggerUI* debugger)
{
m_Debugger = debugger;
m_bHaveAddress = false;
m_bHaveType = false;
return CDialogImpl<CAddSymbolDlg>::DoModal();
m_Debugger = debugger;
m_bHaveAddress = false;
m_bHaveType = false;
return CDialogImpl<CAddSymbolDlg>::DoModal();
}
INT_PTR CAddSymbolDlg::DoModal(CDebuggerUI* debugger, uint32_t initAddress)
{
m_Debugger = debugger;
m_bHaveAddress = true;
m_bHaveType = false;
m_InitAddress = initAddress;
return CDialogImpl<CAddSymbolDlg>::DoModal();
m_Debugger = debugger;
m_bHaveAddress = true;
m_bHaveType = false;
m_InitAddress = initAddress;
return CDialogImpl<CAddSymbolDlg>::DoModal();
}
INT_PTR CAddSymbolDlg::DoModal(CDebuggerUI* debugger, uint32_t initAddress, int initType)
{
m_Debugger = debugger;
m_bHaveAddress = true;
m_bHaveType = true;
m_InitAddress = initAddress;
m_InitType = initType;
return CDialogImpl<CAddSymbolDlg>::DoModal();
m_Debugger = debugger;
m_bHaveAddress = true;
m_bHaveType = true;
m_InitAddress = initAddress;
m_InitType = initType;
return CDialogImpl<CAddSymbolDlg>::DoModal();
}

View File

@ -35,8 +35,8 @@ private:
CEdit m_NameEdit;
CEdit m_DescriptionEdit;
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnDestroy(void)
{
return 0;

View File

@ -1,3 +1,14 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include "stdafx.h"
#include "DebuggerUI.h"
#include "CPULog.h"
@ -75,6 +86,8 @@ LRESULT CDebugCPULogView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM
LRESULT CDebugCPULogView::OnDestroy(void)
{
UnhookWindowsHookEx(hWinMessageHook);
m_CPUListView.Detach();
m_StateInfoEdit.Detach();
m_EnabledChk.Detach();

View File

@ -1,3 +1,14 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once
#include <stdafx.h>

View File

@ -141,14 +141,14 @@ LRESULT CDebugCommandsView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARA
LoadWindowPos();
RedrawCommandsAndRegisters();
WindowCreated();
WindowCreated();
m_Attached = true;
return TRUE;
}
void CDebugCommandsView::OnExitSizeMove(void)
{
SaveWindowPos(true);
SaveWindowPos(true);
}
LRESULT CDebugCommandsView::OnDestroy(void)
@ -530,8 +530,6 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top, bool bUserInput
m_bvAnnotatedLines.clear();
CSymbols::EnterCriticalSection();
for (int i = 0; i < m_CommandListRows; i++)
{
uint32_t opAddr = m_StartAddress + i * 4;
@ -546,7 +544,7 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top, bool bUserInput
COpInfo OpInfo;
OPCODE& OpCode = OpInfo.m_OpCode;
if (!m_Debugger->DebugLW_VAddr(opAddr, OpCode.Hex))
if (!m_Debugger->DebugLoad_VAddr(opAddr, OpCode.Hex))
{
m_CommandList.AddItem(i, CCommandList::COL_COMMAND, "***");
m_bvAnnotatedLines.push_back(false);
@ -562,11 +560,10 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top, bool bUserInput
{
uint32_t targetAddr = (0x80000000 | (OpCode.target << 2));
// todo move symbols management to CDebuggerUI
const char* targetSymbolName = CSymbols::GetNameByAddress(targetAddr);
if (targetSymbolName != NULL)
CSymbol symbol;
if (m_Debugger->SymbolTable()->GetSymbolByAddress(targetAddr, &symbol))
{
cmdArgs = (char*)targetSymbolName;
cmdArgs = (char*)symbol.m_Name;
}
}
@ -580,7 +577,7 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top, bool bUserInput
{
OPCODE OpCodeTest;
if (!m_Debugger->DebugLW_VAddr(opAddr + offset, OpCodeTest.Hex))
if (!m_Debugger->DebugLoad_VAddr(opAddr + offset, OpCodeTest.Hex))
{
break;
}
@ -597,9 +594,12 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top, bool bUserInput
uint32_t memAddr = (OpCodeTest.immediate << 16) + (short)OpCode.offset;
annotation = CSymbols::GetNameByAddress(memAddr);
if (annotation == NULL)
CSymbol symbol;
if (m_Debugger->SymbolTable()->GetSymbolByAddress(memAddr, &symbol))
{
annotation = symbol.m_Name;
}
else
{
annotation = GetDataAddressNotes(memAddr);
}
@ -620,10 +620,10 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top, bool bUserInput
m_CommandList.AddItem(i, CCommandList::COL_PARAMETERS, cmdArgs);
// Show routine symbol name for this address
const char* routineSymbolName = CSymbols::GetNameByAddress(opAddr);
if (routineSymbolName != NULL)
CSymbol symbol;
if (m_Debugger->SymbolTable()->GetSymbolByAddress(opAddr, &symbol))
{
m_CommandList.AddItem(i, CCommandList::COL_SYMBOL, routineSymbolName);
m_CommandList.AddItem(i, CCommandList::COL_SYMBOL, symbol.m_Name);
m_bvAnnotatedLines.push_back(false);
}
else if (annotation != NULL)
@ -660,8 +660,6 @@ void CDebugCommandsView::ShowAddress(uint32_t address, bool top, bool bUserInput
}
}
CSymbols::LeaveCriticalSection();
if (!top) // update registers when called via breakpoint/stepping
{
m_RegisterTabs.RefreshEdits();
@ -697,7 +695,7 @@ LRESULT CDebugCommandsView::OnCustomDrawList(NMHDR* pNMHDR)
uint32_t pc = (g_Reg != NULL) ? g_Reg->m_PROGRAM_COUNTER : 0;
OPCODE pcOpcode;
if (!m_Debugger->DebugLW_VAddr(pc, pcOpcode.Hex))
if (!m_Debugger->DebugLoad_VAddr(pc, pcOpcode.Hex))
{
pcOpcode.Hex = 0;
}
@ -747,7 +745,7 @@ LRESULT CDebugCommandsView::OnCustomDrawList(NMHDR* pNMHDR)
// cmd & args
COpInfo OpInfo;
OPCODE& OpCode = OpInfo.m_OpCode;
bool bAddrOkay = m_Debugger->DebugLW_VAddr(address, OpCode.Hex);
bool bAddrOkay = m_Debugger->DebugLoad_VAddr(address, OpCode.Hex);
struct {
COLORREF bg;
@ -1068,7 +1066,7 @@ void CDebugCommandsView::CPUResume()
void CDebugCommandsView::CPUStepOver()
{
COpInfo opInfo;
if (!m_Debugger->DebugLW_VAddr(g_Reg->m_PROGRAM_COUNTER, opInfo.m_OpCode.Hex))
if (!m_Debugger->DebugLoad_VAddr(g_Reg->m_PROGRAM_COUNTER, opInfo.m_OpCode.Hex))
{
return;
}
@ -1220,7 +1218,7 @@ LRESULT CDebugCommandsView::OnPopupmenuRestoreAll(WORD /*wNotifyCode*/, WORD /*w
LRESULT CDebugCommandsView::OnPopupmenuAddSymbol(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hwnd*/, BOOL& /*bHandled*/)
{
m_AddSymbolDlg.DoModal(m_Debugger, m_SelectedAddress, CSymbols::TYPE_CODE);
m_AddSymbolDlg.DoModal(m_Debugger, m_SelectedAddress, SYM_CODE);
return FALSE;
}
@ -1255,7 +1253,7 @@ LRESULT CDebugCommandsView::OnPopupmenuClearBP(WORD /*wNotifyCode*/, WORD /*wID*
void CDebugCommandsView::BeginOpEdit(uint32_t address)
{
uint32_t opcode;
if (!m_Debugger->DebugLW_VAddr(address, opcode))
if (!m_Debugger->DebugLoad_VAddr(address, opcode))
{
return;
}
@ -1368,7 +1366,7 @@ LRESULT CDebugCommandsView::OnCommandListRightClicked(NMHDR* pNMHDR)
uint32_t address = m_StartAddress + nItem * 4;
m_SelectedAddress = address;
if (!m_Debugger->DebugLW_VAddr(m_SelectedAddress, m_SelectedOpCode.Hex))
if (!m_Debugger->DebugLoad_VAddr(m_SelectedAddress, m_SelectedOpCode.Hex))
{
return 0;
}
@ -1578,7 +1576,7 @@ BOOL CDebugCommandsView::IsOpEdited(uint32_t address)
void CDebugCommandsView::EditOp(uint32_t address, uint32_t op)
{
uint32_t currentOp;
if (!m_Debugger->DebugLW_VAddr(address, currentOp))
if (!m_Debugger->DebugLoad_VAddr(address, currentOp))
{
return;
}
@ -1588,7 +1586,7 @@ void CDebugCommandsView::EditOp(uint32_t address, uint32_t op)
return;
}
g_MMU->SW_VAddr(address, op);
m_Debugger->DebugStore_VAddr(address, op);
if (!IsOpEdited(address))
{
@ -1604,7 +1602,7 @@ void CDebugCommandsView::RestoreOp(uint32_t address)
{
if (m_EditedOps[i].address == address)
{
g_MMU->SW_VAddr(m_EditedOps[i].address, m_EditedOps[i].originalOp);
m_Debugger->DebugStore_VAddr(m_EditedOps[i].address, m_EditedOps[i].originalOp);
m_EditedOps.erase(m_EditedOps.begin() + i);
break;
}
@ -1616,7 +1614,7 @@ void CDebugCommandsView::RestoreAllOps()
int lastIndex = m_EditedOps.size() - 1;
for (int i = lastIndex; i >= 0; i--)
{
g_MMU->SW_VAddr(m_EditedOps[i].address, m_EditedOps[i].originalOp);
m_Debugger->DebugStore_VAddr(m_EditedOps[i].address, m_EditedOps[i].originalOp);
m_EditedOps.erase(m_EditedOps.begin() + i);
}
}

View File

@ -168,7 +168,7 @@ private:
static void StaticWaitingForStepChanged(CDebugCommandsView * __this) { __this->WaitingForStepChanged(); }
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnSizing(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnScroll(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnMeasureItem(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
@ -199,11 +199,11 @@ private:
LRESULT OnPopupmenuClearBP(WORD wNotifyCode, WORD wID, HWND hwnd, BOOL& bHandled);
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
LRESULT OnOpKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnOpKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnCommandListClicked(NMHDR* pNMHDR);
LRESULT OnCommandListDblClicked(NMHDR* pNMHDR);
LRESULT OnCommandListRightClicked(NMHDR* pNMHDR);
LRESULT OnCommandListClicked(NMHDR* pNMHDR);
LRESULT OnCommandListDblClicked(NMHDR* pNMHDR);
LRESULT OnCommandListRightClicked(NMHDR* pNMHDR);
LRESULT OnRegisterTabChange(NMHDR* pNMHDR);
LRESULT OnCustomDrawList(NMHDR* pNMHDR);
LRESULT OnDestroy(void);

View File

@ -16,10 +16,10 @@
CDebugDMALogView::CDebugDMALogView(CDebuggerUI* debugger) :
CDebugDialog<CDebugDMALogView>(debugger)
{
m_DMALog = debugger->DMALog();
m_bFilterChanged = false;
m_bUniqueRomAddresses = true;
m_bCustomDrawClrNext = false;
m_DMALog = debugger->DMALog();
m_bFilterChanged = false;
m_bUniqueRomAddresses = true;
m_bCustomDrawClrNext = false;
}
CDebugDMALogView::~CDebugDMALogView()
@ -29,152 +29,152 @@ CDebugDMALogView::~CDebugDMALogView()
/*
bool CDebugDMALogView::FilterEntry(int dmaLogIndex)
{
DMALogEntry entry = m_Debugger->DMALog()->at(dmaLogIndex);
DMALogEntry entry = m_Debugger->DMALog()->at(dmaLogIndex);
for (int i = 0; i < dmaLogIndex; i++)
{
DMALogEntry testEntry = m_Debugger->DMALog()->at(i);
for (int i = 0; i < dmaLogIndex; i++)
{
DMALogEntry testEntry = m_Debugger->DMALog()->at(i);
// Don't show if another entry has the same ROM address
if (entry.romAddr == testEntry.romAddr)
{
return false;
}
}
// Don't show if another entry has the same ROM address
if (entry.romAddr == testEntry.romAddr)
{
return false;
}
}
return true;
return true;
}
*/
void CDebugDMALogView::RefreshList()
{
if (g_Rom == NULL)
{
return;
}
uint8_t* rom = g_Rom->GetRomAddress();
// Get scrollbar state
SCROLLINFO scroll;
scroll.cbSize = sizeof(SCROLLINFO);
scroll.fMask = SIF_ALL;
m_DMAList.GetScrollInfo(SB_VERT, &scroll);
if (g_Rom == NULL)
{
return;
}
uint8_t* rom = g_Rom->GetRomAddress();
// Get scrollbar state
SCROLLINFO scroll;
scroll.cbSize = sizeof(SCROLLINFO);
scroll.fMask = SIF_ALL;
m_DMAList.GetScrollInfo(SB_VERT, &scroll);
bool bScrolledDown = false;
bool bScrolledDown = false;
if ((scroll.nPage + scroll.nPos) - 1 == (uint32_t)scroll.nMax)
{
bScrolledDown = true;
}
if ((scroll.nPage + scroll.nPos) - 1 == (uint32_t)scroll.nMax)
{
bScrolledDown = true;
}
int startIndex;
int dmaLogSize = m_Debugger->DMALog()->GetNumEntries();
if (dmaLogSize == 0)
{
// Reset
m_DMAList.DeleteAllItems();
startIndex = 0;
m_bFilterChanged = false;
}
else
{
// Continue from last index
startIndex = m_nLastStartIndex;
}
m_DMAList.SetRedraw(FALSE);
int startIndex;
int dmaLogSize = m_Debugger->DMALog()->GetNumEntries();
if (dmaLogSize == 0)
{
// Reset
m_DMAList.DeleteAllItems();
startIndex = 0;
m_bFilterChanged = false;
}
else
{
// Continue from last index
startIndex = m_nLastStartIndex;
}
m_DMAList.SetRedraw(FALSE);
int itemIndex = m_DMAList.GetItemCount();
for (int i = startIndex; i < dmaLogSize; i++)
{
DMALOGENTRY* lpEntry = m_DMALog->GetEntryByIndex(i);
int itemIndex = m_DMAList.GetItemCount();
for (int i = startIndex; i < dmaLogSize; i++)
{
DMALOGENTRY* lpEntry = m_DMALog->GetEntryByIndex(i);
//if (!FilterEntry(i))
//{
// continue;
//}
m_DMAList.AddItem(itemIndex, 0, stdstr_f("%08X", lpEntry->romAddr).c_str());
m_DMAList.AddItem(itemIndex, 1, stdstr_f("%08X", lpEntry->ramAddr).c_str());
m_DMAList.AddItem(itemIndex, 2, stdstr_f("%08X (%d)", lpEntry->length, lpEntry->length).c_str());
char sigc[5];
memset(sigc, 0, sizeof(sigc));
//if (!FilterEntry(i))
//{
// continue;
//}
m_DMAList.AddItem(itemIndex, 0, stdstr_f("%08X", lpEntry->romAddr).c_str());
m_DMAList.AddItem(itemIndex, 1, stdstr_f("%08X", lpEntry->ramAddr).c_str());
m_DMAList.AddItem(itemIndex, 2, stdstr_f("%08X (%d)", lpEntry->length, lpEntry->length).c_str());
union
{
uint32_t u32;
uint8_t sz[5];
} sig = { 0 };
if (lpEntry->romAddr < g_Rom->GetRomSize())
{
uint32_t sig = *(uint32_t*)&rom[lpEntry->romAddr];
sig = _byteswap_ulong(sig);
memcpy(sigc, &sig, 4);
sigc[4] = '\0';
sig.u32 = *(uint32_t*)&rom[lpEntry->romAddr];
}
// Todo checkbox to display all in hex
if (isalnum(sigc[0]) && isalnum(sigc[1]) && isalnum(sigc[2]) && isalnum(sigc[3]))
{
m_DMAList.AddItem(itemIndex, 4, sigc);
}
// Todo checkbox to display all in hex
if (isalnum(sig.sz[0]) && isalnum(sig.sz[1]) && isalnum(sig.sz[2]) && isalnum(sig.sz[3]))
{
m_DMAList.AddItem(itemIndex, 4, (char*)sig.sz);
}
itemIndex++;
}
if (bScrolledDown)
{
m_DMAList.EnsureVisible(m_DMAList.GetItemCount() - 1, FALSE);
}
itemIndex++;
}
if (bScrolledDown)
{
m_DMAList.EnsureVisible(m_DMAList.GetItemCount() - 1, FALSE);
}
m_DMAList.SetRedraw(TRUE);
m_nLastStartIndex = dmaLogSize;
m_DMAList.SetRedraw(TRUE);
m_nLastStartIndex = dmaLogSize;
}
LRESULT CDebugDMALogView::OnActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
//RefreshList();
return FALSE;
//RefreshList();
return FALSE;
}
LRESULT CDebugDMALogView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
DlgResize_Init(false, true);
DlgResize_Init(false, true);
DlgSavePos_Init(DebuggerUI_DMALogPos);
m_bConvertingAddress = false;
m_nLastStartIndex = 0;
m_bConvertingAddress = false;
m_nLastStartIndex = 0;
m_DMAList.Attach(GetDlgItem(IDC_DMA_LIST));
m_DMAList.Attach(GetDlgItem(IDC_DMA_LIST));
m_DMARamEdit.Attach(GetDlgItem(IDC_DMA_RAM_EDIT));
m_DMARomEdit.Attach(GetDlgItem(IDC_DMA_ROM_EDIT));
m_BlockInfo.Attach(GetDlgItem(IDC_BLOCK_INFO));
m_DMAList.ModifyStyle(LVS_OWNERDRAWFIXED, 0, 0);
m_DMAList.ModifyStyle(LVS_OWNERDRAWFIXED, 0, 0);
m_DMAList.AddColumn("ROM", 0);
m_DMAList.AddColumn("RAM", 1);
m_DMAList.AddColumn("Length", 2);
m_DMAList.AddColumn("Symbol (RAM)", 3);
m_DMAList.AddColumn("Signature", 4);
m_DMAList.AddColumn("ROM", 0);
m_DMAList.AddColumn("RAM", 1);
m_DMAList.AddColumn("Length", 2);
m_DMAList.AddColumn("Symbol (RAM)", 3);
m_DMAList.AddColumn("Signature", 4);
m_DMAList.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);
m_DMAList.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);
m_DMAList.SetColumnWidth(0, 65);
m_DMAList.SetColumnWidth(1, 65);
m_DMAList.SetColumnWidth(2, 120);
//m_DMAList.SetColumnWidth(3, 50);
//m_DMAList.SetColumnWidth(4, 50);
//m_DMAList.SetColumnWidth(5, 50);
m_DMARamEdit.SetLimitText(8);
m_DMARomEdit.SetLimitText(8);
m_DMAList.SetColumnWidth(0, 65);
m_DMAList.SetColumnWidth(1, 65);
m_DMAList.SetColumnWidth(2, 120);
//m_DMAList.SetColumnWidth(3, 50);
//m_DMAList.SetColumnWidth(4, 50);
//m_DMAList.SetColumnWidth(5, 50);
m_DMARamEdit.SetLimitText(8);
m_DMARomEdit.SetLimitText(8);
RefreshList();
RefreshList();
LoadWindowPos();
WindowCreated();
LoadWindowPos();
WindowCreated();
return TRUE;
return TRUE;
}
void CDebugDMALogView::RefreshDMALogWindow(bool bReset)
@ -216,147 +216,147 @@ LRESULT CDebugDMALogView::OnDestroy(void)
m_DMARomEdit.Detach();
m_BlockInfo.Detach();
return 0;
return 0;
}
LRESULT CDebugDMALogView::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND, BOOL& /*bHandled*/)
{
switch (wID)
{
case IDOK:
EndDialog(0);
break;
case IDCANCEL:
EndDialog(0);
break;
case IDC_CLEAR_BTN:
m_DMALog->ClearEntries();
RefreshList();
break;
}
return FALSE;
switch (wID)
{
case IDOK:
EndDialog(0);
break;
case IDCANCEL:
EndDialog(0);
break;
case IDC_CLEAR_BTN:
m_DMALog->ClearEntries();
RefreshList();
break;
}
return FALSE;
}
LRESULT CDebugDMALogView::OnRamAddrChanged(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
if (m_bConvertingAddress)
{
return FALSE;
}
if (m_bConvertingAddress)
{
return FALSE;
}
char szRamAddr[9];
char szRomAddr[9];
char szRamAddr[9];
char szRomAddr[9];
m_DMARamEdit.GetWindowTextA(szRamAddr, 9);
uint32_t ramAddr = strtoul(szRamAddr, NULL, 16);
uint32_t romAddr, offset;
m_DMARamEdit.GetWindowTextA(szRamAddr, 9);
uint32_t ramAddr = strtoul(szRamAddr, NULL, 16);
uint32_t romAddr, offset;
DMALOGENTRY* lpEntry = m_DMALog->GetEntryByRamAddress(ramAddr, &romAddr, &offset);
DMALOGENTRY* lpEntry = m_DMALog->GetEntryByRamAddress(ramAddr, &romAddr, &offset);
if (lpEntry != NULL)
{
sprintf(szRomAddr, "%08X", romAddr);
stdstr blockInfo = stdstr_f("Block: %08X -> %08X [%X] +%X", romAddr, ramAddr, lpEntry->length, offset);
m_BlockInfo.SetWindowTextA(blockInfo.c_str());
}
else
{
sprintf(szRomAddr, "????????");
m_BlockInfo.SetWindowTextA("Block: ?");
}
m_bConvertingAddress = true;
m_DMARomEdit.SetWindowTextA(szRomAddr);
m_bConvertingAddress = false;
return FALSE;
if (lpEntry != NULL)
{
sprintf(szRomAddr, "%08X", romAddr);
stdstr blockInfo = stdstr_f("Block: %08X -> %08X [%X] +%X", romAddr, ramAddr, lpEntry->length, offset);
m_BlockInfo.SetWindowTextA(blockInfo.c_str());
}
else
{
sprintf(szRomAddr, "????????");
m_BlockInfo.SetWindowTextA("Block: ?");
}
m_bConvertingAddress = true;
m_DMARomEdit.SetWindowTextA(szRomAddr);
m_bConvertingAddress = false;
return FALSE;
}
LRESULT CDebugDMALogView::OnRomAddrChanged(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
if (m_bConvertingAddress)
{
return FALSE;
}
if (m_bConvertingAddress)
{
return FALSE;
}
char szRamAddr[9];
char szRomAddr[9];
char szRamAddr[9];
char szRomAddr[9];
m_DMARomEdit.GetWindowTextA(szRomAddr, 9);
uint32_t romAddr = strtoul(szRomAddr, NULL, 16);
uint32_t ramAddr, offset;
m_DMARomEdit.GetWindowTextA(szRomAddr, 9);
uint32_t romAddr = strtoul(szRomAddr, NULL, 16);
uint32_t ramAddr, offset;
DMALOGENTRY* lpEntry = m_DMALog->GetEntryByRomAddress(romAddr, &ramAddr, &offset);
DMALOGENTRY* lpEntry = m_DMALog->GetEntryByRomAddress(romAddr, &ramAddr, &offset);
if (lpEntry != NULL)
{
sprintf(szRamAddr, "%08X", ramAddr);
stdstr blockInfo = stdstr_f("Block: %08X -> %08X [%X] +%X", romAddr, ramAddr, lpEntry->length, offset);
m_BlockInfo.SetWindowTextA(blockInfo.c_str());
}
else
{
sprintf(szRamAddr, "????????");
m_BlockInfo.SetWindowTextA("Block: ?");
}
if (lpEntry != NULL)
{
sprintf(szRamAddr, "%08X", ramAddr);
stdstr blockInfo = stdstr_f("Block: %08X -> %08X [%X] +%X", romAddr, ramAddr, lpEntry->length, offset);
m_BlockInfo.SetWindowTextA(blockInfo.c_str());
}
else
{
sprintf(szRamAddr, "????????");
m_BlockInfo.SetWindowTextA("Block: ?");
}
m_bConvertingAddress = true;
m_DMARamEdit.SetWindowTextA(szRamAddr);
m_bConvertingAddress = false;
return FALSE;
m_bConvertingAddress = true;
m_DMARamEdit.SetWindowTextA(szRamAddr);
m_bConvertingAddress = false;
return FALSE;
}
LRESULT CDebugDMALogView::OnCustomDrawList(NMHDR* pNMHDR)
{
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
DWORD drawStage = pLVCD->nmcd.dwDrawStage;
NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);
DWORD drawStage = pLVCD->nmcd.dwDrawStage;
switch (drawStage)
{
case CDDS_PREPAINT: return CDRF_NOTIFYITEMDRAW;
case CDDS_ITEMPREPAINT: return CDRF_NOTIFYSUBITEMDRAW;
case (CDDS_ITEMPREPAINT | CDDS_SUBITEM): break;
default: return CDRF_DODEFAULT;
}
DWORD nItem = pLVCD->nmcd.dwItemSpec;
DWORD nSubItem = pLVCD->iSubItem;
switch (drawStage)
{
case CDDS_PREPAINT: return CDRF_NOTIFYITEMDRAW;
case CDDS_ITEMPREPAINT: return CDRF_NOTIFYSUBITEMDRAW;
case (CDDS_ITEMPREPAINT | CDDS_SUBITEM): break;
default: return CDRF_DODEFAULT;
}
DWORD nItem = pLVCD->nmcd.dwItemSpec;
DWORD nSubItem = pLVCD->iSubItem;
if (nSubItem != 0)
{
return CDRF_DODEFAULT;
}
size_t nEntries = m_DMALog->GetNumEntries();
if (nSubItem != 0)
{
return CDRF_DODEFAULT;
}
size_t nEntries = m_DMALog->GetNumEntries();
if (nEntries == 0)
{
return CDRF_DODEFAULT;
}
DMALOGENTRY* lpEntry = m_DMALog->GetEntryByIndex(nItem);
if (nItem >= 1) // continuation
{
DMALOGENTRY* lpPrevEntry = m_DMALog->GetEntryByIndex(nItem - 1);
if (nEntries == 0)
{
return CDRF_DODEFAULT;
}
DMALOGENTRY* lpEntry = m_DMALog->GetEntryByIndex(nItem);
if (nItem >= 1) // continuation
{
DMALOGENTRY* lpPrevEntry = m_DMALog->GetEntryByIndex(nItem - 1);
if (lpEntry->romAddr == lpPrevEntry->romAddr + lpPrevEntry->length)
{
pLVCD->clrTextBk = RGB(0xFF, 0xFF, 0xCC);
return CDRF_DODEFAULT;
}
}
if (lpEntry->romAddr == lpPrevEntry->romAddr + lpPrevEntry->length)
{
pLVCD->clrTextBk = RGB(0xFF, 0xFF, 0xCC);
return CDRF_DODEFAULT;
}
}
if (nEntries >= 2 && nItem <= nEntries - 2) // head
{
DMALOGENTRY* lpNextEntry = m_DMALog->GetEntryByIndex(nItem + 1);
if (nEntries >= 2 && nItem <= nEntries - 2) // head
{
DMALOGENTRY* lpNextEntry = m_DMALog->GetEntryByIndex(nItem + 1);
if (lpNextEntry->romAddr == lpEntry->romAddr + lpEntry->length)
{
pLVCD->clrTextBk = RGB(0xFF, 0xFF, 0x88);
return CDRF_DODEFAULT;
}
}
return CDRF_DODEFAULT;
if (lpNextEntry->romAddr == lpEntry->romAddr + lpEntry->length)
{
pLVCD->clrTextBk = RGB(0xFF, 0xFF, 0x88);
return CDRF_DODEFAULT;
}
}
return CDRF_DODEFAULT;
}

View File

@ -1,3 +1,14 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include "stdafx.h"
#include "DebuggerUI.h"

View File

@ -1,3 +1,14 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once
#include <stdafx.h>

View File

@ -23,34 +23,34 @@ CDumpMemory::~CDumpMemory()
{
}
LRESULT CDumpMemory::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
LRESULT CDumpMemory::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
DlgSavePos_Init(DebuggerUI_MemoryDumpPos);
m_StartAddress.Attach(GetDlgItem(IDC_E_START_ADDR));
m_EndAddress.Attach(GetDlgItem(IDC_E_END_ADDR));
m_PC.Attach(GetDlgItem(IDC_E_ALT_PC));
m_FormatList.Attach(GetDlgItem(IDC_FORMAT));
m_FileName.Attach(GetDlgItem(IDC_FILENAME));
m_FormatList.Attach(GetDlgItem(IDC_FORMAT));
m_FileName.Attach(GetDlgItem(IDC_FILENAME));
m_StartAddress.SetDisplayType(CEditNumber32::DisplayHex);
m_EndAddress.SetDisplayType(CEditNumber32::DisplayHex);
m_PC.SetDisplayType(CEditNumber32::DisplayHex);
uint32_t startAddress = 0x80000000;
uint32_t endAddress = startAddress + (g_MMU ? g_MMU->RdramSize() : 0x400000);
uint32_t startAddress = 0x80000000;
uint32_t endAddress = startAddress + (g_MMU ? g_MMU->RdramSize() : 0x400000);
m_StartAddress.SetValue(startAddress, true, true);
m_EndAddress.SetValue(endAddress, true, true);
m_PC.SetValue(startAddress);
int nIndex = m_FormatList.AddString("TEXT - Disassembly + PC");
m_FormatList.SetItemData(nIndex, (DWORD_PTR)DisassemblyWithPC);
int nIndex = m_FormatList.AddString("TEXT - Disassembly + PC");
m_FormatList.SetItemData(nIndex, (DWORD_PTR)DisassemblyWithPC);
nIndex = m_FormatList.AddString("RAW - Big Endian (N64)");
m_FormatList.SetItemData(nIndex, (LPARAM)RawBigEndian);
nIndex = m_FormatList.AddString("RAW - Big Endian (N64)");
m_FormatList.SetItemData(nIndex, (LPARAM)RawBigEndian);
m_FormatList.SetCurSel(0);
m_FormatList.SetCurSel(0);
LoadWindowPos();
WindowCreated();
@ -62,7 +62,7 @@ void CDumpMemory::OnExitSizeMove(void)
SaveWindowPos(0);
}
LRESULT CDumpMemory::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
LRESULT CDumpMemory::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
switch (wID)
{
@ -73,28 +73,28 @@ LRESULT CDumpMemory::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/,
{
g_BaseSystem->ExternalEvent(SysEvent_PauseCPU_DumpMemory);
int CurrentFormatSel = m_FormatList.GetCurSel();
DumpFormat Format = (DumpFormat)m_FormatList.GetItemData(CurrentFormatSel);
int CurrentFormatSel = m_FormatList.GetCurSel();
DumpFormat Format = (DumpFormat)m_FormatList.GetItemData(CurrentFormatSel);
const char* FileFilter = "All files (*.*)\0*.*\0";
const char* FileFilter = "All files (*.*)\0*.*\0";
if (Format == RawBigEndian)
{
FileFilter = "Binary file (*.bin)\0*.bin;\0All files (*.*)\0*.*\0";
}
else if (Format == DisassemblyWithPC)
{
FileFilter = "Text file (*.txt)\0*.txt;\0All files (*.*)\0*.*\0";
}
if (Format == RawBigEndian)
{
FileFilter = "Binary file (*.bin)\0*.bin;\0All files (*.*)\0*.*\0";
}
else if (Format == DisassemblyWithPC)
{
FileFilter = "Text file (*.txt)\0*.txt;\0All files (*.*)\0*.*\0";
}
CPath FileName;
if (FileName.SelectFile(m_hWnd, CPath(CPath::MODULE_DIRECTORY), FileFilter, false))
{
if (FileName.GetExtension().length() == 0)
{
FileName.SetExtension(Format == RawBigEndian ? "bin" : "txt");
m_FileName.SetWindowTextA(FileName);
m_FileName.SetWindowTextA(FileName);
}
}
g_BaseSystem->ExternalEvent(SysEvent_ResumeCPU_DumpMemory);
@ -105,7 +105,7 @@ LRESULT CDumpMemory::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/,
TCHAR FileName[MAX_PATH];
int CurrentFormatSel = m_FormatList.GetCurSel();
DumpFormat Format = (DumpFormat) m_FormatList.GetItemData(CurrentFormatSel);
DWORD StartPC = m_StartAddress.GetValue();
DWORD EndPC = m_EndAddress.GetValue();
DWORD DumpPC = m_PC.GetValue();
@ -147,69 +147,69 @@ LRESULT CDumpMemory::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/,
bool CDumpMemory::DumpMemory(LPCSTR FileName, DumpFormat Format, DWORD StartPC, DWORD EndPC, DWORD DumpPC)
{
if (Format == DisassemblyWithPC)
{
CLog LogFile;
if (!LogFile.Open(FileName))
{
g_Notify->DisplayError(stdstr_f("Failed to open\n%s", FileName).c_str());
return false;
}
LogFile.SetFlush(false);
LogFile.SetTruncateFile(false);
if (Format == DisassemblyWithPC)
{
CLog LogFile;
if (!LogFile.Open(FileName))
{
g_Notify->DisplayError(stdstr_f("Failed to open\n%s", FileName).c_str());
return false;
}
LogFile.SetFlush(false);
LogFile.SetTruncateFile(false);
for (uint32_t pc = StartPC; pc < EndPC; pc += 4, DumpPC += 4)
{
OPCODE opcode;
g_MMU->LW_VAddr(pc, opcode.Hex);
for (uint32_t pc = StartPC; pc < EndPC; pc += 4, DumpPC += 4)
{
OPCODE opcode;
m_Debugger->DebugLoad_VAddr(pc, opcode.Hex);
const char* command = R4300iOpcodeName(opcode.Hex, DumpPC);
const char* command = R4300iOpcodeName(opcode.Hex, DumpPC);
char* cmdName = strtok((char*)command, "\t");
char* cmdArgs = strtok(NULL, "\t");
cmdArgs = cmdArgs ? cmdArgs : "";
char* cmdName = strtok((char*)command, "\t");
char* cmdArgs = strtok(NULL, "\t");
cmdArgs = cmdArgs ? cmdArgs : "";
LogFile.LogF("%X: %-15s%s\r\n", DumpPC, cmdName, cmdArgs);
}
LogFile.LogF("%X: %-15s%s\r\n", DumpPC, cmdName, cmdArgs);
}
m_StartAddress.SetValue(StartPC, true, true);
m_EndAddress.SetValue(EndPC, true, true);
return true;
}
m_StartAddress.SetValue(StartPC, true, true);
m_EndAddress.SetValue(EndPC, true, true);
return true;
}
if (Format == RawBigEndian)
{
CFile dumpFile;
if (Format == RawBigEndian)
{
CFile dumpFile;
if (!dumpFile.Open(FileName, CFile::modeCreate | CFile::modeWrite))
{
g_Notify->DisplayError(stdstr_f("Failed to open\n%s", FileName).c_str());
return false;
}
if (!dumpFile.Open(FileName, CFile::modeCreate | CFile::modeWrite))
{
g_Notify->DisplayError(stdstr_f("Failed to open\n%s", FileName).c_str());
return false;
}
uint32_t dumpLen = EndPC - StartPC;
uint8_t* dumpBuf = (uint8_t*)malloc(dumpLen);
uint32_t dumpIdx = 0;
uint32_t dumpLen = EndPC - StartPC;
uint8_t* dumpBuf = (uint8_t*)malloc(dumpLen);
uint32_t dumpIdx = 0;
for (uint32_t pc = StartPC; pc < EndPC; pc++, dumpIdx++)
{
bool bReadable = g_MMU->LB_VAddr(pc, dumpBuf[dumpIdx]);
for (uint32_t pc = StartPC; pc < EndPC; pc++, dumpIdx++)
{
bool bReadable = m_Debugger->DebugLoad_VAddr(pc, dumpBuf[dumpIdx]);
if (!bReadable)
{
g_Notify->DisplayError(stdstr_f("Address error\n%s", FileName).c_str());
dumpFile.Close();
free(dumpBuf);
return false;
}
}
if (!bReadable)
{
g_Notify->DisplayError(stdstr_f("Address error\n%s", FileName).c_str());
dumpFile.Close();
free(dumpBuf);
return false;
}
}
dumpFile.SeekToBegin();
dumpFile.Write(dumpBuf, dumpLen);
dumpFile.Close();
free(dumpBuf);
return true;
}
dumpFile.SeekToBegin();
dumpFile.Write(dumpBuf, dumpLen);
dumpFile.Close();
free(dumpBuf);
return true;
}
return false;
}

View File

@ -20,9 +20,9 @@ public:
virtual ~CDumpMemory(void);
private:
CDumpMemory(void); // Disable default constructor
CDumpMemory(const CDumpMemory&); // Disable copy constructor
CDumpMemory& operator=(const CDumpMemory&); // Disable assignment
CDumpMemory(void); // Disable default constructor
CDumpMemory(const CDumpMemory&); // Disable copy constructor
CDumpMemory& operator=(const CDumpMemory&); // Disable assignment
enum DumpFormat
{
@ -36,8 +36,8 @@ private:
MSG_WM_EXITSIZEMOVE(OnExitSizeMove);
END_MSG_MAP()
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled);
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled);
void OnExitSizeMove(void);
bool DumpMemory(LPCSTR FileName, DumpFormat Format, DWORD StartPC, DWORD EndPC, DWORD DumpPC);

View File

@ -107,8 +107,10 @@ LRESULT CDebugMemorySearch::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARA
::GetWindowRect(GetDlgItem(IDC_SEPARATOR), &m_InitialSeparatorRect);
ScreenToClient(&m_InitialSeparatorRect);
uint32_t ramSize = (g_MMU != NULL) ? g_MMU->RdramSize() : 0x00400000;
m_AddrStart.SetValue(0x80000000, true, true);
m_AddrEnd.SetValue(0x80000000 + g_MMU->RdramSize() - 1, true, true);
m_AddrEnd.SetValue(0x80000000 + ramSize - 1, true, true);
FixListHeader(m_WatchListCtrl);
FixListHeader(m_ResultsListCtrl);
@ -134,6 +136,7 @@ LRESULT CDebugMemorySearch::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARA
LRESULT CDebugMemorySearch::OnDestroy(void)
{
UnhookWindowsHookEx(hWinMessageHook);
KillTimer(TIMER_ID_AUTO_REFRESH);
m_UnsignedCheckbox.Detach();
@ -343,8 +346,9 @@ LRESULT CDebugMemorySearch::OnRdramButton(WORD /*wNotifyCode*/, WORD /*wID*/, HW
{
bool bPhysicalChecked = (m_PhysicalCheckbox.GetCheck() == BST_CHECKED);
uint32_t addrStart = bPhysicalChecked ? 0 : 0x80000000;
uint32_t ramSize = (g_MMU != NULL) ? g_MMU->RdramSize() : 0x00400000;
m_AddrStart.SetValue(addrStart, true, true);
m_AddrEnd.SetValue(addrStart + g_MMU->RdramSize() - 1, true, true);
m_AddrEnd.SetValue(addrStart + ramSize - 1, true, true);
return FALSE;
}

View File

@ -97,7 +97,7 @@ private:
CEdit m_Value;
CComboBox m_CmbValue;
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnDestroy(void);
LRESULT OnOK(WORD wNotifyCode, WORD wID, HWND hwnd, BOOL& bHandled);
LRESULT OnCancel(WORD wNotifyCode, WORD wID, HWND hwnd, BOOL& bHandled);

View File

@ -498,7 +498,7 @@ INT_PTR CALLBACK CRegisterTabs::TabProcGPR(HWND hDlg, UINT msg, WPARAM wParam, L
WORD ctrlId = (WORD) ::GetWindowLong(hWnd, GWL_ID);
COpInfo opInfo;
g_MMU->LW_VAddr(g_Reg->m_PROGRAM_COUNTER, opInfo.m_OpCode.Hex);
m_Debugger->DebugLoad_VAddr(g_Reg->m_PROGRAM_COUNTER, opInfo.m_OpCode.Hex);
bool bOpReads = false;
bool bOpWrites = false;

View File

@ -19,14 +19,12 @@ CDebugScripts::CDebugScripts(CDebuggerUI* debugger) :
CDebugDialog<CDebugScripts>(debugger)
{
m_SelectedScriptName = (char*)malloc(MAX_PATH);
InitializeCriticalSection(&m_CriticalSection);
//CScriptSystem::SetScriptsWindow(this);
//CScriptSystem::SetScriptsWindow(this);
}
CDebugScripts::~CDebugScripts(void)
{
DeleteCriticalSection(&m_CriticalSection);
free(m_SelectedScriptName);
free(m_SelectedScriptName);
}
LRESULT CDebugScripts::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
@ -59,8 +57,8 @@ LRESULT CDebugScripts::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*l
RefreshList();
LoadWindowPos();
WindowCreated();
LoadWindowPos();
WindowCreated();
return 0;
}
@ -93,7 +91,7 @@ void CDebugScripts::ConsolePrint(const char* text)
void CDebugScripts::RefreshConsole()
{
EnterCriticalSection(&m_CriticalSection);
CGuard guard(m_CS);
m_Debugger->OpenScriptsWindow();
CScriptSystem* scriptSystem = m_Debugger->ScriptSystem();
@ -105,8 +103,6 @@ void CDebugScripts::RefreshConsole()
free((*logData)[0]);
logData->erase(logData->begin() + 0);
}
LeaveCriticalSection(&m_CriticalSection);
}
void CDebugScripts::ConsoleClear()
@ -139,16 +135,15 @@ void CDebugScripts::ConsoleCopy()
void CDebugScripts::RefreshList()
{
EnterCriticalSection(&m_CriticalSection);
CGuard guard(m_CS);
int nIndex = m_ScriptList.GetSelectedIndex();
int nIndex = m_ScriptList.GetSelectedIndex();
CPath SearchPath("Scripts", "*");
if (!SearchPath.FindFirst(CPath::FIND_ATTRIBUTE_ALLFILES))
{
LeaveCriticalSection(&m_CriticalSection);
return;
return;
}
m_ScriptList.SetRedraw(false);
@ -168,8 +163,6 @@ void CDebugScripts::RefreshList()
m_ScriptList.SelectItem(nIndex);
RefreshStatus();
}
LeaveCriticalSection(&m_CriticalSection);
}
LRESULT CDebugScripts::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
@ -195,7 +188,7 @@ LRESULT CDebugScripts::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*
return FALSE;
}
LRESULT CDebugScripts::OnScriptListDblClicked(NMHDR* pNMHDR)
LRESULT CDebugScripts::OnScriptListDblClicked(NMHDR* pNMHDR)
{
// Run script on double click
NMITEMACTIVATE* pIA = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR);
@ -210,13 +203,13 @@ LRESULT CDebugScripts::OnScriptListDblClicked(NMHDR* pNMHDR)
void CDebugScripts::RefreshStatus()
{
EnterCriticalSection(&m_CriticalSection);
INSTANCE_STATE state = m_Debugger->ScriptSystem()->GetInstanceState(m_SelectedScriptName);
CGuard guard(m_CS);
INSTANCE_STATE state = m_Debugger->ScriptSystem()->GetInstanceState(m_SelectedScriptName);
char* szState = "";
switch (state)
{
case STATE_RUNNING: szState = "Running"; break;
case STATE_RUNNING: szState = "Running"; break;
case STATE_STARTED: szState = "Started"; break;
case STATE_STOPPED: szState = "Stopped"; break;
case STATE_INVALID: szState = "Not running"; break;
@ -234,11 +227,9 @@ void CDebugScripts::RefreshStatus()
{
m_EvalEdit.EnableWindow(FALSE);
}
LeaveCriticalSection(&m_CriticalSection);
}
LRESULT CDebugScripts::OnScriptListClicked(NMHDR* pNMHDR)
LRESULT CDebugScripts::OnScriptListClicked(NMHDR* pNMHDR)
{
// Select instance for console input
NMITEMACTIVATE* pIA = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR);
@ -251,7 +242,7 @@ LRESULT CDebugScripts::OnScriptListClicked(NMHDR* pNMHDR)
return 0;
}
LRESULT CDebugScripts::OnScriptListRClicked(NMHDR* pNMHDR)
LRESULT CDebugScripts::OnScriptListRClicked(NMHDR* pNMHDR)
{
OnScriptListClicked(pNMHDR);
@ -411,7 +402,7 @@ void CDebugScripts::RunSelected()
void CDebugScripts::StopSelected()
{
m_Debugger->ScriptSystem()->StopScript(m_SelectedScriptName);
m_Debugger->ScriptSystem()->StopScript(m_SelectedScriptName);
//m_Debugger->Debug_RefreshScriptsWindow();
//m_Debugger->Debug_RefreshScriptsWindow();
}

View File

@ -89,7 +89,7 @@ private:
char* m_SelectedScriptName;
void RefreshStatus();
CRITICAL_SECTION m_CriticalSection;
CriticalSection m_CS;
public:
enum { IDD = IDD_Debugger_Scripts };

View File

@ -26,24 +26,24 @@ CDebugStackTrace::~CDebugStackTrace()
LRESULT CDebugStackTrace::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
DlgResize_Init();
DlgResize_Init();
DlgSavePos_Init(DebuggerUI_StackTracePos);
m_List.Attach(GetDlgItem(IDC_STACKTRACE_LIST));
m_List.AddColumn("Caller", 0);
m_List.AddColumn("Routine", 1);
m_List.AddColumn("Name", 2);
m_List.Attach(GetDlgItem(IDC_STACKTRACE_LIST));
m_List.AddColumn("Caller", 0);
m_List.AddColumn("Routine", 1);
m_List.AddColumn("Name", 2);
m_List.SetColumnWidth(0, 70);
m_List.SetColumnWidth(1, 70);
m_List.SetColumnWidth(2, 160);
m_List.SetColumnWidth(0, 70);
m_List.SetColumnWidth(1, 70);
m_List.SetColumnWidth(2, 160);
m_List.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT);
m_List.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT);
LoadWindowPos();
WindowCreated();
return TRUE;
LoadWindowPos();
WindowCreated();
return TRUE;
}
void CDebugStackTrace::OnExitSizeMove(void)
@ -53,79 +53,76 @@ void CDebugStackTrace::OnExitSizeMove(void)
LRESULT CDebugStackTrace::OnActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
Refresh();
return FALSE;
Refresh();
return FALSE;
}
LRESULT CDebugStackTrace::OnDestroy(void)
{
m_List.Detach();
return FALSE;
return FALSE;
}
LRESULT CDebugStackTrace::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
switch (wID)
{
case IDCANCEL:
EndDialog(0);
break;
}
return FALSE;
switch (wID)
{
case IDCANCEL:
EndDialog(0);
break;
}
return FALSE;
}
LRESULT CDebugStackTrace::OnListDblClicked(NMHDR* pNMHDR)
{
NMITEMACTIVATE* pIA = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR);
int nItem = pIA->iItem;
NMITEMACTIVATE* pIA = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR);
int nItem = pIA->iItem;
uint32_t address = m_List.GetItemData(nItem);
uint32_t address = m_List.GetItemData(nItem);
m_Debugger->Debug_ShowCommandsLocation(address, true);
m_Debugger->Debug_ShowCommandsLocation(address, true);
return 0;
return 0;
}
void CDebugStackTrace::Refresh()
{
if (!isStepping())
{
return;
}
if (!isStepping())
{
return;
}
SetWindowText(stdstr_f("Stack Trace (%d)", m_EntriesIndex).c_str());
SetWindowText(stdstr_f("Stack Trace (%d)", m_EntriesIndex).c_str());
m_List.SetRedraw(FALSE);
m_List.DeleteAllItems();
CSymbols::EnterCriticalSection();
m_List.SetRedraw(FALSE);
m_List.DeleteAllItems();
for (int i = 0; i < m_EntriesIndex; i++)
{
uint32_t routineAddress = m_Entries[i].routineAddress;
uint32_t callingAddress = m_Entries[i].callingAddress;
char szAddress[9];
sprintf(szAddress, "%08X", callingAddress);
m_List.AddItem(i, 0, szAddress);
for (int i = 0; i < m_EntriesIndex; i++)
{
uint32_t routineAddress = m_Entries[i].routineAddress;
uint32_t callingAddress = m_Entries[i].callingAddress;
char szAddress[9];
sprintf(szAddress, "%08X", callingAddress);
m_List.AddItem(i, 0, szAddress);
sprintf(szAddress, "%08X", routineAddress);
m_List.AddItem(i, 1, szAddress);
sprintf(szAddress, "%08X", routineAddress);
m_List.AddItem(i, 1, szAddress);
CSymbolEntry* symbol = CSymbols::GetEntryByAddress(routineAddress);
if(symbol != NULL)
{
m_List.AddItem(i, 2, symbol->m_Name);
}
else
{
m_List.AddItem(i, 2, "");
}
m_List.SetItemData(i, routineAddress);
}
CSymbol symbol;
CSymbols::LeaveCriticalSection();
if (m_Debugger->SymbolTable()->GetSymbolByAddress(routineAddress, &symbol))
{
m_List.AddItem(i, 2, symbol.m_Name);
}
else
{
m_List.AddItem(i, 2, "");
}
m_List.SetItemData(i, routineAddress);
}
m_List.SetRedraw(TRUE);
m_List.SetRedraw(TRUE);
}

View File

@ -59,9 +59,6 @@ private:
STACKTRACE_ENTRY m_Entries[STACKTRACE_MAX_ENTRIES];
int m_EntriesIndex;
HANDLE m_AutoRefreshThread;
static DWORD WINAPI AutoRefreshProc(void* _this);
CListViewCtrl m_List;
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);

View File

@ -91,8 +91,6 @@ void CDebugStackView::Refresh()
uint32_t spBase = g_Reg->m_GPR[29].UW[0];
m_SPStatic.SetWindowTextA(stdstr_f("SP: %08X", spBase).c_str());
CSymbols::EnterCriticalSection();
for (int i = 0; i < 0x10; i++)
{
char t[4];
@ -104,7 +102,7 @@ void CDebugStackView::Refresh()
uint32_t vaddr = spBase + (i * 0x10) + (j * 4);
uint32_t val;
if (!m_Debugger->DebugLW_VAddr(vaddr, val))
if (!m_Debugger->DebugLoad_VAddr(vaddr, val))
{
m_StackList.AddItem(i, j + 1, "????????");
continue;
@ -116,7 +114,5 @@ void CDebugStackView::Refresh()
}
}
CSymbols::LeaveCriticalSection();
m_StackList.SetRedraw(TRUE);
}

View File

@ -44,10 +44,10 @@ LRESULT CDebugSymbols::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*l
Refresh();
m_AutoRefreshThread = CreateThread(NULL, 0, AutoRefreshProc, (void*)this, 0, NULL);
SetTimer(TIMER_ID_AUTO_REFRESH, 100, NULL);
LoadWindowPos();
WindowCreated();
LoadWindowPos();
WindowCreated();
return 0;
}
@ -58,22 +58,16 @@ void CDebugSymbols::OnExitSizeMove(void)
LRESULT CDebugSymbols::OnDestroy(void)
{
KillTimer(TIMER_ID_AUTO_REFRESH);
m_SymbolsListView.Detach();
if (m_AutoRefreshThread != NULL)
{
TerminateThread(m_AutoRefreshThread, 0);
CloseHandle(m_AutoRefreshThread);
}
return 0;
}
DWORD WINAPI CDebugSymbols::AutoRefreshProc(void* _this)
void CDebugSymbols::OnTimer(UINT_PTR nIDEvent)
{
CDebugSymbols* self = (CDebugSymbols*)_this;
while (true)
if (nIDEvent == TIMER_ID_AUTO_REFRESH)
{
self->RefreshValues();
Sleep(100);
RefreshValues();
}
}
@ -89,34 +83,41 @@ LRESULT CDebugSymbols::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*
break;
case IDC_REMOVESYMBOL_BTN:
{
int id = m_SymbolsListView.GetItemData(m_SymbolsListView.GetSelectedIndex());
CSymbols::EnterCriticalSection();
CSymbols::RemoveEntryById(id);
CSymbols::Save();
CSymbols::LeaveCriticalSection();
Refresh();
int nItem = m_SymbolsListView.GetSelectedIndex();
if (nItem != -1)
{
int id = m_SymbolsListView.GetItemData(nItem);
m_Debugger->SymbolTable()->RemoveSymbolById(id);
m_Debugger->SymbolTable()->Save();
Refresh();
}
break;
}
}
return FALSE;
}
LRESULT CDebugSymbols::OnListDblClicked(NMHDR* pNMHDR)
LRESULT CDebugSymbols::OnListDblClicked(NMHDR* pNMHDR)
{
// Open it in memory viewer/commands viewer
NMITEMACTIVATE* pIA = reinterpret_cast<NMITEMACTIVATE*>(pNMHDR);
int nItem = pIA->iItem;
int id = m_SymbolsListView.GetItemData(nItem);
CSymbolEntry* symbol = CSymbols::GetEntryById(id);
if (symbol->m_Type == 0) // code
CSymbol symbol;
if (!m_Debugger->SymbolTable()->GetSymbolById(id, &symbol))
{
m_Debugger->Debug_ShowCommandsLocation(symbol->m_Address, true);
return 0;
}
if (symbol.m_Type == SYM_CODE) // code
{
m_Debugger->Debug_ShowCommandsLocation(symbol.m_Address, true);
}
else // data/number
{
m_Debugger->Debug_ShowMemoryLocation(symbol->m_Address, true);
m_Debugger->Debug_ShowMemoryLocation(symbol.m_Address, true);
}
return 0;
@ -131,33 +132,26 @@ void CDebugSymbols::Refresh()
m_SymbolsListView.SetRedraw(FALSE);
m_SymbolsListView.DeleteAllItems();
CSymbols::EnterCriticalSection();
CSymbol symbol;
int nItem = 0;
int count = CSymbols::GetCount();
for (int i = 0; i < count; i++)
while (m_Debugger->SymbolTable()->GetSymbolByIndex(nItem, &symbol))
{
CSymbolEntry* lpSymbol = CSymbols::GetEntryByIndex(i);
char szValue[64];
m_Debugger->SymbolTable()->GetValueString(szValue, &symbol);
stdstr addrStr = stdstr_f("%08X", lpSymbol->m_Address);
stdstr strAddr = stdstr_f("%08X", symbol.m_Address);
m_SymbolsListView.AddItem(i, 0, addrStr.c_str());
m_SymbolsListView.AddItem(i, 1, lpSymbol->TypeName());
m_SymbolsListView.AddItem(i, 2, lpSymbol->m_Name);
m_SymbolsListView.AddItem(i, 4, lpSymbol->m_Description);
m_SymbolsListView.AddItem(nItem, 0, strAddr.c_str());
m_SymbolsListView.AddItem(nItem, 1, symbol.TypeName());
m_SymbolsListView.AddItem(nItem, 2, symbol.m_Name);
m_SymbolsListView.AddItem(nItem, 4, symbol.m_Description);
m_SymbolsListView.AddItem(nItem, 5, szValue);
m_SymbolsListView.SetItemData(i, lpSymbol->m_Id);
if (g_MMU)
{
char szValue[64];
CSymbols::GetValueString(szValue, lpSymbol);
m_SymbolsListView.AddItem(i, 3, szValue);
}
m_SymbolsListView.SetItemData(nItem, symbol.m_Id);
nItem++;
}
CSymbols::LeaveCriticalSection();
m_SymbolsListView.SetRedraw(TRUE);
}
@ -169,20 +163,21 @@ void CDebugSymbols::RefreshValues()
}
int count = m_SymbolsListView.GetItemCount();
CSymbols::EnterCriticalSection();
CSymbol symbol;
for (int i = 0; i < count; i++)
{
int symbolId = m_SymbolsListView.GetItemData(i);
CSymbolEntry* lpSymbol = CSymbols::GetEntryById(symbolId);
if (!m_Debugger->SymbolTable()->GetSymbolById(symbolId, &symbol))
{
break;
}
char szValue[64];
CSymbols::GetValueString(szValue, lpSymbol);
m_Debugger->SymbolTable()->GetValueString(szValue, &symbol);
m_SymbolsListView.SetItemText(i, 3, szValue);
}
CSymbols::LeaveCriticalSection();
}
}

View File

@ -23,11 +23,9 @@ private:
CListViewCtrl m_SymbolsListView;
CAddSymbolDlg m_AddSymbolDlg;
HANDLE m_AutoRefreshThread;
static DWORD WINAPI CDebugSymbols::AutoRefreshProc(void* _this);
public:
enum { IDD = IDD_Debugger_Symbols };
enum { TIMER_ID_AUTO_REFRESH };
CDebugSymbols(CDebuggerUI * debugger);
//virtual ~CDebugScripts(void);
@ -40,13 +38,14 @@ public:
LRESULT OnListDblClicked(NMHDR* pNMHDR);
LRESULT OnDestroy(void);
void OnExitSizeMove(void);
void OnTimer(UINT_PTR nIDEvent);
BEGIN_MSG_MAP_EX(CDebugSymbols)
COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
MSG_WM_DESTROY(OnDestroy)
NOTIFY_HANDLER_EX(IDC_SYMBOLS_LIST, NM_DBLCLK, OnListDblClicked)
//NOTIFY_HANDLER_EX(IDC_CMD_LIST, NM_RCLICK, OnListClicked)
MSG_WM_TIMER(OnTimer)
CHAIN_MSG_MAP(CDialogResize<CDebugSymbols>)
MSG_WM_EXITSIZEMOVE(OnExitSizeMove);
END_MSG_MAP()

View File

@ -21,7 +21,7 @@ CDebugTlb::~CDebugTlb()
{
}
LRESULT CDebugTlb::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
LRESULT CDebugTlb::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
DlgSavePos_Init(DebuggerUI_TLBPos);
@ -79,14 +79,14 @@ LRESULT CDebugTlb::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lPara
RefreshTLBWindow();
SendMessage(GetDlgItem(IDC_TLB_ENTRIES), BM_SETCHECK, BST_CHECKED, 0);
LoadWindowPos();
WindowCreated();
LoadWindowPos();
WindowCreated();
return TRUE;
}
void CDebugTlb::OnExitSizeMove(void)
{
SaveWindowPos(0);
SaveWindowPos(0);
}
LRESULT CDebugTlb::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND, BOOL& /*bHandled*/)

View File

@ -16,12 +16,12 @@ class CDebugTlb :
BEGIN_MSG_MAP_EX(CDebugTlb)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
COMMAND_CODE_HANDLER(BN_CLICKED, OnClicked)
MSG_WM_EXITSIZEMOVE(OnExitSizeMove)
END_MSG_MAP()
MSG_WM_EXITSIZEMOVE(OnExitSizeMove)
END_MSG_MAP()
LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/);
LRESULT OnClicked(WORD wNotifyCode, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled);
void OnExitSizeMove(void);
void OnExitSizeMove(void);
public:
enum { IDD = IDD_Debugger_TLB };

View File

@ -33,7 +33,7 @@ CDebugMemoryView::jump_item_t CDebugMemoryView::JumpItems[] = {
{ 0xA4700000, 0x04700000, 0x0000020, "RI Registers" },
{ 0xA4800000, 0x04800000, 0x0000010, "SI Registers" },
{ 0xA5000500, 0x05000500, 0x000004C, "DD Registers" },
{ 0xA8000000, 0xA8000000, 0x0000000, "Cartridge Save Data" },
{ 0xA8000000, 0x08000000, 0x1000000, "Cartridge Save Data" },
{ 0xB0000000, 0x10000000, 0xFC00000, "Cartridge ROM" },
{ 0xBFC00000, 0x1FC00000, 0x00007C0, "PIF ROM" },
{ 0xBFC007C0, 0x1FC007C0, 0x0000040, "PIF RAM" },
@ -76,11 +76,11 @@ bool CDebugMemoryView::GetByte(uint32_t address, uint8_t* value)
{
if (m_bVirtualMemory)
{
return m_Debugger->DebugLB_VAddr(address, *value);
return m_Debugger->DebugLoad_VAddr(address, *value);
}
else
{
return m_Debugger->DebugLB_PAddr(address, *value);
return m_Debugger->DebugLoad_PAddr(address, *value);
}
}
@ -88,11 +88,11 @@ bool CDebugMemoryView::SetByte(uint32_t address, uint8_t value)
{
if (m_bVirtualMemory)
{
return m_Debugger->DebugSB_VAddr(address, value);
return m_Debugger->DebugStore_VAddr(address, value);
}
else
{
return m_Debugger->DebugSB_PAddr(address, value);
return m_Debugger->DebugStore_PAddr(address, value);
}
}
@ -200,18 +200,28 @@ void CDebugMemoryView::FollowPointer(bool bContextMenuAddress)
if (bContextMenuAddress)
{
address = m_ContextMenuAddress - (m_ContextMenuAddress % 4);
address = m_ContextMenuAddress & (~3);
}
else
{
address = m_HexEditCtrl.GetCaretAddress();
address -= (address % 4);
uint32_t selStartAddress, selEndAddress;
m_HexEditCtrl.GetSelectionRange(&selStartAddress, &selEndAddress);
address = selStartAddress & (~3);
}
address += (m_bVirtualMemory ? 0 : 0x80000000);
uint32_t pointer;
if (m_Debugger->DebugLW_VAddr(address, pointer))
bool bValid;
if (m_bVirtualMemory)
{
bValid = m_Debugger->DebugLoad_VAddr(address, pointer);
}
else
{
bValid = m_Debugger->DebugLoad_VAddr(address, pointer);
}
if (bValid)
{
OpenNewTab(pointer, m_bVirtualMemory, 4, true, true);
}
@ -349,6 +359,7 @@ LRESULT CDebugMemoryView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM
SetupJumpMenu(true);
m_CmbJump.SetCurSel(0);
m_TabData.clear();
AddTab(0x80000000, true, 4);
m_HexEditCtrl.Draw();
@ -391,7 +402,7 @@ LRESULT CDebugMemoryView::OnClicked(WORD /*wNotifyCode*/, WORD wID, HWND, BOOL&
case IDC_CHK_VADDR:
m_bVirtualMemory = (m_VirtualCheckbox.GetCheck() == BST_CHECKED);
SetupJumpMenu(m_bVirtualMemory);
UpdateCurrentTab(m_MemAddr.GetValue());
m_CmbJump.SetCurSel(GetJumpItemIndex(m_MemAddr.GetValue(), m_bVirtualMemory));
break;
case IDC_SYMBOLS_BTN:
m_Debugger->OpenSymbolsWindow();
@ -493,6 +504,7 @@ void CDebugMemoryView::OnAddrChanged(UINT /*Code*/, int /*id*/, HWND /*ctl*/)
uint32_t address = m_MemAddr.GetValue();
m_HexEditCtrl.SetBaseAddress(address);
UpdateCurrentTab(address);
m_CmbJump.SetCurSel(GetJumpItemIndex(address, m_bVirtualMemory));
}
void CDebugMemoryView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar pScrollBar)
@ -545,9 +557,7 @@ LRESULT CDebugMemoryView::OnHxCtrlKeyPressed(LPNMHDR lpNMHDR)
switch (nmck->nChar)
{
case 'G':
{
JumpToSelection();
}
break;
case 'W':
m_Breakpoints->WBPToggle(address);
@ -787,17 +797,13 @@ LRESULT CDebugMemoryView::OnHxGetByteInfo(LPNMHDR lpNMHDR)
// todo should be the other way around
uint32_t vaddress = m_bVirtualMemory ? address : address + 0x80000000;
CSymbols::EnterCriticalSection();
CSymbolEntry* symbol = CSymbols::GetEntryByAddress(vaddress);
if (symbol != NULL)
CSymbol symbol;
if (m_Debugger->SymbolTable()->GetSymbolByAddress(vaddress, &symbol))
{
m_SymbolColorStride = symbol->TypeSize();
m_SymbolColorStride = symbol.TypeSize();
m_SymbolColorPhase = m_SymbolColorPhase ? 0 : 1;
}
CSymbols::LeaveCriticalSection();
if (bHaveWriteTarget && address == cpuReadWriteAddress)
{
m_WriteTargetColorStride = cpuReadWriteNumBytes;
@ -923,24 +929,10 @@ LRESULT CDebugMemoryView::OnHxHotAddrChanged(LPNMHDR /*lpNMHDR*/)
m_HotAddress = m_HexEditCtrl.GetHotAddress();
stdstr strAddrInfo = "";
CSymbols::EnterCriticalSection();
CSymbolEntry* foundSymbol = NULL;
int numSymbols = CSymbols::GetCount();
for (int i = 0; i < numSymbols; i++)
CSymbol symbol;
if (m_Debugger->SymbolTable()->GetSymbolByOverlappedAddress(m_HotAddress, &symbol))
{
CSymbolEntry* symbol = CSymbols::GetEntryByIndex(i);
if (m_HotAddress >= symbol->m_Address && m_HotAddress < symbol->m_Address + symbol->TypeSize())
{
foundSymbol = symbol;
break;
}
}
if (foundSymbol != NULL)
{
strAddrInfo += stdstr_f("%08X %s %s", foundSymbol->m_Address, foundSymbol->TypeName(), foundSymbol->m_Name);
strAddrInfo += stdstr_f("%08X %s %s", symbol.m_Address, symbol.TypeName(), symbol.m_Name);
}
else
{
@ -948,8 +940,6 @@ LRESULT CDebugMemoryView::OnHxHotAddrChanged(LPNMHDR /*lpNMHDR*/)
}
m_StatusBar.SetText(MEMSB_HOTADDR, strAddrInfo.c_str());
CSymbols::LeaveCriticalSection();
return FALSE;
}

View File

@ -36,6 +36,7 @@ CDebuggerUI::CDebuggerUI() :
m_ExcBreakpoints(NULL),
m_DMALog(NULL),
m_CPULog(NULL),
m_SymbolTable(NULL),
m_StepEvent(false)
{
g_Debugger = this;
@ -45,10 +46,8 @@ CDebuggerUI::CDebuggerUI() :
m_DMALog = new CDMALog();
m_CPULog = new CCPULog();
m_SymbolTable = new CSymbolTable(this);
InitializeCriticalSection(&m_CriticalSection);
CSymbols::InitializeCriticalSection();
g_Settings->RegisterChangeCB(GameRunning_InReset, this, (CSettings::SettingChangedFunc)GameReset);
g_Settings->RegisterChangeCB(Debugger_SteppingOps, this, (CSettings::SettingChangedFunc)SteppingOpsChanged);
g_Settings->RegisterChangeCB(GameRunning_CPU_Running, this, (CSettings::SettingChangedFunc)GameCpuRunningChanged);
@ -75,9 +74,7 @@ CDebuggerUI::~CDebuggerUI(void)
delete m_ExcBreakpoints;
delete m_DMALog;
delete m_CPULog;
CSymbols::DeleteCriticalSection();
DeleteCriticalSection(&m_CriticalSection);
delete m_SymbolTable;
}
void CDebuggerUI::SteppingOpsChanged(CDebuggerUI * _this)
@ -129,9 +126,10 @@ void CDebuggerUI::GameReset(CDebuggerUI * _this)
_this->m_StackTrace->ClearEntries();
}
CSymbols::EnterCriticalSection();
CSymbols::Load();
CSymbols::LeaveCriticalSection();
if (_this->m_SymbolTable)
{
_this->m_SymbolTable->Load();
}
if (_this->m_Symbols)
{
@ -458,6 +456,11 @@ CCPULog* CDebuggerUI::CPULog()
return m_CPULog;
}
CSymbolTable* CDebuggerUI::SymbolTable()
{
return m_SymbolTable;
}
// CDebugger implementation
void CDebuggerUI::TLBChanged()

View File

@ -409,6 +409,11 @@ bool CScanResult::SetMemoryValueFromString(char* str)
bool CScanResult::SetAddressSafe(uint32_t address)
{
if (!g_MMU || !g_Rom)
{
return false;
}
uint32_t ramSize = g_MMU->RdramSize();
uint32_t romSize = g_Rom->GetRomSize();
@ -442,6 +447,11 @@ bool CScanResult::SetAddressSafe(uint32_t address)
bool CScanResult::SetStrLengthSafe(int length)
{
if (!g_MMU || !g_Rom)
{
return false;
}
uint32_t ramSize = g_MMU->RdramSize();
uint32_t romSize = g_Rom->GetRomSize();
@ -536,6 +546,11 @@ void CMemoryScanner::Reset(void)
bool CMemoryScanner::SetAddressRange(uint32_t startAddress, uint32_t endAddress)
{
if (!g_MMU || !g_Rom)
{
return false;
}
if(m_DidFirstScan)
{
return false;
@ -596,6 +611,11 @@ bool CMemoryScanner::SetAddressRange(uint32_t startAddress, uint32_t endAddress)
uint8_t* CMemoryScanner::GetMemoryPool(uint32_t physAddr)
{
if (!g_MMU || !g_Rom)
{
return NULL;
}
if ((physAddr >= 0x00000000 && physAddr < g_MMU->RdramSize()) ||
(physAddr >= 0x04000000 && physAddr <= 0x04001FFF))
{

View File

@ -1,3 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include <stdafx.h>
#include "ScriptHook.h"
@ -78,32 +88,32 @@ void CScriptHook::InvokeByAddressInRange_MaskedOpcode(uint32_t pc, uint32_t opco
void CScriptHook::InvokeByAddressInRange_GPRValue(uint32_t pc)
{
int nCallbacks = m_Callbacks.size();
int nCallbacks = m_Callbacks.size();
for (int i = 0; i < nCallbacks; i++)
{
uint32_t startAddress = m_Callbacks[i].param;
uint32_t endAddress = m_Callbacks[i].param2;
uint32_t registers = m_Callbacks[i].param3;
uint32_t value = m_Callbacks[i].param4;
for (int i = 0; i < nCallbacks; i++)
{
uint32_t startAddress = m_Callbacks[i].param;
uint32_t endAddress = m_Callbacks[i].param2;
uint32_t registers = m_Callbacks[i].param3;
uint32_t value = m_Callbacks[i].param4;
if (!(pc == startAddress || (pc >= startAddress && pc <= endAddress)))
{
continue;
}
if (!(pc == startAddress || (pc >= startAddress && pc <= endAddress)))
{
continue;
}
for (int nReg = 0; nReg < 32; nReg++)
{
if (registers & (1 << nReg))
{
if (value == g_Reg->m_GPR[nReg].UW[0])
{
m_Callbacks[i].scriptInstance->Invoke2(m_Callbacks[i].heapptr, pc, nReg);
for (int nReg = 0; nReg < 32; nReg++)
{
if (registers & (1 << nReg))
{
if (value == g_Reg->m_GPR[nReg].UW[0])
{
m_Callbacks[i].scriptInstance->Invoke2(m_Callbacks[i].heapptr, pc, nReg);
break;
}
}
}
}
}
}
}
}
}
void CScriptHook::InvokeAll()

View File

@ -1,3 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once
#include <stdafx.h>
@ -36,7 +46,7 @@ public:
void InvokeByAddressInRange(uint32_t address);
/* invoke if param >= cb.param && param < cb.param2 && (value & cb.param4) == cb.param3 */
void InvokeByAddressInRange_MaskedOpcode(uint32_t pc, uint32_t value);
void InvokeByAddressInRange_GPRValue(uint32_t pc);
void InvokeByAddressInRange_GPRValue(uint32_t pc);
void RemoveById(int callbackId);
void RemoveByParam(uint32_t tag);
void RemoveByInstance(CScriptInstance* scriptInstance);

View File

@ -1,3 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include <stdafx.h>
#include <sys/stat.h>
@ -47,29 +57,27 @@ CScriptInstance::CScriptInstance(CDebuggerUI* debugger)
m_ScriptSystem = m_Debugger->ScriptSystem();
m_NextListenerId = 0;
m_hIOCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
InitializeCriticalSection(&m_CriticalSection);
CacheInstance(this);
m_hKernel = LoadLibrary("Kernel32.dll");
m_CancelIoEx = NULL;
if (m_hKernel != NULL)
{
m_CancelIoEx = (Dynamic_CancelIoEx)GetProcAddress(m_hKernel, "CancelIoEx");
}
m_hKernel = LoadLibrary("Kernel32.dll");
m_CancelIoEx = NULL;
if (m_hKernel != NULL)
{
m_CancelIoEx = (Dynamic_CancelIoEx)GetProcAddress(m_hKernel, "CancelIoEx");
}
}
CScriptInstance::~CScriptInstance()
{
UncacheInstance(this);
DeleteCriticalSection(&m_CriticalSection);
duk_destroy_heap(m_Ctx);
TerminateThread(m_hThread, 0);
CloseHandle(m_hThread);
m_CancelIoEx = NULL;
if (m_hKernel != NULL)
{
FreeLibrary(m_hKernel);
}
TerminateThread(m_hThread, 0);
CloseHandle(m_hThread);
m_CancelIoEx = NULL;
if (m_hKernel != NULL)
{
FreeLibrary(m_hKernel);
}
}
void CScriptInstance::Start(char* path)
@ -81,9 +89,8 @@ void CScriptInstance::Start(char* path)
void CScriptInstance::ForceStop()
{
// Close all files and delete all hooked callbacks
EnterCriticalSection(&m_CriticalSection);
CGuard guard(m_CS);
CleanUp();
LeaveCriticalSection(&m_CriticalSection);
SetState(STATE_STOPPED);
}
@ -364,18 +371,18 @@ void CScriptInstance::RemoveListenerByIndex(UINT index)
free(lpListener->data);
}
// Original call to CancelIoEx:
// Original call to CancelIoEx:
//CancelIoEx(lpListener->fd, (LPOVERLAPPED)lpListener);
if (m_CancelIoEx != NULL)
{
m_CancelIoEx(lpListener->fd, (LPOVERLAPPED)lpListener);
}
else
{
// This isn't a good replacement and the script aspects of the debugger shouldn't
// be used in WindowsXP
CancelIo(lpListener->fd);
}
if (m_CancelIoEx != NULL)
{
m_CancelIoEx(lpListener->fd, (LPOVERLAPPED)lpListener);
}
else
{
// This isn't a good replacement and the script aspects of the debugger shouldn't
// be used in WindowsXP
CancelIo(lpListener->fd);
}
free(lpListener);
@ -408,13 +415,13 @@ void CScriptInstance::RemoveListenersByFd(HANDLE fd)
void CScriptInstance::InvokeListenerCallback(IOLISTENER* lpListener)
{
CGuard guard(m_CS);
if (lpListener->callback == NULL)
{
return;
}
EnterCriticalSection(&m_CriticalSection);
duk_push_heapptr(m_Ctx, lpListener->callback);
int nargs = 0;
@ -458,57 +465,27 @@ void CScriptInstance::InvokeListenerCallback(IOLISTENER* lpListener)
const char* msg = duk_safe_to_string(m_Ctx, -1);
MessageBox(NULL, msg, "Script error", MB_OK | MB_ICONWARNING);
}
LeaveCriticalSection(&m_CriticalSection);
}
const char* CScriptInstance::Eval(const char* jsCode)
{
CGuard guard(m_CS);
int result = duk_peval_string(m_Ctx, jsCode);
const char* msg = duk_safe_to_string(m_Ctx, -1);
const char* msg = NULL;
if (result != 0)
{
MessageBox(NULL, msg, "Script error", MB_OK | MB_ICONWARNING);
}
else
{
msg = duk_safe_to_string(m_Ctx, -1);
}
duk_pop(m_Ctx);
return msg;
}
class PendingEval {
char* m_CodeCopy;
CScriptInstance* m_ScriptInstance;
public:
PendingEval(CScriptInstance* instance, const char* jsCode)
{
m_CodeCopy = (char*)malloc(strlen(jsCode));
m_ScriptInstance = instance;
MessageBox(NULL, "pending eval created", "", MB_OK);
}
~PendingEval()
{
MessageBox(NULL, "pending eval deleted", "", MB_OK);
free(m_CodeCopy);
}
void Run()
{
MessageBox(NULL, "pending eval invoked", "", MB_OK);
m_ScriptInstance->Eval(m_CodeCopy);
}
};
void CScriptInstance::EvalAsync(const char* jsCode)
{
PendingEval* pendingEval = new PendingEval(this, jsCode);
QueueAPC(EvalAsyncCallback, (ULONG_PTR)pendingEval);
}
void CALLBACK CScriptInstance::EvalAsyncCallback(ULONG_PTR _pendingEval)
{
PendingEval* evalWait = (PendingEval*)_pendingEval;
evalWait->Run();
delete evalWait;
}
bool CScriptInstance::AddFile(const char* path, const char* mode, int* fd)
{
FILE* fp = fopen(path, mode);
@ -584,7 +561,7 @@ const char* CScriptInstance::EvalFile(const char* jsPath)
void CScriptInstance::Invoke(void* heapptr, uint32_t param)
{
EnterCriticalSection(&m_CriticalSection);
CGuard guard(m_CS);
duk_push_heapptr(m_Ctx, heapptr);
duk_push_uint(m_Ctx, param);
@ -598,12 +575,11 @@ void CScriptInstance::Invoke(void* heapptr, uint32_t param)
}
duk_pop(m_Ctx);
LeaveCriticalSection(&m_CriticalSection);
}
void CScriptInstance::Invoke2(void* heapptr, uint32_t param, uint32_t param2)
{
EnterCriticalSection(&m_CriticalSection);
CGuard guard(m_CS);
duk_push_heapptr(m_Ctx, heapptr);
duk_push_uint(m_Ctx, param);
duk_push_uint(m_Ctx, param2);
@ -618,7 +594,6 @@ void CScriptInstance::Invoke2(void* heapptr, uint32_t param, uint32_t param2)
}
duk_pop(m_Ctx);
LeaveCriticalSection(&m_CriticalSection);
}
void CScriptInstance::QueueAPC(PAPCFUNC userProc, ULONG_PTR param)
@ -718,7 +693,7 @@ duk_ret_t CScriptInstance::js_ioSockAccept(duk_context* ctx)
IOLISTENER* lpListener = _this->AddListener(fd, EVENT_ACCEPT, jsCallback, data, 0);
lpListener->childFd = _this->CreateSocket();
static DWORD unused;
static DWORD unused;
int ok = AcceptEx(
(SOCKET)fd,
@ -731,13 +706,13 @@ duk_ret_t CScriptInstance::js_ioSockAccept(duk_context* ctx)
(LPOVERLAPPED)lpListener
);
duk_pop_n(ctx, 2);
duk_pop_n(ctx, 2);
if (!ok) {
duk_push_boolean(ctx, false);
} else {
duk_push_boolean(ctx, true);
}
if (!ok) {
duk_push_boolean(ctx, false);
} else {
duk_push_boolean(ctx, true);
}
return 1;
}
@ -1008,19 +983,19 @@ duk_ret_t CScriptInstance::js_SetFPRVal(duk_context* ctx)
duk_ret_t CScriptInstance::js_GetCauseVal(duk_context* ctx)
{
duk_push_uint(ctx, g_Reg->FAKE_CAUSE_REGISTER);
return 1;
duk_push_uint(ctx, g_Reg->FAKE_CAUSE_REGISTER);
return 1;
}
duk_ret_t CScriptInstance::js_SetCauseVal(duk_context* ctx)
{
uint32_t val = duk_to_uint32(ctx, 0);
uint32_t val = duk_to_uint32(ctx, 0);
g_Reg->FAKE_CAUSE_REGISTER = val;
g_Reg->CheckInterrupts();
g_Reg->FAKE_CAUSE_REGISTER = val;
g_Reg->CheckInterrupts();
duk_pop_n(ctx, 1);
return 1;
duk_pop_n(ctx, 1);
return 1;
}
duk_ret_t CScriptInstance::js_GetROMInt(duk_context* ctx)
@ -1138,6 +1113,7 @@ return_err:
duk_ret_t CScriptInstance::js_GetRDRAMInt(duk_context* ctx)
{
CScriptInstance* _this = FetchInstance(ctx);
uint32_t address = duk_to_uint32(ctx, 0);
int bitwidth = duk_to_int(ctx, 1);
duk_bool_t bSigned = duk_to_boolean(ctx, 2);
@ -1156,7 +1132,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMInt(duk_context* ctx)
case 8:
{
uint8_t val;
if (!g_MMU->LB_VAddr(address, val))
if (!_this->m_Debugger->DebugLoad_VAddr(address, val))
{
goto return_err;
}
@ -1166,7 +1142,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMInt(duk_context* ctx)
case 16:
{
uint16_t val;
if (!g_MMU->LH_VAddr(address, val))
if (!_this->m_Debugger->DebugLoad_VAddr(address, val))
{
goto return_err;
}
@ -1176,7 +1152,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMInt(duk_context* ctx)
case 32:
{
uint32_t val;
if (!g_MMU->LW_VAddr(address, val))
if (!_this->m_Debugger->DebugLoad_VAddr(address, val))
{
goto return_err;
}
@ -1205,6 +1181,7 @@ return_err:
duk_ret_t CScriptInstance::js_SetRDRAMInt(duk_context* ctx)
{
CScriptInstance* _this = FetchInstance(ctx);
uint32_t address = duk_to_uint32(ctx, 0);
int bitwidth = duk_to_int(ctx, 1);
DWORD newValue = duk_to_uint32(ctx, 2);
@ -1219,19 +1196,19 @@ duk_ret_t CScriptInstance::js_SetRDRAMInt(duk_context* ctx)
switch (bitwidth)
{
case 8:
if (!g_MMU->SB_VAddr(address, (uint8_t)newValue))
if (!_this->m_Debugger->DebugStore_VAddr(address, (uint8_t)newValue))
{
goto return_err;
}
goto return_ok;
case 16:
if (!g_MMU->SH_VAddr(address, (uint16_t)newValue))
if (!_this->m_Debugger->DebugStore_VAddr(address, (uint16_t)newValue))
{
goto return_err;
}
goto return_ok;
case 32:
if (!g_MMU->SW_VAddr(address, (uint32_t)newValue))
if (!_this->m_Debugger->DebugStore_VAddr(address, (uint32_t)newValue))
{
goto return_err;
}
@ -1251,6 +1228,7 @@ return_err:
duk_ret_t CScriptInstance::js_GetRDRAMFloat(duk_context* ctx)
{
CScriptInstance* _this = FetchInstance(ctx);
int argc = duk_get_top(ctx);
uint32_t address = duk_to_uint32(ctx, 0);
@ -1271,7 +1249,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMFloat(duk_context* ctx)
if (!bDouble)
{
uint32_t rawValue;
if (!g_MMU->LW_VAddr(address, rawValue))
if (!_this->m_Debugger->DebugLoad_VAddr(address, rawValue))
{
goto return_err;
}
@ -1284,7 +1262,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMFloat(duk_context* ctx)
}
uint64_t rawValue;
if (!g_MMU->LD_VAddr(address, rawValue))
if (!_this->m_Debugger->DebugLoad_VAddr(address, rawValue))
{
goto return_err;
}
@ -1302,6 +1280,7 @@ return_err:
duk_ret_t CScriptInstance::js_SetRDRAMFloat(duk_context* ctx)
{
CScriptInstance* _this = FetchInstance(ctx);
int argc = duk_get_top(ctx);
uint32_t address = duk_to_uint32(ctx, 0);
@ -1325,7 +1304,7 @@ duk_ret_t CScriptInstance::js_SetRDRAMFloat(duk_context* ctx)
float floatValue = (float)value;
uint32_t rawValue;
memcpy(&rawValue, &floatValue, sizeof(float));
if (!g_MMU->SW_VAddr(address, rawValue))
if (!_this->m_Debugger->DebugStore_VAddr(address, rawValue))
{
goto return_err;
}
@ -1335,7 +1314,7 @@ duk_ret_t CScriptInstance::js_SetRDRAMFloat(duk_context* ctx)
double floatValue = (double)value;
uint64_t rawValue;
memcpy(&rawValue, &floatValue, sizeof(double));
if (!g_MMU->SD_VAddr(address, rawValue))
if (!_this->m_Debugger->DebugStore_VAddr(address, rawValue))
{
goto return_err;
}
@ -1351,6 +1330,7 @@ return_err:
duk_ret_t CScriptInstance::js_GetRDRAMBlock(duk_context* ctx)
{
CScriptInstance* _this = FetchInstance(ctx);
uint32_t address = duk_get_uint(ctx, 0);
uint32_t size = duk_get_uint(ctx, 1);
@ -1366,7 +1346,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMBlock(duk_context* ctx)
for (uint32_t i = 0; i < size; i++)
{
g_MMU->LB_VAddr(address + i, block[i]);
_this->m_Debugger->DebugLoad_VAddr(address + i, block[i]);
}
return 1;
@ -1394,6 +1374,8 @@ duk_ret_t CScriptInstance::js_MsgBox(duk_context* ctx)
// Return zero-terminated string from ram
duk_ret_t CScriptInstance::js_GetRDRAMString(duk_context* ctx)
{
CScriptInstance* _this = FetchInstance(ctx);
// (address[, maxLen])
int nargs = duk_get_top(ctx);
uint32_t address = duk_get_uint(ctx, 0);
@ -1412,7 +1394,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMString(duk_context* ctx)
int len = 0;
// determine length of string
while (len < maxLen && g_MMU->LB_VAddr(address + len, test) && test != 0) // todo protect from ram overrun
while (len < maxLen && _this->m_Debugger->DebugLoad_VAddr(address + len, test) && test != 0) // todo protect from ram overrun
{
if ((address & 0xFFFFFF) + len >= g_MMU->RdramSize())
{
@ -1425,7 +1407,7 @@ duk_ret_t CScriptInstance::js_GetRDRAMString(duk_context* ctx)
for (int i = 0; i < len; i++)
{
g_MMU->LB_VAddr(address + i, str[i]);
_this->m_Debugger->DebugLoad_VAddr(address + i, str[i]);
}
str[len] = '\0';

View File

@ -1,3 +1,13 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once
#include "stdafx.h"
@ -60,7 +70,7 @@ class CScriptInstance
int fd;
} FILE_FD;
typedef BOOL(__stdcall *Dynamic_CancelIoEx)(HANDLE, LPOVERLAPPED);
typedef BOOL(__stdcall *Dynamic_CancelIoEx)(HANDLE, LPOVERLAPPED);
public:
CScriptInstance(CDebuggerUI* debugger);
@ -73,7 +83,6 @@ public:
INSTANCE_STATE GetState();
friend class PendingEval;
void EvalAsync(const char* jsCode);
const char* Eval(const char* jsCode);
private:
@ -83,7 +92,7 @@ private:
HANDLE m_hThread;
HANDLE m_hIOCompletionPort;
CRITICAL_SECTION m_CriticalSection;
CriticalSection m_CS;
vector<IOFD> m_AsyncFiles;
vector<IOLISTENER*> m_Listeners;
@ -121,7 +130,7 @@ private:
void RemoveListenersByFd(HANDLE fd);
void InvokeListenerCallback(IOLISTENER* lpListener);
static void CALLBACK EvalAsyncCallback(ULONG_PTR evalWait);
//static void CALLBACK EvalAsyncCallback(ULONG_PTR evalWait);
bool AddFile(const char* path, const char* mode, int* fd); // return fd
void CloseFile(int fd);
@ -130,9 +139,9 @@ private:
const char* EvalFile(const char* jsPath);
// Handle to to dynamically load CancelIoEx for Windows XP compatibility
HMODULE m_hKernel;
Dynamic_CancelIoEx m_CancelIoEx;
// Handle to to dynamically load CancelIoEx for Windows XP compatibility
HMODULE m_hKernel;
Dynamic_CancelIoEx m_CancelIoEx;
// Lookup list of CScriptInstance instances for static js_* functions
static vector<CScriptInstance*> Cache;
@ -161,8 +170,8 @@ private:
static duk_ret_t js_SetGPRVal(duk_context*); // (regNum, bUpper, value)
static duk_ret_t js_GetFPRVal(duk_context*); // (regNum, bDouble)
static duk_ret_t js_SetFPRVal(duk_context*); // (regNum, bDouble, value)
static duk_ret_t js_GetCauseVal(duk_context*); // ()
static duk_ret_t js_SetCauseVal(duk_context*); // (value)
static duk_ret_t js_GetCauseVal(duk_context*); // ()
static duk_ret_t js_SetCauseVal(duk_context*); // (value)
static duk_ret_t js_GetROMInt(duk_context*); // (address, bitwidth, signed)
static duk_ret_t js_GetROMFloat(duk_context*); // (address, bDouble)
static duk_ret_t js_GetROMBlock(duk_context*); // (address, nBytes) ; returns Buffer
@ -209,8 +218,8 @@ private:
{ "getGPRVal", js_GetGPRVal, DUK_VARARGS },
{ "setFPRVal", js_SetFPRVal, DUK_VARARGS },
{ "getFPRVal", js_GetFPRVal, DUK_VARARGS },
{ "setCauseVal", js_SetCauseVal, DUK_VARARGS },
{ "getCauseVal", js_GetCauseVal, DUK_VARARGS },
{ "setCauseVal", js_SetCauseVal, DUK_VARARGS },
{ "getCauseVal", js_GetCauseVal, DUK_VARARGS },
{ "getROMInt", js_GetROMInt, DUK_VARARGS },
{ "getROMFloat", js_GetROMFloat, DUK_VARARGS },

View File

@ -25,8 +25,6 @@ CScriptSystem::CScriptSystem(CDebuggerUI* debugger)
m_Debugger = debugger;
InitializeCriticalSection(&m_CriticalSection);
m_HookCPUExec = new CScriptHook(this);
m_HookCPUExecOpcode = new CScriptHook(this);
m_HookCPURead = new CScriptHook(this);
@ -38,7 +36,7 @@ CScriptSystem::CScriptSystem(CDebuggerUI* debugger)
RegisterHook("read", m_HookCPURead);
RegisterHook("write", m_HookCPUWrite);
RegisterHook("opcode", m_HookCPUExecOpcode);
RegisterHook("gprvalue", m_HookCPUGPRValue);
RegisterHook("gprvalue", m_HookCPUGPRValue);
RegisterHook("draw", m_HookFrameDrawn);
HMODULE hInst = GetModuleHandle(NULL);
@ -63,8 +61,6 @@ CScriptSystem::~CScriptSystem()
UnregisterHooks();
free(m_APIScript);
DeleteCriticalSection(&m_CriticalSection);
}
const char* CScriptSystem::APIScript()
@ -74,14 +70,13 @@ const char* CScriptSystem::APIScript()
void CScriptSystem::RunScript(char* path)
{
CGuard guard(m_CS);
CScriptInstance* scriptInstance = new CScriptInstance(m_Debugger);
char* pathSaved = (char*)malloc(strlen(path)+1); // freed via DeleteStoppedInstances
strcpy(pathSaved, path);
EnterCriticalSection(&m_CriticalSection);
m_RunningInstances.push_back({ pathSaved, scriptInstance });
LeaveCriticalSection(&m_CriticalSection);
scriptInstance->Start(pathSaved);
m_RunningInstances.push_back({ pathSaved, scriptInstance });
scriptInstance->Start(pathSaved);
}
void CScriptSystem::StopScript(char* path)
@ -94,12 +89,12 @@ void CScriptSystem::StopScript(char* path)
}
scriptInstance->ForceStop();
DeleteStoppedInstances();
DeleteStoppedInstances();
}
void CScriptSystem::DeleteStoppedInstances()
{
EnterCriticalSection(&m_CriticalSection);
CGuard guard(m_CS);
int lastIndex = m_RunningInstances.size() - 1;
for (int i = lastIndex; i >= 0; i--)
@ -112,44 +107,37 @@ void CScriptSystem::DeleteStoppedInstances()
m_RunningInstances.erase(m_RunningInstances.begin() + i);
}
}
LeaveCriticalSection(&m_CriticalSection);
}
INSTANCE_STATE CScriptSystem::GetInstanceState(char* path)
{
EnterCriticalSection(&m_CriticalSection);
for (size_t i = 0; i < m_RunningInstances.size(); i++)
{
if (strcmp(m_RunningInstances[i].path, path) == 0)
{
INSTANCE_STATE ret = m_RunningInstances[i].scriptInstance->GetState();
LeaveCriticalSection(&m_CriticalSection);
return ret;
}
}
LeaveCriticalSection(&m_CriticalSection);
return STATE_INVALID;
}
CScriptInstance* CScriptSystem::GetInstance(char* path)
{
EnterCriticalSection(&m_CriticalSection);
CGuard guard(m_CS);
for (size_t i = 0; i < m_RunningInstances.size(); i++)
{
if (strcmp(m_RunningInstances[i].path, path) == 0)
{
CScriptInstance *ret = m_RunningInstances[i].scriptInstance;
LeaveCriticalSection(&m_CriticalSection);
INSTANCE_STATE ret = m_RunningInstances[i].scriptInstance->GetState();
return ret;
}
}
return STATE_INVALID;
}
CScriptInstance* CScriptSystem::GetInstance(char* path)
{
CGuard guard(m_CS);
for (size_t i = 0; i < m_RunningInstances.size(); i++)
{
if (strcmp(m_RunningInstances[i].path, path) == 0)
{
CScriptInstance *ret = m_RunningInstances[i].scriptInstance;
return ret;
}
}
LeaveCriticalSection(&m_CriticalSection);
return NULL;
}

View File

@ -55,10 +55,10 @@ private:
CScriptHook* m_HookCPURead;
CScriptHook* m_HookCPUWrite;
CScriptHook* m_HookCPUExecOpcode;
CScriptHook* m_HookCPUGPRValue;
CScriptHook* m_HookCPUGPRValue;
CScriptHook* m_HookFrameDrawn;
CRITICAL_SECTION m_CriticalSection;
CriticalSection m_CS;
void RegisterHook(const char* hookId, CScriptHook* cbList); // associate string id with callback list
void UnregisterHooks();
@ -135,10 +135,10 @@ public:
return m_HookCPUExecOpcode;
}
CScriptHook* HookCPUGPRValue()
{
return m_HookCPUGPRValue;
}
CScriptHook* HookCPUGPRValue()
{
return m_HookCPUGPRValue;
}
CScriptHook* HookFrameDrawn()
{

View File

@ -1,470 +1,485 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include "stdafx.h"
#include "Symbols.h"
bool CSymbols::m_bInitialized = false;
vector<CSymbolEntry*> CSymbols::m_Symbols;
int CSymbols::m_NextSymbolId;
CFile CSymbols::m_SymFileHandle;
char* CSymbols::m_SymFileBuffer;
size_t CSymbols::m_SymFileSize;
char CSymbols::m_ParserDelimeter;
char* CSymbols::m_ParserToken;
size_t CSymbols::m_ParserTokenLength;
bool CSymbols::m_bHaveFirstToken;
char* CSymbols::m_SymFileParseBuffer;
CRITICAL_SECTION CSymbols::m_CriticalSection = {0};
int CSymbols::GetTypeNumber(char* typeName)
CSymbolTable::CSymbolTable(CDebuggerUI* debugger) :
m_Debugger(debugger),
m_NextSymbolId(0),
m_SymFileBuffer(NULL),
m_SymFileSize(0),
m_ParserToken(NULL),
m_ParserTokenLength(0),
m_ParserDelimeter(0),
m_SymFileParseBuffer(NULL),
m_bHaveFirstToken(false),
m_TokPos(NULL)
{
const char* name;
for (int i = 0; (name = SymbolTypes[i]) != NULL; i++)
{
if (strcmp(typeName, name) == 0)
{
return i;
}
}
return -1;
}
const char* CSymbols::GetTypeName(int typeNumber)
CSymbolTable::~CSymbolTable()
{
if (typeNumber > 11)
{
return NULL;
}
return SymbolTypes[typeNumber];
if (m_SymFileBuffer != NULL)
{
free(m_SymFileBuffer);
}
if (m_SymFileParseBuffer != NULL)
{
free(m_SymFileParseBuffer);
}
}
symbol_type_info_t CSymbolTable::m_SymbolTypes[] = {
{ SYM_CODE, "code", 1 },
{ SYM_DATA, "data", 1 },
{ SYM_U8, "u8", 1 },
{ SYM_U16, "u16", 2 },
{ SYM_U32, "u32", 4 },
{ SYM_U64, "u64", 8 },
{ SYM_S8, "s8", 1 },
{ SYM_S16, "s16", 2 },
{ SYM_S32, "s32", 4 },
{ SYM_S64, "s64", 8 },
{ SYM_FLOAT, "float", 4 },
{ SYM_DOUBLE, "double", 8 },
{ SYM_INVALID, NULL, 0 }
};
symbol_type_id_t CSymbolTable::GetTypeId(char* typeName)
{
const char* name;
for (int i = 0; (name = m_SymbolTypes[i].name) != NULL; i++)
{
if (strcmp(typeName, name) == 0)
{
return (symbol_type_id_t)i;
}
}
return SYM_INVALID;
}
const char* CSymbolTable::GetTypeName(int typeId)
{
if (typeId >= NUM_SYM_TYPES)
{
return NULL;
}
return m_SymbolTypes[typeId].name;
}
int CSymbolTable::GetTypeSize(int typeId)
{
if (typeId >= NUM_SYM_TYPES)
{
return NULL;
}
return m_SymbolTypes[typeId].size;
}
// Open symbols file for game and parse into list
CPath CSymbols::GetSymFilePath()
CPath CSymbolTable::GetSymFilePath()
{
stdstr symFileName;
symFileName.Format("%s.sym", g_Settings->LoadStringVal(Game_GameName).c_str());
stdstr symFileName;
symFileName.Format("%s.sym", g_Settings->LoadStringVal(Game_GameName).c_str());
CPath symFilePath(g_Settings->LoadStringVal(Directory_NativeSave).c_str(), symFileName.c_str());
CPath symFilePath(g_Settings->LoadStringVal(Directory_NativeSave).c_str(), symFileName.c_str());
if (g_Settings->LoadBool(Setting_UniqueSaveDir))
{
symFilePath.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str());
}
symFilePath.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
if (!symFilePath.DirectoryExists())
{
symFilePath.DirectoryCreate();
}
if (g_Settings->LoadBool(Setting_UniqueSaveDir))
{
symFilePath.AppendDirectory(g_Settings->LoadStringVal(Game_UniqueSaveDir).c_str());
}
return symFilePath;
symFilePath.NormalizePath(CPath(CPath::MODULE_DIRECTORY));
if (!symFilePath.DirectoryExists())
{
symFilePath.DirectoryCreate();
}
return symFilePath;
}
void CSymbols::ParserInit()
void CSymbolTable::ParserInit()
{
m_SymFileParseBuffer = (char*)malloc(m_SymFileSize + 1);
strcpy(m_SymFileParseBuffer, m_SymFileBuffer);
m_bHaveFirstToken = false;
if (m_SymFileParseBuffer != NULL)
{
free(m_SymFileParseBuffer);
}
m_SymFileParseBuffer = (char*)malloc(m_SymFileSize + 1);
strcpy(m_SymFileParseBuffer, m_SymFileBuffer);
m_bHaveFirstToken = false;
}
void CSymbols::ParserDone()
void CSymbolTable::ParserDone()
{
free(m_SymFileParseBuffer);
free(m_SymFileParseBuffer);
}
void CSymbols::ParserFetchToken(const char* delim)
void CSymbolTable::ParserFetchToken(const char* delim)
{
if (!m_bHaveFirstToken)
{
m_ParserToken = strtok(m_SymFileParseBuffer, delim);
m_bHaveFirstToken = true;
}
else
{
m_ParserToken = strtok(NULL, delim);
}
if (m_ParserToken != NULL)
{
m_ParserTokenLength = strlen(m_ParserToken);
m_ParserDelimeter = m_SymFileBuffer[m_ParserToken - m_SymFileParseBuffer + m_ParserTokenLength];
}
else
{
m_ParserTokenLength = 0;
m_ParserDelimeter = '\0';
}
if (!m_bHaveFirstToken)
{
m_TokPos = NULL;
m_ParserToken = strtok_s(m_SymFileParseBuffer, delim, &m_TokPos);
m_bHaveFirstToken = true;
}
else
{
m_ParserToken = strtok_s(NULL, delim, &m_TokPos);
}
if (m_ParserToken != NULL)
{
m_ParserTokenLength = strlen(m_ParserToken);
m_ParserDelimeter = m_SymFileBuffer[m_ParserToken - m_SymFileParseBuffer + m_ParserTokenLength];
}
else
{
m_ParserTokenLength = 0;
m_ParserDelimeter = '\0';
}
}
void CSymbols::Load()
void CSymbolTable::Load()
{
m_NextSymbolId = 0;
Reset();
CGuard guard(m_CS);
if (g_Settings->LoadStringVal(Game_GameName).length() == 0)
{
MessageBox(NULL, "Game must be loaded", "Symbols", MB_ICONWARNING | MB_OK);
return;
}
CPath symFilePath = GetSymFilePath();
bool bOpened = m_SymFileHandle.Open(symFilePath, CFileBase::modeRead);
if (!bOpened)
{
return;
}
m_SymFileSize = m_SymFileHandle.GetLength();
m_SymFileBuffer = (char*)malloc(m_SymFileSize + 1);
m_SymFileHandle.Read(m_SymFileBuffer, m_SymFileSize);
m_SymFileHandle.Close();
m_SymFileBuffer[m_SymFileSize] = '\0';
ParseError errorCode = ERR_SUCCESS;
int lineNumber = 1;
m_NextSymbolId = 0;
m_Symbols.clear();
ParserInit();
if (g_Settings->LoadStringVal(Game_GameName).length() == 0)
{
MessageBox(NULL, "Game must be loaded", "Symbols", MB_ICONWARNING | MB_OK);
return;
}
CPath symFilePath = GetSymFilePath();
bool bOpened = m_SymFileHandle.Open(symFilePath, CFileBase::modeRead);
if (!bOpened)
{
return;
}
m_SymFileSize = m_SymFileHandle.GetLength();
m_SymFileBuffer = (char*)malloc(m_SymFileSize + 1);
m_SymFileHandle.Read(m_SymFileBuffer, m_SymFileSize);
m_SymFileHandle.Close();
m_SymFileBuffer[m_SymFileSize] = '\0';
symbol_parse_error_t errorCode = ERR_SUCCESS;
int lineNumber = 1;
while (true)
{
uint32_t address = 0;
int type = 0;
char* name = NULL;
char* description = NULL;
// Address
ParserFetchToken(",\n\0");
ParserInit();
if (m_ParserToken == NULL || m_ParserTokenLength == 0)
{
// Empty line @EOF
errorCode = ERR_SUCCESS;
break;
}
while (true)
{
uint32_t address = 0;
int type = 0;
char* name = NULL;
char* description = NULL;
// Address
ParserFetchToken(",\n\0");
char* endptr;
address = (uint32_t)strtoull(m_ParserToken, &endptr, 16);
if (endptr == m_ParserToken)
{
errorCode = ERR_INVALID_ADDR;
break;
}
// Type
if (m_ParserDelimeter != ',')
{
errorCode = ERR_MISSING_FIELDS;
break;
}
ParserFetchToken(",\n\0");
type = GetTypeNumber(m_ParserToken);
if (m_ParserToken == NULL || m_ParserTokenLength == 0)
{
// Empty line @EOF
errorCode = ERR_SUCCESS;
break;
}
if (type == -1)
{
errorCode = ERR_INVALID_TYPE;
break;
}
// Name
if (m_ParserDelimeter != ',')
{
errorCode = ERR_MISSING_FIELDS;
break;
}
char* endptr;
address = (uint32_t)strtoull(m_ParserToken, &endptr, 16);
if (endptr == m_ParserToken)
{
errorCode = ERR_INVALID_ADDR;
break;
}
// Type
if (m_ParserDelimeter != ',')
{
errorCode = ERR_MISSING_FIELDS;
break;
}
ParserFetchToken(",\n\0");
type = GetTypeId(m_ParserToken);
ParserFetchToken(",\n\0");
name = m_ParserToken;
if (type == -1)
{
errorCode = ERR_INVALID_TYPE;
break;
}
// Name
if (m_ParserDelimeter != ',')
{
errorCode = ERR_MISSING_FIELDS;
break;
}
// Optional description
if (m_ParserDelimeter == ',')
{
ParserFetchToken("\n\0");
description = m_ParserToken;
}
// Add symbol object to the vector
Add(type, address, name, description);
ParserFetchToken(",\n\0");
name = m_ParserToken;
if (m_ParserDelimeter == '\0')
{
errorCode = ERR_SUCCESS;
break;
}
// Optional description
if (m_ParserDelimeter == ',')
{
ParserFetchToken("\n\0");
description = m_ParserToken;
}
// Add symbol object to the vector
AddSymbol(type, address, name, description);
lineNumber++;
}
ParserDone();
free(m_SymFileBuffer);
if (m_ParserDelimeter == '\0')
{
errorCode = ERR_SUCCESS;
break;
}
switch (errorCode)
{
case ERR_SUCCESS:
break;
case ERR_INVALID_ADDR:
ParseErrorAlert("Invalid address", lineNumber);
break;
case ERR_INVALID_TYPE:
ParseErrorAlert("Invalid type", lineNumber);
break;
case ERR_INVALID_NAME:
ParseErrorAlert("Invalid name", lineNumber);
break;
case ERR_MISSING_FIELDS:
ParseErrorAlert("Missing required field(s)", lineNumber);
break;
}
lineNumber++;
}
ParserDone();
free(m_SymFileBuffer);
switch (errorCode)
{
case ERR_SUCCESS:
break;
case ERR_INVALID_ADDR:
ParseErrorAlert("Invalid address", lineNumber);
break;
case ERR_INVALID_TYPE:
ParseErrorAlert("Invalid type", lineNumber);
break;
case ERR_INVALID_NAME:
ParseErrorAlert("Invalid name", lineNumber);
break;
case ERR_MISSING_FIELDS:
ParseErrorAlert("Missing required field(s)", lineNumber);
break;
}
}
void CSymbols::Save()
void CSymbolTable::Save()
{
int nSymbols = m_Symbols.size();
char* symfile;
int symfile_size = 0;
int symfile_idx = 0;
CGuard guard(m_CS);
// Determine file size
for (int i = 0; i < nSymbols; i++)
{
CSymbolEntry* symbol = m_Symbols[i];
m_SymFileHandle.Open(GetSymFilePath(), CFileBase::modeCreate | CFileBase::modeReadWrite);
m_SymFileHandle.SeekToBegin();
symfile_size += 11; // address 8, required commas 2, newline 1
symfile_size += strlen(symbol->m_Name);
symfile_size += strlen(symbol->TypeName());
for (size_t i = 0; i < m_Symbols.size(); i++)
{
CSymbol& symbol = m_Symbols[i];
stdstr strLine = stdstr_f("%08X,%s,%s", symbol.m_Address, symbol.TypeName(), symbol.m_Name);
if (symbol.m_Description != NULL)
{
strLine += stdstr_f(",%s", symbol.m_Description);
}
if (symbol->m_Description != NULL && strlen(symbol->m_Description) != 0)
{
symfile_size += 1; // comma
symfile_size += strlen(symbol->m_Description);
}
}
strLine += "\n";
m_SymFileHandle.Write(strLine.c_str(), strLine.length());
}
if (symfile_size == 0)
{
return;
}
symfile = (char*) malloc(symfile_size + 1);
symfile[symfile_size] = '\0';
// Write out
for (int i = 0; i < nSymbols; i++)
{
CSymbolEntry* symbol = m_Symbols[i];
symfile_idx += sprintf(&symfile[symfile_idx], "%08X,%s,%s", symbol->m_Address, symbol->TypeName(), symbol->m_Name);
if (symbol->m_Description != NULL)
{
symfile_idx += sprintf(&symfile[symfile_idx], ",%s", symbol->m_Description);
}
symfile_idx += sprintf(&symfile[symfile_idx], "\n");
}
m_SymFileHandle.Open(GetSymFilePath(), CFileBase::modeCreate | CFileBase::modeReadWrite);
m_SymFileHandle.SeekToBegin();
m_SymFileHandle.Write(symfile, symfile_size);
m_SymFileHandle.SetEndOfFile();
m_SymFileHandle.Close();
free(symfile);
m_SymFileHandle.SetEndOfFile();
m_SymFileHandle.Close();
}
void CSymbols::GetValueString(char* dest, CSymbolEntry* lpSymbol)
void CSymbolTable::GetValueString(char* dst, CSymbol* symbol)
{
uint8_t v8;
uint16_t v16;
uint32_t v32;
uint64_t v64;
float vf;
double vd;
union
{
uint8_t u8;
int8_t s8;
uint16_t u16;
int16_t s16;
uint32_t u32;
int32_t s32;
uint64_t u64;
int64_t s64;
float f32;
double f64;
} value;
uint32_t address = lpSymbol->m_Address;
uint32_t address = symbol->m_Address;
switch (lpSymbol->m_Type)
{
case TYPE_CODE:
case TYPE_DATA:
sprintf(dest, "");
break;
case TYPE_U8:
g_MMU->LB_VAddr(address, v8);
sprintf(dest, "%u", v8);
break;
case TYPE_U16:
g_MMU->LH_VAddr(address, v16);
sprintf(dest, "%u", v16);
break;
case TYPE_U32:
g_MMU->LW_VAddr(address, v32);
sprintf(dest, "%u", v32);
break;
case TYPE_U64:
g_MMU->LD_VAddr(address, v64);
sprintf(dest, "%I64u", v64);
break;
case TYPE_S8:
g_MMU->LB_VAddr(address, v8);
sprintf(dest, "%ihh", v8);
break;
case TYPE_S16:
g_MMU->LH_VAddr(address, v16);
sprintf(dest, "%i", v16);
break;
case TYPE_S32:
g_MMU->LW_VAddr(address, v32);
sprintf(dest, "%i", v32);
break;
case TYPE_S64:
g_MMU->LD_VAddr(address, v64);
sprintf(dest, "%I64i", v64);
break;
case TYPE_FLOAT:
g_MMU->LW_VAddr(address, *(uint32_t*)&vf);
sprintf(dest, "%f", vf);
break;
case TYPE_DOUBLE:
g_MMU->LD_VAddr(address, *(uint64_t*)&vd);
sprintf(dest, "%f", vd);
break;
default:
MessageBox(NULL, "unkown type", "", MB_OK);
break;
}
switch (symbol->m_Type)
{
case SYM_CODE:
case SYM_DATA:
sprintf(dst, "");
break;
case SYM_U8:
m_Debugger->DebugLoad_VAddr(address, value.u8);
sprintf(dst, "%u", value.u8);
break;
case SYM_U16:
m_Debugger->DebugLoad_VAddr(address, value.u16);
sprintf(dst, "%u", value.u16);
break;
case SYM_U32:
m_Debugger->DebugLoad_VAddr(address, value.u32);
sprintf(dst, "%u", value.u32);
break;
case SYM_U64:
m_Debugger->DebugLoad_VAddr(address, value.u64);
sprintf(dst, "%I64u", value.u64);
break;
case SYM_S8:
m_Debugger->DebugLoad_VAddr(address, value.s8);
sprintf(dst, "%ihh", value.s8);
break;
case SYM_S16:
m_Debugger->DebugLoad_VAddr(address, value.s16);
sprintf(dst, "%i", value.s16);
break;
case SYM_S32:
m_Debugger->DebugLoad_VAddr(address, value.s32);
sprintf(dst, "%i", value.s32);
break;
case SYM_S64:
m_Debugger->DebugLoad_VAddr(address, value.s64);
sprintf(dst, "%I64i", value.s64);
break;
case SYM_FLOAT:
m_Debugger->DebugLoad_VAddr(address, value.f32);
sprintf(dst, "%f", value.f32);
break;
case SYM_DOUBLE:
m_Debugger->DebugLoad_VAddr(address, value.f64);
sprintf(dst, "%f", value.f64);
break;
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
break;
}
}
void CSymbols::ParseErrorAlert(char* message, int lineNumber)
void CSymbolTable::ParseErrorAlert(char* message, int lineNumber)
{
stdstr messageFormatted = stdstr_f("%s\nLine %d", message, lineNumber);
MessageBox(NULL, messageFormatted.c_str(), "Parse error", MB_OK | MB_ICONWARNING);
stdstr messageFormatted = stdstr_f("%s\nLine %d", message, lineNumber);
MessageBox(NULL, messageFormatted.c_str(), "Parse error", MB_OK | MB_ICONWARNING);
}
void CSymbols::Reset()
void CSymbolTable::Reset()
{
for (int i = 0; i < GetCount(); i++)
{
delete m_Symbols[i];
}
m_Symbols.clear();
CGuard guard(m_CS);
m_Symbols.clear();
}
const char* CSymbols::GetNameByAddress(uint32_t address)
bool CSymbolTable::CmpSymbolAddresses(CSymbol& a, CSymbol& b)
{
uint32_t len = GetCount();
for (uint32_t i = 0; i < len; i++)
{
if (m_Symbols[i]->m_Address == address)
{
return m_Symbols[i]->m_Name;
}
}
return NULL;
return (a.m_Address < b.m_Address);
}
bool CSymbols::SortFunction(CSymbolEntry* a, CSymbolEntry* b)
void CSymbolTable::AddSymbol(int type, uint32_t address, char* name, char* description)
{
return (a->m_Address < b->m_Address);
CGuard guard(m_CS);
if (name == NULL || strlen(name) == 0)
{
return;
}
if (description == NULL || strlen(description) == 0)
{
description = NULL;
}
int id = m_NextSymbolId++;
CSymbol symbol = CSymbol(id, type, address, name, description);
m_Symbols.push_back(symbol);
sort(m_Symbols.begin(), m_Symbols.end(), CmpSymbolAddresses);
}
void CSymbols::Add(int type, uint32_t address, char* name, char* description)
int CSymbolTable::GetCount()
{
if (name == NULL || strlen(name) == 0)
{
return;
}
if (description == NULL || strlen(description) == 0)
{
description = NULL;
}
int id = m_NextSymbolId++;
CSymbolEntry* symbol = new CSymbolEntry(id, type, address, name, description);
m_Symbols.push_back(symbol);
sort(m_Symbols.begin(), m_Symbols.end(), SortFunction);
CGuard guard(m_CS);
return m_Symbols.size();
}
int CSymbols::GetCount()
bool CSymbolTable::GetSymbolByIndex(size_t index, CSymbol* symbol)
{
return m_Symbols.size();
CGuard guard(m_CS);
if (index < 0 || index >= m_Symbols.size())
{
return false;
}
*symbol = m_Symbols[index];
return true;
}
CSymbolEntry* CSymbols::GetEntryByIndex(int index)
bool CSymbolTable::GetSymbolByAddress(uint32_t address, CSymbol* symbol)
{
if (index < 0 || index >= GetCount())
{
return NULL;
}
return m_Symbols[index];
CGuard guard(m_CS);
for (size_t i = 0; i < m_Symbols.size(); i++)
{
if (m_Symbols[i].m_Address == address)
{
*symbol = m_Symbols[i];
return true;
}
}
return false;
}
CSymbolEntry* CSymbols::GetEntryByAddress(uint32_t address)
bool CSymbolTable::GetSymbolByOverlappedAddress(uint32_t address, CSymbol* symbol)
{
for (int i = 0; i < GetCount(); i++)
{
if (m_Symbols[i]->m_Address == address)
{
return m_Symbols[i];
}
}
return NULL;
CGuard guard(m_CS);
for (size_t i = 0; i < m_Symbols.size(); i++)
{
if (address >= m_Symbols[i].m_Address &&
address < m_Symbols[i].m_Address + m_Symbols[i].TypeSize())
{
*symbol = m_Symbols[i];
return true;
}
}
return false;
}
CSymbolEntry* CSymbols::GetEntryById(int id)
bool CSymbolTable::GetSymbolById(int id, CSymbol* symbol)
{
for (int i = 0; i < GetCount(); i++)
{
if (m_Symbols[i]->m_Id == id)
{
return m_Symbols[i];
}
}
return NULL;
CGuard guard(m_CS);
for (size_t i = 0; i < m_Symbols.size(); i++)
{
if (m_Symbols[i].m_Id == id)
{
*symbol = m_Symbols[i];
return true;
}
}
return false;
}
void CSymbols::RemoveEntryById(int id)
bool CSymbolTable::RemoveSymbolById(int id)
{
for (int i = 0; i < GetCount(); i++)
{
if (m_Symbols[i]->m_Id == id)
{
delete m_Symbols[i];
m_Symbols.erase(m_Symbols.begin() + i);
break;
}
}
CGuard guard(m_CS);
for (size_t i = 0; i < m_Symbols.size(); i++)
{
if (m_Symbols[i].m_Id == id)
{
m_Symbols.erase(m_Symbols.begin() + i);
return true;
}
}
return false;
}
void CSymbols::EnterCriticalSection()
{
::EnterCriticalSection(&m_CriticalSection);
}
void CSymbols::LeaveCriticalSection()
{
::LeaveCriticalSection(&m_CriticalSection);
}
void CSymbols::InitializeCriticalSection()
{
if (!m_bInitialized)
{
m_bInitialized = true;
::InitializeCriticalSection(&m_CriticalSection);
}
}
void CSymbols::DeleteCriticalSection()
{
if (m_bInitialized)
{
m_bInitialized = false;
::DeleteCriticalSection(&m_CriticalSection);
}
}

View File

@ -1,145 +1,175 @@
/****************************************************************************
* *
* Project64 - A Nintendo 64 emulator. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2012 Project64. All rights reserved. *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once
#include "stdafx.h"
class CSymbolEntry;
class CSymbol;
class CSymbols
typedef enum {
SYM_INVALID = -1,
SYM_CODE,
SYM_DATA,
SYM_U8,
SYM_U16,
SYM_U32,
SYM_U64,
SYM_S8,
SYM_S16,
SYM_S32,
SYM_S64,
SYM_FLOAT,
SYM_DOUBLE,
NUM_SYM_TYPES
} symbol_type_id_t;
typedef struct
{
symbol_type_id_t id;
const char* name;
int size;
} symbol_type_info_t;
typedef enum {
ERR_SUCCESS,
ERR_INVALID_TYPE,
ERR_INVALID_ADDR,
ERR_INVALID_NAME,
ERR_MISSING_FIELDS,
} symbol_parse_error_t;
class CSymbolTable
{
public:
typedef enum {
ERR_SUCCESS,
ERR_INVALID_TYPE,
ERR_INVALID_ADDR,
ERR_INVALID_NAME,
ERR_MISSING_FIELDS,
} ParseError;
typedef enum {
TYPE_CODE,
TYPE_DATA,
TYPE_U8,
TYPE_U16,
TYPE_U32,
TYPE_U64,
TYPE_S8,
TYPE_S16,
TYPE_S32,
TYPE_S64,
TYPE_FLOAT,
TYPE_DOUBLE
} DataType;
static constexpr char* SymbolTypes[] = {
"code", // 0
"data", // 1
"u8",
"u16",
"u32",
"u64",
"s8",
"s16",
"s32",
"s64",
"float",
"double",
NULL
};
static constexpr int TypeSizes[] = {
1, 1, // code data
1, 2, 4, 8, // u8 u16 u32 u64
1, 2, 4, 8, // s8 s16 s32 s64
4, 8 // float double
};
CSymbolTable(CDebuggerUI* debugger);
~CSymbolTable();
private:
static bool m_bInitialized;
static vector<CSymbolEntry*> m_Symbols;
static int m_NextSymbolId;
CSymbolTable();
CDebuggerUI* m_Debugger;
CriticalSection m_CS;
std::vector<CSymbol> m_Symbols;
int m_NextSymbolId;
static CFile m_SymFileHandle;
static char* m_SymFileBuffer;
static size_t m_SymFileSize;
CFile m_SymFileHandle;
char* m_SymFileBuffer;
size_t m_SymFileSize;
char* m_ParserToken;
size_t m_ParserTokenLength;
char* m_TokPos;
char m_ParserDelimeter;
char* m_SymFileParseBuffer;
bool m_bHaveFirstToken;
static CRITICAL_SECTION m_CriticalSection;
static char* m_ParserToken;
static size_t m_ParserTokenLength;
static char m_ParserDelimeter;
static char* m_SymFileParseBuffer;
static bool m_bHaveFirstToken;
static void ParserInit();
static void ParserDone();
static void ParserFetchToken(const char* delim);
static bool SortFunction(CSymbolEntry* a, CSymbolEntry* b);
void ParserInit();
void ParserDone();
void ParserFetchToken(const char* delim);
public:
static CPath GetSymFilePath();
static void Load();
static void Save();
static void ParseErrorAlert(char* message, int lineNumber);
static symbol_type_info_t m_SymbolTypes[];
static const char* GetTypeName(int typeId);
static int GetTypeSize(int typeId);
static symbol_type_id_t GetTypeId(char* typeName);
static bool CmpSymbolAddresses(CSymbol& a, CSymbol& b);
static void Add(int type, uint32_t address, char* name, char* description = NULL);
static void RemoveEntryById(int id);
void GetValueString(char* dst, CSymbol* symbol);
static void Reset();
CPath GetSymFilePath();
void Load();
void Save();
void ParseErrorAlert(char* message, int lineNumber);
static const char* GetTypeName(int typeNumber);
static int GetTypeNumber(char* typeName);
static void GetValueString(char* str, CSymbolEntry* lpSymbol);
static int GetCount();
static CSymbolEntry* GetEntryById(int id);
static CSymbolEntry* GetEntryByIndex(int id);
static CSymbolEntry* GetEntryByAddress(uint32_t address);
static const char* GetNameByAddress(uint32_t address);
static void InitializeCriticalSection();
static void DeleteCriticalSection();
static void EnterCriticalSection();
static void LeaveCriticalSection();
void AddSymbol(int type, uint32_t address, char* name, char* description = NULL);
void Reset();
int GetCount();
bool GetSymbolById(int id, CSymbol* symbol);
bool GetSymbolByIndex(size_t index, CSymbol* symbol);
bool GetSymbolByAddress(uint32_t address, CSymbol* symbol);
bool GetSymbolByOverlappedAddress(uint32_t address, CSymbol* symbol);
bool RemoveSymbolById(int id);
};
class CSymbolEntry {
class CSymbol {
public:
int m_Id;
int m_Type;
int m_Id;
int m_Type;
uint32_t m_Address;
char* m_Name;
char* m_Description;
char* m_Name;
char* m_Description;
CSymbolEntry(int id, int type, uint32_t address, char* name, char* description) :
CSymbol() :
m_Id(0),
m_Type(SYM_INVALID),
m_Address(0),
m_Name(NULL),
m_Description(NULL),
m_Description(NULL)
{
}
CSymbol(int id, int type, uint32_t address, char* name, char* description) :
m_Id(id),
m_Type(type),
m_Address(address)
m_Address(address),
m_Name(NULL),
m_Description(NULL)
{
if (name != NULL)
{
size_t nameLen = strlen(name);
m_Name = (char*)malloc(nameLen + 1);
strcpy(m_Name, name);
m_Name = _strdup(name);
}
if (description != NULL)
{
size_t descLen = strlen(description);
m_Description = (char*)malloc(descLen + 1);
strcpy(m_Description, description);
m_Description = _strdup(description);
}
}
~CSymbolEntry()
CSymbol(const CSymbol& symbol):
m_Id(symbol.m_Id),
m_Type(symbol.m_Type),
m_Address(symbol.m_Address),
m_Name(NULL),
m_Description(NULL)
{
m_Name = symbol.m_Name ? _strdup(symbol.m_Name) : NULL;
m_Description = symbol.m_Description ? _strdup(symbol.m_Description) : NULL;
}
CSymbol& operator= (const CSymbol& symbol)
{
if (m_Name != NULL)
{
free(m_Name);
}
if (m_Description != NULL)
{
free(m_Description);
}
m_Id = symbol.m_Id;
m_Type = symbol.m_Type;
m_Address = symbol.m_Address;
m_Name = symbol.m_Name ? _strdup(symbol.m_Name) : NULL;
m_Description = symbol.m_Description ? _strdup(symbol.m_Description) : NULL;
return *this;
}
~CSymbol()
{
if (m_Name != NULL)
{
free(m_Name);
}
if (m_Description != NULL)
{
free(m_Description);
@ -148,11 +178,11 @@ public:
const char* TypeName()
{
return CSymbols::SymbolTypes[m_Type];
return CSymbolTable::GetTypeName(m_Type);
}
int TypeSize()
{
return CSymbols::TypeSizes[m_Type];
return CSymbolTable::GetTypeSize(m_Type);
}
};

View File

@ -29,6 +29,7 @@ class CDebugExcBreakpoints;
class CCPULog;
class CDMALog;
class CSymbolTable;
class CBreakpoints;
class CScriptSystem;
@ -84,15 +85,13 @@ public:
CDebugScripts* ScriptConsole();
CDMALog* DMALog();
CCPULog* CPULog();
CSymbolTable* SymbolTable();
static void GameReset(CDebuggerUI * _this);
static void GameCpuRunningChanged(CDebuggerUI * _this);
static void GameNameChanged(CDebuggerUI * _this);
static void SteppingOpsChanged(CDebuggerUI * _this);
//bool DebugLW_PAddr(uint32_t vaddr, uint32_t& value);
//bool DebugLW_VAddr(uint32_t vaddr, uint32_t& value);
protected:
void TLBChanged(void);
void CPUStepStarted(void);
@ -104,7 +103,6 @@ private:
CDebuggerUI(const CDebuggerUI&); // Disable copy constructor
CDebuggerUI& operator=(const CDebuggerUI&); // Disable assignment
CRITICAL_SECTION m_CriticalSection;
CDumpMemory * m_MemoryDump;
CDebugMemoryView * m_MemoryView;
CDebugMemorySearch * m_MemorySearch;
@ -120,6 +118,7 @@ private:
CBreakpoints * m_Breakpoints;
CScriptSystem * m_ScriptSystem;
CSymbolTable * m_SymbolTable;
CDMALog * m_DMALog;
CCPULog * m_CPULog;

View File

@ -1048,13 +1048,17 @@ void CMainMenu::FillOutMenu(HMENU hMenu)
*******************/
//ID_DEBUGGER_LOGOPTIONS
Item.Reset(ID_DEBUGGER_BREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"R4300i &Commands...");
Item.SetItemEnabled(CPURunning);
Item.Reset(ID_DEBUGGER_BREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"&Commands...");
DebugR4300Menu.push_back(Item);
//Item.Reset(ID_DEBUGGER_R4300REGISTERS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"R4300i &Registers...");
//Item.SetItemEnabled(true);
// DebugR4300Menu.push_back(Item);
Item.Reset(ID_DEBUGGER_CPULOG, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Command Log...");
DebugR4300Menu.push_back(Item);
Item.Reset(ID_DEBUGGER_EXCBREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Exceptions...");
DebugR4300Menu.push_back(Item);
Item.Reset(ID_DEBUGGER_STACKVIEW, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Stack...");
DebugR4300Menu.push_back(Item);
Item.Reset(ID_DEBUGGER_STACKTRACE, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Stack Trace...");
DebugR4300Menu.push_back(Item);
Item.Reset(ID_DEBUG_DISABLE_GAMEFIX, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Disable Game Fixes");
if (g_Settings->LoadBool(Debugger_DisableGameFixes))
{
@ -1070,10 +1074,14 @@ void CMainMenu::FillOutMenu(HMENU hMenu)
DebugMemoryMenu.push_back(Item);
Item.Reset(ID_DEBUGGER_SEARCHMEMORY, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Search...");
DebugMemoryMenu.push_back(Item);
Item.Reset(ID_DEBUGGER_SYMBOLS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Symbols...");
DebugMemoryMenu.push_back(Item);
Item.Reset(ID_DEBUGGER_DUMPMEMORY, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Dump...");
DebugMemoryMenu.push_back(Item);
Item.Reset(ID_DEBUGGER_TLBENTRIES, EMPTY_STRING, EMPTY_STDSTR, NULL, L"TLB Entries...");
DebugMemoryMenu.push_back(Item);
Item.Reset(ID_DEBUGGER_DMALOG, EMPTY_STRING, EMPTY_STDSTR, NULL, L"DMA Log...");
DebugMemoryMenu.push_back(Item);
/* Debug - App logging
*******************/
@ -1166,52 +1174,25 @@ void CMainMenu::FillOutMenu(HMENU hMenu)
/* Debugger Main Menu
****************/
Item.Reset(ID_DEBUGGER_BREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Breakpoint...");
//Item.SetItemEnabled(CPURunning);
Item.Reset(ID_DEBUGGER_BREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Commands...");
DebugMenu.push_back(Item);
/* Debug - Exception breakpoints
*******************/
Item.Reset(ID_DEBUGGER_EXCBREAKPOINTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"CPU Exception Breakpoints...");
//Item.SetItemEnabled(CPURunning);
Item.Reset(ID_DEBUGGER_MEMORY, EMPTY_STRING, EMPTY_STDSTR, NULL, L"View Memory...");
DebugMenu.push_back(Item);
/* Debugger - Symbols
****************/
Item.Reset(ID_DEBUGGER_SYMBOLS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Symbols...");
//Item.SetItemEnabled(CPURunning);
DebugMenu.push_back(Item);
/* Debug - Scripts
*******************/
Item.Reset(ID_DEBUGGER_SCRIPTS, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Scripts...");
//Item.SetItemEnabled(CPURunning);
DebugMenu.push_back(Item);
/* Debug - DMA Log
*******************/
Item.Reset(ID_DEBUGGER_DMALOG, EMPTY_STRING, EMPTY_STDSTR, NULL, L"DMA Log...");
//Item.SetItemEnabled(CPURunning);
DebugMenu.push_back(Item);
/* Debug - CPU Log
*******************/
Item.Reset(ID_DEBUGGER_CPULOG, EMPTY_STRING, EMPTY_STDSTR, NULL, L"CPU Log...");
//Item.SetItemEnabled(CPURunning);
DebugMenu.push_back(Item);
/* Debug - Stack
*******************/
Item.Reset(ID_DEBUGGER_STACKVIEW, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Stack...");
DebugMenu.push_back(Item);
/* Debug - Stack Trace
*******************/
Item.Reset(ID_DEBUGGER_STACKTRACE, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Stack Trace...");
DebugMenu.push_back(Item);
DebugMenu.push_back(MENU_ITEM(SPLITER));
/* Debug - Memory
*******************/
Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugMemoryMenu, L"Memory");
DebugMenu.push_back(Item);
/* Debug - R4300i
*******************/
Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugR4300Menu, L"&R4300i");
DebugMenu.push_back(Item);
/* Debug - RSP
*******************/
if (g_Plugins && g_Plugins->RSP() != NULL && IsMenu((HMENU)g_Plugins->RSP()->GetDebugMenu()))
@ -1249,10 +1230,6 @@ void CMainMenu::FillOutMenu(HMENU hMenu)
}
DebugNotificationMenu.push_back(Item);
Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugR4300Menu, L"&R4300i");
DebugMenu.push_back(Item);
Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugMemoryMenu, L"Memory");
DebugMenu.push_back(Item);
DebugMenu.push_back(MENU_ITEM(SPLITER));
Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugProfileMenu, L"Profile");
DebugMenu.push_back(Item);

View File

@ -909,7 +909,7 @@ STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | W
CAPTION "Symbols"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "",IDC_SYMBOLS_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_TABSTOP,0,0,313,123
CONTROL "",IDC_SYMBOLS_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_ALIGNLEFT | WS_TABSTOP,0,0,313,123
PUSHBUTTON "+",IDC_ADDSYMBOL_BTN,284,125,24,12
PUSHBUTTON "-",IDC_REMOVESYMBOL_BTN,259,125,24,12
EDITTEXT IDC_FILTER_EDIT,29,125,150,12,ES_AUTOHSCROLL | WS_DISABLED
@ -1076,13 +1076,13 @@ BEGIN
END
IDD_Debugger_RegSI DIALOGEX 0, 0, 190, 210
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU
STYLE DS_SETFONT | WS_CHILD | WS_SYSMENU
FONT 9, "Lucida Console", 400, 0, 0x1
BEGIN
LTEXT "00 SI_DRAM_ADDR_REG",-1,3,29,94,8
LTEXT "04 SI_PIF_ADDR_RD64B_REG",-1,3,39,98,8
LTEXT "08 SI_PIF_ADDR_WR64B_REG",-1,3,50,100,8
LTEXT "0C SI_STATUS_REG",-1,3,61,94,8
LTEXT "10 SI_PIF_ADDR_WR64B_REG",-1,3,50,100,8
LTEXT "18 SI_STATUS_REG",-1,3,61,94,8
EDITTEXT IDC_SI00_EDIT,107,28,39,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT
EDITTEXT IDC_SI04_EDIT,107,39,39,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT
EDITTEXT IDC_SI08_EDIT,107,50,39,10,ES_UPPERCASE | ES_AUTOHSCROLL,WS_EX_RIGHT