#include "CPU.hpp" void CPU::Implicit() { pc += 1; // Do nothing fetchedByte = acc; } void CPU::Immediate() { pc += 2; fetchedAddress = pc - 1; fetchedByte = ReadMemory(fetchedAddress); } void CPU::ZeroPage() { pc += 2; fetchedAddress = ReadMemory(pc - 1); fetchedByte = ReadMemory(fetchedAddress); } void CPU::ZeroPageX() { pc += 2; uint8_t operand = ReadMemory(pc - 1); fetchedAddress = (operand + x) & 0xFFu; fetchedByte = ReadMemory(fetchedAddress); } void CPU::ZeroPageY() { pc += 2; uint8_t operand = ReadMemory(pc - 1); fetchedAddress = (operand + y) & 0xFFu; fetchedByte = ReadMemory(fetchedAddress); } void CPU::Absolute() { pc += 3; uint8_t addressLsb = ReadMemory(pc - 2); uint8_t addressMsb = ReadMemory(pc - 1); fetchedAddress = ComposeAddress(addressMsb, addressLsb); fetchedByte = ReadMemory(fetchedAddress); } void CPU::AbsoluteX() { pc += 3; uint8_t addressLsb = ReadMemory(pc - 2); uint8_t addressMsb = ReadMemory(pc - 1); uint16_t preAddress = ComposeAddress(addressMsb, addressLsb); fetchedAddress = preAddress + x; fetchedByte = ReadMemory(fetchedAddress); pageBoundaryCrossed = IsPageBoundaryCrossed(preAddress, fetchedAddress); } void CPU::AbsoluteY() { pc += 3; uint8_t addressLsb = ReadMemory(pc - 2); uint8_t addressMsb = ReadMemory(pc - 1); uint16_t preAddress = ComposeAddress(addressMsb, addressLsb); fetchedAddress = preAddress + y; fetchedByte = ReadMemory(fetchedAddress); pageBoundaryCrossed = IsPageBoundaryCrossed(preAddress, fetchedAddress); } void CPU::Indirect() { pc += 3; uint8_t indirectLsb = ReadMemory(pc - 2); uint8_t indirectMsb = ReadMemory(pc - 1); // NOTE: 6502 BUG - indirect address wraps // $02FF + 1 = $0200 uint16_t addressIndirect = ComposeAddress(indirectMsb, indirectLsb); uint8_t addressLsb = ReadMemory(addressIndirect); // Increment LSB to read second byte - it will wrap ++indirectLsb; addressIndirect = ComposeAddress(indirectMsb, indirectLsb); uint8_t addressMsb = ReadMemory(addressIndirect); fetchedAddress = ComposeAddress(addressMsb, addressLsb); fetchedByte = ReadMemory(fetchedAddress); } void CPU::IndirectX() { pc += 2; uint8_t addressIndirect = ReadMemory(pc - 1) + x; // Modulo to keep within zero-page uint16_t addressLsb = ReadMemory((addressIndirect % 0x100)); uint16_t addressMsb = ReadMemory((addressIndirect + 1) % 0x100); fetchedAddress = ComposeAddress(addressMsb, addressLsb); fetchedByte = ReadMemory(fetchedAddress); } void CPU::IndirectY() { pc += 2; uint8_t addressIndirect = ReadMemory(pc - 1); // Modulo to keep within zero-page uint8_t addressLsb = ReadMemory(addressIndirect % 0x100); uint8_t addressMsb = ReadMemory((addressIndirect + 1) % 0x100); uint16_t preAddress = ComposeAddress(addressMsb, addressLsb); fetchedAddress = preAddress + y; fetchedByte = ReadMemory(fetchedAddress); pageBoundaryCrossed = IsPageBoundaryCrossed(preAddress, fetchedAddress); } void CPU::Relative() { pc += 2; int8_t operand = ReadMemory(pc - 1); uint16_t oldPc = pc; fetchedAddress = pc + operand; fetchedByte = ReadMemory(fetchedAddress); pageBoundaryCrossed = IsPageBoundaryCrossed(oldPc, fetchedAddress); }