This commit is contained in:
Souryo 2014-06-15 09:35:17 -04:00
parent 177d53e8bf
commit 608c9a03cf
5 changed files with 62 additions and 36 deletions

View file

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

View file

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

View file

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

View file

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

View file

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