130 lines
2.4 KiB
C++
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);
|
|
}
|
|
}
|