Fixed release mode crashes (operation order is undetermined in expression evaluation)

This commit is contained in:
Souryo 2014-06-11 21:30:35 -04:00
parent 4c5dbdcb42
commit 6ffeb46732
5 changed files with 222 additions and 310 deletions

95
CPU.cpp
View file

@ -2,7 +2,53 @@
#include "CPU.h"
#include "Timer.h"
void Core::Reset()
CPU::CPU(MemoryManager *memoryManager) : _memoryManager(memoryManager)
{
Reset();
Func opTable[] = {
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
&CPU::BRK, &CPU::ORA_IndX, nullptr, nullptr, nullptr, &CPU::ORA_Zero, &CPU::ASL_Zero, nullptr, &CPU::PHP, &CPU::ORA_Imm, &CPU::ASL_Acc, nullptr, nullptr, &CPU::ORA_Abs, &CPU::ASL_Abs, nullptr, //0
&CPU::BPL, &CPU::ORA_IndY, nullptr, nullptr, nullptr, &CPU::ORA_ZeroX, &CPU::ASL_ZeroX, nullptr, &CPU::CLC, &CPU::ORA_AbsY, nullptr, nullptr, nullptr, &CPU::ORA_AbsX, &CPU::ASL_AbsX, nullptr, //1
&CPU::JSR, &CPU::AND_IndX, nullptr, nullptr, &CPU::BIT_Zero, &CPU::AND_Zero, &CPU::ROL_Zero, nullptr, &CPU::PLP, &CPU::AND_Imm, &CPU::ROL_Acc, nullptr, &CPU::BIT_Abs, &CPU::AND_Abs, &CPU::ROL_Abs, nullptr, //2
&CPU::BMI, &CPU::AND_IndY, nullptr, nullptr, nullptr, &CPU::AND_ZeroX, &CPU::ROL_ZeroX, nullptr, &CPU::SEC, &CPU::AND_AbsY, nullptr, nullptr, nullptr, &CPU::AND_AbsX, &CPU::ROL_AbsX, nullptr, //3
&CPU::RTI, &CPU::EOR_IndX, nullptr, nullptr, nullptr, &CPU::EOR_Zero, &CPU::LSR_Zero, nullptr, &CPU::PHA, &CPU::EOR_Imm, &CPU::LSR_Acc, nullptr, &CPU::JMP_Abs, &CPU::EOR_Abs, &CPU::LSR_Abs, nullptr, //4
&CPU::BVC, &CPU::EOR_IndY, nullptr, nullptr, nullptr, &CPU::EOR_ZeroX, &CPU::LSR_ZeroX, nullptr, &CPU::CLI, &CPU::EOR_AbsY, nullptr, nullptr, nullptr, &CPU::EOR_AbsX, &CPU::LSR_AbsX, nullptr, //5
&CPU::RTS, &CPU::ADC_IndX, nullptr, nullptr, nullptr, &CPU::ADC_Zero, &CPU::ROR_Zero, nullptr, &CPU::PLA, &CPU::ADC_Imm, &CPU::ROR_Acc, nullptr, &CPU::JMP_Ind, &CPU::ADC_Abs, &CPU::ROR_Abs, nullptr, //6
&CPU::BVS, &CPU::ADC_IndY, nullptr, nullptr, nullptr, &CPU::ADC_ZeroX, &CPU::ROR_ZeroX, nullptr, &CPU::SEI, &CPU::ADC_AbsY, nullptr, nullptr, nullptr, &CPU::ADC_AbsX, &CPU::ROR_AbsX, nullptr, //7
nullptr, &CPU::STA_IndX, nullptr, nullptr, &CPU::STY_Zero, &CPU::STA_Zero, &CPU::STX_Zero, nullptr, &CPU::DEY, nullptr, &CPU::TXA, nullptr, &CPU::STY_Abs, &CPU::STA_Abs, &CPU::STX_Abs, nullptr, //8
&CPU::BCC, &CPU::STA_IndY, nullptr, nullptr, &CPU::STY_ZeroX, &CPU::STA_ZeroX, &CPU::STX_ZeroY, nullptr, &CPU::TYA, &CPU::STA_AbsY, &CPU::TXS, nullptr, nullptr, &CPU::STA_AbsX, nullptr, nullptr, //9
&CPU::LDY_Imm, &CPU::LDA_IndX, &CPU::LDX_Imm, nullptr, &CPU::LDY_Zero, &CPU::LDA_Zero, &CPU::LDX_Zero, nullptr, &CPU::TAY, &CPU::LDA_Imm, &CPU::TAX, nullptr, &CPU::LDY_Abs, &CPU::LDA_Abs, &CPU::LDX_Abs, nullptr, //A
&CPU::BCS, &CPU::LDA_IndY, nullptr, nullptr, &CPU::LDY_ZeroX, &CPU::LDA_ZeroX, &CPU::LDX_ZeroY, nullptr, &CPU::CLV, &CPU::LDA_AbsY, &CPU::TSX, nullptr, &CPU::LDY_AbsX, &CPU::LDA_AbsX, &CPU::LDX_AbsY, nullptr, //B
&CPU::CPY_Imm, &CPU::CMP_IndX, nullptr, nullptr, &CPU::CPY_Zero, &CPU::CMP_Zero, &CPU::DEC_Zero, nullptr, &CPU::INY, &CPU::CMP_Imm, &CPU::DEX, nullptr, &CPU::CPY_Abs, &CPU::CMP_Abs, &CPU::DEC_Abs, nullptr, //C
&CPU::BNE, &CPU::CMP_IndY, nullptr, nullptr, nullptr, &CPU::CMP_ZeroX, &CPU::DEC_ZeroX, nullptr, &CPU::CLD, &CPU::CMP_AbsY, nullptr, nullptr, nullptr, &CPU::CMP_AbsX, &CPU::DEC_AbsX, nullptr, //D
&CPU::CPX_Imm, &CPU::SBC_IndX, nullptr, nullptr, &CPU::CPX_Zero, &CPU::SBC_Zero, &CPU::INC_Zero, nullptr, &CPU::INX, &CPU::SBC_Imm, &CPU::NOP, nullptr, &CPU::CPX_Abs, &CPU::SBC_Abs, &CPU::INC_Abs, nullptr, //E
&CPU::BEQ, &CPU::SBC_IndY, nullptr, nullptr, nullptr, &CPU::SBC_ZeroX, &CPU::INC_ZeroX, nullptr, &CPU::SED, &CPU::SBC_AbsY, nullptr, nullptr, nullptr, &CPU::SBC_AbsX, &CPU::INC_AbsX, nullptr //F
};
uint8_t cycles[] = {
7,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,
2,5,2,8,4,4,6,6,2,4,2,7,5,5,7,7,
6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,
2,5,2,8,4,4,6,6,2,4,2,7,5,5,7,7,
6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,
2,5,2,8,4,4,6,6,2,4,2,7,5,5,7,7,
6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,
2,5,2,8,4,4,6,6,2,4,2,7,5,5,7,7,
2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,
2,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,
2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,
2,5,2,5,4,4,4,4,2,4,2,5,4,4,4,4,
2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,
2,5,2,8,4,4,6,6,2,4,2,7,5,5,7,7,
2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,
2,5,2,8,4,4,6,6,2,4,2,7,5,5,7,7
};
memcpy(_opTable, opTable, sizeof(Func) * 256);
memcpy(_cycles, cycles, sizeof(uint8_t) * 256);
}
void CPU::Reset()
{
_state.A = 0;
_state.PC = 0x0400;
@ -12,29 +58,60 @@ void Core::Reset()
_state.PS = PSFlags::Zero | PSFlags::Reserved;// | PSFlags::Interrupt;
}
void Core::Exec()
void CPU::Exec()
{
uint16_t lastPC = 65535;
int executedCount = 0;
std::list<int> pcList;
uint32_t cycleCount = 0;
Timer timer;
while(true) {
_currentPC = _state.PC;
uint8_t opCode = ReadByte();
if(_opTable[opCode] != 0) {
if(_opTable[opCode] != nullptr) {
(this->*_opTable[opCode])();
cycleCount += this->_cycles[opCode];
//std::cout << "OPCode: " << std::hex << (short)opCode << " PC:" << _currentPC << std::endl;
} else {
std::cout << "Invalid opcode: PC:" << _currentPC << std::endl;
throw;
}
lastPC = _currentPC;
executedCount++;
if(executedCount >= 200000000) {
if(cycleCount >= 200000000) {
break;
}
}
std::cout << "Executed:" << executedCount << " in " << timer.GetElapsedMS() << " ms";
std::wstring result = L"Frequency: " + std::to_wstring((int)(cycleCount / timer.GetElapsedMS() * 1000 / 1000000)) + L"mhz\n";
OutputDebugString(result.c_str());
}
class Test : public IMemoryHandler
{
public:
int _counter = 0;
public:
void MemoryRead(uint16_t aa) {
//_counter++;
}
void MemoryWrite(uint16_t aa) {
}
};
void CPU::RunBenchmark()
{
std::ifstream romFile("6502_functional_test.bin", std::ios::in | std::ios::binary);
if(!romFile) {
std::cout << "Error";
}
uint8_t *romMemory = new uint8_t[65536];
romFile.read((char *)romMemory, 65536);
Test a;
MemoryManager memoryManager(romMemory);
memoryManager.OnMemoryRead()->RegisterHandler(&a, &IMemoryHandler::MemoryRead);
CPU core(&memoryManager);
core.Exec();
}

366
CPU.h
View file

@ -1,4 +1,5 @@
#include "stdafx.h"
#include "Memory.h"
namespace PSFlags
{
@ -25,24 +26,30 @@ struct State
uint8_t PS;
};
class Core
class CPU
{
private:
typedef void(Core::*Func)();
typedef void(CPU::*Func)();
Func _opTable[256];
State _state;
int8_t* _memory;
uint16_t _currentPC;
uint8_t _cycles[256];
inline uint8_t Core::ReadByte()
State _state;
MemoryManager *_memoryManager = nullptr;
uint16_t _currentPC = 0;
uint8_t _cyclePenalty = 0;
uint8_t ReadByte()
{
return _memory[_state.PC++];
return MemoryRead(_state.PC++);
}
uint16_t Core::ReadWord()
uint16_t ReadWord()
{
uint16_t value = (uint16_t)(((uint8_t)_memory[_state.PC] | (((uint8_t)_memory[_state.PC + 1]) << 8)));
uint16_t value = MemoryReadWord(PC());
_state.PC += 2;
return value;
}
@ -52,12 +59,8 @@ private:
_state.PS &= ~flags;
}
uint16_t lastNegative = 0;
void SetFlags(uint8_t flags)
{
if(flags & PSFlags::Negative) {
lastNegative = _state.PC;
}
_state.PS |= flags;
}
@ -75,26 +78,29 @@ private:
}
}
bool IsPageCrossed(uint16_t valA, uint8_t valB)
{
return (uint8_t)valA + valB >= 0x100;
}
void MemoryWrite(uint16_t addr, uint8_t value)
{
//SetZeroNegativeFlags(value);
_memory[addr] = value;
if(addr == 0x200) {
_memoryManager->Write(addr, value);
/*if(addr == 0x200) {
std::cout << "------------------" << std::endl;
std::cout << "TEST NUMBER: " << std::dec << (int)value << std::endl;
std::cout << "(0x" << std::hex << (short)_currentPC << ") TEST NUMBER: " << std::dec << (int)value << std::endl;
std::cout << "------------------" << std::endl;
} else {
//std::cout << "(0x" << std::hex << (short)_currentPC << ") W: 0x" << std::hex << (short)addr << " = 0x" << std::hex << (short)value << std::endl;
}
}*/
}
uint8_t MemoryRead(uint16_t addr) {
//std::cout << "\t\t\t\t(0x" << std::hex << (short)_currentPC << ") R: 0x" << std::hex << (short)addr << " = 0x" << std::hex << (short)_memory[addr] << std::endl;
return _memory[addr];
return _memoryManager->Read(addr);
}
uint16_t MemoryReadWord(uint16_t addr) {
return (_memory[addr] | (_memory[addr + 1] << 8));
return _memoryManager->ReadWord(addr);
}
void SetRegister(uint8_t &reg, int8_t value) {
@ -104,7 +110,7 @@ private:
}
void Push(uint8_t value) {
_memory[SP() + 0x100] = value;
MemoryWrite(SP() + 0x100, value);
SetSP(SP() - 1);
}
@ -115,12 +121,14 @@ private:
uint8_t Pop() {
SetSP(SP() + 1);
int8_t value = _memory[0x100 + SP()];
return value;
return MemoryRead(0x100 + SP());
}
uint16_t PopWord() {
return Pop() | (Pop() << 8);
uint8_t lo = Pop();
uint8_t hi = Pop();
return lo | hi << 8;
}
uint8_t A() { return _state.A; }
@ -145,52 +153,55 @@ private:
int8_t GetZeroY() { return MemoryRead(GetZeroYAddr()); }
int8_t GetZeroYAddr() { return ReadByte() + Y(); }
int8_t GetAbs() { return MemoryRead(GetAbsAddr()); }
uint16_t GetAbsAddr() { return ReadWord(); }
int8_t GetAbsX() { return MemoryRead(GetAbsXAddr()); }
uint16_t GetAbsXAddr() {
return ReadWord() + X();
uint16_t GetAbsXAddr() {
uint16_t baseAddr = ReadWord();
if(IsPageCrossed(baseAddr, X())) {
SetCyclePenalty(1);
}
return baseAddr + X();
}
int8_t GetAbsY() { return MemoryRead(GetAbsYAddr()); }
uint16_t GetAbsYAddr() {
return ReadWord() + Y();
uint16_t GetAbsYAddr() {
uint16_t baseAddr = ReadWord();
if(IsPageCrossed(baseAddr, Y())) {
SetCyclePenalty(1);
}
return baseAddr + Y();
}
uint16_t GetInd() { return MemoryReadWord(ReadByte() | (ReadByte() << 8)); }
uint16_t GetInd() { return MemoryReadWord(ReadWord()); }
int8_t GetIndX() { return MemoryRead(GetIndXAddr()); }
uint16_t GetIndXAddr() {
uint8_t zero = ReadByte() + X();
//std::cout << (int)zero << std::endl;
uint16_t addr = MemoryRead(zero) | (MemoryRead(zero + 1) << 8);
uint16_t addr = MemoryReadWord(zero);
return addr;
}
int8_t GetIndY() { return MemoryRead(GetIndYAddr()); }
uint16_t GetIndYAddr() {
uint8_t zero = ReadByte();
//std::cout << (int)zero << std::endl;
uint16_t addr = MemoryRead(zero) | (MemoryRead(zero + 1) << 8);
uint16_t addr = MemoryReadWord(zero);
if(IsPageCrossed(addr, Y())) {
SetCyclePenalty(1);
}
return addr + Y();
}
void AND(int8_t value) { SetA(A() & value); }
void XOR(int8_t value) {
SetA(A() ^ value);
}
void XOR(int8_t value) { SetA(A() ^ value); }
void OR(int8_t value) { SetA(A() | value); }
void ADC(uint8_t value) {
uint16_t result = (uint16_t)A() + (uint16_t)value + (CheckFlag(PSFlags::Carry) ? PSFlags::Carry : 0x00);
if(result == 0x100) {
//std::cout << std::hex << (short)A() << " + " << (short)value << (CheckFlag(PSFlags::Carry) ? "(+1) " : "") << " = " << (short)result << std::endl;
}
ClearFlags(PSFlags::Carry | PSFlags::Negative | PSFlags::Overflow | PSFlags::Zero);
SetZeroNegativeFlags((uint8_t)result);
if(~(A() ^ value) & (A() ^ result) & 0x80) {
@ -202,18 +213,7 @@ private:
SetA((uint8_t)result);
}
void SBC(int8_t value) {
ADC(value ^ 0xFF);
/*uint8_t result = A() - (value - ~(CheckFlag(PSFlags::Carry) ? PSFlags::Carry : 0x00));
ClearFlags(PSFlags::Carry | PSFlags::Negative | PSFlags::Overflow | PSFlags::Zero);
if (result & 0x80) {
SetFlags(PSFlags::Overflow);
}
SetA(result);*/
}
void SBC(int8_t value) { ADC(value ^ 0xFF); }
void CMP(uint8_t reg, uint8_t value) {
ClearFlags(PSFlags::Carry | PSFlags::Negative | PSFlags::Zero);
@ -315,22 +315,55 @@ private:
}
void JMP(uint16_t addr) {
_state.PC = addr;
//std::cout << "JMP from 0x" << std::hex << _currentPC << " to " << addr << std::endl;
SetPC(addr);
}
void BranchRelative(bool branch) {
int8_t offset = GetImmediate();
if(branch) {
if(IsPageCrossed(PC(), offset)) {
SetCyclePenalty(2);
} else {
SetCyclePenalty(1);
}
SetPC(PC() + offset);
if(_currentPC == PC()) {
std::cout << "Infinite loop at: 0x" << std::hex << (short)_currentPC;
std::cout << std::endl;
Reset();
if(_currentPC != 0x33a7) {
std::cout << "Infinite loop at: 0x" << std::hex << (short)_currentPC;
std::cout << std::endl;
} else {
Reset();
}
}
}
}
#pragma region OP Codes
void BIT(uint8_t value) {
ClearFlags(PSFlags::Zero | PSFlags::Overflow | PSFlags::Negative);
if((A() & value) == 0) {
SetFlags(PSFlags::Zero);
}
if(value & 0x40) {
SetFlags(PSFlags::Overflow);
}
if(value & 0x80) {
SetFlags(PSFlags::Negative);
}
}
void SetCyclePenalty(uint8_t penalty) {
_cyclePenalty = penalty;
}
uint8_t GetCyclePenalty() {
uint8_t penalty = _cyclePenalty;
_cyclePenalty = 0;
return penalty;
}
#pragma region OP Codes
void LDA_Imm() { SetA(GetImmediate()); }
void LDA_Zero() { SetA(GetZero()); }
void LDA_ZeroX() { SetA(GetZeroX()); }
@ -352,21 +385,21 @@ private:
void LDY_Abs() { SetY(GetAbs()); }
void LDY_AbsX() { SetY(GetAbsX()); }
void STA_Zero() { MemoryWrite(ReadByte(), A()); }
void STA_ZeroX() { MemoryWrite((uint8_t)(ReadByte() + X()), A()); }
void STA_Abs() { MemoryWrite(ReadWord(), A()); }
void STA_Zero() { MemoryWrite(GetZeroAddr(), A()); }
void STA_ZeroX() { MemoryWrite(GetZeroXAddr(), A()); }
void STA_Abs() { MemoryWrite(GetAbsAddr(), A()); }
void STA_AbsX() { MemoryWrite(GetAbsXAddr(), A()); }
void STA_AbsY() { MemoryWrite(GetAbsYAddr(), A()); }
void STA_IndX() { MemoryWrite(GetIndXAddr(), A()); }
void STA_IndY() { MemoryWrite(GetIndYAddr(), A()); }
void STX_Zero() { MemoryWrite(ReadByte(), X()); }
void STX_ZeroY() { MemoryWrite((uint8_t)(ReadByte() + Y()), X()); }
void STX_Abs() { MemoryWrite(ReadWord(), X()); }
void STX_Zero() { MemoryWrite(GetZeroAddr(), X()); }
void STX_ZeroY() { MemoryWrite(GetZeroYAddr(), X()); }
void STX_Abs() { MemoryWrite(GetAbsAddr(), X()); }
void STY_Zero() { MemoryWrite(ReadByte(), Y()); }
void STY_ZeroX() { MemoryWrite((uint8_t)(ReadByte() + X()), Y()); }
void STY_Abs() { MemoryWrite(ReadWord(), Y()); }
void STY_Zero() { MemoryWrite(GetZeroAddr(), Y()); }
void STY_ZeroX() { MemoryWrite(GetZeroXAddr(), Y()); }
void STY_Abs() { MemoryWrite(GetAbsAddr(), Y()); }
void TAX() { SetX(A()); }
void TAY() { SetY(A()); }
@ -410,19 +443,6 @@ private:
void ORA_IndX() { OR(GetIndX()); }
void ORA_IndY() { OR(GetIndY()); }
void BIT(uint8_t value) {
ClearFlags(PSFlags::Zero | PSFlags::Overflow | PSFlags::Negative);
if((A() & value) == 0) {
SetFlags(PSFlags::Zero);
}
if(value & 0x40) {
SetFlags(PSFlags::Overflow);
}
if(value & 0x80) {
SetFlags(PSFlags::Negative);
}
}
void BIT_Zero() {
BIT(GetZero());
}
@ -504,20 +524,19 @@ private:
void ROR_AbsX() { RORAddr(GetAbsXAddr()); }
void JMP_Abs() {
auto currentPC = _state.PC - 1;
auto newPC = ReadWord();
if(currentPC == newPC) {
std::cout << "Infinite loop at: " << std::hex << (short)newPC << std::endl;
}
JMP(newPC);
JMP(GetAbsAddr());
}
void JMP_Ind() { JMP(GetInd()); }
void JSR() {
Push((uint16_t)(PC() + 1));
JMP(GetAbsAddr());
uint16_t addr = GetAbsAddr();
//std::cout << "JSR from 0x" << std::hex << _currentPC << " to " << addr;
Push((uint16_t)(PC() - 1));
JMP(addr);
}
void RTS() {
SetPC(PopWord() + 1);
uint16_t addr = PopWord();
//std::cout << "RTS from 0x" << std::hex << _currentPC << " to " << addr;
SetPC(addr + 1);
}
void BCC() {
@ -566,7 +585,8 @@ private:
Push((uint8_t)PS());
SetFlags(PSFlags::Interrupt);
ClearFlags(PSFlags::Break);
SetPC((uint8_t)_memory[0xFFFE] | ((uint8_t)_memory[0xFFFF] << 8));
SetPC(MemoryReadWord(0xFFFE));
}
void NOP() {}
@ -574,163 +594,11 @@ private:
SetPS(Pop());
SetPC(PopWord());
}
#pragma endregion
#pragma endregion
public:
Core(int8_t *memory) : _memory(memory) {
Reset();
memset(_opTable, 0, 256 * sizeof(void*));
_opTable[0x00] = &Core::BRK;
_opTable[0x01] = &Core::ORA_IndX;
_opTable[0x05] = &Core::ORA_Zero;
_opTable[0x06] = &Core::ASL_Zero;
_opTable[0x08] = &Core::PHP;
_opTable[0x09] = &Core::ORA_Imm;
_opTable[0x0A] = &Core::ASL_Acc;
_opTable[0x0D] = &Core::ORA_Abs;
_opTable[0x0E] = &Core::ASL_Abs;
_opTable[0x10] = &Core::BPL;
_opTable[0x11] = &Core::ORA_IndY;
_opTable[0x15] = &Core::ORA_ZeroX;
_opTable[0x16] = &Core::ASL_ZeroX;
_opTable[0x18] = &Core::CLC;
_opTable[0x19] = &Core::ORA_AbsY;
_opTable[0x1D] = &Core::ORA_AbsX;
_opTable[0x1E] = &Core::ASL_AbsX;
_opTable[0x20] = &Core::JSR;
_opTable[0x21] = &Core::AND_IndX;
_opTable[0x24] = &Core::BIT_Zero;
_opTable[0x25] = &Core::AND_Zero;
_opTable[0x26] = &Core::ROL_Zero;
_opTable[0x28] = &Core::PLP;
_opTable[0x29] = &Core::AND_Imm;
_opTable[0x2A] = &Core::ROL_Acc;
_opTable[0x2C] = &Core::BIT_Abs;
_opTable[0x2D] = &Core::AND_Abs;
_opTable[0x2E] = &Core::ROL_Abs;
_opTable[0x30] = &Core::BMI;
_opTable[0x31] = &Core::AND_IndY;
_opTable[0x35] = &Core::AND_ZeroX;
_opTable[0x36] = &Core::ROL_ZeroX;
_opTable[0x38] = &Core::SEC;
_opTable[0x39] = &Core::AND_AbsY;
_opTable[0x3D] = &Core::AND_AbsX;
_opTable[0x3E] = &Core::ROL_AbsX;
_opTable[0x40] = &Core::RTI;
_opTable[0x41] = &Core::EOR_IndX;
_opTable[0x45] = &Core::EOR_Zero;
_opTable[0x46] = &Core::LSR_Zero;
_opTable[0x48] = &Core::PHA;
_opTable[0x49] = &Core::EOR_Imm;
_opTable[0x4A] = &Core::LSR_Acc;
_opTable[0x4C] = &Core::JMP_Abs;
_opTable[0x4D] = &Core::EOR_Abs;
_opTable[0x4E] = &Core::LSR_Abs;
_opTable[0x50] = &Core::BVC;
_opTable[0x51] = &Core::EOR_IndY;
_opTable[0x55] = &Core::EOR_ZeroX;
_opTable[0x56] = &Core::LSR_ZeroX;
_opTable[0x58] = &Core::CLI;
_opTable[0x59] = &Core::EOR_AbsY;
_opTable[0x5D] = &Core::EOR_AbsX;
_opTable[0x5E] = &Core::LSR_AbsX;
_opTable[0x60] = &Core::RTS;
_opTable[0x61] = &Core::ADC_IndX;
_opTable[0x65] = &Core::ADC_Zero;
_opTable[0x66] = &Core::ROR_Zero;
_opTable[0x68] = &Core::PLA;
_opTable[0x69] = &Core::ADC_Imm;
_opTable[0x6A] = &Core::ROR_Acc;
_opTable[0x6C] = &Core::JMP_Ind;
_opTable[0x6D] = &Core::ADC_Abs;
_opTable[0x6E] = &Core::ROR_Abs;
_opTable[0x70] = &Core::BVS;
_opTable[0x71] = &Core::ADC_IndY;
_opTable[0x75] = &Core::ADC_ZeroX;
_opTable[0x76] = &Core::ROR_ZeroX;
_opTable[0x78] = &Core::SEI;
_opTable[0x79] = &Core::ADC_AbsY;
_opTable[0x7D] = &Core::ADC_AbsX;
_opTable[0x7E] = &Core::ROR_AbsX;
_opTable[0x81] = &Core::STA_IndX;
_opTable[0x84] = &Core::STY_Zero;
_opTable[0x85] = &Core::STA_Zero;
_opTable[0x86] = &Core::STX_Zero;
_opTable[0x88] = &Core::DEY;
_opTable[0x8A] = &Core::TXA;
_opTable[0x8C] = &Core::STY_Abs;
_opTable[0x8D] = &Core::STA_Abs;
_opTable[0x8E] = &Core::STX_Abs;
_opTable[0x90] = &Core::BCC;
_opTable[0x91] = &Core::STA_IndY;
_opTable[0x94] = &Core::STY_ZeroX;
_opTable[0x95] = &Core::STA_ZeroX;
_opTable[0x96] = &Core::STX_ZeroY;
_opTable[0x98] = &Core::TYA;
_opTable[0x99] = &Core::STA_AbsY;
_opTable[0x9A] = &Core::TXS;
_opTable[0x9D] = &Core::STA_AbsX;
_opTable[0xA0] = &Core::LDY_Imm;
_opTable[0xA1] = &Core::LDA_IndX;
_opTable[0xA2] = &Core::LDX_Imm;
_opTable[0xA4] = &Core::LDY_Zero;
_opTable[0xA5] = &Core::LDA_Zero;
_opTable[0xA6] = &Core::LDX_Zero;
_opTable[0xA8] = &Core::TAY;
_opTable[0xA9] = &Core::LDA_Imm;
_opTable[0xAA] = &Core::TAX;
_opTable[0xAC] = &Core::LDY_Abs;
_opTable[0xAD] = &Core::LDA_Abs;
_opTable[0xAE] = &Core::LDX_Abs;
_opTable[0xB0] = &Core::BCS;
_opTable[0xB1] = &Core::LDA_IndY;
_opTable[0xB4] = &Core::LDY_ZeroX;
_opTable[0xB5] = &Core::LDA_ZeroX;
_opTable[0xB6] = &Core::LDX_ZeroY;
_opTable[0xB8] = &Core::CLV;
_opTable[0xB9] = &Core::LDA_AbsY;
_opTable[0xBA] = &Core::TSX;
_opTable[0xBC] = &Core::LDY_AbsX;
_opTable[0xBD] = &Core::LDA_AbsX;
_opTable[0xBE] = &Core::LDX_AbsY;
_opTable[0xC0] = &Core::CPY_Imm;
_opTable[0xC1] = &Core::CMP_IndX;
_opTable[0xC4] = &Core::CPY_Zero;
_opTable[0xC5] = &Core::CMP_Zero;
_opTable[0xC6] = &Core::DEC_Zero;
_opTable[0xC8] = &Core::INY;
_opTable[0xC9] = &Core::CMP_Imm;
_opTable[0xCA] = &Core::DEX;
_opTable[0xCC] = &Core::CPY_Abs;
_opTable[0xCD] = &Core::CMP_Abs;
_opTable[0xCE] = &Core::DEC_Abs;
_opTable[0xD0] = &Core::BNE;
_opTable[0xD1] = &Core::CMP_IndY;
_opTable[0xD5] = &Core::CMP_ZeroX;
_opTable[0xD6] = &Core::DEC_ZeroX;
_opTable[0xD8] = &Core::CLD;
_opTable[0xD9] = &Core::CMP_AbsY;
_opTable[0xDD] = &Core::CMP_AbsX;
_opTable[0xDE] = &Core::DEC_AbsX;
_opTable[0xE0] = &Core::CPX_Imm;
_opTable[0xE1] = &Core::SBC_IndX;
_opTable[0xE4] = &Core::CPX_Zero;
_opTable[0xE5] = &Core::SBC_Zero;
_opTable[0xE6] = &Core::INC_Zero;
_opTable[0xE8] = &Core::INX;
_opTable[0xE9] = &Core::SBC_Imm;
_opTable[0xEA] = &Core::NOP;
_opTable[0xEC] = &Core::CPX_Abs;
_opTable[0xED] = &Core::SBC_Abs;
_opTable[0xEE] = &Core::INC_Abs;
_opTable[0xF0] = &Core::BEQ;
_opTable[0xF1] = &Core::SBC_IndY;
_opTable[0xF5] = &Core::SBC_ZeroX;
_opTable[0xF6] = &Core::INC_ZeroX;
_opTable[0xF8] = &Core::SED;
_opTable[0xF9] = &Core::SBC_AbsY;
_opTable[0xFD] = &Core::SBC_AbsX;
_opTable[0xFE] = &Core::INC_AbsX;
}
CPU(MemoryManager *memoryManager);
void Reset();
void Exec();
static void RunBenchmark();
};

View file

@ -73,7 +73,8 @@
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<OmitFramePointers>true</OmitFramePointers>
<OmitFramePointers>false</OmitFramePointers>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -87,6 +88,8 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="CPU.h" />
<ClInclude Include="EventHandler.h" />
<ClInclude Include="Memory.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
@ -95,6 +98,7 @@
<ClCompile Include="CPU.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="Timer.h" />
</ItemGroup>

View file

@ -27,6 +27,12 @@
<ClInclude Include="CPU.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="EventHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Memory.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">

View file

@ -2,44 +2,6 @@
#include "CPU.h"
/*
template<typename... Types>
class Event
{
typedef void(*Func)(Types...);
private:
std::list<Func> handlerList;
Func lastFunc;
public:
void RegisterHandler(Func handler);
void operator+=(Func handler);
void operator()(Types ...types);
};
template<typename... Types>
void Event<Types...>::RegisterHandler(Func handler)
{
this->handlerList.push_back(handler);
lastFunc = this->handlerList.size() == 1 ? handler : nullptr;
}
template<typename... Types>
void Event<Types...>::operator+=(Func handler) {
this->RegisterHandler(handler);
}
template<typename... Types>
void Event<Types...>::operator()(Types... types)
{
if (lastFunc) {
lastFunc(types...);
} else {
for (auto handler : this->handlerList) {
handler(types...);
}
}
}
template<typename T>
class TemplatedClass
{
@ -103,19 +65,14 @@ void func2(int a)
int _tmain(int argc, _TCHAR* argv[])
{
std::ifstream romFile("6502_functional_test.bin", std::ios::in | std::ios::binary);
if(!romFile) {
std::cout << "Error";
}
int8_t romMemory[65536];
romFile.read((char *)romMemory, 65536);
/*int8_t* memory = new int8_t[8000];
memory[0x0600] = 0xA9;
memory[0x0601] = 0x55;*/
Core core(romMemory);
core.Exec();
/* BaseMemoryHandler a;
Test b;
EventHandler<BaseMemoryHandler, uint16_t> eventHandler;
eventHandler.RegisterHandler(&a, &BaseMemoryHandler::CallbackTest);
eventHandler.RegisterHandler(&b, &BaseMemoryHandler::CallbackTest);
eventHandler(eMemoryOperation::Read, 0);
*/
CPU::RunBenchmark();
/*Event<> eventHandler;
eventHandler += somefunction;