summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addressing.h121
-rw-r--r--applesystem.h26
-rw-r--r--assembler.c2
-rw-r--r--include.h11
-rw-r--r--instruction-init77
-rw-r--r--instruction.h118
6 files changed, 234 insertions, 121 deletions
diff --git a/addressing.h b/addressing.h
index 1a80466..300dac5 100644
--- a/addressing.h
+++ b/addressing.h
@@ -1,6 +1,3 @@
-#define FALSE 0
-#define TRUE 1
-
enum Addressing {
eImmediate,
eAccumulator,
@@ -19,13 +16,8 @@ enum Addressing {
typedef int Addressing;
- /*
- * Any addressing method which is single line commented out without definition
- * implies that handling should be hard-coded in the switch case of the
- * instruction from which it came.
- */
-
-
+//Holds address of current instruction.
+void (*current_instruction)(Addressing, address);
struct AddData{
int cycles;
@@ -35,26 +27,27 @@ struct AddData{
AddData fAddress(Addressing addr, short x) {
AddData ret;
+
+ // VALUE
+
switch(addr){
case eImmediate: ret.value = x; break;
case eAccumulator: ret.value = acc; break;
- case eAbsolute: ret.value = Memory[x]; break;
- case eAbsoluteIndexedX: ret.value = Memory[(x + X)]; break;
- case eAbsoluteIndexedY: ret.value = 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;
- 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;
+ 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;
- case eIndexedIndirect: ret.value = Memory[((x + X) << 8) + ((x + X) + 1)]; break;
- case eIndirectIndexed: ret.value = ((Memory[x] + Memory[(x+1 << 8)]) + Y); break;
-
- //case eImplied: No reference
- //case eIndirectAbsolute: Only used in the JMP instruction
- //case eRelative: Only used in branch instructions
+ 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;
}
+ // LENGTH
+
switch(addr){
case eAbsolute: case eAbsoluteIndexedX: case eAbsoluteIndexedY:
ret.length = 3; break;
@@ -64,10 +57,86 @@ AddData fAddress(Addressing addr, short x) {
ret.length = 2; break;
}
+ // CYCLES
+
+ switch(current_function){ // Initial value
+ 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:
+ 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;
+ }
+ break;
+
+ case &fASL: case &fDEC: case &fINC: case &fLSR: case &fROL: case &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;
+ }
+ break;
+
+ case &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;
+ }
+ break;
+
+ case &fBRK:
+ ret.cycles = 7;
+ break;
+
+ case &RTI: case &RTS: case &JSR:
+ ret.cycles = 6;
+ break;
+
+ case &fJMP:
+ ret.cycles = 5;
+ break;
+
+ case &fPLA: case &fPLP:
+ ret.cycles = 4;
+ break;
+
+ case &fPHA: case &fPHP:
+ 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
+ ret.cycles = 2;
+ }
- // FOR TIME, FIND THE PARTICULAR VALUE SET FOR THE FIRST TYPE,
- // APPLY RELATIVE MOVEMENT
- // THEN LET THE FUNCTION WHICH CALLED fAddress HANDLE A NON-TYPICAL VALUE.
-
+ switch(current_function){ // Page Boundary
+ case &fADC: case &fSBC: case &fLDA: case &fLDX: case &fLDY: case &fEOR: case &fAND: case &fORA: case &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: //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;
+ }
+ }
}
diff --git a/applesystem.h b/applesystem.h
index 469fcb3..f561d36 100644
--- a/applesystem.h
+++ b/applesystem.h
@@ -2,14 +2,7 @@ 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.
-
-/*
-To Do.
- + Find variables better passed as pointers instead
- + Clean up this messy code
-*/
-
+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)
@@ -45,7 +38,7 @@ void flagClear(byte flag){
// BCD
-
+// need to actually look into BCD on the 6502
byte toBCD(byte x){
if (x < 100){
byte a = ((x / 10) << 4);
@@ -63,21 +56,6 @@ byte fromBCD(byte x){
return (a + b);
}
-// addBCD()
-
-
-
-// Class of instructions
-//each one has every type of addressing mode, inherited from a base class.
-// the different addressing modes will be distinguished when the bytecode is called, it will run the instructions function with a selection for the
-/* example
-
-Immediate ADC #$44 $69 2 2
-instruction(0x69); -> ADC({enum for immediate});
-
-Zero Page ADC $44 $65 2 3
-instruction(0x65); -> ADC({enum for Zero Page});
-*/
// Set particular flags
// Functions which quickly set specific flags that are straightforward checks, and are repeated often.
void setFlagN(byte x){
diff --git a/assembler.c b/assembler.c
index 5112dc5..e302218 100644
--- a/assembler.c
+++ b/assembler.c
@@ -29,7 +29,7 @@ int main(int argc; char* argv[]){
// DRAFTING PROG LOGIC
char c = 0;
char in[10];
-while((c != '\n') && (c != '\0')
+while((c != '\n') && (c != EOF)
c = getchar;
if(c == '#') c = '\n';
in[i] = c;
diff --git a/include.h b/include.h
index de16188..e4c3ee2 100644
--- a/include.h
+++ b/include.h
@@ -1,4 +1,13 @@
#include"stdio.h"
#include"applesystem.h"
+#include"instruction-init.h"
#include"addressing.h"
-#include"instruction.h" \ No newline at end of file
+#include"instruction.h"
+
+
+/*
+Programs which may come in handy?
+1. Memory dumping utility
+2. An external menu for managing the system
+*/
+
diff --git a/instruction-init b/instruction-init
new file mode 100644
index 0000000..73c80b9
--- /dev/null
+++ b/instruction-init
@@ -0,0 +1,77 @@
+// Load and Store Instructions
+void fLDA(Addressing addr, address val);
+void fLDX(Addressing addr, address val);
+void fLDY(Addressing addr, address val);
+void fSTA(Addressing addr, address val);
+void fSTX(Addressing addr, address val);
+void fSTY(Addressing addr, address val);
+
+// Arithmetic Instructions
+void fADC(Addressing addr, address val);
+void fSBC(Addressing addr, address val);
+
+//Increment and Decrement Instructions
+void fINC(Addressing addr, address val);
+void fINX(Addressing addr, address val);
+void fINY(Addressing addr, address val);
+void fDEC(Addressing addr, address val);
+void fDEX(Addressing addr, address val);
+void fDEY(Addressing addr, address val);
+
+// Logical Instructions
+void fAND(Addressing addr, address val)
+void fORA(Addressing addr, address val);
+void fEOR(Addressing addr, address val);
+
+// Jump, Branch, Compare, and Test Bits
+void fJMP(Addressing addr, address val);
+void fBCC(Addressing addr, address val);
+void fBCS(Addressing addr, address val);
+void fBEQ(Addressing addr, address val);
+void fBNE(Addressing addr, address val);
+void fBMI(Addressing addr, address val);
+void fBPL(Addressing addr, address val);
+void fBVS(Addressing addr, address val);
+void fBVC(Addressing addr, address val);
+void fCMP(Addressing addr, address val);
+void fCPX(Addressing addr, address val);
+void fCPY(Addressing addr, address val);
+void fBIT(Addressing addr, address val);
+
+// Shift and Rotate Instructions
+void fASL(Addressing addr, address val);
+void fLSR(Addressing addr, address val);
+void fROL(Addressing addr, address val);
+void fROR(Addressing addr, address val);
+
+// Transfer Instructions
+void fTAX(Addressing addr, address val);
+void fTAY(Addressing addr, address val);
+void fTXA(Addressing addr, address val);
+void fTYA(Addressing addr, address val);
+
+// Stack Instructions
+void fTSX(Addressing addr, address val);
+void fTXS(Addressing addr, address val);
+void fPHA(Addressing addr, address val);
+void fPHP(Addressing addr, address val);
+void fPLA(Addressing addr, address val);
+void fPLP(Addressing addr, address val);
+
+// Subroutine Instructions
+void fJSR(Addressing addr, address val);
+void fRTS(Addressing addr, address val);
+void fRTI(Addressing addr, address val);
+
+// Set/Reset Insutrctions
+void fCLC(Addressing addr, address val);
+void fCLD(Addressing addr, address val);
+void fCLI(Addressing addr, address val);
+void fCLV(Addressing addr, address val);
+void fSEC(Addressing addr, address val);
+void fSED(Addressing addr, address val);
+void fSEI(Addressing addr, address val);
+
+// NOP/BRK Instructions
+void fNOP(Addressing addr, address val);
+void fBRK(Addressing addr, address val);
diff --git a/instruction.h b/instruction.h
index 2c4c3a2..c1b4843 100644
--- a/instruction.h
+++ b/instruction.h
@@ -1,4 +1,3 @@
-
// array/map of pointers which all point
// to the functions which the index corresponds to.
// use that like a sort of map
@@ -36,8 +35,7 @@ void fSTY(Addressing addr, address val){ idata = fAddress(addr, val);
// Arithmetic Instructions
-instruction_data fADC(Addressing addr, address val){
- instruction_data d; d.length = getLength(addr);
+void fADC(Addressing addr, address val){ idata = fAddress(addr, val);
int buffer = acc + fAddress(addr, val);
setFlagV(buffer, acc);
@@ -52,7 +50,7 @@ instruction_data fADC(Addressing addr, address val){
setFlagZ(acc);
}
-instruction_data fSBC(Addressing addr, address val){
+void fSBC(Addressing addr, address val){ idata = fAddress(addr, val);
int buffer = acc - fAddress(addr, val);
setFlagV(buffer, acc);
@@ -68,37 +66,37 @@ instruction_data fSBC(Addressing addr, address val){
//Increment and Decrement Instructions
-instruction_data fINC(Addressing addr, address val){
+void fINC(Addressing addr, address val){ idata = fAddress(addr, val);
Memory[x]++;
setFlagD(Memory[x]);
setFlagZ(Memory[x]);
}
-instruction_data fINX(){
+void fINX(Addressing addr, address val){ idata = fAddress(addr, val);
X++;
setFlagD(X);
setFlagZ(X);
}
-instruction_data fINY(){
+void fINY(Addressing addr, address val){ idata = fAddress(addr, val);
Y++;
setFlagD(Y);
setFlagZ(Y);
}
-instruction_data fDEC(Addressing addr, address val){
+void fDEC(Addressing addr, address val){ idata = fAddress(addr, val);
Memory[x]--;
setFlagD(Memory[x]);
setFlagZ(Memory[x]);
}
-instruction_data fDEX(){
+void fDEX(Addressing addr, address val){ idata = fAddress(addr, val);
X--;
setFlagD(X);
setFlagZ(X);
}
-instruction_data fDEY(){
+void fDEY(Addressing addr, address val){ idata = fAddress(addr, val);
Y--;
setFlagD(Y);
setFlagZ(Y);
@@ -106,19 +104,19 @@ instruction_data fDEY(){
// Logical Instructions
-instruction_data fAND(Addressing addr, address val){
+void fAND(Addressing addr, address val){ idata = fAddress(addr, val);
acc = acc & fAddress(addr, val);
setFlagN();
setFlagZ(acc);
}
-instruction_data fORA(Addressing addr, address val){
+void fORA(Addressing addr, address val){ idata = fAddress(addr, val);
acc = acc | fAddress(addr, val);
setFlagN();
setFlagZ(acc);
}
-instruction_data fEOR(Addressing addr, address val){
+void fEOR(Addressing addr, address val){ idata = fAddress(addr, val);
acc = acc ^ fAddress(addr, val);
setFlagN(acc);
setFlagZ(acc);
@@ -126,43 +124,44 @@ instruction_data fEOR(Addressing addr, address val){
// Jump, Branch, Compare, and Test Bits
-instruction_data fJMP(address val){
+void fJMP(Addressing addr, address val){ idata = fAddress(addr, val);
PC = val;
}
-instruction_data fBCC(signed char val){
+void fBCC(Addressing addr, address val){ idata = fAddress(addr, val);
+ //signed char val down to BVC
if (getFlag(flag_C) == 0) PC += val;
}
-instruction_data fBCS(signed char val){
+void fBCS(Addressing addr, address val){ idata = fAddress(addr, val);
if (getFlag(flag_C) == 1) PC += val;
}
-instruction_data fBEQ(signed char val){
+void fBEQ(Addressing addr, address val){ idata = fAddress(addr, val);
if (getFlag(flag_Z) == 1) PC += val;
}
-instruction_data fBNE(signed char val){
+void fBNE(Addressing addr, address val){ idata = fAddress(addr, val);
if (getFlag(flag_Z) == 0) PC += val;
}
-instruction_data fBMI(signed char val){
+void fBMI(Addressing addr, address val){ idata = fAddress(addr, val);
if (getFlag(flag_N) == 1) PC += val;
}
-instruction_data fBPL(signed char val){
+void fBPL(Addressing addr, address val){ idata = fAddress(addr, val);
if (getFlag(flag_N) == 0) PC += val;
}
-instruction_data fBVS(signed char val){
+void fBVS(Addressing addr, address val){ idata = fAddress(addr, val);
if (getFlag(flag_V) == 1) PC += val;
}
-instruction_data fBVC(signed char val){
+void fBVC(Addressing addr, address val){ idata = fAddress(addr, val);
if (getFlag(flag_V) == 0) PC += val;
}
-instruction_data fCMP(address val){
+void fCMP(Addressing addr, address val){ idata = fAddress(addr, val);
if (acc < Memory[val]){
flagSet(flag_N); flagClear(flag_Z); flagClear(flag_C);
}if (acc == Memory[val]){
@@ -172,7 +171,7 @@ instruction_data fCMP(address val){
}
}
-instruction_data fCPX(address val){
+void fCPX(Addressing addr, address val){ idata = fAddress(addr, val);
if (X < Memory[val]){
flagSet(flag_N); flagClear(flag_Z); flagClear(flag_C);
}if (X == Memory[val]){
@@ -182,7 +181,7 @@ instruction_data fCPX(address val){
}
}
-instruction_data fCPY(address val){
+void fCPY(Addressing addr, address val){ idata = fAddress(addr, val);
if (Y < Memory[val]){
flagSet(flag_N); flagClear(flag_Z); flagClear(flag_C);
}if (Y == Memory[val]){
@@ -192,7 +191,7 @@ instruction_data fCPY(address val){
}
}
-instruction_data fBIT(address val){
+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) {
@@ -204,21 +203,21 @@ instruction_data fBIT(address val){
// Shift and Rotate Instructions
-instruction_data fASL(Addressing addr, address val){
+void fASL(Addressing addr, address val){ idata = fAddress(addr, val);
setFlag(flag_C, (val & 0x80));
acc = (val << 1);
setFlagN(acc);
setFlagZ(acc);
}
-instruction_data fASL(Addressing addr, address val){
+void fASL(Addressing addr, address val){ idata = fAddress(addr, val);
setFlag(flag_C, (val & 0x01));
acc = (val >> 1);
setFlagN(acc);
setFlagZ(acc);
}
-instruction_data fROL(Addressing addr, address val){
+void fROL(Addressing addr, address val){ idata = fAddress(addr, val);
setFlag(flag_C, (val & 0x80));
acc = (val << 1);
acc |= (getFlag(flag_C) * 0x01);
@@ -226,7 +225,7 @@ instruction_data fROL(Addressing addr, address val){
setFlagZ(acc);
}
-instruction_data fROR(Addressing addr, address val){
+void fROR(Addressing addr, address val){ idata = fAddress(addr, val);
setFlag(flag_C, (val & 0x01));
acc = (val >> 1);
acc |= (getFlag(flag_C) * 0x80);
@@ -236,25 +235,25 @@ instruction_data fROR(Addressing addr, address val){
// Transfer Instructions
-instruction_data fTAX(){
+void fTAX(Addressing addr, address val){ idata = fAddress(addr, val);
X = acc;
setFlagN(X);
setFlagZ(X);
}
-instruction_data fTAY(){
+void fTAY(Addressing addr, address val){ idata = fAddress(addr, val);
Y = acc;
setFlagN(Y);
setFlagZ(Y);
}
-instruction_data fTXA(){
+void fTXA(Addressing addr, address val){ idata = fAddress(addr, val);
acc = X;
setFlagN(acc);
setFlagZ(acc);
}
-instruction_data fTYA(){
+void fTYA(Addressing addr, address val){ idata = fAddress(addr, val);
acc = Y;
setFlagN(acc);
setFlagZ(acc);
@@ -262,27 +261,27 @@ instruction_data fTYA(){
// Stack Instructions
-instruction_data fTSX(){
+void fTSX(Addressing addr, address val){ idata = fAddress(addr, val);
X = S;
}
-instruction_data fTXS(){
+void fTXS(Addressing addr, address val){ idata = fAddress(addr, val);
S = X;
}
-instruction_data fPHA(){
+void fPHA(Addressing addr, address val){ idata = fAddress(addr, val);
}
-instruction_data fPHP(){
+void fPHP(Addressing addr, address val){ idata = fAddress(addr, val);
}
-instruction_data fPLA(){
+void fPLA(Addressing addr, address val){ idata = fAddress(addr, val);
}
-instruction_data fPLP(){
+void fPLP(Addressing addr, address val){ idata = fAddress(addr, val);
}
@@ -292,67 +291,48 @@ instruction_data fPLP(){
// Set/Reset Insutrctions
-instruction_data fCLC(){
+void fCLC(Addressing addr, address val){ idata = fAddress(addr, val);
flagClear(flag_C);
return {1, 2};
}
-instruction_data fCLD(){
+void fCLD(Addressing addr, address val){ idata = fAddress(addr, val);
flagClear(flag_D);
return {1, 2};
}
-instruction_data fCLI(){
+void fCLI(Addressing addr, address val){ idata = fAddress(addr, val);
flagClear(flag_I);
return {1, 2};
}
-instruction_data fCLV(){
+void fCLV(Addressing addr, address val){ idata = fAddress(addr, val);
flagClear(flag_V);
return {1, 2};
}
-instruction_data fSEC(){
+void fSEC(Addressing addr, address val){ idata = fAddress(addr, val);
flagSet(flag_C);
return {1, 2};
}
-instruction_data fSED(){
+void fSED(Addressing addr, address val){ idata = fAddress(addr, val);
flagSet(flag_D);
return {1, 2};
}
-instruction_data fSEI(){
+void fSEI(Addressing addr, address val){ idata = fAddress(addr, val);
flagSet(flag_I);
return {1, 2};
}
// NOP/BRK Instructions
-instruction_data fNOP(){
+void fNOP(Addressing addr, address val){ idata = fAddress(addr, val);
return {1, 2};
}
-instruction_data fBRK(){
+void fBRK(Addressing addr, address val){ idata = fAddress(addr, val);
flagSet(flag_B);
return {1, 7};
-}
-
-
-
-
-
-
-
-
-
-
-/*
-void runInstruction(int code, int val){
- switch(code){
-
- }
-
-}
-
-*/ \ No newline at end of file
+} \ No newline at end of file