diff --git a/README.md b/README.md index 3163088..a415ef2 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # emu -Emulators written in C +Emulators written in C and C++ * `chip8.c` - [CHIP8](https://en.wikipedia.org/wiki/CHIP-8) * `mos6502.c` - [MOS 6502](https://en.wikipedia.org/wiki/MOS_Technology_6502) -* `riscv64.c & riscv64_dis.h` - [RV64IM instruction set](https://en.wikipedia.org/wiki/RISC-V) (more extensions coming soon-ish) +* `riscv64.cc` - [RV64IM instruction set](https://en.wikipedia.org/wiki/RISC-V) (more extensions coming soon-ish) ## Building ``` diff --git a/build.sh b/build.sh index 890df72..8fab4c1 100755 --- a/build.sh +++ b/build.sh @@ -1,6 +1,6 @@ #!/bin/bash -COMMON="-g -Wall -Wextra -Wpedantic -Wno-unused-variable -Wno-gnu-binary-literal" +COMMON="-g -Wall -Wextra -Wpedantic -Wno-unused-variable" echo "building mos6502..." cc $COMMON -std=c99 -o mos6502 mos6502.c @@ -17,7 +17,7 @@ if command -v pkg-config >/dev/null; then LIBELF_FLAGS=$(pkg-config --cflags --libs libelf 2>/dev/null) if [ $? -eq 0 ]; then echo "building riscv64..." - cc $COMMON -std=gnu11 -o riscv64 riscv64.c $LIBELF_FLAGS + c++ $COMMON -o riscv64 riscv64.cc $LIBELF_FLAGS else echo "libelf not found - skipping riscv64..." fi diff --git a/mos6502.c b/mos6502.c index cbcc429..7f68feb 100644 --- a/mos6502.c +++ b/mos6502.c @@ -20,12 +20,12 @@ typedef struct MOS6502 { uint8_t *memory; - uint16_t pc; - uint8_t A; - uint8_t X; - uint8_t Y; - uint8_t SP; - uint8_t P; + uint16_t pc; // program counter + uint8_t A; // accumulator + uint8_t X; // register X + uint8_t Y; // register Y + uint8_t SP; // stack pointer + uint8_t P; // processor status (see FLAG_*) uint8_t display_modified_this_cycle; } MOS6502; diff --git a/riscv64.cc b/riscv64.cc new file mode 100644 index 0000000..94c0a30 --- /dev/null +++ b/riscv64.cc @@ -0,0 +1,91 @@ +// https://docs.riscv.org/reference/isa/unpriv/rv-32-64g.html +// https://riscv.org/wp-content/uploads/2024/12/riscv-calling.pdf + +#if !defined(__cplusplus) || __cplusplus < 201703L +#error "This file requires at least C++17" +#endif + +#include +#include +#include +#include +#include +#include + +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +static constexpr u64 MEMORY_SIZE = 20 * 1024 * 1024; // should be enough + +static std::array REGS = { + "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "fp", "s1", "a0", + "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", + "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6"}; + +struct Section { + u64 offset; + u64 size; + u64 entrypoint; +}; + +class RISCV64 { +public: + RISCV64(const std::vector &exe_bytes) {} + +private: + std::array m_memory; + u64 m_pc; + i64 m_regs[32]; + Section m_code_section; +}; + +int main(int argc, char *argv[]) { + if (elf_version(EV_CURRENT) == EV_NONE) { + std::cerr << "Failed to initialize libelf: " << elf_errmsg(-1) << "\n"; + return 1; + } + + const char *path = nullptr; + for (int i = 1; i < argc; i++) { + path = argv[i]; + } + + if (path == nullptr) { + std::cerr << "Usage: " << argv[0] << " \n"; + return 1; + } + + std::ifstream file(path, std::ios::binary | std::ios::ate); + if (!file) { + std::cerr << "Failed to open: " << path << "\n"; + return 1; + } + + i64 exe_size = file.tellg(); + file.seekg(0, std::ios::beg); + + std::vector exe_bytes(exe_size); + file.read(exe_bytes.data(), exe_size); + file.close(); + + RISCV64 r(exe_bytes); + + exe_bytes = {}; + + r.disassemble_all(); + std::cout << "END DISASSEMBLY\n"; + + // for (r.pc = r.code_section.offset; + // r.pc < r.code_section.offset + r.code_section.size; r.pc += 4) { + // riscv64_disassemble_one(&r); + // } + // printf("END DISASSEMBLY\n"); + + // riscv64_execute(&r); +}