uxn

Varvara Ordinator, written in ANSI C(SDL2)
git clone https://git.eamoncaddigan.net/uxn.git
Log | Files | Refs | README | LICENSE

commit 099d1f08455ceffce3512e6a7655c0d3df70ffe4
parent 72d9c98f358c54d3d082ef61761ba768ba8a68c3
Author: neauoire <aliceffekt@gmail.com>
Date:   Fri, 29 Jan 2021 21:56:19 -0800

*

Diffstat:
M.clang-format | 2++
Mbuild.sh | 7++++---
Aexample.usm | 2++
Dprogram.usm | 2--
Muxn.c | 114+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
Muxnasm.c | 55+++++++++++++++++++++++++++++++++++++------------------
6 files changed, 125 insertions(+), 57 deletions(-)

diff --git a/.clang-format b/.clang-format @@ -1,7 +1,9 @@ AlignAfterOpenBracket: DontAlign AlignEscapedNewlines: DontAlign +AlignOperands: DontAlign AllowShortBlocksOnASingleLine: Empty AllowShortCaseLabelsOnASingleLine: true +AllowShortEnumsOnASingleLine: true AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: TopLevel diff --git a/build.sh b/build.sh @@ -7,10 +7,11 @@ clang-format -i uxn.c # remove old rm -f ./uxnasm rm -f ./uxn +rm -f ./boot.rom # debug(slow) cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxnasm.c -o uxnasm -# cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxn.c -o uxn +cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxn.c -o uxn # build(fast) # cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn @@ -19,5 +20,5 @@ cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werr # echo "Size: $(du -sk ./uxn)" # run -./uxnasm program.usm program.rom -# ./uxn program.rom +./uxnasm example.usm boot.rom +./uxn boot.rom diff --git a/example.usm b/example.usm @@ -0,0 +1 @@ +{ 25 26 27 28 } SWP POP DUP BRK +\ No newline at end of file diff --git a/program.usm b/program.usm @@ -1 +0,0 @@ -LIT 25 26 LIT DUP ADD BRK -\ No newline at end of file diff --git a/uxn.c b/uxn.c @@ -11,20 +11,38 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE. */ +#define FLAG_HALT 0x01 +#define FLAG_ZERO 0x02 +#define FLAG_CARRY 0x04 +#define FLAG_TRAPS 0x08 + #define STACK_DEPTH 256 -#define ECHO 1 typedef unsigned char Uint8; -typedef unsigned char Uint16; typedef struct { - + Uint8 literal; + Uint8 status, counter; + Uint8 memory[STACK_DEPTH]; + Uint8 mptr, sptr; + Uint8 stack[STACK_DEPTH]; + Uint8 address[STACK_DEPTH]; } Computer; -Uint8 sptr; -Uint8 stack[STACK_DEPTH]; -Uint8 address[STACK_DEPTH]; -Uint16 memory[STACK_DEPTH]; +void +setflag(Computer *cpu, char flag, int b) +{ + if(b) + cpu->status |= flag; + else + cpu->status &= (~flag); +} + +int +getflag(Computer *cpu, char flag) +{ + return cpu->status & flag; +} void echo(Uint8 *s, Uint8 len, char *name) @@ -34,51 +52,79 @@ echo(Uint8 *s, Uint8 len, char *name) for(i = 0; i < len; ++i) { if(i % 16 == 0) printf("\n"); - if(sptr == i) - printf("[%02x]", s[i]); - else - printf(" %02x ", s[i]); + printf("%02x ", s[i]); } - printf("\n"); + printf("\n\n"); } void -op_push(Uint8 *s, Uint8 v) +op_push(Uint8 *s, Uint8 *ptr, Uint8 v) { - s[sptr++] = v; + s[*ptr] = v; + (*ptr) += 1; } void -op_pop(Uint8 *s) +op_pop(Uint8 *s, Uint8 *ptr) { - s[sptr--] = 0x00; + s[*ptr--] = 0x00; } void reset(Computer *cpu) { + int i; + cpu->status = 0x00; + cpu->counter = 0x00; + cpu->mptr = 0x00; + cpu->sptr = 0x00; + cpu->literal = 0x00; + for(i = 0; i < 256; i++) + cpu->stack[i] = 0x00; } int -disk(Computer *cpu, FILE *f) +error(char *name) { - int i; - unsigned short buffer[256]; - reset(cpu); - if(!fread(buffer, sizeof(buffer), 1, f)) - return 0; - - for(i = 0; i < 128; i++) { - cpu->memory[i * 2] |= (buffer[i] >> 8) & 0xFF; - cpu->memory[i * 2 + 1] |= buffer[i] & 0xFF; - } + printf("Error: %s\n", name); + return 0; +} + +void +load(Computer *cpu, FILE *f) +{ + fread(cpu->memory, sizeof(cpu->memory), 1, f); +} - return 1; +void +eval(Computer *cpu) +{ + Uint8 instr = cpu->memory[cpu->mptr++]; + + if(cpu->literal > 0) { + printf("push: %02x[%d](%d)\n", instr, cpu->literal, cpu->sptr); + op_push(cpu->stack, &cpu->sptr, instr); + cpu->literal--; + return; + } + switch(instr) { + case 0x0: setflag(cpu, FLAG_HALT, 1); break; + case 0x1: cpu->literal += 4; break; + default: printf("Unknown instruction: #%02x\n", instr); + } } void -run(Computer *cpu, int debug) +run(Computer *cpu) { + int i; + while((cpu->status & FLAG_HALT) == 0) + eval(cpu); + /* debug */ + printf("ended @ %d | ", cpu->counter); + for(i = 0; i < 4; i++) + printf("%d-", (cpu->status & (1 << i)) != 0); + printf("\n\n"); } int @@ -90,11 +136,11 @@ main(int argc, char *argv[]) return error("No input."); if(!(f = fopen(argv[1], "rb"))) return error("Missing input."); - if(!disk(&cpu, f)) - return error("Unreadable input."); - run(&cpu, ECHO); + reset(&cpu); + load(&cpu, f); + run(&cpu); /* print result */ - echo(stack, 0x40, "stack"); - echo(memory, 0x40, "memory"); + echo(cpu.stack, 0x40, "stack"); + echo(cpu.memory, 0x40, "memory"); return 0; } diff --git a/uxnasm.c b/uxnasm.c @@ -20,7 +20,39 @@ typedef struct { Uint8 data[PRGLEN]; } Program; -char opcodes[][4] = {"BRK", "LIT", "DUP", "DRP", "SWP", "SLP", "PSH", "POP", "JMP", "JSR", "RST", "BEQ", "EQU", "NEQ", "LTH", "GTH"}; +char opcodes[][4] = { + "BRK", + "LIT", + "DUP", + "DRP", + "SWP", + "SLP", + "PSH", + "POP", /* --- */ + "JMP", + "JSR", + "RST", + "BEQ", + "EQU", + "NEQ", + "LTH", + "GTH", /* --- */ + "---", + "---", + "---", + "---", + "---", + "---", + "---", + "---", /* --- */ + "---", + "---", + "---", + "---", + "---", + "---", + "---", + "---"}; Program p; @@ -65,6 +97,8 @@ Uint8 getopcode(char *s) { int i; + if(s[0] == '{') /* TODO catch closing */ + return 0x01; for(i = 0; i < 16; ++i) if(scmp(opcodes[i], suca(s))) return i; @@ -72,27 +106,13 @@ getopcode(char *s) } void -echo(Uint8 *s, Uint8 len, Uint8 ptr, char *name) -{ - int i; - printf("%s\n", name); - for(i = 0; i < len; ++i) { - if(i % 16 == 0) - printf("\n"); - if(ptr == i) - printf("[%02x]", s[i]); - else - printf(" %02x ", s[i]); - } - printf("\n"); -} - -void pass1(FILE *f) { char word[64]; while(fscanf(f, "%s", word) == 1) { int op = getopcode(word); + if(word[0] == '}') + continue; if(op == 0xff) op = shex(word); p.data[p.ptr++] = op; @@ -117,6 +137,5 @@ main(int argc, char *argv[]) pass1(f); fwrite(p.data, sizeof(p.data), 1, fopen(argv[2], "wb")); fclose(f); - echo(p.data, 0x40, 0, "program"); return 0; }