diff options
-rw-r--r-- | addressing.h | 121 | ||||
-rw-r--r-- | applesystem.h | 26 | ||||
-rw-r--r-- | assembler.c | 2 | ||||
-rw-r--r-- | include.h | 11 | ||||
-rw-r--r-- | instruction-init | 77 | ||||
-rw-r--r-- | instruction.h | 118 |
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; @@ -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 |