summaryrefslogtreecommitdiff
path: root/src/cpu/instructions.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/instructions.c')
-rw-r--r--src/cpu/instructions.c393
1 files changed, 229 insertions, 164 deletions
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);