summaryrefslogtreecommitdiff
path: root/src/cpu/instructions.c
diff options
context:
space:
mode:
authoralekseiplusplus <alekseijeaves@protonmail.com>2023-07-27 11:36:01 +1000
committeralekseiplusplus <alekseijeaves@protonmail.com>2023-07-27 11:36:01 +1000
commit9a6188f821b11b69fff3d3a303dbfcce2e52e6f4 (patch)
treeb06aa0d876b19cca281cbc26db9086ab7241d6bd /src/cpu/instructions.c
parentb158eaeb489bce502198e844593b38a2f5f5b9ee (diff)
refactoring of src/cpu/
Diffstat (limited to 'src/cpu/instructions.c')
-rw-r--r--src/cpu/instructions.c439
1 files changed, 439 insertions, 0 deletions
diff --git a/src/cpu/instructions.c b/src/cpu/instructions.c
new file mode 100644
index 0000000..e61d082
--- /dev/null
+++ b/src/cpu/instructions.c
@@ -0,0 +1,439 @@
+// instructions.c
+// Definition of all instruction functions, handling effect of instruction and flags.
+
+#include"instructions.h"
+
+/* 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);
+ }
+ else if (acc == idata.value){
+ flagClear(flag_N); flagSet(flag_Z); flagClear(flag_C);
+ }
+ else 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);
+ }
+ else if (X == idata.value){
+ flagClear(flag_N); flagSet(flag_Z); flagClear(flag_C);
+ }
+ else 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);
+ }
+ else if (Y == idata.value){
+ flagClear(flag_N); flagSet(flag_Z); flagClear(flag_C);
+ }
+ else 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);
+ SET_STACK(acc);
+ S++;
+}
+
+void fPHP(Addressing addr, address val){
+ idata = fAddress(addr, val);
+ SET_STACK(P);
+ S++;
+}
+
+void fPLA(Addressing addr, address val){
+ idata = fAddress(addr, val);
+ S--;
+ acc = GET_STACK;
+}
+
+void fPLP(Addressing addr, address val){
+ idata = fAddress(addr, val);
+ S--;
+ P = GET_STACK;
+}
+
+// Subroutine Instructions
+// NEED TO FINISH THESE
+
+void fJSR(Addressing addr, address val){
+ idata = fAddress(addr, val);
+ SET_STACK(((PC-1) & 0xFF00) >> 8);
+ S++;
+ SET_STACK((PC-1) & 0x00FF);
+ S++;
+ PC = idata.add;
+}
+
+void fRTS(Addressing addr, address val){
+ idata = fAddress(addr, val);
+ S--;
+ PC = (address)(GET_STACK + 1);
+ S--;
+ PC += ((address)(GET_STACK)) << 8;
+}
+
+void fRTI(Addressing addr, address val){
+ idata = fAddress(addr, val);
+ S--;
+ P = GET_STACK; //NEED TO FIX
+ S--;
+ PC = (address)(GET_STACK);
+ S--;
+ PC += (address)(GET_STACK << 8);
+}
+
+// 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);
+ SET_STACK((((PC+2) & 0xFF00) >> 8));
+ S++;
+ SET_STACK((PC+2) & 0x00FF);
+ S++;
+ SET_STACK(P);
+ S++;
+ PC = (address)(getMemory(0xFFFE));
+ PC += ((address)(getMemory(0xFFFF)) << 8);
+}
+
+#ifdef ILLEGAL_INSTRUCTIONS
+
+
+#endif \ No newline at end of file