PPU: Added barebones implementation of PPU/DMA to allow test roms to display their result on screen

This commit is contained in:
Sour 2019-02-13 23:03:01 -05:00
parent aed9270e52
commit f0bd820264
2 changed files with 80 additions and 8 deletions

View file

@ -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;
}
}

View file

@ -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);