Debugger: Event Viewer - Use hclock values to display events, instead of PPU cycles

This commit is contained in:
Sour 2020-01-17 21:17:56 -05:00
parent bb03856475
commit 0ab9a0f0d1
5 changed files with 52 additions and 31 deletions

View file

@ -63,7 +63,7 @@ Debugger::Debugger(shared_ptr<Console> console)
_traceLogger.reset(new TraceLogger(this, _console));
_memoryAccessCounter.reset(new MemoryAccessCounter(this, console.get()));
_ppuTools.reset(new PpuTools(_console.get(), _ppu.get()));
_eventManager.reset(new EventManager(this, _cpu.get(), _ppu.get(), _console->GetDmaController().get()));
_eventManager.reset(new EventManager(this, _cpu.get(), _ppu.get(), _memoryManager.get(), _console->GetDmaController().get()));
_scriptManager.reset(new ScriptManager(this));
_cpuDebugger.reset(new CpuDebugger(this, CpuType::Cpu));

View file

@ -4,15 +4,17 @@
#include "Cpu.h"
#include "Ppu.h"
#include "DmaController.h"
#include "MemoryManager.h"
#include "Debugger.h"
#include "DebugBreakHelper.h"
#include "DefaultVideoFilter.h"
EventManager::EventManager(Debugger *debugger, Cpu *cpu, Ppu *ppu, DmaController *dmaController)
EventManager::EventManager(Debugger *debugger, Cpu *cpu, Ppu *ppu, MemoryManager *memoryManager, DmaController *dmaController)
{
_debugger = debugger;
_cpu = cpu;
_ppu = ppu;
_memoryManager = memoryManager;
_dmaController = dmaController;
_ppuBuffer = new uint16_t[512 * 478];
@ -30,7 +32,7 @@ void EventManager::AddEvent(DebugEventType type, MemoryOperationInfo &operation,
evt.Type = type;
evt.Operation = operation;
evt.Scanline = _ppu->GetScanline();
evt.Cycle = _ppu->GetCycle();
evt.Cycle = _memoryManager->GetHClock();
evt.BreakpointId = breakpointId;
if(operation.Type == MemoryOperationType::DmaRead || operation.Type == MemoryOperationType::DmaWrite) {
@ -51,7 +53,7 @@ void EventManager::AddEvent(DebugEventType type)
DebugEventInfo evt = {};
evt.Type = type;
evt.Scanline = _ppu->GetScanline();
evt.Cycle = _ppu->GetCycle();
evt.Cycle = _memoryManager->GetHClock();
evt.BreakpointId = -1;
evt.DmaChannel = -1;
@ -104,9 +106,9 @@ void EventManager::FilterEvents(EventViewerDisplayOptions &options)
vector<DebugEventInfo> events = _snapshot;
if(options.ShowPreviousFrameEvents && _snapshotScanline != 0) {
uint32_t key = (_snapshotScanline << 9) + _snapshotCycle;
uint32_t key = (_snapshotScanline << 16) + _snapshotCycle;
for(DebugEventInfo &evt : _prevDebugEvents) {
uint32_t evtKey = (evt.Scanline << 9) + evt.Cycle;
uint32_t evtKey = (evt.Scanline << 16) + evt.Cycle;
if(evtKey > key) {
events.push_back(evt);
}
@ -220,12 +222,12 @@ void EventManager::DrawEvent(DebugEventInfo &evt, bool drawBackground, uint32_t
int jMin = drawBackground ? -2 : 0;
int jMax = drawBackground ? 3 : 1;
uint32_t y = std::min<uint32_t>(evt.Scanline * 2, _scanlineCount * 2);
uint32_t x = evt.Cycle * 2;
uint32_t x = evt.Cycle / 2;
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 * (int)_scanlineCount * 2) {
int32_t pos = (y + i) * EventManager::ScanlineWidth + x + j;
if(pos < 0 || pos >= EventManager::ScanlineWidth * (int)_scanlineCount * 2) {
continue;
}
buffer[pos] = color;
@ -239,9 +241,8 @@ uint32_t EventManager::TakeEventSnapshot(EventViewerDisplayOptions options)
auto lock = _lock.AcquireSafe();
_snapshot.clear();
uint16_t cycle = _ppu->GetCycle();
uint16_t cycle = _memoryManager->GetHClock();
uint16_t scanline = _ppu->GetScanline();
uint32_t key = (scanline << 9) + cycle;
_overscanMode = _ppu->GetState().OverscanMode;
_useHighResOutput = _ppu->IsHighResOutput();
@ -267,7 +268,7 @@ void EventManager::GetDisplayBuffer(uint32_t *buffer, EventViewerDisplayOptions
{
auto lock = _lock.AcquireSafe();
for(int i = 0; i < 340 * 2 * (int)_scanlineCount * 2; i++) {
for(int i = 0; i < EventManager::ScanlineWidth * (int)_scanlineCount * 2; i++) {
buffer[i] = 0xFF555555;
}
@ -277,20 +278,20 @@ void EventManager::GetDisplayBuffer(uint32_t *buffer, EventViewerDisplayOptions
for(uint32_t y = 0, len = _overscanMode ? 239*2 : 224*2; y < len; y++) {
for(uint32_t x = 0; x < 512; x++) {
int srcOffset = _useHighResOutput ? ((y << 9) | x) : (((y >> 1) << 8) | (x >> 1));
buffer[(y + 2)*340*2 + x + 22*2] = DefaultVideoFilter::ToArgb(src[srcOffset]);
buffer[(y + 2)*EventManager::ScanlineWidth + x + 22*2] = DefaultVideoFilter::ToArgb(src[srcOffset]);
}
}
constexpr uint32_t nmiColor = 0xFF55FFFF;
constexpr uint32_t currentScanlineColor = 0xFFFFFF55;
int nmiScanline = (_overscanMode ? 240 : 225) * 2 * 340 * 2;
uint32_t scanlineOffset = _snapshotScanline * 2 * 340 * 2;
for(int i = 0; i < 340 * 2; i++) {
int nmiScanline = (_overscanMode ? 240 : 225) * 2 * EventManager::ScanlineWidth;
uint32_t scanlineOffset = _snapshotScanline * 2 * EventManager::ScanlineWidth;
for(int i = 0; i < EventManager::ScanlineWidth; i++) {
buffer[nmiScanline + i] = nmiColor;
buffer[nmiScanline + 340 * 2 + i] = nmiColor;
buffer[nmiScanline + EventManager::ScanlineWidth + i] = nmiColor;
if(_snapshotScanline != 0) {
buffer[scanlineOffset + i] = currentScanlineColor;
buffer[scanlineOffset + 340 * 2 + i] = currentScanlineColor;
buffer[scanlineOffset + EventManager::ScanlineWidth + i] = currentScanlineColor;
}
}

View file

@ -11,12 +11,16 @@ class Cpu;
class Ppu;
class Debugger;
class DmaController;
class MemoryManager;
class EventManager
{
private:
static constexpr int ScanlineWidth = 1364 / 2;
Cpu * _cpu;
Ppu *_ppu;
MemoryManager* _memoryManager;
DmaController *_dmaController;
Debugger *_debugger;
vector<DebugEventInfo> _debugEvents;
@ -37,7 +41,7 @@ private:
void FilterEvents(EventViewerDisplayOptions &options);
public:
EventManager(Debugger *debugger, Cpu *cpu, Ppu *ppu, DmaController *dmaController);
EventManager(Debugger *debugger, Cpu *cpu, Ppu *ppu, MemoryManager *memoryManager, DmaController *dmaController);
~EventManager();
void AddEvent(DebugEventType type, MemoryOperationInfo &operation, int32_t breakpointId = -1);

View file

@ -21,7 +21,7 @@ namespace Mesen.GUI.Debugger
{
public const int HdmaChannelFlag = 0x40;
private int _baseWidth = 340 * 2;
private int _baseWidth = 1364 / 2;
private Point _lastPos = new Point(-1, -1);
private bool _needUpdate = false;
@ -30,6 +30,7 @@ namespace Mesen.GUI.Debugger
private Bitmap _displayBitmap = null;
private byte[] _pictureData = null;
private Font _overlayFont;
private Font _smallOverlayFont;
public UInt32 ScanlineCount { get; set; } = 262;
public int ImageScale { get { return picViewer.ImageScale; } set { picViewer.ImageScale = value; } }
@ -46,6 +47,7 @@ namespace Mesen.GUI.Debugger
if(!IsDesignMode) {
tmrOverlay.Start();
_overlayFont = new Font(BaseControl.MonospaceFontFamily, 10);
_smallOverlayFont = new Font(BaseControl.MonospaceFontFamily, 8);
}
}
@ -93,14 +95,17 @@ namespace Mesen.GUI.Debugger
int x = _lastPos.X + 5;
int y = _lastPos.Y - (int)size.Height / 2 - 5;
if(x*2 - picViewer.ScrollOffsets.X / picViewer.ImageScale + size.Width > (picViewer.Width / picViewer.ImageScale) - 5) {
x -= (int)size.Width / 2 + 10;
if(x/2 - picViewer.ScrollOffsets.X / picViewer.ImageScale + size.Width > (picViewer.Width / picViewer.ImageScale) - 5) {
x -= (int)size.Width * 2 + 10;
}
if(y*2 - picViewer.ScrollOffsets.Y / picViewer.ImageScale < size.Height + 5) {
y = _lastPos.Y + 5;
}
g.DrawOutlinedString(location, _overlayFont, Brushes.Black, Brushes.White, x*2, y*2);
g.DrawOutlinedString(location, _overlayFont, Brushes.Black, Brushes.White, x/2, y*2);
location = GetCycle(_lastPos.X).ToString();
g.DrawOutlinedString(location, _smallOverlayFont, Brushes.Black, Brushes.White, x/2, y*2 + (int)size.Height - 5);
}
}
@ -111,7 +116,7 @@ namespace Mesen.GUI.Debugger
private void UpdateOverlay(Point p)
{
Point pos = GetCycleScanline(p);
Point pos = GetHClockAndScanline(p);
if(_lastPos == pos) {
//Same x,y location, no need to update
@ -121,7 +126,7 @@ namespace Mesen.GUI.Debugger
using(Graphics g = Graphics.FromImage(_overlayBitmap)) {
g.Clear(Color.Transparent);
using(Pen bg = new Pen(Color.FromArgb(128, Color.LightGray))) {
g.DrawRectangle(bg, pos.X * 2 - 1, 0, 3, _overlayBitmap.Height);
g.DrawRectangle(bg, pos.X / 2 - 1, 0, 3, _overlayBitmap.Height);
g.DrawRectangle(bg, 0, pos.Y * 2 - 1, _overlayBitmap.Width, 3);
}
}
@ -139,17 +144,28 @@ namespace Mesen.GUI.Debugger
_lastPos = new Point(-1, -1);
}
private Point GetCycleScanline(Point location)
private Point GetHClockAndScanline(Point location)
{
return new Point(
((location.X & ~0x01) / this.ImageScale) / 2,
(location.X / this.ImageScale) * 2,
((location.Y & ~0x01) / this.ImageScale) / 2
);
}
private int GetCycle(int hClock)
{
if(hClock <= 1292) {
return hClock >> 2;
} else if(hClock <= 1310) {
return (hClock - 2) >> 2;
} else {
return (hClock - 4) >> 2;
}
}
private void picPicture_MouseMove(object sender, MouseEventArgs e)
{
Point pos = GetCycleScanline(e.Location);
Point pos = GetHClockAndScanline(e.Location);
if(_lastPos == pos) {
return;
}
@ -166,7 +182,7 @@ namespace Mesen.GUI.Debugger
Dictionary<string, string> values = new Dictionary<string, string>() {
{ "Type", ResourceHelper.GetEnumText(evt.Type) },
{ "Scanline", evt.Scanline.ToString() },
{ "Cycle", evt.Cycle.ToString() },
{ "H-Clock", evt.Cycle.ToString() + " (" + GetCycle(evt.Cycle) + ")" },
{ "PC", "$" + evt.ProgramCounter.ToString("X6") },
};
@ -225,7 +241,7 @@ namespace Mesen.GUI.Debugger
break;
}
UpdateOverlay(new Point((int)(evt.Cycle * 2 * this.ImageScale), (int)(evt.Scanline * 2 * this.ImageScale)));
UpdateOverlay(new Point((int)(evt.Cycle / 2 * this.ImageScale), (int)(evt.Scanline * 2 * this.ImageScale)));
Form parentForm = this.FindForm();
Point location = parentForm.PointToClient(this.PointToScreen(new Point(e.Location.X - picViewer.ScrollOffsets.X, e.Location.Y - picViewer.ScrollOffsets.Y)));

View file

@ -113,7 +113,7 @@ namespace Mesen.GUI
[DllImport(DllPath, EntryPoint = "GetEventViewerOutput")] private static extern void GetEventViewerOutputWrapper([In, Out]byte[] buffer, EventViewerDisplayOptions options);
public static byte[] GetEventViewerOutput(UInt32 scanlineCount, EventViewerDisplayOptions options)
{
byte[] buffer = new byte[340*2 * scanlineCount*2 * 4];
byte[] buffer = new byte[1364/2 * scanlineCount*2 * 4];
DebugApi.GetEventViewerOutputWrapper(buffer, options);
return buffer;
}