diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp index 380f1e1..c3f70a1 100644 --- a/Core/Debugger.cpp +++ b/Core/Debugger.cpp @@ -48,7 +48,7 @@ Debugger::Debugger(shared_ptr console) _memoryAccessCounter.reset(new MemoryAccessCounter(this, _spc.get(), _memoryManager.get())); _breakpointManager.reset(new BreakpointManager(this)); _ppuTools.reset(new PpuTools(_console.get(), _ppu.get())); - _eventManager.reset(new EventManager(this, _cpu.get(), _ppu.get())); + _eventManager.reset(new EventManager(this, _cpu.get(), _ppu.get(), _console->GetDmaController().get())); _callstackManager.reset(new CallstackManager(this)); _spcCallstackManager.reset(new CallstackManager(this)); diff --git a/Core/DmaController.cpp b/Core/DmaController.cpp index 84a065e..167a8b4 100644 --- a/Core/DmaController.cpp +++ b/Core/DmaController.cpp @@ -218,6 +218,7 @@ void DmaController::ProcessHdmaChannels(bool applyOverhead) //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; RunHdmaTransfer(ch); } } @@ -330,6 +331,7 @@ void DmaController::ProcessPendingTransfers() if(_requestedDmaChannels & (1 << i)) { //"Then perform the DMA: 8 master cycles overhead and 8 master cycles per byte per channel" _memoryManager->IncrementMasterClockValue<8>(); + _activeChannel = i; RunDma(_channel[i]); } } @@ -544,6 +546,16 @@ uint8_t DmaController::Read(uint16_t addr) return _memoryManager->GetOpenBus(); } +uint8_t DmaController::GetActiveChannel() +{ + return _activeChannel; +} + +DmaChannelConfig DmaController::GetChannelConfig(uint8_t channel) +{ + return _channel[channel]; +} + void DmaController::Serialize(Serializer &s) { s.Stream(_hdmaPending, _hdmaChannels, _nmiIrqDelayCounter, _requestedDmaChannels, _inDma, _dmaStartClock, _hdmaInitPending); diff --git a/Core/DmaController.h b/Core/DmaController.h index 4f7f51f..d99a151 100644 --- a/Core/DmaController.h +++ b/Core/DmaController.h @@ -16,11 +16,11 @@ struct DmaChannelConfig uint16_t SrcAddress; uint8_t SrcBank; - uint8_t DestAddress; uint16_t TransferSize; + uint8_t DestAddress; - uint8_t HdmaBank; uint16_t HdmaTableAddress; + uint8_t HdmaBank; uint8_t HdmaLineCounterAndRepeat; bool DoTransfer; bool HdmaFinished; @@ -39,6 +39,8 @@ private: uint8_t _nmiIrqDelayCounter = 0; uint8_t _requestedDmaChannels = 0; uint64_t _dmaStartClock = 0; + + uint8_t _activeChannel = 0; //Used by debugger's event viewer DmaChannelConfig _channel[8] = {}; MemoryManager *_memoryManager; @@ -70,5 +72,8 @@ public: void Write(uint16_t addr, uint8_t value); uint8_t Read(uint16_t addr); + uint8_t GetActiveChannel(); + DmaChannelConfig GetChannelConfig(uint8_t channel); + void Serialize(Serializer &s) override; }; \ No newline at end of file diff --git a/Core/EventManager.cpp b/Core/EventManager.cpp index 03831f8..1725501 100644 --- a/Core/EventManager.cpp +++ b/Core/EventManager.cpp @@ -3,15 +3,17 @@ #include "DebugTypes.h" #include "Cpu.h" #include "Ppu.h" +#include "DmaController.h" #include "Debugger.h" #include "DebugBreakHelper.h" #include "DefaultVideoFilter.h" -EventManager::EventManager(Debugger *debugger, Cpu *cpu, Ppu *ppu) +EventManager::EventManager(Debugger *debugger, Cpu *cpu, Ppu *ppu, DmaController *dmaController) { _debugger = debugger; _cpu = cpu; _ppu = ppu; + _dmaController = dmaController; } void EventManager::AddEvent(DebugEventType type, MemoryOperationInfo &operation, int32_t breakpointId) @@ -23,6 +25,11 @@ void EventManager::AddEvent(DebugEventType type, MemoryOperationInfo &operation, evt.Cycle = _ppu->GetCycle(); evt.BreakpointId = breakpointId; + if(operation.Type == MemoryOperationType::DmaRead || operation.Type == MemoryOperationType::DmaWrite) { + evt.DmaChannel = _dmaController->GetActiveChannel(); + evt.DmaChannelInfo = _dmaController->GetChannelConfig(evt.DmaChannel); + } + CpuState state = _cpu->GetState(); evt.ProgramCounter = (state.K << 16) | state.PC; @@ -82,6 +89,7 @@ void EventManager::ClearFrameEvents() void EventManager::DrawEvent(DebugEventInfo &evt, bool drawBackground, uint32_t *buffer, EventViewerDisplayOptions &options) { bool isWrite = evt.Operation.Type == MemoryOperationType::Write || evt.Operation.Type == MemoryOperationType::DmaWrite; + bool isDma = evt.Operation.Type == MemoryOperationType::DmaWrite || evt.Operation.Type == MemoryOperationType::DmaRead; bool showEvent = false; uint32_t color = 0; switch(evt.Type) { @@ -89,6 +97,11 @@ void EventManager::DrawEvent(DebugEventInfo &evt, bool drawBackground, uint32_t case DebugEventType::Irq: showEvent = options.ShowIrq; color = options.IrqColor; break; case DebugEventType::Nmi: showEvent = options.ShowNmi; color = options.NmiColor; break; case DebugEventType::Register: + if(isDma && !options.ShowDmaChannels[evt.DmaChannel]) { + showEvent = false; + break; + } + uint16_t reg = evt.Operation.Address & 0xFFFF; if(reg <= 0x213F) { showEvent = isWrite ? options.ShowPpuRegisterWrites : options.ShowPpuRegisterReads; diff --git a/Core/EventManager.h b/Core/EventManager.h index 666cff4..d6ea5b6 100644 --- a/Core/EventManager.h +++ b/Core/EventManager.h @@ -10,12 +10,14 @@ struct EventViewerDisplayOptions; class Cpu; class Ppu; class Debugger; +class DmaController; class EventManager { private: Cpu * _cpu; Ppu *_ppu; + DmaController *_dmaController; Debugger *_debugger; vector _debugEvents; vector _prevDebugEvents; @@ -28,7 +30,7 @@ private: void DrawEvent(DebugEventInfo &evt, bool drawBackground, uint32_t *buffer, EventViewerDisplayOptions &options); public: - EventManager(Debugger *debugger, Cpu *cpu, Ppu *ppu); + EventManager(Debugger *debugger, Cpu *cpu, Ppu *ppu, DmaController *dmaController); void AddEvent(DebugEventType type, MemoryOperationInfo &operation, int32_t breakpointId = -1); void AddEvent(DebugEventType type); @@ -58,8 +60,8 @@ struct DebugEventInfo uint16_t Scanline; uint16_t Cycle; int16_t BreakpointId; - //DmaChannelConfig DmaChannelInfo; - //uint8_t DmaChannel; + uint8_t DmaChannel; + DmaChannelConfig DmaChannelInfo; }; struct EventViewerDisplayOptions @@ -80,6 +82,8 @@ struct EventViewerDisplayOptions bool ShowMarkedBreakpoints; bool ShowPreviousFrameEvents; + bool ShowDmaChannels[8]; + uint32_t IrqColor; uint32_t NmiColor; uint32_t BreakpointColor; diff --git a/UI/Debugger/Config/EventViewerConfig.cs b/UI/Debugger/Config/EventViewerConfig.cs index 307ccd4..d6860a2 100644 --- a/UI/Debugger/Config/EventViewerConfig.cs +++ b/UI/Debugger/Config/EventViewerConfig.cs @@ -32,6 +32,15 @@ namespace Mesen.GUI.Config public bool ShowMarkedBreakpoints = true; public bool ShowPreviousFrameEvents = true; + public bool ShowDmaChannel0 = true; + public bool ShowDmaChannel1 = true; + public bool ShowDmaChannel2 = true; + public bool ShowDmaChannel3 = true; + public bool ShowDmaChannel4 = true; + public bool ShowDmaChannel5 = true; + public bool ShowDmaChannel6 = true; + public bool ShowDmaChannel7 = true; + public XmlColor IrqColor = ColorTranslator.FromHtml("#FFADAC"); public XmlColor NmiColor = ColorTranslator.FromHtml("#FFADAC"); public XmlColor BreakpointColor = ColorTranslator.FromHtml("#FFADAC"); @@ -69,7 +78,18 @@ namespace Mesen.GUI.Config CpuRegisterReadColor = (uint)this.CpuRegisterReadColor.Color.ToArgb(), CpuRegisterWriteColor = (uint)this.CpuRegisterWriteColor.Color.ToArgb(), WorkRamRegisterReadColor = (uint)this.WorkRamRegisterReadColor.Color.ToArgb(), - WorkRamRegisterWriteColor = (uint)this.WorkRamRegisterWriteColor.Color.ToArgb() + WorkRamRegisterWriteColor = (uint)this.WorkRamRegisterWriteColor.Color.ToArgb(), + + ShowDmaChannels = new bool[8] { + this.ShowDmaChannel0, + this.ShowDmaChannel1, + this.ShowDmaChannel2, + this.ShowDmaChannel3, + this.ShowDmaChannel4, + this.ShowDmaChannel5, + this.ShowDmaChannel6, + this.ShowDmaChannel7 + } }; } } diff --git a/UI/Debugger/EventViewer/ctrlEventViewerPpuView.Designer.cs b/UI/Debugger/EventViewer/ctrlEventViewerPpuView.Designer.cs index 909d893..1d4fab2 100644 --- a/UI/Debugger/EventViewer/ctrlEventViewerPpuView.Designer.cs +++ b/UI/Debugger/EventViewer/ctrlEventViewerPpuView.Designer.cs @@ -33,7 +33,6 @@ namespace Mesen.GUI.Debugger this.tmrOverlay = new System.Windows.Forms.Timer(this.components); this.grpOptions = new System.Windows.Forms.GroupBox(); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); - this.chkShowPreviousFrameEvents = new System.Windows.Forms.CheckBox(); this.picNmi = new Mesen.GUI.Debugger.ctrlColorPicker(); this.chkShowNmi = new System.Windows.Forms.CheckBox(); this.picIrq = new Mesen.GUI.Debugger.ctrlColorPicker(); @@ -61,6 +60,17 @@ namespace Mesen.GUI.Debugger this.picPpuReads = new Mesen.GUI.Debugger.ctrlColorPicker(); this.chkShowMarkedBreakpoints = new System.Windows.Forms.CheckBox(); this.picMarkedBreakpoints = new Mesen.GUI.Debugger.ctrlColorPicker(); + this.chkShowPreviousFrameEvents = new System.Windows.Forms.CheckBox(); + this.grpDmaFilters = new System.Windows.Forms.GroupBox(); + this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); + this.chkDmaChannel0 = new System.Windows.Forms.CheckBox(); + this.chkDmaChannel1 = new System.Windows.Forms.CheckBox(); + this.chkDmaChannel2 = new System.Windows.Forms.CheckBox(); + this.chkDmaChannel3 = new System.Windows.Forms.CheckBox(); + this.chkDmaChannel4 = new System.Windows.Forms.CheckBox(); + this.chkDmaChannel5 = new System.Windows.Forms.CheckBox(); + this.chkDmaChannel6 = new System.Windows.Forms.CheckBox(); + this.chkDmaChannel7 = new System.Windows.Forms.CheckBox(); this.picViewer = new Mesen.GUI.Debugger.PpuViewer.ctrlImagePanel(); this.grpOptions.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); @@ -75,6 +85,8 @@ namespace Mesen.GUI.Debugger ((System.ComponentModel.ISupportInitialize)(this.picPpuWrites)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.picPpuReads)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.picMarkedBreakpoints)).BeginInit(); + this.grpDmaFilters.SuspendLayout(); + this.tableLayoutPanel2.SuspendLayout(); this.SuspendLayout(); // // tmrOverlay @@ -102,7 +114,6 @@ namespace Mesen.GUI.Debugger this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 15F)); this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel1.Controls.Add(this.chkShowPreviousFrameEvents, 0, 6); this.tableLayoutPanel1.Controls.Add(this.picNmi, 5, 4); this.tableLayoutPanel1.Controls.Add(this.chkShowNmi, 4, 4); this.tableLayoutPanel1.Controls.Add(this.picIrq, 2, 4); @@ -130,10 +141,13 @@ namespace Mesen.GUI.Debugger this.tableLayoutPanel1.Controls.Add(this.picPpuReads, 2, 0); this.tableLayoutPanel1.Controls.Add(this.chkShowMarkedBreakpoints, 0, 5); this.tableLayoutPanel1.Controls.Add(this.picMarkedBreakpoints, 2, 5); + this.tableLayoutPanel1.Controls.Add(this.chkShowPreviousFrameEvents, 0, 6); + this.tableLayoutPanel1.Controls.Add(this.grpDmaFilters, 0, 7); this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 16); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 7; + this.tableLayoutPanel1.RowCount = 8; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); @@ -144,19 +158,6 @@ namespace Mesen.GUI.Debugger this.tableLayoutPanel1.Size = new System.Drawing.Size(255, 510); this.tableLayoutPanel1.TabIndex = 0; // - // chkShowPreviousFrameEvents - // - this.chkShowPreviousFrameEvents.AutoSize = true; - this.tableLayoutPanel1.SetColumnSpan(this.chkShowPreviousFrameEvents, 6); - this.chkShowPreviousFrameEvents.Location = new System.Drawing.Point(3, 148); - this.chkShowPreviousFrameEvents.Margin = new System.Windows.Forms.Padding(3, 10, 3, 3); - this.chkShowPreviousFrameEvents.Name = "chkShowPreviousFrameEvents"; - this.chkShowPreviousFrameEvents.Size = new System.Drawing.Size(167, 17); - this.chkShowPreviousFrameEvents.TabIndex = 28; - this.chkShowPreviousFrameEvents.Text = "Show previous frame\'s events"; - this.chkShowPreviousFrameEvents.UseVisualStyleBackColor = true; - this.chkShowPreviousFrameEvents.Click += new System.EventHandler(this.chkOption_Click); - // // picNmi // this.picNmi.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; @@ -429,6 +430,143 @@ namespace Mesen.GUI.Debugger this.picMarkedBreakpoints.TabIndex = 27; this.picMarkedBreakpoints.TabStop = false; // + // chkShowPreviousFrameEvents + // + this.chkShowPreviousFrameEvents.AutoSize = true; + this.tableLayoutPanel1.SetColumnSpan(this.chkShowPreviousFrameEvents, 6); + this.chkShowPreviousFrameEvents.Location = new System.Drawing.Point(3, 148); + this.chkShowPreviousFrameEvents.Margin = new System.Windows.Forms.Padding(3, 10, 3, 3); + this.chkShowPreviousFrameEvents.Name = "chkShowPreviousFrameEvents"; + this.chkShowPreviousFrameEvents.Size = new System.Drawing.Size(167, 17); + this.chkShowPreviousFrameEvents.TabIndex = 28; + this.chkShowPreviousFrameEvents.Text = "Show previous frame\'s events"; + this.chkShowPreviousFrameEvents.UseVisualStyleBackColor = true; + this.chkShowPreviousFrameEvents.Click += new System.EventHandler(this.chkOption_Click); + // + // grpDmaFilters + // + this.tableLayoutPanel1.SetColumnSpan(this.grpDmaFilters, 6); + this.grpDmaFilters.Controls.Add(this.tableLayoutPanel2); + this.grpDmaFilters.Location = new System.Drawing.Point(3, 171); + this.grpDmaFilters.Name = "grpDmaFilters"; + this.grpDmaFilters.Size = new System.Drawing.Size(249, 113); + this.grpDmaFilters.TabIndex = 29; + this.grpDmaFilters.TabStop = false; + this.grpDmaFilters.Text = "DMA Filters"; + // + // tableLayoutPanel2 + // + this.tableLayoutPanel2.ColumnCount = 2; + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel2.Controls.Add(this.chkDmaChannel0, 0, 0); + this.tableLayoutPanel2.Controls.Add(this.chkDmaChannel1, 0, 1); + this.tableLayoutPanel2.Controls.Add(this.chkDmaChannel2, 0, 2); + this.tableLayoutPanel2.Controls.Add(this.chkDmaChannel3, 0, 3); + this.tableLayoutPanel2.Controls.Add(this.chkDmaChannel4, 1, 0); + this.tableLayoutPanel2.Controls.Add(this.chkDmaChannel5, 1, 1); + this.tableLayoutPanel2.Controls.Add(this.chkDmaChannel6, 1, 2); + this.tableLayoutPanel2.Controls.Add(this.chkDmaChannel7, 1, 3); + this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 16); + this.tableLayoutPanel2.Name = "tableLayoutPanel2"; + this.tableLayoutPanel2.RowCount = 5; + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle()); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel2.Size = new System.Drawing.Size(243, 94); + this.tableLayoutPanel2.TabIndex = 0; + // + // chkDmaChannel0 + // + this.chkDmaChannel0.AutoSize = true; + this.chkDmaChannel0.Location = new System.Drawing.Point(3, 3); + this.chkDmaChannel0.Name = "chkDmaChannel0"; + this.chkDmaChannel0.Size = new System.Drawing.Size(74, 17); + this.chkDmaChannel0.TabIndex = 0; + this.chkDmaChannel0.Text = "Channel 0"; + this.chkDmaChannel0.UseVisualStyleBackColor = true; + this.chkDmaChannel0.Click += new System.EventHandler(this.chkOption_Click); + // + // chkDmaChannel1 + // + this.chkDmaChannel1.AutoSize = true; + this.chkDmaChannel1.Location = new System.Drawing.Point(3, 26); + this.chkDmaChannel1.Name = "chkDmaChannel1"; + this.chkDmaChannel1.Size = new System.Drawing.Size(74, 17); + this.chkDmaChannel1.TabIndex = 2; + this.chkDmaChannel1.Text = "Channel 1"; + this.chkDmaChannel1.UseVisualStyleBackColor = true; + this.chkDmaChannel1.Click += new System.EventHandler(this.chkOption_Click); + // + // chkDmaChannel2 + // + this.chkDmaChannel2.AutoSize = true; + this.chkDmaChannel2.Location = new System.Drawing.Point(3, 49); + this.chkDmaChannel2.Name = "chkDmaChannel2"; + this.chkDmaChannel2.Size = new System.Drawing.Size(74, 17); + this.chkDmaChannel2.TabIndex = 4; + this.chkDmaChannel2.Text = "Channel 2"; + this.chkDmaChannel2.UseVisualStyleBackColor = true; + this.chkDmaChannel2.Click += new System.EventHandler(this.chkOption_Click); + // + // chkDmaChannel3 + // + this.chkDmaChannel3.AutoSize = true; + this.chkDmaChannel3.Location = new System.Drawing.Point(3, 72); + this.chkDmaChannel3.Name = "chkDmaChannel3"; + this.chkDmaChannel3.Size = new System.Drawing.Size(74, 17); + this.chkDmaChannel3.TabIndex = 6; + this.chkDmaChannel3.Text = "Channel 3"; + this.chkDmaChannel3.UseVisualStyleBackColor = true; + this.chkDmaChannel3.Click += new System.EventHandler(this.chkOption_Click); + // + // chkDmaChannel4 + // + this.chkDmaChannel4.AutoSize = true; + this.chkDmaChannel4.Location = new System.Drawing.Point(124, 3); + this.chkDmaChannel4.Name = "chkDmaChannel4"; + this.chkDmaChannel4.Size = new System.Drawing.Size(74, 17); + this.chkDmaChannel4.TabIndex = 1; + this.chkDmaChannel4.Text = "Channel 4"; + this.chkDmaChannel4.UseVisualStyleBackColor = true; + this.chkDmaChannel4.Click += new System.EventHandler(this.chkOption_Click); + // + // chkDmaChannel5 + // + this.chkDmaChannel5.AutoSize = true; + this.chkDmaChannel5.Location = new System.Drawing.Point(124, 26); + this.chkDmaChannel5.Name = "chkDmaChannel5"; + this.chkDmaChannel5.Size = new System.Drawing.Size(74, 17); + this.chkDmaChannel5.TabIndex = 3; + this.chkDmaChannel5.Text = "Channel 5"; + this.chkDmaChannel5.UseVisualStyleBackColor = true; + this.chkDmaChannel5.Click += new System.EventHandler(this.chkOption_Click); + // + // chkDmaChannel6 + // + this.chkDmaChannel6.AutoSize = true; + this.chkDmaChannel6.Location = new System.Drawing.Point(124, 49); + this.chkDmaChannel6.Name = "chkDmaChannel6"; + this.chkDmaChannel6.Size = new System.Drawing.Size(74, 17); + this.chkDmaChannel6.TabIndex = 5; + this.chkDmaChannel6.Text = "Channel 6"; + this.chkDmaChannel6.UseVisualStyleBackColor = true; + this.chkDmaChannel6.Click += new System.EventHandler(this.chkOption_Click); + // + // chkDmaChannel7 + // + this.chkDmaChannel7.AutoSize = true; + this.chkDmaChannel7.Location = new System.Drawing.Point(124, 72); + this.chkDmaChannel7.Name = "chkDmaChannel7"; + this.chkDmaChannel7.Size = new System.Drawing.Size(74, 17); + this.chkDmaChannel7.TabIndex = 7; + this.chkDmaChannel7.Text = "Channel 7"; + this.chkDmaChannel7.UseVisualStyleBackColor = true; + this.chkDmaChannel7.Click += new System.EventHandler(this.chkOption_Click); + // // picViewer // this.picViewer.Dock = System.Windows.Forms.DockStyle.Fill; @@ -466,6 +604,9 @@ namespace Mesen.GUI.Debugger ((System.ComponentModel.ISupportInitialize)(this.picPpuWrites)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.picPpuReads)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.picMarkedBreakpoints)).EndInit(); + this.grpDmaFilters.ResumeLayout(false); + this.tableLayoutPanel2.ResumeLayout(false); + this.tableLayoutPanel2.PerformLayout(); this.ResumeLayout(false); } @@ -503,5 +644,15 @@ namespace Mesen.GUI.Debugger private ctrlColorPicker picMarkedBreakpoints; private System.Windows.Forms.CheckBox chkShowPreviousFrameEvents; private PpuViewer.ctrlImagePanel picViewer; + private System.Windows.Forms.GroupBox grpDmaFilters; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; + private System.Windows.Forms.CheckBox chkDmaChannel0; + private System.Windows.Forms.CheckBox chkDmaChannel1; + private System.Windows.Forms.CheckBox chkDmaChannel2; + private System.Windows.Forms.CheckBox chkDmaChannel3; + private System.Windows.Forms.CheckBox chkDmaChannel4; + private System.Windows.Forms.CheckBox chkDmaChannel5; + private System.Windows.Forms.CheckBox chkDmaChannel6; + private System.Windows.Forms.CheckBox chkDmaChannel7; } } diff --git a/UI/Debugger/EventViewer/ctrlEventViewerPpuView.cs b/UI/Debugger/EventViewer/ctrlEventViewerPpuView.cs index e92b019..bd35af1 100644 --- a/UI/Debugger/EventViewer/ctrlEventViewerPpuView.cs +++ b/UI/Debugger/EventViewer/ctrlEventViewerPpuView.cs @@ -68,6 +68,15 @@ namespace Mesen.GUI.Debugger _entityBinder.AddBinding(nameof(EventViewerConfig.ShowWorkRamRegisterReads), chkShowWorkRamRegisterReads); _entityBinder.AddBinding(nameof(EventViewerConfig.ShowWorkRamRegisterWrites), chkShowWorkRamRegisterWrites); + _entityBinder.AddBinding(nameof(EventViewerConfig.ShowDmaChannel0), chkDmaChannel0); + _entityBinder.AddBinding(nameof(EventViewerConfig.ShowDmaChannel1), chkDmaChannel1); + _entityBinder.AddBinding(nameof(EventViewerConfig.ShowDmaChannel2), chkDmaChannel2); + _entityBinder.AddBinding(nameof(EventViewerConfig.ShowDmaChannel3), chkDmaChannel3); + _entityBinder.AddBinding(nameof(EventViewerConfig.ShowDmaChannel4), chkDmaChannel4); + _entityBinder.AddBinding(nameof(EventViewerConfig.ShowDmaChannel5), chkDmaChannel5); + _entityBinder.AddBinding(nameof(EventViewerConfig.ShowDmaChannel6), chkDmaChannel6); + _entityBinder.AddBinding(nameof(EventViewerConfig.ShowDmaChannel7), chkDmaChannel7); + _entityBinder.AddBinding(nameof(EventViewerConfig.ShowPreviousFrameEvents), chkShowPreviousFrameEvents); _entityBinder.UpdateUI(); @@ -224,6 +233,30 @@ namespace Mesen.GUI.Debugger bool isDma = evt.Operation.Type == MemoryOperationType.DmaWrite|| evt.Operation.Type == MemoryOperationType.DmaRead; values["Register"] = "$" + evt.Operation.Address.ToString("X4") + (isWrite ? " (Write)" : " (Read)") + (isDma ? " (DMA)" : ""); values["Value"] = "$" + evt.Operation.Value.ToString("X2"); + + if(isDma) { + bool indirectHdma = false; + values["Channel"] = evt.DmaChannel.ToString(); + if(evt.DmaChannelInfo.InterruptedByHdma != 0) { + indirectHdma = evt.DmaChannelInfo.HdmaIndirectAddressing != 0; + values["Channel"] += indirectHdma ? " (Indirect HDMA)" : " (HDMA)"; + values["Line Counter"] = "$" + evt.DmaChannelInfo.HdmaLineCounterAndRepeat.ToString("X2"); + } + values["Mode"] = evt.DmaChannelInfo.TransferMode.ToString(); + + int aBusAddress; + if(indirectHdma) { + aBusAddress = (evt.DmaChannelInfo.SrcBank << 16) | evt.DmaChannelInfo.TransferSize; + } else { + aBusAddress = (evt.DmaChannelInfo.SrcBank << 16) | evt.DmaChannelInfo.SrcAddress; + } + + if(evt.DmaChannelInfo.InvertDirection == 0) { + values["Transfer"] = "$" + aBusAddress.ToString("X4") + " -> $" + evt.DmaChannelInfo.DestAddress.ToString("X2"); + } else { + values["Transfer"] = "$" + aBusAddress.ToString("X4") + " <- $" + evt.DmaChannelInfo.DestAddress.ToString("X2"); + } + } break; case DebugEventType.Breakpoint: diff --git a/UI/Interop/DebugApi.cs b/UI/Interop/DebugApi.cs index d49d475..54f2175 100644 --- a/UI/Interop/DebugApi.cs +++ b/UI/Interop/DebugApi.cs @@ -378,16 +378,40 @@ namespace Mesen.GUI Breakpoint } + public struct DmaChannelConfig + { + public byte InvertDirection; + public byte Decrement; + public byte FixedTransfer; + public byte HdmaIndirectAddressing; + public byte TransferMode; + + public UInt16 SrcAddress; + public byte SrcBank; + + public UInt16 TransferSize; + public byte DestAddress; + + public UInt16 HdmaTableAddress; + public byte HdmaBank; + public byte HdmaLineCounterAndRepeat; + public byte DoTransfer; + public byte HdmaFinished; + + public byte InterruptedByHdma; + public byte UnusedFlag; + } + public struct DebugEventInfo { - //public DmaChannelConfig DmaChannelInfo; public MemoryOperationInfo Operation; public DebugEventType Type; public UInt32 ProgramCounter; public UInt16 Scanline; public UInt16 Cycle; public UInt16 BreakpointId; - //public byte DmaChannel; + public byte DmaChannel; + public DmaChannelConfig DmaChannelInfo; }; public struct EventViewerDisplayOptions @@ -408,6 +432,9 @@ namespace Mesen.GUI [MarshalAs(UnmanagedType.I1)] public bool ShowMarkedBreakpoints; [MarshalAs(UnmanagedType.I1)] public bool ShowPreviousFrameEvents; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8, ArraySubType = UnmanagedType.I1)] + public bool[] ShowDmaChannels; + public UInt32 IrqColor; public UInt32 NmiColor; public UInt32 BreakpointColor;