summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralekseiplusplus <alekseijeaves@protonmail.com>2023-04-07 02:35:46 +1000
committeralekseiplusplus <alekseijeaves@protonmail.com>2023-04-07 02:35:46 +1000
commitfbca225d25db812fe7823a8528dff17320cf1c53 (patch)
treef99d672c7245233814cd038fd683ef8bf4270961
parent4b2952578ece47358960e29825443f77070a7457 (diff)
commit so I can access it tomorrow.
-rw-r--r--addressing.h78
-rw-r--r--applesystem.h32
-rw-r--r--assembler.c9
-rw-r--r--debug.h16
-rw-r--r--instruction-init.h3
-rw-r--r--instruction.h123
-rw-r--r--interpreter.c6
-rw-r--r--main.c8
-rw-r--r--test.c25
9 files changed, 174 insertions, 126 deletions
diff --git a/addressing.h b/addressing.h
index 300dac5..9c57592 100644
--- a/addressing.h
+++ b/addressing.h
@@ -1,12 +1,15 @@
+// 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,
- eAbsolute,
- eAbsoluteIndexedX,
- eAbsoluteIndexedY,
eZeroPage,
eZeroPageIndexedX,
eZeroPageIndexedY,
+ eAbsolute,
+ eAbsoluteIndexedX,
+ eAbsoluteIndexedY,
eIndexedIndirect,
eIndirectIndexed,
eImplied,
@@ -22,30 +25,70 @@ void (*current_instruction)(Addressing, address);
struct AddData{
int cycles;
int length;
+ address add;
byte value;
};
AddData fAddress(Addressing addr, short x) {
AddData ret;
- // VALUE
+ // ADDRESS
switch(addr){
- case eImmediate: ret.value = x; break;
- case eAccumulator: ret.value = acc; break;
+ case eImplied:
+ case eIndirectAbsolute:
+ case eRelative:
+ 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;
+ }
- case eAbsolute: ret.value = Memory[x]; break;
- case eAbsoluteIndexedX: ret.value = Memory[(x + X)]; break;
- case eAbsoluteIndexedY: ret.value = Memory[(x + Y)]; break;
+ // VALUE
- case eZeroPage: ret.value = Memory[(x & 0x00FF)]; break;
- case eZeroPageIndexedX: ret.value = Memory[((x + X) & 0x00FF)]; break;
- case eZeroPageIndexedY: ret.value = Memory[((x + Y) & 0x00FF)]; break;
+ switch(addr){
+ case eImplied:
+ case eIndirectAbsolute:
+ case eRelative:
+ break;
+
+ case eImmediate:
+ ret.value = x;
+ break;
- case eIndexedIndirect: ret.value = Memory[ (((address)Memory[x+X+1])<<8) + (Memory[x+X]) ]; break;
- case eIndirectIndexed: ret.value = Memory[ (((address)Memory[x+1])<<8) + (Memory[x]) + Y ]; break;
+ case eAccumulator:
+ ret.value = acc;
+ break;
+
+ default:
+ ret.value = Memory[ret.add]
}
+
// LENGTH
switch(addr){
@@ -122,7 +165,7 @@ AddData fAddress(Addressing addr, short x) {
ret.cycles = 3;
break;
- default: //Any instruction which doesn't fit any of these conditions is probably an implied/relative mode instruction which costs 2 cycles
+ default:
ret.cycles = 2;
}
@@ -133,9 +176,8 @@ AddData fAddress(Addressing addr, short x) {
if ((x & 0xFFFC) != ((x + X) & 0xFFFC)) ret.cycles++; break;
case eAbsoluteIndexedY:
if ((x & 0xFFFC) != ((x + Y) & 0xFFFC)) ret.cycles++; break;
- case eIndirectIndexed: //I am not 100% sure if this is the correct handling a page boundary cross with indirect indexed addressing. also its kinda ugly
- if( (((((address)Memory[x+1])<<8) + (Memory[x]) + Y) & 0xFFFC) !=
- (((((address)Memory[x+1])<<8) + (Memory[x])) & 0xFFFC)) ret.cycles++; break;
+ case eIndirectIndexed:
+ if ((ret.add & 0xFFFC) != (ret.add - Y & 0xFFFC)) ret.cycles++; break;
}
}
}
diff --git a/applesystem.h b/applesystem.h
index f561d36..4cff655 100644
--- a/applesystem.h
+++ b/applesystem.h
@@ -1,3 +1,6 @@
+// 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;
@@ -5,7 +8,7 @@ address PC = 0x0000;
register byte Memory[4096]; // TO DO. Add expansion capability to memory.
// FLAGS
-const byte flag_N = 0x80; // Negative (Note that byte cast is necessary here only)
+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
@@ -56,14 +59,14 @@ byte fromBCD(byte x){
return (a + b);
}
-// Set particular flags
-// Functions which quickly set specific flags that are straightforward checks, and are repeated often.
+
+// Functions which perform reusable routines for finding if a specific flag should be set.
+
void setFlagN(byte x){
- if (x ^ flag_N == flag_N){
+ if (x & flag_N == flag_N)
setFlag(flag_N, 1);
- }else{ //not sure if this should be present, I think it is
+ else
setFlag(flag_N, 0);
- }
}
//Perform prior to any changes
@@ -76,22 +79,29 @@ void setFlagV(byte x, byte y){
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
+
+/*void setFlagI(){ //WORK ON
setFlag(flag_Z, 1);
-}
+}*/
+
void setFlagZ(int x){
- if (x == 0) {
+ if (x == 0)
setFlag(flag_Z, 1);
- }
+ else
+ setFlag(flag_Z, 0);
}
+
//Only 6 instructions, 2 not including stack instructions, use the carry flag.
-/*void setFlagC(){ // NOTE. Must make setFlagC functional with independence. Look into carrying on 6502
+// Need to look further into implementation details for this.
+/*void setFlagC(){
setFlag(flag_Z, 1);
}*/
diff --git a/assembler.c b/assembler.c
index e302218..b20d13b 100644
--- a/assembler.c
+++ b/assembler.c
@@ -1,10 +1,10 @@
+// assembler.c
+// A minimalistic assembler for creating binary files.
+
#include"stdio.h"
//syscall library
-//Will probably need to make a special case which will prevent EOF
-//from being written.
-
int main(int argc; char* argv[]){
int output = 0;
switch(argc){
@@ -27,13 +27,14 @@ int main(int argc; char* argv[]){
//call open file
// DRAFTING PROG LOGIC
+/*
char c = 0;
char in[10];
while((c != '\n') && (c != EOF)
c = getchar;
if(c == '#') c = '\n';
in[i] = c;
-
+*/
}
diff --git a/debug.h b/debug.h
new file mode 100644
index 0000000..c46f220
--- /dev/null
+++ b/debug.h
@@ -0,0 +1,16 @@
+// debug.h
+// Various functions useful for use during development.
+
+void dPageDump(){
+ for(int i = 0; i < 256; i+=16){
+ printf("\t");
+ for(int j = 0; j < 16; j+=1){
+ printf("%2x ", Memory[(i+j)]);
+ }
+ printf("\n");
+ }
+}
+
+void dStatusDump(){
+ printf("acc:\t%x\nX:\t%x\nY:\t%x\nstack:\t%x\nflags:\t%x\n", acc, X, Y, S, P);
+} \ No newline at end of file
diff --git a/instruction-init.h b/instruction-init.h
index 73c80b9..4a82d8a 100644
--- a/instruction-init.h
+++ b/instruction-init.h
@@ -1,3 +1,6 @@
+// instruction-init.h
+// Initializes every instruction function prior to addressing.h so that function addresses are accessible
+
// Load and Store Instructions
void fLDA(Addressing addr, address val);
void fLDX(Addressing addr, address val);
diff --git a/instruction.h b/instruction.h
index c1b4843..e8e9bbc 100644
--- a/instruction.h
+++ b/instruction.h
@@ -1,16 +1,18 @@
+// 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
-AddData idata; //Instruction Data
+//Instruction Data
+AddData idata;
// Load and Store Instructions
-// the load and store instructions are currently
-// used to express how data structures will work eventually.
void fLDA(Addressing addr, address val){ idata = fAddress(addr, val);
- acc = idata.val;
+ acc = idata.value;
}
void fLDX(Addressing addr, address val){ idata = fAddress(addr, val);
@@ -22,44 +24,43 @@ void fLDY(Addressing addr, address val){ idata = fAddress(addr, val);
}
void fSTA(Addressing addr, address val){ idata = fAddress(addr, val);
- Memory[idata.value] = acc;
+ Memory[idata.add] = acc;
}
void fSTX(Addressing addr, address val){ idata = fAddress(addr, val);
- Memory[idata.value] = X;
+ Memory[idata.add] = X;
}
void fSTY(Addressing addr, address val){ idata = fAddress(addr, val);
- Memory[idata.value] = Y;
+ Memory[idata.add] = Y;
}
// Arithmetic Instructions
void fADC(Addressing addr, address val){ idata = fAddress(addr, val);
- int buffer = acc + fAddress(addr, val);
+ int buffer = acc + idata.value;
setFlagV(buffer, acc);
- if (buffer > 255){
+ if (buffer > 255)
flagSet(flag_C);
- }else{
+ else
flagClear(flag_C);
- }
- acc += fAddress(addr, val);
+ acc += idata.value;
setFlagN(acc);
setFlagZ(acc);
}
void fSBC(Addressing addr, address val){ idata = fAddress(addr, val);
- int buffer = acc - fAddress(addr, val);
+ int buffer = acc - idata.value;
setFlagV(buffer, acc);
- if (buffer < 0){
+ if (buffer < 0)
flagSet(flag_C);
- }else{
+ else
flagClear(flag_C);
- }
- acc -= fAddress(addr, val);
+
+ acc -= idata.value;
setFlagN(acc);
setFlagZ(acc);
}
@@ -67,14 +68,14 @@ void fSBC(Addressing addr, address val){ idata = fAddress(addr, val);
//Increment and Decrement Instructions
void fINC(Addressing addr, address val){ idata = fAddress(addr, val);
- Memory[x]++;
- setFlagD(Memory[x]);
- setFlagZ(Memory[x]);
+ Memory[idata.add]++;
+ setFlagN(Memory[idata.add]);
+ setFlagZ(Memory[idata.add]);
}
void fINX(Addressing addr, address val){ idata = fAddress(addr, val);
X++;
- setFlagD(X);
+ setFlagN(X);
setFlagZ(X);
}
@@ -85,9 +86,9 @@ void fINY(Addressing addr, address val){ idata = fAddress(addr, val);
}
void fDEC(Addressing addr, address val){ idata = fAddress(addr, val);
- Memory[x]--;
- setFlagD(Memory[x]);
- setFlagZ(Memory[x]);
+ Memory[idata.add]--;
+ setFlagD(Memory[idata.add]);
+ setFlagZ(Memory[idata.add]);
}
void fDEX(Addressing addr, address val){ idata = fAddress(addr, val);
@@ -105,19 +106,19 @@ void fDEY(Addressing addr, address val){ idata = fAddress(addr, val);
// Logical Instructions
void fAND(Addressing addr, address val){ idata = fAddress(addr, val);
- acc = acc & fAddress(addr, val);
- setFlagN();
+ acc &= idata.value;
+ setFlagN(acc);
setFlagZ(acc);
}
void fORA(Addressing addr, address val){ idata = fAddress(addr, val);
- acc = acc | fAddress(addr, val);
- setFlagN();
+ acc |= idata.value;
+ setFlagN(acc);
setFlagZ(acc);
}
void fEOR(Addressing addr, address val){ idata = fAddress(addr, val);
- acc = acc ^ fAddress(addr, val);
+ acc ^= idata.value;
setFlagN(acc);
setFlagZ(acc);
}
@@ -128,7 +129,7 @@ void fJMP(Addressing addr, address val){ idata = fAddress(addr, val);
PC = val;
}
-void fBCC(Addressing addr, address val){ idata = fAddress(addr, 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;
}
@@ -162,35 +163,36 @@ void fBVC(Addressing addr, address val){ idata = fAddress(addr, val);
}
void fCMP(Addressing addr, address val){ idata = fAddress(addr, val);
- if (acc < Memory[val]){
+ if (acc < idata.value){
flagSet(flag_N); flagClear(flag_Z); flagClear(flag_C);
- }if (acc == Memory[val]){
+ }if (acc == idata.value){
flagClear(flag_N); flagSet(flag_Z); flagClear(flag_C);
- }if (acc > Memory[val]){
+ }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 < Memory[val]){
+ if (X < idata.value){
flagSet(flag_N); flagClear(flag_Z); flagClear(flag_C);
- }if (X == Memory[val]){
+ }if (X == idata.value){
flagClear(flag_N); flagSet(flag_Z); flagClear(flag_C);
- }if (X > Memory[val]){
+ }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 < Memory[val]){
+ if (Y < idata.value){
flagSet(flag_N); flagClear(flag_Z); flagClear(flag_C);
- }if (Y == Memory[val]){
+ }if (Y == idata.value){
flagClear(flag_N); flagSet(flag_Z); flagClear(flag_C);
- }if (Y > Memory[val]){
+ }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));
@@ -210,7 +212,7 @@ void fASL(Addressing addr, address val){ idata = fAddress(addr, val);
setFlagZ(acc);
}
-void fASL(Addressing addr, address val){ idata = fAddress(addr, val);
+void fLSR(Addressing addr, address val){ idata = fAddress(addr, val);
setFlag(flag_C, (val & 0x01));
acc = (val >> 1);
setFlagN(acc);
@@ -237,14 +239,14 @@ void fROR(Addressing addr, address val){ idata = fAddress(addr, val);
void fTAX(Addressing addr, address val){ idata = fAddress(addr, val);
X = acc;
- setFlagN(X);
- setFlagZ(X);
+ //setFlagN(X);
+ //setFlagZ(X);
}
void fTAY(Addressing addr, address val){ idata = fAddress(addr, val);
Y = acc;
- setFlagN(Y);
- setFlagZ(Y);
+ //setFlagN(Y);
+ //setFlagZ(Y);
}
void fTXA(Addressing addr, address val){ idata = fAddress(addr, val);
@@ -270,69 +272,76 @@ void fTXS(Addressing addr, address val){ idata = fAddress(addr, val);
}
void fPHA(Addressing addr, address val){ idata = fAddress(addr, val);
-
+ Memory[0x01FF-S] = A;
+ 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--;
+ A = 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);
- return {1, 2};
}
void fCLD(Addressing addr, address val){ idata = fAddress(addr, val);
flagClear(flag_D);
- return {1, 2};
}
void fCLI(Addressing addr, address val){ idata = fAddress(addr, val);
flagClear(flag_I);
- return {1, 2};
}
void fCLV(Addressing addr, address val){ idata = fAddress(addr, val);
flagClear(flag_V);
- return {1, 2};
}
void fSEC(Addressing addr, address val){ idata = fAddress(addr, val);
flagSet(flag_C);
- return {1, 2};
}
void fSED(Addressing addr, address val){ idata = fAddress(addr, val);
flagSet(flag_D);
- return {1, 2};
}
void fSEI(Addressing addr, address val){ idata = fAddress(addr, val);
flagSet(flag_I);
- return {1, 2};
}
// NOP/BRK Instructions
void fNOP(Addressing addr, address val){ idata = fAddress(addr, val);
- return {1, 2};
}
void fBRK(Addressing addr, address val){ idata = fAddress(addr, val);
flagSet(flag_B);
- return {1, 7};
} \ No newline at end of file
diff --git a/interpreter.c b/interpreter.c
index 0df27ce..82cb9b2 100644
--- a/interpreter.c
+++ b/interpreter.c
@@ -1,5 +1,5 @@
/*
- * interpreter.c is a tool which can be used to interpret 6502 machine code inline.
+ * interpreter.c WILL BE a tool which can be used to interpret 6502 machine code inline.
* Machine code is expected as hexadecimal of length 2 or 6, depending on the instruction.
* Note that zero-page addressing is not fully emulated yet; it will still address the zero-page
section of memory but the instructions still take an address of length 4.
@@ -19,9 +19,7 @@ int charToNum (char c, int mul) {
}
}
-void debug_print(){
- printf("\nacc:\t%x\nX:\t%x\nY:\t%x\nstack:\t%x\nflags:\t%x", acc, X, Y, S, P);
-}
+
int main(){
char c;
diff --git a/main.c b/main.c
index 1d212c5..1df62a0 100644
--- a/main.c
+++ b/main.c
@@ -1,12 +1,6 @@
#include"include.h"
-
+#include"debug.h"
int main(int argc, char *argv[]){
- printf("%d\n",acc);
- fLDA(eImmediate, 0x20);
- printf("%d\n",acc);
- fSTA(fAbsolute)
- printf("%d\n",P);
- return 0;
} \ No newline at end of file
diff --git a/test.c b/test.c
deleted file mode 100644
index e1898c3..0000000
--- a/test.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// BCD
-#include"stdio.h"
-
-int toBCD(int x){
- if (x < 100){
- int a = ((x / 10) << 4);
- int b = (x % 10);
- return (a + b);
- }
- else{
- fprintf(stderr, "Number greater than 99 passed to toBCD()");
- }
-}
-
-int fromBCD(int x){
- int a = ((x >> 4) * 10);
- int b = (x & 0xF);
- return (a + b);
-}
-
-int main (){
- int i = 39;
- printf("1. %d\n2. %d\n3. %d\n", i, toBCD(i), fromBCD(toBCD(i)));
- return 0;
-} \ No newline at end of file