Obviously this works best for someone who already knows C - but, given it's C89 mitigates against this aspect somewhat.
Or the same but for testing some verilog/vhdl CPU implemetation in a simulator?
Or since it's only 500SLOC, maybe it's just for fun!
[0] https://github.com/mnurzia/chip8-ce
Slightly unrelated, but just thought I should mention: the sokol libraries are awesome!
> All I want for Christmas is C89 with stdint.h
I get that same feeling now. This kid is 20 and still using C89? Shouldn't people his age have been reared entirely in the crystal-spires-and-togas utopia of Rust, with raw pointers and buffer overruns being mere legends of their people's benighted past told to them by their elders?
It's kind of comforting to see young programmers embracing the old ways, even if it's for hack value only.
I also like the idea of being able to run my code anywhere, kind of like Doom.
I was kind of the opposite as a kid, if it wasn’t crazy futuristic I didn’t want it. So even in the 80s I wanted an FPGA accelerators in every machine.
Mostly unrelated, but I recently discovered that you can buy TPUs, right now, as a consumer product, from https://coral.ai.
The stock firmware already allows you to run these things so hard they overheat, which is amazing.
But yes, I also want FPGA accelerators.
RISC-V doesn't have those. Compare+branch is a single instruction.
RISC-V is a type of CPU architecture (a set of plans for how to build one, not an actual CPU itself), that also happens to be open source. Anyone can build a RISC-V CPU without having to buy the rights to do so. (Many are.)
This project is an emulation of a RISC-V CPU. A kind of virtual "reference" CPU in software. It can be used to compile code that can run on a RISC-V type CPU, and to help understand what's happening inside the CPU when it runs.
It's written in C, which is and was a very fundamental programming language that's influenced the design of many other languages. It is a language that is very close the fundamental language CPU's natively decode and process.
CPU's natively use a language referred to as "Assembly", but which actually has many varieties particular to each CPU design. Regardless of variety of CPU, assembly is usually is about as reasonably "close to metal" as it gets.
It's literally communicating with the CPU directly in its own language. This makes it extremely fast to run, but laborious to code, and also somewhat "dangerous" in that with such low-level control, it's easy to mess things up.
This project takes an input of a text list of RISC-V assembly instructions (a "program") and pretends to be RISC-V CPU with those instructions loaded into it and being run on it. Useful for understanding, prototyping and building a RISC-V program.
CPU's are designed rather to run assembly that already "works", having been created programmatically (compiled or interpreted), by a higher level language that isn't going to give it things that make no sense (hopefully).
So there is not usually a lot of provisioning done in the design of the CPU to make it easy to watch it and its state carefully at a low level and examine how your assembly program is working, or not working. Emulation eases this.
Strictly, CPUs use machine code. Assembly targeting a particular CPU is a very thin more-human-readable abstraction around the underlying machine code, but it is not, itself, what the CPU executes. That’s why “assemblers” exist – they are compilers from assembly language to machine code (though, because assembly is a very thin abstraction, they are much simpler than most other compilers.)
I wrote a short news about the emulator on the french collaborative website linuxfr.org (see https://linuxfr.org/news/un-emulateur-et-un-desassembleur-ri...)
I would like to translate your comment and add it. Can I ?
https://github.com/andportnoy/riscv-disassembler/blob/master...
When compared to AVR 16-bit RISC instruction set, RISC-V looks so much simpler. (You may be indirectly familiar with AVR architecture by the household name "Arduino".)
The intriguing part is that AVR is just a microcontroller, while RISC-V is intended to be a full-blown CPU.
i.e. the GD32V microcontrollers implement RV32IMAC, Allwinner D1 which is a "full-blown" CPU meant to run Linux implements RV64IMAFDCVU.
RV32I/RV64I are the base 32/64 bit integer instruction sets and every letter after that is a different extension. Most of the extensions are relatively small and simple, but the C (compressed instructions) extension introduces some decoder complexity and the V (vector) extension adds several hundred instructions.
Though even with all the extensions it is still a very small/simple ISA by modern standards.
This works because, well, memory operations are mostly(all?) a CPU does so this "core" takes the program and does the same kind of memory operations the silicon would do, only in SW.