summaryrefslogtreecommitdiff
path: root/src/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu')
-rw-r--r--src/cpu/6502.c50
-rw-r--r--src/cpu/6502.h53
-rw-r--r--src/cpu/addressing.c161
-rw-r--r--src/cpu/addressing.h17
-rw-r--r--src/cpu/core.h31
-rw-r--r--src/cpu/instructions.c393
-rw-r--r--src/cpu/instructions.h112
-rw-r--r--src/cpu/table.c512
-rw-r--r--src/cpu/table.h10
9 files changed, 611 insertions, 728 deletions
diff --git a/src/cpu/6502.c b/src/cpu/6502.c
index 595cd4e..7ae3f16 100644
--- a/src/cpu/6502.c
+++ b/src/cpu/6502.c
@@ -7,34 +7,23 @@ byte acc, X, Y, P, S = 0x00;
address PC = 0x0000;
byte* Memory;
-byte getFlag(byte flag) {
+
+byte GetFlag(byte flag) {
return (P & flag) ? 1 : 0;
}
+
void SetFlag(byte flag, int x) {
P = (P & ~flag) | ((x != 0) ? flag : 0);
}
-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);*/
+void SetFlag_N(byte x){
P = (x & flag_N) | (P & ~flag_N);
}
-//Perform prior to any changes TODO: FIX THIS! WTF WERE YOU THINKING?
-void SetFlagV(byte x, byte y){
+
+void SetFlag_V(byte x, byte y){
address z = (address)x + (address)y;
if ((x & 0x80) != (y & 0x80))
SetFlag(flag_V, 1);
@@ -42,44 +31,21 @@ void SetFlagV(byte x, byte y){
SetFlag(flag_V, 0);
}
-/*void SetFlagB(){ //WORK ON
- SetFlag(flag_B, 1);
-}*/
-/*void SetFlagD(){
- SetFlag(flag_D, 1);
-}*/
-
-/*void SetFlagI(){ //WORK ON
- SetFlag(flag_Z, 1);
-}*/
-
-void SetFlagZ(int x){
+void SetFlag_Z(int x){
if (x == 0)
SetFlag(flag_Z, 1);
else
SetFlag(flag_Z, 0);
}
-/*void SetFlagC(){
- SetFlag(flag_Z, 1);
-}*/
-
-
-/*byte GetMemory(address x){
- return Memory[x];
-}
-
-void SetMemory(address x, byte y){
- Memory[x] = y;
-}*/
-
byte GetStack() {
S--;
return GetMemory(0x01FF - S);
}
+
void SetStack(byte x) {
SetMemory(0x01FF - S, x);
S++;
diff --git a/src/cpu/6502.h b/src/cpu/6502.h
index bad36fb..41ecb7a 100644
--- a/src/cpu/6502.h
+++ b/src/cpu/6502.h
@@ -6,7 +6,7 @@
#include"stdio.h"
#include"core.h"
-// FLAGS
+// CPU Flags
#define flag_N 0x80 // Negative
#define flag_V 0x40 // Overflow
#define flag_B 0x10 // BRK command
@@ -15,50 +15,21 @@
#define flag_Z 0x02 // Zero
#define flag_C 0x01 // Carry
-byte getFlag(byte flag);
-// Get the value of a flag.
+// Return a truth value of 1 or 0.
+byte GetFlag(byte flag);
+// x can be a conditional, and any non-zero value will set the flag.
void SetFlag(byte flag, int x);
-// Set a flag with some value.
-void flagSet(byte flag);
-// Sets some flag.
+// Reusable routines for setting specific flags
+void SetFlag_N(byte x);
+void SetFlag_V(byte x, byte y);
+void SetFlag_Z(int x);
-void flagClear(byte flag);
-// Clears some flag.
-
-// Functions which perform reusable routines for finding if a specific flag should be set.
-
-void SetFlagN(byte x);
-
-//Perform prior to any changes
-void SetFlagV(byte x, byte y);
-
-//void SetFlagB();
-//May not need since its dependent on the BRK insturction
-
-//void SetFlagD();
-//Might not be necessary.
-
-//void SetFlagI();
-//Need to work on.
-
-void SetFlagZ(int x);
-
-//void SetFlagC();
-//Only 6 instructions, 2 not including stack instructions, use the carry flag.
-
-// The following two may be better defined within apple.c
-
-//byte GetMemory(address x);
-// Retrieve value from the computers address space.
-// It is important not to directly access the memory array because some value hold special meaning.
-
-//void SetMemory(address x, byte y);
-// Set a piece of memory to some value.
+// Memory access declarations; to be defined somewhere computer-specific, not CPU-specific
+byte GetMemory(address x);
+void SetMemory(address x, byte y);
+// Stack access and manipulation
byte GetStack();
-// Get top value of the stack.
-
void SetStack(byte z);
-// Set top value of the stack. \ No newline at end of file
diff --git a/src/cpu/addressing.c b/src/cpu/addressing.c
index b8f9330..8c6c619 100644
--- a/src/cpu/addressing.c
+++ b/src/cpu/addressing.c
@@ -1,15 +1,12 @@
// addressing.h
-// Contains definitions relevant to addressing, as well as fAddress() which returns time, length, value, and address for an instruction function call.
-// Would like to refactor the code into something better, such as switch-case statements for the cycles calculation.
-#include"addressing.h"
+#include "addressing.h"
-//Holds address of current instruction. I don't think it's being used at all besides fAddressGetCycles(), so will be removed.
-void* current_instruction;
-
-address fAddressGetAddress(Addressing mode, address x) {
- switch(mode){
+address fAddressGetAddress(Addressing mode, address x)
+{
+ switch(mode)
+ {
case eImplied:
case eRelative:
case eImmediate:
@@ -18,7 +15,7 @@ address fAddressGetAddress(Addressing mode, address x) {
case eAbsolute:
return x;
case eIndirectAbsolute:
- return (address)GetMemory(x) + (((address)GetMemory(x+1)) << 8);
+ return (((address)GetMemory(x+1)) << 8) + (address)GetMemory(x);
case eAbsoluteIndexedX:
return x + X;
case eAbsoluteIndexedY:
@@ -30,26 +27,31 @@ address fAddressGetAddress(Addressing mode, address x) {
case eZeroPageIndexedY:
return ((x + Y) & 0x00FF);
case eIndexedIndirect:
- return (((address)(GetMemory(x+X+1)))<<8) + (address)(GetMemory(x+X));
+ return (((address)(GetMemory(x+X+1))) << 8) + (address)(GetMemory(x+X));
case eIndirectIndexed:
- return ((address)(GetMemory(x+1))<<8) + ((address)(GetMemory(x))) + ((address)Y);
- //return ((x >> 8) & 0xFF) (x & 0xFF)
- }
+ return ((address)(GetMemory(x+1)) << 8) + ((address)(GetMemory(x))) + ((address)Y);
+ }
}
-int fAddressGetLength(Addressing mode){
- switch(mode){
+
+int fAddressGetLength(Addressing mode)
+{
+ switch(mode)
+ {
case eAbsolute: case eAbsoluteIndexedX: case eAbsoluteIndexedY: case eIndirectAbsolute:
return 3;
case eAccumulator: case eImplied:
return 1;
default:
return 2;
- }
+ }
}
-byte fAddressGetValue(Addressing mode, address x, address addr) {
- switch(mode){
+
+byte fAddressGetValue(Addressing mode, address x, address addr)
+{
+ switch(mode)
+ {
case eImplied:
return 0;
case eRelative:
@@ -59,124 +61,15 @@ byte fAddressGetValue(Addressing mode, address x, address addr) {
return acc;
default:
return GetMemory(addr);
- }
-}
-
-// At the moment not run, and will probably be replaced by just direct storage of values.
-// The code making up this is likely way less performant and larger than just looking up stored values, so I will change it in the future to do that instead.
-int fAddressGetCycles(Addressing mode, address x, address addr) {
- int 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(mode){
- case eImmediate:
- cycles = 2; break;
- case eZeroPage:
- cycles = 3; break;
- case eZeroPageIndexedX: case eAbsolute: case eAbsoluteIndexedX: case eAbsoluteIndexedY:
- cycles = 4; break;
- case eIndexedIndirect:
- cycles = 6; break;
- case eIndirectIndexed:
- 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(mode){
- case eAccumulator:
- cycles = 2; break;
- case eZeroPage:
- cycles = 5; break;
- case eZeroPageIndexedX: case eAbsolute:
- cycles = 6; break;
- case eAbsoluteIndexedX:
- cycles = 7; break;
}
- }
-
- //case &fSTA:
- else if (current_instruction == &fSTA){
- switch(mode){
- case eZeroPage:
- cycles = 3; break;
- case eZeroPageIndexedX: case eAbsolute:
- cycles = 4; break;
- case eAbsoluteIndexedX: case eAbsoluteIndexedY:
- cycles = 5; break;
- case eIndexedIndirect: case eIndirectIndexed:
- cycles = 6; break;
- }
- }
-
-
- //case &fBRK:
- else if (current_instruction == &fBRK){
- cycles = 7;
- }
-
-
- //case &fRTI: case &fRTS: case &fJSR:
- else if (current_instruction == &fRTI || current_instruction == &fRTS || current_instruction == &fJSR){
- cycles = 6;
- }
-
- //case &fJMP:
- else if (current_instruction == &fJMP){
- cycles = 5;
- }
-
- //case &fPLA: case &fPLP:
- else if (current_instruction == &fPLA || current_instruction == &fPLP){
- cycles = 4;
- }
-
- //case &fPHA: case &fPHP:
- else if (current_instruction == &fPHA || current_instruction == &fPHP){
- cycles = 3;
- }
-
- else {
- 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(mode){
- case eAbsoluteIndexedX:
- if ((x & 0xFF00) != ((x + X) & 0xFF00))
- cycles++;
- break;
- case eAbsoluteIndexedY:
- if ((x & 0xFF00) != ((x + Y) & 0xFF00))
- cycles++;
- break;
- case eIndirectIndexed:
- if ((addr & 0xFF00) != (addr - Y & 0xFF00))
- cycles++;
- break;
- }
- }
-
- return cycles;
}
-AddData fAddress(Addressing mode, address x) {
- AddData ret;
- ret.add = fAddressGetAddress (mode, x);
- ret.value = fAddressGetValue (mode, x, ret.add);
- ret.length = fAddressGetLength (mode);
- //ret.cycles = fAddressGetCycles (mode, x, ret.add);
+
+struct State fAddress(Addressing mode, address x)
+{
+ struct State ret;
+ ret.address = fAddressGetAddress (mode, x);
+ ret.value = fAddressGetValue (mode, x, ret.address);
+ ret.length = fAddressGetLength (mode);
return ret;
}
diff --git a/src/cpu/addressing.h b/src/cpu/addressing.h
index 790b912..d8f12a3 100644
--- a/src/cpu/addressing.h
+++ b/src/cpu/addressing.h
@@ -3,17 +3,12 @@
#pragma once
-#include"core.h"
-#include"6502.h"
-#include"instructions.h"
-
-
-#define getInstructionLength(c) fAddressGetLength(*GetInstructionTableAddressing(c))
-
+#include "core.h"
+#include "6502.h"
+#include "instructions.h"
// For a given addressing mode and opcode, return data about the instruction.
-AddData fAddress (Addressing mode, address x );
-address fAddressGetAddress (Addressing mode, address x );
-int fAddressGetLength (Addressing mode );
+struct State fAddress (Addressing mode, address x);
+address fAddressGetAddress (Addressing mode, address x);
+int fAddressGetLength (Addressing mode);
byte fAddressGetValue (Addressing mode, address x, address addr);
-int fAddressGetCycles (Addressing mode, address x, address addr);
diff --git a/src/cpu/core.h b/src/cpu/core.h
index 7c0f284..f83002f 100644
--- a/src/cpu/core.h
+++ b/src/cpu/core.h
@@ -1,12 +1,9 @@
#pragma once
-typedef
-unsigned char
-byte;
+#include <stdint.h>
-typedef
-unsigned short
-address;
+typedef uint8_t byte;
+typedef uint16_t address;
extern byte acc;
extern byte X;
@@ -17,7 +14,6 @@ extern address PC;
extern byte* Memory;
extern byte ROM[];
-
enum Addressing
{
eImmediate,
@@ -34,28 +30,19 @@ enum Addressing
eIndirectAbsolute,
eRelative
};
+
typedef
int
Addressing;
-typedef
-struct AddData
+struct State
{
int cycles;
int length;
- address add;
+ address address;
byte value;
-}
-AddData;
-
-
-
-// GetMemory and SetMemory are declared here, but defined in apple.c
-// This is because memory access of particular memory locations is influenced by the Apple I's specific setup, not by the CPU alone.
-byte GetMemory(address x);
-void SetMemory(address x, byte y);
+};
-extern void *current_instruction;
-extern AddData idata;
-extern void (*func)(Addressing);
+extern struct State state;
+extern void (*Instruction)(Addressing);
diff --git a/src/cpu/instructions.c b/src/cpu/instructions.c
index 0f002d3..8828f3e 100644
--- a/src/cpu/instructions.c
+++ b/src/cpu/instructions.c
@@ -3,368 +3,433 @@
#include"instructions.h"
-/* TO DO
+struct State state;
-!!!!!!!! CHECK THAT idata.value IS USED ACROSS ALL FUNCTIONS, NOT VAL !!!!!!!!!!!!!!
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Fix all functions before performing testing
-
-*/
+// Load and Store Instructions
-AddData idata;
+void PageBoundary(Addressing r) {
+ switch(r)
+ {
+ case eAbsoluteIndexedX:
+ if ((state.address & 0xFF00) != ((state.address + X) & 0xFF00))
+ state.cycles++;
+ break;
+ case eAbsoluteIndexedY:
+ if ((state.address & 0xFF00) != ((state.address + Y) & 0xFF00))
+ state.cycles++;
+ break;
+ case eIndirectIndexed:
+ if ((state.address & 0xFF00) != (state.address - Y & 0xFF00))
+ state.cycles++;
+ break;
+ case eRelative:
+ // Assuming that this goes at the end of the break function.
+ if ((PC & 0xFF00) != ((PC - (char)state.value) & 0xFF00))
+ state.cycles++;
+ break;
+ }
+}
-// Load and Store Instructions
-void fLDA(Addressing addr){
- acc = idata.value;
- SetFlagN(acc);
- SetFlagZ(acc);
+void LDA(Addressing addr){
+ acc = state.value;
+ SetFlag_N(acc);
+ SetFlag_Z(acc);
+ PageBoundary(addr);
}
-void fLDX(Addressing addr){
- X = idata.value;
- SetFlagN(X);
- SetFlagZ(X);
+void LDX(Addressing addr){
+ X = state.value;
+ SetFlag_N(X);
+ SetFlag_Z(X);
+ PageBoundary(addr);
}
-void fLDY(Addressing addr){
- Y = idata.value;
- SetFlagN(Y);
- SetFlagZ(Y);
+void LDY(Addressing addr){
+ Y = state.value;
+ SetFlag_N(Y);
+ SetFlag_Z(Y);
+ PageBoundary(addr);
}
-void fSTA(Addressing addr){
- SetMemory(idata.add, acc);
+void STA(Addressing addr){
+ SetMemory(state.address, acc);
}
-void fSTX(Addressing addr){
- SetMemory(idata.add, X);
+void STX(Addressing addr){
+ SetMemory(state.address, X);
}
-void fSTY(Addressing addr){
- SetMemory(idata.add, Y);
+void STY(Addressing addr){
+ SetMemory(state.address, Y);
}
// Arithmetic Instructions
+// TODO: Add BCD arithmetic modes.
-void fADC(Addressing addr){
- byte buffer = acc + idata.value + getFlag(flag_C);
+void ADC(Addressing addr){
+ byte buffer = acc + state.value + GetFlag(flag_C);
- SetFlagV(buffer, acc);
+ SetFlag_V(buffer, acc);
SetFlag(flag_C, (buffer < acc) ? 1 : 0);
acc = buffer;
- SetFlagN(acc);
- SetFlagZ(acc);
+ SetFlag_N(acc);
+ SetFlag_Z(acc);
+ PageBoundary(addr);
}
-void fSBC(Addressing addr){
- byte buffer = acc - idata.value - !getFlag(flag_C);
+void SBC(Addressing addr){
+ byte buffer = acc - state.value - !GetFlag(flag_C);
- SetFlagV(buffer, acc);
+ SetFlag_V(buffer, acc);
SetFlag(flag_C, (buffer > acc) ? 0 : 1);
acc = buffer;
- SetFlagN(acc);
- SetFlagZ(acc);
+ SetFlag_N(acc);
+ SetFlag_Z(acc);
+ PageBoundary(addr);
}
+
//Increment and Decrement Instructions
-void fINC(Addressing addr){
- byte a = idata.value;
- SetMemory(idata.add, ++a);
- SetFlagN(a);
- SetFlagZ(a);
+void INC(Addressing addr){
+ byte a = state.value;
+ SetMemory(state.address, ++a);
+ SetFlag_N(a);
+ SetFlag_Z(a);
}
-void fINX(Addressing addr){
+void INX(Addressing addr){
X++;
- SetFlagN(X);
- SetFlagZ(X);
+ SetFlag_N(X);
+ SetFlag_Z(X);
}
-void fINY(Addressing addr){
+void INY(Addressing addr){
Y++;
- SetFlagN(Y);
- SetFlagZ(Y);
+ SetFlag_N(Y);
+ SetFlag_Z(Y);
}
-void fDEC(Addressing addr){
- byte a = idata.value;
- SetMemory(idata.add, --a);
- SetFlagN(a);
- SetFlagZ(a);
+void DEC(Addressing addr){
+ byte a = state.value;
+ SetMemory(state.address, --a);
+ SetFlag_N(a);
+ SetFlag_Z(a);
}
-void fDEX(Addressing addr){
+void DEX(Addressing addr){
X--;
- SetFlagN(X);
- SetFlagZ(X);
+ SetFlag_N(X);
+ SetFlag_Z(X);
}
-void fDEY(Addressing addr){
+void DEY(Addressing addr){
Y--;
- SetFlagN(Y);
- SetFlagZ(Y);
+ SetFlag_N(Y);
+ SetFlag_Z(Y);
}
+
// Logical Instructions
-void fAND(Addressing addr){
- acc &= idata.value;
- SetFlagN(acc);
- SetFlagZ(acc);
+void AND(Addressing addr){
+ acc &= state.value;
+ SetFlag_N(acc);
+ SetFlag_Z(acc);
+ PageBoundary(addr);
}
-void fORA(Addressing addr){
- acc |= idata.value;
- SetFlagN(acc);
- SetFlagZ(acc);
+void ORA(Addressing addr){
+ acc |= state.value;
+ SetFlag_N(acc);
+ SetFlag_Z(acc);
+ PageBoundary(addr);
}
-void fEOR(Addressing addr){
- acc ^= idata.value;
- SetFlagN(acc);
- SetFlagZ(acc);
+void EOR(Addressing addr){
+ acc ^= state.value;
+ SetFlag_N(acc);
+ SetFlag_Z(acc);
+ PageBoundary(addr);
}
+
// Jump, Branch, Compare, and Test Bits
-void fJMP(Addressing addr){
- PC = idata.add - idata.length;
+void JMP(Addressing addr){
+ PC = state.address - state.length;
}
-void fBCC(Addressing addr){
- if (getFlag(flag_C) == 0) PC += (char)idata.value;
+void BCC(Addressing addr){
+ if (GetFlag(flag_C) == 0) {
+ PC += (char)state.value;
+ state.cycles++;
+ PageBoundary(addr);
+ }
}
-void fBCS(Addressing addr){
- if (getFlag(flag_C) == 1) PC += (char)idata.value;
+void BCS(Addressing addr){
+ if (GetFlag(flag_C) == 1) {
+ PC += (char)state.value;
+ state.cycles++;
+ PageBoundary(addr);
+ }
}
-void fBEQ(Addressing addr){
- if (getFlag(flag_Z) == 1) PC += (char)idata.value;
+void BEQ(Addressing addr){
+ if (GetFlag(flag_Z) == 1) {
+ PC += (char)state.value;
+ state.cycles++;
+ PageBoundary(addr);
+ }
}
-void fBNE(Addressing addr){
- if (getFlag(flag_Z) == 0) PC += (char)idata.value;
+void BNE(Addressing addr){
+ if (GetFlag(flag_Z) == 0) {
+ PC += (char)state.value;
+ state.cycles++;
+ PageBoundary(addr);
+ }
}
-void fBMI(Addressing addr){
- if (getFlag(flag_N) == 1) PC += (char)idata.value;
+void BMI(Addressing addr){
+ if (GetFlag(flag_N) == 1) {
+ PC += (char)state.value;
+ state.cycles++;
+ PageBoundary(addr);
+ }
}
-void fBPL(Addressing addr){
- if (getFlag(flag_N) == 0) PC += (char)idata.value;
+void BPL(Addressing addr){
+ if (GetFlag(flag_N) == 0) {
+ PC += (char)state.value;
+ state.cycles++;
+ PageBoundary(addr);
+ }
}
-void fBVS(Addressing addr){
- if (getFlag(flag_V) == 1) PC += (char)idata.value;
+void BVS(Addressing addr){
+ if (GetFlag(flag_V) == 1) {
+ PC += (char)state.value;
+ state.cycles++;
+ PageBoundary(addr);
+ }
}
-void fBVC(Addressing addr){
- if (getFlag(flag_V) == 0) PC += (char)idata.value;
+void BVC(Addressing addr){
+ if (GetFlag(flag_V) == 0) {
+ PC += (char)state.value;
+ state.cycles++;
+ PageBoundary(addr);
+ }
}
-void fCMP(Addressing addr){
- SetFlag(flag_C, (acc >= idata.value) ? 1 : 0);
- SetFlag(flag_Z, (acc == idata.value) ? 1 : 0);
- SetFlag(flag_N, (acc < idata.value) ? 1 : 0);
+void CMP(Addressing addr){
+ SetFlag(flag_C, (acc >= state.value) ? 1 : 0);
+ SetFlag(flag_Z, (acc == state.value) ? 1 : 0);
+ SetFlag(flag_N, (acc < state.value) ? 1 : 0);
+ PageBoundary(addr);
}
-void fCPX(Addressing addr){
- SetFlag(flag_C, (X >= idata.value) ? 1 : 0);
- SetFlag(flag_Z, (X == idata.value) ? 1 : 0);
- SetFlag(flag_N, (X < idata.value) ? 1 : 0);
+void CPX(Addressing addr){
+ SetFlag(flag_C, (X >= state.value) ? 1 : 0);
+ SetFlag(flag_Z, (X == state.value) ? 1 : 0);
+ SetFlag(flag_N, (X < state.value) ? 1 : 0);
}
-void fCPY(Addressing addr){
- SetFlag(flag_C, (Y >= idata.value) ? 1 : 0);
- SetFlag(flag_Z, (Y == idata.value) ? 1 : 0);
- SetFlag(flag_N, (Y < idata.value) ? 1 : 0);
+void CPY(Addressing addr){
+ SetFlag(flag_C, (Y >= state.value) ? 1 : 0);
+ SetFlag(flag_Z, (Y == state.value) ? 1 : 0);
+ SetFlag(flag_N, (Y < state.value) ? 1 : 0);
}
-void fBIT(Addressing addr){
- SetFlag(flag_N, ((idata.value & flag_N) != 0));
- SetFlag(flag_V, ((idata.value & flag_V) != 0));
- SetFlag(flag_Z, ((idata.value & acc) == 0));
+void BIT(Addressing addr){
+ SetFlag(flag_N, ((state.value & flag_N) != 0));
+ SetFlag(flag_V, ((state.value & flag_V) != 0));
+ SetFlag(flag_Z, ((state.value & acc) == 0));
}
+
// Shift and Rotate Instructions
-void fASL(Addressing addr){
- byte m = (addr == eAccumulator) ? acc : idata.value;
+void ASL(Addressing addr){
+ byte m = (addr == eAccumulator) ? acc : state.value;
SetFlag(flag_C, (m & 0b10000000));
m = (m << 1) & 0b11111110;
- SetFlagN(m);
- SetFlagZ(m);
+ SetFlag_N(m);
+ SetFlag_Z(m);
(addr == eAccumulator)
? acc = m
- : SetMemory(idata.add, m);
+ : SetMemory(state.address, m);
}
-void fLSR(Addressing addr) {
- byte m = (addr == eAccumulator) ? acc : idata.value;
+void LSR(Addressing addr) {
+ byte m = (addr == eAccumulator) ? acc : state.value;
SetFlag(flag_C, (m & 0b00000001));
m = (m >> 1) & 0b01111111;
- SetFlagN(m);
- SetFlagZ(m);
+ SetFlag_N(m);
+ SetFlag_Z(m);
(addr == eAccumulator)
? acc = m
- : SetMemory(idata.add, m);
+ : SetMemory(state.address, m);
}
-void fROL(Addressing addr){
- byte m = (addr == eAccumulator) ? acc : idata.value;
+void ROL(Addressing addr){
+ byte m = (addr == eAccumulator) ? acc : state.value;
byte flag_store = (m & 0b10000000);
- //SetFlag(flag_C, (m & 0b10000000));
m = (m << 1) & 0b11111110;
- m |= (getFlag(flag_C)) ? 0b00000001 : 0;
+ m |= (GetFlag(flag_C)) ? 0b00000001 : 0;
SetFlag(flag_C, flag_store);
- SetFlagN(m);
- SetFlagZ(m);
+ SetFlag_N(m);
+ SetFlag_Z(m);
(addr == eAccumulator)
? acc = m
- : SetMemory(idata.add, m);
+ : SetMemory(state.address, m);
}
-void fROR(Addressing addr){
- byte m = (addr == eAccumulator) ? acc : idata.value;
+void ROR(Addressing addr){
+ byte m = (addr == eAccumulator) ? acc : state.value;
byte flag_store = (m & 0b00000001);
- //SetFlag(flag_C, (m & 0b00000001));
m = (m >> 1) & 0b01111111;
- m |= (getFlag(flag_C)) ? 0b10000000 : 0;
+ m |= (GetFlag(flag_C)) ? 0b10000000 : 0;
SetFlag(flag_C, flag_store);
- SetFlagN(m);
- SetFlagZ(m);
+ SetFlag_N(m);
+ SetFlag_Z(m);
(addr == eAccumulator)
? acc = m
- : SetMemory(idata.add, m);
+ : SetMemory(state.address, m);
}
+
// Transfer Instructions
-void fTAX(Addressing addr){
+void TAX(Addressing addr){
X = acc;
- SetFlagN(X);
- SetFlagZ(X);
+ SetFlag_N(X);
+ SetFlag_Z(X);
}
-void fTAY(Addressing addr){
+void TAY(Addressing addr){
Y = acc;
- SetFlagN(Y);
- SetFlagZ(Y);
+ SetFlag_N(Y);
+ SetFlag_Z(Y);
}
-void fTXA(Addressing addr){
+void TXA(Addressing addr){
acc = X;
- SetFlagN(acc);
- SetFlagZ(acc);
+ SetFlag_N(acc);
+ SetFlag_Z(acc);
}
-void fTYA(Addressing addr){
+void TYA(Addressing addr){
acc = Y;
- SetFlagN(acc);
- SetFlagZ(acc);
+ SetFlag_N(acc);
+ SetFlag_Z(acc);
}
+
// Stack Instructions
-void fTSX(Addressing addr){
+void TSX(Addressing addr){
X = S;
}
-void fTXS(Addressing addr){
+void TXS(Addressing addr){
S = X;
}
-void fPHA(Addressing addr){
+void PHA(Addressing addr){
SetStack(acc);
}
-void fPHP(Addressing addr){
+void PHP(Addressing addr){
SetStack(P);
}
-void fPLA(Addressing addr){
+void PLA(Addressing addr){
acc = GetStack();
}
-void fPLP(Addressing addr){
+void PLP(Addressing addr){
P = GetStack();
}
+
// Subroutine Instructions
-void fJSR(Addressing addr){
- SetStack ((PC+idata.length) >> 8);
- SetStack(((PC+idata.length) & 0x00FF) - 1);
- PC = idata.add;
- PC -= idata.length;
+void JSR(Addressing addr){
+ SetStack ((PC+state.length) >> 8);
+ SetStack(((PC+state.length) & 0x00FF) - 1);
+ PC = state.address;
+ PC -= state.length;
}
-void fRTS(Addressing addr){
+void RTS(Addressing addr){
PC = (address)(GetStack()) + 1;
PC += ((address)(GetStack())) << 8;
- PC -= idata.length;
+ PC -= state.length;
}
-void fRTI(Addressing addr){
- P = GetStack(); //NEED TO FIX
+void RTI(Addressing addr){
+ P = GetStack();
PC = (address)(GetStack());
PC += (address)(GetStack() << 8);
}
+
// Set/Reset Insutrctions
-void fCLC(Addressing addr){
+void CLC(Addressing addr){
SetFlag(flag_C, 0);
}
-void fCLD(Addressing addr){
+void CLD(Addressing addr){
SetFlag(flag_D, 0);
}
-void fCLI(Addressing addr){
+void CLI(Addressing addr){
SetFlag(flag_I, 0);
}
-void fCLV(Addressing addr){
+void CLV(Addressing addr){
SetFlag(flag_V, 0);
}
-void fSEC(Addressing addr){
+void SEC(Addressing addr){
SetFlag(flag_C, 1);
}
-void fSED(Addressing addr){
+void SED(Addressing addr){
SetFlag(flag_D, 1);
}
-void fSEI(Addressing addr){
+void SEI(Addressing addr){
SetFlag(flag_I, 1);
}
+
// NOP/BRK Instructions
-void fNOP(Addressing addr){
+void NOP(Addressing addr){
}
-void fBRK(Addressing addr){
+void BRK(Addressing addr){
SetStack((((PC+2) & 0xFF00) >> 8));
SetStack((PC+2) & 0x00FF);
SetStack(P);
diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h
index 705cc0d..4bf93b3 100644
--- a/src/cpu/instructions.h
+++ b/src/cpu/instructions.h
@@ -5,79 +5,79 @@
#include"6502.h"
// Load and Store Instructions
-void fLDA(Addressing);
-void fLDX(Addressing);
-void fLDY(Addressing);
-void fSTA(Addressing);
-void fSTX(Addressing);
-void fSTY(Addressing);
+void LDA(Addressing);
+void LDX(Addressing);
+void LDY(Addressing);
+void STA(Addressing);
+void STX(Addressing);
+void STY(Addressing);
// Arithmetic Instructions
-void fADC(Addressing);
-void fSBC(Addressing);
+void ADC(Addressing);
+void SBC(Addressing);
//Increment and Decrement Instructions
-void fINC(Addressing);
-void fINX(Addressing);
-void fINY(Addressing);
-void fDEC(Addressing);
-void fDEX(Addressing);
-void fDEY(Addressing);
+void INC(Addressing);
+void INX(Addressing);
+void INY(Addressing);
+void DEC(Addressing);
+void DEX(Addressing);
+void DEY(Addressing);
// Logical Instructions
-void fAND(Addressing);
-void fORA(Addressing);
-void fEOR(Addressing);
+void AND(Addressing);
+void ORA(Addressing);
+void EOR(Addressing);
// Jump, Branch, Compare, and Test Bits
-void fJMP(Addressing);
-void fBCC(Addressing);
-void fBCS(Addressing);
-void fBEQ(Addressing);
-void fBNE(Addressing);
-void fBMI(Addressing);
-void fBPL(Addressing);
-void fBVS(Addressing);
-void fBVC(Addressing);
-void fCMP(Addressing);
-void fCPX(Addressing);
-void fCPY(Addressing);
-void fBIT(Addressing);
+void JMP(Addressing);
+void BCC(Addressing);
+void BCS(Addressing);
+void BEQ(Addressing);
+void BNE(Addressing);
+void BMI(Addressing);
+void BPL(Addressing);
+void BVS(Addressing);
+void BVC(Addressing);
+void CMP(Addressing);
+void CPX(Addressing);
+void CPY(Addressing);
+void BIT(Addressing);
// Shift and Rotate Instructions
-void fASL(Addressing);
-void fLSR(Addressing);
-void fROL(Addressing);
-void fROR(Addressing);
+void ASL(Addressing);
+void LSR(Addressing);
+void ROL(Addressing);
+void ROR(Addressing);
// Transfer Instructions
-void fTAX(Addressing);
-void fTAY(Addressing);
-void fTXA(Addressing);
-void fTYA(Addressing);
+void TAX(Addressing);
+void TAY(Addressing);
+void TXA(Addressing);
+void TYA(Addressing);
// Stack Instructions
-void fTSX(Addressing);
-void fTXS(Addressing);
-void fPHA(Addressing);
-void fPHP(Addressing);
-void fPLA(Addressing);
-void fPLP(Addressing);
+void TSX(Addressing);
+void TXS(Addressing);
+void PHA(Addressing);
+void PHP(Addressing);
+void PLA(Addressing);
+void PLP(Addressing);
// Subroutine Instructions
-void fJSR(Addressing);
-void fRTS(Addressing);
-void fRTI(Addressing);
+void JSR(Addressing);
+void RTS(Addressing);
+void RTI(Addressing);
// Set/Reset Insutrctions
-void fCLC(Addressing);
-void fCLD(Addressing);
-void fCLI(Addressing);
-void fCLV(Addressing);
-void fSEC(Addressing);
-void fSED(Addressing);
-void fSEI(Addressing);
+void CLC(Addressing);
+void CLD(Addressing);
+void CLI(Addressing);
+void CLV(Addressing);
+void SEC(Addressing);
+void SED(Addressing);
+void SEI(Addressing);
// NOP/BRK Instructions
-void fNOP(Addressing);
-void fBRK(Addressing);
+void NOP(Addressing);
+void BRK(Addressing);
diff --git a/src/cpu/table.c b/src/cpu/table.c
index 052fce7..a5c1c41 100644
--- a/src/cpu/table.c
+++ b/src/cpu/table.c
@@ -2,283 +2,295 @@
#include"table.h"
-
void* InstructionTable;
+void (*Instruction)(Addressing);
-void (*func)(Addressing);
+// Macros for accessing the InstructionTable
+#define InstructionTableFunction(x) ((uintptr_t*)(InstructionTable + (sizeof(uintptr_t) * x)))
+#define InstructionTableAddressing(x) ((Addressing*)(InstructionTable + (sizeof(uintptr_t) * 256) + (sizeof(Addressing) * x)))
+#define InstructionTableCycles(x) ((int*)(InstructionTable + (sizeof(uintptr_t) * 256) + (sizeof(Addressing) * 256) + (sizeof(int) * x)))
-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;
-}
+const InstructionTableSize = (256 * (sizeof(uintptr_t) + sizeof(Addressing) + sizeof(int)));
-Addressing* GetInstructionTableAddressing(int i){
- Addressing* r = (InstructionTable + (sizeof(uintptr_t)*256) + (sizeof(Addressing)*i));
- return r;
-}
-void CallInstructionTable(){
- int val = 0;
- // Setup to call the correct function.
- int i = (int)GetMemory(PC);
- uintptr_t a = GetInstructionTableFunction(i);
- memcpy(&func, a, sizeof(uintptr_t));
- // Find the correct addressing mode.
- Addressing r = *(Addressing*)(InstructionTable + ((sizeof(uintptr_t)*256) + (sizeof(Addressing) * i)));
+void CallInstructionTable()
+{
+ // Set function.
+ memcpy(&Instruction,
+ InstructionTableFunction((int)GetMemory(PC)),
+ sizeof(uintptr_t));
+
+ // Find the addressing mode.
+ Addressing r = *InstructionTableAddressing(GetMemory(PC));
// Set val
+ int val = 0;
if (fAddressGetLength(r) >= 2)
- val += (address)GetMemory(PC+1);
+ val += GetMemory(PC+1);
if (fAddressGetLength(r) == 3)
- val += (address)GetMemory(PC+2) << 8;
+ val += ((address)GetMemory(PC+2)) << 8;
- // Set idata
- idata = fAddress(r, val);
+ // Set state
+ state = fAddress(r, val);
// Perform function
- func(r);
+ Instruction(r);
-
- PC += idata.length;
+ // Incrememt the program counter.
+ PC += state.length;
}
-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 SetInstructionTable(int index, void* function, Addressing addressing, int cycles)
+{
+ *InstructionTableFunction(index) = (uintptr_t)function;
+ *InstructionTableAddressing(index) = addressing;
+ *InstructionTableCycles(index) = cycles;
}
-void InitInstructionTable(){
+
+void InitInstructionTable()
+{
+ // Create InstructionTable
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);
+ // Load and Store Instructions
+
+ // LDA
+ SetInstructionTable(0xA9, &LDA, eImmediate, 2);
+ SetInstructionTable(0xA5, &LDA, eZeroPage, 3);
+ SetInstructionTable(0xB5, &LDA, eZeroPageIndexedX, 4);
+ SetInstructionTable(0xAD, &LDA, eAbsolute, 4);
+ SetInstructionTable(0xBD, &LDA, eAbsoluteIndexedX, 4);
+ SetInstructionTable(0xB9, &LDA, eAbsoluteIndexedY, 4);
+ SetInstructionTable(0xA1, &LDA, eIndexedIndirect, 6);
+ SetInstructionTable(0xB1, &LDA, eIndirectIndexed, 5);
+ // LDX
+ SetInstructionTable(0xA2, &LDX, eImmediate, 2);
+ SetInstructionTable(0xA6, &LDX, eZeroPage, 3);
+ SetInstructionTable(0xB6, &LDX, eZeroPageIndexedY, 4);
+ SetInstructionTable(0xAE, &LDX, eAbsolute, 4);
+ SetInstructionTable(0xBE, &LDX, eAbsoluteIndexedY, 4);
+ // LDY
+ SetInstructionTable(0xA0, &LDY, eImmediate, 2);
+ SetInstructionTable(0xA4, &LDY, eZeroPage, 3);
+ SetInstructionTable(0xB4, &LDY, eZeroPageIndexedX, 4);
+ SetInstructionTable(0xAC, &LDY, eAbsolute, 4);
+ SetInstructionTable(0xBC, &LDY, eAbsoluteIndexedX, 4);
+ // STA
+ SetInstructionTable(0x85, &STA, eZeroPage, 3);
+ SetInstructionTable(0x95, &STA, eZeroPageIndexedX, 4);
+ SetInstructionTable(0x8D, &STA, eAbsolute, 4);
+ SetInstructionTable(0x9D, &STA, eAbsoluteIndexedX, 5);
+ SetInstructionTable(0x99, &STA, eAbsoluteIndexedY, 5);
+ SetInstructionTable(0x81, &STA, eIndexedIndirect, 6);
+ SetInstructionTable(0x91, &STA, eIndirectIndexed, 6);
+ // STX
+ SetInstructionTable(0x86, &STX, eZeroPage, 3);
+ SetInstructionTable(0x96, &STX, eZeroPageIndexedX, 4);
+ SetInstructionTable(0x8E, &STX, eAbsolute, 4);
+ // STY
+ SetInstructionTable(0x84, &STY, eZeroPage, 3);
+ SetInstructionTable(0x94, &STY, eZeroPageIndexedY, 4);
+ SetInstructionTable(0x8C, &STY, eAbsolute, 4);
+
// 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);
-
+
+ // ADC
+ SetInstructionTable(0x69, &ADC, eImmediate, 2);
+ SetInstructionTable(0x65, &ADC, eZeroPage, 3);
+ SetInstructionTable(0x75, &ADC, eZeroPageIndexedX, 4);
+ SetInstructionTable(0x6D, &ADC, eAbsolute, 4);
+ SetInstructionTable(0x7D, &ADC, eAbsoluteIndexedX, 4);
+ SetInstructionTable(0x79, &ADC, eAbsoluteIndexedY, 4);
+ SetInstructionTable(0x61, &ADC, eIndexedIndirect, 6);
+ SetInstructionTable(0x71, &ADC, eIndirectIndexed, 5);
+ // SBC
+ SetInstructionTable(0xE9, &SBC, eImmediate, 2);
+ SetInstructionTable(0xE5, &SBC, eZeroPage, 3);
+ SetInstructionTable(0xF5, &SBC, eZeroPageIndexedX, 4);
+ SetInstructionTable(0xED, &SBC, eAbsolute, 4);
+ SetInstructionTable(0xFD, &SBC, eAbsoluteIndexedX, 4);
+ SetInstructionTable(0xF9, &SBC, eAbsoluteIndexedY, 4);
+ SetInstructionTable(0xE1, &SBC, eIndexedIndirect, 6);
+ SetInstructionTable(0xF1, &SBC, eIndirectIndexed, 5);
+
+ // Increment and Decrement Instructions
+
+ // INC
+ SetInstructionTable(0xE6, &INC, eZeroPage, 5);
+ SetInstructionTable(0xF6, &INC, eZeroPageIndexedX, 6);
+ SetInstructionTable(0xEE, &INC, eAbsolute, 6);
+ SetInstructionTable(0xFE, &INC, eAbsoluteIndexedX, 7);
+ // INX
+ SetInstructionTable(0xE8, &INX, eImplied, 2);
+ // INY
+ SetInstructionTable(0xC8, &INY, eImplied, 2);
+ // DEC
+ SetInstructionTable(0xC6, &DEC, eZeroPage, 5);
+ SetInstructionTable(0xD6, &DEC, eZeroPageIndexedX, 6);
+ SetInstructionTable(0xCE, &DEC, eAbsolute, 6);
+ SetInstructionTable(0xDE, &DEC, eAbsoluteIndexedX, 7);
+ // DEX
+ SetInstructionTable(0xCA, &DEX, eImplied, 2);
+ // DEY
+ SetInstructionTable(0x88, &DEY, eImplied, 2);
+
// 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);
-
+
+ // AND
+ SetInstructionTable(0x29, &AND, eImmediate, 2);
+ SetInstructionTable(0x25, &AND, eZeroPage, 3);
+ SetInstructionTable(0x35, &AND, eZeroPageIndexedX, 4);
+ SetInstructionTable(0x2D, &AND, eAbsolute, 4);
+ SetInstructionTable(0x3D, &AND, eAbsoluteIndexedX, 4);
+ SetInstructionTable(0x39, &AND, eAbsoluteIndexedY, 4);
+ SetInstructionTable(0x21, &AND, eIndexedIndirect, 6);
+ SetInstructionTable(0x31, &AND, eIndirectIndexed, 5);
+ // ORA
+ SetInstructionTable(0x09, &ORA, eImmediate, 2);
+ SetInstructionTable(0x05, &ORA, eZeroPage, 3);
+ SetInstructionTable(0x15, &ORA, eZeroPageIndexedX, 4);
+ SetInstructionTable(0x0D, &ORA, eAbsolute, 4);
+ SetInstructionTable(0x1D, &ORA, eAbsoluteIndexedX, 4);
+ SetInstructionTable(0x19, &ORA, eAbsoluteIndexedY, 4);
+ SetInstructionTable(0x01, &ORA, eIndexedIndirect, 6);
+ SetInstructionTable(0x11, &ORA, eIndirectIndexed, 5);
+ // EOR
+ SetInstructionTable(0x49, &EOR, eImmediate, 2);
+ SetInstructionTable(0x45, &EOR, eZeroPage, 3);
+ SetInstructionTable(0x55, &EOR, eZeroPageIndexedX, 4);
+ SetInstructionTable(0x4D, &EOR, eAbsolute, 4);
+ SetInstructionTable(0x5D, &EOR, eAbsoluteIndexedX, 4);
+ SetInstructionTable(0x59, &EOR, eAbsoluteIndexedY, 4);
+ SetInstructionTable(0x41, &EOR, eIndexedIndirect, 6);
+ SetInstructionTable(0x51, &EOR, eIndirectIndexed, 5);
+
// 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(0x24, (uintptr_t)&fBIT, eZeroPage);
- SetInstructionTable(0x2C, (uintptr_t)&fBIT, eAbsolute);
-
+
+ // JMP
+ SetInstructionTable(0x4C, &JMP, eAbsolute, 3);
+ SetInstructionTable(0x6C, &JMP, eIndirectAbsolute, 5);
+ // BCC
+ SetInstructionTable(0x90, &BCC, eRelative, 2);
+ // BCS
+ SetInstructionTable(0xB0, &BCS, eRelative, 2);
+ // BEQ
+ SetInstructionTable(0xF0, &BEQ, eRelative, 2);
+ // BNE
+ SetInstructionTable(0xD0, &BNE, eRelative, 2);
+ // BMI
+ SetInstructionTable(0x30, &BMI, eRelative, 2);
+ // BPL
+ SetInstructionTable(0x10, &BPL, eRelative, 2);
+ // BVS
+ SetInstructionTable(0x70, &BVS, eRelative, 2);
+ // BVC
+ SetInstructionTable(0x50, &BVC, eRelative, 2);
+ // CMP
+ SetInstructionTable(0xC9, &CMP, eImmediate, 2);
+ SetInstructionTable(0xC5, &CMP, eZeroPage, 3);
+ SetInstructionTable(0xD5, &CMP, eZeroPageIndexedX, 4);
+ SetInstructionTable(0xCD, &CMP, eAbsolute, 4);
+ SetInstructionTable(0xDD, &CMP, eAbsoluteIndexedX, 4);
+ SetInstructionTable(0xD9, &CMP, eAbsoluteIndexedY, 4);
+ SetInstructionTable(0xC1, &CMP, eIndexedIndirect, 6);
+ SetInstructionTable(0xD1, &CMP, eIndirectIndexed, 5);
+ // CPX
+ SetInstructionTable(0xE0, &CPX, eImmediate, 2);
+ SetInstructionTable(0xE4, &CPX, eZeroPage, 3);
+ SetInstructionTable(0xEC, &CPX, eAbsolute, 4);
+ // CPY
+ SetInstructionTable(0xC0, &CPY, eImmediate, 2);
+ SetInstructionTable(0xC4, &CPY, eZeroPage, 3);
+ SetInstructionTable(0xCC, &CPY, eAbsolute, 4);
+ // BIT
+ SetInstructionTable(0x24, &BIT, eZeroPage, 3);
+ SetInstructionTable(0x2C, &BIT, eAbsolute, 4);
+
// 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);
-
+
+ // ASL
+ SetInstructionTable(0x0A, &ASL, eAccumulator, 2);
+ SetInstructionTable(0x06, &ASL, eZeroPage, 5);
+ SetInstructionTable(0x16, &ASL, eZeroPageIndexedX, 6);
+ SetInstructionTable(0x0E, &ASL, eAbsolute, 6);
+ SetInstructionTable(0x1E, &ASL, eAbsoluteIndexedX, 7);
+ // LSR
+ SetInstructionTable(0x4A, &LSR, eAccumulator, 2);
+ SetInstructionTable(0x46, &LSR, eZeroPage, 5);
+ SetInstructionTable(0x56, &LSR, eZeroPageIndexedX, 6);
+ SetInstructionTable(0x4E, &LSR, eAbsolute, 6);
+ SetInstructionTable(0x5E, &LSR, eAbsoluteIndexedX, 7);
+ // ROL
+ SetInstructionTable(0x2A, &ROL, eAccumulator, 2);
+ SetInstructionTable(0x26, &ROL, eZeroPage, 5);
+ SetInstructionTable(0x36, &ROL, eZeroPageIndexedX, 6);
+ SetInstructionTable(0x2E, &ROL, eAbsolute, 6);
+ SetInstructionTable(0x3E, &ROL, eAbsoluteIndexedX, 7);
+ // ROR
+ SetInstructionTable(0x6A, &ROR, eAccumulator, 2);
+ SetInstructionTable(0x66, &ROR, eZeroPage, 5);
+ SetInstructionTable(0x76, &ROR, eZeroPageIndexedX, 6);
+ SetInstructionTable(0x6E, &ROR, eAbsolute, 6);
+ SetInstructionTable(0x7E, &ROR, eAbsoluteIndexedX, 7);
+
// 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);
-
+
+ // TAX
+ SetInstructionTable(0xAA, &TAX, eImplied, 2);
+ // TAY
+ SetInstructionTable(0xA8, &TAY, eImplied, 2);
+ // TXA
+ SetInstructionTable(0x8A, &TXA, eImplied, 2);
+ // TYA
+ SetInstructionTable(0x98, &TYA, eImplied, 2);
+
// 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);
-
+
+ // TSX
+ SetInstructionTable(0xBA, &TSX, eImplied, 2);
+ // TXS
+ SetInstructionTable(0x9A, &TXS, eImplied, 2);
+ // PHA
+ SetInstructionTable(0x48, &PHA, eImplied, 3);
+ // PHP
+ SetInstructionTable(0x08, &PHP, eImplied, 3);
+ // PLA
+ SetInstructionTable(0x68, &PLA, eImplied, 4);
+ // PLP
+ SetInstructionTable(0x28, &PLP, eImplied, 4);
+
// 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);
-
+
+ // JSR
+ SetInstructionTable(0x20, &JSR, eAbsolute, 6);
+ // RTS
+ SetInstructionTable(0x60, &RTS, eImplied, 6);
+ // RTI
+ SetInstructionTable(0x40, &RTI, eImplied, 6);
+
// 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);
-
+
+ // CLC
+ SetInstructionTable(0x18, &CLC, eImplied, 2);
+ // CLD
+ SetInstructionTable(0xD8, &CLD, eImplied, 2);
+ // CLI
+ SetInstructionTable(0x58, &CLI, eImplied, 2);
+ // CLV
+ SetInstructionTable(0xB8, &CLV, eImplied, 2);
+ // SEC
+ SetInstructionTable(0x38, &SEC, eImplied, 2);
+ // SED
+ SetInstructionTable(0xF8, &SED, eImplied, 2);
+ // SEI
+ SetInstructionTable(0x78, &SEI, eImplied, 2);
+
// NOP/BRK Instructions
- //NOP(Addressing, address);
- SetInstructionTable(0xEA, (uintptr_t)&fNOP, eImplied);
- //BRK(Addressing, address);
- SetInstructionTable(0x00, (uintptr_t)&fBRK, eImplied);
+
+ // NOP
+ SetInstructionTable(0xEA, &NOP, eImplied, 2);
+ // BRK
+ SetInstructionTable(0x00, &BRK, eImplied, 7);
}
-
diff --git a/src/cpu/table.h b/src/cpu/table.h
index 7406c9c..70be525 100644
--- a/src/cpu/table.h
+++ b/src/cpu/table.h
@@ -7,17 +7,11 @@
#include"string.h"
#include"addressing.h"
-
-#define InstructionTableSize (256 * (sizeof(uintptr_t) + sizeof(Addressing)))
-
-uintptr_t* GetInstructionTableFunction(int i);
-
-Addressing* GetInstructionTableAddressing(int i);
-
+// Runs the next instruction through the CPU
void CallInstructionTable();
// Sets an individual portion of an instruction set
-void SetInstructionTable(int i, uintptr_t p, Addressing r);
+void SetInstructionTable(int index, void* function, Addressing addressing, int cycles);
// Initializes instruction table in memory.
void InitInstructionTable();