From 54e5a3fc57b9cfdaf4650486971834fd111b209b Mon Sep 17 00:00:00 2001 From: kdx Date: Thu, 13 Apr 2023 14:22:25 +0200 Subject: easy clap --- samples/helloworld.orgaasm | 2 +- src/orgaasm.c | 4 +- src/orgaemu.c | 109 ++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 101 insertions(+), 14 deletions(-) diff --git a/samples/helloworld.orgaasm b/samples/helloworld.orgaasm index 9401e8f..d968543 100644 --- a/samples/helloworld.orgaasm +++ b/samples/helloworld.orgaasm @@ -10,4 +10,4 @@ RET RET ( "hello world" ) -@hellostr 0068 0065 006c 006c 006f 0020 0077 006f 0072 006c 0064 0000 +@hellostr 0068 0065 006c 006c 006f 0020 0077 006f 0072 006c 0064 000a 0000 diff --git a/src/orgaasm.c b/src/orgaasm.c index d48ad94..cafab0e 100644 --- a/src/orgaasm.c +++ b/src/orgaasm.c @@ -58,7 +58,9 @@ skip_comments(void) static void write_short(uint_least16_t v) { - if (verbose) printf("write: %04x\n", v); + static unsigned int write_n = 0; + if (verbose) printf("write %04x: %04x\n", write_n, v); + write_n += 1; if (fputc(v & 0x00ff, outfile) == EOF || fputc(v / 0x0100, outfile) == EOF) { fprintf(stderr, "fputc failed\n"); diff --git a/src/orgaemu.c b/src/orgaemu.c index be53a22..b824415 100644 --- a/src/orgaemu.c +++ b/src/orgaemu.c @@ -5,8 +5,20 @@ #define MEM_SIZE 0xffff -static uint16_t *stack = NULL; -static size_t stack_ptr = 0; +static uint16_t *mem = NULL, *stack = NULL, *rstack = NULL; +static size_t stack_ptr = 0, rstack_ptr = 0; + +static int +fail(void) +{ + if (mem != NULL) + free(mem); + if (stack != NULL) + free(stack); + if (rstack != NULL) + free(rstack); + return 1; +} static uint16_t get_short(const unsigned char *s) @@ -21,7 +33,7 @@ push(uint16_t v) stack_ptr += 1; if (stack_ptr >= MEM_SIZE) { fprintf(stderr, "stack overflow\n"); - return; + exit(fail()); } } @@ -30,16 +42,38 @@ pop(void) { if (stack_ptr == 0) { fprintf(stderr, "stack underflow\n"); - return 0; + exit(fail()); } stack_ptr -= 1; return stack[stack_ptr]; } + +static void +push_rs(uint16_t v) +{ + rstack[rstack_ptr] = v; + rstack_ptr += 1; + if (rstack_ptr >= MEM_SIZE) { + fprintf(stderr, "return stack overflow\n"); + exit(fail()); + } +} +static uint16_t +pop_rs(void) +{ + if (rstack_ptr == 0) { + fprintf(stderr, "return stack underflow\n"); + exit(fail()); + } + rstack_ptr -= 1; + return rstack[rstack_ptr]; +} + static void exec_data(uint16_t *mem) { - for (long pc = 0; pc < MEM_SIZE; pc++) { + for (long pc = 0; pc < MEM_SIZE;) { switch (mem[pc]) { case OP_NOP: break; @@ -47,15 +81,63 @@ exec_data(uint16_t *mem) push(mem[pc + 1]); pc += 1; break; + case OP_POP: + pop(); + break; + case OP_NIP: { + const uint16_t a = pop(); + pop(); + push(a); + } break; + case OP_SWP: { + const uint16_t a = pop(); + const uint16_t b = pop(); + push(a); + push(b); + } break; + case OP_DUP: { + const uint16_t a = pop(); + push(a); + push(a); + } break; + case OP_ADD: + push(pop() + pop()); + break; case OP_WRT: putchar(pop()); break; + case OP_JNZ: + if (pop() != 0) { + pc = mem[pc + 1]; + continue; + } + pc += 1; + break; + case OP_JRT: + push_rs(pc); + pc = mem[pc + 1]; + continue; case OP_RET: + if (rstack_ptr > 0) { + pc = pop_rs() + 1; + break; + } return; + case OP_LDA: + push(mem[pop()]); + break; + case OP_STA: { + const uint16_t a = pop(); + const uint16_t b = pop(); + mem[a] = b; + } break; default: fprintf(stderr, "unhandled opcode %04x\n", mem[pc]); - return; + if (mem[pc] <= OP_SLP) + fprintf(stderr, "(%s)\n", ops[mem[pc]]); + exit(fail()); } + pc += 1; } } @@ -79,7 +161,7 @@ main(int argc, char **argv) if (data == NULL) return 1; - uint16_t *mem = calloc(MEM_SIZE, sizeof(uint16_t)); + mem = calloc(MEM_SIZE, sizeof(uint16_t)); if (mem == NULL) { perror("main:calloc"); free(data); @@ -93,12 +175,15 @@ main(int argc, char **argv) stack = calloc(MEM_SIZE, sizeof(uint16_t)); if (stack == NULL) { perror("main:calloc"); - free(mem); - return 1; + return fail(); + } + + rstack = calloc(MEM_SIZE, sizeof(uint16_t)); + if (rstack == NULL) { + perror("main:calloc"); + return fail(); } exec_data(mem); - free(mem); - free(stack); - return 0; + return fail(), 0; } -- cgit v1.2.3