diff options
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/6502.c | 50 | ||||
-rw-r--r-- | src/cpu/6502.h | 53 | ||||
-rw-r--r-- | src/cpu/addressing.c | 161 | ||||
-rw-r--r-- | src/cpu/addressing.h | 17 | ||||
-rw-r--r-- | src/cpu/core.h | 31 | ||||
-rw-r--r-- | src/cpu/instructions.c | 393 | ||||
-rw-r--r-- | src/cpu/instructions.h | 112 | ||||
-rw-r--r-- | src/cpu/table.c | 512 | ||||
-rw-r--r-- | src/cpu/table.h | 10 |
9 files changed, 611 insertions, 728 deletions
diff --git a/src/cpu/6502.c b/src/cpu/6502.c index 595cd4e..7ae3f16 100644 --- a/src/cpu/6502.c +++ b/src/cpu/6502.c @@ -7,34 +7,23 @@ byte acc, X, Y, P, S = 0x00; address PC = 0x0000; byte* Memory; -byte getFlag(byte flag) { + +byte GetFlag(byte flag) { return (P & flag) ? 1 : 0; } + void SetFlag(byte flag, int x) { P = (P & ~flag) | ((x != 0) ? flag : 0); } -void flagSet(byte flag){ - P |= flag; -} - -void flagClear(byte flag){ - P &= ~flag; -} - -// Functions which perform reusable routines for finding if a specific flag should be set. -void SetFlagN(byte x){ - /*if ((x & flag_N) == flag_N) - SetFlag(flag_N, 1); - else - SetFlag(flag_N, 0);*/ +void SetFlag_N(byte x){ P = (x & flag_N) | (P & ~flag_N); } -//Perform prior to any changes TODO: FIX THIS! WTF WERE YOU THINKING? -void SetFlagV(byte x, byte y){ + +void SetFlag_V(byte x, byte y){ address z = (address)x + (address)y; if ((x & 0x80) != (y & 0x80)) SetFlag(flag_V, 1); @@ -42,44 +31,21 @@ void SetFlagV(byte x, byte y){ SetFlag(flag_V, 0); } -/*void SetFlagB(){ //WORK ON - SetFlag(flag_B, 1); -}*/ -/*void SetFlagD(){ - SetFlag(flag_D, 1); -}*/ - -/*void SetFlagI(){ //WORK ON - SetFlag(flag_Z, 1); -}*/ - -void SetFlagZ(int x){ +void SetFlag_Z(int x){ if (x == 0) SetFlag(flag_Z, 1); else SetFlag(flag_Z, 0); } -/*void SetFlagC(){ - SetFlag(flag_Z, 1); -}*/ - - -/*byte GetMemory(address x){ - return Memory[x]; -} - -void SetMemory(address x, byte y){ - Memory[x] = y; -}*/ - byte GetStack() { S--; return GetMemory(0x01FF - S); } + void SetStack(byte x) { SetMemory(0x01FF - S, x); S++; diff --git a/src/cpu/6502.h b/src/cpu/6502.h index bad36fb..41ecb7a 100644 --- a/src/cpu/6502.h +++ b/src/cpu/6502.h @@ -6,7 +6,7 @@ #include"stdio.h" #include"core.h" -// FLAGS +// CPU Flags #define flag_N 0x80 // Negative #define flag_V 0x40 // Overflow #define flag_B 0x10 // BRK command @@ -15,50 +15,21 @@ #define flag_Z 0x02 // Zero #define flag_C 0x01 // Carry -byte getFlag(byte flag); -// Get the value of a flag. +// Return a truth value of 1 or 0. +byte GetFlag(byte flag); +// x can be a conditional, and any non-zero value will set the flag. void SetFlag(byte flag, int x); -// Set a flag with some value. -void flagSet(byte flag); -// Sets some flag. +// Reusable routines for setting specific flags +void SetFlag_N(byte x); +void SetFlag_V(byte x, byte y); +void SetFlag_Z(int x); -void flagClear(byte flag); -// Clears some flag. - -// Functions which perform reusable routines for finding if a specific flag should be set. - -void SetFlagN(byte x); - -//Perform prior to any changes -void SetFlagV(byte x, byte y); - -//void SetFlagB(); -//May not need since its dependent on the BRK insturction - -//void SetFlagD(); -//Might not be necessary. - -//void SetFlagI(); -//Need to work on. - -void SetFlagZ(int x); - -//void SetFlagC(); -//Only 6 instructions, 2 not including stack instructions, use the carry flag. - -// The following two may be better defined within apple.c - -//byte GetMemory(address x); -// Retrieve value from the computers address space. -// It is important not to directly access the memory array because some value hold special meaning. - -//void SetMemory(address x, byte y); -// Set a piece of memory to some value. +// Memory access declarations; to be defined somewhere computer-specific, not CPU-specific +byte GetMemory(address x); +void SetMemory(address x, byte y); +// Stack access and manipulation byte GetStack(); -// Get top value of the stack. - void SetStack(byte z); -// Set top value of the stack.
\ No newline at end of file diff --git a/src/cpu/addressing.c b/src/cpu/addressing.c index b8f9330..8c6c619 100644 --- a/src/cpu/addressing.c +++ b/src/cpu/addressing.c @@ -1,15 +1,12 @@ // addressing.h -// Contains definitions relevant to addressing, as well as fAddress() which returns time, length, value, and address for an instruction function call. -// Would like to refactor the code into something better, such as switch-case statements for the cycles calculation. -#include"addressing.h" +#include "addressing.h" -//Holds address of current instruction. I don't think it's being used at all besides fAddressGetCycles(), so will be removed. -void* current_instruction; - -address fAddressGetAddress(Addressing mode, address x) { - switch(mode){ +address fAddressGetAddress(Addressing mode, address x) +{ + switch(mode) + { case eImplied: case eRelative: case eImmediate: @@ -18,7 +15,7 @@ address fAddressGetAddress(Addressing mode, address x) { case eAbsolute: return x; case eIndirectAbsolute: - return (address)GetMemory(x) + (((address)GetMemory(x+1)) << 8); + return (((address)GetMemory(x+1)) << 8) + (address)GetMemory(x); case eAbsoluteIndexedX: return x + X; case eAbsoluteIndexedY: @@ -30,26 +27,31 @@ address fAddressGetAddress(Addressing mode, address x) { case eZeroPageIndexedY: return ((x + Y) & 0x00FF); case eIndexedIndirect: - return (((address)(GetMemory(x+X+1)))<<8) + (address)(GetMemory(x+X)); + return (((address)(GetMemory(x+X+1))) << 8) + (address)(GetMemory(x+X)); case eIndirectIndexed: - return ((address)(GetMemory(x+1))<<8) + ((address)(GetMemory(x))) + ((address)Y); - //return ((x >> 8) & 0xFF) (x & 0xFF) - } + return ((address)(GetMemory(x+1)) << 8) + ((address)(GetMemory(x))) + ((address)Y); + } } -int fAddressGetLength(Addressing mode){ - switch(mode){ + +int fAddressGetLength(Addressing mode) +{ + switch(mode) + { case eAbsolute: case eAbsoluteIndexedX: case eAbsoluteIndexedY: case eIndirectAbsolute: return 3; case eAccumulator: case eImplied: return 1; default: return 2; - } + } } -byte fAddressGetValue(Addressing mode, address x, address addr) { - switch(mode){ + +byte fAddressGetValue(Addressing mode, address x, address addr) +{ + switch(mode) + { case eImplied: return 0; case eRelative: @@ -59,124 +61,15 @@ byte fAddressGetValue(Addressing mode, address x, address addr) { return acc; default: return GetMemory(addr); - } -} - -// At the moment not run, and will probably be replaced by just direct storage of values. -// The code making up this is likely way less performant and larger than just looking up stored values, so I will change it in the future to do that instead. -int fAddressGetCycles(Addressing mode, address x, address addr) { - int cycles; - - //case &fADC: case &fAND: case &fBIT: case &fCMP: case &fCPX: case &fCPY: case &fEOR: case &fLDA: - //case &fLDX: case &fLDY: case &fORA: case &fSBC: case &fSTX: case &fSTY: - - if ( current_instruction == &fADC || current_instruction == &fAND || current_instruction == &fBIT || current_instruction == &fCMP || current_instruction == &fCPX - || current_instruction == &fCPY || current_instruction == &fEOR || current_instruction == &fLDA || current_instruction == &fLDX || current_instruction == &fLDY - || current_instruction == &fORA || current_instruction == &fSBC || current_instruction == &fSTX || current_instruction == &fSTY ){ - switch(mode){ - case eImmediate: - cycles = 2; break; - case eZeroPage: - cycles = 3; break; - case eZeroPageIndexedX: case eAbsolute: case eAbsoluteIndexedX: case eAbsoluteIndexedY: - cycles = 4; break; - case eIndexedIndirect: - cycles = 6; break; - case eIndirectIndexed: - cycles = 5; break; - } - } - - //case &fASL: case &fDEC: case &fINC: case &fLSR: case &fROL: case &fROR: - else if( current_instruction == &fASL || current_instruction == &fDEC || current_instruction == &fINC - || current_instruction == &fLSR || current_instruction == &fROL || current_instruction == &fROR ){ - switch(mode){ - case eAccumulator: - cycles = 2; break; - case eZeroPage: - cycles = 5; break; - case eZeroPageIndexedX: case eAbsolute: - cycles = 6; break; - case eAbsoluteIndexedX: - cycles = 7; break; } - } - - //case &fSTA: - else if (current_instruction == &fSTA){ - switch(mode){ - case eZeroPage: - cycles = 3; break; - case eZeroPageIndexedX: case eAbsolute: - cycles = 4; break; - case eAbsoluteIndexedX: case eAbsoluteIndexedY: - cycles = 5; break; - case eIndexedIndirect: case eIndirectIndexed: - cycles = 6; break; - } - } - - - //case &fBRK: - else if (current_instruction == &fBRK){ - cycles = 7; - } - - - //case &fRTI: case &fRTS: case &fJSR: - else if (current_instruction == &fRTI || current_instruction == &fRTS || current_instruction == &fJSR){ - cycles = 6; - } - - //case &fJMP: - else if (current_instruction == &fJMP){ - cycles = 5; - } - - //case &fPLA: case &fPLP: - else if (current_instruction == &fPLA || current_instruction == &fPLP){ - cycles = 4; - } - - //case &fPHA: case &fPHP: - else if (current_instruction == &fPHA || current_instruction == &fPHP){ - cycles = 3; - } - - else { - cycles = 2; - } - - - // Page Boundary - - //case &fADC: case &fSBC: case &fLDA: case &fLDX: case &fLDY: case &fEOR: case &fAND: case &fORA: case &fCMP: - if ( current_instruction == &fADC || current_instruction == &fSBC || current_instruction == &fLDA || current_instruction == &fLDX || current_instruction == &fLDY - || current_instruction == &fEOR || current_instruction == &fAND || current_instruction == &fORA || current_instruction == &fCMP ){ - switch(mode){ - case eAbsoluteIndexedX: - if ((x & 0xFF00) != ((x + X) & 0xFF00)) - cycles++; - break; - case eAbsoluteIndexedY: - if ((x & 0xFF00) != ((x + Y) & 0xFF00)) - cycles++; - break; - case eIndirectIndexed: - if ((addr & 0xFF00) != (addr - Y & 0xFF00)) - cycles++; - break; - } - } - - return cycles; } -AddData fAddress(Addressing mode, address x) { - AddData ret; - ret.add = fAddressGetAddress (mode, x); - ret.value = fAddressGetValue (mode, x, ret.add); - ret.length = fAddressGetLength (mode); - //ret.cycles = fAddressGetCycles (mode, x, ret.add); + +struct State fAddress(Addressing mode, address x) +{ + struct State ret; + ret.address = fAddressGetAddress (mode, x); + ret.value = fAddressGetValue (mode, x, ret.address); + ret.length = fAddressGetLength (mode); return ret; } diff --git a/src/cpu/addressing.h b/src/cpu/addressing.h index 790b912..d8f12a3 100644 --- a/src/cpu/addressing.h +++ b/src/cpu/addressing.h @@ -3,17 +3,12 @@ #pragma once -#include"core.h" -#include"6502.h" -#include"instructions.h" - - -#define getInstructionLength(c) fAddressGetLength(*GetInstructionTableAddressing(c)) - +#include "core.h" +#include "6502.h" +#include "instructions.h" // For a given addressing mode and opcode, return data about the instruction. -AddData fAddress (Addressing mode, address x ); -address fAddressGetAddress (Addressing mode, address x ); -int fAddressGetLength (Addressing mode ); +struct State fAddress (Addressing mode, address x); +address fAddressGetAddress (Addressing mode, address x); +int fAddressGetLength (Addressing mode); byte fAddressGetValue (Addressing mode, address x, address addr); -int fAddressGetCycles (Addressing mode, address x, address addr); diff --git a/src/cpu/core.h b/src/cpu/core.h index 7c0f284..f83002f 100644 --- a/src/cpu/core.h +++ b/src/cpu/core.h @@ -1,12 +1,9 @@ #pragma once -typedef -unsigned char -byte; +#include <stdint.h> -typedef -unsigned short -address; +typedef uint8_t byte; +typedef uint16_t address; extern byte acc; extern byte X; @@ -17,7 +14,6 @@ extern address PC; extern byte* Memory; extern byte ROM[]; - enum Addressing { eImmediate, @@ -34,28 +30,19 @@ enum Addressing eIndirectAbsolute, eRelative }; + typedef int Addressing; -typedef -struct AddData +struct State { int cycles; int length; - address add; + address address; byte value; -} -AddData; - - - -// GetMemory and SetMemory are declared here, but defined in apple.c -// This is because memory access of particular memory locations is influenced by the Apple I's specific setup, not by the CPU alone. -byte GetMemory(address x); -void SetMemory(address x, byte y); +}; -extern void *current_instruction; -extern AddData idata; -extern void (*func)(Addressing); +extern struct State state; +extern void (*Instruction)(Addressing); 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); diff --git a/src/cpu/instructions.h b/src/cpu/instructions.h index 705cc0d..4bf93b3 100644 --- a/src/cpu/instructions.h +++ b/src/cpu/instructions.h @@ -5,79 +5,79 @@ #include"6502.h" // Load and Store Instructions -void fLDA(Addressing); -void fLDX(Addressing); -void fLDY(Addressing); -void fSTA(Addressing); -void fSTX(Addressing); -void fSTY(Addressing); +void LDA(Addressing); +void LDX(Addressing); +void LDY(Addressing); +void STA(Addressing); +void STX(Addressing); +void STY(Addressing); // Arithmetic Instructions -void fADC(Addressing); -void fSBC(Addressing); +void ADC(Addressing); +void SBC(Addressing); //Increment and Decrement Instructions -void fINC(Addressing); -void fINX(Addressing); -void fINY(Addressing); -void fDEC(Addressing); -void fDEX(Addressing); -void fDEY(Addressing); +void INC(Addressing); +void INX(Addressing); +void INY(Addressing); +void DEC(Addressing); +void DEX(Addressing); +void DEY(Addressing); // Logical Instructions -void fAND(Addressing); -void fORA(Addressing); -void fEOR(Addressing); +void AND(Addressing); +void ORA(Addressing); +void EOR(Addressing); // Jump, Branch, Compare, and Test Bits -void fJMP(Addressing); -void fBCC(Addressing); -void fBCS(Addressing); -void fBEQ(Addressing); -void fBNE(Addressing); -void fBMI(Addressing); -void fBPL(Addressing); -void fBVS(Addressing); -void fBVC(Addressing); -void fCMP(Addressing); -void fCPX(Addressing); -void fCPY(Addressing); -void fBIT(Addressing); +void JMP(Addressing); +void BCC(Addressing); +void BCS(Addressing); +void BEQ(Addressing); +void BNE(Addressing); +void BMI(Addressing); +void BPL(Addressing); +void BVS(Addressing); +void BVC(Addressing); +void CMP(Addressing); +void CPX(Addressing); +void CPY(Addressing); +void BIT(Addressing); // Shift and Rotate Instructions -void fASL(Addressing); -void fLSR(Addressing); -void fROL(Addressing); -void fROR(Addressing); +void ASL(Addressing); +void LSR(Addressing); +void ROL(Addressing); +void ROR(Addressing); // Transfer Instructions -void fTAX(Addressing); -void fTAY(Addressing); -void fTXA(Addressing); -void fTYA(Addressing); +void TAX(Addressing); +void TAY(Addressing); +void TXA(Addressing); +void TYA(Addressing); // Stack Instructions -void fTSX(Addressing); -void fTXS(Addressing); -void fPHA(Addressing); -void fPHP(Addressing); -void fPLA(Addressing); -void fPLP(Addressing); +void TSX(Addressing); +void TXS(Addressing); +void PHA(Addressing); +void PHP(Addressing); +void PLA(Addressing); +void PLP(Addressing); // Subroutine Instructions -void fJSR(Addressing); -void fRTS(Addressing); -void fRTI(Addressing); +void JSR(Addressing); +void RTS(Addressing); +void RTI(Addressing); // Set/Reset Insutrctions -void fCLC(Addressing); -void fCLD(Addressing); -void fCLI(Addressing); -void fCLV(Addressing); -void fSEC(Addressing); -void fSED(Addressing); -void fSEI(Addressing); +void CLC(Addressing); +void CLD(Addressing); +void CLI(Addressing); +void CLV(Addressing); +void SEC(Addressing); +void SED(Addressing); +void SEI(Addressing); // NOP/BRK Instructions -void fNOP(Addressing); -void fBRK(Addressing); +void NOP(Addressing); +void BRK(Addressing); diff --git a/src/cpu/table.c b/src/cpu/table.c index 052fce7..a5c1c41 100644 --- a/src/cpu/table.c +++ b/src/cpu/table.c @@ -2,283 +2,295 @@ #include"table.h" - void* InstructionTable; +void (*Instruction)(Addressing); -void (*func)(Addressing); +// Macros for accessing the InstructionTable +#define InstructionTableFunction(x) ((uintptr_t*)(InstructionTable + (sizeof(uintptr_t) * x))) +#define InstructionTableAddressing(x) ((Addressing*)(InstructionTable + (sizeof(uintptr_t) * 256) + (sizeof(Addressing) * x))) +#define InstructionTableCycles(x) ((int*)(InstructionTable + (sizeof(uintptr_t) * 256) + (sizeof(Addressing) * 256) + (sizeof(int) * x))) -uintptr_t* GetInstructionTableFunction(int i){ //Segmentation fault is occurring here, likely in next one too - uintptr_t* r = (InstructionTable + (sizeof(uintptr_t)*i)); - return r; -} +const InstructionTableSize = (256 * (sizeof(uintptr_t) + sizeof(Addressing) + sizeof(int))); -Addressing* GetInstructionTableAddressing(int i){ - Addressing* r = (InstructionTable + (sizeof(uintptr_t)*256) + (sizeof(Addressing)*i)); - return r; -} -void CallInstructionTable(){ - int val = 0; - // Setup to call the correct function. - int i = (int)GetMemory(PC); - uintptr_t a = GetInstructionTableFunction(i); - memcpy(&func, a, sizeof(uintptr_t)); - // Find the correct addressing mode. - Addressing r = *(Addressing*)(InstructionTable + ((sizeof(uintptr_t)*256) + (sizeof(Addressing) * i))); +void CallInstructionTable() +{ + // Set function. + memcpy(&Instruction, + InstructionTableFunction((int)GetMemory(PC)), + sizeof(uintptr_t)); + + // Find the addressing mode. + Addressing r = *InstructionTableAddressing(GetMemory(PC)); // Set val + int val = 0; if (fAddressGetLength(r) >= 2) - val += (address)GetMemory(PC+1); + val += GetMemory(PC+1); if (fAddressGetLength(r) == 3) - val += (address)GetMemory(PC+2) << 8; + val += ((address)GetMemory(PC+2)) << 8; - // Set idata - idata = fAddress(r, val); + // Set state + state = fAddress(r, val); // Perform function - func(r); + Instruction(r); - - PC += idata.length; + // Incrememt the program counter. + PC += state.length; } -void SetInstructionTable(int i, uintptr_t p, Addressing r){ - uintptr_t* p1 = ( InstructionTable + (sizeof(uintptr_t) * i) ); - *p1 = p; - Addressing* r1 = ( InstructionTable + (sizeof(uintptr_t) * 256) + (sizeof(Addressing) * i) ); - *r1 = r; +void SetInstructionTable(int index, void* function, Addressing addressing, int cycles) +{ + *InstructionTableFunction(index) = (uintptr_t)function; + *InstructionTableAddressing(index) = addressing; + *InstructionTableCycles(index) = cycles; } -void InitInstructionTable(){ + +void InitInstructionTable() +{ + // Create InstructionTable InstructionTable = malloc(InstructionTableSize); - // Load and Store Instructions - // fLDA(Addressing, address); - SetInstructionTable(0xA9, (uintptr_t)&fLDA, eImmediate); - SetInstructionTable(0xA5, (uintptr_t)&fLDA, eZeroPage); - SetInstructionTable(0xB5, (uintptr_t)&fLDA, eZeroPageIndexedX); - SetInstructionTable(0xAD, (uintptr_t)&fLDA, eAbsolute); - SetInstructionTable(0xBD, (uintptr_t)&fLDA, eAbsoluteIndexedX); - SetInstructionTable(0xB9, (uintptr_t)&fLDA, eAbsoluteIndexedY); - SetInstructionTable(0xA1, (uintptr_t)&fLDA, eIndexedIndirect); - SetInstructionTable(0xB1, (uintptr_t)&fLDA, eIndirectIndexed); - // fLDX(Addressing, address); - SetInstructionTable(0xA2, (uintptr_t)&fLDX, eImmediate); - SetInstructionTable(0xA6, (uintptr_t)&fLDX, eZeroPage); - SetInstructionTable(0xB6, (uintptr_t)&fLDX, eZeroPageIndexedY); - SetInstructionTable(0xAE, (uintptr_t)&fLDX, eAbsolute); - SetInstructionTable(0xBE, (uintptr_t)&fLDX, eAbsoluteIndexedY); - // fLDY(Addressing, address); - SetInstructionTable(0xA0, (uintptr_t)&fLDY, eImmediate); - SetInstructionTable(0xA4, (uintptr_t)&fLDY, eZeroPage); - SetInstructionTable(0xB4, (uintptr_t)&fLDY, eZeroPageIndexedX); - SetInstructionTable(0xAC, (uintptr_t)&fLDY, eAbsolute); - SetInstructionTable(0xBC, (uintptr_t)&fLDY, eAbsoluteIndexedX); - // fSTA(Addressing, address); - SetInstructionTable(0x85, (uintptr_t)&fSTA, eZeroPage); - SetInstructionTable(0x95, (uintptr_t)&fSTA, eZeroPageIndexedX); - SetInstructionTable(0x8D, (uintptr_t)&fSTA, eAbsolute); - SetInstructionTable(0x9D, (uintptr_t)&fSTA, eAbsoluteIndexedX); - SetInstructionTable(0x99, (uintptr_t)&fSTA, eAbsoluteIndexedY); - SetInstructionTable(0x81, (uintptr_t)&fSTA, eIndexedIndirect); - SetInstructionTable(0x91, (uintptr_t)&fSTA, eIndirectIndexed); - // fSTX(Addressing, address); - SetInstructionTable(0x86, (uintptr_t)&fSTX, eZeroPage); - SetInstructionTable(0x96, (uintptr_t)&fSTX, eZeroPageIndexedX); - SetInstructionTable(0x8E, (uintptr_t)&fSTX, eAbsolute); - // fSTY(Addressing, address); - SetInstructionTable(0x84, (uintptr_t)&fSTY, eZeroPage); - SetInstructionTable(0x94, (uintptr_t)&fSTY, eZeroPageIndexedY); - SetInstructionTable(0x8C, (uintptr_t)&fSTY, eAbsolute); + // Load and Store Instructions + + // LDA + SetInstructionTable(0xA9, &LDA, eImmediate, 2); + SetInstructionTable(0xA5, &LDA, eZeroPage, 3); + SetInstructionTable(0xB5, &LDA, eZeroPageIndexedX, 4); + SetInstructionTable(0xAD, &LDA, eAbsolute, 4); + SetInstructionTable(0xBD, &LDA, eAbsoluteIndexedX, 4); + SetInstructionTable(0xB9, &LDA, eAbsoluteIndexedY, 4); + SetInstructionTable(0xA1, &LDA, eIndexedIndirect, 6); + SetInstructionTable(0xB1, &LDA, eIndirectIndexed, 5); + // LDX + SetInstructionTable(0xA2, &LDX, eImmediate, 2); + SetInstructionTable(0xA6, &LDX, eZeroPage, 3); + SetInstructionTable(0xB6, &LDX, eZeroPageIndexedY, 4); + SetInstructionTable(0xAE, &LDX, eAbsolute, 4); + SetInstructionTable(0xBE, &LDX, eAbsoluteIndexedY, 4); + // LDY + SetInstructionTable(0xA0, &LDY, eImmediate, 2); + SetInstructionTable(0xA4, &LDY, eZeroPage, 3); + SetInstructionTable(0xB4, &LDY, eZeroPageIndexedX, 4); + SetInstructionTable(0xAC, &LDY, eAbsolute, 4); + SetInstructionTable(0xBC, &LDY, eAbsoluteIndexedX, 4); + // STA + SetInstructionTable(0x85, &STA, eZeroPage, 3); + SetInstructionTable(0x95, &STA, eZeroPageIndexedX, 4); + SetInstructionTable(0x8D, &STA, eAbsolute, 4); + SetInstructionTable(0x9D, &STA, eAbsoluteIndexedX, 5); + SetInstructionTable(0x99, &STA, eAbsoluteIndexedY, 5); + SetInstructionTable(0x81, &STA, eIndexedIndirect, 6); + SetInstructionTable(0x91, &STA, eIndirectIndexed, 6); + // STX + SetInstructionTable(0x86, &STX, eZeroPage, 3); + SetInstructionTable(0x96, &STX, eZeroPageIndexedX, 4); + SetInstructionTable(0x8E, &STX, eAbsolute, 4); + // STY + SetInstructionTable(0x84, &STY, eZeroPage, 3); + SetInstructionTable(0x94, &STY, eZeroPageIndexedY, 4); + SetInstructionTable(0x8C, &STY, eAbsolute, 4); + // Arithmetic Instructions - // fADC(Addressing, address); - SetInstructionTable(0x69, (uintptr_t)&fADC, eImmediate); - SetInstructionTable(0x65, (uintptr_t)&fADC, eZeroPage); - SetInstructionTable(0x75, (uintptr_t)&fADC, eZeroPageIndexedX); - SetInstructionTable(0x6D, (uintptr_t)&fADC, eAbsolute); - SetInstructionTable(0x7D, (uintptr_t)&fADC, eAbsoluteIndexedX); - SetInstructionTable(0x79, (uintptr_t)&fADC, eAbsoluteIndexedY); - SetInstructionTable(0x61, (uintptr_t)&fADC, eIndexedIndirect); - SetInstructionTable(0x71, (uintptr_t)&fADC, eIndirectIndexed); - // fSBC(Addressing, address); - SetInstructionTable(0xE9, (uintptr_t)&fSBC, eImmediate); - SetInstructionTable(0xE5, (uintptr_t)&fSBC, eZeroPage); - SetInstructionTable(0xF5, (uintptr_t)&fSBC, eZeroPageIndexedX); - SetInstructionTable(0xED, (uintptr_t)&fSBC, eAbsolute); - SetInstructionTable(0xFD, (uintptr_t)&fSBC, eAbsoluteIndexedX); - SetInstructionTable(0xF9, (uintptr_t)&fSBC, eAbsoluteIndexedY); - SetInstructionTable(0xE1, (uintptr_t)&fSBC, eIndexedIndirect); - SetInstructionTable(0xF1, (uintptr_t)&fSBC, eIndirectIndexed); - - //Increment and Decrement Instructions - //INC(Addressing, address); - SetInstructionTable(0xE6, (uintptr_t)&fINC, eZeroPage); - SetInstructionTable(0xF6, (uintptr_t)&fINC, eZeroPageIndexedX); - SetInstructionTable(0xEE, (uintptr_t)&fINC, eAbsolute); - SetInstructionTable(0xFE, (uintptr_t)&fINC, eAbsoluteIndexedX); - //INX(Addressing, address); - SetInstructionTable(0xE8, (uintptr_t)&fINX, eImplied); - //INY(Addressing, address); - SetInstructionTable(0xC8, (uintptr_t)&fINY, eImplied); - //DEC(Addressing, address); - SetInstructionTable(0xC6, (uintptr_t)&fDEC, eZeroPage); - SetInstructionTable(0xD6, (uintptr_t)&fDEC, eZeroPageIndexedX); - SetInstructionTable(0xCE, (uintptr_t)&fDEC, eAbsolute); - SetInstructionTable(0xDE, (uintptr_t)&fDEC, eAbsoluteIndexedX); - //DEX(Addressing, address); - SetInstructionTable(0xCA, (uintptr_t)&fDEX, eImplied); - //DEY(Addressing, address); - SetInstructionTable(0x88, (uintptr_t)&fDEY, eImplied); - + + // ADC + SetInstructionTable(0x69, &ADC, eImmediate, 2); + SetInstructionTable(0x65, &ADC, eZeroPage, 3); + SetInstructionTable(0x75, &ADC, eZeroPageIndexedX, 4); + SetInstructionTable(0x6D, &ADC, eAbsolute, 4); + SetInstructionTable(0x7D, &ADC, eAbsoluteIndexedX, 4); + SetInstructionTable(0x79, &ADC, eAbsoluteIndexedY, 4); + SetInstructionTable(0x61, &ADC, eIndexedIndirect, 6); + SetInstructionTable(0x71, &ADC, eIndirectIndexed, 5); + // SBC + SetInstructionTable(0xE9, &SBC, eImmediate, 2); + SetInstructionTable(0xE5, &SBC, eZeroPage, 3); + SetInstructionTable(0xF5, &SBC, eZeroPageIndexedX, 4); + SetInstructionTable(0xED, &SBC, eAbsolute, 4); + SetInstructionTable(0xFD, &SBC, eAbsoluteIndexedX, 4); + SetInstructionTable(0xF9, &SBC, eAbsoluteIndexedY, 4); + SetInstructionTable(0xE1, &SBC, eIndexedIndirect, 6); + SetInstructionTable(0xF1, &SBC, eIndirectIndexed, 5); + + // Increment and Decrement Instructions + + // INC + SetInstructionTable(0xE6, &INC, eZeroPage, 5); + SetInstructionTable(0xF6, &INC, eZeroPageIndexedX, 6); + SetInstructionTable(0xEE, &INC, eAbsolute, 6); + SetInstructionTable(0xFE, &INC, eAbsoluteIndexedX, 7); + // INX + SetInstructionTable(0xE8, &INX, eImplied, 2); + // INY + SetInstructionTable(0xC8, &INY, eImplied, 2); + // DEC + SetInstructionTable(0xC6, &DEC, eZeroPage, 5); + SetInstructionTable(0xD6, &DEC, eZeroPageIndexedX, 6); + SetInstructionTable(0xCE, &DEC, eAbsolute, 6); + SetInstructionTable(0xDE, &DEC, eAbsoluteIndexedX, 7); + // DEX + SetInstructionTable(0xCA, &DEX, eImplied, 2); + // DEY + SetInstructionTable(0x88, &DEY, eImplied, 2); + // Logical Instructions - //AND(Addressing, address); - SetInstructionTable(0x29, (uintptr_t)&fAND, eImmediate); - SetInstructionTable(0x25, (uintptr_t)&fAND, eZeroPage); - SetInstructionTable(0x35, (uintptr_t)&fAND, eZeroPageIndexedX); - SetInstructionTable(0x2D, (uintptr_t)&fAND, eAbsolute); - SetInstructionTable(0x3D, (uintptr_t)&fAND, eAbsoluteIndexedX); - SetInstructionTable(0x39, (uintptr_t)&fAND, eAbsoluteIndexedY); - SetInstructionTable(0x21, (uintptr_t)&fAND, eIndexedIndirect); - SetInstructionTable(0x31, (uintptr_t)&fAND, eIndirectIndexed); - //ORA(Addressing, address); - SetInstructionTable(0x09, (uintptr_t)&fORA, eImmediate); - SetInstructionTable(0x05, (uintptr_t)&fORA, eZeroPage); - SetInstructionTable(0x15, (uintptr_t)&fORA, eZeroPageIndexedX); - SetInstructionTable(0x0D, (uintptr_t)&fORA, eAbsolute); - SetInstructionTable(0x1D, (uintptr_t)&fORA, eAbsoluteIndexedX); - SetInstructionTable(0x19, (uintptr_t)&fORA, eAbsoluteIndexedY); - SetInstructionTable(0x01, (uintptr_t)&fORA, eIndexedIndirect); - SetInstructionTable(0x11, (uintptr_t)&fORA, eIndirectIndexed); - //EOR(Addressing, address); - SetInstructionTable(0x49, (uintptr_t)&fEOR, eImmediate); - SetInstructionTable(0x45, (uintptr_t)&fEOR, eZeroPage); - SetInstructionTable(0x55, (uintptr_t)&fEOR, eZeroPageIndexedX); - SetInstructionTable(0x4D, (uintptr_t)&fEOR, eAbsolute); - SetInstructionTable(0x5D, (uintptr_t)&fEOR, eAbsoluteIndexedX); - SetInstructionTable(0x59, (uintptr_t)&fEOR, eAbsoluteIndexedY); - SetInstructionTable(0x41, (uintptr_t)&fEOR, eIndexedIndirect); - SetInstructionTable(0x51, (uintptr_t)&fEOR, eIndirectIndexed); - + + // AND + SetInstructionTable(0x29, &AND, eImmediate, 2); + SetInstructionTable(0x25, &AND, eZeroPage, 3); + SetInstructionTable(0x35, &AND, eZeroPageIndexedX, 4); + SetInstructionTable(0x2D, &AND, eAbsolute, 4); + SetInstructionTable(0x3D, &AND, eAbsoluteIndexedX, 4); + SetInstructionTable(0x39, &AND, eAbsoluteIndexedY, 4); + SetInstructionTable(0x21, &AND, eIndexedIndirect, 6); + SetInstructionTable(0x31, &AND, eIndirectIndexed, 5); + // ORA + SetInstructionTable(0x09, &ORA, eImmediate, 2); + SetInstructionTable(0x05, &ORA, eZeroPage, 3); + SetInstructionTable(0x15, &ORA, eZeroPageIndexedX, 4); + SetInstructionTable(0x0D, &ORA, eAbsolute, 4); + SetInstructionTable(0x1D, &ORA, eAbsoluteIndexedX, 4); + SetInstructionTable(0x19, &ORA, eAbsoluteIndexedY, 4); + SetInstructionTable(0x01, &ORA, eIndexedIndirect, 6); + SetInstructionTable(0x11, &ORA, eIndirectIndexed, 5); + // EOR + SetInstructionTable(0x49, &EOR, eImmediate, 2); + SetInstructionTable(0x45, &EOR, eZeroPage, 3); + SetInstructionTable(0x55, &EOR, eZeroPageIndexedX, 4); + SetInstructionTable(0x4D, &EOR, eAbsolute, 4); + SetInstructionTable(0x5D, &EOR, eAbsoluteIndexedX, 4); + SetInstructionTable(0x59, &EOR, eAbsoluteIndexedY, 4); + SetInstructionTable(0x41, &EOR, eIndexedIndirect, 6); + SetInstructionTable(0x51, &EOR, eIndirectIndexed, 5); + // Jump, Branch, Compare, and Test Bits - //JMP(Addressing, address); - SetInstructionTable(0x4C, (uintptr_t)&fJMP, eAbsolute); - SetInstructionTable(0x6C, (uintptr_t)&fJMP, eIndirectAbsolute); - //BCC(Addressing, address); - SetInstructionTable(0x90, (uintptr_t)&fBCC, eRelative); - //BCS(Addressing, address); - SetInstructionTable(0xB0, (uintptr_t)&fBCS, eRelative); - //BEQ(Addressing, address); - SetInstructionTable(0xF0, (uintptr_t)&fBEQ, eRelative); - //BNE(Addressing, address); - SetInstructionTable(0xD0, (uintptr_t)&fBNE, eRelative); - //BMI(Addressing, address); - SetInstructionTable(0x30, (uintptr_t)&fBMI, eRelative); - //BPL(Addressing, address); - SetInstructionTable(0x10, (uintptr_t)&fBPL, eRelative); - //BVS(Addressing, address); - SetInstructionTable(0x70, (uintptr_t)&fBVS, eRelative); - //BVC(Addressing, address); - SetInstructionTable(0x50, (uintptr_t)&fBVC, eRelative); - //CMP(Addressing, address); - SetInstructionTable(0xC9, (uintptr_t)&fCMP, eImmediate); - SetInstructionTable(0xC5, (uintptr_t)&fCMP, eZeroPage); - SetInstructionTable(0xD5, (uintptr_t)&fCMP, eZeroPageIndexedX); - SetInstructionTable(0xCD, (uintptr_t)&fCMP, eAbsolute); - SetInstructionTable(0xDD, (uintptr_t)&fCMP, eAbsoluteIndexedX); - SetInstructionTable(0xD9, (uintptr_t)&fCMP, eAbsoluteIndexedY); - SetInstructionTable(0xC1, (uintptr_t)&fCMP, eIndexedIndirect); - SetInstructionTable(0xD1, (uintptr_t)&fCMP, eIndirectIndexed); - //CPX(Addressing, address); - SetInstructionTable(0xE0, (uintptr_t)&fCPX, eImmediate); - SetInstructionTable(0xE4, (uintptr_t)&fCPX, eZeroPage); - SetInstructionTable(0xEC, (uintptr_t)&fCPX, eAbsolute); - //CPY(Addressing, address); - SetInstructionTable(0xC0, (uintptr_t)&fCPY, eImmediate); - SetInstructionTable(0xC4, (uintptr_t)&fCPY, eZeroPage); - SetInstructionTable(0xCC, (uintptr_t)&fCPY, eAbsolute); - //BIT(Addressing, address); - SetInstructionTable(0x24, (uintptr_t)&fBIT, eZeroPage); - SetInstructionTable(0x2C, (uintptr_t)&fBIT, eAbsolute); - + + // JMP + SetInstructionTable(0x4C, &JMP, eAbsolute, 3); + SetInstructionTable(0x6C, &JMP, eIndirectAbsolute, 5); + // BCC + SetInstructionTable(0x90, &BCC, eRelative, 2); + // BCS + SetInstructionTable(0xB0, &BCS, eRelative, 2); + // BEQ + SetInstructionTable(0xF0, &BEQ, eRelative, 2); + // BNE + SetInstructionTable(0xD0, &BNE, eRelative, 2); + // BMI + SetInstructionTable(0x30, &BMI, eRelative, 2); + // BPL + SetInstructionTable(0x10, &BPL, eRelative, 2); + // BVS + SetInstructionTable(0x70, &BVS, eRelative, 2); + // BVC + SetInstructionTable(0x50, &BVC, eRelative, 2); + // CMP + SetInstructionTable(0xC9, &CMP, eImmediate, 2); + SetInstructionTable(0xC5, &CMP, eZeroPage, 3); + SetInstructionTable(0xD5, &CMP, eZeroPageIndexedX, 4); + SetInstructionTable(0xCD, &CMP, eAbsolute, 4); + SetInstructionTable(0xDD, &CMP, eAbsoluteIndexedX, 4); + SetInstructionTable(0xD9, &CMP, eAbsoluteIndexedY, 4); + SetInstructionTable(0xC1, &CMP, eIndexedIndirect, 6); + SetInstructionTable(0xD1, &CMP, eIndirectIndexed, 5); + // CPX + SetInstructionTable(0xE0, &CPX, eImmediate, 2); + SetInstructionTable(0xE4, &CPX, eZeroPage, 3); + SetInstructionTable(0xEC, &CPX, eAbsolute, 4); + // CPY + SetInstructionTable(0xC0, &CPY, eImmediate, 2); + SetInstructionTable(0xC4, &CPY, eZeroPage, 3); + SetInstructionTable(0xCC, &CPY, eAbsolute, 4); + // BIT + SetInstructionTable(0x24, &BIT, eZeroPage, 3); + SetInstructionTable(0x2C, &BIT, eAbsolute, 4); + // Shift and Rotate Instructions - //ASL(Addressing, address); - SetInstructionTable(0x0A, (uintptr_t)&fASL, eAccumulator); - SetInstructionTable(0x06, (uintptr_t)&fASL, eZeroPage); - SetInstructionTable(0x16, (uintptr_t)&fASL, eZeroPageIndexedX); - SetInstructionTable(0x0E, (uintptr_t)&fASL, eAbsolute); - SetInstructionTable(0x1E, (uintptr_t)&fASL, eAbsoluteIndexedX); - //LSR(Addressing, address); - SetInstructionTable(0x4A, (uintptr_t)&fLSR, eAccumulator); - SetInstructionTable(0x46, (uintptr_t)&fLSR, eZeroPage); - SetInstructionTable(0x56, (uintptr_t)&fLSR, eZeroPageIndexedX); - SetInstructionTable(0x4E, (uintptr_t)&fLSR, eAbsolute); - SetInstructionTable(0x5E, (uintptr_t)&fLSR, eAbsoluteIndexedX); - //ROL(Addressing, address); - SetInstructionTable(0x2A, (uintptr_t)&fROL, eAccumulator); - SetInstructionTable(0x26, (uintptr_t)&fROL, eZeroPage); - SetInstructionTable(0x36, (uintptr_t)&fROL, eZeroPageIndexedX); - SetInstructionTable(0x2E, (uintptr_t)&fROL, eAbsolute); - SetInstructionTable(0x3E, (uintptr_t)&fROL, eAbsoluteIndexedX); - //ROR(Addressing, address); - SetInstructionTable(0x6A, (uintptr_t)&fROR, eAccumulator); - SetInstructionTable(0x66, (uintptr_t)&fROR, eZeroPage); - SetInstructionTable(0x76, (uintptr_t)&fROR, eZeroPageIndexedX); - SetInstructionTable(0x6E, (uintptr_t)&fROR, eAbsolute); - SetInstructionTable(0x7E, (uintptr_t)&fROR, eAbsoluteIndexedX); - + + // ASL + SetInstructionTable(0x0A, &ASL, eAccumulator, 2); + SetInstructionTable(0x06, &ASL, eZeroPage, 5); + SetInstructionTable(0x16, &ASL, eZeroPageIndexedX, 6); + SetInstructionTable(0x0E, &ASL, eAbsolute, 6); + SetInstructionTable(0x1E, &ASL, eAbsoluteIndexedX, 7); + // LSR + SetInstructionTable(0x4A, &LSR, eAccumulator, 2); + SetInstructionTable(0x46, &LSR, eZeroPage, 5); + SetInstructionTable(0x56, &LSR, eZeroPageIndexedX, 6); + SetInstructionTable(0x4E, &LSR, eAbsolute, 6); + SetInstructionTable(0x5E, &LSR, eAbsoluteIndexedX, 7); + // ROL + SetInstructionTable(0x2A, &ROL, eAccumulator, 2); + SetInstructionTable(0x26, &ROL, eZeroPage, 5); + SetInstructionTable(0x36, &ROL, eZeroPageIndexedX, 6); + SetInstructionTable(0x2E, &ROL, eAbsolute, 6); + SetInstructionTable(0x3E, &ROL, eAbsoluteIndexedX, 7); + // ROR + SetInstructionTable(0x6A, &ROR, eAccumulator, 2); + SetInstructionTable(0x66, &ROR, eZeroPage, 5); + SetInstructionTable(0x76, &ROR, eZeroPageIndexedX, 6); + SetInstructionTable(0x6E, &ROR, eAbsolute, 6); + SetInstructionTable(0x7E, &ROR, eAbsoluteIndexedX, 7); + // Transfer Instructions - //TAX(Addressing, address); - SetInstructionTable(0xAA, (uintptr_t)&fTAX, eImplied); - //TAY(Addressing, address); - SetInstructionTable(0xA8, (uintptr_t)&fTAY, eImplied); - //TXA(Addressing, address); - SetInstructionTable(0x8A, (uintptr_t)&fTXA, eImplied); - //TYA(Addressing, address); - SetInstructionTable(0x98, (uintptr_t)&fTYA, eImplied); - + + // TAX + SetInstructionTable(0xAA, &TAX, eImplied, 2); + // TAY + SetInstructionTable(0xA8, &TAY, eImplied, 2); + // TXA + SetInstructionTable(0x8A, &TXA, eImplied, 2); + // TYA + SetInstructionTable(0x98, &TYA, eImplied, 2); + // Stack Instructions - //TSX(Addressing, address); - SetInstructionTable(0xBA, (uintptr_t)&fTSX, eImplied); - //TXS(Addressing, address); - SetInstructionTable(0x9A, (uintptr_t)&fTXS, eImplied); - //PHA(Addressing, address); - SetInstructionTable(0x48, (uintptr_t)&fPHA, eImplied); - //PHP(Addressing, address); - SetInstructionTable(0x08, (uintptr_t)&fPHP, eImplied); - //PLA(Addressing, address); - SetInstructionTable(0x68, (uintptr_t)&fPLA, eImplied); - //PLP(Addressing, address); - SetInstructionTable(0x28, (uintptr_t)&fPLP, eImplied); - + + // TSX + SetInstructionTable(0xBA, &TSX, eImplied, 2); + // TXS + SetInstructionTable(0x9A, &TXS, eImplied, 2); + // PHA + SetInstructionTable(0x48, &PHA, eImplied, 3); + // PHP + SetInstructionTable(0x08, &PHP, eImplied, 3); + // PLA + SetInstructionTable(0x68, &PLA, eImplied, 4); + // PLP + SetInstructionTable(0x28, &PLP, eImplied, 4); + // Subroutine Instructions - //JSR(Addressing, address); - SetInstructionTable(0x20, (uintptr_t)&fJSR, eAbsolute); - //RTS(Addressing, address); - SetInstructionTable(0x60, (uintptr_t)&fRTS, eImplied); - //RTI(Addressing, address); - SetInstructionTable(0x40, (uintptr_t)&fRTI, eImplied); - + + // JSR + SetInstructionTable(0x20, &JSR, eAbsolute, 6); + // RTS + SetInstructionTable(0x60, &RTS, eImplied, 6); + // RTI + SetInstructionTable(0x40, &RTI, eImplied, 6); + // Set/Reset Insutrctions - //CLC(Addressing, address); - SetInstructionTable(0x18, (uintptr_t)&fCLC, eImplied); - //CLD(Addressing, address); - SetInstructionTable(0xD8, (uintptr_t)&fCLD, eImplied); - //CLI(Addressing, address); - SetInstructionTable(0x58, (uintptr_t)&fCLI, eImplied); - //CLV(Addressing, address); - SetInstructionTable(0xB8, (uintptr_t)&fCLV, eImplied); - //SEC(Addressing, address); - SetInstructionTable(0x38, (uintptr_t)&fSEC, eImplied); - //SED(Addressing, address); - SetInstructionTable(0xF8, (uintptr_t)&fSED, eImplied); - //SEI(Addressing, address); - SetInstructionTable(0x78, (uintptr_t)&fSEI, eImplied); - + + // CLC + SetInstructionTable(0x18, &CLC, eImplied, 2); + // CLD + SetInstructionTable(0xD8, &CLD, eImplied, 2); + // CLI + SetInstructionTable(0x58, &CLI, eImplied, 2); + // CLV + SetInstructionTable(0xB8, &CLV, eImplied, 2); + // SEC + SetInstructionTable(0x38, &SEC, eImplied, 2); + // SED + SetInstructionTable(0xF8, &SED, eImplied, 2); + // SEI + SetInstructionTable(0x78, &SEI, eImplied, 2); + // NOP/BRK Instructions - //NOP(Addressing, address); - SetInstructionTable(0xEA, (uintptr_t)&fNOP, eImplied); - //BRK(Addressing, address); - SetInstructionTable(0x00, (uintptr_t)&fBRK, eImplied); + + // NOP + SetInstructionTable(0xEA, &NOP, eImplied, 2); + // BRK + SetInstructionTable(0x00, &BRK, eImplied, 7); } - diff --git a/src/cpu/table.h b/src/cpu/table.h index 7406c9c..70be525 100644 --- a/src/cpu/table.h +++ b/src/cpu/table.h @@ -7,17 +7,11 @@ #include"string.h" #include"addressing.h" - -#define InstructionTableSize (256 * (sizeof(uintptr_t) + sizeof(Addressing))) - -uintptr_t* GetInstructionTableFunction(int i); - -Addressing* GetInstructionTableAddressing(int i); - +// Runs the next instruction through the CPU void CallInstructionTable(); // Sets an individual portion of an instruction set -void SetInstructionTable(int i, uintptr_t p, Addressing r); +void SetInstructionTable(int index, void* function, Addressing addressing, int cycles); // Initializes instruction table in memory. void InitInstructionTable(); |