diff options
Diffstat (limited to 'subx/020syscalls.cc')
-rw-r--r-- | subx/020syscalls.cc | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/subx/020syscalls.cc b/subx/020syscalls.cc new file mode 100644 index 00000000..177ba6f1 --- /dev/null +++ b/subx/020syscalls.cc @@ -0,0 +1,32 @@ +:(before "End Initialize Op Names(name)") +put(name, "cd", "software interrupt"); + +:(before "End Single-Byte Opcodes") +case 0xcd: { // int imm8 (software interrupt) + trace(90, "run") << "syscall" << end(); + uint8_t code = next(); + if (code != 0x80) { + raise << "Unimplemented interrupt code " << HEXBYTE << code << '\n' << end(); + raise << " Only `int 80h` supported for now.\n" << end(); + break; + } + process_int80(); + break; +} + +:(code) +void process_int80() { + switch (Reg[EAX].u) { + case 1: + exit(/*exit code*/Reg[EBX].u); + break; + case 3: + Reg[EAX].i = read(/*file descriptor*/Reg[EBX].u, /*memory buffer*/mem_addr_u8(Reg[ECX].u), /*size*/Reg[EDX].u); + break; + case 4: + Reg[EAX].i = write(/*file descriptor*/Reg[EBX].u, /*memory buffer*/mem_addr_u8(Reg[ECX].u), /*size*/Reg[EDX].u); + break; + default: + raise << HEXWORD << EIP << ": unimplemented syscall " << Reg[EAX].u << '\n' << end(); + } +} |