Refactor and rename to align with new IR better
This commit is contained in:
parent
99e2f2c0c3
commit
c90f236ab3
12
Makefile
12
Makefile
|
|
@ -86,13 +86,17 @@ VM_SOURCES := \
|
||||||
ifeq ($(BUILD_MODE), release)
|
ifeq ($(BUILD_MODE), release)
|
||||||
PLATFORM_SOURCE := $(ARCH_DIR)/main.c \
|
PLATFORM_SOURCE := $(ARCH_DIR)/main.c \
|
||||||
$(ARCH_DIR)/devices.c\
|
$(ARCH_DIR)/devices.c\
|
||||||
$(SRC_DIR)/tools/assembler/parser.c \
|
$(SRC_DIR)/tools/old_assembler/parser.c \
|
||||||
$(SRC_DIR)/tools/assembler/assembler.c
|
$(SRC_DIR)/tools/old_assembler/assembler.c \
|
||||||
|
$(SRC_DIR)/tools/assembler/lexer.c \
|
||||||
|
$(SRC_DIR)/tools/assembler/assembler.c
|
||||||
else
|
else
|
||||||
PLATFORM_SOURCE := $(ARCH_DIR)/main.c \
|
PLATFORM_SOURCE := $(ARCH_DIR)/main.c \
|
||||||
$(ARCH_DIR)/devices.c \
|
$(ARCH_DIR)/devices.c \
|
||||||
$(SRC_DIR)/tools/assembler/parser.c \
|
$(SRC_DIR)/tools/old_assembler/parser.c \
|
||||||
$(SRC_DIR)/tools/assembler/assembler.c
|
$(SRC_DIR)/tools/old_assembler/assembler.c\
|
||||||
|
$(SRC_DIR)/tools/assembler/lexer.c \
|
||||||
|
$(SRC_DIR)/tools/assembler/assembler.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# --- OBJECT FILES ---
|
# --- OBJECT FILES ---
|
||||||
|
|
|
||||||
16
README.org
16
README.org
|
|
@ -21,7 +21,7 @@ Undâr is a programming language for the purpose of creating 3D games and graphi
|
||||||
|
|
||||||
It has an internal REPL that allows for quick development as well as the ability to dump the program to a binary rom for preserving that program/game/etc.
|
It has an internal REPL that allows for quick development as well as the ability to dump the program to a binary rom for preserving that program/game/etc.
|
||||||
|
|
||||||
It runs on the =Reality Engine=, a VM written in freestanding C89, has a CISC like instruction format of one byte opcode and a variable byte operand. 32 general purpose registers.
|
It runs on the =Reality Engine=, a VM written in freestanding C89, has a CISC like instruction format of one byte opcode and a variable byte operand. 32 local variables per frame.
|
||||||
|
|
||||||
* Philosophy
|
* Philosophy
|
||||||
|
|
||||||
|
|
@ -58,7 +58,7 @@ You can view some examples in the =.ul.ir= files in =/test=
|
||||||
function main ()
|
function main ()
|
||||||
str hello is $0
|
str hello is $0
|
||||||
|
|
||||||
load_heap_immediate "nuqneH 'u'?" -> hello
|
malloc_immediate "nuqneH 'u'?" -> hello
|
||||||
call pln hello
|
call pln hello
|
||||||
exit 0
|
exit 0
|
||||||
|
|
||||||
|
|
@ -69,12 +69,12 @@ function pln (str message is $0)
|
||||||
int nl_length is $4
|
int nl_length is $4
|
||||||
int mode is $5
|
int mode is $5
|
||||||
|
|
||||||
load_heap_immediate "/dev/term/0" -> ts # get terminal device
|
malloc_immediate "/dev/term/0" -> ts # get terminal device
|
||||||
load_immediate 0 -> mode
|
load_immediate 0 -> mode
|
||||||
syscall OPEN ts mode -> ts
|
syscall OPEN ts mode -> ts
|
||||||
strlen message -> msg_length
|
strlen message -> msg_length
|
||||||
syscall WRITE ts message msg_length
|
syscall WRITE ts message msg_length
|
||||||
load_heap_immediate "\n" -> nl
|
malloc_immediate "\n" -> nl
|
||||||
strlen nl -> nl_length
|
strlen nl -> nl_length
|
||||||
syscall WRITE ts nl nl_length
|
syscall WRITE ts nl nl_length
|
||||||
return
|
return
|
||||||
|
|
@ -97,11 +97,11 @@ function main ()
|
||||||
int mode is $11
|
int mode is $11
|
||||||
str term is $10
|
str term is $10
|
||||||
|
|
||||||
load_heap_immediate "/dev/term/0" -> term
|
malloc_immediate "/dev/term/0" -> 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);
|
||||||
|
|
||||||
load_heap_immediate "Enter a string:" -> $7
|
malloc_immediate "Enter a string:" -> $7
|
||||||
string_length $7 -> $8
|
string_length $7 -> $8
|
||||||
syscall WRITE term $7 $8 # print prompt
|
syscall WRITE term $7 $8 # print prompt
|
||||||
|
|
||||||
|
|
@ -120,12 +120,12 @@ function pln (str message is $0)
|
||||||
str nl is $3
|
str nl is $3
|
||||||
int nl_length is $4
|
int nl_length is $4
|
||||||
|
|
||||||
load_heap_immediate "/dev/term/0" -> ts
|
malloc_immediate "/dev/term/0" -> ts
|
||||||
load_immediate 0 -> mode
|
load_immediate 0 -> mode
|
||||||
syscall OPEN ts mode -> ts # get terminal device
|
syscall OPEN ts mode -> ts # get terminal device
|
||||||
strlen message -> msg_length
|
strlen message -> msg_length
|
||||||
syscall WRITE ts message msg_length
|
syscall WRITE ts message msg_length
|
||||||
load_heap_immediate "\n" -> nl
|
malloc_immediate "\n" -> nl
|
||||||
strlen nl -> nl_length
|
strlen nl -> nl_length
|
||||||
syscall WRITE ts nl nl_length
|
syscall WRITE ts nl nl_length
|
||||||
|
|
||||||
|
|
|
||||||
10
ROADMAP.org
10
ROADMAP.org
|
|
@ -10,6 +10,16 @@
|
||||||
|
|
||||||
* Roadmap
|
* Roadmap
|
||||||
|
|
||||||
|
** Fixes for devices
|
||||||
|
|
||||||
|
Devices should be moved into the Tunnel concept
|
||||||
|
|
||||||
|
Make it so that instead of returning the whole plex from the OPEN syscall we only return the handle
|
||||||
|
|
||||||
|
We should remove the "refesh" options and make it so that "stat"
|
||||||
|
|
||||||
|
Stat is the one that actually returns the plex with that info
|
||||||
|
|
||||||
** Example: Hello world (=hello.ul=)
|
** Example: Hello world (=hello.ul=)
|
||||||
|
|
||||||
*WIP syntax, not final implementation**
|
*WIP syntax, not final implementation**
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
|
#include "../../tools/old_assembler/assembler.h"
|
||||||
|
#include "../../tools/old_assembler/parser.h"
|
||||||
#include "../../tools/assembler/assembler.h"
|
#include "../../tools/assembler/assembler.h"
|
||||||
#include "../../tools/assembler/parser.h"
|
|
||||||
#include "../../vm/vm.h"
|
#include "../../vm/vm.h"
|
||||||
#include "devices.h"
|
#include "devices.h"
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
@ -52,7 +53,7 @@ bool saveVM(const char *filename, VM *vm) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write VM state (registers and pointers)
|
// Write VM state (locals and pointers)
|
||||||
if (fwrite(&vm->pc, sizeof(u32), 1, file) != 1 ||
|
if (fwrite(&vm->pc, sizeof(u32), 1, file) != 1 ||
|
||||||
fwrite(&vm->cp, sizeof(u32), 1, file) != 1 ||
|
fwrite(&vm->cp, sizeof(u32), 1, file) != 1 ||
|
||||||
fwrite(&vm->fp, sizeof(u32), 1, file) != 1 ||
|
fwrite(&vm->fp, sizeof(u32), 1, file) != 1 ||
|
||||||
|
|
@ -90,7 +91,7 @@ bool loadVM(const char *filename, VM *vm) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read VM state (registers and pointers)
|
// Read VM state (locals and pointers)
|
||||||
if (fread(&vm->pc, sizeof(u32), 1, file) != 1 ||
|
if (fread(&vm->pc, sizeof(u32), 1, file) != 1 ||
|
||||||
fread(&vm->cp, sizeof(u32), 1, file) != 1 ||
|
fread(&vm->cp, sizeof(u32), 1, file) != 1 ||
|
||||||
fread(&vm->fp, sizeof(u32), 1, file) != 1 ||
|
fread(&vm->fp, sizeof(u32), 1, file) != 1 ||
|
||||||
|
|
@ -145,7 +146,7 @@ bool compileAndSave(const char *source_file, const char *output_file, VM *vm) {
|
||||||
source[read] = '\0';
|
source[read] = '\0';
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
|
assemble(vm, source);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -177,7 +178,7 @@ bool assembleAndSave(const char *source_file, const char *output_file, VM *vm) {
|
||||||
printf("Parse failed.\n");
|
printf("Parse failed.\n");
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
assemble(vm, ast);
|
old_assemble(vm, ast);
|
||||||
expr_free(ast);
|
expr_free(ast);
|
||||||
|
|
||||||
// If output file specified, save the VM
|
// If output file specified, save the VM
|
||||||
|
|
@ -192,216 +193,6 @@ bool assembleAndSave(const char *source_file, const char *output_file, VM *vm) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void repl(VM *vm) {
|
|
||||||
USED(vm);
|
|
||||||
|
|
||||||
char buffer[1024 * 10] = {0}; // Larger buffer for multi-line input
|
|
||||||
char line[1024];
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
// Count current parentheses balance
|
|
||||||
i32 paren_balance = 0;
|
|
||||||
for (i32 i = 0; buffer[i]; i++) {
|
|
||||||
if (buffer[i] == '(')
|
|
||||||
paren_balance++;
|
|
||||||
else if (buffer[i] == ')')
|
|
||||||
paren_balance--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show appropriate prompt
|
|
||||||
if (paren_balance > 0) {
|
|
||||||
printf(".. "); // Continuation prompt when unbalanced
|
|
||||||
} else {
|
|
||||||
printf("> "); // Normal prompt when balanced
|
|
||||||
}
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
if (!fgets(line, sizeof(line), stdin)) {
|
|
||||||
printf("\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append the new line to buffer
|
|
||||||
strncat(buffer, line, sizeof(buffer) - strlen(buffer) - 1);
|
|
||||||
|
|
||||||
// Recalculate balance after adding new line
|
|
||||||
paren_balance = 0;
|
|
||||||
for (i32 i = 0; buffer[i]; i++) {
|
|
||||||
if (buffer[i] == '(')
|
|
||||||
paren_balance++;
|
|
||||||
else if (buffer[i] == ')')
|
|
||||||
paren_balance--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only parse when parentheses are balanced
|
|
||||||
if (paren_balance == 0) {
|
|
||||||
// Check if buffer has actual content (not just whitespace)
|
|
||||||
i32 has_content = 0;
|
|
||||||
for (i32 i = 0; buffer[i]; i++) {
|
|
||||||
if (!isspace(buffer[i])) {
|
|
||||||
has_content = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (has_content) {
|
|
||||||
ExprNode *ast = expr_parse(buffer, strlen(buffer));
|
|
||||||
if (!ast) {
|
|
||||||
printf("Parse failed.\n");
|
|
||||||
} else {
|
|
||||||
assemble(vm, ast);
|
|
||||||
while (step_vm(vm)) {
|
|
||||||
}
|
|
||||||
expr_free(ast);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset buffer for next input
|
|
||||||
buffer[0] = '\0';
|
|
||||||
}
|
|
||||||
// If unbalanced, continue reading more lines
|
|
||||||
}
|
|
||||||
exit(vm->flag);
|
|
||||||
}
|
|
||||||
#ifdef ASM_DEBUG
|
|
||||||
const char *opcode_to_string(Opcode op) {
|
|
||||||
static const char *names[] = {
|
|
||||||
[OP_HALT] = "halt",
|
|
||||||
[OP_JMP] = "jump",
|
|
||||||
[OP_JMPF] = "jmpf",
|
|
||||||
[OP_FCALL] = "fcall",
|
|
||||||
[OP_FRETURN] = "return",
|
|
||||||
|
|
||||||
/* Immediate loads (only 32-bit variant needed) */
|
|
||||||
[OP_LOAD_IMM] = "ldi",
|
|
||||||
|
|
||||||
/* Register-indirect loads */
|
|
||||||
[OP_LOAD_IND_8] = "ld8",
|
|
||||||
[OP_LOAD_IND_16] = "ld16",
|
|
||||||
[OP_LOAD_IND_32] = "ld32",
|
|
||||||
|
|
||||||
/* Absolute address loads */
|
|
||||||
[OP_LOAD_ABS_8] = "lda8",
|
|
||||||
[OP_LOAD_ABS_16] = "lda16",
|
|
||||||
[OP_LOAD_ABS_32] = "lda32",
|
|
||||||
|
|
||||||
/* Base+offset loads */
|
|
||||||
[OP_LOAD_OFF_8] = "ldo8",
|
|
||||||
[OP_LOAD_OFF_16] = "ldo16",
|
|
||||||
[OP_LOAD_OFF_32] = "ldo32",
|
|
||||||
|
|
||||||
/* Absolute address stores */
|
|
||||||
[OP_STORE_ABS_8] = "sta8",
|
|
||||||
[OP_STORE_ABS_16] = "sta16",
|
|
||||||
[OP_STORE_ABS_32] = "sta32",
|
|
||||||
|
|
||||||
/* Register-indirect stores */
|
|
||||||
[OP_STORE_IND_8] = "sti8",
|
|
||||||
[OP_STORE_IND_16] = "sti16",
|
|
||||||
[OP_STORE_IND_32] = "sti32",
|
|
||||||
|
|
||||||
/* Base+offset stores */
|
|
||||||
[OP_STORE_OFF_8] = "sto8",
|
|
||||||
[OP_STORE_OFF_16] = "sto16",
|
|
||||||
[OP_STORE_OFF_32] = "sto32",
|
|
||||||
|
|
||||||
/* Memory operations */
|
|
||||||
[OP_MALLOC] = "malloc",
|
|
||||||
[OP_MEMSET_8] = "set8",
|
|
||||||
[OP_MEMSET_16] = "set16",
|
|
||||||
[OP_MEMSET_32] = "set32",
|
|
||||||
|
|
||||||
/* Register operations */
|
|
||||||
[OP_REG_MOV] = "mov",
|
|
||||||
[OP_SYSCALL] = "syscall",
|
|
||||||
|
|
||||||
/* Bit operations */
|
|
||||||
[OP_BIT_SHIFT_LEFT] = "sll",
|
|
||||||
[OP_BIT_SHIFT_RIGHT] = "srl",
|
|
||||||
[OP_BIT_SHIFT_R_EXT] = "sre",
|
|
||||||
[OP_BAND] = "and",
|
|
||||||
[OP_BOR] = "or",
|
|
||||||
[OP_BXOR] = "xor",
|
|
||||||
|
|
||||||
/* Integer arithmetic */
|
|
||||||
[OP_ADD_INT] = "addi",
|
|
||||||
[OP_SUB_INT] = "subi",
|
|
||||||
[OP_MUL_INT] = "muli",
|
|
||||||
[OP_DIV_INT] = "divi",
|
|
||||||
[OP_ABS_INT] = "absi", // ← NEW
|
|
||||||
[OP_NEG_INT] = "negi", // ← NEW
|
|
||||||
|
|
||||||
/* Natural number arithmetic */
|
|
||||||
[OP_ADD_NAT] = "addn",
|
|
||||||
[OP_SUB_NAT] = "subn",
|
|
||||||
[OP_MUL_NAT] = "muln",
|
|
||||||
[OP_DIV_NAT] = "divn",
|
|
||||||
[OP_ABS_NAT] = "absn", // ← NEW
|
|
||||||
[OP_NEG_NAT] = "negn", // ← NEW
|
|
||||||
|
|
||||||
/* Floating point operations */
|
|
||||||
[OP_ADD_REAL] = "addr",
|
|
||||||
[OP_SUB_REAL] = "subr",
|
|
||||||
[OP_MUL_REAL] = "mulr",
|
|
||||||
[OP_DIV_REAL] = "divr",
|
|
||||||
[OP_ABS_REAL] = "absr", // ← NEW
|
|
||||||
[OP_NEG_REAL] = "negr", // ← NEW
|
|
||||||
|
|
||||||
/* Type conversions */
|
|
||||||
[OP_INT_TO_REAL] = "itor",
|
|
||||||
[OP_NAT_TO_REAL] = "ntor",
|
|
||||||
[OP_REAL_TO_INT] = "rtoi",
|
|
||||||
[OP_REAL_TO_NAT] = "rton",
|
|
||||||
|
|
||||||
/* Integer comparisons */
|
|
||||||
[OP_JEQ_INT] = "jeqi",
|
|
||||||
[OP_JNEQ_INT] = "jneqi",
|
|
||||||
[OP_JGT_INT] = "jgti",
|
|
||||||
[OP_JLT_INT] = "jlti",
|
|
||||||
[OP_JLE_INT] = "jlei",
|
|
||||||
[OP_JGE_INT] = "jgei",
|
|
||||||
|
|
||||||
/* Natural number comparisons */
|
|
||||||
[OP_JEQ_NAT] = "jeqn",
|
|
||||||
[OP_JNEQ_NAT] = "jneqn",
|
|
||||||
[OP_JGT_NAT] = "jgtn",
|
|
||||||
[OP_JLT_NAT] = "jltn",
|
|
||||||
[OP_JLE_NAT] = "jlen",
|
|
||||||
[OP_JGE_NAT] = "jgen",
|
|
||||||
|
|
||||||
/* Floating point comparisons */
|
|
||||||
[OP_JEQ_REAL] = "jeqr",
|
|
||||||
[OP_JNEQ_REAL] = "jneqr",
|
|
||||||
[OP_JGE_REAL] = "jger",
|
|
||||||
[OP_JGT_REAL] = "jgtr",
|
|
||||||
[OP_JLT_REAL] = "jltr",
|
|
||||||
[OP_JLE_REAL] = "jler",
|
|
||||||
|
|
||||||
/* String operations */
|
|
||||||
[OP_STRLEN] = "strlen",
|
|
||||||
[OP_STREQ] = "streq",
|
|
||||||
[OP_STRCAT] = "strcat",
|
|
||||||
[OP_STR_GET_CHAR] = "getch",
|
|
||||||
[OP_STR_FIND_CHAR] = "findch",
|
|
||||||
[OP_STR_SLICE] = "strcut",
|
|
||||||
|
|
||||||
/* String conversions */
|
|
||||||
[OP_INT_TO_STRING] = "itos",
|
|
||||||
[OP_NAT_TO_STRING] = "ntos",
|
|
||||||
[OP_REAL_TO_STRING] = "rtos",
|
|
||||||
[OP_STRING_TO_INT] = "stoi",
|
|
||||||
[OP_STRING_TO_NAT] = "ston",
|
|
||||||
[OP_STRING_TO_REAL] = "stor"};
|
|
||||||
|
|
||||||
if (op < 0 || op >= (int)(sizeof(names) / sizeof(names[0]))) {
|
|
||||||
return "<invalid-opcode>";
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *name = names[op];
|
|
||||||
return name ? name : "<unknown-opcode>";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
i32 main(i32 argc, char *argv[]) {
|
i32 main(i32 argc, char *argv[]) {
|
||||||
bool dump_rom = false;
|
bool dump_rom = false;
|
||||||
char *input_file = nil;
|
char *input_file = nil;
|
||||||
|
|
@ -453,8 +244,7 @@ i32 main(i32 argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No input file - enter REPL mode
|
printf("usage: undar <src.ul>...");
|
||||||
repl(&vm);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -567,9 +357,6 @@ i32 main(i32 argc, char *argv[]) {
|
||||||
int cycles_this_frame = 0;
|
int cycles_this_frame = 0;
|
||||||
int max_cycles_per_frame = 100; // Adjust this value
|
int max_cycles_per_frame = 100; // Adjust this value
|
||||||
while (cycles_this_frame < max_cycles_per_frame) {
|
while (cycles_this_frame < max_cycles_per_frame) {
|
||||||
#ifdef ASM_DEBUG
|
|
||||||
printf("| %s %d\n", opcode_to_string(vm.code[vm.pc]), vm.pc);
|
|
||||||
#endif
|
|
||||||
if (!step_vm(&vm)) {
|
if (!step_vm(&vm)) {
|
||||||
running = false;
|
running = false;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,20 +1,10 @@
|
||||||
#ifndef ASSEMBLER_H
|
#ifndef UNDAR_IR_ASSEMBLER_H
|
||||||
#define ASSEMBLER_H
|
#define UNDAR_IR_ASSEMBLER_H
|
||||||
|
|
||||||
#include "../../vm/common.h"
|
#include "../../vm/common.h"
|
||||||
#include "../../vm/vm.h"
|
#include "../../vm/opcodes.h"
|
||||||
#include "parser.h"
|
#include "lexer.h"
|
||||||
|
|
||||||
#include <string.h>
|
void assemble(VM *vm, char *source);
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#define AS_FIXED(v) ((float)(i32)(v) / 65536.0f)
|
#endif
|
||||||
#define TO_FIXED(f) ((i32)( \
|
|
||||||
((f) >= 0.0f) ? ((f) * 65536.0f + 0.5f) : ((f) * 65536.0f - 0.5f) \
|
|
||||||
))
|
|
||||||
|
|
||||||
void assemble(VM *vm, ExprNode *program);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../vm/common.h"
|
#include "../../vm/common.h"
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef ASSEMBLER_H
|
||||||
|
#define ASSEMBLER_H
|
||||||
|
|
||||||
|
#include "../../vm/common.h"
|
||||||
|
#include "../../vm/vm.h"
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#define AS_FIXED(v) ((float)(i32)(v) / 65536.0f)
|
||||||
|
#define TO_FIXED(f) ((i32)( \
|
||||||
|
((f) >= 0.0f) ? ((f) * 65536.0f + 0.5f) : ((f) * 65536.0f - 0.5f) \
|
||||||
|
))
|
||||||
|
|
||||||
|
void old_assemble(VM *vm, ExprNode *program);
|
||||||
|
|
||||||
|
#endif
|
||||||
171
src/vm/opcodes.h
171
src/vm/opcodes.h
|
|
@ -4,99 +4,100 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
OP_HALT, /* halt : terminate execution with code [src1] */
|
OP_EXIT, /* exit : terminate execution with code [src1] */
|
||||||
OP_CALL, /* call : creates a new frame */
|
OP_CALL, /* call : creates a new frame */
|
||||||
OP_RETURN, /* return : returns from a frame to the parent frame */
|
OP_RETURN, /* return : returns from a frame to the parent frame */
|
||||||
OP_SYSCALL, /* syscall : src1 src2 src3 src4 more? does a system call based on args */
|
OP_SYSCALL, /* syscall : src1 src2 src3 src4 more? does a system call based on args */
|
||||||
OP_LOAD_IMM, /* load-immediate : registers[dest] = constant */
|
OP_LOAD_IMM, /* load_immediate : locals[dest] = constant */
|
||||||
OP_LOAD_IND_8, /* load-indirect-8 : registers[dest] = memory[registers[src1]] as u8 */
|
OP_LOAD_IND_8, /* load_indirect_8 : locals[dest] = memory[locals[src1]] as u8 */
|
||||||
OP_LOAD_IND_16, /* load-indirect-16 : registers[dest] = memory[registers[src1]] as u8 */
|
OP_LOAD_IND_16, /* load_indirect_16 : locals[dest] = memory[locals[src1]] as u8 */
|
||||||
OP_LOAD_IND_32, /* load-indirect-32 : registers[dest] = memory[registers[src1]] as u32 */
|
OP_LOAD_IND_32, /* load_indirect_32 : locals[dest] = memory[locals[src1]] as u32 */
|
||||||
OP_LOAD_ABS_8, /* load-absolute-8 : registers[dest] = memory[src1 as u32] */
|
OP_LOAD_ABS_8, /* load_absolute_8 : locals[dest] = memory[src1 as u32] */
|
||||||
OP_LOAD_ABS_16, /* load-absolute-16 : registers[dest] = memory[src1 as u32] */
|
OP_LOAD_ABS_16, /* load_absolute_16 : locals[dest] = memory[src1 as u32] */
|
||||||
OP_LOAD_ABS_32, /* load-absolute-32 : registers[dest] = memory[src1 as u32] */
|
OP_LOAD_ABS_32, /* load_absolute_32 : locals[dest] = memory[src1 as u32] */
|
||||||
OP_LOAD_OFF_8, /* load-offset-8 : registers[dest] = memory[registers[src1] + offset] as u8 */
|
OP_LOAD_OFF_8, /* load_offset_8 : locals[dest] = memory[locals[src1] + offset] as u8 */
|
||||||
OP_LOAD_OFF_16, /* load-offset-16 : registers[dest] = memory[registers[src1] + offset] as u16 */
|
OP_LOAD_OFF_16, /* load_offset_16 : locals[dest] = memory[locals[src1] + offset] as u16 */
|
||||||
OP_LOAD_OFF_32, /* load-offset-32 : registers[dest] = memory[registers[src1] + offset] as u32 */
|
OP_LOAD_OFF_32, /* load_offset_32 : locals[dest] = memory[locals[src1] + offset] as u32 */
|
||||||
OP_STORE_ABS_8, /* store-absolute-8 : memory[dest] = src1 && 0xFF */
|
OP_STORE_ABS_8, /* store_absolute_8 : memory[dest] = src1 && 0xFF */
|
||||||
OP_STORE_ABS_16, /* store-absolute-16 : memory[dest] = src1 && 0xFFFF */
|
OP_STORE_ABS_16, /* store_absolute_16 : memory[dest] = src1 && 0xFFFF */
|
||||||
OP_STORE_ABS_32, /* store-absolute-32 : memory[dest] = src1 */
|
OP_STORE_ABS_32, /* store_absolute_32 : memory[dest] = src1 */
|
||||||
OP_STORE_IND_8, /* store-indirect-8 : memory[dest] = registers[src1] && 0xFF */
|
OP_STORE_IND_8, /* store_indirect_8 : memory[dest] = locals[src1] && 0xFF */
|
||||||
OP_STORE_IND_16, /* store-indirect-16 : memory[dest] = registers[src1] && 0xFFFF*/
|
OP_STORE_IND_16, /* store_indirect_16 : memory[dest] = locals[src1] && 0xFFFF*/
|
||||||
OP_STORE_IND_32, /* store-indirect-32 : memory[dest] = registers[src1] */
|
OP_STORE_IND_32, /* store_indirect_32 : memory[dest] = locals[src1] */
|
||||||
OP_STORE_OFF_8, /* store-offset-8 : memory[registers[dest] + offset] = registers[src1] && 0xFF */
|
OP_STORE_OFF_8, /* store_offset_8 : memory[locals[dest] + offset] = locals[src1] && 0xFF */
|
||||||
OP_STORE_OFF_16, /* store-offset-16 : memory[registers[dest] + offset] = registers[src1] && 0xFFFF */
|
OP_STORE_OFF_16, /* store_offset_16 : memory[locals[dest] + offset] = locals[src1] && 0xFFFF */
|
||||||
OP_STORE_OFF_32, /* store-offset-32 : memory[registers[dest] + offset] = registers[src1] */
|
OP_STORE_OFF_32, /* store_offset_32 : memory[locals[dest] + offset] = locals[src1] */
|
||||||
OP_MALLOC, /* malloc : dest = fat ptr to memory of ((src1 as size) + 4) */
|
OP_MALLOC, /* malloc : dest = fat ptr to memory of ((src1 as size) + 4) */
|
||||||
OP_MEMSET_8, /* memset-8 : dest <-> dest+count = src1 as u8 */
|
OP_MALLOC_IMM, /* malloc_immediate : dest = fat ptr to memory of raw <str or array or plex>*/
|
||||||
OP_MEMSET_16, /* memset-16 : dest <-> dest+count = src1 as u8 */
|
OP_MEMSET_8, /* memset_8 : dest <-> dest+count = src1 as u8 */
|
||||||
OP_MEMSET_32, /* memset-32 : dest <-> dest+count = src1 as u32 */
|
OP_MEMSET_16, /* memset_16 : dest <-> dest+count = src1 as u8 */
|
||||||
OP_REG_MOV, /* register-move : registers[dest] = registers[src1] */
|
OP_MEMSET_32, /* memset_32 : dest <-> dest+count = src1 as u32 */
|
||||||
OP_ADD_INT, /* add-int : registers[dest] = registers[src1] + registers[src2] */
|
OP_REG_MOV, /* register_move : locals[dest] = locals[src1] */
|
||||||
OP_SUB_INT, /* sub-int : registers[dest] = registers[src1] - registers[src2] */
|
OP_ADD_INT, /* add_int : locals[dest] = locals[src1] + locals[src2] */
|
||||||
OP_MUL_INT, /* mul-int : registers[dest] = registers[src1] * registers[src2] */
|
OP_SUB_INT, /* sub_int : locals[dest] = locals[src1] _ locals[src2] */
|
||||||
OP_DIV_INT, /* div-int : registers[dest] = registers[src1] / registers[src2] */
|
OP_MUL_INT, /* mul_int : locals[dest] = locals[src1] * locals[src2] */
|
||||||
OP_ABS_INT, /* abs-int : registers[dest] = | registers[src1] | */
|
OP_DIV_INT, /* div_int : locals[dest] = locals[src1] / locals[src2] */
|
||||||
OP_NEG_INT, /* neg-int : registers[dest] = -registers[src1] */
|
OP_ABS_INT, /* abs_int : locals[dest] = | locals[src1] | */
|
||||||
OP_ADD_NAT, /* add-nat : registers[dest] = registers[src1] + registers[src2] */
|
OP_NEG_INT, /* neg_int : locals[dest] = -locals[src1] */
|
||||||
OP_SUB_NAT, /* sub-nat : registers[dest] = registers[src1] - registers[src2] */
|
OP_ADD_NAT, /* add_nat : locals[dest] = locals[src1] + locals[src2] */
|
||||||
OP_MUL_NAT, /* mul-nat : registers[dest] = registers[src1] * registers[src2] */
|
OP_SUB_NAT, /* sub_nat : locals[dest] = locals[src1] _ locals[src2] */
|
||||||
OP_DIV_NAT, /* div-nat : registers[dest] = registers[src1] / registers[src2] */
|
OP_MUL_NAT, /* mul_nat : locals[dest] = locals[src1] * locals[src2] */
|
||||||
OP_ABS_NAT, /* abs-nat : registers[dest] = | registers[src1] | */
|
OP_DIV_NAT, /* div_nat : locals[dest] = locals[src1] / locals[src2] */
|
||||||
OP_NEG_NAT, /* neg-nat : registers[dest] = -registers[src1] */
|
OP_ABS_NAT, /* abs_nat : locals[dest] = | locals[src1] | */
|
||||||
OP_ADD_REAL, /* add-real : registers[dest] = registers[src1] + registers[src2] */
|
OP_NEG_NAT, /* neg_nat : locals[dest] = -locals[src1] */
|
||||||
OP_SUB_REAL, /* sub-real : registers[dest] = registers[src1] - registers[src2] */
|
OP_ADD_REAL, /* add_real : locals[dest] = locals[src1] + locals[src2] */
|
||||||
OP_MUL_REAL, /* mul-real : registers[dest] = registers[src1] * registers[src2] */
|
OP_SUB_REAL, /* sub_real : locals[dest] = locals[src1] _ locals[src2] */
|
||||||
OP_DIV_REAL, /* div-real : registers[dest] = registers[src1] / registers[src2] */
|
OP_MUL_REAL, /* mul_real : locals[dest] = locals[src1] * locals[src2] */
|
||||||
OP_ABS_REAL, /* abs-real : registers[dest] = | registers[src1] | */
|
OP_DIV_REAL, /* div_real : locals[dest] = locals[src1] / locals[src2] */
|
||||||
OP_NEG_REAL, /* neg-real : registers[dest] = -registers[src1] */
|
OP_ABS_REAL, /* abs_real : locals[dest] = | locals[src1] | */
|
||||||
OP_INT_TO_REAL, /* int-to-real : registers[dest] = registers[src1] as real */
|
OP_NEG_REAL, /* neg_real : locals[dest] = _locals[src1] */
|
||||||
OP_NAT_TO_REAL, /* nat-to-real : registers[dest] = registers[src1] as real */
|
OP_INT_TO_REAL, /* int_to_real : locals[dest] = locals[src1] as real */
|
||||||
OP_REAL_TO_INT, /* real-to-int : registers[dest] = registers[src1] as int */
|
OP_NAT_TO_REAL, /* nat_to_real : locals[dest] = locals[src1] as real */
|
||||||
OP_REAL_TO_NAT, /* real-to-nat : registers[dest] = registers[src1] as nat */
|
OP_REAL_TO_INT, /* real_to_int : locals[dest] = locals[src1] as int */
|
||||||
OP_BIT_SHIFT_LEFT, /* bit-shift-left : registers[dest] = registers[src1] << registers[src2] */
|
OP_REAL_TO_NAT, /* real_to_nat : locals[dest] = locals[src1] as nat */
|
||||||
OP_BIT_SHIFT_RIGHT,/* bit-shift-right : registers[dest] = registers[src1] >> registers[src2] */
|
OP_BIT_SHIFT_LEFT, /* bit_shift_left : locals[dest] = locals[src1] << locals[src2] */
|
||||||
OP_BIT_SHIFT_R_EXT,/* bit-shift-r-ext : registers[dest] as i32 = registers[src1] >> registers[src2] */
|
OP_BIT_SHIFT_RIGHT,/* bit_shift_right : locals[dest] = locals[src1] >> locals[src2] */
|
||||||
OP_BAND, /* bit-and : registers[dest] = registers[src1] & registers[src2] */
|
OP_BIT_SHIFT_R_EXT,/* bit_shift_r_ext : locals[dest] as i32 = locals[src1] >> locals[src2] */
|
||||||
OP_BOR, /* bit-or : registers[dest] = registers[src1] | registers[src2] */
|
OP_BAND, /* bit_and : locals[dest] = locals[src1] & locals[src2] */
|
||||||
OP_BXOR, /* bit-xor : registers[dest] = registers[src1] ^ registers[src2] */
|
OP_BOR, /* bit_or : locals[dest] = locals[src1] | locals[src2] */
|
||||||
|
OP_BXOR, /* bit_xor : locals[dest] = locals[src1] ^ locals[src2] */
|
||||||
OP_JMP, /* jump : jump to &dest unconditionally */
|
OP_JMP, /* jump : jump to &dest unconditionally */
|
||||||
OP_JMPF, /* jump-if-flag : jump to &dest if flag != 0 */
|
OP_JMPF, /* jump_if_flag : jump to &dest if flag != 0 */
|
||||||
OP_JEQ_INT, /* jump-eq-int : jump to &dest if registers[src1] as int == registers[src2] as int */
|
OP_JEQ_INT, /* jump_eq_int : jump to &dest if locals[src1] as int == locals[src2] as int */
|
||||||
OP_JNEQ_INT, /* jump-neq-int : jump to &dest if registers[src1] as int != registers[src2] as int */
|
OP_JNEQ_INT, /* jump_neq_int : jump to &dest if locals[src1] as int != locals[src2] as int */
|
||||||
OP_JGT_INT, /* jump-gt-int : jump to &dest if registers[src1] as int > registers[src2] as int */
|
OP_JGT_INT, /* jump_gt_int : jump to &dest if locals[src1] as int > locals[src2] as int */
|
||||||
OP_JLT_INT, /* jump-lt-int : jump to &dest if registers[src1] as int < registers[src2] as int */
|
OP_JLT_INT, /* jump_lt_int : jump to &dest if locals[src1] as int < locals[src2] as int */
|
||||||
OP_JLE_INT, /* jump-le-int : jump to &dest if registers[src1] as int <= registers[src2] as int */
|
OP_JLE_INT, /* jump_le_int : jump to &dest if locals[src1] as int <= locals[src2] as int */
|
||||||
OP_JGE_INT, /* jump-ge-int : jump to &dest if registers[src1] as int >= registers[src2] as int */
|
OP_JGE_INT, /* jump_ge_int : jump to &dest if locals[src1] as int >= locals[src2] as int */
|
||||||
OP_JEQ_NAT, /* jump-eq-nat : jump to &dest if registers[src1] as nat == registers[src2] as nat */
|
OP_JEQ_NAT, /* jump_eq_nat : jump to &dest if locals[src1] as nat == locals[src2] as nat */
|
||||||
OP_JNEQ_NAT, /* jump-neq-nat : jump to &dest if registers[src1] as nat != registers[src2] as nat */
|
OP_JNEQ_NAT, /* jump_neq_nat : jump to &dest if locals[src1] as nat != locals[src2] as nat */
|
||||||
OP_JGT_NAT, /* jump-gt-nat : jump to &dest if registers[src1] as nat > registers[src2] as nat */
|
OP_JGT_NAT, /* jump_gt_nat : jump to &dest if locals[src1] as nat > locals[src2] as nat */
|
||||||
OP_JLT_NAT, /* jump-lt-nat : jump to &dest if registers[src1] as nat < registers[src2] as nat */
|
OP_JLT_NAT, /* jump_lt_nat : jump to &dest if locals[src1] as nat < locals[src2] as nat */
|
||||||
OP_JLE_NAT, /* jump-le-nat : jump to &dest if registers[src1] as nat <= registers[src2] as nat */
|
OP_JLE_NAT, /* jump_le_nat : jump to &dest if locals[src1] as nat <= locals[src2] as nat */
|
||||||
OP_JGE_NAT, /* jump-ge-nat : jump to &dest if registers[src1] as nat >= registers[src2] as nat */
|
OP_JGE_NAT, /* jump_ge_nat : jump to &dest if locals[src1] as nat >= locals[src2] as nat */
|
||||||
OP_JEQ_REAL, /* jump-eq-real : jump to &dest if registers[src1] as real == registers[src2] as real */
|
OP_JEQ_REAL, /* jump_eq_real : jump to &dest if locals[src1] as real == locals[src2] as real */
|
||||||
OP_JNEQ_REAL, /* jump-neq-real : jump to &dest if registers[src1] as real != registers[src2] as real */
|
OP_JNEQ_REAL, /* jump_neq_real : jump to &dest if locals[src1] as real != locals[src2] as real */
|
||||||
OP_JGE_REAL, /* jump-ge-real : jump to &dest if registers[src1] as real >= registers[src2] as real */
|
OP_JGE_REAL, /* jump_ge_real : jump to &dest if locals[src1] as real >= locals[src2] as real */
|
||||||
OP_JGT_REAL, /* jump-gt-real : jump to &dest if registers[src1] as real > registers[src2] as real */
|
OP_JGT_REAL, /* jump_gt_real : jump to &dest if locals[src1] as real > locals[src2] as real */
|
||||||
OP_JLT_REAL, /* jump-lt-real : jump to &dest if registers[src1] as real < registers[src2] as real */
|
OP_JLT_REAL, /* jump_lt_real : jump to &dest if locals[src1] as real < locals[src2] as real */
|
||||||
OP_JLE_REAL, /* jump-le-real : jump to &dest if registers[src1] as real <= registers[src2] as real */
|
OP_JLE_REAL, /* jump_le_real : jump to &dest if locals[src1] as real <= locals[src2] as real */
|
||||||
OP_STRLEN, /* string-length : registers[dest] = length of str at src1 ptr */
|
OP_STRLEN, /* string_length : locals[dest] = length of str at src1 ptr */
|
||||||
OP_STREQ, /* string-eq : registers[dest] = src1 ptr string == src2 ptr string */
|
OP_STREQ, /* string_eq : locals[dest] = src1 ptr string == src2 ptr string */
|
||||||
OP_STRCAT, /* string-concat : registers[dest] = ptr of src1 ptr string + src2 ptr string */
|
OP_STRCAT, /* string_concat : locals[dest] = ptr of src1 ptr string + src2 ptr string */
|
||||||
OP_STR_GET_CHAR, /* string-get-char : registers[dest] = ptr of src1 ptr str, src2 index of str */
|
OP_STR_GET_CHAR, /* string_get_char : locals[dest] = ptr of src1 ptr str, src2 index of str */
|
||||||
OP_STR_FIND_CHAR, /* string-find-char : registers[dest] = ptr of src1 ptr string, src2 nat8 char */
|
OP_STR_FIND_CHAR, /* string_find_char : locals[dest] = ptr of src1 ptr string, src2 nat8 char */
|
||||||
OP_STR_SLICE, /* string-slice : registers[dest] = ptr of src1 ptr str, src2 start index, src3 end index */
|
OP_STR_SLICE, /* string_slice : locals[dest] = ptr of src1 ptr str, src2 start index, src3 end index */
|
||||||
OP_INT_TO_STRING, /* int-to-string : registers[dest] = src1 as str */
|
OP_INT_TO_STRING, /* int_to_string : locals[dest] = src1 as str */
|
||||||
OP_NAT_TO_STRING, /* nat-to-string : registers[dest] = src1 as str */
|
OP_NAT_TO_STRING, /* nat_to_string : locals[dest] = src1 as str */
|
||||||
OP_REAL_TO_STRING, /* real-to-string : registers[dest] = src1 as str */
|
OP_REAL_TO_STRING, /* real_to_string : locals[dest] = src1 as str */
|
||||||
OP_STRING_TO_INT, /* string-to-int : registers[dest] = src1 as int */
|
OP_STRING_TO_INT, /* string_to_int : locals[dest] = src1 as int */
|
||||||
OP_STRING_TO_NAT, /* string-to-nat : registers[dest] = src1 as nat */
|
OP_STRING_TO_NAT, /* string_to_nat : locals[dest] = src1 as nat */
|
||||||
OP_STRING_TO_REAL /* string-to-real : registers[dest] = src1 as real */
|
OP_STRING_TO_REAL /* string_to_real : locals[dest] = src1 as real */
|
||||||
} Opcode;
|
} Opcode;
|
||||||
|
|
||||||
#define MAX_REGS 32
|
#define MAX_REGS 32
|
||||||
typedef struct frame_s {
|
typedef struct frame_s {
|
||||||
u32 registers[MAX_REGS]; /* R0-R31 */
|
u32 locals[MAX_REGS]; /* R0-R31 */
|
||||||
u32 start; /* start of memory block */
|
u32 start; /* start of memory block */
|
||||||
u32 end; /* end of memory block */
|
u32 end; /* end of memory block */
|
||||||
u32 return_reg; /* register to store return value in parent */
|
u32 return_reg; /* register to store return value in parent */
|
||||||
|
|
@ -130,7 +131,7 @@ typedef struct device_s {
|
||||||
char type[DEVICE_TYPE_MAX_LENGTH]; /* e.g., "screen", "mouse", "gpio" */
|
char type[DEVICE_TYPE_MAX_LENGTH]; /* e.g., "screen", "mouse", "gpio" */
|
||||||
char path[DEVICE_PATH_MAX_LENGTH]; /* "/dev/screen", "/dev/input/mouse/0",
|
char path[DEVICE_PATH_MAX_LENGTH]; /* "/dev/screen", "/dev/input/mouse/0",
|
||||||
etc. */
|
etc. */
|
||||||
void *data; /* device-specific data */
|
void *data; /* device_specific data */
|
||||||
DeviceOps *ops; /* operations vtable */
|
DeviceOps *ops; /* operations vtable */
|
||||||
u32 flags; /* permissions, status, etc. */
|
u32 flags; /* permissions, status, etc. */
|
||||||
u32 handle; /* id for fast access in VM */
|
u32 handle; /* id for fast access in VM */
|
||||||
|
|
|
||||||
198
src/vm/vm.c
198
src/vm/vm.c
|
|
@ -17,8 +17,8 @@
|
||||||
vm->pc++; \
|
vm->pc++; \
|
||||||
src2 = read_u8(vm, code, vm->pc); \
|
src2 = read_u8(vm, code, vm->pc); \
|
||||||
vm->pc++; \
|
vm->pc++; \
|
||||||
value = (type)frame->registers[src1]; \
|
value = (type)frame->locals[src1]; \
|
||||||
value2 = (type)frame->registers[src2]; \
|
value2 = (type)frame->locals[src2]; \
|
||||||
cond = !!(value op value2); \
|
cond = !!(value op value2); \
|
||||||
mask = -(u32)cond; \
|
mask = -(u32)cond; \
|
||||||
vm->pc = (target & mask) | (vm->pc & ~mask); \
|
vm->pc = (target & mask) | (vm->pc & ~mask); \
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
#define MATH_OP(type, op) \
|
#define MATH_OP(type, op) \
|
||||||
do { \
|
do { \
|
||||||
u32 *regs = frame->registers; \
|
u32 *regs = frame->locals; \
|
||||||
dest = read_u8(vm, code, vm->pc); \
|
dest = read_u8(vm, code, vm->pc); \
|
||||||
vm->pc++; \
|
vm->pc++; \
|
||||||
src1 = read_u8(vm, code, vm->pc); \
|
src1 = read_u8(vm, code, vm->pc); \
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
#define BIT_OP(op) \
|
#define BIT_OP(op) \
|
||||||
do { \
|
do { \
|
||||||
u32 *regs = frame->registers; \
|
u32 *regs = frame->locals; \
|
||||||
dest = read_u8(vm, code, vm->pc); \
|
dest = read_u8(vm, code, vm->pc); \
|
||||||
vm->pc++; \
|
vm->pc++; \
|
||||||
src1 = read_u8(vm, code, vm->pc); \
|
src1 = read_u8(vm, code, vm->pc); \
|
||||||
|
|
@ -93,7 +93,7 @@ bool step_vm(VM *vm) {
|
||||||
frame = &vm->frames[vm->fp];
|
frame = &vm->frames[vm->fp];
|
||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case OP_HALT: {
|
case OP_EXIT: {
|
||||||
vm->flag = read_u32(vm, code, vm->pc);
|
vm->flag = read_u32(vm, code, vm->pc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -130,7 +130,7 @@ bool step_vm(VM *vm) {
|
||||||
heap_mask = 0;
|
heap_mask = 0;
|
||||||
for (i = 0; i < N; i++) {
|
for (i = 0; i < N; i++) {
|
||||||
src_reg = args[i];
|
src_reg = args[i];
|
||||||
child->registers[i] = frame->registers[src_reg];
|
child->locals[i] = frame->locals[src_reg];
|
||||||
|
|
||||||
/* Bitmask operation instead of conditional branch */
|
/* Bitmask operation instead of conditional branch */
|
||||||
heap_mask |= ((frame->heap_mask >> src_reg) & 1) << i;
|
heap_mask |= ((frame->heap_mask >> src_reg) & 1) << i;
|
||||||
|
|
@ -154,7 +154,7 @@ bool step_vm(VM *vm) {
|
||||||
parent = &vm->frames[vm->fp - 1];
|
parent = &vm->frames[vm->fp - 1];
|
||||||
|
|
||||||
if (child_return_reg != 0xFF && parent->return_reg != 0xFF) {
|
if (child_return_reg != 0xFF && parent->return_reg != 0xFF) {
|
||||||
value = child->registers[child_return_reg];
|
value = child->locals[child_return_reg];
|
||||||
|
|
||||||
if (is_heap_value(vm, child_return_reg)) {
|
if (is_heap_value(vm, child_return_reg)) {
|
||||||
ptr = value;
|
ptr = value;
|
||||||
|
|
@ -171,7 +171,7 @@ bool step_vm(VM *vm) {
|
||||||
memcopy(vm->memory + new_ptr + 4, vm->memory + ptr + 4, size);
|
memcopy(vm->memory + new_ptr + 4, vm->memory + ptr + 4, size);
|
||||||
parent->end += size + 4;
|
parent->end += size + 4;
|
||||||
|
|
||||||
parent->registers[parent->return_reg] = new_ptr;
|
parent->locals[parent->return_reg] = new_ptr;
|
||||||
parent->heap_mask |= (1 << parent->return_reg);
|
parent->heap_mask |= (1 << parent->return_reg);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -184,10 +184,10 @@ bool step_vm(VM *vm) {
|
||||||
*(u32 *)(vm->memory + new_ptr) = size;
|
*(u32 *)(vm->memory + new_ptr) = size;
|
||||||
memcopy(vm->memory + new_ptr + 4, vm->memory + ptr + 4, size);
|
memcopy(vm->memory + new_ptr + 4, vm->memory + ptr + 4, size);
|
||||||
parent->end += size + 4;
|
parent->end += size + 4;
|
||||||
parent->registers[parent->return_reg] = new_ptr;
|
parent->locals[parent->return_reg] = new_ptr;
|
||||||
parent->heap_mask |= (1 << parent->return_reg);
|
parent->heap_mask |= (1 << parent->return_reg);
|
||||||
} else {
|
} else {
|
||||||
parent->registers[parent->return_reg] = value;
|
parent->locals[parent->return_reg] = value;
|
||||||
parent->heap_mask &= ~(1 << parent->return_reg);
|
parent->heap_mask &= ~(1 << parent->return_reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -203,8 +203,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame->registers[dest] = vm->mp;
|
frame->locals[dest] = vm->mp;
|
||||||
size = frame->registers[src1];
|
size = frame->locals[src1];
|
||||||
write_u32(vm, memory, vm->mp, size);
|
write_u32(vm, memory, vm->mp, size);
|
||||||
vm->mp += (size + 4);
|
vm->mp += (size + 4);
|
||||||
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
||||||
|
|
@ -216,9 +216,9 @@ bool step_vm(VM *vm) {
|
||||||
u8 value_reg = read_u8(vm, code, vm->pc++);
|
u8 value_reg = read_u8(vm, code, vm->pc++);
|
||||||
u8 count_reg = read_u8(vm, code, vm->pc++);
|
u8 count_reg = read_u8(vm, code, vm->pc++);
|
||||||
|
|
||||||
u32 dest = frame->registers[dest_reg];
|
u32 dest = frame->locals[dest_reg];
|
||||||
u32 value = frame->registers[value_reg];
|
u32 value = frame->locals[value_reg];
|
||||||
u32 count = frame->registers[count_reg];
|
u32 count = frame->locals[count_reg];
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
vm->flag = 1;
|
vm->flag = 1;
|
||||||
|
|
@ -237,7 +237,7 @@ bool step_vm(VM *vm) {
|
||||||
write_u32(vm, memory, i, value);
|
write_u32(vm, memory, i, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->registers[0] = dest;
|
frame->locals[0] = dest;
|
||||||
vm->flag = 1;
|
vm->flag = 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -247,9 +247,9 @@ bool step_vm(VM *vm) {
|
||||||
u8 value_reg = read_u8(vm, code, vm->pc++);
|
u8 value_reg = read_u8(vm, code, vm->pc++);
|
||||||
u8 count_reg = read_u8(vm, code, vm->pc++);
|
u8 count_reg = read_u8(vm, code, vm->pc++);
|
||||||
|
|
||||||
u32 dest = frame->registers[dest_reg];
|
u32 dest = frame->locals[dest_reg];
|
||||||
u16 value = (u16)(frame->registers[value_reg]);
|
u16 value = (u16)(frame->locals[value_reg]);
|
||||||
u32 count = frame->registers[count_reg];
|
u32 count = frame->locals[count_reg];
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
vm->flag = 1;
|
vm->flag = 1;
|
||||||
|
|
@ -268,7 +268,7 @@ bool step_vm(VM *vm) {
|
||||||
write_u16(vm, memory, i, value);
|
write_u16(vm, memory, i, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->registers[0] = dest;
|
frame->locals[0] = dest;
|
||||||
vm->flag = 1;
|
vm->flag = 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -278,9 +278,9 @@ bool step_vm(VM *vm) {
|
||||||
u8 value_reg = read_u8(vm, code, vm->pc++);
|
u8 value_reg = read_u8(vm, code, vm->pc++);
|
||||||
u8 count_reg = read_u8(vm, code, vm->pc++);
|
u8 count_reg = read_u8(vm, code, vm->pc++);
|
||||||
|
|
||||||
u32 dest = frame->registers[dest_reg];
|
u32 dest = frame->locals[dest_reg];
|
||||||
u8 value = (u8)(frame->registers[value_reg]);
|
u8 value = (u8)(frame->locals[value_reg]);
|
||||||
u32 count = frame->registers[count_reg];
|
u32 count = frame->locals[count_reg];
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
vm->flag = 1;
|
vm->flag = 1;
|
||||||
|
|
@ -299,7 +299,7 @@ bool step_vm(VM *vm) {
|
||||||
write_u8(vm, memory, i, value);
|
write_u8(vm, memory, i, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->registers[0] = dest;
|
frame->locals[0] = dest;
|
||||||
vm->flag = 1;
|
vm->flag = 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -308,7 +308,7 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
v = read_u32(vm, code, vm->pc);
|
v = read_u32(vm, code, vm->pc);
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
frame->registers[dest] = v;
|
frame->locals[dest] = v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_LOAD_ABS_32: {
|
case OP_LOAD_ABS_32: {
|
||||||
|
|
@ -317,7 +317,7 @@ bool step_vm(VM *vm) {
|
||||||
ptr = read_u32(vm, code, vm->pc);
|
ptr = read_u32(vm, code, vm->pc);
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
v = read_u32(vm, memory, ptr);
|
v = read_u32(vm, memory, ptr);
|
||||||
frame->registers[dest] = v;
|
frame->locals[dest] = v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_LOAD_ABS_16: {
|
case OP_LOAD_ABS_16: {
|
||||||
|
|
@ -326,7 +326,7 @@ bool step_vm(VM *vm) {
|
||||||
ptr = read_u32(vm, code, vm->pc);
|
ptr = read_u32(vm, code, vm->pc);
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
v = read_u16(vm, memory, ptr);
|
v = read_u16(vm, memory, ptr);
|
||||||
frame->registers[dest] = v;
|
frame->locals[dest] = v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_LOAD_ABS_8: {
|
case OP_LOAD_ABS_8: {
|
||||||
|
|
@ -335,7 +335,7 @@ bool step_vm(VM *vm) {
|
||||||
ptr = read_u32(vm, code, vm->pc);
|
ptr = read_u32(vm, code, vm->pc);
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
v = read_u8(vm, memory, ptr);
|
v = read_u8(vm, memory, ptr);
|
||||||
frame->registers[dest] = v;
|
frame->locals[dest] = v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_LOAD_IND_32: {
|
case OP_LOAD_IND_32: {
|
||||||
|
|
@ -343,9 +343,9 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
v = frame->registers[src1];
|
v = frame->locals[src1];
|
||||||
ptr = read_u32(vm, memory, v);
|
ptr = read_u32(vm, memory, v);
|
||||||
frame->registers[dest] = ptr;
|
frame->locals[dest] = ptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_LOAD_IND_16: {
|
case OP_LOAD_IND_16: {
|
||||||
|
|
@ -354,9 +354,9 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
v = frame->registers[src1];
|
v = frame->locals[src1];
|
||||||
v16 = read_u16(vm, memory, v);
|
v16 = read_u16(vm, memory, v);
|
||||||
frame->registers[dest] = v16;
|
frame->locals[dest] = v16;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_LOAD_IND_8: {
|
case OP_LOAD_IND_8: {
|
||||||
|
|
@ -365,9 +365,9 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
v = frame->registers[src1];
|
v = frame->locals[src1];
|
||||||
v8 = read_u8(vm, memory, v);
|
v8 = read_u8(vm, memory, v);
|
||||||
frame->registers[dest] = v8;
|
frame->locals[dest] = v8;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_LOAD_OFF_8: {
|
case OP_LOAD_OFF_8: {
|
||||||
|
|
@ -379,9 +379,9 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
offset = read_u32(vm, code, vm->pc);
|
offset = read_u32(vm, code, vm->pc);
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
v = frame->registers[src1];
|
v = frame->locals[src1];
|
||||||
v8 = read_u8(vm, memory, (v + offset));
|
v8 = read_u8(vm, memory, (v + offset));
|
||||||
frame->registers[dest] = v8;
|
frame->locals[dest] = v8;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_LOAD_OFF_16: {
|
case OP_LOAD_OFF_16: {
|
||||||
|
|
@ -393,9 +393,9 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
offset = read_u32(vm, code, vm->pc);
|
offset = read_u32(vm, code, vm->pc);
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
v = frame->registers[src1];
|
v = frame->locals[src1];
|
||||||
v16 = read_u16(vm, memory, (v + offset));
|
v16 = read_u16(vm, memory, (v + offset));
|
||||||
frame->registers[dest] = v16;
|
frame->locals[dest] = v16;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_LOAD_OFF_32: {
|
case OP_LOAD_OFF_32: {
|
||||||
|
|
@ -406,9 +406,9 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
offset = read_u32(vm, code, vm->pc);
|
offset = read_u32(vm, code, vm->pc);
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
v = frame->registers[src1];
|
v = frame->locals[src1];
|
||||||
ptr = read_u32(vm, memory, (v + offset));
|
ptr = read_u32(vm, memory, (v + offset));
|
||||||
frame->registers[dest] = ptr;
|
frame->locals[dest] = ptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_STORE_ABS_32: {
|
case OP_STORE_ABS_32: {
|
||||||
|
|
@ -416,8 +416,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
v = frame->registers[src1];
|
v = frame->locals[src1];
|
||||||
ptr = frame->registers[dest];
|
ptr = frame->locals[dest];
|
||||||
write_u32(vm, memory, ptr, v);
|
write_u32(vm, memory, ptr, v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -426,8 +426,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
v = frame->registers[src1];
|
v = frame->locals[src1];
|
||||||
ptr = frame->registers[dest];
|
ptr = frame->locals[dest];
|
||||||
write_u16(vm, memory, ptr, v);
|
write_u16(vm, memory, ptr, v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -436,8 +436,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
v = frame->registers[src1];
|
v = frame->locals[src1];
|
||||||
ptr = frame->registers[dest];
|
ptr = frame->locals[dest];
|
||||||
write_u8(vm, memory, ptr, v);
|
write_u8(vm, memory, ptr, v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -446,8 +446,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
ptr = frame->registers[dest];
|
ptr = frame->locals[dest];
|
||||||
v = frame->registers[src1];
|
v = frame->locals[src1];
|
||||||
write_u32(vm, memory, ptr, v);
|
write_u32(vm, memory, ptr, v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -457,8 +457,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
ptr = frame->registers[dest];
|
ptr = frame->locals[dest];
|
||||||
v16 = frame->registers[src1];
|
v16 = frame->locals[src1];
|
||||||
write_u16(vm, memory, ptr, v16);
|
write_u16(vm, memory, ptr, v16);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -468,8 +468,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
ptr = frame->registers[dest];
|
ptr = frame->locals[dest];
|
||||||
v8 = frame->registers[src1];
|
v8 = frame->locals[src1];
|
||||||
write_u8(vm, memory, ptr, v8);
|
write_u8(vm, memory, ptr, v8);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -482,8 +482,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
offset = read_u32(vm, code, vm->pc);
|
offset = read_u32(vm, code, vm->pc);
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
ptr = frame->registers[dest];
|
ptr = frame->locals[dest];
|
||||||
v8 = frame->registers[src1];
|
v8 = frame->locals[src1];
|
||||||
write_u8(vm, memory, (ptr + offset), v8);
|
write_u8(vm, memory, (ptr + offset), v8);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -496,8 +496,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
offset = read_u32(vm, code, vm->pc);
|
offset = read_u32(vm, code, vm->pc);
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
ptr = frame->registers[dest];
|
ptr = frame->locals[dest];
|
||||||
v16 = frame->registers[src1];
|
v16 = frame->locals[src1];
|
||||||
write_u16(vm, memory, (ptr + offset), v16);
|
write_u16(vm, memory, (ptr + offset), v16);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -509,8 +509,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
offset = read_u32(vm, code, vm->pc);
|
offset = read_u32(vm, code, vm->pc);
|
||||||
vm->pc += 4;
|
vm->pc += 4;
|
||||||
ptr = frame->registers[dest];
|
ptr = frame->locals[dest];
|
||||||
v = frame->registers[src1];
|
v = frame->locals[src1];
|
||||||
write_u32(vm, memory, (ptr + offset), v);
|
write_u32(vm, memory, (ptr + offset), v);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -519,7 +519,7 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame->registers[dest] = frame->registers[src1];
|
frame->locals[dest] = frame->locals[src1];
|
||||||
|
|
||||||
if (is_heap_value(vm, src1)) {
|
if (is_heap_value(vm, src1)) {
|
||||||
set_heap_status(vm, dest, true);
|
set_heap_status(vm, dest, true);
|
||||||
|
|
@ -559,14 +559,14 @@ bool step_vm(VM *vm) {
|
||||||
mode_reg = read_u8(vm, code, vm->pc);
|
mode_reg = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
|
||||||
path_ptr = frame->registers[path_reg];
|
path_ptr = frame->locals[path_reg];
|
||||||
mode = frame->registers[mode_reg];
|
mode = frame->locals[mode_reg];
|
||||||
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
|
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
|
||||||
if (dev) {
|
if (dev) {
|
||||||
if (dev->ops->open) {
|
if (dev->ops->open) {
|
||||||
/* return device plex to user */
|
/* return device plex to user */
|
||||||
device_ptr = vm->mp;
|
device_ptr = vm->mp;
|
||||||
frame->registers[dest_reg] = device_ptr;
|
frame->locals[dest_reg] = device_ptr;
|
||||||
/* malloc size for device */
|
/* malloc size for device */
|
||||||
write_u32(vm, memory, device_ptr, dev->size);
|
write_u32(vm, memory, device_ptr, dev->size);
|
||||||
vm->mp += (dev->size + 4);
|
vm->mp += (dev->size + 4);
|
||||||
|
|
@ -594,9 +594,9 @@ bool step_vm(VM *vm) {
|
||||||
size_reg = read_u8(vm, code, vm->pc);
|
size_reg = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
|
||||||
device_ptr = frame->registers[device_reg]; /* device pointer */
|
device_ptr = frame->locals[device_reg]; /* device pointer */
|
||||||
buffer_ptr = frame->registers[buffer_reg];
|
buffer_ptr = frame->locals[buffer_reg];
|
||||||
size = frame->registers[size_reg]; /* size */
|
size = frame->locals[size_reg]; /* size */
|
||||||
|
|
||||||
handle = vm->memory[device_ptr + 4]; /* get device handle */
|
handle = vm->memory[device_ptr + 4]; /* get device handle */
|
||||||
dev = &vm->devices[handle];
|
dev = &vm->devices[handle];
|
||||||
|
|
@ -616,7 +616,7 @@ bool step_vm(VM *vm) {
|
||||||
device_reg = read_u8(vm, code, vm->pc);
|
device_reg = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
|
||||||
device_ptr = frame->registers[device_reg]; /* device pointer */
|
device_ptr = frame->locals[device_reg]; /* device pointer */
|
||||||
handle = vm->memory[device_ptr + 4]; /* get device handle */
|
handle = vm->memory[device_ptr + 4]; /* get device handle */
|
||||||
dev = &vm->devices[handle];
|
dev = &vm->devices[handle];
|
||||||
if (dev && dev->ops->refresh) {
|
if (dev && dev->ops->refresh) {
|
||||||
|
|
@ -639,9 +639,9 @@ bool step_vm(VM *vm) {
|
||||||
size_reg = read_u8(vm, code, vm->pc);
|
size_reg = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
|
||||||
device_ptr = frame->registers[device_reg]; /* device pointer */
|
device_ptr = frame->locals[device_reg]; /* device pointer */
|
||||||
buffer_ptr = frame->registers[buffer_reg]; /* R1: buffer pointer */
|
buffer_ptr = frame->locals[buffer_reg]; /* R1: buffer pointer */
|
||||||
size = frame->registers[size_reg]; /* R2: size */
|
size = frame->locals[size_reg]; /* R2: size */
|
||||||
|
|
||||||
handle = vm->memory[device_ptr + 4]; /* get device handle */
|
handle = vm->memory[device_ptr + 4]; /* get device handle */
|
||||||
dev = &vm->devices[handle];
|
dev = &vm->devices[handle];
|
||||||
|
|
@ -662,7 +662,7 @@ bool step_vm(VM *vm) {
|
||||||
device_reg = read_u8(vm, code, vm->pc);
|
device_reg = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
|
||||||
device_ptr = frame->registers[device_reg]; /* device pointer */
|
device_ptr = frame->locals[device_reg]; /* device pointer */
|
||||||
|
|
||||||
handle = vm->memory[device_ptr + 4]; /* get device handle */
|
handle = vm->memory[device_ptr + 4]; /* get device handle */
|
||||||
dev = &vm->devices[handle];
|
dev = &vm->devices[handle];
|
||||||
|
|
@ -687,9 +687,9 @@ bool step_vm(VM *vm) {
|
||||||
args_ptr_reg = read_u8(vm, code, vm->pc);
|
args_ptr_reg = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
|
||||||
device_ptr = frame->registers[device_reg]; /* device pointer */
|
device_ptr = frame->locals[device_reg]; /* device pointer */
|
||||||
cmd = frame->registers[cmd_reg]; /* R1: ioctl command */
|
cmd = frame->locals[cmd_reg]; /* R1: ioctl command */
|
||||||
args_ptr = frame->registers[args_ptr_reg]; /* R2: args pointer */
|
args_ptr = frame->locals[args_ptr_reg]; /* R2: args pointer */
|
||||||
|
|
||||||
handle = vm->memory[device_ptr + 4]; /* get device handle */
|
handle = vm->memory[device_ptr + 4]; /* get device handle */
|
||||||
dev = &vm->devices[handle];
|
dev = &vm->devices[handle];
|
||||||
|
|
@ -740,12 +740,12 @@ bool step_vm(VM *vm) {
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
|
||||||
value = frame->registers[src1];
|
value = frame->locals[src1];
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
value = -value;
|
value = -value;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame->registers[dest] = value;
|
frame->locals[dest] = value;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_NEG_INT: {
|
case OP_NEG_INT: {
|
||||||
|
|
@ -754,8 +754,8 @@ bool step_vm(VM *vm) {
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
|
||||||
value = frame->registers[src1];
|
value = frame->locals[src1];
|
||||||
frame->registers[dest] = -value;
|
frame->locals[dest] = -value;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_ADD_NAT:
|
case OP_ADD_NAT:
|
||||||
|
|
@ -773,8 +773,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src2 = read_u8(vm, code, vm->pc);
|
src2 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame->registers[dest] =
|
frame->locals[dest] =
|
||||||
fixed_mul(frame->registers[src1], frame->registers[src2]);
|
fixed_mul(frame->locals[src1], frame->locals[src2]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -785,8 +785,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src2 = read_u8(vm, code, vm->pc);
|
src2 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame->registers[dest] =
|
frame->locals[dest] =
|
||||||
fixed_div(frame->registers[src1], frame->registers[src2]);
|
fixed_div(frame->locals[src1], frame->locals[src2]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -797,8 +797,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src2 = read_u8(vm, code, vm->pc);
|
src2 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame->registers[dest] =
|
frame->locals[dest] =
|
||||||
fixed_add(frame->registers[src1], frame->registers[src2]);
|
fixed_add(frame->locals[src1], frame->locals[src2]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -809,8 +809,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src2 = read_u8(vm, code, vm->pc);
|
src2 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame->registers[dest] =
|
frame->locals[dest] =
|
||||||
fixed_sub(frame->registers[src1], frame->registers[src2]);
|
fixed_sub(frame->locals[src1], frame->locals[src2]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_REAL_TO_INT: {
|
case OP_REAL_TO_INT: {
|
||||||
|
|
@ -818,9 +818,9 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
value = frame->registers[src1];
|
value = frame->locals[src1];
|
||||||
|
|
||||||
frame->registers[dest] = fixed_to_int(value);
|
frame->locals[dest] = fixed_to_int(value);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -829,7 +829,7 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame->registers[dest] = int_to_fixed(frame->registers[src1]);
|
frame->locals[dest] = int_to_fixed(frame->locals[src1]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_REAL_TO_NAT: {
|
case OP_REAL_TO_NAT: {
|
||||||
|
|
@ -837,8 +837,8 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
value = frame->registers[src1];
|
value = frame->locals[src1];
|
||||||
frame->registers[dest] = fixed_to_int(value);
|
frame->locals[dest] = fixed_to_int(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_NAT_TO_REAL: {
|
case OP_NAT_TO_REAL: {
|
||||||
|
|
@ -846,7 +846,7 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
frame->registers[dest] = int_to_fixed(frame->registers[src1]);
|
frame->locals[dest] = int_to_fixed(frame->locals[src1]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_JEQ_NAT: {
|
case OP_JEQ_NAT: {
|
||||||
|
|
@ -909,9 +909,9 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
int_to_string(AS_INT(frame->registers[src1]), buffer);
|
int_to_string(AS_INT(frame->locals[src1]), buffer);
|
||||||
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
|
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
|
||||||
frame->registers[dest] = ptr;
|
frame->locals[dest] = ptr;
|
||||||
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -921,9 +921,9 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
nat_to_string(frame->registers[src1], buffer);
|
nat_to_string(frame->locals[src1], buffer);
|
||||||
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
|
ptr = str_alloc(vm, frame, buffer, strlength(buffer));
|
||||||
frame->registers[dest] = ptr;
|
frame->locals[dest] = ptr;
|
||||||
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -933,10 +933,10 @@ bool step_vm(VM *vm) {
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
fixed_to_string(AS_INT(frame->registers[src1]), buffer);
|
fixed_to_string(AS_INT(frame->locals[src1]), buffer);
|
||||||
ptr = str_alloc(vm, frame, buffer,
|
ptr = str_alloc(vm, frame, buffer,
|
||||||
strlength(buffer)); /* copy buffer to dest */
|
strlength(buffer)); /* copy buffer to dest */
|
||||||
frame->registers[dest] = ptr;
|
frame->locals[dest] = ptr;
|
||||||
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
set_heap_status(vm, dest, true); /* Mark as heap pointer */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -947,9 +947,9 @@ bool step_vm(VM *vm) {
|
||||||
src1 = read_u8(vm, code, vm->pc);
|
src1 = read_u8(vm, code, vm->pc);
|
||||||
vm->pc++;
|
vm->pc++;
|
||||||
|
|
||||||
ptr = frame->registers[src1];
|
ptr = frame->locals[src1];
|
||||||
length = read_u32(vm, memory, ptr);
|
length = read_u32(vm, memory, ptr);
|
||||||
frame->registers[dest] = length;
|
frame->locals[dest] = length;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case OP_STRCAT: {
|
case OP_STRCAT: {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
(call &add ($0 $1) $2)
|
(call &add ($0 $1) $2)
|
||||||
(int-to-string $3 $2)
|
(int-to-string $3 $2)
|
||||||
(call &pln ($3) nil)
|
(call &pln ($3) nil)
|
||||||
(halt 0))
|
(exit 0))
|
||||||
|
|
||||||
(label add
|
(label add
|
||||||
(add-int $2 $1 $0)
|
(add-int $2 $1 $0)
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,12 @@ function pln (str message is $0)
|
||||||
str nl is $3
|
str nl is $3
|
||||||
int nl_length is $4
|
int nl_length is $4
|
||||||
|
|
||||||
load_heap_immediate ts "/dev/term/0" # get terminal device
|
malloc_immediate "/dev/term/0" -> ts
|
||||||
load_immediate 0 -> mode
|
load_immediate 0 -> mode
|
||||||
syscall OPEN ts mode -> ts
|
syscall OPEN ts mode -> ts
|
||||||
strlen message -> msg_length
|
strlen message -> msg_length
|
||||||
syscall WRITE ts message msg_length
|
syscall WRITE ts message msg_length
|
||||||
load_heap_immediate "\n" -> nl
|
malloc_immediate "\n" -> nl
|
||||||
strlen nl -> nl_length
|
strlen nl -> nl_length
|
||||||
syscall WRITE ts nl nl_length
|
syscall WRITE ts nl nl_length
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
(call &fib ($0) $0)
|
(call &fib ($0) $0)
|
||||||
(int-to-string $1 $0)
|
(int-to-string $1 $0)
|
||||||
(call &pln ($1) nil)
|
(call &pln ($1) nil)
|
||||||
(halt 0))
|
(exit 0))
|
||||||
(label fib
|
(label fib
|
||||||
(load-immediate $1 2)
|
(load-immediate $1 2)
|
||||||
(jump-lt-int &base-case $0 $1)
|
(jump-lt-int &base-case $0 $1)
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,12 @@ function pln (str message is $0)
|
||||||
str nl is $3
|
str nl is $3
|
||||||
int nl_length is $4
|
int nl_length is $4
|
||||||
|
|
||||||
load_heap_immediate ts "/dev/term/0" # get terminal device
|
malloc_immediate "/dev/term/0" -> ts
|
||||||
load_immediate 0 -> mode
|
load_immediate 0 -> mode
|
||||||
syscall OPEN ts mode -> ts
|
syscall OPEN ts mode -> ts
|
||||||
strlen message -> msg_length
|
strlen message -> msg_length
|
||||||
syscall WRITE ts message msg_length
|
syscall WRITE ts message msg_length
|
||||||
load_heap_immediate "\n" -> nl
|
malloc_immediate "\n" -> nl
|
||||||
strlen nl -> nl_length
|
strlen nl -> nl_length
|
||||||
syscall WRITE ts nl nl_length
|
syscall WRITE ts nl nl_length
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
(label main
|
(label main
|
||||||
(load-immediate $1 &hello-str) ; load hello string ptr
|
(load-immediate $1 &hello-str) ; load hello string ptr
|
||||||
(call &pln ($1) nil)
|
(call &pln ($1) nil)
|
||||||
(halt 0)) ; done
|
(exit 0)) ; done
|
||||||
(label pln
|
(label pln
|
||||||
(load-immediate $1 &terminal-namespace) ; get terminal device
|
(load-immediate $1 &terminal-namespace) ; get terminal device
|
||||||
(load-immediate $11 0)
|
(load-immediate $11 0)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
function main ()
|
function main ()
|
||||||
str hello is $0
|
str hello is $0
|
||||||
|
|
||||||
load_heap_immediate "nuqneH 'u'?" -> hello
|
malloc_immediate "nuqneH 'u'?" -> hello
|
||||||
call pln hello
|
call pln hello
|
||||||
exit 0
|
exit 0
|
||||||
|
|
||||||
|
|
@ -12,12 +12,12 @@ function pln (str message is $0)
|
||||||
int nl_length is $4
|
int nl_length is $4
|
||||||
int mode is $5
|
int mode is $5
|
||||||
|
|
||||||
load_heap_immediate "/dev/term/0" -> ts # get terminal device
|
malloc_immediate "/dev/term/0" -> ts
|
||||||
load_immediate 0 -> mode
|
load_immediate 0 -> mode
|
||||||
syscall OPEN ts mode -> ts
|
syscall OPEN ts mode -> ts
|
||||||
strlen message -> msg_length
|
strlen message -> msg_length
|
||||||
syscall WRITE ts message msg_length
|
syscall WRITE ts message msg_length
|
||||||
load_heap_immediate "\n" -> nl
|
malloc_immediate "\n" -> nl
|
||||||
strlen nl -> nl_length
|
strlen nl -> nl_length
|
||||||
syscall WRITE ts nl nl_length
|
syscall WRITE ts nl nl_length
|
||||||
return
|
return
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
(call &pln ($4) nil)
|
(call &pln ($4) nil)
|
||||||
(real-to-string $3 $0)
|
(real-to-string $3 $0)
|
||||||
(call &pln ($3) nil)
|
(call &pln ($3) nil)
|
||||||
(halt 0))
|
(exit 0))
|
||||||
(label pln
|
(label pln
|
||||||
(load-immediate $1 &terminal-namespace) ; get terminal device
|
(load-immediate $1 &terminal-namespace) ; get terminal device
|
||||||
(load-immediate $11 0)
|
(load-immediate $11 0)
|
||||||
|
|
|
||||||
|
|
@ -14,13 +14,13 @@ function main ()
|
||||||
add_real a $5 -> a
|
add_real a $5 -> a
|
||||||
add_int i $3 -> i
|
add_int i $3 -> i
|
||||||
jump_ge_int &loop_body i $2
|
jump_ge_int &loop_body i $2
|
||||||
load_heap_immediate "/dev/term/0" -> term
|
malloc_immediate "/dev/term/0" -> 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);
|
||||||
|
|
||||||
nat b is $1
|
nat b is $1
|
||||||
real_to_nat a -> b
|
real_to_nat a -> b
|
||||||
load_heap_immediate "Enter a string:" -> $7
|
malloc_immediate "Enter a string:" -> $7
|
||||||
string_length $7 -> $8
|
string_length $7 -> $8
|
||||||
syscall WRITE term $7 $8 # print prompt
|
syscall WRITE term $7 $8 # print prompt
|
||||||
|
|
||||||
|
|
@ -43,12 +43,12 @@ function pln (str message is $0)
|
||||||
str nl is $3
|
str nl is $3
|
||||||
int nl_length is $4
|
int nl_length is $4
|
||||||
|
|
||||||
load_heap_immediate "/dev/term/0" -> ts
|
malloc_immediate "/dev/term/0" -> ts
|
||||||
load_immediate 0 -> mode
|
load_immediate 0 -> mode
|
||||||
syscall OPEN ts mode -> ts # get terminal device
|
syscall OPEN ts mode -> ts # get terminal device
|
||||||
strlen message -> msg_length
|
strlen message -> msg_length
|
||||||
syscall WRITE ts message msg_length
|
syscall WRITE ts message msg_length
|
||||||
load_heap_immediate "\n" -> nl
|
malloc_immediate "\n" -> nl
|
||||||
strlen nl -> nl_length
|
strlen nl -> nl_length
|
||||||
syscall WRITE ts nl nl_length
|
syscall WRITE ts nl nl_length
|
||||||
return
|
return
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
(syscall READ $0 $4 $1) ; read the string
|
(syscall READ $0 $4 $1) ; read the string
|
||||||
|
|
||||||
(call &pln ($0 $4) nil) ; print the string
|
(call &pln ($0 $4) nil) ; print the string
|
||||||
(halt 0))
|
(exit 0))
|
||||||
(label pln
|
(label pln
|
||||||
(load-immediate $3 &new-line)
|
(load-immediate $3 &new-line)
|
||||||
(string-length $2 $1)
|
(string-length $2 $1)
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@ function main ()
|
||||||
int mode is $11
|
int mode is $11
|
||||||
str term is $10
|
str term is $10
|
||||||
|
|
||||||
load_heap_immediate "/dev/term/0" -> term
|
malloc_immediate "/dev/term/0" -> 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);
|
||||||
|
|
||||||
load_heap_immediate "Enter a string:" -> $7
|
malloc_immediate "Enter a string:" -> $7
|
||||||
string_length $7 -> $8
|
string_length $7 -> $8
|
||||||
syscall WRITE term $7 $8 # print prompt
|
syscall WRITE term $7 $8 # print prompt
|
||||||
|
|
||||||
|
|
@ -26,11 +26,11 @@ function pln (str message is $0)
|
||||||
str nl is $3
|
str nl is $3
|
||||||
int nl_length is $4
|
int nl_length is $4
|
||||||
|
|
||||||
load_heap_immediate "/dev/term/0" -> ts
|
malloc_immediate "/dev/term/0" -> ts
|
||||||
load_immediate 0 -> mode
|
load_immediate 0 -> mode
|
||||||
syscall OPEN ts mode -> ts # get terminal device
|
syscall OPEN ts mode -> ts # get terminal device
|
||||||
strlen message -> msg_length
|
strlen message -> msg_length
|
||||||
syscall WRITE ts message msg_length
|
syscall WRITE ts message msg_length
|
||||||
load_heap_immediate "\n" -> nl
|
malloc_immediate "\n" -> nl
|
||||||
strlen nl -> nl_length
|
strlen nl -> nl_length
|
||||||
syscall WRITE ts nl nl_length
|
syscall WRITE ts nl nl_length
|
||||||
|
|
|
||||||
|
|
@ -66,8 +66,8 @@
|
||||||
|
|
||||||
(jump &draw-loop))
|
(jump &draw-loop))
|
||||||
|
|
||||||
; Flush and halt
|
; Flush and exit
|
||||||
(halt 0))
|
(exit 0))
|
||||||
|
|
||||||
(label set-color-if-clicked
|
(label set-color-if-clicked
|
||||||
; (click_x, click_y, box_x, box_y, color, box_size)
|
; (click_x, click_y, box_x, box_y, color, box_size)
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ function main ()
|
||||||
|
|
||||||
jump &draw_loop
|
jump &draw_loop
|
||||||
|
|
||||||
# Flush and halt
|
# Flush and exit
|
||||||
exit 0
|
exit 0
|
||||||
|
|
||||||
function set_color_if_clicked (int click_x is $0, int click_y is $1,
|
function set_color_if_clicked (int click_x is $0, int click_y is $1,
|
||||||
|
|
|
||||||
|
|
@ -153,8 +153,8 @@
|
||||||
|
|
||||||
(jump &draw-loop))
|
(jump &draw-loop))
|
||||||
|
|
||||||
; Flush and halt
|
; Flush and exit
|
||||||
(halt 0))
|
(exit 0))
|
||||||
|
|
||||||
(label set-color-if-clicked
|
(label set-color-if-clicked
|
||||||
; (click_x, click_y, box_x, box_y, color, box_size)
|
; (click_x, click_y, box_x, box_y, color, box_size)
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ function main ()
|
||||||
|
|
||||||
jump &draw_loop
|
jump &draw_loop
|
||||||
|
|
||||||
# Flush and halt
|
# Flush and exit
|
||||||
exit 0
|
exit 0
|
||||||
|
|
||||||
function set_color_if_clicked (int click_x is $0, int click_y is $1,
|
function set_color_if_clicked (int click_x is $0, int click_y is $1,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
(add-real $2 $1 $0)
|
(add-real $2 $1 $0)
|
||||||
(real-to-string $3 $2)
|
(real-to-string $3 $2)
|
||||||
(call &pln ($3) nil)
|
(call &pln ($3) nil)
|
||||||
(halt 0))
|
(exit 0))
|
||||||
(label pln
|
(label pln
|
||||||
(load-immediate $1 &terminal-namespace) ; get terminal device
|
(load-immediate $1 &terminal-namespace) ; get terminal device
|
||||||
(load-immediate $11 0)
|
(load-immediate $11 0)
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,12 @@ function pln (str message is $0)
|
||||||
int nl_length is $4
|
int nl_length is $4
|
||||||
int mode is $5
|
int mode is $5
|
||||||
|
|
||||||
load_heap_immediate "/dev/term/0" -> term # get terminal device
|
malloc_immediate "/dev/term/0" -> term
|
||||||
load_immediate 0 -> mode
|
load_immediate 0 -> mode
|
||||||
syscall OPEN term mode -> term
|
syscall OPEN term mode -> term
|
||||||
strlen message -> msg_length
|
strlen message -> msg_length
|
||||||
syscall WRITE term message msg_length
|
syscall WRITE term message msg_length
|
||||||
load_heap_immediate "\n" -> nl
|
malloc_immediate "\n" -> nl
|
||||||
strlen nl -> nl_length
|
strlen nl -> nl_length
|
||||||
syscall WRITE term nl nl_length
|
syscall WRITE term nl nl_length
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
(syscall WRITE $0 $21 $22) ; redraw
|
(syscall WRITE $0 $21 $22) ; redraw
|
||||||
|
|
||||||
(jump &draw-loop))
|
(jump &draw-loop))
|
||||||
(halt 0))
|
(exit 0))
|
||||||
(label pln
|
(label pln
|
||||||
(load-immediate $1 &terminal-namespace) ; get terminal device
|
(load-immediate $1 &terminal-namespace) ; get terminal device
|
||||||
(load-immediate $11 0)
|
(load-immediate $11 0)
|
||||||
|
|
|
||||||
|
|
@ -40,21 +40,21 @@ function main () {
|
||||||
|
|
||||||
byte left_down = mouse.left;
|
byte left_down = mouse.left;
|
||||||
|
|
||||||
if (left_down == 0) continue;
|
if (left_down == 1) {
|
||||||
|
nat x = mouse.x;
|
||||||
|
nat y = mouse.y;
|
||||||
|
|
||||||
nat x = mouse.x;
|
// Compute start address: y*width + x
|
||||||
nat y = mouse.y;
|
nat pixel_pos = y * width; // = y * width
|
||||||
|
pixel_pos = x + pixel_pos; // += x
|
||||||
|
pixel_pos = screen_buffer + pixel_pos; // += pixel_offset
|
||||||
|
nat fat_ptr_size = 4; // need to add offset for fat pointer size
|
||||||
|
pixel_pos = pixel_pos + fat_ptr_size;
|
||||||
|
|
||||||
// Compute start address: y*width + x
|
byte color = WHITE;
|
||||||
nat pixel_pos = y * width; // = y * width
|
store_absolute_8(pixel_pos, color); // draw color at screen [x,y]
|
||||||
pixel_pos = x + pixel_pos; // += x
|
write(screen, screen_buffer, buffer_size); // redraw
|
||||||
pixel_pos = screen_buffer + pixel_pos; // += pixel_offset
|
}
|
||||||
nat fat_ptr_size = 4; // need to add offset for fat pointer size
|
|
||||||
pixel_pos = pixel_pos + fat_ptr_size;
|
|
||||||
|
|
||||||
byte color = WHITE;
|
|
||||||
store_absolute_8(pixel_pos, color); // draw color at screen [x,y]
|
|
||||||
write(screen, screen_buffer, buffer_size); // redraw
|
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue