Core: move CInterpreterCPU into R4300iOp
This commit is contained in:
parent
d4dbc5a3f4
commit
d3edbf6dda
|
@ -1,294 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
#include "InterpreterCPU.h"
|
||||
|
||||
#include <Project64-core/Debugger.h>
|
||||
#include <Project64-core/ExceptionHandler.h>
|
||||
#include <Project64-core/N64System/Mips/MemoryVirtualMem.h>
|
||||
#include <Project64-core/N64System/Mips/R4300iInstruction.h>
|
||||
#include <Project64-core/N64System/N64System.h>
|
||||
#include <Project64-core/N64System/SystemGlobals.h>
|
||||
#include <Project64-core/Plugins/GFXPlugin.h>
|
||||
#include <Project64-core/Plugins/Plugin.h>
|
||||
|
||||
R4300iOp::Func * CInterpreterCPU::m_R4300i_Opcode = nullptr;
|
||||
|
||||
void ExecuteInterpreterOps(uint32_t /*Cycles*/)
|
||||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
void CInterpreterCPU::BuildCPU()
|
||||
{
|
||||
R4300iOp::m_TestTimer = false;
|
||||
m_R4300i_Opcode = R4300iOp::BuildInterpreter();
|
||||
}
|
||||
|
||||
void CInterpreterCPU::InPermLoop()
|
||||
{
|
||||
if (EndOnPermLoop() &&
|
||||
((g_Reg->STATUS_REGISTER.InterruptEnable) == 0 ||
|
||||
(g_Reg->STATUS_REGISTER.ExceptionLevel) != 0 ||
|
||||
(g_Reg->STATUS_REGISTER.ErrorLevel) != 0 ||
|
||||
(g_Reg->STATUS_REGISTER.InterruptMask) == 0))
|
||||
{
|
||||
if (g_Plugins->Gfx()->UpdateScreen != nullptr)
|
||||
{
|
||||
g_Plugins->Gfx()->UpdateScreen();
|
||||
}
|
||||
g_Notify->DisplayError(GS(MSG_PERM_LOOP));
|
||||
g_System->CloseCpu();
|
||||
}
|
||||
else if (*g_NextTimer > 0)
|
||||
{
|
||||
g_SystemTimer->UpdateTimers();
|
||||
*g_NextTimer = 0 - g_System->CountPerOp();
|
||||
g_SystemTimer->UpdateTimers();
|
||||
}
|
||||
}
|
||||
|
||||
void CInterpreterCPU::ExecuteCPU()
|
||||
{
|
||||
WriteTrace(TraceN64System, TraceDebug, "Start");
|
||||
|
||||
bool & Done = g_System->m_EndEmulation;
|
||||
PIPELINE_STAGE & PipelineStage = g_System->m_PipelineStage;
|
||||
uint32_t & PROGRAM_COUNTER = *_PROGRAM_COUNTER;
|
||||
R4300iOpcode & Opcode = R4300iOp::m_Opcode;
|
||||
uint32_t & JumpToLocation = g_System->m_JumpToLocation;
|
||||
uint32_t & JumpDelayLocation = g_System->m_JumpDelayLocation;
|
||||
bool & TestTimer = R4300iOp::m_TestTimer;
|
||||
const int32_t & bDoSomething = g_SystemEvents->DoSomething();
|
||||
uint32_t CountPerOp = g_System->CountPerOp();
|
||||
int32_t & NextTimer = *g_NextTimer;
|
||||
bool CheckTimer = false;
|
||||
|
||||
__except_try()
|
||||
{
|
||||
while (!Done)
|
||||
{
|
||||
if (!g_MMU->MemoryValue32(PROGRAM_COUNTER, Opcode.Value))
|
||||
{
|
||||
g_Reg->TriggerAddressException(PROGRAM_COUNTER, EXC_RMISS);
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (HaveDebugger())
|
||||
{
|
||||
if (HaveExecutionBP() && g_Debugger->ExecutionBP(PROGRAM_COUNTER))
|
||||
{
|
||||
g_Settings->SaveBool(Debugger_SteppingOps, true);
|
||||
}
|
||||
|
||||
g_Debugger->CPUStepStarted(); // May set stepping ops/skip op
|
||||
|
||||
if (isStepping())
|
||||
{
|
||||
g_Debugger->WaitForStep();
|
||||
}
|
||||
|
||||
if (SkipOp())
|
||||
{
|
||||
// Skip command if instructed by the debugger
|
||||
g_Settings->SaveBool(Debugger_SkipOp, false);
|
||||
PROGRAM_COUNTER += 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
g_Debugger->CPUStep();
|
||||
}
|
||||
|
||||
/* if (PROGRAM_COUNTER > 0x80000300 && PROGRAM_COUNTER < 0x80380000)
|
||||
{
|
||||
WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s",*_PROGRAM_COUNTER,R4300iInstruction(*_PROGRAM_COUNTER, Opcode.Value).NameAndParam().c_str());
|
||||
// WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s t9: %08X v1: %08X",*_PROGRAM_COUNTER,R4300iInstruction(*_PROGRAM_COUNTER, Opcode.Value).NameAndParam().c_str(),_GPR[0x19].UW[0],_GPR[0x03].UW[0]);
|
||||
// WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %d %d",*_PROGRAM_COUNTER,*g_NextTimer,g_SystemTimer->CurrentType());
|
||||
} */
|
||||
|
||||
m_R4300i_Opcode[Opcode.op]();
|
||||
_GPR[0].DW = 0; // MIPS $zero hard-wired to 0
|
||||
NextTimer -= CountPerOp;
|
||||
|
||||
if (CDebugSettings::HaveDebugger())
|
||||
{
|
||||
g_Debugger->CPUStepEnded();
|
||||
}
|
||||
|
||||
PROGRAM_COUNTER += 4;
|
||||
switch (PipelineStage)
|
||||
{
|
||||
case PIPELINE_STAGE_NORMAL:
|
||||
break;
|
||||
case PIPELINE_STAGE_DELAY_SLOT:
|
||||
PipelineStage = PIPELINE_STAGE_JUMP;
|
||||
break;
|
||||
case PIPELINE_STAGE_PERMLOOP_DO_DELAY:
|
||||
PipelineStage = PIPELINE_STAGE_PERMLOOP_DELAY_DONE;
|
||||
break;
|
||||
case PIPELINE_STAGE_JUMP:
|
||||
CheckTimer = (JumpToLocation < PROGRAM_COUNTER - 4 || TestTimer);
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
if ((PROGRAM_COUNTER & 0x3) != 0)
|
||||
{
|
||||
g_Reg->DoAddressError((int32_t)JumpToLocation, true);
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
}
|
||||
else if (CheckTimer)
|
||||
{
|
||||
TestTimer = false;
|
||||
if (NextTimer < 0)
|
||||
{
|
||||
g_SystemTimer->TimerDone();
|
||||
}
|
||||
if (bDoSomething)
|
||||
{
|
||||
g_SystemEvents->ExecuteEvents();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPELINE_STAGE_JUMP_DELAY_SLOT:
|
||||
PipelineStage = PIPELINE_STAGE_JUMP;
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
JumpToLocation = JumpDelayLocation;
|
||||
break;
|
||||
case PIPELINE_STAGE_PERMLOOP_DELAY_DONE:
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
CInterpreterCPU::InPermLoop();
|
||||
g_SystemTimer->TimerDone();
|
||||
if (bDoSomething)
|
||||
{
|
||||
g_SystemEvents->ExecuteEvents();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
__except_catch()
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_UNKNOWN_MEM_ACTION));
|
||||
}
|
||||
WriteTrace(TraceN64System, TraceDebug, "Done");
|
||||
}
|
||||
|
||||
void CInterpreterCPU::ExecuteOps(int32_t Cycles)
|
||||
{
|
||||
bool & Done = g_System->m_EndEmulation;
|
||||
uint32_t & PROGRAM_COUNTER = *_PROGRAM_COUNTER;
|
||||
R4300iOpcode & Opcode = R4300iOp::m_Opcode;
|
||||
PIPELINE_STAGE & PipelineStage = g_System->m_PipelineStage;
|
||||
uint32_t & JumpDelayLocation = g_System->m_JumpDelayLocation;
|
||||
uint32_t & JumpToLocation = g_System->m_JumpToLocation;
|
||||
bool & TestTimer = R4300iOp::m_TestTimer;
|
||||
const int32_t & DoSomething = g_SystemEvents->DoSomething();
|
||||
uint32_t CountPerOp = g_System->CountPerOp();
|
||||
bool CheckTimer = false;
|
||||
|
||||
__except_try()
|
||||
{
|
||||
while (!Done)
|
||||
{
|
||||
if (Cycles <= 0)
|
||||
{
|
||||
g_SystemTimer->UpdateTimers();
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_MMU->MemoryValue32(PROGRAM_COUNTER, Opcode.Value))
|
||||
{
|
||||
/*if (PROGRAM_COUNTER > 0x80000300 && PROGRAM_COUNTER< 0x80380000)
|
||||
{
|
||||
WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s",*_PROGRAM_COUNTER,R4300iInstruction(*_PROGRAM_COUNTER, Opcode.Value).NameAndParam().c_str());
|
||||
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s t9: %08X v1: %08X",*_PROGRAM_COUNTER,R4300iInstruction(*_PROGRAM_COUNTER, Opcode.Value).NameAndParam().c_str(),_GPR[0x19].UW[0],_GPR[0x03].UW[0]);
|
||||
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %d %d",*_PROGRAM_COUNTER,*g_NextTimer,g_SystemTimer->CurrentType());
|
||||
}*/
|
||||
/*if (PROGRAM_COUNTER > 0x80323000 && PROGRAM_COUNTER< 0x80380000)
|
||||
{
|
||||
WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s",*_PROGRAM_COUNTER,R4300iInstruction(*_PROGRAM_COUNTER, Opcode.Value).NameAndParam().c_str());
|
||||
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s t9: %08X v1: %08X",*_PROGRAM_COUNTER,R4300iInstruction(*_PROGRAM_COUNTER, Opcode.Value).NameAndParam().c_str(),_GPR[0x19].UW[0],_GPR[0x03].UW[0]);
|
||||
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %d %d",*_PROGRAM_COUNTER,*g_NextTimer,g_SystemTimer->CurrentType());
|
||||
}*/
|
||||
m_R4300i_Opcode[Opcode.op]();
|
||||
_GPR[0].DW = 0; /* MIPS $zero hard-wired to 0 */
|
||||
|
||||
Cycles -= CountPerOp;
|
||||
*g_NextTimer -= CountPerOp;
|
||||
|
||||
/*static uint32_t TestAddress = 0x80077B0C, TestValue = 0, CurrentValue = 0;
|
||||
if (g_MMU->MemoryValue32(TestAddress, TestValue))
|
||||
{
|
||||
if (TestValue != CurrentValue)
|
||||
{
|
||||
WriteTraceF(TraceError,"%X: %X changed (%s)",PROGRAM_COUNTER,TestAddress,R4300iInstruction(PROGRAM_COUNTER, m_Opcode.Value).NameAndParam().c_str());
|
||||
CurrentValue = TestValue;
|
||||
}
|
||||
}*/
|
||||
|
||||
switch (PipelineStage)
|
||||
{
|
||||
case PIPELINE_STAGE_NORMAL:
|
||||
PROGRAM_COUNTER += 4;
|
||||
break;
|
||||
case PIPELINE_STAGE_DELAY_SLOT:
|
||||
PipelineStage = PIPELINE_STAGE_JUMP;
|
||||
PROGRAM_COUNTER += 4;
|
||||
break;
|
||||
case PIPELINE_STAGE_PERMLOOP_DO_DELAY:
|
||||
PipelineStage = PIPELINE_STAGE_PERMLOOP_DELAY_DONE;
|
||||
PROGRAM_COUNTER += 4;
|
||||
break;
|
||||
case PIPELINE_STAGE_JUMP:
|
||||
CheckTimer = (JumpToLocation < PROGRAM_COUNTER || TestTimer);
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
if (CheckTimer)
|
||||
{
|
||||
TestTimer = false;
|
||||
if (*g_NextTimer < 0)
|
||||
{
|
||||
g_SystemTimer->TimerDone();
|
||||
}
|
||||
if (DoSomething)
|
||||
{
|
||||
g_SystemEvents->ExecuteEvents();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPELINE_STAGE_JUMP_DELAY_SLOT:
|
||||
PipelineStage = PIPELINE_STAGE_JUMP;
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
JumpToLocation = JumpDelayLocation;
|
||||
break;
|
||||
case PIPELINE_STAGE_PERMLOOP_DELAY_DONE:
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
CInterpreterCPU::InPermLoop();
|
||||
g_SystemTimer->TimerDone();
|
||||
if (DoSomething)
|
||||
{
|
||||
g_SystemEvents->ExecuteEvents();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_Reg->TriggerAddressException(PROGRAM_COUNTER, EXC_RMISS);
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
__except_catch()
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_UNKNOWN_MEM_ACTION));
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <Project64-core/N64System/Interpreter/InterpreterOps.h>
|
||||
|
||||
class CInterpreterCPU :
|
||||
private R4300iOp
|
||||
{
|
||||
public:
|
||||
static void BuildCPU();
|
||||
static void ExecuteCPU();
|
||||
static void ExecuteOps(int32_t Cycles);
|
||||
static void InPermLoop();
|
||||
|
||||
private:
|
||||
CInterpreterCPU();
|
||||
CInterpreterCPU(const CInterpreterCPU &);
|
||||
CInterpreterCPU & operator=(const CInterpreterCPU &);
|
||||
|
||||
static R4300iOp::Func * m_R4300i_Opcode;
|
||||
};
|
|
@ -1,8 +1,8 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
#include <Project64-core/Debugger.h>
|
||||
#include <Project64-core/ExceptionHandler.h>
|
||||
#include <Project64-core/Logging.h>
|
||||
#include <Project64-core/N64System/Interpreter/InterpreterCPU.h>
|
||||
#include <Project64-core/N64System/Interpreter/InterpreterOps.h>
|
||||
#include <Project64-core/N64System/Mips/MemoryVirtualMem.h>
|
||||
#include <Project64-core/N64System/Mips/R4300iInstruction.h>
|
||||
|
@ -15,6 +15,7 @@
|
|||
#include <math.h>
|
||||
|
||||
bool R4300iOp::m_TestTimer = false;
|
||||
R4300iOp::Func * R4300iOp::m_R4300i_Opcode = nullptr;
|
||||
R4300iOpcode R4300iOp::m_Opcode;
|
||||
|
||||
R4300iOp::Func R4300iOp::Jump_Opcode[64];
|
||||
|
@ -40,6 +41,281 @@ const int32_t R4300iOp::SWR_SHIFT[4] = {24, 16, 8, 0};
|
|||
const int32_t R4300iOp::LWL_SHIFT[4] = {0, 8, 16, 24};
|
||||
const int32_t R4300iOp::LWR_SHIFT[4] = {24, 16, 8, 0};
|
||||
|
||||
void R4300iOp::BuildCPU()
|
||||
{
|
||||
R4300iOp::m_TestTimer = false;
|
||||
m_R4300i_Opcode = R4300iOp::BuildInterpreter();
|
||||
}
|
||||
|
||||
void R4300iOp::InPermLoop()
|
||||
{
|
||||
if (EndOnPermLoop() &&
|
||||
((g_Reg->STATUS_REGISTER.InterruptEnable) == 0 ||
|
||||
(g_Reg->STATUS_REGISTER.ExceptionLevel) != 0 ||
|
||||
(g_Reg->STATUS_REGISTER.ErrorLevel) != 0 ||
|
||||
(g_Reg->STATUS_REGISTER.InterruptMask) == 0))
|
||||
{
|
||||
if (g_Plugins->Gfx()->UpdateScreen != nullptr)
|
||||
{
|
||||
g_Plugins->Gfx()->UpdateScreen();
|
||||
}
|
||||
g_Notify->DisplayError(GS(MSG_PERM_LOOP));
|
||||
g_System->CloseCpu();
|
||||
}
|
||||
else if (*g_NextTimer > 0)
|
||||
{
|
||||
g_SystemTimer->UpdateTimers();
|
||||
*g_NextTimer = 0 - g_System->CountPerOp();
|
||||
g_SystemTimer->UpdateTimers();
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp::ExecuteCPU()
|
||||
{
|
||||
WriteTrace(TraceN64System, TraceDebug, "Start");
|
||||
|
||||
bool & Done = g_System->m_EndEmulation;
|
||||
PIPELINE_STAGE & PipelineStage = g_System->m_PipelineStage;
|
||||
uint32_t & PROGRAM_COUNTER = *_PROGRAM_COUNTER;
|
||||
R4300iOpcode & Opcode = R4300iOp::m_Opcode;
|
||||
uint32_t & JumpToLocation = g_System->m_JumpToLocation;
|
||||
uint32_t & JumpDelayLocation = g_System->m_JumpDelayLocation;
|
||||
bool & TestTimer = R4300iOp::m_TestTimer;
|
||||
const int32_t & bDoSomething = g_SystemEvents->DoSomething();
|
||||
uint32_t CountPerOp = g_System->CountPerOp();
|
||||
int32_t & NextTimer = *g_NextTimer;
|
||||
bool CheckTimer = false;
|
||||
|
||||
__except_try()
|
||||
{
|
||||
while (!Done)
|
||||
{
|
||||
if (!g_MMU->MemoryValue32(PROGRAM_COUNTER, Opcode.Value))
|
||||
{
|
||||
g_Reg->TriggerAddressException(PROGRAM_COUNTER, EXC_RMISS);
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (HaveDebugger())
|
||||
{
|
||||
if (HaveExecutionBP() && g_Debugger->ExecutionBP(PROGRAM_COUNTER))
|
||||
{
|
||||
g_Settings->SaveBool(Debugger_SteppingOps, true);
|
||||
}
|
||||
|
||||
g_Debugger->CPUStepStarted(); // May set stepping ops/skip op
|
||||
|
||||
if (isStepping())
|
||||
{
|
||||
g_Debugger->WaitForStep();
|
||||
}
|
||||
|
||||
if (SkipOp())
|
||||
{
|
||||
// Skip command if instructed by the debugger
|
||||
g_Settings->SaveBool(Debugger_SkipOp, false);
|
||||
PROGRAM_COUNTER += 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
g_Debugger->CPUStep();
|
||||
}
|
||||
|
||||
/* if (PROGRAM_COUNTER > 0x80000300 && PROGRAM_COUNTER < 0x80380000)
|
||||
{
|
||||
WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s",*_PROGRAM_COUNTER,R4300iInstruction(*_PROGRAM_COUNTER, Opcode.Value).NameAndParam().c_str());
|
||||
// WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s t9: %08X v1: %08X",*_PROGRAM_COUNTER,R4300iInstruction(*_PROGRAM_COUNTER, Opcode.Value).NameAndParam().c_str(),_GPR[0x19].UW[0],_GPR[0x03].UW[0]);
|
||||
// WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %d %d",*_PROGRAM_COUNTER,*g_NextTimer,g_SystemTimer->CurrentType());
|
||||
} */
|
||||
|
||||
m_R4300i_Opcode[Opcode.op]();
|
||||
_GPR[0].DW = 0; // MIPS $zero hard-wired to 0
|
||||
NextTimer -= CountPerOp;
|
||||
|
||||
if (CDebugSettings::HaveDebugger())
|
||||
{
|
||||
g_Debugger->CPUStepEnded();
|
||||
}
|
||||
|
||||
PROGRAM_COUNTER += 4;
|
||||
switch (PipelineStage)
|
||||
{
|
||||
case PIPELINE_STAGE_NORMAL:
|
||||
break;
|
||||
case PIPELINE_STAGE_DELAY_SLOT:
|
||||
PipelineStage = PIPELINE_STAGE_JUMP;
|
||||
break;
|
||||
case PIPELINE_STAGE_PERMLOOP_DO_DELAY:
|
||||
PipelineStage = PIPELINE_STAGE_PERMLOOP_DELAY_DONE;
|
||||
break;
|
||||
case PIPELINE_STAGE_JUMP:
|
||||
CheckTimer = (JumpToLocation < PROGRAM_COUNTER - 4 || TestTimer);
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
if ((PROGRAM_COUNTER & 0x3) != 0)
|
||||
{
|
||||
g_Reg->DoAddressError((int32_t)JumpToLocation, true);
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
}
|
||||
else if (CheckTimer)
|
||||
{
|
||||
TestTimer = false;
|
||||
if (NextTimer < 0)
|
||||
{
|
||||
g_SystemTimer->TimerDone();
|
||||
}
|
||||
if (bDoSomething)
|
||||
{
|
||||
g_SystemEvents->ExecuteEvents();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPELINE_STAGE_JUMP_DELAY_SLOT:
|
||||
PipelineStage = PIPELINE_STAGE_JUMP;
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
JumpToLocation = JumpDelayLocation;
|
||||
break;
|
||||
case PIPELINE_STAGE_PERMLOOP_DELAY_DONE:
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
InPermLoop();
|
||||
g_SystemTimer->TimerDone();
|
||||
if (bDoSomething)
|
||||
{
|
||||
g_SystemEvents->ExecuteEvents();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
__except_catch()
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_UNKNOWN_MEM_ACTION));
|
||||
}
|
||||
WriteTrace(TraceN64System, TraceDebug, "Done");
|
||||
}
|
||||
|
||||
void R4300iOp::ExecuteOps(int32_t Cycles)
|
||||
{
|
||||
bool & Done = g_System->m_EndEmulation;
|
||||
uint32_t & PROGRAM_COUNTER = *_PROGRAM_COUNTER;
|
||||
R4300iOpcode & Opcode = R4300iOp::m_Opcode;
|
||||
PIPELINE_STAGE & PipelineStage = g_System->m_PipelineStage;
|
||||
uint32_t & JumpDelayLocation = g_System->m_JumpDelayLocation;
|
||||
uint32_t & JumpToLocation = g_System->m_JumpToLocation;
|
||||
bool & TestTimer = R4300iOp::m_TestTimer;
|
||||
const int32_t & DoSomething = g_SystemEvents->DoSomething();
|
||||
uint32_t CountPerOp = g_System->CountPerOp();
|
||||
bool CheckTimer = false;
|
||||
|
||||
__except_try()
|
||||
{
|
||||
while (!Done)
|
||||
{
|
||||
if (Cycles <= 0)
|
||||
{
|
||||
g_SystemTimer->UpdateTimers();
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_MMU->MemoryValue32(PROGRAM_COUNTER, Opcode.Value))
|
||||
{
|
||||
/*if (PROGRAM_COUNTER > 0x80000300 && PROGRAM_COUNTER< 0x80380000)
|
||||
{
|
||||
WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s",*_PROGRAM_COUNTER,R4300iInstruction(*_PROGRAM_COUNTER, Opcode.Value).NameAndParam().c_str());
|
||||
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s t9: %08X v1: %08X",*_PROGRAM_COUNTER,R4300iInstruction(*_PROGRAM_COUNTER, Opcode.Value).NameAndParam().c_str(),_GPR[0x19].UW[0],_GPR[0x03].UW[0]);
|
||||
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %d %d",*_PROGRAM_COUNTER,*g_NextTimer,g_SystemTimer->CurrentType());
|
||||
}*/
|
||||
/*if (PROGRAM_COUNTER > 0x80323000 && PROGRAM_COUNTER< 0x80380000)
|
||||
{
|
||||
WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s",*_PROGRAM_COUNTER,R4300iInstruction(*_PROGRAM_COUNTER, Opcode.Value).NameAndParam().c_str());
|
||||
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s t9: %08X v1: %08X",*_PROGRAM_COUNTER,R4300iInstruction(*_PROGRAM_COUNTER, Opcode.Value).NameAndParam().c_str(),_GPR[0x19].UW[0],_GPR[0x03].UW[0]);
|
||||
//WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %d %d",*_PROGRAM_COUNTER,*g_NextTimer,g_SystemTimer->CurrentType());
|
||||
}*/
|
||||
m_R4300i_Opcode[Opcode.op]();
|
||||
_GPR[0].DW = 0; /* MIPS $zero hard-wired to 0 */
|
||||
|
||||
Cycles -= CountPerOp;
|
||||
*g_NextTimer -= CountPerOp;
|
||||
|
||||
/*static uint32_t TestAddress = 0x80077B0C, TestValue = 0, CurrentValue = 0;
|
||||
if (g_MMU->MemoryValue32(TestAddress, TestValue))
|
||||
{
|
||||
if (TestValue != CurrentValue)
|
||||
{
|
||||
WriteTraceF(TraceError,"%X: %X changed (%s)",PROGRAM_COUNTER,TestAddress,R4300iInstruction(PROGRAM_COUNTER, m_Opcode.Value).NameAndParam().c_str());
|
||||
CurrentValue = TestValue;
|
||||
}
|
||||
}*/
|
||||
|
||||
switch (PipelineStage)
|
||||
{
|
||||
case PIPELINE_STAGE_NORMAL:
|
||||
PROGRAM_COUNTER += 4;
|
||||
break;
|
||||
case PIPELINE_STAGE_DELAY_SLOT:
|
||||
PipelineStage = PIPELINE_STAGE_JUMP;
|
||||
PROGRAM_COUNTER += 4;
|
||||
break;
|
||||
case PIPELINE_STAGE_PERMLOOP_DO_DELAY:
|
||||
PipelineStage = PIPELINE_STAGE_PERMLOOP_DELAY_DONE;
|
||||
PROGRAM_COUNTER += 4;
|
||||
break;
|
||||
case PIPELINE_STAGE_JUMP:
|
||||
CheckTimer = (JumpToLocation < PROGRAM_COUNTER || TestTimer);
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
if (CheckTimer)
|
||||
{
|
||||
TestTimer = false;
|
||||
if (*g_NextTimer < 0)
|
||||
{
|
||||
g_SystemTimer->TimerDone();
|
||||
}
|
||||
if (DoSomething)
|
||||
{
|
||||
g_SystemEvents->ExecuteEvents();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPELINE_STAGE_JUMP_DELAY_SLOT:
|
||||
PipelineStage = PIPELINE_STAGE_JUMP;
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
JumpToLocation = JumpDelayLocation;
|
||||
break;
|
||||
case PIPELINE_STAGE_PERMLOOP_DELAY_DONE:
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
InPermLoop();
|
||||
g_SystemTimer->TimerDone();
|
||||
if (DoSomething)
|
||||
{
|
||||
g_SystemEvents->ExecuteEvents();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_Reg->TriggerAddressException(PROGRAM_COUNTER, EXC_RMISS);
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
__except_catch()
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_UNKNOWN_MEM_ACTION));
|
||||
}
|
||||
}
|
||||
|
||||
void R4300iOp::SPECIAL()
|
||||
{
|
||||
Jump_Special[m_Opcode.funct]();
|
||||
|
|
|
@ -14,6 +14,11 @@ class R4300iOp :
|
|||
friend CX86RecompilerOps;
|
||||
|
||||
public:
|
||||
static void BuildCPU();
|
||||
static void ExecuteCPU();
|
||||
static void ExecuteOps(int32_t Cycles);
|
||||
static void InPermLoop();
|
||||
|
||||
typedef void (*Func)();
|
||||
|
||||
// Opcode functions
|
||||
|
@ -274,4 +279,5 @@ protected:
|
|||
|
||||
static const uint32_t SWL_MASK[4], SWR_MASK[4], LWL_MASK[4], LWR_MASK[4];
|
||||
static const int32_t SWL_SHIFT[4], SWR_SHIFT[4], LWL_SHIFT[4], LWR_SHIFT[4];
|
||||
static R4300iOp::Func * m_R4300i_Opcode;
|
||||
};
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <Project64-core/ExceptionHandler.h>
|
||||
#include <Project64-core/Logging.h>
|
||||
#include <Project64-core/N64System/Enhancement/Enhancements.h>
|
||||
#include <Project64-core/N64System/Interpreter/InterpreterCPU.h>
|
||||
#include <Project64-core/N64System/Mips/Disk.h>
|
||||
#include <Project64-core/N64System/Mips/Mempak.h>
|
||||
#include <Project64-core/N64System/Mips/R4300iInstruction.h>
|
||||
|
@ -63,7 +62,7 @@ CN64System::CN64System(CPlugins * Plugins, uint32_t randomizer_seed, bool SavesR
|
|||
m_Limiter.SetHertz(gameHertz);
|
||||
g_Settings->SaveDword(GameRunning_ScreenHertz, gameHertz);
|
||||
WriteTrace(TraceN64System, TraceDebug, "Setting up system");
|
||||
CInterpreterCPU::BuildCPU();
|
||||
R4300iOp::BuildCPU();
|
||||
|
||||
if (!m_MMU_VM.Initialize(SyncSystem))
|
||||
{
|
||||
|
@ -1078,7 +1077,7 @@ void CN64System::ExecuteCPU()
|
|||
void CN64System::ExecuteInterpret()
|
||||
{
|
||||
SetActiveSystem();
|
||||
CInterpreterCPU::ExecuteCPU();
|
||||
R4300iOp::ExecuteCPU();
|
||||
}
|
||||
|
||||
void CN64System::ExecuteRecompiler()
|
||||
|
@ -1124,7 +1123,7 @@ void CN64System::UpdateSyncCPU(CN64System * const SecondCPU, uint32_t const Cycl
|
|||
}
|
||||
|
||||
SecondCPU->SetActiveSystem(true);
|
||||
CInterpreterCPU::ExecuteOps(Cycles);
|
||||
R4300iOp::ExecuteOps(Cycles);
|
||||
SetActiveSystem(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -141,8 +141,6 @@ private:
|
|||
friend class CX86RecompilerOps;
|
||||
friend class CArmRecompilerOps;
|
||||
friend class CMipsMemoryVM;
|
||||
friend class CInterpreterCPU;
|
||||
friend class R4300iOp32;
|
||||
friend class R4300iOp;
|
||||
friend class CSystemEvents;
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <Project64-core/Debugger.h>
|
||||
#include <Project64-core/ExceptionHandler.h>
|
||||
#include <Project64-core/N64System/Interpreter/InterpreterCPU.h>
|
||||
#include <Project64-core/N64System/Mips/MemoryVirtualMem.h>
|
||||
#include <Project64-core/N64System/Mips/R4300iInstruction.h>
|
||||
#include <Project64-core/N64System/Mips/R4300iOpcode.h>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
#include <Project64-core/ExceptionHandler.h>
|
||||
#include <Project64-core/N64System/Interpreter/InterpreterCPU.h>
|
||||
#include <Project64-core/N64System/N64System.h>
|
||||
#include <Project64-core/N64System/Recompiler/Recompiler.h>
|
||||
#include <Project64-core/N64System/SystemGlobals.h>
|
||||
|
@ -184,7 +183,7 @@ void CRecompiler::RecompilerMain_Lookup()
|
|||
|
||||
while (m_MMU.VAddrToPAddr(PROGRAM_COUNTER, PhysicalAddr) && PhysicalAddr >= g_System->RdramSize())
|
||||
{
|
||||
CInterpreterCPU::ExecuteOps(g_System->CountPerOp());
|
||||
R4300iOp::ExecuteOps(g_System->CountPerOp());
|
||||
opsExecuted += g_System->CountPerOp();
|
||||
}
|
||||
|
||||
|
@ -297,7 +296,7 @@ void CRecompiler::RecompilerMain_Lookup_validate()
|
|||
|
||||
while (m_MMU.VAddrToPAddr(PC, PhysicalAddr) && PhysicalAddr >= g_System->RdramSize())
|
||||
{
|
||||
CInterpreterCPU::ExecuteOps(g_System->CountPerOp());
|
||||
R4300iOp::ExecuteOps(g_System->CountPerOp());
|
||||
opsExecuted += g_System->CountPerOp();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include <Project64-core/Debugger.h>
|
||||
#include <Project64-core/ExceptionHandler.h>
|
||||
#include <Project64-core/N64System/Interpreter/InterpreterCPU.h>
|
||||
#include <Project64-core/N64System/Interpreter/InterpreterOps.h>
|
||||
#include <Project64-core/N64System/Mips/Disk.h>
|
||||
#include <Project64-core/N64System/Mips/MemoryVirtualMem.h>
|
||||
|
@ -57,7 +56,7 @@ void CX86RecompilerOps::x86CompilerBreakPoint()
|
|||
}
|
||||
continue;
|
||||
}
|
||||
CInterpreterCPU::ExecuteOps(g_System->CountPerOp());
|
||||
R4300iOp::ExecuteOps(g_System->CountPerOp());
|
||||
if (g_SyncSystem)
|
||||
{
|
||||
g_System->UpdateSyncCPU(g_SyncSystem, g_System->CountPerOp());
|
||||
|
@ -68,7 +67,7 @@ void CX86RecompilerOps::x86CompilerBreakPoint()
|
|||
|
||||
if (g_System->PipelineStage() != PIPELINE_STAGE_NORMAL)
|
||||
{
|
||||
CInterpreterCPU::ExecuteOps(g_System->CountPerOp());
|
||||
R4300iOp::ExecuteOps(g_System->CountPerOp());
|
||||
if (g_SyncSystem)
|
||||
{
|
||||
g_System->UpdateSyncCPU(g_SyncSystem, g_System->CountPerOp());
|
||||
|
@ -79,7 +78,7 @@ void CX86RecompilerOps::x86CompilerBreakPoint()
|
|||
|
||||
void CX86RecompilerOps::x86BreakPointDelaySlot()
|
||||
{
|
||||
CInterpreterCPU::ExecuteOps(g_System->CountPerOp());
|
||||
R4300iOp::ExecuteOps(g_System->CountPerOp());
|
||||
if (g_SyncSystem)
|
||||
{
|
||||
g_System->UpdateSyncCPU(g_SyncSystem, g_System->CountPerOp());
|
||||
|
@ -91,7 +90,7 @@ void CX86RecompilerOps::x86BreakPointDelaySlot()
|
|||
}
|
||||
if (g_System->PipelineStage() != PIPELINE_STAGE_NORMAL)
|
||||
{
|
||||
CInterpreterCPU::ExecuteOps(g_System->CountPerOp());
|
||||
R4300iOp::ExecuteOps(g_System->CountPerOp());
|
||||
if (g_SyncSystem)
|
||||
{
|
||||
g_System->UpdateSyncCPU(g_SyncSystem, g_System->CountPerOp());
|
||||
|
@ -111,7 +110,7 @@ void CX86RecompilerOps::x86MemoryBreakPoint()
|
|||
{
|
||||
g_Reg->m_PROGRAM_COUNTER -= 4;
|
||||
*g_NextTimer += g_System->CountPerOp();
|
||||
CInterpreterCPU::ExecuteOps(g_System->CountPerOp());
|
||||
R4300iOp::ExecuteOps(g_System->CountPerOp());
|
||||
}
|
||||
x86CompilerBreakPoint();
|
||||
}
|
||||
|
@ -8689,7 +8688,7 @@ void CX86RecompilerOps::CompileInPermLoop(CRegInfo & RegSet, uint32_t ProgramCou
|
|||
m_Assembler.MoveConstToVariable(&m_Reg.m_PROGRAM_COUNTER, "PROGRAM_COUNTER", ProgramCounter);
|
||||
RegSet.WriteBackRegisters();
|
||||
UpdateCounters(RegSet, false, true, false);
|
||||
m_Assembler.CallFunc(AddressOf(CInterpreterCPU::InPermLoop), "CInterpreterCPU::InPermLoop");
|
||||
m_Assembler.CallFunc(AddressOf(R4300iOp::InPermLoop), "R4300iOp::InPermLoop");
|
||||
m_Assembler.CallThis((uint32_t)g_SystemTimer, AddressOf(&CSystemTimer::TimerDone), "CSystemTimer::TimerDone", 4);
|
||||
m_CodeBlock.Log("CompileSystemCheck 3");
|
||||
CompileSystemCheck((uint32_t)-1, RegSet);
|
||||
|
@ -9406,17 +9405,10 @@ void CX86RecompilerOps::JumpToUnknown(CJumpInfo * JumpInfo)
|
|||
void CX86RecompilerOps::SetCurrentPC(uint32_t ProgramCounter)
|
||||
{
|
||||
m_CompilePC = ProgramCounter;
|
||||
__except_try()
|
||||
{
|
||||
if (!g_MMU->MemoryValue32(m_CompilePC, m_Opcode.Value))
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_FAIL_LOAD_WORD));
|
||||
}
|
||||
}
|
||||
__except_catch()
|
||||
{
|
||||
g_Notify->FatalError(GS(MSG_UNKNOWN_MEM_ACTION));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t CX86RecompilerOps::GetCurrentPC(void)
|
||||
|
@ -9584,7 +9576,7 @@ void CX86RecompilerOps::OverflowDelaySlot(bool TestTimer)
|
|||
}
|
||||
|
||||
m_Assembler.PushImm32("g_System->CountPerOp()", g_System->CountPerOp());
|
||||
m_Assembler.CallFunc((uint32_t)CInterpreterCPU::ExecuteOps, "CInterpreterCPU::ExecuteOps");
|
||||
m_Assembler.CallFunc((uint32_t)R4300iOp::ExecuteOps, "R4300iOp::ExecuteOps");
|
||||
m_Assembler.AddConstToX86Reg(asmjit::x86::esp, 4);
|
||||
|
||||
if (g_System->bFastSP() && g_Recompiler)
|
||||
|
|
|
@ -56,7 +56,6 @@
|
|||
<ClCompile Include="N64System\Enhancement\EnhancementList.cpp" />
|
||||
<ClCompile Include="N64System\Enhancement\Enhancements.cpp" />
|
||||
<ClCompile Include="N64System\FramePerSecond.cpp" />
|
||||
<ClCompile Include="N64System\Interpreter\InterpreterCPU.cpp" />
|
||||
<ClCompile Include="N64System\Interpreter\InterpreterOps.cpp" />
|
||||
<ClCompile Include="N64System\MemoryHandler\AudioInterfaceHandler.cpp" />
|
||||
<ClCompile Include="N64System\MemoryHandler\CartridgeDomain1Address1Handler.cpp" />
|
||||
|
@ -176,7 +175,6 @@
|
|||
<ClInclude Include="N64System\Enhancement\EnhancementList.h" />
|
||||
<ClInclude Include="N64System\Enhancement\Enhancements.h" />
|
||||
<ClInclude Include="N64System\FramePerSecond.h" />
|
||||
<ClInclude Include="N64System\Interpreter\InterpreterCPU.h" />
|
||||
<ClInclude Include="N64System\Interpreter\InterpreterOps.h" />
|
||||
<ClInclude Include="N64System\MemoryHandler\AudioInterfaceHandler.h" />
|
||||
<ClInclude Include="N64System\MemoryHandler\CartridgeDomain1Address1Handler.h" />
|
||||
|
|
|
@ -279,9 +279,6 @@
|
|||
<ClCompile Include="N64System\Mips\TLB.cpp">
|
||||
<Filter>Source Files\N64 System\Mips</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Interpreter\InterpreterCPU.cpp">
|
||||
<Filter>Source Files\N64 System\Interpreter</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="N64System\Interpreter\InterpreterOps.cpp">
|
||||
<Filter>Source Files\N64 System\Interpreter</Filter>
|
||||
</ClCompile>
|
||||
|
@ -641,9 +638,6 @@
|
|||
<ClInclude Include="N64System\Mips\TLB.h">
|
||||
<Filter>Header Files\N64 System\Mips</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Interpreter\InterpreterCPU.h">
|
||||
<Filter>Header Files\N64 System\Interpreter</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="N64System\Interpreter\InterpreterOps.h">
|
||||
<Filter>Header Files\N64 System\Interpreter</Filter>
|
||||
</ClInclude>
|
||||
|
|
Loading…
Reference in New Issue