mirror of
https://github.com/libretro/Mesen.git
synced 2024-11-26 18:40:46 +00:00
Initial commit
This commit is contained in:
commit
4c5dbdcb42
63
.gitattributes
vendored
Normal file
63
.gitattributes
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
156
.gitignore
vendored
Normal file
156
.gitignore
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
|
||||
# Build results
|
||||
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
build/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
|
||||
!packages/*/build/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.log
|
||||
*.scc
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
*.ncrunch*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.Publish.xml
|
||||
|
||||
# NuGet Packages Directory
|
||||
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
|
||||
#packages/
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
sql/
|
||||
*.Cache
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.[Pp]ublish.xml
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
App_Data/*.mdf
|
||||
App_Data/*.ldf
|
||||
|
||||
|
||||
#LightSwitch generated files
|
||||
GeneratedArtifacts/
|
||||
_Pvt_Extensions/
|
||||
ModelManifest.xml
|
||||
|
||||
# =========================
|
||||
# Windows detritus
|
||||
# =========================
|
||||
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Mac desktop service store files
|
||||
.DS_Store
|
BIN
6502_functional_test.bin
Normal file
BIN
6502_functional_test.bin
Normal file
Binary file not shown.
40
CPU.cpp
Normal file
40
CPU.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "stdafx.h"
|
||||
#include "CPU.h"
|
||||
#include "Timer.h"
|
||||
|
||||
void Core::Reset()
|
||||
{
|
||||
_state.A = 0;
|
||||
_state.PC = 0x0400;
|
||||
_state.SP = 0xFF;
|
||||
_state.X = 0;
|
||||
_state.Y = 0;
|
||||
_state.PS = PSFlags::Zero | PSFlags::Reserved;// | PSFlags::Interrupt;
|
||||
}
|
||||
|
||||
void Core::Exec()
|
||||
{
|
||||
uint16_t lastPC = 65535;
|
||||
int executedCount = 0;
|
||||
std::list<int> pcList;
|
||||
|
||||
Timer timer;
|
||||
while(true) {
|
||||
_currentPC = _state.PC;
|
||||
uint8_t opCode = ReadByte();
|
||||
if(_opTable[opCode] != 0) {
|
||||
(this->*_opTable[opCode])();
|
||||
} else {
|
||||
std::cout << "Invalid opcode: PC:" << _currentPC << std::endl;
|
||||
}
|
||||
lastPC = _currentPC;
|
||||
executedCount++;
|
||||
|
||||
if(executedCount >= 200000000) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "Executed:" << executedCount << " in " << timer.GetElapsedMS() << " ms";
|
||||
}
|
||||
|
736
CPU.h
Normal file
736
CPU.h
Normal file
@ -0,0 +1,736 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
namespace PSFlags
|
||||
{
|
||||
enum PSFlags : uint8_t
|
||||
{
|
||||
Carry = 0x01,
|
||||
Zero = 0x02,
|
||||
Interrupt = 0x04,
|
||||
Decimal = 0x08,
|
||||
Break = 0x10,
|
||||
Reserved = 0x20,
|
||||
Overflow = 0x40,
|
||||
Negative = 0x80
|
||||
};
|
||||
}
|
||||
|
||||
struct State
|
||||
{
|
||||
uint16_t PC;
|
||||
uint8_t SP;
|
||||
uint8_t A;
|
||||
uint8_t X;
|
||||
uint8_t Y;
|
||||
uint8_t PS;
|
||||
};
|
||||
|
||||
class Core
|
||||
{
|
||||
private:
|
||||
typedef void(Core::*Func)();
|
||||
|
||||
Func _opTable[256];
|
||||
State _state;
|
||||
int8_t* _memory;
|
||||
uint16_t _currentPC;
|
||||
|
||||
inline uint8_t Core::ReadByte()
|
||||
{
|
||||
return _memory[_state.PC++];
|
||||
}
|
||||
|
||||
uint16_t Core::ReadWord()
|
||||
{
|
||||
uint16_t value = (uint16_t)(((uint8_t)_memory[_state.PC] | (((uint8_t)_memory[_state.PC + 1]) << 8)));
|
||||
_state.PC += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
void ClearFlags(uint8_t flags)
|
||||
{
|
||||
_state.PS &= ~flags;
|
||||
}
|
||||
|
||||
uint16_t lastNegative = 0;
|
||||
void SetFlags(uint8_t flags)
|
||||
{
|
||||
if(flags & PSFlags::Negative) {
|
||||
lastNegative = _state.PC;
|
||||
}
|
||||
_state.PS |= flags;
|
||||
}
|
||||
|
||||
bool CheckFlag(uint8_t flag)
|
||||
{
|
||||
return (_state.PS & flag) == flag;
|
||||
}
|
||||
|
||||
void SetZeroNegativeFlags(uint8_t value)
|
||||
{
|
||||
if(value == 0) {
|
||||
SetFlags(PSFlags::Zero);
|
||||
} else if(value & 0x80) {
|
||||
SetFlags(PSFlags::Negative);
|
||||
}
|
||||
}
|
||||
|
||||
void MemoryWrite(uint16_t addr, uint8_t value)
|
||||
{
|
||||
//SetZeroNegativeFlags(value);
|
||||
_memory[addr] = value;
|
||||
if(addr == 0x200) {
|
||||
std::cout << "------------------" << std::endl;
|
||||
std::cout << "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];
|
||||
}
|
||||
|
||||
uint16_t MemoryReadWord(uint16_t addr) {
|
||||
return (_memory[addr] | (_memory[addr + 1] << 8));
|
||||
}
|
||||
|
||||
void SetRegister(uint8_t ®, int8_t value) {
|
||||
ClearFlags(PSFlags::Zero | PSFlags::Negative);
|
||||
SetZeroNegativeFlags(value);
|
||||
reg = value;
|
||||
}
|
||||
|
||||
void Push(uint8_t value) {
|
||||
_memory[SP() + 0x100] = value;
|
||||
SetSP(SP() - 1);
|
||||
}
|
||||
|
||||
void Push(uint16_t value) {
|
||||
Push((uint8_t)(value >> 8));
|
||||
Push((uint8_t)value);
|
||||
}
|
||||
|
||||
uint8_t Pop() {
|
||||
SetSP(SP() + 1);
|
||||
int8_t value = _memory[0x100 + SP()];
|
||||
return value;
|
||||
}
|
||||
|
||||
uint16_t PopWord() {
|
||||
return Pop() | (Pop() << 8);
|
||||
}
|
||||
|
||||
uint8_t A() { return _state.A; }
|
||||
void SetA(uint8_t value) { SetRegister(_state.A, value); }
|
||||
uint8_t X() { return _state.X; }
|
||||
void SetX(uint8_t value) { SetRegister(_state.X, value); }
|
||||
uint8_t Y() { return _state.Y; }
|
||||
void SetY(uint8_t value) { SetRegister(_state.Y, value); }
|
||||
uint8_t SP() { return _state.SP; }
|
||||
void SetSP(uint8_t value) { _state.SP = value; }
|
||||
uint8_t PS() { return _state.PS; }
|
||||
void SetPS(uint8_t value) { _state.PS = value | PSFlags::Reserved; }
|
||||
uint16_t PC() { return _state.PC; }
|
||||
void SetPC(uint16_t value) { _state.PC = value; }
|
||||
|
||||
uint8_t GetImmediate() { return ReadByte(); }
|
||||
uint8_t GetZero() { return MemoryRead(GetZeroAddr()); }
|
||||
uint8_t GetZeroAddr() { return ReadByte(); }
|
||||
|
||||
uint8_t GetZeroX() { return MemoryRead(GetZeroXAddr()); }
|
||||
uint8_t GetZeroXAddr() { return ReadByte() + X(); }
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
int8_t GetAbsY() { return MemoryRead(GetAbsYAddr()); }
|
||||
uint16_t GetAbsYAddr() {
|
||||
return ReadWord() + Y();
|
||||
}
|
||||
|
||||
uint16_t GetInd() { return MemoryReadWord(ReadByte() | (ReadByte() << 8)); }
|
||||
|
||||
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);
|
||||
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);
|
||||
return addr + Y();
|
||||
}
|
||||
|
||||
|
||||
void AND(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) {
|
||||
SetFlags(PSFlags::Overflow);
|
||||
}
|
||||
if(result > 0xFF) {
|
||||
SetFlags(PSFlags::Carry);
|
||||
}
|
||||
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 CMP(uint8_t reg, uint8_t value) {
|
||||
ClearFlags(PSFlags::Carry | PSFlags::Negative | PSFlags::Zero);
|
||||
if(reg >= value) {
|
||||
SetFlags(PSFlags::Carry);
|
||||
}
|
||||
if(reg == value) {
|
||||
SetFlags(PSFlags::Zero);
|
||||
}
|
||||
if(reg < value) {
|
||||
SetFlags(PSFlags::Negative);
|
||||
}
|
||||
}
|
||||
|
||||
void CPA(int8_t value) { CMP(A(), value); }
|
||||
void CPX(int8_t value) { CMP(X(), value); }
|
||||
void CPY(int8_t value) { CMP(Y(), value); }
|
||||
|
||||
void INC(uint16_t addr) {
|
||||
ClearFlags(PSFlags::Negative | PSFlags::Zero);
|
||||
uint8_t memory = MemoryRead(addr) + 1;
|
||||
SetZeroNegativeFlags(memory);
|
||||
MemoryWrite(addr, memory);
|
||||
}
|
||||
|
||||
void DEC(uint16_t addr) {
|
||||
ClearFlags(PSFlags::Negative | PSFlags::Zero);
|
||||
uint8_t memory = MemoryRead(addr) - 1;
|
||||
SetZeroNegativeFlags(memory);
|
||||
MemoryWrite(addr, memory);
|
||||
}
|
||||
|
||||
uint8_t ASL(uint8_t value)
|
||||
{
|
||||
ClearFlags(PSFlags::Carry | PSFlags::Negative | PSFlags::Zero);
|
||||
if(value & 0x80) {
|
||||
SetFlags(PSFlags::Carry);
|
||||
}
|
||||
|
||||
uint8_t result = value << 1;
|
||||
SetZeroNegativeFlags(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t LSR(uint8_t value) {
|
||||
ClearFlags(PSFlags::Carry | PSFlags::Negative | PSFlags::Zero);
|
||||
if(value & 0x01) {
|
||||
SetFlags(PSFlags::Carry);
|
||||
}
|
||||
|
||||
uint8_t result = value >> 1;
|
||||
SetZeroNegativeFlags(result);
|
||||
return value >> 1;
|
||||
}
|
||||
|
||||
uint8_t ROL(uint8_t value) {
|
||||
bool carryFlag = CheckFlag(PSFlags::Carry);
|
||||
ClearFlags(PSFlags::Carry | PSFlags::Negative | PSFlags::Zero);
|
||||
|
||||
if(value & 0x80) {
|
||||
SetFlags(PSFlags::Carry);
|
||||
}
|
||||
|
||||
uint8_t result = (value << 1 | (carryFlag ? 0x01 : 0x00));
|
||||
SetZeroNegativeFlags(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t ROR(uint8_t value) {
|
||||
bool carryFlag = CheckFlag(PSFlags::Carry);
|
||||
ClearFlags(PSFlags::Carry | PSFlags::Negative | PSFlags::Zero);
|
||||
if(value & 0x01) {
|
||||
SetFlags(PSFlags::Carry);
|
||||
}
|
||||
|
||||
uint8_t result = (value >> 1 | (carryFlag ? 0x80 : 0x00));
|
||||
SetZeroNegativeFlags(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void ASLAddr(uint16_t addr) {
|
||||
int8_t value = MemoryRead(addr);
|
||||
MemoryWrite(addr, ASL(value));
|
||||
}
|
||||
|
||||
void LSRAddr(uint16_t addr) {
|
||||
int8_t value = MemoryRead(addr);
|
||||
MemoryWrite(addr, LSR(value));
|
||||
}
|
||||
|
||||
void ROLAddr(uint16_t addr) {
|
||||
int8_t value = MemoryRead(addr);
|
||||
MemoryWrite(addr, ROL(value));
|
||||
}
|
||||
|
||||
void RORAddr(uint16_t addr) {
|
||||
int8_t value = MemoryRead(addr);
|
||||
MemoryWrite(addr, ROR(value));
|
||||
}
|
||||
|
||||
void JMP(uint16_t addr) {
|
||||
_state.PC = addr;
|
||||
}
|
||||
|
||||
void BranchRelative(bool branch) {
|
||||
int8_t offset = GetImmediate();
|
||||
if(branch) {
|
||||
SetPC(PC() + offset);
|
||||
if(_currentPC == PC()) {
|
||||
std::cout << "Infinite loop at: 0x" << std::hex << (short)_currentPC;
|
||||
std::cout << std::endl;
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma region OP Codes
|
||||
void LDA_Imm() { SetA(GetImmediate()); }
|
||||
void LDA_Zero() { SetA(GetZero()); }
|
||||
void LDA_ZeroX() { SetA(GetZeroX()); }
|
||||
void LDA_Abs() { SetA(GetAbs()); }
|
||||
void LDA_AbsX() { SetA(GetAbsX()); }
|
||||
void LDA_AbsY() { SetA(GetAbsY()); }
|
||||
void LDA_IndX() { SetA(GetIndX()); }
|
||||
void LDA_IndY() { SetA(GetIndY()); }
|
||||
|
||||
void LDX_Imm() { SetX(GetImmediate()); }
|
||||
void LDX_Zero() { SetX(GetZero()); }
|
||||
void LDX_ZeroY() { SetX(GetZeroY()); }
|
||||
void LDX_Abs() { SetX(GetAbs()); }
|
||||
void LDX_AbsY() { SetX(GetAbsY()); }
|
||||
|
||||
void LDY_Imm() { SetY(GetImmediate()); }
|
||||
void LDY_Zero() { SetY(GetZero()); }
|
||||
void LDY_ZeroX() { SetY(GetZeroX()); }
|
||||
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_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 STY_Zero() { MemoryWrite(ReadByte(), Y()); }
|
||||
void STY_ZeroX() { MemoryWrite((uint8_t)(ReadByte() + X()), Y()); }
|
||||
void STY_Abs() { MemoryWrite(ReadWord(), Y()); }
|
||||
|
||||
void TAX() { SetX(A()); }
|
||||
void TAY() { SetY(A()); }
|
||||
void TSX() { SetX(SP()); }
|
||||
void TXA() { SetA(X()); }
|
||||
void TXS() { SetSP(X()); }
|
||||
void TYA() { SetA(Y()); }
|
||||
|
||||
void PHA() { Push(A()); }
|
||||
void PHP() {
|
||||
SetFlags(PSFlags::Break);
|
||||
Push((uint8_t)PS());
|
||||
}
|
||||
void PLA() { SetA(Pop()); }
|
||||
void PLP() { SetPS(Pop()); }
|
||||
|
||||
void AND_Imm() { AND(GetImmediate()); }
|
||||
void AND_Zero() { AND(GetZero()); }
|
||||
void AND_ZeroX() { AND(GetZeroX()); }
|
||||
void AND_Abs() { AND(GetAbs()); }
|
||||
void AND_AbsX() { AND(GetAbsX()); }
|
||||
void AND_AbsY() { AND(GetAbsY()); }
|
||||
void AND_IndX() { AND(GetIndX()); }
|
||||
void AND_IndY() { AND(GetIndY()); }
|
||||
|
||||
void EOR_Imm() { XOR(GetImmediate()); }
|
||||
void EOR_Zero() { XOR(GetZero()); }
|
||||
void EOR_ZeroX() { XOR(GetZeroX()); }
|
||||
void EOR_Abs() { XOR(GetAbs()); }
|
||||
void EOR_AbsX() { XOR(GetAbsX()); }
|
||||
void EOR_AbsY() { XOR(GetAbsY()); }
|
||||
void EOR_IndX() { XOR(GetIndX()); }
|
||||
void EOR_IndY() { XOR(GetIndY()); }
|
||||
|
||||
void ORA_Imm() { OR(GetImmediate()); }
|
||||
void ORA_Zero() { OR(GetZero()); }
|
||||
void ORA_ZeroX() { OR(GetZeroX()); }
|
||||
void ORA_Abs() { OR(GetAbs()); }
|
||||
void ORA_AbsX() { OR(GetAbsX()); }
|
||||
void ORA_AbsY() { OR(GetAbsY()); }
|
||||
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());
|
||||
}
|
||||
void BIT_Abs() {
|
||||
BIT(GetAbs());
|
||||
}
|
||||
|
||||
void ADC_Imm() { ADC(GetImmediate()); }
|
||||
void ADC_Zero() { ADC(GetZero()); }
|
||||
void ADC_ZeroX() { ADC(GetZeroX()); }
|
||||
void ADC_Abs() { ADC(GetAbs()); }
|
||||
void ADC_AbsX() { ADC(GetAbsX()); }
|
||||
void ADC_AbsY() { ADC(GetAbsY()); }
|
||||
void ADC_IndX() { ADC(GetIndX()); }
|
||||
void ADC_IndY() { ADC(GetIndY()); }
|
||||
|
||||
void SBC_Imm() { SBC(GetImmediate()); }
|
||||
void SBC_Zero() { SBC(GetZero()); }
|
||||
void SBC_ZeroX() { SBC(GetZeroX()); }
|
||||
void SBC_Abs() { SBC(GetAbs()); }
|
||||
void SBC_AbsX() { SBC(GetAbsX()); }
|
||||
void SBC_AbsY() { SBC(GetAbsY()); }
|
||||
void SBC_IndX() { SBC(GetIndX()); }
|
||||
void SBC_IndY() { SBC(GetIndY()); }
|
||||
|
||||
void CMP_Imm() { CPA(GetImmediate()); }
|
||||
void CMP_Zero() { CPA(GetZero()); }
|
||||
void CMP_ZeroX() { CPA(GetZeroX()); }
|
||||
void CMP_Abs() { CPA(GetAbs()); }
|
||||
void CMP_AbsX() { CPA(GetAbsX()); }
|
||||
void CMP_AbsY() { CPA(GetAbsY()); }
|
||||
void CMP_IndX() { CPA(GetIndX()); }
|
||||
void CMP_IndY() { CPA(GetIndY()); }
|
||||
|
||||
void CPX_Imm() { CPX(GetImmediate()); }
|
||||
void CPX_Zero() { CPX(GetZero()); }
|
||||
void CPX_Abs() { CPX(GetAbs()); }
|
||||
|
||||
void CPY_Imm() { CPY(GetImmediate()); }
|
||||
void CPY_Zero() { CPY(GetZero()); }
|
||||
void CPY_Abs() { CPY(GetAbs()); }
|
||||
|
||||
void INC_Zero() { INC(GetZeroAddr()); }
|
||||
void INC_ZeroX() { INC(GetZeroXAddr()); }
|
||||
void INC_Abs() { INC(GetAbsAddr()); }
|
||||
void INC_AbsX() { INC(GetAbsXAddr()); }
|
||||
void INX() { SetX(X() + 1); }
|
||||
void INY() { SetY(Y() + 1); }
|
||||
|
||||
void DEC_Zero() { DEC(GetZeroAddr()); }
|
||||
void DEC_ZeroX() { DEC(GetZeroXAddr()); }
|
||||
void DEC_Abs() { DEC(GetAbsAddr()); }
|
||||
void DEC_AbsX() { DEC(GetAbsXAddr()); }
|
||||
void DEX() { SetX(X() - 1); }
|
||||
void DEY() { SetY(Y() - 1); }
|
||||
|
||||
void ASL_Acc() { SetA(ASL(A())); }
|
||||
void ASL_Zero() { ASLAddr(GetZeroAddr()); }
|
||||
void ASL_ZeroX() { ASLAddr(GetZeroXAddr()); }
|
||||
void ASL_Abs() { ASLAddr(GetAbsAddr()); }
|
||||
void ASL_AbsX() { ASLAddr(GetAbsXAddr()); }
|
||||
|
||||
void LSR_Acc() { SetA(LSR(A())); }
|
||||
void LSR_Zero() { LSRAddr(GetZeroAddr()); }
|
||||
void LSR_ZeroX() { LSRAddr(GetZeroXAddr()); }
|
||||
void LSR_Abs() { LSRAddr(GetAbsAddr()); }
|
||||
void LSR_AbsX() { LSRAddr(GetAbsXAddr()); }
|
||||
|
||||
void ROL_Acc() { SetA(ROL(A())); }
|
||||
void ROL_Zero() { ROLAddr(GetZeroAddr()); }
|
||||
void ROL_ZeroX() { ROLAddr(GetZeroXAddr()); }
|
||||
void ROL_Abs() { ROLAddr(GetAbsAddr()); }
|
||||
void ROL_AbsX() { ROLAddr(GetAbsXAddr()); }
|
||||
|
||||
void ROR_Acc() { SetA(ROR(A())); }
|
||||
void ROR_Zero() { RORAddr(GetZeroAddr()); }
|
||||
void ROR_ZeroX() { RORAddr(GetZeroXAddr()); }
|
||||
void ROR_Abs() { RORAddr(GetAbsAddr()); }
|
||||
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);
|
||||
}
|
||||
void JMP_Ind() { JMP(GetInd()); }
|
||||
void JSR() {
|
||||
Push((uint16_t)(PC() + 1));
|
||||
JMP(GetAbsAddr());
|
||||
}
|
||||
void RTS() {
|
||||
SetPC(PopWord() + 1);
|
||||
}
|
||||
|
||||
void BCC() {
|
||||
BranchRelative(!CheckFlag(PSFlags::Carry));
|
||||
}
|
||||
|
||||
void BCS() {
|
||||
BranchRelative(CheckFlag(PSFlags::Carry));
|
||||
}
|
||||
|
||||
void BEQ() {
|
||||
BranchRelative(CheckFlag(PSFlags::Zero));
|
||||
}
|
||||
|
||||
void BMI() {
|
||||
BranchRelative(CheckFlag(PSFlags::Negative));
|
||||
}
|
||||
|
||||
void BNE() {
|
||||
BranchRelative(!CheckFlag(PSFlags::Zero));
|
||||
}
|
||||
|
||||
void BPL() {
|
||||
BranchRelative(!CheckFlag(PSFlags::Negative));
|
||||
}
|
||||
|
||||
void BVC() {
|
||||
BranchRelative(!CheckFlag(PSFlags::Overflow));
|
||||
}
|
||||
|
||||
void BVS() {
|
||||
BranchRelative(CheckFlag(PSFlags::Overflow));
|
||||
}
|
||||
|
||||
void CLC() { ClearFlags(PSFlags::Carry); }
|
||||
void CLD() { ClearFlags(PSFlags::Decimal); }
|
||||
void CLI() { ClearFlags(PSFlags::Interrupt); }
|
||||
void CLV() { ClearFlags(PSFlags::Overflow); }
|
||||
void SEC() { SetFlags(PSFlags::Carry); }
|
||||
void SED() { SetFlags(PSFlags::Decimal); }
|
||||
void SEI() { SetFlags(PSFlags::Interrupt); }
|
||||
|
||||
void BRK() {
|
||||
SetFlags(PSFlags::Break);
|
||||
Push((uint16_t)(PC() + 1));
|
||||
Push((uint8_t)PS());
|
||||
SetFlags(PSFlags::Interrupt);
|
||||
ClearFlags(PSFlags::Break);
|
||||
SetPC((uint8_t)_memory[0xFFFE] | ((uint8_t)_memory[0xFFFF] << 8));
|
||||
}
|
||||
|
||||
void NOP() {}
|
||||
void RTI() {
|
||||
SetPS(Pop());
|
||||
SetPC(PopWord());
|
||||
}
|
||||
#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;
|
||||
}
|
||||
void Reset();
|
||||
void Exec();
|
||||
};
|
104
Core.vcxproj
Normal file
104
Core.vcxproj
Normal file
@ -0,0 +1,104 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{78FEF1A1-6DF1-4CBB-A373-AE6FA7CE5CE0}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>Core</RootNamespace>
|
||||
<ProjectName>Core</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<Profile>
|
||||
</Profile>
|
||||
<OptimizeReferences>
|
||||
</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CPU.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="CPU.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Timer.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
45
Core.vcxproj.filters
Normal file
45
Core.vcxproj.filters
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CPU.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Timer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CPU.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
22
NES.sln
Normal file
22
NES.sln
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.30501.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Core", "Core.vcxproj", "{78FEF1A1-6DF1-4CBB-A373-AE6FA7CE5CE0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{78FEF1A1-6DF1-4CBB-A373-AE6FA7CE5CE0}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{78FEF1A1-6DF1-4CBB-A373-AE6FA7CE5CE0}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{78FEF1A1-6DF1-4CBB-A373-AE6FA7CE5CE0}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{78FEF1A1-6DF1-4CBB-A373-AE6FA7CE5CE0}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
40
ReadMe.txt
Normal file
40
ReadMe.txt
Normal file
@ -0,0 +1,40 @@
|
||||
========================================================================
|
||||
CONSOLE APPLICATION : ConsoleApplication1 Project Overview
|
||||
========================================================================
|
||||
|
||||
AppWizard has created this ConsoleApplication1 application for you.
|
||||
|
||||
This file contains a summary of what you will find in each of the files that
|
||||
make up your ConsoleApplication1 application.
|
||||
|
||||
|
||||
ConsoleApplication1.vcxproj
|
||||
This is the main project file for VC++ projects generated using an Application Wizard.
|
||||
It contains information about the version of Visual C++ that generated the file, and
|
||||
information about the platforms, configurations, and project features selected with the
|
||||
Application Wizard.
|
||||
|
||||
ConsoleApplication1.vcxproj.filters
|
||||
This is the filters file for VC++ projects generated using an Application Wizard.
|
||||
It contains information about the association between the files in your project
|
||||
and the filters. This association is used in the IDE to show grouping of files with
|
||||
similar extensions under a specific node (for e.g. ".cpp" files are associated with the
|
||||
"Source Files" filter).
|
||||
|
||||
ConsoleApplication1.cpp
|
||||
This is the main application source file.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Other standard files:
|
||||
|
||||
StdAfx.h, StdAfx.cpp
|
||||
These files are used to build a precompiled header (PCH) file
|
||||
named ConsoleApplication1.pch and a precompiled types file named StdAfx.obj.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Other notes:
|
||||
|
||||
AppWizard uses "TODO:" comments to indicate parts of the source code you
|
||||
should add to or customize.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
28
Timer.h
Normal file
28
Timer.h
Normal file
@ -0,0 +1,28 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
class Timer
|
||||
{
|
||||
private:
|
||||
double _frequency = 0.0;
|
||||
LARGE_INTEGER _start;
|
||||
|
||||
public:
|
||||
Timer() {
|
||||
LARGE_INTEGER li;
|
||||
if(!QueryPerformanceFrequency(&li)) {
|
||||
throw;
|
||||
}
|
||||
|
||||
_frequency = double(li.QuadPart) / 1000.0;
|
||||
|
||||
QueryPerformanceCounter(&li);
|
||||
_start = li;
|
||||
}
|
||||
|
||||
double GetElapsedMS()
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
QueryPerformanceCounter(&li);
|
||||
return double(li.QuadPart - _start.QuadPart) / _frequency;
|
||||
}
|
||||
};
|
164
main.cpp
Normal file
164
main.cpp
Normal file
@ -0,0 +1,164 @@
|
||||
#include "stdafx.h"
|
||||
#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
|
||||
{
|
||||
public:
|
||||
T Sum(T a, T b);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T TemplatedClass<T>::Sum(T a, T b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
template<typename T> using ptr = std::unique_ptr<T>;
|
||||
|
||||
class Test
|
||||
{
|
||||
private:
|
||||
int counter = 0;
|
||||
Test();
|
||||
|
||||
public:
|
||||
int Sum(int, int);
|
||||
void NewThread();
|
||||
static std::unique_ptr<Test> NewInstance();
|
||||
};
|
||||
|
||||
Test::Test()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int Test::Sum(int x, int y)
|
||||
{
|
||||
return x + y;
|
||||
}
|
||||
|
||||
void Test::NewThread()
|
||||
{
|
||||
for (int i = 0; i < 100; i++) {
|
||||
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(1000));
|
||||
printf("test %i", this->counter);
|
||||
this->counter++;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<Test> Test::NewInstance()
|
||||
{
|
||||
return std::unique_ptr<Test>(new Test());
|
||||
}
|
||||
|
||||
void somefunction(void)
|
||||
{
|
||||
printf("test11111");
|
||||
}
|
||||
|
||||
void func2(int a)
|
||||
{
|
||||
//printf("%i", 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();
|
||||
|
||||
/*Event<> eventHandler;
|
||||
eventHandler += somefunction;
|
||||
|
||||
Event<int> intHandler;
|
||||
intHandler += func2;
|
||||
intHandler += func2;
|
||||
intHandler += func2;
|
||||
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
intHandler(i);
|
||||
}
|
||||
eventHandler();
|
||||
|
||||
TemplatedClass<double> DoubleSum;
|
||||
printf("%d", DoubleSum.Sum(10.0, 20.0));
|
||||
|
||||
TemplatedClass<std::string> StringSum;
|
||||
std::cout << StringSum.Sum("asdas", "dsadasdsa");
|
||||
|
||||
auto str1 = std::string("aaaa");
|
||||
auto str2 = std::string("bbbb");
|
||||
auto str3 = str1 + str2;
|
||||
std::cout << str3;
|
||||
|
||||
std::unique_ptr<Test> test;
|
||||
|
||||
if (!test) {
|
||||
test = Test::NewInstance();
|
||||
}
|
||||
|
||||
std::thread t1(&Test::NewThread, test.get());
|
||||
|
||||
std::thread t2([]() {
|
||||
printf("test2");
|
||||
});
|
||||
|
||||
if (test) {
|
||||
printf("%i", test->Sum(1000, 10));
|
||||
}
|
||||
|
||||
t1.join();
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
1
stdafx.cpp
Normal file
1
stdafx.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "stdafx.h"
|
26
stdafx.h
Normal file
26
stdafx.h
Normal file
@ -0,0 +1,26 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <memory>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <list>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
8
targetver.h
Normal file
8
targetver.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
// Including SDKDDKVer.h defines the highest available Windows platform.
|
||||
|
||||
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
|
||||
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
|
||||
|
||||
#include <SDKDDKVer.h>
|
Loading…
Reference in New Issue
Block a user