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

152 lines
3.1 KiB
C++

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