all repos — 3ByteBadVM @ 081b72c6ea4b2b09b15b073845d676f3d72669cb

3ByteBadVM

Add stubbed EMC (emulator call) instruction
x1phosura x1phosura@x1phosura.zone
Mon, 03 May 2021 09:35:00 -0400
commit

081b72c6ea4b2b09b15b073845d676f3d72669cb

parent

736bc261c184c872daaa37bd8f0759c7e8bb7ece

10 files changed, 60 insertions(+), 8 deletions(-)

jump to
M MakefileMakefile

@@ -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.shass.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.csrc/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.csrc/main.c

@@ -1,3 +1,5 @@

+/* x1phosura 2021 */ + #include <assert.h> #include <stdbool.h> #include <stdint.h>
M src/rom.asmsrc/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.hsrc/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.csrc/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]); }
M src/vm.hsrc/vm.h

@@ -23,6 +23,7 @@ RET = 12,

JMP = 13, BEQ = 14, BNQ = 15, + EMC = 16, // every opcode 0x10-0xfe is basically just a NOP just to be annoying NOP = 0xff };