Browse Source

Emulator: Add more opcodes, convenience functions

master
Riyyi 2 years ago
parent
commit
687990edca
  1. 74
      src/cpu.cpp
  2. 36
      src/cpu.h

74
src/cpu.cpp

@ -5,7 +5,7 @@
* SPDX-License-Identifier: MIT
*/
#include <cstdint> // uint8_t, uint32_t
#include <cstdint> // int32_t, uint8_t, uint32_t
#include "cpu.h"
#include "emu.h"
@ -25,7 +25,7 @@ CPU::CPU(uint32_t frequency)
, m_l(0x0d)
// , m_pc(0x100)
, m_pc(0x0)
, m_sp(0xffe)
, m_sp(0xfffe)
// Flags
, m_zf(0x1)
, m_nf(0x0)
@ -48,22 +48,24 @@ CPU::CPU(uint32_t frequency)
// Add opcode functions to lookup table
m_opcode_lookup_table.emplace(0xc6, std::bind(&CPU::add, this));
m_opcode_lookup_table.emplace(0x08, std::bind(&CPU::ldStack, this));
m_opcode_lookup_table.emplace(0x31, std::bind(&CPU::ldStack, this));
m_opcode_lookup_table.emplace(0xf8, std::bind(&CPU::ldStack, this));
m_opcode_lookup_table.emplace(0xf9, std::bind(&CPU::ldStack, this));
m_opcode_lookup_table.emplace(0x01, std::bind(&CPU::ld16, this));
m_opcode_lookup_table.emplace(0x11, std::bind(&CPU::ld16, this));
m_opcode_lookup_table.emplace(0x21, std::bind(&CPU::ld16, this));
m_opcode_lookup_table.emplace(0x31, std::bind(&CPU::ld16, this));
}
CPU::~CPU()
{
}
// -----------------------------------------
void CPU::update()
{
m_wait_cycles--;
if (m_wait_cycles <= 0) {
// Read next opcode
uint8_t opcode = Emu::the().bootrom()[m_pc];
uint8_t opcode = peekBootrom();
m_opcode_lookup_table[opcode]();
}
@ -72,8 +74,8 @@ void CPU::update()
void CPU::add()
{
uint8_t opcode = Emu::the().bootrom()[m_pc];
uint8_t immediate = Emu::the().bootrom()[m_pc + 1];
uint8_t opcode = consumeBootrom();
uint8_t immediate = consumeBootrom();
switch (opcode) {
case 0xc6: // ADD A,d8
// Program counter +2
@ -99,21 +101,59 @@ void CPU::add()
}
}
void CPU::ldStack()
void CPU::ld16()
{
print("Calling stack LD\n");
uint8_t opcode = Emu::the().bootrom()[m_pc];
uint8_t opcode = consumeBootrom();
switch (opcode) {
case 0x08:
case 0x01: {
m_wait_cycles += 12;
setBc(immediate16());
break;
case 0x31:
}
case 0x11:
m_wait_cycles += 12;
setDe(immediate16());
break;
case 0xf8:
case 0x21:
m_wait_cycles += 12;
setHl(immediate16());
break;
case 0xf9:
case 0x31: {
m_wait_cycles += 12;
m_sp = immediate16();
break;
}
default:
VERIFY_NOT_REACHED();
}
}
// -----------------------------------------
uint8_t CPU::peekBootrom(int32_t offset) const
{
return Emu::the().bootrom()[m_pc + offset];
}
uint8_t CPU::consumeBootrom()
{
return Emu::the().bootrom()[m_pc++];
}
void CPU::setBc(uint32_t value)
{
m_b = value >> 8;
m_c = value;
}
void CPU::setDe(uint32_t value)
{
m_d = value >> 8;
m_e = value;
}
void CPU::setHl(uint32_t value)
{
m_h = value >> 8;
m_l = value;
}

36
src/cpu.h

@ -7,8 +7,8 @@
#pragma once
#include <cstdint> // int8_t, uint8_t, uint32_t
#include <functional> // function
#include <cstdint> // int8_t, int32_t, uint8_t, uint32_t
#include <functional> // std::function
#include <unordered_map>
#include "processing-unit.h"
@ -20,27 +20,51 @@ public:
void update() override;
// 8-bit Arithmetic and Logic Instructions
// -------------------------------------
// Arithmetic and Logic Instructions
// 8-bit
void add();
// 16-bit Arithmetic Instructions
// 16-bit
// -------------------------------------
// Bit Operations Instructions
// -------------------------------------
// Bit Shift Instructions
// -------------------------------------
// Load Instructions
// 8-bit
// 16-bit
void ld16();
// -------------------------------------
// Jumps and Subroutines
// -------------------------------------
// Stack Operations Instructions
void ldStack();
// -------------------------------------
// Miscellaneous Instructions
private:
uint8_t peekBootrom(int32_t offset = 0) const;
uint8_t consumeBootrom();
uint32_t immediate16() { return (consumeBootrom() << 8) | consumeBootrom(); }
void setBc(uint32_t value);
void setDe(uint32_t value);
void setHl(uint32_t value);
uint32_t bc() const { return m_b << 8 | m_c; }
uint32_t de() const { return m_b << 8 | m_c; }
uint32_t hl() const { return m_b << 8 | m_c; }
// Registers
uint32_t m_a { 0 }; // Accumulator
uint32_t m_b { 0 }; // B

Loading…
Cancel
Save