Update devices to use plexes instead of raw memory

This commit is contained in:
zongor 2025-10-17 16:11:20 -07:00
parent 3f3c6e1b80
commit d69b83f4eb
12 changed files with 379 additions and 331 deletions

View File

@ -1,78 +0,0 @@
str screen_namespace = "/dev/screen/0";
str mouse_namespace = "/dev/mouse/0";
byte selected_color = 255;
const byte BLACK = 0;
const byte WHITE = 255;
const byte DARK_GRAY = 73;
const byte GRAY = 146;
const byte LIGHT_GRAY = 182;
function main() {
Device screen(screen_namespace);
screen.open(0);
Device mouse(mouse_namespace);
mouse.open(0);
outline_swatch(screen, BLACK, 1, 1);
outline_swatch(screen, WHITE, 21, 1);
screen.draw();
while (true) {
mouse.read();
if (mouse.btn1) {
int box_size = 20;
int x = 1;
int y = 1;
byte color = BLACK;
outlined_swatch(screen, color, x, y);
set_color_if_clicked(box_size, x, y, mouse.x, mouse.y, color, mouse.btn1);
color = WHITE;
x = 21;
outlined_swatch(screen, color, x, y);
set_color_if_clicked(box_size, x, y, mouse.x, mouse.y, color, mouse.btn1);
screen.draw();
box(screen, selected_color, x, y, 5, 5);
}
}
exit(0);
}
function set_color_if_clicked(int box_size, int bx, int by, int mx, int my, byte color, bool btn1_down) {
int right = bx + box_size;
int bottom = by + box_size;
if (mx < mx) return;
if (mx > right) return;
if (my < by) return;
if (my > bottom) return;
if (not btn1_down) return;
selected_color = color;
return;
}
function outline_swatch(ref Device screen, byte color, int x, int y) {
byte bg_color = GRAY;
if (selected_color == color) {
bg_color = DARK_GRAY;
}
box(screen, bg_color, x, y, 20, 20);
box(screen, color, x + 2, y + 2, 17, 17);
return;
}
function box(ref Device screen, byte color, int x, int y, int width, int height) {
int pixel = y * width + x + &screen.buffer + 4;
do (int i = height, i > 0, i--) {
int row = pixel + width;
screen.set(row, color, width);
pixel += width;
}
return;
}

119
docs/paint.ul Executable file
View File

@ -0,0 +1,119 @@
/**
* Constatnts
*/
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;
const byte GRAY = 146;
const byte LIGHT_GRAY = 182;
byte selected_color = 255;
interface Device {
nat handle;
}
plex Screen implements Device {
nat handle;
nat width;
nat height;
nat buffer_size;
byte[] screen_buffer;
init(str namespace) {
this.handle = open(namespace);
}
}
plex Mouse implements Device {
u32 handle;
u32 x;
u32 y;
u8 btn1;
u8 btn2;
u8 btn3;
u8 btn4;
u32 size;
}
/**
* Main function
*/
function main() {
Screen screen(screen_namespace);
screen.open(0);
Mouse mouse(mouse_namespace);
mouse.open(0);
outline_swatch(screen, BLACK, 1, 1);
outline_swatch(screen, WHITE, 21, 1);
screen.draw();
loop {
mouse.read();
if (not mouse.left) continue;
int box_size = 20;
int x = 1;
int y = 1;
byte color = BLACK;
outlined_swatch(screen, color, x, y);
set_color(box_size, x, y, mouse.x, mouse.y, color);
color = WHITE;
x = 21;
outlined_swatch(screen, color, x, y);
set_color(box_size, x, y, mouse.x, mouse.y, color);
screen.draw();
rectangle(screen, selected_color, x, y, 5, 5);
}
exit(0);
}
/**
* Checks if the click is within the bound and update the selected color if so.
*/
function set_color(int box_size, int bx, int by, int mx, int my, byte color) {
int right = bx + box_size;
int bottom = by + box_size;
if (mx < bx) return;
if (mx > right) return;
if (my < by) return;
if (my > bottom) return;
selected_color = color;
return;
}
/**
* 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) {
byte bg_color = GRAY;
if (selected_color == color) {
bg_color = DARK_GRAY;
}
rectangle(screen, bg_color, x, y, 20, 20);
rectangle(screen, color, x + 2, y + 2, 17, 17);
return;
}
/**
* Draw a rectanlge
*/
function rectangle(ref Device screen, byte color, int x, int y, int width, int height) {
int pixel = y * width + x + &screen.buffer + 4;
do (int i = height; i > 0; i--) {
int row = pixel + width;
screen.set(row, color, width);
pixel += width;
}
return;
}

View File

@ -4,20 +4,25 @@
#include <emscripten.h>
#include <emscripten/html5.h>
i32 console_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
USED(mode);
USED(data);
USED(buffer);
USED(size);
return 0;
ConsoleDeviceData *console = (ConsoleDeviceData *)data;
console->handle = handle;
u8 *info = (u8 *)buffer;
memcpy(&info[0], &console->handle, sizeof(u32));
return 0; /* Success */
}
i32 console_read(void *data, u8 *buffer, u32 size) {
USED(data);
for (u32 i = 0; i < size; i++) {
u8 ch = getchar();
if (ch == '\0' || ch == '\n') break;
if (ch == '\0')
break;
if (ch == '\n')
break;
buffer[i] = ch;
}
return 0;
@ -33,6 +38,7 @@ i32 console_write(void *data, const u8 *buffer, u32 size) {
i32 console_close(void *data) {
USED(data);
/* Nothing to close — stdin/stdout are process-owned */
return 0;
}
@ -40,98 +46,66 @@ i32 console_ioctl(void *data, u32 cmd, const u8 *buffer) {
USED(data);
USED(cmd);
USED(buffer);
return -1;
return -1; /* Unsupported */
}
i32 screen_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
USED(mode);
USED(size);
ScreenDeviceData *screen = (ScreenDeviceData *)data;
screen->handle = handle;
// Initialize with proper values
screen->width = 640;
screen->height = 480;
screen->size = 640 * 480 + 12;
screen->window = NULL;
screen->renderer = NULL;
screen->texture = NULL;
printf("handle=%d, size=%d\n", handle, size);
u8 *info = (u8 *)buffer;
memcpy(&info[0], &screen->width, sizeof(u32));
memcpy(&info[4], &screen->height, sizeof(u32));
memcpy(&info[8], &screen->size, sizeof(u32));
memcpy(&info[0], &screen->handle, sizeof(u32));
memcpy(&info[4], &screen->width, sizeof(u32));
memcpy(&info[8], &screen->height, sizeof(u32));
memcpy(&info[12], &screen->buffer_size, sizeof(u32));
screen->screen_buffer = (u8*)(buffer + 16);
#ifdef __EMSCRIPTEN__
emscripten_set_canvas_element_size("#canvas", screen->width, screen->height);
#endif
screen->window = SDL_CreateWindow(
"Reality Engine VM",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
screen->width,
screen->height,
SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI
);
screen->window =
SDL_CreateWindow("Reality Engine VM", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, screen->width, screen->height,
SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
if (!screen->window) {
fprintf(stderr, "Failed to create SDL window: %s\n", SDL_GetError());
return -1;
}
// Create renderer with hardware acceleration
screen->renderer = SDL_CreateRenderer(
screen->window, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
);
screen->renderer =
SDL_CreateRenderer(screen->window, -1, SDL_RENDERER_ACCELERATED);
if (!screen->renderer) {
fprintf(stderr, "Failed to create SDL renderer: %s\n", SDL_GetError());
return -1;
}
// Create the texture with RGB332 format
screen->texture = SDL_CreateTexture(
screen->renderer,
SDL_PIXELFORMAT_RGB332,
screen->texture = SDL_CreateTexture(screen->renderer, SDL_PIXELFORMAT_RGB332,
SDL_TEXTUREACCESS_STREAMING,
screen->width,
screen->height
);
screen->width, screen->height);
if (!screen->texture) {
// If RGB332 isn't supported, try RGB888
screen->texture = SDL_CreateTexture(
screen->renderer,
SDL_PIXELFORMAT_RGB888,
SDL_TEXTUREACCESS_STREAMING,
screen->width,
screen->height
);
if (!screen->texture) {
fprintf(stderr, "Failed to create SDL texture: %s\n", SDL_GetError());
fprintf(stderr, "SDL_CreateTexture failed: %s\n", SDL_GetError());
return -1;
}
printf("Using RGB888 format (conversion needed)\n");
} else {
printf("Using direct RGB332 format\n");
}
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
return 0;
}
i32 screen_read(void *data, u8 *buffer, u32 size) {
USED(data);
USED(buffer);
USED(size);
return -1;
}
i32 screen_write(void *data, const u8 *buffer, u32 size) {
ScreenDeviceData *screen = (ScreenDeviceData *)data;
if (size > screen->size) {
printf("Screen write size mismatch: %d > %d\n", size, screen->size);
if (size > screen->buffer_size * sizeof(u8)) {
return -1;
}
if (!screen->screen_buffer) {
screen->screen_buffer = (u8*)buffer;
}
// Update texture with new frame data
SDL_UpdateTexture(screen->texture, NULL, buffer, screen->width);
screen->update = true;
@ -142,31 +116,13 @@ i32 screen_write(void *data, const u8 *buffer, u32 size) {
i32 screen_close(void *data) {
ScreenDeviceData *screen = (ScreenDeviceData *)data;
if (screen->texture) {
SDL_DestroyTexture(screen->texture);
screen->texture = NULL;
}
if (screen->renderer) {
SDL_DestroyRenderer(screen->renderer);
screen->renderer = NULL;
}
if (screen->window) {
SDL_DestroyWindow(screen->window);
screen->window = NULL;
}
return 0;
}
i32 screen_read(void *data, u8 *buffer, u32 size) {
USED(data);
USED(buffer);
USED(size);
return -1;
}
i32 screen_ioctl(void *data, u32 cmd, const u8 *buffer) {
USED(data);
USED(cmd);
@ -174,23 +130,32 @@ i32 screen_ioctl(void *data, u32 cmd, const u8 *buffer) {
return 0;
}
/* MOUSE */
i32 mouse_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
USED(mode);
USED(size);
MouseDeviceData *mouse = (MouseDeviceData *)data;
mouse->handle = handle;
u8 *info = (u8 *)buffer;
memcpy(&info[0], &mouse->handle, sizeof(u32));
return 0;
}
i32 mouse_read(void *data, u8 *buffer, u32 size) {
MouseDeviceData *mouse_data = (MouseDeviceData *)data;
if (size < 12) return -1;
if (size < 12)
return -1;
u8 *info = (u8 *)buffer;
memcpy(&info[0], &mouse_data->x, sizeof(u32));
memcpy(&info[4], &mouse_data->y, sizeof(u32));
memcpy(&info[8], &mouse_data->btn1, sizeof(u8));
memcpy(&info[9], &mouse_data->btn2, sizeof(u8));
memcpy(&info[10], &mouse_data->btn3, sizeof(u8));
memcpy(&info[11], &mouse_data->btn4, sizeof(u8));
memcpy(&info[4], &mouse_data->x, sizeof(u32));
memcpy(&info[8], &mouse_data->y, sizeof(u32));
memcpy(&info[12], &mouse_data->btn1, sizeof(u8));
memcpy(&info[13], &mouse_data->btn2, sizeof(u8));
memcpy(&info[14], &mouse_data->btn3, sizeof(u8));
memcpy(&info[15], &mouse_data->btn4, sizeof(u8));
return 0;
}
@ -207,18 +172,25 @@ i32 mouse_close(void *data) {
}
i32 keyboard_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
USED(data);
USED(mode);
USED(buffer);
USED(size);
KeyboardDeviceData *kbd = (KeyboardDeviceData *)data;
kbd->handle = handle;
u8 *info = (u8 *)buffer;
memcpy(&info[0], &kbd->handle, sizeof(u32));
return 0;
}
i32 keyboard_read(void *data, u8 *buffer, u32 size) {
KeyboardDeviceData *kbd = (KeyboardDeviceData *)data;
if (size < (u32)kbd->key_count) return -1;
if (size < (u32)kbd->key_count)
return -1;
memcpy(buffer, kbd->keys, kbd->key_count);
u8 *info = (u8 *)buffer;
memcpy(&info[0], &kbd->handle, sizeof(u32));
return 0;
}
@ -226,7 +198,7 @@ i32 keyboard_write(void *data, const u8 *buffer, u32 size) {
USED(data);
USED(buffer);
USED(size);
return -1;
return -1; /* not writable */
}
i32 keyboard_close(void *data) {

View File

@ -1,14 +1,17 @@
#include "../../vm/device.h"
#include "../../vm/vm.h"
#include <SDL2/SDL.h>
#define IOCTL_GET_INFO 0x01
/* Screen device data */
typedef struct screen_device_data_s {
u32 handle;
u32 width;
u32 height;
u32 size;
u32 buffer_size;
u8 *screen_buffer;
u32 pos;
bool update;
u32 update;
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *texture;
@ -23,15 +26,14 @@ typedef struct mouse_device_data_s {
u8 btn2;
u8 btn3;
u8 btn4;
u32 pos;
u32 size;
} MouseDeviceData;
/* Keyboard device data */
typedef struct keyboard_device_data_s {
u32 handle;
i32 key_count;
const u8 *keys;
i32 key_count;
u32 pos;
u32 size;
} KeyboardDeviceData;

View File

@ -30,6 +30,7 @@ static DeviceOps console_device_ops = {
static ScreenDeviceData screen_data = {0};
static MouseDeviceData mouse_data = {0};
static ConsoleDeviceData console_data = {0};
void mainloop() {
SDL_Event event;
@ -166,7 +167,7 @@ int main(int argc, char **argv) {
// Initialize device data
screen_data.width = 640;
screen_data.height = 480;
screen_data.size = 640 * 480;
screen_data.buffer_size = screen_data.width * screen_data.height;
screen_data.window = NULL;
screen_data.renderer = NULL;
screen_data.texture = NULL;
@ -177,12 +178,15 @@ int main(int argc, char **argv) {
mouse_data.btn2 = 0;
mouse_data.btn3 = 0;
mouse_data.btn4 = 0;
mouse_data.size = 12;
mouse_data.size = 16;
// Register devices
vm_register_device(&vm, "/dev/screen/0", "screen", &screen_data, &screen_ops);
vm_register_device(&vm, "/dev/mouse/0", "mouse", &mouse_data, &mouse_ops);
vm_register_device(&vm, "/dev/term/0", "terminal", NULL, &console_device_ops);
vm_register_device(&vm, "/dev/screen/0", "screen", &screen_data,
&screen_ops, 16 + screen_data.buffer_size);
vm_register_device(&vm, "/dev/mouse/0", "mouse", &mouse_data, &mouse_ops,
mouse_data.size);
vm_register_device(&vm, "/dev/term/0", "terminal", &console_data,
&console_device_ops, 4);
// Set up main loop
emscripten_set_main_loop(mainloop, 0, 1);

View File

@ -54,11 +54,14 @@ i32 screen_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
ScreenDeviceData *screen = (ScreenDeviceData *)data;
screen->handle = handle;
printf("handle=%d, size=%d\n", handle, size);
u8 *info = (u8 *)buffer;
memcpy(&info[0], &screen->handle, sizeof(u32));
memcpy(&info[4], &screen->width, sizeof(u32));
memcpy(&info[8], &screen->height, sizeof(u32));
memcpy(&info[12], &screen->size, sizeof(u32));
memcpy(&info[12], &screen->buffer_size, sizeof(u32));
screen->screen_buffer = (u8*)(buffer + 16);
screen->window =
SDL_CreateWindow("Reality Engine VM", SDL_WINDOWPOS_CENTERED,
@ -98,12 +101,9 @@ i32 screen_read(void *data, u8 *buffer, u32 size) {
i32 screen_write(void *data, const u8 *buffer, u32 size) {
ScreenDeviceData *screen = (ScreenDeviceData *)data;
if (size > screen->size * sizeof(u8)) {
if (size > screen->buffer_size * sizeof(u8)) {
return -1;
}
if (!screen->screen_buffer) {
screen->screen_buffer = (u8*)buffer;
}
// Update texture with new frame data
SDL_UpdateTexture(screen->texture, NULL, buffer, screen->width);
@ -147,24 +147,14 @@ i32 mouse_read(void *data, u8 *buffer, u32 size) {
if (size < 12)
return -1;
SDL_PumpEvents();
int x, y;
Uint32 state = SDL_GetMouseState(&x, &y);
mouse_data->x = x;
mouse_data->y = y;
mouse_data->btn1 = (state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? 1 : 0;
mouse_data->btn2 = (state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? 1 : 0;
mouse_data->btn3 = (state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? 1 : 0;
mouse_data->btn4 = (state & SDL_BUTTON(SDL_BUTTON_X1)) ? 1 : 0;
u8 *info = (u8 *)buffer;
memcpy(&info[4], &mouse_data->x, sizeof(u32));
memcpy(&info[8], &mouse_data->y, sizeof(u32));
memcpy(&info[9], &mouse_data->btn1, sizeof(u8));
memcpy(&info[10], &mouse_data->btn2, sizeof(u8));
memcpy(&info[11], &mouse_data->btn3, sizeof(u8));
memcpy(&info[12], &mouse_data->btn4, sizeof(u8));
memcpy(&info[12], &mouse_data->btn1, sizeof(u8));
memcpy(&info[13], &mouse_data->btn2, sizeof(u8));
memcpy(&info[14], &mouse_data->btn3, sizeof(u8));
memcpy(&info[15], &mouse_data->btn4, sizeof(u8));
return 0;
}
@ -199,7 +189,7 @@ i32 keyboard_read(void *data, u8 *buffer, u32 size) {
return -1;
u8 *info = (u8 *)buffer;
memcpy(&info[4], kbd->keys, kbd->key_count);
memcpy(&info[0], &kbd->handle, sizeof(u32));
return 0;
}

View File

@ -9,7 +9,7 @@ typedef struct screen_device_data_s {
u32 handle;
u32 width;
u32 height;
u32 size;
u32 buffer_size;
u8 *screen_buffer;
u32 update;
SDL_Window *window;

View File

@ -395,10 +395,10 @@ i32 main(i32 argc, char *argv[]) {
screen_data.width = 640;
screen_data.height = 480;
screen_data.size = screen_data.width * screen_data.height;
screen_data.buffer_size = screen_data.width * screen_data.height;
vm_register_device(&vm, "/dev/screen/0", "screen", &screen_data,
&screen_ops, 16 + screen_data.size);
&screen_ops, 16 + screen_data.buffer_size);
mouse_data.x = 0;
mouse_data.y = 0;

View File

@ -5,24 +5,29 @@
(load-immediate $0 &screen-namespace)
(load-immediate $11 0)
(syscall OPEN $18 $0 $11) ; open(out Plex screen, in namespace, in flags)
(get $0 $18) ; load handle (offset 0)
; open mouse
(load-immediate $16 &mouse-namespace)
(syscall OPEN $15 $16 0)
(get $16 $15) ; load handle (offset 0)
(load-immediate $1 4) ; offset for handle
(add-nat $19 $18 $1)
(get $0 $19) ; load handle
(load-immediate $1 4) ; offset for width
(load-immediate $1 8) ; offset for width
(add-nat $19 $18 $1)
(get $20 $19) ; load width
(load-immediate $1 8) ; offset for size
(load-immediate $1 12) ; offset for size
(add-nat $19 $18 $1)
(get $22 $19) ; load size
(load-immediate $1 12) ; offset for screen buffer
(add-nat $19 $18 $1)
(get $21 $19)
(load-immediate $1 16) ; offset for screen buffer
(add-nat $21 $18 $1)
; open mouse
(load-immediate $16 &mouse-namespace)
(syscall OPEN $15 $16 $11) ; open(out Plex mouse, in namespace, in flags)
(load-immediate $1 4) ; offset for handle
(add-nat $19 $15 $1)
(get $16 $19) ; load handle
; outline_swatch(screen, BLACK, 1, 1);
(push $21)
@ -46,21 +51,23 @@
(push $13)
(call &draw-outlined-swatch)
; screen.draw();
(syscall WRITE $0 $21 $22)
(load-immediate $3 16)
(label draw-loop
; load mouse click data
(syscall READ $16 $2 $3 $4)
(load-immediate $5 12) ; offset for btn1
(add-nat $6 $5 $2)
(syscall READ $16 $2 $3 $15)
(load-immediate $5 16) ; offset for btn1
(add-nat $6 $15 $5)
(get-8 $9 $6) ; load btn1 pressed
(jump-eq-nat &draw-loop $9 $11)
(load-immediate $5 4) ; offset for x
(load-immediate $5 8) ; offset for x
(add-nat $6 $5 $2)
(get $7 $6) ; load x
(load-immediate $5 8) ; offset for y
(load-immediate $5 12) ; offset for y
(add-nat $6 $5 $2)
(get $8 $6) ; load y
@ -83,7 +90,6 @@
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
(push $21)
@ -102,7 +108,6 @@
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
(syscall WRITE $0 $21 $22)
@ -126,7 +131,6 @@
(label set-color-if-clicked
; Pop inputs from stack (in reverse order of pushing)
(pop $12) ; $12 = btn1 down?
(pop $11) ; $11 = color
(pop $0) ; $0 = click_x
(pop $1) ; $1 = click_y
@ -145,9 +149,7 @@
(jump-gt-int &fail $0 $6)
(jump-lt-int &fail $1 $3)
(jump-gt-int &fail $1 $7)
; If btn1 is pressed (==1), set color
(load-immediate $8 1)
(jump-eq-int &fail $12 $8)
(load-immediate $10 &SELECTED-COLOR)
(store-8 $10 $11)

View File

@ -4,38 +4,72 @@
; use load immediate because it is a pointer to a string, not a value
(load-immediate $0 &screen-namespace)
(load-immediate $11 0)
(syscall OPEN $0 $0 $11)
(syscall OPEN $18 $0 $11) ; open(out Plex screen, in namespace, in flags)
(load-immediate $16 1) ; device info call
(load-immediate $17 16) ; sizeof screen device info
(malloc $18 $17)
(syscall IOCTL $0 $16 $18)
(load-immediate $1 12) ; offset for width
(load-immediate $1 4) ; offset for handle
(add-nat $19 $18 $1)
(get $0 $19) ; load handle
(load-immediate $1 8) ; offset for width
(add-nat $19 $18 $1)
(get $20 $19) ; load width
(load-immediate $1 8) ; offset for size
(load-immediate $1 12) ; offset for size
(add-nat $19 $18 $1)
(get $22 $19) ; load size
(malloc $21 $22) ; malloc frame buffer
(load-immediate $1 16) ; offset for screen buffer
(add-nat $21 $18 $1)
; open mouse
(load-immediate $16 &mouse-namespace)
(syscall OPEN $15 $16 $11) ; open(out Plex mouse, in namespace, in flags)
(load-immediate $1 4) ; offset for handle
(add-nat $19 $15 $1)
(get $16 $19) ; load handle
; outline_swatch(screen, BLACK, 1, 1);
(push $21)
(push $20)
(load $1 &BLACK)
(push $1)
(load-immediate $12 1)
(push $12)
(load-immediate $13 1)
(push $13)
(call &draw-outlined-swatch)
; outline_swatch(screen, WHITE, 1, 1);
(push $21)
(push $20)
(load $1 &WHITE)
(push $1)
(load-immediate $12 21)
(push $12)
(load-immediate $13 1)
(push $13)
(call &draw-outlined-swatch)
; screen.draw();
(syscall WRITE $0 $21 $22)
(load-immediate $16 &mouse-namespace)
(load-immediate $3 12) ; malloc sizeof mouse data
(malloc $4 $3)
(syscall OPEN $16 $16 $4)
(load-immediate $3 16)
(label draw-loop
; load mouse click data
(syscall READ $16 $2 $3 $4)
(load-immediate $5 4) ; offset for x
(syscall READ $16 $2 $3 $15)
(load-immediate $5 16) ; offset for btn1
(add-nat $6 $15 $5)
(get-8 $9 $6) ; load btn1 pressed
(jump-eq-nat &draw-loop $9 $11)
(load-immediate $5 8) ; offset for x
(add-nat $6 $5 $2)
(get $7 $6) ; load x
(load-immediate $5 8) ; offset for y
(load-immediate $5 12) ; offset for y
(add-nat $6 $5 $2)
(get $8 $6) ; load y
(load-immediate $5 12) ; offset for btn1
(add-nat $6 $5 $2)
(get-8 $9 $6) ; load btn1 pressed
(load-immediate $14 20) ; box size
@ -49,14 +83,13 @@
(load-immediate $13 1)
(push $13)
(call &draw-outlined-swatch)
(syscall WRITE $0 $21 $22)
(push $14) ; box_size (20)
(push $13) ; box_y
(push $12) ; box_x
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
(push $21)
@ -75,7 +108,6 @@
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
; row 2
@ -95,7 +127,6 @@
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
(push $21)
@ -114,7 +145,6 @@
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
; row 3
@ -134,7 +164,6 @@
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
(push $21)
@ -153,7 +182,6 @@
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
; row 3
@ -173,7 +201,6 @@
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
(push $21)
@ -192,7 +219,6 @@
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
; row 4
@ -212,7 +238,6 @@
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
(push $21)
@ -231,15 +256,12 @@
(push $8) ; click_y
(push $7) ; click_x
(push $1) ; color
(push $9) ; is btn1 clicked?
(call &set-color-if-clicked)
(syscall WRITE $0 $21 $22)
(jump-eq-nat &draw-loop $9 $11)
(load $22 &SELECTED-COLOR) ; color
(load-immediate $1 3) ; size of brush
(load-immediate $1 5) ; size of brush
(push $21) ;base
(push $20) ;width
@ -250,14 +272,13 @@
(push $1)
(call &draw-box)
(jump-eq-nat &draw-loop $11 $11))
(jump &draw-loop))
; Flush and halt
(halt))
(label set-color-if-clicked
; Pop inputs from stack (in reverse order of pushing)
(pop $12) ; $12 = btn1 down?
(pop $11) ; $11 = color
(pop $0) ; $0 = click_x
(pop $1) ; $1 = click_y
@ -271,33 +292,16 @@
; Compute bottom = box_y + box_size
(add-int $7 $3 $5) ; $7 = bottom edge
; Check 1: click_x >= box_x ?
(jump-ge-int &check2 $0 $2)
(return)
; Bounds check: x in [box_x, right] and y in [box_y, bottom]
(jump-lt-int &fail $0 $2)
(jump-gt-int &fail $0 $6)
(jump-lt-int &fail $1 $3)
(jump-gt-int &fail $1 $7)
(label check2)
; Check 2: click_x <= right ?
(jump-le-int &check3 $0 $6)
(return)
(label check3)
; Check 3: click_y >= box_y ?
(jump-ge-int &check4 $1 $3)
(return)
(label check4)
; Check 4: click_y <= bottom ?
(jump-le-int &check5 $1 $7)
(return)
(label check5) ; if it was selected then set the color
(load-immediate $13 1)
(jump-eq-int &set-color $12 $13)
(return)
(label set-color)
(load-immediate $10 &SELECTED-COLOR)
(store-8 $10 $11)
(label fail)
(return))
(label draw-outlined-swatch

Binary file not shown.

View File

@ -1,75 +1,108 @@
((code
(label main
(load-immediate $0 &screen-namespace)
(load-immediate $11 0)
(syscall OPEN $0 $0 $11)
; open terminal for debug
(load-immediate $32 &terminal-namespace)
(load-immediate $11 0)
(syscall OPEN $32 $32 $11)
(load-immediate $16 1) ; device info call
(load-immediate $17 16) ; sizeof screen device info
(malloc $18 $17)
(syscall IOCTL $0 $16 $18)
(load-immediate $1 12) ; offset for width
(add-nat $19 $18 $1)
(get $20 $19) ; load width
(load-immediate $1 8) ; offset for size
(add-nat $19 $18 $1)
(get $22 $19) ; load size
(malloc $21 $22) ; malloc frame buffer
(syscall WRITE $0 $21 $22)
; 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-immediate $16 &mouse-namespace)
(load-immediate $3 12) ; malloc sizeof mouse data
(malloc $4 $3)
(syscall OPEN $16 $16 $4)
(load-immediate $1 4) ; offset for handle
(add-nat $19 $18 $1)
(get $0 $19) ; load handle
(nat-to-string $5 $4)
(nat-to-string $5 $0)
(push $32)
(push $5)
(call &pln)
(load-immediate $1 8) ; offset for width
(add-nat $19 $18 $1)
(get $20 $19) ; load width
(nat-to-string $5 $20)
(push $32)
(push $5)
(call &pln)
(load-immediate $1 12) ; offset for size
(add-nat $19 $18 $1)
(get $22 $19) ; load size
(nat-to-string $5 $22)
(push $32)
(push $5)
(call &pln)
(load-immediate $1 16) ; offset for screen buffer
(add-nat $21 $18 $1)
(nat-to-string $5 $21)
(push $32)
(push $5)
(call &pln)
; open mouse
(load-immediate $16 &mouse-namespace)
(syscall OPEN $15 $16 $11) ; open(out Plex mouse, in namespace, in flags)
(load-immediate $1 4) ; offset for handle
(add-nat $19 $15 $1)
(nat-to-string $5 $19)
(push $32)
(push $5)
(call &pln)
(get $16 $19) ; load handle
(syscall WRITE $0 $21 $22) ; redraw
(load-immediate $3 16)
(label draw-loop
; load mouse click data
(syscall READ $16 $2 $3 $4)
(load-immediate $5 12) ; offset for btn1
(add-nat $6 $5 $2)
(syscall READ $16 $2 $3 $15)
(load-immediate $5 16) ; offset for btn1
(add-nat $6 $15 $5)
(get-8 $9 $6) ; load btn1 pressed
(jump-eq-nat &draw-loop $9 $11)
(load-immediate $5 4) ; offset for x
(load-immediate $5 8) ; offset for x
(add-nat $6 $5 $2)
(get $7 $6) ; load x
(load-immediate $5 8) ; offset for y
(load-immediate $5 12) ; offset for y
(add-nat $6 $5 $2)
(get $8 $6) ; load y
; Compute start address: y*width + x
(mul-nat $15 $8 $20) ; $15 = y * width
(add-nat $15 $15 $7) ; $15 += x
(add-nat $15 $21 $15) ; $15 = base + pixel_offset
(mul-nat $30 $8 $20) ; $15 = y * width
(add-nat $30 $30 $7) ; $15 += x
(add-nat $30 $30 $21) ; $15 += pixel_offset
(load-immediate $1 4) ; need to add offset for fat pointer size
(add-nat $15 $15 $1)
(add-nat $30 $30 $1)
(load $3 &WHITE) ; color
(store-8 $15 $3) ; draw color at screen [x,y]
(store-8 $30 $3) ; draw color at screen [x,y]
(syscall WRITE $0 $21 $22) ; redraw
(load-immediate $5 13) ; offset for btn2
(add-nat $6 $5 $2)
(get-8 $10 $6) ; load btn2 pressed
(jump-eq-nat &draw-loop $10 $11))
(jump &draw-loop))
(halt))
(label pln
(load-immediate $3 &new-line)
(pop $1)
(pop $0)
(load-immediate $5 4) ; offset for handle
(add-nat $6 $0 $5)
(get $7 $6) ; load handle
(string-length $2 $1)
(syscall WRITE $0 $1 $2)
(syscall WRITE $7 $1 $2)
(string-length $4 $3)
(syscall WRITE $0 $3 $4)
(syscall WRITE $7 $3 $4)
(return)))
(data
(label screen-namespace "/dev/screen/0")