From d23a3e49ffd17322c16ec8b23b760a72da34f102 Mon Sep 17 00:00:00 2001 From: cannoli-fruit Date: Fri, 24 Jul 2026 02:56:45 -0400 Subject: [PATCH] Init --- .gitignore | 2 + .gitmodules | 3 + ISA.md | 352 +++++++++++++++++++++++++++++++++++++ Lazyc | 1 + README.md | 4 + bldit.lua | 63 +++++++ flagvm | Bin 0 -> 22248 bytes hexer.sh | 20 +++ src/interp.c | 193 ++++++++++++++++++++ tests/UARTcat.bin | Bin 0 -> 39 bytes tests/UARTcat.hex | 9 + tests/UARTtruthMachine.hex | 8 + tests/cat | Bin 0 -> 39 bytes tests/cat.asm | 11 ++ tests/fvm.inc | 267 ++++++++++++++++++++++++++++ tests/halt.bin | Bin 0 -> 1 bytes tests/hw | Bin 0 -> 80 bytes tests/hw.asm | 17 ++ tests/movi64.bin | Bin 0 -> 11 bytes tests/uartH.bin | Bin 0 -> 24 bytes tests/uartHW.bin | Bin 0 -> 183 bytes tests/uartHW.hex | 29 +++ 22 files changed, 979 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 ISA.md create mode 160000 Lazyc create mode 100644 README.md create mode 100644 bldit.lua create mode 100755 flagvm create mode 100755 hexer.sh create mode 100644 src/interp.c create mode 100644 tests/UARTcat.bin create mode 100644 tests/UARTcat.hex create mode 100644 tests/UARTtruthMachine.hex create mode 100644 tests/cat create mode 100644 tests/cat.asm create mode 100644 tests/fvm.inc create mode 100644 tests/halt.bin create mode 100644 tests/hw create mode 100644 tests/hw.asm create mode 100644 tests/movi64.bin create mode 100644 tests/uartH.bin create mode 100644 tests/uartHW.bin create mode 100644 tests/uartHW.hex diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9ef9604 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1a426d8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Lazyc"] + path = Lazyc + url = https://youra.monster/git/Cody/Lazyc.git diff --git a/ISA.md b/ISA.md new file mode 100644 index 0000000..eab87de --- /dev/null +++ b/ISA.md @@ -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; +} + diff --git a/Lazyc b/Lazyc new file mode 160000 index 0000000..5bb6ab1 --- /dev/null +++ b/Lazyc @@ -0,0 +1 @@ +Subproject commit 5bb6ab1d1bf289e01e8fa2e482e1c1bd51fd3867 diff --git a/README.md b/README.md new file mode 100644 index 0000000..38088c9 --- /dev/null +++ b/README.md @@ -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 diff --git a/bldit.lua b/bldit.lua new file mode 100644 index 0000000..a963e45 --- /dev/null +++ b/bldit.lua @@ -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, + } +} diff --git a/flagvm b/flagvm new file mode 100755 index 0000000000000000000000000000000000000000..364a20fe3e2046080c28a4fa9830195e68b335c4 GIT binary patch literal 22248 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

o7c_J=yR|>wrP(bfIkw8yTn0NH`?2co%&1M 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 ObG6_&&mrI_vi|{w4JfJr literal 0 HcmV?d00001 diff --git a/hexer.sh b/hexer.sh new file mode 100755 index 0000000..08f79ea --- /dev/null +++ b/hexer.sh @@ -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" \ No newline at end of file diff --git a/src/interp.c b/src/interp.c new file mode 100644 index 0000000..81d2d56 --- /dev/null +++ b/src/interp.c @@ -0,0 +1,193 @@ +#include +#include +#include +#include +#include +#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 \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*)(®isters[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); + } + } + } +} + + + diff --git a/tests/UARTcat.bin b/tests/UARTcat.bin new file mode 100644 index 0000000000000000000000000000000000000000..f9b07e0af182e4cb152efe828ddd3f17b02cc464 GIT binary patch literal 39 jcmaD^fBruh{C!ymW&NAXST~8W{w1>m0~m-LU}gXSO?(!F literal 0 HcmV?d00001 diff --git a/tests/UARTcat.hex b/tests/UARTcat.hex new file mode 100644 index 0000000..7febfe2 --- /dev/null +++ b/tests/UARTcat.hex @@ -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 diff --git a/tests/UARTtruthMachine.hex b/tests/UARTtruthMachine.hex new file mode 100644 index 0000000..57fce3b --- /dev/null +++ b/tests/UARTtruthMachine.hex @@ -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 + diff --git a/tests/cat b/tests/cat new file mode 100644 index 0000000000000000000000000000000000000000..998d4bc65154f097f99253476e09db2fe310e82b GIT binary patch literal 39 jcmaDEfBruh{Cyb*W&NAX7&nPA{w1>m0~m-LU}gXSL0lFD literal 0 HcmV?d00001 diff --git a/tests/cat.asm b/tests/cat.asm new file mode 100644 index 0000000..816ce62 --- /dev/null +++ b/tests/cat.asm @@ -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 diff --git a/tests/fvm.inc b/tests/fvm.inc new file mode 100644 index 0000000..8aefca8 --- /dev/null +++ b/tests/fvm.inc @@ -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 + diff --git a/tests/halt.bin b/tests/halt.bin new file mode 100644 index 0000000000000000000000000000000000000000..f76dd238ade08917e6712764a16a22005a50573d GIT binary patch literal 1 IcmZPo000310RR91 literal 0 HcmV?d00001 diff --git a/tests/hw b/tests/hw new file mode 100644 index 0000000000000000000000000000000000000000..c46187badd3e94fc481fd9af3e9270f0a3c71f7b GIT binary patch literal 80 zcmaFK?7#p9PA?fD3!C^<57tj&icer>gp0@>sAup<&B@7E N2+uFdNm1lt007->7!Uve literal 0 HcmV?d00001 diff --git a/tests/hw.asm b/tests/hw.asm new file mode 100644 index 0000000..6fac8d9 --- /dev/null +++ b/tests/hw.asm @@ -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 diff --git a/tests/movi64.bin b/tests/movi64.bin new file mode 100644 index 0000000000000000000000000000000000000000..72bfa7517b549c5c7231c811019d292ac2ca56dd GIT binary patch literal 11 NcmaE<#Q*`W3;+x~0a*Y5 literal 0 HcmV?d00001 diff --git a/tests/uartH.bin b/tests/uartH.bin new file mode 100644 index 0000000000000000000000000000000000000000..04ccbd0a438ce2522d1bee5874f3ab7a73f4dc60 GIT binary patch literal 24 XcmaFKc>X^a{C&y900AD8m>3xVwZ#f~ literal 0 HcmV?d00001 diff --git a/tests/uartHW.bin b/tests/uartHW.bin new file mode 100644 index 0000000000000000000000000000000000000000..c5117c36fac0d1cfa13902b150b139ae06772a35 GIT binary patch literal 183 zcmaFKc>X^a{C&y900AD8m>A)lRAf#Lkb}(6N9O1ta}