fix drawing, add ioctl for screen (wip), assembler fixes

This commit is contained in:
zongor 2025-09-28 17:44:10 -07:00
parent 7a42429cf2
commit 807d5b8705
9 changed files with 387 additions and 178 deletions

View File

@ -99,11 +99,11 @@ DEPS := $(VM_OBJS:.o=.d) $(PLATFORM_OBJ:.o=.d)
all: $(TARGET)
# 'debug' target — just set BUILD_MODE and build
debug: BUILD_MODE = debug
debug: BUILD_MODE=debug
debug: $(TARGET)
# 'release' target — just set BUILD_MODE and build
release: BUILD_MODE = release
release: BUILD_MODE=release
release: $(TARGET)
# --- COMPILE VM CORE (freestanding) ---

View File

@ -1,54 +1,52 @@
#include "devices.h"
#include <unistd.h>
#include <string.h>
#include <unistd.h>
i32 console_open(void *data, u32 mode) {
USED(mode);
USED(data);
/* Nothing to open — stdin/stdout are always available */
return 0; /* Success */
USED(mode);
USED(data);
/* Nothing to open — stdin/stdout are always available */
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')
break;
if (ch == '\n')
break;
buffer[i] = ch;
}
return 0;
USED(data);
for (u32 i = 0; i < size; i++) {
u8 ch = getchar();
if (ch == '\0')
break;
if (ch == '\n')
break;
buffer[i] = ch;
}
return 0;
}
i32 console_write(void *data, const u8 *buffer, u32 size) {
USED(data);
for (u32 i = 0; i < size; i++) {
putchar(buffer[i]);
}
return 0;
USED(data);
for (u32 i = 0; i < size; i++) {
putchar(buffer[i]);
}
return 0;
}
i32 console_close(void *data) {
USED(data);
/* Nothing to close — stdin/stdout are process-owned */
return 0;
USED(data);
/* Nothing to close — stdin/stdout are process-owned */
return 0;
}
i32 console_ioctl(void *data, u32 cmd, void *args) {
USED(data);
USED(cmd);
USED(args);
return -1; /* Unsupported */
USED(data);
USED(cmd);
USED(args);
return -1; /* Unsupported */
}
i32 screen_open(void *data, u32 mode) {
USED(mode);
ScreenDeviceData *screen = (ScreenDeviceData *)data;
screen->window =
SDL_CreateWindow("Reality Engine VM", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, screen->width, screen->height,
@ -62,9 +60,9 @@ i32 screen_open(void *data, u32 mode) {
if (!screen->renderer)
return -1;
screen->texture = SDL_CreateTexture(
screen->renderer, SDL_PIXELFORMAT_RGB332, SDL_TEXTUREACCESS_STREAMING,
screen->width, screen->height);
screen->texture = SDL_CreateTexture(screen->renderer, SDL_PIXELFORMAT_RGB332,
SDL_TEXTUREACCESS_STREAMING,
screen->width, screen->height);
if (!screen->texture)
return -1;
@ -81,12 +79,34 @@ i32 screen_read(void *data, u8 *buffer, u32 size) {
i32 screen_write(void *data, const u8 *buffer, u32 size) {
ScreenDeviceData *screen = (ScreenDeviceData *)data;
USED(buffer);
if (size > screen->framebuffer_size * sizeof(u8)) {
return -1;
}
memcpy(&screen->vm->memory[screen->framebuffer_pos], buffer, size);
if (screen->texture && screen->renderer) {
SDL_UpdateTexture(screen->texture, nil,
&screen->vm->memory[screen->framebuffer_pos],
screen->width);
SDL_RenderClear(screen->renderer);
SDL_Rect output_rect;
SDL_RenderGetViewport(screen->renderer, &output_rect);
float scale_x = (float)output_rect.w / screen->width;
float scale_y = (float)output_rect.h / screen->height;
float scale = SDL_min(scale_x, scale_y);
SDL_Rect dstrect = {(i32)((output_rect.w - screen->width * scale) / 2),
(i32)((output_rect.h - screen->height * scale) / 2),
(i32)(screen->width * scale),
(i32)(screen->height * scale)};
SDL_RenderCopy(screen->renderer, screen->texture, nil, &dstrect);
SDL_RenderPresent(screen->renderer);
}
return 0;
}
@ -108,6 +128,24 @@ i32 screen_close(void *data) {
return 0;
}
i32 screen_ioctl(void *data, u32 cmd, void *args) {
ScreenDeviceData *screen = (ScreenDeviceData *)data;
switch (cmd) {
case IOCTL_GET_INFO: {
u32 *info = (u32 *)args;
memcpy(&screen->vm->memory[*info], &screen->framebuffer_pos, sizeof(u32));
memcpy(&screen->vm->memory[*info + 1], &screen->framebuffer_size, sizeof(u32));
memcpy(&screen->vm->memory[*info + 2], &screen->width, sizeof(u32));
memcpy(&screen->vm->memory[*info + 3], &screen->height, sizeof(u32));
return 0;
}
default:
return -1; // Error
}
}
/* MOUSE */
i32 mouse_open(void *data, u32 mode) {
USED(data);

View File

@ -2,6 +2,8 @@
#include "../../vm/vm.h"
#include <SDL2/SDL.h>
#define IOCTL_GET_INFO 0x01
/* Screen device data */
typedef struct screen_device_data_s {
u32 width;
@ -34,6 +36,7 @@ i32 screen_open(void *data, u32 mode);
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, void *args);
i32 mouse_open(void *data, u32 mode);
i32 mouse_read(void *data, u8 *buffer, u32 size);

View File

@ -14,7 +14,7 @@ static DeviceOps screen_ops = {.open = screen_open,
.read = screen_read,
.write = screen_write,
.close = screen_close,
.ioctl = nil};
.ioctl = screen_ioctl};
static DeviceOps mouse_ops = {.open = mouse_open,
.read = mouse_read,
@ -242,7 +242,10 @@ void register_sdl_devices(VM *vm) {
screen_data.height = 480;
screen_data.framebuffer_size = 640 * 480;
screen_data.framebuffer_pos = vm->mp;
vm->mp += screen_data.framebuffer_size / 4; /* advance memory pointer */
vm->mp += screen_data.framebuffer_size; /* advance memory pointer */
vm->frames[vm->fp].end = vm->mp;
printf("%d\n", screen_data.framebuffer_pos );
vm_register_device(vm, "/dev/screen/0", "screen", &screen_data, &screen_ops);
@ -292,9 +295,6 @@ i32 main(i32 argc, char *argv[]) {
VM vm = {0};
// Register terminal device first
vm_register_device(&vm, "/dev/term/0", "terminal", nil, &console_device_ops);
bool compilation_success = true;
if (input_file) {
if (is_rom) {
@ -330,6 +330,8 @@ i32 main(i32 argc, char *argv[]) {
bool running = true;
vm_register_device(&vm, "/dev/term/0", "terminal", nil, &console_device_ops);
if (gui_mode) {
register_sdl_devices(&vm);
@ -375,35 +377,6 @@ i32 main(i32 argc, char *argv[]) {
}
step_vm(&vm);
for (u32 i = 0; i < vm.dc; i++) {
Device *dev = &vm.devices[i];
if (strcmp(dev->type, "screen") == 0) {
ScreenDeviceData *screen = (ScreenDeviceData *)dev->data;
if (screen->texture && screen->renderer) {
SDL_UpdateTexture(screen->texture, nil,
&vm.memory[screen->framebuffer_pos],
screen->width * sizeof(u32));
SDL_RenderClear(screen->renderer);
SDL_Rect output_rect;
SDL_RenderGetViewport(screen->renderer, &output_rect);
float scale_x = (float)output_rect.w / screen->width;
float scale_y = (float)output_rect.h / screen->height;
float scale = SDL_min(scale_x, scale_y);
SDL_Rect dstrect = {
(i32)((output_rect.w - screen->width * scale) / 2),
(i32)((output_rect.h - screen->height * scale) / 2),
(i32)(screen->width * scale), (i32)(screen->height * scale)};
SDL_RenderCopy(screen->renderer, screen->texture, nil, &dstrect);
SDL_RenderPresent(screen->renderer);
}
break;
}
}
}
} else {
while (running) {

View File

@ -76,8 +76,8 @@ int get_instruction_byte_size(ExprNode *node) {
}
// Register-based opcodes (2 bytes: opcode + register)
if (strcmp(opname, "pop") == 0 || strcmp(opname, "push") == 0 ||
strcmp(opname, "jump") == 0 || strcmp(opname, "jump-if-flag") == 0) {
if (strcmp(opname, "pop") == 0 || strcmp(opname, "jump-if-flag") == 0 ||
strcmp(opname, "jump") == 0 || strcmp(opname, "push") == 0) {
return 2;
}
@ -89,19 +89,14 @@ int get_instruction_byte_size(ExprNode *node) {
strcmp(opname, "real-to-int") == 0 ||
strcmp(opname, "real-to-nat") == 0 || strcmp(opname, "int-to-nat") == 0 ||
strcmp(opname, "nat-to-int") == 0 ||
strcmp(opname, "string-length") == 0) {
strcmp(opname, "string-length") == 0 || strcmp(opname, "load") == 0 ||
strcmp(opname, "store") == 0 || strcmp(opname, "load-u8") == 0 ||
strcmp(opname, "load-i8") == 0 || strcmp(opname, "store-8") == 0 ||
strcmp(opname, "load-u16") == 0 || strcmp(opname, "load-i16") == 0 ||
strcmp(opname, "store-16") == 0 || strcmp(opname, "register-move") == 0) {
return 3;
}
// Load/store with register and address (5 bytes: 1 + 1 + 4)
if (strcmp(opname, "load") == 0 || strcmp(opname, "store") == 0 ||
strcmp(opname, "load-u8") == 0 || strcmp(opname, "load-i8") == 0 ||
strcmp(opname, "store-8") == 0 || strcmp(opname, "load-u16") == 0 ||
strcmp(opname, "load-i16") == 0 || strcmp(opname, "store-16") == 0 ||
strcmp(opname, "call") == 0) {
return 5;
}
// Register-register-register opcodes (4 bytes: 1 + 3)
if (strcmp(opname, "add-int") == 0 || strcmp(opname, "sub-int") == 0 ||
strcmp(opname, "mul-int") == 0 || strcmp(opname, "div-int") == 0 ||
@ -116,9 +111,13 @@ int get_instruction_byte_size(ExprNode *node) {
return 4;
}
// Load, Load-immediate (5 bytes: 1 + 1 + 4)
if (strcmp(opname, "load-immediate") == 0 || strcmp(opname, "load") == 0 ||
strcmp(opname, "store") == 0) {
// (5 bytes: 1 + 4)
if (strcmp(opname, "call") == 0) {
return 5;
}
// Load, Load-immediate (6 bytes: 1 + 1 + 4)
if (strcmp(opname, "load-immediate") == 0) {
return 6;
}
@ -163,12 +162,16 @@ void collect_symbols_in_node(SymbolTable *table, ExprNode *node,
for (int i = 0; i < depth; i++)
strcat(indent, " ");
// printf("%s%d %s ", indent, *current_addr, node->token);
#ifdef ASM_DEBUG
printf("%s%d %s ", indent, *current_addr, node->token);
#endif
if (strcmp(node->token, "label") == 0) {
if (node->child_count >= 1) {
const char *name = node->children[0]->token;
// printf(" %s -> %d\n", name, *current_addr);
#ifdef ASM_DEBUG
printf(" %s -> %d\n", name, *current_addr);
#endif
symbol_table_add(table, name, *current_addr, SYMBOL_CODE);
}
@ -179,8 +182,9 @@ void collect_symbols_in_node(SymbolTable *table, ExprNode *node,
} else {
int size = get_instruction_byte_size(node);
*current_addr += size;
// printf(" +%d bytes -> %d\n", size, *current_addr);
// printf("\n");
#ifdef ASM_DEBUG
printf(" +%d bytes -> %d\n", size, *current_addr);
#endif
}
}
@ -242,15 +246,37 @@ int parse_register(const char *reg_str) {
}
u32 resolve_symbol(SymbolTable *table, const char *ref) {
// Handle symbol references (e.g., &label)
if (ref[0] == '&') {
return find_label_in_table(table, ref + 1);
}
// Handle immediate values
// Handle fixed-point numbers (e.g., 0.5)
if (strchr(ref, '.')) {
return TO_FIXED(atof(ref));
}
return (u32)atoi(ref);
// Handle hexadecimal literals (e.g., 0x7)
if (ref[0] == '0' && (ref[1] == 'x' || ref[1] == 'X')) {
char *endptr;
u32 value = (u32)strtoul(ref + 2, &endptr, 16); // Skip "0x"
if (endptr == ref + 2 || *endptr != '\0') {
fprintf(stderr, "Invalid hex literal: %s\n", ref);
exit(1);
}
return value;
}
// Handle decimal literals (e.g., 7)
char *endptr;
u32 value = (u32)strtoul(ref, &endptr, 10);
if (endptr == ref || *endptr != '\0') {
fprintf(stderr, "Invalid decimal literal: %s\n", ref);
exit(1);
}
return value;
}
static char *unwrap_string(const char *quoted_str) {
@ -327,26 +353,59 @@ void process_data_block(VM *vm, SymbolTable *table, ExprNode *block) {
ExprNode *val = item->children[1];
if (val->child_count == 0) {
if (strchr(val->token, '.')) {
float f = atof(val->token);
u32 addr = allocate_data(vm, table, name, 4);
write_u32(vm, memory, addr, TO_FIXED(f));
} else {
// unwrap deals with control characters and "" literals
char *unwrapped = unwrap_string(val->token);
int len = strlen(unwrapped) + 1; // Include length + null terminator
const char *token = val->token;
// Case 1: String literal (enclosed in quotes)
if (token[0] == '"' && token[strlen(token) - 1] == '"') {
char *unwrapped = unwrap_string(token);
int len = strlen(unwrapped) + 1;
u32 addr = allocate_data(vm, table, name, len + 4);
write_u32(vm, memory, addr, len);
// Copy string to memory
for (int i = 0; i < len; i++) {
write_u8(vm, memory, addr + 4 + i, unwrapped[i]);
}
vm->mp += 4 + len;
free(unwrapped);
}
// Case 2: Hexadecimal integer (0x...)
else if (token[0] == '0' && (token[1] == 'x' || token[1] == 'X')) {
char *endptr;
u32 value = (u32)strtoul(token + 2, &endptr, 16);
if (endptr != token + strlen(token)) {
fprintf(stderr, "Invalid hex in data block: %s\n", token);
exit(1);
}
u32 addr = allocate_data(vm, table, name, 4);
write_u32(vm, memory, addr, value);
vm->mp += 4;
}
// Case 3: Floating-point (has decimal point)
else if (strchr(token, '.')) {
float f = atof(token);
u32 addr = allocate_data(vm, table, name, 4);
write_u32(vm, memory, addr, TO_FIXED(f));
vm->mp += 4;
}
// Case 4: Decimal integer
else {
char *endptr;
u32 value = (u32)strtoul(token, &endptr, 10);
if (endptr != token + strlen(token)) {
fprintf(stderr, "Invalid decimal in data block: %s\n", token);
exit(1);
}
u32 addr = allocate_data(vm, table, name, 4);
write_u32(vm, memory, addr, value);
vm->mp += 4;
}
} else {
fprintf(stderr, "Unsupported data item\n");
exit(1);
}
}
}
@ -374,24 +433,60 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) {
emit_u32(vm, addr);
} else if (strcmp(opname, "return") == 0) {
emit_opcode(vm, OP_RETURN);
} else if (strcmp(opname, "load") == 0) {
emit_opcode(vm, OP_LOAD);
int reg = parse_register(node->children[0]->token);
u32 addr = resolve_symbol(table, node->children[1]->token);
emit_byte(vm, reg);
emit_u32(vm, addr);
} else if (strcmp(opname, "load-immediate") == 0) {
emit_opcode(vm, OP_LOAD_IMM);
int reg = parse_register(node->children[0]->token);
u32 addr = resolve_symbol(table, node->children[1]->token);
emit_byte(vm, reg);
emit_u32(vm, addr);
} else if (strcmp(opname, "load") == 0) {
emit_opcode(vm, OP_LOAD);
int dest = parse_register(node->children[0]->token);
int src1 = parse_register(node->children[1]->token);
emit_byte(vm, dest);
emit_byte(vm, src1);
} else if (strcmp(opname, "load-i8") == 0) {
emit_opcode(vm, OP_LOADI8);
int dest = parse_register(node->children[0]->token);
int src1 = parse_register(node->children[1]->token);
emit_byte(vm, dest);
emit_byte(vm, src1);
} else if (strcmp(opname, "load-u8") == 0) {
emit_opcode(vm, OP_LOADU8);
int dest = parse_register(node->children[0]->token);
int src1 = parse_register(node->children[1]->token);
emit_byte(vm, dest);
emit_byte(vm, src1);
} else if (strcmp(opname, "load-u16") == 0) {
emit_opcode(vm, OP_LOADU16);
int dest = parse_register(node->children[0]->token);
int src1 = parse_register(node->children[1]->token);
emit_byte(vm, dest);
emit_byte(vm, src1);
} else if (strcmp(opname, "load-i16") == 0) {
emit_opcode(vm, OP_LOADI16);
int dest = parse_register(node->children[0]->token);
int src1 = parse_register(node->children[1]->token);
emit_byte(vm, dest);
emit_byte(vm, src1);
} else if (strcmp(opname, "store") == 0) {
emit_opcode(vm, OP_STORE);
int reg = parse_register(node->children[0]->token);
u32 addr = resolve_symbol(table, node->children[1]->token);
emit_byte(vm, reg);
emit_u32(vm, addr);
int dest = parse_register(node->children[0]->token);
int src1 = parse_register(node->children[1]->token);
emit_byte(vm, dest);
emit_byte(vm, src1);
} else if (strcmp(opname, "store-8") == 0) {
emit_opcode(vm, OP_STORE8);
int dest = parse_register(node->children[0]->token);
int src1 = parse_register(node->children[1]->token);
emit_byte(vm, dest);
emit_byte(vm, src1);
} else if (strcmp(opname, "store-16") == 0) {
emit_opcode(vm, OP_STORE16);
int dest = parse_register(node->children[0]->token);
int src1 = parse_register(node->children[1]->token);
emit_byte(vm, dest);
emit_byte(vm, src1);
} else if (strcmp(opname, "push") == 0) {
emit_opcode(vm, OP_PUSH);
int reg = parse_register(node->children[0]->token);
@ -432,6 +527,54 @@ void process_code_expr(VM *vm, SymbolTable *table, ExprNode *node) {
int reg = parse_register(node->children[i]->token);
emit_byte(vm, reg);
}
} else if (strcmp(opname, "bit-shift-left") == 0) {
emit_opcode(vm, OP_SLL);
int dest = parse_register(node->children[0]->token);
int src1 = parse_register(node->children[1]->token);
int src2 = parse_register(node->children[2]->token);
emit_byte(vm, dest);
emit_byte(vm, src1);
emit_byte(vm, src2);
} else if (strcmp(opname, "bit-shift-right") == 0) {
emit_opcode(vm, OP_SRL);
int dest = parse_register(node->children[0]->token);
int src1 = parse_register(node->children[1]->token);
int src2 = parse_register(node->children[2]->token);
emit_byte(vm, dest);
emit_byte(vm, src1);
emit_byte(vm, src2);
} else if (strcmp(opname, "bit-shift-right-extend") == 0) {
emit_opcode(vm, OP_SRE);
int dest = parse_register(node->children[0]->token);
int src1 = parse_register(node->children[1]->token);
int src2 = parse_register(node->children[2]->token);
emit_byte(vm, dest);
emit_byte(vm, src1);
emit_byte(vm, src2);
} else if (strcmp(opname, "bit-and") == 0) {
emit_opcode(vm, OP_BAND);
int dest = parse_register(node->children[0]->token);
int src1 = parse_register(node->children[1]->token);
int src2 = parse_register(node->children[2]->token);
emit_byte(vm, dest);
emit_byte(vm, src1);
emit_byte(vm, src2);
} else if (strcmp(opname, "bit-or") == 0) {
emit_opcode(vm, OP_BOR);
int dest = parse_register(node->children[0]->token);
int src1 = parse_register(node->children[1]->token);
int src2 = parse_register(node->children[2]->token);
emit_byte(vm, dest);
emit_byte(vm, src1);
emit_byte(vm, src2);
} else if (strcmp(opname, "bit-xor") == 0) {
emit_opcode(vm, OP_BXOR);
int dest = parse_register(node->children[0]->token);
int src1 = parse_register(node->children[1]->token);
int src2 = parse_register(node->children[2]->token);
emit_byte(vm, dest);
emit_byte(vm, src1);
emit_byte(vm, src2);
} else if (strcmp(opname, "add-int") == 0) {
emit_opcode(vm, OP_ADD_INT);
int dest = parse_register(node->children[0]->token);
@ -780,14 +923,18 @@ void assemble(VM *vm, ExprNode *program) {
for (size_t i = 0; i < program->child_count; ++i) {
ExprNode *section = program->children[i];
if (strcmp(section->token, "code") == 0) {
for (size_t i = 0; i < section->child_count; ++i) {
process_code_expr(vm, &table, section->children[i]);
for (size_t j = 0; j < section->child_count; ++j) {
process_code_expr(vm, &table, section->children[j]);
}
}
}
// Cleanup symbol table
for (int i = 0; i < table.count; i++) {
#ifdef ASM_DEBUG
Symbol s = table.symbols[i];
printf("%s[%d]\n", s.name, s.address);
#endif
free(table.symbols[i].name);
}
free(table.symbols);

View File

@ -37,19 +37,17 @@
return true; \
} while (0)
#define BIT_OP(op) \
do { \
dest = read_u8(vm, code, vm->pc); \
vm->pc++; \
src1 = read_u8(vm, code, vm->pc); \
vm->pc++; \
src2 = read_u8(vm, code, vm->pc); \
vm->pc++; \
frame->registers[dest] = \
frame->registers[src1] op frame->registers[src2]; \
return true; \
} while (0)
#define BIT_OP(op) \
do { \
dest = read_u8(vm, code, vm->pc); \
vm->pc++; \
src1 = read_u8(vm, code, vm->pc); \
vm->pc++; \
src2 = read_u8(vm, code, vm->pc); \
vm->pc++; \
frame->registers[dest] = frame->registers[src1] op frame->registers[src2]; \
return true; \
} while (0)
u32 str_alloc(VM *vm, Frame *frame, const char *str, u32 length) {
u32 str_addr = vm->mp;
@ -110,8 +108,10 @@ bool step_vm(VM *vm) {
case OP_LOAD: {
dest = read_u8(vm, code, vm->pc);
vm->pc++;
ptr = read_u32(vm, code, vm->pc);
vm->pc += 4;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
v = frame->registers[src1];
ptr = frame->registers[dest];
v = read_u32(vm, memory, ptr);
frame->registers[dest] = v;
return true;
@ -120,28 +120,33 @@ bool step_vm(VM *vm) {
i8 v8;
dest = read_u8(vm, code, vm->pc);
vm->pc++;
ptr = read_u32(vm, code, vm->pc);
vm->pc += 4;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
v = frame->registers[src1];
ptr = frame->registers[dest];
v8 = (i8)read_u8(vm, memory, ptr);
frame->registers[dest] = v8;
frame->registers[ptr] = v8;
return true;
}
case OP_LOADU8: {
u8 v8;
dest = read_u8(vm, code, vm->pc);
vm->pc++;
ptr = read_u32(vm, code, vm->pc);
vm->pc += 4;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
ptr = frame->registers[src1];
v8 = read_u8(vm, memory, ptr);
frame->registers[dest] = v8;
frame->registers[ptr] = v8;
return true;
}
case OP_LOADI16: {
i16 v16;
dest = read_u8(vm, code, vm->pc);
vm->pc++;
ptr = read_u32(vm, code, vm->pc);
vm->pc += 4;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
v = frame->registers[src1];
ptr = frame->registers[dest];
v16 = (i16)read_u16(vm, memory, ptr);
frame->registers[dest] = v16;
return true;
@ -150,34 +155,41 @@ bool step_vm(VM *vm) {
u16 v16;
dest = read_u8(vm, code, vm->pc);
vm->pc++;
ptr = read_u32(vm, code, vm->pc);
vm->pc += 4;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
v = frame->registers[src1];
ptr = frame->registers[dest];
v16 = read_u16(vm, memory, ptr);
frame->registers[dest] = v16;
frame->registers[ptr] = v16;
return true;
}
case OP_STORE: {
dest = read_u8(vm, code, vm->pc);
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
ptr = read_u32(vm, code, vm->pc);
vm->pc += 4;
v = frame->registers[src1];
ptr = frame->registers[dest];
write_u32(vm, memory, ptr, v);
return true;
}case OP_STORE8: {
}
case OP_STORE8: {
dest = read_u8(vm, code, vm->pc);
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
ptr = read_u32(vm, code, vm->pc);
vm->pc += 4;
v = frame->registers[src1];
ptr = frame->registers[dest];
write_u8(vm, memory, ptr, v);
return true;
}case OP_STORE16: {
}
case OP_STORE16: {
dest = read_u8(vm, code, vm->pc);
vm->pc++;
src1 = read_u8(vm, code, vm->pc);
vm->pc++;
ptr = read_u32(vm, code, vm->pc);
vm->pc += 4;
v = frame->registers[src1];
ptr = frame->registers[dest];
write_u16(vm, memory, ptr, v);
return true;
}
@ -261,16 +273,22 @@ bool step_vm(VM *vm) {
vm->pc++;
path_ptr = frame->registers[path_reg]; /* path pointer */
size = frame->registers[size_reg]; /* size */
buffer_ptr = (dest > 32) ? vm->mp : dest; /* dest ptr, if > 32 then use memory pointer*/
size = frame->registers[size_reg]; /* size */
buffer_ptr = (dest > 32)
? vm->mp
: dest; /* dest ptr, if > 32 then use memory pointer*/
dev = find_device_by_path(vm, (const char *)&vm->memory[path_ptr + 4]);
if (dev && dev->ops->read) {
vm->flag =
dev->ops->read(dev->data, (u8 *)&vm->memory[buffer_ptr + 4], size);
if (dest > 32) { vm->mp += size + 4;}
if (dest > 32) {
vm->mp += size + 4;
}
write_u32(vm, memory, buffer_ptr, size);
if (dest > 32) { frame->end = vm->mp; }
if (dest > 32) {
frame->end = vm->mp;
}
frame->registers[buffer_reg] = buffer_ptr;
} else {
vm->flag = 0;

20
test/box.asm.lisp Normal file
View File

@ -0,0 +1,20 @@
((code
(label main
(load-immediate $0 &screen-namespace)
(load-immediate $1 0)
(syscall DEVICE-OPEN $0 $1)
(load-immediate $3 0xE0)
(load-immediate $4 36)
(load-immediate $1 1)
(load-immediate $5 50)
(label loop-x
(store-8 $4 $3)
(add-int $4 $4 $1)
(jump-lt-int &loop-x $4 $5))
(syscall DEVICE-WRITE $0 $0 $0)
(halt)))
(data
(label screen-namespace "/dev/screen/0")))

View File

@ -1,16 +1,21 @@
((code
(label main
(load $0 &x)
(load $1 &y)
(load-immediate $0 &x)
(load-immediate $1 &y)
(add-real $2 $1 $0)
(real-to-string $3 $2)
(string-length $4 $3)
(load-immediate $5 &terminal-namespace)
(syscall DEVICE-WRITE $5 $3 $4)
(load-immediate $6 &new-line)
(string-length $7 $6)
(syscall DEVICE-WRITE $5 $6 $7)
(halt)))
(push $3)
(call &println)
(halt))
(label println
(load-immediate $0 &terminal-namespace)
(load-immediate $3 &new-line)
(pop $1)
(string-length $2 $1)
(syscall DEVICE-WRITE $0 $1 $2)
(string-length $4 $3)
(syscall DEVICE-WRITE $0 $3 $4)
(return)))
(data (label terminal-namespace "/dev/term/0")
(label new-line "\n")
(label x 1.0)

View File

@ -1,9 +1,14 @@
((code
(label main
(load-immediate $0 &screen-namespace)
(load-immediate $1 0) ; mode 0
(syscall DEVICE-OPEN $0 $2)
(label main
(load-immediate $0 &screen-namespace)
(load-immediate $1 0)
(syscall DEVICE-OPEN $0 $2)
(load-immediate $3 0x55)
(load-immediate $4 36)
(store-8 $4 $3)
(syscall DEVICE-WRITE $0 $0 $0)
(halt)))
(data (label screen-namespace "/dev/term/0")))
(halt)))
(data
(label screen-namespace "/dev/screen/0")))