Files
Bear/cpu.cpp
2026-03-03 23:50:39 -06:00

130 lines
2.4 KiB
C++

#include "cpu.h"
CPU::CPU(IMemoryAccessor* memory) : a(0), x(0), y(0), pc(0), sp(0), stat(0), cycles(0)
{
_memory = memory;
}
void CPU::start()
{
a = 0;
x = 0;
y = 0;
sp = 0xFF;
pc = 0xFFFC;
}
void CPU::reset()
{
pc = 0xFFFC;
sp -= 3;
}
void CPU::loop()
{
bool stop = false;
while (!stop)
{
const std::uint8_t op = _memory->read8(pc++);
switch (static_cast<int>(op))
{
case 0x69:
case 0x65:
case 0x75:
case 0x6D:
adc(op);
break;
default:
stop = true;
break;
}
}
}
std::uint8_t CPU::readImm() const
{
return _memory->read8(pc);
}
std::uint8_t CPU::readZp() const
{
const std::uint8_t zpOffset = _memory->read8(pc);
return _memory->read8(0x0000 + zpOffset);
}
std::uint8_t CPU::readZpX() const
{
const std::uint8_t zpOffset = _memory->read8(pc);
const uint16_t eff = 0x0000 + zpOffset + x & 0x00FF;
return _memory->read8(eff);
}
std::uint8_t CPU::readAbs()
{
const std::uint8_t low = _memory->read8(pc++);
const std::uint8_t high = _memory->read8(pc);
const uint16_t eff = static_cast<uint16_t>(high) << 8 | low;
return _memory->read8(eff);
}
std::uint8_t CPU::readAbsX()
{
const std::uint8_t low = _memory->read8(pc++);
const std::uint8_t high = _memory->read8(pc);
const uint16_t eff = (static_cast<uint16_t>(high) << 8 | low) + x;
return _memory->read8(eff);
}
std::uint8_t CPU::readAbsY()
{
const std::uint8_t low = _memory->read8(pc++);
const std::uint8_t high = _memory->read8(pc);
const uint16_t eff = (static_cast<uint16_t>(high) << 8 | low) + y;
return _memory->read8(eff);
}
std::uint8_t CPU::readIdxInd()
{
}
std::uint8_t CPU::readIndIdx()
{
}
void CPU::adc(std::uint8_t opcode)
{
uint8_t val;
switch (static_cast<int>(opcode))
{
case 0x69:
val = readImm();
break;
case 0x65:
val = readZp();
break;
case 0x75:
val = readZpX();
break;
case 0x6D:
val = readAbs();
break;
default:
stop = true;
return;
}
const uint16_t result = a + val + static_cast<std::uint8_t>(c());
a = result & 0xFF;
setFlagsFromResult(result);
}
void CPU::setFlagsFromResult(std::uint16_t result)
{
if (result > 0xFF) // unsigned overflow
{
c(true);
}
}