Debugger: Event Viewer - Use hclock values to display events, instead of PPU cycles
This commit is contained in:
parent
bb03856475
commit
0ab9a0f0d1
5 changed files with 52 additions and 31 deletions
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue