summaryrefslogtreecommitdiff
path: root/addressing.h
diff options
context:
space:
mode:
Diffstat (limited to 'addressing.h')
-rw-r--r--addressing.h121
1 files changed, 95 insertions, 26 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;
+ }
+ }
}