Fix tests, make auto compile for rom files
This commit is contained in:
parent
89ef394888
commit
6c1bf1ff8c
18
Makefile
18
Makefile
|
|
@ -152,7 +152,19 @@ clean-all:
|
|||
@rm -rf build/
|
||||
@echo "All cleaned."
|
||||
|
||||
# --- HELP ---
|
||||
# --- TEST COMPILATION TARGET ---
|
||||
# Compiles all .asm.lisp test files to .rom using the debug VM executable
|
||||
# Usage: make compile-tests PLATFORM=linux
|
||||
compile-tests: $(BUILD_DIR)/undar-$(PLATFORM)$(TARGET_SUFFIX)
|
||||
@echo "Compiling test assembly files for $(PLATFORM)..."
|
||||
@for f in ./test/*.asm.lisp; do \
|
||||
base=$$(basename "$$f" .asm.lisp); \
|
||||
echo " [$$base] $$f -> ./test/$$base.rom"; \
|
||||
$(BUILD_DIR)/undar-$(PLATFORM)$(TARGET_SUFFIX) "$$f" -o "./test/$$base.rom"; \
|
||||
done
|
||||
@echo "Compilation complete: $$(ls -1 ./test/*.rom | wc -l) ROM files generated"
|
||||
|
||||
# Update help target to include new command
|
||||
help:
|
||||
@echo "Undar VM"
|
||||
@echo ""
|
||||
|
|
@ -160,13 +172,13 @@ help:
|
|||
@echo " make -> debug build (default: linux)"
|
||||
@echo " make debug -> same as above"
|
||||
@echo " make release -> optimized, stripped build"
|
||||
@echo " make compile-tests -> compile all test assembly files"
|
||||
@echo " make clean -> clean current platform"
|
||||
@echo " make clean-all→ clean all platforms"
|
||||
@echo " make clean-all-> clean all platforms"
|
||||
@echo ""
|
||||
@echo "Platforms:"
|
||||
@echo " make PLATFORM=linux -> GCC + SDL2"
|
||||
@echo " make PLATFORM=emscripten -> Emscripten + SDL2 for Web"
|
||||
@echo " make PLATFORM=avr -> (example) AVR-GCC"
|
||||
@echo ""
|
||||
@echo "Output:"
|
||||
@echo " Linux: build/linux/undar-linux-<debug|release>"
|
||||
|
|
|
|||
|
|
@ -234,6 +234,144 @@ void repl(VM *vm) {
|
|||
exit(0);
|
||||
}
|
||||
|
||||
#ifdef ASM_DEBUG
|
||||
const char *opcode_to_string(Opcode op) {
|
||||
static const char *names[] = {
|
||||
[OP_HALT] = "halt",
|
||||
[OP_JMP] = "jump",
|
||||
[OP_JMPF] = "jump-if-flag",
|
||||
[OP_CALL] = "call",
|
||||
[OP_RETURN] = "return",
|
||||
|
||||
/* Immediate loads (only 32-bit variant needed) */
|
||||
[OP_LOAD_IMM] = "load-immediate",
|
||||
|
||||
/* Register-indirect loads */
|
||||
[OP_LOAD_IND_8] = "load-indirect-8",
|
||||
[OP_LOAD_IND_16] = "load-indirect-16",
|
||||
[OP_LOAD_IND_32] = "load-indirect-32",
|
||||
|
||||
/* Absolute address loads */
|
||||
[OP_LOAD_ABS_8] = "load-absolute-8",
|
||||
[OP_LOAD_ABS_16] = "load-absolute-16",
|
||||
[OP_LOAD_ABS_32] = "load-absolute-32",
|
||||
|
||||
/* Base+offset loads */
|
||||
[OP_LOAD_OFF_8] = "load-offset-8",
|
||||
[OP_LOAD_OFF_16] = "load-offset-16",
|
||||
[OP_LOAD_OFF_32] = "load-offset-32",
|
||||
|
||||
/* Absolute address stores */
|
||||
[OP_STORE_ABS_8] = "store-absolute-8",
|
||||
[OP_STORE_ABS_16] = "store-absolute-16",
|
||||
[OP_STORE_ABS_32] = "store-absolute-32",
|
||||
|
||||
/* Register-indirect stores */
|
||||
[OP_STORE_IND_8] = "store-indirect-8",
|
||||
[OP_STORE_IND_16] = "store-indirect-16",
|
||||
[OP_STORE_IND_32] = "store-indirect-32",
|
||||
|
||||
/* Base+offset stores */
|
||||
[OP_STORE_OFF_8] = "store-offset-8",
|
||||
[OP_STORE_OFF_16] = "store-offset-16",
|
||||
[OP_STORE_OFF_32] = "store-offset-32",
|
||||
|
||||
/* Memory operations */
|
||||
[OP_MALLOC] = "malloc",
|
||||
[OP_MEMSET_8] = "memset-8",
|
||||
[OP_MEMSET_16] = "memset-16",
|
||||
[OP_MEMSET_32] = "memset-32",
|
||||
|
||||
/* Stack operations */
|
||||
[OP_PUSH] = "push",
|
||||
[OP_POP] = "pop",
|
||||
|
||||
/* Register operations */
|
||||
[OP_REG_MOV] = "register-move",
|
||||
[OP_SYSCALL] = "syscall",
|
||||
|
||||
/* Bit operations */
|
||||
[OP_SLL] = "bit-shift-left",
|
||||
[OP_SRL] = "bit-shift-right",
|
||||
[OP_SRE] = "bit-shift-re",
|
||||
[OP_BAND] = "bit-and",
|
||||
[OP_BOR] = "bit-or",
|
||||
[OP_BXOR] = "bit-xor",
|
||||
|
||||
/* Integer arithmetic */
|
||||
[OP_ADD_INT] = "add-int",
|
||||
[OP_SUB_INT] = "sub-int",
|
||||
[OP_MUL_INT] = "mul-int",
|
||||
[OP_DIV_INT] = "div-int",
|
||||
|
||||
/* Natural number arithmetic */
|
||||
[OP_ADD_NAT] = "add-nat",
|
||||
[OP_SUB_NAT] = "sub-nat",
|
||||
[OP_MUL_NAT] = "mul-nat",
|
||||
[OP_DIV_NAT] = "div-nat",
|
||||
|
||||
/* Floating point operations */
|
||||
[OP_ADD_REAL] = "add-real",
|
||||
[OP_SUB_REAL] = "sub-real",
|
||||
[OP_MUL_REAL] = "mul-real",
|
||||
[OP_DIV_REAL] = "div-real",
|
||||
|
||||
/* Type conversions */
|
||||
[OP_INT_TO_REAL] = "int-to-real",
|
||||
[OP_NAT_TO_REAL] = "nat-to-real",
|
||||
[OP_REAL_TO_INT] = "real-to-int",
|
||||
[OP_REAL_TO_NAT] = "real-to-nat",
|
||||
|
||||
/* Integer comparisons */
|
||||
[OP_JEQ_INT] = "jump-eq-int",
|
||||
[OP_JNEQ_INT] = "jump-neq-int",
|
||||
[OP_JGT_INT] = "jump-gt-int",
|
||||
[OP_JLT_INT] = "jump-lt-int",
|
||||
[OP_JLE_INT] = "jump-le-int",
|
||||
[OP_JGE_INT] = "jump-ge-int",
|
||||
|
||||
/* Natural number comparisons */
|
||||
[OP_JEQ_NAT] = "jump-eq-nat",
|
||||
[OP_JNEQ_NAT] = "jump-neq-nat",
|
||||
[OP_JGT_NAT] = "jump-gt-nat",
|
||||
[OP_JLT_NAT] = "jump-lt-nat",
|
||||
[OP_JLE_NAT] = "jump-le-nat",
|
||||
[OP_JGE_NAT] = "jump-ge-nat",
|
||||
|
||||
/* Floating point comparisons */
|
||||
[OP_JEQ_REAL] = "jump-eq-real",
|
||||
[OP_JNEQ_REAL] = "jump-neq-real",
|
||||
[OP_JGE_REAL] = "jump-ge-real",
|
||||
[OP_JGT_REAL] = "jump-gt-real",
|
||||
[OP_JLT_REAL] = "jump-lt-real",
|
||||
[OP_JLE_REAL] = "jump-le-real",
|
||||
|
||||
/* String operations */
|
||||
[OP_STRLEN] = "string-length",
|
||||
[OP_STREQ] = "string-eq",
|
||||
[OP_STRCAT] = "string-concat",
|
||||
[OP_STR_GET_CHAR] = "string-get-char",
|
||||
[OP_STR_FIND_CHAR] = "string-find-char",
|
||||
[OP_STR_SLICE] = "string-slice",
|
||||
|
||||
/* String conversions */
|
||||
[OP_INT_TO_STRING] = "int-to-string",
|
||||
[OP_NAT_TO_STRING] = "nat-to-string",
|
||||
[OP_REAL_TO_STRING] = "real-to-string",
|
||||
[OP_STRING_TO_INT] = "string-to-int",
|
||||
[OP_STRING_TO_NAT] = "string-to-nat",
|
||||
[OP_STRING_TO_REAL] = "string-to-real"
|
||||
};
|
||||
|
||||
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[]) {
|
||||
bool gui_mode = false;
|
||||
bool dump_rom = false;
|
||||
|
|
@ -397,8 +535,12 @@ i32 main(i32 argc, char *argv[]) {
|
|||
int cycles_this_frame = 0;
|
||||
int max_cycles_per_frame = 1000; // Adjust this value
|
||||
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)) {
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
cycles_this_frame++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "assembler.h"
|
||||
typedef enum { SYMBOL_CODE, SYMBOL_DATA, SYMBOL_PLEX } SymbolType;
|
||||
typedef enum { SYMBOL_CODE, SYMBOL_DATA } SymbolType;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
|
|
@ -26,10 +26,6 @@ void symbol_table_add(SymbolTable *table, const char *name, u32 address,
|
|||
// Check for duplicates
|
||||
for (int i = 0; i < table->count; i++) {
|
||||
if (strcmp(table->symbols[i].name, name) == 0) {
|
||||
// Allow plex redefinition for compiler evolution
|
||||
if (type == SYMBOL_PLEX && table->symbols[i].type == SYMBOL_PLEX) {
|
||||
return;
|
||||
}
|
||||
fprintf(stderr, "Error: Duplicate label '%s'\n", name);
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@
|
|||
#include <ctype.h>
|
||||
|
||||
#define AS_FIXED(v) ((float)(i32)(v) / 65536.0f)
|
||||
#define TO_FIXED(f) ((u32)((i32)( \
|
||||
#define TO_FIXED(f) ((i32)( \
|
||||
((f) >= 0.0f) ? ((f) * 65536.0f + 0.5f) : ((f) * 65536.0f - 0.5f) \
|
||||
)))
|
||||
))
|
||||
|
||||
void assemble(VM *vm, ExprNode *program);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
gcc math_gen.c -o math_gen -lm
|
||||
./math_gen > ./math.h
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("#ifndef ZRE_TRIG_TABLES_H\n#define ZRE_TRIG_TABLES_H\n#include <stdint.h>\n\n");
|
||||
|
||||
// Generate SINE table (256 entries, Q16.16 format)
|
||||
printf("const int32_t sin_table[256] = {\n");
|
||||
for (int i = 0; i < 256; i++) {
|
||||
double angle = i * 2 * M_PI / 256.0; // 0-360° in radians
|
||||
double value = sin(angle) * 65536.0; // Scale to Q16.16
|
||||
int32_t fixed = (int32_t)(value + 0.5); // Round to nearest
|
||||
printf(" %d,", fixed);
|
||||
if (i % 8 == 7) printf("\n");
|
||||
}
|
||||
printf("};\n\n");
|
||||
|
||||
// Generate COSINE table (256 entries, Q16.16 format)
|
||||
printf("const int32_t cos_table[256] = {\n");
|
||||
for (int i = 0; i < 256; i++) {
|
||||
double angle = i * 2 * M_PI / 256.0; // 0-360° in radians
|
||||
double value = cos(angle) * 65536.0; // Scale to Q16.16
|
||||
int32_t fixed = (int32_t)(value + 0.5); // Round to nearest
|
||||
printf(" %d,", fixed);
|
||||
if (i % 8 == 7) printf("\n");
|
||||
}
|
||||
printf("};\n");
|
||||
printf("#endif\n");
|
||||
return 0;
|
||||
}
|
||||
37
src/vm/str.c
37
src/vm/str.c
|
|
@ -108,8 +108,9 @@ void fixed_to_string(i32 value, char *buffer) {
|
|||
char temp[32];
|
||||
i32 negative;
|
||||
u32 int_part;
|
||||
u32 frac_part, frac_digits;
|
||||
u32 frac_part, frac_digits, original_frac_digits;
|
||||
char *end = temp + sizeof(temp) - 1;
|
||||
char *frac_start;
|
||||
*end = '\0';
|
||||
|
||||
negative = 0;
|
||||
|
|
@ -122,14 +123,40 @@ void fixed_to_string(i32 value, char *buffer) {
|
|||
frac_part = AS_NAT(value & 0xFFFF);
|
||||
|
||||
/* Convert fractional part to 5 decimal digits */
|
||||
frac_digits = (frac_part * 100000U) / 65536U;
|
||||
original_frac_digits = (frac_part * 100000U) / 65536U;
|
||||
frac_digits = original_frac_digits;
|
||||
|
||||
if (frac_digits > 0) {
|
||||
end = write_digits_backwards(frac_digits, end, temp);
|
||||
*--end = '.';
|
||||
/* Write fractional digits backwards */
|
||||
frac_start = write_digits_backwards(frac_digits, end, temp);
|
||||
|
||||
/* Remove trailing zeros by moving the start pointer */
|
||||
while (*(end - 1) == '0' && end > frac_start) {
|
||||
end--;
|
||||
}
|
||||
|
||||
if (int_part == 0 && frac_digits == 0) {
|
||||
/* If all fractional digits were zeros after removing trailing zeros,
|
||||
we need to add back one zero to represent the .0 */
|
||||
if (end == frac_start) {
|
||||
*--end = '0';
|
||||
}
|
||||
|
||||
/* Add decimal point */
|
||||
*--end = '.';
|
||||
} else if (frac_part > 0) {
|
||||
/* Handle case where original_frac_digits was rounded to 0 but frac_part was not 0 */
|
||||
/* This means we have a very small fractional part that should be represented as .0 */
|
||||
*--end = '0';
|
||||
*--end = '.';
|
||||
} else if (frac_part == 0) {
|
||||
/* No fractional part - just add .0 if we have an integer part */
|
||||
if (int_part != 0) {
|
||||
*--end = '0';
|
||||
*--end = '.';
|
||||
}
|
||||
}
|
||||
|
||||
if (int_part == 0 && frac_digits == 0 && frac_part == 0) {
|
||||
*--end = '0';
|
||||
} else {
|
||||
end = write_digits_backwards(int_part, end, temp);
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
(pop $0)
|
||||
(int-to-string $1 $0)
|
||||
(push $1)
|
||||
(call &println)
|
||||
(call &pln)
|
||||
(halt))
|
||||
|
||||
(label add
|
||||
|
|
@ -18,15 +18,17 @@
|
|||
(push $2)
|
||||
(return))
|
||||
|
||||
(label println
|
||||
(load-immediate $0 &terminal-namespace)
|
||||
(syscall OPEN $0 $0 $0)
|
||||
(label pln
|
||||
(load-immediate $0 &terminal-namespace) ; get terminal device
|
||||
(load-immediate $11 0)
|
||||
(syscall OPEN $0 $0 $11)
|
||||
(load-immediate $3 &new-line)
|
||||
(pop $1)
|
||||
(load-offset-32 $7 $0 4) ; 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 terminal-namespace "/dev/term/0")
|
||||
|
|
|
|||
BIN
test/add.rom
BIN
test/add.rom
Binary file not shown.
|
|
@ -29,14 +29,16 @@
|
|||
(push $0)
|
||||
(return)))
|
||||
(label pln
|
||||
(load-immediate $0 &terminal-namespace)
|
||||
(syscall OPEN $0 $0 $0)
|
||||
(load-immediate $0 &terminal-namespace) ; get terminal device
|
||||
(load-immediate $11 0)
|
||||
(syscall OPEN $0 $0 $11)
|
||||
(load-immediate $3 &new-line)
|
||||
(pop $1)
|
||||
(load-offset-32 $7 $0 4) ; 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 terminal-namespace "/dev/term/0")
|
||||
|
|
|
|||
BIN
test/fib.rom
BIN
test/fib.rom
Binary file not shown.
|
|
@ -1,11 +1,22 @@
|
|||
((code
|
||||
(label main
|
||||
(load-immediate $0 &terminal-namespace) ; load terminal namespace
|
||||
(syscall OPEN $0 $0 $0)
|
||||
(load-immediate $1 &hello-str) ; load hello string ptr
|
||||
(string-length $2 $1) ; get length to write to stdout
|
||||
(syscall WRITE $0 $1 $2) ; do the write syscall
|
||||
(halt))) ; done
|
||||
(push $1)
|
||||
(call &pln)
|
||||
(halt)) ; done
|
||||
(label pln
|
||||
(load-immediate $0 &terminal-namespace) ; get terminal device
|
||||
(load-immediate $11 0)
|
||||
(syscall OPEN $0 $0 $11)
|
||||
(load-immediate $3 &new-line)
|
||||
(pop $1)
|
||||
(load-offset-32 $7 $0 4) ; load handle
|
||||
(string-length $2 $1)
|
||||
(syscall WRITE $7 $1 $2)
|
||||
(string-length $4 $3)
|
||||
(syscall WRITE $7 $3 $4)
|
||||
(return)))
|
||||
(data
|
||||
(label terminal-namespace "/dev/term/0")
|
||||
(label hello-str "nuqneH 'u'?\n")))
|
||||
(label new-line "\n")
|
||||
(label hello-str "nuqneH 'u'?")))
|
||||
|
|
|
|||
BIN
test/hello.rom
BIN
test/hello.rom
Binary file not shown.
|
|
@ -28,14 +28,16 @@
|
|||
(call &pln)
|
||||
(halt))
|
||||
(label pln
|
||||
(load-immediate $0 &terminal-namespace)
|
||||
(syscall OPEN $0 $0 $0)
|
||||
(load-immediate $0 &terminal-namespace) ; get terminal device
|
||||
(load-immediate $11 0)
|
||||
(syscall OPEN $0 $0 $11)
|
||||
(load-immediate $3 &new-line)
|
||||
(pop $1)
|
||||
(load-offset-32 $7 $0 4) ; 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 terminal-namespace "/dev/term/0")
|
||||
|
|
|
|||
BIN
test/loop.rom
BIN
test/loop.rom
Binary file not shown.
|
|
@ -1,24 +1,32 @@
|
|||
((code
|
||||
(label main
|
||||
(load-immediate $0 &terminal-namespace) ; get terminal device
|
||||
(load-immediate $11 0)
|
||||
(syscall OPEN $0 $0 $11)
|
||||
|
||||
(load-immediate $1 &help) ; print help message
|
||||
(push $0)
|
||||
(push $1)
|
||||
(call &pln)
|
||||
|
||||
(load-immediate $1 32) ; read in a string of max 32 char length
|
||||
(malloc $2 $1) ; allocate memory for the string
|
||||
(syscall READ $0 $3 $1 $2) ; read the string
|
||||
(push $3)
|
||||
(malloc $4 $1) ; allocate memory for the string
|
||||
(load-offset-32 $7 $0 4) ; load handle
|
||||
(syscall READ $7 $2 $1 $4) ; read the string
|
||||
|
||||
(push $0)
|
||||
(push $4)
|
||||
(call &pln) ; print the string
|
||||
(halt))
|
||||
(label pln
|
||||
(load-immediate $0 &terminal-namespace)
|
||||
(syscall OPEN $0 $0 $0)
|
||||
(load-immediate $3 &new-line)
|
||||
(pop $1)
|
||||
(pop $0)
|
||||
(load-offset-32 $7 $0 4) ; 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 terminal-namespace "/dev/term/0")
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
BIN
test/paint.rom
BIN
test/paint.rom
Binary file not shown.
|
|
@ -1,21 +1,23 @@
|
|||
((code
|
||||
(label main
|
||||
(load-immediate $0 &x)
|
||||
(load-immediate $1 &y)
|
||||
(load-absolute-32 $0 &x)
|
||||
(load-absolute-32 $1 &y)
|
||||
(add-real $2 $1 $0)
|
||||
(real-to-string $3 $2)
|
||||
(push $3)
|
||||
(call &pln)
|
||||
(halt))
|
||||
(label pln
|
||||
(load-immediate $0 &terminal-namespace)
|
||||
(syscall OPEN $0 $0 $0)
|
||||
(load-immediate $0 &terminal-namespace) ; get terminal device
|
||||
(load-immediate $11 0)
|
||||
(syscall OPEN $0 $0 $11)
|
||||
(load-immediate $3 &new-line)
|
||||
(pop $1)
|
||||
(load-offset-32 $7 $0 4) ; 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 terminal-namespace "/dev/term/0")
|
||||
(label new-line "\n")
|
||||
|
|
|
|||
BIN
test/simple.rom
BIN
test/simple.rom
Binary file not shown.
|
|
@ -43,14 +43,7 @@
|
|||
(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)
|
||||
(load-indirect-32 $16 $19) ; load handle
|
||||
(load-offset-32 $16 $15 4) ; load handle
|
||||
|
||||
(syscall WRITE $0 $21 $22) ; redraw
|
||||
|
||||
|
|
|
|||
BIN
test/window.rom
BIN
test/window.rom
Binary file not shown.
Loading…
Reference in New Issue