Added GSU (Super FX) support
This commit is contained in:
parent
468921eabb
commit
33cee67e61
81 changed files with 4174 additions and 214 deletions
|
@ -10,6 +10,7 @@
|
|||
#include "EmuSettings.h"
|
||||
#include "NecDsp.h"
|
||||
#include "Sa1.h"
|
||||
#include "Gsu.h"
|
||||
#include "../Utilities/HexUtilities.h"
|
||||
#include "../Utilities/VirtualFile.h"
|
||||
#include "../Utilities/FolderUtilities.h"
|
||||
|
@ -162,6 +163,15 @@ void BaseCartridge::Init()
|
|||
|
||||
_coprocessorType = GetCoprocessorType();
|
||||
|
||||
if(_coprocessorType != CoprocessorType::None && _cartInfo.ExpansionRamSize > 0 && _cartInfo.ExpansionRamSize <= 7) {
|
||||
_coprocessorRamSize = _cartInfo.ExpansionRamSize > 0 ? 1024 * (1 << _cartInfo.ExpansionRamSize) : 0;
|
||||
}
|
||||
|
||||
if(_coprocessorType == CoprocessorType::GSU && _coprocessorRamSize == 0) {
|
||||
//Use a min of 64kb by default for GSU games
|
||||
_coprocessorRamSize = 0x10000;
|
||||
}
|
||||
|
||||
_saveRamSize = _cartInfo.SramSize > 0 ? 1024 * (1 << _cartInfo.SramSize) : 0;
|
||||
_saveRam = new uint8_t[_saveRamSize];
|
||||
_console->GetSettings()->InitializeRam(_saveRam, _saveRamSize);
|
||||
|
@ -174,7 +184,7 @@ CoprocessorType BaseCartridge::GetCoprocessorType()
|
|||
if((_cartInfo.RomType & 0x0F) >= 0x03) {
|
||||
switch((_cartInfo.RomType & 0xF0) >> 4) {
|
||||
case 0x00: return GetDspVersion(); break;
|
||||
case 0x01: return CoprocessorType::GSU1; break; //Or mariochip1/gsu2
|
||||
case 0x01: return CoprocessorType::GSU; break;
|
||||
case 0x02: return CoprocessorType::OBC1; break;
|
||||
case 0x03: return CoprocessorType::SA1; break;
|
||||
case 0x04: return CoprocessorType::DD1; break;
|
||||
|
@ -224,7 +234,9 @@ CoprocessorType BaseCartridge::GetDspVersion()
|
|||
|
||||
void BaseCartridge::Reset()
|
||||
{
|
||||
_coprocessor->Reset();
|
||||
if(_coprocessor) {
|
||||
_coprocessor->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
RomInfo BaseCartridge::GetRomInfo()
|
||||
|
@ -300,7 +312,7 @@ void BaseCartridge::Init(MemoryMappings &mm)
|
|||
|
||||
void BaseCartridge::RegisterHandlers(MemoryMappings &mm)
|
||||
{
|
||||
if(MapSpecificCarts(mm)) {
|
||||
if(_coprocessorType == CoprocessorType::GSU || MapSpecificCarts(mm)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -351,6 +363,9 @@ void BaseCartridge::InitCoprocessor()
|
|||
if(_coprocessorType == CoprocessorType::SA1) {
|
||||
_coprocessor.reset(new Sa1(_console));
|
||||
_sa1 = dynamic_cast<Sa1*>(_coprocessor.get());
|
||||
} else if(_coprocessorType == CoprocessorType::GSU) {
|
||||
_coprocessor.reset(new Gsu(_console, _coprocessorRamSize));
|
||||
_gsu = dynamic_cast<Gsu*>(_coprocessor.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -459,9 +474,7 @@ void BaseCartridge::DisplayCartInfo()
|
|||
case CoprocessorType::DSP2: coProcMessage += "DSP2"; break;
|
||||
case CoprocessorType::DSP3: coProcMessage += "DSP3"; break;
|
||||
case CoprocessorType::DSP4: coProcMessage += "DSP4"; break;
|
||||
case CoprocessorType::GSU1: coProcMessage += "Super FX (GSU1)"; break;
|
||||
case CoprocessorType::GSU2: coProcMessage += "Super FX (GSU2)"; break;
|
||||
case CoprocessorType::MarioChip: coProcMessage += "Super FX (Mario Chip 1)"; break;
|
||||
case CoprocessorType::GSU: coProcMessage += "Super FX (GSU1/2)"; break;
|
||||
case CoprocessorType::OBC1: coProcMessage += "OBC1"; break;
|
||||
case CoprocessorType::RTC: coProcMessage += "RTC"; break;
|
||||
case CoprocessorType::SA1: coProcMessage += "SA1"; break;
|
||||
|
@ -489,6 +502,9 @@ void BaseCartridge::DisplayCartInfo()
|
|||
if(_saveRamSize > 0) {
|
||||
MessageManager::Log("SRAM size: " + std::to_string(_saveRamSize / 1024) + " KB");
|
||||
}
|
||||
if(_coprocessorRamSize > 0) {
|
||||
MessageManager::Log("Coprocessor RAM size: " + std::to_string(_coprocessorRamSize / 1024) + " KB");
|
||||
}
|
||||
MessageManager::Log("-----------------------------");
|
||||
}
|
||||
|
||||
|
@ -502,6 +518,19 @@ Sa1* BaseCartridge::GetSa1()
|
|||
return _sa1;
|
||||
}
|
||||
|
||||
Gsu* BaseCartridge::GetGsu()
|
||||
{
|
||||
return _gsu;
|
||||
}
|
||||
|
||||
void BaseCartridge::RunCoprocessors()
|
||||
{
|
||||
//These coprocessors are run at the end of the frame, or as needed
|
||||
if(_necDsp) {
|
||||
_necDsp->Run();
|
||||
}
|
||||
}
|
||||
|
||||
BaseCoprocessor* BaseCartridge::GetCoprocessor()
|
||||
{
|
||||
return _coprocessor.get();
|
||||
|
|
|
@ -10,6 +10,7 @@ class VirtualFile;
|
|||
class EmuSettings;
|
||||
class NecDsp;
|
||||
class Sa1;
|
||||
class Gsu;
|
||||
class Console;
|
||||
|
||||
class BaseCartridge : public ISerializable
|
||||
|
@ -24,6 +25,7 @@ private:
|
|||
unique_ptr<BaseCoprocessor> _coprocessor;
|
||||
NecDsp *_necDsp = nullptr;
|
||||
Sa1 *_sa1 = nullptr;
|
||||
Gsu *_gsu = nullptr;
|
||||
|
||||
CartFlags::CartFlags _flags = CartFlags::CartFlags::None;
|
||||
CoprocessorType _coprocessorType = CoprocessorType::None;
|
||||
|
@ -35,6 +37,7 @@ private:
|
|||
|
||||
uint32_t _prgRomSize = 0;
|
||||
uint32_t _saveRamSize = 0;
|
||||
uint32_t _coprocessorRamSize = 0;
|
||||
|
||||
void LoadBattery();
|
||||
|
||||
|
@ -76,6 +79,10 @@ public:
|
|||
|
||||
NecDsp* GetDsp();
|
||||
Sa1* GetSa1();
|
||||
Gsu* GetGsu();
|
||||
|
||||
void RunCoprocessors();
|
||||
|
||||
BaseCoprocessor* GetCoprocessor();
|
||||
|
||||
vector<unique_ptr<IMemoryHandler>>& GetPrgRomHandlers();
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
class BaseCoprocessor : public ISerializable, public IMemoryHandler
|
||||
{
|
||||
public:
|
||||
virtual void Run() = 0;
|
||||
virtual void Reset() = 0;
|
||||
|
||||
|
||||
virtual void ProcessEndOfFrame() { }
|
||||
virtual void LoadBattery(string filePath) { }
|
||||
virtual void SaveBattery(string filePath) { }
|
||||
};
|
|
@ -1,10 +1,11 @@
|
|||
#include "stdafx.h"
|
||||
#include "Breakpoint.h"
|
||||
#include "DebugTypes.h"
|
||||
#include "DebugUtilities.h"
|
||||
|
||||
bool Breakpoint::Matches(uint32_t memoryAddr, AddressInfo &info)
|
||||
{
|
||||
if(_memoryType <= SnesMemoryType::Sa1Memory) {
|
||||
if(_memoryType <= DebugUtilities::GetLastCpuMemoryType()) {
|
||||
if(_startAddr == -1) {
|
||||
return true;
|
||||
} else if(_endAddr == -1) {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "DebugTypes.h"
|
||||
#include "Debugger.h"
|
||||
#include "Breakpoint.h"
|
||||
#include "DebugUtilities.h"
|
||||
#include "ExpressionEvaluator.h"
|
||||
|
||||
BreakpointManager::BreakpointManager(Debugger *debugger)
|
||||
|
@ -12,7 +13,7 @@ BreakpointManager::BreakpointManager(Debugger *debugger)
|
|||
|
||||
void BreakpointManager::SetBreakpoints(Breakpoint breakpoints[], uint32_t count)
|
||||
{
|
||||
for(int j = 0; j < (int)CpuType::Sa1 + 1; j++) {
|
||||
for(int j = 0; j <= (int)DebugUtilities::GetLastCpuType(); j++) {
|
||||
for(int i = 0; i < BreakpointManager::BreakpointTypeCount; i++) {
|
||||
_breakpoints[j][i].clear();
|
||||
_rpnList[j][i].clear();
|
||||
|
@ -22,6 +23,8 @@ void BreakpointManager::SetBreakpoints(Breakpoint breakpoints[], uint32_t count)
|
|||
|
||||
_bpExpEval[(int)CpuType::Cpu].reset(new ExpressionEvaluator(_debugger, CpuType::Cpu));
|
||||
_bpExpEval[(int)CpuType::Spc].reset(new ExpressionEvaluator(_debugger, CpuType::Spc));
|
||||
_bpExpEval[(int)CpuType::Sa1].reset(new ExpressionEvaluator(_debugger, CpuType::Sa1));
|
||||
_bpExpEval[(int)CpuType::Gsu].reset(new ExpressionEvaluator(_debugger, CpuType::Gsu));
|
||||
|
||||
for(uint32_t j = 0; j < count; j++) {
|
||||
Breakpoint &bp = breakpoints[j];
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "stdafx.h"
|
||||
#include "Breakpoint.h"
|
||||
#include "DebugTypes.h"
|
||||
#include "DebugUtilities.h"
|
||||
|
||||
class ExpressionEvaluator;
|
||||
class Debugger;
|
||||
|
@ -15,11 +16,11 @@ private:
|
|||
|
||||
Debugger *_debugger;
|
||||
|
||||
vector<Breakpoint> _breakpoints[(int)CpuType::Sa1 + 1][BreakpointTypeCount];
|
||||
vector<ExpressionData> _rpnList[(int)CpuType::Sa1 + 1][BreakpointTypeCount];
|
||||
bool _hasBreakpoint[(int)CpuType::Sa1 + 1][BreakpointTypeCount] = {};
|
||||
vector<Breakpoint> _breakpoints[(int)DebugUtilities::GetLastCpuType() + 1][BreakpointTypeCount];
|
||||
vector<ExpressionData> _rpnList[(int)DebugUtilities::GetLastCpuType() + 1][BreakpointTypeCount];
|
||||
bool _hasBreakpoint[(int)DebugUtilities::GetLastCpuType() + 1][BreakpointTypeCount] = {};
|
||||
|
||||
unique_ptr<ExpressionEvaluator> _bpExpEval[(int)CpuType::Sa1 + 1];
|
||||
unique_ptr<ExpressionEvaluator> _bpExpEval[(int)DebugUtilities::GetLastCpuType() + 1];
|
||||
|
||||
BreakpointType GetBreakpointType(MemoryOperationType type);
|
||||
|
||||
|
|
|
@ -33,9 +33,7 @@ enum class CoprocessorType
|
|||
DSP2,
|
||||
DSP3,
|
||||
DSP4,
|
||||
GSU1,
|
||||
GSU2,
|
||||
MarioChip,
|
||||
GSU,
|
||||
OBC1,
|
||||
SA1,
|
||||
DD1,
|
||||
|
|
|
@ -107,9 +107,11 @@ void Console::Run()
|
|||
_cpu->Exec();
|
||||
|
||||
if(previousFrameCount != _ppu->GetFrameCount()) {
|
||||
_cart->RunCoprocessors();
|
||||
if(_cart->GetCoprocessor()) {
|
||||
_cart->GetCoprocessor()->Run();
|
||||
_cart->GetCoprocessor()->ProcessEndOfFrame();
|
||||
}
|
||||
|
||||
_rewindManager->ProcessEndOfFrame();
|
||||
|
||||
WaitForLock();
|
||||
|
@ -169,6 +171,11 @@ void Console::RunSingleFrame()
|
|||
_cpu->Exec();
|
||||
}
|
||||
|
||||
_cart->RunCoprocessors();
|
||||
if(_cart->GetCoprocessor()) {
|
||||
_cart->GetCoprocessor()->ProcessEndOfFrame();
|
||||
}
|
||||
|
||||
_controlManager->UpdateControlDevices();
|
||||
}
|
||||
|
||||
|
@ -231,7 +238,7 @@ void Console::Reset()
|
|||
_spc->Reset();
|
||||
_ppu->Reset();
|
||||
_cpu->Reset();
|
||||
//_cart->Reset();
|
||||
_cart->Reset();
|
||||
//_controlManager->Reset();
|
||||
|
||||
_notificationManager->SendNotification(ConsoleNotificationType::GameReset);
|
||||
|
@ -673,9 +680,7 @@ void Console::ProcessPpuCycle()
|
|||
if(_debugger) {
|
||||
_debugger->ProcessPpuCycle();
|
||||
_spc->Run();
|
||||
if(_cart->GetCoprocessor()) {
|
||||
_cart->GetCoprocessor()->Run();
|
||||
}
|
||||
_cart->RunCoprocessors();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -697,10 +702,12 @@ void Console::ProcessEvent(EventType type)
|
|||
template void Console::ProcessMemoryRead<CpuType::Cpu>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
template void Console::ProcessMemoryRead<CpuType::Sa1>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
template void Console::ProcessMemoryRead<CpuType::Spc>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
template void Console::ProcessMemoryRead<CpuType::Gsu>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
|
||||
template void Console::ProcessMemoryWrite<CpuType::Cpu>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
template void Console::ProcessMemoryWrite<CpuType::Sa1>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
template void Console::ProcessMemoryWrite<CpuType::Spc>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
template void Console::ProcessMemoryWrite<CpuType::Gsu>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
|
||||
template void Console::ProcessInterrupt<CpuType::Cpu>(uint32_t originalPc, uint32_t currentPc, bool forNmi);
|
||||
template void Console::ProcessInterrupt<CpuType::Sa1>(uint32_t originalPc, uint32_t currentPc, bool forNmi);
|
|
@ -51,6 +51,12 @@
|
|||
<ClInclude Include="Cpu.Shared.h" />
|
||||
<ClInclude Include="CpuDebugger.h" />
|
||||
<ClInclude Include="DebugUtilities.h" />
|
||||
<ClInclude Include="Gsu.h" />
|
||||
<ClInclude Include="GsuDebugger.h" />
|
||||
<ClInclude Include="GsuDisUtils.h" />
|
||||
<ClInclude Include="GsuRamHandler.h" />
|
||||
<ClInclude Include="GsuRomHandler.h" />
|
||||
<ClInclude Include="GsuTypes.h" />
|
||||
<ClInclude Include="MemoryMappings.h" />
|
||||
<ClInclude Include="BaseRenderer.h" />
|
||||
<ClInclude Include="BaseSoundManager.h" />
|
||||
|
@ -184,6 +190,10 @@
|
|||
<ClCompile Include="EmuSettings.cpp" />
|
||||
<ClCompile Include="EventManager.cpp" />
|
||||
<ClCompile Include="ExpressionEvaluator.cpp" />
|
||||
<ClCompile Include="Gsu.cpp" />
|
||||
<ClCompile Include="Gsu.Instructions.cpp" />
|
||||
<ClCompile Include="GsuDebugger.cpp" />
|
||||
<ClCompile Include="GsuDisUtils.cpp" />
|
||||
<ClCompile Include="InternalRegisters.cpp" />
|
||||
<ClCompile Include="KeyManager.cpp" />
|
||||
<ClCompile Include="LabelManager.cpp" />
|
||||
|
|
|
@ -329,10 +329,30 @@
|
|||
<ClInclude Include="CpuDebugger.h">
|
||||
<Filter>Debugger\Debuggers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Cpu.Instructions.h" />
|
||||
<ClInclude Include="Cpu.Shared.h">
|
||||
<Filter>SNES</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GsuTypes.h">
|
||||
<Filter>SNES\Coprocessors\GSU</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Gsu.h">
|
||||
<Filter>SNES\Coprocessors\GSU</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GsuDebugger.h">
|
||||
<Filter>Debugger\Debuggers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GsuDisUtils.h">
|
||||
<Filter>Debugger\Disassembler</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Cpu.Instructions.h">
|
||||
<Filter>SNES</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GsuRomHandler.h">
|
||||
<Filter>SNES\Coprocessors\GSU</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GsuRamHandler.h">
|
||||
<Filter>SNES\Coprocessors\GSU</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp" />
|
||||
|
@ -537,6 +557,18 @@
|
|||
<ClCompile Include="CpuDebugger.cpp">
|
||||
<Filter>Debugger\Debuggers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Gsu.cpp">
|
||||
<Filter>SNES\Coprocessors\GSU</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Gsu.Instructions.cpp">
|
||||
<Filter>SNES\Coprocessors\GSU</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GsuDebugger.cpp">
|
||||
<Filter>Debugger\Debuggers</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GsuDisUtils.cpp">
|
||||
<Filter>Debugger\Disassembler</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="SNES">
|
||||
|
@ -581,5 +613,8 @@
|
|||
<Filter Include="Debugger\Debuggers">
|
||||
<UniqueIdentifier>{799edb31-b81c-4842-a1e5-a81d5b28459a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="SNES\Coprocessors\GSU">
|
||||
<UniqueIdentifier>{5bda57b5-9204-46f4-85f5-3b550c589a18}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -66,7 +66,7 @@ void CpuDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
}
|
||||
_codeDataLogger->SetFlags(addressInfo.Address, flags);
|
||||
}
|
||||
_disassembler->BuildCache(addressInfo, state.PS, _cpuType);
|
||||
_disassembler->BuildCache(addressInfo, state.PS & (ProcFlags::IndexMode8 | ProcFlags::MemoryMode8), _cpuType);
|
||||
}
|
||||
|
||||
DebugState debugState;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "PpuTypes.h"
|
||||
#include "SpcTypes.h"
|
||||
#include "NecDspTypes.h"
|
||||
#include "GsuTypes.h"
|
||||
|
||||
struct DebugState
|
||||
{
|
||||
|
@ -13,6 +14,7 @@ struct DebugState
|
|||
SpcState Spc;
|
||||
NecDspState Dsp;
|
||||
CpuState Sa1;
|
||||
GsuState Gsu;
|
||||
};
|
||||
|
||||
enum class SnesMemoryType
|
||||
|
@ -20,6 +22,7 @@ enum class SnesMemoryType
|
|||
CpuMemory,
|
||||
SpcMemory,
|
||||
Sa1Memory,
|
||||
GsuMemory,
|
||||
PrgRom,
|
||||
WorkRam,
|
||||
SaveRam,
|
||||
|
@ -32,6 +35,7 @@ enum class SnesMemoryType
|
|||
DspDataRom,
|
||||
DspDataRam,
|
||||
Sa1InternalRam,
|
||||
GsuWorkRam,
|
||||
Register,
|
||||
};
|
||||
|
||||
|
@ -253,5 +257,5 @@ enum class CpuType : uint8_t
|
|||
Spc,
|
||||
NecDsp,
|
||||
Sa1,
|
||||
//SuperFx,
|
||||
Gsu,
|
||||
};
|
||||
|
|
|
@ -11,9 +11,20 @@ public:
|
|||
case CpuType::Cpu: return SnesMemoryType::CpuMemory;
|
||||
case CpuType::Spc: return SnesMemoryType::SpcMemory;
|
||||
case CpuType::Sa1: return SnesMemoryType::Sa1Memory;
|
||||
case CpuType::Gsu: return SnesMemoryType::GsuMemory;
|
||||
case CpuType::NecDsp: break;
|
||||
}
|
||||
|
||||
throw std::runtime_error("Invalid CPU type");
|
||||
}
|
||||
|
||||
static constexpr SnesMemoryType GetLastCpuMemoryType()
|
||||
{
|
||||
return SnesMemoryType::GsuMemory;
|
||||
}
|
||||
|
||||
static constexpr CpuType GetLastCpuType()
|
||||
{
|
||||
return CpuType::Gsu;
|
||||
}
|
||||
};
|
|
@ -6,9 +6,11 @@
|
|||
#include "Ppu.h"
|
||||
#include "Spc.h"
|
||||
#include "Sa1.h"
|
||||
#include "Gsu.h"
|
||||
#include "NecDsp.h"
|
||||
#include "CpuDebugger.h"
|
||||
#include "SpcDebugger.h"
|
||||
#include "GsuDebugger.h"
|
||||
#include "BaseCartridge.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "EmuSettings.h"
|
||||
|
@ -48,6 +50,7 @@ Debugger::Debugger(shared_ptr<Console> console)
|
|||
_watchExpEval[(int)CpuType::Cpu].reset(new ExpressionEvaluator(this, CpuType::Cpu));
|
||||
_watchExpEval[(int)CpuType::Spc].reset(new ExpressionEvaluator(this, CpuType::Spc));
|
||||
_watchExpEval[(int)CpuType::Sa1].reset(new ExpressionEvaluator(this, CpuType::Sa1));
|
||||
_watchExpEval[(int)CpuType::Gsu].reset(new ExpressionEvaluator(this, CpuType::Gsu));
|
||||
|
||||
_codeDataLogger.reset(new CodeDataLogger(_cart->DebugGetPrgRomSize(), _memoryManager.get()));
|
||||
_memoryDumper.reset(new MemoryDumper(_ppu, console->GetSpc(), _memoryManager, _cart));
|
||||
|
@ -63,6 +66,8 @@ Debugger::Debugger(shared_ptr<Console> console)
|
|||
_spcDebugger.reset(new SpcDebugger(this));
|
||||
if(_cart->GetSa1()) {
|
||||
_sa1Debugger.reset(new CpuDebugger(this, CpuType::Sa1));
|
||||
} else if(_cart->GetGsu()) {
|
||||
_gsuDebugger.reset(new GsuDebugger(this));
|
||||
}
|
||||
|
||||
_step.reset(new StepRequest());
|
||||
|
@ -106,8 +111,9 @@ void Debugger::ProcessMemoryRead(uint32_t addr, uint8_t value, MemoryOperationTy
|
|||
{
|
||||
switch(type) {
|
||||
case CpuType::Cpu: _cpuDebugger->ProcessRead(addr, value, opType); break;
|
||||
case CpuType::Sa1: _sa1Debugger->ProcessRead(addr, value, opType); break;
|
||||
case CpuType::Spc: _spcDebugger->ProcessRead(addr, value, opType); break;
|
||||
case CpuType::Sa1: _sa1Debugger->ProcessRead(addr, value, opType); break;
|
||||
case CpuType::Gsu: _gsuDebugger->ProcessRead(addr, value, opType); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,8 +122,9 @@ void Debugger::ProcessMemoryWrite(uint32_t addr, uint8_t value, MemoryOperationT
|
|||
{
|
||||
switch(type) {
|
||||
case CpuType::Cpu: _cpuDebugger->ProcessWrite(addr, value, opType); break;
|
||||
case CpuType::Sa1: _sa1Debugger->ProcessWrite(addr, value, opType); break;
|
||||
case CpuType::Spc: _spcDebugger->ProcessWrite(addr, value, opType); break;
|
||||
case CpuType::Sa1: _sa1Debugger->ProcessWrite(addr, value, opType); break;
|
||||
case CpuType::Gsu: _gsuDebugger->ProcessWrite(addr, value, opType); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,6 +207,8 @@ void Debugger::SleepUntilResume(BreakSource source, MemoryOperationInfo *operati
|
|||
_disassembler->Disassemble(CpuType::Spc);
|
||||
if(_cart->GetSa1()) {
|
||||
_disassembler->Disassemble(CpuType::Sa1);
|
||||
} else if(_cart->GetGsu()) {
|
||||
_disassembler->Disassemble(CpuType::Gsu);
|
||||
}
|
||||
|
||||
_executionStopped = true;
|
||||
|
@ -283,6 +292,9 @@ void Debugger::Run()
|
|||
if(_sa1Debugger) {
|
||||
_sa1Debugger->Run();
|
||||
}
|
||||
if(_gsuDebugger) {
|
||||
_gsuDebugger->Run();
|
||||
}
|
||||
_waitForBreakResume = false;
|
||||
}
|
||||
|
||||
|
@ -295,6 +307,9 @@ void Debugger::Step(CpuType cpuType, int32_t stepCount, StepType type)
|
|||
if(_sa1Debugger) {
|
||||
_sa1Debugger->Run();
|
||||
}
|
||||
if(_gsuDebugger) {
|
||||
_gsuDebugger->Run();
|
||||
}
|
||||
|
||||
switch(type) {
|
||||
case StepType::PpuStep: step.PpuStepCount = stepCount; break;
|
||||
|
@ -305,6 +320,7 @@ void Debugger::Step(CpuType cpuType, int32_t stepCount, StepType type)
|
|||
case CpuType::Cpu: _cpuDebugger->Step(stepCount, type); break;
|
||||
case CpuType::Spc: _spcDebugger->Step(stepCount, type); break;
|
||||
case CpuType::Sa1: _sa1Debugger->Step(stepCount, type); break;
|
||||
case CpuType::Gsu: _gsuDebugger->Step(stepCount, type); break;
|
||||
case CpuType::NecDsp: throw std::runtime_error("Step(): Unsupported CPU type.");
|
||||
}
|
||||
break;
|
||||
|
@ -349,6 +365,9 @@ void Debugger::GetState(DebugState &state, bool partialPpuState)
|
|||
if(_cart->GetSa1()) {
|
||||
state.Sa1 = _cart->GetSa1()->GetCpuState();
|
||||
}
|
||||
if(_cart->GetGsu()) {
|
||||
state.Gsu = _cart->GetGsu()->GetState();
|
||||
}
|
||||
}
|
||||
|
||||
AddressInfo Debugger::GetAbsoluteAddress(AddressInfo relAddress)
|
||||
|
@ -363,6 +382,8 @@ AddressInfo Debugger::GetAbsoluteAddress(AddressInfo relAddress)
|
|||
return _spc->GetAbsoluteAddress(relAddress.Address);
|
||||
} else if(relAddress.Type == SnesMemoryType::Sa1Memory) {
|
||||
return _cart->GetSa1()->GetMemoryMappings()->GetAbsoluteAddress(relAddress.Address);
|
||||
} else if(relAddress.Type == SnesMemoryType::GsuMemory) {
|
||||
return _cart->GetGsu()->GetMemoryMappings()->GetAbsoluteAddress(relAddress.Address);
|
||||
}
|
||||
|
||||
throw std::runtime_error("Unsupported address type");
|
||||
|
@ -468,6 +489,8 @@ shared_ptr<CallstackManager> Debugger::GetCallstackManager(CpuType cpuType)
|
|||
case CpuType::Cpu: return _cpuDebugger->GetCallstackManager();
|
||||
case CpuType::Spc: return _spcDebugger->GetCallstackManager();
|
||||
case CpuType::Sa1: return _sa1Debugger->GetCallstackManager();
|
||||
|
||||
case CpuType::Gsu:
|
||||
case CpuType::NecDsp: break;
|
||||
}
|
||||
throw std::runtime_error("GetCallstackManager() - Unsupported CPU type");
|
||||
|
@ -481,10 +504,12 @@ shared_ptr<Console> Debugger::GetConsole()
|
|||
template void Debugger::ProcessMemoryRead<CpuType::Cpu>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
template void Debugger::ProcessMemoryRead<CpuType::Sa1>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
template void Debugger::ProcessMemoryRead<CpuType::Spc>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
template void Debugger::ProcessMemoryRead<CpuType::Gsu>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
|
||||
template void Debugger::ProcessMemoryWrite<CpuType::Cpu>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
template void Debugger::ProcessMemoryWrite<CpuType::Sa1>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
template void Debugger::ProcessMemoryWrite<CpuType::Spc>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
template void Debugger::ProcessMemoryWrite<CpuType::Gsu>(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
|
||||
template void Debugger::ProcessInterrupt<CpuType::Cpu>(uint32_t originalPc, uint32_t currentPc, bool forNmi);
|
||||
template void Debugger::ProcessInterrupt<CpuType::Sa1>(uint32_t originalPc, uint32_t currentPc, bool forNmi);
|
||||
|
|
|
@ -26,6 +26,7 @@ class LabelManager;
|
|||
class ScriptManager;
|
||||
class SpcDebugger;
|
||||
class CpuDebugger;
|
||||
class GsuDebugger;
|
||||
|
||||
enum class EventType;
|
||||
enum class EvalResultType : int32_t;
|
||||
|
@ -44,6 +45,7 @@ private:
|
|||
unique_ptr<SpcDebugger> _spcDebugger;
|
||||
unique_ptr<CpuDebugger> _cpuDebugger;
|
||||
unique_ptr<CpuDebugger> _sa1Debugger;
|
||||
unique_ptr<GsuDebugger> _gsuDebugger;
|
||||
|
||||
shared_ptr<ScriptManager> _scriptManager;
|
||||
shared_ptr<TraceLogger> _traceLogger;
|
||||
|
@ -56,7 +58,7 @@ private:
|
|||
shared_ptr<EventManager> _eventManager;
|
||||
shared_ptr<LabelManager> _labelManager;
|
||||
|
||||
unique_ptr<ExpressionEvaluator> _watchExpEval[(int)CpuType::Sa1 + 1];
|
||||
unique_ptr<ExpressionEvaluator> _watchExpEval[(int)CpuType::Gsu + 1];
|
||||
|
||||
atomic<bool> _executionStopped;
|
||||
atomic<uint32_t> _breakRequestCount;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "Spc.h"
|
||||
#include "NecDsp.h"
|
||||
#include "Sa1.h"
|
||||
#include "Gsu.h"
|
||||
#include "Debugger.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "LabelManager.h"
|
||||
|
@ -49,6 +50,9 @@ Disassembler::Disassembler(shared_ptr<Console> console, shared_ptr<CodeDataLogge
|
|||
_sa1InternalRam = console->GetCartridge()->GetSa1() ? console->GetCartridge()->GetSa1()->DebugGetInternalRam() : nullptr;
|
||||
_sa1InternalRamSize = console->GetCartridge()->GetSa1() ? console->GetCartridge()->GetSa1()->DebugGetInternalRamSize() : 0;
|
||||
|
||||
_gsuWorkRam = console->GetCartridge()->GetGsu() ? console->GetCartridge()->GetGsu()->DebugGetWorkRam() : nullptr;
|
||||
_gsuWorkRamSize = console->GetCartridge()->GetGsu() ? console->GetCartridge()->GetGsu()->DebugGetWorkRamSize() : 0;
|
||||
|
||||
_prgCache = vector<DisassemblyInfo>(_prgRomSize);
|
||||
_sramCache = vector<DisassemblyInfo>(_sramSize);
|
||||
_wramCache = vector<DisassemblyInfo>(_wramSize);
|
||||
|
@ -56,6 +60,11 @@ Disassembler::Disassembler(shared_ptr<Console> console, shared_ptr<CodeDataLogge
|
|||
_spcRomCache = vector<DisassemblyInfo>(_spcRomSize);
|
||||
_necDspRomCache = vector<DisassemblyInfo>(_necDspProgramRomSize);
|
||||
_sa1InternalRamCache = vector<DisassemblyInfo>(_sa1InternalRamSize);
|
||||
_gsuWorkRamCache = vector<DisassemblyInfo>(_gsuWorkRamSize);
|
||||
|
||||
for(int i = 0; i < (int)DebugUtilities::GetLastCpuType(); i++) {
|
||||
_needDisassemble[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Disassembler::GetSource(AddressInfo &info, uint8_t **source, uint32_t &size, vector<DisassemblyInfo> **cache)
|
||||
|
@ -103,6 +112,12 @@ void Disassembler::GetSource(AddressInfo &info, uint8_t **source, uint32_t &size
|
|||
size = _sa1InternalRamSize;
|
||||
break;
|
||||
|
||||
case SnesMemoryType::GsuWorkRam:
|
||||
*source = _gsuWorkRam;
|
||||
*cache = &_gsuWorkRamCache;
|
||||
size = _gsuWorkRamSize;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw std::runtime_error("Disassembler::GetSource() invalid memory type");
|
||||
}
|
||||
|
@ -114,6 +129,7 @@ vector<DisassemblyResult>& Disassembler::GetDisassemblyList(CpuType type)
|
|||
case CpuType::Cpu: return _disassembly;
|
||||
case CpuType::Spc: return _spcDisassembly;
|
||||
case CpuType::Sa1: return _sa1Disassembly;
|
||||
case CpuType::Gsu: return _gsuDisassembly;
|
||||
case CpuType::NecDsp: break;
|
||||
}
|
||||
throw std::runtime_error("Disassembly::GetDisassemblyList(): Invalid cpu type");
|
||||
|
@ -156,9 +172,10 @@ uint32_t Disassembler::BuildCache(AddressInfo &addrInfo, uint8_t cpuFlags, CpuTy
|
|||
|
||||
void Disassembler::SetDisassembleFlag(CpuType type)
|
||||
{
|
||||
if(type == CpuType::Cpu || type == CpuType::Sa1) {
|
||||
if(type == CpuType::Cpu || type == CpuType::Sa1 || type == CpuType::Gsu) {
|
||||
_needDisassemble[(int)CpuType::Cpu] = true;
|
||||
_needDisassemble[(int)CpuType::Sa1] = true;
|
||||
_needDisassemble[(int)CpuType::Gsu] = true;
|
||||
} else if(type == CpuType::Spc) {
|
||||
_needDisassemble[(int)CpuType::Spc] = true;
|
||||
} else {
|
||||
|
@ -171,6 +188,7 @@ void Disassembler::ResetPrgCache()
|
|||
_prgCache = vector<DisassemblyInfo>(_prgRomSize);
|
||||
_needDisassemble[(int)CpuType::Cpu] = true;
|
||||
_needDisassemble[(int)CpuType::Sa1] = true;
|
||||
_needDisassemble[(int)CpuType::Gsu] = true;
|
||||
}
|
||||
|
||||
void Disassembler::InvalidateCache(AddressInfo addrInfo, CpuType type)
|
||||
|
@ -208,7 +226,28 @@ void Disassembler::Disassemble(CpuType cpuType)
|
|||
auto lock = _disassemblyLock.AcquireSafe();
|
||||
|
||||
bool isSpc = cpuType == CpuType::Spc;
|
||||
MemoryMappings *mappings = cpuType == CpuType::Sa1 ? _console->GetCartridge()->GetSa1()->GetMemoryMappings() : _memoryManager->GetMemoryMappings();
|
||||
MemoryMappings *mappings = nullptr;
|
||||
switch(cpuType) {
|
||||
case CpuType::Cpu: mappings = _memoryManager->GetMemoryMappings(); break;
|
||||
|
||||
case CpuType::Sa1:
|
||||
if(!_console->GetCartridge()->GetSa1()) {
|
||||
return;
|
||||
}
|
||||
mappings = _console->GetCartridge()->GetSa1()->GetMemoryMappings();
|
||||
break;
|
||||
|
||||
case CpuType::Gsu:
|
||||
if(!_console->GetCartridge()->GetGsu()) {
|
||||
return;
|
||||
}
|
||||
mappings = _console->GetCartridge()->GetGsu()->GetMemoryMappings();
|
||||
break;
|
||||
|
||||
case CpuType::Spc: mappings = nullptr; break;
|
||||
default: throw std::runtime_error("Disassemble(): Invalid cpu type");
|
||||
}
|
||||
|
||||
vector<DisassemblyResult> &results = GetDisassemblyList(cpuType);
|
||||
int32_t maxAddr = isSpc ? 0xFFFF : 0xFFFFFF;
|
||||
results.clear();
|
||||
|
@ -462,11 +501,12 @@ bool Disassembler::GetLineData(CpuType type, uint32_t lineIndex, CodeLineData &d
|
|||
vector<DisassemblyInfo> *cache;
|
||||
GetSource(result.Address, &source, sourceLength, &cache);
|
||||
DisassemblyInfo disInfo = (*cache)[result.Address.Address];
|
||||
CpuType lineCpuType = disInfo.IsInitialized() ? disInfo.GetCpuType() : type;
|
||||
|
||||
data.Address = result.CpuAddress;
|
||||
data.AbsoluteAddress = result.Address.Address;
|
||||
|
||||
switch(type) {
|
||||
switch(lineCpuType) {
|
||||
case CpuType::Cpu:
|
||||
case CpuType::Sa1: {
|
||||
CpuState state = _console->GetCpu()->GetState();
|
||||
|
@ -511,6 +551,19 @@ bool Disassembler::GetLineData(CpuType type, uint32_t lineIndex, CodeLineData &d
|
|||
break;
|
||||
}
|
||||
|
||||
case CpuType::Gsu: {
|
||||
if(!disInfo.IsInitialized()) {
|
||||
disInfo = DisassemblyInfo(source + result.Address.Address, 0, CpuType::Gsu);
|
||||
} else {
|
||||
data.Flags |= LineFlags::VerifiedCode;
|
||||
}
|
||||
|
||||
data.OpSize = disInfo.GetOpSize();
|
||||
data.EffectiveAddress = -1;
|
||||
data.ValueSize = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case CpuType::NecDsp:
|
||||
throw std::runtime_error("GetLineData - CPU type not supported");
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "stdafx.h"
|
||||
#include "DisassemblyInfo.h"
|
||||
#include "DebugTypes.h"
|
||||
#include "DebugUtilities.h"
|
||||
#include "../Utilities/SimpleLock.h"
|
||||
|
||||
class MemoryManager;
|
||||
|
@ -32,13 +33,15 @@ private:
|
|||
vector<DisassemblyInfo> _spcRomCache;
|
||||
vector<DisassemblyInfo> _necDspRomCache;
|
||||
vector<DisassemblyInfo> _sa1InternalRamCache;
|
||||
vector<DisassemblyInfo> _gsuWorkRamCache;
|
||||
|
||||
SimpleLock _disassemblyLock;
|
||||
vector<DisassemblyResult> _disassembly;
|
||||
vector<DisassemblyResult> _spcDisassembly;
|
||||
vector<DisassemblyResult> _sa1Disassembly;
|
||||
vector<DisassemblyResult> _gsuDisassembly;
|
||||
|
||||
bool _needDisassemble[(int)CpuType::Sa1+1] = { true, true, true, true };
|
||||
bool _needDisassemble[(int)DebugUtilities::GetLastCpuType()+1];
|
||||
|
||||
uint8_t *_prgRom;
|
||||
uint32_t _prgRomSize;
|
||||
|
@ -57,6 +60,9 @@ private:
|
|||
uint8_t *_sa1InternalRam;
|
||||
uint32_t _sa1InternalRamSize;
|
||||
|
||||
uint8_t *_gsuWorkRam;
|
||||
uint32_t _gsuWorkRamSize;
|
||||
|
||||
void GetSource(AddressInfo &info, uint8_t **source, uint32_t &size, vector<DisassemblyInfo> **cache);
|
||||
vector<DisassemblyResult>& GetDisassemblyList(CpuType type);
|
||||
void SetDisassembleFlag(CpuType type);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "MemoryDumper.h"
|
||||
#include "CpuDisUtils.h"
|
||||
#include "SpcDisUtils.h"
|
||||
#include "GsuDisUtils.h"
|
||||
#include "NecDspDisUtils.h"
|
||||
#include "../Utilities/HexUtilities.h"
|
||||
#include "../Utilities/FastString.h"
|
||||
|
@ -21,7 +22,7 @@ DisassemblyInfo::DisassemblyInfo(uint8_t *opPointer, uint8_t cpuFlags, CpuType t
|
|||
void DisassemblyInfo::Initialize(uint8_t *opPointer, uint8_t cpuFlags, CpuType type)
|
||||
{
|
||||
_cpuType = type;
|
||||
_flags = cpuFlags & (ProcFlags::MemoryMode8 | ProcFlags::IndexMode8);
|
||||
_flags = cpuFlags;
|
||||
_opSize = GetOpSize(opPointer[0], _flags, _cpuType);
|
||||
memcpy(_byteCode, opPointer, _opSize);
|
||||
|
||||
|
@ -35,7 +36,7 @@ bool DisassemblyInfo::IsInitialized()
|
|||
|
||||
bool DisassemblyInfo::IsValid(uint8_t cpuFlags)
|
||||
{
|
||||
return _flags == (cpuFlags & (ProcFlags::MemoryMode8 | ProcFlags::IndexMode8));
|
||||
return _flags == cpuFlags;
|
||||
}
|
||||
|
||||
void DisassemblyInfo::Reset()
|
||||
|
@ -53,6 +54,7 @@ void DisassemblyInfo::GetDisassembly(string &out, uint32_t memoryAddr, LabelMana
|
|||
|
||||
case CpuType::Spc: SpcDisUtils::GetDisassembly(*this, out, memoryAddr, labelManager); break;
|
||||
case CpuType::NecDsp: NecDspDisUtils::GetDisassembly(*this, out, memoryAddr, labelManager); break;
|
||||
case CpuType::Gsu: GsuDisUtils::GetDisassembly(*this, out, memoryAddr, labelManager); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,11 +66,18 @@ int32_t DisassemblyInfo::GetEffectiveAddress(Console *console, void *cpuState)
|
|||
return CpuDisUtils::GetEffectiveAddress(*this, console, *(CpuState*)cpuState);
|
||||
|
||||
case CpuType::Spc: return SpcDisUtils::GetEffectiveAddress(*this, console, *(SpcState*)cpuState);
|
||||
|
||||
case CpuType::Gsu:
|
||||
case CpuType::NecDsp: return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
CpuType DisassemblyInfo::GetCpuType()
|
||||
{
|
||||
return _cpuType;
|
||||
}
|
||||
|
||||
uint8_t DisassemblyInfo::GetOpCode()
|
||||
{
|
||||
return _byteCode[0];
|
||||
|
@ -114,6 +123,17 @@ uint8_t DisassemblyInfo::GetOpSize(uint8_t opCode, uint8_t flags, CpuType type)
|
|||
return CpuDisUtils::GetOpSize(opCode, flags);
|
||||
|
||||
case CpuType::Spc: return SpcDisUtils::GetOpSize(opCode);
|
||||
|
||||
case CpuType::Gsu:
|
||||
if(opCode >= 0x05 && opCode <= 0x0F) {
|
||||
return 2;
|
||||
} else if(opCode >= 0xA0 && opCode <= 0xAF) {
|
||||
return 2;
|
||||
} else if(opCode >= 0xF0 && opCode <= 0xFF) {
|
||||
return 3;
|
||||
}
|
||||
return 1;
|
||||
|
||||
case CpuType::NecDsp: return 4;
|
||||
}
|
||||
return 0;
|
||||
|
@ -127,6 +147,8 @@ bool DisassemblyInfo::IsJumpToSub(uint8_t opCode, CpuType type)
|
|||
return opCode == 0x20 || opCode == 0x22 || opCode == 0xFC; //JSR, JSL
|
||||
|
||||
case CpuType::Spc: return opCode == 0x3F || opCode == 0x0F; //JSR, BRK
|
||||
|
||||
case CpuType::Gsu:
|
||||
case CpuType::NecDsp: return false;
|
||||
}
|
||||
return false;
|
||||
|
@ -141,6 +163,8 @@ bool DisassemblyInfo::IsReturnInstruction(uint8_t opCode, CpuType type)
|
|||
return opCode == 0x60 || opCode == 0x6B || opCode == 0x40;
|
||||
|
||||
case CpuType::Spc: return opCode == 0x6F || opCode == 0x7F;
|
||||
|
||||
case CpuType::Gsu:
|
||||
case CpuType::NecDsp: return false;
|
||||
}
|
||||
|
||||
|
@ -170,6 +194,7 @@ bool DisassemblyInfo::UpdateCpuFlags(uint8_t &cpuFlags)
|
|||
}
|
||||
return true;
|
||||
|
||||
case CpuType::Gsu:
|
||||
case CpuType::Spc:
|
||||
case CpuType::NecDsp: return false;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
|
||||
void GetDisassembly(string &out, uint32_t memoryAddr, LabelManager *labelManager);
|
||||
|
||||
CpuType GetCpuType();
|
||||
uint8_t GetOpCode();
|
||||
uint8_t GetOpSize();
|
||||
uint8_t GetFlags();
|
||||
|
|
|
@ -71,60 +71,139 @@ bool ExpressionEvaluator::CheckSpecialTokens(string expression, size_t &pos, str
|
|||
}
|
||||
} while(pos < len);
|
||||
|
||||
if(token == "a") {
|
||||
output += std::to_string((int64_t)EvalValues::RegA);
|
||||
} else if(token == "x") {
|
||||
output += std::to_string((int64_t)EvalValues::RegX);
|
||||
} else if(token == "y") {
|
||||
output += std::to_string((int64_t)EvalValues::RegY);
|
||||
} else if(token == "ps") {
|
||||
output += std::to_string((int64_t)EvalValues::RegPS);
|
||||
} else if(token == "sp") {
|
||||
output += std::to_string((int64_t)EvalValues::RegSP);
|
||||
} else if(token == "pc") {
|
||||
output += std::to_string((int64_t)EvalValues::RegPC);
|
||||
} else if(token == "oppc") {
|
||||
output += std::to_string((int64_t)EvalValues::RegOpPC);
|
||||
} else if(token == "previousoppc") {
|
||||
output += std::to_string((int64_t)EvalValues::PreviousOpPC);
|
||||
} else if(token == "frame") {
|
||||
output += std::to_string((int64_t)EvalValues::PpuFrameCount);
|
||||
} else if(token == "cycle") {
|
||||
output += std::to_string((int64_t)EvalValues::PpuCycle);
|
||||
} else if(token == "scanline") {
|
||||
output += std::to_string((int64_t)EvalValues::PpuScanline);
|
||||
} else if(token == "irq") {
|
||||
output += std::to_string((int64_t)EvalValues::Irq);
|
||||
} else if(token == "nmi") {
|
||||
output += std::to_string((int64_t)EvalValues::Nmi);
|
||||
} else if(token == "value") {
|
||||
output += std::to_string((int64_t)EvalValues::Value);
|
||||
} else if(token == "address") {
|
||||
output += std::to_string((int64_t)EvalValues::Address);
|
||||
} else if(token == "romaddress") {
|
||||
output += std::to_string((int64_t)EvalValues::AbsoluteAddress);
|
||||
} else if(token == "iswrite") {
|
||||
output += std::to_string((int64_t)EvalValues::IsWrite);
|
||||
} else if(token == "isread") {
|
||||
output += std::to_string((int64_t)EvalValues::IsRead);
|
||||
} else {
|
||||
string originalExpression = expression.substr(initialPos, pos - initialPos);
|
||||
bool validLabel = _labelManager->ContainsLabel(originalExpression);
|
||||
if(!validLabel) {
|
||||
//Check if a multi-byte label exists for this name
|
||||
string label = originalExpression + "+0";
|
||||
validLabel = _labelManager->ContainsLabel(label);
|
||||
if(_cpuType == CpuType::Gsu) {
|
||||
int64_t gsuToken = ProcessGsuTokens(token);
|
||||
if(gsuToken != -1) {
|
||||
output += std::to_string(gsuToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(validLabel) {
|
||||
data.Labels.push_back(originalExpression);
|
||||
output += std::to_string(EvalValues::FirstLabelIndex + data.Labels.size() - 1);
|
||||
} else {
|
||||
return false;
|
||||
} else {
|
||||
int64_t cpuToken = ProcessCpuSpcTokens(token);
|
||||
if(cpuToken != -1) {
|
||||
output += std::to_string(cpuToken);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
int64_t sharedToken = ProcessSharedTokens(token);
|
||||
if(sharedToken != -1) {
|
||||
output += std::to_string(sharedToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
string originalExpression = expression.substr(initialPos, pos - initialPos);
|
||||
bool validLabel = _labelManager->ContainsLabel(originalExpression);
|
||||
if(!validLabel) {
|
||||
//Check if a multi-byte label exists for this name
|
||||
string label = originalExpression + "+0";
|
||||
validLabel = _labelManager->ContainsLabel(label);
|
||||
}
|
||||
|
||||
if(validLabel) {
|
||||
data.Labels.push_back(originalExpression);
|
||||
output += std::to_string(EvalValues::FirstLabelIndex + data.Labels.size() - 1);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t ExpressionEvaluator::ProcessCpuSpcTokens(string token)
|
||||
{
|
||||
if(token == "a") {
|
||||
return EvalValues::RegA;
|
||||
} else if(token == "x") {
|
||||
return EvalValues::RegX;
|
||||
} else if(token == "y") {
|
||||
return EvalValues::RegY;
|
||||
} else if(token == "ps") {
|
||||
return EvalValues::RegPS;
|
||||
} else if(token == "sp") {
|
||||
return EvalValues::RegSP;
|
||||
} else if(token == "pc") {
|
||||
return EvalValues::RegPC;
|
||||
} else if(token == "oppc") {
|
||||
return EvalValues::RegOpPC;
|
||||
} else if(token == "previousoppc") {
|
||||
return EvalValues::PreviousOpPC;
|
||||
} else if(token == "irq") {
|
||||
return EvalValues::Irq;
|
||||
} else if(token == "nmi") {
|
||||
return EvalValues::Nmi;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t ExpressionEvaluator::ProcessSharedTokens(string token)
|
||||
{
|
||||
if(token == "frame") {
|
||||
return EvalValues::PpuFrameCount;
|
||||
} else if(token == "cycle") {
|
||||
return EvalValues::PpuCycle;
|
||||
} else if(token == "scanline") {
|
||||
return EvalValues::PpuScanline;
|
||||
} else if(token == "value") {
|
||||
return EvalValues::Value;
|
||||
} else if(token == "address") {
|
||||
return EvalValues::Address;
|
||||
} else if(token == "romaddress") {
|
||||
return EvalValues::AbsoluteAddress;
|
||||
} else if(token == "iswrite") {
|
||||
return EvalValues::IsWrite;
|
||||
} else if(token == "isread") {
|
||||
return EvalValues::IsRead;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t ExpressionEvaluator::ProcessGsuTokens(string token)
|
||||
{
|
||||
if(token == "r0") {
|
||||
return EvalValues::R0;
|
||||
} else if(token == "r1") {
|
||||
return EvalValues::R1;
|
||||
} else if(token == "r2") {
|
||||
return EvalValues::R2;
|
||||
} else if(token == "r3") {
|
||||
return EvalValues::R3;
|
||||
} else if(token == "r4") {
|
||||
return EvalValues::R4;
|
||||
} else if(token == "r5") {
|
||||
return EvalValues::R5;
|
||||
} else if(token == "r6") {
|
||||
return EvalValues::R6;
|
||||
} else if(token == "r7") {
|
||||
return EvalValues::R7;
|
||||
} else if(token == "r8") {
|
||||
return EvalValues::R8;
|
||||
} else if(token == "r9") {
|
||||
return EvalValues::R9;
|
||||
} else if(token == "r10") {
|
||||
return EvalValues::R10;
|
||||
} else if(token == "r11") {
|
||||
return EvalValues::R11;
|
||||
} else if(token == "r12") {
|
||||
return EvalValues::R12;
|
||||
} else if(token == "r13") {
|
||||
return EvalValues::R13;
|
||||
} else if(token == "r14") {
|
||||
return EvalValues::R14;
|
||||
} else if(token == "r15") {
|
||||
return EvalValues::R15;
|
||||
} else if(token == "srcreg") {
|
||||
return EvalValues::SrcReg;
|
||||
} else if(token == "dstreg") {
|
||||
return EvalValues::DstReg;
|
||||
} else if(token == "sfr") {
|
||||
return EvalValues::SFR;
|
||||
} else if(token == "pbr") {
|
||||
return EvalValues::PBR;
|
||||
} else if(token == "rombr") {
|
||||
return EvalValues::RomBR;
|
||||
} else if(token == "rambr") {
|
||||
return EvalValues::RamBR;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
string ExpressionEvaluator::GetNextToken(string expression, size_t &pos, ExpressionData &data, bool &success)
|
||||
|
@ -406,6 +485,35 @@ int32_t ExpressionEvaluator::Evaluate(ExpressionData &data, DebugState &state, E
|
|||
}
|
||||
break;
|
||||
|
||||
case CpuType::Gsu:
|
||||
switch(token) {
|
||||
case EvalValues::R0: token = state.Gsu.R[0]; break;
|
||||
case EvalValues::R1: token = state.Gsu.R[1]; break;
|
||||
case EvalValues::R2: token = state.Gsu.R[2]; break;
|
||||
case EvalValues::R3: token = state.Gsu.R[3]; break;
|
||||
case EvalValues::R4: token = state.Gsu.R[4]; break;
|
||||
case EvalValues::R5: token = state.Gsu.R[5]; break;
|
||||
case EvalValues::R6: token = state.Gsu.R[6]; break;
|
||||
case EvalValues::R7: token = state.Gsu.R[7]; break;
|
||||
case EvalValues::R8: token = state.Gsu.R[8]; break;
|
||||
case EvalValues::R9: token = state.Gsu.R[9]; break;
|
||||
case EvalValues::R10: token = state.Gsu.R[10]; break;
|
||||
case EvalValues::R11: token = state.Gsu.R[11]; break;
|
||||
case EvalValues::R12: token = state.Gsu.R[12]; break;
|
||||
case EvalValues::R13: token = state.Gsu.R[13]; break;
|
||||
case EvalValues::R14: token = state.Gsu.R[14]; break;
|
||||
case EvalValues::R15: token = state.Gsu.R[15]; break;
|
||||
|
||||
case EvalValues::SrcReg: token = state.Gsu.SrcReg; break;
|
||||
case EvalValues::DstReg: token = state.Gsu.DestReg; break;
|
||||
|
||||
case EvalValues::SFR: token = (state.Gsu.SFR.GetFlagsHigh() << 8) | state.Gsu.SFR.GetFlagsLow(); break;
|
||||
case EvalValues::PBR: token = state.Gsu.ProgramBank; break;
|
||||
case EvalValues::RomBR: token = state.Gsu.ProgramBank; break;
|
||||
case EvalValues::RamBR: token = state.Gsu.ProgramBank; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CpuType::NecDsp: throw std::runtime_error("Invalid CPU type");
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -67,6 +67,29 @@ enum EvalValues : int64_t
|
|||
IsRead = 20000000116,
|
||||
PreviousOpPC = 20000000117,
|
||||
|
||||
R0 = 20000000120,
|
||||
R1 = 20000000121,
|
||||
R2 = 20000000122,
|
||||
R3 = 20000000123,
|
||||
R4 = 20000000124,
|
||||
R5 = 20000000125,
|
||||
R6 = 20000000126,
|
||||
R7 = 20000000127,
|
||||
R8 = 20000000128,
|
||||
R9 = 20000000129,
|
||||
R10 = 20000000130,
|
||||
R11 = 20000000131,
|
||||
R12 = 20000000132,
|
||||
R13 = 20000000133,
|
||||
R14 = 20000000134,
|
||||
R15 = 20000000135,
|
||||
SrcReg = 20000000137,
|
||||
DstReg = 20000000138,
|
||||
SFR = 20000000139,
|
||||
PBR = 20000000140,
|
||||
RomBR = 20000000141,
|
||||
RamBR = 20000000142,
|
||||
|
||||
FirstLabelIndex = 20000002000,
|
||||
};
|
||||
|
||||
|
@ -116,6 +139,9 @@ private:
|
|||
bool IsOperator(string token, int &precedence, bool unaryOperator);
|
||||
EvalOperators GetOperator(string token, bool unaryOperator);
|
||||
bool CheckSpecialTokens(string expression, size_t &pos, string &output, ExpressionData &data);
|
||||
int64_t ProcessCpuSpcTokens(string token);
|
||||
int64_t ProcessSharedTokens(string token);
|
||||
int64_t ProcessGsuTokens(string token);
|
||||
string GetNextToken(string expression, size_t &pos, ExpressionData &data, bool &success);
|
||||
bool ProcessSpecialOperator(EvalOperators evalOp, std::stack<EvalOperators> &opStack, std::stack<int> &precedenceStack, vector<int64_t> &outputQueue);
|
||||
bool ToRpn(string expression, ExpressionData &data);
|
||||
|
|
734
Core/Gsu.Instructions.cpp
Normal file
734
Core/Gsu.Instructions.cpp
Normal file
|
@ -0,0 +1,734 @@
|
|||
#include "stdafx.h"
|
||||
#include "Gsu.h"
|
||||
#include "Cpu.h"
|
||||
#include "MemoryManager.h"
|
||||
|
||||
void Gsu::STOP()
|
||||
{
|
||||
if(!_state.IrqDisabled) {
|
||||
_state.SFR.Irq = true;
|
||||
_cpu->SetIrqSource(IrqSource::Coprocessor);
|
||||
}
|
||||
_state.ProgramReadBuffer = 0x01; //Run a NOP first when the GSU is restarted
|
||||
_state.SFR.Running = false;
|
||||
ResetFlags();
|
||||
|
||||
UpdateRunningState();
|
||||
}
|
||||
|
||||
void Gsu::NOP()
|
||||
{
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::CACHE()
|
||||
{
|
||||
if(_state.CacheBase != (_state.R[15] & 0xFFF0)) {
|
||||
_state.CacheBase = _state.R[15] & 0xFFF0;
|
||||
InvalidateCache();
|
||||
}
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::Branch(bool branch)
|
||||
{
|
||||
int8_t offset = (int8_t)ReadOperand();
|
||||
if(branch) {
|
||||
WriteRegister(15, _state.R[15] + offset);
|
||||
}
|
||||
}
|
||||
|
||||
void Gsu::BRA()
|
||||
{
|
||||
Branch(true);
|
||||
}
|
||||
|
||||
void Gsu::BLT()
|
||||
{
|
||||
Branch(_state.SFR.Sign == _state.SFR.Overflow);
|
||||
}
|
||||
|
||||
void Gsu::BGE()
|
||||
{
|
||||
Branch(_state.SFR.Sign != _state.SFR.Overflow);
|
||||
}
|
||||
|
||||
void Gsu::BNE()
|
||||
{
|
||||
Branch(!_state.SFR.Zero);
|
||||
}
|
||||
|
||||
void Gsu::BEQ()
|
||||
{
|
||||
Branch(_state.SFR.Zero);
|
||||
}
|
||||
|
||||
void Gsu::BPL()
|
||||
{
|
||||
Branch(!_state.SFR.Sign);
|
||||
}
|
||||
|
||||
void Gsu::BMI()
|
||||
{
|
||||
Branch(_state.SFR.Sign);
|
||||
}
|
||||
|
||||
void Gsu::BCC()
|
||||
{
|
||||
Branch(!_state.SFR.Carry);
|
||||
}
|
||||
|
||||
void Gsu::BCS()
|
||||
{
|
||||
Branch(_state.SFR.Carry);
|
||||
}
|
||||
|
||||
void Gsu::BCV()
|
||||
{
|
||||
Branch(!_state.SFR.Overflow);
|
||||
}
|
||||
|
||||
void Gsu::BVS()
|
||||
{
|
||||
Branch(_state.SFR.Overflow);
|
||||
}
|
||||
|
||||
void Gsu::JMP(uint8_t reg)
|
||||
{
|
||||
if(_state.SFR.Alt1) {
|
||||
//LJMP
|
||||
_state.ProgramBank = _state.R[reg] & 0x7F;
|
||||
WriteRegister(15, ReadSrcReg());
|
||||
|
||||
_state.CacheBase = _state.R[15] & 0xFFF0;
|
||||
InvalidateCache();
|
||||
} else {
|
||||
//JMP
|
||||
WriteRegister(15, _state.R[reg]);
|
||||
}
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::TO(uint8_t reg)
|
||||
{
|
||||
if(_state.SFR.Prefix) {
|
||||
//MOVE
|
||||
WriteRegister(reg, ReadSrcReg());
|
||||
ResetFlags();
|
||||
} else {
|
||||
//TO
|
||||
_state.DestReg = reg;
|
||||
}
|
||||
}
|
||||
|
||||
void Gsu::FROM(uint8_t reg)
|
||||
{
|
||||
if(_state.SFR.Prefix) {
|
||||
//MOVES
|
||||
WriteDestReg(_state.R[reg]);
|
||||
_state.SFR.Overflow = (_state.R[reg] & 0x80) != 0;
|
||||
_state.SFR.Sign = (_state.R[reg] & 0x8000) != 0;
|
||||
_state.SFR.Zero = (_state.R[reg] == 0);
|
||||
ResetFlags();
|
||||
} else {
|
||||
//FROM
|
||||
_state.SrcReg = reg;
|
||||
}
|
||||
}
|
||||
|
||||
void Gsu::WITH(uint8_t reg)
|
||||
{
|
||||
_state.SrcReg = reg;
|
||||
_state.DestReg = reg;
|
||||
_state.SFR.Prefix = true;
|
||||
}
|
||||
|
||||
void Gsu::STORE(uint8_t reg)
|
||||
{
|
||||
_state.RamAddress = _state.R[reg];
|
||||
WriteRam(_state.RamAddress, (uint8_t)ReadSrcReg());
|
||||
if(!_state.SFR.Alt1) {
|
||||
WriteRam(_state.RamAddress ^ 0x01, ReadSrcReg() >> 8);
|
||||
}
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::LOAD(uint8_t reg)
|
||||
{
|
||||
_state.RamAddress = _state.R[reg];
|
||||
uint16_t value = ReadRamBuffer(_state.RamAddress);
|
||||
if(!_state.SFR.Alt1) {
|
||||
value |= ReadRamBuffer(_state.RamAddress ^ 0x01) << 8;
|
||||
}
|
||||
WriteDestReg(value);
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::LOOP()
|
||||
{
|
||||
_state.R[12]--;
|
||||
_state.SFR.Zero = (_state.R[12] == 0);
|
||||
_state.SFR.Sign = (_state.R[12] & 0x8000) != 0;
|
||||
|
||||
//Loop until counter hits zero
|
||||
if(!_state.SFR.Zero) {
|
||||
WriteRegister(15, _state.R[13]);
|
||||
}
|
||||
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::ALT1()
|
||||
{
|
||||
_state.SFR.Prefix = false;
|
||||
_state.SFR.Alt1 = true;
|
||||
}
|
||||
|
||||
void Gsu::ALT2()
|
||||
{
|
||||
_state.SFR.Prefix = false;
|
||||
_state.SFR.Alt2 = true;
|
||||
}
|
||||
|
||||
void Gsu::ALT3()
|
||||
{
|
||||
_state.SFR.Prefix = false;
|
||||
_state.SFR.Alt1 = true;
|
||||
_state.SFR.Alt2 = true;
|
||||
}
|
||||
|
||||
void Gsu::MERGE()
|
||||
{
|
||||
uint16_t value = (_state.R[7] & 0xFF00) | (_state.R[8] >> 8);
|
||||
WriteDestReg(value);
|
||||
_state.SFR.Carry = (value & 0xE0E0) != 0;
|
||||
_state.SFR.Overflow = (value & 0xC0C0) != 0;
|
||||
_state.SFR.Sign = (value & 0x8080) != 0;
|
||||
_state.SFR.Zero = (value & 0xF0F0) != 0;
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::SWAP()
|
||||
{
|
||||
uint16_t value = (ReadSrcReg() >> 8) | (ReadSrcReg() << 8);
|
||||
WriteDestReg(value);
|
||||
_state.SFR.Zero = value == 0;
|
||||
_state.SFR.Sign = (value & 0x8000) != 0;
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::Add(uint8_t reg)
|
||||
{
|
||||
uint16_t operand;
|
||||
if(_state.SFR.Alt2) {
|
||||
//Immediate value
|
||||
operand = reg;
|
||||
} else {
|
||||
operand = _state.R[reg];
|
||||
}
|
||||
|
||||
uint32_t result = ReadSrcReg() + operand;
|
||||
if(_state.SFR.Alt1) {
|
||||
//ADC - Add with carry
|
||||
result += (uint8_t)_state.SFR.Carry;
|
||||
}
|
||||
|
||||
_state.SFR.Carry = (result & 0x10000) != 0;
|
||||
_state.SFR.Overflow = ~(ReadSrcReg() ^ operand) & (operand ^ result) & 0x8000;
|
||||
_state.SFR.Sign = (result & 0x8000) != 0;
|
||||
_state.SFR.Zero = (result & 0xFFFF) == 0;
|
||||
|
||||
WriteDestReg(result);
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::SubCompare(uint8_t reg)
|
||||
{
|
||||
uint16_t operand;
|
||||
if(_state.SFR.Alt2 && !_state.SFR.Alt1) {
|
||||
//Immediate value, SUB #val
|
||||
operand = reg;
|
||||
} else {
|
||||
operand = _state.R[reg];
|
||||
}
|
||||
|
||||
int32_t result = ReadSrcReg() - operand;
|
||||
if(!_state.SFR.Alt2 && _state.SFR.Alt1) {
|
||||
//SBC - SUB with carry
|
||||
result -= _state.SFR.Carry ? 0 : 1;
|
||||
}
|
||||
|
||||
_state.SFR.Carry = (result >= 0);
|
||||
_state.SFR.Overflow = ((ReadSrcReg() ^ operand) & (ReadSrcReg() ^ result) & 0x8000) != 0;
|
||||
_state.SFR.Sign = (result & 0x8000) != 0;
|
||||
_state.SFR.Zero = (result & 0xFFFF) == 0;
|
||||
|
||||
if(!_state.SFR.Alt2 || !_state.SFR.Alt1) {
|
||||
//SUB/SBC, other CMP (and no write occurs for CMP)
|
||||
WriteDestReg(result);
|
||||
}
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::MULT(uint8_t reg)
|
||||
{
|
||||
uint16_t operand;
|
||||
if(_state.SFR.Alt2) {
|
||||
//Immediate value
|
||||
operand = reg;
|
||||
} else {
|
||||
operand = _state.R[reg];
|
||||
}
|
||||
|
||||
uint16_t value;
|
||||
if(_state.SFR.Alt1) {
|
||||
//UMULT - Unsigned multiply
|
||||
value = (uint16_t)((uint8_t)ReadSrcReg() * (uint8_t)operand);
|
||||
} else {
|
||||
//MULT - Signed multiply
|
||||
value = (uint16_t)((int8_t)ReadSrcReg() * (int8_t)operand);
|
||||
}
|
||||
|
||||
WriteDestReg(value);
|
||||
_state.SFR.Sign = (value & 0x8000) != 0;
|
||||
_state.SFR.Zero = value == 0;
|
||||
|
||||
ResetFlags();
|
||||
|
||||
Step(_state.HighSpeedMode ? 1 : 2);
|
||||
}
|
||||
|
||||
void Gsu::FMultLMult()
|
||||
{
|
||||
uint32_t multResult = (int16_t)ReadSrcReg() * (int16_t)_state.R[6];
|
||||
|
||||
if(_state.SFR.Alt1) {
|
||||
//LMULT - "16x16 signed multiply", LSB in R4, MSB in DREG
|
||||
_state.R[4] = multResult;
|
||||
}
|
||||
|
||||
uint16_t value = multResult >> 16;
|
||||
WriteDestReg(value);
|
||||
|
||||
_state.SFR.Carry = (multResult & 0x8000);
|
||||
_state.SFR.Sign = (value & 0x8000);
|
||||
_state.SFR.Zero = (value == 0);
|
||||
ResetFlags();
|
||||
|
||||
Step((_state.HighSpeedMode ? 3 : 7) * (_state.ClockSelect ? 1 : 2));
|
||||
}
|
||||
|
||||
void Gsu::AndBitClear(uint8_t reg)
|
||||
{
|
||||
uint16_t operand;
|
||||
if(_state.SFR.Alt2) {
|
||||
//Immediate value
|
||||
operand = reg;
|
||||
} else {
|
||||
operand = _state.R[reg];
|
||||
}
|
||||
|
||||
uint16_t value;
|
||||
if(_state.SFR.Alt1) {
|
||||
//Bit clear
|
||||
value = ReadSrcReg() & ~operand;
|
||||
} else {
|
||||
//AND
|
||||
value = ReadSrcReg() & operand;
|
||||
}
|
||||
|
||||
WriteDestReg(value);
|
||||
_state.SFR.Zero = value == 0;
|
||||
_state.SFR.Sign = (value & 0x8000) != 0;
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::SBK()
|
||||
{
|
||||
//"Store word data, last RAM address used"
|
||||
WriteRam(_state.RamAddress, (uint8_t)ReadSrcReg());
|
||||
WriteRam(_state.RamAddress ^ 1, ReadSrcReg() >> 8);
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::LINK(uint8_t value)
|
||||
{
|
||||
//"Link Return Address"
|
||||
_state.R[11] = _state.R[15] + value;
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::SignExtend()
|
||||
{
|
||||
int16_t value = (int8_t)ReadSrcReg();
|
||||
WriteDestReg((uint16_t)value);
|
||||
_state.SFR.Zero = value == 0;
|
||||
_state.SFR.Sign = (value & 0x8000) != 0;
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::NOT()
|
||||
{
|
||||
uint16_t value = ~ReadSrcReg();
|
||||
WriteDestReg(value);
|
||||
_state.SFR.Zero = value == 0;
|
||||
_state.SFR.Sign = (value & 0x8000) != 0;
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::LSR()
|
||||
{
|
||||
uint16_t src = ReadSrcReg();
|
||||
_state.SFR.Carry = (src & 0x01) != 0;
|
||||
|
||||
uint16_t dst = src >> 1;
|
||||
WriteDestReg(dst);
|
||||
_state.SFR.Zero = dst == 0;
|
||||
_state.SFR.Sign = (dst & 0x8000) != 0;
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::ROL()
|
||||
{
|
||||
uint16_t src = ReadSrcReg();
|
||||
|
||||
uint16_t dst = (src << 1) | (uint8_t)_state.SFR.Carry;
|
||||
_state.SFR.Carry = (src & 0x8000) != 0;
|
||||
|
||||
WriteDestReg(dst);
|
||||
_state.SFR.Zero = dst == 0;
|
||||
_state.SFR.Sign = (dst & 0x8000) != 0;
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::ASR()
|
||||
{
|
||||
uint16_t src = ReadSrcReg();
|
||||
_state.SFR.Carry = (src & 0x01) != 0;
|
||||
|
||||
uint16_t dst = (int16_t)src >> 1;
|
||||
if(_state.SFR.Alt1) {
|
||||
dst += (src + 1) >> 16;
|
||||
}
|
||||
|
||||
WriteDestReg(dst);
|
||||
_state.SFR.Zero = dst == 0;
|
||||
_state.SFR.Sign = (dst & 0x8000) != 0;
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::ROR()
|
||||
{
|
||||
uint16_t src = ReadSrcReg();
|
||||
|
||||
uint16_t dst = (src >> 1) | ((int)_state.SFR.Carry << 15);
|
||||
_state.SFR.Carry = (src & 0x01) != 0;
|
||||
|
||||
WriteDestReg(dst);
|
||||
_state.SFR.Zero = dst == 0;
|
||||
_state.SFR.Sign = (dst & 0x8000) != 0;
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::LOB()
|
||||
{
|
||||
//"Value of low byte of register"
|
||||
uint8_t value = (uint8_t)ReadSrcReg();
|
||||
WriteDestReg(value);
|
||||
_state.SFR.Zero = value == 0;
|
||||
_state.SFR.Sign = (value & 0x80) != 0;
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::HIB()
|
||||
{
|
||||
//"Value of high byte of register"
|
||||
uint8_t value = (uint8_t)(ReadSrcReg() >> 8);
|
||||
WriteDestReg(value);
|
||||
_state.SFR.Zero = value == 0;
|
||||
_state.SFR.Sign = (value & 0x80) != 0;
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::IbtSmsLms(uint8_t reg)
|
||||
{
|
||||
if(_state.SFR.Alt1) {
|
||||
//LMS - "Load word data from RAM, short address"
|
||||
_state.RamAddress = ReadOperand() << 1;
|
||||
uint8_t lsb = ReadRamBuffer(_state.RamAddress);
|
||||
uint8_t msb = ReadRamBuffer(_state.RamAddress | 0x01);
|
||||
|
||||
WriteRegister(reg, (msb << 8) | lsb);
|
||||
} else if(_state.SFR.Alt2) {
|
||||
//SMS - "Store word data to RAM, short address"
|
||||
_state.RamAddress = ReadOperand() << 1;
|
||||
WriteRam(_state.RamAddress, (uint8_t)_state.R[reg]);
|
||||
WriteRam(_state.RamAddress | 0x01, _state.R[reg] >> 8);
|
||||
} else {
|
||||
//IBT - "Load immediate byte data"
|
||||
WriteRegister(reg, (int8_t)ReadOperand());
|
||||
}
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::IwtLmSm(uint8_t reg)
|
||||
{
|
||||
if(_state.SFR.Alt1) {
|
||||
//LM - Load memory
|
||||
_state.RamAddress = ReadOperand();
|
||||
_state.RamAddress |= ReadOperand() << 8;
|
||||
|
||||
uint8_t lsb = ReadRamBuffer(_state.RamAddress);
|
||||
uint8_t msb = ReadRamBuffer(_state.RamAddress ^ 0x01);
|
||||
WriteRegister(reg, (msb << 8) | lsb);
|
||||
} else if(_state.SFR.Alt2) {
|
||||
//SM - Store Memory
|
||||
_state.RamAddress = ReadOperand();
|
||||
_state.RamAddress |= ReadOperand() << 8;
|
||||
|
||||
WriteRam(_state.RamAddress, (uint8_t)_state.R[reg]);
|
||||
WriteRam(_state.RamAddress ^ 0x01, _state.R[reg] >> 8);
|
||||
} else {
|
||||
//IWT - Load immediate word
|
||||
uint8_t lsb = ReadOperand();
|
||||
uint8_t msb = ReadOperand();
|
||||
WriteRegister(reg, (msb << 8) | lsb);
|
||||
}
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::OrXor(uint8_t operand)
|
||||
{
|
||||
uint16_t operandValue;
|
||||
if(_state.SFR.Alt2) {
|
||||
//Immediate value
|
||||
operandValue = operand;
|
||||
} else {
|
||||
//Indirect register value
|
||||
operandValue = _state.R[operand];
|
||||
}
|
||||
|
||||
uint16_t value;
|
||||
if(_state.SFR.Alt1) {
|
||||
//XOR
|
||||
value = ReadSrcReg() ^ operandValue;
|
||||
} else {
|
||||
//OR
|
||||
value = ReadSrcReg() | operandValue;
|
||||
}
|
||||
WriteDestReg(value);
|
||||
_state.SFR.Zero = value == 0;
|
||||
_state.SFR.Sign = (value & 0x8000) != 0;
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::INC(uint8_t reg)
|
||||
{
|
||||
WriteRegister(reg, _state.R[reg] + 1);
|
||||
_state.SFR.Zero = _state.R[reg] == 0;
|
||||
_state.SFR.Sign = (_state.R[reg] & 0x8000) != 0;
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::DEC(uint8_t reg)
|
||||
{
|
||||
WriteRegister(reg, _state.R[reg] - 1);
|
||||
_state.SFR.Zero = _state.R[reg] == 0;
|
||||
_state.SFR.Sign = (_state.R[reg] & 0x8000) != 0;
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::GetCRamBRomB()
|
||||
{
|
||||
if(!_state.SFR.Alt2) {
|
||||
//GETC - "Get byte from ROM to color register"
|
||||
_state.ColorReg = GetColor(ReadRomBuffer());
|
||||
} else if(!_state.SFR.Alt1) {
|
||||
//RAMB - "Set RAM data bank"
|
||||
WaitRamOperation();
|
||||
_state.RamBank = ReadSrcReg() & 0x01;
|
||||
} else {
|
||||
//ROMB - "Set ROM data bank"
|
||||
WaitRomOperation();
|
||||
_state.RomBank = ReadSrcReg() & 0x7F;
|
||||
}
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::GETB()
|
||||
{
|
||||
if(_state.SFR.Alt2 && _state.SFR.Alt1) {
|
||||
//GETBS - "Get signed byte from ROM buffer"
|
||||
WriteDestReg((int8_t)ReadRomBuffer());
|
||||
} else if(_state.SFR.Alt2) {
|
||||
//GETBL - "Get low byte from ROM buffer"
|
||||
WriteDestReg((ReadSrcReg() & 0xFF00) | ReadRomBuffer());
|
||||
} else if(_state.SFR.Alt1) {
|
||||
//GETBH - "Get high byte from ROM buffer"
|
||||
WriteDestReg((ReadSrcReg() & 0xFF) | (ReadRomBuffer() << 8));
|
||||
} else {
|
||||
//GETB - "Get byte from ROM buffer"
|
||||
WriteDestReg(ReadRomBuffer());
|
||||
}
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::PlotRpix()
|
||||
{
|
||||
if(_state.SFR.Alt1) {
|
||||
//RPIX - "Read pixel color"
|
||||
uint8_t value = ReadPixel((uint8_t)_state.R[1], (uint8_t)_state.R[2]);
|
||||
_state.SFR.Zero = (value == 0);
|
||||
_state.SFR.Sign = (value & 0x8000);
|
||||
} else {
|
||||
//PLOT
|
||||
DrawPixel((uint8_t)_state.R[1], (uint8_t)_state.R[2]);
|
||||
_state.R[1]++;
|
||||
}
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
void Gsu::ColorCMode()
|
||||
{
|
||||
if(_state.SFR.Alt1) {
|
||||
//CMODE - "Set plot mode"
|
||||
uint8_t value = (uint8_t)ReadSrcReg();
|
||||
_state.PlotTransparent = (value & 0x01) != 0;
|
||||
_state.PlotDither = (value & 0x02) != 0;
|
||||
_state.ColorHighNibble = (value & 0x04) != 0;
|
||||
_state.ColorFreezeHigh = (value & 0x08) != 0;
|
||||
_state.ObjMode = (value & 0x10) != 0;
|
||||
} else {
|
||||
//COLOR - "Set plot color"
|
||||
_state.ColorReg = GetColor((uint8_t)ReadSrcReg());
|
||||
}
|
||||
ResetFlags();
|
||||
}
|
||||
|
||||
uint16_t Gsu::GetTileIndex(uint8_t x, uint8_t y)
|
||||
{
|
||||
switch(_state.ObjMode ? 3 : _state.ScreenHeight) {
|
||||
default:
|
||||
case 0: return ((x & 0xF8) << 1) + ((y & 0xF8) >> 3); break;
|
||||
case 1: return ((x & 0xF8) << 1) + ((x & 0xF8) >> 1) + ((y & 0xF8) >> 3); break;
|
||||
case 2: return ((x & 0xF8) << 1) + ((x & 0xF8) << 0) + ((y & 0xF8) >> 3); break;
|
||||
case 3: return ((y & 0x80) << 2) + ((x & 0x80) << 1) + ((y & 0x78) << 1) + ((x & 0x78) >> 3); break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t Gsu::GetTileAddress(uint8_t x, uint8_t y)
|
||||
{
|
||||
uint16_t tileIndex = GetTileIndex(x, y);
|
||||
return (0x700000 | (_state.ScreenBase << 10)) + (tileIndex * (_state.PlotBpp << 3)) + ((y & 0x07) * 2);
|
||||
}
|
||||
|
||||
uint8_t Gsu::ReadPixel(uint8_t x, uint8_t y)
|
||||
{
|
||||
WritePixelCache(_state.SecondaryCache);
|
||||
WritePixelCache(_state.PrimaryCache);
|
||||
|
||||
uint32_t tileAddress = GetTileAddress(x, y);
|
||||
|
||||
x = (x & 7) ^ 7;
|
||||
|
||||
uint8_t data = 0;
|
||||
for(int i = 0; i < _state.PlotBpp; i++) {
|
||||
//Select which byte to read/write based on the current bit (0/1, 16/17, 32/33, 48/49)
|
||||
uint8_t byteOffset = ((i >> 1) << 4) + (i & 0x01);
|
||||
data |= ((ReadGsu(tileAddress + byteOffset, MemoryOperationType::Read) >> x) & 1) << i;
|
||||
Step(_state.ClockSelect ? 5 : 6);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
bool Gsu::IsTransparentPixel()
|
||||
{
|
||||
uint8_t color = _state.ColorFreezeHigh ? (_state.ColorReg & 0x0F) : _state.ColorReg;
|
||||
|
||||
switch(_state.PlotBpp) {
|
||||
default:
|
||||
case 2: return (color & 0x03) == 0;
|
||||
case 4: return (color & 0x0F) == 0;
|
||||
case 8: return color == 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Gsu::DrawPixel(uint8_t x, uint8_t y)
|
||||
{
|
||||
if(!_state.PlotTransparent && IsTransparentPixel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t color = _state.ColorReg;
|
||||
if(_state.PlotDither && _state.PlotBpp != 8) {
|
||||
if((x ^ y) & 0x01) {
|
||||
color >>= 4;
|
||||
}
|
||||
color &= 0x0F;
|
||||
}
|
||||
|
||||
if(_state.PrimaryCache.X != (x & 0xF8) || _state.PrimaryCache.Y != y) {
|
||||
FlushPrimaryCache(x, y);
|
||||
}
|
||||
|
||||
uint8_t xOffset = (x & 7) ^ 7;
|
||||
_state.PrimaryCache.Pixels[xOffset] = color;
|
||||
_state.PrimaryCache.ValidBits |= (1 << xOffset);
|
||||
if(_state.PrimaryCache.ValidBits == 0xFF) {
|
||||
FlushPrimaryCache(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void Gsu::FlushPrimaryCache(uint8_t x, uint8_t y)
|
||||
{
|
||||
WritePixelCache(_state.SecondaryCache);
|
||||
_state.SecondaryCache = _state.PrimaryCache;
|
||||
_state.PrimaryCache.ValidBits = 0;
|
||||
_state.PrimaryCache.X = x & 0xF8;
|
||||
_state.PrimaryCache.Y = y;
|
||||
}
|
||||
|
||||
void Gsu::WritePixelCache(GsuPixelCache &cache)
|
||||
{
|
||||
if(cache.ValidBits == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t tileAddress = GetTileAddress(cache.X, cache.Y);
|
||||
|
||||
for(int i = 0; i < _state.PlotBpp; i++) {
|
||||
uint8_t value = 0;
|
||||
for(int x = 0; x < 8; x++) {
|
||||
value |= ((cache.Pixels[x] >> i) & 0x01) << x;
|
||||
}
|
||||
|
||||
//Select which byte to read/write based on the current bit (0/1, 16/17, 32/33, 48/49)
|
||||
uint8_t byte = ((i >> 1) << 4) + (i & 0x01);
|
||||
|
||||
if(cache.ValidBits != 0xFF) {
|
||||
//Read the pixels in memory before to merge them before writing the cache's content to memory
|
||||
Step(_state.ClockSelect ? 5 : 6);
|
||||
value &= cache.ValidBits;
|
||||
value |= ReadGsu(tileAddress + byte, MemoryOperationType::Read) & ~cache.ValidBits;
|
||||
}
|
||||
|
||||
Step(_state.ClockSelect ? 5 : 6);
|
||||
WaitForRamAccess();
|
||||
WriteGsu(tileAddress + byte, value, MemoryOperationType::Write);
|
||||
}
|
||||
|
||||
cache.ValidBits = 0;
|
||||
}
|
||||
|
||||
uint8_t Gsu::GetColor(uint8_t value)
|
||||
{
|
||||
if(_state.ColorHighNibble) {
|
||||
return (_state.ColorReg & 0xF0) | (value >> 4);
|
||||
}
|
||||
if(_state.ColorFreezeHigh) {
|
||||
return (_state.ColorReg & 0xF0) | (value & 0x0F);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
649
Core/Gsu.cpp
Normal file
649
Core/Gsu.cpp
Normal file
|
@ -0,0 +1,649 @@
|
|||
#include "stdafx.h"
|
||||
#include "Gsu.h"
|
||||
#include "Console.h"
|
||||
#include "Cpu.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "BaseCartridge.h"
|
||||
#include "RamHandler.h"
|
||||
#include "GsuRomHandler.h"
|
||||
#include "GsuRamHandler.h"
|
||||
#include "EmuSettings.h"
|
||||
#include "MessageManager.h"
|
||||
#include "../Utilities/HexUtilities.h"
|
||||
|
||||
Gsu::Gsu(Console *console, uint32_t gsuRamSize)
|
||||
{
|
||||
_console = console;
|
||||
_memoryManager = console->GetMemoryManager().get();
|
||||
_cpu = console->GetCpu().get();
|
||||
_memoryType = SnesMemoryType::Register;
|
||||
_settings = _console->GetSettings().get();
|
||||
|
||||
_clockMultiplier = _settings->GetEmulationConfig().GsuClockSpeed / 100;
|
||||
|
||||
_state = {};
|
||||
_state.ProgramReadBuffer = 0x01; //Run a NOP on first cycle
|
||||
|
||||
_settings->InitializeRam(_cache, 512);
|
||||
|
||||
_gsuRamSize = gsuRamSize;
|
||||
_gsuRam = new uint8_t[_gsuRamSize];
|
||||
_settings->InitializeRam(_gsuRam, _gsuRamSize);
|
||||
|
||||
for(uint32_t i = 0; i < _gsuRamSize / 0x1000; i++) {
|
||||
_gsuRamHandlers.push_back(unique_ptr<IMemoryHandler>(new RamHandler(_gsuRam, i * 0x1000, _gsuRamSize, SnesMemoryType::GsuWorkRam)));
|
||||
_gsuCpuRamHandlers.push_back(unique_ptr<IMemoryHandler>(new GsuRamHandler(_state, _gsuRamHandlers.back().get())));
|
||||
}
|
||||
|
||||
//CPU mappings
|
||||
MemoryMappings *cpuMappings = _memoryManager->GetMemoryMappings();
|
||||
vector<unique_ptr<IMemoryHandler>> &prgRomHandlers = _console->GetCartridge()->GetPrgRomHandlers();
|
||||
for(unique_ptr<IMemoryHandler> &handler : prgRomHandlers) {
|
||||
_gsuCpuRomHandlers.push_back(unique_ptr<IMemoryHandler>(new GsuRomHandler(_state, handler.get())));
|
||||
}
|
||||
|
||||
//GSU registers in CPU memory space
|
||||
cpuMappings->RegisterHandler(0x00, 0x3F, 0x3000, 0x3FFF, this);
|
||||
cpuMappings->RegisterHandler(0x80, 0xBF, 0x3000, 0x3FFF, this);
|
||||
|
||||
for(int i = 0; i < 0x3F; i++) {
|
||||
cpuMappings->RegisterHandler(i, i, 0x6000, 0x7FFF, _gsuCpuRamHandlers);
|
||||
cpuMappings->RegisterHandler(i + 0x80, i + 0x80, 0x6000, 0x7FFF, _gsuCpuRamHandlers);
|
||||
}
|
||||
cpuMappings->RegisterHandler(0x70, 0x71, 0x0000, 0xFFFF, _gsuCpuRamHandlers);
|
||||
cpuMappings->RegisterHandler(0xF0, 0xF1, 0x0000, 0xFFFF, _gsuCpuRamHandlers);
|
||||
|
||||
cpuMappings->RegisterHandler(0x00, 0x3F, 0x8000, 0xFFFF, _gsuCpuRomHandlers);
|
||||
cpuMappings->RegisterHandler(0x80, 0xBF, 0x8000, 0xFFFF, _gsuCpuRomHandlers);
|
||||
|
||||
cpuMappings->RegisterHandler(0x40, 0x5F, 0x0000, 0xFFFF, _gsuCpuRomHandlers);
|
||||
cpuMappings->RegisterHandler(0xC0, 0xDF, 0x0000, 0xFFFF, _gsuCpuRomHandlers);
|
||||
|
||||
//GSU mappings
|
||||
_mappings.RegisterHandler(0x00, 0x3F, 0x8000, 0xFFFF, prgRomHandlers);
|
||||
_mappings.RegisterHandler(0x00, 0x3F, 0x0000, 0x7FFF, prgRomHandlers); //Mirror
|
||||
|
||||
_mappings.RegisterHandler(0x40, 0x5F, 0x0000, 0xFFFF, prgRomHandlers);
|
||||
_mappings.RegisterHandler(0x70, 0x71, 0x0000, 0xFFFF, _gsuRamHandlers);
|
||||
}
|
||||
|
||||
void Gsu::ProcessEndOfFrame()
|
||||
{
|
||||
uint8_t clockMultiplier = _settings->GetEmulationConfig().GsuClockSpeed / 100;
|
||||
if(_clockMultiplier != clockMultiplier) {
|
||||
_state.CycleCount = _state.CycleCount / _clockMultiplier * clockMultiplier;
|
||||
_clockMultiplier = clockMultiplier;
|
||||
}
|
||||
}
|
||||
|
||||
void Gsu::Run()
|
||||
{
|
||||
uint64_t targetCycle = _memoryManager->GetMasterClock() * _clockMultiplier;
|
||||
|
||||
while(!_stopped && _state.CycleCount < targetCycle) {
|
||||
Exec();
|
||||
}
|
||||
|
||||
if(targetCycle > _state.CycleCount) {
|
||||
Step(targetCycle - _state.CycleCount);
|
||||
}
|
||||
}
|
||||
|
||||
void Gsu::Exec()
|
||||
{
|
||||
uint8_t opCode = ReadOpCode();
|
||||
|
||||
switch(opCode) {
|
||||
case 0x00: STOP(); break;
|
||||
case 0x01: NOP(); break;
|
||||
case 0x02: CACHE(); break;
|
||||
case 0x03: LSR(); break;
|
||||
case 0x04: ROL(); break;
|
||||
case 0x05: BRA(); break;
|
||||
case 0x06: BLT(); break;
|
||||
case 0x07: BGE(); break;
|
||||
case 0x08: BNE(); break;
|
||||
case 0x09: BEQ(); break;
|
||||
case 0x0A: BPL(); break;
|
||||
case 0x0B: BMI(); break;
|
||||
case 0x0C: BCC(); break;
|
||||
case 0x0D: BCS(); break;
|
||||
case 0x0E: BCV(); break;
|
||||
case 0x0F: BVS(); break;
|
||||
|
||||
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
|
||||
case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1E: case 0x1F:
|
||||
TO(opCode & 0x0F);
|
||||
break;
|
||||
|
||||
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
|
||||
case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2E: case 0x2F:
|
||||
WITH(opCode & 0x0F);
|
||||
break;
|
||||
|
||||
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
|
||||
case 0x38: case 0x39: case 0x3A: case 0x3B:
|
||||
STORE(opCode & 0x0F);
|
||||
break;
|
||||
|
||||
case 0x3C: LOOP(); break;
|
||||
case 0x3D: ALT1(); break;
|
||||
case 0x3E: ALT2(); break;
|
||||
case 0x3F: ALT3(); break;
|
||||
|
||||
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
|
||||
case 0x48: case 0x49: case 0x4A: case 0x4B:
|
||||
LOAD(opCode & 0x0F);
|
||||
break;
|
||||
|
||||
case 0x4C: PlotRpix(); break;
|
||||
case 0x4D: SWAP(); break;
|
||||
case 0x4E: ColorCMode(); break;
|
||||
case 0x4F: NOT(); break;
|
||||
|
||||
case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
|
||||
case 0x58: case 0x59: case 0x5A: case 0x5B: case 0x5C: case 0x5D: case 0x5E: case 0x5F:
|
||||
Add(opCode & 0x0F);
|
||||
break;
|
||||
|
||||
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
|
||||
case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6D: case 0x6E: case 0x6F:
|
||||
SubCompare(opCode & 0x0F);
|
||||
break;
|
||||
|
||||
case 0x70: MERGE(); break;
|
||||
|
||||
case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
|
||||
case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D: case 0x7E: case 0x7F:
|
||||
AndBitClear(opCode & 0x0F);
|
||||
break;
|
||||
|
||||
case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
|
||||
case 0x88: case 0x89: case 0x8A: case 0x8B: case 0x8C: case 0x8D: case 0x8E: case 0x8F:
|
||||
MULT(opCode & 0x0F);
|
||||
break;
|
||||
|
||||
case 0x90: SBK(); break;
|
||||
|
||||
case 0x91: LINK(1); break;
|
||||
case 0x92: LINK(2); break;
|
||||
case 0x93: LINK(3); break;
|
||||
case 0x94: LINK(4); break;
|
||||
|
||||
case 0x95: SignExtend(); break;
|
||||
|
||||
case 0x96: ASR(); break;
|
||||
case 0x97: ROR(); break;
|
||||
|
||||
case 0x98: case 0x99: case 0x9A: case 0x9B: case 0x9C: case 0x9D:
|
||||
JMP(opCode & 0x0F);
|
||||
break;
|
||||
|
||||
case 0x9E: LOB(); break;
|
||||
case 0x9F: FMultLMult(); break;
|
||||
|
||||
case 0xA0: case 0xA1: case 0xA2: case 0xA3: case 0xA4: case 0xA5: case 0xA6: case 0xA7:
|
||||
case 0xA8: case 0xA9: case 0xAA: case 0xAB: case 0xAC: case 0xAD: case 0xAE: case 0xAF:
|
||||
IbtSmsLms(opCode & 0x0F);
|
||||
break;
|
||||
|
||||
case 0xB0: case 0xB1: case 0xB2: case 0xB3: case 0xB4: case 0xB5: case 0xB6: case 0xB7:
|
||||
case 0xB8: case 0xB9: case 0xBA: case 0xBB: case 0xBC: case 0xBD: case 0xBE: case 0xBF:
|
||||
FROM(opCode & 0x0F);
|
||||
break;
|
||||
|
||||
case 0xC0: HIB(); break;
|
||||
|
||||
case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7:
|
||||
case 0xC8: case 0xC9: case 0xCA: case 0xCB: case 0xCC: case 0xCD: case 0xCE: case 0xCF:
|
||||
OrXor(opCode & 0x0F);
|
||||
break;
|
||||
|
||||
case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: case 0xD5: case 0xD6: case 0xD7:
|
||||
case 0xD8: case 0xD9: case 0xDA: case 0xDB: case 0xDC: case 0xDD: case 0xDE:
|
||||
INC(opCode & 0x0F);
|
||||
break;
|
||||
|
||||
case 0xDF: GetCRamBRomB(); break;
|
||||
|
||||
case 0xE0: case 0xE1: case 0xE2: case 0xE3: case 0xE4: case 0xE5: case 0xE6: case 0xE7:
|
||||
case 0xE8: case 0xE9: case 0xEA: case 0xEB: case 0xEC: case 0xED: case 0xEE:
|
||||
DEC(opCode & 0x0F);
|
||||
break;
|
||||
|
||||
case 0xEF: GETB(); break;
|
||||
|
||||
case 0xF0: case 0xF1: case 0xF2: case 0xF3: case 0xF4: case 0xF5: case 0xF6: case 0xF7:
|
||||
case 0xF8: case 0xF9: case 0xFA: case 0xFB: case 0xFC: case 0xFD: case 0xFE: case 0xFF:
|
||||
IwtLmSm(opCode & 0x0F);
|
||||
break;
|
||||
}
|
||||
|
||||
_console->ProcessMemoryRead<CpuType::Gsu>(_lastOpAddr, _state.ProgramReadBuffer, MemoryOperationType::ExecOpCode);
|
||||
|
||||
if(!_r15Changed) {
|
||||
_state.R[15]++;
|
||||
} else {
|
||||
_r15Changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Gsu::ReadGsu(uint32_t addr, MemoryOperationType opType)
|
||||
{
|
||||
IMemoryHandler *handler = _mappings.GetHandler(addr);
|
||||
uint8_t value;
|
||||
if(handler) {
|
||||
value = handler->Read(addr);
|
||||
} else {
|
||||
//TODO: Open bus?
|
||||
value = 0;
|
||||
LogDebug("[Debug] GSU - Missing read handler: " + HexUtilities::ToHex(addr));
|
||||
}
|
||||
_console->ProcessMemoryRead<CpuType::Gsu>(addr, value, opType);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void Gsu::WriteGsu(uint32_t addr, uint8_t value, MemoryOperationType opType)
|
||||
{
|
||||
IMemoryHandler *handler = _mappings.GetHandler(addr);
|
||||
if(handler) {
|
||||
handler->Write(addr, value);
|
||||
} else {
|
||||
LogDebug("[Debug] GSU - Missing write handler: " + HexUtilities::ToHex(addr));
|
||||
}
|
||||
_console->ProcessMemoryWrite<CpuType::Gsu>(addr, value, opType);
|
||||
}
|
||||
|
||||
void Gsu::InitProgramCache(uint16_t cacheAddr)
|
||||
{
|
||||
uint16_t dest = (cacheAddr & 0x01F0);
|
||||
|
||||
if(_state.ProgramBank <= 0x5F) {
|
||||
WaitRomOperation();
|
||||
WaitForRomAccess();
|
||||
} else {
|
||||
WaitRamOperation();
|
||||
WaitForRamAccess();
|
||||
}
|
||||
|
||||
uint32_t srcBaseAddr = (_state.ProgramBank << 16) + _state.CacheBase + dest;
|
||||
for(int i = 0; i < 16; i++) {
|
||||
_cache[dest + i] = ReadGsu(srcBaseAddr + i, MemoryOperationType::Read);
|
||||
}
|
||||
Step(_state.ClockSelect ? 5*16 : 6*16);
|
||||
|
||||
_cacheValid[cacheAddr >> 4] = true;
|
||||
}
|
||||
|
||||
uint8_t Gsu::ReadOperand()
|
||||
{
|
||||
uint8_t result = _state.ProgramReadBuffer;
|
||||
_state.R[15]++;
|
||||
_state.ProgramReadBuffer = ReadProgramByte(MemoryOperationType::Read);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t Gsu::ReadOpCode()
|
||||
{
|
||||
uint8_t result = _state.ProgramReadBuffer;
|
||||
_state.ProgramReadBuffer = ReadProgramByte(MemoryOperationType::Read);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t Gsu::ReadProgramByte(MemoryOperationType opType)
|
||||
{
|
||||
_lastOpAddr = (_state.ProgramBank << 16) | _state.R[15];
|
||||
uint16_t cacheAddr = _state.R[15] - _state.CacheBase;
|
||||
if(cacheAddr < 512) {
|
||||
if(!_cacheValid[cacheAddr >> 4]) {
|
||||
InitProgramCache(cacheAddr & 0xFFF0);
|
||||
}
|
||||
|
||||
Step(_state.ClockSelect ? 1 : 2);
|
||||
_console->ProcessMemoryRead<CpuType::Gsu>(_lastOpAddr, _cache[cacheAddr], opType);
|
||||
return _cache[cacheAddr];
|
||||
} else {
|
||||
if(_state.ProgramBank <= 0x5F) {
|
||||
WaitRomOperation();
|
||||
WaitForRomAccess();
|
||||
} else {
|
||||
WaitRamOperation();
|
||||
WaitForRamAccess();
|
||||
}
|
||||
Step(_state.ClockSelect ? 5 : 6);
|
||||
return ReadGsu(_lastOpAddr, opType);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t Gsu::ReadSrcReg()
|
||||
{
|
||||
return _state.R[_state.SrcReg];
|
||||
}
|
||||
|
||||
void Gsu::WriteDestReg(uint16_t value)
|
||||
{
|
||||
WriteRegister(_state.DestReg, value);
|
||||
}
|
||||
|
||||
void Gsu::WriteRegister(uint8_t reg, uint16_t value)
|
||||
{
|
||||
_state.R[reg] = value;
|
||||
|
||||
if(reg == 14) {
|
||||
_state.SFR.RomReadPending = true;
|
||||
_state.RomDelay = _state.ClockSelect ? 5 : 6;
|
||||
} else if(reg == 15) {
|
||||
_r15Changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Gsu::ResetFlags()
|
||||
{
|
||||
_state.SFR.Prefix = 0;
|
||||
_state.SFR.Alt1 = false;
|
||||
_state.SFR.Alt2 = false;
|
||||
|
||||
_state.SrcReg = 0;
|
||||
_state.DestReg = 0;
|
||||
}
|
||||
|
||||
void Gsu::InvalidateCache()
|
||||
{
|
||||
memset(_cacheValid, 0, sizeof(_cacheValid));
|
||||
}
|
||||
|
||||
void Gsu::WaitRomOperation()
|
||||
{
|
||||
if(_state.RomDelay) {
|
||||
//Wait for existing RAM operation to complete
|
||||
Step(_state.RomDelay);
|
||||
}
|
||||
}
|
||||
|
||||
void Gsu::WaitRamOperation()
|
||||
{
|
||||
if(_state.RamDelay) {
|
||||
//Wait for existing RAM operation to complete
|
||||
Step(_state.RamDelay);
|
||||
}
|
||||
}
|
||||
|
||||
void Gsu::WaitForRomAccess()
|
||||
{
|
||||
if(!_state.GsuRomAccess) {
|
||||
_waitForRomAccess = true;
|
||||
_stopped = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Gsu::WaitForRamAccess()
|
||||
{
|
||||
if(!_state.GsuRamAccess) {
|
||||
_waitForRamAccess = true;
|
||||
_stopped = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Gsu::UpdateRunningState()
|
||||
{
|
||||
_stopped = !_state.SFR.Running || _waitForRamAccess || _waitForRomAccess;
|
||||
}
|
||||
|
||||
uint8_t Gsu::ReadRomBuffer()
|
||||
{
|
||||
WaitRomOperation();
|
||||
return _state.RomReadBuffer;
|
||||
}
|
||||
|
||||
uint8_t Gsu::ReadRamBuffer(uint16_t addr)
|
||||
{
|
||||
WaitRamOperation();
|
||||
WaitForRamAccess();
|
||||
return ReadGsu(0x700000 | (_state.RamBank << 16) | addr, MemoryOperationType::Read);
|
||||
}
|
||||
|
||||
void Gsu::WriteRam(uint16_t addr, uint8_t value)
|
||||
{
|
||||
WaitRamOperation();
|
||||
|
||||
_state.RamDelay = _state.ClockSelect ? 5 : 6;
|
||||
_state.RamWriteAddress = addr;
|
||||
_state.RamWriteValue = value;
|
||||
}
|
||||
|
||||
void Gsu::Step(uint64_t cycles)
|
||||
{
|
||||
_state.CycleCount += cycles;
|
||||
|
||||
if(_state.RomDelay) {
|
||||
_state.RomDelay -= std::min<uint8_t>((uint8_t)cycles, _state.RomDelay);
|
||||
if(_state.RomDelay == 0) {
|
||||
WaitForRomAccess();
|
||||
_state.RomReadBuffer = ReadGsu((_state.RomBank << 16) | _state.R[14], MemoryOperationType::Read);
|
||||
_state.SFR.RomReadPending = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(_state.RamDelay) {
|
||||
_state.RamDelay -= std::min<uint8_t>((uint8_t)cycles, _state.RamDelay);
|
||||
if(_state.RamDelay == 0) {
|
||||
WaitForRamAccess();
|
||||
WriteGsu(0x700000 | (_state.RamBank << 16) | _state.RamWriteAddress, _state.RamWriteValue, MemoryOperationType::Write);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Gsu::Reset()
|
||||
{
|
||||
_state = {};
|
||||
_state.ProgramReadBuffer = 0x01; //Run a NOP on first cycle
|
||||
|
||||
_console->GetSettings()->InitializeRam(_cache, 512);
|
||||
memset(_cacheValid, 0, sizeof(_cacheValid));
|
||||
_waitForRomAccess = false;
|
||||
_waitForRamAccess = false;
|
||||
_stopped = true;
|
||||
_lastOpAddr = 0;
|
||||
}
|
||||
|
||||
uint8_t Gsu::Read(uint32_t addr)
|
||||
{
|
||||
addr &= 0x33FF;
|
||||
if(_state.SFR.Running && addr != 0x3030 && addr != 0x3031 && addr != 0x303B) {
|
||||
//"During GSU operation, only SFR, SCMR, and VCR may be accessed."
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x3000: case 0x3002: case 0x3004: case 0x3006: case 0x3008: case 0x300A: case 0x300C:case 0x300E:
|
||||
case 0x3010: case 0x3012: case 0x3014: case 0x3016: case 0x3018: case 0x301A: case 0x301C:case 0x301E:
|
||||
return (uint8_t)_state.R[(addr >> 1) & 0x0F];
|
||||
|
||||
case 0x3001: case 0x3003: case 0x3005: case 0x3007: case 0x3009: case 0x300B: case 0x300D:case 0x300F:
|
||||
case 0x3011: case 0x3013: case 0x3015: case 0x3017: case 0x3019: case 0x301B: case 0x301D:case 0x301F:
|
||||
return _state.R[(addr >> 1) & 0x0F] >> 8;
|
||||
|
||||
case 0x3030: return _state.SFR.GetFlagsLow();
|
||||
case 0x3031: {
|
||||
uint8_t flags = _state.SFR.GetFlagsHigh();
|
||||
_state.SFR.Irq = false;
|
||||
_cpu->ClearIrqSource(IrqSource::Coprocessor);
|
||||
return flags;
|
||||
}
|
||||
|
||||
case 0x3034: return _state.ProgramBank;
|
||||
case 0x3036: return _state.RomBank;
|
||||
case 0x303B: return 0x04; //Version (can be 1 or 4?)
|
||||
case 0x303C: return _state.RamBank;
|
||||
case 0x303E: return (uint8_t)_state.CacheBase;
|
||||
case 0x303F: return _state.CacheBase >> 8;
|
||||
}
|
||||
|
||||
if(addr >= 0x3100 && addr <= 0x32FF) {
|
||||
return _cache[(_state.CacheBase + (addr - 0x3100)) & 0x1FF];
|
||||
}
|
||||
|
||||
LogDebug("[Debug] Missing read handler: $" + HexUtilities::ToHex(addr));
|
||||
|
||||
//TODO open bus and proper mirroring?
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Gsu::Write(uint32_t addr, uint8_t value)
|
||||
{
|
||||
addr &= 0x33FF;
|
||||
if(_state.SFR.Running && addr != 0x3030 && addr != 0x303A) {
|
||||
//"During GSU operation, only SFR, SCMR, and VCR may be accessed."
|
||||
return;
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x3000: case 0x3002: case 0x3004: case 0x3006: case 0x3008: case 0x300A: case 0x300C: case 0x300E:
|
||||
case 0x3010: case 0x3012: case 0x3014: case 0x3016: case 0x3018: case 0x301A: case 0x301C: case 0x301E:
|
||||
_state.RegisterLatch = value;
|
||||
break;
|
||||
|
||||
case 0x3001: case 0x3003: case 0x3005: case 0x3007: case 0x3009: case 0x300B: case 0x300D: case 0x300F:
|
||||
case 0x3011: case 0x3013: case 0x3015: case 0x3017: case 0x3019: case 0x301B: case 0x301D: case 0x301F: {
|
||||
uint8_t reg = (addr >> 1) & 0x0F;
|
||||
_state.R[reg] = (value << 8) | _state.RegisterLatch;
|
||||
|
||||
if(reg == 14) {
|
||||
_state.SFR.RomReadPending = true;
|
||||
_state.RomDelay = _state.ClockSelect ? 5 : 6;
|
||||
} else if(addr == 0x301F) {
|
||||
_state.SFR.Running = true;
|
||||
UpdateRunningState();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x3030: {
|
||||
bool running = _state.SFR.Running;
|
||||
_state.SFR.Zero = (value & 0x02) != 0;
|
||||
_state.SFR.Carry = (value & 0x04) != 0;
|
||||
_state.SFR.Sign = (value & 0x08) != 0;
|
||||
_state.SFR.Overflow = (value & 0x10) != 0;
|
||||
_state.SFR.Running = (value & 0x20) != 0;
|
||||
|
||||
if(running && !_state.SFR.Running) {
|
||||
_state.CacheBase = 0;
|
||||
InvalidateCache();
|
||||
}
|
||||
UpdateRunningState();
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x3033: _state.BackupRamEnabled = (value & 0x01); break;
|
||||
case 0x3034: _state.ProgramBank = (value & 0x7F); InvalidateCache(); break;
|
||||
|
||||
case 0x3037:
|
||||
_state.HighSpeedMode = (value & 0x20) != 0;
|
||||
_state.IrqDisabled = (value & 0x80) != 0;
|
||||
break;
|
||||
|
||||
case 0x3038: _state.ScreenBase = value; break;
|
||||
case 0x3039: _state.ClockSelect = (value & 0x01); break;
|
||||
|
||||
case 0x303A:
|
||||
_state.ColorGradient = (value & 0x03);
|
||||
switch(_state.ColorGradient) {
|
||||
case 0: _state.PlotBpp = 2; break;
|
||||
case 1: _state.PlotBpp = 4; break;
|
||||
case 2: _state.PlotBpp = 4; break;
|
||||
case 3: _state.PlotBpp = 8; break;
|
||||
}
|
||||
_state.ScreenHeight = ((value & 0x04) >> 2) | ((value & 0x20) >> 4);
|
||||
_state.GsuRamAccess = (value & 0x08) != 0;
|
||||
_state.GsuRomAccess = (value & 0x10) != 0;
|
||||
|
||||
if(_state.GsuRamAccess) {
|
||||
_waitForRamAccess = false;
|
||||
}
|
||||
if(_state.GsuRomAccess) {
|
||||
_waitForRomAccess = false;
|
||||
}
|
||||
UpdateRunningState();
|
||||
break;
|
||||
}
|
||||
|
||||
if(addr >= 0x3100 && addr <= 0x32FF) {
|
||||
uint16_t cacheAddr = (_state.CacheBase + (addr - 0x3100)) & 0x1FF;
|
||||
_cache[cacheAddr] = value;
|
||||
if((cacheAddr & 0x0F) == 0x0F) {
|
||||
_cacheValid[cacheAddr >> 4] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Gsu::Peek(uint32_t addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Gsu::PeekBlock(uint8_t *output)
|
||||
{
|
||||
memset(output, 0, 0x1000);
|
||||
}
|
||||
|
||||
AddressInfo Gsu::GetAbsoluteAddress(uint32_t address)
|
||||
{
|
||||
return { -1, SnesMemoryType::Register };
|
||||
}
|
||||
|
||||
void Gsu::Serialize(Serializer &s)
|
||||
{
|
||||
s.Stream(
|
||||
_state.CycleCount, _state.RegisterLatch, _state.ProgramBank, _state.RomBank, _state.RamBank, _state.IrqDisabled,
|
||||
_state.HighSpeedMode, _state.ClockSelect, _state.BackupRamEnabled, _state.ScreenBase, _state.ColorGradient, _state.PlotBpp,
|
||||
_state.ScreenHeight, _state.GsuRamAccess, _state.GsuRomAccess, _state.CacheBase, _state.PlotTransparent, _state.PlotDither,
|
||||
_state.ColorHighNibble, _state.ColorFreezeHigh, _state.ObjMode, _state.ColorReg, _state.SrcReg, _state.DestReg,
|
||||
_state.RomReadBuffer, _state.RomDelay, _state.ProgramReadBuffer, _state.RamWriteAddress, _state.RamWriteValue, _state.RamDelay,
|
||||
_state.RamAddress, _state.PrimaryCache.X, _state.PrimaryCache.Y, _state.PrimaryCache.ValidBits, _state.SecondaryCache.X,
|
||||
_state.SecondaryCache.Y, _state.SecondaryCache.ValidBits,
|
||||
_state.SFR.Alt1, _state.SFR.Alt2, _state.SFR.Carry, _state.SFR.ImmHigh, _state.SFR.ImmLow, _state.SFR.Irq, _state.SFR.Overflow,
|
||||
_state.SFR.Prefix, _state.SFR.RomReadPending, _state.SFR.Running, _state.SFR.Sign, _state.SFR.Zero
|
||||
);
|
||||
|
||||
s.StreamArray(_state.R, 16);
|
||||
s.StreamArray(_state.PrimaryCache.Pixels, 8);
|
||||
s.StreamArray(_state.SecondaryCache.Pixels, 8);
|
||||
|
||||
s.Stream(_waitForRamAccess, _waitForRomAccess, _stopped);
|
||||
s.StreamArray(_cacheValid, 32);
|
||||
s.StreamArray(_cache, 512);
|
||||
s.StreamArray(_gsuRam, _gsuRamSize);
|
||||
}
|
||||
|
||||
void Gsu::LoadBattery(string filePath)
|
||||
{
|
||||
VirtualFile saveFile(filePath);
|
||||
saveFile.ReadFile((uint8_t*)_gsuRam, _gsuRamSize);
|
||||
}
|
||||
|
||||
void Gsu::SaveBattery(string filePath)
|
||||
{
|
||||
ofstream saveFile(filePath, ios::binary);
|
||||
saveFile.write((char*)_gsuRam, _gsuRamSize);
|
||||
}
|
||||
|
||||
GsuState Gsu::GetState()
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
|
||||
MemoryMappings* Gsu::GetMemoryMappings()
|
||||
{
|
||||
return &_mappings;
|
||||
}
|
||||
|
||||
uint8_t* Gsu::DebugGetWorkRam()
|
||||
{
|
||||
return _gsuRam;
|
||||
}
|
||||
|
||||
uint32_t Gsu::DebugGetWorkRamSize()
|
||||
{
|
||||
return _gsuRamSize;
|
||||
}
|
172
Core/Gsu.h
Normal file
172
Core/Gsu.h
Normal file
|
@ -0,0 +1,172 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "BaseCoprocessor.h"
|
||||
#include "GsuTypes.h"
|
||||
#include "MemoryMappings.h"
|
||||
#include "IMemoryHandler.h"
|
||||
|
||||
class Console;
|
||||
class Cpu;
|
||||
class MemoryManager;
|
||||
class EmuSettings;
|
||||
|
||||
class Gsu : public BaseCoprocessor
|
||||
{
|
||||
private:
|
||||
Console *_console;
|
||||
MemoryManager *_memoryManager;
|
||||
Cpu *_cpu;
|
||||
EmuSettings *_settings;
|
||||
uint8_t _clockMultiplier;
|
||||
|
||||
GsuState _state;
|
||||
|
||||
uint8_t _cache[512];
|
||||
bool _cacheValid[32] = {};
|
||||
bool _waitForRomAccess = false;
|
||||
bool _waitForRamAccess = false;
|
||||
bool _stopped = true;
|
||||
bool _r15Changed = false;
|
||||
uint32_t _lastOpAddr = 0;
|
||||
|
||||
uint32_t _gsuRamSize = 0;
|
||||
uint8_t* _gsuRam = nullptr;
|
||||
|
||||
MemoryMappings _mappings;
|
||||
vector<unique_ptr<IMemoryHandler>> _gsuRamHandlers;
|
||||
vector<unique_ptr<IMemoryHandler>> _gsuCpuRamHandlers;
|
||||
vector<unique_ptr<IMemoryHandler>> _gsuCpuRomHandlers;
|
||||
|
||||
void Exec();
|
||||
|
||||
void InitProgramCache(uint16_t cacheAddr);
|
||||
|
||||
uint8_t ReadOperand();
|
||||
uint8_t ReadOpCode();
|
||||
uint8_t ReadProgramByte(MemoryOperationType opType);
|
||||
|
||||
uint16_t ReadSrcReg();
|
||||
void WriteDestReg(uint16_t value);
|
||||
void WriteRegister(uint8_t reg, uint16_t value);
|
||||
|
||||
void ResetFlags();
|
||||
void InvalidateCache();
|
||||
|
||||
void WaitRomOperation();
|
||||
void WaitRamOperation();
|
||||
|
||||
void WaitForRomAccess();
|
||||
void WaitForRamAccess();
|
||||
void UpdateRunningState();
|
||||
|
||||
uint8_t ReadRomBuffer();
|
||||
uint8_t ReadRamBuffer(uint16_t addr);
|
||||
void WriteRam(uint16_t addr, uint8_t value);
|
||||
void Step(uint64_t cycles);
|
||||
|
||||
void STOP();
|
||||
void NOP();
|
||||
void CACHE();
|
||||
|
||||
void Branch(bool branch);
|
||||
|
||||
void BRA();
|
||||
void BLT();
|
||||
void BGE();
|
||||
void BNE();
|
||||
void BEQ();
|
||||
void BPL();
|
||||
void BMI();
|
||||
void BCC();
|
||||
void BCS();
|
||||
void BCV();
|
||||
void BVS();
|
||||
void JMP(uint8_t reg);
|
||||
|
||||
void TO(uint8_t reg);
|
||||
void FROM(uint8_t reg);
|
||||
void WITH(uint8_t reg);
|
||||
|
||||
void STORE(uint8_t reg);
|
||||
void LOAD(uint8_t reg);
|
||||
|
||||
void LOOP();
|
||||
void ALT1();
|
||||
void ALT2();
|
||||
void ALT3();
|
||||
|
||||
void MERGE();
|
||||
void SWAP();
|
||||
|
||||
void PlotRpix();
|
||||
void ColorCMode();
|
||||
|
||||
uint16_t GetTileIndex(uint8_t x, uint8_t y);
|
||||
uint32_t GetTileAddress(uint8_t x, uint8_t y);
|
||||
|
||||
uint8_t ReadPixel(uint8_t x, uint8_t y);
|
||||
bool IsTransparentPixel();
|
||||
void DrawPixel(uint8_t x, uint8_t y);
|
||||
void FlushPrimaryCache(uint8_t x, uint8_t y);
|
||||
void WritePixelCache(GsuPixelCache &cache);
|
||||
|
||||
uint8_t GetColor(uint8_t source);
|
||||
|
||||
void Add(uint8_t reg);
|
||||
void SubCompare(uint8_t reg);
|
||||
void MULT(uint8_t reg);
|
||||
void FMultLMult();
|
||||
|
||||
void AndBitClear(uint8_t reg);
|
||||
void SBK();
|
||||
|
||||
void LINK(uint8_t reg);
|
||||
|
||||
void SignExtend();
|
||||
|
||||
void NOT();
|
||||
void LSR();
|
||||
void ROL();
|
||||
void ASR();
|
||||
void ROR();
|
||||
|
||||
void LOB();
|
||||
void HIB();
|
||||
|
||||
void IbtSmsLms(uint8_t reg);
|
||||
void IwtLmSm(uint8_t reg);
|
||||
|
||||
void OrXor(uint8_t reg);
|
||||
void INC(uint8_t reg);
|
||||
void DEC(uint8_t reg);
|
||||
|
||||
void GetCRamBRomB();
|
||||
void GETB();
|
||||
|
||||
public:
|
||||
Gsu(Console *console, uint32_t gsuRamSize);
|
||||
|
||||
void ProcessEndOfFrame() override;
|
||||
|
||||
uint8_t ReadGsu(uint32_t addr, MemoryOperationType opType);
|
||||
void WriteGsu(uint32_t addr, uint8_t value, MemoryOperationType opType);
|
||||
|
||||
void LoadBattery(string filePath) override;
|
||||
void SaveBattery(string filePath) override;
|
||||
|
||||
void Run();
|
||||
void Reset() override;
|
||||
|
||||
uint8_t Read(uint32_t addr) override;
|
||||
uint8_t Peek(uint32_t addr) override;
|
||||
void PeekBlock(uint8_t *output) override;
|
||||
void Write(uint32_t addr, uint8_t value) override;
|
||||
AddressInfo GetAbsoluteAddress(uint32_t address) override;
|
||||
|
||||
void Serialize(Serializer &s) override;
|
||||
|
||||
GsuState GetState();
|
||||
MemoryMappings* GetMemoryMappings();
|
||||
uint8_t* DebugGetWorkRam();
|
||||
uint32_t DebugGetWorkRamSize();
|
||||
};
|
95
Core/GsuDebugger.cpp
Normal file
95
Core/GsuDebugger.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
#include "stdafx.h"
|
||||
#include "GsuDebugger.h"
|
||||
#include "DisassemblyInfo.h"
|
||||
#include "Disassembler.h"
|
||||
#include "BaseCartridge.h"
|
||||
#include "Gsu.h"
|
||||
#include "TraceLogger.h"
|
||||
#include "CallstackManager.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "Debugger.h"
|
||||
#include "Console.h"
|
||||
#include "MemoryAccessCounter.h"
|
||||
|
||||
GsuDebugger::GsuDebugger(Debugger* debugger)
|
||||
{
|
||||
_debugger = debugger;
|
||||
_traceLogger = debugger->GetTraceLogger().get();
|
||||
_disassembler = debugger->GetDisassembler().get();
|
||||
_memoryAccessCounter = debugger->GetMemoryAccessCounter().get();
|
||||
_gsu = debugger->GetConsole()->GetCartridge()->GetGsu();
|
||||
_memoryManager = debugger->GetConsole()->GetMemoryManager().get();
|
||||
|
||||
_step.reset(new StepRequest());
|
||||
}
|
||||
|
||||
void GsuDebugger::Reset()
|
||||
{
|
||||
_prevOpCode = 0xFF;
|
||||
}
|
||||
|
||||
void GsuDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType type)
|
||||
{
|
||||
if(type == MemoryOperationType::DummyRead) {
|
||||
//Ignore all dummy reads for now
|
||||
return;
|
||||
}
|
||||
|
||||
AddressInfo addressInfo = _gsu->GetMemoryMappings()->GetAbsoluteAddress(addr);
|
||||
MemoryOperationInfo operation { addr, value, type };
|
||||
|
||||
if(type == MemoryOperationType::ExecOpCode) {
|
||||
DebugState debugState;
|
||||
_debugger->GetState(debugState, true);
|
||||
|
||||
_disassembler->BuildCache(addressInfo, debugState.Gsu.SFR.GetFlagsHigh() & 0x13, CpuType::Gsu);
|
||||
debugState.Gsu.R[15] = addr;
|
||||
|
||||
DisassemblyInfo disInfo = _disassembler->GetDisassemblyInfo(addressInfo);
|
||||
_traceLogger->Log(CpuType::Gsu, debugState, disInfo);
|
||||
|
||||
_prevOpCode = value;
|
||||
_prevProgramCounter = addr;
|
||||
|
||||
if(_step->StepCount > 0) {
|
||||
_step->StepCount--;
|
||||
}
|
||||
}
|
||||
|
||||
_debugger->ProcessBreakConditions(_step->StepCount == 0, CpuType::Gsu, operation, addressInfo);
|
||||
|
||||
_memoryAccessCounter->ProcessMemoryAccess(addressInfo, type, _memoryManager->GetMasterClock());
|
||||
}
|
||||
|
||||
void GsuDebugger::ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType type)
|
||||
{
|
||||
AddressInfo addressInfo = _gsu->GetMemoryMappings()->GetAbsoluteAddress(addr);
|
||||
MemoryOperationInfo operation { addr, value, type };
|
||||
_debugger->ProcessBreakConditions(false, CpuType::Gsu, operation, addressInfo);
|
||||
|
||||
_disassembler->InvalidateCache(addressInfo, CpuType::Gsu);
|
||||
|
||||
_memoryAccessCounter->ProcessMemoryAccess(addressInfo, type, _memoryManager->GetMasterClock());
|
||||
}
|
||||
|
||||
void GsuDebugger::Run()
|
||||
{
|
||||
_step.reset(new StepRequest());
|
||||
}
|
||||
|
||||
void GsuDebugger::Step(int32_t stepCount, StepType type)
|
||||
{
|
||||
StepRequest step;
|
||||
|
||||
switch(type) {
|
||||
case StepType::StepOut:
|
||||
case StepType::StepOver:
|
||||
case StepType::Step: step.StepCount = stepCount; break;
|
||||
|
||||
case StepType::SpecificScanline:
|
||||
case StepType::PpuStep:
|
||||
break;
|
||||
}
|
||||
|
||||
_step.reset(new StepRequest(step));
|
||||
}
|
35
Core/GsuDebugger.h
Normal file
35
Core/GsuDebugger.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "DebugTypes.h"
|
||||
|
||||
class Disassembler;
|
||||
class Debugger;
|
||||
class TraceLogger;
|
||||
class Gsu;
|
||||
class MemoryAccessCounter;
|
||||
class MemoryManager;
|
||||
|
||||
class GsuDebugger
|
||||
{
|
||||
Debugger* _debugger;
|
||||
Disassembler* _disassembler;
|
||||
TraceLogger* _traceLogger;
|
||||
MemoryAccessCounter* _memoryAccessCounter;
|
||||
MemoryManager* _memoryManager;
|
||||
Gsu* _gsu;
|
||||
|
||||
unique_ptr<StepRequest> _step;
|
||||
|
||||
uint8_t _prevOpCode = 0xFF;
|
||||
uint32_t _prevProgramCounter = 0;
|
||||
|
||||
public:
|
||||
GsuDebugger(Debugger* debugger);
|
||||
|
||||
void Reset();
|
||||
|
||||
void ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType type);
|
||||
void ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType type);
|
||||
void Run();
|
||||
void Step(int32_t stepCount, StepType type);
|
||||
};
|
198
Core/GsuDisUtils.cpp
Normal file
198
Core/GsuDisUtils.cpp
Normal file
|
@ -0,0 +1,198 @@
|
|||
#include "stdafx.h"
|
||||
#include "GsuDisUtils.h"
|
||||
#include "DisassemblyInfo.h"
|
||||
#include "../Utilities/FastString.h"
|
||||
#include "../Utilities/HexUtilities.h"
|
||||
|
||||
void GsuDisUtils::GetDisassembly(DisassemblyInfo &info, string &out, uint32_t memoryAddr, LabelManager *labelManager)
|
||||
{
|
||||
constexpr const char* registerNames[16] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15" };
|
||||
bool alt1 = (info.GetFlags() & 0x01) != 0;
|
||||
bool alt2 = (info.GetFlags() & 0x02) != 0;
|
||||
bool prefix = (info.GetFlags() & 0x10) != 0;
|
||||
|
||||
uint8_t opCode = info.GetOpCode();
|
||||
|
||||
FastString str;
|
||||
const char* reg = registerNames[opCode & 0x0F];
|
||||
uint32_t jmpTarget = memoryAddr + (int8_t)info.GetByteCode()[1];
|
||||
|
||||
switch(opCode) {
|
||||
case 0x00: str.Write("STOP"); break;
|
||||
case 0x01: str.Write("NOP"); break;
|
||||
case 0x02: str.Write("CACHE"); break;
|
||||
case 0x03: str.Write("LSR"); break;
|
||||
case 0x04: str.Write("ROL"); break;
|
||||
|
||||
case 0x05: str.WriteAll("BRA $", HexUtilities::ToHex24(jmpTarget)); break;
|
||||
case 0x06: str.WriteAll("BLT $", HexUtilities::ToHex24(jmpTarget)); break;
|
||||
case 0x07: str.WriteAll("BGE $", HexUtilities::ToHex24(jmpTarget)); break;
|
||||
case 0x08: str.WriteAll("BNE $", HexUtilities::ToHex24(jmpTarget)); break;
|
||||
case 0x09: str.WriteAll("BEQ $", HexUtilities::ToHex24(jmpTarget)); break;
|
||||
case 0x0A: str.WriteAll("BPL $", HexUtilities::ToHex24(jmpTarget)); break;
|
||||
case 0x0B: str.WriteAll("BMI $", HexUtilities::ToHex24(jmpTarget)); break;
|
||||
case 0x0C: str.WriteAll("BCC $", HexUtilities::ToHex24(jmpTarget)); break;
|
||||
case 0x0D: str.WriteAll("BCS $", HexUtilities::ToHex24(jmpTarget)); break;
|
||||
case 0x0E: str.WriteAll("BCV $", HexUtilities::ToHex24(jmpTarget)); break;
|
||||
case 0x0F: str.WriteAll("BVS $", HexUtilities::ToHex24(jmpTarget)); break;
|
||||
|
||||
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
|
||||
case 0x18: case 0x19: case 0x1A: case 0x1B: case 0x1C: case 0x1D: case 0x1E: case 0x1F:
|
||||
str.WriteAll(prefix ? "MOVE R" : "TO R", reg);
|
||||
break;
|
||||
|
||||
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
|
||||
case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2C: case 0x2D: case 0x2E: case 0x2F:
|
||||
str.WriteAll("WITH R", reg);
|
||||
break;
|
||||
|
||||
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
|
||||
case 0x38: case 0x39: case 0x3A: case 0x3B:
|
||||
str.WriteAll(alt1 ? "STB (R" : "STW (R", reg, ')');
|
||||
break;
|
||||
|
||||
case 0x3C: str.Write("LOOP"); break;
|
||||
case 0x3D: str.Write("ALT1"); break;
|
||||
case 0x3E: str.Write("ALT2"); break;
|
||||
case 0x3F: str.Write("ALT3"); break;
|
||||
|
||||
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
|
||||
case 0x48: case 0x49: case 0x4A: case 0x4B:
|
||||
str.WriteAll(alt1 ? "LDB (R" : "LDW (R", reg, ')');
|
||||
break;
|
||||
|
||||
case 0x4C: str.Write(alt1 ? "RPIX" : "PLOT"); break;
|
||||
|
||||
case 0x4D: str.Write("SWAP"); break;
|
||||
case 0x4E: str.Write(alt1 ? "CMODE" : "COLOR"); break;
|
||||
|
||||
case 0x4F: str.Write("NOT"); break;
|
||||
|
||||
case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
|
||||
case 0x58: case 0x59: case 0x5A: case 0x5B: case 0x5C: case 0x5D: case 0x5E: case 0x5F:
|
||||
str.Write(alt1 ? "ADC " : "ADD ");
|
||||
str.WriteAll(alt2 ? '#' : 'R', reg);
|
||||
break;
|
||||
|
||||
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
|
||||
case 0x68: case 0x69: case 0x6A: case 0x6B: case 0x6C: case 0x6D: case 0x6E: case 0x6F:
|
||||
if(alt2 && alt1) {
|
||||
str.WriteAll("CMP R", reg);
|
||||
} else {
|
||||
if(!alt2 && alt1) {
|
||||
str.Write("SBC ");
|
||||
} else {
|
||||
str.Write("SUB ");
|
||||
}
|
||||
if(alt2 && !alt1) {
|
||||
str.WriteAll('#', reg);
|
||||
} else {
|
||||
str.WriteAll('R', reg);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x70: str.Write("MERGE"); break;
|
||||
|
||||
case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
|
||||
case 0x78: case 0x79: case 0x7A: case 0x7B: case 0x7C: case 0x7D: case 0x7E: case 0x7F:
|
||||
str.Write(alt1 ? "BIC " : "AND ");
|
||||
str.WriteAll(alt2 ? '#' : 'R', reg);
|
||||
break;
|
||||
|
||||
case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87:
|
||||
case 0x88: case 0x89: case 0x8A: case 0x8B: case 0x8C: case 0x8D: case 0x8E: case 0x8F:
|
||||
str.Write(alt1 ? "UMULT " : "MULT ");
|
||||
str.WriteAll(alt2 ? '#' : 'R', reg);
|
||||
break;
|
||||
|
||||
case 0x90: str.Write("SBK"); break;
|
||||
|
||||
case 0x91: case 0x92: case 0x93: case 0x94:
|
||||
str.WriteAll("LINK #", reg);
|
||||
break;
|
||||
|
||||
case 0x95: str.Write("SEX"); break;
|
||||
|
||||
case 0x96: str.Write(alt1 ? "DIV2" : "ASR"); break;
|
||||
case 0x97: str.Write("ROR"); break;
|
||||
|
||||
case 0x98: case 0x99: case 0x9A: case 0x9B: case 0x9C: case 0x9D:
|
||||
str.WriteAll(alt1 ? "LJMP R" : "JMP R", reg);
|
||||
break;
|
||||
|
||||
case 0x9E: str.Write("LOB"); break;
|
||||
case 0x9F: str.Write(alt1 ? "LMULT" : "FMULT"); break;
|
||||
|
||||
case 0xA0: case 0xA1: case 0xA2: case 0xA3: case 0xA4: case 0xA5: case 0xA6: case 0xA7:
|
||||
case 0xA8: case 0xA9: case 0xAA: case 0xAB: case 0xAC: case 0xAD: case 0xAE: case 0xAF:
|
||||
if(alt1) {
|
||||
str.WriteAll("LMS R", reg, ", ($", HexUtilities::ToHex(info.GetByteCode()[1] << 1), ')');
|
||||
} else if(alt2) {
|
||||
str.WriteAll("SMS R", reg, ", ($", HexUtilities::ToHex(info.GetByteCode()[1] << 1), ')');
|
||||
} else {
|
||||
str.WriteAll("IBT R", reg, ", #$", HexUtilities::ToHex(info.GetByteCode()[1]));
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xB0: case 0xB1: case 0xB2: case 0xB3: case 0xB4: case 0xB5: case 0xB6: case 0xB7:
|
||||
case 0xB8: case 0xB9: case 0xBA: case 0xBB: case 0xBC: case 0xBD: case 0xBE: case 0xBF:
|
||||
str.WriteAll(prefix ? "MOVES R" : "FROM R", reg);
|
||||
break;
|
||||
|
||||
case 0xC0: str.Write("HIB"); break;
|
||||
|
||||
case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7:
|
||||
case 0xC8: case 0xC9: case 0xCA: case 0xCB: case 0xCC: case 0xCD: case 0xCE: case 0xCF:
|
||||
str.Write(alt1 ? "XOR " : "OR ");
|
||||
str.WriteAll(alt2 ? '#' : 'R', reg);
|
||||
break;
|
||||
|
||||
case 0xD0: case 0xD1: case 0xD2: case 0xD3: case 0xD4: case 0xD5: case 0xD6: case 0xD7:
|
||||
case 0xD8: case 0xD9: case 0xDA: case 0xDB: case 0xDC: case 0xDD: case 0xDE:
|
||||
str.WriteAll("INC R", reg);
|
||||
break;
|
||||
|
||||
case 0xDF:
|
||||
if(!alt2) {
|
||||
//GETC - "Get byte from ROM to color register"
|
||||
str.Write("GETC");
|
||||
} else if(!alt1) {
|
||||
//RAMB - "Set RAM data bank"
|
||||
str.Write("RAMB");
|
||||
} else {
|
||||
str.Write("ROMB");
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xE0: case 0xE1: case 0xE2: case 0xE3: case 0xE4: case 0xE5: case 0xE6: case 0xE7:
|
||||
case 0xE8: case 0xE9: case 0xEA: case 0xEB: case 0xEC: case 0xED: case 0xEE:
|
||||
str.WriteAll("DEC R", reg);
|
||||
break;
|
||||
|
||||
case 0xEF:
|
||||
if(alt2 && alt1) {
|
||||
str.Write("GETBS");
|
||||
} else if(alt2) {
|
||||
str.Write("GETBL");
|
||||
} else if(alt1) {
|
||||
str.Write("GETBH");
|
||||
} else {
|
||||
str.Write("GETB");
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xF0: case 0xF1: case 0xF2: case 0xF3: case 0xF4: case 0xF5: case 0xF6: case 0xF7:
|
||||
case 0xF8: case 0xF9: case 0xFA: case 0xFB: case 0xFC: case 0xFD: case 0xFE: case 0xFF:
|
||||
if(alt1) {
|
||||
str.WriteAll("LM R", reg, ", ($", HexUtilities::ToHex(info.GetByteCode()[2]), HexUtilities::ToHex(info.GetByteCode()[1]), ')');
|
||||
} else if(alt2) {
|
||||
str.WriteAll("SM R", reg, ", ($", HexUtilities::ToHex(info.GetByteCode()[2]), HexUtilities::ToHex(info.GetByteCode()[1]), ')');
|
||||
} else {
|
||||
str.WriteAll("IWT R", reg, ", #$", HexUtilities::ToHex(info.GetByteCode()[2]), HexUtilities::ToHex(info.GetByteCode()[1]));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
out += str.ToString();
|
||||
}
|
11
Core/GsuDisUtils.h
Normal file
11
Core/GsuDisUtils.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
|
||||
class DisassemblyInfo;
|
||||
class LabelManager;
|
||||
|
||||
class GsuDisUtils
|
||||
{
|
||||
public:
|
||||
static void GetDisassembly(DisassemblyInfo &info, string &out, uint32_t memoryAddr, LabelManager* labelManager);
|
||||
};
|
57
Core/GsuRamHandler.h
Normal file
57
Core/GsuRamHandler.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "IMemoryHandler.h"
|
||||
#include "GsuTypes.h"
|
||||
|
||||
class GsuRamHandler : public IMemoryHandler
|
||||
{
|
||||
private:
|
||||
GsuState *_state;
|
||||
IMemoryHandler *_handler;
|
||||
|
||||
public:
|
||||
GsuRamHandler(GsuState &state, IMemoryHandler *handler)
|
||||
{
|
||||
_memoryType = SnesMemoryType::GsuWorkRam;
|
||||
_handler = handler;
|
||||
_state = &state;
|
||||
}
|
||||
|
||||
uint8_t Read(uint32_t addr) override
|
||||
{
|
||||
if(!_state->SFR.Running || !_state->GsuRamAccess) {
|
||||
return _handler->Read(addr);
|
||||
}
|
||||
|
||||
//TODO: open bus
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t Peek(uint32_t addr) override
|
||||
{
|
||||
return Read(addr);
|
||||
}
|
||||
|
||||
void PeekBlock(uint8_t *output) override
|
||||
{
|
||||
for(int i = 0; i < 0x1000; i++) {
|
||||
output[i] = Read(i);
|
||||
}
|
||||
}
|
||||
|
||||
void Write(uint32_t addr, uint8_t value) override
|
||||
{
|
||||
if(!_state->SFR.Running || !_state->GsuRamAccess) {
|
||||
_handler->Write(addr, value);
|
||||
}
|
||||
}
|
||||
|
||||
AddressInfo GetAbsoluteAddress(uint32_t address) override
|
||||
{
|
||||
if(!_state->SFR.Running || !_state->GsuRamAccess) {
|
||||
return _handler->GetAbsoluteAddress(address);
|
||||
} else {
|
||||
return { -1, SnesMemoryType::Register };
|
||||
}
|
||||
}
|
||||
};
|
66
Core/GsuRomHandler.h
Normal file
66
Core/GsuRomHandler.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "IMemoryHandler.h"
|
||||
#include "GsuTypes.h"
|
||||
|
||||
class GsuRomHandler : public IMemoryHandler
|
||||
{
|
||||
private:
|
||||
GsuState *_state;
|
||||
IMemoryHandler *_romHandler;
|
||||
|
||||
public:
|
||||
GsuRomHandler(GsuState &state, IMemoryHandler *romHandler)
|
||||
{
|
||||
_memoryType = SnesMemoryType::PrgRom;
|
||||
_romHandler = romHandler;
|
||||
_state = &state;
|
||||
}
|
||||
|
||||
uint8_t Read(uint32_t addr) override
|
||||
{
|
||||
if(!_state->SFR.Running || !_state->GsuRomAccess) {
|
||||
return _romHandler->Read(addr);
|
||||
}
|
||||
|
||||
if(addr & 0x01) {
|
||||
return 0x01;
|
||||
}
|
||||
|
||||
switch(addr & 0x0E) {
|
||||
default:
|
||||
case 2: case 6: case 8: case 0x0C:
|
||||
return 0;
|
||||
|
||||
case 4: return 0x04;
|
||||
case 0x0A: return 0x08;
|
||||
case 0x0E: return 0x0C;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Peek(uint32_t addr) override
|
||||
{
|
||||
return Read(addr);
|
||||
}
|
||||
|
||||
void PeekBlock(uint8_t *output) override
|
||||
{
|
||||
for(int i = 0; i < 0x1000; i++) {
|
||||
output[i] = Read(i);
|
||||
}
|
||||
}
|
||||
|
||||
void Write(uint32_t addr, uint8_t value) override
|
||||
{
|
||||
//ROM
|
||||
}
|
||||
|
||||
AddressInfo GetAbsoluteAddress(uint32_t address) override
|
||||
{
|
||||
if(!_state->SFR.Running || !_state->GsuRomAccess) {
|
||||
return _romHandler->GetAbsoluteAddress(address);
|
||||
} else {
|
||||
return { -1, SnesMemoryType::Register };
|
||||
}
|
||||
}
|
||||
};
|
103
Core/GsuTypes.h
Normal file
103
Core/GsuTypes.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
|
||||
struct GsuFlags
|
||||
{
|
||||
bool Zero;
|
||||
bool Carry;
|
||||
bool Sign;
|
||||
bool Overflow;
|
||||
bool Running;
|
||||
bool RomReadPending;
|
||||
bool Alt1;
|
||||
bool Alt2;
|
||||
bool ImmLow;
|
||||
bool ImmHigh;
|
||||
bool Prefix;
|
||||
bool Irq;
|
||||
|
||||
uint8_t GetFlagsLow()
|
||||
{
|
||||
return (
|
||||
(Zero << 1) |
|
||||
(Carry << 2) |
|
||||
(Sign << 3) |
|
||||
(Overflow << 4) |
|
||||
(Running << 5) |
|
||||
(RomReadPending << 6)
|
||||
);
|
||||
}
|
||||
|
||||
uint8_t GetFlagsHigh()
|
||||
{
|
||||
return (
|
||||
(Alt1 << 0) |
|
||||
(Alt2 << 1) |
|
||||
(ImmLow << 2) |
|
||||
(ImmHigh << 3) |
|
||||
(Prefix << 4) |
|
||||
(Irq << 7)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct GsuPixelCache
|
||||
{
|
||||
uint8_t X;
|
||||
uint8_t Y;
|
||||
uint8_t Pixels[8];
|
||||
uint8_t ValidBits;
|
||||
};
|
||||
|
||||
struct GsuState
|
||||
{
|
||||
uint64_t CycleCount;
|
||||
|
||||
uint16_t R[16];
|
||||
|
||||
GsuFlags SFR;
|
||||
|
||||
uint8_t RegisterLatch;
|
||||
|
||||
uint8_t ProgramBank;
|
||||
uint8_t RomBank;
|
||||
uint8_t RamBank;
|
||||
|
||||
bool IrqDisabled;
|
||||
bool HighSpeedMode;
|
||||
bool ClockSelect;
|
||||
bool BackupRamEnabled;
|
||||
uint8_t ScreenBase;
|
||||
|
||||
uint8_t ColorGradient;
|
||||
uint8_t PlotBpp;
|
||||
uint8_t ScreenHeight;
|
||||
bool GsuRamAccess;
|
||||
bool GsuRomAccess;
|
||||
|
||||
uint16_t CacheBase;
|
||||
|
||||
bool PlotTransparent;
|
||||
bool PlotDither;
|
||||
bool ColorHighNibble;
|
||||
bool ColorFreezeHigh;
|
||||
bool ObjMode;
|
||||
|
||||
uint8_t ColorReg;
|
||||
uint8_t SrcReg;
|
||||
uint8_t DestReg;
|
||||
|
||||
uint8_t RomReadBuffer;
|
||||
uint8_t RomDelay;
|
||||
|
||||
uint8_t ProgramReadBuffer;
|
||||
|
||||
uint16_t RamWriteAddress;
|
||||
uint8_t RamWriteValue;
|
||||
uint8_t RamDelay;
|
||||
|
||||
uint16_t RamAddress;
|
||||
|
||||
GsuPixelCache PrimaryCache;
|
||||
GsuPixelCache SecondaryCache;
|
||||
};
|
|
@ -1,6 +1,7 @@
|
|||
#include "stdafx.h"
|
||||
#include "LabelManager.h"
|
||||
#include "Debugger.h"
|
||||
#include "DebugUtilities.h"
|
||||
|
||||
LabelManager::LabelManager(Debugger *debugger)
|
||||
{
|
||||
|
@ -49,6 +50,7 @@ int64_t LabelManager::GetLabelKey(uint32_t absoluteAddr, SnesMemoryType memType)
|
|||
case SnesMemoryType::SpcRam: return absoluteAddr | ((uint64_t)5 << 32);
|
||||
case SnesMemoryType::SpcRom: return absoluteAddr | ((uint64_t)6 << 32);
|
||||
case SnesMemoryType::Sa1InternalRam: return absoluteAddr | ((uint64_t)7 << 32);
|
||||
case SnesMemoryType::GsuWorkRam: return absoluteAddr | ((uint64_t)8 << 32);
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +65,7 @@ SnesMemoryType LabelManager::GetKeyMemoryType(uint64_t key)
|
|||
case ((uint64_t)5 << 32): return SnesMemoryType::SpcRam; break;
|
||||
case ((uint64_t)6 << 32): return SnesMemoryType::SpcRom; break;
|
||||
case ((uint64_t)7 << 32): return SnesMemoryType::Sa1InternalRam; break;
|
||||
case ((uint64_t)8 << 32): return SnesMemoryType::GsuWorkRam; break;
|
||||
}
|
||||
|
||||
throw std::runtime_error("Invalid label key");
|
||||
|
@ -70,7 +73,7 @@ SnesMemoryType LabelManager::GetKeyMemoryType(uint64_t key)
|
|||
|
||||
string LabelManager::GetLabel(AddressInfo address)
|
||||
{
|
||||
if(address.Type <= SnesMemoryType::Sa1Memory) {
|
||||
if(address.Type <= DebugUtilities::GetLastCpuMemoryType()) {
|
||||
address = _debugger->GetAbsoluteAddress(address);
|
||||
}
|
||||
|
||||
|
@ -103,7 +106,7 @@ string LabelManager::GetComment(AddressInfo absAddress)
|
|||
|
||||
void LabelManager::GetLabelAndComment(AddressInfo address, string &label, string &comment)
|
||||
{
|
||||
if(address.Type <= SnesMemoryType::Sa1Memory) {
|
||||
if(address.Type <= DebugUtilities::GetLastCpuMemoryType()) {
|
||||
address = _debugger->GetAbsoluteAddress(address);
|
||||
}
|
||||
|
||||
|
@ -151,7 +154,7 @@ int32_t LabelManager::GetLabelRelativeAddress(string &label)
|
|||
|
||||
bool LabelManager::HasLabelOrComment(AddressInfo address)
|
||||
{
|
||||
if(address.Type <= SnesMemoryType::Sa1Memory) {
|
||||
if(address.Type <= DebugUtilities::GetLastCpuMemoryType()) {
|
||||
address = _debugger->GetAbsoluteAddress(address);
|
||||
}
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ int LuaApi::GetLibrary(lua_State *lua)
|
|||
lua_pushintvalue(cpu, SnesMemoryType::CpuMemory);
|
||||
lua_pushintvalue(spc, SnesMemoryType::SpcMemory);
|
||||
lua_pushintvalue(sa1, SnesMemoryType::Sa1Memory);
|
||||
lua_pushintvalue(gsu, SnesMemoryType::GsuMemory);
|
||||
lua_pushintvalue(cgram, SnesMemoryType::CGRam);
|
||||
lua_pushintvalue(vram, SnesMemoryType::VideoRam);
|
||||
lua_pushintvalue(oam, SnesMemoryType::SpriteRam);
|
||||
|
@ -112,6 +113,7 @@ int LuaApi::GetLibrary(lua_State *lua)
|
|||
lua_pushintvalue(cpuDebug, SnesMemoryType::CpuMemory | 0x100);
|
||||
lua_pushintvalue(spcDebug, SnesMemoryType::SpcMemory | 0x100);
|
||||
lua_pushintvalue(sa1Debug, SnesMemoryType::Sa1Memory | 0x100);
|
||||
lua_pushintvalue(gsuDebug, SnesMemoryType::GsuMemory | 0x100);
|
||||
lua_settable(lua, -3);
|
||||
|
||||
lua_pushliteral(lua, "memCallbackType");
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "MemoryDumper.h"
|
||||
#include "Spc.h"
|
||||
#include "Sa1.h"
|
||||
#include "Gsu.h"
|
||||
#include "BaseCartridge.h"
|
||||
|
||||
MemoryAccessCounter::MemoryAccessCounter(Debugger* debugger, Console *console)
|
||||
|
@ -14,6 +15,7 @@ MemoryAccessCounter::MemoryAccessCounter(Debugger* debugger, Console *console)
|
|||
_memoryManager = console->GetMemoryManager().get();
|
||||
_spc = console->GetSpc().get();
|
||||
_sa1 = console->GetCartridge()->GetSa1();
|
||||
_gsu = console->GetCartridge()->GetGsu();
|
||||
|
||||
for(int i = (int)SnesMemoryType::PrgRom; i < (int)SnesMemoryType::Register; i++) {
|
||||
uint32_t memSize = _debugger->GetMemoryDumper()->GetMemorySize((SnesMemoryType)i);
|
||||
|
@ -133,6 +135,15 @@ void MemoryAccessCounter::GetAccessStamps(uint32_t offset, uint32_t length, Snes
|
|||
}
|
||||
break;
|
||||
|
||||
case SnesMemoryType::GsuMemory:
|
||||
for(uint32_t i = 0; i < length; i++) {
|
||||
AddressInfo info = _gsu->GetMemoryMappings()->GetAbsoluteAddress(offset + i);
|
||||
if(info.Address >= 0) {
|
||||
stamps[i] = GetStampArray(operationType, info.Type)[info.Address];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
memcpy(stamps, GetStampArray(operationType, memoryType).data() + offset, length * sizeof(uint64_t));
|
||||
break;
|
||||
|
@ -169,6 +180,15 @@ void MemoryAccessCounter::GetAccessCounts(uint32_t offset, uint32_t length, Snes
|
|||
}
|
||||
break;
|
||||
|
||||
case SnesMemoryType::GsuMemory:
|
||||
for(uint32_t i = 0; i < length; i++) {
|
||||
AddressInfo info = _gsu->GetMemoryMappings()->GetAbsoluteAddress(offset + i);
|
||||
if(info.Address >= 0) {
|
||||
counts[i] = GetCountArray(operationType, info.Type)[info.Address];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
memcpy(counts, GetCountArray(operationType, memoryType).data() + offset, length * sizeof(uint32_t));
|
||||
break;
|
||||
|
|
|
@ -7,6 +7,7 @@ class MemoryManager;
|
|||
class Spc;
|
||||
class Console;
|
||||
class Sa1;
|
||||
class Gsu;
|
||||
|
||||
class MemoryAccessCounter
|
||||
{
|
||||
|
@ -25,6 +26,7 @@ private:
|
|||
MemoryManager* _memoryManager;
|
||||
Spc* _spc;
|
||||
Sa1* _sa1;
|
||||
Gsu* _gsu;
|
||||
|
||||
vector<uint32_t>& GetCountArray(MemoryOperationType operationType, SnesMemoryType memType);
|
||||
vector<uint64_t>& GetStampArray(MemoryOperationType operationType, SnesMemoryType memType);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "Spc.h"
|
||||
#include "NecDsp.h"
|
||||
#include "Sa1.h"
|
||||
#include "Gsu.h"
|
||||
#include "MemoryDumper.h"
|
||||
#include "BaseCartridge.h"
|
||||
#include "VideoDecoder.h"
|
||||
|
@ -29,6 +30,7 @@ void MemoryDumper::SetMemoryState(SnesMemoryType type, uint8_t *buffer, uint32_t
|
|||
case SnesMemoryType::CpuMemory:
|
||||
case SnesMemoryType::SpcMemory:
|
||||
case SnesMemoryType::Sa1Memory:
|
||||
case SnesMemoryType::GsuMemory:
|
||||
break;
|
||||
|
||||
case SnesMemoryType::PrgRom: memcpy(_cartridge->DebugGetPrgRom(), buffer, length); break;
|
||||
|
@ -45,6 +47,8 @@ void MemoryDumper::SetMemoryState(SnesMemoryType type, uint8_t *buffer, uint32_t
|
|||
case SnesMemoryType::DspDataRam: memcpy(_cartridge->GetDsp()->DebugGetDataRam(), buffer, length); break;
|
||||
|
||||
case SnesMemoryType::Sa1InternalRam: memcpy(_cartridge->GetSa1()->DebugGetInternalRam(), buffer, length); break;
|
||||
|
||||
case SnesMemoryType::GsuWorkRam: memcpy(_cartridge->GetGsu()->DebugGetWorkRam(), buffer, length); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,6 +59,7 @@ uint32_t MemoryDumper::GetMemorySize(SnesMemoryType type)
|
|||
case SnesMemoryType::CpuMemory: return 0x1000000;
|
||||
case SnesMemoryType::SpcMemory: return 0x10000;
|
||||
case SnesMemoryType::Sa1Memory: return 0x1000000;
|
||||
case SnesMemoryType::GsuMemory: return 0x1000000;
|
||||
case SnesMemoryType::PrgRom: return _cartridge->DebugGetPrgRomSize();
|
||||
case SnesMemoryType::WorkRam: return MemoryManager::WorkRamSize;
|
||||
case SnesMemoryType::SaveRam: return _cartridge->DebugGetSaveRamSize();
|
||||
|
@ -70,6 +75,8 @@ uint32_t MemoryDumper::GetMemorySize(SnesMemoryType type)
|
|||
case SnesMemoryType::DspDataRam: return _cartridge->GetDsp() ? _cartridge->GetDsp()->DebugGetDataRamSize() : 0;
|
||||
|
||||
case SnesMemoryType::Sa1InternalRam: return _cartridge->GetSa1() ? _cartridge->GetSa1()->DebugGetInternalRamSize() : 0;;
|
||||
|
||||
case SnesMemoryType::GsuWorkRam: return _cartridge->GetGsu() ? _cartridge->GetGsu()->DebugGetWorkRamSize() : 0;;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,6 +103,12 @@ void MemoryDumper::GetMemoryState(SnesMemoryType type, uint8_t *buffer)
|
|||
}
|
||||
break;
|
||||
|
||||
case SnesMemoryType::GsuMemory:
|
||||
for(int i = 0; i <= 0xFFFFFF; i += 0x1000) {
|
||||
_cartridge->GetGsu()->GetMemoryMappings()->PeekBlock(i, buffer + i);
|
||||
}
|
||||
break;
|
||||
|
||||
case SnesMemoryType::PrgRom: memcpy(buffer, _cartridge->DebugGetPrgRom(), _cartridge->DebugGetPrgRomSize()); break;
|
||||
case SnesMemoryType::WorkRam: memcpy(buffer, _memoryManager->DebugGetWorkRam(), MemoryManager::WorkRamSize); break;
|
||||
case SnesMemoryType::SaveRam: memcpy(buffer, _cartridge->DebugGetSaveRam(), _cartridge->DebugGetSaveRamSize()); break;
|
||||
|
@ -110,6 +123,8 @@ void MemoryDumper::GetMemoryState(SnesMemoryType type, uint8_t *buffer)
|
|||
case SnesMemoryType::DspDataRam: memcpy(buffer, _cartridge->GetDsp()->DebugGetDataRam(), _cartridge->GetDsp()->DebugGetDataRamSize()); break;
|
||||
|
||||
case SnesMemoryType::Sa1InternalRam: memcpy(buffer, _cartridge->GetSa1()->DebugGetInternalRam(), _cartridge->GetSa1()->DebugGetInternalRamSize()); break;
|
||||
|
||||
case SnesMemoryType::GsuWorkRam: memcpy(buffer, _cartridge->GetGsu()->DebugGetWorkRam(), _cartridge->GetGsu()->DebugGetWorkRamSize()); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,6 +148,7 @@ void MemoryDumper::SetMemoryValue(SnesMemoryType memoryType, uint32_t address, u
|
|||
case SnesMemoryType::CpuMemory: _memoryManager->Write(address, value, MemoryOperationType::Write); break;
|
||||
case SnesMemoryType::SpcMemory: _spc->DebugWrite(address, value); break;
|
||||
case SnesMemoryType::Sa1Memory: _cartridge->GetSa1()->WriteSa1(address, value, MemoryOperationType::Write); break;
|
||||
case SnesMemoryType::GsuMemory: _cartridge->GetGsu()->WriteGsu(address, value, MemoryOperationType::Write); break;
|
||||
|
||||
case SnesMemoryType::PrgRom: _cartridge->DebugGetPrgRom()[address] = value; break;
|
||||
case SnesMemoryType::WorkRam: _memoryManager->DebugGetWorkRam()[address] = value; break;
|
||||
|
@ -149,6 +165,8 @@ void MemoryDumper::SetMemoryValue(SnesMemoryType memoryType, uint32_t address, u
|
|||
case SnesMemoryType::DspDataRam: _cartridge->GetDsp()->DebugGetDataRam()[address] = value;
|
||||
|
||||
case SnesMemoryType::Sa1InternalRam: _cartridge->GetSa1()->DebugGetInternalRam()[address] = value;
|
||||
|
||||
case SnesMemoryType::GsuWorkRam: _cartridge->GetGsu()->DebugGetWorkRam()[address] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,6 +182,7 @@ uint8_t MemoryDumper::GetMemoryValue(SnesMemoryType memoryType, uint32_t address
|
|||
case SnesMemoryType::CpuMemory: return _memoryManager->Peek(address);
|
||||
case SnesMemoryType::SpcMemory: return _spc->DebugRead(address);
|
||||
case SnesMemoryType::Sa1Memory: return _cartridge->GetSa1()->GetMemoryMappings()->Peek(address);
|
||||
case SnesMemoryType::GsuMemory: return _cartridge->GetGsu()->GetMemoryMappings()->Peek(address);
|
||||
|
||||
case SnesMemoryType::PrgRom: return _cartridge->DebugGetPrgRom()[address];
|
||||
case SnesMemoryType::WorkRam: return _memoryManager->DebugGetWorkRam()[address];
|
||||
|
@ -180,6 +199,8 @@ uint8_t MemoryDumper::GetMemoryValue(SnesMemoryType memoryType, uint32_t address
|
|||
case SnesMemoryType::DspDataRam: return _cartridge->GetDsp()->DebugGetDataRam()[address];
|
||||
|
||||
case SnesMemoryType::Sa1InternalRam: return _cartridge->GetSa1()->DebugGetInternalRam()[address];
|
||||
|
||||
case SnesMemoryType::GsuWorkRam: return _cartridge->GetGsu()->DebugGetWorkRam()[address];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "MessageManager.h"
|
||||
#include "DebugTypes.h"
|
||||
#include "EmuSettings.h"
|
||||
#include "Sa1.h"
|
||||
#include "Gsu.h"
|
||||
#include "BaseCoprocessor.h"
|
||||
#include "../Utilities/Serializer.h"
|
||||
#include "../Utilities/HexUtilities.h"
|
||||
|
@ -189,6 +191,17 @@ void MemoryManager::UpdateEvents()
|
|||
_hasEvent[_dramRefreshPosition] = true;
|
||||
}
|
||||
|
||||
void MemoryManager::SyncCoprocessors()
|
||||
{
|
||||
if(_cart->GetCoprocessor()) {
|
||||
if(_cart->GetGsu()) {
|
||||
_cart->GetGsu()->Run();
|
||||
} else if(_cart->GetSa1()) {
|
||||
_cart->GetSa1()->Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryManager::Exec()
|
||||
{
|
||||
_masterClock += 2;
|
||||
|
@ -222,9 +235,7 @@ void MemoryManager::Exec()
|
|||
_regs->ProcessIrqCounters();
|
||||
}
|
||||
|
||||
if(_cart->GetCoprocessor()) {
|
||||
_cart->GetCoprocessor()->Run();
|
||||
}
|
||||
SyncCoprocessors();
|
||||
}
|
||||
|
||||
uint8_t MemoryManager::Read(uint32_t addr, MemoryOperationType type)
|
||||
|
|
|
@ -47,6 +47,7 @@ private:
|
|||
uint8_t _masterClockTable[2][0x10000];
|
||||
|
||||
void UpdateEvents();
|
||||
__forceinline void SyncCoprocessors();
|
||||
void Exec();
|
||||
|
||||
public:
|
||||
|
|
|
@ -17,6 +17,7 @@ NecDsp::NecDsp(CoprocessorType type, Console* console, vector<uint8_t> &programR
|
|||
_console = console;
|
||||
_type = type;
|
||||
_memoryManager = console->GetMemoryManager().get();
|
||||
_memoryType = SnesMemoryType::Register;
|
||||
MemoryMappings *mm = _memoryManager->GetMemoryMappings();
|
||||
|
||||
if(type == CoprocessorType::ST010 || type == CoprocessorType::ST011) {
|
||||
|
@ -219,6 +220,7 @@ void NecDsp::Write(uint32_t addr, uint8_t value)
|
|||
|
||||
uint8_t NecDsp::Peek(uint32_t addr)
|
||||
{
|
||||
//Avoid side effects for now
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -229,7 +231,7 @@ void NecDsp::PeekBlock(uint8_t *output)
|
|||
|
||||
AddressInfo NecDsp::GetAbsoluteAddress(uint32_t address)
|
||||
{
|
||||
return { -1, SnesMemoryType::CpuMemory };
|
||||
return { -1, SnesMemoryType::Register };
|
||||
}
|
||||
|
||||
void NecDsp::RunApuOp(uint8_t aluOperation, uint16_t source)
|
||||
|
|
|
@ -48,15 +48,13 @@ private:
|
|||
void Load(uint8_t dest, uint16_t value);
|
||||
uint16_t GetSourceValue(uint8_t source);
|
||||
|
||||
static bool LoadFirmware(Console *console, string combinedFilename, string splitFilenameProgram, string splitFilenameData, vector<uint8_t> &programRom, vector<uint8_t> &dataRom, uint32_t programSize, uint32_t dataSize);
|
||||
|
||||
NecDsp(CoprocessorType type, Console* console, vector<uint8_t> &programRom, vector<uint8_t> &dataRom);
|
||||
|
||||
public:
|
||||
static NecDsp* InitCoprocessor(CoprocessorType type, Console* console);
|
||||
|
||||
void Reset() override;
|
||||
void Run() override;
|
||||
void Run();
|
||||
|
||||
void LoadBattery(string filePath) override;
|
||||
void SaveBattery(string filePath) override;
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
#include "stdafx.h"
|
||||
|
||||
class DisassemblyInfo;
|
||||
class Console;
|
||||
class LabelManager;
|
||||
struct NecDspState;
|
||||
|
||||
class NecDspDisUtils
|
||||
{
|
||||
|
|
|
@ -16,6 +16,7 @@ Sa1::Sa1(Console* console)
|
|||
{
|
||||
_console = console;
|
||||
_memoryManager = console->GetMemoryManager().get();
|
||||
_memoryType = SnesMemoryType::Register;
|
||||
_lastAccessMemType = SnesMemoryType::PrgRom;
|
||||
_openBus = 0;
|
||||
_cart = _console->GetCartridge().get();
|
||||
|
@ -405,11 +406,14 @@ uint8_t Sa1::Read(uint32_t addr)
|
|||
|
||||
uint8_t Sa1::Peek(uint32_t addr)
|
||||
{
|
||||
return 0;
|
||||
return Sa1RegisterRead(addr);
|
||||
}
|
||||
|
||||
void Sa1::PeekBlock(uint8_t *output)
|
||||
{
|
||||
for(int i = 0; i < 0x1000; i++) {
|
||||
output[i] = Sa1RegisterRead(i);
|
||||
}
|
||||
}
|
||||
|
||||
void Sa1::Write(uint32_t addr, uint8_t value)
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
void Write(uint32_t addr, uint8_t value) override;
|
||||
AddressInfo GetAbsoluteAddress(uint32_t address) override;
|
||||
|
||||
void Run() override;
|
||||
void Run();
|
||||
void Reset() override;
|
||||
|
||||
SnesMemoryType GetSa1MemoryType();
|
||||
|
|
|
@ -263,6 +263,7 @@ struct EmulationConfig
|
|||
|
||||
uint32_t PpuExtraScanlinesBeforeNmi = 0;
|
||||
uint32_t PpuExtraScanlinesAfterNmi = 0;
|
||||
uint32_t GsuClockSpeed = 0;
|
||||
|
||||
RamState RamPowerOnState = RamState::Random;
|
||||
};
|
||||
|
@ -443,6 +444,7 @@ enum class DebuggerFlags : uint32_t
|
|||
ShowUnidentifiedData = 0x400,
|
||||
DisassembleUnidentifiedData = 0x800,
|
||||
|
||||
GsuDebuggerEnabled = 0x10000000,
|
||||
Sa1DebuggerEnabled = 0x20000000,
|
||||
SpcDebuggerEnabled = 0x40000000,
|
||||
CpuDebuggerEnabled = 0x80000000
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "Debugger.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "LabelManager.h"
|
||||
#include "DebugUtilities.h"
|
||||
#include "CpuTypes.h"
|
||||
#include "SpcTypes.h"
|
||||
#include "NecDspTypes.h"
|
||||
|
@ -64,6 +65,7 @@ void TraceLogger::SetOptions(TraceLoggerOptions options)
|
|||
_logCpu[(int)CpuType::Spc] = options.LogSpc;
|
||||
_logCpu[(int)CpuType::NecDsp] = options.LogNecDsp;
|
||||
_logCpu[(int)CpuType::Sa1] = options.LogSa1;
|
||||
_logCpu[(int)CpuType::Gsu] = options.LogGsu;
|
||||
|
||||
string condition = _options.Condition;
|
||||
string format = _options.Format;
|
||||
|
@ -79,8 +81,9 @@ void TraceLogger::SetOptions(TraceLoggerOptions options)
|
|||
}*/
|
||||
|
||||
ParseFormatString(_rowParts, format);
|
||||
ParseFormatString(_spcRowParts, "[PC,4h] [ByteCode,15h] [Disassembly][EffectiveAddress] [MemoryValue,h][Align,48] A:[A,2h] X:[X,2h] Y:[Y,2h] S:[SP,2h] P:[P,8] H:[Cycle,3] V:[Scanline,3]");
|
||||
ParseFormatString(_dspRowParts, "[PC,4h] [ByteCode,15h] [Disassembly] [Align,65] [A,2h] S:[SP,2h] H:[Cycle,3] V:[Scanline,3]");
|
||||
ParseFormatString(_spcRowParts, "[PC,4h] [ByteCode,11h] [Disassembly][EffectiveAddress] [MemoryValue,h][Align,48] A:[A,2h] X:[X,2h] Y:[Y,2h] S:[SP,2h] P:[P,8] H:[Cycle,3] V:[Scanline,3]");
|
||||
ParseFormatString(_dspRowParts, "[PC,4h] [ByteCode,11h] [Disassembly] [Align,65] [A,2h] S:[SP,2h] H:[Cycle,3] V:[Scanline,3]");
|
||||
ParseFormatString(_gsuRowParts, "[PC,6h] [ByteCode,11h] [Disassembly] [Align,50] SRC:[X,2] DST:[Y,2] R0:[A,2h] H:[Cycle,3] V:[Scanline,3]");
|
||||
}
|
||||
|
||||
void TraceLogger::ParseFormatString(vector<RowPart> &rowParts, string format)
|
||||
|
@ -384,6 +387,37 @@ void TraceLogger::GetTraceRow(string &output, NecDspState &cpuState, PpuState &p
|
|||
output += _options.UseWindowsEol ? "\r\n" : "\n";
|
||||
}
|
||||
|
||||
void TraceLogger::GetTraceRow(string &output, GsuState &gsuState, PpuState &ppuState, DisassemblyInfo &disassemblyInfo)
|
||||
{
|
||||
int originalSize = (int)output.size();
|
||||
uint32_t pcAddress = (gsuState.ProgramBank << 16) | gsuState.R[15];
|
||||
for(RowPart& rowPart : _gsuRowParts) {
|
||||
switch(rowPart.DataType) {
|
||||
case RowDataType::Text: output += rowPart.Text; break;
|
||||
case RowDataType::ByteCode: WriteByteCode(disassemblyInfo, rowPart, output); break;
|
||||
case RowDataType::Disassembly: WriteDisassembly(disassemblyInfo, rowPart, 0, pcAddress, output); break;
|
||||
case RowDataType::Align: WriteAlign(originalSize, rowPart, output); break;
|
||||
|
||||
case RowDataType::PC: WriteValue(output, HexUtilities::ToHex24(pcAddress), rowPart); break;
|
||||
case RowDataType::A:
|
||||
WriteValue(output, gsuState.R[0], rowPart);
|
||||
for(int i = 1; i < 16; i++) {
|
||||
output += " R" + std::to_string(i) + ":" + HexUtilities::ToHex(gsuState.R[i]);
|
||||
}
|
||||
break;
|
||||
case RowDataType::X: WriteValue(output, gsuState.SrcReg, rowPart); break;
|
||||
case RowDataType::Y: WriteValue(output, gsuState.DestReg, rowPart); break;
|
||||
|
||||
case RowDataType::Cycle: WriteValue(output, ppuState.Cycle, rowPart); break;
|
||||
case RowDataType::Scanline: WriteValue(output, ppuState.Scanline, rowPart); break;
|
||||
case RowDataType::HClock: WriteValue(output, ppuState.HClock, rowPart); break;
|
||||
case RowDataType::FrameCount: WriteValue(output, ppuState.FrameCount, rowPart); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
output += _options.UseWindowsEol ? "\r\n" : "\n";
|
||||
}
|
||||
|
||||
/*
|
||||
bool TraceLogger::ConditionMatches(DebugState &state, DisassemblyInfo &disassemblyInfo, OperationInfo &operationInfo)
|
||||
{
|
||||
|
@ -410,6 +444,7 @@ void TraceLogger::GetTraceRow(string &output, CpuType cpuType, DisassemblyInfo &
|
|||
case CpuType::Spc: GetTraceRow(output, state.Spc, state.Ppu, disassemblyInfo); break;
|
||||
case CpuType::NecDsp: GetTraceRow(output, state.Dsp, state.Ppu, disassemblyInfo); break;
|
||||
case CpuType::Sa1: GetTraceRow(output, state.Sa1, state.Ppu, disassemblyInfo, SnesMemoryType::Sa1Memory); break;
|
||||
case CpuType::Gsu: GetTraceRow(output, state.Gsu, state.Ppu, disassemblyInfo); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -476,7 +511,7 @@ const char* TraceLogger::GetExecutionTrace(uint32_t lineCount)
|
|||
}
|
||||
|
||||
bool enabled = false;
|
||||
for(int i = 0; i < (int)CpuType::Sa1 + 1; i++) {
|
||||
for(int i = 0; i <= (int)DebugUtilities::GetLastCpuType(); i++) {
|
||||
enabled |= _logCpu[i];
|
||||
}
|
||||
|
||||
|
@ -503,6 +538,7 @@ const char* TraceLogger::GetExecutionTrace(uint32_t lineCount)
|
|||
case CpuType::Spc: _executionTrace += "\x3\x1" + HexUtilities::ToHex(_stateCacheCopy[index].Spc.PC) + "\x1"; break;
|
||||
case CpuType::NecDsp: _executionTrace += "\x4\x1" + HexUtilities::ToHex(_stateCacheCopy[index].Dsp.PC) + "\x1"; break;
|
||||
case CpuType::Sa1: _executionTrace += "\x4\x1" + HexUtilities::ToHex24((_stateCacheCopy[index].Sa1.K << 16) | _stateCacheCopy[index].Sa1.PC) + "\x1"; break;
|
||||
case CpuType::Gsu: _executionTrace += "\x4\x1" + HexUtilities::ToHex24((_stateCacheCopy[index].Gsu.ProgramBank << 16) | _stateCacheCopy[index].Gsu.R[15]) + "\x1"; break;
|
||||
}
|
||||
|
||||
string byteCode;
|
||||
|
|
|
@ -19,6 +19,7 @@ struct TraceLoggerOptions
|
|||
bool LogSpc;
|
||||
bool LogNecDsp;
|
||||
bool LogSa1;
|
||||
bool LogGsu;
|
||||
|
||||
bool ShowExtraInfo;
|
||||
bool IndentCode;
|
||||
|
@ -80,8 +81,9 @@ private:
|
|||
vector<RowPart> _rowParts;
|
||||
vector<RowPart> _spcRowParts;
|
||||
vector<RowPart> _dspRowParts;
|
||||
vector<RowPart> _gsuRowParts;
|
||||
|
||||
bool _logCpu[(int)CpuType::Sa1 + 1] = {};
|
||||
bool _logCpu[(int)CpuType::Gsu + 1] = {};
|
||||
|
||||
bool _pendingLog;
|
||||
//CpuState _lastState;
|
||||
|
@ -116,6 +118,7 @@ private:
|
|||
void GetTraceRow(string &output, CpuState &cpuState, PpuState &ppuState, DisassemblyInfo &disassemblyInfo, SnesMemoryType memType);
|
||||
void GetTraceRow(string &output, SpcState &cpuState, PpuState &ppuState, DisassemblyInfo &disassemblyInfo);
|
||||
void GetTraceRow(string &output, NecDspState &cpuState, PpuState &ppuState, DisassemblyInfo &disassemblyInfo);
|
||||
void GetTraceRow(string &output, GsuState &gsuState, PpuState &ppuState, DisassemblyInfo &disassemblyInfo);
|
||||
|
||||
template<typename T> void WriteValue(string &output, T value, RowPart& rowPart);
|
||||
|
||||
|
|
|
@ -47,6 +47,10 @@ SOURCES_CXX := $(LIBRETRO_DIR)/libretro.cpp \
|
|||
$(CORE_DIR)/EmuSettings.cpp \
|
||||
$(CORE_DIR)/EventManager.cpp \
|
||||
$(CORE_DIR)/ExpressionEvaluator.cpp \
|
||||
$(CORE_DIR)/Gsu.cpp \
|
||||
$(CORE_DIR)/Gsu.Instructions.cpp \
|
||||
$(CORE_DIR)/GsuDisUtils.cpp \
|
||||
$(CORE_DIR)/GsuDebugger.cpp \
|
||||
$(CORE_DIR)/InternalRegisters.cpp \
|
||||
$(CORE_DIR)/KeyManager.cpp \
|
||||
$(CORE_DIR)/LabelManager.cpp \
|
||||
|
|
|
@ -41,6 +41,7 @@ static constexpr const char* MesenOverscanHorizontal = "mesen-s_overscan_horizon
|
|||
static constexpr const char* MesenRamState = "mesen-s_ramstate";
|
||||
static constexpr const char* MesenOverclock = "mesen-s_overclock";
|
||||
static constexpr const char* MesenOverclockType = "mesen-s_overclock_type";
|
||||
static constexpr const char* MesenSuperFxOverclock = "mesen-s_superfx_overclock";
|
||||
|
||||
extern "C" {
|
||||
void logMessage(retro_log_level level, const char* message)
|
||||
|
@ -105,6 +106,7 @@ extern "C" {
|
|||
{ MesenAspectRatio, "Aspect Ratio; Auto|No Stretching|NTSC|PAL|4:3|16:9" },
|
||||
{ MesenOverclock, "Overclock; None|Low|Medium|High|Very High" },
|
||||
{ MesenOverclockType, "Overclock Type; Before NMI|After NMI" },
|
||||
{ MesenSuperFxOverclock, "Super FX Clock Speed; 100%|200%|300%|400%|500%|1000%" },
|
||||
{ MesenRamState, "Default power-on state for RAM; Random Values (Default)|All 0s|All 1s" },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
@ -260,6 +262,24 @@ extern "C" {
|
|||
}
|
||||
}
|
||||
|
||||
emulation.GsuClockSpeed = 100;
|
||||
if(readVariable(MesenSuperFxOverclock, var)) {
|
||||
string value = string(var.value);
|
||||
if(value == "100%") {
|
||||
emulation.GsuClockSpeed = 100;
|
||||
} else if(value == "200%") {
|
||||
emulation.GsuClockSpeed = 200;
|
||||
} else if(value == "300%") {
|
||||
emulation.GsuClockSpeed = 300;
|
||||
} else if(value == "400%") {
|
||||
emulation.GsuClockSpeed = 400;
|
||||
} else if(value == "500%") {
|
||||
emulation.GsuClockSpeed = 500;
|
||||
} else if(value == "1000%") {
|
||||
emulation.GsuClockSpeed = 1000;
|
||||
}
|
||||
}
|
||||
|
||||
int overscanHorizontal = 0;
|
||||
int overscanVertical = 0;
|
||||
if(readVariable(MesenOverscanHorizontal, var)) {
|
||||
|
|
|
@ -21,6 +21,7 @@ namespace Mesen.GUI.Config
|
|||
|
||||
[MinMax(0, 1000)] public UInt32 PpuExtraScanlinesBeforeNmi = 0;
|
||||
[MinMax(0, 1000)] public UInt32 PpuExtraScanlinesAfterNmi = 0;
|
||||
[MinMax(100, 1000)] public UInt32 GsuClockSpeed = 100;
|
||||
|
||||
public RamState RamPowerOnState = RamState.Random;
|
||||
|
||||
|
|
|
@ -109,6 +109,7 @@ namespace Mesen.GUI.Debugger
|
|||
case SnesMemoryType.CpuMemory: type = "CPU"; break;
|
||||
case SnesMemoryType.SpcMemory: type = "SPC"; break;
|
||||
case SnesMemoryType.Sa1Memory: type = "SA1"; break;
|
||||
case SnesMemoryType.GsuMemory: type = "GSU"; break;
|
||||
|
||||
case SnesMemoryType.PrgRom: type = "PRG"; break;
|
||||
case SnesMemoryType.WorkRam: type = "WRAM"; break;
|
||||
|
@ -121,6 +122,7 @@ namespace Mesen.GUI.Debugger
|
|||
case SnesMemoryType.SpcRom: type = "ROM"; break;
|
||||
|
||||
case SnesMemoryType.Sa1InternalRam: type = "IRAM"; break;
|
||||
case SnesMemoryType.GsuWorkRam: type = "GWRAM"; break;
|
||||
|
||||
case SnesMemoryType.Register: type = "REG"; break;
|
||||
}
|
||||
|
|
|
@ -37,14 +37,14 @@ namespace Mesen.GUI.Debugger
|
|||
_cpuType = breakpoint.CpuType;
|
||||
|
||||
cboBreakpointType.Items.Clear();
|
||||
if(_cpuType == CpuType.Cpu || _cpuType == CpuType.Sa1) {
|
||||
if(_cpuType == CpuType.Cpu || _cpuType == CpuType.Sa1 || _cpuType == CpuType.Gsu) {
|
||||
cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(_cpuType.ToMemoryType()));
|
||||
cboBreakpointType.Items.Add("-");
|
||||
|
||||
if(DebugApi.GetMemorySize(SnesMemoryType.PrgRom) > 0) {
|
||||
cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.PrgRom));
|
||||
}
|
||||
if(DebugApi.GetMemorySize(SnesMemoryType.WorkRam) > 0) {
|
||||
if(_cpuType == CpuType.Cpu && DebugApi.GetMemorySize(SnesMemoryType.WorkRam) > 0) {
|
||||
cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.WorkRam));
|
||||
}
|
||||
if(DebugApi.GetMemorySize(SnesMemoryType.SaveRam) > 0) {
|
||||
|
@ -53,6 +53,9 @@ namespace Mesen.GUI.Debugger
|
|||
if(DebugApi.GetMemorySize(SnesMemoryType.Sa1InternalRam) > 0) {
|
||||
cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.Sa1InternalRam));
|
||||
}
|
||||
if(DebugApi.GetMemorySize(SnesMemoryType.GsuWorkRam) > 0) {
|
||||
cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.GsuWorkRam));
|
||||
}
|
||||
|
||||
if(_cpuType == CpuType.Cpu) {
|
||||
if(cboBreakpointType.Items.Count > 2) {
|
||||
|
|
29
UI/Debugger/Code/GsuDisassemblyManager.cs
Normal file
29
UI/Debugger/Code/GsuDisassemblyManager.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
using Mesen.GUI.Debugger.Controls;
|
||||
using Mesen.GUI.Debugger.Integration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Mesen.GUI.Debugger.Code
|
||||
{
|
||||
public class GsuDisassemblyManager : CpuDisassemblyManager
|
||||
{
|
||||
public override CpuType CpuType { get { return CpuType.Gsu; } }
|
||||
public override SnesMemoryType RelativeMemoryType { get { return SnesMemoryType.GsuMemory; } }
|
||||
public override int AddressSize { get { return 6; } }
|
||||
public override int ByteCodeSize { get { return 3; } }
|
||||
public override bool AllowSourceView { get { return false; } }
|
||||
|
||||
public override void RefreshCode(DbgImporter symbolProvider, DbgImporter.FileInfo file)
|
||||
{
|
||||
this._provider = new CodeDataProvider(CpuType.Gsu);
|
||||
}
|
||||
|
||||
protected override int GetFullAddress(int address, int length)
|
||||
{
|
||||
return address;
|
||||
}
|
||||
}
|
||||
}
|
64
UI/Debugger/Code/GsuLineStyleProvider.cs
Normal file
64
UI/Debugger/Code/GsuLineStyleProvider.cs
Normal file
|
@ -0,0 +1,64 @@
|
|||
using Mesen.GUI.Config;
|
||||
using Mesen.GUI.Debugger.Controls;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Mesen.GUI.Debugger.Code
|
||||
{
|
||||
public class GsuLineStyleProvider : BaseStyleProvider
|
||||
{
|
||||
public GsuLineStyleProvider()
|
||||
{
|
||||
}
|
||||
|
||||
public override string GetLineComment(int lineNumber)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void ConfigureActiveStatement(LineProperties props)
|
||||
{
|
||||
props.FgColor = Color.Black;
|
||||
props.TextBgColor = ConfigManager.Config.Debug.Debugger.CodeActiveStatementColor;
|
||||
props.Symbol |= LineSymbol.Arrow;
|
||||
}
|
||||
|
||||
public override LineProperties GetLineStyle(CodeLineData lineData, int lineIndex)
|
||||
{
|
||||
DebuggerInfo cfg = ConfigManager.Config.Debug.Debugger;
|
||||
LineProperties props = new LineProperties();
|
||||
|
||||
if(lineData.Address >= 0) {
|
||||
GetBreakpointLineProperties(props, lineData.Address);
|
||||
}
|
||||
|
||||
bool isActiveStatement = ActiveAddress.HasValue && ActiveAddress.Value == lineData.Address;
|
||||
if(isActiveStatement) {
|
||||
ConfigureActiveStatement(props);
|
||||
}
|
||||
|
||||
if(lineData.Flags.HasFlag(LineFlags.VerifiedData)) {
|
||||
props.LineBgColor = cfg.CodeVerifiedDataColor;
|
||||
} else if(!lineData.Flags.HasFlag(LineFlags.VerifiedCode)) {
|
||||
props.LineBgColor = cfg.CodeUnidentifiedDataColor;
|
||||
}
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
private void GetBreakpointLineProperties(LineProperties props, int cpuAddress)
|
||||
{
|
||||
AddressInfo absAddress = DebugApi.GetAbsoluteAddress(new AddressInfo() { Address = cpuAddress, Type = SnesMemoryType.GsuMemory });
|
||||
foreach(Breakpoint breakpoint in BreakpointManager.Breakpoints) {
|
||||
if(breakpoint.Matches((uint)cpuAddress, SnesMemoryType.GsuMemory, CpuType.Gsu) || (absAddress.Address >= 0 && breakpoint.Matches((uint)absAddress.Address, absAddress.Type, CpuType.Gsu))) {
|
||||
SetBreakpointLineProperties(props, breakpoint);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -77,6 +77,8 @@ namespace Mesen.GUI.Config
|
|||
public XmlKeys OpenSpcDebugger = Keys.Control | Keys.F;
|
||||
[ShortcutName("Open SA-1 Debugger")]
|
||||
public XmlKeys OpenSa1Debugger = Keys.None;
|
||||
[ShortcutName("Open GSU Debugger")]
|
||||
public XmlKeys OpenGsuDebugger = Keys.None;
|
||||
[ShortcutName("Open Event Viewer")]
|
||||
public XmlKeys OpenEventViewer = Keys.Control | Keys.E;
|
||||
[ShortcutName("Open Memory Tools")]
|
||||
|
|
|
@ -49,6 +49,7 @@ namespace Mesen.GUI.Config
|
|||
public bool LogSpc;
|
||||
public bool LogNecDsp;
|
||||
public bool LogSa1;
|
||||
public bool LogGsu;
|
||||
|
||||
public bool ShowByteCode;
|
||||
public bool ShowRegisters;
|
||||
|
|
778
UI/Debugger/Controls/ctrlGsuStatus.Designer.cs
generated
Normal file
778
UI/Debugger/Controls/ctrlGsuStatus.Designer.cs
generated
Normal file
|
@ -0,0 +1,778 @@
|
|||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
partial class ctrlGsuStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if(disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.grpSpc = new System.Windows.Forms.GroupBox();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.lblR0 = new System.Windows.Forms.Label();
|
||||
this.txtR0 = new System.Windows.Forms.TextBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.txtR1 = new System.Windows.Forms.TextBox();
|
||||
this.txtR2 = new System.Windows.Forms.TextBox();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.txtR3 = new System.Windows.Forms.TextBox();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.label8 = new System.Windows.Forms.Label();
|
||||
this.label9 = new System.Windows.Forms.Label();
|
||||
this.label10 = new System.Windows.Forms.Label();
|
||||
this.label11 = new System.Windows.Forms.Label();
|
||||
this.label12 = new System.Windows.Forms.Label();
|
||||
this.label13 = new System.Windows.Forms.Label();
|
||||
this.label14 = new System.Windows.Forms.Label();
|
||||
this.label15 = new System.Windows.Forms.Label();
|
||||
this.label16 = new System.Windows.Forms.Label();
|
||||
this.txtR4 = new System.Windows.Forms.TextBox();
|
||||
this.txtR8 = new System.Windows.Forms.TextBox();
|
||||
this.txtR12 = new System.Windows.Forms.TextBox();
|
||||
this.txtR5 = new System.Windows.Forms.TextBox();
|
||||
this.txtR9 = new System.Windows.Forms.TextBox();
|
||||
this.txtR13 = new System.Windows.Forms.TextBox();
|
||||
this.txtR6 = new System.Windows.Forms.TextBox();
|
||||
this.txtR10 = new System.Windows.Forms.TextBox();
|
||||
this.txtR14 = new System.Windows.Forms.TextBox();
|
||||
this.txtR7 = new System.Windows.Forms.TextBox();
|
||||
this.txtR11 = new System.Windows.Forms.TextBox();
|
||||
this.txtR15 = new System.Windows.Forms.TextBox();
|
||||
this.label17 = new System.Windows.Forms.Label();
|
||||
this.label18 = new System.Windows.Forms.Label();
|
||||
this.txtSrc = new System.Windows.Forms.TextBox();
|
||||
this.txtDest = new System.Windows.Forms.TextBox();
|
||||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.txtSFR = new System.Windows.Forms.TextBox();
|
||||
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.chkPrefix = new System.Windows.Forms.CheckBox();
|
||||
this.chkAlt2 = new System.Windows.Forms.CheckBox();
|
||||
this.chkZero = new System.Windows.Forms.CheckBox();
|
||||
this.chkCarry = new System.Windows.Forms.CheckBox();
|
||||
this.chkNegative = new System.Windows.Forms.CheckBox();
|
||||
this.chkOverflow = new System.Windows.Forms.CheckBox();
|
||||
this.chkAlt1 = new System.Windows.Forms.CheckBox();
|
||||
this.chkIrq = new System.Windows.Forms.CheckBox();
|
||||
this.chkRomRead = new System.Windows.Forms.CheckBox();
|
||||
this.chkRunning = new System.Windows.Forms.CheckBox();
|
||||
this.label19 = new System.Windows.Forms.Label();
|
||||
this.txtProgramBank = new System.Windows.Forms.TextBox();
|
||||
this.txtRamBank = new System.Windows.Forms.TextBox();
|
||||
this.txtRomBank = new System.Windows.Forms.TextBox();
|
||||
this.label20 = new System.Windows.Forms.Label();
|
||||
this.label21 = new System.Windows.Forms.Label();
|
||||
this.grpSpc.SuspendLayout();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// grpSpc
|
||||
//
|
||||
this.grpSpc.Controls.Add(this.tableLayoutPanel1);
|
||||
this.grpSpc.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.grpSpc.Location = new System.Drawing.Point(0, 0);
|
||||
this.grpSpc.Name = "grpSpc";
|
||||
this.grpSpc.Size = new System.Drawing.Size(342, 226);
|
||||
this.grpSpc.TabIndex = 0;
|
||||
this.grpSpc.TabStop = false;
|
||||
this.grpSpc.Text = "GSU (Super FX)";
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 9;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.label1, 2, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblR0, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR0, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label2, 4, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR1, 3, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR2, 5, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label6, 6, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR3, 7, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label3, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label4, 0, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label5, 2, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label8, 4, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label9, 6, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label10, 2, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label11, 4, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label12, 6, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label13, 0, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label14, 2, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label15, 4, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label16, 6, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR4, 1, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR8, 1, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR12, 1, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR5, 3, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR9, 3, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR13, 3, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR6, 5, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR10, 5, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR14, 5, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR7, 7, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR11, 7, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtR15, 7, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label17, 0, 4);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label18, 2, 4);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtSrc, 1, 4);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtDest, 3, 4);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label7, 0, 5);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtSFR, 1, 5);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 1, 7);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label19, 6, 4);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtProgramBank, 7, 4);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtRamBank, 7, 5);
|
||||
this.tableLayoutPanel1.Controls.Add(this.txtRomBank, 5, 5);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label20, 6, 5);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label21, 4, 5);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 16);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 10;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(336, 207);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(87, 6);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(24, 13);
|
||||
this.label1.TabIndex = 2;
|
||||
this.label1.Text = "R1:";
|
||||
//
|
||||
// lblR0
|
||||
//
|
||||
this.lblR0.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblR0.AutoSize = true;
|
||||
this.lblR0.Location = new System.Drawing.Point(3, 6);
|
||||
this.lblR0.Name = "lblR0";
|
||||
this.lblR0.Size = new System.Drawing.Size(24, 13);
|
||||
this.lblR0.TabIndex = 0;
|
||||
this.lblR0.Text = "R0:";
|
||||
//
|
||||
// txtR0
|
||||
//
|
||||
this.txtR0.Location = new System.Drawing.Point(41, 3);
|
||||
this.txtR0.Name = "txtR0";
|
||||
this.txtR0.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR0.TabIndex = 1;
|
||||
this.txtR0.Text = "DDDD";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(171, 6);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(24, 13);
|
||||
this.label2.TabIndex = 3;
|
||||
this.label2.Text = "R2:";
|
||||
//
|
||||
// txtR1
|
||||
//
|
||||
this.txtR1.Location = new System.Drawing.Point(125, 3);
|
||||
this.txtR1.Name = "txtR1";
|
||||
this.txtR1.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR1.TabIndex = 4;
|
||||
//
|
||||
// txtR2
|
||||
//
|
||||
this.txtR2.Location = new System.Drawing.Point(209, 3);
|
||||
this.txtR2.Name = "txtR2";
|
||||
this.txtR2.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR2.TabIndex = 5;
|
||||
//
|
||||
// label6
|
||||
//
|
||||
this.label6.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label6.AutoSize = true;
|
||||
this.label6.Location = new System.Drawing.Point(255, 6);
|
||||
this.label6.Name = "label6";
|
||||
this.label6.Size = new System.Drawing.Size(24, 13);
|
||||
this.label6.TabIndex = 12;
|
||||
this.label6.Text = "R3:";
|
||||
//
|
||||
// txtR3
|
||||
//
|
||||
this.txtR3.Location = new System.Drawing.Point(292, 3);
|
||||
this.txtR3.Name = "txtR3";
|
||||
this.txtR3.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR3.TabIndex = 13;
|
||||
this.txtR3.Text = "DDDD";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(3, 32);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(24, 13);
|
||||
this.label3.TabIndex = 17;
|
||||
this.label3.Text = "R4:";
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(3, 58);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(24, 13);
|
||||
this.label4.TabIndex = 18;
|
||||
this.label4.Text = "R8:";
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.Location = new System.Drawing.Point(87, 32);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(24, 13);
|
||||
this.label5.TabIndex = 19;
|
||||
this.label5.Text = "R5:";
|
||||
//
|
||||
// label8
|
||||
//
|
||||
this.label8.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label8.AutoSize = true;
|
||||
this.label8.Location = new System.Drawing.Point(171, 32);
|
||||
this.label8.Name = "label8";
|
||||
this.label8.Size = new System.Drawing.Size(24, 13);
|
||||
this.label8.TabIndex = 20;
|
||||
this.label8.Text = "R6:";
|
||||
//
|
||||
// label9
|
||||
//
|
||||
this.label9.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label9.AutoSize = true;
|
||||
this.label9.Location = new System.Drawing.Point(255, 32);
|
||||
this.label9.Name = "label9";
|
||||
this.label9.Size = new System.Drawing.Size(24, 13);
|
||||
this.label9.TabIndex = 21;
|
||||
this.label9.Text = "R7:";
|
||||
//
|
||||
// label10
|
||||
//
|
||||
this.label10.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label10.AutoSize = true;
|
||||
this.label10.Location = new System.Drawing.Point(87, 58);
|
||||
this.label10.Name = "label10";
|
||||
this.label10.Size = new System.Drawing.Size(24, 13);
|
||||
this.label10.TabIndex = 22;
|
||||
this.label10.Text = "R9:";
|
||||
//
|
||||
// label11
|
||||
//
|
||||
this.label11.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label11.AutoSize = true;
|
||||
this.label11.Location = new System.Drawing.Point(171, 58);
|
||||
this.label11.Name = "label11";
|
||||
this.label11.Size = new System.Drawing.Size(30, 13);
|
||||
this.label11.TabIndex = 23;
|
||||
this.label11.Text = "R10:";
|
||||
//
|
||||
// label12
|
||||
//
|
||||
this.label12.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label12.AutoSize = true;
|
||||
this.label12.Location = new System.Drawing.Point(255, 58);
|
||||
this.label12.Name = "label12";
|
||||
this.label12.Size = new System.Drawing.Size(30, 13);
|
||||
this.label12.TabIndex = 24;
|
||||
this.label12.Text = "R11:";
|
||||
//
|
||||
// label13
|
||||
//
|
||||
this.label13.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label13.AutoSize = true;
|
||||
this.label13.Location = new System.Drawing.Point(3, 84);
|
||||
this.label13.Name = "label13";
|
||||
this.label13.Size = new System.Drawing.Size(30, 13);
|
||||
this.label13.TabIndex = 25;
|
||||
this.label13.Text = "R12:";
|
||||
//
|
||||
// label14
|
||||
//
|
||||
this.label14.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label14.AutoSize = true;
|
||||
this.label14.Location = new System.Drawing.Point(87, 84);
|
||||
this.label14.Name = "label14";
|
||||
this.label14.Size = new System.Drawing.Size(30, 13);
|
||||
this.label14.TabIndex = 26;
|
||||
this.label14.Text = "R13:";
|
||||
//
|
||||
// label15
|
||||
//
|
||||
this.label15.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label15.AutoSize = true;
|
||||
this.label15.Location = new System.Drawing.Point(171, 84);
|
||||
this.label15.Name = "label15";
|
||||
this.label15.Size = new System.Drawing.Size(30, 13);
|
||||
this.label15.TabIndex = 27;
|
||||
this.label15.Text = "R14:";
|
||||
//
|
||||
// label16
|
||||
//
|
||||
this.label16.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label16.AutoSize = true;
|
||||
this.label16.Location = new System.Drawing.Point(255, 84);
|
||||
this.label16.Name = "label16";
|
||||
this.label16.Size = new System.Drawing.Size(30, 13);
|
||||
this.label16.TabIndex = 28;
|
||||
this.label16.Text = "R15:";
|
||||
//
|
||||
// txtR4
|
||||
//
|
||||
this.txtR4.Location = new System.Drawing.Point(41, 29);
|
||||
this.txtR4.Name = "txtR4";
|
||||
this.txtR4.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR4.TabIndex = 29;
|
||||
this.txtR4.Text = "DDDD";
|
||||
//
|
||||
// txtR8
|
||||
//
|
||||
this.txtR8.Location = new System.Drawing.Point(41, 55);
|
||||
this.txtR8.Name = "txtR8";
|
||||
this.txtR8.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR8.TabIndex = 30;
|
||||
this.txtR8.Text = "DDDD";
|
||||
//
|
||||
// txtR12
|
||||
//
|
||||
this.txtR12.Location = new System.Drawing.Point(41, 81);
|
||||
this.txtR12.Name = "txtR12";
|
||||
this.txtR12.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR12.TabIndex = 31;
|
||||
this.txtR12.Text = "DDDD";
|
||||
//
|
||||
// txtR5
|
||||
//
|
||||
this.txtR5.Location = new System.Drawing.Point(125, 29);
|
||||
this.txtR5.Name = "txtR5";
|
||||
this.txtR5.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR5.TabIndex = 32;
|
||||
this.txtR5.Text = "DDDD";
|
||||
//
|
||||
// txtR9
|
||||
//
|
||||
this.txtR9.Location = new System.Drawing.Point(125, 55);
|
||||
this.txtR9.Name = "txtR9";
|
||||
this.txtR9.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR9.TabIndex = 33;
|
||||
this.txtR9.Text = "DDDD";
|
||||
//
|
||||
// txtR13
|
||||
//
|
||||
this.txtR13.Location = new System.Drawing.Point(125, 81);
|
||||
this.txtR13.Name = "txtR13";
|
||||
this.txtR13.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR13.TabIndex = 34;
|
||||
this.txtR13.Text = "DDDD";
|
||||
//
|
||||
// txtR6
|
||||
//
|
||||
this.txtR6.Location = new System.Drawing.Point(209, 29);
|
||||
this.txtR6.Name = "txtR6";
|
||||
this.txtR6.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR6.TabIndex = 35;
|
||||
this.txtR6.Text = "DDDD";
|
||||
//
|
||||
// txtR10
|
||||
//
|
||||
this.txtR10.Location = new System.Drawing.Point(209, 55);
|
||||
this.txtR10.Name = "txtR10";
|
||||
this.txtR10.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR10.TabIndex = 36;
|
||||
this.txtR10.Text = "DDDD";
|
||||
//
|
||||
// txtR14
|
||||
//
|
||||
this.txtR14.Location = new System.Drawing.Point(209, 81);
|
||||
this.txtR14.Name = "txtR14";
|
||||
this.txtR14.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR14.TabIndex = 37;
|
||||
this.txtR14.Text = "DDDD";
|
||||
//
|
||||
// txtR7
|
||||
//
|
||||
this.txtR7.Location = new System.Drawing.Point(292, 29);
|
||||
this.txtR7.Name = "txtR7";
|
||||
this.txtR7.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR7.TabIndex = 38;
|
||||
this.txtR7.Text = "DDDD";
|
||||
//
|
||||
// txtR11
|
||||
//
|
||||
this.txtR11.Location = new System.Drawing.Point(292, 55);
|
||||
this.txtR11.Name = "txtR11";
|
||||
this.txtR11.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR11.TabIndex = 39;
|
||||
this.txtR11.Text = "DDDD";
|
||||
//
|
||||
// txtR15
|
||||
//
|
||||
this.txtR15.Location = new System.Drawing.Point(292, 81);
|
||||
this.txtR15.Name = "txtR15";
|
||||
this.txtR15.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtR15.TabIndex = 40;
|
||||
this.txtR15.Text = "DDDD";
|
||||
//
|
||||
// label17
|
||||
//
|
||||
this.label17.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label17.AutoSize = true;
|
||||
this.label17.Location = new System.Drawing.Point(3, 110);
|
||||
this.label17.Name = "label17";
|
||||
this.label17.Size = new System.Drawing.Size(32, 13);
|
||||
this.label17.TabIndex = 41;
|
||||
this.label17.Text = "SRC:";
|
||||
//
|
||||
// label18
|
||||
//
|
||||
this.label18.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label18.AutoSize = true;
|
||||
this.label18.Location = new System.Drawing.Point(87, 110);
|
||||
this.label18.Name = "label18";
|
||||
this.label18.Size = new System.Drawing.Size(32, 13);
|
||||
this.label18.TabIndex = 42;
|
||||
this.label18.Text = "DST:";
|
||||
//
|
||||
// txtSrc
|
||||
//
|
||||
this.txtSrc.Location = new System.Drawing.Point(41, 107);
|
||||
this.txtSrc.Name = "txtSrc";
|
||||
this.txtSrc.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtSrc.TabIndex = 43;
|
||||
//
|
||||
// txtDest
|
||||
//
|
||||
this.txtDest.Location = new System.Drawing.Point(125, 107);
|
||||
this.txtDest.Name = "txtDest";
|
||||
this.txtDest.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtDest.TabIndex = 44;
|
||||
//
|
||||
// label7
|
||||
//
|
||||
this.label7.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label7.AutoSize = true;
|
||||
this.label7.Location = new System.Drawing.Point(3, 136);
|
||||
this.label7.Name = "label7";
|
||||
this.label7.Size = new System.Drawing.Size(31, 13);
|
||||
this.label7.TabIndex = 14;
|
||||
this.label7.Text = "SFR:";
|
||||
//
|
||||
// txtSFR
|
||||
//
|
||||
this.txtSFR.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.txtSFR.Location = new System.Drawing.Point(41, 133);
|
||||
this.txtSFR.Name = "txtSFR";
|
||||
this.txtSFR.Size = new System.Drawing.Size(40, 20);
|
||||
this.txtSFR.TabIndex = 15;
|
||||
this.txtSFR.Text = "DD";
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
this.tableLayoutPanel2.ColumnCount = 6;
|
||||
this.tableLayoutPanel1.SetColumnSpan(this.tableLayoutPanel2, 7);
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkPrefix, 0, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkAlt2, 0, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkZero, 0, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkCarry, 1, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkNegative, 2, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkOverflow, 3, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkAlt1, 0, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkIrq, 1, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkRomRead, 4, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkRunning, 4, 1);
|
||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(41, 159);
|
||||
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
this.tableLayoutPanel2.RowCount = 2;
|
||||
this.tableLayoutPanel1.SetRowSpan(this.tableLayoutPanel2, 2);
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(288, 46);
|
||||
this.tableLayoutPanel2.TabIndex = 16;
|
||||
//
|
||||
// chkPrefix
|
||||
//
|
||||
this.chkPrefix.AutoSize = true;
|
||||
this.chkPrefix.Location = new System.Drawing.Point(103, 26);
|
||||
this.chkPrefix.Name = "chkPrefix";
|
||||
this.chkPrefix.Size = new System.Drawing.Size(33, 17);
|
||||
this.chkPrefix.TabIndex = 27;
|
||||
this.chkPrefix.Text = "B";
|
||||
this.chkPrefix.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkAlt2
|
||||
//
|
||||
this.chkAlt2.AutoSize = true;
|
||||
this.chkAlt2.Location = new System.Drawing.Point(53, 26);
|
||||
this.chkAlt2.Name = "chkAlt2";
|
||||
this.chkAlt2.Size = new System.Drawing.Size(44, 17);
|
||||
this.chkAlt2.TabIndex = 26;
|
||||
this.chkAlt2.Text = "Alt2";
|
||||
this.chkAlt2.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkZero
|
||||
//
|
||||
this.chkZero.AutoSize = true;
|
||||
this.chkZero.Location = new System.Drawing.Point(3, 3);
|
||||
this.chkZero.Name = "chkZero";
|
||||
this.chkZero.Size = new System.Drawing.Size(33, 17);
|
||||
this.chkZero.TabIndex = 21;
|
||||
this.chkZero.Text = "Z";
|
||||
this.chkZero.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkCarry
|
||||
//
|
||||
this.chkCarry.AutoSize = true;
|
||||
this.chkCarry.Location = new System.Drawing.Point(53, 3);
|
||||
this.chkCarry.Name = "chkCarry";
|
||||
this.chkCarry.Size = new System.Drawing.Size(33, 17);
|
||||
this.chkCarry.TabIndex = 23;
|
||||
this.chkCarry.Text = "C";
|
||||
this.chkCarry.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkNegative
|
||||
//
|
||||
this.chkNegative.AutoSize = true;
|
||||
this.chkNegative.Location = new System.Drawing.Point(103, 3);
|
||||
this.chkNegative.Name = "chkNegative";
|
||||
this.chkNegative.Size = new System.Drawing.Size(33, 17);
|
||||
this.chkNegative.TabIndex = 17;
|
||||
this.chkNegative.Text = "S";
|
||||
this.chkNegative.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkOverflow
|
||||
//
|
||||
this.chkOverflow.AutoSize = true;
|
||||
this.chkOverflow.Location = new System.Drawing.Point(142, 3);
|
||||
this.chkOverflow.Name = "chkOverflow";
|
||||
this.chkOverflow.Size = new System.Drawing.Size(33, 17);
|
||||
this.chkOverflow.TabIndex = 20;
|
||||
this.chkOverflow.Text = "V";
|
||||
this.chkOverflow.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkAlt1
|
||||
//
|
||||
this.chkAlt1.AutoSize = true;
|
||||
this.chkAlt1.Location = new System.Drawing.Point(3, 26);
|
||||
this.chkAlt1.Name = "chkAlt1";
|
||||
this.chkAlt1.Size = new System.Drawing.Size(44, 17);
|
||||
this.chkAlt1.TabIndex = 19;
|
||||
this.chkAlt1.Text = "Alt1";
|
||||
this.chkAlt1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkIrq
|
||||
//
|
||||
this.chkIrq.AutoSize = true;
|
||||
this.chkIrq.Location = new System.Drawing.Point(142, 26);
|
||||
this.chkIrq.Name = "chkIrq";
|
||||
this.chkIrq.Size = new System.Drawing.Size(45, 17);
|
||||
this.chkIrq.TabIndex = 18;
|
||||
this.chkIrq.Text = "IRQ";
|
||||
this.chkIrq.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkRomRead
|
||||
//
|
||||
this.chkRomRead.AutoSize = true;
|
||||
this.chkRomRead.Location = new System.Drawing.Point(193, 3);
|
||||
this.chkRomRead.Name = "chkRomRead";
|
||||
this.chkRomRead.Size = new System.Drawing.Size(80, 17);
|
||||
this.chkRomRead.TabIndex = 24;
|
||||
this.chkRomRead.Text = "ROM Read";
|
||||
this.chkRomRead.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkRunning
|
||||
//
|
||||
this.chkRunning.AutoSize = true;
|
||||
this.chkRunning.Location = new System.Drawing.Point(193, 26);
|
||||
this.chkRunning.Name = "chkRunning";
|
||||
this.chkRunning.Size = new System.Drawing.Size(66, 17);
|
||||
this.chkRunning.TabIndex = 25;
|
||||
this.chkRunning.Text = "Running";
|
||||
this.chkRunning.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// label19
|
||||
//
|
||||
this.label19.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label19.AutoSize = true;
|
||||
this.label19.Location = new System.Drawing.Point(255, 110);
|
||||
this.label19.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
|
||||
this.label19.Name = "label19";
|
||||
this.label19.Size = new System.Drawing.Size(32, 13);
|
||||
this.label19.TabIndex = 45;
|
||||
this.label19.Text = "PBR:";
|
||||
//
|
||||
// txtProgramBank
|
||||
//
|
||||
this.txtProgramBank.Location = new System.Drawing.Point(292, 107);
|
||||
this.txtProgramBank.Name = "txtProgramBank";
|
||||
this.txtProgramBank.Size = new System.Drawing.Size(25, 20);
|
||||
this.txtProgramBank.TabIndex = 46;
|
||||
this.txtProgramBank.Text = "DD";
|
||||
//
|
||||
// txtRamBank
|
||||
//
|
||||
this.txtRamBank.Location = new System.Drawing.Point(292, 133);
|
||||
this.txtRamBank.Name = "txtRamBank";
|
||||
this.txtRamBank.Size = new System.Drawing.Size(25, 20);
|
||||
this.txtRamBank.TabIndex = 49;
|
||||
this.txtRamBank.Text = "DD";
|
||||
//
|
||||
// txtRomBank
|
||||
//
|
||||
this.txtRomBank.Location = new System.Drawing.Point(209, 133);
|
||||
this.txtRomBank.Name = "txtRomBank";
|
||||
this.txtRomBank.Size = new System.Drawing.Size(25, 20);
|
||||
this.txtRomBank.TabIndex = 50;
|
||||
this.txtRomBank.Text = "DD";
|
||||
//
|
||||
// label20
|
||||
//
|
||||
this.label20.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label20.AutoSize = true;
|
||||
this.label20.Location = new System.Drawing.Point(255, 136);
|
||||
this.label20.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
|
||||
this.label20.Name = "label20";
|
||||
this.label20.Size = new System.Drawing.Size(34, 13);
|
||||
this.label20.TabIndex = 47;
|
||||
this.label20.Text = "RAM:";
|
||||
//
|
||||
// label21
|
||||
//
|
||||
this.label21.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label21.AutoSize = true;
|
||||
this.label21.Location = new System.Drawing.Point(171, 136);
|
||||
this.label21.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
|
||||
this.label21.Name = "label21";
|
||||
this.label21.Size = new System.Drawing.Size(35, 13);
|
||||
this.label21.TabIndex = 48;
|
||||
this.label21.Text = "ROM:";
|
||||
//
|
||||
// ctrlGsuStatus
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.grpSpc);
|
||||
this.Name = "ctrlGsuStatus";
|
||||
this.Size = new System.Drawing.Size(342, 225);
|
||||
this.grpSpc.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.tableLayoutPanel2.ResumeLayout(false);
|
||||
this.tableLayoutPanel2.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.GroupBox grpSpc;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label lblR0;
|
||||
private System.Windows.Forms.TextBox txtR0;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.TextBox txtR1;
|
||||
private System.Windows.Forms.TextBox txtR2;
|
||||
private System.Windows.Forms.Label label6;
|
||||
private System.Windows.Forms.TextBox txtR3;
|
||||
private System.Windows.Forms.Label label7;
|
||||
private System.Windows.Forms.TextBox txtSFR;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
|
||||
private System.Windows.Forms.CheckBox chkRunning;
|
||||
private System.Windows.Forms.CheckBox chkRomRead;
|
||||
private System.Windows.Forms.CheckBox chkCarry;
|
||||
private System.Windows.Forms.CheckBox chkZero;
|
||||
private System.Windows.Forms.CheckBox chkIrq;
|
||||
private System.Windows.Forms.CheckBox chkAlt1;
|
||||
private System.Windows.Forms.CheckBox chkNegative;
|
||||
private System.Windows.Forms.CheckBox chkOverflow;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.Label label8;
|
||||
private System.Windows.Forms.Label label9;
|
||||
private System.Windows.Forms.Label label10;
|
||||
private System.Windows.Forms.Label label11;
|
||||
private System.Windows.Forms.Label label12;
|
||||
private System.Windows.Forms.Label label13;
|
||||
private System.Windows.Forms.Label label14;
|
||||
private System.Windows.Forms.Label label15;
|
||||
private System.Windows.Forms.Label label16;
|
||||
private System.Windows.Forms.TextBox txtR4;
|
||||
private System.Windows.Forms.TextBox txtR8;
|
||||
private System.Windows.Forms.TextBox txtR12;
|
||||
private System.Windows.Forms.TextBox txtR5;
|
||||
private System.Windows.Forms.TextBox txtR9;
|
||||
private System.Windows.Forms.TextBox txtR13;
|
||||
private System.Windows.Forms.TextBox txtR6;
|
||||
private System.Windows.Forms.TextBox txtR10;
|
||||
private System.Windows.Forms.TextBox txtR14;
|
||||
private System.Windows.Forms.TextBox txtR7;
|
||||
private System.Windows.Forms.TextBox txtR11;
|
||||
private System.Windows.Forms.TextBox txtR15;
|
||||
private System.Windows.Forms.Label label17;
|
||||
private System.Windows.Forms.Label label18;
|
||||
private System.Windows.Forms.TextBox txtSrc;
|
||||
private System.Windows.Forms.TextBox txtDest;
|
||||
private System.Windows.Forms.CheckBox chkAlt2;
|
||||
private System.Windows.Forms.CheckBox chkPrefix;
|
||||
private System.Windows.Forms.Label label19;
|
||||
private System.Windows.Forms.TextBox txtProgramBank;
|
||||
private System.Windows.Forms.TextBox txtRamBank;
|
||||
private System.Windows.Forms.TextBox txtRomBank;
|
||||
private System.Windows.Forms.Label label20;
|
||||
private System.Windows.Forms.Label label21;
|
||||
}
|
||||
}
|
83
UI/Debugger/Controls/ctrlGsuStatus.cs
Normal file
83
UI/Debugger/Controls/ctrlGsuStatus.cs
Normal file
|
@ -0,0 +1,83 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Mesen.GUI.Controls;
|
||||
using Mesen.GUI.Forms;
|
||||
|
||||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
public partial class ctrlGsuStatus : BaseControl
|
||||
{
|
||||
public ctrlGsuStatus()
|
||||
{
|
||||
InitializeComponent();
|
||||
if(IsDesignMode) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateStatus(GsuState state)
|
||||
{
|
||||
txtR0.Text = state.R[0].ToString("X4");
|
||||
txtR1.Text = state.R[1].ToString("X4");
|
||||
txtR2.Text = state.R[2].ToString("X4");
|
||||
txtR3.Text = state.R[3].ToString("X4");
|
||||
txtR4.Text = state.R[4].ToString("X4");
|
||||
txtR5.Text = state.R[5].ToString("X4");
|
||||
txtR6.Text = state.R[6].ToString("X4");
|
||||
txtR7.Text = state.R[7].ToString("X4");
|
||||
txtR8.Text = state.R[8].ToString("X4");
|
||||
txtR9.Text = state.R[9].ToString("X4");
|
||||
txtR10.Text = state.R[10].ToString("X4");
|
||||
txtR11.Text = state.R[11].ToString("X4");
|
||||
txtR12.Text = state.R[12].ToString("X4");
|
||||
txtR13.Text = state.R[13].ToString("X4");
|
||||
txtR14.Text = state.R[14].ToString("X4");
|
||||
txtR15.Text = state.R[15].ToString("X4");
|
||||
|
||||
txtProgramBank.Text = state.ProgramBank.ToString("X2");
|
||||
txtRamBank.Text = state.RamBank.ToString("X2");
|
||||
txtRomBank.Text = state.RomBank.ToString("X2");
|
||||
|
||||
txtSrc.Text = state.SrcReg.ToString();
|
||||
txtDest.Text = state.DestReg.ToString();
|
||||
|
||||
chkAlt1.Checked = state.SFR.Alt1;
|
||||
chkAlt2.Checked = state.SFR.Alt2;
|
||||
chkPrefix.Checked = state.SFR.Prefix;
|
||||
chkIrq.Checked = state.SFR.Irq;
|
||||
chkRunning.Checked = state.SFR.Running;
|
||||
chkNegative.Checked = state.SFR.Sign;
|
||||
chkZero.Checked = state.SFR.Zero;
|
||||
chkOverflow.Checked = state.SFR.Overflow;
|
||||
chkCarry.Checked = state.SFR.Carry;
|
||||
chkRomRead.Checked = state.SFR.RomReadPending;
|
||||
|
||||
txtSFR.Text = GetFlags(ref state).ToString("X4");
|
||||
}
|
||||
|
||||
private UInt16 GetFlags(ref GsuState state)
|
||||
{
|
||||
return (UInt16)(
|
||||
(state.SFR.Zero ? 2 : 0) |
|
||||
(state.SFR.Carry ? 4 : 0) |
|
||||
(state.SFR.Sign ? 8 : 0) |
|
||||
(state.SFR.Overflow ? 0x10 : 0) |
|
||||
(state.SFR.Running ? 0x20 : 0) |
|
||||
(state.SFR.RomReadPending ? 0x40 : 0) |
|
||||
(state.SFR.Alt1 ? 0x100 : 0) |
|
||||
(state.SFR.Alt2 ? 0x200 : 0) |
|
||||
(state.SFR.ImmLow ? 0x400 : 0) |
|
||||
(state.SFR.ImmHigh ? 0x800 : 0) |
|
||||
(state.SFR.Prefix ? 0x1000 : 0) |
|
||||
(state.SFR.Irq ? 0x8000 : 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
120
UI/Debugger/Controls/ctrlGsuStatus.resx
Normal file
120
UI/Debugger/Controls/ctrlGsuStatus.resx
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
|
@ -29,6 +29,7 @@ namespace Mesen.GUI.Debugger
|
|||
case DebugWindow.Debugger: frm = new frmDebugger(CpuType.Cpu); frm.Icon = Properties.Resources.Debugger; break;
|
||||
case DebugWindow.SpcDebugger: frm = new frmDebugger(CpuType.Spc); frm.Icon = Properties.Resources.SpcDebugger; break;
|
||||
case DebugWindow.Sa1Debugger: frm = new frmDebugger(CpuType.Sa1); frm.Icon = Properties.Resources.Sa1Debugger; break;
|
||||
case DebugWindow.GsuDebugger: frm = new frmDebugger(CpuType.Gsu); frm.Icon = Properties.Resources.GsuDebugger; break;
|
||||
case DebugWindow.TraceLogger: frm = new frmTraceLogger(); frm.Icon = Properties.Resources.LogWindow; break;
|
||||
case DebugWindow.MemoryTools: frm = new frmMemoryTools(); frm.Icon = Properties.Resources.CheatCode; break;
|
||||
case DebugWindow.TileViewer: frm = new frmTileViewer(); frm.Icon = Properties.Resources.VerticalLayout; break;
|
||||
|
@ -82,6 +83,7 @@ namespace Mesen.GUI.Debugger
|
|||
case CpuType.Cpu: return (frmDebugger)OpenDebugWindow(DebugWindow.Debugger);
|
||||
case CpuType.Spc: return (frmDebugger)OpenDebugWindow(DebugWindow.SpcDebugger);
|
||||
case CpuType.Sa1: return (frmDebugger)OpenDebugWindow(DebugWindow.Sa1Debugger);
|
||||
case CpuType.Gsu: return (frmDebugger)OpenDebugWindow(DebugWindow.GsuDebugger);
|
||||
}
|
||||
throw new Exception("Invalid CPU type");
|
||||
}
|
||||
|
@ -114,6 +116,7 @@ namespace Mesen.GUI.Debugger
|
|||
case DebugWindow.Debugger: return _openedWindows.ToList().Find((form) => form.GetType() == typeof(frmDebugger) && ((frmDebugger)form).CpuType == CpuType.Cpu);
|
||||
case DebugWindow.SpcDebugger: return _openedWindows.ToList().Find((form) => form.GetType() == typeof(frmDebugger) && ((frmDebugger)form).CpuType == CpuType.Spc);
|
||||
case DebugWindow.Sa1Debugger: return _openedWindows.ToList().Find((form) => form.GetType() == typeof(frmDebugger) && ((frmDebugger)form).CpuType == CpuType.Sa1);
|
||||
case DebugWindow.GsuDebugger: return _openedWindows.ToList().Find((form) => form.GetType() == typeof(frmDebugger) && ((frmDebugger)form).CpuType == CpuType.Gsu);
|
||||
case DebugWindow.TraceLogger: return _openedWindows.ToList().Find((form) => form.GetType() == typeof(frmTraceLogger));
|
||||
case DebugWindow.EventViewer: return _openedWindows.ToList().Find((form) => form.GetType() == typeof(frmEventViewer));
|
||||
}
|
||||
|
@ -153,6 +156,7 @@ namespace Mesen.GUI.Debugger
|
|||
Debugger,
|
||||
SpcDebugger,
|
||||
Sa1Debugger,
|
||||
GsuDebugger,
|
||||
MemoryTools,
|
||||
TraceLogger,
|
||||
TileViewer,
|
||||
|
|
|
@ -68,9 +68,9 @@ namespace Mesen.GUI.Debugger.Labels
|
|||
return _labels.Where((lbl) => lbl.Matches(cpu)).ToList<CodeLabel>();
|
||||
}
|
||||
|
||||
private static UInt64 GetKey(UInt32 address, SnesMemoryType SnesMemoryType)
|
||||
private static UInt64 GetKey(UInt32 address, SnesMemoryType memType)
|
||||
{
|
||||
switch(SnesMemoryType) {
|
||||
switch(memType) {
|
||||
case SnesMemoryType.PrgRom: return address | ((ulong)1 << 32);
|
||||
case SnesMemoryType.WorkRam: return address | ((ulong)2 << 32);
|
||||
case SnesMemoryType.SaveRam: return address | ((ulong)3 << 32);
|
||||
|
@ -78,6 +78,7 @@ namespace Mesen.GUI.Debugger.Labels
|
|||
case SnesMemoryType.SpcRam: return address | ((ulong)5 << 32);
|
||||
case SnesMemoryType.SpcRom: return address | ((ulong)6 << 32);
|
||||
case SnesMemoryType.Sa1InternalRam: return address | ((ulong)7 << 32);
|
||||
case SnesMemoryType.GsuWorkRam: return address | ((ulong)8 << 32);
|
||||
}
|
||||
throw new Exception("Invalid type");
|
||||
}
|
||||
|
|
|
@ -173,6 +173,12 @@ namespace Mesen.GUI.Debugger
|
|||
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.Sa1InternalRam));
|
||||
}
|
||||
|
||||
if(DebugApi.GetMemorySize(SnesMemoryType.GsuWorkRam) > 0) {
|
||||
cboMemoryType.Items.Add("-");
|
||||
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.GsuMemory));
|
||||
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.GsuWorkRam));
|
||||
}
|
||||
|
||||
cboMemoryType.SelectedIndex = 0;
|
||||
cboMemoryType.SetEnumValue(originalValue);
|
||||
cboMemoryType.SelectedIndexChanged += this.cboMemoryType_SelectedIndexChanged;
|
||||
|
|
|
@ -266,6 +266,10 @@ namespace Mesen.GUI.Debugger
|
|||
cboMemoryType.Items.Add("-");
|
||||
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.PrgRom));
|
||||
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.WorkRam));
|
||||
if(DebugApi.GetMemorySize(SnesMemoryType.GsuWorkRam) > 0) {
|
||||
cboMemoryType.Items.Add("-");
|
||||
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.GsuWorkRam));
|
||||
}
|
||||
|
||||
cboMemoryType.SelectedIndex = 0;
|
||||
cboMemoryType.EndUpdate();
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace Mesen.GUI.Debugger.Workspace
|
|||
public List<string> WatchValues = new List<string>();
|
||||
public List<string> SpcWatchValues = new List<string>();
|
||||
public List<string> Sa1WatchValues = new List<string>();
|
||||
public List<string> GsuWatchValues = new List<string>();
|
||||
public List<CodeLabel> CpuLabels = new List<CodeLabel>();
|
||||
public List<CodeLabel> SpcLabels = new List<CodeLabel>();
|
||||
public List<string> TblMappings = null;
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace Mesen.GUI.Debugger.Workspace
|
|||
_workspace.WatchValues = new List<string>(WatchManager.GetWatchManager(CpuType.Cpu).WatchEntries);
|
||||
_workspace.SpcWatchValues = new List<string>(WatchManager.GetWatchManager(CpuType.Spc).WatchEntries);
|
||||
_workspace.Sa1WatchValues = new List<string>(WatchManager.GetWatchManager(CpuType.Sa1).WatchEntries);
|
||||
_workspace.GsuWatchValues = new List<string>(WatchManager.GetWatchManager(CpuType.Gsu).WatchEntries);
|
||||
_workspace.Breakpoints = new List<Breakpoint>(BreakpointManager.Breakpoints);
|
||||
_workspace.CpuLabels = new List<CodeLabel>(LabelManager.GetLabels(CpuType.Cpu));
|
||||
_workspace.SpcLabels = new List<CodeLabel>(LabelManager.GetLabels(CpuType.Spc));
|
||||
|
@ -47,11 +48,13 @@ namespace Mesen.GUI.Debugger.Workspace
|
|||
_workspace.WatchValues = new List<string>();
|
||||
_workspace.SpcWatchValues = new List<string>();
|
||||
_workspace.Sa1WatchValues = new List<string>();
|
||||
_workspace.GsuWatchValues = new List<string>();
|
||||
_workspace.CpuLabels = new List<CodeLabel>();
|
||||
_workspace.SpcLabels = new List<CodeLabel>();
|
||||
WatchManager.GetWatchManager(CpuType.Cpu).WatchEntries = _workspace.WatchValues;
|
||||
WatchManager.GetWatchManager(CpuType.Spc).WatchEntries = _workspace.SpcWatchValues;
|
||||
WatchManager.GetWatchManager(CpuType.Sa1).WatchEntries = _workspace.Sa1WatchValues;
|
||||
WatchManager.GetWatchManager(CpuType.Gsu).WatchEntries = _workspace.GsuWatchValues;
|
||||
BreakpointManager.SetBreakpoints(_workspace.Breakpoints);
|
||||
LabelManager.SetDefaultLabels();
|
||||
LabelManager.RefreshLabels();
|
||||
|
@ -85,6 +88,7 @@ namespace Mesen.GUI.Debugger.Workspace
|
|||
WatchManager.GetWatchManager(CpuType.Cpu).WatchEntries = _workspace.WatchValues;
|
||||
WatchManager.GetWatchManager(CpuType.Spc).WatchEntries = _workspace.SpcWatchValues;
|
||||
WatchManager.GetWatchManager(CpuType.Sa1).WatchEntries = _workspace.Sa1WatchValues;
|
||||
WatchManager.GetWatchManager(CpuType.Gsu).WatchEntries = _workspace.GsuWatchValues;
|
||||
|
||||
LabelManager.ResetLabels();
|
||||
LabelManager.SetLabels(_workspace.CpuLabels);
|
||||
|
|
|
@ -59,6 +59,7 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
GetMember(nameof(DebuggerShortcutsConfig.OpenSpcDebugger)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.OpenSa1Debugger)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.OpenGsuDebugger)),
|
||||
};
|
||||
|
||||
ctrlDbgShortcutsMemoryViewer.Shortcuts = new FieldInfo[] {
|
||||
|
|
60
UI/Debugger/frmDebugger.Designer.cs
generated
60
UI/Debugger/frmDebugger.Designer.cs
generated
|
@ -116,9 +116,10 @@
|
|||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.ctrlLabelList = new Mesen.GUI.Debugger.Controls.ctrlLabelList();
|
||||
this.ctrlPpuStatus = new Mesen.GUI.Debugger.Controls.ctrlPpuStatus();
|
||||
this.ctrlGsuStatus = new Mesen.GUI.Debugger.Controls.ctrlGsuStatus();
|
||||
this.ctrlSpcStatus = new Mesen.GUI.Debugger.Controls.ctrlSpcStatus();
|
||||
this.ctrlCpuStatus = new Mesen.GUI.Debugger.Controls.ctrlCpuStatus();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.tlpBottomPanel = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.grpWatch = new System.Windows.Forms.GroupBox();
|
||||
this.picWatchHelp = new System.Windows.Forms.PictureBox();
|
||||
this.ctrlWatch = new Mesen.GUI.Debugger.ctrlWatch();
|
||||
|
@ -133,7 +134,7 @@
|
|||
this.ctrlSplitContainer.Panel2.SuspendLayout();
|
||||
this.ctrlSplitContainer.SuspendLayout();
|
||||
this.panel1.SuspendLayout();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.tlpBottomPanel.SuspendLayout();
|
||||
this.grpWatch.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picWatchHelp)).BeginInit();
|
||||
this.grpBreakpoints.SuspendLayout();
|
||||
|
@ -208,7 +209,7 @@
|
|||
//
|
||||
this.mnuResetCdlLog.Image = global::Mesen.GUI.Properties.Resources.Refresh;
|
||||
this.mnuResetCdlLog.Name = "mnuResetCdlLog";
|
||||
this.mnuResetCdlLog.Size = new System.Drawing.Size(152, 22);
|
||||
this.mnuResetCdlLog.Size = new System.Drawing.Size(122, 22);
|
||||
this.mnuResetCdlLog.Text = "Reset log";
|
||||
this.mnuResetCdlLog.Click += new System.EventHandler(this.mnuResetCdlLog_Click);
|
||||
//
|
||||
|
@ -766,7 +767,7 @@
|
|||
//
|
||||
// ctrlSplitContainer.Panel2
|
||||
//
|
||||
this.ctrlSplitContainer.Panel2.Controls.Add(this.tableLayoutPanel1);
|
||||
this.ctrlSplitContainer.Panel2.Controls.Add(this.tlpBottomPanel);
|
||||
this.ctrlSplitContainer.Panel2MinSize = 100;
|
||||
this.ctrlSplitContainer.Size = new System.Drawing.Size(832, 595);
|
||||
this.ctrlSplitContainer.SplitterDistance = 433;
|
||||
|
@ -776,6 +777,7 @@
|
|||
//
|
||||
this.panel1.Controls.Add(this.ctrlLabelList);
|
||||
this.panel1.Controls.Add(this.ctrlPpuStatus);
|
||||
this.panel1.Controls.Add(this.ctrlGsuStatus);
|
||||
this.panel1.Controls.Add(this.ctrlSpcStatus);
|
||||
this.panel1.Controls.Add(this.ctrlCpuStatus);
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Right;
|
||||
|
@ -788,20 +790,29 @@
|
|||
//
|
||||
this.ctrlLabelList.CpuType = Mesen.GUI.CpuType.Cpu;
|
||||
this.ctrlLabelList.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlLabelList.Location = new System.Drawing.Point(0, 315);
|
||||
this.ctrlLabelList.Location = new System.Drawing.Point(0, 551);
|
||||
this.ctrlLabelList.Name = "ctrlLabelList";
|
||||
this.ctrlLabelList.Size = new System.Drawing.Size(348, 118);
|
||||
this.ctrlLabelList.Size = new System.Drawing.Size(348, 0);
|
||||
this.ctrlLabelList.TabIndex = 4;
|
||||
//
|
||||
// ctrlPpuStatus
|
||||
//
|
||||
this.ctrlPpuStatus.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.ctrlPpuStatus.Location = new System.Drawing.Point(0, 268);
|
||||
this.ctrlPpuStatus.Location = new System.Drawing.Point(0, 504);
|
||||
this.ctrlPpuStatus.Name = "ctrlPpuStatus";
|
||||
this.ctrlPpuStatus.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.ctrlPpuStatus.Size = new System.Drawing.Size(348, 47);
|
||||
this.ctrlPpuStatus.TabIndex = 3;
|
||||
//
|
||||
// ctrlGsuStatus
|
||||
//
|
||||
this.ctrlGsuStatus.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.ctrlGsuStatus.Location = new System.Drawing.Point(0, 268);
|
||||
this.ctrlGsuStatus.Name = "ctrlGsuStatus";
|
||||
this.ctrlGsuStatus.Padding = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.ctrlGsuStatus.Size = new System.Drawing.Size(348, 236);
|
||||
this.ctrlGsuStatus.TabIndex = 5;
|
||||
//
|
||||
// ctrlSpcStatus
|
||||
//
|
||||
this.ctrlSpcStatus.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
|
@ -820,22 +831,22 @@
|
|||
this.ctrlCpuStatus.Size = new System.Drawing.Size(348, 148);
|
||||
this.ctrlCpuStatus.TabIndex = 1;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
// tlpBottomPanel
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 3;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.grpWatch, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.grpBreakpoints, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.grpCallstack, 2, 0);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 1;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(832, 158);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
this.tlpBottomPanel.ColumnCount = 3;
|
||||
this.tlpBottomPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
|
||||
this.tlpBottomPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
|
||||
this.tlpBottomPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
|
||||
this.tlpBottomPanel.Controls.Add(this.grpWatch, 0, 0);
|
||||
this.tlpBottomPanel.Controls.Add(this.grpBreakpoints, 1, 0);
|
||||
this.tlpBottomPanel.Controls.Add(this.grpCallstack, 2, 0);
|
||||
this.tlpBottomPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tlpBottomPanel.Location = new System.Drawing.Point(0, 0);
|
||||
this.tlpBottomPanel.Name = "tlpBottomPanel";
|
||||
this.tlpBottomPanel.RowCount = 1;
|
||||
this.tlpBottomPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpBottomPanel.Size = new System.Drawing.Size(832, 158);
|
||||
this.tlpBottomPanel.TabIndex = 0;
|
||||
//
|
||||
// grpWatch
|
||||
//
|
||||
|
@ -937,7 +948,7 @@
|
|||
((System.ComponentModel.ISupportInitialize)(this.ctrlSplitContainer)).EndInit();
|
||||
this.ctrlSplitContainer.ResumeLayout(false);
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tlpBottomPanel.ResumeLayout(false);
|
||||
this.grpWatch.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.picWatchHelp)).EndInit();
|
||||
this.grpBreakpoints.ResumeLayout(false);
|
||||
|
@ -973,7 +984,7 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem mnuBreakIn;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuBreakOn;
|
||||
private GUI.Controls.ctrlSplitContainer ctrlSplitContainer;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private System.Windows.Forms.TableLayoutPanel tlpBottomPanel;
|
||||
private ctrlWatch ctrlWatch;
|
||||
private System.Windows.Forms.GroupBox grpWatch;
|
||||
private System.Windows.Forms.GroupBox grpBreakpoints;
|
||||
|
@ -1045,5 +1056,6 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem mnuResetCdlLog;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem13;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuExit;
|
||||
private Controls.ctrlGsuStatus ctrlGsuStatus;
|
||||
}
|
||||
}
|
|
@ -63,6 +63,18 @@ namespace Mesen.GUI.Debugger
|
|||
ConfigApi.SetDebuggerFlag(DebuggerFlags.Sa1DebuggerEnabled, true);
|
||||
this.Text = "SA-1 Debugger";
|
||||
break;
|
||||
|
||||
case CpuType.Gsu:
|
||||
ctrlDisassemblyView.Initialize(new GsuDisassemblyManager(), new GsuLineStyleProvider());
|
||||
ConfigApi.SetDebuggerFlag(DebuggerFlags.GsuDebuggerEnabled, true);
|
||||
this.Text = "GSU Debugger";
|
||||
ctrlCallstack.Visible = false;
|
||||
ctrlLabelList.Visible = false;
|
||||
mnuStepOver.Visible = false;
|
||||
mnuStepOut.Visible = false;
|
||||
mnuStepInto.Text = "Step";
|
||||
tlpBottomPanel.ColumnCount = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
ctrlBreakpoints.CpuType = _cpuType;
|
||||
|
@ -94,6 +106,7 @@ namespace Mesen.GUI.Debugger
|
|||
case CpuType.Cpu: ConfigApi.SetDebuggerFlag(DebuggerFlags.CpuDebuggerEnabled, false); break;
|
||||
case CpuType.Spc: ConfigApi.SetDebuggerFlag(DebuggerFlags.SpcDebuggerEnabled, false); break;
|
||||
case CpuType.Sa1: ConfigApi.SetDebuggerFlag(DebuggerFlags.Sa1DebuggerEnabled, false); break;
|
||||
case CpuType.Gsu: ConfigApi.SetDebuggerFlag(DebuggerFlags.GsuDebuggerEnabled, false); break;
|
||||
}
|
||||
|
||||
BreakpointManager.RemoveCpuType(_cpuType);
|
||||
|
@ -248,9 +261,15 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
private void InitToolbar()
|
||||
{
|
||||
tsToolbar.AddItemsToToolbar(mnuContinue, mnuBreak, null);
|
||||
|
||||
if(_cpuType != CpuType.Gsu) {
|
||||
tsToolbar.AddItemsToToolbar(mnuStepInto, mnuStepOver, mnuStepOut, null);
|
||||
} else {
|
||||
tsToolbar.AddItemsToToolbar(mnuStepInto, null);
|
||||
}
|
||||
|
||||
tsToolbar.AddItemsToToolbar(
|
||||
mnuContinue, mnuBreak, null,
|
||||
mnuStepInto, mnuStepOver, mnuStepOut, null,
|
||||
mnuRunPpuCycle, mnuRunScanline, mnuRunOneFrame, null,
|
||||
mnuToggleBreakpoint, mnuEnableDisableBreakpoint, null,
|
||||
mnuBreakIn, null, mnuBreakOn
|
||||
|
@ -338,11 +357,20 @@ namespace Mesen.GUI.Debugger
|
|||
ctrlSpcStatus.Visible = false;
|
||||
}
|
||||
|
||||
if(_cpuType == CpuType.Gsu) {
|
||||
ctrlGsuStatus.UpdateStatus(state.Gsu);
|
||||
} else {
|
||||
ctrlGsuStatus.Visible = false;
|
||||
}
|
||||
|
||||
ctrlPpuStatus.UpdateStatus(state);
|
||||
ctrlDisassemblyView.UpdateCode();
|
||||
ctrlDisassemblyView.SetActiveAddress(activeAddress);
|
||||
ctrlWatch.UpdateWatch(true);
|
||||
ctrlCallstack.UpdateCallstack(_cpuType);
|
||||
|
||||
if(_cpuType != CpuType.Gsu) {
|
||||
ctrlCallstack.UpdateCallstack(_cpuType);
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessBreakEvent(BreakEvent evt, DebugState state, int activeAddress)
|
||||
|
@ -414,6 +442,7 @@ namespace Mesen.GUI.Debugger
|
|||
case CpuType.Cpu: activeAddress = (int)((state.Cpu.K << 16) | state.Cpu.PC); break;
|
||||
case CpuType.Spc: activeAddress = (int)state.Spc.PC; break;
|
||||
case CpuType.Sa1: activeAddress = (int)((state.Sa1.K << 16) | state.Sa1.PC); break;
|
||||
case CpuType.Gsu: activeAddress = (int)((state.Gsu.ProgramBank << 16) | state.Gsu.R[15]); break;
|
||||
default: throw new Exception("Unsupported cpu type");
|
||||
}
|
||||
|
||||
|
|
111
UI/Debugger/frmTraceLogger.Designer.cs
generated
111
UI/Debugger/frmTraceLogger.Designer.cs
generated
|
@ -61,9 +61,11 @@ namespace Mesen.GUI.Debugger
|
|||
this.cboStatusFlagFormat = new System.Windows.Forms.ComboBox();
|
||||
this.chkUseWindowsEol = new System.Windows.Forms.CheckBox();
|
||||
this.chkExtendZeroPage = new System.Windows.Forms.CheckBox();
|
||||
this.lblTarget = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel6 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.chkLogSa1 = new System.Windows.Forms.CheckBox();
|
||||
this.chkLogCpu = new System.Windows.Forms.CheckBox();
|
||||
this.chkLogSpc = new System.Windows.Forms.CheckBox();
|
||||
this.lblTarget = new System.Windows.Forms.Label();
|
||||
this.chkLogNecDsp = new System.Windows.Forms.CheckBox();
|
||||
this.btnClearLog = new System.Windows.Forms.Button();
|
||||
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
|
||||
|
@ -91,8 +93,7 @@ namespace Mesen.GUI.Debugger
|
|||
this.mnuAutoRefresh = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuRefresh = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.tableLayoutPanel6 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.chkLogSa1 = new System.Windows.Forms.CheckBox();
|
||||
this.chkLogGsu = new System.Windows.Forms.CheckBox();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.grpLogOptions.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
|
@ -101,11 +102,11 @@ namespace Mesen.GUI.Debugger
|
|||
this.tableLayoutPanel4.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picHelp)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picExpressionWarning)).BeginInit();
|
||||
this.tableLayoutPanel6.SuspendLayout();
|
||||
this.tableLayoutPanel3.SuspendLayout();
|
||||
this.grpExecutionLog.SuspendLayout();
|
||||
this.ctxMenu.SuspendLayout();
|
||||
this.menuStrip1.SuspendLayout();
|
||||
this.tableLayoutPanel6.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
|
@ -541,6 +542,51 @@ namespace Mesen.GUI.Debugger
|
|||
this.chkExtendZeroPage.Visible = false;
|
||||
this.chkExtendZeroPage.CheckedChanged += new System.EventHandler(this.chkOptions_CheckedChanged);
|
||||
//
|
||||
// lblTarget
|
||||
//
|
||||
this.lblTarget.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblTarget.AutoSize = true;
|
||||
this.lblTarget.Location = new System.Drawing.Point(3, 4);
|
||||
this.lblTarget.Name = "lblTarget";
|
||||
this.lblTarget.Size = new System.Drawing.Size(46, 13);
|
||||
this.lblTarget.TabIndex = 23;
|
||||
this.lblTarget.Text = "Targets:";
|
||||
//
|
||||
// tableLayoutPanel6
|
||||
//
|
||||
this.tableLayoutPanel6.ColumnCount = 5;
|
||||
this.tableLayoutPanel2.SetColumnSpan(this.tableLayoutPanel6, 5);
|
||||
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel6.Controls.Add(this.chkLogSa1, 3, 0);
|
||||
this.tableLayoutPanel6.Controls.Add(this.chkLogCpu, 0, 0);
|
||||
this.tableLayoutPanel6.Controls.Add(this.chkLogSpc, 1, 0);
|
||||
this.tableLayoutPanel6.Controls.Add(this.chkLogNecDsp, 2, 0);
|
||||
this.tableLayoutPanel6.Controls.Add(this.chkLogGsu, 4, 0);
|
||||
this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel6.Location = new System.Drawing.Point(81, 0);
|
||||
this.tableLayoutPanel6.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel6.Name = "tableLayoutPanel6";
|
||||
this.tableLayoutPanel6.RowCount = 1;
|
||||
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel6.Size = new System.Drawing.Size(589, 22);
|
||||
this.tableLayoutPanel6.TabIndex = 25;
|
||||
//
|
||||
// chkLogSa1
|
||||
//
|
||||
this.chkLogSa1.AutoSize = true;
|
||||
this.chkLogSa1.Checked = true;
|
||||
this.chkLogSa1.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkLogSa1.Location = new System.Drawing.Point(212, 3);
|
||||
this.chkLogSa1.Name = "chkLogSa1";
|
||||
this.chkLogSa1.Size = new System.Drawing.Size(49, 16);
|
||||
this.chkLogSa1.TabIndex = 25;
|
||||
this.chkLogSa1.Text = "SA-1";
|
||||
this.chkLogSa1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkLogCpu
|
||||
//
|
||||
this.chkLogCpu.AutoSize = true;
|
||||
|
@ -567,16 +613,6 @@ namespace Mesen.GUI.Debugger
|
|||
this.chkLogSpc.UseVisualStyleBackColor = true;
|
||||
this.chkLogSpc.CheckedChanged += new System.EventHandler(this.chkOptions_CheckedChanged);
|
||||
//
|
||||
// lblTarget
|
||||
//
|
||||
this.lblTarget.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblTarget.AutoSize = true;
|
||||
this.lblTarget.Location = new System.Drawing.Point(3, 4);
|
||||
this.lblTarget.Name = "lblTarget";
|
||||
this.lblTarget.Size = new System.Drawing.Size(46, 13);
|
||||
this.lblTarget.TabIndex = 23;
|
||||
this.lblTarget.Text = "Targets:";
|
||||
//
|
||||
// chkLogNecDsp
|
||||
//
|
||||
this.chkLogNecDsp.AutoSize = true;
|
||||
|
@ -824,39 +860,17 @@ namespace Mesen.GUI.Debugger
|
|||
this.mnuRefresh.Text = "Refresh";
|
||||
this.mnuRefresh.Click += new System.EventHandler(this.mnuRefresh_Click);
|
||||
//
|
||||
// tableLayoutPanel6
|
||||
// chkLogGsu
|
||||
//
|
||||
this.tableLayoutPanel6.ColumnCount = 5;
|
||||
this.tableLayoutPanel2.SetColumnSpan(this.tableLayoutPanel6, 5);
|
||||
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel6.Controls.Add(this.chkLogSa1, 3, 0);
|
||||
this.tableLayoutPanel6.Controls.Add(this.chkLogCpu, 0, 0);
|
||||
this.tableLayoutPanel6.Controls.Add(this.chkLogSpc, 1, 0);
|
||||
this.tableLayoutPanel6.Controls.Add(this.chkLogNecDsp, 2, 0);
|
||||
this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel6.Location = new System.Drawing.Point(81, 0);
|
||||
this.tableLayoutPanel6.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);
|
||||
this.tableLayoutPanel6.Name = "tableLayoutPanel6";
|
||||
this.tableLayoutPanel6.RowCount = 1;
|
||||
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel6.Size = new System.Drawing.Size(589, 22);
|
||||
this.tableLayoutPanel6.TabIndex = 25;
|
||||
//
|
||||
// chkLogSa1
|
||||
//
|
||||
this.chkLogSa1.AutoSize = true;
|
||||
this.chkLogSa1.Checked = true;
|
||||
this.chkLogSa1.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkLogSa1.Location = new System.Drawing.Point(212, 3);
|
||||
this.chkLogSa1.Name = "chkLogSa1";
|
||||
this.chkLogSa1.Size = new System.Drawing.Size(49, 16);
|
||||
this.chkLogSa1.TabIndex = 25;
|
||||
this.chkLogSa1.Text = "SA-1";
|
||||
this.chkLogSa1.UseVisualStyleBackColor = true;
|
||||
this.chkLogGsu.AutoSize = true;
|
||||
this.chkLogGsu.Checked = true;
|
||||
this.chkLogGsu.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkLogGsu.Location = new System.Drawing.Point(267, 3);
|
||||
this.chkLogGsu.Name = "chkLogGsu";
|
||||
this.chkLogGsu.Size = new System.Drawing.Size(49, 16);
|
||||
this.chkLogGsu.TabIndex = 26;
|
||||
this.chkLogGsu.Text = "GSU";
|
||||
this.chkLogGsu.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// frmTraceLogger
|
||||
//
|
||||
|
@ -882,13 +896,13 @@ namespace Mesen.GUI.Debugger
|
|||
this.tableLayoutPanel4.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picHelp)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picExpressionWarning)).EndInit();
|
||||
this.tableLayoutPanel6.ResumeLayout(false);
|
||||
this.tableLayoutPanel6.PerformLayout();
|
||||
this.tableLayoutPanel3.ResumeLayout(false);
|
||||
this.grpExecutionLog.ResumeLayout(false);
|
||||
this.ctxMenu.ResumeLayout(false);
|
||||
this.menuStrip1.ResumeLayout(false);
|
||||
this.menuStrip1.PerformLayout();
|
||||
this.tableLayoutPanel6.ResumeLayout(false);
|
||||
this.tableLayoutPanel6.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
|
@ -959,5 +973,6 @@ namespace Mesen.GUI.Debugger
|
|||
private System.Windows.Forms.CheckBox chkLogNecDsp;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel6;
|
||||
private System.Windows.Forms.CheckBox chkLogSa1;
|
||||
private System.Windows.Forms.CheckBox chkLogGsu;
|
||||
}
|
||||
}
|
|
@ -49,6 +49,7 @@ namespace Mesen.GUI.Debugger
|
|||
_entityBinder.AddBinding(nameof(TraceLoggerOptions.LogSpc), chkLogSpc);
|
||||
_entityBinder.AddBinding(nameof(TraceLoggerOptions.LogNecDsp), chkLogNecDsp);
|
||||
_entityBinder.AddBinding(nameof(TraceLoggerOptions.LogSa1), chkLogSa1);
|
||||
_entityBinder.AddBinding(nameof(TraceLoggerOptions.LogGsu), chkLogGsu);
|
||||
|
||||
_entityBinder.AddBinding(nameof(TraceLoggerOptions.ShowByteCode), chkShowByteCode);
|
||||
//_entityBinder.AddBinding(nameof(TraceLoggerOptions.ShowCpuCycles), chkShowCpuCycles);
|
||||
|
@ -221,6 +222,7 @@ namespace Mesen.GUI.Debugger
|
|||
interopOptions.LogSpc = !disableLogging && options.LogSpc;
|
||||
interopOptions.LogNecDsp = !disableLogging && options.LogNecDsp;
|
||||
interopOptions.LogSa1 = !disableLogging && options.LogSa1;
|
||||
interopOptions.LogGsu = !disableLogging && options.LogGsu;
|
||||
interopOptions.IndentCode = options.IndentCode;
|
||||
interopOptions.ShowExtraInfo = options.ShowExtraInfo;
|
||||
interopOptions.UseLabels = options.UseLabels;
|
||||
|
|
|
@ -948,6 +948,7 @@
|
|||
<Value ID="CpuMemory">CPU Memory</Value>
|
||||
<Value ID="SpcMemory">SPC Memory</Value>
|
||||
<Value ID="Sa1Memory">SA-1 Memory</Value>
|
||||
<Value ID="GsuMemory">GSU Memory</Value>
|
||||
<Value ID="PrgRom">PRG ROM</Value>
|
||||
<Value ID="WorkRam">Work RAM</Value>
|
||||
<Value ID="SaveRam">Save RAM</Value>
|
||||
|
@ -956,10 +957,11 @@
|
|||
<Value ID="CGRam">CG RAM (Palette)</Value>
|
||||
<Value ID="SpcRam">SPC RAM</Value>
|
||||
<Value ID="SpcRom">SPC ROM (IPL)</Value>
|
||||
<Value ID="DspProgramRom">DSP-n - Program ROM</Value>
|
||||
<Value ID="DspDataRom">DSP-n - Data ROM</Value>
|
||||
<Value ID="DspDataRam">DSP-n - Data RAM</Value>
|
||||
<Value ID="DspProgramRom">DSP-n Program ROM</Value>
|
||||
<Value ID="DspDataRom">DSP-n Data ROM</Value>
|
||||
<Value ID="DspDataRam">DSP-n Data RAM</Value>
|
||||
<Value ID="Sa1InternalRam">SA-1 IRAM</Value>
|
||||
<Value ID="GsuWorkRam">GSU Work RAM</Value>
|
||||
<Value ID="Register">Register</Value>
|
||||
</Enum>
|
||||
<Enum ID="TileFormat">
|
||||
|
|
76
UI/Forms/Config/frmEmulationConfig.Designer.cs
generated
76
UI/Forms/Config/frmEmulationConfig.Designer.cs
generated
|
@ -59,6 +59,9 @@
|
|||
this.nudExtraScanlinesBeforeNmi = new Mesen.GUI.Controls.MesenNumericUpDown();
|
||||
this.lblExtraScanlinesBeforeNmi = new System.Windows.Forms.Label();
|
||||
this.lblExtraScanlinesAfterNmi = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.nudGsuClockSpeed = new Mesen.GUI.Controls.MesenNumericUpDown();
|
||||
this.lblGsuClockSpeed = new System.Windows.Forms.Label();
|
||||
this.tabMain.SuspendLayout();
|
||||
this.tpgGeneral.SuspendLayout();
|
||||
this.tableLayoutPanel4.SuspendLayout();
|
||||
|
@ -72,6 +75,7 @@
|
|||
this.tableLayoutPanel3.SuspendLayout();
|
||||
this.grpPpuTiming.SuspendLayout();
|
||||
this.tableLayoutPanel5.SuspendLayout();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// baseConfigPanel
|
||||
|
@ -405,18 +409,15 @@
|
|||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel3.Controls.Add(this.lblOverclockHint, 0, 0);
|
||||
this.tableLayoutPanel3.Controls.Add(this.grpPpuTiming, 0, 1);
|
||||
this.tableLayoutPanel3.Controls.Add(this.tableLayoutPanel1, 0, 2);
|
||||
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
|
||||
this.tableLayoutPanel3.RowCount = 3;
|
||||
this.tableLayoutPanel3.RowCount = 4;
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel3.Size = new System.Drawing.Size(406, 264);
|
||||
this.tableLayoutPanel3.TabIndex = 1;
|
||||
//
|
||||
|
@ -542,6 +543,64 @@
|
|||
this.lblExtraScanlinesAfterNmi.TabIndex = 1;
|
||||
this.lblExtraScanlinesAfterNmi.Text = "Additional scanlines after NMI:";
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.nudGsuClockSpeed, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblGsuClockSpeed, 0, 0);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 131);
|
||||
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 1;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(406, 25);
|
||||
this.tableLayoutPanel1.TabIndex = 8;
|
||||
//
|
||||
// nudGsuClockSpeed
|
||||
//
|
||||
this.nudGsuClockSpeed.DecimalPlaces = 0;
|
||||
this.nudGsuClockSpeed.Increment = new decimal(new int[] {
|
||||
100,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudGsuClockSpeed.Location = new System.Drawing.Point(138, 3);
|
||||
this.nudGsuClockSpeed.Margin = new System.Windows.Forms.Padding(0, 3, 0, 3);
|
||||
this.nudGsuClockSpeed.Maximum = new decimal(new int[] {
|
||||
1000,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudGsuClockSpeed.MaximumSize = new System.Drawing.Size(10000, 20);
|
||||
this.nudGsuClockSpeed.Minimum = new decimal(new int[] {
|
||||
100,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudGsuClockSpeed.MinimumSize = new System.Drawing.Size(0, 21);
|
||||
this.nudGsuClockSpeed.Name = "nudGsuClockSpeed";
|
||||
this.nudGsuClockSpeed.Size = new System.Drawing.Size(46, 21);
|
||||
this.nudGsuClockSpeed.TabIndex = 4;
|
||||
this.nudGsuClockSpeed.Value = new decimal(new int[] {
|
||||
100,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudGsuClockSpeed.Leave += new System.EventHandler(this.nudGsuClockSpeed_Leave);
|
||||
//
|
||||
// lblGsuClockSpeed
|
||||
//
|
||||
this.lblGsuClockSpeed.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblGsuClockSpeed.AutoSize = true;
|
||||
this.lblGsuClockSpeed.Location = new System.Drawing.Point(3, 6);
|
||||
this.lblGsuClockSpeed.Name = "lblGsuClockSpeed";
|
||||
this.lblGsuClockSpeed.Size = new System.Drawing.Size(132, 13);
|
||||
this.lblGsuClockSpeed.TabIndex = 0;
|
||||
this.lblGsuClockSpeed.Text = "Super FX clock speed (%):";
|
||||
//
|
||||
// frmEmulationConfig
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
@ -577,6 +636,8 @@
|
|||
this.grpPpuTiming.ResumeLayout(false);
|
||||
this.tableLayoutPanel5.ResumeLayout(false);
|
||||
this.tableLayoutPanel5.PerformLayout();
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
|
@ -615,5 +676,8 @@
|
|||
private System.Windows.Forms.Label lblExtraScanlinesBeforeNmi;
|
||||
private System.Windows.Forms.Label lblExtraScanlinesAfterNmi;
|
||||
private System.Windows.Forms.PictureBox picHint;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private Controls.MesenNumericUpDown nudGsuClockSpeed;
|
||||
private System.Windows.Forms.Label lblGsuClockSpeed;
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ namespace Mesen.GUI.Forms.Config
|
|||
|
||||
AddBinding(nameof(EmulationConfig.PpuExtraScanlinesBeforeNmi), nudExtraScanlinesBeforeNmi);
|
||||
AddBinding(nameof(EmulationConfig.PpuExtraScanlinesAfterNmi), nudExtraScanlinesAfterNmi);
|
||||
AddBinding(nameof(EmulationConfig.GsuClockSpeed), nudGsuClockSpeed);
|
||||
}
|
||||
|
||||
protected override void OnApply()
|
||||
|
@ -38,5 +39,10 @@ namespace Mesen.GUI.Forms.Config
|
|||
ConfigManager.Config.Emulation = (EmulationConfig)this.Entity;
|
||||
ConfigManager.ApplyChanges();
|
||||
}
|
||||
|
||||
private void nudGsuClockSpeed_Leave(object sender, EventArgs e)
|
||||
{
|
||||
nudGsuClockSpeed.Value = Math.Ceiling(nudGsuClockSpeed.Value / 100) * 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
52
UI/Forms/frmMain.Designer.cs
generated
52
UI/Forms/frmMain.Designer.cs
generated
|
@ -123,8 +123,7 @@
|
|||
this.mnuTakeScreenshot = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuDebug = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuDebugger = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuSpcDebugger = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuSa1Debugger = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuEventViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuMemoryTools = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuTraceLogger = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuScriptWindow = new System.Windows.Forms.ToolStripMenuItem();
|
||||
|
@ -134,7 +133,9 @@
|
|||
this.mnuSpriteViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuPaletteViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem22 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuEventViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuSpcDebugger = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuSa1Debugger = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuGsuDebugger = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuHelp = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuCheckForUpdates = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem20 = new System.Windows.Forms.ToolStripSeparator();
|
||||
|
@ -868,7 +869,8 @@
|
|||
this.mnuPaletteViewer,
|
||||
this.toolStripMenuItem22,
|
||||
this.mnuSpcDebugger,
|
||||
this.mnuSa1Debugger});
|
||||
this.mnuSa1Debugger,
|
||||
this.mnuGsuDebugger});
|
||||
this.mnuDebug.Name = "mnuDebug";
|
||||
this.mnuDebug.Size = new System.Drawing.Size(54, 20);
|
||||
this.mnuDebug.Text = "Debug";
|
||||
|
@ -882,19 +884,12 @@
|
|||
this.mnuDebugger.Size = new System.Drawing.Size(155, 22);
|
||||
this.mnuDebugger.Text = "Debugger";
|
||||
//
|
||||
// mnuSpcDebugger
|
||||
// mnuEventViewer
|
||||
//
|
||||
this.mnuSpcDebugger.Image = global::Mesen.GUI.Properties.Resources.SpcDebugger;
|
||||
this.mnuSpcDebugger.Name = "mnuSpcDebugger";
|
||||
this.mnuSpcDebugger.Size = new System.Drawing.Size(155, 22);
|
||||
this.mnuSpcDebugger.Text = "SPC Debugger";
|
||||
//
|
||||
// mnuSa1Debugger
|
||||
//
|
||||
this.mnuSa1Debugger.Image = global::Mesen.GUI.Properties.Resources.Sa1Debugger;
|
||||
this.mnuSa1Debugger.Name = "mnuSa1Debugger";
|
||||
this.mnuSa1Debugger.Size = new System.Drawing.Size(155, 22);
|
||||
this.mnuSa1Debugger.Text = "SA-1 Debugger";
|
||||
this.mnuEventViewer.Image = global::Mesen.GUI.Properties.Resources.NesEventViewer;
|
||||
this.mnuEventViewer.Name = "mnuEventViewer";
|
||||
this.mnuEventViewer.Size = new System.Drawing.Size(155, 22);
|
||||
this.mnuEventViewer.Text = "Event Viewer";
|
||||
//
|
||||
// mnuMemoryTools
|
||||
//
|
||||
|
@ -955,12 +950,26 @@
|
|||
this.toolStripMenuItem22.Name = "toolStripMenuItem22";
|
||||
this.toolStripMenuItem22.Size = new System.Drawing.Size(152, 6);
|
||||
//
|
||||
// mnuEventViewer
|
||||
// mnuSpcDebugger
|
||||
//
|
||||
this.mnuEventViewer.Image = global::Mesen.GUI.Properties.Resources.NesEventViewer;
|
||||
this.mnuEventViewer.Name = "mnuEventViewer";
|
||||
this.mnuEventViewer.Size = new System.Drawing.Size(155, 22);
|
||||
this.mnuEventViewer.Text = "Event Viewer";
|
||||
this.mnuSpcDebugger.Image = global::Mesen.GUI.Properties.Resources.SpcDebugger;
|
||||
this.mnuSpcDebugger.Name = "mnuSpcDebugger";
|
||||
this.mnuSpcDebugger.Size = new System.Drawing.Size(155, 22);
|
||||
this.mnuSpcDebugger.Text = "SPC Debugger";
|
||||
//
|
||||
// mnuSa1Debugger
|
||||
//
|
||||
this.mnuSa1Debugger.Image = global::Mesen.GUI.Properties.Resources.Sa1Debugger;
|
||||
this.mnuSa1Debugger.Name = "mnuSa1Debugger";
|
||||
this.mnuSa1Debugger.Size = new System.Drawing.Size(155, 22);
|
||||
this.mnuSa1Debugger.Text = "SA-1 Debugger";
|
||||
//
|
||||
// mnuGsuDebugger
|
||||
//
|
||||
this.mnuGsuDebugger.Image = global::Mesen.GUI.Properties.Resources.GsuDebugger;
|
||||
this.mnuGsuDebugger.Name = "mnuGsuDebugger";
|
||||
this.mnuGsuDebugger.Size = new System.Drawing.Size(155, 22);
|
||||
this.mnuGsuDebugger.Text = "GSU Debugger";
|
||||
//
|
||||
// mnuHelp
|
||||
//
|
||||
|
@ -1171,5 +1180,6 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem mnuSpriteViewer;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuScriptWindow;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuSa1Debugger;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuGsuDebugger;
|
||||
}
|
||||
}
|
|
@ -247,6 +247,7 @@ namespace Mesen.GUI.Forms
|
|||
mnuDebugger.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenDebugger));
|
||||
mnuSpcDebugger.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenSpcDebugger));
|
||||
mnuSa1Debugger.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenSa1Debugger));
|
||||
mnuGsuDebugger.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenGsuDebugger));
|
||||
mnuMemoryTools.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenMemoryTools));
|
||||
mnuEventViewer.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenEventViewer));
|
||||
mnuTilemapViewer.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenTilemapViewer));
|
||||
|
@ -293,6 +294,7 @@ namespace Mesen.GUI.Forms
|
|||
mnuDebugger.Click += (s, e) => { DebugWindowManager.OpenDebugWindow(DebugWindow.Debugger); };
|
||||
mnuSpcDebugger.Click += (s, e) => { DebugWindowManager.OpenDebugWindow(DebugWindow.SpcDebugger); };
|
||||
mnuSa1Debugger.Click += (s, e) => { DebugWindowManager.OpenDebugWindow(DebugWindow.Sa1Debugger); };
|
||||
mnuGsuDebugger.Click += (s, e) => { DebugWindowManager.OpenDebugWindow(DebugWindow.GsuDebugger); };
|
||||
mnuTraceLogger.Click += (s, e) => { DebugWindowManager.OpenDebugWindow(DebugWindow.TraceLogger); };
|
||||
mnuMemoryTools.Click += (s, e) => { DebugWindowManager.OpenDebugWindow(DebugWindow.MemoryTools); };
|
||||
mnuTilemapViewer.Click += (s, e) => { DebugWindowManager.OpenDebugWindow(DebugWindow.TilemapViewer); };
|
||||
|
@ -313,6 +315,11 @@ namespace Mesen.GUI.Forms
|
|||
|
||||
CoprocessorType coprocessor = EmuApi.GetRomInfo().CoprocessorType;
|
||||
mnuSa1Debugger.Enabled = coprocessor == CoprocessorType.SA1;
|
||||
mnuSa1Debugger.Visible = coprocessor == CoprocessorType.SA1;
|
||||
|
||||
mnuGsuDebugger.Enabled = coprocessor == CoprocessorType.GSU;
|
||||
mnuGsuDebugger.Visible = coprocessor == CoprocessorType.GSU;
|
||||
|
||||
|
||||
mnuTraceLogger.Enabled = running;
|
||||
mnuScriptWindow.Enabled = running;
|
||||
|
|
|
@ -57,6 +57,7 @@ namespace Mesen.GUI
|
|||
ShowUnidentifiedData = 0x400,
|
||||
DisassembleUnidentifiedData = 0x800,
|
||||
|
||||
GsuDebuggerEnabled = 0x10000000,
|
||||
Sa1DebuggerEnabled = 0x20000000,
|
||||
SpcDebuggerEnabled = 0x40000000,
|
||||
CpuDebuggerEnabled = 0x80000000
|
||||
|
|
|
@ -162,6 +162,7 @@ namespace Mesen.GUI
|
|||
CpuMemory,
|
||||
SpcMemory,
|
||||
Sa1Memory,
|
||||
GsuMemory,
|
||||
PrgRom,
|
||||
WorkRam,
|
||||
SaveRam,
|
||||
|
@ -174,6 +175,7 @@ namespace Mesen.GUI
|
|||
DspDataRom,
|
||||
DspDataRam,
|
||||
Sa1InternalRam,
|
||||
GsuWorkRam,
|
||||
Register,
|
||||
}
|
||||
|
||||
|
@ -422,6 +424,85 @@ namespace Mesen.GUI
|
|||
public byte SP;
|
||||
}
|
||||
|
||||
public struct GsuFlags
|
||||
{
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Zero;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Carry;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Sign;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Overflow;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Running;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool RomReadPending;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Alt1;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Alt2;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ImmLow;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ImmHigh;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Prefix;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Irq;
|
||||
};
|
||||
|
||||
public struct GsuPixelCache
|
||||
{
|
||||
public byte X;
|
||||
public byte Y;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public byte[] Pixels;
|
||||
public byte ValidBits;
|
||||
};
|
||||
|
||||
public struct GsuState
|
||||
{
|
||||
public UInt64 CycleCount;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public UInt16[] R;
|
||||
|
||||
public GsuFlags SFR;
|
||||
|
||||
public byte RegisterLatch;
|
||||
|
||||
public byte ProgramBank;
|
||||
public byte RomBank;
|
||||
public byte RamBank;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool IrqDisabled;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool HighSpeedMode;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ClockSelect;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool BackupRamEnabled;
|
||||
public byte ScreenBase;
|
||||
|
||||
public byte ColorGradient;
|
||||
public byte PlotBpp;
|
||||
public byte ScreenHeight;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool GsuRamAccess;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool GsuRomAccess;
|
||||
|
||||
public UInt16 CacheBase;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool PlotTransparent;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool PlotDither;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ColorHighNibble;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ColorFreezeHigh;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ObjMode;
|
||||
|
||||
public byte ColorReg;
|
||||
public byte SrcReg;
|
||||
public byte DestReg;
|
||||
|
||||
public byte RomReadBuffer;
|
||||
public byte RomDelay;
|
||||
|
||||
public byte ProgramReadBuffer;
|
||||
|
||||
public UInt16 RamWriteAddress;
|
||||
public byte RamWriteValue;
|
||||
public byte RamDelay;
|
||||
|
||||
public UInt16 RamAddress;
|
||||
|
||||
public GsuPixelCache PrimaryCache;
|
||||
public GsuPixelCache SecondaryCache;
|
||||
};
|
||||
|
||||
public struct DebugState
|
||||
{
|
||||
public UInt64 MasterClock;
|
||||
|
@ -430,6 +511,7 @@ namespace Mesen.GUI
|
|||
public SpcState Spc;
|
||||
public NecDspState NecDsp;
|
||||
public CpuState Sa1;
|
||||
public GsuState Gsu;
|
||||
}
|
||||
|
||||
public enum MemoryOperationType
|
||||
|
@ -570,6 +652,7 @@ namespace Mesen.GUI
|
|||
[MarshalAs(UnmanagedType.I1)] public bool LogSpc;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool LogNecDsp;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool LogSa1;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool LogGsu;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowExtraInfo;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool IndentCode;
|
||||
|
@ -614,6 +697,7 @@ namespace Mesen.GUI
|
|||
Spc,
|
||||
NecDsp,
|
||||
Sa1,
|
||||
Gsu
|
||||
}
|
||||
|
||||
public static class CpuTypeExtensions
|
||||
|
@ -624,6 +708,7 @@ namespace Mesen.GUI
|
|||
case CpuType.Cpu: return SnesMemoryType.CpuMemory;
|
||||
case CpuType.Spc: return SnesMemoryType.SpcMemory;
|
||||
case CpuType.Sa1: return SnesMemoryType.Sa1Memory;
|
||||
case CpuType.Gsu: return SnesMemoryType.GsuMemory;
|
||||
|
||||
default:
|
||||
throw new Exception("Invalid CPU type");
|
||||
|
@ -636,6 +721,7 @@ namespace Mesen.GUI
|
|||
case CpuType.Cpu: return 6;
|
||||
case CpuType.Spc: return 4;
|
||||
case CpuType.Sa1: return 6;
|
||||
case CpuType.Gsu: return 6;
|
||||
|
||||
default:
|
||||
throw new Exception("Invalid CPU type");
|
||||
|
|
|
@ -166,9 +166,7 @@ namespace Mesen.GUI
|
|||
DSP2,
|
||||
DSP3,
|
||||
DSP4,
|
||||
GSU1,
|
||||
GSU2,
|
||||
MarioChip,
|
||||
GSU,
|
||||
OBC1,
|
||||
SA1,
|
||||
DD1,
|
||||
|
|
10
UI/Properties/Resources.Designer.cs
generated
10
UI/Properties/Resources.Designer.cs
generated
|
@ -460,6 +460,16 @@ namespace Mesen.GUI.Properties {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap GsuDebugger {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("GsuDebugger", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
|
|
@ -457,4 +457,7 @@
|
|||
<data name="Sa1Debugger" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Sa1Debugger.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="GsuDebugger" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\GsuDebugger.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
BIN
UI/Resources/GsuDebugger.png
Normal file
BIN
UI/Resources/GsuDebugger.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 689 B |
12
UI/UI.csproj
12
UI/UI.csproj
|
@ -248,6 +248,8 @@
|
|||
<Compile Include="Debugger\Code\Sa1LineStyleProvider.cs" />
|
||||
<Compile Include="Debugger\Code\DbgCodeDataProvider.cs" />
|
||||
<Compile Include="Debugger\Code\Sa1DisassemblyManager.cs" />
|
||||
<Compile Include="Debugger\Code\GsuDisassemblyManager.cs" />
|
||||
<Compile Include="Debugger\Code\GsuLineStyleProvider.cs" />
|
||||
<Compile Include="Debugger\Code\SpcLineStyleProvider.cs" />
|
||||
<Compile Include="Debugger\Code\CodeDataProvider.cs" />
|
||||
<Compile Include="Debugger\Code\SpcDisassemblyManager.cs" />
|
||||
|
@ -269,6 +271,12 @@
|
|||
<Compile Include="Debugger\Controls\ctrlPpuStatus.Designer.cs">
|
||||
<DependentUpon>ctrlPpuStatus.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlGsuStatus.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlGsuStatus.Designer.cs">
|
||||
<DependentUpon>ctrlGsuStatus.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlSpcStatus.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
|
@ -822,6 +830,7 @@
|
|||
<Compile Include="Utilities\Md5Helper.cs" />
|
||||
<Compile Include="Updates\UpdateHelper.cs" />
|
||||
<Compile Include="Utilities\XmlColor.cs" />
|
||||
<None Include="Resources\GsuDebugger.png" />
|
||||
<None Include="Resources\Sa1Debugger.png" />
|
||||
<None Include="Dependencies\LuaScripts\DrawMode.lua">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
|
@ -874,6 +883,9 @@
|
|||
<EmbeddedResource Include="Debugger\Controls\ctrlPpuStatus.resx">
|
||||
<DependentUpon>ctrlPpuStatus.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\Controls\ctrlGsuStatus.resx">
|
||||
<DependentUpon>ctrlGsuStatus.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\Controls\ctrlSpcStatus.resx">
|
||||
<DependentUpon>ctrlSpcStatus.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
|
Loading…
Add table
Reference in a new issue