// instructions.h // Definition of all instruction functions, handling effect of instruction and flags. AddData idata; /* 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); Memory[idata.add] = acc; } void fSTX(Addressing addr, address val){ idata = fAddress(addr, val); Memory[idata.add] = X; } void fSTY(Addressing addr, address val){ idata = fAddress(addr, val); Memory[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); Memory[idata.add]++; 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); Memory[idata.add]--; 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); }if (acc == idata.value){ flagClear(flag_N); flagSet(flag_Z); flagClear(flag_C); }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); }if (X == idata.value){ flagClear(flag_N); flagSet(flag_Z); flagClear(flag_C); }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); }if (Y == idata.value){ flagClear(flag_N); flagSet(flag_Z); flagClear(flag_C); }if (Y > idata.value){ flagClear(flag_N); flagClear(flag_Z); flagSet(flag_C); } } //Need to double check the function of this instruction void fBIT(Addressing addr, address val){ idata = fAddress(addr, val); setFlag(flag_N, (Memory[val] & flag_N)); setFlag(flag_V, (Memory[val] & flag_V)); if (((Memory[val] & flag_N) & (Memory[val] & 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); Memory[0x01FF-S] = acc; S++; } void fPHP(Addressing addr, address val){ idata = fAddress(addr, val); Memory[0x01FF-S] = P; S++; } void fPLA(Addressing addr, address val){ idata = fAddress(addr, val); S--; acc = Memory[0x01FF-S]; } void fPLP(Addressing addr, address val){ idata = fAddress(addr, val); S--; P = Memory[0x01FF-S]; } // Subroutine Instructions void fJSR(Addressing addr, address val){ idata = fAddress(addr, val); Memory[0x01FF-S] = (idata.add-1); S++; PC = idata.add; } void fRTS(Addressing addr, address val){ idata = fAddress(addr, val); } void fRTI(Addressing addr, address val){ idata = fAddress(addr, val); } // 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); flagSet(flag_B); }