From 32837712fedf4557ff44df7d5b8ddbd40c5f7990 Mon Sep 17 00:00:00 2001 From: kotorifan Date: Fri, 23 Jan 2026 15:15:48 +0100 Subject: Stupid problems with the old git repo. New one, unfortunately. --- src/Processor.cpp | 243 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 src/Processor.cpp (limited to 'src/Processor.cpp') diff --git a/src/Processor.cpp b/src/Processor.cpp new file mode 100644 index 0000000..38cf9ba --- /dev/null +++ b/src/Processor.cpp @@ -0,0 +1,243 @@ +/** @file Processor.cpp */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Processor.hpp" +#include "Memory.hpp" +#include "Common.hpp" + +/** * @name Register shorthands + * These macros are there so I don't have to write out + * the whole union's name every time I want to access + * a register. + * @{ + */ +#define R_A sm83.af.byte.higher +#define R_F sm83.af.byte.lower +#define R_AF sm83.af.word +#define R_H sm83.hl.byte.higher +#define R_L sm83.hl.byte.lower +#define R_HL sm83.hl.word +#define R_D sm83.de.byte.higher +#define R_E sm83.de.byte.lower +#define R_DE sm83.de.word +#define R_B sm83.bc.byte.higher +#define R_C sm83.bc.byte.lower +#define R_BC sm83.bc.word +#define R_PC sm83.pc +#define R_SP sm83.sp +/** @} */ + +/** * @name Flag shorthands + * Same as with the register shorthands, just + * convenience. + * @{ + */ +#define F_CARRY 4 +#define F_HALF_CARRY 5 +#define F_SUBSTRACTION 6 +#define F_ZERO 7 +/** @} */ + +#define ADD_CYC(val) add_cycles(cycles, val) + +namespace DMG01 +{ + + inline void SM83::add_cycles(Cycles& cycles, const uint32_t count) + { + cycles.total_cycles += count; + } + + inline void SM83::set_flag(uint8_t& f, const uint8_t index, const bool on) + { + std::bitset<8>(f).set(index, on); + } + + inline bool SM83::test_flag(uint8_t& f, const uint8_t index) + { + return std::bitset<8>(f).test(index); + } + + /* + @brief Loads the ROM/executable into the emulator + */ + void SM83::load_bin(const std::string& filename, Memory& memory) + { + std::ifstream f((filename), std::ios_base::binary); + if(!f) throw std::runtime_error("Failed to open the file"); + f.seekg(0, std::ios_base::end); + auto f_size = f.tellg(); + f.seekg(0, std::ios_base::beg); + f.read(reinterpret_cast(memory.space.get()), f_size); + } + + template + inline void SM83::ld_imm(T1& reg, const T2& data) + { + reg = static_cast(data); + } + + template + inline void SM83::ld_reg(T1& reg1, const T2& reg2) + { + reg1 = reg2; + } + + template + inline void SM83::inc_reg(T& val) + { + val++; + } + + template + inline void SM83::dec_reg(T& val) + { + val--; + } + + inline void SM83::rlca(SM83& sm83) + { + R_A = (R_A >> 1 | R_A << 7); + if(sm83.test_flag(R_F, F_CARRY)) + sm83.set_flag(R_F, F_CARRY, true); + else if(sm83.test_flag(R_F, F_CARRY)) + sm83.set_flag(R_F, F_CARRY, false); + } + + template + inline void SM83::add_reg(T1& aug, const T2& add) + { + aug =+ add; + } + + inline void SM83::rrca(SM83& sm83) + { + R_A = (R_A << 1 | R_A >> 7); + if(sm83.test_flag(R_F, F_CARRY)) + sm83.set_flag(R_F, F_CARRY, true); + else if(sm83.test_flag(R_F, F_CARRY)) + sm83.set_flag(R_F, F_CARRY, false); + } + + inline void SM83::stop(SM83& sm83, Memory& memory) + { + R_PC++; + memory.space[0xff04] = 0x00; + sm83.stop_state = true; + } + /* + @brief Processes opcodes and calls the according function + @param opcode The opcode it should process + */ + void SM83::process_opcodes(const uint8_t opcode, Memory& memory, SM83& sm83) + { + switch(opcode) + { + case 0x00: /* NOP */ + ADD_CYC(4); + break; + case 0x01: /* LD BC, n16 */ + ld_imm(R_BC, memory.space[R_PC++]); + ADD_CYC(12); + break; + case 0x02: /* LD (BC), A */ + ld_reg(memory.space[R_BC], R_A); + ADD_CYC(8); + break; + case 0x03: /* INC BC */ + inc_reg(R_BC); + ADD_CYC(8); + break; + case 0x04: /* INC B */ + inc_reg(R_B); + ADD_CYC(4); + break; + case 0x05: /* DEC B */ + dec_reg(R_B); + ADD_CYC(4); + break; + case 0x06: /* LD B, d6 */ + ld_imm(R_B, memory.space[R_PC++]); + ADD_CYC(8); + break; + case 0x07: /* RLCA */ + rlca(sm83); + ADD_CYC(4); + break; + case 0x08: /* LD (a16), SP */ + ld_imm(memory.space[R_PC++], R_SP); + ADD_CYC(20); + break; + case 0x09: + add_reg(R_HL, R_BC); + ADD_CYC(8); + break; + case 0x0a: + ld_reg(R_A, memory.space[R_BC]); + ADD_CYC(8); + break; + case 0x0b: + dec_reg(R_BC); + ADD_CYC(8); + break; + case 0x0c: + inc_reg(R_C); + ADD_CYC(4); + break; + case 0x0d: + dec_reg(R_C); + ADD_CYC(4); + break; + case 0x0e: + ld_imm(R_C, memory.space[R_PC++]); + ADD_CYC(8); + break; + case 0x0f: + rrca(sm83); + ADD_CYC(4); + break; + case 0x10: + stop(sm83, memory); + ADD_CYC(4); + break; + case 0x11: + ld_imm(R_DE, memory.space[R_PC++]); + ADD_CYC(12); + break; + case 0x12: + ld_imm(memory.space[R_DE], R_A); + ADD_CYC(8); + break; + case 0x13: + inc_reg(R_DE); + ADD_CYC(8); + break; + case 0x14: + inc_reg(R_D); + ADD_CYC(4); + break; + case 0x15: + dec_reg(R_D); + ADD_CYC(4); + break; + case 0x16: + ld_reg(R_DE, memory.space[R_PC++]); + ADD_CYC(8); + break; + case 0x017: + ADD_CYC + break; + default: + std::cout << "The program has seemingly run into an unrecognized opcode\n"; + break; + } + } +} -- cgit v1.3