1#include "../../../include/ProcessingUnit.hpp"
2#include "../../../include/mmu.hpp"
3#include "../../../include/opcode_table.hpp"
5ProcessingUnit::ProcessingUnit(){
9void ProcessingUnit::reset(){
10 A = 0x01; F = 0xB0; B = 0x00; C = 0x13; D = 0x00; E = 0xD8; H = 0x01; L = 0x4D;
11 SP = 0xFFFE; PC = 0x0100;
12 IME =
false; halt =
false;
15int ProcessingUnit::step(
MMU &mmu) {
16 last_instr_cycles = 0;
17 check_interrupts(mmu);
18 if (last_instr_cycles > 0)
return last_instr_cycles;
25 const u8 opcode = mmu.read(PC++);
27 return instructionTable[opcode](*
this, mmu);
34void ProcessingUnit::check_interrupts(
MMU &mmu) {
35 u8 if_reg = mmu.read(0xFF0F);
36 u8 ie_reg = mmu.read(0xFFFF);
37 u8 pending = if_reg & ie_reg & 0x1F;
43 if (!IME || pending == 0)
return;
45 if (pending & 0x01) execute_interrupt(mmu, 0x0040, 0);
46 else if (pending & 0x02) execute_interrupt(mmu, 0x0048, 1);
47 else if (pending & 0x04) execute_interrupt(mmu, 0x0050, 2);
48 else if (pending & 0x08) execute_interrupt(mmu, 0x0058, 3);
49 else if (pending & 0x10) execute_interrupt(mmu, 0x0060, 4);
52void ProcessingUnit::execute_interrupt(
MMU &mmu, u16 address,
int bit) {
54 u8 if_reg = mmu.read(0xFF0F);
55 mmu.write(0xFF0F, if_reg & ~(1 << bit));
57 mmu.write(--SP, (PC >> 8) & 0xFF);
58 mmu.write(--SP, PC & 0xFF);
60 last_instr_cycles = 20;
63void ProcessingUnit::printStatus()
const {}
64u16 ProcessingUnit::get_pc()
const {
return PC; }
65u16 ProcessingUnit::get_sp()
const {
return SP; }
66void ProcessingUnit::setHalt(
bool newValue) { halt = newValue; }
67bool ProcessingUnit::isHalt()
const {
return halt; }
68void ProcessingUnit::setIME(
bool newValue) { IME = newValue; }
69bool ProcessingUnit::getIME()
const {
return IME; }
70u8& ProcessingUnit::reg(Register r) {
72 case Register::B:
return B;
case Register::C:
return C;
73 case Register::D:
return D;
case Register::E:
return E;
74 case Register::H:
return H;
case Register::L:
return L;
75 case Register::A:
return A;
case Register::F:
return F;
77 throw std::runtime_error(
"Invalid register");
79const u8& ProcessingUnit::reg(Register r)
const {
return const_cast<ProcessingUnit*
>(
this)->reg(r); }
80u16 ProcessingUnit::inc_pc() {
return PC++; }