70 lines
2.0 KiB
C++
70 lines
2.0 KiB
C++
|
|
#include "CPU.h"
|
||
|
|
|
||
|
|
#include <stdexcept>
|
||
|
|
#include <iostream>
|
||
|
|
#include <iomanip>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <array>
|
||
|
|
|
||
|
|
CPU::CPU(std::shared_ptr<Bus> bus) : m_Bus(bus), m_Context({m_Instruction, m_InstructionPointer, m_Flags, m_Registers, m_Bus}){
|
||
|
|
m_InstructionPointer = 0x00008000;
|
||
|
|
|
||
|
|
for(int i = 0; i < 16; i++)
|
||
|
|
{
|
||
|
|
m_Registers[i] = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void CPU::Step(){
|
||
|
|
FetchDecode();
|
||
|
|
Execute();
|
||
|
|
}
|
||
|
|
|
||
|
|
void CPU::FetchDecode(){
|
||
|
|
std::cout << "Fetching instruction: " << std::hex << m_InstructionPointer << std::endl;
|
||
|
|
m_InstructionRaw = m_Bus->AccessX<uint64_t>(m_InstructionPointer); // Slice of 8 bytes.
|
||
|
|
|
||
|
|
std::cout << "Context window fetched: " << std::hex << m_InstructionRaw << std::endl; // Start Decode Instruction
|
||
|
|
uint64_t first_byte = m_InstructionRaw & 0xFF;
|
||
|
|
std::cout << "Decoded first byte: " << std::hex << first_byte << std::endl;
|
||
|
|
Opcode opcode = static_cast<Opcode>(first_byte);
|
||
|
|
|
||
|
|
if(first_byte >= 0xB8 && first_byte <= 0xBF)
|
||
|
|
{
|
||
|
|
m_Instruction.m_Operand1 = first_byte - 0xB8;
|
||
|
|
opcode = Opcode::MOV_R_IMM32;
|
||
|
|
}
|
||
|
|
|
||
|
|
switch(opcode){
|
||
|
|
case Opcode::NOP: m_Instruction.m_Length = 1; break;
|
||
|
|
case Opcode::HLT: m_Instruction.m_Length = 1; break;
|
||
|
|
case Opcode::MOV_R_IMM32:
|
||
|
|
m_Instruction.m_Operand2 = m_Bus->AccessX<uint32_t>(m_InstructionPointer + 1);
|
||
|
|
m_Instruction.m_Length = 5;
|
||
|
|
break;
|
||
|
|
case Opcode::ADD_RM32_R32:
|
||
|
|
m_Instruction.m_Operand1 = m_Bus->AccessX<uint8_t>(m_InstructionPointer + 1);
|
||
|
|
m_Instruction.m_Operand2 = m_Bus->AccessX<uint32_t>(m_InstructionPointer + 2);
|
||
|
|
m_Instruction.m_Length = 6;
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
std::runtime_error("Decode encountered unexpected opcode.");
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
m_Instruction.m_Opcode = opcode;
|
||
|
|
m_InstructionPointer += m_Instruction.m_Length;
|
||
|
|
}
|
||
|
|
|
||
|
|
void CPU::Execute(){
|
||
|
|
std::cout << "Executing... \n";
|
||
|
|
uint8_t opcode_value = static_cast<uint8_t>(m_Instruction.m_Opcode);
|
||
|
|
auto& exec_table = GetExecutorTable();
|
||
|
|
if(exec_table[opcode_value])
|
||
|
|
{
|
||
|
|
exec_table[opcode_value](m_Context);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
throw std::runtime_error("Opcode not found!");
|
||
|
|
}
|