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