diff --git a/Core/DebugTypes.h b/Core/DebugTypes.h index f2bae5a..9ceaf6a 100644 --- a/Core/DebugTypes.h +++ b/Core/DebugTypes.h @@ -6,6 +6,7 @@ #include "NecDspTypes.h" #include "GsuTypes.h" #include "Cx4Types.h" +#include "Sa1Types.h" #include "InternalRegisterTypes.h" #include "DmaControllerTypes.h" @@ -17,7 +18,7 @@ struct DebugState SpcState Spc; DspState Dsp; NecDspState NecDsp; - CpuState Sa1; + DebugSa1State Sa1; GsuState Gsu; Cx4State Cx4; diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp index 75f7a4d..6fa7ecd 100644 --- a/Core/Debugger.cpp +++ b/Core/Debugger.cpp @@ -424,7 +424,7 @@ void Debugger::GetState(DebugState &state, bool partialPpuState) state.NecDsp = _cart->GetDsp()->GetState(); } if(_cart->GetSa1()) { - state.Sa1 = _cart->GetSa1()->GetCpuState(); + state.Sa1 = _cart->GetSa1()->GetState(); } if(_cart->GetGsu()) { state.Gsu = _cart->GetGsu()->GetState(); diff --git a/Core/Sa1.cpp b/Core/Sa1.cpp index ed8af09..6212e7b 100644 --- a/Core/Sa1.cpp +++ b/Core/Sa1.cpp @@ -778,6 +778,14 @@ uint32_t Sa1::DebugGetInternalRamSize() return Sa1::InternalRamSize; } +DebugSa1State Sa1::GetState() +{ + return { + _cpu->GetState(), + _state + }; +} + CpuState Sa1::GetCpuState() { return _cpu->GetState(); diff --git a/Core/Sa1.h b/Core/Sa1.h index 766a6c8..bc6fe8f 100644 --- a/Core/Sa1.h +++ b/Core/Sa1.h @@ -88,7 +88,9 @@ public: uint8_t* DebugGetInternalRam(); uint32_t DebugGetInternalRamSize(); + DebugSa1State GetState(); CpuState GetCpuState(); + uint16_t ReadVector(uint16_t vector); MemoryMappings* GetMemoryMappings(); }; diff --git a/Core/Sa1Types.h b/Core/Sa1Types.h index 45469df..b9106f1 100644 --- a/Core/Sa1Types.h +++ b/Core/Sa1Types.h @@ -1,5 +1,6 @@ #pragma once #include "stdafx.h" +#include "CpuTypes.h" enum class Sa1MathOp { @@ -106,3 +107,9 @@ struct Sa1State uint8_t Banks[4]; }; + +struct DebugSa1State +{ + CpuState Cpu; + Sa1State Sa1; +}; \ No newline at end of file diff --git a/Core/TraceLogger.cpp b/Core/TraceLogger.cpp index 32b7a5a..c6fbf75 100644 --- a/Core/TraceLogger.cpp +++ b/Core/TraceLogger.cpp @@ -492,7 +492,7 @@ void TraceLogger::GetTraceRow(string &output, CpuType cpuType, DisassemblyInfo & case CpuType::Cpu: GetTraceRow(output, state.Cpu, state.Ppu, disassemblyInfo, SnesMemoryType::CpuMemory, cpuType); break; case CpuType::Spc: GetTraceRow(output, state.Spc, state.Ppu, disassemblyInfo); break; case CpuType::NecDsp: GetTraceRow(output, state.NecDsp, state.Ppu, disassemblyInfo); break; - case CpuType::Sa1: GetTraceRow(output, state.Sa1, state.Ppu, disassemblyInfo, SnesMemoryType::Sa1Memory, cpuType); break; + case CpuType::Sa1: GetTraceRow(output, state.Sa1.Cpu, state.Ppu, disassemblyInfo, SnesMemoryType::Sa1Memory, cpuType); break; case CpuType::Gsu: GetTraceRow(output, state.Gsu, state.Ppu, disassemblyInfo); break; case CpuType::Cx4: GetTraceRow(output, state.Cx4, state.Ppu, disassemblyInfo); break; } @@ -588,7 +588,7 @@ const char* TraceLogger::GetExecutionTrace(uint32_t lineCount) case CpuType::Cpu: _executionTrace += "\x2\x1" + HexUtilities::ToHex24((state.Cpu.K << 16) | state.Cpu.PC) + "\x1"; break; case CpuType::Spc: _executionTrace += "\x3\x1" + HexUtilities::ToHex(state.Spc.PC) + "\x1"; break; case CpuType::NecDsp: _executionTrace += "\x4\x1" + HexUtilities::ToHex(state.NecDsp.PC) + "\x1"; break; - case CpuType::Sa1: _executionTrace += "\x4\x1" + HexUtilities::ToHex24((state.Sa1.K << 16) | state.Sa1.PC) + "\x1"; break; + case CpuType::Sa1: _executionTrace += "\x4\x1" + HexUtilities::ToHex24((state.Sa1.Cpu.K << 16) | state.Sa1.Cpu.PC) + "\x1"; break; case CpuType::Gsu: _executionTrace += "\x4\x1" + HexUtilities::ToHex24((state.Gsu.ProgramBank << 16) | state.Gsu.R[15]) + "\x1"; break; case CpuType::Cx4: _executionTrace += "\x4\x1" + HexUtilities::ToHex24((state.Cx4.Cache.Address[state.Cx4.Cache.Page] + (state.Cx4.PC * 2)) & 0xFFFFFF) + "\x1"; break; } diff --git a/UI/Debugger/Code/Sa1DisassemblyManager.cs b/UI/Debugger/Code/Sa1DisassemblyManager.cs index 2b41c61..07bbe37 100644 --- a/UI/Debugger/Code/Sa1DisassemblyManager.cs +++ b/UI/Debugger/Code/Sa1DisassemblyManager.cs @@ -21,7 +21,7 @@ namespace Mesen.GUI.Debugger.Code protected override int GetFullAddress(int address, int length) { - CpuState state = DebugApi.GetState().Sa1; + CpuState state = DebugApi.GetState().Sa1.Cpu; if(length == 4) { //Append current DB register to 2-byte addresses return (state.DBR << 16) | address; diff --git a/UI/Debugger/Controls/ctrlCallstack.cs b/UI/Debugger/Controls/ctrlCallstack.cs index 8ee9f28..734e2e5 100644 --- a/UI/Debugger/Controls/ctrlCallstack.cs +++ b/UI/Debugger/Controls/ctrlCallstack.cs @@ -42,7 +42,7 @@ namespace Mesen.GUI.Debugger.Controls switch(_cpuType) { case CpuType.Cpu: _programCounter = (uint)(state.Cpu.K << 16) | state.Cpu.PC; break; - case CpuType.Sa1: _programCounter = (uint)(state.Sa1.K << 16) | state.Sa1.PC; break; + case CpuType.Sa1: _programCounter = (uint)(state.Sa1.Cpu.K << 16) | state.Sa1.Cpu.PC; break; case CpuType.Spc: _programCounter = (uint)state.Spc.PC; break; default: throw new Exception("Invalid cpu type"); } diff --git a/UI/Debugger/PpuViewer/frmRegisterViewer.cs b/UI/Debugger/PpuViewer/frmRegisterViewer.cs index 4e63c21..abc8b15 100644 --- a/UI/Debugger/PpuViewer/frmRegisterViewer.cs +++ b/UI/Debugger/PpuViewer/frmRegisterViewer.cs @@ -26,6 +26,10 @@ namespace Mesen.GUI.Debugger private byte _reg4211; private byte _reg4212; + private CoprocessorType _coprocessorType; + private TabPage tpgCoprocessor; + private ctrlPropertyList ctrlCoprocessor; + public ctrlScanlineCycleSelect ScanlineCycleSelect { get { return this.ctrlScanlineCycleSelect; } } public frmRegisterViewer() @@ -55,6 +59,8 @@ namespace Mesen.GUI.Debugger _refreshManager.AutoRefresh = config.AutoRefresh; _refreshManager.AutoRefreshSpeed = RefreshSpeed.High; + UpdateTabs(); + RefreshData(); RefreshViewer(); @@ -82,9 +88,30 @@ namespace Mesen.GUI.Debugger base.OnFormClosed(e); } + private void UpdateTabs() + { + if(tpgCoprocessor != null) { + tabMain.TabPages.Remove(tpgCoprocessor); + } + + _coprocessorType = EmuApi.GetRomInfo().CoprocessorType; + if(_coprocessorType == CoprocessorType.SA1) { + tpgCoprocessor = new TabPage(); + tpgCoprocessor.Text = "SA-1"; + ctrlCoprocessor = new ctrlPropertyList(); + ctrlCoprocessor.Dock = DockStyle.Fill; + tpgCoprocessor.Controls.Add(ctrlCoprocessor); + tabMain.TabPages.Add(tpgCoprocessor); + } + } + private void OnNotificationReceived(NotificationEventArgs e) { switch(e.NotificationType) { + case ConsoleNotificationType.GameLoaded: + this.BeginInvoke((Action)(() => UpdateTabs())); + break; + case ConsoleNotificationType.CodeBreak: RefreshData(); this.BeginInvoke((Action)(() => { @@ -149,7 +176,7 @@ namespace Mesen.GUI.Debugger }); } else if(tabMain.SelectedTab == tpgDma) { List entries = new List(); - + //TODO /*for(int i = 0; i < 8; i++) { entries.Add(new RegEntry("$420C." + i.ToString(), "HDMA Channel " + i.ToString() + " Enabled", _state.DmaChannels[i].DmaActive)); @@ -205,7 +232,7 @@ namespace Mesen.GUI.Debugger new RegEntry("$F8 - $F9", "RAM Registers", null), 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)), @@ -450,6 +477,134 @@ namespace Mesen.GUI.Debugger new RegEntry("$2133.3", "High Resolution Mode", ppu.HiResMode), new RegEntry("$2133.4", "Ext. BG Enabled", ppu.ExtBgEnabled), }); + } else if(tabMain.SelectedTab == tpgCoprocessor) { + if(_coprocessorType == CoprocessorType.SA1) { + Sa1State sa1 = _state.Sa1.Sa1; + + List entries = new List() { + new RegEntry("$2200", "SA-1 CPU Control", null), + new RegEntry("$2200.0-3", "Message", sa1.Sa1MessageReceived, Format.X8), + new RegEntry("$2200.4", "NMI Requested", sa1.Sa1NmiRequested), + new RegEntry("$2200.5", "Reset", sa1.Sa1Reset), + new RegEntry("$2200.6", "Wait", sa1.Sa1Wait), + new RegEntry("$2200.7", "IRQ Requested", sa1.Sa1IrqRequested), + + new RegEntry("$2201", "S-CPU Interrupt Enable", null), + new RegEntry("$2201.5", "Character Conversion IRQ Enable", sa1.CharConvIrqEnabled), + new RegEntry("$2201.7", "IRQ Enabled", sa1.CpuIrqEnabled), + + new RegEntry("$2202", "S-CPU Interrupt Clear", null), + new RegEntry("$2202.5", "Character IRQ Flag", sa1.CharConvIrqFlag), + new RegEntry("$2202.7", "IRQ Flag", sa1.CpuIrqRequested), + + new RegEntry("$2203/4", "SA-1 Reset Vector", sa1.Sa1ResetVector, Format.X16), + new RegEntry("$2205/6", "SA-1 NMI Vector", sa1.Sa1ResetVector, Format.X16), + new RegEntry("$2207/8", "SA-1 IRQ Vector", sa1.Sa1ResetVector, Format.X16), + + new RegEntry("$2209", "S-CPU Control", null), + new RegEntry("$2209.0-3", "Message", sa1.CpuMessageReceived, Format.X8), + new RegEntry("$2209.4", "Use NMI Vector", sa1.UseCpuNmiVector), + new RegEntry("$2209.6", "Use IRQ Vector", sa1.UseCpuIrqVector), + new RegEntry("$2209.7", "IRQ Requested", sa1.CpuIrqRequested), + + new RegEntry("$220A", "SA-1 CPU Interrupt Enable", null), + new RegEntry("$220A.4", "SA-1 NMI Enabled", sa1.Sa1NmiEnabled), + new RegEntry("$220A.5", "DMA IRQ Enabled", sa1.DmaIrqEnabled), + new RegEntry("$220A.6", "Timer IRQ Enabled", sa1.TimerIrqEnabled), + new RegEntry("$220A.7", "SA-1 IRQ Enabled", sa1.Sa1IrqEnabled), + + new RegEntry("$220B", "S-CPU Interrupt Clear", null), + new RegEntry("$220B.4", "SA-1 NMI Requested", sa1.Sa1NmiRequested), + new RegEntry("$220B.5", "DMA IRQ Flag", sa1.DmaIrqFlag), + new RegEntry("$220B.7", "SA-1 IRQ Requested", sa1.Sa1IrqRequested), + + new RegEntry("$220C/D", "S-CPU NMI Vector", sa1.CpuNmiVector, Format.X16), + new RegEntry("$220E/F", "S-CPU IRQ Vector", sa1.CpuIrqVector, Format.X16), + + new RegEntry("$2210", "H/V Timer Control", null), + new RegEntry("$2210.0", "Horizontal Timer Enabled", sa1.HorizontalTimerEnabled), + new RegEntry("$2210.1", "Vertical Timer Enabled", sa1.VerticalTimerEnabled), + new RegEntry("$2210.7", "Linear Timer", sa1.UseLinearTimer), + + new RegEntry("$2212/3", "H-Timer", sa1.HTimer, Format.X16), + new RegEntry("$2214/5", "V-Timer", sa1.VTimer, Format.X16), + + new RegEntry("", "ROM/BWRAM/IRAM Mappings", null), + new RegEntry("$2220", "MMC Bank C", sa1.Banks[0], Format.X8), + new RegEntry("$2221", "MMC Bank D", sa1.Banks[1], Format.X8), + new RegEntry("$2222", "MMC Bank E", sa1.Banks[2], Format.X8), + new RegEntry("$2223", "MMC Bank F", sa1.Banks[3], Format.X8), + + new RegEntry("$2224", "S-CPU BW-RAM Bank", sa1.CpuBwBank, Format.X8), + new RegEntry("$2225.0-6", "SA-1 CPU BW-RAM Bank", sa1.Sa1BwBank, Format.X8), + new RegEntry("$2225.7", "SA-1 CPU BW-RAM Mode", sa1.Sa1BwMode, Format.X8), + new RegEntry("$2226.7", "S-CPU BW-RAM Write Enabled", sa1.CpuBwWriteEnabled), + new RegEntry("$2227.7", "SA-1 BW-RAM Write Enabled", sa1.Sa1BwWriteEnabled), + new RegEntry("$2228.0-3", "S-CPU BW-RAM Write Protected Area", sa1.BwWriteProtectedArea, Format.X8), + new RegEntry("$2229", "S-CPU I-RAM Write Protection", sa1.CpuIRamWriteProtect, Format.X8), + new RegEntry("$222A", "SA-1 CPU I-RAM Write Protection", sa1.Sa1IRamWriteProtect, Format.X8), + + new RegEntry("$2230", "DMA Control", null), + new RegEntry("$2230.0-1", "DMA Source Device", sa1.DmaSrcDevice.ToString()), + new RegEntry("$2230.2-3", "DMA Destination Device", sa1.DmaDestDevice.ToString()), + new RegEntry("$2230.4", "Automatic DMA Character Conversion", sa1.DmaCharConvAuto), + new RegEntry("$2230.5", "DMA Character Conversion", sa1.DmaCharConv), + new RegEntry("$2230.6", "DMA Priority", sa1.DmaPriority), + new RegEntry("$2230.7", "DMA Enabled", sa1.DmaEnabled), + + new RegEntry("$2231.0-1", "Character Format (BPP)", sa1.CharConvBpp, Format.D), + new RegEntry("$2231.2-5", "Character Conversion Width", sa1.CharConvWidth, Format.X8), + new RegEntry("$2231.7", "Character DMA Active", sa1.CharConvDmaActive), + + new RegEntry("$2232/3/4", "DMA Source Address", sa1.DmaSrcAddr, Format.X24), + new RegEntry("$2235/6/7", "DMA Destination Address", sa1.DmaDestAddr, Format.X24), + + new RegEntry("$2238/9", "DMA Size", sa1.DmaSize, Format.X16), + new RegEntry("$223F.7", "BW-RAM 2 bpp mode", sa1.BwRam2BppMode) + }; + + entries.Add(new RegEntry("", "Bitmap Register File", null)); + for(int i = 0; i < 8; i++) { + entries.Add(new RegEntry("$224" + i, "BRF #" + i, sa1.BitmapRegister1[i])); + } + for(int i = 0; i < 8; i++) { + entries.Add(new RegEntry("$224" + (8 + i).ToString("X"), "BRF #" + (i+8), sa1.BitmapRegister2[i])); + } + + entries.AddRange(new List() { + new RegEntry("", "Math Registers", null), + new RegEntry("$2250.0-1", "Math Operation", sa1.MathOp.ToString()), + new RegEntry("$2251/2", "Multiplicand/Dividend", sa1.MultiplicandDividend, Format.X16), + new RegEntry("$2253/4", "Multiplier/Divisor", sa1.MultiplierDivisor, Format.X16), + + new RegEntry("", "Variable Length Registers", null), + new RegEntry("$2258", "Variable Length Bit Processing", null), + new RegEntry("$2258.0-3", "Variable Length Bit Count", sa1.VarLenBitCount, Format.X8), + new RegEntry("$2258.7", "Variable Length Auto-Increment", sa1.VarLenAutoInc), + new RegEntry("$2259/A/B", "Variable Length Address", sa1.VarLenAddress, Format.X24), + + new RegEntry("$2300", "S-CPU Status Flags", null), + new RegEntry("$2300.0-3", "Message Received", sa1.CpuMessageReceived, Format.X8), + new RegEntry("$2300.4", "Use NMI Vector", sa1.UseCpuNmiVector), + new RegEntry("$2300.5", "Character Conversion IRQ Flag", sa1.CharConvIrqFlag), + new RegEntry("$2300.6", "Use IRQ Vector", sa1.UseCpuIrqVector), + new RegEntry("$2300.7", "IRQ Requested", sa1.CpuIrqRequested), + + new RegEntry("$2301", "SA-1 Status Flags", null), + new RegEntry("$2301.0-3", "Message Received", sa1.Sa1MessageReceived, Format.X8), + new RegEntry("$2301.4", "NMI Requested", sa1.Sa1NmiRequested), + new RegEntry("$2301.5", "DMA IRQ Flag", sa1.DmaIrqFlag), + new RegEntry("$2301.7", "IRQ Requested", sa1.Sa1IrqRequested), + + new RegEntry("$2302/3", "SA-1 H-Counter", 0, Format.X16), + new RegEntry("$2304/5", "SA-1 V-Counter", 0, Format.X16), + + new RegEntry("$2306/7/8/9/A", "Math Result", sa1.MathOpResult), + new RegEntry("$230B.7", "Math Overflow", sa1.MathOverflow) + }); + + ctrlCoprocessor.UpdateState(entries); + } } } diff --git a/UI/Debugger/frmDebugger.cs b/UI/Debugger/frmDebugger.cs index ee7c6e8..4429efe 100644 --- a/UI/Debugger/frmDebugger.cs +++ b/UI/Debugger/frmDebugger.cs @@ -470,7 +470,7 @@ namespace Mesen.GUI.Debugger case CpuType.Cpu: ctrlCpuStatus.UpdateStatus(state.Cpu); break; case CpuType.Spc: ctrlSpcStatus.UpdateStatus(state.Spc); break; case CpuType.NecDsp: ctrlNecDspStatus.UpdateStatus(state.NecDsp); break; - case CpuType.Sa1: ctrlCpuStatus.UpdateStatus(state.Sa1); break; + case CpuType.Sa1: ctrlCpuStatus.UpdateStatus(state.Sa1.Cpu); break; case CpuType.Gsu: ctrlGsuStatus.UpdateStatus(state.Gsu); break; case CpuType.Cx4: ctrlCx4Status.UpdateStatus(state.Cx4); break; default: throw new Exception("Unsupported CPU type"); @@ -572,7 +572,7 @@ namespace Mesen.GUI.Debugger case CpuType.Cpu: activeAddress = (int)((state.Cpu.K << 16) | state.Cpu.PC); break; case CpuType.Spc: activeAddress = (int)state.Spc.PC; break; case CpuType.NecDsp: activeAddress = (int)(state.NecDsp.PC * 3); break; - case CpuType.Sa1: activeAddress = (int)((state.Sa1.K << 16) | state.Sa1.PC); break; + case CpuType.Sa1: activeAddress = (int)((state.Sa1.Cpu.K << 16) | state.Sa1.Cpu.PC); break; case CpuType.Gsu: activeAddress = (int)((state.Gsu.ProgramBank << 16) | state.Gsu.R[15]); break; case CpuType.Cx4: activeAddress = (int)((state.Cx4.Cache.Address[state.Cx4.Cache.Page] + (state.Cx4.PC * 2)) & 0xFFFFFF); break; default: throw new Exception("Unsupported cpu type"); diff --git a/UI/Interop/DebugState.cs b/UI/Interop/DebugState.cs index cf397b8..d6a544d 100644 --- a/UI/Interop/DebugState.cs +++ b/UI/Interop/DebugState.cs @@ -42,7 +42,7 @@ namespace Mesen.GUI DirectPage = 0x20, Overflow = 0x40, Negative = 0x80 - }; + } public struct CpuState { @@ -71,7 +71,7 @@ namespace Mesen.GUI public byte IrqSource; public byte PrevIrqSource; public CpuStopState StopState; - }; + } public struct PpuState { @@ -144,7 +144,7 @@ namespace Mesen.GUI [MarshalAs(UnmanagedType.I1)] public bool ColorMathSubstractMode; [MarshalAs(UnmanagedType.I1)] public bool ColorMathHalveResult; public UInt16 FixedColor; - }; + } public struct LayerConfig { @@ -253,7 +253,7 @@ namespace Mesen.GUI public SpcTimer Timer0; public SpcTimer Timer1; public SpcTimer Timer2; - }; + } public struct DspState { @@ -307,7 +307,7 @@ namespace Mesen.GUI [MarshalAs(UnmanagedType.I1)] public bool ImmHigh; [MarshalAs(UnmanagedType.I1)] public bool Prefix; [MarshalAs(UnmanagedType.I1)] public bool Irq; - }; + } public struct GsuPixelCache { @@ -316,7 +316,7 @@ namespace Mesen.GUI [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] Pixels; public byte ValidBits; - }; + } public struct GsuState { @@ -370,7 +370,7 @@ namespace Mesen.GUI public GsuPixelCache PrimaryCache; public GsuPixelCache SecondaryCache; - }; + } public struct Cx4Dma { @@ -379,13 +379,13 @@ namespace Mesen.GUI 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 { @@ -402,7 +402,7 @@ namespace Mesen.GUI public UInt16 ProgramBank; public byte ProgramCounter; public UInt16 Pos; - }; + } public struct Cx4Bus { @@ -411,7 +411,7 @@ namespace Mesen.GUI [MarshalAs(UnmanagedType.I1)] public bool Writing; public byte DelayCycles; public UInt32 Address; - }; + } public struct Cx4State { @@ -462,7 +462,122 @@ namespace Mesen.GUI [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] public byte[] Vectors; - }; + } + + public struct Sa1State + { + public UInt16 Sa1ResetVector; + public UInt16 Sa1IrqVector; + public UInt16 Sa1NmiVector; + + [MarshalAs(UnmanagedType.I1)] public bool Sa1IrqRequested; + [MarshalAs(UnmanagedType.I1)] public bool Sa1IrqEnabled; + + [MarshalAs(UnmanagedType.I1)] public bool Sa1NmiRequested; + [MarshalAs(UnmanagedType.I1)] public bool Sa1NmiEnabled; + [MarshalAs(UnmanagedType.I1)] public bool Sa1Wait; + [MarshalAs(UnmanagedType.I1)] public bool Sa1Reset; + + [MarshalAs(UnmanagedType.I1)] public bool DmaIrqEnabled; + [MarshalAs(UnmanagedType.I1)] public bool TimerIrqEnabled; + + public byte Sa1MessageReceived; + public byte CpuMessageReceived; + + public UInt16 CpuIrqVector; + public UInt16 CpuNmiVector; + [MarshalAs(UnmanagedType.I1)] public bool UseCpuIrqVector; + [MarshalAs(UnmanagedType.I1)] public bool UseCpuNmiVector; + + [MarshalAs(UnmanagedType.I1)] public bool CpuIrqRequested; + [MarshalAs(UnmanagedType.I1)] public bool CpuIrqEnabled; + + [MarshalAs(UnmanagedType.I1)] public bool CharConvIrqFlag; + [MarshalAs(UnmanagedType.I1)] public bool CharConvIrqEnabled; + [MarshalAs(UnmanagedType.I1)] public bool CharConvDmaActive; + public byte CharConvBpp; + public byte CharConvFormat; + public byte CharConvWidth; + public byte CharConvCounter; + + public byte CpuBwBank; + [MarshalAs(UnmanagedType.I1)] public bool CpuBwWriteEnabled; + + public byte Sa1BwBank; + public byte Sa1BwMode; + [MarshalAs(UnmanagedType.I1)] public bool Sa1BwWriteEnabled; + public byte BwWriteProtectedArea; + [MarshalAs(UnmanagedType.I1)] public bool BwRam2BppMode; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] BitmapRegister1; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public byte[] BitmapRegister2; + + public byte CpuIRamWriteProtect; + public byte Sa1IRamWriteProtect; + + public UInt32 DmaSrcAddr; + public UInt32 DmaDestAddr; + public UInt16 DmaSize; + [MarshalAs(UnmanagedType.I1)] public bool DmaEnabled; + [MarshalAs(UnmanagedType.I1)] public bool DmaPriority; + [MarshalAs(UnmanagedType.I1)] public bool DmaCharConv; + [MarshalAs(UnmanagedType.I1)] public bool DmaCharConvAuto; + public Sa1DmaDestDevice DmaDestDevice; + public Sa1DmaSrcDevice DmaSrcDevice; + [MarshalAs(UnmanagedType.I1)] public bool DmaRunning; + [MarshalAs(UnmanagedType.I1)] public bool DmaIrqFlag; + + [MarshalAs(UnmanagedType.I1)] public bool HorizontalTimerEnabled; + [MarshalAs(UnmanagedType.I1)] public bool VerticalTimerEnabled; + [MarshalAs(UnmanagedType.I1)] public bool UseLinearTimer; + + public UInt16 HTimer; + public UInt16 VTimer; + public UInt32 LinearTimerValue; + + public Sa1MathOp MathOp; + public UInt16 MultiplicandDividend; + public UInt16 MultiplierDivisor; + public UInt64 MathOpResult; + public byte MathOverflow; + + [MarshalAs(UnmanagedType.I1)] public bool VarLenAutoInc; + public byte VarLenBitCount; + public UInt32 VarLenAddress; + public byte VarLenCurrentBit; + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] + public byte[] Banks; + } + + public struct DebugSa1State + { + public CpuState Cpu; + public Sa1State Sa1; + } + + public enum Sa1MathOp + { + Mul = 0, + Div = 1, + Sum = 2 + } + + public enum Sa1DmaSrcDevice + { + PrgRom = 0, + BwRam = 1, + InternalRam = 2, + Reserved = 3 + } + + public enum Sa1DmaDestDevice + { + InternalRam = 0, + BwRam = 1 + } public struct AluState { @@ -473,7 +588,7 @@ namespace Mesen.GUI public UInt16 Dividend; public byte Divisor; public UInt16 DivResult; - }; + } public struct InternalRegisterState { @@ -490,7 +605,7 @@ namespace Mesen.GUI [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public UInt16[] ControllerData; - }; + } public struct DebugState { @@ -500,7 +615,7 @@ namespace Mesen.GUI public SpcState Spc; public DspState Dsp; public NecDspState NecDsp; - public CpuState Sa1; + public DebugSa1State Sa1; public GsuState Gsu; public Cx4State Cx4;