// addressing.h // Contains definitions relevant to addressing, as well as fAddress() which returns time, length, value, and address for an instruction function call. // Would like to refactor the code into something better, such as switch-case statements for the cycles calculation. #include"addressing.h" //Holds address of current instruction. void* current_instruction; address fAddressGetAddress(Addressing mode, short x) { switch(mode){ case eImplied: case eIndirectAbsolute: case eRelative: case eImmediate: case eAccumulator: return 0x0000; case eAbsolute: return x; case eAbsoluteIndexedX: return x + X; case eAbsoluteIndexedY: return x + Y; case eZeroPage: return x & 0x00FF; case eZeroPageIndexedX: return ((x + X) & 0x00FF); case eZeroPageIndexedY: return ((x + Y) & 0x00FF); case eIndexedIndirect: return ((GetMemory(x+X+1))<<8) + (GetMemory(x+X)); case eIndirectIndexed: return ((GetMemory(x+1))<<8) + (GetMemory(x)) + Y; } } int fAddressGetLength(Addressing mode){ switch(mode){ case eAbsolute: case eAbsoluteIndexedX: case eAbsoluteIndexedY: return 3; case eAccumulator: case eImplied: return 1; default: return 2; } } byte fAddressGetValue(Addressing mode, short x, address addr) { switch(mode){ case eImplied: case eIndirectAbsolute: return 0; case eRelative: // TODO: MARKER FOR 3/12/2023 case eImmediate: return x; case eAccumulator: return acc; default: return GetMemory(addr); } } int fAddressGetCycles(Addressing mode, short x, address addr) { int cycles; //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: if ( current_instruction == &fADC || current_instruction == &fAND || current_instruction == &fBIT || current_instruction == &fCMP || current_instruction == &fCPX || current_instruction == &fCPY || current_instruction == &fEOR || current_instruction == &fLDA || current_instruction == &fLDX || current_instruction == &fLDY || current_instruction == &fORA || current_instruction == &fSBC || current_instruction == &fSTX || current_instruction == &fSTY ){ switch(mode){ case eImmediate: cycles = 2; break; case eZeroPage: cycles = 3; break; case eZeroPageIndexedX: case eAbsolute: case eAbsoluteIndexedX: case eAbsoluteIndexedY: cycles = 4; break; case eIndexedIndirect: cycles = 6; break; case eIndirectIndexed: cycles = 5; break; } } //case &fASL: case &fDEC: case &fINC: case &fLSR: case &fROL: case &fROR: else if( current_instruction == &fASL || current_instruction == &fDEC || current_instruction == &fINC || current_instruction == &fLSR || current_instruction == &fROL || current_instruction == &fROR ){ switch(mode){ case eAccumulator: cycles = 2; break; case eZeroPage: cycles = 5; break; case eZeroPageIndexedX: case eAbsolute: cycles = 6; break; case eAbsoluteIndexedX: cycles = 7; break; } } //case &fSTA: else if (current_instruction == &fSTA){ switch(mode){ case eZeroPage: cycles = 3; break; case eZeroPageIndexedX: case eAbsolute: cycles = 4; break; case eAbsoluteIndexedX: case eAbsoluteIndexedY: cycles = 5; break; case eIndexedIndirect: case eIndirectIndexed: cycles = 6; break; } } //case &fBRK: else if (current_instruction == &fBRK){ cycles = 7; } //case &fRTI: case &fRTS: case &fJSR: else if (current_instruction == &fRTI || current_instruction == &fRTS || current_instruction == &fJSR){ cycles = 6; } //case &fJMP: else if (current_instruction == &fJMP){ cycles = 5; } //case &fPLA: case &fPLP: else if (current_instruction == &fPLA || current_instruction == &fPLP){ cycles = 4; } //case &fPHA: case &fPHP: else if (current_instruction == &fPHA || current_instruction == &fPHP){ cycles = 3; } else { cycles = 2; } // Page Boundary //case &fADC: case &fSBC: case &fLDA: case &fLDX: case &fLDY: case &fEOR: case &fAND: case &fORA: case &fCMP: if ( current_instruction == &fADC || current_instruction == &fSBC || current_instruction == &fLDA || current_instruction == &fLDX || current_instruction == &fLDY || current_instruction == &fEOR || current_instruction == &fAND || current_instruction == &fORA || current_instruction == &fCMP ){ switch(mode){ case eAbsoluteIndexedX: if ((x & 0xFF00) != ((x + X) & 0xFF00)) cycles++; break; case eAbsoluteIndexedY: if ((x & 0xFF00) != ((x + Y) & 0xFF00)) cycles++; break; case eIndirectIndexed: if ((addr & 0xFF00) != (addr - Y & 0xFF00)) cycles++; break; } } return cycles; } AddData fAddress(Addressing mode, short x) { AddData ret; ret.add = fAddressGetAddress (mode, x); ret.value = fAddressGetValue (mode, x, ret.add); ret.length = fAddressGetLength (mode); ret.cycles = fAddressGetCycles (mode, x, ret.add); return ret; }