From 7af20dd1b14134f355e89f64f7e269c137f6f592 Mon Sep 17 00:00:00 2001 From: kdx Date: Thu, 13 Apr 2023 13:54:19 +0200 Subject: execute minimal bullshit --- .gitignore | 1 + compile_flags.txt | 3 ++ samples/minimal.orgaasm | 13 +++++++ src/drain.h | 29 +++++++++++++++ src/ops.h | 69 ++++++++++++++++++++++++++++++++++ src/orgaasm.c | 37 ++----------------- src/orgaemu.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 216 insertions(+), 34 deletions(-) create mode 100644 compile_flags.txt create mode 100644 samples/minimal.orgaasm create mode 100644 src/drain.h create mode 100644 src/ops.h diff --git a/.gitignore b/.gitignore index dee9757..ba302ed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /orgaasm /orgaemu +/*.rom diff --git a/compile_flags.txt b/compile_flags.txt new file mode 100644 index 0000000..c376403 --- /dev/null +++ b/compile_flags.txt @@ -0,0 +1,3 @@ +-Wall +-Wextra +-std=c99 diff --git a/samples/minimal.orgaasm b/samples/minimal.orgaasm new file mode 100644 index 0000000..5ae1d7b --- /dev/null +++ b/samples/minimal.orgaasm @@ -0,0 +1,13 @@ +LIT 0068 WRT ( h ) +LIT 0065 WRT ( e ) +LIT 006c WRT ( l ) +LIT 006c WRT ( l ) +LIT 006f WRT ( o ) +LIT 0020 WRT ( ) +LIT 0077 WRT ( w ) +LIT 006f WRT ( o ) +LIT 0072 WRT ( r ) +LIT 006c WRT ( l ) +LIT 0064 WRT ( d ) +LIT 000a WRT ( \n ) +RET diff --git a/src/drain.h b/src/drain.h new file mode 100644 index 0000000..d0f1111 --- /dev/null +++ b/src/drain.h @@ -0,0 +1,29 @@ +#pragma once +#include +#include + +static char * +drain(FILE *fp, long *size) +{ + if (fseek(fp, 0, SEEK_END) < 0) { + perror("drain:SEEK_END"); + return NULL; + } + *size = ftell(fp); + if (fseek(fp, 0, SEEK_SET) < 0) { + perror("drain:SEEK_SET"); + return NULL; + } + char *const s = malloc(*size + 1); + if (s == NULL) { + perror("drain:malloc"); + return NULL; + } + if ((long)fread(s, 1, *size, fp) != *size) { + perror("drain:fread"); + free(s); + return NULL; + } + s[*size] = '\0'; + return s; +} diff --git a/src/ops.h b/src/ops.h new file mode 100644 index 0000000..2ad2285 --- /dev/null +++ b/src/ops.h @@ -0,0 +1,69 @@ +#pragma once + +enum { + OP_NOP, + OP_LIT, + OP_POP, + OP_NIP, + OP_SWP, + OP_ROT, + OP_DUP, + OP_OVR, + OP_EQU, + OP_NEQ, + OP_GTH, + OP_LTH, + OP_JEZ, + OP_JNZ, + OP_JMP, + OP_JRT, + OP_RET, + OP_LDA, + OP_STA, + OP_RED, + OP_WRT, + OP_ADD, + OP_SUB, + OP_MUL, + OP_DIV, + OP_AND, + OP_ORA, + OP_XOR, + OP_LSF, + OP_RSF, + OP_SLP, +}; + +static const char ops[][4] = { + [OP_NOP] = "NOP", + [OP_LIT] = "LIT", + [OP_POP] = "POP", + [OP_NIP] = "NIP", + [OP_SWP] = "SWP", + [OP_ROT] = "ROT", + [OP_DUP] = "DUP", + [OP_OVR] = "OVR", + [OP_EQU] = "EQU", + [OP_NEQ] = "NEQ", + [OP_GTH] = "GTH", + [OP_LTH] = "LTH", + [OP_JEZ] = "JEZ", + [OP_JNZ] = "JNZ", + [OP_JMP] = "JMP", + [OP_JRT] = "JRT", + [OP_RET] = "RET", + [OP_LDA] = "LDA", + [OP_STA] = "STA", + [OP_RED] = "RED", + [OP_WRT] = "WRT", + [OP_ADD] = "ADD", + [OP_SUB] = "SUB", + [OP_MUL] = "MUL", + [OP_DIV] = "DIV", + [OP_AND] = "AND", + [OP_ORA] = "ORA", + [OP_XOR] = "XOR", + [OP_LSF] = "LSF", + [OP_RSF] = "RSF", + [OP_SLP] = "SLP", +}; diff --git a/src/orgaasm.c b/src/orgaasm.c index 8e1aa3f..d48ad94 100644 --- a/src/orgaasm.c +++ b/src/orgaasm.c @@ -1,3 +1,5 @@ +#include "ops.h" +#include "drain.h" #include #include #include @@ -10,12 +12,6 @@ struct Label { Label *next; }; -static const char ops[][4] = { - "NOP", "LIT", "POP", "NIP", "SWP", "ROT", "DUP", "OVR", "EQU", "NEQ", - "GTH", "LTH", "JEZ", "JNZ", "JMP", "JRT", "RET", "LDA", "STA", "RED", - "WRT", "ADD", "SUB", "MUL", "DIV", "AND", "ORA", "XOR", "LSF", "RSF", - "SLP" -}; static const int hextable[256] = { ['0'] = 0x0, ['1'] = 0x1, ['2'] = 0x2, ['3'] = 0x3, ['4'] = 0x4, ['5'] = 0x5, ['6'] = 0x6, ['7'] = 0x7, ['8'] = 0x8, ['9'] = 0x9, @@ -194,32 +190,6 @@ second_pass(char *s) } } -static char * -drain(FILE *fp) -{ - if (fseek(fp, 0, SEEK_END) < 0) { - perror("drain:SEEK_END"); - return NULL; - } - const long size = ftell(fp); - if (fseek(fp, 0, SEEK_SET) < 0) { - perror("drain:SEEK_SET"); - return NULL; - } - char *const data = malloc(size + 1); - if (data == NULL) { - perror("drain:malloc"); - return NULL; - } - if ((long)fread(data, 1, size, fp) != size) { - perror("drain:fread"); - free(data); - return NULL; - } - data[size] = '\0'; - return data; -} - int main(int argc, char **argv) { @@ -235,7 +205,8 @@ main(int argc, char **argv) perror(argv[1]); return fail(); } - data = drain(fp); + long size; + data = drain(fp, &size); fclose(fp); if (data == NULL) return fail(); diff --git a/src/orgaemu.c b/src/orgaemu.c index 00c30cf..be53a22 100644 --- a/src/orgaemu.c +++ b/src/orgaemu.c @@ -1,8 +1,104 @@ +#include "drain.h" +#include "ops.h" #include +#include + +#define MEM_SIZE 0xffff + +static uint16_t *stack = NULL; +static size_t stack_ptr = 0; + +static uint16_t +get_short(const unsigned char *s) +{ + return s[0] | (s[1] * 0x0100); +} + +static void +push(uint16_t v) +{ + stack[stack_ptr] = v; + stack_ptr += 1; + if (stack_ptr >= MEM_SIZE) { + fprintf(stderr, "stack overflow\n"); + return; + } +} + +static uint16_t +pop(void) +{ + if (stack_ptr == 0) { + fprintf(stderr, "stack underflow\n"); + return 0; + } + stack_ptr -= 1; + return stack[stack_ptr]; +} + +static void +exec_data(uint16_t *mem) +{ + for (long pc = 0; pc < MEM_SIZE; pc++) { + switch (mem[pc]) { + case OP_NOP: + break; + case OP_LIT: + push(mem[pc + 1]); + pc += 1; + break; + case OP_WRT: + putchar(pop()); + break; + case OP_RET: + return; + default: + fprintf(stderr, "unhandled opcode %04x\n", mem[pc]); + return; + } + } +} int main(int argc, char **argv) { - (void)argc, (void)argv; + if (argc != 2) { + fprintf(stderr, "usage: %s \n", argv[0]); + return 1; + } + + FILE *file = fopen(argv[1], "rb"); + if (file == NULL) { + perror(argv[1]); + return 1; + } + + long size; + unsigned char *const data = (unsigned char*)drain(file, &size); + fclose(file); + if (data == NULL) + return 1; + + uint16_t *mem = calloc(MEM_SIZE, sizeof(uint16_t)); + if (mem == NULL) { + perror("main:calloc"); + free(data); + return 1; + } + + for (long i = 0; i < size; i += 2) + mem[i / 2] = get_short(data + i); + free(data); + + stack = calloc(MEM_SIZE, sizeof(uint16_t)); + if (stack == NULL) { + perror("main:calloc"); + free(mem); + return 1; + } + + exec_data(mem); + free(mem); + free(stack); return 0; } -- cgit v1.2.3