2014-06-14 15:27:55 +00:00
|
|
|
#include "stdafx.h"
|
|
|
|
#include "Console.h"
|
2014-06-14 22:20:56 +00:00
|
|
|
#include "Timer.h"
|
2014-06-14 15:27:55 +00:00
|
|
|
|
2014-06-14 22:20:56 +00:00
|
|
|
Console::Console(string filename)
|
2014-06-14 15:27:55 +00:00
|
|
|
{
|
|
|
|
_mapper = MapperFactory::InitializeFromFile(filename);
|
2014-06-19 23:58:15 +00:00
|
|
|
_memoryManager.reset(new MemoryManager(_mapper->GetHeader()));
|
|
|
|
_cpu.reset(new CPU(_memoryManager.get()));
|
|
|
|
_ppu.reset(new PPU(_memoryManager.get()));
|
|
|
|
_memoryManager->RegisterIODevice(_mapper.get());
|
|
|
|
_memoryManager->RegisterIODevice(_ppu.get());
|
|
|
|
|
|
|
|
Reset();
|
2014-06-14 15:27:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Console::~Console()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void Console::Reset()
|
|
|
|
{
|
|
|
|
_cpu->Reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Console::Run()
|
|
|
|
{
|
2014-06-14 22:20:56 +00:00
|
|
|
while(true) {
|
|
|
|
_cpu->Exec();
|
2014-06-16 01:45:36 +00:00
|
|
|
_ppu->Exec();
|
2014-06-14 22:20:56 +00:00
|
|
|
}
|
2014-06-14 15:27:55 +00:00
|
|
|
}
|
|
|
|
|
2014-06-14 22:20:56 +00:00
|
|
|
void Console::RunTest(bool callback(Console*))
|
2014-06-14 15:27:55 +00:00
|
|
|
{
|
2014-06-19 02:54:23 +00:00
|
|
|
Timer timer;
|
|
|
|
uint32_t lastFrameCount = 0;
|
2014-06-14 22:20:56 +00:00
|
|
|
while(true) {
|
|
|
|
if(callback(this)) {
|
|
|
|
break;
|
|
|
|
}
|
2014-06-16 01:45:36 +00:00
|
|
|
|
|
|
|
_cpu->Exec();
|
|
|
|
_ppu->Exec();
|
2014-06-19 02:54:23 +00:00
|
|
|
|
2014-06-19 23:58:15 +00:00
|
|
|
if(timer.GetElapsedMS() > 2000) {
|
2014-06-19 02:54:23 +00:00
|
|
|
uint32_t frameCount = _ppu->GetFrameCount();
|
|
|
|
std::cout << ((frameCount - lastFrameCount) / (timer.GetElapsedMS() / 1000)) << std::endl;
|
|
|
|
timer.Reset();
|
|
|
|
lastFrameCount = frameCount;
|
|
|
|
}
|
2014-06-14 22:20:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Console::RunTests()
|
|
|
|
{
|
2014-06-19 23:58:15 +00:00
|
|
|
//(new Console("TestSuite/mario.nes"))->Run();
|
|
|
|
|
|
|
|
|
2014-06-19 02:54:23 +00:00
|
|
|
vector<string> testROMs {
|
2014-06-19 23:58:15 +00:00
|
|
|
//"Bomberman",
|
|
|
|
"IceClimber",
|
|
|
|
//"Excitebike",
|
|
|
|
//"dk",
|
2014-06-19 02:54:23 +00:00
|
|
|
"mario",
|
|
|
|
"01-basics",
|
2014-06-15 15:25:29 +00:00
|
|
|
"02-implied",
|
2014-06-16 01:45:36 +00:00
|
|
|
"03-immediate",
|
2014-06-19 02:54:23 +00:00
|
|
|
"04-zero_page",
|
|
|
|
"05-zp_xy",
|
2014-06-16 01:45:36 +00:00
|
|
|
"06-absolute",
|
2014-06-19 02:54:23 +00:00
|
|
|
"07-abs_xy",
|
|
|
|
"08-ind_x",
|
|
|
|
"09-ind_y",
|
2014-06-15 15:25:29 +00:00
|
|
|
"10-branches",
|
2014-06-19 02:54:23 +00:00
|
|
|
"11-stack",
|
|
|
|
"12-jmp_jsr",
|
|
|
|
"13-rts",
|
2014-06-16 01:45:36 +00:00
|
|
|
"14-rti",
|
2014-06-19 02:54:23 +00:00
|
|
|
"15-brk",
|
2014-06-15 15:25:29 +00:00
|
|
|
"16-special"
|
2014-06-16 01:45:36 +00:00
|
|
|
};
|
2014-06-14 22:20:56 +00:00
|
|
|
|
|
|
|
for(string testROM : testROMs) {
|
|
|
|
Console *console = new Console(string("TestSuite/") + testROM + ".nes");
|
|
|
|
if(testROM == "nestest") {
|
|
|
|
console->RunTest([] (Console *console) {
|
2014-06-16 01:45:36 +00:00
|
|
|
State state = console->_cpu->GetState();
|
|
|
|
std::cout << std::hex << std::uppercase <<
|
|
|
|
"A:" << std::setfill('0') << std::setw(2) << (short)state.A <<
|
|
|
|
" X:" << std::setfill('0') << std::setw(2) << (short)state.X <<
|
|
|
|
" Y:" << std::setfill('0') << std::setw(2) << (short)state.Y <<
|
|
|
|
" S:" << std::setfill('0') << std::setw(2) << (short)state.SP <<
|
|
|
|
" P:........ $" <<
|
|
|
|
std::setfill('0') << std::setw(4) << (short)state.PC <<std::endl;
|
2014-06-14 22:20:56 +00:00
|
|
|
return false;
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
console->RunTest([] (Console *console) {
|
2014-06-19 02:54:23 +00:00
|
|
|
//static std::ofstream output("test.log", ios::out | ios::binary);
|
2014-06-14 22:20:56 +00:00
|
|
|
static bool testStarted = false;
|
2014-06-19 23:58:15 +00:00
|
|
|
uint8_t testStatus = console->_memoryManager->Read(0x6000);
|
2014-06-15 15:25:29 +00:00
|
|
|
|
|
|
|
State state = console->_cpu->GetState();
|
2014-06-16 01:45:36 +00:00
|
|
|
/*output << std::hex << std::uppercase <<
|
|
|
|
"A:" << std::setfill('0') << std::setw(2) << (short)state.A <<
|
|
|
|
" X:" << std::setfill('0') << std::setw(2) << (short)state.X <<
|
|
|
|
" Y:" << std::setfill('0') << std::setw(2) << (short)state.Y <<
|
|
|
|
" S:" << std::setfill('0') << std::setw(2) << (short)state.SP <<
|
|
|
|
" P:........ $" <<
|
|
|
|
std::setfill('0') << std::setw(4) << (short)state.PC <<std::endl;*/
|
2014-06-15 15:25:29 +00:00
|
|
|
|
2014-06-14 22:20:56 +00:00
|
|
|
if(testStatus == 0x81) {
|
|
|
|
//need reset
|
2014-06-15 15:25:29 +00:00
|
|
|
std::cout << "reset needed";
|
2014-06-14 22:20:56 +00:00
|
|
|
} else if(testStatus == 0x80) {
|
|
|
|
testStarted = true;
|
|
|
|
} else if(testStatus < 0x80 && testStarted) {
|
2014-06-19 23:58:15 +00:00
|
|
|
char *result = console->_memoryManager->GetTestResult();
|
2014-06-15 15:25:29 +00:00
|
|
|
std::cout << result;
|
2014-06-14 22:20:56 +00:00
|
|
|
delete[] result;
|
|
|
|
testStarted = false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
delete console;
|
|
|
|
}
|
2014-06-14 15:27:55 +00:00
|
|
|
}
|