diff options
Diffstat (limited to 'src/cpu/instructions.c')
-rw-r--r-- | src/cpu/instructions.c | 439 |
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 |