TCPU/src/instructions/impl/SYS.c
2024-11-16 23:08:38 +05:00

70 lines
1.5 KiB
C

#include "impl_macros.h"
FILE* NULLABLE(fileFromN)(VM* vm, u32 file_n){
FILE* f = NULL;
switch(file_n){
case 0: f = stdin; break;
case 1: f = stdout; break;
case 2: f = stderr; break;
default:
VM_setError(vm, "invalid file_n (%x) ", file_n);
break;
}
return f;
}
// sys_read
// bx - file n
// cx - buffer ptr
// dx - buffer size
i32 SYS_read(VM* vm){
const u32 file_n = vm->bx.u32v;
u8* const buf = vm->data + vm->cx.u32v;
const u32 size = vm->dx.u32v;
if(buf + size > vm->data + vm->data_size)
return 40;
FILE* f = fileFromN(vm, file_n);
return fread(buf, 1, size, f);
}
// sys_write
// bx - file n
// cx - buffer ptr
// dx - buffer size
i32 SYS_write(VM* vm){
const u32 file_n = vm->bx.u32v;
u8* const buf = vm->data + vm->cx.u32v;
const u32 size = vm->dx.u32v;
if(buf + size > vm->data + vm->data_size)
return 41;
FILE* f = fileFromN(vm, file_n);
return fwrite(buf, 1, size, f);
}
/// SYS
/// before call: ax - func code
/// after call: ax - result code
i32 SYS_impl(VM* vm){
u8 func_code = vm->ax.u8v0;
u32 result_code = 0;
switch(func_code){
case 0:
result_code = SYS_read(vm);
break;
case 1:;
result_code = SYS_write(vm);
break;
default:
VM_setError(vm, "invalid system call (%x) ", func_code);
return -1;
}
vm->ax.u32v = result_code;
return 0;
}