PPU: Added barebones implementation of PPU/DMA to allow test roms to display their result on screen
This commit is contained in:
parent
aed9270e52
commit
f0bd820264
2 changed files with 80 additions and 8 deletions
82
Core/Ppu.cpp
82
Core/Ppu.cpp
|
@ -1,7 +1,9 @@
|
|||
#include "stdafx.h"
|
||||
#include "Ppu.h"
|
||||
#include "Console.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "Cpu.h"
|
||||
#include "VideoDecoder.h"
|
||||
|
||||
Ppu::Ppu(shared_ptr<Console> console)
|
||||
{
|
||||
|
@ -64,12 +66,35 @@ void Ppu::Exec()
|
|||
|
||||
void Ppu::SendFrame()
|
||||
{
|
||||
for(int i = 0; i < 256 * 224; i++) {
|
||||
_currentBuffer[i] = i;
|
||||
}
|
||||
_currentBuffer = _currentBuffer == _outputBuffers[0] ? _outputBuffers[1] : _outputBuffers[0];
|
||||
uint16_t tilemapAddr = _layerConfig[0].TilemapAddress;
|
||||
uint16_t chrAddr = _layerConfig[0].ChrAddress;
|
||||
|
||||
//_console->GetVideoDecoder()->SendFrame(_currentBuffer);
|
||||
for(int y = 0; y < 28; y++) {
|
||||
for(int x = 0; x < 32; x++) {
|
||||
uint8_t byte1 = _vram[tilemapAddr + (y * 32 + x) * 2];
|
||||
uint8_t byte2 = _vram[tilemapAddr + (y * 32 + x) * 2 + 1];
|
||||
|
||||
uint8_t palette = (byte2 >> 2) & 0x07;
|
||||
uint16_t tileIndex = ((byte2 & 0x03) << 8) | byte1;
|
||||
|
||||
uint16_t tileStart = chrAddr + tileIndex * 8 * 2;
|
||||
for(int i = 0; i < 8; i++) {
|
||||
for(int j = 0; j < 8; j++) {
|
||||
uint8_t color = 0;
|
||||
for(int plane = 0; plane < 2; plane++) {
|
||||
color |= (((_vram[tileStart + i * 2 + plane] >> (7 - j)) & 0x01) << 2);
|
||||
color >>= 1;
|
||||
}
|
||||
|
||||
uint16_t paletteColor = _cgram[(palette * 4 + color) * 2] | (_cgram[(palette * 4 + color) * 2 + 1] << 8);
|
||||
_currentBuffer[(y * 8 + i) * 256 + x * 8 + j] = paletteColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_currentBuffer = _currentBuffer == _outputBuffers[0] ? _outputBuffers[1] : _outputBuffers[0];
|
||||
_console->GetVideoDecoder()->UpdateFrame(_currentBuffer, _frameCount);
|
||||
}
|
||||
|
||||
uint8_t Ppu::Read(uint16_t addr)
|
||||
|
@ -95,7 +120,7 @@ void Ppu::Write(uint32_t addr, uint8_t value)
|
|||
switch(addr) {
|
||||
case 0x2107: case 0x2108: case 0x2109: case 0x210A:
|
||||
//BG 1-4 Tilemap Address and Size (BG1SC, BG2SC, BG3SC, BG4SC)
|
||||
_layerConfig[addr - 0x2107].TilemapAddress = (value & 0xFC) << 8;
|
||||
_layerConfig[addr - 0x2107].TilemapAddress = (value & 0xFC) << 9;
|
||||
_layerConfig[addr - 0x2107].HorizontalMirrorring = (value & 0x01) != 0;
|
||||
_layerConfig[addr - 0x2107].VerticalMirrorring = (value & 0x02) != 0;
|
||||
break;
|
||||
|
@ -147,16 +172,59 @@ void Ppu::Write(uint32_t addr, uint8_t value)
|
|||
|
||||
case 0x2121:
|
||||
//CGRAM Address(CGADD)
|
||||
_cgramAddress = value;
|
||||
_cgramAddress = value * 2;
|
||||
break;
|
||||
|
||||
case 0x2122:
|
||||
//CGRAM Data write (CGDATA)
|
||||
_cgram[_cgramAddress] = value;
|
||||
_cgramAddress++;
|
||||
break;
|
||||
|
||||
case 0x4200:
|
||||
_enableNmi = (value & 0x80) != 0;
|
||||
break;
|
||||
|
||||
case 0x420B:
|
||||
//MDMAEN - DMA Enable
|
||||
if(value & 0x01) {
|
||||
for(int i = 0; i < _dmaSize; i++) {
|
||||
uint8_t valToWrite = _console->GetMemoryManager()->Read(_dmaSource, MemoryOperationType::Read);
|
||||
_console->GetMemoryManager()->Write(0x2100 | _dmaDest, valToWrite, MemoryOperationType::Write);
|
||||
_dmaSource++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x4300:
|
||||
//DMAPx - DMA Control for Channel x
|
||||
break;
|
||||
|
||||
case 0x4301:
|
||||
//BBADx - DMA Destination Register for Channel x
|
||||
_dmaDest = value;
|
||||
break;
|
||||
|
||||
case 0x4305:
|
||||
//DASxL - DMA Size / HDMA Indirect Address low byte(x = 0 - 7)
|
||||
_dmaSize = (_dmaSize & 0xFF00) | value;
|
||||
break;
|
||||
|
||||
case 0x4306:
|
||||
//DASxL - DMA Size / HDMA Indirect Address low byte(x = 0 - 7)
|
||||
_dmaSize = (_dmaSize & 0xFF) | (value << 8);
|
||||
break;
|
||||
|
||||
case 0x4302:
|
||||
_dmaSource = (_dmaSource & 0xFFFF00) | value;
|
||||
break;
|
||||
|
||||
case 0x4303:
|
||||
_dmaSource = (_dmaSource & 0xFF00FF) | (value << 8);
|
||||
break;
|
||||
|
||||
case 0x4304:
|
||||
_dmaSource = (_dmaSource & 0x00FFFF) | (value << 16);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,13 +22,17 @@ private:
|
|||
bool _vramAddrIncrementOnSecondReg;
|
||||
|
||||
uint16_t _cgramAddress;
|
||||
uint16_t _cgram[256];
|
||||
uint8_t _cgram[512];
|
||||
|
||||
uint16_t *_outputBuffers[2];
|
||||
uint16_t *_currentBuffer;
|
||||
|
||||
LayerConfig _layerConfig[4];
|
||||
|
||||
uint8_t _dmaDest = 0;
|
||||
uint32_t _dmaSource = 0;
|
||||
uint16_t _dmaSize = 0;
|
||||
|
||||
public:
|
||||
Ppu(shared_ptr<Console> console);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue