Debugger: Added Register Viewer tool
This commit is contained in:
parent
f2be04343a
commit
af175616cd
38 changed files with 2329 additions and 829 deletions
|
@ -1,11 +1,16 @@
|
|||
#include "stdafx.h"
|
||||
#include "AluMulDiv.h"
|
||||
#include "Cpu.h"
|
||||
#include "InternalRegisterTypes.h"
|
||||
#include "../Utilities/Serializer.h"
|
||||
|
||||
void AluMulDiv::Initialize(Cpu* cpu)
|
||||
{
|
||||
_cpu = cpu;
|
||||
|
||||
_state = {};
|
||||
_state.MultOperand1 = 0xFF;
|
||||
_state.Dividend = 0xFFFF;
|
||||
}
|
||||
|
||||
void AluMulDiv::Run(bool isRead)
|
||||
|
@ -27,22 +32,22 @@ void AluMulDiv::Run(bool isRead)
|
|||
if(_multCounter > 0) {
|
||||
_multCounter--;
|
||||
|
||||
if(_divResult & 0x01) {
|
||||
_multOrRemainderResult += _shift;
|
||||
if(_state.DivResult & 0x01) {
|
||||
_state.MultOrRemainderResult += _shift;
|
||||
}
|
||||
|
||||
_shift <<= 1;
|
||||
_divResult >>= 1;
|
||||
_state.DivResult >>= 1;
|
||||
}
|
||||
|
||||
if(_divCounter > 0) {
|
||||
_divCounter--;
|
||||
_shift >>= 1;
|
||||
_divResult <<= 1;
|
||||
_state.DivResult <<= 1;
|
||||
|
||||
if(_multOrRemainderResult >= _shift) {
|
||||
_multOrRemainderResult -= _shift;
|
||||
_divResult |= 1;
|
||||
if(_state.MultOrRemainderResult >= _shift) {
|
||||
_state.MultOrRemainderResult -= _shift;
|
||||
_state.DivResult |= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,11 +61,11 @@ uint8_t AluMulDiv::Read(uint16_t addr)
|
|||
Run(true);
|
||||
|
||||
switch(addr) {
|
||||
case 0x4214: return (uint8_t)_divResult;
|
||||
case 0x4215: return (uint8_t)(_divResult >> 8);
|
||||
case 0x4214: return (uint8_t)_state.DivResult;
|
||||
case 0x4215: return (uint8_t)(_state.DivResult >> 8);
|
||||
|
||||
case 0x4216: return (uint8_t)_multOrRemainderResult;
|
||||
case 0x4217: return (uint8_t)(_multOrRemainderResult >> 8);
|
||||
case 0x4216: return (uint8_t)_state.MultOrRemainderResult;
|
||||
case 0x4217: return (uint8_t)(_state.MultOrRemainderResult >> 8);
|
||||
}
|
||||
|
||||
throw std::runtime_error("ALU: invalid address");
|
||||
|
@ -71,27 +76,27 @@ void AluMulDiv::Write(uint16_t addr, uint8_t value)
|
|||
Run(false);
|
||||
|
||||
switch(addr) {
|
||||
case 0x4202: _multOperand1 = value; break;
|
||||
case 0x4202: _state.MultOperand1 = value; break;
|
||||
case 0x4203:
|
||||
_multOrRemainderResult = 0;
|
||||
_state.MultOrRemainderResult = 0;
|
||||
if(!_divCounter && !_multCounter) {
|
||||
_multCounter = 8;
|
||||
|
||||
_multOperand2 = value;
|
||||
_divResult = (value << 8) | _multOperand1;
|
||||
_state.MultOperand2 = value;
|
||||
_state.DivResult = (value << 8) | _state.MultOperand1;
|
||||
_shift = value;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x4204: _dividend = (_dividend & 0xFF00) | value; break;
|
||||
case 0x4205: _dividend = (_dividend & 0xFF) | (value << 8); break;
|
||||
case 0x4204: _state.Dividend = (_state.Dividend & 0xFF00) | value; break;
|
||||
case 0x4205: _state.Dividend = (_state.Dividend & 0xFF) | (value << 8); break;
|
||||
|
||||
case 0x4206:
|
||||
_multOrRemainderResult = _dividend;
|
||||
_state.MultOrRemainderResult = _state.Dividend;
|
||||
|
||||
if(!_divCounter && !_multCounter) {
|
||||
_divCounter = 16;
|
||||
_divisor = value;
|
||||
_state.Divisor = value;
|
||||
_shift = (value << 16);
|
||||
}
|
||||
break;
|
||||
|
@ -100,10 +105,15 @@ void AluMulDiv::Write(uint16_t addr, uint8_t value)
|
|||
}
|
||||
}
|
||||
|
||||
AluState AluMulDiv::GetState()
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
|
||||
void AluMulDiv::Serialize(Serializer &s)
|
||||
{
|
||||
s.Stream(
|
||||
_multOperand1, _multOperand2, _multOrRemainderResult, _dividend, _divisor, _divResult,
|
||||
_state.MultOperand1, _state.MultOperand2, _state.MultOrRemainderResult, _state.Dividend, _state.Divisor, _state.DivResult,
|
||||
_divCounter, _multCounter, _shift, _prevCpuCycle
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "InternalRegisterTypes.h"
|
||||
#include "../Utilities/ISerializable.h"
|
||||
|
||||
class Cpu;
|
||||
|
@ -11,13 +12,7 @@ private:
|
|||
|
||||
uint64_t _prevCpuCycle = 0;
|
||||
|
||||
uint8_t _multOperand1 = 0xFF;
|
||||
uint8_t _multOperand2 = 0;
|
||||
uint16_t _multOrRemainderResult = 0;
|
||||
|
||||
uint16_t _dividend = 0xFFFF;
|
||||
uint8_t _divisor = 0;
|
||||
uint16_t _divResult = 0;
|
||||
AluState _state;
|
||||
|
||||
uint32_t _shift = 0;
|
||||
uint8_t _multCounter = 0;
|
||||
|
@ -31,5 +26,7 @@ public:
|
|||
uint8_t Read(uint16_t addr);
|
||||
void Write(uint16_t addr, uint8_t value);
|
||||
|
||||
AluState GetState();
|
||||
|
||||
void Serialize(Serializer &s) override;
|
||||
};
|
|
@ -56,12 +56,14 @@
|
|||
<ClInclude Include="Cx4DisUtils.h" />
|
||||
<ClInclude Include="Cx4Types.h" />
|
||||
<ClInclude Include="DebugUtilities.h" />
|
||||
<ClInclude Include="DmaControllerTypes.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="InternalRegisterTypes.h" />
|
||||
<ClInclude Include="MemoryMappings.h" />
|
||||
<ClInclude Include="BaseRenderer.h" />
|
||||
<ClInclude Include="BaseSoundManager.h" />
|
||||
|
|
|
@ -401,6 +401,12 @@
|
|||
<ClInclude Include="SuperScope.h">
|
||||
<Filter>SNES\Input</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="InternalRegisterTypes.h">
|
||||
<Filter>SNES</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DmaControllerTypes.h">
|
||||
<Filter>SNES</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp" />
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "NecDspTypes.h"
|
||||
#include "GsuTypes.h"
|
||||
#include "Cx4Types.h"
|
||||
#include "InternalRegisterTypes.h"
|
||||
#include "DmaControllerTypes.h"
|
||||
|
||||
struct DebugState
|
||||
{
|
||||
|
@ -17,6 +19,10 @@ struct DebugState
|
|||
CpuState Sa1;
|
||||
GsuState Gsu;
|
||||
Cx4State Cx4;
|
||||
|
||||
DmaChannelConfig DmaChannels[8];
|
||||
InternalRegisterState InternalRegs;
|
||||
AluState Alu;
|
||||
};
|
||||
|
||||
enum class SnesMemoryType
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include "ScriptManager.h"
|
||||
#include "CallstackManager.h"
|
||||
#include "ExpressionEvaluator.h"
|
||||
#include "InternalRegisters.h"
|
||||
#include "AluMulDiv.h"
|
||||
#include "../Utilities/HexUtilities.h"
|
||||
#include "../Utilities/FolderUtilities.h"
|
||||
|
||||
|
@ -46,6 +48,8 @@ Debugger::Debugger(shared_ptr<Console> console)
|
|||
_cart = console->GetCartridge();
|
||||
_settings = console->GetSettings();
|
||||
_memoryManager = console->GetMemoryManager();
|
||||
_dmaController = console->GetDmaController();
|
||||
_internalRegs = console->GetInternalRegisters();
|
||||
|
||||
_labelManager.reset(new LabelManager(this));
|
||||
_watchExpEval[(int)CpuType::Cpu].reset(new ExpressionEvaluator(this, CpuType::Cpu));
|
||||
|
@ -396,6 +400,13 @@ void Debugger::GetState(DebugState &state, bool partialPpuState)
|
|||
state.Cpu = _cpu->GetState();
|
||||
_ppu->GetState(state.Ppu, partialPpuState);
|
||||
state.Spc = _spc->GetState();
|
||||
|
||||
for(int i = 0; i < 8; i++) {
|
||||
state.DmaChannels[i] = _dmaController->GetChannelConfig(i);
|
||||
}
|
||||
state.InternalRegs = _internalRegs->GetState();
|
||||
state.Alu = _internalRegs->GetAluState();
|
||||
|
||||
if(_cart->GetDsp()) {
|
||||
state.Dsp = _cart->GetDsp()->GetState();
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ class Ppu;
|
|||
class Spc;
|
||||
class BaseCartridge;
|
||||
class MemoryManager;
|
||||
class InternalRegisters;
|
||||
class DmaController;
|
||||
class EmuSettings;
|
||||
|
||||
class TraceLogger;
|
||||
|
@ -41,6 +43,8 @@ private:
|
|||
shared_ptr<Spc> _spc;
|
||||
shared_ptr<MemoryManager> _memoryManager;
|
||||
shared_ptr<BaseCartridge> _cart;
|
||||
shared_ptr<InternalRegisters> _internalRegs;
|
||||
shared_ptr<DmaController> _dmaController;
|
||||
|
||||
shared_ptr<EmuSettings> _settings;
|
||||
unique_ptr<SpcDebugger> _spcDebugger;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "stdafx.h"
|
||||
#include "DmaController.h"
|
||||
#include "DmaControllerTypes.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "MessageManager.h"
|
||||
#include "../Utilities/Serializer.h"
|
||||
|
@ -240,7 +241,7 @@ bool DmaController::ProcessHdmaChannels()
|
|||
//1. If DoTransfer is false, skip to step 3.
|
||||
if(ch.DoTransfer) {
|
||||
//2. For the number of bytes (1, 2, or 4) required for this Transfer Mode...
|
||||
_activeChannel = i;
|
||||
_activeChannel = DmaController::HdmaChannelFlag | i;
|
||||
RunHdmaTransfer(ch);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,38 +1,16 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "CpuTypes.h"
|
||||
#include "DmaControllerTypes.h"
|
||||
#include "../Utilities/ISerializable.h"
|
||||
|
||||
class MemoryManager;
|
||||
|
||||
struct DmaChannelConfig
|
||||
{
|
||||
bool DmaActive;
|
||||
|
||||
bool InvertDirection;
|
||||
bool Decrement;
|
||||
bool FixedTransfer;
|
||||
bool HdmaIndirectAddressing;
|
||||
uint8_t TransferMode;
|
||||
|
||||
uint16_t SrcAddress;
|
||||
uint8_t SrcBank;
|
||||
|
||||
uint16_t TransferSize;
|
||||
uint8_t DestAddress;
|
||||
|
||||
uint16_t HdmaTableAddress;
|
||||
uint8_t HdmaBank;
|
||||
uint8_t HdmaLineCounterAndRepeat;
|
||||
bool DoTransfer;
|
||||
bool HdmaFinished;
|
||||
|
||||
bool UnusedFlag;
|
||||
};
|
||||
|
||||
class DmaController final : public ISerializable
|
||||
{
|
||||
private:
|
||||
static constexpr uint8_t HdmaChannelFlag = 0x80;
|
||||
|
||||
bool _needToProcess = false;
|
||||
bool _hdmaPending = false;
|
||||
bool _hdmaInitPending = false;
|
||||
|
|
27
Core/DmaControllerTypes.h
Normal file
27
Core/DmaControllerTypes.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
|
||||
struct DmaChannelConfig
|
||||
{
|
||||
bool DmaActive;
|
||||
|
||||
bool InvertDirection;
|
||||
bool Decrement;
|
||||
bool FixedTransfer;
|
||||
bool HdmaIndirectAddressing;
|
||||
uint8_t TransferMode;
|
||||
|
||||
uint16_t SrcAddress;
|
||||
uint8_t SrcBank;
|
||||
|
||||
uint16_t TransferSize;
|
||||
uint8_t DestAddress;
|
||||
|
||||
uint16_t HdmaTableAddress;
|
||||
uint8_t HdmaBank;
|
||||
uint8_t HdmaLineCounterAndRepeat;
|
||||
bool DoTransfer;
|
||||
bool HdmaFinished;
|
||||
|
||||
bool UnusedFlag;
|
||||
};
|
|
@ -148,7 +148,7 @@ void EventManager::DrawEvent(DebugEventInfo &evt, bool drawBackground, uint32_t
|
|||
for(int i = iMin; i <= iMax; i++) {
|
||||
for(int j = jMin; j <= jMax; j++) {
|
||||
int32_t pos = (y + i) * 340 * 2 + x + j;
|
||||
if(pos < 0 || pos >= 340 * 2 * _scanlineCount * 2) {
|
||||
if(pos < 0 || pos >= 340 * 2 * (int)_scanlineCount * 2) {
|
||||
continue;
|
||||
}
|
||||
buffer[pos] = color;
|
||||
|
@ -190,7 +190,7 @@ void EventManager::GetDisplayBuffer(uint32_t *buffer, EventViewerDisplayOptions
|
|||
auto lock = _lock.AcquireSafe();
|
||||
_sentEvents.clear();
|
||||
|
||||
for(int i = 0; i < 340 * 2 * _scanlineCount * 2; i++) {
|
||||
for(int i = 0; i < 340 * 2 * (int)_scanlineCount * 2; i++) {
|
||||
buffer[i] = 0xFF555555;
|
||||
}
|
||||
|
||||
|
|
29
Core/InternalRegisterTypes.h
Normal file
29
Core/InternalRegisterTypes.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
|
||||
struct AluState
|
||||
{
|
||||
uint8_t MultOperand1;
|
||||
uint8_t MultOperand2;
|
||||
uint16_t MultOrRemainderResult;
|
||||
|
||||
uint16_t Dividend;
|
||||
uint8_t Divisor;
|
||||
uint16_t DivResult;
|
||||
};
|
||||
|
||||
struct InternalRegisterState
|
||||
{
|
||||
bool EnableAutoJoypadRead;
|
||||
bool EnableFastRom;
|
||||
|
||||
bool EnableNmi;
|
||||
bool EnableHorizontalIrq;
|
||||
bool EnableVerticalIrq;
|
||||
uint16_t HorizontalTimer;
|
||||
uint16_t VerticalTimer;
|
||||
|
||||
uint8_t IoPortOutput;
|
||||
|
||||
uint16_t ControllerData[4];
|
||||
};
|
|
@ -6,6 +6,7 @@
|
|||
#include "ControlManager.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "MessageManager.h"
|
||||
#include "InternalRegisterTypes.h"
|
||||
#include "../Utilities/Serializer.h"
|
||||
#include "../Utilities/HexUtilities.h"
|
||||
|
||||
|
@ -22,17 +23,18 @@ void InternalRegisters::Initialize(Console* console)
|
|||
Reset();
|
||||
|
||||
//Power on values
|
||||
_horizontalTimer = 0x1FF;
|
||||
_verticalTimer = 0x1FF;
|
||||
_ioPortOutput = 0xFF;
|
||||
_state = {};
|
||||
_state.HorizontalTimer = 0x1FF;
|
||||
_state.VerticalTimer = 0x1FF;
|
||||
_state.IoPortOutput = 0xFF;
|
||||
}
|
||||
|
||||
void InternalRegisters::Reset()
|
||||
{
|
||||
_enableAutoJoypadRead = false;
|
||||
_enableNmi = false;
|
||||
_enableHorizontalIrq = false;
|
||||
_enableVerticalIrq = false;
|
||||
_state.EnableAutoJoypadRead = false;
|
||||
_state.EnableNmi = false;
|
||||
_state.EnableHorizontalIrq = false;
|
||||
_state.EnableVerticalIrq = false;
|
||||
_nmiFlag = false;
|
||||
_irqLevel = false;
|
||||
_needIrq = false;
|
||||
|
@ -40,7 +42,7 @@ void InternalRegisters::Reset()
|
|||
|
||||
void InternalRegisters::ProcessAutoJoypadRead()
|
||||
{
|
||||
if(!_enableAutoJoypadRead) {
|
||||
if(!_state.EnableAutoJoypadRead) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -50,28 +52,28 @@ void InternalRegisters::ProcessAutoJoypadRead()
|
|||
controlManager->Write(0x4016, 0);
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
_controllerData[i] = 0;
|
||||
_state.ControllerData[i] = 0;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 16; i++) {
|
||||
uint8_t port1 = controlManager->Read(0x4016);
|
||||
uint8_t port2 = controlManager->Read(0x4017);
|
||||
|
||||
_controllerData[0] <<= 1;
|
||||
_controllerData[1] <<= 1;
|
||||
_controllerData[2] <<= 1;
|
||||
_controllerData[3] <<= 1;
|
||||
_state.ControllerData[0] <<= 1;
|
||||
_state.ControllerData[1] <<= 1;
|
||||
_state.ControllerData[2] <<= 1;
|
||||
_state.ControllerData[3] <<= 1;
|
||||
|
||||
_controllerData[0] |= (port1 & 0x01);
|
||||
_controllerData[1] |= (port2 & 0x01);
|
||||
_controllerData[2] |= (port1 & 0x02) >> 1;
|
||||
_controllerData[3] |= (port2 & 0x02) >> 1;
|
||||
_state.ControllerData[0] |= (port1 & 0x01);
|
||||
_state.ControllerData[1] |= (port2 & 0x01);
|
||||
_state.ControllerData[2] |= (port1 & 0x02) >> 1;
|
||||
_state.ControllerData[3] |= (port2 & 0x02) >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t InternalRegisters::GetIoPortOutput()
|
||||
{
|
||||
return _ioPortOutput;
|
||||
return _state.IoPortOutput;
|
||||
}
|
||||
|
||||
void InternalRegisters::SetNmiFlag(bool nmiFlag)
|
||||
|
@ -79,6 +81,15 @@ void InternalRegisters::SetNmiFlag(bool nmiFlag)
|
|||
_nmiFlag = nmiFlag;
|
||||
}
|
||||
|
||||
uint8_t InternalRegisters::Peek(uint16_t addr)
|
||||
{
|
||||
switch(addr) {
|
||||
case 0x4210: return (_nmiFlag ? 0x80 : 0) | 0x02;
|
||||
case 0x4211: return (_console->GetCpu()->CheckIrqSource(IrqSource::Ppu) ? 0x80 : 0);
|
||||
default: return Read(addr);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t InternalRegisters::Read(uint16_t addr)
|
||||
{
|
||||
switch(addr) {
|
||||
|
@ -105,7 +116,7 @@ uint8_t InternalRegisters::Read(uint16_t addr)
|
|||
return (
|
||||
(scanline >= nmiScanline ? 0x80 : 0) |
|
||||
((hClock >= 1*4 && hClock <= 274*4) ? 0 : 0x40) |
|
||||
((_enableAutoJoypadRead && scanline >= nmiScanline && scanline <= nmiScanline + 2) ? 0x01 : 0) | //Auto joypad read in progress
|
||||
((_state.EnableAutoJoypadRead && scanline >= nmiScanline && scanline <= nmiScanline + 2) ? 0x01 : 0) | //Auto joypad read in progress
|
||||
(_memoryManager->GetOpenBus() & 0x3E)
|
||||
);
|
||||
}
|
||||
|
@ -120,14 +131,14 @@ uint8_t InternalRegisters::Read(uint16_t addr)
|
|||
case 0x4217:
|
||||
return _aluMulDiv.Read(addr);
|
||||
|
||||
case 0x4218: return (uint8_t)_controllerData[0];
|
||||
case 0x4219: return (uint8_t)(_controllerData[0] >> 8);
|
||||
case 0x421A: return (uint8_t)_controllerData[1];
|
||||
case 0x421B: return (uint8_t)(_controllerData[1] >> 8);
|
||||
case 0x421C: return (uint8_t)_controllerData[2];
|
||||
case 0x421D: return (uint8_t)(_controllerData[2] >> 8);
|
||||
case 0x421E: return (uint8_t)_controllerData[3];
|
||||
case 0x421F: return (uint8_t)(_controllerData[3] >> 8);
|
||||
case 0x4218: return (uint8_t)_state.ControllerData[0];
|
||||
case 0x4219: return (uint8_t)(_state.ControllerData[0] >> 8);
|
||||
case 0x421A: return (uint8_t)_state.ControllerData[1];
|
||||
case 0x421B: return (uint8_t)(_state.ControllerData[1] >> 8);
|
||||
case 0x421C: return (uint8_t)_state.ControllerData[2];
|
||||
case 0x421D: return (uint8_t)(_state.ControllerData[2] >> 8);
|
||||
case 0x421E: return (uint8_t)_state.ControllerData[3];
|
||||
case 0x421F: return (uint8_t)(_state.ControllerData[3] >> 8);
|
||||
|
||||
default:
|
||||
LogDebug("[Debug] Unimplemented register read: " + HexUtilities::ToHex(addr));
|
||||
|
@ -139,33 +150,33 @@ void InternalRegisters::Write(uint16_t addr, uint8_t value)
|
|||
{
|
||||
switch(addr) {
|
||||
case 0x4200:
|
||||
if((value & 0x30) == 0x20 && !_enableVerticalIrq && _ppu->GetRealScanline() == _verticalTimer) {
|
||||
if((value & 0x30) == 0x20 && !_state.EnableVerticalIrq && _ppu->GetRealScanline() == _state.VerticalTimer) {
|
||||
//When enabling vertical irqs, if the current scanline matches the target scanline, set the irq flag right away
|
||||
_console->GetCpu()->SetIrqSource(IrqSource::Ppu);
|
||||
}
|
||||
|
||||
if((value & 0x80) && !_enableNmi && _nmiFlag) {
|
||||
if((value & 0x80) && !_state.EnableNmi && _nmiFlag) {
|
||||
_console->GetCpu()->SetNmiFlag();
|
||||
}
|
||||
|
||||
_enableNmi = (value & 0x80) != 0;
|
||||
_enableVerticalIrq = (value & 0x20) != 0;
|
||||
_enableHorizontalIrq = (value & 0x10) != 0;
|
||||
_state.EnableNmi = (value & 0x80) != 0;
|
||||
_state.EnableVerticalIrq = (value & 0x20) != 0;
|
||||
_state.EnableHorizontalIrq = (value & 0x10) != 0;
|
||||
|
||||
if(!_enableHorizontalIrq && !_enableVerticalIrq) {
|
||||
if(!_state.EnableHorizontalIrq && !_state.EnableVerticalIrq) {
|
||||
//TODO VERIFY
|
||||
_console->GetCpu()->ClearIrqSource(IrqSource::Ppu);
|
||||
}
|
||||
|
||||
_enableAutoJoypadRead = (value & 0x01) != 0;
|
||||
_state.EnableAutoJoypadRead = (value & 0x01) != 0;
|
||||
break;
|
||||
|
||||
case 0x4201:
|
||||
//TODO WRIO - Programmable I/O port (out-port)
|
||||
if((_ioPortOutput & 0x80) && !(value & 0x80)) {
|
||||
if((_state.IoPortOutput & 0x80) && !(value & 0x80)) {
|
||||
_ppu->LatchLocationValues();
|
||||
}
|
||||
_ioPortOutput = value;
|
||||
_state.IoPortOutput = value;
|
||||
break;
|
||||
|
||||
case 0x4202:
|
||||
|
@ -176,13 +187,13 @@ void InternalRegisters::Write(uint16_t addr, uint8_t value)
|
|||
_aluMulDiv.Write(addr, value);
|
||||
break;
|
||||
|
||||
case 0x4207: _horizontalTimer = (_horizontalTimer & 0x100) | value; break;
|
||||
case 0x4208: _horizontalTimer = (_horizontalTimer & 0xFF) | ((value & 0x01) << 8); break;
|
||||
case 0x4207: _state.HorizontalTimer = (_state.HorizontalTimer & 0x100) | value; break;
|
||||
case 0x4208: _state.HorizontalTimer = (_state.HorizontalTimer & 0xFF) | ((value & 0x01) << 8); break;
|
||||
|
||||
case 0x4209: _verticalTimer = (_verticalTimer & 0x100) | value; break;
|
||||
case 0x420A: _verticalTimer = (_verticalTimer & 0xFF) | ((value & 0x01) << 8); break;
|
||||
case 0x4209: _state.VerticalTimer = (_state.VerticalTimer & 0x100) | value; break;
|
||||
case 0x420A: _state.VerticalTimer = (_state.VerticalTimer & 0xFF) | ((value & 0x01) << 8); break;
|
||||
|
||||
case 0x420D: _enableFastRom = (value & 0x01) != 0; break;
|
||||
case 0x420D: _state.EnableFastRom = (value & 0x01) != 0; break;
|
||||
|
||||
default:
|
||||
LogDebug("[Debug] Unimplemented register write: " + HexUtilities::ToHex(addr) + " = " + HexUtilities::ToHex(value));
|
||||
|
@ -190,12 +201,22 @@ void InternalRegisters::Write(uint16_t addr, uint8_t value)
|
|||
}
|
||||
}
|
||||
|
||||
InternalRegisterState InternalRegisters::GetState()
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
|
||||
AluState InternalRegisters::GetAluState()
|
||||
{
|
||||
return _aluMulDiv.GetState();
|
||||
}
|
||||
|
||||
void InternalRegisters::Serialize(Serializer &s)
|
||||
{
|
||||
s.Stream(
|
||||
_enableFastRom, _nmiFlag, _enableNmi, _enableHorizontalIrq, _enableVerticalIrq, _horizontalTimer,
|
||||
_verticalTimer, _ioPortOutput, _controllerData[0], _controllerData[1], _controllerData[2], _controllerData[3],
|
||||
_irqLevel, _needIrq, _enableAutoJoypadRead
|
||||
_state.EnableFastRom, _nmiFlag, _state.EnableNmi, _state.EnableHorizontalIrq, _state.EnableVerticalIrq, _state.HorizontalTimer,
|
||||
_state.VerticalTimer, _state.IoPortOutput, _state.ControllerData[0], _state.ControllerData[1], _state.ControllerData[2], _state.ControllerData[3],
|
||||
_irqLevel, _needIrq, _state.EnableAutoJoypadRead
|
||||
);
|
||||
|
||||
s.Stream(&_aluMulDiv);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "Console.h"
|
||||
#include "Cpu.h"
|
||||
#include "Ppu.h"
|
||||
#include "InternalRegisterTypes.h"
|
||||
#include "../Utilities/ISerializable.h"
|
||||
|
||||
class MemoryManager;
|
||||
|
@ -17,23 +18,11 @@ private:
|
|||
|
||||
AluMulDiv _aluMulDiv;
|
||||
|
||||
bool _enableAutoJoypadRead = false;
|
||||
bool _enableFastRom = false;
|
||||
|
||||
InternalRegisterState _state;
|
||||
bool _nmiFlag = false;
|
||||
bool _enableNmi = false;
|
||||
|
||||
bool _enableHorizontalIrq = false;
|
||||
bool _enableVerticalIrq = false;
|
||||
uint16_t _horizontalTimer = 0x1FF;
|
||||
uint16_t _verticalTimer = 0x1FF;
|
||||
bool _irqLevel = false;
|
||||
bool _needIrq = false;
|
||||
|
||||
uint8_t _ioPortOutput = 0;
|
||||
|
||||
uint16_t _controllerData[4] = {};
|
||||
|
||||
public:
|
||||
InternalRegisters();
|
||||
void Initialize(Console* console);
|
||||
|
@ -47,16 +36,20 @@ public:
|
|||
uint8_t GetIoPortOutput();
|
||||
void SetNmiFlag(bool nmiFlag);
|
||||
|
||||
bool IsVerticalIrqEnabled() { return _enableVerticalIrq; }
|
||||
bool IsHorizontalIrqEnabled() { return _enableHorizontalIrq; }
|
||||
bool IsNmiEnabled() { return _enableNmi; }
|
||||
bool IsFastRomEnabled() { return _enableFastRom; }
|
||||
uint16_t GetHorizontalTimer() { return _horizontalTimer; }
|
||||
uint16_t GetVerticalTimer() { return _verticalTimer; }
|
||||
bool IsVerticalIrqEnabled() { return _state.EnableVerticalIrq; }
|
||||
bool IsHorizontalIrqEnabled() { return _state.EnableHorizontalIrq; }
|
||||
bool IsNmiEnabled() { return _state.EnableNmi; }
|
||||
bool IsFastRomEnabled() { return _state.EnableFastRom; }
|
||||
uint16_t GetHorizontalTimer() { return _state.HorizontalTimer; }
|
||||
uint16_t GetVerticalTimer() { return _state.VerticalTimer; }
|
||||
|
||||
uint8_t Peek(uint16_t addr);
|
||||
uint8_t Read(uint16_t addr);
|
||||
void Write(uint16_t addr, uint8_t value);
|
||||
|
||||
InternalRegisterState GetState();
|
||||
AluState GetAluState();
|
||||
|
||||
void Serialize(Serializer &s) override;
|
||||
};
|
||||
|
||||
|
@ -68,9 +61,9 @@ void InternalRegisters::ProcessIrqCounters()
|
|||
}
|
||||
|
||||
bool irqLevel = (
|
||||
(_enableHorizontalIrq || _enableVerticalIrq) &&
|
||||
(!_enableHorizontalIrq || (_horizontalTimer <= 339 && (_ppu->GetCycle() == _horizontalTimer) && (_ppu->GetLastScanline() != _ppu->GetRealScanline() || _horizontalTimer < 339))) &&
|
||||
(!_enableVerticalIrq || _ppu->GetRealScanline() == _verticalTimer)
|
||||
(_state.EnableHorizontalIrq || _state.EnableVerticalIrq) &&
|
||||
(!_state.EnableHorizontalIrq || (_state.HorizontalTimer <= 339 && (_ppu->GetCycle() == _state.HorizontalTimer) && (_ppu->GetLastScanline() != _ppu->GetRealScanline() || _state.HorizontalTimer < 339))) &&
|
||||
(!_state.EnableVerticalIrq || _ppu->GetRealScanline() == _state.VerticalTimer)
|
||||
);
|
||||
|
||||
if(!_irqLevel && irqLevel) {
|
||||
|
|
601
Core/Ppu.cpp
601
Core/Ppu.cpp
File diff suppressed because it is too large
Load diff
56
Core/Ppu.h
56
Core/Ppu.h
|
@ -48,9 +48,6 @@ private:
|
|||
uint8_t _spriteTileCount = 0;
|
||||
bool _hasSpritePriority[4] = {};
|
||||
|
||||
bool _forcedVblank = false;
|
||||
uint8_t _screenBrightness = 0;
|
||||
|
||||
uint16_t _scanline = 0;
|
||||
uint32_t _frameCount = 0;
|
||||
|
||||
|
@ -63,37 +60,14 @@ private:
|
|||
|
||||
uint8_t _oddFrame = 0;
|
||||
|
||||
PpuState _state;
|
||||
|
||||
uint16_t _drawStartX = 0;
|
||||
uint16_t _drawEndX = 0;
|
||||
|
||||
uint8_t _bgMode = 0;
|
||||
bool _mode1Bg3Priority = false;
|
||||
|
||||
uint8_t _mainScreenLayers = 0;
|
||||
uint8_t _subScreenLayers = 0;
|
||||
LayerConfig _layerConfig[4] = {};
|
||||
|
||||
WindowConfig _window[2] = {};
|
||||
WindowMaskLogic _maskLogic[6] = {};
|
||||
bool _windowMaskMain[5] = {};
|
||||
bool _windowMaskSub[5] = {};
|
||||
|
||||
Mode7Config _mode7 = {};
|
||||
|
||||
uint16_t *_vram = nullptr;
|
||||
uint16_t _vramAddress = 0;
|
||||
uint8_t _vramIncrementValue = 0;
|
||||
uint8_t _vramAddressRemapping = 0;
|
||||
bool _vramAddrIncrementOnSecondReg = 0;
|
||||
uint16_t _vramReadBuffer = 0;
|
||||
|
||||
uint8_t _ppu1OpenBus = 0;
|
||||
uint8_t _ppu2OpenBus = 0;
|
||||
|
||||
uint8_t _cgramAddress = 0;
|
||||
uint8_t _cgramWriteBuffer = 0;
|
||||
bool _cgramAddressLatch = false;
|
||||
uint16_t _cgram[Ppu::CgRamSize >> 1] = {};
|
||||
uint8_t _oamRam[Ppu::SpriteRamSize] = {};
|
||||
|
||||
uint16_t *_outputBuffers[2] = {};
|
||||
uint16_t *_currentBuffer = nullptr;
|
||||
|
@ -109,17 +83,7 @@ private:
|
|||
uint16_t _subScreenBuffer[256] = {};
|
||||
|
||||
uint32_t _mosaicColor[4] = {};
|
||||
uint8_t _mosaicSize = 0;
|
||||
uint8_t _mosaicEnabled = 0;
|
||||
uint16_t _mosaicScanlineCounter = 0;
|
||||
|
||||
uint8_t _oamMode = 0;
|
||||
uint16_t _oamBaseAddress = 0;
|
||||
uint16_t _oamAddressOffset = 0;
|
||||
|
||||
uint8_t _oamRam[Ppu::SpriteRamSize] = {};
|
||||
uint16_t _oamRamAddress = 0;
|
||||
bool _enableOamPriority = false;
|
||||
|
||||
uint16_t _internalOamAddress = 0;
|
||||
uint8_t _oamWriteBuffer = 0;
|
||||
|
@ -127,20 +91,6 @@ private:
|
|||
bool _timeOver = false;
|
||||
bool _rangeOver = false;
|
||||
|
||||
bool _hiResMode = false;
|
||||
bool _screenInterlace = false;
|
||||
bool _objInterlace = false;
|
||||
bool _overscanMode = false;
|
||||
bool _directColorMode = false;
|
||||
|
||||
ColorWindowMode _colorMathClipMode = ColorWindowMode::Never;
|
||||
ColorWindowMode _colorMathPreventMode = ColorWindowMode::Never;
|
||||
bool _colorMathAddSubscreen = false;
|
||||
uint8_t _colorMathEnabled = 0;
|
||||
bool _colorMathSubstractMode = false;
|
||||
bool _colorMathHalveResult = false;
|
||||
uint16_t _fixedColor = 0;
|
||||
|
||||
uint8_t _hvScrollLatchValue = 0;
|
||||
uint8_t _hScrollLatchValue = 0;
|
||||
|
||||
|
|
111
Core/PpuTypes.h
111
Core/PpuTypes.h
|
@ -1,6 +1,22 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
|
||||
enum class WindowMaskLogic
|
||||
{
|
||||
Or = 0,
|
||||
And = 1,
|
||||
Xor = 2,
|
||||
Xnor = 3
|
||||
};
|
||||
|
||||
enum class ColorWindowMode
|
||||
{
|
||||
Never = 0,
|
||||
OutsideWindow = 1,
|
||||
InsideWindow = 2,
|
||||
Always = 3
|
||||
};
|
||||
|
||||
struct SpriteInfo
|
||||
{
|
||||
int16_t X;
|
||||
|
@ -73,35 +89,12 @@ struct Mode7Config
|
|||
bool FillWithTile0;
|
||||
bool HorizontalMirroring;
|
||||
bool VerticalMirroring;
|
||||
bool ExtBgEnabled;
|
||||
|
||||
//Holds the scroll values at the start of a scanline for the entire scanline
|
||||
int16_t HScrollLatch;
|
||||
int16_t VScrollLatch;
|
||||
};
|
||||
|
||||
struct PpuState
|
||||
{
|
||||
uint16_t Cycle;
|
||||
uint16_t Scanline;
|
||||
uint16_t HClock;
|
||||
uint32_t FrameCount;
|
||||
bool OverscanMode;
|
||||
|
||||
uint8_t BgMode;
|
||||
bool DirectColorMode;
|
||||
bool HiResMode;
|
||||
bool ScreenInterlace;
|
||||
Mode7Config Mode7;
|
||||
LayerConfig Layers[4];
|
||||
|
||||
uint8_t OamMode;
|
||||
uint16_t OamBaseAddress;
|
||||
uint16_t OamAddressOffset;
|
||||
bool EnableOamPriority;
|
||||
bool ObjInterlace;
|
||||
};
|
||||
|
||||
struct WindowConfig
|
||||
{
|
||||
bool ActiveLayers[6];
|
||||
|
@ -128,21 +121,69 @@ struct WindowConfig
|
|||
}
|
||||
};
|
||||
|
||||
enum class WindowMaskLogic
|
||||
struct PpuState
|
||||
{
|
||||
Or = 0,
|
||||
And = 1,
|
||||
Xor = 2,
|
||||
Xnor = 3
|
||||
uint16_t Cycle;
|
||||
uint16_t Scanline;
|
||||
uint16_t HClock;
|
||||
uint32_t FrameCount;
|
||||
|
||||
bool ForcedVblank;
|
||||
uint8_t ScreenBrightness;
|
||||
|
||||
Mode7Config Mode7;
|
||||
|
||||
uint8_t BgMode;
|
||||
bool Mode1Bg3Priority;
|
||||
|
||||
uint8_t MainScreenLayers;
|
||||
uint8_t SubScreenLayers;
|
||||
LayerConfig Layers[4];
|
||||
|
||||
WindowConfig Window[2];
|
||||
WindowMaskLogic MaskLogic[6];
|
||||
bool WindowMaskMain[5];
|
||||
bool WindowMaskSub[5];
|
||||
|
||||
uint16_t VramAddress;
|
||||
uint8_t VramIncrementValue;
|
||||
uint8_t VramAddressRemapping;
|
||||
bool VramAddrIncrementOnSecondReg;
|
||||
uint16_t VramReadBuffer;
|
||||
|
||||
uint8_t Ppu1OpenBus;
|
||||
uint8_t Ppu2OpenBus;
|
||||
|
||||
uint8_t CgramAddress;
|
||||
uint8_t CgramWriteBuffer;
|
||||
bool CgramAddressLatch;
|
||||
|
||||
uint8_t MosaicSize = 0;
|
||||
uint8_t MosaicEnabled = 0;
|
||||
|
||||
uint16_t OamRamAddress = 0;
|
||||
|
||||
uint8_t OamMode;
|
||||
uint16_t OamBaseAddress;
|
||||
uint16_t OamAddressOffset;
|
||||
bool EnableOamPriority;
|
||||
|
||||
bool ExtBgEnabled = false;
|
||||
bool HiResMode = false;
|
||||
bool ScreenInterlace = false;
|
||||
bool ObjInterlace = false;
|
||||
bool OverscanMode = false;
|
||||
bool DirectColorMode = false;
|
||||
|
||||
ColorWindowMode ColorMathClipMode = ColorWindowMode::Never;
|
||||
ColorWindowMode ColorMathPreventMode = ColorWindowMode::Never;
|
||||
bool ColorMathAddSubscreen = false;
|
||||
uint8_t ColorMathEnabled = 0;
|
||||
bool ColorMathSubstractMode = false;
|
||||
bool ColorMathHalveResult = false;
|
||||
uint16_t FixedColor = 0;
|
||||
};
|
||||
|
||||
enum class ColorWindowMode
|
||||
{
|
||||
Never = 0,
|
||||
OutsideWindow = 1,
|
||||
InsideWindow = 2,
|
||||
Always = 3
|
||||
};
|
||||
|
||||
enum PixelFlags
|
||||
{
|
||||
|
|
|
@ -35,8 +35,14 @@ public:
|
|||
|
||||
uint8_t Peek(uint32_t addr) override
|
||||
{
|
||||
//Avoid side effects for now
|
||||
return 0;
|
||||
if(addr == 0x4016 || addr == 0x4017) {
|
||||
//Avoid side effects for now
|
||||
return 0;
|
||||
} else if(addr >= 0x4300) {
|
||||
return _dmaController->Read(addr);
|
||||
} else {
|
||||
return _regs->Peek(addr);
|
||||
}
|
||||
}
|
||||
|
||||
void PeekBlock(uint8_t *output) override
|
||||
|
|
12
Core/Spc.cpp
12
Core/Spc.cpp
|
@ -236,12 +236,14 @@ void Spc::Write(uint16_t addr, uint8_t value, MemoryOperationType type)
|
|||
if(!CheckFlag(SpcFlags::DirectPage)) {
|
||||
_state.InternalSpeed = (value >> 6) & 0x03;
|
||||
_state.ExternalSpeed = (value >> 4) & 0x03;
|
||||
_state.TimersEnabled = (value & 0x09) == 0x08;
|
||||
_state.TimersEnabled = (value & 0x08) != 0;
|
||||
_state.TimersDisabled = (value & 0x01) != 0;
|
||||
_state.WriteEnabled = value & 0x02;
|
||||
|
||||
_state.Timer0.SetGlobalEnabled(_state.TimersEnabled);
|
||||
_state.Timer1.SetGlobalEnabled(_state.TimersEnabled);
|
||||
_state.Timer2.SetGlobalEnabled(_state.TimersEnabled);
|
||||
bool timersEnabled = _state.TimersEnabled && !_state.TimersDisabled;
|
||||
_state.Timer0.SetGlobalEnabled(timersEnabled);
|
||||
_state.Timer1.SetGlobalEnabled(timersEnabled);
|
||||
_state.Timer2.SetGlobalEnabled(timersEnabled);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -409,7 +411,7 @@ void Spc::Serialize(Serializer &s)
|
|||
_dsp->set_output(_soundBuffer, Spc::SampleBufferSize >> 1);
|
||||
}
|
||||
|
||||
s.Stream(_operandA, _operandB, _tmp1, _tmp2, _tmp3, _opCode, _opStep, _opSubStep, _enabled);
|
||||
s.Stream(_operandA, _operandB, _tmp1, _tmp2, _tmp3, _opCode, _opStep, _opSubStep, _enabled, _state.TimersDisabled);
|
||||
}
|
||||
|
||||
uint8_t Spc::GetOpCode()
|
||||
|
|
|
@ -18,6 +18,7 @@ struct SpcState
|
|||
uint8_t InternalSpeed;
|
||||
uint8_t ExternalSpeed;
|
||||
bool TimersEnabled;
|
||||
bool TimersDisabled;
|
||||
CpuStopState StopState;
|
||||
|
||||
uint8_t DspReg;
|
||||
|
|
|
@ -89,7 +89,7 @@ extern "C"
|
|||
DllExport void __stdcall GetDebugEvents(DebugEventInfo *infoArray, uint32_t &maxEventCount, bool getPreviousFrameData) { GetDebugger()->GetEventManager()->GetEvents(infoArray, maxEventCount, getPreviousFrameData); }
|
||||
DllExport uint32_t __stdcall GetDebugEventCount(bool getPreviousFrameData) { return GetDebugger()->GetEventManager()->GetEventCount(getPreviousFrameData); }
|
||||
DllExport void __stdcall GetEventViewerOutput(uint32_t *buffer, EventViewerDisplayOptions options) { GetDebugger()->GetEventManager()->GetDisplayBuffer(buffer, options); }
|
||||
DllExport DebugEventInfo __stdcall GetEventViewerEvent(uint16_t scanline, uint16_t cycle, EventViewerDisplayOptions options) { return GetDebugger()->GetEventManager()->GetEvent(scanline, cycle, options); }
|
||||
DllExport void __stdcall GetEventViewerEvent(DebugEventInfo *evtInfo, uint16_t scanline, uint16_t cycle, EventViewerDisplayOptions options) { *evtInfo = GetDebugger()->GetEventManager()->GetEvent(scanline, cycle, options); }
|
||||
DllExport uint32_t __stdcall TakeEventSnapshot(EventViewerDisplayOptions options) { return GetDebugger()->GetEventManager()->TakeEventSnapshot(options); }
|
||||
|
||||
DllExport int32_t __stdcall LoadScript(char* name, char* content, int32_t scriptId) { return GetDebugger()->GetScriptManager()->LoadScript(name, content, scriptId); }
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace Mesen.GUI.Config
|
|||
public DebuggerInfo Debugger = new DebuggerInfo();
|
||||
public TilemapViewerConfig TilemapViewer = new TilemapViewerConfig();
|
||||
public TileViewerConfig TileViewer = new TileViewerConfig();
|
||||
public RegisterViewerConfig RegisterViewer = new RegisterViewerConfig();
|
||||
public SpriteViewerConfig SpriteViewer = new SpriteViewerConfig();
|
||||
public DbgIntegrationConfig DbgIntegration = new DbgIntegrationConfig();
|
||||
public ScriptWindowConfig ScriptWindow = new ScriptWindowConfig();
|
||||
|
|
|
@ -69,8 +69,6 @@ namespace Mesen.GUI.Config
|
|||
|
||||
[ShortcutName("Open APU Viewer")]
|
||||
public XmlKeys OpenApuViewer = Keys.Control | Keys.U;
|
||||
[ShortcutName("Open Assembler")]
|
||||
public XmlKeys OpenAssembler = Keys.Control | Keys.K;
|
||||
[ShortcutName("Open Debugger")]
|
||||
public XmlKeys OpenDebugger = Keys.Control | Keys.D;
|
||||
[ShortcutName("Open SPC Debugger")]
|
||||
|
@ -89,6 +87,8 @@ namespace Mesen.GUI.Config
|
|||
public XmlKeys OpenScriptWindow = Keys.Control | Keys.N;
|
||||
[ShortcutName("Open Trace Logger")]
|
||||
public XmlKeys OpenTraceLogger = Keys.Control | Keys.J;
|
||||
[ShortcutName("Open Register Viewer")]
|
||||
public XmlKeys OpenRegisterViewer = Keys.Control | Keys.K;
|
||||
[ShortcutName("Open Text Hooker")]
|
||||
public XmlKeys OpenTextHooker = Keys.Control | Keys.H;
|
||||
[ShortcutName("Open Watch Window")]
|
||||
|
|
30
UI/Debugger/Config/RegisterViewerConfig.cs
Normal file
30
UI/Debugger/Config/RegisterViewerConfig.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using Mesen.GUI.Debugger;
|
||||
using Mesen.GUI.Controls;
|
||||
using Mesen.GUI.Utilities;
|
||||
|
||||
namespace Mesen.GUI.Config
|
||||
{
|
||||
public class RegisterViewerConfig
|
||||
{
|
||||
public Size WindowSize = new Size(0, 0);
|
||||
public Point WindowLocation;
|
||||
|
||||
public bool AutoRefresh = true;
|
||||
public int RefreshScanline = 240;
|
||||
public int RefreshCycle = 0;
|
||||
|
||||
public RegisterViewerConfig()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,6 +38,7 @@ namespace Mesen.GUI.Debugger
|
|||
case DebugWindow.SpriteViewer: frm = new frmSpriteViewer(); frm.Icon = Properties.Resources.PerfTracker; break;
|
||||
case DebugWindow.EventViewer: frm = new frmEventViewer(); frm.Icon = Properties.Resources.NesEventViewer; break;
|
||||
case DebugWindow.ScriptWindow: frm = new frmScript(); frm.Icon = Properties.Resources.Script; break;
|
||||
case DebugWindow.RegisterViewer: frm = new frmRegisterViewer(); frm.Icon = Properties.Resources.RegisterIcon; break;
|
||||
}
|
||||
|
||||
if(_openedWindows.Count == 0) {
|
||||
|
@ -164,6 +165,7 @@ namespace Mesen.GUI.Debugger
|
|||
PaletteViewer,
|
||||
SpriteViewer,
|
||||
EventViewer,
|
||||
ScriptWindow
|
||||
ScriptWindow,
|
||||
RegisterViewer
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ namespace Mesen.GUI.Debugger
|
|||
{
|
||||
public partial class ctrlEventViewerPpuView : BaseControl
|
||||
{
|
||||
private const int HdmaChannelFlag = 0x80;
|
||||
|
||||
private int _baseWidth = 340 * 2;
|
||||
|
||||
private EntityBinder _entityBinder = new EntityBinder();
|
||||
|
@ -215,7 +217,8 @@ namespace Mesen.GUI.Debugger
|
|||
}
|
||||
|
||||
EventViewerDisplayOptions options = ConfigManager.Config.Debug.EventViewer.GetInteropOptions();
|
||||
DebugEventInfo evt = DebugApi.GetEventViewerEvent((UInt16)pos.Y, (UInt16)pos.X, options);
|
||||
DebugEventInfo evt = new DebugEventInfo();
|
||||
DebugApi.GetEventViewerEvent(ref evt, (UInt16)pos.Y, (UInt16)pos.X, options);
|
||||
if(evt.ProgramCounter == 0xFFFFFFFF) {
|
||||
ResetTooltip();
|
||||
UpdateOverlay(e.Location);
|
||||
|
@ -245,12 +248,14 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
if(isDma) {
|
||||
bool indirectHdma = false;
|
||||
values["Channel"] = evt.DmaChannel.ToString();
|
||||
if(evt.DmaChannelInfo.InterruptedByHdma != 0) {
|
||||
indirectHdma = evt.DmaChannelInfo.HdmaIndirectAddressing != 0;
|
||||
values["Channel"] = (evt.DmaChannel & 0x07).ToString();
|
||||
|
||||
if((evt.DmaChannel & ctrlEventViewerPpuView.HdmaChannelFlag) != 0) {
|
||||
indirectHdma = evt.DmaChannelInfo.HdmaIndirectAddressing;
|
||||
values["Channel"] += indirectHdma ? " (Indirect HDMA)" : " (HDMA)";
|
||||
values["Line Counter"] = "$" + evt.DmaChannelInfo.HdmaLineCounterAndRepeat.ToString("X2");
|
||||
}
|
||||
|
||||
values["Mode"] = evt.DmaChannelInfo.TransferMode.ToString();
|
||||
|
||||
int aBusAddress;
|
||||
|
@ -260,7 +265,7 @@ namespace Mesen.GUI.Debugger
|
|||
aBusAddress = (evt.DmaChannelInfo.SrcBank << 16) | evt.DmaChannelInfo.SrcAddress;
|
||||
}
|
||||
|
||||
if(evt.DmaChannelInfo.InvertDirection == 0) {
|
||||
if(!evt.DmaChannelInfo.InvertDirection) {
|
||||
values["Transfer"] = "$" + aBusAddress.ToString("X4") + " -> $" + evt.DmaChannelInfo.DestAddress.ToString("X2");
|
||||
} else {
|
||||
values["Transfer"] = "$" + aBusAddress.ToString("X4") + " <- $" + evt.DmaChannelInfo.DestAddress.ToString("X2");
|
||||
|
|
97
UI/Debugger/PpuViewer/ctrlPropertyList.Designer.cs
generated
Normal file
97
UI/Debugger/PpuViewer/ctrlPropertyList.Designer.cs
generated
Normal file
|
@ -0,0 +1,97 @@
|
|||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
partial class ctrlPropertyList
|
||||
{
|
||||
/// <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.lstProperties = new Mesen.GUI.Controls.DoubleBufferedListView();
|
||||
this.colAddress = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.colName = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.colValue = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.colValueHex = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// lstProperties
|
||||
//
|
||||
this.lstProperties.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.colAddress,
|
||||
this.colName,
|
||||
this.colValue,
|
||||
this.colValueHex});
|
||||
this.lstProperties.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.lstProperties.FullRowSelect = true;
|
||||
this.lstProperties.GridLines = true;
|
||||
this.lstProperties.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
|
||||
this.lstProperties.HideSelection = false;
|
||||
this.lstProperties.Location = new System.Drawing.Point(0, 0);
|
||||
this.lstProperties.Name = "lstProperties";
|
||||
this.lstProperties.Size = new System.Drawing.Size(424, 292);
|
||||
this.lstProperties.TabIndex = 1;
|
||||
this.lstProperties.UseCompatibleStateImageBehavior = false;
|
||||
this.lstProperties.View = System.Windows.Forms.View.Details;
|
||||
this.lstProperties.VirtualMode = true;
|
||||
this.lstProperties.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.lstProperties_RetrieveVirtualItem);
|
||||
//
|
||||
// colAddress
|
||||
//
|
||||
this.colAddress.Text = "Address";
|
||||
this.colAddress.Width = 125;
|
||||
//
|
||||
// colName
|
||||
//
|
||||
this.colName.Text = "Name";
|
||||
this.colName.Width = 114;
|
||||
//
|
||||
// colValue
|
||||
//
|
||||
this.colValue.Text = "Value";
|
||||
this.colValue.Width = 79;
|
||||
//
|
||||
// colValueHex
|
||||
//
|
||||
this.colValueHex.Text = "Value (Hex)";
|
||||
this.colValueHex.Width = 90;
|
||||
//
|
||||
// ctrlPropertyList
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.lstProperties);
|
||||
this.Name = "ctrlPropertyList";
|
||||
this.Size = new System.Drawing.Size(424, 292);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private GUI.Controls.DoubleBufferedListView lstProperties;
|
||||
private System.Windows.Forms.ColumnHeader colName;
|
||||
private System.Windows.Forms.ColumnHeader colValue;
|
||||
private System.Windows.Forms.ColumnHeader colAddress;
|
||||
private System.Windows.Forms.ColumnHeader colValueHex;
|
||||
}
|
||||
}
|
110
UI/Debugger/PpuViewer/ctrlPropertyList.cs
Normal file
110
UI/Debugger/PpuViewer/ctrlPropertyList.cs
Normal file
|
@ -0,0 +1,110 @@
|
|||
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;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public partial class ctrlPropertyList : UserControl
|
||||
{
|
||||
private List<RegEntry> _values = new List<RegEntry>();
|
||||
|
||||
public ctrlPropertyList()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnResize(EventArgs e)
|
||||
{
|
||||
base.OnResize(e);
|
||||
colAddress.Width = this.ClientSize.Width / 5 - 5;
|
||||
colName.Width = (int)(this.ClientSize.Width / 2.6 - 5);
|
||||
colValue.Width = this.ClientSize.Width / 5 - 5;
|
||||
colValueHex.Width = this.ClientSize.Width / 5 - 5;
|
||||
}
|
||||
|
||||
public void UpdateState(List<RegEntry> values)
|
||||
{
|
||||
lstProperties.BeginUpdate();
|
||||
_values = values;
|
||||
lstProperties.VirtualListSize = _values.Count;
|
||||
lstProperties.EndUpdate();
|
||||
}
|
||||
|
||||
private void lstProperties_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
|
||||
{
|
||||
string val = _values[e.ItemIndex].GetValue();
|
||||
|
||||
e.Item = new ListViewItem(new string[] {
|
||||
(val == null ? "" : " ") + _values[e.ItemIndex].Reg,
|
||||
_values[e.ItemIndex].Name,
|
||||
val,
|
||||
_values[e.ItemIndex].GetHexValue()
|
||||
});
|
||||
|
||||
if(val == null) {
|
||||
e.Item.BackColor = SystemColors.MenuBar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class RegEntry
|
||||
{
|
||||
public string Reg;
|
||||
public string Name;
|
||||
|
||||
private object _value;
|
||||
private Format _format;
|
||||
|
||||
public RegEntry(string reg, string name, object value, Format format = Format.None)
|
||||
{
|
||||
this.Reg = reg;
|
||||
this.Name = name;
|
||||
|
||||
this._value = value;
|
||||
this._format = format;
|
||||
}
|
||||
|
||||
public string GetValue()
|
||||
{
|
||||
if(_value is string) {
|
||||
return _value as string;
|
||||
} else if(_value is bool) {
|
||||
return (bool)_value ? "☑ true" : "☐ false";
|
||||
} else if(_value is IFormattable) {
|
||||
return _value.ToString();
|
||||
} else if(_value == null) {
|
||||
return null;
|
||||
}
|
||||
throw new Exception("Unsupported type");
|
||||
}
|
||||
|
||||
public string GetHexValue()
|
||||
{
|
||||
if(_value == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
switch(_format) {
|
||||
default: return "";
|
||||
case Format.X8: return "$" + ((IFormattable)_value).ToString("X2", null);
|
||||
case Format.X16: return "$" + ((IFormattable)_value).ToString("X4", null);
|
||||
case Format.X24: return "$" + ((IFormattable)_value).ToString("X6", null);
|
||||
}
|
||||
}
|
||||
|
||||
public enum Format
|
||||
{
|
||||
None,
|
||||
D,
|
||||
X8,
|
||||
X16,
|
||||
X24
|
||||
}
|
||||
}
|
||||
}
|
120
UI/Debugger/PpuViewer/ctrlPropertyList.resx
Normal file
120
UI/Debugger/PpuViewer/ctrlPropertyList.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>
|
252
UI/Debugger/PpuViewer/frmRegisterViewer.Designer.cs
generated
Normal file
252
UI/Debugger/PpuViewer/frmRegisterViewer.Designer.cs
generated
Normal file
|
@ -0,0 +1,252 @@
|
|||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
partial class frmRegisterViewer
|
||||
{
|
||||
/// <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 Windows Form 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.ctrlScanlineCycleSelect = new Mesen.GUI.Debugger.Controls.ctrlScanlineCycleSelect();
|
||||
this.ctrlMesenMenuStrip1 = new Mesen.GUI.Controls.ctrlMesenMenuStrip();
|
||||
this.mnuFile = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuClose = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuView = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuAutoRefresh = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuRefresh = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.tabMain = new System.Windows.Forms.TabControl();
|
||||
this.tpgCpu = new System.Windows.Forms.TabPage();
|
||||
this.ctrlPropertyCpu = new Mesen.GUI.Debugger.ctrlPropertyList();
|
||||
this.tpgDma = new System.Windows.Forms.TabPage();
|
||||
this.ctrlPropertyDma = new Mesen.GUI.Debugger.ctrlPropertyList();
|
||||
this.tpgPpu = new System.Windows.Forms.TabPage();
|
||||
this.ctrlPropertyPpu = new Mesen.GUI.Debugger.ctrlPropertyList();
|
||||
this.tpgSpc = new System.Windows.Forms.TabPage();
|
||||
this.ctrlPropertySpc = new Mesen.GUI.Debugger.ctrlPropertyList();
|
||||
this.ctrlMesenMenuStrip1.SuspendLayout();
|
||||
this.tabMain.SuspendLayout();
|
||||
this.tpgCpu.SuspendLayout();
|
||||
this.tpgDma.SuspendLayout();
|
||||
this.tpgPpu.SuspendLayout();
|
||||
this.tpgSpc.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// ctrlScanlineCycleSelect
|
||||
//
|
||||
this.ctrlScanlineCycleSelect.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.ctrlScanlineCycleSelect.Location = new System.Drawing.Point(0, 411);
|
||||
this.ctrlScanlineCycleSelect.Name = "ctrlScanlineCycleSelect";
|
||||
this.ctrlScanlineCycleSelect.Size = new System.Drawing.Size(384, 28);
|
||||
this.ctrlScanlineCycleSelect.TabIndex = 5;
|
||||
//
|
||||
// ctrlMesenMenuStrip1
|
||||
//
|
||||
this.ctrlMesenMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuFile,
|
||||
this.mnuView});
|
||||
this.ctrlMesenMenuStrip1.Location = new System.Drawing.Point(0, 0);
|
||||
this.ctrlMesenMenuStrip1.Name = "ctrlMesenMenuStrip1";
|
||||
this.ctrlMesenMenuStrip1.Size = new System.Drawing.Size(384, 24);
|
||||
this.ctrlMesenMenuStrip1.TabIndex = 9;
|
||||
this.ctrlMesenMenuStrip1.Text = "ctrlMesenMenuStrip1";
|
||||
//
|
||||
// mnuFile
|
||||
//
|
||||
this.mnuFile.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuClose});
|
||||
this.mnuFile.Name = "mnuFile";
|
||||
this.mnuFile.Size = new System.Drawing.Size(37, 20);
|
||||
this.mnuFile.Text = "File";
|
||||
//
|
||||
// mnuClose
|
||||
//
|
||||
this.mnuClose.Image = global::Mesen.GUI.Properties.Resources.Exit;
|
||||
this.mnuClose.Name = "mnuClose";
|
||||
this.mnuClose.Size = new System.Drawing.Size(103, 22);
|
||||
this.mnuClose.Text = "Close";
|
||||
this.mnuClose.Click += new System.EventHandler(this.mnuClose_Click);
|
||||
//
|
||||
// mnuView
|
||||
//
|
||||
this.mnuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuAutoRefresh,
|
||||
this.toolStripMenuItem2,
|
||||
this.mnuRefresh});
|
||||
this.mnuView.Name = "mnuView";
|
||||
this.mnuView.Size = new System.Drawing.Size(44, 20);
|
||||
this.mnuView.Text = "View";
|
||||
//
|
||||
// mnuAutoRefresh
|
||||
//
|
||||
this.mnuAutoRefresh.Checked = true;
|
||||
this.mnuAutoRefresh.CheckOnClick = true;
|
||||
this.mnuAutoRefresh.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.mnuAutoRefresh.Name = "mnuAutoRefresh";
|
||||
this.mnuAutoRefresh.Size = new System.Drawing.Size(141, 22);
|
||||
this.mnuAutoRefresh.Text = "Auto-refresh";
|
||||
//
|
||||
// toolStripMenuItem2
|
||||
//
|
||||
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
|
||||
this.toolStripMenuItem2.Size = new System.Drawing.Size(138, 6);
|
||||
//
|
||||
// mnuRefresh
|
||||
//
|
||||
this.mnuRefresh.Image = global::Mesen.GUI.Properties.Resources.Refresh;
|
||||
this.mnuRefresh.Name = "mnuRefresh";
|
||||
this.mnuRefresh.Size = new System.Drawing.Size(141, 22);
|
||||
this.mnuRefresh.Text = "Refresh";
|
||||
this.mnuRefresh.Click += new System.EventHandler(this.mnuRefresh_Click);
|
||||
//
|
||||
// tabMain
|
||||
//
|
||||
this.tabMain.Controls.Add(this.tpgCpu);
|
||||
this.tabMain.Controls.Add(this.tpgDma);
|
||||
this.tabMain.Controls.Add(this.tpgPpu);
|
||||
this.tabMain.Controls.Add(this.tpgSpc);
|
||||
this.tabMain.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tabMain.Location = new System.Drawing.Point(0, 24);
|
||||
this.tabMain.Name = "tabMain";
|
||||
this.tabMain.SelectedIndex = 0;
|
||||
this.tabMain.Size = new System.Drawing.Size(384, 387);
|
||||
this.tabMain.TabIndex = 10;
|
||||
this.tabMain.SelectedIndexChanged += new System.EventHandler(this.tabMain_SelectedIndexChanged);
|
||||
//
|
||||
// tpgCpu
|
||||
//
|
||||
this.tpgCpu.Controls.Add(this.ctrlPropertyCpu);
|
||||
this.tpgCpu.Location = new System.Drawing.Point(4, 22);
|
||||
this.tpgCpu.Name = "tpgCpu";
|
||||
this.tpgCpu.Size = new System.Drawing.Size(376, 361);
|
||||
this.tpgCpu.TabIndex = 0;
|
||||
this.tpgCpu.Text = "CPU";
|
||||
this.tpgCpu.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// ctrlPropertyCpu
|
||||
//
|
||||
this.ctrlPropertyCpu.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlPropertyCpu.Location = new System.Drawing.Point(0, 0);
|
||||
this.ctrlPropertyCpu.Name = "ctrlPropertyCpu";
|
||||
this.ctrlPropertyCpu.Size = new System.Drawing.Size(376, 361);
|
||||
this.ctrlPropertyCpu.TabIndex = 0;
|
||||
//
|
||||
// tpgDma
|
||||
//
|
||||
this.tpgDma.Controls.Add(this.ctrlPropertyDma);
|
||||
this.tpgDma.Location = new System.Drawing.Point(4, 22);
|
||||
this.tpgDma.Name = "tpgDma";
|
||||
this.tpgDma.Size = new System.Drawing.Size(526, 461);
|
||||
this.tpgDma.TabIndex = 2;
|
||||
this.tpgDma.Text = "DMA";
|
||||
this.tpgDma.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// ctrlPropertyDma
|
||||
//
|
||||
this.ctrlPropertyDma.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlPropertyDma.Location = new System.Drawing.Point(0, 0);
|
||||
this.ctrlPropertyDma.Name = "ctrlPropertyDma";
|
||||
this.ctrlPropertyDma.Size = new System.Drawing.Size(526, 461);
|
||||
this.ctrlPropertyDma.TabIndex = 1;
|
||||
//
|
||||
// tpgPpu
|
||||
//
|
||||
this.tpgPpu.Controls.Add(this.ctrlPropertyPpu);
|
||||
this.tpgPpu.Location = new System.Drawing.Point(4, 22);
|
||||
this.tpgPpu.Name = "tpgPpu";
|
||||
this.tpgPpu.Size = new System.Drawing.Size(526, 461);
|
||||
this.tpgPpu.TabIndex = 1;
|
||||
this.tpgPpu.Text = "PPU";
|
||||
this.tpgPpu.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// ctrlPropertyPpu
|
||||
//
|
||||
this.ctrlPropertyPpu.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlPropertyPpu.Location = new System.Drawing.Point(0, 0);
|
||||
this.ctrlPropertyPpu.Name = "ctrlPropertyPpu";
|
||||
this.ctrlPropertyPpu.Size = new System.Drawing.Size(526, 461);
|
||||
this.ctrlPropertyPpu.TabIndex = 2;
|
||||
//
|
||||
// tpgSpc
|
||||
//
|
||||
this.tpgSpc.Controls.Add(this.ctrlPropertySpc);
|
||||
this.tpgSpc.Location = new System.Drawing.Point(4, 22);
|
||||
this.tpgSpc.Name = "tpgSpc";
|
||||
this.tpgSpc.Size = new System.Drawing.Size(526, 461);
|
||||
this.tpgSpc.TabIndex = 5;
|
||||
this.tpgSpc.Text = "SPC";
|
||||
this.tpgSpc.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// ctrlPropertySpc
|
||||
//
|
||||
this.ctrlPropertySpc.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlPropertySpc.Location = new System.Drawing.Point(0, 0);
|
||||
this.ctrlPropertySpc.Name = "ctrlPropertySpc";
|
||||
this.ctrlPropertySpc.Size = new System.Drawing.Size(526, 461);
|
||||
this.ctrlPropertySpc.TabIndex = 2;
|
||||
//
|
||||
// frmRegisterViewer
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(384, 439);
|
||||
this.Controls.Add(this.tabMain);
|
||||
this.Controls.Add(this.ctrlScanlineCycleSelect);
|
||||
this.Controls.Add(this.ctrlMesenMenuStrip1);
|
||||
this.Name = "frmRegisterViewer";
|
||||
this.Text = "Register Viewer";
|
||||
this.Controls.SetChildIndex(this.ctrlMesenMenuStrip1, 0);
|
||||
this.Controls.SetChildIndex(this.ctrlScanlineCycleSelect, 0);
|
||||
this.Controls.SetChildIndex(this.tabMain, 0);
|
||||
this.ctrlMesenMenuStrip1.ResumeLayout(false);
|
||||
this.ctrlMesenMenuStrip1.PerformLayout();
|
||||
this.tabMain.ResumeLayout(false);
|
||||
this.tpgCpu.ResumeLayout(false);
|
||||
this.tpgDma.ResumeLayout(false);
|
||||
this.tpgPpu.ResumeLayout(false);
|
||||
this.tpgSpc.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
private Controls.ctrlScanlineCycleSelect ctrlScanlineCycleSelect;
|
||||
private GUI.Controls.ctrlMesenMenuStrip ctrlMesenMenuStrip1;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuFile;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuClose;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuView;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefresh;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuRefresh;
|
||||
private System.Windows.Forms.TabControl tabMain;
|
||||
private System.Windows.Forms.TabPage tpgCpu;
|
||||
private System.Windows.Forms.TabPage tpgPpu;
|
||||
private System.Windows.Forms.TabPage tpgDma;
|
||||
private System.Windows.Forms.TabPage tpgSpc;
|
||||
private ctrlPropertyList ctrlPropertyCpu;
|
||||
private ctrlPropertyList ctrlPropertyDma;
|
||||
private ctrlPropertyList ctrlPropertyPpu;
|
||||
private ctrlPropertyList ctrlPropertySpc;
|
||||
}
|
||||
}
|
436
UI/Debugger/PpuViewer/frmRegisterViewer.cs
Normal file
436
UI/Debugger/PpuViewer/frmRegisterViewer.cs
Normal file
|
@ -0,0 +1,436 @@
|
|||
using Mesen.GUI.Config;
|
||||
using Mesen.GUI.Debugger.Controls;
|
||||
using Mesen.GUI.Forms;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using static Mesen.GUI.Debugger.RegEntry;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public partial class frmRegisterViewer : BaseForm, IRefresh
|
||||
{
|
||||
private NotificationListener _notifListener;
|
||||
|
||||
private WindowRefreshManager _refreshManager;
|
||||
private DebugState _state;
|
||||
private byte _reg4210;
|
||||
private byte _reg4211;
|
||||
private byte _reg4212;
|
||||
|
||||
public ctrlScanlineCycleSelect ScanlineCycleSelect { get { return this.ctrlScanlineCycleSelect; } }
|
||||
|
||||
public frmRegisterViewer()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs evt)
|
||||
{
|
||||
base.OnLoad(evt);
|
||||
if(DesignMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
_notifListener = new NotificationListener();
|
||||
_notifListener.OnNotification += OnNotificationReceived;
|
||||
|
||||
InitShortcuts();
|
||||
|
||||
RegisterViewerConfig config = ConfigManager.Config.Debug.RegisterViewer;
|
||||
RestoreLocation(config.WindowLocation, config.WindowSize);
|
||||
|
||||
mnuAutoRefresh.Checked = config.AutoRefresh;
|
||||
ctrlScanlineCycleSelect.Initialize(config.RefreshScanline, config.RefreshCycle);
|
||||
|
||||
_refreshManager = new WindowRefreshManager(this);
|
||||
_refreshManager.AutoRefresh = config.AutoRefresh;
|
||||
_refreshManager.AutoRefreshSpeed = RefreshSpeed.High;
|
||||
|
||||
RefreshData();
|
||||
RefreshViewer();
|
||||
|
||||
mnuAutoRefresh.CheckedChanged += mnuAutoRefresh_CheckedChanged;
|
||||
}
|
||||
|
||||
private void InitShortcuts()
|
||||
{
|
||||
mnuRefresh.InitShortcut(this, nameof(DebuggerShortcutsConfig.Refresh));
|
||||
}
|
||||
|
||||
protected override void OnFormClosed(FormClosedEventArgs e)
|
||||
{
|
||||
_notifListener?.Dispose();
|
||||
_refreshManager?.Dispose();
|
||||
|
||||
RegisterViewerConfig config = ConfigManager.Config.Debug.RegisterViewer;
|
||||
config.WindowSize = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Size : this.Size;
|
||||
config.WindowLocation = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Location : this.Location;
|
||||
config.AutoRefresh = mnuAutoRefresh.Checked;
|
||||
config.RefreshScanline = ctrlScanlineCycleSelect.Scanline;
|
||||
config.RefreshCycle = ctrlScanlineCycleSelect.Cycle;
|
||||
ConfigManager.ApplyChanges();
|
||||
|
||||
base.OnFormClosed(e);
|
||||
}
|
||||
|
||||
private void OnNotificationReceived(NotificationEventArgs e)
|
||||
{
|
||||
switch(e.NotificationType) {
|
||||
case ConsoleNotificationType.CodeBreak:
|
||||
RefreshData();
|
||||
this.BeginInvoke((Action)(() => {
|
||||
this.RefreshViewer();
|
||||
}));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void RefreshData()
|
||||
{
|
||||
_state = DebugApi.GetState();
|
||||
_reg4210 = DebugApi.GetMemoryValue(SnesMemoryType.CpuMemory, 0x4210);
|
||||
_reg4211 = DebugApi.GetMemoryValue(SnesMemoryType.CpuMemory, 0x4211);
|
||||
_reg4212 = DebugApi.GetMemoryValue(SnesMemoryType.CpuMemory, 0x4212);
|
||||
}
|
||||
|
||||
public void RefreshViewer()
|
||||
{
|
||||
if(tabMain.SelectedTab == tpgCpu) {
|
||||
InternalRegisterState regs = _state.InternalRegs;
|
||||
AluState alu = _state.Alu;
|
||||
ctrlPropertyCpu.UpdateState(new List<RegEntry>() {
|
||||
new RegEntry("$4200 - $4201", "IRQ/NMI/Autopoll Enabled", null),
|
||||
new RegEntry("$4200.7", "NMI Enabled", regs.EnableNmi),
|
||||
new RegEntry("$4200.5", "H IRQ Enabled", regs.EnableHorizontalIrq),
|
||||
new RegEntry("$4200.4", "V IRQ Enabled", regs.EnableVerticalIrq),
|
||||
new RegEntry("$4200.1", "Auto Joypad Poll", regs.EnableAutoJoypadRead),
|
||||
|
||||
new RegEntry("$4201", "IO Port", regs.IoPortOutput, Format.X8),
|
||||
|
||||
new RegEntry("$4202 - $4206", "Mult/Div Registers (Input)", null),
|
||||
new RegEntry("$4202", "Multiplicand", alu.MultOperand1, Format.X8),
|
||||
new RegEntry("$4203", "Multiplier", alu.MultOperand2, Format.X8),
|
||||
new RegEntry("$4204/5", "Dividend", alu.Dividend, Format.X16),
|
||||
new RegEntry("$4206", "Divisor", alu.Divisor, Format.X8),
|
||||
|
||||
new RegEntry("$4207 - $420A", "H/V IRQ Timers", null),
|
||||
new RegEntry("$4207/8", "H Timer", regs.HorizontalTimer, Format.X16),
|
||||
new RegEntry("$4209/A", "V Timer", regs.VerticalTimer, Format.X16),
|
||||
|
||||
new RegEntry("$4207 - $420A", "Misc. Flags", null),
|
||||
|
||||
new RegEntry("$420D", "FastROM Enabled", regs.EnableFastRom),
|
||||
new RegEntry("$4210", "NMI Flag", (_reg4210 & 0x80) != 0),
|
||||
new RegEntry("$4211", "IRQ Flag", (_reg4211 & 0x80) != 0),
|
||||
|
||||
new RegEntry("$4212.x", "V-Blank Flag", (_reg4212 & 0x80) != 0),
|
||||
new RegEntry("$4212.x", "H-Blank Flag", (_reg4212 & 0x40) != 0),
|
||||
new RegEntry("$4212.x", "Auto Joypad Read", (_reg4212 & 0x01) != 0),
|
||||
|
||||
new RegEntry("$4214 - $4217", "Mult/Div Registers (Result)", null),
|
||||
new RegEntry("$4214/5", "Quotient", alu.DivResult, Format.X16),
|
||||
new RegEntry("$4216/7", "Product / Remainder", alu.MultOrRemainderResult, Format.X16),
|
||||
|
||||
new RegEntry("$4218 - $421F", "Input Data", null),
|
||||
new RegEntry("$4218/9", "P1 Data", regs.ControllerData[0], Format.X16),
|
||||
new RegEntry("$421A/B", "P2 Data", regs.ControllerData[1], Format.X16),
|
||||
new RegEntry("$421C/D", "P3 Data", regs.ControllerData[2], Format.X16),
|
||||
new RegEntry("$421E/F", "P4 Data", regs.ControllerData[3], Format.X16),
|
||||
|
||||
});
|
||||
} else if(tabMain.SelectedTab == tpgDma) {
|
||||
List<RegEntry> entries = new List<RegEntry>();
|
||||
|
||||
//TODO
|
||||
/*for(int i = 0; i < 8; i++) {
|
||||
entries.Add(new RegEntry("$420C." + i.ToString(), "HDMA Channel " + i.ToString() + " Enabled", _state.DmaChannels[i].DmaActive));
|
||||
}*/
|
||||
|
||||
for(int i = 0; i < 8; i++) {
|
||||
DmaChannelConfig ch = _state.DmaChannels[i];
|
||||
entries.Add(new RegEntry("DMA Channel " + i.ToString(), "", null));
|
||||
entries.Add(new RegEntry("$420B." + i.ToString(), "Channel Enabled", _state.DmaChannels[i].DmaActive));
|
||||
entries.Add(new RegEntry("$43" + i.ToString() + "0.0-2", "Transfer Mode", ch.TransferMode, Format.D));
|
||||
entries.Add(new RegEntry("$43" + i.ToString() + "0.3", "Fixed", ch.FixedTransfer));
|
||||
entries.Add(new RegEntry("$43" + i.ToString() + "0.4", "Decrement", ch.Decrement));
|
||||
entries.Add(new RegEntry("$43" + i.ToString() + "0.6", "Indirect HDMA", ch.HdmaIndirectAddressing));
|
||||
entries.Add(new RegEntry("$43" + i.ToString() + "0.7", "Direction", ch.InvertDirection ? "B -> A" : "A -> B"));
|
||||
|
||||
entries.Add(new RegEntry("$43" + i.ToString() + "1", "B Bus Address", ch.DestAddress, Format.X8));
|
||||
entries.Add(new RegEntry("$43" + i.ToString() + "2/3/4", "A Bus Address", ((ch.SrcBank << 16) | ch.SrcAddress), Format.X24));
|
||||
entries.Add(new RegEntry("$43" + i.ToString() + "5/6", "Size", ch.TransferSize, Format.X16));
|
||||
entries.Add(new RegEntry("$43" + i.ToString() + "7", "HDMA Bank", ch.HdmaBank, Format.X8));
|
||||
entries.Add(new RegEntry("$43" + i.ToString() + "8/9", "HDMA Address", ch.HdmaTableAddress, Format.X16));
|
||||
entries.Add(new RegEntry("$43" + i.ToString() + "A", "HDMA Line Counter", ch.HdmaLineCounterAndRepeat, Format.X8));
|
||||
}
|
||||
ctrlPropertyDma.UpdateState(entries);
|
||||
} else if(tabMain.SelectedTab == tpgSpc) {
|
||||
SpcState spc = _state.Spc;
|
||||
ctrlPropertySpc.UpdateState(new List<RegEntry>() {
|
||||
new RegEntry("$F0", "Test", null),
|
||||
new RegEntry("$F0.0", "Timers Disabled", spc.TimersDisabled),
|
||||
new RegEntry("$F0.1", "RAM Write Enabled", spc.WriteEnabled),
|
||||
new RegEntry("$F0.3", "Timers Enabled", spc.TimersEnabled),
|
||||
new RegEntry("$F0.4-5", "External Speed", spc.ExternalSpeed, Format.D),
|
||||
new RegEntry("$F0.6-7", "Internal Speed", spc.InternalSpeed, Format.D),
|
||||
|
||||
new RegEntry("$F1", "Control", null),
|
||||
new RegEntry("$F1.0", "Timer 0 Enabled", spc.Timer0.Enabled),
|
||||
new RegEntry("$F1.1", "Timer 1 Enabled", spc.Timer1.Enabled),
|
||||
new RegEntry("$F1.2", "Timer 2 Enabled", spc.Timer2.Enabled),
|
||||
new RegEntry("$F1.7", "IPL ROM Enabled", spc.RomEnabled),
|
||||
|
||||
new RegEntry("$F2", "DSP", null),
|
||||
new RegEntry("$F2", "DSP Register", spc.DspReg, Format.X8),
|
||||
|
||||
new RegEntry("$F4 - $F7", "CPU<->SPC Ports", null),
|
||||
new RegEntry("$F4", "Port 0 (CPU read)", spc.OutputReg[0], Format.X8),
|
||||
new RegEntry("$F4", "Port 0 (SPC read)", spc.CpuRegs[0], Format.X8),
|
||||
new RegEntry("$F5", "Port 1 (CPU read)", spc.OutputReg[1], Format.X8),
|
||||
new RegEntry("$F5", "Port 1 (SPC read)", spc.CpuRegs[1], Format.X8),
|
||||
new RegEntry("$F6", "Port 2 (CPU read)", spc.OutputReg[2], Format.X8),
|
||||
new RegEntry("$F6", "Port 2 (SPC read)", spc.CpuRegs[2], Format.X8),
|
||||
new RegEntry("$F7", "Port 3 (CPU read)", spc.OutputReg[3], Format.X8),
|
||||
new RegEntry("$F7", "Port 3 (SPC read)", spc.CpuRegs[3], Format.X8),
|
||||
|
||||
new RegEntry("$F8", "RAM Reg 0", spc.RamReg[0], Format.X8),
|
||||
new RegEntry("$F9", "RAM Reg 1", spc.RamReg[1], Format.X8),
|
||||
|
||||
|
||||
new RegEntry("$FA - $FF", "Timers", null),
|
||||
new RegEntry("$FA", "Timer 0 Divider", spc.Timer0.Target, Format.X8),
|
||||
new RegEntry("$FA", "Timer 0 Frequency", GetTimerFrequency(8000, spc.Timer0.Target)),
|
||||
new RegEntry("$FB", "Timer 1 Divider", spc.Timer1.Target, Format.X8),
|
||||
new RegEntry("$FA", "Timer 1 Frequency", GetTimerFrequency(8000, spc.Timer1.Target)),
|
||||
new RegEntry("$FC", "Timer 2 Divider", spc.Timer2.Target, Format.X8),
|
||||
new RegEntry("$FA", "Timer 2 Frequency", GetTimerFrequency(64000, spc.Timer2.Target)),
|
||||
|
||||
new RegEntry("$FD", "Timer 0 Output", spc.Timer0.Output, Format.X8),
|
||||
new RegEntry("$FE", "Timer 1 Output", spc.Timer1.Output, Format.X8),
|
||||
new RegEntry("$FF", "Timer 2 Output", spc.Timer2.Output, Format.X8),
|
||||
});
|
||||
} else if(tabMain.SelectedTab == tpgPpu) {
|
||||
PpuState ppu = _state.Ppu;
|
||||
|
||||
ctrlPropertyPpu.UpdateState(new List<RegEntry>() {
|
||||
new RegEntry("$2100", "Brightness", null),
|
||||
new RegEntry("$2100.0", "Forced Blank", ppu.ForcedVblank),
|
||||
new RegEntry("$2100.4-7", "Brightness", ppu.ScreenBrightness),
|
||||
new RegEntry("$2101", "OAM Settings", null),
|
||||
new RegEntry("$2100.0-2", "OAM Table Address", ppu.OamBaseAddress, Format.X16),
|
||||
new RegEntry("$2100.3-4", "OAM Second Table Address", (ppu.OamBaseAddress + ppu.OamAddressOffset) & 0x7FFF, Format.X16),
|
||||
new RegEntry("$2101.5-7", "OAM Size Mode", ppu.OamMode),
|
||||
new RegEntry("$2102-2103", "OAM Base Address", ppu.OamRamAddress),
|
||||
new RegEntry("$2103.7", "OAM Priority", ppu.EnableOamPriority),
|
||||
|
||||
new RegEntry("$2105", "BG Mode/Size", null),
|
||||
new RegEntry("$2105.0-2", "BG Mode", ppu.BgMode),
|
||||
new RegEntry("$2105.3", "Mode 1 BG3 Priority", ppu.Mode1Bg3Priority),
|
||||
new RegEntry("$2105.4", "BG1 16x16 Tiles", ppu.Layers[0].LargeTiles),
|
||||
new RegEntry("$2105.5", "BG2 16x16 Tiles", ppu.Layers[1].LargeTiles),
|
||||
new RegEntry("$2105.6", "BG3 16x16 Tiles", ppu.Layers[2].LargeTiles),
|
||||
new RegEntry("$2105.7", "BG4 16x16 Tiles", ppu.Layers[3].LargeTiles),
|
||||
|
||||
new RegEntry("$2106", "Mosaic", null),
|
||||
new RegEntry("$2106.0", "BG1 Mosaic Enabled", (ppu.MosaicEnabled & 0x01) != 0),
|
||||
new RegEntry("$2106.1", "BG2 Mosaic Enabled", (ppu.MosaicEnabled & 0x02) != 0),
|
||||
new RegEntry("$2106.2", "BG3 Mosaic Enabled", (ppu.MosaicEnabled & 0x04) != 0),
|
||||
new RegEntry("$2106.3", "BG4 Mosaic Enabled", (ppu.MosaicEnabled & 0x08) != 0),
|
||||
new RegEntry("$2106.4-7", "Mosaic Size", (ppu.MosaicSize - 1).ToString() + " (" + ppu.MosaicSize.ToString() + "x" + ppu.MosaicSize.ToString() + ")"),
|
||||
|
||||
new RegEntry("$2107 - $210A", "Tilemap Addresses/Sizes", null),
|
||||
new RegEntry("$2107.0-1", "BG1 Size", GetLayerSize(ppu.Layers[0])),
|
||||
new RegEntry("$2107.2-6", "BG1 Address", ppu.Layers[0].TilemapAddress, Format.X16),
|
||||
new RegEntry("$2108.0-1", "BG1 Size", GetLayerSize(ppu.Layers[1])),
|
||||
new RegEntry("$2108.2-6", "BG2 Address", ppu.Layers[1].TilemapAddress, Format.X16),
|
||||
new RegEntry("$2109.0-1", "BG1 Size", GetLayerSize(ppu.Layers[2])),
|
||||
new RegEntry("$2109.2-6", "BG3 Address", ppu.Layers[2].TilemapAddress, Format.X16),
|
||||
new RegEntry("$210A.0-1", "BG1 Size", GetLayerSize(ppu.Layers[3])),
|
||||
new RegEntry("$210A.2-6", "BG4 Address", ppu.Layers[3].TilemapAddress, Format.X16),
|
||||
|
||||
new RegEntry("$210B - $210C", "Tile Addresses", null),
|
||||
new RegEntry("$210B.0-2", "BG1 Tile Address", ppu.Layers[0].ChrAddress, Format.X16),
|
||||
new RegEntry("$210B.4-6", "BG2 Tile Address", ppu.Layers[1].ChrAddress, Format.X16),
|
||||
new RegEntry("$210C.0-2", "BG3 Tile Address", ppu.Layers[2].ChrAddress, Format.X16),
|
||||
new RegEntry("$210C.4-6", "BG4 Tile Address", ppu.Layers[3].ChrAddress, Format.X16),
|
||||
|
||||
new RegEntry("$210D - $2114", "H/V Scroll Offsets", null),
|
||||
new RegEntry("$210D", "BG1 H Offset", ppu.Layers[0].HScroll, Format.X16),
|
||||
new RegEntry("$210D", "Mode7 H Offset", ppu.Mode7.HScroll, Format.X16),
|
||||
new RegEntry("$210E", "BG1 V Offset", ppu.Layers[0].VScroll, Format.X16),
|
||||
new RegEntry("$210E", "Mode7 V Offset", ppu.Mode7.VScroll, Format.X16),
|
||||
|
||||
new RegEntry("$210F", "BG2 H Offset", ppu.Layers[1].HScroll, Format.X16),
|
||||
new RegEntry("$2110", "BG2 V Offset", ppu.Layers[1].VScroll, Format.X16),
|
||||
new RegEntry("$2111", "BG3 H Offset", ppu.Layers[2].HScroll, Format.X16),
|
||||
new RegEntry("$2112", "BG3 V Offset", ppu.Layers[2].VScroll, Format.X16),
|
||||
new RegEntry("$2113", "BG4 H Offset", ppu.Layers[3].HScroll, Format.X16),
|
||||
new RegEntry("$2114", "BG4 V Offset", ppu.Layers[3].VScroll, Format.X16),
|
||||
|
||||
new RegEntry("$2115 - $2117", "VRAM", null),
|
||||
new RegEntry("$2115.0-1", "Increment Value", ppu.VramIncrementValue),
|
||||
new RegEntry("$2115.2-3", "Address Mapping", ppu.VramAddressRemapping),
|
||||
new RegEntry("$2115.7", "Increment on $2119", ppu.VramAddrIncrementOnSecondReg),
|
||||
new RegEntry("$2116/7", "VRAM Address", ppu.VramAddress, Format.X16),
|
||||
|
||||
new RegEntry("$211A - $2120", "Mode 7", null),
|
||||
new RegEntry("$211A.0", "Mode 7 - Hor. Mirroring", ppu.Mode7.HorizontalMirroring),
|
||||
new RegEntry("$211A.1", "Mode 7 - Vert. Mirroring", ppu.Mode7.VerticalMirroring),
|
||||
new RegEntry("$211A.6", "Mode 7 - Fill w/ Tile 0", ppu.Mode7.FillWithTile0),
|
||||
new RegEntry("$211A.7", "Mode 7 - Large Tilemap", ppu.Mode7.LargeMap),
|
||||
|
||||
new RegEntry("$211B", "Mode 7 - Matrix A", ppu.Mode7.Matrix[0], Format.X16),
|
||||
new RegEntry("$211C", "Mode 7 - Matrix B", ppu.Mode7.Matrix[1], Format.X16),
|
||||
new RegEntry("$211D", "Mode 7 - Matrix C", ppu.Mode7.Matrix[2], Format.X16),
|
||||
new RegEntry("$211E", "Mode 7 - Matrix D", ppu.Mode7.Matrix[3], Format.X16),
|
||||
|
||||
new RegEntry("$211F", "Mode 7 - Center X", ppu.Mode7.CenterX, Format.X16),
|
||||
new RegEntry("$2120", "Mode 7 - Center Y", ppu.Mode7.CenterY, Format.X16),
|
||||
|
||||
new RegEntry("$2123 - $212B", "Windows", null),
|
||||
new RegEntry("", "BG1 Windows", null),
|
||||
new RegEntry("$2123.0", "BG1 Window 1 Inverted", ppu.Window[0].InvertedLayers[0]),
|
||||
new RegEntry("$2123.1", "BG1 Window 1 Active", ppu.Window[0].ActiveLayers[0]),
|
||||
new RegEntry("$2123.2", "BG1 Window 2 Inverted", ppu.Window[1].InvertedLayers[0]),
|
||||
new RegEntry("$2123.3", "BG1 Window 2 Active", ppu.Window[1].ActiveLayers[0]),
|
||||
|
||||
new RegEntry("", "BG2 Windows", null),
|
||||
new RegEntry("$2123.4", "BG2 Window 1 Inverted", ppu.Window[0].InvertedLayers[1]),
|
||||
new RegEntry("$2123.5", "BG2 Window 1 Active", ppu.Window[0].ActiveLayers[1]),
|
||||
new RegEntry("$2123.6", "BG2 Window 2 Inverted", ppu.Window[1].InvertedLayers[1]),
|
||||
new RegEntry("$2123.7", "BG2 Window 2 Active", ppu.Window[1].ActiveLayers[1]),
|
||||
|
||||
new RegEntry("", "BG3 Windows", null),
|
||||
new RegEntry("$2124.0", "BG3 Window 1 Inverted", ppu.Window[0].InvertedLayers[2]),
|
||||
new RegEntry("$2124.1", "BG3 Window 1 Active", ppu.Window[0].ActiveLayers[2]),
|
||||
new RegEntry("$2124.2", "BG3 Window 2 Inverted", ppu.Window[1].InvertedLayers[2]),
|
||||
new RegEntry("$2124.3", "BG3 Window 2 Active", ppu.Window[1].ActiveLayers[2]),
|
||||
|
||||
new RegEntry("", "BG4 Windows", null),
|
||||
new RegEntry("$2124.4", "BG4 Window 1 Inverted", ppu.Window[0].InvertedLayers[3]),
|
||||
new RegEntry("$2124.5", "BG4 Window 1 Active", ppu.Window[0].ActiveLayers[3]),
|
||||
new RegEntry("$2124.6", "BG4 Window 2 Inverted", ppu.Window[1].InvertedLayers[3]),
|
||||
new RegEntry("$2124.7", "BG4 Window 2 Active", ppu.Window[1].ActiveLayers[3]),
|
||||
|
||||
new RegEntry("", "OAM Windows", null),
|
||||
new RegEntry("$2125.0", "OAM Window 1 Inverted", ppu.Window[0].InvertedLayers[4]),
|
||||
new RegEntry("$2125.1", "OAM Window 1 Active", ppu.Window[0].ActiveLayers[4]),
|
||||
new RegEntry("$2125.2", "OAM Window 2 Inverted", ppu.Window[1].InvertedLayers[4]),
|
||||
new RegEntry("$2125.3", "OAM Window 2 Active", ppu.Window[1].ActiveLayers[4]),
|
||||
|
||||
new RegEntry("", "Color Windows", null),
|
||||
new RegEntry("$2125.4", "Color Window 1 Inverted", ppu.Window[0].InvertedLayers[5]),
|
||||
new RegEntry("$2125.5", "Color Window 1 Active", ppu.Window[0].ActiveLayers[5]),
|
||||
new RegEntry("$2125.6", "Color Window 2 Inverted", ppu.Window[1].InvertedLayers[5]),
|
||||
new RegEntry("$2125.7", "Color Window 2 Active", ppu.Window[1].ActiveLayers[5]),
|
||||
|
||||
new RegEntry("", "Window Position", null),
|
||||
new RegEntry("$2126", "Window 1 Left", ppu.Window[0].Left),
|
||||
new RegEntry("$2127", "Window 1 Right", ppu.Window[0].Right),
|
||||
new RegEntry("$2128", "Window 2 Left", ppu.Window[1].Left),
|
||||
new RegEntry("$2129", "Window 2 Right", ppu.Window[1].Right),
|
||||
|
||||
new RegEntry("", "Window Masks", null),
|
||||
new RegEntry("$212A.0-1", "BG1 Window Mask", ppu.MaskLogic[0].ToString().ToUpper()),
|
||||
new RegEntry("$212A.2-3", "BG2 Window Mask", ppu.MaskLogic[1].ToString().ToUpper()),
|
||||
new RegEntry("$212A.4-5", "BG3 Window Mask", ppu.MaskLogic[2].ToString().ToUpper()),
|
||||
new RegEntry("$212A.6-7", "BG4 Window Mask", ppu.MaskLogic[3].ToString().ToUpper()),
|
||||
new RegEntry("$212B.6-7", "OAM Window Mask", ppu.MaskLogic[4].ToString().ToUpper()),
|
||||
new RegEntry("$212B.6-7", "Color Window Mask", ppu.MaskLogic[5].ToString().ToUpper()),
|
||||
|
||||
new RegEntry("$212C", "Main Screen Layers", null),
|
||||
new RegEntry("$212C.0", "BG1 Enabled", (ppu.MainScreenLayers & 0x01) != 0),
|
||||
new RegEntry("$212C.1", "BG2 Enabled", (ppu.MainScreenLayers & 0x02) != 0),
|
||||
new RegEntry("$212C.2", "BG3 Enabled", (ppu.MainScreenLayers & 0x04) != 0),
|
||||
new RegEntry("$212C.3", "BG4 Enabled", (ppu.MainScreenLayers & 0x08) != 0),
|
||||
new RegEntry("$212C.4", "OAM Enabled", (ppu.MainScreenLayers & 0x10) != 0),
|
||||
|
||||
new RegEntry("$212D", "Sub Screen Layers", null),
|
||||
new RegEntry("$212D.0", "BG1 Enabled", (ppu.SubScreenLayers & 0x01) != 0),
|
||||
new RegEntry("$212D.1", "BG2 Enabled", (ppu.SubScreenLayers & 0x02) != 0),
|
||||
new RegEntry("$212D.2", "BG3 Enabled", (ppu.SubScreenLayers & 0x04) != 0),
|
||||
new RegEntry("$212D.3", "BG4 Enabled", (ppu.SubScreenLayers & 0x08) != 0),
|
||||
new RegEntry("$212D.4", "OAM Enabled", (ppu.SubScreenLayers & 0x10) != 0),
|
||||
|
||||
new RegEntry("$212E", "Main Screen Windows", null),
|
||||
new RegEntry("$212E.0", "BG1 Mainscreen Window Enabled", ppu.WindowMaskMain[0]),
|
||||
new RegEntry("$212E.1", "BG2 Mainscreen Window Enabled", ppu.WindowMaskMain[1]),
|
||||
new RegEntry("$212E.2", "BG3 Mainscreen Window Enabled", ppu.WindowMaskMain[2]),
|
||||
new RegEntry("$212E.3", "BG4 Mainscreen Window Enabled", ppu.WindowMaskMain[3]),
|
||||
new RegEntry("$212E.4", "OAM Mainscreen Window Enabled", ppu.WindowMaskMain[4]),
|
||||
|
||||
new RegEntry("$212F", "Sub Screen Windows", null),
|
||||
new RegEntry("$212F.0", "BG1 Subscreen Window Enabled", ppu.WindowMaskSub[0]),
|
||||
new RegEntry("$212F.1", "BG2 Subscreen Window Enabled", ppu.WindowMaskSub[1]),
|
||||
new RegEntry("$212F.2", "BG3 Subscreen Window Enabled", ppu.WindowMaskSub[2]),
|
||||
new RegEntry("$212F.3", "BG4 Subscreen Window Enabled", ppu.WindowMaskSub[3]),
|
||||
new RegEntry("$212F.4", "OAM Subscreen Window Enabled", ppu.WindowMaskSub[4]),
|
||||
|
||||
new RegEntry("$2130 - $2131", "Color Math", null),
|
||||
new RegEntry("$2130.0", "Direct Color Mode", ppu.DirectColorMode),
|
||||
new RegEntry("$2130.1", "CM - Add Subscreen", ppu.ColorMathAddSubscreen),
|
||||
new RegEntry("$2130.4-5", "CM - Prevent Mode", ppu.ColorMathPreventMode.ToString()),
|
||||
new RegEntry("$2130.6-7", "CM - Clip Mode", ppu.ColorMathClipMode.ToString()),
|
||||
|
||||
new RegEntry("$2131.0", "CM - BG1 Enabled", (ppu.ColorMathEnabled & 0x01) != 0),
|
||||
new RegEntry("$2131.1", "CM - BG2 Enabled", (ppu.ColorMathEnabled & 0x02) != 0),
|
||||
new RegEntry("$2131.2", "CM - BG3 Enabled", (ppu.ColorMathEnabled & 0x04) != 0),
|
||||
new RegEntry("$2131.3", "CM - BG4 Enabled", (ppu.ColorMathEnabled & 0x08) != 0),
|
||||
new RegEntry("$2131.4", "CM - OAM Enabled", (ppu.ColorMathEnabled & 0x10) != 0),
|
||||
new RegEntry("$2131.5", "CM - Background Enabled", (ppu.ColorMathEnabled & 0x20) != 0),
|
||||
new RegEntry("$2131.6", "CM - Half Mode", ppu.ColorMathHalveResult),
|
||||
new RegEntry("$2131.7", "CM - Substract Mode", ppu.ColorMathSubstractMode),
|
||||
|
||||
new RegEntry("$2132 - $2133", "Misc.", null),
|
||||
new RegEntry("$2132", "Fixed Color - BGR", ppu.FixedColor, Format.X16),
|
||||
|
||||
new RegEntry("$2133.0", "Screen Interlace", ppu.ScreenInterlace),
|
||||
new RegEntry("$2133.1", "OAM Interlace", ppu.ObjInterlace),
|
||||
new RegEntry("$2133.2", "Overscan Mode", ppu.OverscanMode),
|
||||
new RegEntry("$2133.3", "High Resolution Mode", ppu.HiResMode),
|
||||
new RegEntry("$2133.4", "Ext. BG Enabled", ppu.ExtBgEnabled),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private string GetTimerFrequency(double baseFreq, int divider)
|
||||
{
|
||||
return (divider == 0 ? (baseFreq / 256) : (baseFreq / divider)).ToString(".00") + " Hz";
|
||||
}
|
||||
|
||||
private string GetLayerSize(LayerConfig layer)
|
||||
{
|
||||
return (layer.DoubleWidth ? "64" : "32") + "x" + (layer.DoubleHeight ? "64" : "32");
|
||||
}
|
||||
|
||||
private void mnuRefresh_Click(object sender, EventArgs e)
|
||||
{
|
||||
RefreshData();
|
||||
RefreshViewer();
|
||||
}
|
||||
|
||||
private void mnuClose_Click(object sender, EventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void mnuAutoRefresh_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
_refreshManager.AutoRefresh = mnuAutoRefresh.Checked;
|
||||
}
|
||||
|
||||
private void tabMain_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
RefreshViewer();
|
||||
}
|
||||
}
|
||||
}
|
126
UI/Debugger/PpuViewer/frmRegisterViewer.resx
Normal file
126
UI/Debugger/PpuViewer/frmRegisterViewer.resx
Normal file
|
@ -0,0 +1,126 @@
|
|||
<?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>
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="ctrlMesenMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>107, 17</value>
|
||||
</metadata>
|
||||
</root>
|
|
@ -47,6 +47,7 @@ namespace Mesen.GUI.Debugger
|
|||
GetMember(nameof(DebuggerShortcutsConfig.OpenDebugger)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.OpenEventViewer)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.OpenMemoryTools)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.OpenRegisterViewer)),
|
||||
//GetMember(nameof(DebuggerShortcutsConfig.OpenProfiler)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.OpenScriptWindow)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.OpenTraceLogger)),
|
||||
|
|
12
UI/Forms/frmMain.Designer.cs
generated
12
UI/Forms/frmMain.Designer.cs
generated
|
@ -150,6 +150,7 @@
|
|||
this.pnlRenderer = new System.Windows.Forms.Panel();
|
||||
this.ctrlRecentGames = new Mesen.GUI.Controls.ctrlRecentGames();
|
||||
this.mnuBilinearInterpolation = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuRegisterViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuMain.SuspendLayout();
|
||||
this.pnlRenderer.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
|
@ -909,8 +910,9 @@
|
|||
this.mnuDebugger,
|
||||
this.mnuEventViewer,
|
||||
this.mnuMemoryTools,
|
||||
this.mnuTraceLogger,
|
||||
this.mnuRegisterViewer,
|
||||
this.mnuScriptWindow,
|
||||
this.mnuTraceLogger,
|
||||
this.toolStripMenuItem12,
|
||||
this.mnuTilemapViewer,
|
||||
this.mnuTileViewer,
|
||||
|
@ -1095,6 +1097,13 @@
|
|||
this.mnuBilinearInterpolation.Size = new System.Drawing.Size(231, 22);
|
||||
this.mnuBilinearInterpolation.Text = "Use Bilinear Interpolation";
|
||||
//
|
||||
// mnuRegisterViewer
|
||||
//
|
||||
this.mnuRegisterViewer.Image = global::Mesen.GUI.Properties.Resources.RegisterIcon;
|
||||
this.mnuRegisterViewer.Name = "mnuRegisterViewer";
|
||||
this.mnuRegisterViewer.Size = new System.Drawing.Size(155, 22);
|
||||
this.mnuRegisterViewer.Text = "Register Viewer";
|
||||
//
|
||||
// frmMain
|
||||
//
|
||||
this.AllowDrop = true;
|
||||
|
@ -1243,5 +1252,6 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem mnuStopMovie;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem25;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuBilinearInterpolation;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuRegisterViewer;
|
||||
}
|
||||
}
|
|
@ -251,6 +251,7 @@ namespace Mesen.GUI.Forms
|
|||
mnuPaletteViewer.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenPaletteViewer));
|
||||
mnuTraceLogger.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenTraceLogger));
|
||||
mnuScriptWindow.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenScriptWindow));
|
||||
mnuRegisterViewer.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenRegisterViewer));
|
||||
|
||||
mnuNoneFilter.Click += (s, e) => { _shortcuts.SetVideoFilter(VideoFilterType.None); };
|
||||
mnuNtscFilter.Click += (s, e) => { _shortcuts.SetVideoFilter(VideoFilterType.NTSC); };
|
||||
|
@ -299,6 +300,7 @@ namespace Mesen.GUI.Forms
|
|||
mnuPaletteViewer.Click += (s, e) => { DebugWindowManager.OpenDebugWindow(DebugWindow.PaletteViewer); };
|
||||
mnuEventViewer.Click += (s, e) => { DebugWindowManager.OpenDebugWindow(DebugWindow.EventViewer); };
|
||||
mnuScriptWindow.Click += (s, e) => { DebugWindowManager.OpenDebugWindow(DebugWindow.ScriptWindow); };
|
||||
mnuRegisterViewer.Click += (s, e) => { DebugWindowManager.OpenDebugWindow(DebugWindow.RegisterViewer); };
|
||||
|
||||
UpdateDebuggerMenu();
|
||||
}
|
||||
|
@ -316,7 +318,6 @@ namespace Mesen.GUI.Forms
|
|||
mnuGsuDebugger.Enabled = coprocessor == CoprocessorType.GSU;
|
||||
mnuGsuDebugger.Visible = coprocessor == CoprocessorType.GSU;
|
||||
|
||||
|
||||
mnuTraceLogger.Enabled = running;
|
||||
mnuScriptWindow.Enabled = running;
|
||||
mnuMemoryTools.Enabled = running;
|
||||
|
@ -325,6 +326,7 @@ namespace Mesen.GUI.Forms
|
|||
mnuSpriteViewer.Enabled = running;
|
||||
mnuPaletteViewer.Enabled = running;
|
||||
mnuEventViewer.Enabled = running;
|
||||
mnuRegisterViewer.Enabled = running;
|
||||
}
|
||||
|
||||
private void ResizeRecentGames()
|
||||
|
|
|
@ -107,7 +107,7 @@ namespace Mesen.GUI
|
|||
return debugEvents;
|
||||
}
|
||||
|
||||
[DllImport(DllPath)] public static extern DebugEventInfo GetEventViewerEvent(UInt16 scanline, UInt16 cycle, EventViewerDisplayOptions options);
|
||||
[DllImport(DllPath)] public static extern void GetEventViewerEvent(ref DebugEventInfo evtInfo, UInt16 scanline, UInt16 cycle, EventViewerDisplayOptions options);
|
||||
[DllImport(DllPath)] public static extern UInt32 TakeEventSnapshot(EventViewerDisplayOptions options);
|
||||
|
||||
[DllImport(DllPath, EntryPoint = "GetEventViewerOutput")] private static extern void GetEventViewerOutputWrapper([In, Out]byte[] buffer, EventViewerDisplayOptions options);
|
||||
|
@ -243,291 +243,6 @@ namespace Mesen.GUI
|
|||
public SnesMemoryType Type;
|
||||
}
|
||||
|
||||
public enum CpuStopState : byte
|
||||
{
|
||||
Running = 0,
|
||||
Stopped = 1,
|
||||
WaitingForIrq = 2
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ProcFlags : byte
|
||||
{
|
||||
Carry = 0x01,
|
||||
Zero = 0x02,
|
||||
IrqDisable = 0x04,
|
||||
Decimal = 0x08,
|
||||
IndexMode8 = 0x10,
|
||||
MemoryMode8 = 0x20,
|
||||
Overflow = 0x40,
|
||||
Negative = 0x80
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum SpcFlags : byte
|
||||
{
|
||||
Carry = 0x01,
|
||||
Zero = 0x02,
|
||||
IrqEnable = 0x04,
|
||||
HalfCarry = 0x08,
|
||||
Break = 0x10,
|
||||
DirectPage = 0x20,
|
||||
Overflow = 0x40,
|
||||
Negative = 0x80
|
||||
};
|
||||
|
||||
public struct CpuState
|
||||
{
|
||||
public UInt64 CycleCount;
|
||||
|
||||
public UInt16 A;
|
||||
public UInt16 X;
|
||||
public UInt16 Y;
|
||||
|
||||
public UInt16 SP;
|
||||
public UInt16 D;
|
||||
public UInt16 PC;
|
||||
|
||||
public byte K;
|
||||
public byte DBR;
|
||||
public ProcFlags PS;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool EmulationMode;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool NmiFlag;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool PrevNmiFlag;
|
||||
public byte IrqSource;
|
||||
public byte PrevIrqSource;
|
||||
public CpuStopState StopState;
|
||||
};
|
||||
|
||||
public struct PpuState
|
||||
{
|
||||
public UInt16 Cycle;
|
||||
public UInt16 Scanline;
|
||||
public UInt16 HClock;
|
||||
public UInt32 FrameCount;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool OverscanMode;
|
||||
|
||||
public byte BgMode;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool DirectColorMode;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool HiResMode;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ScreenInterlace;
|
||||
|
||||
public Mode7Config Mode7;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public LayerConfig[] Layers;
|
||||
|
||||
public byte OamMode;
|
||||
public UInt16 OamBaseAddress;
|
||||
public UInt16 OamAddressOffset;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool EnableOamPriority;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ObjInterlace;
|
||||
};
|
||||
|
||||
public struct LayerConfig
|
||||
{
|
||||
public UInt16 TilemapAddress;
|
||||
public UInt16 ChrAddress;
|
||||
|
||||
public UInt16 HScroll;
|
||||
public UInt16 VScroll;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool DoubleWidth;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool DoubleHeight;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool LargeTiles;
|
||||
}
|
||||
|
||||
public struct Mode7Config
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public Int16[] Matrix;
|
||||
|
||||
public Int16 HScroll;
|
||||
public Int16 VScroll;
|
||||
public Int16 CenterX;
|
||||
public Int16 CenterY;
|
||||
|
||||
public Byte ValueLatch;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool LargeMap;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool FillWithTile0;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool HorizontalMirroring;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool VerticalMirroring;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ExtBgEnabled;
|
||||
|
||||
public Int16 HScrollLatch;
|
||||
public Int16 VScrollLatch;
|
||||
}
|
||||
|
||||
public struct SpcTimer
|
||||
{
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Enabled;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool TimersEnabled;
|
||||
public byte Output;
|
||||
public byte Stage0;
|
||||
public byte Stage1;
|
||||
public byte PrevStage1;
|
||||
public byte Stage2;
|
||||
public byte Target;
|
||||
}
|
||||
|
||||
public struct SpcState
|
||||
{
|
||||
public UInt64 Cycle;
|
||||
public UInt16 PC;
|
||||
public byte A;
|
||||
public byte X;
|
||||
public byte Y;
|
||||
public byte SP;
|
||||
public SpcFlags PS;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool WriteEnabled;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool RomEnabled;
|
||||
public byte InternalSpeed;
|
||||
public byte ExternalSpeed;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool TimersEnabled;
|
||||
public CpuStopState StopState;
|
||||
|
||||
public byte DspReg;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public byte[] OutputReg;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
public byte[] RamReg;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public byte[] CpuRegs;
|
||||
|
||||
public SpcTimer Timer0;
|
||||
public SpcTimer Timer1;
|
||||
public SpcTimer Timer2;
|
||||
};
|
||||
|
||||
public struct NecDspAccFlags
|
||||
{
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Carry;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Zero;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Overflow0;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Overflow1;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Sign0;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Sign1;
|
||||
}
|
||||
|
||||
public struct NecDspState
|
||||
{
|
||||
public UInt16 A;
|
||||
public NecDspAccFlags FlagsA;
|
||||
public UInt16 B;
|
||||
public NecDspAccFlags FlagsB;
|
||||
public UInt16 TR;
|
||||
public UInt16 TRB;
|
||||
public UInt16 PC;
|
||||
public UInt16 RP;
|
||||
public UInt16 DP;
|
||||
public UInt16 DR;
|
||||
public UInt16 SR;
|
||||
public UInt16 K;
|
||||
public UInt16 L;
|
||||
public UInt16 M;
|
||||
public UInt16 N;
|
||||
public UInt16 SerialOut;
|
||||
public UInt16 SerialIn;
|
||||
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;
|
||||
public CpuState Cpu;
|
||||
public PpuState Ppu;
|
||||
public SpcState Spc;
|
||||
public NecDspState NecDsp;
|
||||
public CpuState Sa1;
|
||||
public GsuState Gsu;
|
||||
}
|
||||
|
||||
public enum MemoryOperationType
|
||||
{
|
||||
Read = 0,
|
||||
|
@ -556,10 +271,13 @@ namespace Mesen.GUI
|
|||
|
||||
public struct DmaChannelConfig
|
||||
{
|
||||
public byte InvertDirection;
|
||||
public byte Decrement;
|
||||
public byte FixedTransfer;
|
||||
public byte HdmaIndirectAddressing;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool DmaActive;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool InvertDirection;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Decrement;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool FixedTransfer;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool HdmaIndirectAddressing;
|
||||
|
||||
public byte TransferMode;
|
||||
|
||||
public UInt16 SrcAddress;
|
||||
|
@ -571,11 +289,10 @@ namespace Mesen.GUI
|
|||
public UInt16 HdmaTableAddress;
|
||||
public byte HdmaBank;
|
||||
public byte HdmaLineCounterAndRepeat;
|
||||
public byte DoTransfer;
|
||||
public byte HdmaFinished;
|
||||
|
||||
public byte InterruptedByHdma;
|
||||
public byte UnusedFlag;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool DoTransfer;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool HdmaFinished;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool UnusedFlag;
|
||||
}
|
||||
|
||||
public struct DebugEventInfo
|
||||
|
|
501
UI/Interop/DebugState.cs
Normal file
501
UI/Interop/DebugState.cs
Normal file
|
@ -0,0 +1,501 @@
|
|||
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 System.Runtime.InteropServices;
|
||||
|
||||
namespace Mesen.GUI
|
||||
{
|
||||
public enum CpuStopState : byte
|
||||
{
|
||||
Running = 0,
|
||||
Stopped = 1,
|
||||
WaitingForIrq = 2
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum ProcFlags : byte
|
||||
{
|
||||
Carry = 0x01,
|
||||
Zero = 0x02,
|
||||
IrqDisable = 0x04,
|
||||
Decimal = 0x08,
|
||||
IndexMode8 = 0x10,
|
||||
MemoryMode8 = 0x20,
|
||||
Overflow = 0x40,
|
||||
Negative = 0x80
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum SpcFlags : byte
|
||||
{
|
||||
Carry = 0x01,
|
||||
Zero = 0x02,
|
||||
IrqEnable = 0x04,
|
||||
HalfCarry = 0x08,
|
||||
Break = 0x10,
|
||||
DirectPage = 0x20,
|
||||
Overflow = 0x40,
|
||||
Negative = 0x80
|
||||
};
|
||||
|
||||
public struct CpuState
|
||||
{
|
||||
public UInt64 CycleCount;
|
||||
|
||||
public UInt16 A;
|
||||
public UInt16 X;
|
||||
public UInt16 Y;
|
||||
|
||||
public UInt16 SP;
|
||||
public UInt16 D;
|
||||
public UInt16 PC;
|
||||
|
||||
public byte K;
|
||||
public byte DBR;
|
||||
public ProcFlags PS;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool EmulationMode;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool NmiFlag;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool PrevNmiFlag;
|
||||
public byte IrqSource;
|
||||
public byte PrevIrqSource;
|
||||
public CpuStopState StopState;
|
||||
};
|
||||
|
||||
public struct PpuState
|
||||
{
|
||||
public UInt16 Cycle;
|
||||
public UInt16 Scanline;
|
||||
public UInt16 HClock;
|
||||
public UInt32 FrameCount;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ForcedVblank;
|
||||
public byte ScreenBrightness;
|
||||
|
||||
public Mode7Config Mode7;
|
||||
|
||||
public byte BgMode;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Mode1Bg3Priority;
|
||||
|
||||
public byte MainScreenLayers;
|
||||
public byte SubScreenLayers;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public LayerConfig[] Layers;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
public WindowConfig[] Window;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
|
||||
public WindowMaskLogic[] MaskLogic;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5, ArraySubType = UnmanagedType.I1)]
|
||||
public bool[] WindowMaskMain;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5, ArraySubType = UnmanagedType.I1)]
|
||||
public bool[] WindowMaskSub;
|
||||
|
||||
public UInt16 VramAddress;
|
||||
public byte VramIncrementValue;
|
||||
public byte VramAddressRemapping;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool VramAddrIncrementOnSecondReg;
|
||||
public UInt16 VramReadBuffer;
|
||||
|
||||
public byte Ppu1OpenBus;
|
||||
public byte Ppu2OpenBus;
|
||||
|
||||
public byte CgramAddress;
|
||||
public byte CgramWriteBuffer;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool CgramAddressLatch;
|
||||
|
||||
public byte MosaicSize;
|
||||
public byte MosaicEnabled;
|
||||
|
||||
public UInt16 OamRamAddress;
|
||||
|
||||
public byte OamMode;
|
||||
public UInt16 OamBaseAddress;
|
||||
public UInt16 OamAddressOffset;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool EnableOamPriority;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ExtBgEnabled;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool HiResMode;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ScreenInterlace;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ObjInterlace;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool OverscanMode;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool DirectColorMode;
|
||||
|
||||
public ColorWindowMode ColorMathClipMode;
|
||||
public ColorWindowMode ColorMathPreventMode;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ColorMathAddSubscreen;
|
||||
public byte ColorMathEnabled;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ColorMathSubstractMode;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ColorMathHalveResult;
|
||||
public UInt16 FixedColor;
|
||||
};
|
||||
|
||||
public struct LayerConfig
|
||||
{
|
||||
public UInt16 TilemapAddress;
|
||||
public UInt16 ChrAddress;
|
||||
|
||||
public UInt16 HScroll;
|
||||
public UInt16 VScroll;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool DoubleWidth;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool DoubleHeight;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool LargeTiles;
|
||||
}
|
||||
|
||||
public struct WindowConfig
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.I1)]
|
||||
public bool[] ActiveLayers;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.I1)]
|
||||
public bool[] InvertedLayers;
|
||||
|
||||
public Byte Left;
|
||||
public Byte Right;
|
||||
}
|
||||
|
||||
public struct Mode7Config
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public Int16[] Matrix;
|
||||
|
||||
public Int16 HScroll;
|
||||
public Int16 VScroll;
|
||||
public Int16 CenterX;
|
||||
public Int16 CenterY;
|
||||
|
||||
public Byte ValueLatch;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool LargeMap;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool FillWithTile0;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool HorizontalMirroring;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool VerticalMirroring;
|
||||
|
||||
public Int16 HScrollLatch;
|
||||
public Int16 VScrollLatch;
|
||||
}
|
||||
|
||||
public enum WindowMaskLogic
|
||||
{
|
||||
Or = 0,
|
||||
And = 1,
|
||||
Xor = 2,
|
||||
Xnor = 3
|
||||
}
|
||||
|
||||
public enum ColorWindowMode
|
||||
{
|
||||
Never = 0,
|
||||
OutsideWindow = 1,
|
||||
InsideWindow = 2,
|
||||
Always = 3
|
||||
}
|
||||
|
||||
public struct SpcTimer
|
||||
{
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Enabled;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool TimersEnabled;
|
||||
public byte Output;
|
||||
public byte Stage0;
|
||||
public byte Stage1;
|
||||
public byte PrevStage1;
|
||||
public byte Stage2;
|
||||
public byte Target;
|
||||
}
|
||||
|
||||
public struct SpcState
|
||||
{
|
||||
public UInt64 Cycle;
|
||||
public UInt16 PC;
|
||||
public byte A;
|
||||
public byte X;
|
||||
public byte Y;
|
||||
public byte SP;
|
||||
public SpcFlags PS;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool WriteEnabled;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool RomEnabled;
|
||||
public byte InternalSpeed;
|
||||
public byte ExternalSpeed;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool TimersEnabled;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool TimersDisabled;
|
||||
public CpuStopState StopState;
|
||||
|
||||
public byte DspReg;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public byte[] OutputReg;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
public byte[] RamReg;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public byte[] CpuRegs;
|
||||
|
||||
public SpcTimer Timer0;
|
||||
public SpcTimer Timer1;
|
||||
public SpcTimer Timer2;
|
||||
};
|
||||
|
||||
public struct NecDspAccFlags
|
||||
{
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Carry;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Zero;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Overflow0;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Overflow1;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Sign0;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Sign1;
|
||||
}
|
||||
|
||||
public struct NecDspState
|
||||
{
|
||||
public UInt16 A;
|
||||
public NecDspAccFlags FlagsA;
|
||||
public UInt16 B;
|
||||
public NecDspAccFlags FlagsB;
|
||||
public UInt16 TR;
|
||||
public UInt16 TRB;
|
||||
public UInt16 PC;
|
||||
public UInt16 RP;
|
||||
public UInt16 DP;
|
||||
public UInt16 DR;
|
||||
public UInt16 SR;
|
||||
public UInt16 K;
|
||||
public UInt16 L;
|
||||
public UInt16 M;
|
||||
public UInt16 N;
|
||||
public UInt16 SerialOut;
|
||||
public UInt16 SerialIn;
|
||||
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 Cx4Dma
|
||||
{
|
||||
public UInt32 Source;
|
||||
public UInt32 Dest;
|
||||
public UInt16 Length;
|
||||
public UInt32 Pos;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Enabled;
|
||||
};
|
||||
|
||||
public struct Cx4Suspend
|
||||
{
|
||||
public UInt32 Duration;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Enabled;
|
||||
};
|
||||
|
||||
public struct Cx4Cache
|
||||
{
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Enabled;
|
||||
public byte Page;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2, ArraySubType = UnmanagedType.I1)]
|
||||
public bool[] Lock;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
public UInt32[] Address;
|
||||
|
||||
public UInt32 Base;
|
||||
public UInt16 ProgramBank;
|
||||
public byte ProgramCounter;
|
||||
public UInt16 Pos;
|
||||
};
|
||||
|
||||
public struct Cx4Bus
|
||||
{
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Enabled;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Reading;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Writing;
|
||||
public byte DelayCycles;
|
||||
public UInt32 Address;
|
||||
};
|
||||
|
||||
public struct Cx4State
|
||||
{
|
||||
public UInt64 CycleCount;
|
||||
public UInt16 PB;
|
||||
public byte PC;
|
||||
public UInt32 A;
|
||||
public UInt16 P;
|
||||
|
||||
public byte SP;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public UInt32[] Stack;
|
||||
|
||||
public UInt64 Mult;
|
||||
|
||||
public UInt32 RomBuffer;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
public byte[] RamBuffer;
|
||||
|
||||
public UInt32 MemoryDataReg;
|
||||
public UInt32 MemoryAddressReg;
|
||||
public UInt32 DataPointerReg;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
||||
public UInt32[] Regs;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Negative;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Zero;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Carry;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Overflow;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool IrqFlag;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Stopped;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool Locked;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool IrqDisabled;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool SingleRom;
|
||||
|
||||
public byte RomAccessDelay;
|
||||
public byte RamAccessDelay;
|
||||
|
||||
public Cx4Bus Bus;
|
||||
public Cx4Dma Dma;
|
||||
public Cx4Cache Cache;
|
||||
public Cx4Suspend Suspend;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
|
||||
public byte[] Vectors;
|
||||
};
|
||||
|
||||
public struct AluState
|
||||
{
|
||||
public byte MultOperand1;
|
||||
public byte MultOperand2;
|
||||
public UInt16 MultOrRemainderResult;
|
||||
|
||||
public UInt16 Dividend;
|
||||
public byte Divisor;
|
||||
public UInt16 DivResult;
|
||||
};
|
||||
|
||||
public struct InternalRegisterState
|
||||
{
|
||||
[MarshalAs(UnmanagedType.I1)] public bool EnableAutoJoypadRead;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool EnableFastRom;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool EnableNmi;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool EnableHorizontalIrq;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool EnableVerticalIrq;
|
||||
public UInt16 HorizontalTimer;
|
||||
public UInt16 VerticalTimer;
|
||||
|
||||
public byte IoPortOutput;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
public UInt16[] ControllerData;
|
||||
};
|
||||
|
||||
public struct DebugState
|
||||
{
|
||||
public UInt64 MasterClock;
|
||||
public CpuState Cpu;
|
||||
public PpuState Ppu;
|
||||
public SpcState Spc;
|
||||
public NecDspState NecDsp;
|
||||
public CpuState Sa1;
|
||||
public GsuState Gsu;
|
||||
public Cx4State Cx4;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
public DmaChannelConfig[] DmaChannels;
|
||||
|
||||
public InternalRegisterState InternalRegs;
|
||||
public AluState Alu;
|
||||
}
|
||||
}
|
20
UI/UI.csproj
20
UI/UI.csproj
|
@ -261,6 +261,7 @@
|
|||
<Compile Include="Debugger\Config\DebuggerInfo.cs" />
|
||||
<Compile Include="Debugger\Config\ScriptWindowConfig.cs" />
|
||||
<Compile Include="Debugger\Config\SpriteViewerConfig.cs" />
|
||||
<Compile Include="Debugger\Config\RegisterViewerConfig.cs" />
|
||||
<Compile Include="Debugger\Config\TileViewerConfig.cs" />
|
||||
<Compile Include="Debugger\Config\TilemapViewerConfig.cs" />
|
||||
<Compile Include="Debugger\Controls\ctrlPanel.cs">
|
||||
|
@ -326,6 +327,12 @@
|
|||
<Compile Include="Debugger\PpuViewer\ctrlImageViewer.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\PpuViewer\ctrlPropertyList.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\PpuViewer\ctrlPropertyList.Designer.cs">
|
||||
<DependentUpon>ctrlPropertyList.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\PpuViewer\ctrlSpriteList.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
|
@ -338,6 +345,12 @@
|
|||
<Compile Include="Debugger\PpuViewer\frmSpriteViewer.Designer.cs">
|
||||
<DependentUpon>frmSpriteViewer.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\PpuViewer\frmRegisterViewer.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\PpuViewer\frmRegisterViewer.Designer.cs">
|
||||
<DependentUpon>frmRegisterViewer.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\PpuViewer\SpriteInfo.cs" />
|
||||
<Compile Include="Debugger\PpuViewer\WindowRefreshManager.cs" />
|
||||
<Compile Include="Debugger\Scripts\FastColoredTextBox\AutocompleteItem.cs" />
|
||||
|
@ -799,6 +812,7 @@
|
|||
<Compile Include="Forms\Tools\frmRecordAvi.Designer.cs">
|
||||
<DependentUpon>frmRecordAvi.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Interop\DebugState.cs" />
|
||||
<Compile Include="Interop\RecordApi.cs" />
|
||||
<Compile Include="Updates\frmDownloadProgress.cs">
|
||||
<SubType>Form</SubType>
|
||||
|
@ -960,6 +974,9 @@
|
|||
<EmbeddedResource Include="Debugger\PpuViewer\ctrlImagePanel.resx">
|
||||
<DependentUpon>ctrlImagePanel.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\PpuViewer\ctrlPropertyList.resx">
|
||||
<DependentUpon>ctrlPropertyList.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\PpuViewer\ctrlScanlineCycleSelect.resx">
|
||||
<DependentUpon>ctrlScanlineCycleSelect.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
@ -972,6 +989,9 @@
|
|||
<EmbeddedResource Include="Debugger\PpuViewer\frmSpriteViewer.resx">
|
||||
<DependentUpon>frmSpriteViewer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\PpuViewer\frmRegisterViewer.resx">
|
||||
<DependentUpon>frmRegisterViewer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\PpuViewer\frmTileViewer.resx">
|
||||
<DependentUpon>frmTileViewer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
|
Loading…
Add table
Reference in a new issue