mem.w[(addr ^ MEM_SIZE_M4) >> 2] = data;
}
+void _syscall(uint32_t *v0, uint32_t *a0, uint32_t *a1) {
+ switch (*v0) {
+ case 1: /* print int */
+ printf("%d", *a0);
+ break;
+ case 4: /* print string */
+ for (int p = *a0, c; (c = mem.b[p ^ MEM_SIZE_M1]) != 0; ++p)
+ putchar(c);
+ break;
+ case 5: /* read int */
+ {
+ fflush(stdout);
+
+ char buf[0x100];
+ if (fgets(buf, 0x100, stdin) == NULL) {
+ perror("fgets()");
+ exit(EXIT_FAILURE);
+ }
+ *v0 = atoi(buf);
+ }
+ break;
+ case 8: /* read string */
+ {
+ fflush(stdout);
+
+ char *buf = malloc(*a1);
+ if (buf == NULL) {
+ perror("malloc()");
+ exit(EXIT_FAILURE);
+ }
+ if (fgets(buf, *a1, stdin) == NULL) {
+ perror("fgets()");
+ exit(EXIT_FAILURE);
+ }
+ char *p = buf;
+ int q = *a0;
+ while ((mem.b[q++ ^ MEM_SIZE_M1] = *p++) != 0)
+ ;
+ free(buf);
+ }
+ break;
+ case 10: /* end program */
+ exit(EXIT_SUCCESS);
+ case 11: /* print char */
+ putchar(*a0);
+ break;
+ case 12: /* read char */
+ fflush(stdout);
+ *a0 = getchar();
+ break;
+ default:
+ fprintf(stderr, "unimplemented syscall %d\n", *v0);
+ exit(EXIT_FAILURE);
+ }
+}
+
#if ALT_BACKEND
int simulator_bigendian = 1;
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);
- }
+ _syscall(
+ cpu->registers + R2, // v0
+ cpu->registers + R4, // a0
+ cpu->registers + R5 // a1
+ );
cpu->exception_pending = NoException;
cpu->registers[PC] = cpu->next_pc;
cpu->next_pc += 4;