diff options
author | alekseiplusplus <alekseijeaves@protonmail.com> | 2023-04-06 15:35:12 +1000 |
---|---|---|
committer | alekseiplusplus <alekseijeaves@protonmail.com> | 2023-04-06 15:35:12 +1000 |
commit | 7b62c20136b2164d392668d0d74b519e9eeb487b (patch) | |
tree | 01fa3c221d7ea590e32076895b24132860d3c9d3 /addressing.h | |
parent | 98c242def30ae70f327323d65485b41bdbd151b4 (diff) |
shifting towards new structure
Diffstat (limited to 'addressing.h')
-rw-r--r-- | addressing.h | 121 |
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; + } + } } |