From 6ac543f312ae222ca445b90db32a1d0f8c88f8ad Mon Sep 17 00:00:00 2001 From: neauoire Date: Thu, 4 Feb 2021 12:22:08 -0800 Subject: [PATCH] Starting 16bits mode --- README.md | 24 ++++- examples/core.usm | 14 +-- examples/vectors.usm | 11 ++ uxn.c | 23 ++++- uxnasm.c | 233 ++++++++++++++++++++----------------------- 5 files changed, 162 insertions(+), 143 deletions(-) create mode 100644 examples/vectors.usm diff --git a/README.md b/README.md index be3a33a..4e0a482 100644 --- a/README.md +++ b/README.md @@ -10,13 +10,27 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn ## Assembly Syntax -- `;variable`, a named address(zero-page) -- `:label`, a named address -- `.pointer`, a pointer to a label -- `@0010`, a position in the program +### Write + +- `;variable`, set a name to address on the zero-page +- `:label`, set a name to an address + +### Read + +- `,literal`, get a literal pointer +- `.pointer`, get a raw pointer + +### Special + +- `@0010`, move to position in the program +- `( comment )` ``` -< conditionals > +( comment ) + +;variable1 +;variable2 +;variable3 .there ( 0a 05 GTH ) JMC diff --git a/examples/core.usm b/examples/core.usm index 0ee657d..141991b 100644 --- a/examples/core.usm +++ b/examples/core.usm @@ -1,13 +1,3 @@ -< conditionals > +( comment ) -.there ( 0a 05 GTH ) JMC - -:here - < when not equal > - ee - BRK - -:there - < when is equal > - ff - BRK +,abcd ,ef STR \ No newline at end of file diff --git a/examples/vectors.usm b/examples/vectors.usm new file mode 100644 index 0000000..182d2a2 --- /dev/null +++ b/examples/vectors.usm @@ -0,0 +1,11 @@ +< vectors > + +:RESET BRK +:FRAME BRK +:ERROR BRK + +@FFFA < vectors > + +.RESET +.FRAME +.ERROR \ No newline at end of file diff --git a/uxn.c b/uxn.c index 366a8ce..9b47f13 100644 --- a/uxn.c +++ b/uxn.c @@ -74,6 +74,13 @@ echo(Stack *s, Uint8 len, char *name) void wspush(Uint8 v) { cpu.wst.dat[cpu.wst.ptr++] = v; } Uint8 wspop(void) { return cpu.wst.dat[--cpu.wst.ptr]; } +Uint16 wspop16(void) { + + Uint8 a = cpu.wst.dat[--cpu.wst.ptr]; + Uint8 b = cpu.wst.dat[--cpu.wst.ptr]; + return a + (b << 8); + +} Uint8 wspeek(void) { return cpu.wst.dat[cpu.wst.ptr - 1]; } void rspush(Uint8 v) { cpu.rst.dat[cpu.rst.ptr++] = v; } Uint8 rspop(void) { return cpu.rst.dat[--cpu.rst.ptr]; } @@ -102,17 +109,27 @@ void op_add() { wspush(wspop() + wspop()); } void op_sub() { wspush(wspop() - wspop()); } void op_mul() { wspush(wspop() * wspop()); } void op_div() { wspush(wspop() / wspop()); } +void op_ldr() { } +void op_str() { + + Uint8 b = wspop(); + Uint16 addr = wspop16(); + printf("store: %02x @ %04x\n", b, addr); +} void (*ops[])(void) = { op_brk, op_rts, op_lit, op_drp, op_dup, op_swp, op_ovr, op_rot, op_jmu, op_jsu, op_jmc, op_jsc, op_equ, op_neq, op_gth, op_lth, - op_and, op_ora, op_rol, op_ror, op_add, op_sub, op_mul, op_div}; + op_and, op_ora, op_rol, op_ror, op_add, op_sub, op_mul, op_div, + op_ldr, op_str, op_brk, op_brk, op_brk, op_brk, op_brk, op_brk +}; Uint8 opr[][2] = { {0,0}, {0,0}, {0,0}, {1,0}, {0,1}, {1,1}, {0,1}, {3,3}, {2,0}, {2,0}, {2,0}, {2,0}, {2,1}, {2,1}, {2,1}, {2,1}, {1,0}, {1,0}, {1,0}, {1,0}, {2,1}, {0,0}, {0,0}, {0,0}, - {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1} + {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, + {3,1}, {3,1} }; /* clang-format on */ @@ -155,7 +172,7 @@ eval() cpu.literal--; return 1; } - if(instr < 24) { + if(instr < 32) { if(cpu.wst.ptr < opr[instr][0]) return error("Stack underflow"); /* TODO stack overflow */ diff --git a/uxnasm.c b/uxnasm.c index f9068e1..5aafa04 100644 --- a/uxnasm.c +++ b/uxnasm.c @@ -11,19 +11,17 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE. */ -#define PRGLEN 256 -#define LABELIDLEN 32 - typedef unsigned char Uint8; +typedef unsigned short Uint16; typedef struct { int ptr; - Uint8 data[PRGLEN]; + Uint8 data[65536]; } Program; typedef struct { - Uint8 addr; - char name[LABELIDLEN]; + Uint16 addr; + char name[64]; } Label; int labelslen; @@ -34,7 +32,9 @@ Label labels[256]; char opcodes[][4] = { "BRK", "RTS", "LIT", "POP", "DUP", "SWP", "OVR", "ROT", "JMU", "JSU", "JMC", "JSC", "EQU", "NEQ", "GTH", "LTH", - "AND", "ORA", "ROL", "ROR", "ADD", "SUB", "MUL", "DIV"}; + "AND", "ORA", "ROL", "ROR", "ADD", "SUB", "MUL", "DIV", + "LDR", "STR", "---", "---", "---", "---", "---", "---" +}; /* clang-format on */ @@ -82,7 +82,7 @@ suca(char *s) /* string to uppercase */ } int -sihx(char *s) +sihx(char *s) /* string is hexadecimal */ { int i = 0; char c; @@ -107,59 +107,68 @@ shex(char *s) /* string to num */ return n; } +int +ismarker(char *w) +{ + return w[0] == '[' || w[0] == ']' || w[0] == '{' || w[0] == '}'; +} + +int +iscomment(char *w, int *skip) +{ + if(w[0] == ')') { + *skip = 0; + return 1; + } + if(w[0] == '(') *skip = 1; + if(*skip) return 1; + return 0; +} + +#pragma mark - I/O + +void +pushbyte(Uint8 b, int lit) +{ + if(lit) { + pushbyte(0x02, 0); + pushbyte(0x01, 0); + } + p.data[p.ptr++] = b; +} + +void +pushshort(Uint16 s, int lit) +{ + if(lit) { + pushbyte(0x02, 0); + pushbyte(0x02, 0); + } + pushbyte((s >> 8) & 0xff, 0); + pushbyte(s & 0xff, 0); +} + #pragma mark - Parser -void -pushprg(Uint8 hex) +Uint8 +findop(char *s) { - p.data[p.ptr++] = hex; + int i; + for(i = 0; i < 32; ++i) + if(scmp(opcodes[i], s)) + return i; + return 0; } 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) +makelabel(char *id, Uint8 addr) { Label *l = &labels[labelslen++]; - scpy(suca(id), l->name, LABELIDLEN); + scpy(suca(id), l->name, 64); l->addr = addr; printf("New label: %s[0x%02x]\n", l->name, l->addr); } -void -addconst(char *id, Uint8 value) -{ - printf("New const: %s[%02x]\n", id, value); -} - Label * findlabel(char *s) { @@ -170,94 +179,72 @@ findlabel(char *s) return NULL; } -Uint8 -findop(char *s) +#pragma mark - Parser + +int +error(char *name, char *id) { - int i; - for(i = 0; i < 24; ++i) - if(scmp(opcodes[i], s)) - return i; + printf("Error: %s - %s\n", name, id); return 0; } int -ismarker(char *w) -{ - return w[0] == '(' || w[0] == ')' || w[0] == '{' || w[0] == '}'; -} - -int -iscomment(char *w, int *skip) -{ - if(w[0] == '>') { - *skip = 0; - return 1; - } - if(w[0] == '<') *skip = 1; - if(*skip) return 1; - return 0; -} - -int -getlength(char *w) -{ - if(findop(w) || scmp(w, "BRK")) return 1; - if(w[0] == '.') return 3; - if(w[0] == ':') return 0; - if(w[0] == ';') return 0; - if(w[0] == '@') return 0; - if(sihx(w)) { return slen(w) / 2 + 2; } - if(ismarker(w)) return 0; - printf("Unknown length %s\n", w); - return 0; -} - -void pass1(FILE *f) { - int skip = 0; - int addr = 0; - int vars = 0; - char word[64]; - while(fscanf(f, "%s", word) == 1) { - if(iscomment(word, &skip)) continue; - if(word[0] == ':') addlabel(word + 1, addr); - if(word[0] == ';') addlabel(word + 1, vars++); - addr += getlength(word); + int skip = 0, addr = 0, vars = 0; + char w[64]; + while(fscanf(f, "%s", w) == 1) { + if(iscomment(w, &skip)) continue; + if(w[0] == ':') makelabel(w + 1, addr); + if(w[0] == ';') makelabel(w + 1, vars++); + /* move addr ptr */ + if(findop(w) || scmp(w, "BRK")) + addr += 1; + else if(w[0] == '@') + addr += 0; + else if(w[0] == ':') + addr += 0; + else if(w[0] == ';') + addr += 0; + else if(w[0] == '.') + addr += 2; + else if(w[0] == ',') + addr += 4; + else if(ismarker(w)) + addr += 0; + else + return error("Unknown label(pass1)", w); } rewind(f); + return 1; } -void +int pass2(FILE *f) { int skip = 0; - char word[64]; - while(fscanf(f, "%s", word) == 1) { + char w[64]; + while(fscanf(f, "%s", w) == 1) { Uint8 op = 0; Label *l; - if(word[0] == ':') continue; - if(word[0] == ';') continue; - suca(word); - if(iscomment(word, &skip) || ismarker(word)) continue; - if(word[0] == '@') - p.ptr = shex(word + 1); - else if((op = findop(word)) || scmp(word, "BRK")) - pushprg(op); - else if((l = findlabel(word + 1))) - pushlabel(l); - else if(sihx(word)) - pushliteral(word); + if(w[0] == ':') continue; + if(w[0] == ';') continue; + suca(w); + if(iscomment(w, &skip) || ismarker(w)) continue; + if(w[0] == '@') + p.ptr = shex(w + 1); + else if((op = findop(w)) || scmp(w, "BRK")) + pushbyte(op, 0); + else if((l = findlabel(w + 1))) + pushshort(l->addr, w[0] == ','); + else if(sihx(w + 1) && slen(w + 1) == 2) + pushbyte(shex(w + 1), w[0] == ','); + else if(sihx(w + 1) && slen(w + 1) == 4) + pushshort(shex(w + 1), w[0] == ','); else - printf("Unknown label: %s\n", word); + return error("Unknown label(pass2)", w); } -} - -int -error(char *name) -{ - printf("Error: %s\n", name); - return 0; + return 1; } int @@ -265,11 +252,11 @@ main(int argc, char *argv[]) { FILE *f; if(argc < 3) - return error("No input."); + return error("Input", "Missing"); if(!(f = fopen(argv[1], "r"))) - return error("Missing input."); - pass1(f); - pass2(f); + return error("Open", "Failed"); + if(!pass1(f) || !pass2(f)) + return error("Assembly", "Failed"); fwrite(p.data, sizeof(p.data), 1, fopen(argv[2], "wb")); fclose(f); return 0;