Fix assembler, update tests, update roms, add back nogui mode for speed.
This commit is contained in:
parent
07528b1f3f
commit
0d30ea292a
21
Makefile
21
Makefile
|
|
@ -2,6 +2,9 @@
|
||||||
PLATFORM ?= linux
|
PLATFORM ?= linux
|
||||||
BUILD_MODE ?= debug # 'debug' or 'release'
|
BUILD_MODE ?= debug # 'debug' or 'release'
|
||||||
|
|
||||||
|
# Ensure BUILD_MODE is fixed before any conditionals
|
||||||
|
$(eval BUILD_MODE := $(or $(BUILD_MODE),debug))
|
||||||
|
|
||||||
# --- DIRECTORIES ---
|
# --- DIRECTORIES ---
|
||||||
SRC_DIR := src
|
SRC_DIR := src
|
||||||
BUILD_DIR := build/$(PLATFORM)
|
BUILD_DIR := build/$(PLATFORM)
|
||||||
|
|
@ -107,13 +110,11 @@ DEPS := $(VM_OBJS:.o=.d) $(PLATFORM_OBJ:.o=.d)
|
||||||
# Default target
|
# Default target
|
||||||
all: $(TARGET)
|
all: $(TARGET)
|
||||||
|
|
||||||
# 'debug' target — just set BUILD_MODE and build
|
debug:
|
||||||
debug: BUILD_MODE=debug
|
$(MAKE) BUILD_MODE=debug all
|
||||||
debug: $(TARGET)
|
|
||||||
|
|
||||||
# 'release' target — just set BUILD_MODE and build
|
release:
|
||||||
release: BUILD_MODE=release
|
$(MAKE) BUILD_MODE=release all
|
||||||
release: $(TARGET)
|
|
||||||
|
|
||||||
# --- COMPILE VM CORE (freestanding) ---
|
# --- COMPILE VM CORE (freestanding) ---
|
||||||
$(BUILD_DIR)/vm/%.o: $(SRC_DIR)/vm/%.c
|
$(BUILD_DIR)/vm/%.o: $(SRC_DIR)/vm/%.c
|
||||||
|
|
@ -155,11 +156,11 @@ clean-all:
|
||||||
|
|
||||||
# --- TEST COMPILATION TARGET ---
|
# --- TEST COMPILATION TARGET ---
|
||||||
# Compiles all .asm.lisp test files to .rom using the debug VM executable
|
# Compiles all .asm.lisp test files to .rom using the debug VM executable
|
||||||
# Usage: make compile-tests PLATFORM=linux
|
# Usage: make tests PLATFORM=linux
|
||||||
compile-tests: $(BUILD_DIR)/undar-$(PLATFORM)$(TARGET_SUFFIX)
|
tests: $(BUILD_DIR)/undar-$(PLATFORM)$(TARGET_SUFFIX)
|
||||||
@echo "Compiling test assembly files for $(PLATFORM)..."
|
@echo "Compiling test assembly files for $(PLATFORM)..."
|
||||||
@for f in ./test/*.asm.lisp; do \
|
@for f in ./test/*.ul.ir; do \
|
||||||
base=$$(basename "$$f" .asm.lisp); \
|
base=$$(basename "$$f" .ul.ir); \
|
||||||
echo " [$$base] $$f -> ./test/$$base.rom"; \
|
echo " [$$base] $$f -> ./test/$$base.rom"; \
|
||||||
$(BUILD_DIR)/undar-$(PLATFORM)$(TARGET_SUFFIX) "$$f" -o "./test/$$base.rom"; \
|
$(BUILD_DIR)/undar-$(PLATFORM)$(TARGET_SUFFIX) "$$f" -o "./test/$$base.rom"; \
|
||||||
done
|
done
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,6 @@ function fib(n)
|
||||||
return fib(n-1) + fib(n-2)
|
return fib(n-1) + fib(n-2)
|
||||||
end
|
end
|
||||||
|
|
||||||
local result = fib(36)
|
local result = fib(35)
|
||||||
|
|
||||||
print(result)
|
print(result)
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,6 @@ sub fib {
|
||||||
return fib($n-1) + fib($n-2);
|
return fib($n-1) + fib($n-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
my $result = fib(36);
|
my $result = fib(35);
|
||||||
|
|
||||||
print "$result\n";
|
print "$result\n";
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ def fib(n):
|
||||||
return n
|
return n
|
||||||
return fib(n-1) + fib(n-2)
|
return fib(n-1) + fib(n-2)
|
||||||
|
|
||||||
result = fib(36)
|
result = fib(35)
|
||||||
print(result)
|
print(result)
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@ fn fib(n) {
|
||||||
return fib(n - 2) + fib(n - 1);
|
return fib(n - 2) + fib(n - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = fib(36);
|
let result = fib(35);
|
||||||
print result;
|
print result;
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,9 @@ print_section "zre ($FILENAME.t.ul)"
|
||||||
echo "test input" | time ../build/old/zre -t "$FILENAME.ul"
|
echo "test input" | time ../build/old/zre -t "$FILENAME.ul"
|
||||||
|
|
||||||
# Undâr Implementation (inline assembled)
|
# Undâr Implementation (inline assembled)
|
||||||
print_section "undar ($FILENAME.asm.lisp)"
|
print_section "undar ($FILENAME.ul.ir)"
|
||||||
echo "test input" | time ../build/linux/undar-linux-release "../test/$FILENAME.asm.lisp"
|
echo "test input" | time ../build/linux/undar-linux-release -t "../test/$FILENAME.ul.ir"
|
||||||
|
|
||||||
# Undâr Implementation (binary)
|
# Undâr Implementation (binary)
|
||||||
print_section "undar ($FILENAME.rom)"
|
print_section "undar ($FILENAME.rom)"
|
||||||
echo "test input" | time ../build/linux/undar-linux-release "../test/$FILENAME.rom"
|
echo "test input" | time ../build/linux/undar-linux-release -t "../test/$FILENAME.rom"
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
print(tostring(1 + 2))
|
print(tostring(1.0 + 2.0))
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
print((1 + 2) . "\n");
|
print((1.0 + 2.0) . "\n");
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
print(str(1 + 2))
|
print(str(1.0 + 2.0))
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
let sum = 1 + 2;
|
let sum = 1.0 + 2.0;
|
||||||
print sum;
|
print sum;
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,11 @@ i32 console_read(void *data, u8 *buffer, u32 size) {
|
||||||
|
|
||||||
i32 console_write(void *data, const u8 *buffer, u32 size) {
|
i32 console_write(void *data, const u8 *buffer, u32 size) {
|
||||||
USED(data);
|
USED(data);
|
||||||
|
|
||||||
|
if (size > MEMORY_SIZE) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (u32 i = 0; i < size; i++) {
|
for (u32 i = 0; i < size; i++) {
|
||||||
putchar(buffer[i]);
|
putchar(buffer[i]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,38 @@ bool compileAndSave(const char *source_file, const char *output_file, VM *vm) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef STATIC
|
||||||
|
#define SYMBOLS_COUNT 2048
|
||||||
|
Symbol symbols[SYMBOLS_COUNT];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void symbol_table_init(SymbolTable *t) {
|
||||||
|
#ifdef STATIC
|
||||||
|
memset(symbols, 0, SYMBOLS_COUNT*sizeof(Symbol));
|
||||||
|
t->symbols = symbols;
|
||||||
|
t->count = 0;
|
||||||
|
t->capacity = SYMBOLS_COUNT;
|
||||||
|
#else
|
||||||
|
t->symbols = calloc(16, sizeof(Symbol));
|
||||||
|
t->count = 0;
|
||||||
|
t->capacity = 16;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool resize_or_check_size(SymbolTable *table) {
|
||||||
|
#ifdef STATIC
|
||||||
|
if (table->count >= table->capacity) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (table->count >= table->capacity) {
|
||||||
|
table->capacity *= 2;
|
||||||
|
table->symbols = realloc(table->symbols, table->capacity * sizeof(Symbol));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Function to assemble and optionally save
|
// Function to assemble and optionally save
|
||||||
bool assembleAndSave(const char *source_file, const char *output_file, VM *vm) {
|
bool assembleAndSave(const char *source_file, const char *output_file, VM *vm) {
|
||||||
FILE *f = fopen(source_file, "rb");
|
FILE *f = fopen(source_file, "rb");
|
||||||
|
|
@ -151,7 +183,12 @@ bool assembleAndSave(const char *source_file, const char *output_file, VM *vm) {
|
||||||
source[read] = '\0';
|
source[read] = '\0';
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
assemble(vm, source);
|
SymbolTable table = {0};
|
||||||
|
symbol_table_init(&table);
|
||||||
|
assemble(vm, &table, source);
|
||||||
|
#ifndef STATIC
|
||||||
|
free(table.symbols);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (output_file) {
|
if (output_file) {
|
||||||
if (!saveVM(output_file, vm)) {
|
if (!saveVM(output_file, vm)) {
|
||||||
|
|
@ -167,6 +204,7 @@ i32 main(i32 argc, char *argv[]) {
|
||||||
bool dump_rom = false;
|
bool dump_rom = false;
|
||||||
char *input_file = nil;
|
char *input_file = nil;
|
||||||
char *output_file = nil;
|
char *output_file = nil;
|
||||||
|
bool terminal_only_mode = false;
|
||||||
bool is_rom = false;
|
bool is_rom = false;
|
||||||
bool is_ir = false;
|
bool is_ir = false;
|
||||||
|
|
||||||
|
|
@ -174,6 +212,8 @@ i32 main(i32 argc, char *argv[]) {
|
||||||
for (i32 i = 1; i < argc; i++) {
|
for (i32 i = 1; i < argc; i++) {
|
||||||
if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--dump-rom") == 0) {
|
if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--dump-rom") == 0) {
|
||||||
dump_rom = true;
|
dump_rom = true;
|
||||||
|
} else if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--term") == 0) {
|
||||||
|
terminal_only_mode = true;
|
||||||
} else if (input_file == nil) {
|
} else if (input_file == nil) {
|
||||||
// This is the input file
|
// This is the input file
|
||||||
input_file = argv[i];
|
input_file = argv[i];
|
||||||
|
|
@ -234,6 +274,11 @@ i32 main(i32 argc, char *argv[]) {
|
||||||
vm_register_device(&vm, "/dev/term/0", "terminal", &console_data,
|
vm_register_device(&vm, "/dev/term/0", "terminal", &console_data,
|
||||||
&console_device_ops, 4);
|
&console_device_ops, 4);
|
||||||
|
|
||||||
|
if (terminal_only_mode) {
|
||||||
|
while (step_vm(&vm));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||||
printf("SDL initialization failed: %s\n", SDL_GetError());
|
printf("SDL initialization failed: %s\n", SDL_GetError());
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -326,6 +371,7 @@ i32 main(i32 argc, char *argv[]) {
|
||||||
i32 cycles_this_frame = 0;
|
i32 cycles_this_frame = 0;
|
||||||
i32 max_cycles_per_frame = 100; // Adjust this value
|
i32 max_cycles_per_frame = 100; // Adjust this value
|
||||||
while (cycles_this_frame < max_cycles_per_frame) {
|
while (cycles_this_frame < max_cycles_per_frame) {
|
||||||
|
//printf("code[%d] = %s\n", vm.pc, opcode_to_string(vm.code[vm.pc]));
|
||||||
if (!step_vm(&vm)) {
|
if (!step_vm(&vm)) {
|
||||||
running = false;
|
running = false;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
#include "assembler.h"
|
|
||||||
#include "../../vm/common.h"
|
#include "../../vm/common.h"
|
||||||
#include "../../vm/fixed.h"
|
#include "../../vm/fixed.h"
|
||||||
#include "../../vm/libc.h"
|
#include "../../vm/libc.h"
|
||||||
#include "../../vm/opcodes.h"
|
#include "../../vm/opcodes.h"
|
||||||
|
|
||||||
|
#include "assembler.h"
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
|
|
||||||
|
/* FIXME: remove these and replace with libc.h instead */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -12,124 +15,123 @@ const char *opcode_to_string(Opcode op) {
|
||||||
static const char *names[] = {
|
static const char *names[] = {
|
||||||
[OP_EXIT] = "exit",
|
[OP_EXIT] = "exit",
|
||||||
[OP_JMP] = "jump",
|
[OP_JMP] = "jump",
|
||||||
[OP_JMPF] = "jump-if-flag",
|
[OP_JMPF] = "jump_if_flag",
|
||||||
[OP_CALL] = "call",
|
[OP_CALL] = "call",
|
||||||
[OP_RETURN] = "return",
|
[OP_RETURN] = "return",
|
||||||
|
|
||||||
/* Immediate loads (only 32-bit variant needed) */
|
[OP_LOAD_IMM] = "load_immediate",
|
||||||
[OP_LOAD_IMM] = "load-immediate",
|
|
||||||
|
|
||||||
/* Register-indirect loads */
|
/* Register_indirect loads */
|
||||||
[OP_LOAD_IND_8] = "load-indirect-8",
|
[OP_LOAD_IND_8] = "load_indirect_8",
|
||||||
[OP_LOAD_IND_16] = "load-indirect-16",
|
[OP_LOAD_IND_16] = "load_indirect_16",
|
||||||
[OP_LOAD_IND_32] = "load-indirect-32",
|
[OP_LOAD_IND_32] = "load_indirect_32",
|
||||||
|
|
||||||
/* Absolute address loads */
|
/* Absolute address loads */
|
||||||
[OP_LOAD_ABS_8] = "load-absolute-8",
|
[OP_LOAD_ABS_8] = "load_absolute_8",
|
||||||
[OP_LOAD_ABS_16] = "load-absolute-16",
|
[OP_LOAD_ABS_16] = "load_absolute_16",
|
||||||
[OP_LOAD_ABS_32] = "load-absolute-32",
|
[OP_LOAD_ABS_32] = "load_absolute_32",
|
||||||
|
|
||||||
/* Base+offset loads */
|
/* Base+offset loads */
|
||||||
[OP_LOAD_OFF_8] = "load-offset-8",
|
[OP_LOAD_OFF_8] = "load_offset_8",
|
||||||
[OP_LOAD_OFF_16] = "load-offset-16",
|
[OP_LOAD_OFF_16] = "load_offset_16",
|
||||||
[OP_LOAD_OFF_32] = "load-offset-32",
|
[OP_LOAD_OFF_32] = "load_offset_32",
|
||||||
|
|
||||||
/* Absolute address stores */
|
/* Absolute address stores */
|
||||||
[OP_STORE_ABS_8] = "store-absolute-8",
|
[OP_STORE_ABS_8] = "store_absolute_8",
|
||||||
[OP_STORE_ABS_16] = "store-absolute-16",
|
[OP_STORE_ABS_16] = "store_absolute_16",
|
||||||
[OP_STORE_ABS_32] = "store-absolute-32",
|
[OP_STORE_ABS_32] = "store_absolute_32",
|
||||||
|
|
||||||
/* Register-indirect stores */
|
/* Register_indirect stores */
|
||||||
[OP_STORE_IND_8] = "store-indirect-8",
|
[OP_STORE_IND_8] = "store_indirect_8",
|
||||||
[OP_STORE_IND_16] = "store-indirect-16",
|
[OP_STORE_IND_16] = "store_indirect_16",
|
||||||
[OP_STORE_IND_32] = "store-indirect-32",
|
[OP_STORE_IND_32] = "store_indirect_32",
|
||||||
|
|
||||||
/* Base+offset stores */
|
/* Base+offset stores */
|
||||||
[OP_STORE_OFF_8] = "store-offset-8",
|
[OP_STORE_OFF_8] = "store_offset_8",
|
||||||
[OP_STORE_OFF_16] = "store-offset-16",
|
[OP_STORE_OFF_16] = "store_offset_16",
|
||||||
[OP_STORE_OFF_32] = "store-offset-32",
|
[OP_STORE_OFF_32] = "store_offset_32",
|
||||||
|
|
||||||
/* Memory operations */
|
/* Memory operations */
|
||||||
[OP_MALLOC] = "malloc",
|
[OP_MALLOC] = "malloc",
|
||||||
[OP_MEMSET_8] = "memset-8",
|
[OP_MEMSET_8] = "memset_8",
|
||||||
[OP_MEMSET_16] = "memset-16",
|
[OP_MEMSET_16] = "memset_16",
|
||||||
[OP_MEMSET_32] = "memset-32",
|
[OP_MEMSET_32] = "memset_32",
|
||||||
|
|
||||||
/* Register operations */
|
/* Register operations */
|
||||||
[OP_REG_MOV] = "register-move",
|
[OP_REG_MOV] = "register_move",
|
||||||
[OP_SYSCALL] = "syscall",
|
[OP_SYSCALL] = "syscall",
|
||||||
|
|
||||||
/* Bit operations */
|
/* Bit operations */
|
||||||
[OP_BIT_SHIFT_LEFT] = "bit-shift-left",
|
[OP_BIT_SHIFT_LEFT] = "bit_shift_left",
|
||||||
[OP_BIT_SHIFT_RIGHT] = "bit-shift-right",
|
[OP_BIT_SHIFT_RIGHT] = "bit_shift_right",
|
||||||
[OP_BIT_SHIFT_R_EXT] = "bit-shift-re",
|
[OP_BIT_SHIFT_R_EXT] = "bit_shift_re",
|
||||||
[OP_BAND] = "bit-and",
|
[OP_BAND] = "bit_and",
|
||||||
[OP_BOR] = "bit-or",
|
[OP_BOR] = "bit_or",
|
||||||
[OP_BXOR] = "bit-xor",
|
[OP_BXOR] = "bit_xor",
|
||||||
|
|
||||||
/* Integer arithmetic */
|
/* Integer arithmetic */
|
||||||
[OP_ADD_INT] = "add-int",
|
[OP_ADD_INT] = "add_int",
|
||||||
[OP_SUB_INT] = "sub-int",
|
[OP_SUB_INT] = "sub_int",
|
||||||
[OP_MUL_INT] = "mul-int",
|
[OP_MUL_INT] = "mul_int",
|
||||||
[OP_DIV_INT] = "div-int",
|
[OP_DIV_INT] = "div_int",
|
||||||
|
|
||||||
/* Natural number arithmetic */
|
/* Natural number arithmetic */
|
||||||
[OP_ADD_NAT] = "add-nat",
|
[OP_ADD_NAT] = "add_nat",
|
||||||
[OP_SUB_NAT] = "sub-nat",
|
[OP_SUB_NAT] = "sub_nat",
|
||||||
[OP_MUL_NAT] = "mul-nat",
|
[OP_MUL_NAT] = "mul_nat",
|
||||||
[OP_DIV_NAT] = "div-nat",
|
[OP_DIV_NAT] = "div_nat",
|
||||||
|
|
||||||
/* Floating point operations */
|
/* Floating point operations */
|
||||||
[OP_ADD_REAL] = "add-real",
|
[OP_ADD_REAL] = "add_real",
|
||||||
[OP_SUB_REAL] = "sub-real",
|
[OP_SUB_REAL] = "sub_real",
|
||||||
[OP_MUL_REAL] = "mul-real",
|
[OP_MUL_REAL] = "mul_real",
|
||||||
[OP_DIV_REAL] = "div-real",
|
[OP_DIV_REAL] = "div_real",
|
||||||
|
|
||||||
/* Type conversions */
|
/* Type conversions */
|
||||||
[OP_INT_TO_REAL] = "int-to-real",
|
[OP_INT_TO_REAL] = "int_to_real",
|
||||||
[OP_NAT_TO_REAL] = "nat-to-real",
|
[OP_NAT_TO_REAL] = "nat_to_real",
|
||||||
[OP_REAL_TO_INT] = "real-to-int",
|
[OP_REAL_TO_INT] = "real_to_int",
|
||||||
[OP_REAL_TO_NAT] = "real-to-nat",
|
[OP_REAL_TO_NAT] = "real_to_nat",
|
||||||
|
|
||||||
/* Integer comparisons */
|
/* Integer comparisons */
|
||||||
[OP_JEQ_INT] = "jump-eq-int",
|
[OP_JEQ_INT] = "jump_eq_int",
|
||||||
[OP_JNEQ_INT] = "jump-neq-int",
|
[OP_JNEQ_INT] = "jump_neq_int",
|
||||||
[OP_JGT_INT] = "jump-gt-int",
|
[OP_JGT_INT] = "jump_gt_int",
|
||||||
[OP_JLT_INT] = "jump-lt-int",
|
[OP_JLT_INT] = "jump_lt_int",
|
||||||
[OP_JLE_INT] = "jump-le-int",
|
[OP_JLE_INT] = "jump_le_int",
|
||||||
[OP_JGE_INT] = "jump-ge-int",
|
[OP_JGE_INT] = "jump_ge_int",
|
||||||
|
|
||||||
/* Natural number comparisons */
|
/* Natural number comparisons */
|
||||||
[OP_JEQ_NAT] = "jump-eq-nat",
|
[OP_JEQ_NAT] = "jump_eq_nat",
|
||||||
[OP_JNEQ_NAT] = "jump-neq-nat",
|
[OP_JNEQ_NAT] = "jump_neq_nat",
|
||||||
[OP_JGT_NAT] = "jump-gt-nat",
|
[OP_JGT_NAT] = "jump_gt_nat",
|
||||||
[OP_JLT_NAT] = "jump-lt-nat",
|
[OP_JLT_NAT] = "jump_lt_nat",
|
||||||
[OP_JLE_NAT] = "jump-le-nat",
|
[OP_JLE_NAT] = "jump_le_nat",
|
||||||
[OP_JGE_NAT] = "jump-ge-nat",
|
[OP_JGE_NAT] = "jump_ge_nat",
|
||||||
|
|
||||||
/* Floating point comparisons */
|
/* Floating point comparisons */
|
||||||
[OP_JEQ_REAL] = "jump-eq-real",
|
[OP_JEQ_REAL] = "jump_eq_real",
|
||||||
[OP_JNEQ_REAL] = "jump-neq-real",
|
[OP_JNEQ_REAL] = "jump_neq_real",
|
||||||
[OP_JGE_REAL] = "jump-ge-real",
|
[OP_JGE_REAL] = "jump_ge_real",
|
||||||
[OP_JGT_REAL] = "jump-gt-real",
|
[OP_JGT_REAL] = "jump_gt_real",
|
||||||
[OP_JLT_REAL] = "jump-lt-real",
|
[OP_JLT_REAL] = "jump_lt_real",
|
||||||
[OP_JLE_REAL] = "jump-le-real",
|
[OP_JLE_REAL] = "jump_le_real",
|
||||||
|
|
||||||
/* String operations */
|
/* String operations */
|
||||||
[OP_STRLEN] = "string-length",
|
[OP_STRLEN] = "string_length",
|
||||||
[OP_STREQ] = "string-eq",
|
[OP_STREQ] = "string_eq",
|
||||||
[OP_STRCAT] = "string-concat",
|
[OP_STRCAT] = "string_concat",
|
||||||
[OP_STR_GET_CHAR] = "string-get-char",
|
[OP_STR_GET_CHAR] = "string_get_char",
|
||||||
[OP_STR_FIND_CHAR] = "string-find-char",
|
[OP_STR_FIND_CHAR] = "string_find_char",
|
||||||
[OP_STR_SLICE] = "string-slice",
|
[OP_STR_SLICE] = "string_slice",
|
||||||
|
|
||||||
/* String conversions */
|
/* String conversions */
|
||||||
[OP_INT_TO_STRING] = "int-to-string",
|
[OP_INT_TO_STRING] = "int_to_string",
|
||||||
[OP_NAT_TO_STRING] = "nat-to-string",
|
[OP_NAT_TO_STRING] = "nat_to_string",
|
||||||
[OP_REAL_TO_STRING] = "real-to-string",
|
[OP_REAL_TO_STRING] = "real_to_string",
|
||||||
[OP_STRING_TO_INT] = "string-to-int",
|
[OP_STRING_TO_INT] = "string_to_int",
|
||||||
[OP_STRING_TO_NAT] = "string-to-nat",
|
[OP_STRING_TO_NAT] = "string_to_nat",
|
||||||
[OP_STRING_TO_REAL] = "string-to-real"};
|
[OP_STRING_TO_REAL] = "string_to_real"};
|
||||||
|
|
||||||
if (op < 0 || op >= (int)(sizeof(names) / sizeof(names[0]))) {
|
if (op < 0 || op >= (int)(sizeof(names) / sizeof(names[0]))) {
|
||||||
return "<invalid-opcode>";
|
return "<invalid-opcode>";
|
||||||
|
|
@ -139,27 +141,28 @@ const char *opcode_to_string(Opcode op) {
|
||||||
return name ? name : "<unknown-opcode>";
|
return name ? name : "<unknown-opcode>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void emit_op(VM *vm, u8 byte) {
|
void emit_op(VM *vm, u8 byte) {
|
||||||
printf("vm->code[%d] = %s\n", vm->cp, opcode_to_string(byte));
|
#ifdef DEBUG_PRINT
|
||||||
|
printf("code[%d] = %s\n", vm->cp, opcode_to_string(byte));
|
||||||
|
#endif
|
||||||
vm->code[vm->cp] = byte;
|
vm->code[vm->cp] = byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emit_byte(VM *vm, u8 byte) {
|
void emit_byte(VM *vm, u8 byte) {
|
||||||
printf("vm->code[%d] = %d\n", vm->cp, byte);
|
#ifdef DEBUG_PRINT
|
||||||
|
printf("code[%d] = %d\n", vm->cp, byte);
|
||||||
|
#endif
|
||||||
vm->code[vm->cp] = byte;
|
vm->code[vm->cp] = byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emit_u32(VM *vm, u32 value) {
|
void emit_u32(VM *vm, u32 value) {
|
||||||
printf("vm->code[%d..%d] = %d\n", vm->cp, vm->cp + 3, value);
|
#ifdef DEBUG_PRINT
|
||||||
|
printf("code[%d..%d] = %d\n", vm->cp, vm->cp + 3, value);
|
||||||
|
#endif
|
||||||
write_u32(vm, code, vm->cp, value);
|
write_u32(vm, code, vm->cp, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void symbol_table_init(SymbolTable *table) {
|
|
||||||
table->symbols = calloc(16, sizeof(Symbol));
|
|
||||||
table->count = 0;
|
|
||||||
table->capacity = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
Symbol *symbol_table_lookup(SymbolTable *table, const char *name, u32 length) {
|
Symbol *symbol_table_lookup(SymbolTable *table, const char *name, u32 length) {
|
||||||
for (u32 i = 0; i < table->count; i++) {
|
for (u32 i = 0; i < table->count; i++) {
|
||||||
if (table->symbols[i].name_length == length) {
|
if (table->symbols[i].name_length == length) {
|
||||||
|
|
@ -182,19 +185,23 @@ u32 symbol_table_add(SymbolTable *table, Symbol s) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (table->count >= table->capacity) {
|
if (!resize_or_check_size(table)) {
|
||||||
table->capacity *= 2;
|
fprintf(stderr,
|
||||||
table->symbols = realloc(table->symbols, table->capacity * sizeof(Symbol));
|
"Error: Symbol table is out of memory! This is likely because you built this in static mode."
|
||||||
|
"if you built using malloc, that means your computer is out of memory. Close a few tabs in your web browser and try again."
|
||||||
|
"Count was %d, while capacity was %d\n",
|
||||||
|
table->count, table->capacity);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
if (s.scope == VAR) {
|
if (s.scope == VAR) {
|
||||||
// ignore for now
|
printf("$%d = %s\n", s.ref, s.name);
|
||||||
// printf("$%d = %s\n", s.ref, s.name);
|
|
||||||
} else if (s.scope == GLOBAL) {
|
} else if (s.scope == GLOBAL) {
|
||||||
printf("memory[%d] = %s\n", s.ref, s.name);
|
printf("memory[%d] = %s\n", s.ref, s.name);
|
||||||
} else {
|
} else {
|
||||||
printf("code[%d] = %s\n", s.ref, s.name);
|
printf("code[%d] = %s\n", s.ref, s.name);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
table->symbols[table->count] = s;
|
table->symbols[table->count] = s;
|
||||||
u32 index = table->count;
|
u32 index = table->count;
|
||||||
|
|
@ -232,7 +239,7 @@ u32 get_ptr(Token token, SymbolTable *st) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "Error: Not a register or symbol '%.*s'\n", token.length,
|
fprintf(stderr, "Error: Not a pointer or symbol '%.*s'\n", token.length,
|
||||||
token.start);
|
token.start);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
@ -595,6 +602,7 @@ void define_branch(VM *vm, SymbolTable *st) {
|
||||||
}
|
}
|
||||||
memcpy(s.name, name.start, name.length);
|
memcpy(s.name, name.start, name.length);
|
||||||
s.name_length = name.length;
|
s.name_length = name.length;
|
||||||
|
s.name[name.length] = '\0';
|
||||||
|
|
||||||
s.ref = vm->cp;
|
s.ref = vm->cp;
|
||||||
symbol_table_add(st, s);
|
symbol_table_add(st, s);
|
||||||
|
|
@ -625,9 +633,6 @@ int get_instruction_byte_size(const char *opname) {
|
||||||
strcmp(opname, "real_to_nat") == 0 || strcmp(opname, "nat_to_int") == 0 ||
|
strcmp(opname, "real_to_nat") == 0 || strcmp(opname, "nat_to_int") == 0 ||
|
||||||
strcmp(opname, "int_to_nat") == 0 ||
|
strcmp(opname, "int_to_nat") == 0 ||
|
||||||
strcmp(opname, "string_length") == 0 ||
|
strcmp(opname, "string_length") == 0 ||
|
||||||
strcmp(opname, "store_absolute_32") == 0 ||
|
|
||||||
strcmp(opname, "store_absolute_8") == 0 ||
|
|
||||||
strcmp(opname, "store_absolute_16") == 0 ||
|
|
||||||
strcmp(opname, "memset") == 0 || strcmp(opname, "memset") == 0 ||
|
strcmp(opname, "memset") == 0 || strcmp(opname, "memset") == 0 ||
|
||||||
strcmp(opname, "memset_8") == 0 || strcmp(opname, "memset_16") == 0 ||
|
strcmp(opname, "memset_8") == 0 || strcmp(opname, "memset_16") == 0 ||
|
||||||
strcmp(opname, "register_move") == 0 || strcmp(opname, "malloc") == 0) {
|
strcmp(opname, "register_move") == 0 || strcmp(opname, "malloc") == 0) {
|
||||||
|
|
@ -660,7 +665,10 @@ int get_instruction_byte_size(const char *opname) {
|
||||||
strcmp(opname, "load_immediate") == 0 ||
|
strcmp(opname, "load_immediate") == 0 ||
|
||||||
strcmp(opname, "load_address") == 0 ||
|
strcmp(opname, "load_address") == 0 ||
|
||||||
strcmp(opname, "load_absolute_16") == 0 ||
|
strcmp(opname, "load_absolute_16") == 0 ||
|
||||||
strcmp(opname, "load_absolute_8") == 0) {
|
strcmp(opname, "load_absolute_8") == 0 ||
|
||||||
|
strcmp(opname, "store_absolute_32") == 0 ||
|
||||||
|
strcmp(opname, "store_absolute_8") == 0 ||
|
||||||
|
strcmp(opname, "store_absolute_16") == 0) {
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -697,11 +705,14 @@ int get_instruction_byte_size(const char *opname) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FAKE_OP(op) \
|
#define FAKE_OP(op) \
|
||||||
} \
|
} else if (strleq(token.start, op, token.length)) { \
|
||||||
else if (strleq(token.start, op, token.length)) { \
|
do { \
|
||||||
while (token.type != TOKEN_SEMICOLON) \
|
while (token.type != TOKEN_SEMICOLON) { \
|
||||||
token = next_token(); \
|
token = next_token(); \
|
||||||
vm->cp += get_instruction_byte_size(op);
|
} \
|
||||||
|
/*printf("code[%d]=%s\n %d + %d = %d\n", vm->cp, op, get_instruction_byte_size(op), vm->cp, vm->cp + get_instruction_byte_size(op)); */\
|
||||||
|
vm->cp += get_instruction_byte_size(op); \
|
||||||
|
} while(0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build the symbol table and calculate the types/size/offsets of all values.
|
* Build the symbol table and calculate the types/size/offsets of all values.
|
||||||
|
|
@ -760,6 +771,9 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
printf("-- %.*s --\n", token.length, token.start);
|
||||||
|
#endif
|
||||||
if (token.type == TOKEN_IDENTIFIER) {
|
if (token.type == TOKEN_IDENTIFIER) {
|
||||||
// check to see if it is an opcode first
|
// check to see if it is an opcode first
|
||||||
if (strleq(token.start, "exit", token.length)) {
|
if (strleq(token.start, "exit", token.length)) {
|
||||||
|
|
@ -769,6 +783,10 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) {
|
||||||
next_token();
|
next_token();
|
||||||
vm->cp += 4;
|
vm->cp += 4;
|
||||||
|
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
printf("code[%d] = exit\n", vm->cp);
|
||||||
|
#endif
|
||||||
|
|
||||||
next_token_is(TOKEN_SEMICOLON);
|
next_token_is(TOKEN_SEMICOLON);
|
||||||
} else if (strleq(token.start, "call", token.length)) {
|
} else if (strleq(token.start, "call", token.length)) {
|
||||||
|
|
||||||
|
|
@ -777,27 +795,27 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) {
|
||||||
next_token_is(TOKEN_IDENTIFIER);
|
next_token_is(TOKEN_IDENTIFIER);
|
||||||
vm->cp += 4;
|
vm->cp += 4;
|
||||||
|
|
||||||
bool has_return = false;
|
|
||||||
u8 arg_count = 0;
|
|
||||||
vm->cp++;
|
vm->cp++;
|
||||||
|
Token next = next_token_is(TOKEN_LPAREN);
|
||||||
Token next = next_token();
|
next = next_token();
|
||||||
while (next.type != TOKEN_SEMICOLON) {
|
while (next.type != TOKEN_RPAREN) {
|
||||||
if (next.type != TOKEN_ARROW_RIGHT) {
|
|
||||||
get_reg(next, st);
|
get_reg(next, st);
|
||||||
vm->cp++;
|
vm->cp++;
|
||||||
arg_count++;
|
|
||||||
} else {
|
|
||||||
has_return = true;
|
|
||||||
arg_count--; // is a return not an arg
|
|
||||||
}
|
|
||||||
next = next_token();
|
next = next_token();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_return) {
|
next = next_token();
|
||||||
|
if (next.type == TOKEN_SEMICOLON) {
|
||||||
|
vm->cp++;
|
||||||
|
} else {
|
||||||
|
next = next_token();
|
||||||
|
get_reg(next, st);
|
||||||
vm->cp++;
|
vm->cp++;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
printf("code[%d] = call\n", vm->cp);
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
} else if (strleq(token.start, "syscall", token.length)) {
|
} else if (strleq(token.start, "syscall", token.length)) {
|
||||||
|
|
||||||
vm->cp++;
|
vm->cp++;
|
||||||
|
|
@ -807,13 +825,14 @@ void build_symbol_table(VM *vm, char *source, SymbolTable *st) {
|
||||||
|
|
||||||
next = next_token();
|
next = next_token();
|
||||||
while (next.type != TOKEN_SEMICOLON) {
|
while (next.type != TOKEN_SEMICOLON) {
|
||||||
if (next.type != TOKEN_ARROW_RIGHT) {
|
|
||||||
get_reg(next, st);
|
get_reg(next, st);
|
||||||
vm->cp++;
|
vm->cp++;
|
||||||
}
|
|
||||||
next = next_token();
|
next = next_token();
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
printf("code[%d] = syscall\n", vm->cp);
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
FAKE_OP("load_immediate")
|
FAKE_OP("load_immediate")
|
||||||
FAKE_OP("load_address")
|
FAKE_OP("load_address")
|
||||||
FAKE_OP("malloc")
|
FAKE_OP("malloc")
|
||||||
|
|
@ -982,6 +1001,9 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
printf("-- %.*s --\n", token.length, token.start);
|
||||||
|
#endif
|
||||||
if (token.type == TOKEN_IDENTIFIER) {
|
if (token.type == TOKEN_IDENTIFIER) {
|
||||||
// check to see if it is an opcode first
|
// check to see if it is an opcode first
|
||||||
if (strleq(token.start, "exit", token.length)) {
|
if (strleq(token.start, "exit", token.length)) {
|
||||||
|
|
@ -1005,35 +1027,36 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) {
|
||||||
emit_u32(vm, ptr);
|
emit_u32(vm, ptr);
|
||||||
vm->cp += 4;
|
vm->cp += 4;
|
||||||
|
|
||||||
bool has_return = false;
|
|
||||||
u8 arg_count = 0;
|
u8 arg_count = 0;
|
||||||
u32 arg_pos = vm->cp++;
|
u32 arg_pos = vm->cp++;
|
||||||
printf("vm->code[%d] = ?\n", arg_pos);
|
Token next = next_token_is(TOKEN_LPAREN);
|
||||||
|
next = next_token();
|
||||||
Token next = next_token();
|
while (next.type != TOKEN_RPAREN) {
|
||||||
while (next.type != TOKEN_SEMICOLON) {
|
|
||||||
if (next.type != TOKEN_ARROW_RIGHT) {
|
|
||||||
u8 arg = get_reg(next, st);
|
u8 arg = get_reg(next, st);
|
||||||
emit_byte(vm, arg);
|
emit_byte(vm, arg);
|
||||||
vm->cp++;
|
vm->cp++;
|
||||||
arg_count++;
|
arg_count++;
|
||||||
} else {
|
|
||||||
has_return = true;
|
|
||||||
arg_count--; // is a return not an arg
|
|
||||||
}
|
|
||||||
next = next_token();
|
next = next_token();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* patch number of args */
|
|
||||||
vm->code[arg_pos] = arg_count;
|
vm->code[arg_pos] = arg_count;
|
||||||
|
|
||||||
printf("^vm->code[%d] = %d\n", arg_pos, arg_count);
|
#ifdef DEBUG_PRINT
|
||||||
|
printf("^code[%d] = %d\n", arg_pos, arg_count);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!has_return) {
|
next = next_token();
|
||||||
vm->cp++;
|
if (next.type == TOKEN_SEMICOLON) {
|
||||||
emit_byte(vm, 255);
|
emit_byte(vm, 255);
|
||||||
continue;
|
vm->cp++;
|
||||||
|
} else {
|
||||||
|
next = next_token();
|
||||||
|
u8 arg = get_reg(next, st);
|
||||||
|
emit_byte(vm, arg);
|
||||||
|
vm->cp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
} else if (strleq(token.start, "syscall", token.length)) {
|
} else if (strleq(token.start, "syscall", token.length)) {
|
||||||
|
|
||||||
emit_op(vm, OP_SYSCALL);
|
emit_op(vm, OP_SYSCALL);
|
||||||
|
|
@ -1062,15 +1085,20 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) {
|
||||||
vm->cp += 4;
|
vm->cp += 4;
|
||||||
|
|
||||||
next = next_token();
|
next = next_token();
|
||||||
while (next.type != TOKEN_SEMICOLON) {
|
while (next.type != TOKEN_SEMICOLON && next.type != TOKEN_ARROW_RIGHT) {
|
||||||
if (next.type != TOKEN_ARROW_RIGHT) {
|
|
||||||
u8 arg =get_reg(next, st);
|
u8 arg =get_reg(next, st);
|
||||||
emit_byte(vm, arg);
|
emit_byte(vm, arg);
|
||||||
vm->cp++;
|
vm->cp++;
|
||||||
}
|
|
||||||
next = next_token();
|
next = next_token();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (next.type == TOKEN_ARROW_RIGHT) {
|
||||||
|
next = next_token();
|
||||||
|
u8 arg = get_reg(next, st);
|
||||||
|
emit_byte(vm, arg);
|
||||||
|
vm->cp++;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (strleq(token.start, "load_immediate", token.length)) {
|
} else if (strleq(token.start, "load_immediate", token.length)) {
|
||||||
|
|
||||||
emit_op(vm, OP_LOAD_IMM);
|
emit_op(vm, OP_LOAD_IMM);
|
||||||
|
|
@ -1168,6 +1196,8 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) {
|
||||||
emit_byte(vm, arg);
|
emit_byte(vm, arg);
|
||||||
vm->cp++;
|
vm->cp++;
|
||||||
|
|
||||||
|
next_token_is(TOKEN_ARROW_RIGHT);
|
||||||
|
|
||||||
reg = next_token();
|
reg = next_token();
|
||||||
arg = get_reg(reg, st);
|
arg = get_reg(reg, st);
|
||||||
emit_byte(vm, arg);
|
emit_byte(vm, arg);
|
||||||
|
|
@ -1188,6 +1218,8 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) {
|
||||||
emit_byte(vm, arg);
|
emit_byte(vm, arg);
|
||||||
vm->cp++;
|
vm->cp++;
|
||||||
|
|
||||||
|
next_token_is(TOKEN_ARROW_RIGHT);
|
||||||
|
|
||||||
reg = next_token();
|
reg = next_token();
|
||||||
arg = get_reg(reg, st);
|
arg = get_reg(reg, st);
|
||||||
emit_byte(vm, arg);
|
emit_byte(vm, arg);
|
||||||
|
|
@ -1208,6 +1240,8 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) {
|
||||||
emit_byte(vm, arg);
|
emit_byte(vm, arg);
|
||||||
vm->cp++;
|
vm->cp++;
|
||||||
|
|
||||||
|
next_token_is(TOKEN_ARROW_RIGHT);
|
||||||
|
|
||||||
reg = next_token();
|
reg = next_token();
|
||||||
arg = get_reg(reg, st);
|
arg = get_reg(reg, st);
|
||||||
emit_byte(vm, arg);
|
emit_byte(vm, arg);
|
||||||
|
|
@ -1444,10 +1478,10 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) {
|
||||||
|
|
||||||
next_token_is(TOKEN_ARROW_RIGHT);
|
next_token_is(TOKEN_ARROW_RIGHT);
|
||||||
|
|
||||||
Token id = next_token();
|
reg = next_token();
|
||||||
u32 ptr = get_ptr(id, st);
|
arg = get_reg(reg, st);
|
||||||
emit_u32(vm, ptr);
|
emit_byte(vm, arg);
|
||||||
vm->cp += 4;
|
vm->cp++;
|
||||||
|
|
||||||
next_token_is(TOKEN_SEMICOLON);
|
next_token_is(TOKEN_SEMICOLON);
|
||||||
} else if (strleq(token.start, "store_indirect_16", token.length)) {
|
} else if (strleq(token.start, "store_indirect_16", token.length)) {
|
||||||
|
|
@ -1461,10 +1495,10 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) {
|
||||||
|
|
||||||
next_token_is(TOKEN_ARROW_RIGHT);
|
next_token_is(TOKEN_ARROW_RIGHT);
|
||||||
|
|
||||||
Token id = next_token();
|
reg = next_token();
|
||||||
u32 ptr = get_ptr(id, st);
|
arg = get_reg(reg, st);
|
||||||
emit_u32(vm, ptr);
|
emit_byte(vm, arg);
|
||||||
vm->cp += 4;
|
vm->cp++;
|
||||||
|
|
||||||
next_token_is(TOKEN_SEMICOLON);
|
next_token_is(TOKEN_SEMICOLON);
|
||||||
} else if (strleq(token.start, "store_indirect_32", token.length)) {
|
} else if (strleq(token.start, "store_indirect_32", token.length)) {
|
||||||
|
|
@ -1478,10 +1512,10 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) {
|
||||||
|
|
||||||
next_token_is(TOKEN_ARROW_RIGHT);
|
next_token_is(TOKEN_ARROW_RIGHT);
|
||||||
|
|
||||||
Token id = next_token();
|
reg = next_token();
|
||||||
u32 ptr = get_ptr(id, st);
|
arg = get_reg(reg, st);
|
||||||
emit_u32(vm, ptr);
|
emit_byte(vm, arg);
|
||||||
vm->cp += 4;
|
vm->cp++;
|
||||||
|
|
||||||
next_token_is(TOKEN_SEMICOLON);
|
next_token_is(TOKEN_SEMICOLON);
|
||||||
} else if (strleq(token.start, "store_offset_8", token.length)) {
|
} else if (strleq(token.start, "store_offset_8", token.length)) {
|
||||||
|
|
@ -2383,11 +2417,8 @@ void emit_bytecode(VM *vm, char *source, SymbolTable *st) {
|
||||||
/**
|
/**
|
||||||
* Emit bytecode to the VM from the source string.
|
* Emit bytecode to the VM from the source string.
|
||||||
*/
|
*/
|
||||||
void assemble(VM *vm, char *source) {
|
void assemble(VM *vm, SymbolTable *st, char *source) {
|
||||||
SymbolTable st = {0};
|
build_symbol_table(vm, source, st);
|
||||||
symbol_table_init(&st);
|
vm->cp = 0; /* actually start emitting code */
|
||||||
build_symbol_table(vm, source, &st);
|
emit_bytecode(vm, source, st);
|
||||||
vm->cp = 0; /* actuall start emitting code */
|
|
||||||
emit_bytecode(vm, source, &st);
|
|
||||||
free(st.symbols);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,9 @@ struct symbol_tab_s {
|
||||||
u32 capacity;
|
u32 capacity;
|
||||||
};
|
};
|
||||||
|
|
||||||
void assemble(VM *vm, char *source);
|
void assemble(VM *vm, SymbolTable *st, char *source);
|
||||||
|
extern bool resize_or_check_size(SymbolTable *table);/* implement this in arch/ not here */
|
||||||
|
|
||||||
|
const char *opcode_to_string(Opcode op);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,10 @@ struct names_tab_s {
|
||||||
u32 capacity;
|
u32 capacity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME:
|
||||||
|
* Symbols need to be inside a scope so we can have duplicates
|
||||||
|
*/
|
||||||
struct symbol_tab_s {
|
struct symbol_tab_s {
|
||||||
Symbol *symbols;
|
Symbol *symbols;
|
||||||
u32 count;
|
u32 count;
|
||||||
|
|
|
||||||
21
src/vm/vm.c
21
src/vm/vm.c
|
|
@ -349,37 +349,34 @@ bool step_vm(VM *vm) {
|
||||||
}
|
}
|
||||||
case OP_STORE_ABS_32: {
|
case OP_STORE_ABS_32: {
|
||||||
u32 v, ptr;
|
u32 v, ptr;
|
||||||
u8 dest, src1;
|
u8 src1;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
dest = read_u8(vm, code, vm->pc);
|
ptr = read_u32(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc += 4;
|
||||||
v = frame->locals[src1];
|
v = frame->locals[src1];
|
||||||
ptr = frame->locals[dest];
|
|
||||||
write_u32(vm, memory, ptr, v);
|
write_u32(vm, memory, ptr, v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_STORE_ABS_16: {
|
case OP_STORE_ABS_16: {
|
||||||
u32 v, ptr;
|
u32 v, ptr;
|
||||||
u8 dest, src1;
|
u8 src1;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
dest = read_u8(vm, code, vm->pc);
|
ptr = read_u32(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc += 4;
|
||||||
v = frame->locals[src1];
|
v = frame->locals[src1];
|
||||||
ptr = frame->locals[dest];
|
|
||||||
write_u16(vm, memory, ptr, v);
|
write_u16(vm, memory, ptr, v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_STORE_ABS_8: {
|
case OP_STORE_ABS_8: {
|
||||||
u32 v, ptr;
|
u32 v, ptr;
|
||||||
u8 dest, src1;
|
u8 src1;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
dest = read_u8(vm, code, vm->pc);
|
ptr = read_u32(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc += 4;
|
||||||
v = frame->locals[src1];
|
v = frame->locals[src1];
|
||||||
ptr = frame->locals[dest];
|
|
||||||
write_u8(vm, memory, ptr, v);
|
write_u8(vm, memory, ptr, v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
((code
|
|
||||||
(label main
|
|
||||||
(load-immediate $0 1)
|
|
||||||
(load-immediate $1 1)
|
|
||||||
(call &add ($0 $1) $2)
|
|
||||||
(int-to-string $3 $2)
|
|
||||||
(call &pln ($3) nil)
|
|
||||||
(exit 0))
|
|
||||||
|
|
||||||
(label add
|
|
||||||
(add-int $2 $1 $0)
|
|
||||||
(return $2))
|
|
||||||
|
|
||||||
(label pln
|
|
||||||
(load-immediate $1 &terminal-namespace) ; get terminal device
|
|
||||||
(load-immediate $11 0)
|
|
||||||
(syscall OPEN $1 $1 $11)
|
|
||||||
(string-length $2 $0)
|
|
||||||
(syscall WRITE $1 $0 $2)
|
|
||||||
(load-immediate $3 &new-line)
|
|
||||||
(string-length $4 $3)
|
|
||||||
(syscall WRITE $1 $3 $4)
|
|
||||||
(return nil)))
|
|
||||||
(data
|
|
||||||
(label terminal-namespace "/dev/term/0")
|
|
||||||
(label new-line "\n")))
|
|
||||||
Binary file not shown.
|
|
@ -6,9 +6,9 @@ global int y = 1;
|
||||||
function main ()
|
function main ()
|
||||||
load_absolute_32 x -> $0;
|
load_absolute_32 x -> $0;
|
||||||
load_absolute_32 y -> $1;
|
load_absolute_32 y -> $1;
|
||||||
call add $0 $1 -> $2;
|
call add ($0 $1) -> $2;
|
||||||
int_to_string $2 -> $3;
|
int_to_string $2 -> $3;
|
||||||
call pln $3;
|
call pln ($3);
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
function add (int a $0, int b $1)
|
function add (int a $0, int b $1)
|
||||||
|
|
@ -26,7 +26,7 @@ function pln (str message $0)
|
||||||
|
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
load_address terminal_namespace -> term_ns;
|
load_address terminal_namespace -> term_ns;
|
||||||
syscall OPEN term_ns mode -> term;
|
syscall OPEN term_ns mode term;
|
||||||
string_length message -> msg_length;
|
string_length message -> msg_length;
|
||||||
syscall WRITE term message msg_length;
|
syscall WRITE term message msg_length;
|
||||||
load_address new_line -> nl;
|
load_address new_line -> nl;
|
||||||
|
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
((code
|
|
||||||
(label main
|
|
||||||
(load-immediate $0 35)
|
|
||||||
(call &fib ($0) $0)
|
|
||||||
(int-to-string $1 $0)
|
|
||||||
(call &pln ($1) nil)
|
|
||||||
(exit 0))
|
|
||||||
(label fib
|
|
||||||
(load-immediate $1 2)
|
|
||||||
(jump-lt-int &base-case $0 $1)
|
|
||||||
(load-immediate $3 2)
|
|
||||||
(sub-int $4 $0 $3)
|
|
||||||
(call &fib ($4) $5)
|
|
||||||
(load-immediate $3 1)
|
|
||||||
(sub-int $4 $0 $3)
|
|
||||||
(call &fib ($4) $6)
|
|
||||||
(add-int $7 $6 $5)
|
|
||||||
(return $7)
|
|
||||||
(label base-case
|
|
||||||
(return $0)))
|
|
||||||
(label pln
|
|
||||||
(load-immediate $1 &terminal-namespace) ; get terminal device
|
|
||||||
(load-immediate $11 0)
|
|
||||||
(syscall OPEN $1 $1 $11)
|
|
||||||
(load-immediate $3 &new-line)
|
|
||||||
(string-length $2 $0)
|
|
||||||
(syscall WRITE $1 $0 $2)
|
|
||||||
(string-length $4 $3)
|
|
||||||
(syscall WRITE $1 $3 $4)
|
|
||||||
(return nil)))
|
|
||||||
(data
|
|
||||||
(label terminal-namespace "/dev/term/0")
|
|
||||||
(label new-line "\n")))
|
|
||||||
Binary file not shown.
|
|
@ -4,10 +4,10 @@ global str new_line = "\n";
|
||||||
function main ()
|
function main ()
|
||||||
int str_n $1;
|
int str_n $1;
|
||||||
|
|
||||||
load_immediate 36 -> $0;
|
load_immediate 35 -> $0;
|
||||||
call fib $0 -> $0;
|
call fib ($0) -> $0;
|
||||||
int_to_string $0 -> str_n;
|
int_to_string $0 -> str_n;
|
||||||
call pln str_n;
|
call pln (str_n);
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
function fib (int n $0)
|
function fib (int n $0)
|
||||||
|
|
@ -17,11 +17,11 @@ function fib (int n $0)
|
||||||
|
|
||||||
load_immediate 2 -> $3;
|
load_immediate 2 -> $3;
|
||||||
sub_int n $3 -> $4;
|
sub_int n $3 -> $4;
|
||||||
call fib $4 -> $5;
|
call fib ($4) -> $5;
|
||||||
|
|
||||||
load_immediate 1 -> $3;
|
load_immediate 1 -> $3;
|
||||||
sub_int n $3 -> $4;
|
sub_int n $3 -> $4;
|
||||||
call fib $4 -> $6;
|
call fib ($4) -> $6;
|
||||||
|
|
||||||
add_int $6 $5 -> $7;
|
add_int $6 $5 -> $7;
|
||||||
return $7;
|
return $7;
|
||||||
|
|
@ -39,7 +39,7 @@ function pln (str message $0)
|
||||||
|
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
load_address terminal_namespace -> term_ns;
|
load_address terminal_namespace -> term_ns;
|
||||||
syscall OPEN term_ns mode -> term;
|
syscall OPEN term_ns mode term;
|
||||||
string_length message -> msg_length;
|
string_length message -> msg_length;
|
||||||
syscall WRITE term message msg_length;
|
syscall WRITE term message msg_length;
|
||||||
load_address new_line -> nl;
|
load_address new_line -> nl;
|
||||||
|
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
((code
|
|
||||||
(label main
|
|
||||||
(load-immediate $1 &hello-str) ; load hello string ptr
|
|
||||||
(call &pln ($1) nil)
|
|
||||||
(exit 0)) ; done
|
|
||||||
(label pln
|
|
||||||
(load-immediate $1 &terminal-namespace) ; get terminal device
|
|
||||||
(load-immediate $11 0)
|
|
||||||
(syscall OPEN $1 $1 $11)
|
|
||||||
(load-immediate $3 &new-line)
|
|
||||||
(string-length $2 $0)
|
|
||||||
(syscall WRITE $1 $0 $2)
|
|
||||||
(string-length $4 $3)
|
|
||||||
(syscall WRITE $1 $3 $4)
|
|
||||||
(return nil)))
|
|
||||||
(data
|
|
||||||
(label terminal-namespace "/dev/term/0")
|
|
||||||
(label new-line "\n")
|
|
||||||
(label hello-str "nuqneH 'u'?")))
|
|
||||||
Binary file not shown.
|
|
@ -6,7 +6,7 @@ function main ()
|
||||||
str msg $0;
|
str msg $0;
|
||||||
|
|
||||||
load_address hello -> msg;
|
load_address hello -> msg;
|
||||||
call pln msg;
|
call pln (msg);
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
function pln (str message $0)
|
function pln (str message $0)
|
||||||
|
|
@ -19,7 +19,7 @@ function pln (str message $0)
|
||||||
|
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
load_address terminal_namespace -> term_ns;
|
load_address terminal_namespace -> term_ns;
|
||||||
syscall OPEN term_ns mode -> term;
|
syscall OPEN term_ns mode term;
|
||||||
string_length message -> msg_length;
|
string_length message -> msg_length;
|
||||||
syscall WRITE term message msg_length;
|
syscall WRITE term message msg_length;
|
||||||
load_address new_line -> nl;
|
load_address new_line -> nl;
|
||||||
|
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
((code
|
|
||||||
(label main
|
|
||||||
(load-immediate $0 5.0)
|
|
||||||
(load-immediate $1 5000)
|
|
||||||
(load-immediate $2 0)
|
|
||||||
(load-immediate $3 -1)
|
|
||||||
(load-immediate $5 5.0)
|
|
||||||
(label loop-body
|
|
||||||
(add-real $0 $0 $5)
|
|
||||||
(add-int $1 $1 $3)
|
|
||||||
(jump-ge-int &loop-body $1 $2))
|
|
||||||
(load-immediate $10 &terminal-namespace)
|
|
||||||
(load-immediate $11 0)
|
|
||||||
(syscall OPEN $10 $10 $11) ; Terminal term = open(namespace, flags)
|
|
||||||
|
|
||||||
(real-to-nat $1 $0)
|
|
||||||
(load-immediate $7 &prompt)
|
|
||||||
(string-length $8 $7)
|
|
||||||
(syscall WRITE $10 $7 $8) ; print prompt
|
|
||||||
|
|
||||||
(load-immediate $8 32)
|
|
||||||
(malloc $11 $8)
|
|
||||||
(syscall READ $10 $11 $8) ; read in max 32 byte string
|
|
||||||
|
|
||||||
(call &pln ($11) nil)
|
|
||||||
(nat-to-string $4 $1)
|
|
||||||
(call &pln ($4) nil)
|
|
||||||
(real-to-string $3 $0)
|
|
||||||
(call &pln ($3) nil)
|
|
||||||
(exit 0))
|
|
||||||
(label pln
|
|
||||||
(load-immediate $1 &terminal-namespace) ; get terminal device
|
|
||||||
(load-immediate $11 0)
|
|
||||||
(syscall OPEN $1 $1 $11)
|
|
||||||
(load-immediate $3 &new-line)
|
|
||||||
(string-length $2 $0)
|
|
||||||
(syscall WRITE $1 $0 $2)
|
|
||||||
(string-length $4 $3)
|
|
||||||
(syscall WRITE $1 $3 $4)
|
|
||||||
(return nil)))
|
|
||||||
(data
|
|
||||||
(label terminal-namespace "/dev/term/0")
|
|
||||||
(label prompt "Enter a string: ")
|
|
||||||
(label new-line "\n")))
|
|
||||||
Binary file not shown.
|
|
@ -20,7 +20,7 @@ function main ()
|
||||||
|
|
||||||
load_address terminal_namespace -> in_term;
|
load_address terminal_namespace -> in_term;
|
||||||
load_immediate 0 -> in_mode;
|
load_immediate 0 -> in_mode;
|
||||||
syscall OPEN in_term in_mode -> in_term; // Terminal term = open("/dev/term/0", 0);
|
syscall OPEN in_term in_mode in_term; // Terminal term = open("/dev/term/0", 0);
|
||||||
|
|
||||||
nat b $1;
|
nat b $1;
|
||||||
real_to_nat a -> b;
|
real_to_nat a -> b;
|
||||||
|
|
@ -33,11 +33,11 @@ function main ()
|
||||||
malloc $8 -> user_string;
|
malloc $8 -> user_string;
|
||||||
syscall READ in_term user_string $8; // read in max 32 byte string
|
syscall READ in_term user_string $8; // read in max 32 byte string
|
||||||
|
|
||||||
call pln user_string;
|
call pln (user_string);
|
||||||
nat_to_string b -> $4;
|
nat_to_string b -> $4;
|
||||||
call pln $4;
|
call pln ($4);
|
||||||
real_to_string a -> $3;
|
real_to_string a -> $3;
|
||||||
call pln $3;
|
call pln ($3);
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
function pln (str message $0)
|
function pln (str message $0)
|
||||||
|
|
@ -49,7 +49,7 @@ function pln (str message $0)
|
||||||
|
|
||||||
load_address terminal_namespace -> term;
|
load_address terminal_namespace -> term;
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
syscall OPEN term mode -> term; // Terminal term = open("/dev/term/0", 0);
|
syscall OPEN term mode term; // Terminal term = open("/dev/term/0", 0);
|
||||||
string_length message -> msg_length;
|
string_length message -> msg_length;
|
||||||
syscall WRITE term message msg_length;
|
syscall WRITE term message msg_length;
|
||||||
load_address new_line -> nl;
|
load_address new_line -> nl;
|
||||||
|
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
((code
|
|
||||||
(label main
|
|
||||||
(load-immediate $0 &terminal-namespace) ; get terminal device
|
|
||||||
(load-immediate $11 0)
|
|
||||||
(syscall OPEN $0 $0 $11)
|
|
||||||
|
|
||||||
(load-immediate $1 &help) ; print help message
|
|
||||||
(call &pln ($0 $1) nil)
|
|
||||||
|
|
||||||
(load-immediate $1 32) ; read in a string of max 32 char length
|
|
||||||
(malloc $4 $1) ; allocate memory for the string
|
|
||||||
(syscall READ $0 $4 $1) ; read the string
|
|
||||||
|
|
||||||
(call &pln ($0 $4) nil) ; print the string
|
|
||||||
(exit 0))
|
|
||||||
(label pln
|
|
||||||
(load-immediate $3 &new-line)
|
|
||||||
(string-length $2 $1)
|
|
||||||
(syscall WRITE $0 $1 $2)
|
|
||||||
(string-length $4 $3)
|
|
||||||
(syscall WRITE $0 $3 $4)
|
|
||||||
(return nil)))
|
|
||||||
(data
|
|
||||||
(label terminal-namespace "/dev/term/0")
|
|
||||||
(label help "Enter a string: ")
|
|
||||||
(label new-line "\n")))
|
|
||||||
Binary file not shown.
|
|
@ -8,7 +8,7 @@ function main ()
|
||||||
|
|
||||||
load_address terminal_namespace -> in_term;
|
load_address terminal_namespace -> in_term;
|
||||||
load_immediate 0 -> in_mode;
|
load_immediate 0 -> in_mode;
|
||||||
syscall OPEN in_term in_mode -> in_term; // Terminal term = open("/dev/term/0", 0);
|
syscall OPEN in_term in_mode in_term; // Terminal term = open("/dev/term/0", 0);
|
||||||
|
|
||||||
load_address prompt -> $7;
|
load_address prompt -> $7;
|
||||||
string_length $7 -> $8;
|
string_length $7 -> $8;
|
||||||
|
|
@ -19,7 +19,7 @@ function main ()
|
||||||
malloc $8 -> user_string;
|
malloc $8 -> user_string;
|
||||||
syscall READ in_term user_string $8; // read in max 32 byte string
|
syscall READ in_term user_string $8; // read in max 32 byte string
|
||||||
|
|
||||||
call pln user_string;
|
call pln (user_string);
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
function pln (str message $0)
|
function pln (str message $0)
|
||||||
|
|
@ -32,10 +32,11 @@ function pln (str message $0)
|
||||||
|
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
load_address terminal_namespace -> term_ns;
|
load_address terminal_namespace -> term_ns;
|
||||||
syscall OPEN term_ns mode -> term;
|
syscall OPEN term_ns mode term;
|
||||||
string_length message -> msg_length;
|
string_length message -> msg_length;
|
||||||
syscall WRITE term message msg_length;
|
syscall WRITE term message msg_length;
|
||||||
load_address new_line -> nl;
|
load_address new_line -> nl;
|
||||||
string_length nl -> nl_length;
|
string_length nl -> nl_length;
|
||||||
syscall WRITE term nl nl_length;
|
syscall WRITE term nl nl_length;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1,147 +0,0 @@
|
||||||
((code
|
|
||||||
(label main
|
|
||||||
; Open screen
|
|
||||||
; use load immediate because it is a pointer to a string, not a value
|
|
||||||
(load-immediate $0 &screen-namespace)
|
|
||||||
(load-immediate $11 0)
|
|
||||||
(syscall OPEN $0 $18 $11) ; open(out Plex screen, in namespace, in flags)
|
|
||||||
|
|
||||||
(load-offset-32 $20 $0 8) ; load width
|
|
||||||
(load-offset-32 $22 $0 12) ; load size
|
|
||||||
(load-immediate $1 16) ; offset for screen buffer
|
|
||||||
(add-nat $21 $0 $1)
|
|
||||||
|
|
||||||
; open mouse
|
|
||||||
(load-immediate $16 &mouse-namespace)
|
|
||||||
(syscall OPEN $15 $16 $11) ; open(out Plex mouse, in namespace, in flags)
|
|
||||||
|
|
||||||
; outline_swatch(screen, BLACK, 1, 1);
|
|
||||||
(load-absolute-32 $1 &BLACK)
|
|
||||||
(load-immediate $12 1)
|
|
||||||
(load-immediate $13 1)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
|
|
||||||
; outline_swatch(screen, WHITE, 1, 1);
|
|
||||||
(load-absolute-32 $1 &WHITE)
|
|
||||||
(load-immediate $12 21)
|
|
||||||
(load-immediate $13 1)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
|
|
||||||
; screen.draw();
|
|
||||||
(syscall WRITE $0 $21 $22)
|
|
||||||
|
|
||||||
(label draw-loop
|
|
||||||
; load mouse click data
|
|
||||||
(syscall REFRESH $15)
|
|
||||||
(load-offset-8 $9 $15 16) ; load btn1 pressed
|
|
||||||
|
|
||||||
(jump-eq-nat &draw-loop $9 $11)
|
|
||||||
|
|
||||||
(load-offset-32 $7 $15 8) ; load x
|
|
||||||
(load-offset-32 $8 $15 12) ; load y
|
|
||||||
|
|
||||||
(load-immediate $14 20) ; box size
|
|
||||||
|
|
||||||
; first row
|
|
||||||
(load-absolute-32 $1 &BLACK)
|
|
||||||
(load-immediate $12 1)
|
|
||||||
(load-immediate $13 1)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
|
|
||||||
(call &set-color-if-clicked ($7 $8 $12 $13 $1 $14) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &WHITE)
|
|
||||||
(load-immediate $12 21)
|
|
||||||
(load-immediate $13 1)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
|
|
||||||
(call &set-color-if-clicked ($7 $8 $12 $13 $1 $14) nil)
|
|
||||||
|
|
||||||
(syscall WRITE $0 $21 $22)
|
|
||||||
|
|
||||||
(load-absolute-32 $22 &SELECTED-COLOR) ; color
|
|
||||||
(load-immediate $1 5) ; size of brush
|
|
||||||
|
|
||||||
(call &draw-box ($21 $20 $22 $7 $8 $1 $1) nil)
|
|
||||||
|
|
||||||
(jump &draw-loop))
|
|
||||||
|
|
||||||
; Flush and exit
|
|
||||||
(exit 0))
|
|
||||||
|
|
||||||
(label set-color-if-clicked
|
|
||||||
; (click_x, click_y, box_x, box_y, color, box_size)
|
|
||||||
|
|
||||||
; Compute right = box_x + box_size
|
|
||||||
(add-int $6 $2 $5) ; $6 = right edge
|
|
||||||
|
|
||||||
; Compute bottom = box_y + box_size
|
|
||||||
(add-int $7 $3 $5) ; $7 = bottom edge
|
|
||||||
|
|
||||||
; Bounds check: x in [box_x, right] and y in [box_y, bottom]
|
|
||||||
(jump-lt-int &fail $0 $2)
|
|
||||||
(jump-gt-int &fail $0 $6)
|
|
||||||
(jump-lt-int &fail $1 $3)
|
|
||||||
(jump-gt-int &fail $1 $7)
|
|
||||||
|
|
||||||
(load-immediate $10 &SELECTED-COLOR)
|
|
||||||
(store-absolute-8 $10 $4)
|
|
||||||
|
|
||||||
(label fail)
|
|
||||||
(return nil))
|
|
||||||
|
|
||||||
(label draw-outlined-swatch
|
|
||||||
; (base, color, x, y, width)
|
|
||||||
|
|
||||||
; Constants
|
|
||||||
(load-absolute-32 $5 &GRAY)
|
|
||||||
(load-absolute-32 $10 &SELECTED-COLOR)
|
|
||||||
(jump-eq-int &set-selected $10 $1)
|
|
||||||
(jump-eq-int &end-set-selected $5 $5)
|
|
||||||
(label set-selected)
|
|
||||||
(load-absolute-32 $5 &DARK-GRAY)
|
|
||||||
(label end-set-selected)
|
|
||||||
|
|
||||||
(load-immediate $6 20) ; outline size
|
|
||||||
(load-immediate $7 17) ; fill size
|
|
||||||
(load-immediate $8 2) ; offset
|
|
||||||
|
|
||||||
(call &draw-box ($0 $4 $5 $2 $3 $6 $6) nil)
|
|
||||||
|
|
||||||
(add-int $9 $2 $8) ; x + 2
|
|
||||||
(add-int $10 $3 $8) ; y + 2
|
|
||||||
|
|
||||||
(call &draw-box ($0 $4 $1 $9 $10 $7 $7) nil)
|
|
||||||
|
|
||||||
(return nil))
|
|
||||||
|
|
||||||
(label draw-box
|
|
||||||
; (base, screen_width, color, x_start, y_start, width, height)
|
|
||||||
|
|
||||||
; Compute start address: base + y*640 + x
|
|
||||||
(mul-int $15 $4 $1) ; $15 = y * 640
|
|
||||||
(add-int $15 $15 $3) ; $15 += x
|
|
||||||
(add-nat $15 $0 $15) ; $15 = base + pixel_offset
|
|
||||||
(load-immediate $25 4)
|
|
||||||
(add-nat $15 $15 $25) ; need to add offset for fat pointer size
|
|
||||||
|
|
||||||
; Outer loop: height times
|
|
||||||
(load-immediate $30 1) ; increment
|
|
||||||
|
|
||||||
(label draw-box-outer
|
|
||||||
(add-int $27 $15 $5) ; $27 = row end = current + width
|
|
||||||
(register-move $29 $15) ; $7 = pixel pointer
|
|
||||||
(memset-8 $29 $2 $5) ; draw row
|
|
||||||
(add-int $15 $15 $1) ; next row (+= 640)
|
|
||||||
(sub-int $6 $6 $30) ; decrement row count
|
|
||||||
(jump-gt-int &draw-box-outer $6 0))
|
|
||||||
(return nil)))
|
|
||||||
(data
|
|
||||||
(label screen-namespace "/dev/screen/0")
|
|
||||||
(label mouse-namespace "/dev/mouse/0")
|
|
||||||
(label SELECTED-COLOR 255)
|
|
||||||
(label BLACK 0)
|
|
||||||
(label WHITE 255)
|
|
||||||
(label DARK-GRAY 73)
|
|
||||||
(label GRAY 146)
|
|
||||||
(label LIGHT-GRAY 182)))
|
|
||||||
Binary file not shown.
|
|
@ -1,10 +1,10 @@
|
||||||
global const str screen_namespace = "/dev/screen/0";
|
global str screen_namespace = "/dev/screen/0";
|
||||||
global const str mouse_namespace = "/dev/mouse/0";
|
global str mouse_namespace = "/dev/mouse/0";
|
||||||
global const byte BLACK = 0;
|
global byte BLACK = 0;
|
||||||
global const byte WHITE = 255;
|
global byte WHITE = 255;
|
||||||
global const byte DARK_GRAY = 73;
|
global byte DARK_GRAY = 73;
|
||||||
global const byte GRAY = 146;
|
global byte GRAY = 146;
|
||||||
global const byte LIGHT_GRAY = 182;
|
global byte LIGHT_GRAY = 182;
|
||||||
global byte SELECTED_COLOR = 255;
|
global byte SELECTED_COLOR = 255;
|
||||||
|
|
||||||
function main ()
|
function main ()
|
||||||
|
|
@ -17,7 +17,7 @@ function main ()
|
||||||
// use load immediate because it a pointer to a string, not a value
|
// use load immediate because it a pointer to a string, not a value
|
||||||
load_address screen_namespace -> screen_name;
|
load_address screen_namespace -> screen_name;
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
syscall OPEN screen_name mode -> screen; // Screen screen = open("/dev/screen/0", 0);
|
syscall OPEN screen_name mode screen; // Screen screen = open("/dev/screen/0", 0);
|
||||||
|
|
||||||
nat width $20;
|
nat width $20;
|
||||||
nat size $22;
|
nat size $22;
|
||||||
|
|
@ -30,26 +30,26 @@ function main ()
|
||||||
plex mouse $15;
|
plex mouse $15;
|
||||||
str mouse_name $16;
|
str mouse_name $16;
|
||||||
load_address mouse_namespace -> mouse_name;
|
load_address mouse_namespace -> mouse_name;
|
||||||
syscall OPEN mouse_name mode -> mouse; // Mouse mouse = open("/dev/mouse/0", 0);
|
syscall OPEN mouse_name mode mouse; // Mouse mouse = open("/dev/mouse/0", 0);
|
||||||
|
|
||||||
byte color $1;
|
byte color $1;
|
||||||
nat x_pos $12;
|
nat x_pos $12;
|
||||||
nat y_pos $13;
|
nat y_pos $13;
|
||||||
|
|
||||||
load_absolute_32 BLACK -> color;
|
load_absolute_8 BLACK -> color;
|
||||||
load_immediate 1 -> x_pos;
|
load_immediate 1 -> x_pos;
|
||||||
load_immediate 1 -> y_pos;
|
load_immediate 1 -> y_pos;
|
||||||
call draw_outlined_swatch screen_buffer color x_pos y_pos width -> void;
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
|
||||||
load_absolute_32 WHITE -> color;
|
load_absolute_8 WHITE -> color;
|
||||||
load_immediate 21 -> x_pos;
|
load_immediate 21 -> x_pos;
|
||||||
load_immediate 1 -> y_pos;
|
load_immediate 1 -> y_pos;
|
||||||
call draw_outlined_swatch screen_buffer color x_pos y_pos width -> void;
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
|
||||||
// screen.draw
|
// screen.draw
|
||||||
syscall WRITE screen screen_buffer size;
|
syscall WRITE screen screen_buffer size;
|
||||||
|
|
||||||
nat zero $11;
|
nat m_zero $11;
|
||||||
|
|
||||||
loop draw_loop
|
loop draw_loop
|
||||||
// load mouse click data
|
// load mouse click data
|
||||||
|
|
@ -58,7 +58,7 @@ function main ()
|
||||||
byte left_down $9;
|
byte left_down $9;
|
||||||
load_offset_8 mouse 16 -> left_down; // load btn1 pressed
|
load_offset_8 mouse 16 -> left_down; // load btn1 pressed
|
||||||
|
|
||||||
jump_eq_nat draw_loop left_down zero;
|
jump_eq_nat draw_loop left_down m_zero;
|
||||||
|
|
||||||
nat mouse_x $7;
|
nat mouse_x $7;
|
||||||
nat mouse_y $8;
|
nat mouse_y $8;
|
||||||
|
|
@ -69,28 +69,28 @@ function main ()
|
||||||
load_immediate 20 -> box_size;
|
load_immediate 20 -> box_size;
|
||||||
|
|
||||||
// first row
|
// first row
|
||||||
load_absolute_32 BLACK -> color;
|
load_absolute_8 BLACK -> color;
|
||||||
load_immediate 1 -> x_pos;
|
load_immediate 1 -> x_pos;
|
||||||
load_immediate 1 -> y_pos;
|
load_immediate 1 -> y_pos;
|
||||||
call draw_outlined_swatch screen_buffer color x_pos y_pos width -> void;
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
call set_color_if_clicked mouse_x mouse_y x_pos y_pos color box_size -> void;
|
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
|
||||||
|
|
||||||
|
|
||||||
load_absolute_32 WHITE -> color;
|
load_absolute_8 WHITE -> color;
|
||||||
load_immediate 21 -> x_pos;
|
load_immediate 21 -> x_pos;
|
||||||
load_immediate 1 -> y_pos;
|
load_immediate 1 -> y_pos;
|
||||||
call draw_outlined_swatch screen_buffer color x_pos y_pos width -> void;
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
call set_color_if_clicked mouse_x mouse_y x_pos y_pos color box_size -> void;
|
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
|
||||||
|
|
||||||
syscall WRITE screen screen_buffer size;
|
syscall WRITE screen screen_buffer size;
|
||||||
|
|
||||||
byte selected_color $25;
|
byte selected_color $25;
|
||||||
load_absolute_32 SELECTED_COLOR -> selected_color;
|
load_absolute_8 SELECTED_COLOR -> selected_color;
|
||||||
|
|
||||||
nat brush_size $19;
|
nat brush_size $19;
|
||||||
load_immediate 5 -> brush_size;
|
load_immediate 5 -> brush_size;
|
||||||
|
|
||||||
call draw_box screen_buffer width selected_color mouse_x mouse_y brush_size brush_size -> void;
|
call draw_box (screen_buffer width selected_color mouse_x mouse_y brush_size brush_size);
|
||||||
|
|
||||||
jump draw_loop;
|
jump draw_loop;
|
||||||
|
|
||||||
|
|
@ -98,41 +98,41 @@ function main ()
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
function set_color_if_clicked (int click_x $0, int click_y $1,
|
function set_color_if_clicked (int click_x $0, int click_y $1,
|
||||||
int box_x $2, int box_y $3, byte color $4, int box_size $5)
|
int box_x $2, int box_y $3, byte check_color $4, int bsize $5)
|
||||||
|
|
||||||
// Compute right
|
// Compute right
|
||||||
int right_edge $6;
|
int right_edge $6;
|
||||||
add_int box_x box_size -> right_edge;
|
add_int box_x bsize -> right_edge;
|
||||||
|
|
||||||
// Compute bottom = box_y + box_size
|
// Compute bottom = box_y + bsize
|
||||||
int bottom_edge $7;
|
int bottom_edge $7;
|
||||||
add_int box_y box_size -> bottom_edge;
|
add_int box_y bsize -> bottom_edge;
|
||||||
|
|
||||||
// Bounds check: x in [box_x, right] and y in [box_y, bottom]
|
// Bounds check: x in [box_x, right] and y in [box_y, bottom]
|
||||||
jump_lt_int fail click_x box_x;
|
jump_lt_int fail click_x box_x;
|
||||||
jump_ge_int fail click_x right_edge;
|
jump_gt_int fail click_x right_edge;
|
||||||
jump_lt_int fail click_y box_y;
|
jump_lt_int fail click_y box_y;
|
||||||
jump_ge_int fail click_y bottom_edge;
|
jump_gt_int fail click_y bottom_edge;
|
||||||
|
|
||||||
store_absolute_8 SELECTED_COLOR color;
|
store_absolute_8 check_color -> SELECTED_COLOR;
|
||||||
|
|
||||||
else fail
|
else fail
|
||||||
return;
|
return;
|
||||||
|
|
||||||
function draw_outlined_swatch(nat base $0,
|
function draw_outlined_swatch(nat dos_base $0,
|
||||||
byte color $1, int x $2, int y $3, int width $4)
|
byte swatch_color $1, int x $2, int y $3, int dos_width $4)
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
nat background_color $5;
|
nat background_color $5;
|
||||||
load_absolute_32 GRAY -> background_color;
|
load_absolute_8 GRAY -> background_color;
|
||||||
|
|
||||||
byte selected_color $10;
|
byte dos_selected_color $10;
|
||||||
load_absolute_32 SELECTED_COLOR -> selected_color;
|
load_absolute_8 SELECTED_COLOR -> dos_selected_color;
|
||||||
|
|
||||||
jump_eq_int set_selected selected_color color;
|
jump_eq_int set_selected swatch_color dos_selected_color;
|
||||||
jump end_set_selected;
|
jump end_set_selected;
|
||||||
do set_selected
|
do set_selected
|
||||||
load_absolute_32 DARK_GRAY -> background_color;
|
load_absolute_8 DARK_GRAY -> background_color;
|
||||||
else end_set_selected
|
else end_set_selected
|
||||||
|
|
||||||
nat outline_size $6;
|
nat outline_size $6;
|
||||||
|
|
@ -141,27 +141,27 @@ function draw_outlined_swatch(nat base $0,
|
||||||
nat fill_size $7;
|
nat fill_size $7;
|
||||||
load_immediate 17 -> fill_size;
|
load_immediate 17 -> fill_size;
|
||||||
|
|
||||||
nat offset $8;
|
nat dos_offset $8;
|
||||||
load_immediate 2 -> offset;
|
load_immediate 2 -> dos_offset;
|
||||||
|
|
||||||
call draw_box base width background_color x y outline_size outline_size -> void;
|
call draw_box (dos_base dos_width background_color x y outline_size outline_size);
|
||||||
|
|
||||||
add_int x offset -> $9; // x + 2
|
add_int x dos_offset -> $9; // x + 2
|
||||||
add_int y offset -> $10; // y + 2
|
add_int y dos_offset -> $10; // y + 2
|
||||||
|
|
||||||
call draw_box base width color $9 $10 fill_size fill_size -> void;
|
call draw_box (dos_base dos_width swatch_color $9 $10 fill_size fill_size);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
function draw_box (nat base $0, nat screen_width $1,
|
function draw_box (nat db_base $0, nat screen_width $1,
|
||||||
byte color $2, nat x_start $3, nat y_start $4,
|
byte box_color $2, nat x_start $3, nat y_start $4,
|
||||||
nat width $5, nat height $6)
|
nat db_width $5, nat height $6)
|
||||||
|
|
||||||
// Compute start address: base + y*640 + x
|
// Compute start address: base + y*640 + x
|
||||||
nat offset $15;
|
nat offset $15;
|
||||||
mul_int y_start screen_width -> offset;
|
mul_int y_start screen_width -> offset;
|
||||||
add_int offset x_start -> offset;
|
add_int offset x_start -> offset;
|
||||||
add_nat offset base -> offset;
|
add_nat offset db_base -> offset;
|
||||||
nat fat_ptr_size $25;
|
nat fat_ptr_size $25;
|
||||||
load_immediate 4 -> fat_ptr_size;
|
load_immediate 4 -> fat_ptr_size;
|
||||||
add_nat offset fat_ptr_size -> offset; // need to add offset for fat pointer size
|
add_nat offset fat_ptr_size -> offset; // need to add offset for fat pointer size
|
||||||
|
|
@ -172,13 +172,8 @@ function draw_box (nat base $0, nat screen_width $1,
|
||||||
int zero $26;
|
int zero $26;
|
||||||
load_immediate 0 -> zero;
|
load_immediate 0 -> zero;
|
||||||
|
|
||||||
int row_end $27;
|
|
||||||
nat pixel_ptr $29;
|
|
||||||
|
|
||||||
loop draw_box_outer
|
loop draw_box_outer
|
||||||
add_int offset width -> row_end; // current + width
|
memset_8 box_color db_width -> offset; // draw row
|
||||||
register_move offset -> pixel_ptr; // set pixel point
|
|
||||||
memset_8 pixel_ptr color width; // draw row
|
|
||||||
add_int offset screen_width -> offset; // next row += 640
|
add_int offset screen_width -> offset; // next row += 640
|
||||||
sub_int height i -> height; // decrement row count
|
sub_int height i -> height; // decrement row count
|
||||||
jump_gt_int draw_box_outer height zero;
|
jump_gt_int draw_box_outer height zero;
|
||||||
|
|
|
||||||
|
|
@ -1,261 +0,0 @@
|
||||||
((code
|
|
||||||
(label main
|
|
||||||
; Open screen
|
|
||||||
; use load immediate because it is a pointer to a string, not a value
|
|
||||||
(load-immediate $0 &screen-namespace)
|
|
||||||
(load-immediate $11 0)
|
|
||||||
(syscall OPEN $0 $0 $11) ; Screen screen = open(namespace, flags)
|
|
||||||
|
|
||||||
(load-offset-32 $20 $0 8) ; load width
|
|
||||||
(load-offset-32 $22 $0 12) ; load size
|
|
||||||
(load-immediate $1 16) ; pointer offset for screen buffer
|
|
||||||
(add-nat $21 $0 $1)
|
|
||||||
|
|
||||||
; open mouse
|
|
||||||
(load-immediate $16 &mouse-namespace)
|
|
||||||
(syscall OPEN $15 $16 $11) ; Mouse mouse = open(namespace, flags)
|
|
||||||
|
|
||||||
; outline_swatch(screen, BLACK, 1, 1);
|
|
||||||
(load-absolute-32 $1 &BLACK)
|
|
||||||
(load-immediate $12 1)
|
|
||||||
(load-immediate $13 1)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
|
|
||||||
; outline_swatch(screen, WHITE, 1, 1);
|
|
||||||
(load-absolute-32 $1 &WHITE)
|
|
||||||
(load-immediate $12 21)
|
|
||||||
(load-immediate $13 1)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &CHARCOAL)
|
|
||||||
(load-immediate $12 1)
|
|
||||||
(load-immediate $13 21)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &DARK-GRAY)
|
|
||||||
(load-immediate $12 21)
|
|
||||||
(load-immediate $13 21)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &RED)
|
|
||||||
(load-immediate $12 1)
|
|
||||||
(load-immediate $13 41)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &ORANGE)
|
|
||||||
(load-immediate $12 21)
|
|
||||||
(load-immediate $13 41)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &YELLOW)
|
|
||||||
(load-immediate $12 1)
|
|
||||||
(load-immediate $13 61)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &GREEN)
|
|
||||||
(load-immediate $12 21)
|
|
||||||
(load-immediate $13 61)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &BLUE)
|
|
||||||
(load-immediate $12 1)
|
|
||||||
(load-immediate $13 81)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &PURPLE)
|
|
||||||
(load-immediate $12 21)
|
|
||||||
(load-immediate $13 81)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
|
|
||||||
; screen.draw();
|
|
||||||
(syscall WRITE $0 $21 $22)
|
|
||||||
|
|
||||||
(label draw-loop
|
|
||||||
; load mouse click data
|
|
||||||
(syscall REFRESH $15)
|
|
||||||
(load-offset-8 $9 $15 16) ; load btn1 pressed
|
|
||||||
|
|
||||||
(jump-eq-nat &draw-loop $9 $11)
|
|
||||||
|
|
||||||
(load-offset-32 $7 $15 8) ; load x
|
|
||||||
(load-offset-32 $8 $15 12) ; load y
|
|
||||||
|
|
||||||
(load-immediate $14 20) ; box size
|
|
||||||
|
|
||||||
; outline_swatch(screen, BLACK, 1, 1);
|
|
||||||
(load-absolute-32 $1 &BLACK)
|
|
||||||
(load-immediate $12 1)
|
|
||||||
(load-immediate $13 1)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
(call &set-color-if-clicked ($7 $8 $12 $13 $1 $14) nil)
|
|
||||||
|
|
||||||
; outline_swatch(screen, WHITE, 1, 1);
|
|
||||||
(load-absolute-32 $1 &WHITE)
|
|
||||||
(load-immediate $12 21)
|
|
||||||
(load-immediate $13 1)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
(call &set-color-if-clicked ($7 $8 $12 $13 $1 $14) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &CHARCOAL)
|
|
||||||
(load-immediate $12 1)
|
|
||||||
(load-immediate $13 21)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
(call &set-color-if-clicked ($7 $8 $12 $13 $1 $14) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &DARK-GRAY)
|
|
||||||
(load-immediate $12 21)
|
|
||||||
(load-immediate $13 21)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
(call &set-color-if-clicked ($7 $8 $12 $13 $1 $14) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &RED)
|
|
||||||
(load-immediate $12 1)
|
|
||||||
(load-immediate $13 41)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
(call &set-color-if-clicked ($7 $8 $12 $13 $1 $14) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &ORANGE)
|
|
||||||
(load-immediate $12 21)
|
|
||||||
(load-immediate $13 41)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
(call &set-color-if-clicked ($7 $8 $12 $13 $1 $14) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &YELLOW)
|
|
||||||
(load-immediate $12 1)
|
|
||||||
(load-immediate $13 61)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
(call &set-color-if-clicked ($7 $8 $12 $13 $1 $14) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &GREEN)
|
|
||||||
(load-immediate $12 21)
|
|
||||||
(load-immediate $13 61)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
(call &set-color-if-clicked ($7 $8 $12 $13 $1 $14) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &BLUE)
|
|
||||||
(load-immediate $12 1)
|
|
||||||
(load-immediate $13 81)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
(call &set-color-if-clicked ($7 $8 $12 $13 $1 $14) nil)
|
|
||||||
|
|
||||||
(load-absolute-32 $1 &PURPLE)
|
|
||||||
(load-immediate $12 21)
|
|
||||||
(load-immediate $13 81)
|
|
||||||
(call &draw-outlined-swatch ($21 $1 $12 $13 $20) nil)
|
|
||||||
(call &set-color-if-clicked ($7 $8 $12 $13 $1 $14) nil)
|
|
||||||
|
|
||||||
(syscall WRITE $0 $21 $22)
|
|
||||||
|
|
||||||
(load-absolute-32 $22 &SELECTED-COLOR) ; color
|
|
||||||
(load-immediate $1 5) ; size of brush
|
|
||||||
|
|
||||||
(call &draw-box ($21 $20 $22 $7 $8 $1 $1) nil)
|
|
||||||
|
|
||||||
(jump &draw-loop))
|
|
||||||
|
|
||||||
; Flush and exit
|
|
||||||
(exit 0))
|
|
||||||
|
|
||||||
(label set-color-if-clicked
|
|
||||||
; (click_x, click_y, box_x, box_y, color, box_size)
|
|
||||||
|
|
||||||
; Compute right = box_x + box_size
|
|
||||||
(add-int $6 $2 $5) ; $6 = right edge
|
|
||||||
|
|
||||||
; Compute bottom = box_y + box_size
|
|
||||||
(add-int $7 $3 $5) ; $7 = bottom edge
|
|
||||||
|
|
||||||
; Bounds check: x in [box_x, right] and y in [box_y, bottom]
|
|
||||||
(jump-lt-int &fail $0 $2)
|
|
||||||
(jump-gt-int &fail $0 $6)
|
|
||||||
(jump-lt-int &fail $1 $3)
|
|
||||||
(jump-gt-int &fail $1 $7)
|
|
||||||
|
|
||||||
(load-immediate $10 &SELECTED-COLOR)
|
|
||||||
(store-absolute-8 $10 $4)
|
|
||||||
|
|
||||||
(label fail)
|
|
||||||
(return nil))
|
|
||||||
|
|
||||||
(label draw-outlined-swatch
|
|
||||||
; (base, color, x, y, width)
|
|
||||||
|
|
||||||
; Constants
|
|
||||||
(load-absolute-32 $5 &GRAY)
|
|
||||||
(load-absolute-32 $10 &SELECTED-COLOR)
|
|
||||||
(jump-eq-int &set-selected $10 $1)
|
|
||||||
(jump-eq-int &end-set-selected $5 $5)
|
|
||||||
(label set-selected)
|
|
||||||
(load-absolute-32 $5 &DARK-GRAY)
|
|
||||||
(label end-set-selected)
|
|
||||||
|
|
||||||
(load-immediate $6 20) ; outline size
|
|
||||||
(load-immediate $7 17) ; fill size
|
|
||||||
(load-immediate $8 2) ; offset
|
|
||||||
|
|
||||||
(call &draw-box ($0 $4 $5 $2 $3 $6 $6) nil)
|
|
||||||
|
|
||||||
(add-int $9 $2 $8) ; x + 2
|
|
||||||
(add-int $10 $3 $8) ; y + 2
|
|
||||||
|
|
||||||
(call &draw-box ($0 $4 $1 $9 $10 $7 $7) nil)
|
|
||||||
|
|
||||||
(return nil))
|
|
||||||
|
|
||||||
(label draw-box
|
|
||||||
; (base, screen_width, color, x_start, y_start, width, height)
|
|
||||||
|
|
||||||
; Compute start address: base + y*640 + x
|
|
||||||
(mul-int $15 $4 $1) ; $15 = y * 640
|
|
||||||
(add-int $15 $15 $3) ; $15 += x
|
|
||||||
(add-nat $15 $0 $15) ; $15 = base + pixel_offset
|
|
||||||
(load-immediate $25 4)
|
|
||||||
(add-nat $15 $15 $25) ; need to add offset for fat pointer size
|
|
||||||
|
|
||||||
; Outer loop: height times
|
|
||||||
(load-immediate $30 1) ; increment
|
|
||||||
|
|
||||||
(label draw-box-outer
|
|
||||||
(add-int $27 $15 $5) ; $27 = row end = current + width
|
|
||||||
(register-move $29 $15) ; $7 = pixel pointer
|
|
||||||
(memset-8 $29 $2 $5) ; draw row
|
|
||||||
(add-int $15 $15 $1) ; next row (+= 640)
|
|
||||||
(sub-int $6 $6 $30) ; decrement row count
|
|
||||||
(jump-gt-int &draw-box-outer $6 0))
|
|
||||||
(return nil)))
|
|
||||||
(data
|
|
||||||
(label screen-namespace "/dev/screen/0")
|
|
||||||
(label mouse-namespace "/dev/mouse/0")
|
|
||||||
(label SELECTED-COLOR 255)
|
|
||||||
(label BLACK 0)
|
|
||||||
(label WHITE 255)
|
|
||||||
(label CHARCOAL 36)
|
|
||||||
(label DARK-GRAY 73)
|
|
||||||
(label GRAY 146)
|
|
||||||
(label LIGHT-GRAY 182)
|
|
||||||
(label DARK-RED 128)
|
|
||||||
(label RED 224)
|
|
||||||
(label DARK-YELLOW 144)
|
|
||||||
(label YELLOW 252)
|
|
||||||
(label DARK-TEAL 9)
|
|
||||||
(label TEAL 18)
|
|
||||||
(label DARK-GREEN 12)
|
|
||||||
(label GREEN 16)
|
|
||||||
(label LIME 28)
|
|
||||||
(label LIGHT-CYAN 159)
|
|
||||||
(label NAVY 2)
|
|
||||||
(label BLUE 3)
|
|
||||||
(label DEEP-SKY-BLUE 10)
|
|
||||||
(label LIGHT-BLUE 19)
|
|
||||||
(label PURPLE 131)
|
|
||||||
(label LIGHT-PURPLE 147)
|
|
||||||
(label DARK-MAGENTA 130)
|
|
||||||
(label MAGENTA 227)
|
|
||||||
(label PLUM 129)
|
|
||||||
(label PINK 226)
|
|
||||||
(label SADDLE-BROWN 72)
|
|
||||||
(label PERU 141)
|
|
||||||
(label SIENNA 136)
|
|
||||||
(label ORANGE 241)
|
|
||||||
(label DARK-ORANGE 208)
|
|
||||||
(label GOLD 244)))
|
|
||||||
Binary file not shown.
203
test/paint.ul.ir
203
test/paint.ul.ir
|
|
@ -5,6 +5,33 @@ global byte WHITE = 255;
|
||||||
global byte DARK_GRAY = 73;
|
global byte DARK_GRAY = 73;
|
||||||
global byte GRAY = 146;
|
global byte GRAY = 146;
|
||||||
global byte LIGHT_GRAY = 182;
|
global byte LIGHT_GRAY = 182;
|
||||||
|
global byte CHARCOAL = 36;
|
||||||
|
global byte DARK_RED = 128;
|
||||||
|
global byte RED = 224;
|
||||||
|
global byte DARK_YELLOW = 144;
|
||||||
|
global byte YELLOW = 252;
|
||||||
|
global byte DARK_TEAL = 9;
|
||||||
|
global byte TEAL = 18;
|
||||||
|
global byte DARK_GREEN = 12;
|
||||||
|
global byte GREEN = 16;
|
||||||
|
global byte LIME = 28;
|
||||||
|
global byte LIGHT_CYAN = 159;
|
||||||
|
global byte NAVY = 2;
|
||||||
|
global byte BLUE = 3;
|
||||||
|
global byte DEEP_SKY_BLUE = 10;
|
||||||
|
global byte LIGHT_BLUE = 19;
|
||||||
|
global byte PURPLE = 131;
|
||||||
|
global byte LIGHT_PURPLE = 147;
|
||||||
|
global byte DARK_MAGENTA = 130;
|
||||||
|
global byte MAGENTA = 227;
|
||||||
|
global byte PLUM = 129;
|
||||||
|
global byte PINK = 226;
|
||||||
|
global byte SADDLE_BROWN = 72;
|
||||||
|
global byte PERU = 141;
|
||||||
|
global byte SIENNA = 136;
|
||||||
|
global byte ORANGE = 241;
|
||||||
|
global byte DARK_ORANGE = 208;
|
||||||
|
global byte GOLD = 244;
|
||||||
global byte SELECTED_COLOR = 255;
|
global byte SELECTED_COLOR = 255;
|
||||||
|
|
||||||
function main ()
|
function main ()
|
||||||
|
|
@ -17,7 +44,7 @@ function main ()
|
||||||
// use load immediate because it a pointer to a string, not a value
|
// use load immediate because it a pointer to a string, not a value
|
||||||
load_address screen_namespace -> screen_name;
|
load_address screen_namespace -> screen_name;
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
syscall OPEN screen_name mode -> screen; // Screen screen = open("/dev/screen/0", 0);
|
syscall OPEN screen_name mode screen; // Screen screen = open("/dev/screen/0", 0);
|
||||||
|
|
||||||
nat width $20;
|
nat width $20;
|
||||||
nat size $22;
|
nat size $22;
|
||||||
|
|
@ -30,26 +57,66 @@ function main ()
|
||||||
plex mouse $15;
|
plex mouse $15;
|
||||||
str mouse_name $16;
|
str mouse_name $16;
|
||||||
load_address mouse_namespace -> mouse_name;
|
load_address mouse_namespace -> mouse_name;
|
||||||
syscall OPEN mouse_name mode -> mouse; // Mouse mouse = open("/dev/mouse/0", 0);
|
syscall OPEN mouse_name mode mouse; // Mouse mouse = open("/dev/mouse/0", 0);
|
||||||
|
|
||||||
byte color $1;
|
byte color $1;
|
||||||
nat x_pos $12;
|
nat x_pos $12;
|
||||||
nat y_pos $13;
|
nat y_pos $13;
|
||||||
|
|
||||||
load_absolute_32 BLACK -> color;
|
load_absolute_8 BLACK -> color;
|
||||||
load_immediate 1 -> x_pos;
|
load_immediate 1 -> x_pos;
|
||||||
load_immediate 1 -> y_pos;
|
load_immediate 1 -> y_pos;
|
||||||
call draw_outlined_swatch screen_buffer color x_pos y_pos width -> void;
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
|
||||||
load_absolute_32 WHITE -> color;
|
load_absolute_8 WHITE -> color;
|
||||||
load_immediate 21 -> x_pos;
|
load_immediate 21 -> x_pos;
|
||||||
load_immediate 1 -> y_pos;
|
load_immediate 1 -> y_pos;
|
||||||
call draw_outlined_swatch screen_buffer color x_pos y_pos width -> void;
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
|
||||||
|
load_absolute_8 CHARCOAL -> color;
|
||||||
|
load_immediate 1 -> x_pos;
|
||||||
|
load_immediate 21 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
|
||||||
|
load_absolute_8 DARK_GRAY -> color;
|
||||||
|
load_immediate 21 -> x_pos;
|
||||||
|
load_immediate 21 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
|
||||||
|
load_absolute_8 RED -> color;
|
||||||
|
load_immediate 1 -> x_pos;
|
||||||
|
load_immediate 41 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
|
||||||
|
load_absolute_8 ORANGE -> color;
|
||||||
|
load_immediate 21 -> x_pos;
|
||||||
|
load_immediate 41 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
|
||||||
|
load_absolute_8 YELLOW -> color;
|
||||||
|
load_immediate 1 -> x_pos;
|
||||||
|
load_immediate 61 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
|
||||||
|
load_absolute_8 GREEN -> color;
|
||||||
|
load_immediate 21 -> x_pos;
|
||||||
|
load_immediate 61 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
|
||||||
|
load_absolute_8 BLUE -> color;
|
||||||
|
load_immediate 1 -> x_pos;
|
||||||
|
load_immediate 81 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
|
||||||
|
load_absolute_8 PURPLE -> color;
|
||||||
|
load_immediate 21 -> x_pos;
|
||||||
|
load_immediate 81 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
|
||||||
// screen.draw
|
// screen.draw
|
||||||
syscall WRITE screen screen_buffer size;
|
syscall WRITE screen screen_buffer size;
|
||||||
|
|
||||||
nat zero $11;
|
nat m_zero $11;
|
||||||
|
|
||||||
loop draw_loop
|
loop draw_loop
|
||||||
// load mouse click data
|
// load mouse click data
|
||||||
|
|
@ -58,7 +125,7 @@ function main ()
|
||||||
byte left_down $9;
|
byte left_down $9;
|
||||||
load_offset_8 mouse 16 -> left_down; // load btn1 pressed
|
load_offset_8 mouse 16 -> left_down; // load btn1 pressed
|
||||||
|
|
||||||
jump_eq_nat draw_loop left_down zero;
|
jump_eq_nat draw_loop left_down m_zero;
|
||||||
|
|
||||||
nat mouse_x $7;
|
nat mouse_x $7;
|
||||||
nat mouse_y $8;
|
nat mouse_y $8;
|
||||||
|
|
@ -69,28 +136,75 @@ function main ()
|
||||||
load_immediate 20 -> box_size;
|
load_immediate 20 -> box_size;
|
||||||
|
|
||||||
// first row
|
// first row
|
||||||
load_absolute_32 BLACK -> color;
|
load_absolute_8 BLACK -> color;
|
||||||
load_immediate 1 -> x_pos;
|
load_immediate 1 -> x_pos;
|
||||||
load_immediate 1 -> y_pos;
|
load_immediate 1 -> y_pos;
|
||||||
call draw_outlined_swatch screen_buffer color x_pos y_pos width -> void;
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
call set_color_if_clicked mouse_x mouse_y x_pos y_pos color box_size -> void;
|
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
|
||||||
|
|
||||||
|
load_absolute_8 WHITE -> color;
|
||||||
load_absolute_32 WHITE -> color;
|
|
||||||
load_immediate 21 -> x_pos;
|
load_immediate 21 -> x_pos;
|
||||||
load_immediate 1 -> y_pos;
|
load_immediate 1 -> y_pos;
|
||||||
call draw_outlined_swatch screen_buffer color x_pos y_pos width -> void;
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
call set_color_if_clicked mouse_x mouse_y x_pos y_pos color box_size -> void;
|
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
|
||||||
|
|
||||||
|
load_absolute_8 CHARCOAL -> color;
|
||||||
|
load_immediate 1 -> x_pos;
|
||||||
|
load_immediate 21 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
|
||||||
|
|
||||||
|
load_absolute_8 DARK_GRAY -> color;
|
||||||
|
load_immediate 21 -> x_pos;
|
||||||
|
load_immediate 21 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
|
||||||
|
|
||||||
|
load_absolute_8 RED -> color;
|
||||||
|
load_immediate 1 -> x_pos;
|
||||||
|
load_immediate 41 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
|
||||||
|
|
||||||
|
load_absolute_8 ORANGE -> color;
|
||||||
|
load_immediate 21 -> x_pos;
|
||||||
|
load_immediate 41 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
|
||||||
|
|
||||||
|
load_absolute_8 YELLOW -> color;
|
||||||
|
load_immediate 1 -> x_pos;
|
||||||
|
load_immediate 61 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
|
||||||
|
|
||||||
|
load_absolute_8 GREEN -> color;
|
||||||
|
load_immediate 21 -> x_pos;
|
||||||
|
load_immediate 61 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
|
||||||
|
|
||||||
|
load_absolute_8 BLUE -> color;
|
||||||
|
load_immediate 1 -> x_pos;
|
||||||
|
load_immediate 81 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
|
||||||
|
|
||||||
|
load_absolute_8 PURPLE -> color;
|
||||||
|
load_immediate 21 -> x_pos;
|
||||||
|
load_immediate 81 -> y_pos;
|
||||||
|
call draw_outlined_swatch (screen_buffer color x_pos y_pos width);
|
||||||
|
call set_color_if_clicked (mouse_x mouse_y x_pos y_pos color box_size);
|
||||||
|
|
||||||
syscall WRITE screen screen_buffer size;
|
syscall WRITE screen screen_buffer size;
|
||||||
|
|
||||||
byte selected_color $25;
|
byte selected_color $25;
|
||||||
load_absolute_32 SELECTED_COLOR -> selected_color;
|
load_absolute_8 SELECTED_COLOR -> selected_color;
|
||||||
|
|
||||||
nat brush_size $19;
|
nat brush_size $19;
|
||||||
load_immediate 5 -> brush_size;
|
load_immediate 5 -> brush_size;
|
||||||
|
|
||||||
call draw_box screen_buffer width selected_color mouse_x mouse_y brush_size brush_size -> void;
|
call draw_box (screen_buffer width selected_color mouse_x mouse_y brush_size brush_size);
|
||||||
|
|
||||||
jump draw_loop;
|
jump draw_loop;
|
||||||
|
|
||||||
|
|
@ -98,41 +212,41 @@ function main ()
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
function set_color_if_clicked (int click_x $0, int click_y $1,
|
function set_color_if_clicked (int click_x $0, int click_y $1,
|
||||||
int box_x $2, int box_y $3, byte color $4, int box_size $5)
|
int box_x $2, int box_y $3, byte check_color $4, int bsize $5)
|
||||||
|
|
||||||
// Compute right
|
// Compute right
|
||||||
int right_edge $6;
|
int right_edge $6;
|
||||||
add_int box_x box_size -> right_edge;
|
add_int box_x bsize -> right_edge;
|
||||||
|
|
||||||
// Compute bottom = box_y + box_size
|
// Compute bottom = box_y + bsize
|
||||||
int bottom_edge $7;
|
int bottom_edge $7;
|
||||||
add_int box_y box_size -> bottom_edge;
|
add_int box_y bsize -> bottom_edge;
|
||||||
|
|
||||||
// Bounds check: x in [box_x, right] and y in [box_y, bottom]
|
// Bounds check: x in [box_x, right] and y in [box_y, bottom]
|
||||||
jump_lt_int fail click_x box_x;
|
jump_lt_int fail click_x box_x;
|
||||||
jump_ge_int fail click_x right_edge;
|
jump_gt_int fail click_x right_edge;
|
||||||
jump_lt_int fail click_y box_y;
|
jump_lt_int fail click_y box_y;
|
||||||
jump_ge_int fail click_y bottom_edge;
|
jump_gt_int fail click_y bottom_edge;
|
||||||
|
|
||||||
store_absolute_8 color -> SELECTED_COLOR;
|
store_absolute_8 check_color -> SELECTED_COLOR;
|
||||||
|
|
||||||
else fail
|
else fail
|
||||||
return;
|
return;
|
||||||
|
|
||||||
function draw_outlined_swatch(nat base $0,
|
function draw_outlined_swatch(nat dos_base $0,
|
||||||
byte color $1, int x $2, int y $3, int width $4)
|
byte swatch_color $1, int x $2, int y $3, int dos_width $4)
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
nat background_color $5;
|
nat background_color $5;
|
||||||
load_absolute_32 GRAY -> background_color;
|
load_absolute_8 GRAY -> background_color;
|
||||||
|
|
||||||
byte selected_color $10;
|
byte dos_selected_color $10;
|
||||||
load_absolute_32 SELECTED_COLOR -> selected_color;
|
load_absolute_8 SELECTED_COLOR -> dos_selected_color;
|
||||||
|
|
||||||
jump_eq_int set_selected selected_color color;
|
jump_eq_int set_selected swatch_color dos_selected_color;
|
||||||
jump end_set_selected;
|
jump end_set_selected;
|
||||||
do set_selected
|
do set_selected
|
||||||
load_absolute_32 DARK_GRAY -> background_color;
|
load_absolute_8 DARK_GRAY -> background_color;
|
||||||
else end_set_selected
|
else end_set_selected
|
||||||
|
|
||||||
nat outline_size $6;
|
nat outline_size $6;
|
||||||
|
|
@ -141,27 +255,27 @@ function draw_outlined_swatch(nat base $0,
|
||||||
nat fill_size $7;
|
nat fill_size $7;
|
||||||
load_immediate 17 -> fill_size;
|
load_immediate 17 -> fill_size;
|
||||||
|
|
||||||
nat offset $8;
|
nat dos_offset $8;
|
||||||
load_immediate 2 -> offset;
|
load_immediate 2 -> dos_offset;
|
||||||
|
|
||||||
call draw_box base width background_color x y outline_size outline_size -> void;
|
call draw_box (dos_base dos_width background_color x y outline_size outline_size);
|
||||||
|
|
||||||
add_int x offset -> $9; // x + 2
|
add_int x dos_offset -> $9; // x + 2
|
||||||
add_int y offset -> $10; // y + 2
|
add_int y dos_offset -> $10; // y + 2
|
||||||
|
|
||||||
call draw_box base width color $9 $10 fill_size fill_size -> void;
|
call draw_box (dos_base dos_width swatch_color $9 $10 fill_size fill_size);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
function draw_box (nat base $0, nat screen_width $1,
|
function draw_box (nat db_base $0, nat screen_width $1,
|
||||||
byte color $2, nat x_start $3, nat y_start $4,
|
byte box_color $2, nat x_start $3, nat y_start $4,
|
||||||
nat width $5, nat height $6)
|
nat db_width $5, nat height $6)
|
||||||
|
|
||||||
// Compute start address: base + y*640 + x
|
// Compute start address: base + y*640 + x
|
||||||
nat offset $15;
|
nat offset $15;
|
||||||
mul_int y_start screen_width -> offset;
|
mul_int y_start screen_width -> offset;
|
||||||
add_int offset x_start -> offset;
|
add_int offset x_start -> offset;
|
||||||
add_nat offset base -> offset;
|
add_nat offset db_base -> offset;
|
||||||
nat fat_ptr_size $25;
|
nat fat_ptr_size $25;
|
||||||
load_immediate 4 -> fat_ptr_size;
|
load_immediate 4 -> fat_ptr_size;
|
||||||
add_nat offset fat_ptr_size -> offset; // need to add offset for fat pointer size
|
add_nat offset fat_ptr_size -> offset; // need to add offset for fat pointer size
|
||||||
|
|
@ -172,13 +286,8 @@ function draw_box (nat base $0, nat screen_width $1,
|
||||||
int zero $26;
|
int zero $26;
|
||||||
load_immediate 0 -> zero;
|
load_immediate 0 -> zero;
|
||||||
|
|
||||||
int row_end $27;
|
|
||||||
nat pixel_ptr $29;
|
|
||||||
|
|
||||||
loop draw_box_outer
|
loop draw_box_outer
|
||||||
add_int offset width -> row_end; // current + width
|
memset_8 box_color db_width -> offset; // draw row
|
||||||
register_move offset -> pixel_ptr; // set pixel point
|
|
||||||
memset_8 pixel_ptr color width; // draw row
|
|
||||||
add_int offset screen_width -> offset; // next row += 640
|
add_int offset screen_width -> offset; // next row += 640
|
||||||
sub_int height i -> height; // decrement row count
|
sub_int height i -> height; // decrement row count
|
||||||
jump_gt_int draw_box_outer height zero;
|
jump_gt_int draw_box_outer height zero;
|
||||||
|
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
((code
|
|
||||||
(label main
|
|
||||||
(load-absolute-32 $0 &x)
|
|
||||||
(load-absolute-32 $1 &y)
|
|
||||||
(add-real $2 $1 $0)
|
|
||||||
(real-to-string $3 $2)
|
|
||||||
(call &pln ($3) nil)
|
|
||||||
(exit 0))
|
|
||||||
(label pln
|
|
||||||
(load-immediate $1 &terminal-namespace) ; get terminal device
|
|
||||||
(load-immediate $11 0)
|
|
||||||
(syscall OPEN $1 $1 $11)
|
|
||||||
(load-immediate $3 &new-line)
|
|
||||||
(string-length $2 $0)
|
|
||||||
(syscall WRITE $1 $0 $2)
|
|
||||||
(string-length $4 $3)
|
|
||||||
(syscall WRITE $1 $3 $4)
|
|
||||||
(return nil)))
|
|
||||||
(data (label terminal-namespace "/dev/term/0")
|
|
||||||
(label new-line "\n")
|
|
||||||
(label x 1.0)
|
|
||||||
(label y 2.0)))
|
|
||||||
Binary file not shown.
|
|
@ -3,10 +3,10 @@ global str new_line = "\n";
|
||||||
|
|
||||||
function main ()
|
function main ()
|
||||||
load_immediate 1.0 -> $0;
|
load_immediate 1.0 -> $0;
|
||||||
load_immediate 1.0 -> $1;
|
load_immediate 2.0 -> $1;
|
||||||
add_real $0 $1 -> $0;
|
add_real $0 $1 -> $0;
|
||||||
real_to_string $0 -> $0;
|
real_to_string $0 -> $0;
|
||||||
call pln $0;
|
call pln ($0);
|
||||||
exit 0;
|
exit 0;
|
||||||
|
|
||||||
function pln (str message $0)
|
function pln (str message $0)
|
||||||
|
|
@ -19,7 +19,7 @@ function pln (str message $0)
|
||||||
|
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
load_address terminal_namespace -> term_ns;
|
load_address terminal_namespace -> term_ns;
|
||||||
syscall OPEN term_ns mode -> term;
|
syscall OPEN term_ns mode term;
|
||||||
string_length message -> msg_length;
|
string_length message -> msg_length;
|
||||||
syscall WRITE term message msg_length;
|
syscall WRITE term message msg_length;
|
||||||
load_address new_line -> nl;
|
load_address new_line -> nl;
|
||||||
|
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
((code
|
|
||||||
(label main
|
|
||||||
; Open screen
|
|
||||||
; use load immediate because it is a pointer to a string, not a value
|
|
||||||
(load-immediate $18 &screen-namespace)
|
|
||||||
(syscall OPEN $0 $18 $11) ; open(out Plex screen, in namespace, in flags)
|
|
||||||
|
|
||||||
(nat-to-string $5 $0)
|
|
||||||
(call &pln ($5) nil)
|
|
||||||
|
|
||||||
(load-offset-32 $20 $0 8) ; load width
|
|
||||||
|
|
||||||
(nat-to-string $5 $20)
|
|
||||||
(call &pln ($5) nil)
|
|
||||||
|
|
||||||
(load-offset-32 $22 $0 12) ; load size
|
|
||||||
|
|
||||||
(nat-to-string $5 $22)
|
|
||||||
(call &pln ($5) nil)
|
|
||||||
|
|
||||||
(load-immediate $1 16) ; offset for screen buffer
|
|
||||||
(add-nat $21 $0 $1)
|
|
||||||
|
|
||||||
(nat-to-string $5 $21)
|
|
||||||
(call &pln ($5) nil)
|
|
||||||
|
|
||||||
; open mouse
|
|
||||||
(load-immediate $16 &mouse-namespace)
|
|
||||||
(syscall OPEN $15 $16 $11) ; open(out Plex mouse, in namespace, in flags)
|
|
||||||
|
|
||||||
(syscall WRITE $0 $21 $22) ; redraw
|
|
||||||
|
|
||||||
(label draw-loop
|
|
||||||
; load mouse click data
|
|
||||||
(syscall REFRESH $15)
|
|
||||||
(load-offset-8 $9 $15 16) ; load btn1 pressed
|
|
||||||
|
|
||||||
(jump-eq-nat &draw-loop $9 $11)
|
|
||||||
|
|
||||||
(load-offset-32 $7 $15 8) ; load x
|
|
||||||
(load-offset-32 $8 $15 12) ; load y
|
|
||||||
|
|
||||||
; Compute start address: y*width + x
|
|
||||||
(mul-nat $30 $8 $20) ; $15 = y * width
|
|
||||||
(add-nat $30 $30 $7) ; $15 += x
|
|
||||||
(add-nat $30 $30 $21) ; $15 += pixel_offset
|
|
||||||
(load-immediate $1 4) ; need to add offset for fat pointer size
|
|
||||||
(add-nat $30 $30 $1)
|
|
||||||
|
|
||||||
(load-absolute-32 $3 &WHITE) ; color
|
|
||||||
(store-absolute-8 $30 $3) ; draw color at screen [x,y]
|
|
||||||
(syscall WRITE $0 $21 $22) ; redraw
|
|
||||||
|
|
||||||
(jump &draw-loop))
|
|
||||||
(exit 0))
|
|
||||||
(label pln
|
|
||||||
(load-immediate $1 &terminal-namespace) ; get terminal device
|
|
||||||
(load-immediate $11 0)
|
|
||||||
(syscall OPEN $1 $1 $11)
|
|
||||||
(load-immediate $3 &new-line)
|
|
||||||
(string-length $2 $0)
|
|
||||||
(syscall WRITE $1 $0 $2)
|
|
||||||
(string-length $4 $3)
|
|
||||||
(syscall WRITE $1 $3 $4)
|
|
||||||
(return nil)))
|
|
||||||
(data
|
|
||||||
(label screen-namespace "/dev/screen/0")
|
|
||||||
(label mouse-namespace "/dev/mouse/0")
|
|
||||||
(label terminal-namespace "/dev/term/0")
|
|
||||||
(label new-line "\n")
|
|
||||||
(label WHITE 255)))
|
|
||||||
Binary file not shown.
|
|
@ -2,7 +2,7 @@ global str screen_namespace = "/dev/screen/0";
|
||||||
global str mouse_namespace = "/dev/mouse/0";
|
global str mouse_namespace = "/dev/mouse/0";
|
||||||
global str terminal_namespace = "/dev/term/0";
|
global str terminal_namespace = "/dev/term/0";
|
||||||
global str new_line = "\n";
|
global str new_line = "\n";
|
||||||
global byte white = 255;
|
global byte WHITE = 255;
|
||||||
|
|
||||||
function main ()
|
function main ()
|
||||||
plex screen $0;
|
plex screen $0;
|
||||||
|
|
@ -18,37 +18,38 @@ function main ()
|
||||||
nat screen_buffer $10;
|
nat screen_buffer $10;
|
||||||
nat buffer_size $11;
|
nat buffer_size $11;
|
||||||
nat pixel_pos $12;
|
nat pixel_pos $12;
|
||||||
|
nat fat_ptr_size $13;
|
||||||
|
|
||||||
load_immediate screen_namespace -> screen;
|
load_address screen_namespace -> screen;
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> mode;
|
||||||
syscall OPEN screen mode -> screen;
|
syscall OPEN screen mode screen;
|
||||||
|
|
||||||
nat_to_string screen -> tmp_str;
|
nat_to_string screen -> tmp_str;
|
||||||
call pln tmp_str -> void;
|
call pln (tmp_str);
|
||||||
|
|
||||||
load_offset_32 screen 8 -> width;
|
load_offset_32 screen 8 -> width;
|
||||||
nat_to_string width -> tmp_str;
|
nat_to_string width -> tmp_str;
|
||||||
call pln tmp_str -> void;
|
call pln (tmp_str);
|
||||||
|
|
||||||
load_offset_32 screen 12 -> buffer_size;
|
load_offset_32 screen 12 -> buffer_size;
|
||||||
nat_to_string buffer_size -> tmp_str;
|
nat_to_string buffer_size -> tmp_str;
|
||||||
call pln tmp_str -> void;
|
call pln (tmp_str);
|
||||||
|
|
||||||
load_immediate 16 -> offset_temp;
|
load_immediate 16 -> offset_temp;
|
||||||
add_nat screen offset_temp -> screen_buffer;
|
add_nat screen offset_temp -> screen_buffer;
|
||||||
|
|
||||||
nat_to_string screen_buffer -> tmp_str;
|
nat_to_string screen_buffer -> tmp_str;
|
||||||
call pln tmp_str -> void;
|
call pln (tmp_str);
|
||||||
|
|
||||||
// open mouse
|
// open mouse
|
||||||
load_immediate mouse_namespace -> mouse;
|
load_address mouse_namespace -> mouse;
|
||||||
syscall OPEN mouse mode -> mouse;
|
syscall OPEN mouse mode mouse;
|
||||||
|
|
||||||
syscall WRITE screen screen_buffer buffer_size; // redraw
|
syscall WRITE screen screen_buffer buffer_size; // redraw
|
||||||
|
|
||||||
loop draw_loop
|
loop draw_loop
|
||||||
// load mouse click data
|
// load mouse click data
|
||||||
syscall STAT mouse;
|
syscall REFRESH mouse;
|
||||||
|
|
||||||
load_offset_8 mouse 16 -> left_down;
|
load_offset_8 mouse 16 -> left_down;
|
||||||
|
|
||||||
|
|
@ -64,8 +65,9 @@ function main ()
|
||||||
load_immediate 4 -> fat_ptr_size;
|
load_immediate 4 -> fat_ptr_size;
|
||||||
add_nat pixel_pos fat_ptr_size -> pixel_pos;
|
add_nat pixel_pos fat_ptr_size -> pixel_pos;
|
||||||
|
|
||||||
load_absolute_32 white -> color;
|
load_absolute_32 WHITE -> color;
|
||||||
store_absolute_8 pixel_pos color; // draw color at screen [x,y]
|
store_absolute_8 color -> pixel_pos; // draw color at screen [x,y]
|
||||||
|
|
||||||
syscall WRITE screen screen_buffer buffer_size; // redraw
|
syscall WRITE screen screen_buffer buffer_size; // redraw
|
||||||
|
|
||||||
jump draw_loop;
|
jump draw_loop;
|
||||||
|
|
@ -76,12 +78,12 @@ function pln (str message $0)
|
||||||
int msg_length $2;
|
int msg_length $2;
|
||||||
str nl $3;
|
str nl $3;
|
||||||
int nl_length $4;
|
int nl_length $4;
|
||||||
int mode $5;
|
int pln_mode $5;
|
||||||
str term_ns $6;
|
str term_ns $6;
|
||||||
|
|
||||||
load_immediate 0 -> mode;
|
load_immediate 0 -> pln_mode;
|
||||||
load_address terminal_namespace -> term_ns;
|
load_address terminal_namespace -> term_ns;
|
||||||
syscall OPEN term_ns mode -> term;
|
syscall OPEN term_ns pln_mode term;
|
||||||
string_length message -> msg_length;
|
string_length message -> msg_length;
|
||||||
syscall WRITE term message msg_length;
|
syscall WRITE term message msg_length;
|
||||||
load_address new_line -> nl;
|
load_address new_line -> nl;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue