aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2023-04-13 23:56:16 +0200
committerkdx <kikoodx@paranoici.org>2023-04-13 23:56:16 +0200
commitbb465e00c234c9f73f5ad18e2a10dd0709702737 (patch)
treebfa205eaaff7502faa2d48c325a87aacc8d78cf5
parenta721fdf3dfefa817701371a62c834619055d7ce7 (diff)
downloadorga-bb465e00c234c9f73f5ad18e2a10dd0709702737.tar.gz
support entire spec
-rw-r--r--spec.md12
-rw-r--r--src/orgaemu.c61
2 files changed, 67 insertions, 6 deletions
diff --git a/spec.md b/spec.md
index 640622a..19678d4 100644
--- a/spec.md
+++ b/spec.md
@@ -12,10 +12,10 @@ SWP ( a b -- b a ) swap top two values of the stack
ROT ( a b c -- b c a ) rotates top three values of the stack to the left
DUP ( a -- a a ) duplicates top of the stack
OVR ( a b -- a b a ) duplicates second value at the top of the stack
-EQU ( a b -- bool ) push 0001 if a == b, 0001 otherwise
-NEQ ( a b -- bool ) push 0001 if a != b, 0001 otherwise
-GTH ( a b -- bool ) push 0001 if a > b, 0001 otherwise
-LTH ( a b -- bool ) push 0001 if a < b, 0001 otherwise
+EQU ( a b -- bool ) push 0001 if a == b, 0000 otherwise
+NEQ ( a b -- bool ) push 0001 if a != b, 0000 otherwise
+GTH ( a b -- bool ) push 0001 if a > b, 0000 otherwise
+LTH ( a b -- bool ) push 0001 if a < b, 0000 otherwise
JEZ x ( cond -- ) conditional jump to x if cond != 0
JNZ x ( cond -- ) conditional jump to x if cond == 0
JMP x ( -- ) jump to x
@@ -23,8 +23,8 @@ JRT x ( -- ) jump to x and store PC+2 to return stack
RET ( -- ) return from call, or quit if not in call
LDA ( addr -- value ) push value at absolute address to top of the stack
STA ( val addr -- ) write a value to an absolute address
-RED ( -- value ) read short from stdin
-WRT ( value -- ) write short to stdout
+RED ( -- value ) read byte from stdin
+WRT ( value -- ) write byte to stdout
ADD ( a b -- a+b )
SUB ( a b -- a-b )
MUL ( a b -- a*b )
diff --git a/src/orgaemu.c b/src/orgaemu.c
index 38bd412..b3c712d 100644
--- a/src/orgaemu.c
+++ b/src/orgaemu.c
@@ -109,10 +109,42 @@ exec_op(uint16_t *mem, long pc)
push(a);
return pc + 1;
}
+ case OP_OVR: {
+ const uint16_t a = pop();
+ const uint16_t b = pop();
+ push(b);
+ push(a);
+ push(b);
+ return pc + 1;
+ }
+ case OP_EQU:
+ push(pop() == pop());
+ return pc + 1;
+ case OP_NEQ:
+ push(pop() != pop());
+ return pc + 1;
+ case OP_GTH: {
+ const uint16_t b = pop();
+ const uint16_t a = pop();
+ push(a > b);
+ return pc + 1;
+ }
+ case OP_LTH: {
+ const uint16_t b = pop();
+ const uint16_t a = pop();
+ push(a < b);
+ return pc + 1;
+ }
+ case OP_JEZ:
+ if (pop() == 0)
+ return mem[pc + 1];
+ return pc + 2;
case OP_JNZ:
if (pop() != 0)
return mem[pc + 1];
return pc + 2;
+ case OP_JMP:
+ return mem[pc + 1];
case OP_JRT:
push_rs(pc + 2);
return mem[pc + 1];
@@ -129,15 +161,30 @@ exec_op(uint16_t *mem, long pc)
mem[a] = b;
return pc + 1;
}
+ case OP_RED:
+ push(getchar());
+ return pc + 1;
case OP_WRT:
putchar(pop());
return pc + 1;
case OP_ADD:
push(pop() + pop());
return pc + 1;
+ case OP_SUB: {
+ const uint16_t b = pop();
+ const uint16_t a = pop();
+ push(a - b);
+ return pc + 1;
+ }
case OP_MUL:
push(pop() * pop());
return pc + 1;
+ case OP_DIV: {
+ const uint16_t b = pop();
+ const uint16_t a = pop();
+ push(a / b);
+ return pc + 1;
+ }
case OP_AND:
push(pop() & pop());
return pc + 1;
@@ -147,6 +194,20 @@ exec_op(uint16_t *mem, long pc)
case OP_XOR:
push(pop() ^ pop());
return pc + 1;
+ case OP_LSF: {
+ const uint16_t shift = pop();
+ const uint16_t a = pop();
+ push(a << shift);
+ return pc + 1;
+ }
+ case OP_RSF: {
+ const uint16_t shift = pop();
+ const uint16_t a = pop();
+ push(a >> shift);
+ return pc + 1;
+ }
+ case OP_SLP:
+ return pc + 1;
case OP_INC:
push(pop() + 1);
return pc + 1;