Debugger: GB - Properly implemented vram/oam breakpoints

+ Fixed access counters in gameboy-only mode
This commit is contained in:
Sour 2020-07-03 10:06:40 -04:00
parent a22302134d
commit d4f0b34605
7 changed files with 46 additions and 14 deletions

View file

@ -48,9 +48,11 @@ public:
case SnesMemoryType::GbPrgRom:
case SnesMemoryType::GbWorkRam:
case SnesMemoryType::GbCartRam:
case SnesMemoryType::GbVideoRam:
case SnesMemoryType::GbHighRam:
case SnesMemoryType::GbBootRom:
case SnesMemoryType::GbVideoRam:
case SnesMemoryType::GbSpriteRam:
case SnesMemoryType::GameboyMemory:
return CpuType::Gameboy;
default:
@ -72,6 +74,7 @@ public:
case SnesMemoryType::SpriteRam:
case SnesMemoryType::CGRam:
case SnesMemoryType::GbVideoRam:
case SnesMemoryType::GbSpriteRam:
return true;
default:

View file

@ -197,18 +197,22 @@ void Debugger::ProcessPpuRead(uint16_t addr, uint8_t value, SnesMemoryType memor
{
AddressInfo addressInfo { addr, memoryType };
MemoryOperationInfo operation { addr, value, MemoryOperationType::Read };
ProcessBreakConditions(false, _cpuDebugger->GetBreakpointManager(), operation, addressInfo);
BreakpointManager* bpManager = DebugUtilities::ToCpuType(memoryType) == CpuType::Gameboy ? _gbDebugger->GetBreakpointManager() : _cpuDebugger->GetBreakpointManager();
ProcessBreakConditions(false, bpManager, operation, addressInfo);
_memoryAccessCounter->ProcessMemoryRead(addressInfo, _memoryManager->GetMasterClock());
_memoryAccessCounter->ProcessMemoryRead(addressInfo, _console->GetMasterClock());
}
void Debugger::ProcessPpuWrite(uint16_t addr, uint8_t value, SnesMemoryType memoryType)
{
AddressInfo addressInfo { addr, memoryType };
MemoryOperationInfo operation { addr, value, MemoryOperationType::Write };
ProcessBreakConditions(false, _cpuDebugger->GetBreakpointManager(), operation, addressInfo);
BreakpointManager* bpManager = DebugUtilities::ToCpuType(memoryType) == CpuType::Gameboy ? _gbDebugger->GetBreakpointManager() : _cpuDebugger->GetBreakpointManager();
ProcessBreakConditions(false, bpManager, operation, addressInfo);
_memoryAccessCounter->ProcessMemoryWrite(addressInfo, _memoryManager->GetMasterClock());
_memoryAccessCounter->ProcessMemoryWrite(addressInfo, _console->GetMasterClock());
}
template<CpuType cpuType>

View file

@ -811,7 +811,9 @@ bool GbPpu::IsVramWriteAllowed()
uint8_t GbPpu::ReadVram(uint16_t addr)
{
if(IsVramReadAllowed()) {
return _vram[(_state.CgbVramBank << 13) | (addr & 0x1FFF)];
uint16_t vramAddr = (_state.CgbVramBank << 13) | (addr & 0x1FFF);
_console->ProcessPpuRead(vramAddr, _vram[vramAddr], SnesMemoryType::GbVideoRam);
return _vram[vramAddr];
} else {
_console->BreakImmediately(BreakSource::GbInvalidVramAccess);
return 0xFF;
@ -826,7 +828,9 @@ uint8_t GbPpu::PeekVram(uint16_t addr)
void GbPpu::WriteVram(uint16_t addr, uint8_t value)
{
if(IsVramWriteAllowed()) {
_vram[(_state.CgbVramBank << 13) | (addr & 0x1FFF)] = value;
uint16_t vramAddr = (_state.CgbVramBank << 13) | (addr & 0x1FFF);
_console->ProcessPpuWrite(vramAddr, value, SnesMemoryType::GbVideoRam);
_vram[vramAddr] = value;
} else {
_console->BreakImmediately(BreakSource::GbInvalidVramAccess);
}
@ -870,6 +874,7 @@ uint8_t GbPpu::ReadOam(uint8_t addr)
{
if(addr < 0xA0) {
if(IsOamReadAllowed()) {
_console->ProcessPpuRead(addr, _oam[addr], SnesMemoryType::GbSpriteRam);
return _oam[addr];
} else {
_console->BreakImmediately(BreakSource::GbInvalidOamAccess);
@ -887,8 +892,10 @@ void GbPpu::WriteOam(uint8_t addr, uint8_t value, bool forDma)
if(addr < 0xA0) {
if(forDma) {
_oam[addr] = value;
_console->ProcessPpuWrite(addr, value, SnesMemoryType::GbSpriteRam);
} else if(IsOamWriteAllowed()) {
_oam[addr] = value;
_console->ProcessPpuWrite(addr, value, SnesMemoryType::GbSpriteRam);
} else {
_console->BreakImmediately(BreakSource::GbInvalidOamAccess);
}

View file

@ -60,12 +60,7 @@ namespace Mesen.GUI.Debugger
public static bool IsTypeCpuBreakpoint(SnesMemoryType type)
{
return (
type != SnesMemoryType.Register &&
type != SnesMemoryType.VideoRam &&
type != SnesMemoryType.CGRam &&
type != SnesMemoryType.SpriteRam
);
return type != SnesMemoryType.Register && !type.IsPpuMemory();
}
public void SetEnabled(bool enabled)
@ -136,6 +131,8 @@ namespace Mesen.GUI.Debugger
case SnesMemoryType.GbCartRam: type = "SRAM"; break;
case SnesMemoryType.GbHighRam: type = "HRAM"; break;
case SnesMemoryType.GbBootRom: type = "BOOT"; break;
case SnesMemoryType.GbVideoRam: type = "VRAM"; break;
case SnesMemoryType.GbSpriteRam: type = "OAM"; break;
case SnesMemoryType.Register: type = "REG"; break;
}

View file

@ -92,6 +92,9 @@ namespace Mesen.GUI.Debugger
if(DebugApi.GetMemorySize(SnesMemoryType.GbBootRom) > 0) {
cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.GbBootRom));
}
cboBreakpointType.Items.Add("-");
cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.GbVideoRam));
cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.GbSpriteRam));
}
this.toolTip.SetToolTip(this.picExpressionWarning, "Condition contains invalid syntax or symbols.");

View file

@ -49,8 +49,9 @@ namespace Mesen.GUI.Debugger.Controls
DebugApi.GetMemoryAccessCounts(_memoryType, ref _newCounts);
bool isGameboyMode = EmuApi.GetRomInfo().CoprocessorType == CoprocessorType.Gameboy;
DebugState state = DebugApi.GetState();
_masterClock = state.MasterClock;
_masterClock = isGameboyMode ? state.Gameboy.MemoryManager.CycleCount : state.MasterClock;
_sorting = true;
Task.Run(() => {

View file

@ -253,6 +253,8 @@ namespace Mesen.GUI
case SnesMemoryType.GbCartRam:
case SnesMemoryType.GbHighRam:
case SnesMemoryType.GbBootRom:
case SnesMemoryType.GbVideoRam:
case SnesMemoryType.GbSpriteRam:
case SnesMemoryType.GameboyMemory:
return CpuType.Gameboy;
@ -261,6 +263,21 @@ namespace Mesen.GUI
}
}
public static bool IsPpuMemory(this SnesMemoryType memType)
{
switch(memType) {
case SnesMemoryType.VideoRam:
case SnesMemoryType.SpriteRam:
case SnesMemoryType.CGRam:
case SnesMemoryType.GbVideoRam:
case SnesMemoryType.GbSpriteRam:
return true;
default:
return false;
}
}
public static bool IsRelativeMemory(this SnesMemoryType memType)
{
switch(memType) {