about summary refs log tree commit diff stats
path: root/subx/020syscalls.cc
diff options
context:
space:
mode:
Diffstat (limited to 'subx/020syscalls.cc')
-rw-r--r--subx/020syscalls.cc32
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();
+  }
+}