diff --git a/.clang-format b/.clang-format index 67c9a1b..0ad3042 100644 --- 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 index ddb3cad..7fd17c9 100755 --- 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 new file mode 100644 index 0000000..a600afd --- /dev/null +++ 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 deleted file mode 100644 index cd4b5dd..0000000 --- a/program.usm +++ /dev/null @@ -1 +0,0 @@ -LIT 25 26 LIT DUP ADD BRK \ No newline at end of file diff --git a/uxn.c b/uxn.c index 6c88ec0..2c13b42 100644 --- 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; - } - - return 1; + printf("Error: %s\n", name); + return 0; } void -run(Computer *cpu, int debug) +load(Computer *cpu, FILE *f) { + fread(cpu->memory, sizeof(cpu->memory), 1, f); +} + +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 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 index 37d3232..a94fd54 100644 --- 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,34 +97,22 @@ 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; return 0xff; } -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; }