summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralekseiplusplus <alekseijeaves@protonmail.com>2023-03-23 16:43:07 +1100
committeralekseiplusplus <alekseijeaves@protonmail.com>2023-03-23 16:43:07 +1100
commitdae1ec0de59f31b533c225a74019ac77a59c92a1 (patch)
treec331c6620373678ad8fc3452d2d44b1c1a21c05a
first commit I think
-rw-r--r--addressing.h51
-rw-r--r--applesystem.h107
-rw-r--r--include.h4
-rw-r--r--instruction.h405
-rw-r--r--main.c12
-rw-r--r--test.c25
6 files changed, 604 insertions, 0 deletions
diff --git a/addressing.h b/addressing.h
new file mode 100644
index 0000000..ccde083
--- /dev/null
+++ b/addressing.h
@@ -0,0 +1,51 @@
+#define FALSE 0
+#define TRUE 1
+
+enum Addressing {
+ eImmediate,
+ eAbsolute,
+ eZeroPage,
+ eImplied,
+ eIndirectAbsolute,
+ eAbsoluteIndexedX,
+ eAbsoluteIndexedY,
+ eZeroPageIndexedX,
+ eZeroPageIndexedY,
+ eIndexedIndirect,
+ eIndirectIndexed,
+ eRelative,
+ eAccumulator
+};
+
+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.
+ */
+
+
+int fAddressing(Addressing addr, short x) {
+ switch(addr){
+ case eImmediate: return x;
+ case eAccumulator: return acc;
+
+ case eAbsolute: return Memory[x];
+ case eAbsoluteIndexedX: return Memory[(x + X)];
+ case eAbsoluteIndexedY: return Memory[(x + Y)];
+
+ case eZeroPage: return Memory[(x & 0x00FF)];
+ case eZeroPageIndexedX: return Memory[((x = X) & 0x00FF)];
+ case eZeroPageIndexedY: return Memory[((x = Y) & 0x00FF)];
+
+ case eIndexedIndirect: return Memory[((x + X) << 8) + ((x + X) + 1)];
+ case eIndirectIndexed: return ((Memory[x] + Memory[(x+1 << 8)]) + Y);
+
+ //case eImplied: No reference
+ //case eIndirectAbsolute: Only used in the JMP instruction
+ //case eRelative: Only used in branch instructions
+ }
+
+}
+
diff --git a/applesystem.h b/applesystem.h
new file mode 100644
index 0000000..a3a33f5
--- /dev/null
+++ b/applesystem.h
@@ -0,0 +1,107 @@
+typedef unsigned char byte;
+byte acc, X, Y, S, P = 0x00;
+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_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 toggleFlag(byte flag) {
+ P = ((P & flag) == flag) ? (P + flag) : (P - flag);
+}
+
+// BCD
+
+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);
+}
+
+
+
+
+
+// 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
+void setFlagN(){
+ if (acc ^ 0x80){
+ setFlag(flag_N, 1);
+ }else{ //not sure if this should be present, I think it is
+ setFlag(flag_N, 0);
+ }
+}
+
+//Perform prior to any changes
+void setFlagV(byte x, byte y){ //This is pathetic.
+ if ((x & flag_N) == (y & flag_N)){
+ if (((x + y) & (flag_N ^ 0xFF)) > 0x8F) setFlag(flag_V, 1);
+ }else{
+ if (((x - y) & (flag_N ^ 0xFF)) > 0x8F) setFlag(flag_V, 1);
+ }
+}
+/*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);
+ }
+}
+void setFlagC(){ // NOTE. Must make setFlagC functional with independence. Look into carrying on 6502
+ setFlag(flag_Z, 1);
+}
+
+
+
+
+
+
+
diff --git a/include.h b/include.h
new file mode 100644
index 0000000..de16188
--- /dev/null
+++ b/include.h
@@ -0,0 +1,4 @@
+#include"stdio.h"
+#include"applesystem.h"
+#include"addressing.h"
+#include"instruction.h" \ No newline at end of file
diff --git a/instruction.h b/instruction.h
new file mode 100644
index 0000000..af48ba0
--- /dev/null
+++ b/instruction.h
@@ -0,0 +1,405 @@
+//void fXXX(ADDRESSING addr, int val)
+
+
+// Load and Store Instructions
+
+void fLDA(Addressing addr, int val){
+ acc = fAddressing(addr, val);
+}
+
+void fLDX(Addressing addr, int val){
+ X = fAddressing(addr, val);
+}
+
+void fLDY(Addressing addr, int val){
+ Y = fAddressing(addr, val);
+}
+
+void fSTA(Addressing addr, int val){
+ Memory[(fAddressing(addr, val))] = acc;
+}
+
+void fSTX(Addressing addr, int val){
+ Memory[(fAddressing(addr, val))] = X;
+}
+
+void fSTY(Addressing addr, int val){
+ Memory[(fAddressing(addr, val))] = Y;
+}
+
+
+
+// Arithmetic Instructions
+
+//Increment and Decrement Instructions
+
+
+
+
+// Logical Instructions
+
+void fAND(Addressing addr, int val){
+ acc = acc & fAddressing(addr, val);
+ setFlagN();
+ setFlagZ(acc);
+}
+
+void fORA(Addressing addr, int val){
+ acc = acc | fAddressing(addr, val);
+ setFlagN();
+ setFlagZ(acc);
+}
+
+void fEOR(Addressing addr, int val){
+ acc = acc ^ fAddressing(addr, val);
+ setFlagN();
+ setFlagZ(acc);
+}
+
+// Jump, Branch, Compare, and Test Bits
+
+
+
+
+
+// Shift and Rotate Instructions
+
+void fASL(Addressing addr, int val){
+ setFlag(flag_C, (val & 0x80));
+ acc = (val << 1);
+ setFlagN();
+ setFlagZ(acc);
+}
+
+
+// Transfer Instructions
+
+// Stack Instructions
+
+// Subroutine Instructions
+
+// Set/Reset Insutrctions
+
+void fCLC(){
+ setFlag(flag_C, 0);
+}
+
+void fCLD(){
+ setFlag(flag_D, 0);
+}
+
+void fCLI(){
+ setFlag(flag_I, 0);
+}
+
+void fCLV(){
+ setFlag(flag_V, 0);
+}
+
+void fSEC(){
+ setFlag(flag_C, 1);
+}
+
+void fSED(){
+ setFlag(flag_D, 1);
+}
+
+void fSEI(){
+ setFlag(flag_I, 1);
+}
+
+// NOP/BRK Instructions
+
+
+
+
+
+
+
+/* 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
+ }
+
+}
+
+*/ \ No newline at end of file
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..1d212c5
--- /dev/null
+++ b/main.c
@@ -0,0 +1,12 @@
+#include"include.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
new file mode 100644
index 0000000..e1898c3
--- /dev/null
+++ b/test.c
@@ -0,0 +1,25 @@
+// 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