From bb465e00c234c9f73f5ad18e2a10dd0709702737 Mon Sep 17 00:00:00 2001 From: kdx Date: Thu, 13 Apr 2023 23:56:16 +0200 Subject: support entire spec --- spec.md | 12 ++++++------ src/orgaemu.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 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; -- cgit v1.2.3