From a19013da76a7d318cfdc9a8fbb885cd4186d5f6b Mon Sep 17 00:00:00 2001 From: Sour Date: Sun, 17 Feb 2019 21:09:33 -0500 Subject: [PATCH] PPU: Implemented OAM writes --- Core/Ppu.cpp | 37 ++++++++++++++++++++++++------------- Core/Ppu.h | 15 ++++++++++++--- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/Core/Ppu.cpp b/Core/Ppu.cpp index dd27c3b..023d7b3 100644 --- a/Core/Ppu.cpp +++ b/Core/Ppu.cpp @@ -63,6 +63,9 @@ void Ppu::Exec() _scanline++; if(_scanline == 225) { + //Reset OAM address at the start of vblank? + _internalOamAddress = (_oamRamAddress << 1); + _frameCount++; _console->GetSpc()->ProcessEndFrame(); _console->GetControlManager()->UpdateInputState(); @@ -177,7 +180,7 @@ uint8_t* Ppu::GetCgRam() uint8_t* Ppu::GetSpriteRam() { - return _spriteRam; + return _oamRam; } uint8_t Ppu::Read(uint16_t addr) @@ -195,27 +198,35 @@ void Ppu::Write(uint32_t addr, uint8_t value) { switch(addr) { case 0x2101: - //TODO - //_spriteMode = (value & 0xE0) >> 5; - //_spriteBaseAddress = (value & 0x07) << 13; - //_spriteAddressOffset = (value & 0x18) << 9; + _oamMode = (value & 0xE0) >> 5; + _oamBaseAddress = (value & 0x07) << 13; + _oamAddressOffset = (value & 0x18) << 9; break; case 0x2102: - //TODO - //_oamAddress = (value << 1); + _oamRamAddress = (_oamRamAddress & 0x100) | value; + _internalOamAddress = (_oamRamAddress << 1); break; case 0x2103: - //TODO - //_oamTableSelect = value & 0x01; - //_enableOamPriority = (value & 0x80) != 0; + _oamRamAddress = (_oamRamAddress & 0xFF) | ((value & 0x01) << 8); + _internalOamAddress = (_oamRamAddress << 1); + _enableOamPriority = (value & 0x80) != 0; break; case 0x2104: - //TODO - //_oam[_oamAddress] = value; - //_oamAddress++; + if(_internalOamAddress < 512) { + if(_internalOamAddress & 0x01) { + _oamRam[_internalOamAddress - 1] = _oamWriteBuffer; + _oamRam[_internalOamAddress] = value; + } else { + _oamWriteBuffer = value; + } + } else if(_internalOamAddress >= 512) { + uint16_t address = 0x200 | (_internalOamAddress & 0x1F); + _oamRam[address] = value; + } + _internalOamAddress = (_internalOamAddress + 1) & 0x3FF; break; case 0x2105: diff --git a/Core/Ppu.h b/Core/Ppu.h index c961ed9..748db9d 100644 --- a/Core/Ppu.h +++ b/Core/Ppu.h @@ -32,12 +32,21 @@ private: uint16_t _cgramAddress; uint8_t _cgram[Ppu::CgRamSize]; - uint8_t _spriteRam[Ppu::SpriteRamSize]; - uint16_t *_outputBuffers[2]; uint16_t *_currentBuffer; - void RenderTilemap(LayerConfig & config, uint8_t bpp); + uint8_t _oamMode = 0; + uint8_t _oamBaseAddress = 0; + uint8_t _oamAddressOffset = 0; + + uint8_t _oamRam[Ppu::SpriteRamSize]; + uint16_t _oamRamAddress = 0; + bool _enableOamPriority = false; + + uint16_t _internalOamAddress = 0; + uint8_t _oamWriteBuffer = 0; + + void RenderTilemap(LayerConfig &config, uint8_t bpp); public: Ppu(shared_ptr console);