summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/6502.h103
-rw-r--r--src/cpu/addressing.h227
-rw-r--r--src/cpu/instructions/definitions.h360
-rw-r--r--src/cpu/instructions/illegal/definitions.h0
-rw-r--r--src/cpu/instructions/illegal/init.h0
-rw-r--r--src/cpu/instructions/illegal/table-append.h0
-rw-r--r--src/cpu/instructions/init.h74
-rw-r--r--src/cpu/instructions/table.h270
8 files changed, 1034 insertions, 0 deletions
diff --git a/src/cpu/6502.h b/src/cpu/6502.h
new file mode 100644
index 0000000..8ceba29
--- /dev/null
+++ b/src/cpu/6502.h
@@ -0,0 +1,103 @@
+// 6502.h
+// Core elements of the 6502 CPU
+
+typedef unsigned char\
+ byte;
+typedef unsigned short\
+ address;
+
+byte acc, X, Y, P, S = 0x00;
+address PC = 0x0000;
+byte* Memory;
+
+// FLAGS
+#define flag_N 0x80 // Negative
+#define flag_V 0x40 // Overflow
+#define flag_B 0x10 // BRK command
+#define flag_D 0x08 // Decimal mode
+#define flag_I 0x04 // IRQ disable
+#define flag_Z 0x02 // Zero
+#define flag_C 0x01 // Carry
+
+byte getFlag(byte flag) {
+ return ((P & flag) == flag) ? 1 : 0;
+}
+
+void setFlag(byte flag, int x) {
+ if (x == 1){
+ if ((P & flag) == 0x0) P += flag;
+ }else if (x == 0){
+ if ((P & flag) == flag) P -= flag;
+ }
+ else{
+ fprintf(stderr, "setFlag() passed arg neither 0 or 1");
+ }
+}
+
+void flagSet(byte flag){
+ P |= flag;
+}
+
+void flagClear(byte flag){
+ P &= ~flag;
+}
+
+
+// Functions which perform reusable routines for finding if a specific flag should be set.
+
+void setFlagN(byte x){
+ if (x & flag_N == flag_N)
+ setFlag(flag_N, 1);
+ else
+ setFlag(flag_N, 0);
+}
+
+//Perform prior to any changes
+void setFlagV(byte x, byte y){
+ if ((x & flag_N) == (y & flag_N)){
+ if (((x + y) & (flag_N ^ 0xFF)) > 0x7F) setFlag(flag_V, 1);
+ else setFlag(flag_V, 0);
+ }else{
+ if (((x - y) & (flag_N ^ 0xFF)) > 0x7F) setFlag(flag_V, 1);
+ else setFlag(flag_V, 0);
+ }
+}
+
+/*void setFlagB(){ //WORK ON
+ setFlag(flag_B, 1);
+}*/ //Dont really need since its dependent on the BRK insturction
+
+/*void setFlagD(){
+ setFlag(flag_D, 1);
+}*/
+
+/*void setFlagI(){ //WORK ON
+ setFlag(flag_Z, 1);
+}*/
+
+void setFlagZ(int x){
+ if (x == 0)
+ setFlag(flag_Z, 1);
+ else
+ setFlag(flag_Z, 0);
+}
+
+//Only 6 instructions, 2 not including stack instructions, use the carry flag.
+// Need to look further into implementation details for this.
+/*void setFlagC(){
+ setFlag(flag_Z, 1);
+}*/
+
+
+// Memory Manipulation
+
+// Are to be defined by the system to handle special cases.
+
+byte getMemory(address x);
+void setMemory(address x, byte y);
+
+
+
+#include"addressing.h"
+#include"instructions/definitions.h"
+#include"instructions/table.h" \ No newline at end of file
diff --git a/src/cpu/addressing.h b/src/cpu/addressing.h
new file mode 100644
index 0000000..7a72ff5
--- /dev/null
+++ b/src/cpu/addressing.h
@@ -0,0 +1,227 @@
+// addressing.h
+// Contains definitions relevant to addressing, as well as fAddress() which returns time, length, value, and address for an instruction function call.
+
+enum Addressing {
+ eImmediate,
+ eAccumulator,
+ eZeroPage,
+ eZeroPageIndexedX,
+ eZeroPageIndexedY,
+ eAbsolute,
+ eAbsoluteIndexedX,
+ eAbsoluteIndexedY,
+ eIndexedIndirect,
+ eIndirectIndexed,
+ eImplied,
+ eIndirectAbsolute,
+ eRelative
+};
+
+typedef int Addressing;
+
+typedef struct AddData{
+ int cycles;
+ int length;
+ address add;
+ byte value;
+} AddData;
+
+//typedef struct AddData AddData;
+
+#include"instructions/init.h"
+
+//Holds address of current instruction.
+void* current_instruction;
+
+int fAddressGetLength(Addressing addr){
+ switch(addr){
+ case eAbsolute: case eAbsoluteIndexedX: case eAbsoluteIndexedY:
+ return 3;
+ case eAccumulator: case eImplied:
+ return 1;
+ default:
+ return 2;
+ }
+}
+
+int fAddressGetLengthPrempt(int i){ //Check the functions to make sure that there isnt some incorrect values being given for length.
+ switch(i){
+ case 0x6D: case 0x7D: case 0x79: case 0x2D: case 0x3D: case 0x39: case 0x0E: case 0x1E: case 0x2C: case 0xCD: case 0xD0: case 0xD9: case 0xEC:
+ case 0xCC: case 0xCE: case 0xDE: case 0x4D: case 0x5D: case 0x59: case 0xEE: case 0xFE: case 0x4C: case 0x20: case 0xAD: case 0xBD: case 0xB9:
+ case 0xAE: case 0xBE: case 0xAC: case 0xBC: case 0x4E: case 0x5E: case 0x0D: case 0x1D: case 0x19: case 0x2E: case 0x3E: case 0x6E: case 0x7E:
+ case 0xED: case 0xFD: case 0xF9: case 0x8D: case 0x9D: case 0x99: case 0x8E: case 0x8C:
+ return 3;
+ case 0x0A: case 0x2A: case 0x4A: case 0x6A:
+ return 1;
+ default:
+ return 2;
+ }
+}
+
+AddData fAddress(Addressing addr, short x) {
+ AddData ret;
+
+ // ADDRESS
+
+ switch(addr){
+ case eImplied:
+ case eIndirectAbsolute:
+ case eRelative:
+ case eImmediate:
+ case eAccumulator:
+ ret.add = 0x0000;
+ break;
+
+ case eAbsolute:
+ ret.add = x;
+ break;
+ case eAbsoluteIndexedX:
+ ret.add = (x + X);
+ break;
+ case eAbsoluteIndexedY:
+ ret.add = (x + Y);
+ break;
+
+ case eZeroPage:
+ ret.add = (x & 0x00FF);
+ break;
+ case eZeroPageIndexedX:
+ ret.add = ((x + X) & 0x00FF);
+ break;
+ case eZeroPageIndexedY:
+ ret.add = ((x + Y) & 0x00FF);
+ break;
+
+ case eIndexedIndirect:
+ ret.add = ((getMemory(x+X+1))<<8) + (getMemory(x+X));
+ break;
+ case eIndirectIndexed:
+ ret.add = ((getMemory(x+1))<<8) + (getMemory(x)) + Y;
+ break;
+ }
+
+ // VALUE
+
+ switch(addr){
+ case eImplied:
+ case eIndirectAbsolute:
+ case eRelative:
+ break;
+
+ case eImmediate:
+ ret.value = x;
+ break;
+
+ case eAccumulator:
+ ret.value = acc;
+ break;
+
+ default:
+ ret.value = getMemory(ret.add);
+ }
+
+ // LENGTH
+
+ ret.length = fAddressGetLength(addr);
+
+ // CYCLES
+
+ //case &fADC: case &fAND: case &fBIT: case &fCMP: case &fCPX: case &fCPY: case &fEOR: case &fLDA:
+ //case &fLDX: case &fLDY: case &fORA: case &fSBC: case &fSTX: case &fSTY:
+
+ if ( current_instruction == &fADC || current_instruction == &fAND || current_instruction == &fBIT || current_instruction == &fCMP || current_instruction == &fCPX
+ || current_instruction == &fCPY || current_instruction == &fEOR || current_instruction == &fLDA || current_instruction == &fLDX || current_instruction == &fLDY
+ || current_instruction == &fORA || current_instruction == &fSBC || current_instruction == &fSTX || current_instruction == &fSTY ){
+ switch(addr){
+ case eImmediate:
+ ret.cycles = 2; break;
+ case eZeroPage:
+ ret.cycles = 3; break;
+ case eZeroPageIndexedX: case eAbsolute: case eAbsoluteIndexedX: case eAbsoluteIndexedY:
+ ret.cycles = 4; break;
+ case eIndexedIndirect:
+ ret.cycles = 6; break;
+ case eIndirectIndexed:
+ ret.cycles = 5; break;
+ }
+ }
+
+ //case &fASL: case &fDEC: case &fINC: case &fLSR: case &fROL: case &fROR:
+ else if( current_instruction == &fASL || current_instruction == &fDEC || current_instruction == &fINC
+ || current_instruction == &fLSR || current_instruction == &fROL || current_instruction == &fROR ){
+ switch(addr){
+ case eAccumulator:
+ ret.cycles = 2; break;
+ case eZeroPage:
+ ret.cycles = 5; break;
+ case eZeroPageIndexedX: case eAbsolute:
+ ret.cycles = 6; break;
+ case eAbsoluteIndexedX:
+ ret.cycles = 7; break;
+ }
+ }
+
+ //case &fSTA:
+ else if (current_instruction == &fSTA){
+ switch(addr){
+ case eZeroPage:
+ ret.cycles = 3; break;
+ case eZeroPageIndexedX: case eAbsolute:
+ ret.cycles = 4; break;
+ case eAbsoluteIndexedX: case eAbsoluteIndexedY:
+ ret.cycles = 5; break;
+ case eIndexedIndirect: case eIndirectIndexed:
+ ret.cycles = 6; break;
+ }
+ }
+
+
+ //case &fBRK:
+ else if (current_instruction == &fBRK){
+ ret.cycles = 7;
+ }
+
+
+ //case &fRTI: case &fRTS: case &fJSR:
+ else if (current_instruction == &fRTI || current_instruction == &fRTS || current_instruction == &fJSR){
+ ret.cycles = 6;
+ }
+
+ //case &fJMP:
+ else if (current_instruction == &fJMP){
+ ret.cycles = 5;
+ }
+
+ //case &fPLA: case &fPLP:
+ else if (current_instruction == &fPLA || current_instruction == &fPLP){
+ ret.cycles = 4;
+ }
+
+ //case &fPHA: case &fPHP:
+ else if (current_instruction == &fPHA || current_instruction == &fPHP){
+ ret.cycles = 3;
+ }
+
+ else {
+ ret.cycles = 2;
+ }
+
+
+ // Page Boundary
+
+ //case &fADC: case &fSBC: case &fLDA: case &fLDX: case &fLDY: case &fEOR: case &fAND: case &fORA: case &fCMP:
+ if ( current_instruction == &fADC || current_instruction == &fSBC || current_instruction == &fLDA || current_instruction == &fLDX || current_instruction == &fLDY
+ || current_instruction == &fEOR || current_instruction == &fAND || current_instruction == &fORA || current_instruction == &fCMP ){
+ switch(addr){
+ case eAbsoluteIndexedX:
+ if ((x & 0xFF00) != ((x + X) & 0xFF00)) ret.cycles++; break;
+ case eAbsoluteIndexedY:
+ if ((x & 0xFF00) != ((x + Y) & 0xFF00)) ret.cycles++; break;
+ case eIndirectIndexed:
+ if ((ret.add & 0xFF00) != (ret.add - Y & 0xFF00)) ret.cycles++; break;
+ }
+ }
+
+ return ret;
+}
+
diff --git a/src/cpu/instructions/definitions.h b/src/cpu/instructions/definitions.h
new file mode 100644
index 0000000..937ca10
--- /dev/null
+++ b/src/cpu/instructions/definitions.h
@@ -0,0 +1,360 @@
+// instructions.h
+// Definition of all instruction functions, handling effect of instruction and flags.
+
+AddData idata;
+
+
+/* TO DO
+
+!!!!!!!! CHECK THAT idata.value IS USED ACROSS ALL FUNCTIONS, NOT VAL !!!!!!!!!!!!!!
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Fix all functions before performing testing
+
+*/
+
+// Load and Store Instructions
+
+void fLDA(Addressing addr, address val){ idata = fAddress(addr, val);
+ acc = idata.value;
+}
+
+void fLDX(Addressing addr, address val){ idata = fAddress(addr, val);
+ X = idata.value;
+}
+
+void fLDY(Addressing addr, address val){ idata = fAddress(addr, val);
+ Y = idata.value;
+}
+
+void fSTA(Addressing addr, address val){ idata = fAddress(addr, val);
+ setMemory(idata.add, acc);
+}
+
+void fSTX(Addressing addr, address val){ idata = fAddress(addr, val);
+ setMemory(idata.add, X);
+}
+
+void fSTY(Addressing addr, address val){ idata = fAddress(addr, val);
+ setMemory(idata.add, Y);
+}
+
+// Arithmetic Instructions
+
+void fADC(Addressing addr, address val){ idata = fAddress(addr, val);
+ int buffer = acc + idata.value;
+ setFlagV(buffer, acc);
+
+ if (buffer > 255)
+ flagSet(flag_C);
+ else
+ flagClear(flag_C);
+
+ acc += idata.value;
+ setFlagN(acc);
+ setFlagZ(acc);
+}
+
+void fSBC(Addressing addr, address val){ idata = fAddress(addr, val);
+ int buffer = acc - idata.value;
+ setFlagV(buffer, acc);
+
+ if (buffer < 0)
+ flagSet(flag_C);
+ else
+ flagClear(flag_C);
+
+ acc -= idata.value;
+ setFlagN(acc);
+ setFlagZ(acc);
+}
+
+//Increment and Decrement Instructions
+
+void fINC(Addressing addr, address val){ idata = fAddress(addr, val);
+ byte a = getMemory(idata.add);
+ a++;
+ setMemory(idata.add, a);
+ setFlagN(Memory[idata.add]);
+ setFlagZ(Memory[idata.add]);
+}
+
+void fINX(Addressing addr, address val){ idata = fAddress(addr, val);
+ X++;
+ setFlagN(X);
+ setFlagZ(X);
+}
+
+void fINY(Addressing addr, address val){ idata = fAddress(addr, val);
+ Y++;
+ setFlagN(Y);
+ setFlagZ(Y);
+}
+
+void fDEC(Addressing addr, address val){ idata = fAddress(addr, val);
+ byte a = getMemory(idata.add);
+ a--;
+ setMemory(idata.add, a);
+ setFlagN(Memory[idata.add]);
+ setFlagZ(Memory[idata.add]);
+}
+
+void fDEX(Addressing addr, address val){ idata = fAddress(addr, val);
+ X--;
+ setFlagN(X);
+ setFlagZ(X);
+}
+
+void fDEY(Addressing addr, address val){ idata = fAddress(addr, val);
+ Y--;
+ setFlagN(Y);
+ setFlagZ(Y);
+}
+
+// Logical Instructions
+
+void fAND(Addressing addr, address val){ idata = fAddress(addr, val);
+ acc &= idata.value;
+ setFlagN(acc);
+ setFlagZ(acc);
+}
+
+void fORA(Addressing addr, address val){ idata = fAddress(addr, val);
+ acc |= idata.value;
+ setFlagN(acc);
+ setFlagZ(acc);
+}
+
+void fEOR(Addressing addr, address val){ idata = fAddress(addr, val);
+ acc ^= idata.value;
+ setFlagN(acc);
+ setFlagZ(acc);
+}
+
+// Jump, Branch, Compare, and Test Bits
+
+void fJMP(Addressing addr, address val){ idata = fAddress(addr, val);
+ PC = val;
+}
+
+void fBCC(Addressing addr, address val){ idata = fAddress(addr, val); //FINISH ALL BRANCH INSTRUCTIONS
+ //signed char val down to BVC
+ if (getFlag(flag_C) == 0) PC += val;
+}
+
+void fBCS(Addressing addr, address val){ idata = fAddress(addr, val);
+ if (getFlag(flag_C) == 1) PC += val;
+}
+
+void fBEQ(Addressing addr, address val){ idata = fAddress(addr, val);
+ if (getFlag(flag_Z) == 1) PC += val;
+}
+
+void fBNE(Addressing addr, address val){ idata = fAddress(addr, val);
+ if (getFlag(flag_Z) == 0) PC += val;
+}
+
+void fBMI(Addressing addr, address val){ idata = fAddress(addr, val);
+ if (getFlag(flag_N) == 1) PC += val;
+}
+
+void fBPL(Addressing addr, address val){ idata = fAddress(addr, val);
+ if (getFlag(flag_N) == 0) PC += val;
+}
+
+void fBVS(Addressing addr, address val){ idata = fAddress(addr, val);
+ if (getFlag(flag_V) == 1) PC += val;
+}
+
+void fBVC(Addressing addr, address val){ idata = fAddress(addr, val);
+ if (getFlag(flag_V) == 0) PC += val;
+}
+
+void fCMP(Addressing addr, address val){ idata = fAddress(addr, val);
+ if (acc < idata.value){
+ flagSet(flag_N); flagClear(flag_Z); flagClear(flag_C);
+ }if (acc == idata.value){
+ flagClear(flag_N); flagSet(flag_Z); flagClear(flag_C);
+ }if (acc > idata.value){
+ flagClear(flag_N); flagClear(flag_Z); flagSet(flag_C);
+ }
+}
+
+void fCPX(Addressing addr, address val){ idata = fAddress(addr, val);
+ if (X < idata.value){
+ flagSet(flag_N); flagClear(flag_Z); flagClear(flag_C);
+ }if (X == idata.value){
+ flagClear(flag_N); flagSet(flag_Z); flagClear(flag_C);
+ }if (X > idata.value){
+ flagClear(flag_N); flagClear(flag_Z); flagSet(flag_C);
+ }
+}
+
+void fCPY(Addressing addr, address val){ idata = fAddress(addr, val);
+ if (Y < idata.value){
+ flagSet(flag_N); flagClear(flag_Z); flagClear(flag_C);
+ }if (Y == idata.value){
+ flagClear(flag_N); flagSet(flag_Z); flagClear(flag_C);
+ }if (Y > idata.value){
+ flagClear(flag_N); flagClear(flag_Z); flagSet(flag_C);
+ }
+}
+
+//NEED TO DOUBLE CHECK THIS INSTRUCTION
+void fBIT(Addressing addr, address val){ idata = fAddress(addr, val);
+ setFlag(flag_N, (idata.value & flag_N));
+ setFlag(flag_V, (idata.value & flag_V));
+
+ if (((idata.value & flag_N) & (idata.value & flag_V)) == 0) {
+ flagSet(flag_Z);
+ } else {
+ flagSet(flag_Z);
+ }
+}
+
+// Shift and Rotate Instructions
+
+void fASL(Addressing addr, address val){ idata = fAddress(addr, val);
+ setFlag(flag_C, (idata.value & 0x80));
+ acc = (idata.value << 1);
+ setFlagN(acc);
+ setFlagZ(acc);
+}
+
+void fLSR(Addressing addr, address val){ idata = fAddress(addr, val);
+ setFlag(flag_C, (idata.value & 0x01));
+ acc = (idata.value >> 1);
+ setFlagN(acc);
+ setFlagZ(acc);
+}
+
+void fROL(Addressing addr, address val){ idata = fAddress(addr, val);
+ setFlag(flag_C, (val & 0x80));
+ acc = (val << 1);
+ acc |= (getFlag(flag_C) * 0x01);
+ setFlagN(acc);
+ setFlagZ(acc);
+}
+
+void fROR(Addressing addr, address val){ idata = fAddress(addr, val);
+ setFlag(flag_C, (val & 0x01));
+ acc = (val >> 1);
+ acc |= (getFlag(flag_C) * 0x80);
+ setFlagN(acc);
+ setFlagZ(acc);
+}
+
+// Transfer Instructions
+
+void fTAX(Addressing addr, address val){ idata = fAddress(addr, val);
+ X = acc;
+ //setFlagN(X);
+ //setFlagZ(X);
+}
+
+void fTAY(Addressing addr, address val){ idata = fAddress(addr, val);
+ Y = acc;
+ //setFlagN(Y);
+ //setFlagZ(Y);
+}
+
+void fTXA(Addressing addr, address val){ idata = fAddress(addr, val);
+ acc = X;
+ setFlagN(acc);
+ setFlagZ(acc);
+}
+
+void fTYA(Addressing addr, address val){ idata = fAddress(addr, val);
+ acc = Y;
+ setFlagN(acc);
+ setFlagZ(acc);
+}
+
+// Stack Instructions
+
+void fTSX(Addressing addr, address val){ idata = fAddress(addr, val);
+ X = S;
+}
+
+void fTXS(Addressing addr, address val){ idata = fAddress(addr, val);
+ S = X;
+}
+
+void fPHA(Addressing addr, address val){ idata = fAddress(addr, val);
+ setMemory(0x01FF-S, acc);
+ S++;
+}
+
+void fPHP(Addressing addr, address val){ idata = fAddress(addr, val);
+ setMemory(0x01FF-S, P);
+ S++;
+}
+
+void fPLA(Addressing addr, address val){ idata = fAddress(addr, val);
+ S--;
+ acc = getMemory(0x01FF-S);
+}
+
+void fPLP(Addressing addr, address val){ idata = fAddress(addr, val);
+ S--;
+ P = getMemory(0x01FF-S);
+}
+
+// Subroutine Instructions
+// NEED TO FINISH THESE
+
+void fJSR(Addressing addr, address val){ idata = fAddress(addr, val);
+ Memory[0x01FF-S] = (idata.add-1);
+ S++;
+ PC = idata.add;
+}
+
+void fRTS(Addressing addr, address val){ idata = fAddress(addr, val);
+
+}
+
+void fRTI(Addressing addr, address val){ idata = fAddress(addr, val);
+
+}
+
+// Set/Reset Insutrctions
+
+void fCLC(Addressing addr, address val){ idata = fAddress(addr, val);
+ flagClear(flag_C);
+}
+
+void fCLD(Addressing addr, address val){ idata = fAddress(addr, val);
+ flagClear(flag_D);
+}
+
+void fCLI(Addressing addr, address val){ idata = fAddress(addr, val);
+ flagClear(flag_I);
+}
+
+void fCLV(Addressing addr, address val){ idata = fAddress(addr, val);
+ flagClear(flag_V);
+}
+
+void fSEC(Addressing addr, address val){ idata = fAddress(addr, val);
+ flagSet(flag_C);
+}
+
+void fSED(Addressing addr, address val){ idata = fAddress(addr, val);
+ flagSet(flag_D);
+}
+
+void fSEI(Addressing addr, address val){ idata = fAddress(addr, val);
+ flagSet(flag_I);
+}
+
+// NOP/BRK Instructions
+
+void fNOP(Addressing addr, address val){ idata = fAddress(addr, val);
+}
+
+void fBRK(Addressing addr, address val){ idata = fAddress(addr, val);
+ flagSet(flag_B);
+}
+
+#ifdef ILLEGAL
+#include"illegal/definitions.h"
+#endif \ No newline at end of file
diff --git a/src/cpu/instructions/illegal/definitions.h b/src/cpu/instructions/illegal/definitions.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/cpu/instructions/illegal/definitions.h
diff --git a/src/cpu/instructions/illegal/init.h b/src/cpu/instructions/illegal/init.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/cpu/instructions/illegal/init.h
diff --git a/src/cpu/instructions/illegal/table-append.h b/src/cpu/instructions/illegal/table-append.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/cpu/instructions/illegal/table-append.h
diff --git a/src/cpu/instructions/init.h b/src/cpu/instructions/init.h
new file mode 100644
index 0000000..dd2d477
--- /dev/null
+++ b/src/cpu/instructions/init.h
@@ -0,0 +1,74 @@
+// instruction-init.h
+// Initializes every instruction function prior to addressing.h
+
+// Load and Store Instructions
+void fLDA(Addressing, address);
+void fLDX(Addressing, address);
+void fLDY(Addressing, address);
+void fSTA(Addressing, address);
+void fSTX(Addressing, address);
+void fSTY(Addressing, address);
+// Arithmetic Instructions
+void fADC(Addressing, address);
+void fSBC(Addressing, address);
+//Increment and Decrement Instructions
+void fINC(Addressing, address);
+void fINX(Addressing, address);
+void fINY(Addressing, address);
+void fDEC(Addressing, address);
+void fDEX(Addressing, address);
+void fDEY(Addressing, address);
+// Logical Instructions
+void fAND(Addressing, address);
+void fORA(Addressing, address);
+void fEOR(Addressing, address);
+// Jump, Branch, Compare, and Test Bits
+void fJMP(Addressing, address);
+void fBCC(Addressing, address);
+void fBCS(Addressing, address);
+void fBEQ(Addressing, address);
+void fBNE(Addressing, address);
+void fBMI(Addressing, address);
+void fBPL(Addressing, address);
+void fBVS(Addressing, address);
+void fBVC(Addressing, address);
+void fCMP(Addressing, address);
+void fCPX(Addressing, address);
+void fCPY(Addressing, address);
+void fBIT(Addressing, address);
+// Shift and Rotate Instructions
+void fASL(Addressing, address);
+void fLSR(Addressing, address);
+void fROL(Addressing, address);
+void fROR(Addressing, address);
+// Transfer Instructions
+void fTAX(Addressing, address);
+void fTAY(Addressing, address);
+void fTXA(Addressing, address);
+void fTYA(Addressing, address);
+// Stack Instructions
+void fTSX(Addressing, address);
+void fTXS(Addressing, address);
+void fPHA(Addressing, address);
+void fPHP(Addressing, address);
+void fPLA(Addressing, address);
+void fPLP(Addressing, address);
+// Subroutine Instructions
+void fJSR(Addressing, address);
+void fRTS(Addressing, address);
+void fRTI(Addressing, address);
+// Set/Reset Insutrctions
+void fCLC(Addressing, address);
+void fCLD(Addressing, address);
+void fCLI(Addressing, address);
+void fCLV(Addressing, address);
+void fSEC(Addressing, address);
+void fSED(Addressing, address);
+void fSEI(Addressing, address);
+// NOP/BRK Instructions
+void fNOP(Addressing, address);
+void fBRK(Addressing, address);
+
+#ifdef ILLEGAL
+#include"illegal/init.h"
+#endif \ No newline at end of file
diff --git a/src/cpu/instructions/table.h b/src/cpu/instructions/table.h
new file mode 100644
index 0000000..f37814b
--- /dev/null
+++ b/src/cpu/instructions/table.h
@@ -0,0 +1,270 @@
+// instruction-table.h
+// Defines the instruction table, and the functions to access it.
+
+void* InstructionTable;
+void (*func)(Addressing, address);
+
+#define InstructionTableSize (256 * (sizeof(uintptr_t) + sizeof(Addressing)))
+
+uintptr_t* getInstructionTableFunction(int i){ //Segmentation fault is occurring here, likely in next one too
+ uintptr_t* r = (InstructionTable + (sizeof(uintptr_t)*i));
+ return r;
+}
+
+Addressing* getInstructionTableAddressing(int i){
+ Addressing* r = (InstructionTable + (sizeof(uintptr_t)*256) + (sizeof(Addressing)*i));
+ return r;
+}
+
+void callInstructionTable(int i, address val){
+ uintptr_t a = getInstructionTableFunction(i);
+ memcpy(&func, a, sizeof(uintptr_t));
+ Addressing* r = (InstructionTable + ((sizeof(uintptr_t)*256) + (sizeof(Addressing) * i)));
+ func(*r, val);
+}
+
+void setInstructionTable(int i, uintptr_t p, Addressing r){
+ uintptr_t* p1 = (InstructionTable + (sizeof(uintptr_t)*i));
+ *p1 = p;
+
+ Addressing* r1 = (InstructionTable + (sizeof(uintptr_t)*256) + (sizeof(Addressing)*i));
+ *r1 = r;
+}
+
+void initInstructionTable(){
+ InstructionTable = malloc(InstructionTableSize);
+ // Load and Store Instructions
+ // fLDA(Addressing, address);
+ setInstructionTable(0xA9, (uintptr_t)&fLDA, eImmediate);
+ setInstructionTable(0xA5, (uintptr_t)&fLDA, eZeroPage);
+ setInstructionTable(0xB5, (uintptr_t)&fLDA, eZeroPageIndexedX);
+ setInstructionTable(0xAD, (uintptr_t)&fLDA, eAbsolute);
+ setInstructionTable(0xBD, (uintptr_t)&fLDA, eAbsoluteIndexedX);
+ setInstructionTable(0xB9, (uintptr_t)&fLDA, eAbsoluteIndexedY);
+ setInstructionTable(0xA1, (uintptr_t)&fLDA, eIndexedIndirect);
+ setInstructionTable(0xB1, (uintptr_t)&fLDA, eIndirectIndexed);
+ // fLDX(Addressing, address);
+ setInstructionTable(0xA2, (uintptr_t)&fLDX, eImmediate);
+ setInstructionTable(0xA6, (uintptr_t)&fLDX, eZeroPage);
+ setInstructionTable(0xB6, (uintptr_t)&fLDX, eZeroPageIndexedY);
+ setInstructionTable(0xAE, (uintptr_t)&fLDX, eAbsolute);
+ setInstructionTable(0xBE, (uintptr_t)&fLDX, eAbsoluteIndexedY);
+ // fLDY(Addressing, address);
+ setInstructionTable(0xA0, (uintptr_t)&fLDY, eImmediate);
+ setInstructionTable(0xA4, (uintptr_t)&fLDY, eZeroPage);
+ setInstructionTable(0xB4, (uintptr_t)&fLDY, eZeroPageIndexedX);
+ setInstructionTable(0xAC, (uintptr_t)&fLDY, eAbsolute);
+ setInstructionTable(0xBC, (uintptr_t)&fLDY, eAbsoluteIndexedX);
+ // fSTA(Addressing, address);
+ setInstructionTable(0x85, (uintptr_t)&fSTA, eZeroPage);
+ setInstructionTable(0x95, (uintptr_t)&fSTA, eZeroPageIndexedX);
+ setInstructionTable(0x8D, (uintptr_t)&fSTA, eAbsolute);
+ setInstructionTable(0x9D, (uintptr_t)&fSTA, eAbsoluteIndexedX);
+ setInstructionTable(0x99, (uintptr_t)&fSTA, eAbsoluteIndexedY);
+ setInstructionTable(0x81, (uintptr_t)&fSTA, eIndexedIndirect);
+ setInstructionTable(0x91, (uintptr_t)&fSTA, eIndirectIndexed);
+ // fSTX(Addressing, address);
+ setInstructionTable(0x86, (uintptr_t)&fSTX, eZeroPage);
+ setInstructionTable(0x96, (uintptr_t)&fSTX, eZeroPageIndexedX);
+ setInstructionTable(0x8E, (uintptr_t)&fSTX, eAbsolute);
+ // fSTY(Addressing, address);
+ setInstructionTable(0x84, (uintptr_t)&fSTY, eZeroPage);
+ setInstructionTable(0x94, (uintptr_t)&fSTY, eZeroPageIndexedY);
+ setInstructionTable(0x8C, (uintptr_t)&fSTY, eAbsolute);
+
+ // Arithmetic Instructions
+ // fADC(Addressing, address);
+ setInstructionTable(0x69, (uintptr_t)&fADC, eImmediate);
+ setInstructionTable(0x65, (uintptr_t)&fADC, eZeroPage);
+ setInstructionTable(0x75, (uintptr_t)&fADC, eZeroPageIndexedX);
+ setInstructionTable(0x6D, (uintptr_t)&fADC, eAbsolute);
+ setInstructionTable(0x7D, (uintptr_t)&fADC, eAbsoluteIndexedX);
+ setInstructionTable(0x79, (uintptr_t)&fADC, eAbsoluteIndexedY);
+ setInstructionTable(0x61, (uintptr_t)&fADC, eIndexedIndirect);
+ setInstructionTable(0x71, (uintptr_t)&fADC, eIndirectIndexed);
+ // fSBC(Addressing, address);
+ setInstructionTable(0xE9, (uintptr_t)&fSBC, eImmediate);
+ setInstructionTable(0xE5, (uintptr_t)&fSBC, eZeroPage);
+ setInstructionTable(0xF5, (uintptr_t)&fSBC, eZeroPageIndexedX);
+ setInstructionTable(0xED, (uintptr_t)&fSBC, eAbsolute);
+ setInstructionTable(0xFD, (uintptr_t)&fSBC, eAbsoluteIndexedX);
+ setInstructionTable(0xF9, (uintptr_t)&fSBC, eAbsoluteIndexedY);
+ setInstructionTable(0xE1, (uintptr_t)&fSBC, eIndexedIndirect);
+ setInstructionTable(0xF1, (uintptr_t)&fSBC, eIndirectIndexed);
+
+ //Increment and Decrement Instructions
+ //INC(Addressing, address);
+ setInstructionTable(0xE6, (uintptr_t)&fINC, eZeroPage);
+ setInstructionTable(0xF6, (uintptr_t)&fINC, eZeroPageIndexedX);
+ setInstructionTable(0xEE, (uintptr_t)&fINC, eAbsolute);
+ setInstructionTable(0xFE, (uintptr_t)&fINC, eAbsoluteIndexedX);
+ //INX(Addressing, address);
+ setInstructionTable(0xE8, (uintptr_t)&fINX, eImplied);
+ //INY(Addressing, address);
+ setInstructionTable(0xC8, (uintptr_t)&fINY, eImplied);
+ //DEC(Addressing, address);
+ setInstructionTable(0xC6, (uintptr_t)&fDEC, eZeroPage);
+ setInstructionTable(0xD6, (uintptr_t)&fDEC, eZeroPageIndexedX);
+ setInstructionTable(0xCE, (uintptr_t)&fDEC, eAbsolute);
+ setInstructionTable(0xDE, (uintptr_t)&fDEC, eAbsoluteIndexedX);
+ //DEX(Addressing, address);
+ setInstructionTable(0xCA, (uintptr_t)&fDEX, eImplied);
+ //DEY(Addressing, address);
+ setInstructionTable(0x88, (uintptr_t)&fDEY, eImplied);
+
+ // Logical Instructions
+ //AND(Addressing, address);
+ setInstructionTable(0x29, (uintptr_t)&fAND, eImmediate);
+ setInstructionTable(0x25, (uintptr_t)&fAND, eZeroPage);
+ setInstructionTable(0x35, (uintptr_t)&fAND, eZeroPageIndexedX);
+ setInstructionTable(0x2D, (uintptr_t)&fAND, eAbsolute);
+ setInstructionTable(0x3D, (uintptr_t)&fAND, eAbsoluteIndexedX);
+ setInstructionTable(0x39, (uintptr_t)&fAND, eAbsoluteIndexedY);
+ setInstructionTable(0x21, (uintptr_t)&fAND, eIndexedIndirect);
+ setInstructionTable(0x31, (uintptr_t)&fAND, eIndirectIndexed);
+ //ORA(Addressing, address);
+ setInstructionTable(0x09, (uintptr_t)&fORA, eImmediate);
+ setInstructionTable(0x05, (uintptr_t)&fORA, eZeroPage);
+ setInstructionTable(0x15, (uintptr_t)&fORA, eZeroPageIndexedX);
+ setInstructionTable(0x0D, (uintptr_t)&fORA, eAbsolute);
+ setInstructionTable(0x1D, (uintptr_t)&fORA, eAbsoluteIndexedX);
+ setInstructionTable(0x19, (uintptr_t)&fORA, eAbsoluteIndexedY);
+ setInstructionTable(0x01, (uintptr_t)&fORA, eIndexedIndirect);
+ setInstructionTable(0x11, (uintptr_t)&fORA, eIndirectIndexed);
+ //EOR(Addressing, address);
+ setInstructionTable(0x49, (uintptr_t)&fEOR, eImmediate);
+ setInstructionTable(0x45, (uintptr_t)&fEOR, eZeroPage);
+ setInstructionTable(0x55, (uintptr_t)&fEOR, eZeroPageIndexedX);
+ setInstructionTable(0x4D, (uintptr_t)&fEOR, eAbsolute);
+ setInstructionTable(0x5D, (uintptr_t)&fEOR, eAbsoluteIndexedX);
+ setInstructionTable(0x59, (uintptr_t)&fEOR, eAbsoluteIndexedY);
+ setInstructionTable(0x41, (uintptr_t)&fEOR, eIndexedIndirect);
+ setInstructionTable(0x51, (uintptr_t)&fEOR, eIndirectIndexed);
+
+ // Jump, Branch, Compare, and Test Bits
+ //JMP(Addressing, address);
+ setInstructionTable(0x4C, (uintptr_t)&fJMP, eAbsolute);
+ setInstructionTable(0x6C, (uintptr_t)&fJMP, eIndirectAbsolute);
+ //BCC(Addressing, address);
+ setInstructionTable(0x90, (uintptr_t)&fBCC, eRelative);
+ //BCS(Addressing, address);
+ setInstructionTable(0xB0, (uintptr_t)&fBCS, eRelative);
+ //BEQ(Addressing, address);
+ setInstructionTable(0xF0, (uintptr_t)&fBEQ, eRelative);
+ //BNE(Addressing, address);
+ setInstructionTable(0xD0, (uintptr_t)&fBNE, eRelative);
+ //BMI(Addressing, address);
+ setInstructionTable(0x30, (uintptr_t)&fBMI, eRelative);
+ //BPL(Addressing, address);
+ setInstructionTable(0x10, (uintptr_t)&fBPL, eRelative);
+ //BVS(Addressing, address);
+ setInstructionTable(0x70, (uintptr_t)&fBVS, eRelative);
+ //BVC(Addressing, address);
+ setInstructionTable(0x50, (uintptr_t)&fBVC, eRelative);
+ //CMP(Addressing, address);
+ setInstructionTable(0xC9, (uintptr_t)&fCMP, eImmediate);
+ setInstructionTable(0xC5, (uintptr_t)&fCMP, eZeroPage);
+ setInstructionTable(0xD5, (uintptr_t)&fCMP, eZeroPageIndexedX);
+ setInstructionTable(0xCD, (uintptr_t)&fCMP, eAbsolute);
+ setInstructionTable(0xDD, (uintptr_t)&fCMP, eAbsoluteIndexedX);
+ setInstructionTable(0xD9, (uintptr_t)&fCMP, eAbsoluteIndexedY);
+ setInstructionTable(0xC1, (uintptr_t)&fCMP, eIndexedIndirect);
+ setInstructionTable(0xD1, (uintptr_t)&fCMP, eIndirectIndexed);
+ //CPX(Addressing, address);
+ setInstructionTable(0xE0, (uintptr_t)&fCPX, eImmediate);
+ setInstructionTable(0xE4, (uintptr_t)&fCPX, eZeroPage);
+ setInstructionTable(0xEC, (uintptr_t)&fCPX, eAbsolute);
+ //CPY(Addressing, address);
+ setInstructionTable(0xC0, (uintptr_t)&fCPY, eImmediate);
+ setInstructionTable(0xC4, (uintptr_t)&fCPY, eZeroPage);
+ setInstructionTable(0xCC, (uintptr_t)&fCPY, eAbsolute);
+ //BIT(Addressing, address);
+ setInstructionTable(0x4C, (uintptr_t)&fBIT, eZeroPage);
+ setInstructionTable(0x6C, (uintptr_t)&fBIT, eAbsolute);
+
+ // Shift and Rotate Instructions
+ //ASL(Addressing, address);
+ setInstructionTable(0x0A, (uintptr_t)&fASL, eAccumulator);
+ setInstructionTable(0x06, (uintptr_t)&fASL, eZeroPage);
+ setInstructionTable(0x16, (uintptr_t)&fASL, eZeroPageIndexedX);
+ setInstructionTable(0x0E, (uintptr_t)&fASL, eAbsolute);
+ setInstructionTable(0x1E, (uintptr_t)&fASL, eAbsoluteIndexedX);
+ //LSR(Addressing, address);
+ setInstructionTable(0x4A, (uintptr_t)&fLSR, eAccumulator);
+ setInstructionTable(0x46, (uintptr_t)&fLSR, eZeroPage);
+ setInstructionTable(0x56, (uintptr_t)&fLSR, eZeroPageIndexedX);
+ setInstructionTable(0x4E, (uintptr_t)&fLSR, eAbsolute);
+ setInstructionTable(0x5E, (uintptr_t)&fLSR, eAbsoluteIndexedX);
+ //ROL(Addressing, address);
+ setInstructionTable(0x2A, (uintptr_t)&fROL, eAccumulator);
+ setInstructionTable(0x26, (uintptr_t)&fROL, eZeroPage);
+ setInstructionTable(0x36, (uintptr_t)&fROL, eZeroPageIndexedX);
+ setInstructionTable(0x2E, (uintptr_t)&fROL, eAbsolute);
+ setInstructionTable(0x3E, (uintptr_t)&fROL, eAbsoluteIndexedX);
+ //ROR(Addressing, address);
+ setInstructionTable(0x6A, (uintptr_t)&fROR, eAccumulator);
+ setInstructionTable(0x66, (uintptr_t)&fROR, eZeroPage);
+ setInstructionTable(0x76, (uintptr_t)&fROR, eZeroPageIndexedX);
+ setInstructionTable(0x6E, (uintptr_t)&fROR, eAbsolute);
+ setInstructionTable(0x7E, (uintptr_t)&fROR, eAbsoluteIndexedX);
+
+ // Transfer Instructions
+ //TAX(Addressing, address);
+ setInstructionTable(0xAA, (uintptr_t)&fTAX, eImplied);
+ //TAY(Addressing, address);
+ setInstructionTable(0xA8, (uintptr_t)&fTAY, eImplied);
+ //TXA(Addressing, address);
+ setInstructionTable(0x8A, (uintptr_t)&fTXA, eImplied);
+ //TYA(Addressing, address);
+ setInstructionTable(0x98, (uintptr_t)&fTYA, eImplied);
+
+ // Stack Instructions
+ //TSX(Addressing, address);
+ setInstructionTable(0xBA, (uintptr_t)&fTSX, eImplied);
+ //TXS(Addressing, address);
+ setInstructionTable(0x9A, (uintptr_t)&fTXS, eImplied);
+ //PHA(Addressing, address);
+ setInstructionTable(0x48, (uintptr_t)&fPHA, eImplied);
+ //PHP(Addressing, address);
+ setInstructionTable(0x08, (uintptr_t)&fPHP, eImplied);
+ //PLA(Addressing, address);
+ setInstructionTable(0x68, (uintptr_t)&fPLA, eImplied);
+ //PLP(Addressing, address);
+ setInstructionTable(0x28, (uintptr_t)&fPLP, eImplied);
+
+ // Subroutine Instructions
+ //JSR(Addressing, address);
+ setInstructionTable(0x20, (uintptr_t)&fJSR, eAbsolute);
+ //RTS(Addressing, address);
+ setInstructionTable(0x60, (uintptr_t)&fRTS, eImplied);
+ //RTI(Addressing, address);
+ setInstructionTable(0x40, (uintptr_t)&fRTI, eImplied);
+
+ // Set/Reset Insutrctions
+ //CLC(Addressing, address);
+ setInstructionTable(0x18, (uintptr_t)&fCLC, eImplied);
+ //CLD(Addressing, address);
+ setInstructionTable(0xD8, (uintptr_t)&fCLD, eImplied);
+ //CLI(Addressing, address);
+ setInstructionTable(0x58, (uintptr_t)&fCLI, eImplied);
+ //CLV(Addressing, address);
+ setInstructionTable(0xB8, (uintptr_t)&fCLV, eImplied);
+ //SEC(Addressing, address);
+ setInstructionTable(0x38, (uintptr_t)&fSEC, eImplied);
+ //SED(Addressing, address);
+ setInstructionTable(0xF8, (uintptr_t)&fSED, eImplied);
+ //SEI(Addressing, address);
+ setInstructionTable(0x78, (uintptr_t)&fSEI, eImplied);
+
+ // NOP/BRK Instructions
+ //NOP(Addressing, address);
+ setInstructionTable(0xEA, (uintptr_t)&fNOP, eImplied);
+ //BRK(Addressing, address);
+ setInstructionTable(0x00, (uintptr_t)&fBRK, eImplied);
+
+ #ifdef ILLEGAL
+ #include"illegal/table-append.h"
+ #endif
+
+}
+