From 82f7103a55c21b13f898b20e5d1e174e501bc825 Mon Sep 17 00:00:00 2001 From: neauoire Date: Mon, 19 Apr 2021 17:23:30 -0700 Subject: [PATCH] Started migrating to new assembler --- build.sh | 2 +- projects/examples/dev.controller.buttons.usm | 79 +++++++++++++------ src/assembler | Bin 0 -> 25672 bytes src/assembler.c | 70 +++++----------- src/uxn.c | 2 +- src/uxn.h | 1 + 6 files changed, 77 insertions(+), 77 deletions(-) create mode 100755 src/assembler diff --git a/build.sh b/build.sh index ac8a567..ff748ac 100755 --- a/build.sh +++ b/build.sh @@ -32,7 +32,7 @@ else fi echo "Assembling.." -./bin/assembler projects/software/nasu.usm bin/boot.rom +./bin/assembler projects/examples/dev.controller.buttons.usm bin/boot.rom echo "Running.." if [ "${2}" = '--cli' ]; diff --git a/projects/examples/dev.controller.buttons.usm b/projects/examples/dev.controller.buttons.usm index e5bbcae..bf48fb1 100644 --- a/projects/examples/dev.controller.buttons.usm +++ b/projects/examples/dev.controller.buttons.usm @@ -6,60 +6,87 @@ ( variables ) -;slime { color 1 } +@slime [ + &color 00 + &end +] ( devices ) -|0100 ;System { vector 2 pad 6 r 2 g 2 b 2 } -|0120 ;Screen { vector 2 width 2 height 2 pad 2 x 2 y 2 addr 2 color 1 } -|0140 ;Controller { vector 2 button 1 key 1 } +|0100 @System [ + &vector 0000 + &pad 0000 + 0000 + 0000 + &r 0000 + &g 0000 + &b 0000 + &end +] +|0120 @Screen [ + &vector 0000 + &width 0000 + &height 0000 + &pad 0000 + &x 0000 + &y 0000 + &addr 0000 + &color 00 + &end +] +|0140 @Controller [ + &vector 0000 + &button 00 + &key 00 + &end +] |0200 - ( theme ) #0daf =System.r #02ff =System.g #035f =System.b - ( vectors ) ,FRAME =Screen.vector + ( theme ) #0daf =System/r #02ff =System/g #035f =System/b + ( vectors ) ,on-frame =Screen/vector ( set origin ) - ~Screen.width 2/ =Screen.x - ~Screen.height 2/ =Screen.y - ,default_icn =Screen.addr - #31 =Screen.color - #2a =slime + ~Screen/width 2/ =Screen/x + ~Screen/height 2/ =Screen/y + ,default_icn =Screen/addr + #31 =Screen/color + #2a =slime/color BRK -@FRAME +@on-frame - #2a =slime - ,default_icn =Screen.addr + #2a =slime/color + ,default_icn =Screen/addr ( hold ctrl key to change slime color ) - ~Controller.button #0f AND - DUP #01 NEQ ^$no-ctrl JNZ #25 =slime $no-ctrl - DUP #02 NEQ ^$no-alt JNZ #2f =slime $no-alt + ~Controller/button #0f AND + DUP #01 NEQ ^$no-ctrl JNZ #25 =slime/color $no-ctrl + DUP #02 NEQ ^$no-alt JNZ #2f =slime/color $no-alt POP - ( clear ) #30 =Screen.color + ( clear ) #30 =Screen/color ( detect movement ) - ~Controller.button #f0 AND + ~Controller/button #f0 AND DUP #04 SFT #01 AND #01 NEQ ^$no-up JNZ - ( move ) ~Screen.y -- =Screen.y ,up_icn =Screen.addr $no-up + ( move ) ~Screen/y -- =Screen/y ,up_icn =Screen/addr $no-up DUP #05 SFT #01 AND #01 NEQ ^$no-down JNZ - ( move ) ~Screen.y ++ =Screen.y ,down_icn =Screen.addr $no-down + ( move ) ~Screen/y ++ =Screen/y ,down_icn =Screen/addr $no-down DUP #06 SFT #01 AND #01 NEQ ^$no-left JNZ - ( move ) ~Screen.x -- =Screen.x ,left_icn =Screen.addr $no-left + ( move ) ~Screen/x -- =Screen/x ,left_icn =Screen/addr $no-left DUP #07 SFT #01 AND #01 NEQ ^$no-right JNZ - ( move ) ~Screen.x ++ =Screen.x ,right_icn =Screen.addr $no-right + ( move ) ~Screen/x ++ =Screen/x ,right_icn =Screen/addr $no-right POP ( draw face ) - #31 =Screen.color + #31 =Screen/color ( draw slime ) - ,slime_icn =Screen.addr - ~slime =Screen.color + ,slime_icn =Screen/addr + ~slime/color =Screen/color BRK diff --git a/src/assembler b/src/assembler new file mode 100755 index 0000000000000000000000000000000000000000..765b6973fc1e00295f097a4fc52ce029794da98b GIT binary patch literal 25672 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[0].size; - param = s + scin(s, '.') + 1; - for(i = 0; i < l->maps; ++i) - if(scmp(l->map[i].name, param, 64)) - return l->map[i].size; - printf("!!! Warning %s.%s\n", l->name, param); - return 0; -} - Uint8 findopcode(char *s) { @@ -175,7 +158,7 @@ char * sublabel(char *src, char *scope, char *name) { scpy(scope, src, 64); - scpy("-", src + slen(src), 64); + scpy("/", src + slen(src), 64); scpy(name, src + slen(src), 64); return src; } @@ -225,6 +208,13 @@ makelabel(char *name, Uint16 addr) return error("Label name is hex number", name); if(findopcode(name)) return error("Label name is invalid", name); + /* set length of last label */ + if(p.llen) { + l = &p.labels[p.llen - 1]; + l->len = addr - l->addr; + printf(" Set length of #%d \n", l->len); + } + /* make new label */ l = &p.labels[p.llen++]; l->addr = addr; l->refs = 0; @@ -233,25 +223,6 @@ makelabel(char *name, Uint16 addr) return 1; } -int -makevariable(char *name, Uint16 *addr, FILE *f) -{ - Label *l; - char word[64]; - if(!makelabel(name, *addr)) - return error("Could not create variable", name); - l = findlabel(name); - while(fscanf(f, "%s", word)) { - if(word[0] == '{') continue; - if(word[0] == '}') break; - scpy(word, l->map[l->maps].name, 64); - fscanf(f, "%02x", &l->map[l->maps].size); - *addr += l->map[l->maps].size; - l->len += l->map[l->maps++].size; - } - return 1; -} - int skipblock(char *w, int *cap, char a, char b) { @@ -303,25 +274,25 @@ parsetoken(char *w) pushbyte((Sint8)(l->addr - p.ptr - 3), 1); return ++l->refs; } else if(w[0] == '=' && (l = findlabel(w + 1))) { - if(!findlabellen(w + 1) || findlabellen(w + 1) > 2) + if(!l->len || l->len > 2) return error("Invalid store helper", w); if(findlabeladdr(w + 1) < 0x0100) { pushbyte(findlabeladdr(w + 1), 1); - pushbyte(findopcode(findlabellen(w + 1) == 2 ? "STR" : "POK"), 0); + pushbyte(findopcode(l->len == 2 ? "STR" : "POK"), 0); } else { pushshort(findlabeladdr(w + 1), 1); - pushbyte(findopcode(findlabellen(w + 1) == 2 ? "STR2" : "POK2"), 0); + pushbyte(findopcode(l->len == 2 ? "STR2" : "POK2"), 0); } return ++l->refs; } else if(w[0] == '~' && (l = findlabel(w + 1))) { - if(!findlabellen(w + 1) || findlabellen(w + 1) > 2) + if(!l->len || l->len > 2) return error("Invalid load helper", w); if(findlabeladdr(w + 1) < 0x0100) { pushbyte(findlabeladdr(w + 1), 1); - pushbyte(findopcode(findlabellen(w + 1) == 2 ? "LDR" : "PEK"), 0); + pushbyte(findopcode(l->len == 2 ? "LDR" : "PEK"), 0); } else { pushshort(findlabeladdr(w + 1), 1); - pushbyte(findopcode(findlabellen(w + 1) == 2 ? "LDR2" : "PEK2"), 0); + pushbyte(findopcode(l->len == 2 ? "LDR2" : "PEK2"), 0); } return ++l->refs; } else if(w[0] == '.' && (l = findlabel(w + 1))) { @@ -363,7 +334,10 @@ pass1(FILE *f) printf("Pass 1\n"); while(fscanf(f, "%s", w) == 1) { if(skipblock(w, &ccmnt, '(', ')')) continue; - if(skipblock(w, &cbits, '[', ']')) { + if(w[0] == '&') { + if(!makelabel(sublabel(subw, scope, w + 1), addr)) + return error("Pass1 failed", w); + } else if(skipblock(w, &cbits, '[', ']')) { if(w[0] == '[' || w[0] == ']') continue; if(slen(w) == 4 && sihx(w)) @@ -383,9 +357,6 @@ pass1(FILE *f) } else if(w[0] == '$') { if(!makelabel(sublabel(subw, scope, w + 1), addr)) return error("Pass1 failed", w); - } else if(w[0] == ';') { - if(!makevariable(w + 1, &addr, f)) - return error("Pass1 failed", w); } else if(w[0] == '|') { if(shex(w + 1) < addr) return error("Memory Overwrite", w); @@ -406,6 +377,7 @@ pass2(FILE *f) while(fscanf(f, "%s", w) == 1) { if(w[0] == '$') continue; if(w[0] == '%') continue; + if(w[0] == '&') continue; if(skipblock(w, &ccmnt, '(', ')')) continue; if(skipblock(w, &ctemplate, '{', '}')) continue; if(w[0] == ';') { @@ -440,7 +412,7 @@ void cleanup(char *filename) { int i; - printf("Assembled %s(%0.2fkb), %d labels, %d macros.\n\n", filename, (p.ptr - OFFSET) / 1000.0, p.llen, p.mlen); + printf("Assembled %s(%0.2fkb), %d labels, %d macros.\n\n", filename, p.ptr / 1000.0, p.llen, p.mlen); for(i = 0; i < p.llen; ++i) if(!p.labels[i].refs) printf("--- Unused label: %s\n", p.labels[i].name); @@ -459,7 +431,7 @@ main(int argc, char *argv[]) return !error("Open", "Failed"); if(!pass1(f) || !pass2(f)) return !error("Assembly", "Failed"); - fwrite(p.data + OFFSET, p.ptr - OFFSET, 1, fopen(argv[2], "wb")); + fwrite(p.data, p.ptr, 1, fopen(argv[2], "wb")); fclose(f); cleanup(argv[2]); return 0; diff --git a/src/uxn.c b/src/uxn.c index fd7288d..077b91f 100644 --- a/src/uxn.c +++ b/src/uxn.c @@ -166,7 +166,7 @@ loaduxn(Uxn *u, char *filepath) FILE *f; if(!(f = fopen(filepath, "rb"))) return haltuxn(u, "Missing input rom.", 0); - fread(u->ram.dat + PAGE_PROGRAM, sizeof(u->ram.dat) - PAGE_PROGRAM, 1, f); + fread(u->ram.dat + LOAD_OFFSET, sizeof(u->ram.dat) - LOAD_OFFSET, 1, f); printf("Uxn loaded[%s].\n", filepath); return 1; } diff --git a/src/uxn.h b/src/uxn.h index 290dda0..49187b2 100644 --- a/src/uxn.h +++ b/src/uxn.h @@ -18,6 +18,7 @@ typedef signed short Sint16; #define PAGE_DEVICE 0x0100 #define PAGE_PROGRAM 0x0200 +#define LOAD_OFFSET 0x0000 typedef struct { Uint8 ptr, error;