L1VM logo small

Running my blog and keep my hardware going costs money! So you can support me on Ko-fi!


1: Hello world, if, if+, else
2: switch
3: math
4: functions
5: input
6: strings
7: loops
8: arrays
9: logical operators, bit shifting
10: cli arguments
11: preprocessor
12: assembly VOL I
13: assembly VOL II
14: assembly VOL III
15: assembly VOL IV
16: assembly VOL V


The repository list can be found here: L1VM repo

Linux x86_64 binaries

I made static build binaries for Linux x86_64. They should run on any 64 bit Linux system. The needed modules have still to be build. So you need to run the normal build script as usual. The current L1VM 1.5.6 builds are here: L1VM static binaries Here is the sha256 sum of the archive:

cc3a107a410e166ab46ba40e559c9d1f03bbce8192f441f2f5bed431b155bfb7  l1vm-blob.zip

L1VM is an incredible tiny virtual machine with RISC (or comparable style) CPU, about 61 opcodes and about 40 KB binary size on X86_64 Linux (without JIT-compiler)! The VM has a 64 bit core (256 registers for integer and double float) and can run object code written in Brackets (a high level programming language) or l1asm assembly language.

Code and data are in separated memories for a secure execution. Like in Harvard type CPUs (found now in DSPs or microcontrollers). The opcode set with 61 opcodes is my own opinion how things should work. It does not “copy” other instruction sets known in other “real” CPUs.

I did develop an own programming language “Brackets”, which supports all the features of my VM. Brackets is variable type safe and supports constant variables. Brackets also supports multithreading.
I did develop a fractal rendering program in Brackets assembly.

The design goals are:

- be small
- be fast
- be simple
- be modular

The source code is on my GitHub repository: github.com/koder77/l1vm

You can write programs in my language Brackets. Here is a simple “Hello world!” program:

// hello.l1com
// Brackets - Hello world!
#include <intr.l1h>
(main func)
	(set int64 1 zero 0)
	(set int64 1 x 23)
	(set int64 1 y 42)
	(set int64 1 a 0)
	(set string 13 hello "Hello world!")
	// print string
	print_s (hello)
	((x y *) a =)
	print_i (a)
	exit (zero)
$ l1vm prog/hello-2 -q
Hello world!

So for printing a string some interrupts are used there. In the GitHub repo threre are lots of more advanced examples!

You can do GUI/graphics programs too. Here is a fractal drawing multithreading program example: fractalix-3.2
The L1VM can do multithreading! It is possible by using pthreads.

L1VM - fractal

Here is a GUI example: pov-edit
The gadgets are drawn by my SDL graphics/GUI module.

L1VM - pov edit screenshot

The L1VM now runs on Linux (testet on Debian, Ubuntu, Fedora), Windows 10 (via WSL) and macOS. On the Raspberry Pi the serial port and the GPIO pins can be programmed with my rs232 and gpio module. I use them to control a robot with my Raspberry Pi.

The modules

The L1VM can be expanded by modules (shared libraries). A module has an own API to access the functions from the VM. Here is the list of modules:

Cells - linked neural networks with FANN library
endianess - convert to big endian, or little endian functions
fann - FANN neural networks
file - file module
genann - neural networks module
gpio - Raspberry Pi GPIO module
math - some math functions
math-nofp - math module for use without FPU
math-vect - math on arrays functions
mem - memory allocating for arrays and vectors
mem-vect - C++ vector memory library
mpfr-c++ - MPFR floating point big num library
net - TCP/IP sockets module
process - start a new shell process
rs232-libserialport - RS232 serial port using libserialport
rs232 - RS232 serial port module
sdl 2.0 - graphics primitves module, like pixels, lines..., and GUI with buttons, lists, etc.
string - some string functions
time - get time and date

You can use this modules in your own Bracket programs.
And you even can develop your own modules!
I have two examples: a math demo and a switch (like in C). Here is the output of my math library demo:

$ l1vm lib/math-lib -q

The first number is a random number. Which changes on each run. The second and the third numbers are Pi rounded numbers. The last number “1” is the result of the not opcode.

Here is the math library demo:

// math-lib.l1com
// math library demo
#include <math-const.l1h>
#include <intr.l1h>
(main func)
	(set int64 1 zero 0)
	(set int64 1 randstart 2003)
	(set int64 1 random 0)
	(set int64 1 digits 3)
	(set int64 1 numstr_len 30)
	(set int64 1 not_num 0)
	(set int64 1 not_ret)
	(set string 30 numstr "")
	(zero :math_init call)
	(randstart :math_randinit call)
	(:math_randint call)
	(random stpopi)
	print_i (random)
	print_d (m_pi@math)
	// round pi to "digits" (3) digits and store number in string
	(m_pi@math digits numstraddr numstr_len :double_rounded_string call)
	print_s (numstr)
	(not_num :math_not call)
	(not_ret stpopi)
	print_i (not_ret)
	// close module
	free_mod (zero)
	exit (zero)
#include <math-lib.l1h>

Here is the output of my “switch” test program:

$ l1vm prog/switch -q
Hello world!
y = 42

A “switch” compares two variables and then runs the code in it, if they are equal. This is like in C. Here is a full example:

// switch.l1com
// Brackets - Hello world! switch
#include <intr.l1h>
(main func)
	(set int64 1 zero 0)
	(set int64 1 x 23)
	(set int64 1 y 42)
	(set string s 23_str "y = 23")
	(set string s 42_str "y = 42")
	(set const-int64 1 23_const 23)
	(set const-int64 1 42_const 42)
	(set string s hello_str "Hello world!")
	(set int64 1 a 0)
	// print string
	print_s (hello_str)
	((x y *) a =)
	print_i (a)
		(y 23_const ?)
			print_s (23_str)
		(y 42_const ?)
			print_s (42_str)
	exit (zero)

There are more demos in my GitHub repository! For the modules there are more demo programs.