From 4671a62ddfdc574c923d0fd73258bdf8909a11c9 Mon Sep 17 00:00:00 2001 From: 0x221E Date: Wed, 4 Feb 2026 12:52:42 +0100 Subject: [PATCH] Initial Commit --- .gitignore | 6 +++ CMakeLists.txt | 21 +++++++++ MOV — Move.pdf | Bin 0 -> 104961 bytes example/test.c | 5 ++ src/Bus.cpp | 10 ++++ src/Bus.h | 41 +++++++++++++++++ src/CPU.cpp | 69 ++++++++++++++++++++++++++++ src/CPU.h | 33 ++++++++++++++ src/ExecutorCases.cpp | 104 ++++++++++++++++++++++++++++++++++++++++++ src/ExecutorCases.h | 38 +++++++++++++++ src/Instruction.cpp | 19 ++++++++ src/Instruction.h | 27 +++++++++++ src/Metal.cpp | 20 ++++++++ src/Metal.h | 23 ++++++++++ src/main.cpp | 14 ++++++ 15 files changed, 430 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 MOV — Move.pdf create mode 100644 example/test.c create mode 100644 src/Bus.cpp create mode 100644 src/Bus.h create mode 100644 src/CPU.cpp create mode 100644 src/CPU.h create mode 100644 src/ExecutorCases.cpp create mode 100644 src/ExecutorCases.h create mode 100644 src/Instruction.cpp create mode 100644 src/Instruction.h create mode 100644 src/Metal.cpp create mode 100644 src/Metal.h create mode 100644 src/main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4d021de --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +example/test +build/ +build/* +.cache/ +.cache/* +.gdb_history \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f694ae7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.10) +project(emulator CXX) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +set(CMAKE_CXX_STANDDARD 23) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + add_compile_definitions(Debug) + set(CMAKE_BUILD_TYPE Debug) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,undefined -g") + message(STATUS "Building with debug mode.") +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector") +endif() + +file(GLOB_RECURSE SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") + +add_executable(emulator ${SRC_FILES}) diff --git a/MOV — Move.pdf b/MOV — Move.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1425c7ccb43c951ea6410753e766276b08944c42 GIT binary patch literal 104961 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 n}9cT8U!bw$&el(TI9EOzEsuU~2l1y!N0JI`-9u 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 + +Bus::Bus() { + for(int i = 0; i < 992 * 1024; i++) + { + m_RAM[i] = 0; + } +} diff --git a/src/Bus.h b/src/Bus.h new file mode 100644 index 0000000..7300141 --- /dev/null +++ b/src/Bus.h @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include +#include + +class Bus { +public: + Bus(); + ~Bus() = default; + +public: + template + void WriteX(uint64_t address, T value) + { + static_assert(std::is_unsigned_v, "T must be an unsigned int of any size smaller than 8 bytes!"); + T& loc = AccessX(address); + loc = value; + } + + template + T& AccessX(uint64_t address) + { + static_assert(std::is_unsigned_v, "T must be an unsigned int of any size smaller than 8 bytes!"); + + std::cout << "Bus access: " << std::hex << address << std::endl; + + if (address >= 0x00008000 && address <= 0x000FFFFF) + { + uint64_t offset = address - 0x00008000; + T* entry = reinterpret_cast(&m_RAM[offset]); + return entry[0]; + } + + throw std::runtime_error("Illegal Access!"); + } + +private: + uint8_t m_RAM[992 * 1024]; +}; diff --git a/src/CPU.cpp b/src/CPU.cpp new file mode 100644 index 0000000..09990f4 --- /dev/null +++ b/src/CPU.cpp @@ -0,0 +1,69 @@ +#include "CPU.h" + +#include +#include +#include +#include +#include + +CPU::CPU(std::shared_ptr 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(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(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(m_InstructionPointer + 1); + m_Instruction.m_Length = 5; + break; + case Opcode::ADD_RM32_R32: + m_Instruction.m_Operand1 = m_Bus->AccessX(m_InstructionPointer + 1); + m_Instruction.m_Operand2 = m_Bus->AccessX(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(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!"); +} diff --git a/src/CPU.h b/src/CPU.h new file mode 100644 index 0000000..e01a36b --- /dev/null +++ b/src/CPU.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include + +#include "Instruction.h" +#include "Bus.h" +#include "ExecutorCases.h" + +class CPU { +public: + CPU(std::shared_ptr bus); + ~CPU() = default; + +public: + void Step(); + +private: + void FetchDecode(); + void Execute(); + +private: + uint64_t m_Registers[16]; + uint64_t m_InstructionPointer; + uint64_t m_Flags; + + std::shared_ptr m_Bus; + + uint64_t m_InstructionRaw; + Instruction m_Instruction; + + CPUContext m_Context; +}; diff --git a/src/ExecutorCases.cpp b/src/ExecutorCases.cpp new file mode 100644 index 0000000..f05d330 --- /dev/null +++ b/src/ExecutorCases.cpp @@ -0,0 +1,104 @@ +#include "ExecutorCases.h" + +#include "Instruction.h" +#include "Bus.h" + +#include +#include + +CPUContext::CPUContext(Instruction& i, uint64_t& ip, uint64_t& flags, uint64_t* reg, std::shared_ptr& bus) : m_Instruction(i), m_InstructionPointer(ip), m_Flags(flags), m_Registers(reg), m_Bus(bus) { } + +CPUContext::~CPUContext() = default; + +// NO SIB SUPPORT YET +ModRM process_modrm(uint8_t modrm){ + uint8_t mod_mask = 0b11000000; + uint8_t reg_mask = 0b00111000; + uint8_t rm_mask = 0b00000111; + + uint8_t mod = modrm & mod_mask; + uint8_t reg = (modrm & reg_mask) >> 3; + uint8_t rm = modrm & rm_mask; + + ModRMState state = ModRMState::INVALID; + + switch(mod) { + case 0b00000000: + state = ModRMState::LR; + break; + case 0b01000000: + state = ModRMState::LR_DISP8; + break; + case 0b10000000: + state = ModRMState::LR_DISP32; + break; + case 0b11000000: + state = ModRMState::R; + break; + default: + throw std::runtime_error("Mod R/M does not support non-register operands right now!"); + } + return {.m_State = state, .m_Reg = reg, .m_Rm = rm}; +} + +namespace executor_cases { + void Nop(CPUContext& cc){ + std::cout << "No op" << std::endl; + } + + void Hlt(CPUContext& cc){ + std::cout << "Program halted!" << std::endl; + exit(0); + } + + void Mov_r32_imm32(CPUContext& cc){ + cc.m_Registers[cc.m_Instruction.m_Operand1] = cc.m_Instruction.m_Operand2; + std::cout << "Contents of " << x86::Register2Str((x86::Register)cc.m_Instruction.m_Operand1) << " changed to " << cc.m_Registers[cc.m_Instruction.m_Operand1] << std::endl; + } + + //NO SIB SUPPORT YET + void Add_rm32_r32(CPUContext& cc){ + ModRM modrm = process_modrm(cc.m_Instruction.m_Operand1); + + switch(modrm.m_State) { + case ModRMState::R: + { + cc.m_Registers[modrm.m_Rm] += cc.m_Registers[modrm.m_Reg]; + std::cout << "Adding " << x86::Register2Str((x86::Register)modrm.m_Reg) << " to " << x86::Register2Str((x86::Register)modrm.m_Rm) << std::endl; + break; + } + case ModRMState::LR: + { + uint32_t dstPrevValue = cc.m_Bus->AccessX(cc.m_Registers[modrm.m_Rm]); + uint32_t currRegValue = cc.m_Registers[modrm.m_Reg]; + uint32_t result = dstPrevValue + currRegValue; + cc.m_Bus->WriteX(cc.m_Registers[modrm.m_Rm], result); + std::cout << "Memory address " << std::hex << cc.m_Registers[modrm.m_Rm] << " modified to: " << result << std::endl; + break; + } + case ModRMState::LR_DISP8: + { + + } + default: + { + throw std::runtime_error("Invalid ModRM State encountered during Add_rm32_r32"); + } + } + } +} + +constexpr std::array GenerateExecutorTable(){ + std::array table{}; + table[Opcode::NOP] = executor_cases::Nop; + table[Opcode::HLT] = executor_cases::Hlt; + table[Opcode::MOV_R_IMM32] = executor_cases::Mov_r32_imm32; + table[Opcode::ADD_RM32_R32] = executor_cases::Add_rm32_r32; + return table; +} + +static constexpr std::array s_ExecutorTable = GenerateExecutorTable(); + +const std::array& GetExecutorTable() { + return s_ExecutorTable; +} diff --git a/src/ExecutorCases.h b/src/ExecutorCases.h new file mode 100644 index 0000000..37b4b3e --- /dev/null +++ b/src/ExecutorCases.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include + +struct Instruction; +class Bus; + +struct CPUContext { + Instruction& m_Instruction; + uint64_t& m_InstructionPointer; + uint64_t& m_Flags; + uint64_t* m_Registers; + std::shared_ptr m_Bus; + + CPUContext(Instruction& i, uint64_t& ip, uint64_t& flags, uint64_t* reg, std::shared_ptr& bus); + ~CPUContext(); +}; + +enum class ModRMState : uint8_t +{ + INVALID = 0, + LR = 1, + LR_DISP8 = 2, + LR_DISP32 = 3, + R = 4 +}; + +struct ModRM{ + ModRMState m_State; + uint8_t m_Reg; + uint8_t m_Rm; +}; + +typedef void (*ExecutorCase)(CPUContext&); + +const std::array& GetExecutorTable(); diff --git a/src/Instruction.cpp b/src/Instruction.cpp new file mode 100644 index 0000000..7c7d9c0 --- /dev/null +++ b/src/Instruction.cpp @@ -0,0 +1,19 @@ +#include "Instruction.h" + +#include + +namespace x86 { + std::string Register2Str(x86::Register reg) { + switch(reg){ + case x86::Register::EAX: return "EAX"; + case x86::Register::ECX: return "ECX"; + case x86::Register::EDX: return "EDX"; + case x86::Register::EBX: return "EBX"; + case x86::Register::ESP: return "ESP"; + case x86::Register::EBP: return "EBP"; + case x86::Register::ESI: return "ESI"; + case x86::Register::EDI: return "EDI"; + } + throw std::runtime_error("Register not found!"); + } +} diff --git a/src/Instruction.h b/src/Instruction.h new file mode 100644 index 0000000..cf4fbdc --- /dev/null +++ b/src/Instruction.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include + +namespace x86 { + enum Register : uint8_t { + EAX = 0, ECX = 1, EDX = 2, EBX = 3, + ESP = 4, EBP = 5, ESI = 6, EDI = 7 + }; + + std::string Register2Str(x86::Register reg); +} + +enum Opcode : uint8_t { + NOP = 0x90, + HLT = 0xF4, + MOV_R_IMM32 = 0xB8, + ADD_RM32_R32 = 0x01, +}; + +struct Instruction{ + Opcode m_Opcode; + size_t m_Length; + uint64_t m_Operand1; + uint64_t m_Operand2; +}; diff --git a/src/Metal.cpp b/src/Metal.cpp new file mode 100644 index 0000000..229c1e8 --- /dev/null +++ b/src/Metal.cpp @@ -0,0 +1,20 @@ +#include "Metal.h" + +#include "Bus.h" + +Metal::Metal() : m_Bus(std::make_shared()), m_CPU(m_Bus) { } + +void Metal::Upload2Memory(uint8_t bytes[], size_t len) { + uint64_t start = 0x8000; + for (size_t i = 0; i < len; i++) { + m_Bus->WriteX(start + i, bytes[i]); + std::cout << "Written " << bytes[i] << " to " << std::hex << start + i << std::endl; + } +} + +void Metal::Run() { + m_Running = true; + while(m_Running) { + m_CPU.Step(); + } +} diff --git a/src/Metal.h b/src/Metal.h new file mode 100644 index 0000000..e5405fa --- /dev/null +++ b/src/Metal.h @@ -0,0 +1,23 @@ +#pragma once + +class Bus; + +#include +#include + +#include "CPU.h" + +class Metal { + public: + Metal(); + ~Metal() = default; + + void Upload2Memory(uint8_t bytes[], size_t len); + + void Run(); + + private: + std::shared_ptr m_Bus; + CPU m_CPU; + bool m_Running = false; +}; diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..537eea4 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,14 @@ +#include + +#include "Metal.h" + +uint8_t test[] = { + 0x90, 0xF4 +}; + +int main(int argc, char** argv) { + Metal metal; + metal.Upload2Memory(test, 2); + metal.Run(); + return 0; +}