summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--applesystem.h4
-rw-r--r--debug.c22
-rw-r--r--instruction.h465
3 files changed, 134 insertions, 357 deletions
diff --git a/applesystem.h b/applesystem.h
index 9b3dd1c..bf94a72 100644
--- a/applesystem.h
+++ b/applesystem.h
@@ -1,7 +1,7 @@
typedef unsigned char byte;
typedef unsigned short address;
-byte acc, X, Y, P = 0x00;
-unsigned short S = 0x0000;
+byte acc, X, Y, P = 0x00;
+address S = 0x0000;
byte Memory[4096]; // TO DO. Add expansion capability to memory.
/*
diff --git a/debug.c b/debug.c
index ec6a75a..4e0b270 100644
--- a/debug.c
+++ b/debug.c
@@ -4,7 +4,7 @@
* 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.
This will be fixed later when the whole system is functional.
- *
+ * There are a few special keywords which have particular debugging meaning
*/
#include"include.h"
@@ -17,12 +17,30 @@ 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;
unsigned char a, b;
while(true){
// Pass 1
- c = getchar(); if (c == EOF) break;
+ c = getchar();
+ if (c == EOF) break;
+ switch(c){
+ case D: case d:
+ debug_print();
+ break;
+ case M: case m:
+ int m = 0;
+ for(int i = 1; i <= 1000; i *= 10){
+ m += charToNum(getchar(), 1000/i);
+ }
+ printf("Address %d has %x", m, Memory[m]);
+ break;
+
+ }
a += charToNum(c, 0x10);
// Pass 2
c = getchar(); if (c == EOF) break;
diff --git a/instruction.h b/instruction.h
index a5cc2b9..f9ecd0b 100644
--- a/instruction.h
+++ b/instruction.h
@@ -1,35 +1,54 @@
//void fXXX(ADDRESSING addr, int val)
+// Considering making instruction functions return an int of
+// how many cycles passed
+
+struct instruction_data {
+ int length;
+ int cycles;
+};
+
+int getLength(Addressing addr){
+ switch(addr){
+ case eZeroPage: case eZeroPageIndexedX: case eZeroPageIndexedY:
+ return 3;
+ default:
+ return 2;
+ }
+}
+
// Load and Store Instructions
-void fLDA(Addressing addr, int val){
+instruction_data fLDA(Addressing addr, address val){
acc = fAddressing(addr, val);
+ instruction_data d; d.length = getLength(addr);
+
}
-void fLDX(Addressing addr, int val){
+instruction_data fLDX(Addressing addr, address val){
X = fAddressing(addr, val);
}
-void fLDY(Addressing addr, int val){
+instruction_data fLDY(Addressing addr, address val){
Y = fAddressing(addr, val);
}
-void fSTA(Addressing addr, int val){
+instruction_data fSTA(Addressing addr, address val){
Memory[(fAddressing(addr, val))] = acc;
}
-void fSTX(Addressing addr, int val){
+instruction_data fSTX(Addressing addr, address val){
Memory[(fAddressing(addr, val))] = X;
}
-void fSTY(Addressing addr, int val){
+instruction_data fSTY(Addressing addr, address val){
Memory[(fAddressing(addr, val))] = Y;
}
// Arithmetic Instructions
-void fADC(Addressing addr, int val){
+instruction_data fADC(Addressing addr, address val){
int buffer = acc + fAddressing(addr, val);
setFlagV(buffer, acc);
@@ -44,7 +63,7 @@ void fADC(Addressing addr, int val){
setFlagZ(acc);
}
-void fSBC(Addressing addr, int val){
+instruction_data fSBC(Addressing addr, address val){
int buffer = acc - fAddressing(addr, val);
setFlagV(buffer, acc);
@@ -60,37 +79,37 @@ void fSBC(Addressing addr, int val){
//Increment and Decrement Instructions
-void fINC(Addressing addr, int val){
+instruction_data fINC(Addressing addr, address val){
Memory[x]++;
setFlagD(Memory[x]);
setFlagZ(Memory[x]);
}
-void fINX(){
+instruction_data fINX(){
X++;
setFlagD(X);
setFlagZ(X);
}
-void fINY(){
+instruction_data fINY(){
Y++;
setFlagD(Y);
setFlagZ(Y);
}
-void fDEC(Addressing addr, int val){
+instruction_data fDEC(Addressing addr, address val){
Memory[x]--;
setFlagD(Memory[x]);
setFlagZ(Memory[x]);
}
-void fDEX(){
+instruction_data fDEX(){
X--;
setFlagD(X);
setFlagZ(X);
}
-void fDEY(){
+instruction_data fDEY(){
Y--;
setFlagD(Y);
setFlagZ(Y);
@@ -98,19 +117,19 @@ void fDEY(){
// Logical Instructions
-void fAND(Addressing addr, int val){
+instruction_data fAND(Addressing addr, address val){
acc = acc & fAddressing(addr, val);
setFlagN();
setFlagZ(acc);
}
-void fORA(Addressing addr, int val){
+instruction_data fORA(Addressing addr, address val){
acc = acc | fAddressing(addr, val);
setFlagN();
setFlagZ(acc);
}
-void fEOR(Addressing addr, int val){
+instruction_data fEOR(Addressing addr, address val){
acc = acc ^ fAddressing(addr, val);
setFlagN(acc);
setFlagZ(acc);
@@ -118,43 +137,43 @@ void fEOR(Addressing addr, int val){
// Jump, Branch, Compare, and Test Bits
-void fJMP(int val){
+instruction_data fJMP(address val){
S = val;
}
-void fBCC(signed char val){
+instruction_data fBCC(signed char val){
if (getFlag(flag_C) == 0) S += val;
}
-void fBCS(signed char val){
+instruction_data fBCS(signed char val){
if (getFlag(flag_C) == 1) S += val;
}
-void fBEQ(signed char val){
+instruction_data fBEQ(signed char val){
if (getFlag(flag_Z) == 1) S += val;
}
-void fBNE(signed char val){
+instruction_data fBNE(signed char val){
if (getFlag(flag_Z) == 0) S += val;
}
-void fBMI(signed char val){
+instruction_data fBMI(signed char val){
if (getFlag(flag_N) == 1) S += val;
}
-void fBPL(signed char val){
+instruction_data fBPL(signed char val){
if (getFlag(flag_N) == 0) S += val;
}
-void fBVS(signed char val){
+instruction_data fBVS(signed char val){
if (getFlag(flag_V) == 1) S += val;
}
-void fBVC(signed char val){
+instruction_data fBVC(signed char val){
if (getFlag(flag_V) == 0) S += val;
}
-void fCMP(address val){
+instruction_data fCMP(address val){
if (acc < Memory[val]){
setFlag(flag_N, 1); setFlag(flag_Z, 0); setFlag(flag_C, 0);
}if (acc == Memory[val]){
@@ -164,7 +183,7 @@ void fCMP(address val){
}
}
-void fCPX(address val){
+instruction_data fCPX(address val){
if (X < Memory[val]){
setFlag(flag_N, 1); setFlag(flag_Z, 0); setFlag(flag_C, 0);
}if (X == Memory[val]){
@@ -174,7 +193,7 @@ void fCPX(address val){
}
}
-void fCPY(address val){
+instruction_data fCPY(address val){
if (Y < Memory[val]){
setFlag(flag_N, 1); setFlag(flag_Z, 0); setFlag(flag_C, 0);
}if (Y == Memory[val]){
@@ -184,7 +203,7 @@ void fCPY(address val){
}
}
-void fBIT(address val){
+instruction_data fBIT(address 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) {
@@ -196,396 +215,136 @@ void fBIT(address val){
// Shift and Rotate Instructions
-/* ASL - Accumulator Shift Left
- LSR - Logical Shift Right
- ROL - ROtate Left
- ROR - ROtate Right
-
- Z is set if the result it zero. N is set if bit 7 is 1. It is
- always reset on LSR. Remember that ASL A is equal to multiplying by
- two and that LSR is equal to dividing by two.*/
-
-
-void fASL(Addressing addr, int val){
+instruction_data fASL(Addressing addr, address val){
setFlag(flag_C, (val & 0x80));
acc = (val << 1);
setFlagN(acc);
setFlagZ(acc);
}
-/* Use these instructions to move things around in the accumulator or
- memory. The net effects are (where C is the carry flag):
-
-
- +-+-+-+-+-+-+-+-+
- C <- |7|6|5|4|3|2|1|0| <- 0 ASL
- +-+-+-+-+-+-+-+-+
-
- +-+-+-+-+-+-+-+-+
- 0 -> |7|6|5|4|3|2|1|0| -> C LSR
- +-+-+-+-+-+-+-+-+
-
- +-+-+-+-+-+-+-+-+
- C <- |7|6|5|4|3|2|1|0| <- C ROL
- +-+-+-+-+-+-+-+-+
+instruction_data fASL(Addressing addr, address val){
+ setFlag(flag_C, (val & 0x01));
+ acc = (val >> 1);
+ setFlagN(acc);
+ setFlagZ(acc);
+}
- +-+-+-+-+-+-+-+-+
- C -> |7|6|5|4|3|2|1|0| -> C ROR
- +-+-+-+-+-+-+-+-+
-*/
+instruction_data fROL(Addressing addr, address val){
+ setFlag(flag_C, (val & 0x80));
+ acc = (val << 1);
+ acc |= (getFlag(flag_C) * 0x01);
+ setFlagN(acc);
+ setFlagZ(acc);
+}
+instruction_data fROR(Addressing addr, address val){
+ setFlag(flag_C, (val & 0x01));
+ acc = (val >> 1);
+ acc |= (getFlag(flag_C) * 0x80);
+ setFlagN(acc);
+ setFlagZ(acc);
+}
// Transfer Instructions
-void fTAX(){
+instruction_data fTAX(){
X = acc;
setFlagN(X);
setFlagZ(X);
}
-void fTAY(){
+instruction_data fTAY(){
Y = acc;
setFlagN(Y);
setFlagZ(Y);
}
-void fTXA(){
+instruction_data fTXA(){
acc = X;
setFlagN(acc);
setFlagZ(acc);
}
-void fTYA(){
+instruction_data fTYA(){
acc = Y;
setFlagN(acc);
setFlagZ(acc);
}
-
// Stack Instructions
+instruction_data fTSX(){
+ X = S;
+}
+
+instruction_data fTXS(){
+ S = X;
+}
+
+instruction_data fPHA(){
+
+}
+
+instruction_data fPHP(){
+
+}
+
+instruction_data fPLA(){
+
+}
+
+instruction_data fPLP(){
+
+}
+
// Subroutine Instructions
+
+
// Set/Reset Insutrctions
-void fCLC(){
+instruction_data fCLC(){
setFlag(flag_C, 0);
}
-void fCLD(){
+instruction_data fCLD(){
setFlag(flag_D, 0);
}
-void fCLI(){
+instruction_data fCLI(){
setFlag(flag_I, 0);
}
-void fCLV(){
+instruction_data fCLV(){
setFlag(flag_V, 0);
}
-void fSEC(){
+instruction_data fSEC(){
setFlag(flag_C, 1);
}
-void fSED(){
+instruction_data fSED(){
setFlag(flag_D, 1);
}
-void fSEI(){
+instruction_data fSEI(){
setFlag(flag_I, 1);
}
// NOP/BRK Instructions
+instruction_data fNOP(){
+ return {2, 1};
+}
-
-/* Disabled for the purpose of testing functions.
-this will become relevant towards the end of project.
-
-
-// Instruction Meta
-// Alternative would be to make all functions pointer functions, and then look them up
-//according to the code in such a way. It may be more readable that way.
+/*
void runInstruction(int code, int val){
switch(code){
- // 0x0.
- case 0x0
- case 0x0
- case 0x0
- case 0x0
- case 0x0
- case 0x0
- case 0x0
- case 0x0
- case 0x0
- case 0x0
- case 0x0
- case 0x0
- case 0x0
- case 0x0
- case 0x0
- case 0x0
- // 0x1.
- case 0x10
- case 0x11
- case 0x12
- case 0x13
- case 0x14
- case 0x15
- case 0x16
- case 0x17
- case 0x18: fCLC();
- case 0x1
- case 0x1
- case 0x1
- case 0x1
- case 0x1
- case 0x1
- case 0x1
- // 0x2.
- case 0x2
- case 0x2
- case 0x2
- case 0x2
- case 0x2
- case 0x2
- case 0x2
- case 0x2
- case 0x2
- case 0x2
- case 0x2
- case 0x2
- case 0x2
- case 0x2
- case 0x2
- case 0x2
- // 0x3.
- case 0x30
- case 0x31
- case 0x32
- case 0x33
- case 0x34
- case 0x35
- case 0x36
- case 0x37
- case 0x38: fSEC();
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- // 0x4.
- case 0x40:
- case 0x41:
- case 0x42:
- case 0x43:
- case 0x44:
- case 0x45:
- case 0x46:
- case 0x47:
- case 0x48:
- case 0x49:
- case 0x4A:
- case 0x4B:
- case 0x4C:
- case 0x4D:
- case 0x4E:
- case 0x4F:
- // 0x5.
- case 0x50:
- case 0x51:
- case 0x52:
- case 0x53:
- case 0x54:
- case 0x55:
- case 0x56:
- case 0x57:
- case 0x58: fCLI();
- case 0x59:
- case 0x5A:
- case 0x5B:
- case 0x5C:
- case 0x5D:
- case 0x5E:
- case 0x5F:
- // 0x6.
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- // 0x7.
- case 0x70
- case 0x71
- case 0x72
- case 0x73
- case 0x74
- case 0x75
- case 0x76
- case 0x77
- case 0x78: fSEI();
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- // 0x8.
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- // 0x9.
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- // 0xA.
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- // 0xB.
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0xB8: fCLV();
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- // 0xC.
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- // 0xD.
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0xD8: fCLD();
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- // 0xE.
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- // 0xF.
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0xF8: fSED();
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- case 0x
- default: //Error
+
}
}