From 2cf40a429379c90c3bde06bf2ce0f4044b560045 Mon Sep 17 00:00:00 2001 From: neauoire Date: Mon, 1 Feb 2021 20:21:27 -0800 Subject: [PATCH] Started implementing errors --- README.md | 29 ++++++----- examples/cond.usm | 18 +++---- examples/core.usm | 2 +- examples/jump.usm | 10 ++-- examples/rstack.usm | 18 ------- examples/subroutines.usm | 10 ++-- uxn.c | 53 +++++++++++--------- uxnasm.c | 102 ++++++++++++++++++++++----------------- 8 files changed, 124 insertions(+), 118 deletions(-) delete mode 100644 examples/rstack.usm diff --git a/README.md b/README.md index 7e007a2..416198d 100644 --- a/README.md +++ b/README.md @@ -17,20 +17,20 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn ``` < conditionals > -+03 +02 ADD -+05 EQU +0302 ADD +05 EQU -.there JMQ +.there JMQ :here - < when not equal > - +ee - BRK + < when not equal > + ee + BRK :there - < when is equal > - +ff - BRK + < when is equal > + ff + BRK ``` ## Mission @@ -44,10 +44,6 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn - Print word to stdout - Draw pixel to screen - Detect mouse click -- 16 bits addressing -- jumping to subroutine should be relative -- Implement addressing -- Implement 16 bits operations - Jumps should be relative - Catch overflow/underflow - Audo-detect literals length. @@ -55,6 +51,13 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn - Build PPU - Interrupts +### 16 Bit Missions + +- 16 bits addressing +- jumping to subroutine should be relative +- Implement addressing +- Implement 16 bits operations + ## Refs https://code.9front.org/hg/plan9front/file/a7f9946e238f/sys/src/games/nes/cpu.c diff --git a/examples/cond.usm b/examples/cond.usm index c8cd6de..e5efd74 100644 --- a/examples/cond.usm +++ b/examples/cond.usm @@ -1,16 +1,16 @@ < conditionals > -+03 +02 ADD -+05 EQU +0302 ADD +05 EQU -.there JMQ +.there JMQ :here - < when not equal > - +ee - BRK + < when not equal > + ee + BRK :there - < when is equal > - +ff - BRK + < when is equal > + ff + BRK diff --git a/examples/core.usm b/examples/core.usm index 3b9ccf5..9626573 100644 --- a/examples/core.usm +++ b/examples/core.usm @@ -1,4 +1,4 @@ < core > -+12 +34 ADD +01 ADD diff --git a/examples/jump.usm b/examples/jump.usm index e771a27..8d4ff7e 100644 --- a/examples/jump.usm +++ b/examples/jump.usm @@ -1,7 +1,7 @@ -< conditionals > +< jump > -.end JMP +.end JMP BRK -:end - +ff - BRK +:end + ff + BRK diff --git a/examples/rstack.usm b/examples/rstack.usm deleted file mode 100644 index d7be586..0000000 --- a/examples/rstack.usm +++ /dev/null @@ -1,18 +0,0 @@ -< comment > - -.deep JSR [4 6 7 8 9 ] BRK - -:deep - [2 1 2 ] - .deeper JSR - RTS - -:deeper - [3 3 4 5 ] - .deeperyet JSR - RTS - -:deeperyet - [2 aa bb ] - RTS - \ No newline at end of file diff --git a/examples/subroutines.usm b/examples/subroutines.usm index bee09c1..d003529 100644 --- a/examples/subroutines.usm +++ b/examples/subroutines.usm @@ -2,17 +2,17 @@ :begin .addall JSR ADD ADD - +06 EQU .isequal JSR + 06 EQU .isequal JSR BRK :add1 - +01 RTS + 01 RTS :add2 - +02 RTS + 02 RTS :add3 - +03 RTS + 03 RTS :addall .add1 JSR @@ -21,5 +21,5 @@ RTS :isequal - .addall JSR +ff + .addall JSR ff RTS diff --git a/uxn.c b/uxn.c index 450828c..62129d7 100644 --- a/uxn.c +++ b/uxn.c @@ -19,15 +19,15 @@ WITH REGARD TO THIS SOFTWARE. #define STACK_DEPTH 256 typedef unsigned char Uint8; +typedef unsigned short Uint16; typedef struct { - Uint8 literal; - Uint8 status, counter; - Uint8 memory[STACK_DEPTH]; + Uint8 literal, status; Uint8 mptr, sptr, rsptr; + Uint8 memory[STACK_DEPTH]; Uint8 stack[STACK_DEPTH]; Uint8 rstack[STACK_DEPTH]; - Uint8 address[STACK_DEPTH]; + Uint16 counter; } Computer; Computer cpu; @@ -92,7 +92,7 @@ rspop(void) void op_brk() { setflag(FLAG_HALT, 1); } void op_rts() { cpu.mptr = rspop(); } -void op_lit() { cpu.literal += 1; } +void op_lit() { cpu.literal += cpu.memory[cpu.mptr++]; } void op_drp() { spop(); } void op_dup() { spush(cpu.stack[cpu.sptr - 1]); } void op_swp() { Uint8 b = spop(), a = spop(); spush(b); spush(a); } @@ -100,8 +100,8 @@ void op_ovr() { spush(cpu.stack[cpu.sptr - 2]); } void op_rot() { Uint8 c = spop(),b = spop(),a = spop(); spush(b); spush(c); spush(a); } void op_jmp() { cpu.mptr = spop(); } void op_jsr() { rspush(cpu.mptr); cpu.mptr = spop(); } -void op_jmq() { if(getflag(FLAG_ZERO)){ op_jmp(); } setflag(FLAG_ZERO,0); } -void op_jsq() { if(getflag(FLAG_ZERO)){ op_jsr(); } setflag(FLAG_ZERO,0); } +void op_jmq() { Uint8 a = spop(); if(getflag(FLAG_ZERO)){ cpu.mptr = a; } setflag(FLAG_ZERO,0); } +void op_jsq() { Uint8 a = spop(); if(getflag(FLAG_ZERO)){ rspush(cpu.mptr); cpu.mptr = a; } setflag(FLAG_ZERO,0); } void op_equ() { setflag(FLAG_ZERO, spop() == spop()); } void op_neq() { setflag(FLAG_ZERO, spop() != spop()); } void op_lth() { setflag(FLAG_ZERO, spop() < spop()); } @@ -120,6 +120,13 @@ void (*ops[])(void) = { op_jmp, op_jsr, op_jmq, op_jsq, op_equ, op_neq, op_gth, op_lth, op_and, op_ora, op_rol, op_ror, op_add, op_sub, op_mul, op_div}; +Uint8 opr[][2] = { + {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, {2,1}, {0,0}, {0,0}, {0,0}, + {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, +}; + /* clang-format on */ void @@ -148,38 +155,40 @@ load(FILE *f) fread(cpu.memory, sizeof(cpu.memory), 1, f); } -void +int eval() { Uint8 instr = cpu.memory[cpu.mptr++]; if(cpu.literal > 0) { spush(instr); cpu.literal--; - return; + return 1; } - if(instr < 24) + if(instr < 24) { + if(cpu.sptr < opr[instr][0]) + return error("Stack underflow"); + /* TODO stack overflow */ (*ops[instr])(); + } if(instr > 0x10) setflag(FLAG_ZERO, 0); + cpu.counter++; + return 1; } void run(void) { - int i; - while((cpu.status & FLAG_HALT) == 0) - eval(cpu); + while(!(cpu.status & FLAG_HALT) && eval(cpu)) + ; /* debug */ - printf("ended @ %d | ", cpu.counter); + printf("ended @ %d steps | ", cpu.counter); printf("hf: %x zf: %x cf: %x tf: %x\n", - getflag(FLAG_HALT), - getflag(FLAG_ZERO), - getflag(FLAG_CARRY), - getflag(FLAG_TRAPS)); - printf("\n\n"); - for(i = 0; i < 4; i++) - printf("%d-", (cpu.status & (1 << i)) != 0); - printf("\n\n"); + getflag(FLAG_HALT) != 0, + getflag(FLAG_ZERO) != 0, + getflag(FLAG_CARRY) != 0, + getflag(FLAG_TRAPS) != 0); + printf("\n"); } int diff --git a/uxnasm.c b/uxnasm.c index c58a5a6..8f03df7 100644 --- a/uxnasm.c +++ b/uxnasm.c @@ -29,33 +29,14 @@ typedef struct { int labelslen; Label labels[256]; +/* clang-format off */ + char opcodes[][4] = { - "BRK", - "RTS", - "LIT", - "POP", - "DUP", - "SWP", - "OVR", - "ROT", - /* */ - "JMP", - "JSR", - "JMQ", - "JSQ", - "EQU", - "NEQ", - "LTH", - "GTH", - "---", - "---", - "---", - "---", - "ADD", - "SUB", - "MUL", - "DIV" - /* */}; + "BRK", "RTS", "LIT", "POP", "DUP", "SWP", "OVR", "ROT", + "JMP", "JSR", "JMQ", "JSQ", "EQU", "NEQ", "LTH", "GTH", + "AND", "ORA", "ROL", "ROR", "ADD", "SUB", "MUL", "DIV"}; + +/* clang-format on */ Program p; @@ -81,6 +62,15 @@ scpy(char *src, char *dst, int len) /* string copy */ return dst; } +int +slen(char *s) /* string length */ +{ + int i = 0; + while(s[i] && s[++i]) + ; + return i; +} + char * suca(char *s) /* string to uppercase */ { @@ -120,11 +110,41 @@ shex(char *s) /* string to num */ #pragma mark - Parser void -addprg(Uint8 hex) +pushprg(Uint8 hex) { p.data[p.len++] = hex; } +void +pushlabel(Label *l) +{ + pushprg(0x02); + pushprg(0x01); + pushprg(l->addr); +} + +void +pushliteral(char *w) +{ + int len = slen(w) / 2, value = shex(w); + pushprg(0x02); + pushprg(len); + switch(len) { + case 1: + pushprg(value); + break; + case 2: + pushprg(value >> 8); + pushprg(value); + break; + case 3: + pushprg(value >> 16); + pushprg(value >> 8); + pushprg(value); + break; + } +} + void addlabel(char *id, Uint8 addr) { @@ -164,10 +184,9 @@ int getlength(char *w) { if(findop(w) || scmp(w, "BRK")) return 1; - if(w[0] == '.') return 2; + if(w[0] == '.') return 3; if(w[0] == ':') return 0; - if(w[0] == '+') return 2; - if(w[0] == '-') return 2; + if(sihx(w)) { return slen(w) / 2 + 2; } printf("Unknown length %s\n", w); return 0; } @@ -209,21 +228,14 @@ pass2(FILE *f) if(word[0] == ':') continue; suca(word); if(comment(word, &skip)) continue; - /* literals */ - if(word[0] == '+' || word[0] == '-') - addprg(0x02); - if(word[0] == '+') - addprg(shex(word + 1)); - else if(word[0] == '-') - addprg((Uint8)(-1 * shex(word + 1))); - /* opcodes */ - else if((op = findop(word)) || scmp(word, "BRK")) - addprg(op); - else if((l = findlabel(word + 1))) { - addprg(0x02); - addprg(l->addr); - } else - printf("unknown: %s\n", word); + if((op = findop(word)) || scmp(word, "BRK")) + pushprg(op); + else if((l = findlabel(word + 1))) + pushlabel(l); + else if(sihx(word)) + pushliteral(word); + else + printf("Unknown label: %s\n", word); } }