NESemu/src/PPU.cpp

157 lines
2.2 KiB
C++
Raw Normal View History

2022-02-28 15:04:25 +00:00
#include "PPU.hpp"
#include "Log.hpp"
#include "Bus.hpp"
PPU::PPU(Bus* bus) :
bus(bus), ppuctrl{0}, ppustatus{0}
{
}
void PPU::Powerup()
{
ppuctrl.Raw = 0b00000000;
ppumask.Raw = 0b00000000;
ppustatus.Raw = 0b10100000;
ppuscroll.x = 0x00;
ppuscroll.y = 0x00;
ppuaddr.Raw = 0x0000;
x = 0;
y = 0;
addressLatch = 0;
}
void PPU::Reset()
{
ppuctrl.Raw = 0b00000000;
ppumask.Raw = 0b00000000;
ppuscroll.x = 0x00;
ppuscroll.y = 0x00;
x = 0;
y = 0;
addressLatch = 1;
}
void PPU::Tick()
{
if (y == 241 && x == 1)
{
ppustatus.Flag.VBlankStarted = 1;
if (ppuctrl.Flag.VBlankNMI)
bus->NMI();
isFrameDone = true;
}
if (y == 261 && x == 1)
ppustatus.Flag.VBlankStarted = 0;
x++;
if (x > 340)
{
x = 0;
y++;
if (y > 261)
y = 0;
}
}
Byte PPU::ReadRegister(Byte id)
{
Byte returnVal = 0x00;
switch (id)
{
case 0:
returnVal = ppuctrl.Raw;
break;
case 1:
returnVal = ppumask.Raw;
break;
case 2:
returnVal = ppustatus.Raw;
ppustatus.Flag.VBlankStarted = 0;
addressLatch = 0;
break;
case 5:
returnVal = 0x00;
break;
case 6:
returnVal = 0x00;
break;
case 7:
returnVal = bus->ReadPPU(ppuaddr.Raw);
ppuaddr.Raw += (ppuctrl.Flag.VRAMAddrIncrement ? 32 : 1);
break;
default:
LOG_CORE_WARN("Tried to read unimplemented PPU register $20{0:02X}", (Word)id);
break;
}
return returnVal;
}
void PPU::WriteRegister(Byte id, Byte val)
{
switch (id)
{
case 0:
ppuctrl.Raw = val;
break;
case 1:
ppumask.Raw = val;
break;
case 2:
ppustatus.Raw = val;
break;
case 5:
if (addressLatch == 0)
ppuscroll.x = val;
else
ppuscroll.y = val;
addressLatch = 1 - addressLatch;
break;
case 6:
if (addressLatch == 0)
ppuaddr.Bytes.hi = val;
else
ppuaddr.Bytes.lo = val;
addressLatch = 1 - addressLatch;
break;
case 7:
bus->WritePPU(ppuaddr.Raw, val);
ppuaddr.Raw += (ppuctrl.Flag.VRAMAddrIncrement ? 32 : 1);
break;
default:
LOG_CORE_WARN("Tried to write unimplemented PPU register $20{0:02X}", (Word)id);
return;
}
ppustatus.Flag.Unused = val & 0x1F;
}
Byte PPU::Read(Word addr)
{
return bus->ReadPPU(addr);
}
void PPU::Write(Word addr, Byte val)
{
bus->WritePPU(addr, val);
}