diff options
-rw-r--r-- | addressing.h | 51 | ||||
-rw-r--r-- | applesystem.h | 107 | ||||
-rw-r--r-- | include.h | 4 | ||||
-rw-r--r-- | instruction.h | 405 | ||||
-rw-r--r-- | main.c | 12 | ||||
-rw-r--r-- | test.c | 25 |
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 @@ -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 @@ -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 |