Open bus (PPU and CPU) - Fixes several open bus related tests (ppu_open_bus, test_cpu_exec_space_apu, test_cpu_exec_space_ppuio)

This commit is contained in:
Souryo 2016-01-02 20:36:22 -05:00
parent d4046360a0
commit 411967e4fa
4 changed files with 76 additions and 14 deletions

View file

@ -494,7 +494,7 @@ class BaseMapper : public IMemoryHandler, public Snapshotable, public INotificat
} else {
//assert(false);
}
return 0;
return (addr & 0xFF00) >> 8;
}
virtual void WriteRAM(uint16_t addr, uint8_t value)

View file

@ -47,7 +47,7 @@ uint8_t MemoryManager::ReadRegister(uint16_t addr)
if(_ramReadHandlers[addr]) {
return _ramReadHandlers[addr]->ReadRAM(addr);
} else {
return 0;
return (addr & 0xFF00) >> 8;
}
}

View file

@ -31,6 +31,9 @@ PPU::~PPU()
void PPU::Reset()
{
_openBus = 0;
memset(_openBusDecayStamp, 0, sizeof(_openBusDecayStamp));
_skipTick = false;
_state = {};
@ -39,7 +42,7 @@ void PPU::Reset()
_scanline = 0;
_cycle = 0;
_frameCount = -1;
_frameCount = 1;
_memoryReadBuffer = 0;
}
@ -76,15 +79,56 @@ void PPU::UpdateVideoRamAddr()
}
}
void PPU::SetOpenBus(uint8_t mask, uint8_t value)
{
//Decay expired bits, set new bits and update stamps on each individual bit
if(mask == 0xFF) {
//Shortcut when mask is 0xFF - all bits are set to the value and stamps updated
_openBus = value;
for(int i = 0; i < 8; i++) {
_openBusDecayStamp[i] = _frameCount;
}
} else {
uint16_t openBus = (_openBus << 8);
for(int i = 0; i < 8; i++) {
openBus >>= 1;
if(mask & 0x01) {
if(value & 0x01) {
openBus |= 0x80;
} else {
openBus &= 0xFF7F;
}
_openBusDecayStamp[i] = _frameCount;
} else if(_frameCount - _openBusDecayStamp[i] > 30) {
openBus &= 0xFF7F;
}
value >>= 1;
mask >>= 1;
}
_openBus = openBus & 0xFF;
}
}
uint8_t PPU::ApplyOpenBus(uint8_t mask, uint8_t value)
{
SetOpenBus(~mask, value);
return value | (_openBus & mask);
}
uint8_t PPU::ReadRAM(uint16_t addr)
{
uint8_t returnValue;
uint8_t openBusMask = 0xFF;
uint8_t returnValue = 0;
switch(GetRegisterID(addr)) {
case PPURegisters::Status:
_state.WriteToggle = false;
_flags.IntensifyBlue = false;
UpdateStatusFlag();
return _state.Status;
returnValue = _state.Status;
openBusMask = 0x1F;
break;
case PPURegisters::SpriteData:
if(_scanline <= 240 && IsRenderingEnabled() && (_cycle >= 257 || _cycle <= 64)) {
if(_cycle >= 257 && _cycle <= 320) {
@ -94,29 +138,39 @@ uint8_t PPU::ReadRAM(uint16_t addr)
_secondaryOAMAddr = (_cycle - 257) / 8 * 4 + step;
_oamCopybuffer = _secondarySpriteRAM[_secondaryOAMAddr];
}
return _oamCopybuffer;
returnValue = _oamCopybuffer;
} else {
return _spriteRAM[_state.SpriteRamAddr];
returnValue = _spriteRAM[_state.SpriteRamAddr];
}
openBusMask = 0x00;
break;
case PPURegisters::VideoMemoryData:
returnValue = _memoryReadBuffer;
_memoryReadBuffer = _memoryManager->ReadVRAM(_state.VideoRamAddr, MemoryOperationType::Read);
if(_state.VideoRamAddr >= 0x3F00) {
returnValue = ReadPaletteRAM(_state.VideoRamAddr);
returnValue = ReadPaletteRAM(_state.VideoRamAddr) | (_openBus & 0xC0);
openBusMask = 0xC0;
} else {
openBusMask = 0x00;
}
UpdateVideoRamAddr();
return returnValue;
break;
default:
//other registers are meant to be read-only
break;
}
return 0;
return ApplyOpenBus(openBusMask, returnValue);
}
void PPU::WriteRAM(uint16_t addr, uint8_t value)
{
if(addr != 0x4014) {
SetOpenBus(0xFF, value);
}
switch(GetRegisterID(addr)) {
case PPURegisters::Control:
SetControlRegister(value);
@ -750,7 +804,7 @@ void PPU::StreamState(bool saving)
Stream<int32_t>(_scanline);
Stream<uint32_t>(_cycle);
Stream<int32_t>(_frameCount);
Stream<uint32_t>(_frameCount);
Stream<uint8_t>(_memoryReadBuffer);
StreamArray<uint8_t>(_paletteRAM, 0x20);
@ -794,6 +848,9 @@ void PPU::StreamState(bool saving)
Stream<bool>(_skipTick);
Stream<uint8_t>(_openBus);
StreamArray<int32_t>(_openBusDecayStamp, 8);
if(!saving) {
SetNesModel(_nesModel);
}

View file

@ -97,7 +97,7 @@ class PPU : public IMemoryHandler, public Snapshotable
PPUState _state;
int32_t _scanline;
uint32_t _cycle;
int32_t _frameCount;
uint32_t _frameCount;
uint8_t _memoryReadBuffer;
uint8_t _paletteRAM[0x20];
@ -131,6 +131,9 @@ class PPU : public IMemoryHandler, public Snapshotable
uint32_t _spriteIndex = 0;
uint8_t _openBus = 0;
int32_t _openBusDecayStamp[8];
uint16_t _spriteDmaCounter = 0;
uint16_t _spriteDmaAddr = 0;
@ -146,6 +149,9 @@ class PPU : public IMemoryHandler, public Snapshotable
bool IsRenderingEnabled();
void SetOpenBus(uint8_t mask, uint8_t value);
uint8_t ApplyOpenBus(uint8_t mask, uint8_t value);
void UpdateVideoRamAddr();
void IncVerticalScrolling();
void IncHorizontalScrolling();
@ -203,7 +209,6 @@ class PPU : public IMemoryHandler, public Snapshotable
void GetMemoryRanges(MemoryRanges &ranges)
{
ranges.AddHandler(MemoryOperation::Read, 0x2000, 0x3FFF);
ranges.AddHandler(MemoryOperation::Read, 0x4014);
ranges.AddHandler(MemoryOperation::Write, 0x2000, 0x3FFF);
ranges.AddHandler(MemoryOperation::Write, 0x4014);
}