Add stubbed EMC (emulator call) instruction
x1phosura x1phosura@x1phosura.zone
Mon, 03 May 2021 09:35:00 -0400
10 files changed,
60 insertions(+),
8 deletions(-)
M
Makefile
→
Makefile
@@ -32,17 +32,19 @@
bin/%.o: src/%.c $(CC) $(CFLAGS) -o $@ -c $^ +bin/emcalls.o: bin/vm.o: bin/main.o: bin/disass.o: +# needs to be run separately rom: rom.bin xxd -i src/$^ > src/$@.h rom.bin: src/rom.asm src/zeropage.incbin ./ass.sh src/rom.asm src/zeropage.incbin -$(TARGET): bin/main.o bin/vm.o +$(TARGET): bin/main.o bin/vm.o bin/emcalls.o $(CC) $(CFLAGS) -o bin/$@$(TRACE_SUFFIX) $^ clean:
M
ass.sh
→
ass.sh
@@ -37,6 +37,7 @@ sed -i 's/RET[[:blank:]]*/0c 00 00/gi' "$1"
sed -i 's/JMP[[:blank:]]/0d/gi' "$1" sed -i 's/BEQ[[:blank:]]/0e/gi' "$1" sed -i 's/BNQ[[:blank:]]/0f/gi' "$1" + sed -i 's/EMC[[:blank:]]/10/gi' "$1" sed -i 's/NOP[[:blank:]]*/ff 00 00/gi' "$1" sed -i 's/H//gi' "$1" # remove hex suffix 'h' after only hex digits remain
M
src/disass.c
→
src/disass.c
@@ -1,3 +1,5 @@
+/* x1phosura 2021 */ + #include <assert.h> #include <getopt.h> #include <stdbool.h>
A
src/emcalls.c
@@ -0,0 +1,34 @@
+/* emcalls.c: This file implements emulator calls ("emcalls"). Emcalls are +analogous to system calls, except since there's no real OS, they're handled +directly by the emulator. The basic usage should revolve around adding cases +to the emcall switch-case, where each case is a special emcall that calls a +function to handle it. This is perhaps the easiest way to plug fancy features +into the emulator itself; basically treat the EMC instruction is like the ioctl +syscall (_now_ I see why ioctl is such a tempting serpent of a syscall to have) + +x1phosura 2021 +*/ + +#include <stdint.h> +#include <stdio.h> + + +void do_emcall(uint8_t emc_args[2]) +{ + // emc_args[1] may be used in the future + switch(emc_args[0]) { + case 0x00: + printf("I'm a zero emcall!\n"); // replace with emcall handler + break; + case 0x01: + printf("I'm a one emcall!\n"); // replace with emcall handler + break; + case 0x02: + printf("I'm a two emcall!\n"); // replace with emcall handler + break; + default: + printf("EMC: 1st arg: 0x%02x, 2nd arg: 0x%02x\n", emc_args[0], emc_args[1]); + } + printf("[DEBUG] TODO: finish (stubbed)\n"); +} +
A
src/emcalls.h
@@ -0,0 +1,6 @@
+/* x1phosura 2021 */ + +#pragma once // WAAAAAY better than a dumb header guard ;) + +void do_emcall(uint8_t emc_args[2]); +
M
src/main.c
→
src/main.c
@@ -1,3 +1,5 @@
+/* x1phosura 2021 */ + #include <assert.h> #include <stdbool.h> #include <stdint.h>
M
src/rom.asm
→
src/rom.asm
@@ -419,7 +419,7 @@ push 0x400b # check fourth block
pushi 0x1d00 push 0x410b pushi 0x1600 -0xee 0x07 0x30 # junk NOP +emc 0x0122 0x30 0x30 0x30 # junk NOP push 0x420b pushi 0x4400@@ -431,7 +431,7 @@ bnq 0xd102 # Fail if any two bytes ever not equal
pop 0xffff pop 0xffff 0xee 0x07 0x30 # junk NOP -0xee 0x07 0x30 # junk NOP +emc 0x3344 bnq 0xd102 # Fail if any two bytes ever not equal pop 0xffff 0xee 0x07 0x30 # junk NOP
M
src/rom.h
→
src/rom.h
@@ -85,10 +85,10 @@ 0xff, 0x0f, 0xd1, 0x02, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x30, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0xee, 0x07, 0x30, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0x01, 0x40, 0x0b, 0x03, 0x1d, 0x00, 0x01, 0x41, - 0x0b, 0x03, 0x16, 0x00, 0xee, 0x07, 0x30, 0x30, 0x30, 0x30, 0x01, 0x42, + 0x0b, 0x03, 0x16, 0x00, 0x10, 0x01, 0x22, 0x30, 0x30, 0x30, 0x01, 0x42, 0x0b, 0x03, 0x44, 0x00, 0x01, 0x43, 0x0b, 0x03, 0x75, 0x00, 0x0f, 0xd1, - 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0xee, 0x07, 0x30, 0xee, 0x07, - 0x30, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0xee, 0x07, 0x30, 0x02, 0xff, + 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0xee, 0x07, 0x30, 0x10, 0x33, + 0x44, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0xee, 0x07, 0x30, 0x02, 0xff, 0xff, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x02, 0xff, 0xff, 0xee, 0x07, 0x30, 0x0f, 0xd1, 0x02, 0x02, 0xff, 0xff, 0x30, 0x30, 0x30, 0x02, 0xff, 0xff, 0x0d, 0xcb, 0x02, 0x01, 0xcb, 0x02, 0x40, 0x77, 0x12, 0x00, 0x00,
M
src/vm.c
→
src/vm.c
@@ -23,6 +23,7 @@ #include <readline/history.h>
#endif #include "vm.h" +#include "emcalls.h" #ifdef TRACE // TRACE_VARS@@ -50,7 +51,6 @@ if (cpu->sp < STACK_LIM-1)
++cpu->sp; } - static inline uint8_t pop(struct CPU *cpu) { uint8_t val;@@ -61,7 +61,6 @@ } else
return 0; return val; } - /* vm_do_instruction: */@@ -163,6 +162,10 @@ if (sp > 0 && cpu->stack[sp-1] != cpu->stack[sp-2])
return operand; pc += 3; break; + case EMC: + do_emcall(operands); + pc += 3; + break; case NOP: pc += 3; break;@@ -208,6 +211,7 @@ case RET: printf("RET"); break;
case JMP: printf("JMP"); if (pargs) printf(fmt, i[1], i[2]); break; case BEQ: printf("BEQ"); if (pargs) printf(fmt, i[1], i[2]); break; case BNQ: printf("BNQ"); if (pargs) printf(fmt, i[1], i[2]); break; + case EMC: printf("EMC"); if (pargs) printf(fmt, i[1], i[2]); break; case NOP: printf("NOP"); break; default: printf("0x%02x 0x%02x 0x%02x", i[0], i[1], i[2]); }