summaryrefslogtreecommitdiff
path: root/headers
diff options
context:
space:
mode:
authoralekseiplusplus <alekseijeaves@protonmail.com>2023-04-21 03:44:47 +1000
committeralekseiplusplus <alekseijeaves@protonmail.com>2023-04-21 03:44:47 +1000
commitee742e6020248f9695cc9ce5bbace5f42814383e (patch)
treed8be3463f30027c965e821ac63b8b6eae047390d /headers
parentc4c28762385c52d0c349da72e3f3bbed64197411 (diff)
have to call it a night.
Diffstat (limited to 'headers')
-rw-r--r--headers/addressing.h213
-rw-r--r--headers/applesystem.h113
-rw-r--r--headers/debug.h41
-rw-r--r--headers/include.h7
-rw-r--r--headers/instruction-init.h112
-rw-r--r--headers/instructions.h347
6 files changed, 833 insertions, 0 deletions
diff --git a/headers/addressing.h b/headers/addressing.h
new file mode 100644
index 0000000..d9d8e98
--- /dev/null
+++ b/headers/addressing.h
@@ -0,0 +1,213 @@
+// addressing.h
+// Contains definitions relevant to addressing, as well as fAddress() which returns time, length, value, and address for an instruction function call.
+
+enum Addressing {
+ eImmediate,
+ eAccumulator,
+ eZeroPage,
+ eZeroPageIndexedX,
+ eZeroPageIndexedY,
+ eAbsolute,
+ eAbsoluteIndexedX,
+ eAbsoluteIndexedY,
+ eIndexedIndirect,
+ eIndirectIndexed,
+ eImplied,
+ eIndirectAbsolute,
+ eRelative
+};
+
+typedef int Addressing;
+
+struct AddData{
+ int cycles;
+ int length;
+ address add;
+ byte value;
+};
+
+typedef struct AddData AddData;
+
+#include"instruction-init.h"
+
+//Holds address of current instruction.
+void* current_instruction;
+
+Addressing fAddressGetLength(Addressing addr){
+ switch(addr){
+ case eAbsolute: case eAbsoluteIndexedX: case eAbsoluteIndexedY:
+ return 3;
+ case eAccumulator:
+ return 1;
+ default:
+ return 2;
+ }
+}
+
+AddData fAddress(Addressing addr, short x) {
+ AddData ret;
+
+ // ADDRESS
+
+ switch(addr){
+ case eImplied:
+ case eIndirectAbsolute:
+ case eRelative:
+ case eImmediate:
+ case eAccumulator:
+ ret.add = 0x0000;
+ break;
+
+ case eAbsolute:
+ ret.add = x;
+ break;
+ case eAbsoluteIndexedX:
+ ret.add = (x + X);
+ break;
+ case eAbsoluteIndexedY:
+ ret.add = (x + Y);
+ break;
+
+ case eZeroPage:
+ ret.add = (x & 0x00FF);
+ break;
+ case eZeroPageIndexedX:
+ ret.add = ((x + X) & 0x00FF);
+ break;
+ case eZeroPageIndexedY:
+ ret.add = ((x + Y) & 0x00FF);
+ break;
+
+ case eIndexedIndirect:
+ ret.add = (((address)Memory[x+X+1])<<8) + (Memory[x+X]);
+ break;
+ case eIndirectIndexed:
+ ret.add = (((address)Memory[x+1])<<8) + (Memory[x]) + Y;
+ break;
+ }
+
+ // VALUE
+
+ switch(addr){
+ case eImplied:
+ case eIndirectAbsolute:
+ case eRelative:
+ break;
+
+ case eImmediate:
+ ret.value = x;
+ break;
+
+ case eAccumulator:
+ ret.value = acc;
+ break;
+
+ default:
+ ret.value = Memory[ret.add];
+ }
+
+ // LENGTH
+
+ ret.length = fAddressGetLength(addr);
+
+ // 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(addr){
+ case eImmediate:
+ ret.cycles = 2; break;
+ case eZeroPage:
+ ret.cycles = 3; break;
+ case eZeroPageIndexedX: case eAbsolute: case eAbsoluteIndexedX: case eAbsoluteIndexedY:
+ ret.cycles = 4; break;
+ case eIndexedIndirect:
+ ret.cycles = 6; break;
+ case eIndirectIndexed:
+ ret.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(addr){
+ case eAccumulator:
+ ret.cycles = 2; break;
+ case eZeroPage:
+ ret.cycles = 5; break;
+ case eZeroPageIndexedX: case eAbsolute:
+ ret.cycles = 6; break;
+ case eAbsoluteIndexedX:
+ ret.cycles = 7; break;
+ }
+ }
+
+ //case &fSTA:
+ else if (current_instruction == &fSTA){
+ switch(addr){
+ case eZeroPage:
+ ret.cycles = 3; break;
+ case eZeroPageIndexedX: case eAbsolute:
+ ret.cycles = 4; break;
+ case eAbsoluteIndexedX: case eAbsoluteIndexedY:
+ ret.cycles = 5; break;
+ case eIndexedIndirect: case eIndirectIndexed:
+ ret.cycles = 6; break;
+ }
+ }
+
+
+ //case &fBRK:
+ else if (current_instruction == &fBRK){
+ ret.cycles = 7;
+ }
+
+
+ //case &fRTI: case &fRTS: case &fJSR:
+ else if (current_instruction == &fRTI || current_instruction == &fRTS || current_instruction == &fJSR){
+ ret.cycles = 6;
+ }
+
+ //case &fJMP:
+ else if (current_instruction == &fJMP){
+ ret.cycles = 5;
+ }
+
+ //case &fPLA: case &fPLP:
+ else if (current_instruction == &fPLA || current_instruction == &fPLP){
+ ret.cycles = 4;
+ }
+
+ //case &fPHA: case &fPHP:
+ else if (current_instruction == &fPHA || current_instruction == &fPHP){
+ ret.cycles = 3;
+ }
+
+ else {
+ ret.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(addr){
+ case eAbsoluteIndexedX:
+ if ((x & 0xFFFC) != ((x + X) & 0xFFFC)) ret.cycles++; break;
+ case eAbsoluteIndexedY:
+ if ((x & 0xFFFC) != ((x + Y) & 0xFFFC)) ret.cycles++; break;
+ case eIndirectIndexed:
+ if ((ret.add & 0xFFFC) != (ret.add - Y & 0xFFFC)) ret.cycles++; break;
+ }
+ }
+
+ return ret;
+}
+
diff --git a/headers/applesystem.h b/headers/applesystem.h
new file mode 100644
index 0000000..6b2f818
--- /dev/null
+++ b/headers/applesystem.h
@@ -0,0 +1,113 @@
+// applesystem.h
+// Core elements of the 6502 CPU, and flag manipulation.
+
+typedef unsigned char byte;
+typedef unsigned short address;
+byte acc, X, Y, P, S = 0x00;
+address PC = 0x0000;
+byte Memory[4096]; // TO DO. Add expansion capability to memory.
+
+// FLAGS
+const byte flag_N = 0x80; // Negative
+const byte flag_V = 0x40; // Overflow
+const byte flag_B = 0x10; // BRK command
+const byte flag_D = 0x08; // Decimal mode
+const byte flag_I = 0x04; // IRQ disable
+const byte flag_Z = 0x02; // Zero
+const byte flag_C = 0x01; // Carry
+
+byte getFlag(byte flag) {
+ return ((P & flag) == flag) ? 1 : 0;
+}
+
+void setFlag(byte flag, int x) { //OVERLOAD TO ACCEPT INT AS WELL
+ if (x == 1){
+ if ((P & flag) == 0x0) P += flag;
+ }else if (x == 0){
+ if ((P & flag) == flag) P -= flag;
+ }
+ else{
+ fprintf(stderr, "setFlag() passed arg neither 0 or 1");
+ }
+}
+
+void flagSet(byte flag){
+ P |= flag;
+}
+
+void flagClear(byte flag){
+ P &= ~flag;
+}
+
+
+// BCD
+// need to actually look into BCD on the 6502
+byte toBCD(byte x){
+ if (x < 100){
+ byte a = ((x / 10) << 4);
+ byte b = (x % 10);
+ return (a + b);
+ }
+ else{
+ fprintf(stderr, "Number greater than 99 passed to toBCD()");
+ }
+}
+
+byte fromBCD(byte x){
+ byte a = ((x >> 4) * 10);
+ byte b = (x & 0xF);
+ return (a + b);
+}
+
+
+// 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);
+}
+
+//Perform prior to any changes
+void setFlagV(byte x, byte y){
+ if ((x & flag_N) == (y & flag_N)){
+ if (((x + y) & (flag_N ^ 0xFF)) > 0x7F) setFlag(flag_V, 1);
+ else setFlag(flag_V, 0);
+ }else{
+ if (((x - y) & (flag_N ^ 0xFF)) > 0x7F) setFlag(flag_V, 1);
+ else setFlag(flag_V, 0);
+ }
+}
+
+/*void setFlagB(){ //WORK ON
+ setFlag(flag_B, 1);
+}*/ //Dont really need since its dependent on the BRK insturction
+
+/*void setFlagD(){
+ setFlag(flag_D, 1);
+}*/
+
+/*void setFlagI(){ //WORK ON
+ setFlag(flag_Z, 1);
+}*/
+
+void setFlagZ(int x){
+ if (x == 0)
+ setFlag(flag_Z, 1);
+ else
+ setFlag(flag_Z, 0);
+}
+
+//Only 6 instructions, 2 not including stack instructions, use the carry flag.
+// Need to look further into implementation details for this.
+/*void setFlagC(){
+ setFlag(flag_Z, 1);
+}*/
+
+
+
+
+
+
+
diff --git a/headers/debug.h b/headers/debug.h
new file mode 100644
index 0000000..bb6ba40
--- /dev/null
+++ b/headers/debug.h
@@ -0,0 +1,41 @@
+// debug.h
+// Various functions useful for use during development.
+
+// Converts a single character to hexadecimal
+int dCharToNum(char c){
+ // 0x0 - 0x9
+ if (c != 0x20 && (c >= 0x30 && c <= 0x39)){
+ return (c - 0x30);
+ }
+ // 0xA - 0xF
+ else if (c != 0x20 && (c >= 0x41 && c <= 0x46)){
+ return (c - 0x37);
+ // 0xa - 0xf
+ }else if (c != 0x20 && (c >= 0x61 && c <= 0x66)){
+ return (c - 0x57);
+ // Invalid
+ }else{
+ return -1;
+ }
+}
+
+// Dump a particular page in memory.
+void dPageDump(short m){
+ m <<= 8;
+ for(int i = 0; i < 256; i+=16){
+ printf("\t");
+ for(int j = 0; j < 16; j+=1){
+ printf("%2x ", Memory[(m+(i+j))]);
+ }
+ printf("\n");
+ }
+}
+
+// Dump CPU values
+void dStatusDump(void){
+ printf(" acc:\t%x\n X:\t%x\n Y:\t%x\nstack:\t%x\nflags:\t%x\n", acc, X, Y, S, P);
+}
+
+void dIdataDump(void){
+ printf("cycles:\t%d\nlength:\t%d\n add:\t%x\n value:\t%x\n", idata.cycles, idata.length, idata.add, idata.value);
+} \ No newline at end of file
diff --git a/headers/include.h b/headers/include.h
new file mode 100644
index 0000000..9a537c4
--- /dev/null
+++ b/headers/include.h
@@ -0,0 +1,7 @@
+#include"stdio.h"
+#include"stdint.h"
+#include"stdlib.h"
+#include"string.h"
+#include"applesystem.h"
+#include"addressing.h"
+#include"instructions.h" \ No newline at end of file
diff --git a/headers/instruction-init.h b/headers/instruction-init.h
new file mode 100644
index 0000000..488f73c
--- /dev/null
+++ b/headers/instruction-init.h
@@ -0,0 +1,112 @@
+// instruction-init.h
+// Initializes every instruction function prior to addressing.h so that function addresses are accessible
+// also defines the array used to refer to functions
+
+//InstructionTable
+void* InstructionTable;
+void (*func)(Addressing, address);
+
+#define InstructionTableSize (256 * (sizeof(uintptr_t) + sizeof(Addressing)))
+
+/*
+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;
+}
+
+Addressing getInstructionTableAddressing(int i){
+ Addressing r = (InstructionTable + (sizeof(uintptr_t)*256) + (sizeof(Addressing)*i));
+ return r;
+}
+*/
+
+void callInstructionTable(int i, address val){
+ printf("Table:\t%x\n", InstructionTable);
+ uintptr_t* a = (InstructionTable + (sizeof(uintptr_t) * i));
+ printf("A Val:\t%x\n", a);
+ printf("Before:\t%x\n", func); func = *a; printf("After:\t%x\n", func);
+ //printf("Before:\t%x\n", func); memcpy(&func, a, sizeof(uintptr_t)); printf("After:\t%x\n", func);
+ Addressing* r = (InstructionTable + ((sizeof(uintptr_t)*256) + (sizeof(Addressing) * i)));
+ func(*r, val); printf("Statement OK");
+}
+
+void initInstructionTable(){
+ InstructionTable = malloc(InstructionTableSize);
+ FILE* fs = fopen("instructions.bin", "r");
+
+ for(byte* c = InstructionTable; c < (InstructionTable + InstructionTableSize); c++){ //NEED TO MAKE (InstructionTable + (256*(sizeof(uintptr_t) + sizeof(Addressing)))) a macro
+ *c = (byte)fgetc(fs);
+ } //Investigate whether doing word sized units would increase speed
+ fclose(fs);
+ //read in the instruction data binary
+}
+
+
+
+// Load and Store Instructions
+void fLDA(Addressing, address);
+void fLDX(Addressing, address);
+void fLDY(Addressing, address);
+void fSTA(Addressing, address);
+void fSTX(Addressing, address);
+void fSTY(Addressing, address);
+// Arithmetic Instructions
+void fADC(Addressing, address);
+void fSBC(Addressing, address);
+//Increment and Decrement Instructions
+void fINC(Addressing, address);
+void fINX(Addressing, address);
+void fINY(Addressing, address);
+void fDEC(Addressing, address);
+void fDEX(Addressing, address);
+void fDEY(Addressing, address);
+// Logical Instructions
+void fAND(Addressing, address);
+void fORA(Addressing, address);
+void fEOR(Addressing, address);
+// Jump, Branch, Compare, and Test Bits
+void fJMP(Addressing, address);
+void fBCC(Addressing, address);
+void fBCS(Addressing, address);
+void fBEQ(Addressing, address);
+void fBNE(Addressing, address);
+void fBMI(Addressing, address);
+void fBPL(Addressing, address);
+void fBVS(Addressing, address);
+void fBVC(Addressing, address);
+void fCMP(Addressing, address);
+void fCPX(Addressing, address);
+void fCPY(Addressing, address);
+void fBIT(Addressing, address);
+// Shift and Rotate Instructions
+void fASL(Addressing, address);
+void fLSR(Addressing, address);
+void fROL(Addressing, address);
+void fROR(Addressing, address);
+// Transfer Instructions
+void fTAX(Addressing, address);
+void fTAY(Addressing, address);
+void fTXA(Addressing, address);
+void fTYA(Addressing, address);
+// Stack Instructions
+void fTSX(Addressing, address);
+void fTXS(Addressing, address);
+void fPHA(Addressing, address);
+void fPHP(Addressing, address);
+void fPLA(Addressing, address);
+void fPLP(Addressing, address);
+// Subroutine Instructions
+void fJSR(Addressing, address);
+void fRTS(Addressing, address);
+void fRTI(Addressing, address);
+// Set/Reset Insutrctions
+void fCLC(Addressing, address);
+void fCLD(Addressing, address);
+void fCLI(Addressing, address);
+void fCLV(Addressing, address);
+void fSEC(Addressing, address);
+void fSED(Addressing, address);
+void fSEI(Addressing, address);
+// NOP/BRK Instructions
+void fNOP(Addressing, address);
+void fBRK(Addressing, address); \ No newline at end of file
diff --git a/headers/instructions.h b/headers/instructions.h
new file mode 100644
index 0000000..96f5719
--- /dev/null
+++ b/headers/instructions.h
@@ -0,0 +1,347 @@
+// instruction.h
+// Definition of all instruction functions, handling effect of instruction and flags.
+
+// array/map of pointers which all point
+// to the functions which the index corresponds to.
+// use that like a sort of map
+
+
+//Instruction Data
+AddData idata;
+
+// 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, (val & 0x80));
+ acc = (val << 1);
+ setFlagN(acc);
+ setFlagZ(acc);
+}
+
+void fLSR(Addressing addr, address val){ idata = fAddress(addr, val);
+ setFlag(flag_C, (val & 0x01));
+ acc = (val >> 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);
+} \ No newline at end of file