Skip to content
Repository for the vMCU16 assembler, linker, and interpreter.
C Objective-C Other
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.



(virtual 16-bit MicroController Unit)

This is a work in progress of a virtual 16 bit CPU platform complete with an interpreter, assembler, linker, and eventually a C99 compiler.

This virtual CPU is intended to be interpreted on microcontroller units such as the Atmel AVR series, Microchip PIC, Espressif ESP8266, and others. The main reason for the existence of this virtual platform is that these microcontrollers cannot execute instructions from RAM; instructions and data are kept in separate memory areas (typically EEPROM and static RAM, respectively). This makes it difficult to quickly load and execute new programs, or more importantly, to achieve multiprogramming. One solution was instead of executing instructions directly from RAM, which would be impossible, instructions would be loaded into an accessible memory area, then interpreted, similar to virtual machines or emulators for old game consoles. Within the virtual space, multiprogramming and loading/executing new programs would be easy.

I chose to make the vMCU16 CPU a 16 bit CPU with 16 bit and 32 bit addressing modes as a compromise between limiting the amount of reads/writes necessary on an 8-bit host CPU, ease of programming for the platform, limiting unnecessary operations on 16-bit+ host CPUs (e.g. these CPUs can natively deal with numbers larger than 8 bits, so limiting the virtual CPU to 8-bit operations would result in unnecessary math operations when dealing with numbers larger than 8 bits), and allowing at least 256K RAM, among other considerations. 24 bit was considered as 256K can be addressed with 24 bits, but since the interpreters will most likely be written in C and stdint.h does not provide a 24 bit type, I figured the extra byte would typically be used and wasted regardless.

However, an virtual CPU interpreted on an MCU by itself isn't very useful. External hardware, such as a screen or a WiFi radio, needed to be accessible from within the virtual platform. Though I want the interpreter to be a simple as possible for the sake of portability, I made the decision to have external hardware handled by the host CPU interpreter and accessed through virtual interrupts for a few reasons; namely that timing-sensitive external hardware would be difficult to handle from within the vCPU. Therefore, the interpreter also provides the vCPU with UNIX-esque "files" that can be read from and written to from within the vCPU using virtual interrupts. It is the interpreter's job to take this character stream and do something meaningful with it on external hardware.

See meta/docs/cpu_desc for a more detailed look at the virtual CPU, including its full instruction set, interrupts, assembler mnemonics, etc.

Roadmap for this project:

  • Create an assembler to spec with cpu_desc with basic functionality. (COMPLETED)
  • Create a linker to enable more advanced assembly programs to be created. (MOVED TO LATER IN THE ROADMAP)
  • Create an interpreter for Mac/Linux x86 that has the basic functionality of executing instructions already in RAM. (BASE FUNCTIONALITY ACHIEVED)
  • Refine the assembler to accept any source file, and give it basic options to make it usable in practice. (IN PROGRESS)
  • Create a linker to enable more advanced assembly programs to be created.
  • Refine the interpreter to load elf files generated by the linker, and enable access to external devices.
  • Create a C99 compiler with the basic functionality of taking a single C file and generating an assembly source file.
  • Refine linker and compiler to work together to enable the compilation of multi-source file projects.
  • Add options to the C compiler to make it useful in practice.
  • Finally, port/recreate the interpreted for the intended microcontroller hosts.

Future projects to build upon this one:

  • Create a debugger for programs generated using the above tools. Not sure if I should make it run inside the vCPU or as an extension to the interpreter.
  • Create a rudimentary operating system that runs withing the vCPU and provides a libc and enables multiprogramming.
You can’t perform that action at this time.