1
0
Fork 0
2019-nes-emulator/Source/CPU/AddressModes.cpp

139 lines
2.9 KiB
C++

#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);
}