commit 1c106a53cf5cac8d322849f52aa8fa201366069d
parent 8388b8d04e1a9316dd73befe0bd5d56d541ef304
Author: Pavel Renev <an2qzavok@gmail.com>
Date: Fri, 2 Apr 2021 22:17:20 +0000
vsm: fix IF instruction, add primitive I/O instructions
Diffstat:
M | vsm.c | | | 40 | ++++++++++++++++++++++++++++------------ |
M | vsm.h | | | 9 | ++++++++- |
2 files changed, 36 insertions(+), 13 deletions(-)
diff --git a/vsm.c b/vsm.c
@@ -102,9 +102,8 @@ void i_LIT(void)
/* Conditional Branching: */
void i_IF(void)
{
- if (dsp == 0) pc = ram[pc];
- else pc++;
- dsp--;
+ if (*dsp == 0) pc = *(dsp - 1) - 1;
+ dsp -= 2;
}
/* Subroutine Calls: */
@@ -122,6 +121,18 @@ void i_EXIT(void)
rsp--;
}
+/* "Hardware" IO */
+
+void i_PUTC(void)
+{
+ write(1, dsp--, 1);
+}
+
+void i_GETC(void)
+{
+ read(0, ++dsp, 1);
+}
+
instruction instructions[128] = {
[VSM_NOP] i_NOP,
[VSM_ADD] i_ADD,
@@ -141,6 +152,8 @@ instruction instructions[128] = {
[VSM_IF] i_IF,
[VSM_CALL] i_CALL,
[VSM_EXIT] i_EXIT,
+ [VSM_PUTC] i_PUTC,
+ [VSM_GETC] i_GETC,
};
/* VMS Control */
@@ -162,25 +175,28 @@ vsm_exec(CELL op)
pc++;
}
-void
-vsm_halt(void)
-{
-}
void
vsm_run(void)
{
+ CELL op;
for (;;) {
/* TODO: put more sanity checks here */
- CELL op = ram[pc];
- if (op >= NUM_OPS) {
- fprint(2, "invalid op == %x\n", op);
- vsm_halt();
+ if (dsp < dstack) {
+ fprint(2, "dstack underflow\n");
+ return;
+ }
+ if (rsp < rstack) {
+ fprint(2, "rstack underflow\n");
return;
}
if (pc >= IMAGE_SIZE) {
fprint(2, "pc reached end of the image\n");
- vsm_halt();
+ return;
+ }
+ op = ram[pc];
+ if (op >= NUM_OPS) {
+ fprint(2, "invalid op == %x\n", op);
return;
}
vsm_exec(op);
diff --git a/vsm.h b/vsm.h
@@ -19,9 +19,12 @@ enum {
VSM_IF,
/* Subroutine Calls: */
VSM_CALL, VSM_EXIT,
+/* "Hardware" IO: */
+ VSM_PUTC, VSM_GETC,
+/* this should be at the end of enum def: */
+ NUM_OPS,
};
-#define NUM_OPS VSM_EXIT + 1
CELL pc;
CELL ir;
@@ -72,6 +75,10 @@ void i_IF(void);
void i_CALL(void);
void i_EXIT(void);
+/* "Hardware" IO */
+void i_PUTC(void);
+void i_GETC(void);
+
/* VMS Control */
void vsm_exec(CELL);