// 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 */ AddData idata; // Load and Store Instructions void fLDA(Addressing addr, address val){ acc = idata.value; PC += idata.length; } void fLDX(Addressing addr, address val){ X = idata.value; PC += idata.length; } void fLDY(Addressing addr, address val){ Y = idata.value; PC += idata.length; } void fSTA(Addressing addr, address val){ SetMemory(idata.add, acc); PC += idata.length; } void fSTX(Addressing addr, address val){ SetMemory(idata.add, X); PC += idata.length; } void fSTY(Addressing addr, address val){ SetMemory(idata.add, Y); PC += idata.length; } // Arithmetic Instructions void fADC(Addressing addr, address 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); PC += idata.length; } void fSBC(Addressing addr, address 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); PC += idata.length; } //Increment and Decrement Instructions void fINC(Addressing addr, address val){ byte a = GetMemory(idata.add); a++; SetMemory(idata.add, a); SetFlagN(Memory[idata.add]); SetFlagZ(Memory[idata.add]); PC += idata.length; } void fINX(Addressing addr, address val){ X++; SetFlagN(X); SetFlagZ(X); PC += idata.length; } void fINY(Addressing addr, address val){ Y++; SetFlagN(Y); SetFlagZ(Y); PC += idata.length; } void fDEC(Addressing addr, address val){ byte a = GetMemory(idata.add); a--; SetMemory(idata.add, a); SetFlagN(Memory[idata.add]); SetFlagZ(Memory[idata.add]); PC += idata.length; } void fDEX(Addressing addr, address val){ X--; SetFlagN(X); SetFlagZ(X); PC += idata.length; } void fDEY(Addressing addr, address val){ Y--; SetFlagN(Y); SetFlagZ(Y); PC += idata.length; } // Logical Instructions void fAND(Addressing addr, address val){ acc &= idata.value; SetFlagN(acc); SetFlagZ(acc); PC += idata.length; } void fORA(Addressing addr, address val){ acc |= idata.value; SetFlagN(acc); SetFlagZ(acc); PC += idata.length; } void fEOR(Addressing addr, address val){ acc ^= idata.value; SetFlagN(acc); SetFlagZ(acc); PC += idata.length; } // Jump, Branch, Compare, and Test Bits void fJMP(Addressing addr, address val){ PC = val; } void fBCC(Addressing addr, address val){ //FINISH ALL BRANCH INSTRUCTIONS //signed char val down to BVC if (getFlag(flag_C) == 0) PC += val; } void fBCS(Addressing addr, address val){ if (getFlag(flag_C) == 1) PC += val; } void fBEQ(Addressing addr, address val){ if (getFlag(flag_Z) == 1) PC += val; } void fBNE(Addressing addr, address val){ if (getFlag(flag_Z) == 0) PC += val; } void fBMI(Addressing addr, address val){ if (getFlag(flag_N) == 1) PC += val; } void fBPL(Addressing addr, address val){ if (getFlag(flag_N) == 0) PC += val; } void fBVS(Addressing addr, address val){ if (getFlag(flag_V) == 1) PC += val; } void fBVC(Addressing addr, address val){ if (getFlag(flag_V) == 0) PC += val; } void fCMP(Addressing addr, address 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); } PC += idata.length; } void fCPX(Addressing addr, address 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); } PC += idata.length; } void fCPY(Addressing addr, address 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); } PC += idata.length; } //NEED TO DOUBLE CHECK THIS INSTRUCTION void fBIT(Addressing addr, address 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); } PC += idata.length; } // Shift and Rotate Instructions void fASL(Addressing addr, address val){ SetFlag(flag_C, (idata.value & 0x80)); acc = (idata.value << 1); SetFlagN(acc); SetFlagZ(acc); PC += idata.length; } void fLSR(Addressing addr, address val){ SetFlag(flag_C, (idata.value & 0x01)); acc = (idata.value >> 1); SetFlagN(acc); SetFlagZ(acc); PC += idata.length; } void fROL(Addressing addr, address val){ SetFlag(flag_C, (val & 0x80)); acc = (val << 1); acc |= (getFlag(flag_C) * 0x01); SetFlagN(acc); SetFlagZ(acc); PC += idata.length; } void fROR(Addressing addr, address val){ SetFlag(flag_C, (val & 0x01)); acc = (val >> 1); acc |= (getFlag(flag_C) * 0x80); SetFlagN(acc); SetFlagZ(acc); PC += idata.length; } // Transfer Instructions void fTAX(Addressing addr, address val){ X = acc; //SetFlagN(X); //SetFlagZ(X); PC += idata.length; } void fTAY(Addressing addr, address val){ Y = acc; //SetFlagN(Y); //SetFlagZ(Y); PC += idata.length; } void fTXA(Addressing addr, address val){ acc = X; SetFlagN(acc); SetFlagZ(acc); PC += idata.length; } void fTYA(Addressing addr, address val){ acc = Y; SetFlagN(acc); SetFlagZ(acc); PC += idata.length; } // Stack Instructions void fTSX(Addressing addr, address val){ X = S; PC += idata.length; } void fTXS(Addressing addr, address val){ S = X; PC += idata.length; } void fPHA(Addressing addr, address val){ SetStack(acc); S++; PC += idata.length; } void fPHP(Addressing addr, address val){ SetStack(P); S++; PC += idata.length; } void fPLA(Addressing addr, address val){ S--; acc = GetStack(); PC += idata.length; } void fPLP(Addressing addr, address val){ S--; P = GetStack(); PC += idata.length; } // Subroutine Instructions // NEED TO FINISH THESE void fJSR(Addressing addr, address val){ SetStack(((PC-1) & 0xFF00) >> 8); S++; SetStack((PC-1) & 0x00FF); S++; PC = idata.add; } void fRTS(Addressing addr, address val){ S--; PC = (address)(GetStack() + 1); S--; PC += ((address)(GetStack())) << 8; } void fRTI(Addressing addr, address val){ S--; P = GetStack(); //NEED TO FIX S--; PC = (address)(GetStack()); S--; PC += (address)(GetStack() << 8); } // Set/Reset Insutrctions void fCLC(Addressing addr, address val){ flagClear(flag_C); PC += idata.length; } void fCLD(Addressing addr, address val){ flagClear(flag_D); PC += idata.length; } void fCLI(Addressing addr, address val){ flagClear(flag_I); PC += idata.length; } void fCLV(Addressing addr, address val){ flagClear(flag_V); PC += idata.length; } void fSEC(Addressing addr, address val){ flagSet(flag_C); PC += idata.length; } void fSED(Addressing addr, address val){ flagSet(flag_D); PC += idata.length; } void fSEI(Addressing addr, address val){ flagSet(flag_I); PC += idata.length; } // NOP/BRK Instructions void fNOP(Addressing addr, address val){ PC += idata.length; } void fBRK(Addressing addr, address val){ SetStack((((PC+2) & 0xFF00) >> 8)); S++; SetStack((PC+2) & 0x00FF); S++; SetStack(P); S++; PC = (address)(GetMemory(0xFFFE)); PC += ((address)(GetMemory(0xFFFF)) << 8); } #ifdef ILLEGAL_INSTRUCTIONS #endif