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