PPU, NMI
This commit is contained in:
parent
177d53e8bf
commit
608c9a03cf
5 changed files with 62 additions and 36 deletions
17
Core/CPU.cpp
17
Core/CPU.cpp
|
@ -3,6 +3,7 @@
|
|||
#include "Timer.h"
|
||||
|
||||
uint64_t CPU::CycleCount = 0;
|
||||
bool CPU::NMIFlag = false;
|
||||
|
||||
CPU::CPU(MemoryManager *memoryManager) : _memoryManager(memoryManager)
|
||||
{
|
||||
|
@ -63,11 +64,17 @@ void CPU::Reset()
|
|||
|
||||
void CPU::Exec()
|
||||
{
|
||||
uint8_t opCode = ReadByte();
|
||||
if(_opTable[opCode] != nullptr) {
|
||||
(this->*_opTable[opCode])();
|
||||
CPU::CycleCount += this->_cycles[opCode];
|
||||
if(!CPU::NMIFlag) {
|
||||
uint8_t opCode = ReadByte();
|
||||
if(_opTable[opCode] != nullptr) {
|
||||
(this->*_opTable[opCode])();
|
||||
CPU::CycleCount += this->_cycles[opCode];
|
||||
} else {
|
||||
//throw std::exception("Invalid opcode");
|
||||
}
|
||||
} else {
|
||||
//throw std::exception("Invalid opcode");
|
||||
NMI();
|
||||
CPU::CycleCount += 7;
|
||||
CPU::NMIFlag = false;
|
||||
}
|
||||
}
|
||||
|
|
20
Core/CPU.h
20
Core/CPU.h
|
@ -41,6 +41,7 @@ private:
|
|||
MemoryManager *_memoryManager = nullptr;
|
||||
|
||||
static uint64_t CycleCount;
|
||||
static bool NMIFlag;
|
||||
|
||||
uint16_t _currentPC = 0;
|
||||
uint8_t _cyclePenalty = 0;
|
||||
|
@ -592,6 +593,14 @@ private:
|
|||
SetPC(MemoryReadWord(0xFFFE));
|
||||
}
|
||||
|
||||
void NMI() {
|
||||
Push((uint16_t)(PC() + 1));
|
||||
Push((uint8_t)PS());
|
||||
SetFlags(PSFlags::Interrupt);
|
||||
SetPC(MemoryReadWord(0xFFFA));
|
||||
}
|
||||
|
||||
|
||||
void NOP() {}
|
||||
void RTI() {
|
||||
SetPS(Pop());
|
||||
|
@ -601,13 +610,10 @@ private:
|
|||
|
||||
public:
|
||||
CPU(MemoryManager *memoryManager);
|
||||
static uint64_t GetCycleCount() {
|
||||
return CPU::CycleCount;
|
||||
}
|
||||
static uint64_t GetCycleCount() { return CPU::CycleCount; }
|
||||
static void SetNMIFlag() { CPU::NMIFlag = true; }
|
||||
void Reset();
|
||||
void Exec();
|
||||
State GetState()
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
State GetState() { return _state; }
|
||||
|
||||
};
|
|
@ -12,7 +12,7 @@ Console::Console(string filename)
|
|||
|
||||
Console::~Console()
|
||||
{
|
||||
|
||||
_cpu.release();
|
||||
}
|
||||
|
||||
void Console::Reset()
|
||||
|
@ -46,7 +46,7 @@ void Console::RunTests()
|
|||
console->Run();
|
||||
delete console;*/
|
||||
|
||||
vector<std::string> testROMs = { { "nestest", "01-basics", "02-implied", "03-immediate", "04-zero_page", "05-zp_xy", "06-absolute", "07-abs_xy", "08-ind_x", "09-ind_y", "10-branches", "11-stack", "12-jmp_jsr", "13-rts", "14-rti", "15-brk", "16-special" } };
|
||||
vector<std::string> testROMs = { { "01-basics", "02-implied", "03-immediate", "04-zero_page", "05-zp_xy", "06-absolute", "07-abs_xy", "08-ind_x", "09-ind_y", "10-branches", "11-stack", "12-jmp_jsr", "13-rts", "14-rti", "15-brk", "16-special" } };
|
||||
|
||||
for(string testROM : testROMs) {
|
||||
Console *console = new Console(string("TestSuite/") + testROM + ".nes");
|
||||
|
@ -64,7 +64,7 @@ void Console::RunTests()
|
|||
uint8_t testStatus = console->_memoryManager.Read(0x6000);
|
||||
if(testStatus == 0x81) {
|
||||
//need reset
|
||||
throw std::exception("reset needed");
|
||||
OutputDebugStringA("reset needed");
|
||||
} else if(testStatus == 0x80) {
|
||||
testStarted = true;
|
||||
} else if(testStatus < 0x80 && testStarted) {
|
||||
|
|
48
Core/PPU.cpp
48
Core/PPU.cpp
|
@ -5,6 +5,8 @@
|
|||
PPU::PPU()
|
||||
{
|
||||
_state = {};
|
||||
_flags = {};
|
||||
_statusFlags = {};
|
||||
|
||||
_outputBuffer = new uint8_t[256 * 240 * 4];
|
||||
}
|
||||
|
@ -105,7 +107,8 @@ void PPU::UpdateStatusFlag()
|
|||
{
|
||||
_state.Status = ((uint8_t)_statusFlags.SpriteOverflow << 5) |
|
||||
((uint8_t)_statusFlags.Sprite0Hit << 6) |
|
||||
((uint8_t)_statusFlags.VerticalBlank << 7));
|
||||
((uint8_t)_statusFlags.VerticalBlank << 7);
|
||||
_statusFlags.VerticalBlank = false;
|
||||
}
|
||||
|
||||
void PPU::Exec()
|
||||
|
@ -113,14 +116,19 @@ void PPU::Exec()
|
|||
uint64_t equivalentCycleCount = CPU::GetCycleCount() * 3;
|
||||
while(_cycleCount < equivalentCycleCount) {
|
||||
if(_scanline == -1) {
|
||||
//Pre-render scanline
|
||||
if(_cycle == 1) {
|
||||
_statusFlags.SpriteOverflow = false;
|
||||
_statusFlags.Sprite0Hit = false;
|
||||
_statusFlags.VerticalBlank = false;
|
||||
} else if(_cycle == 304) {
|
||||
// Copy scroll latch into VRAMADDR register
|
||||
if(_flags.BackgroundEnabled || _flags.SpritesEnabled) {
|
||||
/*if(_flags.BackgroundEnabled || _flags.SpritesEnabled) {
|
||||
//p->registers.vramAddress = p->registers.vramLatch;
|
||||
}
|
||||
}*/
|
||||
} else if(_cycle == 339 && (_frameCount % 2 == 1)) {
|
||||
//Skip a cycle for odd frames
|
||||
_cycle++;
|
||||
}
|
||||
} else if(_scanline < 240) {
|
||||
if(_cycle == 254) {
|
||||
|
@ -136,38 +144,42 @@ void PPU::Exec()
|
|||
//Ppu_updateEndScanlineRegisters(p);
|
||||
}
|
||||
}
|
||||
} else if(_scanline == 240) {
|
||||
} else if(_scanline == 241) {
|
||||
//Start of VBlank
|
||||
if(_cycle == 1) {
|
||||
if(!_suppressVBlank) {
|
||||
_statusFlags.VerticalBlank = true;
|
||||
/*if(!_suppressVBlank) {
|
||||
// We're in VBlank
|
||||
Ppu_setStatus(p, STATUS_VBLANK_STARTED);
|
||||
p->cycleCount = 0;
|
||||
}*/
|
||||
if(_flags.VBlank) {
|
||||
CPU::SetNMIFlag();
|
||||
}
|
||||
if(_flags.VBlank && !_suppressNMI) {
|
||||
/*if(_flags.VBlank && !_suppressNMI) {
|
||||
VBlankInterrupt();
|
||||
}
|
||||
}*/
|
||||
//Ppu_raster(p);
|
||||
}
|
||||
} else if(_scanline == 260) {
|
||||
// End of vblank
|
||||
if(_cycle == 1) {
|
||||
// Clear VBlank flag
|
||||
Ppu_clearStatus(p, STATUS_VBLANK_STARTED);
|
||||
_cycleCount = 0;
|
||||
} else if(_cycle == 341) {
|
||||
_scanline = -1;
|
||||
_cycle = 1;
|
||||
//End of VBlank
|
||||
if(_cycle == 340) {
|
||||
_frameCount++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(_cycle == 341) {
|
||||
if(_cycle == 340) {
|
||||
_cycle = 0;
|
||||
_scanline++;
|
||||
|
||||
if(_scanline == 261) {
|
||||
_scanline = -1;
|
||||
_frameCount++;
|
||||
}
|
||||
} else {
|
||||
_cycle++;
|
||||
}
|
||||
|
||||
_cycle++;
|
||||
_cycleCount++;
|
||||
}
|
||||
}
|
|
@ -64,9 +64,10 @@ class PPU : public IMemoryHandler
|
|||
|
||||
int16_t _scanline = -1;
|
||||
uint16_t _cycle = 0;
|
||||
uint32_t _frameCount = 0;
|
||||
|
||||
PPUControlFlags _flags = {};
|
||||
PPUStatusFlags _statusFlags = {};
|
||||
PPUControlFlags _flags;
|
||||
PPUStatusFlags _statusFlags;
|
||||
|
||||
void PPU::UpdateStatusFlag();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue