In emu_mips_alt, add syscall handling, but mips-tetris doesn't run yet
authorNick Downing <nick@ndcode.org>
Mon, 2 Jan 2023 22:48:20 +0000 (09:48 +1100)
committerNick Downing <nick@ndcode.org>
Tue, 3 Jan 2023 03:58:22 +0000 (14:58 +1100)
emu_mips.c
mips-tetris

index 6141f10..2e281db 100644 (file)
@@ -309,7 +309,7 @@ int main(int argc, char **argv) {
   // for mips-tetris assume main is at 0x400000
   cpu->registers[PC] = 0x400000;
   cpu->next_pc = cpu->registers[PC] + 4;
-  cpu->registers[R29] = 0x103ffffc;
+  cpu->registers[R29] = 0x103ffffc; // sp -> last word of 4 Mbyte .data section
 
   while (true) {
 #if REG_TRACE
@@ -355,6 +355,40 @@ int main(int argc, char **argv) {
 #endif
 
     cpu_update(cpu);
+    if (cpu->exception_pending == Syscall) {
+      switch (cpu->registers[R2]) {
+      case 1: /* print char */
+        fputc(cpu->registers[R4], stdout);
+        break;
+      case 4: /* print string */
+        {
+          int c;
+          for (int p = cpu->registers[R4]; (c = read_byte(NULL, p)) != 0; ++p)
+            fputc(c, stdout);
+        }
+        break;
+      case 5: /* integer input */
+        {
+          fflush(stdout);
+
+          char buf[0x100];
+          if (fgets(buf, 0x100, stdin) == NULL) {
+            perror("fgets()");
+            exit(EXIT_FAILURE);
+          }
+          cpu->registers[R10] = atoi(buf);
+        }
+        break;
+      case 10: /* end program */
+        exit(EXIT_SUCCESS);
+      default:
+        fprintf(stderr, "unimplemented syscall %d\n", cpu->registers[R2]);
+        exit(EXIT_FAILURE);
+      }
+      cpu->exception_pending = NoException;
+      cpu->registers[PC] = cpu->next_pc;
+      cpu->next_pc += 4;
+    }
   }
 #else
   struct cpu_mips cpu;
index 54c0a47..55bdaca 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 54c0a47e9cd2bc82fd81c8cad3d48512c4d98040
+Subproject commit 55bdaca534c4aeb35be20f78bbb65703e08e4f3e