152 lines
3.1 KiB
C++
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);
|
|
}
|