Hi HN,
I built a RISC-V emulator that implements the RV32IM instruction set and a minimal syscall interface to run DOOM. A few weeks ago, I got my first output with a simple hello world assembly program.
Since then I have been working tirelessly to get DOOM to run.
I needed to figure out how to run C programs first, and came across newlib, which allows the underlying environment to implement the syscall stubs one by one until the programs run.
I have also added ELF loading, but currently only a single `PT_LOAD` segment is supported.
To port DOOM, I used doomgeneric, which was quite convenient to get working once the required stubs were in place.
DOOM renders to a fixed area in memory (0x705FDD = VRAM_START):
0x7FFFFF +-------------------------------------+
| |
| QUEUE_SIZE (32 bytes) |
| |
0x7FFFDF +-------------------------------------+ <-- QUEUE_START
0x7FFFDE | QUEUE_READ_IDX |
0x7FFFDD | QUEUE_WRITE_IDX |
+-------------------------------------+
| |
| |
| VRAM (1,024,000 bytes) |
| |
| |
0x705FDD +-------------------------------------+ <-- STACK_START
| Stack |
| | |
| v |
| |
| ^ |
| | |
| Program data + Heap |
| |
0x000000 +-------------------------------------+
I made a small linker script so that the entry point of a C program is at _start and virtual address is always 0. That kept the ELF loader code simple.Inputs are written to the queue by rvcore which are then intercepted by DOOM running inside it.