diff --git a/docs/favicon.ico b/docs/favicon.ico
index 1bfaf27..7a815a8 100644
Binary files a/docs/favicon.ico and b/docs/favicon.ico differ
diff --git a/docs/undar.png b/docs/undar.png
index 40cd807..cb50d0b 100644
Binary files a/docs/undar.png and b/docs/undar.png differ
diff --git a/docs/undar.svg b/docs/undar.svg
index a54757f..4e34255 100644
--- a/docs/undar.svg
+++ b/docs/undar.svg
@@ -8,7 +8,7 @@
version="1.1"
id="svg1"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
- sodipodi:docname="undâr.svg"
+ sodipodi:docname="undar.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
@@ -24,9 +24,9 @@
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showguides="false"
- inkscape:zoom="10.504938"
- inkscape:cx="69.062756"
- inkscape:cy="50.880831"
+ inkscape:zoom="5.252469"
+ inkscape:cx="31.413798"
+ inkscape:cy="77.392175"
inkscape:window-width="1939"
inkscape:window-height="932"
inkscape:window-x="0"
@@ -40,16 +40,16 @@
inkscape:groupmode="layer"
id="layer1">
diff --git a/src/arch/linux/devices.c b/src/arch/linux/devices.c
index fb85cb8..4d667b1 100644
--- a/src/arch/linux/devices.c
+++ b/src/arch/linux/devices.c
@@ -140,10 +140,14 @@ i32 mouse_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
}
i32 mouse_read(void *data, u8 *buffer, u32 size) {
- MouseDeviceData *mouse_data = (MouseDeviceData *)data;
+ USED(data);
+ USED(buffer);
+ USED(size);
+ return -1;
+}
- if (size < 12)
- return -1;
+i32 mouse_refresh(void *data, u8 *buffer) {
+ MouseDeviceData *mouse_data = (MouseDeviceData *)data;
u8 *info = (u8 *)buffer;
memcpy(&info[4], &mouse_data->x, sizeof(u32));
diff --git a/src/arch/linux/devices.h b/src/arch/linux/devices.h
index b252c03..d0a5549 100644
--- a/src/arch/linux/devices.h
+++ b/src/arch/linux/devices.h
@@ -52,6 +52,7 @@ i32 screen_ioctl(void *data, u32 cmd, const u8 *buffer);
i32 mouse_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size);
i32 mouse_read(void *data, u8 *buffer, u32 size);
+i32 mouse_refresh(void *data, u8 *buffer);
i32 mouse_write(void *data, const u8 *buffer, u32 size);
i32 mouse_close(void *data);
diff --git a/src/arch/linux/main.c b/src/arch/linux/main.c
index 9e52f93..8bcfe9a 100644
--- a/src/arch/linux/main.c
+++ b/src/arch/linux/main.c
@@ -15,19 +15,22 @@ static DeviceOps screen_ops = {.open = screen_open,
.read = screen_read,
.write = screen_write,
.close = screen_close,
- .ioctl = screen_ioctl};
+ .ioctl = screen_ioctl,
+ .refresh = nil};
static DeviceOps mouse_ops = {.open = mouse_open,
.read = mouse_read,
.write = mouse_write,
.close = mouse_close,
- .ioctl = nil};
+ .ioctl = nil,
+ .refresh = mouse_refresh};
static DeviceOps keyboard_ops = {.open = keyboard_open,
.read = keyboard_read,
.write = keyboard_write,
.close = keyboard_close,
- .ioctl = nil};
+ .ioctl = nil,
+ .refresh = nil};
static DeviceOps console_device_ops = {
.open = console_open,
@@ -35,6 +38,7 @@ static DeviceOps console_device_ops = {
.write = console_write,
.close = console_close,
.ioctl = console_ioctl,
+ .refresh = nil
};
static ScreenDeviceData screen_data = {0};
diff --git a/src/tools/assembler.c b/src/tools/assembler.c
index d7005cb..e528283 100644
--- a/src/tools/assembler.c
+++ b/src/tools/assembler.c
@@ -721,6 +721,8 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) {
syscall_id = SYSCALL_DEVICE_CLOSE;
else if (strcmp(syscall_name, "IOCTL") == 0)
syscall_id = SYSCALL_DEVICE_IOCTL;
+ else if (strcmp(syscall_name, "REFRESH") == 0)
+ syscall_id = SYSCALL_DEVICE_REFRESH;
emit_u32(vm, syscall_id);
diff --git a/src/vm/opcodes.h b/src/vm/opcodes.h
index 4b5da65..e3c038b 100644
--- a/src/vm/opcodes.h
+++ b/src/vm/opcodes.h
@@ -103,7 +103,8 @@ typedef enum {
SYSCALL_DEVICE_READ,
SYSCALL_DEVICE_WRITE,
SYSCALL_DEVICE_CLOSE,
- SYSCALL_DEVICE_IOCTL
+ SYSCALL_DEVICE_IOCTL,
+ SYSCALL_DEVICE_REFRESH
} SyscallID;
typedef struct device_ops_s {
@@ -113,6 +114,7 @@ typedef struct device_ops_s {
i32 (*close)(void *device_data);
i32 (*ioctl)(void *device_data, u32 cmd,
const u8 *buffer); /* optional control */
+ i32 (*refresh)(void *device_data, u8 *buffer);
} DeviceOps;
#define DEVICE_TYPE_MAX_LENGTH 16 /* 15 chars + null terminator */
diff --git a/src/vm/vm.c b/src/vm/vm.c
index 50701f2..a511262 100644
--- a/src/vm/vm.c
+++ b/src/vm/vm.c
@@ -556,7 +556,7 @@ bool step_vm(VM *vm) {
switch (syscall_id) {
case SYSCALL_DEVICE_OPEN: {
Device *dev;
- u32 path_ptr, mode, buffer_ptr;
+ u32 path_ptr, mode, device_ptr;
u8 path_reg, mode_reg, dest_reg;
dest_reg = read_u8(vm, code, vm->pc);
vm->pc++;
@@ -571,14 +571,14 @@ bool step_vm(VM *vm) {
if (dev) {
if (dev->ops->open) {
/* return device plex to user */
- buffer_ptr = vm->mp;
- frame->registers[dest_reg] = buffer_ptr;
+ device_ptr = vm->mp;
+ frame->registers[dest_reg] = device_ptr;
/* malloc size for device */
- write_u32(vm, memory, buffer_ptr, dev->size);
+ write_u32(vm, memory, device_ptr, dev->size);
vm->mp += (dev->size + 4);
/* set flag from user */
vm->flag = dev->ops->open(dev->data, mode, dev->handle,
- &vm->memory[buffer_ptr + 4], dev->size);
+ &vm->memory[device_ptr + 4], dev->size);
} else {
vm->flag = 1; /* success, no open needed */
}
@@ -591,25 +591,23 @@ bool step_vm(VM *vm) {
case SYSCALL_DEVICE_READ: {
Device *dev;
- u32 handle, buffer_ptr, size;
- u16 handle_reg, buffer_reg, size_reg;
- handle_reg = read_u8(vm, code, vm->pc);
+ u32 device_ptr, buffer_ptr, size;
+ u8 device_reg, buffer_reg, size_reg, handle;
+ device_reg = read_u8(vm, code, vm->pc);
vm->pc++;
buffer_reg = read_u8(vm, code, vm->pc);
vm->pc++;
size_reg = read_u8(vm, code, vm->pc);
vm->pc++;
- dest = read_u8(vm, code, vm->pc);
- vm->pc++;
- handle = frame->registers[handle_reg]; /* path pointer */
+ device_ptr = frame->registers[device_reg]; /* device pointer */
+ buffer_ptr = frame->registers[buffer_reg];
size = frame->registers[size_reg]; /* size */
- buffer_ptr = frame->registers[dest];
+ handle = vm->memory[device_ptr + 4]; /* get device handle */
dev = &vm->devices[handle];
if (dev && dev->ops->read) {
vm->flag = dev->ops->read(dev->data, &vm->memory[buffer_ptr + 4], size);
- frame->registers[buffer_reg] = buffer_ptr;
} else {
vm->flag = 0;
}
@@ -617,21 +615,42 @@ bool step_vm(VM *vm) {
return true;
}
+ case SYSCALL_DEVICE_REFRESH: {
+ Device *dev;
+ u32 handle, device_ptr;
+ u8 device_reg;
+ device_reg = read_u8(vm, code, vm->pc);
+ vm->pc++;
+
+ device_ptr = frame->registers[device_reg]; /* device pointer */
+ handle = vm->memory[device_ptr + 4]; /* get device handle */
+ dev = &vm->devices[handle];
+ if (dev && dev->ops->refresh) {
+ vm->flag = dev->ops->refresh(dev->data, &vm->memory[device_ptr + 4]);
+ } else {
+ vm->flag = 0;
+ }
+
+ return true;
+ }
+
+
case SYSCALL_DEVICE_WRITE: {
Device *dev;
- u32 handle, buffer_ptr, size;
- u16 handle_reg, buffer_reg, size_reg;
- handle_reg = read_u8(vm, code, vm->pc);
+ u32 handle, buffer_ptr, size, device_ptr;
+ u8 device_reg, buffer_reg, size_reg;
+ device_reg = read_u8(vm, code, vm->pc);
vm->pc++;
buffer_reg = read_u8(vm, code, vm->pc);
vm->pc++;
size_reg = read_u8(vm, code, vm->pc);
vm->pc++;
- handle = frame->registers[handle_reg]; /* R0: path pointer */
+ device_ptr = frame->registers[device_reg]; /* device pointer */
buffer_ptr = frame->registers[buffer_reg]; /* R1: buffer pointer */
size = frame->registers[size_reg]; /* R2: size */
+ handle = vm->memory[device_ptr + 4]; /* get device handle */
dev = &vm->devices[handle];
if (dev && dev->ops->write) {
vm->flag = dev->ops->write(
@@ -645,13 +664,14 @@ bool step_vm(VM *vm) {
case SYSCALL_DEVICE_CLOSE: {
Device *dev;
- u32 handle;
- u8 handle_reg;
- handle_reg = read_u8(vm, code, vm->pc);
+ u32 handle, device_ptr;
+ u8 device_reg;
+ device_reg = read_u8(vm, code, vm->pc);
vm->pc++;
- handle = frame->registers[handle_reg]; /* R0: path pointer */
+ device_ptr = frame->registers[device_reg]; /* device pointer */
+ handle = vm->memory[device_ptr + 4]; /* get device handle */
dev = &vm->devices[handle];
if (dev && dev->ops->close) {
i32 result = dev->ops->close(dev->data);
@@ -665,19 +685,20 @@ bool step_vm(VM *vm) {
case SYSCALL_DEVICE_IOCTL: {
Device *dev;
- u32 handle, args_ptr, cmd;
- u8 handle_reg, cmd_reg, args_ptr_reg;
- handle_reg = read_u8(vm, code, vm->pc);
+ u32 handle, args_ptr, cmd, device_ptr;
+ u8 device_reg, cmd_reg, args_ptr_reg;
+ device_reg = read_u8(vm, code, vm->pc);
vm->pc++;
cmd_reg = read_u8(vm, code, vm->pc);
vm->pc++;
args_ptr_reg = read_u8(vm, code, vm->pc);
vm->pc++;
- handle = frame->registers[handle_reg]; /* R0: device path */
+ device_ptr = frame->registers[device_reg]; /* device pointer */
cmd = frame->registers[cmd_reg]; /* R1: ioctl command */
args_ptr = frame->registers[args_ptr_reg]; /* R2: args pointer */
+ handle = vm->memory[device_ptr + 4]; /* get device handle */
dev = &vm->devices[handle];
if (dev && dev->ops && dev->ops->ioctl) {
i32 result = dev->ops->ioctl(dev->data, cmd, &vm->memory[args_ptr]);
diff --git a/test/paint-bw.asm.lisp b/test/paint-bw.asm.lisp
index 4c45753..92b5785 100644
--- a/test/paint-bw.asm.lisp
+++ b/test/paint-bw.asm.lisp
@@ -4,20 +4,17 @@
; 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 $18 $0 $11) ; open(out Plex screen, in namespace, in flags)
+ (syscall OPEN $0 $18 $11) ; open(out Plex screen, in namespace, in flags)
- (load-offset-32 $0 $18 4) ; load handle
- (load-offset-32 $20 $18 8) ; load width
- (load-offset-32 $22 $18 12) ; load size
+ (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 $18 $1)
+ (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)
- (load-offset-32 $16 $15 4) ; load handle
-
; outline_swatch(screen, BLACK, 1, 1);
(load-absolute-32 $1 &BLACK)
(load-immediate $12 1)
@@ -33,16 +30,15 @@
; screen.draw();
(syscall WRITE $0 $21 $22)
- (load-immediate $3 16)
(label draw-loop
; load mouse click data
- (syscall READ $16 $2 $3 $15)
+ (syscall REFRESH $15)
(load-offset-8 $9 $15 16) ; load btn1 pressed
(jump-eq-nat &draw-loop $9 $11)
- (load-offset-32 $7 $2 8) ; load x
- (load-offset-32 $8 $2 12) ; load y
+ (load-offset-32 $7 $15 8) ; load x
+ (load-offset-32 $8 $15 12) ; load y
(load-immediate $14 20) ; box size
diff --git a/test/paint.asm.lisp b/test/paint.asm.lisp
index 44c617d..8e96811 100644
--- a/test/paint.asm.lisp
+++ b/test/paint.asm.lisp
@@ -4,20 +4,17 @@
; 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 $18 $0 $11) ; Screen screen = open(namespace, flags)
+ (syscall OPEN $0 $0 $11) ; Screen screen = open(namespace, flags)
- (load-offset-32 $0 $18 4) ; load handle
- (load-offset-32 $20 $18 8) ; load width
- (load-offset-32 $22 $18 12) ; load size
- (load-immediate $1 16) ; offset for screen buffer
- (add-nat $21 $18 $1)
+ (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)
- (load-offset-32 $16 $15 4) ; load handle
-
; outline_swatch(screen, BLACK, 1, 1);
(load-absolute-32 $1 &BLACK)
(load-immediate $12 1)
@@ -73,16 +70,15 @@
; screen.draw();
(syscall WRITE $0 $21 $22)
- (load-immediate $3 16)
(label draw-loop
; load mouse click data
- (syscall READ $16 $2 $3 $15)
+ (syscall REFRESH $15)
(load-offset-8 $9 $15 16) ; load btn1 pressed
(jump-eq-nat &draw-loop $9 $11)
- (load-offset-32 $7 $2 8) ; load x
- (load-offset-32 $8 $2 12) ; load y
+ (load-offset-32 $7 $15 8) ; load x
+ (load-offset-32 $8 $15 12) ; load y
(load-immediate $14 20) ; box size
@@ -229,8 +225,8 @@
(return nil)))
(data
(label screen-namespace "/dev/screen/0")
- (label mouse-namespace "/dev/mouse/0")
- (label SELECTED-COLOR 255)
+ (label mouse-namespace "/dev/mouse/0")
+ (label SELECTED-COLOR 255)
(label BLACK 0)
(label WHITE 255)
(label CHARCOAL 36)
diff --git a/test/paint.ul b/test/paint.ul
index f6b936e..0bf6aa8 100644
--- a/test/paint.ul
+++ b/test/paint.ul
@@ -1,8 +1,6 @@
/**
* Constants
*/
-const str screen_namespace = "/dev/screen/0";
-const str mouse_namespace = "/dev/mouse/0";
const byte BLACK = 0;
const byte WHITE = 255;
const byte DARK_GRAY = 73;
@@ -22,8 +20,10 @@ plex Screen implements Device {
nat buffer_size;
byte[] screen_buffer;
- init(str namespace) {
- this.handle = open(namespace);
+ draw() {
+ unsafe {
+ write(this.handle, &this.screen_buffer, this.buffer_size);
+ }
}
}
@@ -35,29 +35,21 @@ plex Mouse implements Device {
bool right;
bool middle;
bool btn4;
- nat size;
-
- init(str namespace) {
- this.handle = open(namespace);
- }
}
/**
* Main function
*/
function main() {
- Screen screen(screen_namespace);
- screen.open(0);
-
- Mouse mouse(mouse_namespace);
- mouse.open(0);
+ Screen screen = open("/dev/screen/0", 0);
+ Mouse mouse = open("/dev/mouse/0", 0);
outline_swatch(screen, BLACK, 1, 1);
outline_swatch(screen, WHITE, 21, 1);
screen.draw();
loop {
- mouse.read();
+ mouse.refresh();
if (not mouse.left) continue;
int box_size = 20;
@@ -98,7 +90,7 @@ function set_color(int box_size, int bx, int by, int mx, int my, byte color) {
/**
* Draw a color box with a grey outline, if selected use a darker color
*/
-function outline_swatch(ref Device screen, byte color, int x, int y) {
+function outline_swatch(Device screen, byte color, int x, int y) {
byte bg_color = GRAY;
if (selected_color == color) {
bg_color = DARK_GRAY;
@@ -112,7 +104,7 @@ function outline_swatch(ref Device screen, byte color, int x, int y) {
/**
* Draw a rectangle
*/
-function rectangle(ref Device screen, byte color, int x, int y, int width, int height) {
+function rectangle(Device screen, byte color, int x, int y, int width, int height) {
// we need unsafe because we are using `ptr` and `memset` directly
// unsafe takes the guardrails off and allows you to access/modify memory directly
unsafe {
diff --git a/test/simple.asm.lisp b/test/simple.asm.lisp
index 8aed424..6562d0b 100644
--- a/test/simple.asm.lisp
+++ b/test/simple.asm.lisp
@@ -11,7 +11,7 @@
(load-immediate $11 0)
(syscall OPEN $1 $1 $11)
(load-immediate $3 &new-line)
- (load-offset-32 $7 $1 4) ; load handle
+ (load-offset-32 $7 $1 4) ; load handle
(string-length $2 $0)
(syscall WRITE $7 $0 $2)
(string-length $4 $3)
diff --git a/test/simple.ul b/test/simple.ul
index 5b26383..ff59272 100644
--- a/test/simple.ul
+++ b/test/simple.ul
@@ -2,12 +2,14 @@
* Constants
*/
const str nl = "\n";
+const real x = 1.0;
+const real y = 1.0;
plex Terminal {
nat handle;
init() {
- handle = open("/dev/term/0", 0);
+ this.handle = open("/dev/term/0", 0);
}
}
@@ -15,7 +17,7 @@ plex Terminal {
* Main function
*/
function main() {
- pln((1 + 2).str);
+ pln((x + y).str);
}
/**
diff --git a/test/window.asm.lisp b/test/window.asm.lisp
index 5b2c0e5..5246bab 100644
--- a/test/window.asm.lisp
+++ b/test/window.asm.lisp
@@ -2,26 +2,24 @@
(label main
; Open screen
; use load immediate because it is a pointer to a string, not a value
- (load-immediate $0 &screen-namespace)
- (syscall OPEN $18 $0 $11) ; open(out Plex screen, in namespace, in flags)
-
- (load-offset-32 $0 $18 4) ; load handle
+ (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 $18 8) ; load width
+ (load-offset-32 $20 $0 8) ; load width
(nat-to-string $5 $20)
(call &pln ($5) nil)
- (load-offset-32 $22 $18 12) ; load size
+ (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 $18 $1)
+ (add-nat $21 $0 $1)
(nat-to-string $5 $21)
(call &pln ($5) nil)
@@ -30,21 +28,17 @@
(load-immediate $16 &mouse-namespace)
(syscall OPEN $15 $16 $11) ; open(out Plex mouse, in namespace, in flags)
- (load-offset-32 $16 $15 4) ; load handle
-
(syscall WRITE $0 $21 $22) ; redraw
- (load-immediate $3 16)
(label draw-loop
; load mouse click data
- (syscall READ $16 $2 $3 $15)
-
+ (syscall REFRESH $15)
(load-offset-8 $9 $15 16) ; load btn1 pressed
(jump-eq-nat &draw-loop $9 $11)
- (load-offset-32 $7 $2 8) ; load x
- (load-offset-32 $8 $2 12) ; load y
+ (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
@@ -64,11 +58,10 @@
(load-immediate $11 0)
(syscall OPEN $1 $1 $11)
(load-immediate $3 &new-line)
- (load-offset-32 $7 $1 4) ; load handle
(string-length $2 $0)
- (syscall WRITE $7 $0 $2)
+ (syscall WRITE $1 $0 $2)
(string-length $4 $3)
- (syscall WRITE $7 $3 $4)
+ (syscall WRITE $1 $3 $4)
(return nil)))
(data
(label screen-namespace "/dev/screen/0")