This commit is contained in:
cannoli-fruit 2026-07-24 02:56:45 -04:00
commit d23a3e49ff
22 changed files with 979 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
build

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "Lazyc"]
path = Lazyc
url = https://youra.monster/git/Cody/Lazyc.git

352
ISA.md Normal file
View file

@ -0,0 +1,352 @@
# FP-Isa
Isa mostly made to run a version of a programming language i once made called flagpole
The compiler for that was written in python and used llvm so that's kinda yucky yk
and whole new isa so that i can have some fun idk
Registers (64 bit):
xSp -> Stack pointer (11111100)
xBp -> Base pointer (11111101)
xPc -> Program Counter (11111111)
r0-r127 -> General purpose (0xxxxxxx) xxxxxxx = r# in bin
Registers (32 bit):
h0-h127 -> General purpose (0xxxxxxx) xxxxxxx = h# in bin
^ Just the bottom 32 bits of r0-r127
r0 & h0 are both null registers
in general programming only use h0-h95, the rest are for assembler (or i guess compiler if yours lets you control registers?)
Flag Register:
Flag register is small with flags Zero, Negative, Positive, Oddness all as single bits (See SetF instructions)
Endianness:
everything is big endian bru (if you don't know what that means you can ignore it)
Memory addresses:
Every program is loaded at memory address 0x4000000000000000
All data between 0xC000000000000000 and 0xD000000000000000 are for MMIO (implementation specific!)
the stack's base is at 0x7FFFFFFFFFFFFFFF and grows down
Instructions:
All instructions start with a 1 byte opcode
depending on the first bits the operands change
000: no operands
001: ^
010: 1 byte of operands (likely reg)
011: 2 bytes of operands (likely 2 reg)
100: ^
101: 4 bytes of operands (likely immediate)
110: 1 byte of operands (jump addr reg)
111: 9 bytes of operands (likely reg, immediate)
Opcode Table
+-----------+----------+---------------------------------------------------------------------------+
| Mneumonic | Opcode | Description |
+-----------+----------+---------------------------------------------------------------------------+
| AddR32 | 011xxxxx | AddR32 dst, src adds the value in src to dst, result in dst (int) |
+-----------+----------+---------------------------------------------------------------------------+
| SubR32 | 011xxxxx | SubR32 dst, src subtracts the value in src from dst, result in dst (int) |
+-----------+----------+---------------------------------------------------------------------------+
| MulR32 | 011xxxxx | MulR32 dst, src multiplies the value in dst by src, result in dst (uint) |
+-----------+----------+---------------------------------------------------------------------------+
| IMulR32 | 011xxxxx | IMulR32 dst, src multiplies the value in dst by src, result in dst (sint) |
+-----------+----------+---------------------------------------------------------------------------+
| DivR32 | 011xxxxx | DivR32 dst, src divides dst by src, Quo in dst, Rem is ignored (uint) |
+-----------+----------+---------------------------------------------------------------------------+
| IDivR32 | 011xxxxx | IDivR32 dst, src divides dst by src, Quo in dst, Rem is ignored (sint) |
+-----------+----------+---------------------------------------------------------------------------+
| ModR32 | 011xxxxx | ModR32 dst, src divides dst by src, Rem in dst, Quo is ignored (uint) |
+-----------+----------+---------------------------------------------------------------------------+
| IModR32 | 011xxxxx | IModR32 dst, src divides dst by src, Rem in dst, Quo is ignored (sint) |
+-----------+----------+---------------------------------------------------------------------------+
| Shr32 | 011xxxxx | Shr32 dst, src logical shifts dst right by src&0b11111 |
+-----------+----------+---------------------------------------------------------------------------+
| Shl32 | 011xxxxx | Shl32 dst, src logical shifts dst left by src&0b11111 |
+-----------+----------+---------------------------------------------------------------------------+
| Sar32 | 011xxxxx | Sar32 dst, src arithmetic shifts dst right by src&0b11111 |
+-----------+----------+---------------------------------------------------------------------------+
| And32 | 011xxxxx | And32 dst, src performs logical ands dst with src and returns in dst |
+-----------+----------+---------------------------------------------------------------------------+
| Or32 | 011xxxxx | Or32 dst, src performs logical ors dst with src and returns in dst |
+-----------+----------+---------------------------------------------------------------------------+
| Xor32 | 011xxxxx | Xor32 dst, src performs logical xors dst with src and returns in dst |
+-----------+----------+---------------------------------------------------------------------------+
| Not32 | 010xxxxx | Not reg performs bitwise not operation on the 32 bit register |
+-----------+----------+---------------------------------------------------------------------------+
| AddR64 | 011xxxxx | AddR64 dst, src adds the value in src to dst, result in dst (int) |
+-----------+----------+---------------------------------------------------------------------------+
| SubR64 | 011xxxxx | SubR64 dst, src subtracts the value in src from dst, result in dst (int) |
+-----------+----------+---------------------------------------------------------------------------+
| MulR64 | 011xxxxx | MulR64 dst, src multiplies the value in dst by src, result in dst (uint) |
+-----------+----------+---------------------------------------------------------------------------+
| IMulR64 | 011xxxxx | IMulR64 dst, src multiplies the value in dst by src, result in dst (sint) |
+-----------+----------+---------------------------------------------------------------------------+
| ModR64 | 011xxxxx | ModR64 dst, src divides dst by src, Rem in dst, Quo is ignored (uint) |
+-----------+----------+---------------------------------------------------------------------------+
| IModR64 | 011xxxxx | IModR64 dst, src divides dst by src, Rem in dst, Quo is ignored (sint) |
+-----------+----------+---------------------------------------------------------------------------+
| DivR64 | 011xxxxx | DivR64 dst, src divides dst by src, Quo in dst, Rem is ignored (uint) |
+-----------+----------+---------------------------------------------------------------------------+
| IDivR64 | 011xxxxx | IDivR64 dst, src divides dst by src, Quo in dst, Rem is ignored (sint) |
+-----------+----------+---------------------------------------------------------------------------+
| Shr64 | 011xxxxx | Shr64 dst, src logical shifts dst right by src&0b111111 |
+-----------+----------+---------------------------------------------------------------------------+
| Shl64 | 011xxxxx | Shl64 dst, src logical shifts dst left by src&0b111111 |
+-----------+----------+---------------------------------------------------------------------------+
| Sar64 | 011xxxxx | Sar64 dst, src arithmetic shifts dst right by src&0b111111 |
+-----------+----------+---------------------------------------------------------------------------+
| And64 | 011xxxxx | And64 dst, src performs logical ands dst with src and returns in dst |
+-----------+----------+---------------------------------------------------------------------------+
| Or64 | 011xxxxx | Or64 dst, src performs logical ors dst with src and returns in dst |
+-----------+----------+---------------------------------------------------------------------------+
| Xor64 | 011xxxxx | Xor64 dst, src performs logical xors dst with src and returns in dst |
+-----------+----------+---------------------------------------------------------------------------+
| Not64 | 010xxxxx | Not reg performs bitwise not operation on the 64 bit register |
+-----------+----------+---------------------------------------------------------------------------+
| FAdd | 011xxxxx | FAdd dst, src adds src to dst as 32 bit float |
+-----------+----------+---------------------------------------------------------------------------+
| FSub | 011xxxxx | FSub dst, src subtracts src from dst as 32 bit float |
+-----------+----------+---------------------------------------------------------------------------+
| FMul | 011xxxxx | FMul dst, src multiplies dst by src as a 32 bit float |
+-----------+----------+---------------------------------------------------------------------------+
| FDiv | 011xxxxx | FDiv dst, src divides dst by src as a 32 bit float |
+-----------+----------+---------------------------------------------------------------------------+
| DAdd | 011xxxxx | DAdd dst, src adds src to dst as 64 bit double |
+-----------+----------+---------------------------------------------------------------------------+
| DSub | 011xxxxx | DSub dst, src subtracts src from dst as 64 bit double |
+-----------+----------+---------------------------------------------------------------------------+
| DMul | 011xxxxx | DMul dst, src multiplies dst by src as a 64 bit double |
+-----------+----------+---------------------------------------------------------------------------+
| DDiv | 011xxxxx | DDiv dst, src divides dst by src as a 64 bit double |
+-----------+----------+---------------------------------------------------------------------------+
| FtoI | 011xxxxx | FtoI dst, src converts src from 32b float to int (trunc), save to dst |
+-----------+----------+---------------------------------------------------------------------------+
| DtoI | 011xxxxx | DtoI dst, src converts src from 64b double to int (trunc), save to dst |
+-----------+----------+---------------------------------------------------------------------------+
| ItoF | 011xxxxx | ItoF dst, src converts src from int to 32b float, save to dst |
+-----------+----------+---------------------------------------------------------------------------+
| ItoD | 011xxxxx | ItoD dst, src converts src from int to 64b double, save to dst |
+-----------+----------+---------------------------------------------------------------------------+
| Jmp | 110xxxxx | Jump Absolutely With 64 bit register value |
+-----------+----------+---------------------------------------------------------------------------+
| JmpIZ | 110xxxxx | Jump Absolutely With 64 bit register value If Zero flag set |
+-----------+----------+---------------------------------------------------------------------------+
| JmpIN | 110xxxxx | Jump Absolutely With 64 bit register value If Negative flag set |
+-----------+----------+---------------------------------------------------------------------------+
| JmpIP | 110xxxxx | Jump Absolutely With 64 bit register value If Positive flag set |
+-----------+----------+---------------------------------------------------------------------------+
| JmpIO | 110xxxxx | Jump Absolutely With 64 bit register value If Parity flag set |
+-----------+----------+---------------------------------------------------------------------------+
| JmpNZ | 110xxxxx | Jump Absolutely With 64 bit register value If Zero flag unset |
+-----------+----------+---------------------------------------------------------------------------+
| JmpNN | 110xxxxx | Jump Absolutely With 64 bit register value If Negative flag unset |
+-----------+----------+---------------------------------------------------------------------------+
| JmpNP | 110xxxxx | Jump Absolutely With 64 bit register value If Positive flag unset |
+-----------+----------+---------------------------------------------------------------------------+
| JmpIE | 110xxxxx | Jump Absolutely With 64 bit register value If Parity flag unset |
+-----------+----------+---------------------------------------------------------------------------+
| St64 | 100xxxxx | Sto src, addr writes the value in src to the address in addr register(64b)|
+-----------+----------+---------------------------------------------------------------------------+
| Ld64 | 100xxxxx | Ld dst, addr reads the address in addr register and writes to dst (64b) |
+-----------+----------+---------------------------------------------------------------------------+
| St32 | 100xxxxx | Sto src, addr writes the value in src to the address in addr register(32b)|
+-----------+----------+---------------------------------------------------------------------------+
| Ld32 | 100xxxxx | Ld dst, addr reads the address in addr register and writes to dst (32b) |
+-----------+----------+---------------------------------------------------------------------------+
| St16 | 100xxxxx | Sto src, addr writes the value in src to the address in addr register(16b)|
+-----------+----------+---------------------------------------------------------------------------+
| Ld16 | 100xxxxx | Ld dst, addr reads the address in addr register and writes to dst (16b) |
+-----------+----------+---------------------------------------------------------------------------+
| St8 | 100xxxxx | Sto src, addr writes the value in src to the address in addr register (8b)|
+-----------+----------+---------------------------------------------------------------------------+
| Ld8 | 100xxxxx | Ld dst, addr reads the address in addr register and writes to dst (8b) |
+-----------+----------+---------------------------------------------------------------------------+
| RSetF | 010xxxxx | Set flags from 64 bit register |
+-----------+----------+---------------------------------------------------------------------------+
| HSetF | 010xxxxx | Set flags from 64 bit register |
+-----------+----------+---------------------------------------------------------------------------+
| HSetFF | 010xxxxx | Set flags from 32 bit register as a float value (no parity flag) |
+-----------+----------+---------------------------------------------------------------------------+
| RSetFD | 010xxxxx | Set flags from 64 bit register as a double value (no parity flag) |
+-----------+----------+---------------------------------------------------------------------------+
| Mov64 | 100xxxxx | MovRR dst, src copies the value from src to dst (64 bit registers) |
+-----------+----------+---------------------------------------------------------------------------+
| Mov32 | 100xxxxx | MovHR dst, src copies the value from src to dst (32 bit registers) |
+-----------+----------+---------------------------------------------------------------------------+
| MovI64 | 110xxxxx | MovI64 dst, imm (7 byte imm) moves imm into the dst register (64 bit) |
+-----------+----------+---------------------------------------------------------------------------+
| Halt | 00000000 | Halts the program execution and tells interpreter to kill the process |
+-----------+----------+---------------------------------------------------------------------------+
| Nop | 00010000 | Does nothing, interpreter is free to delay around 1ms to calm cpu |
+-----------+----------+---------------------------------------------------------------------------+
| Call | 01000000 | Calls the function at the memory address in the register (see call alg) |
+-----------+----------+---------------------------------------------------------------------------+
| Ret | 00000001 | Returns from the current function to the parent function (see call alg) |
+-----------+----------+---------------------------------------------------------------------------+
# real one ->
+-----------+----------+---------------------------------------------------------------------------+
| Mneumonic | Opcode | Description |
+-----------+----------+---------------------------------------------------------------------------+
| AddR32 | 01100000 | AddR32 dst, src adds the value in src to dst, result in dst (int) |
+-----------+----------+---------------------------------------------------------------------------+
| SubR32 | 01100001 | SubR32 dst, src subtracts the value in src from dst, result in dst (int) |
+-----------+----------+---------------------------------------------------------------------------+
| MulR32 | 01100010 | MulR32 dst, src multiplies the value in dst by src, result in dst (uint) |
+-----------+----------+---------------------------------------------------------------------------+
| IMulR32 | 01100011 | IMulR32 dst, src multiplies the value in dst by src, result in dst (sint) |
+-----------+----------+---------------------------------------------------------------------------+
| DivR32 | 01100100 | DivR32 dst, src divides dst by src, Quo in dst, Rem ignored (uint) |
+-----------+----------+---------------------------------------------------------------------------+
| IDivR32 | 01100101 | IDivR32 dst, src divides dst by src, Quo in dst, Rem ignored (sint) |
+-----------+----------+---------------------------------------------------------------------------+
| ModR32 | 01100110 | ModR32 dst, src divides dst by src, Rem in dst, Quo ignored (uint) |
+-----------+----------+---------------------------------------------------------------------------+
| IModR32 | 01100111 | IModR32 dst, src divides dst by src, Rem in dst, Quo ignored (sint) |
+-----------+----------+---------------------------------------------------------------------------+
| Shr32 | 01101000 | Shr32 dst, src logical shifts dst right by src&0b11111 |
+-----------+----------+---------------------------------------------------------------------------+
| Shl32 | 01101001 | Shl32 dst, src logical shifts dst left by src&0b11111 |
+-----------+----------+---------------------------------------------------------------------------+
| Sar32 | 01101010 | Sar32 dst, src arithmetic shifts dst right by src&0b11111 |
+-----------+----------+---------------------------------------------------------------------------+
| And32 | 01101011 | And32 dst, src performs logical and dst with src |
+-----------+----------+---------------------------------------------------------------------------+
| Or32 | 01101100 | Or32 dst, src performs logical or dst with src |
+-----------+----------+---------------------------------------------------------------------------+
| Xor32 | 01101101 | Xor32 dst, src performs logical xor dst with src |
+-----------+----------+---------------------------------------------------------------------------+
| AddR64 | 01101110 | AddR64 dst, src adds the value in src to dst, result in dst (int) |
+-----------+----------+---------------------------------------------------------------------------+
| SubR64 | 01101111 | SubR64 dst, src subtracts the value in src from dst, result in dst (int) |
+-----------+----------+---------------------------------------------------------------------------+
| MulR64 | 01110000 | MulR64 dst, src multiplies dst by src, result in dst (uint) |
+-----------+----------+---------------------------------------------------------------------------+
| IMulR64 | 01110001 | IMulR64 dst, src multiplies dst by src, result in dst (sint) |
+-----------+----------+---------------------------------------------------------------------------+
| DivR64 | 01110010 | DivR64 dst, src divides dst by src, Quo in dst (uint) |
+-----------+----------+---------------------------------------------------------------------------+
| IDivR64 | 01110011 | IDivR64 dst, src divides dst by src, Quo in dst (sint) |
+-----------+----------+---------------------------------------------------------------------------+
| ModR64 | 01110100 | ModR64 dst, src divides dst by src, Rem in dst (uint) |
+-----------+----------+---------------------------------------------------------------------------+
| IModR64 | 01110101 | IModR64 dst, src divides dst by src, Rem in dst (sint) |
+-----------+----------+---------------------------------------------------------------------------+
| Shr64 | 01110110 | Shr64 dst, src logical shifts dst right by src&0b111111 |
+-----------+----------+---------------------------------------------------------------------------+
| Shl64 | 01110111 | Shl64 dst, src logical shifts dst left by src&0b111111 |
+-----------+----------+---------------------------------------------------------------------------+
| Sar64 | 01111000 | Sar64 dst, src arithmetic shifts dst right by src&0b111111 |
+-----------+----------+---------------------------------------------------------------------------+
| And64 | 01111001 | And64 dst, src performs logical and dst with src |
+-----------+----------+---------------------------------------------------------------------------+
| Or64 | 01111010 | Or64 dst, src performs logical or dst with src |
+-----------+----------+---------------------------------------------------------------------------+
| Xor64 | 01111011 | Xor64 dst, src performs logical xor dst with src |
+-----------+----------+---------------------------------------------------------------------------+
| FAdd | 10000000 | FAdd dst, src adds src to dst as 32 bit float |
+-----------+----------+---------------------------------------------------------------------------+
| FSub | 10000001 | FSub dst, src subtracts src from dst as 32 bit float |
+-----------+----------+---------------------------------------------------------------------------+
| FMul | 10000010 | FMul dst, src multiplies dst by src as 32 bit float |
+-----------+----------+---------------------------------------------------------------------------+
| FDiv | 10000011 | FDiv dst, src divides dst by src as 32 bit float |
+-----------+----------+---------------------------------------------------------------------------+
| DAdd | 10000100 | DAdd dst, src adds src to dst as 64 bit double |
+-----------+----------+---------------------------------------------------------------------------+
| DSub | 10000101 | DSub dst, src subtracts src from dst as 64 bit double |
+-----------+----------+---------------------------------------------------------------------------+
| DMul | 10000110 | DMul dst, src multiplies dst by src as 64 bit double |
+-----------+----------+---------------------------------------------------------------------------+
| DDiv | 10000111 | DDiv dst, src divides dst by src as 64 bit double |
+-----------+----------+---------------------------------------------------------------------------+
| FtoI | 10001000 | FtoI dst, src converts src from 32b float to int (trunc), save to dst |
+-----------+----------+---------------------------------------------------------------------------+
| DtoI | 10001001 | DtoI dst, src converts src from 64b double to int (trunc), save to dst |
+-----------+----------+---------------------------------------------------------------------------+
| ItoF | 10001010 | ItoF dst, src converts src from int to 32b float, save to dst |
+-----------+----------+---------------------------------------------------------------------------+
| ItoD | 10001011 | ItoD dst, src converts src from int to 64b double, save to dst |
+-----------+----------+---------------------------------------------------------------------------+
| St64 | 10001100 | St64 src, addr writes src to address in addr register (64b) |
+-----------+----------+---------------------------------------------------------------------------+
| Ld64 | 10001101 | Ld64 dst, addr reads address in addr register and writes dst (64b) |
+-----------+----------+---------------------------------------------------------------------------+
| St32 | 10001110 | St32 src, addr writes src to address in addr register (32b) |
+-----------+---------+---------------------------------------------------------------------------+
| Ld32 | 10001111 | Ld32 dst, addr reads address in addr register and writes dst (32b) |
+-----------+----------+---------------------------------------------------------------------------+
| St16 | 10010000 | St16 src, addr writes src to address in addr register (16b) |
+-----------+----------+---------------------------------------------------------------------------+
| Ld16 | 10010001 | Ld16 dst, addr reads address in addr register and writes dst (16b) |
+-----------+----------+---------------------------------------------------------------------------+
| St8 | 10010010 | St8 src, addr writes src to address in addr register (8b) |
+-----------+----------+---------------------------------------------------------------------------+
| Ld8 | 10010011 | Ld8 dst, addr reads address in addr register and writes dst (8b) |
+-----------+----------+---------------------------------------------------------------------------+
| Mov64 | 10010100 | Mov64 dst, src copies value from src to dst (64 bit registers) |
+-----------+----------+---------------------------------------------------------------------------+
| Mov32 | 10010101 | Mov32 dst, src copies value from src to dst (32 bit registers) |
+-----------+----------+---------------------------------------------------------------------------+
| Jmp | 11000000 | Jump absolutely to 64 bit address |
+-----------+----------+---------------------------------------------------------------------------+
| JmpIZ | 11000001 | Jump absolutely to 64 bit address if Zero flag set |
+-----------+----------+---------------------------------------------------------------------------+
| JmpIN | 11000010 | Jump absolutely to 64 bit address if Negative flag set |
+-----------+----------+---------------------------------------------------------------------------+
| JmpIP | 11000011 | Jump absolutely to 64 bit address if Positive flag set |
+-----------+----------+---------------------------------------------------------------------------+
| JmpIO | 11000100 | Jump absolutely to 64 bit address if Parity flag set |
+-----------+----------+---------------------------------------------------------------------------+
| JmpNZ | 11000101 | Jump absolutely to 64 bit address if Zero flag unset |
+-----------+----------+---------------------------------------------------------------------------+
| JmpNN | 11000110 | Jump absolutely to 64 bit address if Negative flag unset |
+-----------+----------+---------------------------------------------------------------------------+
| JmpNP | 11000111 | Jump absolutely to 64 bit address if Positive flag unset |
+-----------+----------+---------------------------------------------------------------------------+
| JmpIE | 11001000 | Jump absolutely to 64 bit address if Parity flag unset |
+-----------+----------+---------------------------------------------------------------------------+
| MovI64 | 11101001 | MovI64 dst, imm moves 8 byte immediate into 64 bit register |
+-----------+----------+---------------------------------------------------------------------------+
| Not32 | 01000000 | Not32 reg performs bitwise not on 32 bit register |
+-----------+----------+---------------------------------------------------------------------------+
| Not64 | 01000001 | Not64 reg performs bitwise not on 64 bit register |
+-----------+----------+---------------------------------------------------------------------------+
| RSetF | 01000010 | Set flags from 64 bit register |
+-----------+----------+---------------------------------------------------------------------------+
| HSetF | 01000011 | Set flags from 64 bit register |
+-----------+----------+---------------------------------------------------------------------------+
| HSetFF | 01000100 | Set flags from 32 bit register as float value (no parity flag) |
+-----------+----------+---------------------------------------------------------------------------+
| RSetFD | 01000101 | Set flags from 64 bit register as double value (no parity flag) |
+-----------+----------+---------------------------------------------------------------------------+
| Call | 01000110 | Calls function at memory address in register |
+-----------+----------+---------------------------------------------------------------------------+
| Halt | 00000000 | Halts program execution and tells interpreter to kill process |
+-----------+----------+---------------------------------------------------------------------------+
| Nop | 00000001 | Does nothing, interpreter may delay around 1ms |
+-----------+----------+---------------------------------------------------------------------------+
| Ret | 00000010 | Returns from current function to parent function |
+-----------+----------+---------------------------------------------------------------------------+
Calling algorithm:
This is some horrific mix of c and asm but yk
void call(uint64_t addr) {
xSp -= 8;
mem[xSp] = xBp;
xSp -= 8;
mem[xSp] = xPc + 2; // 2 bytes is call instr size
xBp = xSp;
xPc = addr;
}
void ret() {
uint64_t addr = mem[xBp];
uint64_t oldBase = mem[xBp+8];
xPc = addr;
xSp = xBp+16;
xBp = oldBase;
}

1
Lazyc Submodule

@ -0,0 +1 @@
Subproject commit 5bb6ab1d1bf289e01e8fa2e482e1c1bd51fd3867

4
README.md Normal file
View file

@ -0,0 +1,4 @@
# FlagVM
A custom VM for an ISA, very beta right now don't touch it
I think it's technically turing complete with the current implementation
but i'll finish implementing the spec eventually

63
bldit.lua Normal file
View file

@ -0,0 +1,63 @@
bldit_version = "1.1.3"
package_version = "1.1.3"
dependencies = {}
exec_name = "flagvm"
libs = "-Wall -Wextra"
includes = "-I./Lazyc"
execute = function(str)
print(str)
return os.execute(str)
end
targets = {
default = {
build = function()
e,h,c = execute("rm -fr build")
if c ~= 0 and c ~= nil then
print("Build Error")
print("GIVEN UP")
return c
end
e,h,c = execute("mkdir build")
if c ~= 0 and c ~= nil then
print("Build Error")
print("GIVEN UP")
return c
end
cmd = [[find src -type f -name "*.c" -print]]
p = io.popen(cmd)
assert(p, "File detection error, GIVEN UP")
for f in p:lines() do
base = f:match("([^/]+)%.c$")
obj = "build/"..base..".o"
cc = "cc -c '"..f.."' -o '"..obj.."' "..includes
e,h,c = execute(cc)
if c ~= 0 and c ~= nil then
print("Compilation Error")
print("GIVEN UP")
return c
end
end
p:close()
e,h,c = execute("cc build/*.o "..libs.." -o "..exec_name)
if c ~= 0 and c ~= nil then
print("Compilation Error")
print("GIVEN UP")
return c
end
return 0
end,
install = function()
e,h,c = execute("cp "..exec_name.." /bin")
return c or 0
end,
uninstall = function()
e,h,c = execute("rm /bin"..exec_name)
return c or 0
end,
}
}

BIN
flagvm Executable file

Binary file not shown.

20
hexer.sh Executable file
View file

@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -e
if [ $# -lt 1 ]; then
echo "Usage: $0 input.hex [output.bin]"
exit 1
fi
input="$1"
if [ $# -ge 2 ]; then
output="$2"
else
output="${input%.*}.bin"
fi
perl -ne 's/#.*//; print pack("H*", $_ =~ s/\s+//gr)' "$input" > "$output"
echo "Wrote $output"

193
src/interp.c Normal file
View file

@ -0,0 +1,193 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#define LAZY_IMPL
#include "lazy.h"
#define PAGE_SIZE 4096
#define DEBUG false
// MMIO is defined between 0xC000000000000000 and 0xD000000000000000
// Some of that is still normal memory though
#define UART_TX 0xCFFFFFFFFFFFFFFD
#define UART_RX 0xCFFFFFFFFFFFFFFE
#define UART_CT 0xCFFFFFFFFFFFFFFF
static_assert(PAGE_SIZE%8 == 0);
static size_t flag_bytecnt[] = {
0, 0, 1, 2, 2, 4, 1, 9
};
typedef Lz_HM(uint64_t, void*) pageMap;
static pageMap memPages;
uint64_t registers[256];
#define xPc registers[255]
#define xSp registers[251]
#define xBp registers[252]
bool isMMIO(uint64_t addr) {
if (addr == UART_TX) return true;
if (addr == UART_RX) return true;
return false;
}
void memory_set8(uint64_t addr, unsigned char byte) {
if (isMMIO(addr)) {
if (addr == UART_TX) {
putchar(byte);
}
}
uint64_t pageAddr = addr / PAGE_SIZE;
uint64_t inPageAddr = addr % PAGE_SIZE;
if (lz_hm_exists(memPages, pageAddr)) {
void *page = lz_hm_get(memPages, pageAddr);
((unsigned char*)page)[inPageAddr] = byte;
} else {
void *newpage = malloc(PAGE_SIZE);
if (!newpage) {
printf("Buy more ram lol\n");
exit(1);
}
lz_hm_add(memPages, pageAddr, newpage);
((unsigned char*)newpage)[inPageAddr] = byte;
}
}
unsigned char memory_get8(uint64_t addr) {
if (isMMIO(addr)) {
if (addr == UART_RX) {
return fgetc(stdin);
}
}
uint64_t pageAddr = addr / PAGE_SIZE;
uint64_t inPageAddr = addr % PAGE_SIZE;
if (lz_hm_exists(memPages, pageAddr)) {
void *page = lz_hm_get(memPages, pageAddr);
return ((unsigned char*)page)[inPageAddr];
} else {
return 0; // CBF
}
}
int load_program(const char *fname) {
FILE *f = fopen(fname, "rb");
int byte;
xPc = 0x4000000000000000;
uint64_t i = xPc;
while ((byte = fgetc(f)) != EOF) {
memory_set8(i, byte);
++i;
}
fclose(f);
printf("[Info] Loaded file %s to addr 0x%lX\n", fname, xPc);
}
int main(int argc, char **argv) {
if (argc < 2) {
printf("[Usage]: %s <file>\n", argv[0]);
exit(1);
}
char *filename = argv[1];
lz_hm_init(memPages);
load_program(filename);
bool zeroFlag = false;
bool positiveFlag = false;
bool negativeFlag = false;
bool parityFlag = false;
while (1) {
unsigned char inst = memory_get8(xPc);
if (DEBUG) printf("INST: %02X\n", inst);
if (DEBUG) printf("IP: %16lX\n", xPc);
size_t inpflag = (inst & 0xE0) >> 5;
size_t inpcnt = flag_bytecnt[inpflag];
if (DEBUG) printf("Cnt: %zu\n", inpcnt);
unsigned char inputs[9];
for (size_t i = 0; i < inpcnt; ++i) {
inputs[i] = memory_get8(xPc+i+1);
}
xPc += 1;
xPc += inpcnt;
switch (inst) {
case 0x00: { // Halt
printf("\nHALT\n");
exit(0);
break;
}
case 0xE9: { // MovI64
unsigned char reg = inputs[0];
unsigned char x1 = inputs[1];
unsigned char x2 = inputs[2];
unsigned char x3 = inputs[3];
unsigned char x4 = inputs[4];
unsigned char x5 = inputs[5];
unsigned char x6 = inputs[6];
unsigned char x7 = inputs[7];
unsigned char x8 = inputs[8];
uint64_t val =
((uint64_t)x1 << 56) +
((uint64_t)x2 << 48) +
((uint64_t)x3 << 40) +
((uint64_t)x4 << 32) +
((uint64_t)x5 << 24) +
((uint64_t)x6 << 16) +
((uint64_t)x7 << 8) +
((uint64_t)x8 << 0);
registers[reg] = val;
//printf("Moved value 0x%lX into r%d\n", val, reg);
registers[0] = 0;
break;
}
case 0x92: { // St8
unsigned char src = inputs[0];
unsigned char addr = inputs[1];
memory_set8(registers[addr], registers[src]&0xFF);
break;
}
case 0x93: { // Ld8
unsigned char dst = inputs[0];
unsigned char addr = inputs[1];
registers[dst] = memory_get8(registers[addr]);
break;
}
case 0x42: { // RSetF
unsigned char reg = inputs[0];
int64_t val = *(int64_t*)(&registers[reg]); //Fuckery
zeroFlag = (val == 0);
parityFlag = (val & 1);
positiveFlag = (val > 0);
negativeFlag = (val < 0);
break;
}
case 0x60: {
unsigned char dst = inputs[0];
unsigned char src = inputs[1];
registers[dst] += registers[src];
break;
}
case 0xC0: { // Jmp
unsigned char addr = inputs[0];
xPc = registers[addr];
break;
}
case 0xC1: { // JmpIZ
unsigned char addr = inputs[0];
if (zeroFlag) {
if (DEBUG) printf("Jump!\n");
xPc = registers[addr];
}
break;
}
default: {
printf("Unknown instruction: 0x%02X\n", inst);
exit(1);
}
}
}
}

BIN
tests/UARTcat.bin Normal file

Binary file not shown.

9
tests/UARTcat.hex Normal file
View file

@ -0,0 +1,9 @@
E9 7F CFFFFFFFFFFFFFFD # UART TX
E9 7E CFFFFFFFFFFFFFFE # UART RX
# my assembler is shit and doesn't have labels
# this point is 0x4000000000000014 though
93 01 7E # Ld8 r1, RX
92 01 7F # St8 r1, TX
E9 03 4000000000000014 # jumpback addr
C0 03 # jump back
00

View file

@ -0,0 +1,8 @@
E9 7D CFFFFFFFFFFFFFFD # MovI64 7F UART_TX
E9 7E CFFFFFFFFFFFFFFE # MovI64 7F UART_RX
93 02 7E # Ld8 02, UART_RX
E9 01 0000000000000030 # MovI64 R1, 48
6F 01 02 # SubR64, R1, R2 (if R1 > 0 loop)
82 01 # RSetF R1
# This is 0x4000000000000026

BIN
tests/cat Normal file

Binary file not shown.

11
tests/cat.asm Normal file
View file

@ -0,0 +1,11 @@
include 'fvm.inc'
org 0x4000000000000000
start:
MovI64 r95, UART_TX
MovI64 r94, UART_RX
LoopHead:
Ld8 r1, r94
St8 r1, r95
MovI64 r3, LoopHead
JmpR r3
Halt

267
tests/fvm.inc Normal file
View file

@ -0,0 +1,267 @@
define NULL 0
define r0 0
define r1 1
define r2 2
define r3 3
define r4 4
define r5 5
define r6 6
define r7 7
define r8 8
define r9 9
define r10 10
define r11 11
define r12 12
define r13 13
define r14 14
define r15 15
define r16 16
define r17 17
define r18 18
define r19 19
define r20 20
define r21 21
define r22 22
define r23 23
define r24 24
define r25 25
define r26 26
define r27 27
define r28 28
define r29 29
define r30 30
define r31 31
define r32 32
define r33 33
define r34 34
define r35 35
define r36 36
define r37 37
define r38 38
define r39 39
define r40 40
define r41 41
define r42 42
define r43 43
define r44 44
define r45 45
define r46 46
define r47 47
define r48 48
define r49 49
define r50 50
define r51 51
define r52 52
define r53 53
define r54 54
define r55 55
define r56 56
define r57 57
define r58 58
define r59 59
define r60 60
define r61 61
define r62 62
define r63 63
define r64 64
define r65 65
define r66 66
define r67 67
define r68 68
define r69 69
define r70 70
define r71 71
define r72 72
define r73 73
define r74 74
define r75 75
define r76 76
define r77 77
define r78 78
define r79 79
define r80 80
define r81 81
define r82 82
define r83 83
define r84 84
define r85 85
define r86 86
define r87 87
define r88 88
define r89 89
define r90 90
define r91 91
define r92 92
define r93 93
define r94 94
define r95 95
define xSp 252
define xBp 253
define xPc 255
define h0 0
define h1 1
define h2 2
define h3 3
define h4 4
define h5 5
define h6 6
define h7 7
define h8 8
define h9 9
define h10 10
define h11 11
define h12 12
define h13 13
define h14 14
define h15 15
define h16 16
define h17 17
define h18 18
define h19 19
define h20 20
define h21 21
define h22 22
define h23 23
define h24 24
define h25 25
define h26 26
define h27 27
define h28 28
define h29 29
define h30 30
define h31 31
define h32 32
define h33 33
define h34 34
define h35 35
define h36 36
define h37 37
define h38 38
define h39 39
define h40 40
define h41 41
define h42 42
define h43 43
define h44 44
define h45 45
define h46 46
define h47 47
define h48 48
define h49 49
define h50 50
define h51 51
define h52 52
define h53 53
define h54 54
define h55 55
define h56 56
define h57 57
define h58 58
define h59 59
define h60 60
define h61 61
define h62 62
define h63 63
define h64 64
define h65 65
define h66 66
define h67 67
define h68 68
define h69 69
define h70 70
define h71 71
define h72 72
define h73 73
define h74 74
define h75 75
define h76 76
define h77 77
define h78 78
define h79 79
define h80 80
define h81 81
define h82 82
define h83 83
define h84 84
define h85 85
define h86 86
define h87 87
define h88 88
define h89 89
define h90 90
define h91 91
define h92 92
define h93 93
define h94 94
define h95 95
define UART_TX 0xCFFFFFFFFFFFFFFD
define UART_RX 0xCFFFFFFFFFFFFFFE
macro _dq_be val
db (val shr 56) and 0FFh
db (val shr 48) and 0FFh
db (val shr 40) and 0FFh
db (val shr 32) and 0FFh
db (val shr 24) and 0FFh
db (val shr 16) and 0FFh
db (val shr 8) and 0FFh
db (val shr 0) and 0FFh
end macro
macro MovI64 dst, val
db 0xE9
db dst
_dq_be val
end macro
macro Ld8 dst, addr
db 0x93
db dst
db addr
end macro
macro St8 dst, addr
db 0x92
db dst
db addr
end macro
macro AddR64 dst, src
db 0x60
db dst
db src
end macro
macro RSetF reg
db 0x42
db reg
end macro
macro JmpR addr
db 0xC0
db addr
end macro
macro Jmp addr
MovI64 127, addr
JmpR 127
end macro
macro JmpRIZ addr
db 0xC1
db addr
end macro
macro JmpIZ addr
MovI64 127, addr
JmpRIZ 127
end macro
macro Halt
db 0
end macro

BIN
tests/halt.bin Normal file

Binary file not shown.

BIN
tests/hw Normal file

Binary file not shown.

17
tests/hw.asm Normal file
View file

@ -0,0 +1,17 @@
include 'fvm.inc'
org 0x4000000000000000
start:
MovI64 r3, msg
MovI64 r1, 1
MovI64 r95, UART_TX
LoopHead:
Ld8 r2, r3
RSetF r2
JmpIZ LoopTail
St8 r2, r95
AddR64 r3, r1
Jmp LoopHead
LoopTail:
Halt
msg db 'Hello World!', 10, 0

BIN
tests/movi64.bin Normal file

Binary file not shown.

BIN
tests/uartH.bin Normal file

Binary file not shown.

BIN
tests/uartHW.bin Normal file

Binary file not shown.

29
tests/uartHW.hex Normal file
View file

@ -0,0 +1,29 @@
E9 01 CFFFFFFFFFFFFFFD # MovI64 r1, ...
E9 02 0000000000000048 # MovI64 r2, 'H'
92 02 01 # send 2 uart
E9 02 0000000000000065 # 'e'
92 02 01
E9 02 000000000000006C # 'l'*2
92 02 01
92 02 01
E9 02 000000000000006F # 'o'
92 02 01
E9 02 000000000000002C # ','
92 02 01
E9 02 0000000000000020 # ' '
92 02 01
E9 02 0000000000000057 # 'W'
92 02 01
E9 02 000000000000006F # 'o'
92 02 01
E9 02 0000000000000072 # 'r'
92 02 01
E9 02 000000000000006C # 'l'
92 02 01
E9 02 0000000000000064 # 'd'
92 02 01
E9 02 0000000000000021 # '!'
92 02 01
E9 02 000000000000000A # '\n'
92 02 01
00