Debugger: Allow debugger to peek at APU/PPU registers without altering the state
This commit is contained in:
parent
60e0bd4e01
commit
40710c3665
11 changed files with 101 additions and 20 deletions
14
Core/APU.cpp
14
Core/APU.cpp
|
@ -78,7 +78,7 @@ void APU::FrameCounterTick(FrameType type)
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t APU::ReadRAM(uint16_t addr)
|
||||
uint8_t APU::GetStatus()
|
||||
{
|
||||
//$4015 read
|
||||
Run();
|
||||
|
@ -92,12 +92,24 @@ uint8_t APU::ReadRAM(uint16_t addr)
|
|||
status |= _console->GetCpu()->HasIrqSource(IRQSource::FrameCounter) ? 0x40 : 0x00;
|
||||
status |= _console->GetCpu()->HasIrqSource(IRQSource::DMC) ? 0x80 : 0x00;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
uint8_t APU::ReadRAM(uint16_t addr)
|
||||
{
|
||||
uint8_t status = GetStatus();
|
||||
|
||||
//Reading $4015 clears the Frame Counter interrupt flag.
|
||||
_console->GetCpu()->ClearIrqSource(IRQSource::FrameCounter);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
uint8_t APU::PeekRAM(uint16_t addr)
|
||||
{
|
||||
return GetStatus();
|
||||
}
|
||||
|
||||
void APU::WriteRAM(uint16_t addr, uint8_t value)
|
||||
{
|
||||
//$4015 write
|
||||
|
|
|
@ -46,6 +46,7 @@ class APU : public Snapshotable, public IMemoryHandler
|
|||
__forceinline bool NeedToRun(uint32_t currentCycle);
|
||||
|
||||
void FrameCounterTick(FrameType type);
|
||||
uint8_t GetStatus();
|
||||
|
||||
protected:
|
||||
void StreamState(bool saving) override;
|
||||
|
@ -58,6 +59,7 @@ class APU : public Snapshotable, public IMemoryHandler
|
|||
void SetNesModel(NesModel model, bool forceInit = false);
|
||||
|
||||
uint8_t ReadRAM(uint16_t addr) override;
|
||||
uint8_t PeekRAM(uint16_t addr) override;
|
||||
void WriteRAM(uint16_t addr, uint8_t value) override;
|
||||
void GetMemoryRanges(MemoryRanges &ranges) override;
|
||||
|
||||
|
|
|
@ -855,6 +855,11 @@ uint8_t BaseMapper::ReadRAM(uint16_t addr)
|
|||
return _console->GetMemoryManager()->GetOpenBus();
|
||||
}
|
||||
|
||||
uint8_t BaseMapper::PeekRAM(uint16_t addr)
|
||||
{
|
||||
return DebugReadRAM(addr);
|
||||
}
|
||||
|
||||
uint8_t BaseMapper::DebugReadRAM(uint16_t addr)
|
||||
{
|
||||
if(_prgPageAccessType[addr >> 8] & MemoryAccessType::Read) {
|
||||
|
|
|
@ -176,6 +176,7 @@ public:
|
|||
RomInfo GetRomInfo();
|
||||
|
||||
__forceinline uint8_t ReadRAM(uint16_t addr) override;
|
||||
uint8_t PeekRAM(uint16_t addr) override;
|
||||
uint8_t DebugReadRAM(uint16_t addr);
|
||||
virtual void WriteRAM(uint16_t addr, uint8_t value) override;
|
||||
void DebugWriteRAM(uint16_t addr, uint8_t value);
|
||||
|
|
|
@ -436,13 +436,8 @@ void Debugger::ProcessAllBreakpoints(OperationInfo &operationInfo, AddressTypeIn
|
|||
if(_hasBreakpoint[BreakpointType::ReadVram]) {
|
||||
OperationInfo ppuInfo;
|
||||
ppuInfo.OperationType = MemoryOperationType::Read;
|
||||
if((state.PPU.State.VideoRamAddr & 0x3FFF) >= 0x3F00) {
|
||||
ppuInfo.Address = state.PPU.State.VideoRamAddr;
|
||||
ppuInfo.Value = _ppu->ReadPaletteRAM(ppuInfo.Address);
|
||||
} else {
|
||||
ppuInfo.Address = state.PPU.BusAddress;
|
||||
ppuInfo.Value = _mapper->DebugReadVRAM(ppuInfo.Address);
|
||||
}
|
||||
ppuInfo.Address = state.PPU.BusAddress;
|
||||
ppuInfo.Value = _ppu->PeekRAM(addr);
|
||||
if(ProcessBreakpoints(BreakpointType::ReadVram, ppuInfo, true, false)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
virtual void GetMemoryRanges(MemoryRanges &ranges) = 0;
|
||||
virtual uint8_t ReadRAM(uint16_t addr) = 0;
|
||||
virtual void WriteRAM(uint16_t addr, uint8_t value) = 0;
|
||||
virtual uint8_t PeekRAM(uint16_t addr) { return 0; }
|
||||
|
||||
virtual ~IMemoryHandler() {}
|
||||
};
|
|
@ -25,6 +25,11 @@ public:
|
|||
return _internalRam[addr & Mask];
|
||||
}
|
||||
|
||||
uint8_t PeekRAM(uint16_t addr) override
|
||||
{
|
||||
return ReadRAM(addr);
|
||||
}
|
||||
|
||||
void WriteRAM(uint16_t addr, uint8_t value) override
|
||||
{
|
||||
_internalRam[addr & Mask] = value;
|
||||
|
|
|
@ -100,10 +100,7 @@ uint8_t MemoryManager::DebugRead(uint16_t addr, bool disableSideEffects)
|
|||
IMemoryHandler* handler = _ramReadHandlers[addr];
|
||||
if(handler) {
|
||||
if(disableSideEffects) {
|
||||
if(handler == _mapper.get()) {
|
||||
//Only allow reads from prg/chr ram/rom (e.g not ppu, apu, mapper registers, etc.)
|
||||
value = ((BaseMapper*)handler)->DebugReadRAM(addr);
|
||||
}
|
||||
value = handler->PeekRAM(addr);
|
||||
} else {
|
||||
value = handler->ReadRAM(addr);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,11 @@ public:
|
|||
return _lastReadValue;
|
||||
}
|
||||
|
||||
uint8_t PeekRAM(uint16_t addr) override
|
||||
{
|
||||
return addr >> 8; //Fake open bus for debugger
|
||||
}
|
||||
|
||||
__forceinline uint8_t GetOpenBus()
|
||||
{
|
||||
return _lastReadValue;
|
||||
|
|
71
Core/PPU.cpp
71
Core/PPU.cpp
|
@ -227,6 +227,68 @@ uint8_t PPU::ApplyOpenBus(uint8_t mask, uint8_t value)
|
|||
return value | (_openBus & mask);
|
||||
}
|
||||
|
||||
void PPU::ProcessStatusRegOpenBus(uint8_t &openBusMask, uint8_t &returnValue)
|
||||
{
|
||||
switch(_settings->GetPpuModel()) {
|
||||
case PpuModel::Ppu2C05A: openBusMask = 0x00; returnValue |= 0x1B; break;
|
||||
case PpuModel::Ppu2C05B: openBusMask = 0x00; returnValue |= 0x3D; break;
|
||||
case PpuModel::Ppu2C05C: openBusMask = 0x00; returnValue |= 0x1C; break;
|
||||
case PpuModel::Ppu2C05D: openBusMask = 0x00; returnValue |= 0x1B; break;
|
||||
case PpuModel::Ppu2C05E: openBusMask = 0x00; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t PPU::PeekRAM(uint16_t addr)
|
||||
{
|
||||
//Used by debugger to get register values without side-effects (heavily edited copy of ReadRAM)
|
||||
uint8_t openBusMask = 0xFF;
|
||||
uint8_t returnValue = 0;
|
||||
switch(GetRegisterID(addr)) {
|
||||
case PPURegisters::Status:
|
||||
returnValue = ((uint8_t)_statusFlags.SpriteOverflow << 5) | ((uint8_t)_statusFlags.Sprite0Hit << 6) | ((uint8_t)_statusFlags.VerticalBlank << 7);
|
||||
if(_scanline == 241 && _cycle < 3) {
|
||||
//Clear vertical blank flag
|
||||
returnValue &= 0x7F;
|
||||
}
|
||||
openBusMask = 0x1F;
|
||||
ProcessStatusRegOpenBus(openBusMask, returnValue);
|
||||
break;
|
||||
|
||||
case PPURegisters::SpriteData:
|
||||
if(!_settings->CheckFlag(EmulationFlags::DisablePpu2004Reads)) {
|
||||
if(_scanline <= 239 && IsRenderingEnabled()) {
|
||||
if(_cycle >= 257 && _cycle <= 320) {
|
||||
uint8_t step = ((_cycle - 257) % 8) > 3 ? 3 : ((_cycle - 257) % 8);
|
||||
uint8_t addr = (_cycle - 257) / 8 * 4 + step;
|
||||
returnValue = _secondarySpriteRAM[addr];
|
||||
} else {
|
||||
returnValue = _oamCopybuffer;
|
||||
}
|
||||
} else {
|
||||
returnValue = _spriteRAM[_state.SpriteRamAddr];
|
||||
}
|
||||
openBusMask = 0x00;
|
||||
}
|
||||
break;
|
||||
|
||||
case PPURegisters::VideoMemoryData:
|
||||
returnValue = _memoryReadBuffer;
|
||||
|
||||
if((_state.VideoRamAddr & 0x3FFF) >= 0x3F00 && !_settings->CheckFlag(EmulationFlags::DisablePaletteRead)) {
|
||||
returnValue = ReadPaletteRAM(_state.VideoRamAddr) | (_openBus & 0xC0);
|
||||
openBusMask = 0xC0;
|
||||
} else {
|
||||
openBusMask = 0x00;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return returnValue | (_openBus & openBusMask);
|
||||
}
|
||||
|
||||
uint8_t PPU::ReadRAM(uint16_t addr)
|
||||
{
|
||||
uint8_t openBusMask = 0xFF;
|
||||
|
@ -239,14 +301,7 @@ uint8_t PPU::ReadRAM(uint16_t addr)
|
|||
returnValue = _state.Status;
|
||||
openBusMask = 0x1F;
|
||||
|
||||
switch(_settings->GetPpuModel()) {
|
||||
case PpuModel::Ppu2C05A: openBusMask = 0x00; returnValue |= 0x1B; break;
|
||||
case PpuModel::Ppu2C05B: openBusMask = 0x00; returnValue |= 0x3D; break;
|
||||
case PpuModel::Ppu2C05C: openBusMask = 0x00; returnValue |= 0x1C; break;
|
||||
case PpuModel::Ppu2C05D: openBusMask = 0x00; returnValue |= 0x1B; break;
|
||||
case PpuModel::Ppu2C05E: openBusMask = 0x00; break;
|
||||
default: break;
|
||||
}
|
||||
ProcessStatusRegOpenBus(openBusMask, returnValue);
|
||||
break;
|
||||
|
||||
case PPURegisters::SpriteData:
|
||||
|
|
|
@ -114,6 +114,8 @@ class PPU : public IMemoryHandler, public Snapshotable
|
|||
void SetOpenBus(uint8_t mask, uint8_t value);
|
||||
uint8_t ApplyOpenBus(uint8_t mask, uint8_t value);
|
||||
|
||||
void ProcessStatusRegOpenBus(uint8_t & openBusMask, uint8_t & returnValue);
|
||||
|
||||
void UpdateVideoRamAddr();
|
||||
void IncVerticalScrolling();
|
||||
void IncHorizontalScrolling();
|
||||
|
@ -189,6 +191,7 @@ class PPU : public IMemoryHandler, public Snapshotable
|
|||
void WritePaletteRAM(uint16_t addr, uint8_t value);
|
||||
|
||||
uint8_t ReadRAM(uint16_t addr) override;
|
||||
uint8_t PeekRAM(uint16_t addr) override;
|
||||
void WriteRAM(uint16_t addr, uint8_t value) override;
|
||||
|
||||
void SetNesModel(NesModel model);
|
||||
|
|
Loading…
Add table
Reference in a new issue