PPU: Implemented VRAM/CGRAM reads + H/V offset data latches
+ Implemented work ram read register
This commit is contained in:
parent
6e32ebfffd
commit
68e7617c95
5 changed files with 96 additions and 3 deletions
|
@ -43,6 +43,11 @@ void InternalRegisters::ProcessAutoJoypadRead()
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t InternalRegisters::GetIoPortOutput()
|
||||
{
|
||||
return _ioPortOutput;
|
||||
}
|
||||
|
||||
void InternalRegisters::SetNmiFlag(bool nmiFlag)
|
||||
{
|
||||
_nmiFlag = nmiFlag;
|
||||
|
@ -53,7 +58,11 @@ uint8_t InternalRegisters::Read(uint16_t addr)
|
|||
switch(addr) {
|
||||
case 0x4210: {
|
||||
//open bus implementation here is needed to pass CPUPHL test
|
||||
uint8_t value = (_nmiFlag ? 0x80 : 0) | ((addr >> 8) & 0x70);
|
||||
uint8_t value =
|
||||
(_nmiFlag ? 0x80 : 0) |
|
||||
((addr >> 8) & 0x70) |
|
||||
0x2; //CPU revision
|
||||
|
||||
_nmiFlag = false;
|
||||
return value;
|
||||
}
|
||||
|
@ -106,8 +115,11 @@ void InternalRegisters::Write(uint16_t addr, uint8_t value)
|
|||
_enableAutoJoypadRead = (value & 0x01) != 0;
|
||||
break;
|
||||
|
||||
case 0x4201:
|
||||
case 0x4201:
|
||||
//TODO WRIO - Programmable I/O port (out-port)
|
||||
if((_ioPortOutput & 0x80) && !(value & 0x80)) {
|
||||
_console->GetPpu()->LatchLocationValues();
|
||||
}
|
||||
_ioPortOutput = value;
|
||||
break;
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
InternalRegisters(shared_ptr<Console> console);
|
||||
|
||||
void ProcessAutoJoypadRead();
|
||||
uint8_t GetIoPortOutput();
|
||||
void SetNmiFlag(bool nmiFlag);
|
||||
|
||||
bool IsVerticalIrqEnabled() { return _enableVerticalIrq; }
|
||||
|
|
|
@ -41,6 +41,8 @@ public:
|
|||
addr &= 0xFFFF;
|
||||
if(addr >= 0x2140 && addr <= 0x217F) {
|
||||
return _spc->Read(addr & 0x03);
|
||||
} else if(addr == 0x2180) {
|
||||
return _workRam[_wramPosition++];
|
||||
} else if(addr == 0x4016 || addr == 0x4017) {
|
||||
return _controlManager->Read(addr);
|
||||
} else if(addr < 0x4200) {
|
||||
|
|
71
Core/Ppu.cpp
71
Core/Ppu.cpp
|
@ -520,10 +520,23 @@ uint8_t* Ppu::GetSpriteRam()
|
|||
return _oamRam;
|
||||
}
|
||||
|
||||
void Ppu::LatchLocationValues()
|
||||
{
|
||||
_horizontalLocation = _cycle;
|
||||
_verticalLocation = _scanline;
|
||||
}
|
||||
|
||||
uint8_t Ppu::Read(uint16_t addr)
|
||||
{
|
||||
switch(addr) {
|
||||
case 0x2137:
|
||||
//SLHV - Software Latch for H/V Counter
|
||||
//Latch values on read, and return open bus
|
||||
LatchLocationValues();
|
||||
break;
|
||||
|
||||
case 0x2138: {
|
||||
//OAMDATAREAD - Data for OAM read
|
||||
uint8_t value;
|
||||
if(_internalOamAddress < 512) {
|
||||
value = _oamRam[_internalOamAddress];
|
||||
|
@ -534,8 +547,61 @@ uint8_t Ppu::Read(uint16_t addr)
|
|||
return value;
|
||||
}
|
||||
|
||||
case 0x2139: {
|
||||
//VMDATALREAD - VRAM Data Read low byte
|
||||
uint8_t returnValue = _vramReadBuffer;
|
||||
_vramReadBuffer = _vram[_vramAddress << 1];
|
||||
if(!_vramAddrIncrementOnSecondReg) {
|
||||
_vramAddress = (_vramAddress + _vramIncrementValue) & 0x7FFF;
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
case 0x213A: {
|
||||
//VMDATAHREAD - VRAM Data Read high byte
|
||||
uint8_t returnValue = _vramReadBuffer;
|
||||
_vramReadBuffer = _vram[(_vramAddress << 1) + 1];
|
||||
if(_vramAddrIncrementOnSecondReg) {
|
||||
_vramAddress = (_vramAddress + _vramIncrementValue) & 0x7FFF;
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
case 0x213B:{
|
||||
//CGDATAREAD - CGRAM Data read
|
||||
uint8_t value = _cgram[_cgramAddress];
|
||||
_cgramAddress = (_cgramAddress + 1) & (Ppu::CgRamSize - 1);
|
||||
return value;
|
||||
}
|
||||
|
||||
case 0x213C:
|
||||
//OPHCT - Horizontal Scanline Location
|
||||
if(_horizontalLocToggle) {
|
||||
//"Note that the value read is only 9 bits: bits 1-7 of the high byte are PPU2 Open Bus."
|
||||
return ((_horizontalLocation & 0x100) >> 8) | ((addr >> 8) & 0xFE);
|
||||
} else {
|
||||
return _horizontalLocation & 0xFF;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x213D:
|
||||
//OPVCT - Vertical Scanline Location
|
||||
if(_verticalLocationToggle) {
|
||||
//"Note that the value read is only 9 bits: bits 1-7 of the high byte are PPU2 Open Bus."
|
||||
return ((_verticalLocation & 0x100) >> 8) | ((addr >> 8) & 0xFE);
|
||||
} else {
|
||||
return _verticalLocation & 0xFF;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 0x213E:
|
||||
//TODO open bus on bit 4
|
||||
|
||||
//"The high/low selector is reset to <20>elow<6F>f when $213f is read"
|
||||
_horizontalLocToggle = false;
|
||||
_verticalLocationToggle = false;
|
||||
|
||||
return (
|
||||
(_timeOver ? 0x80 : 0) |
|
||||
(_rangeOver ? 0x40 : 0) |
|
||||
|
@ -547,7 +613,7 @@ uint8_t Ppu::Read(uint16_t addr)
|
|||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return addr >> 8;
|
||||
}
|
||||
|
||||
void Ppu::Write(uint32_t addr, uint8_t value)
|
||||
|
@ -654,7 +720,10 @@ void Ppu::Write(uint32_t addr, uint8_t value)
|
|||
case 2:
|
||||
case 3: _vramIncrementValue = 128; break;
|
||||
}
|
||||
|
||||
//TODO : Remapping is not implemented yet
|
||||
_vramAddressRemapping = (value & 0x0C) >> 2;
|
||||
|
||||
_vramAddrIncrementOnSecondReg = (value & 0x80) != 0;
|
||||
break;
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ private:
|
|||
uint8_t _vramIncrementValue;
|
||||
uint8_t _vramAddressRemapping;
|
||||
bool _vramAddrIncrementOnSecondReg;
|
||||
uint8_t _vramReadBuffer = 0;
|
||||
|
||||
uint16_t _cgramAddress;
|
||||
uint8_t _cgram[Ppu::CgRamSize];
|
||||
|
@ -110,6 +111,12 @@ private:
|
|||
uint8_t _hvScrollLatchValue = 0;
|
||||
uint8_t _hScrollLatchValue = 0;
|
||||
|
||||
uint16_t _horizontalLocation = 0;
|
||||
bool _horizontalLocToggle = false;
|
||||
|
||||
uint16_t _verticalLocation = 0;
|
||||
bool _verticalLocationToggle = false;
|
||||
|
||||
template<bool forMainScreen>
|
||||
void RenderBgColor();
|
||||
|
||||
|
@ -136,6 +143,8 @@ public:
|
|||
uint8_t* GetCgRam();
|
||||
uint8_t* GetSpriteRam();
|
||||
|
||||
void LatchLocationValues();
|
||||
|
||||
uint8_t Read(uint16_t addr);
|
||||
void Write(uint32_t addr, uint8_t value);
|
||||
};
|
Loading…
Add table
Reference in a new issue