mirror of
https://github.com/pound-emu/pound.git
synced 2025-12-12 10:37:00 +00:00
Add the first files (ARMv8 basic emu)
This commit is contained in:
parent
304d94e955
commit
3f2d75276c
5 changed files with 93 additions and 1 deletions
|
|
@ -1,4 +1,6 @@
|
||||||
# Pound emulator
|
# Pound emulator
|
||||||
Pound is likely the first real contendor as a Switch 2 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.
|
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.
|
||||||
17
core/ARM/cpu.h
Normal file
17
core/ARM/cpu.h
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef CPU_H
|
||||||
|
#define CPU_H
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
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
|
||||||
44
core/JIT/jit.cpp
Normal file
44
core/JIT/jit.cpp
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
#include "core/JIT/jit.h"
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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<JitFunc>(code);
|
||||||
|
uint64_t result;
|
||||||
|
asm volatile (
|
||||||
|
"call *%1\n"
|
||||||
|
"mov %%rax, %0\n"
|
||||||
|
: "=r"(result)
|
||||||
|
: "r"(fn)
|
||||||
|
: "%rax"
|
||||||
|
);
|
||||||
|
|
||||||
|
cpu.regs[0] = result;
|
||||||
|
}
|
||||||
10
core/JIT/jit.h
Normal file
10
core/JIT/jit.h
Normal file
|
|
@ -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
|
||||||
19
ui/main.cpp
Normal file
19
ui/main.cpp
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue