[wip] rewrite device open to use plex
This commit is contained in:
parent
9d30ffb69b
commit
3f3c6e1b80
92
docs/draw.ul
92
docs/draw.ul
|
|
@ -1,46 +1,78 @@
|
|||
Device screen("/dev/screen/0");
|
||||
u8[] colors = [0,255,36,73,146,182,128,224,144,
|
||||
252,9,18,12,16,28,159,2,3,10,19,131,147,130,227,129,226,
|
||||
72,141,136,241,208,244];
|
||||
str screen_namespace = "/dev/screen/0";
|
||||
str mouse_namespace = "/dev/mouse/0";
|
||||
byte selected_color = 255;
|
||||
|
||||
fn main() {
|
||||
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();
|
||||
|
||||
int x = 10;
|
||||
int y = 20;
|
||||
for (int i = 0; i < colors.length; i+=2) {
|
||||
draw_outline_swatch(colors[i], x, y);
|
||||
draw_outline_swatch(colors[i + 1], x + 20, y);
|
||||
x += 20;
|
||||
y += 20;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
fn draw_outline_swatch(u8 color, int x, int y) {
|
||||
u8 gray = colors[5];
|
||||
int outline_size = 20;
|
||||
int fill_size = 17;
|
||||
int offset = 2;
|
||||
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;
|
||||
|
||||
draw_box(gray, x, y, outline_size, outline_size);
|
||||
int swatch_pos = x + 2;
|
||||
int offset_pos = y + 2;
|
||||
draw_box(color, swatch_pos, offset_pos, fill_size, fill_size);
|
||||
return;
|
||||
}
|
||||
|
||||
fn draw_box(u8 color, int x, int y, int width, int height) {
|
||||
int screen_width = screen.width;
|
||||
int pos = y * 640 + x;
|
||||
function outline_swatch(ref Device screen, byte color, int x, int y) {
|
||||
byte bg_color = GRAY;
|
||||
if (selected_color == color) {
|
||||
bg_color = DARK_GRAY;
|
||||
}
|
||||
|
||||
do (int i = height; i > 0; i--) {
|
||||
int row = pos + width;
|
||||
int pixel = offset;
|
||||
do (int j = ; pos;j++) {
|
||||
screen.buffer[j] = color;
|
||||
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;
|
||||
}
|
||||
|
|
@ -5,9 +5,11 @@
|
|||
#include <emscripten/html5.h>
|
||||
|
||||
|
||||
i32 console_open(void *data, u32 mode) {
|
||||
i32 console_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
|
||||
USED(mode);
|
||||
USED(data);
|
||||
USED(buffer);
|
||||
USED(size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -41,18 +43,23 @@ i32 console_ioctl(void *data, u32 cmd, const u8 *buffer) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
i32 screen_open(void *data, u32 mode) {
|
||||
i32 screen_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
|
||||
USED(mode);
|
||||
ScreenDeviceData *screen = (ScreenDeviceData *)data;
|
||||
|
||||
// Initialize with proper values
|
||||
screen->width = 640;
|
||||
screen->height = 480;
|
||||
screen->size = 640 * 480;
|
||||
screen->size = 640 * 480 + 12;
|
||||
screen->window = NULL;
|
||||
screen->renderer = NULL;
|
||||
screen->texture = NULL;
|
||||
|
||||
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));
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_set_canvas_element_size("#canvas", screen->width, screen->height);
|
||||
#endif
|
||||
|
|
@ -161,30 +168,13 @@ i32 screen_read(void *data, u8 *buffer, u32 size) {
|
|||
}
|
||||
|
||||
i32 screen_ioctl(void *data, u32 cmd, const u8 *buffer) {
|
||||
ScreenDeviceData *screen = (ScreenDeviceData *)data;
|
||||
|
||||
switch (cmd) {
|
||||
case IOCTL_GET_INFO: {
|
||||
u8 *info = (u8 *)buffer;
|
||||
u32 size;
|
||||
memcpy(&size, &info[0], sizeof(u32));
|
||||
|
||||
if (size < 16) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(&info[4], &screen->pos, sizeof(u32));
|
||||
memcpy(&info[8], &screen->size, sizeof(u32));
|
||||
memcpy(&info[12], &screen->width, sizeof(u32));
|
||||
memcpy(&info[16], &screen->height, sizeof(u32));
|
||||
USED(data);
|
||||
USED(cmd);
|
||||
USED(buffer);
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
i32 mouse_open(void *data, u32 mode) {
|
||||
i32 mouse_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
|
||||
USED(mode);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -216,9 +206,10 @@ i32 mouse_close(void *data) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
i32 keyboard_open(void *data, u32 mode) {
|
||||
i32 keyboard_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
|
||||
USED(data);
|
||||
USED(mode);
|
||||
USED(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
#include "../../vm/vm.h"
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#define IOCTL_GET_INFO 0x01
|
||||
|
||||
typedef struct screen_device_data_s {
|
||||
u32 handle;
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 pos;
|
||||
u32 size;
|
||||
u8 *screen_buffer;
|
||||
u32 pos;
|
||||
bool update;
|
||||
SDL_Window *window;
|
||||
SDL_Renderer *renderer;
|
||||
|
|
@ -17,6 +16,7 @@ typedef struct screen_device_data_s {
|
|||
|
||||
/* Mouse device data */
|
||||
typedef struct mouse_device_data_s {
|
||||
u32 handle;
|
||||
u32 x;
|
||||
u32 y;
|
||||
u8 btn1;
|
||||
|
|
@ -29,29 +29,36 @@ typedef struct mouse_device_data_s {
|
|||
|
||||
/* Keyboard device data */
|
||||
typedef struct keyboard_device_data_s {
|
||||
const u8 *keys;
|
||||
u32 handle;
|
||||
i32 key_count;
|
||||
const u8 *keys;
|
||||
u32 pos;
|
||||
u32 size;
|
||||
} KeyboardDeviceData;
|
||||
|
||||
i32 screen_open(void *data, u32 mode);
|
||||
/* Console device data */
|
||||
typedef struct console_device_data_s {
|
||||
u32 handle;
|
||||
u32 size;
|
||||
} ConsoleDeviceData;
|
||||
|
||||
i32 screen_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size);
|
||||
i32 screen_read(void *data, u8 *buffer, u32 size);
|
||||
i32 screen_write(void *data, const u8 *buffer, u32 size);
|
||||
i32 screen_close(void *data);
|
||||
i32 screen_ioctl(void *data, u32 cmd, const u8 *buffer);
|
||||
|
||||
i32 mouse_open(void *data, u32 mode);
|
||||
i32 mouse_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size);
|
||||
i32 mouse_read(void *data, u8 *buffer, u32 size);
|
||||
i32 mouse_write(void *data, const u8 *buffer, u32 size);
|
||||
i32 mouse_close(void *data);
|
||||
|
||||
i32 keyboard_open(void *data, u32 mode);
|
||||
i32 keyboard_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size);
|
||||
i32 keyboard_read(void *data, u8 *buffer, u32 size);
|
||||
i32 keyboard_write(void *data, const u8 *buffer, u32 size);
|
||||
i32 keyboard_close(void *data);
|
||||
|
||||
i32 console_open(void *data, u32 mode);
|
||||
i32 console_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size);
|
||||
i32 console_read(void *data, u8 *buffer, u32 size);
|
||||
i32 console_write(void *data, const u8 *buffer, u32 size);
|
||||
i32 console_close(void *data);
|
||||
|
|
|
|||
|
|
@ -3,10 +3,14 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
i32 console_open(void *data, u32 mode) {
|
||||
i32 console_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
|
||||
USED(mode);
|
||||
USED(data);
|
||||
/* Nothing to open — stdin/stdout are always available */
|
||||
USED(size);
|
||||
ConsoleDeviceData *console = (ConsoleDeviceData *)data;
|
||||
console->handle = handle;
|
||||
|
||||
u8 *info = (u8 *)buffer;
|
||||
memcpy(&info[0], &console->handle, sizeof(u32));
|
||||
return 0; /* Success */
|
||||
}
|
||||
|
||||
|
|
@ -44,9 +48,17 @@ i32 console_ioctl(void *data, u32 cmd, const u8 *buffer) {
|
|||
return -1; /* Unsupported */
|
||||
}
|
||||
|
||||
i32 screen_open(void *data, u32 mode) {
|
||||
i32 screen_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
|
||||
USED(mode);
|
||||
USED(size);
|
||||
ScreenDeviceData *screen = (ScreenDeviceData *)data;
|
||||
screen->handle = handle;
|
||||
|
||||
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));
|
||||
|
||||
screen->window =
|
||||
SDL_CreateWindow("Reality Engine VM", SDL_WINDOWPOS_CENTERED,
|
||||
|
|
@ -111,34 +123,21 @@ i32 screen_close(void *data) {
|
|||
}
|
||||
|
||||
i32 screen_ioctl(void *data, u32 cmd, const u8 *buffer) {
|
||||
ScreenDeviceData *screen = (ScreenDeviceData *)data;
|
||||
|
||||
switch (cmd) {
|
||||
case IOCTL_GET_INFO: {
|
||||
u8 *info = (u8 *)buffer;
|
||||
u32 size;
|
||||
memcpy(&size, &info[0], sizeof(u32));
|
||||
|
||||
if (size < 16) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(&info[4], &screen->pos, sizeof(u32));
|
||||
memcpy(&info[8], &screen->size, sizeof(u32));
|
||||
memcpy(&info[12], &screen->width, sizeof(u32));
|
||||
memcpy(&info[16], &screen->height, sizeof(u32));
|
||||
USED(data);
|
||||
USED(cmd);
|
||||
USED(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
return -1; // Error
|
||||
}
|
||||
}
|
||||
|
||||
/* MOUSE */
|
||||
i32 mouse_open(void *data, u32 mode) {
|
||||
USED(data);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -160,12 +159,12 @@ i32 mouse_read(void *data, u8 *buffer, u32 size) {
|
|||
mouse_data->btn4 = (state & SDL_BUTTON(SDL_BUTTON_X1)) ? 1 : 0;
|
||||
|
||||
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[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));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -181,9 +180,15 @@ i32 mouse_close(void *data) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
i32 keyboard_open(void *data, u32 mode) {
|
||||
USED(data);
|
||||
i32 keyboard_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size) {
|
||||
USED(mode);
|
||||
USED(size);
|
||||
KeyboardDeviceData *kbd = (KeyboardDeviceData *)data;
|
||||
kbd->handle = handle;
|
||||
|
||||
u8 *info = (u8 *)buffer;
|
||||
memcpy(&info[0], &kbd->handle, sizeof(u32));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -193,7 +198,8 @@ i32 keyboard_read(void *data, u8 *buffer, u32 size) {
|
|||
if (size < (u32)kbd->key_count)
|
||||
return -1;
|
||||
|
||||
memcpy(buffer, kbd->keys, kbd->key_count);
|
||||
u8 *info = (u8 *)buffer;
|
||||
memcpy(&info[4], kbd->keys, kbd->key_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@
|
|||
|
||||
/* Screen device data */
|
||||
typedef struct screen_device_data_s {
|
||||
u32 handle;
|
||||
u32 width;
|
||||
u32 height;
|
||||
u32 pos;
|
||||
u32 size;
|
||||
u8 *screen_buffer;
|
||||
u32 update;
|
||||
|
|
@ -19,41 +19,48 @@ typedef struct screen_device_data_s {
|
|||
|
||||
/* Mouse device data */
|
||||
typedef struct mouse_device_data_s {
|
||||
u32 handle;
|
||||
u32 x;
|
||||
u32 y;
|
||||
u8 btn1;
|
||||
u8 btn2;
|
||||
u8 btn3;
|
||||
u8 btn4;
|
||||
u32 pos;
|
||||
u32 size;
|
||||
} MouseDeviceData;
|
||||
|
||||
/* Keyboard device data */
|
||||
typedef struct keyboard_device_data_s {
|
||||
u32 handle;
|
||||
const u8 *keys;
|
||||
i32 key_count;
|
||||
u32 pos;
|
||||
u32 size;
|
||||
} KeyboardDeviceData;
|
||||
|
||||
i32 screen_open(void *data, u32 mode);
|
||||
/* Console device data */
|
||||
typedef struct console_device_data_s {
|
||||
u32 handle;
|
||||
u32 size;
|
||||
} ConsoleDeviceData;
|
||||
|
||||
i32 screen_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size);
|
||||
i32 screen_read(void *data, u8 *buffer, u32 size);
|
||||
i32 screen_write(void *data, const u8 *buffer, u32 size);
|
||||
i32 screen_close(void *data);
|
||||
i32 screen_ioctl(void *data, u32 cmd, const u8 *buffer);
|
||||
|
||||
i32 mouse_open(void *data, u32 mode);
|
||||
i32 mouse_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size);
|
||||
i32 mouse_read(void *data, u8 *buffer, u32 size);
|
||||
i32 mouse_write(void *data, const u8 *buffer, u32 size);
|
||||
i32 mouse_close(void *data);
|
||||
|
||||
i32 keyboard_open(void *data, u32 mode);
|
||||
i32 keyboard_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size);
|
||||
i32 keyboard_read(void *data, u8 *buffer, u32 size);
|
||||
i32 keyboard_write(void *data, const u8 *buffer, u32 size);
|
||||
i32 keyboard_close(void *data);
|
||||
|
||||
i32 console_open(void *data, u32 mode);
|
||||
i32 console_open(void *data, u32 mode, u32 handle, u8 *buffer, u32 size);
|
||||
i32 console_read(void *data, u8 *buffer, u32 size);
|
||||
i32 console_write(void *data, const u8 *buffer, u32 size);
|
||||
i32 console_close(void *data);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ static DeviceOps console_device_ops = {
|
|||
static ScreenDeviceData screen_data = {0};
|
||||
static MouseDeviceData mouse_data = {0};
|
||||
static KeyboardDeviceData keyboard_data = {0};
|
||||
static ConsoleDeviceData console_data = {0};
|
||||
|
||||
// Function to save VM state to ROM file
|
||||
bool saveVM(const char *filename, VM *vm) {
|
||||
|
|
@ -382,7 +383,9 @@ i32 main(i32 argc, char *argv[]) {
|
|||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
vm_register_device(&vm, "/dev/term/0", "terminal", nil, &console_device_ops);
|
||||
vm_register_device(&vm, "/dev/term/0", "terminal", &console_data,
|
||||
&console_device_ops, 4);
|
||||
|
||||
if (gui_mode) {
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
printf("SDL initialization failed: %s\n", SDL_GetError());
|
||||
|
|
@ -395,7 +398,7 @@ i32 main(i32 argc, char *argv[]) {
|
|||
screen_data.size = screen_data.width * screen_data.height;
|
||||
|
||||
vm_register_device(&vm, "/dev/screen/0", "screen", &screen_data,
|
||||
&screen_ops);
|
||||
&screen_ops, 16 + screen_data.size);
|
||||
|
||||
mouse_data.x = 0;
|
||||
mouse_data.y = 0;
|
||||
|
|
@ -403,13 +406,14 @@ i32 main(i32 argc, char *argv[]) {
|
|||
mouse_data.btn2 = 0;
|
||||
mouse_data.btn3 = 0;
|
||||
mouse_data.btn4 = 0;
|
||||
mouse_data.size = 12;
|
||||
mouse_data.size = 16;
|
||||
|
||||
vm_register_device(&vm, "/dev/mouse/0", "mouse", &mouse_data, &mouse_ops);
|
||||
vm_register_device(&vm, "/dev/mouse/0", "mouse", &mouse_data, &mouse_ops,
|
||||
mouse_data.size);
|
||||
|
||||
keyboard_data.keys = SDL_GetKeyboardState(&keyboard_data.key_count);
|
||||
vm_register_device(&vm, "/dev/keyboard/0", "keyboard", &keyboard_data,
|
||||
&keyboard_ops);
|
||||
&keyboard_ops, keyboard_data.key_count + 4);
|
||||
|
||||
SDL_Event event;
|
||||
bool running = true;
|
||||
|
|
|
|||
|
|
@ -75,8 +75,7 @@ int get_instruction_byte_size(ExprNode *node) {
|
|||
}
|
||||
|
||||
// Register-based opcodes (2 bytes: opcode + register)
|
||||
if (strcmp(opname, "pop") == 0 || strcmp(opname, "jump-if-flag") == 0 ||
|
||||
strcmp(opname, "jump") == 0 || strcmp(opname, "push") == 0) {
|
||||
if (strcmp(opname, "pop") == 0 || strcmp(opname, "push") == 0) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +110,8 @@ int get_instruction_byte_size(ExprNode *node) {
|
|||
}
|
||||
|
||||
// (5 bytes: 1 + 4)
|
||||
if (strcmp(opname, "call") == 0) {
|
||||
if (strcmp(opname, "call") == 0 || strcmp(opname, "jump-if-flag") == 0 ||
|
||||
strcmp(opname, "jump") == 0) {
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include "str.h"
|
||||
|
||||
i32 vm_register_device(VM *vm, const char *path, const char *type, void *data,
|
||||
DeviceOps *ops) {
|
||||
DeviceOps *ops, u32 size) {
|
||||
Device *dev;
|
||||
|
||||
if (vm->dc >= DEVICES_SIZE)
|
||||
|
|
@ -18,6 +18,7 @@ i32 vm_register_device(VM *vm, const char *path, const char *type, void *data,
|
|||
|
||||
dev->data = data;
|
||||
dev->ops = ops;
|
||||
dev->size = size;
|
||||
dev->flags = 0;
|
||||
return dev->handle;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "opcodes.h"
|
||||
|
||||
i32 vm_register_device(VM *vm, const char *path, const char *type, void *data, DeviceOps *ops);
|
||||
i32 vm_register_device(VM *vm, const char *path, const char *type, void *data, DeviceOps *ops, u32 size);
|
||||
Device* find_device_by_path(VM *vm, const char *path);
|
||||
Device* find_device_by_type(VM *vm, const char *type);
|
||||
i32 find_devices_by_type(VM *vm, const char *type, Device **results, uint32_t max_results);
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ typedef enum {
|
|||
} SyscallID;
|
||||
|
||||
typedef struct device_ops_s {
|
||||
i32 (*open)(void *device_data, u32 mode);
|
||||
i32 (*open)(void *device_data, u32 mode, u32 handle, u8 *buffer, u32 size);
|
||||
i32 (*read)(void *device_data, u8 *buffer, u32 size);
|
||||
i32 (*write)(void *device_data, const u8 *buffer, u32 size);
|
||||
i32 (*close)(void *device_data);
|
||||
|
|
@ -121,6 +121,7 @@ typedef struct device_s {
|
|||
DeviceOps *ops; /* operations vtable */
|
||||
u32 flags; /* permissions, status, etc. */
|
||||
u32 handle; /* id for fast access in VM */
|
||||
u32 size; /* id for fast access in VM */
|
||||
} Device;
|
||||
|
||||
#define MEMORY_SIZE (640 * 480 + 65536)
|
||||
|
|
|
|||
22
src/vm/vm.c
22
src/vm/vm.c
|
|
@ -355,17 +355,15 @@ bool step_vm(VM *vm) {
|
|||
return true;
|
||||
}
|
||||
case OP_JMP: {
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
vm->pc = frame->registers[dest]; /* Jump to address */
|
||||
u32 jmp = read_u32(vm, code, vm->pc);
|
||||
vm->pc = jmp; /* Jump to address */
|
||||
return true;
|
||||
}
|
||||
case OP_JMPF: { /* error handling for syscall, jump if flag == 0 */
|
||||
u32 mask;
|
||||
dest = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
u32 jmp = read_u32(vm, code, vm->pc);
|
||||
mask = -(u32)(vm->flag == 0);
|
||||
vm->pc = (dest & mask) | (vm->pc & ~mask);
|
||||
vm->pc = (jmp & mask) | (vm->pc & ~mask);
|
||||
return true;
|
||||
}
|
||||
case OP_SYSCALL: {
|
||||
|
|
@ -377,7 +375,7 @@ bool step_vm(VM *vm) {
|
|||
switch (syscall_id) {
|
||||
case SYSCALL_DEVICE_OPEN: {
|
||||
Device *dev;
|
||||
u32 path_ptr, mode;
|
||||
u32 path_ptr, mode, buffer_ptr;
|
||||
u8 path_reg, mode_reg, dest_reg;
|
||||
dest_reg = read_u8(vm, code, vm->pc);
|
||||
vm->pc++;
|
||||
|
|
@ -391,8 +389,14 @@ bool step_vm(VM *vm) {
|
|||
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
|
||||
if (dev) {
|
||||
if (dev->ops->open) {
|
||||
vm->flag = dev->ops->open(dev->data, mode);
|
||||
frame->registers[dest_reg] = dev->handle;
|
||||
/* return device plex to user */
|
||||
buffer_ptr = vm->mp;
|
||||
frame->registers[dest_reg] = buffer_ptr;
|
||||
/* malloc size for device */
|
||||
write_u32(vm, memory, buffer_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);
|
||||
} else {
|
||||
vm->flag = 1; /* success, no open needed */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,25 +4,27 @@
|
|||
; 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)
|
||||
(get $0 $18) ; load handle (offset 0)
|
||||
|
||||
(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
|
||||
; 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 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
|
||||
|
||||
(load-immediate $16 &mouse-namespace)
|
||||
(load-immediate $3 12) ; malloc sizeof mouse data
|
||||
(malloc $4 $3)
|
||||
(syscall OPEN $16 $16 $4)
|
||||
(load-immediate $1 12) ; offset for screen buffer
|
||||
(add-nat $19 $18 $1)
|
||||
(get $21 $19)
|
||||
|
||||
; outline_swatch(screen, BLACK, 1, 1);
|
||||
(push $21)
|
||||
(push $20)
|
||||
(load $1 &BLACK)
|
||||
|
|
@ -33,6 +35,7 @@
|
|||
(push $13)
|
||||
(call &draw-outlined-swatch)
|
||||
|
||||
; outline_swatch(screen, WHITE, 1, 1);
|
||||
(push $21)
|
||||
(push $20)
|
||||
(load $1 &WHITE)
|
||||
|
|
@ -45,7 +48,6 @@
|
|||
|
||||
(syscall WRITE $0 $21 $22)
|
||||
|
||||
|
||||
(label draw-loop
|
||||
; load mouse click data
|
||||
(syscall READ $16 $2 $3 $4)
|
||||
|
|
@ -53,8 +55,6 @@
|
|||
(add-nat $6 $5 $2)
|
||||
(get-8 $9 $6) ; load btn1 pressed
|
||||
|
||||
(load-immediate $14 20) ; box size
|
||||
|
||||
(jump-eq-nat &draw-loop $9 $11)
|
||||
|
||||
(load-immediate $5 4) ; offset for x
|
||||
|
|
@ -63,9 +63,8 @@
|
|||
(load-immediate $5 8) ; offset for y
|
||||
(add-nat $6 $5 $2)
|
||||
(get $8 $6) ; load y
|
||||
(load-immediate $5 13) ; offset for btn2
|
||||
(add-nat $6 $5 $2)
|
||||
(get-8 $10 $6) ; load btn2 pressed
|
||||
|
||||
(load-immediate $14 20) ; box size
|
||||
|
||||
; first row
|
||||
(push $21)
|
||||
|
|
@ -120,7 +119,7 @@
|
|||
(push $1)
|
||||
(call &draw-box)
|
||||
|
||||
(jump-eq-nat &draw-loop $10 $11))
|
||||
(jump &draw-loop))
|
||||
|
||||
; Flush and halt
|
||||
(halt))
|
||||
|
|
@ -147,7 +146,8 @@
|
|||
(jump-lt-int &fail $1 $3)
|
||||
(jump-gt-int &fail $1 $7)
|
||||
; If btn1 is pressed (==1), set color
|
||||
(jump-eq-int &fail $12 1)
|
||||
(load-immediate $8 1)
|
||||
(jump-eq-int &fail $12 $8)
|
||||
(load-immediate $10 &SELECTED-COLOR)
|
||||
(store-8 $10 $11)
|
||||
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@
|
|||
(jump-eq-nat &draw-loop $9 $11)
|
||||
|
||||
(load $22 &SELECTED-COLOR) ; color
|
||||
(load-immediate $1 5) ; size of brush
|
||||
(load-immediate $1 3) ; size of brush
|
||||
|
||||
(push $21) ;base
|
||||
(push $20) ;width
|
||||
|
|
|
|||
Loading…
Reference in New Issue