diff --git a/README.md b/README.md index bddb88a..04aa05a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ # Pound emulator Pound is likely the first real contendor as a Switch 2 emulator. -Progrss will start on the firmware as it is very simular to Switch 1. \ No newline at end of file +Progrss will start on the CPU and firmware as it is nearly identical to Switch 1, and later on smoothing out the differences between the two hardware. + +Pound will likely use some code from other Switch 1 emulators such as Yuzu and will specify which ones in the documentation. \ No newline at end of file diff --git a/core/ARM/cpu.h b/core/ARM/cpu.h new file mode 100644 index 0000000..c2ca23c --- /dev/null +++ b/core/ARM/cpu.h @@ -0,0 +1,17 @@ +#ifndef CPU_H +#define CPU_H +#include +#include + +struct CPU { + uint64_t regs[31] = {0}; // X0–X30 + uint64_t pc = 0; + static const size_t MEM_SIZE = 64 * 1024; + uint8_t memory[MEM_SIZE]; + + CPU() { std::memset(memory, 0, MEM_SIZE); } + + uint64_t& x(int i) { return regs[i]; } +}; + +#endif \ No newline at end of file diff --git a/core/JIT/jit.cpp b/core/JIT/jit.cpp new file mode 100644 index 0000000..b339095 --- /dev/null +++ b/core/JIT/jit.cpp @@ -0,0 +1,44 @@ +#include "core/JIT/jit.h" +#include +#include +#include +#include + +using JitFunc = void(*)(); + +void JIT::translate_and_run(CPU& cpu) { + uint8_t* code = (uint8_t*)mmap(nullptr, 64, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANON, -1, 0); + size_t offset = 0; + + // Decode mock instructions from cpu.memory + if (cpu.memory[0] == 0x05) { // MOVZ placeholder + code[offset++] = 0x48; // mov rax, imm64 + code[offset++] = 0xB8; + uint64_t imm = 5; + std::memcpy(&code[offset], &imm, sizeof(imm)); + offset += 8; + } + + if (cpu.memory[4] == 0x03) { // ADD placeholder + code[offset++] = 0x48; // add rax, imm32 + code[offset++] = 0x05; + uint32_t addval = 3; + std::memcpy(&code[offset], &addval, sizeof(addval)); + offset += 4; + } + + code[offset++] = 0xC3; // ret + + JitFunc fn = reinterpret_cast(code); + uint64_t result; + asm volatile ( + "call *%1\n" + "mov %%rax, %0\n" + : "=r"(result) + : "r"(fn) + : "%rax" + ); + + cpu.regs[0] = result; +} diff --git a/core/JIT/jit.h b/core/JIT/jit.h new file mode 100644 index 0000000..0b2cc8e --- /dev/null +++ b/core/JIT/jit.h @@ -0,0 +1,10 @@ +#ifndef JIT_H +#define JIT_H +#include "core/ARM/cpu.h" + +class JIT { +public: + void translate_and_run(CPU& cpu); +}; + +#endif \ No newline at end of file diff --git a/ui/main.cpp b/ui/main.cpp new file mode 100644 index 0000000..6749a95 --- /dev/null +++ b/ui/main.cpp @@ -0,0 +1,19 @@ +#include "core/ARM/cpu.h" +#include "core/JIT/jit.h" + +int main() { + CPU cpu; + cpu.pc = 0; + + // Simple ARMv8 program in memory (MOVZ X0, #5; ADD X0, X0, #3; RET) + // These are placeholders; real encoding will be parsed later + cpu.memory[0] = 0x05; // MOVZ placeholder + cpu.memory[4] = 0x03; // ADD placeholder + cpu.memory[8] = 0xFF; // RET placeholder + + JIT jit; + jit.translate_and_run(cpu); + + printf("X0 = %llu\n", cpu.regs[0]); + return 0; +} \ No newline at end of file