diff options
-rw-r--r-- | addressing.h | 78 | ||||
-rw-r--r-- | applesystem.h | 32 | ||||
-rw-r--r-- | assembler.c | 9 | ||||
-rw-r--r-- | debug.h | 16 | ||||
-rw-r--r-- | instruction-init.h | 3 | ||||
-rw-r--r-- | instruction.h | 123 | ||||
-rw-r--r-- | interpreter.c | 6 | ||||
-rw-r--r-- | main.c | 8 | ||||
-rw-r--r-- | test.c | 25 |
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; - +*/ } @@ -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; @@ -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 @@ -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 |