diff --git a/projects/examples/dev.controller.buttons.usm b/projects/examples/dev.controller.buttons.usm index bf48fb1..84e7ebd 100644 --- a/projects/examples/dev.controller.buttons.usm +++ b/projects/examples/dev.controller.buttons.usm @@ -18,11 +18,24 @@ &pad 0000 0000 0000 - &r 0000 - &g 0000 - &b 0000 + &r 0daf + &g 02ff + &b 035f &end ] + +|0110 @Console [ + &pad 0000 + 0000 + 0000 + 0000 + &char 00 + &byte 00 + &short 0000 + &string 0000 + &end +] + |0120 @Screen [ &vector 0000 &width 0000 @@ -34,6 +47,7 @@ &color 00 &end ] + |0140 @Controller [ &vector 0000 &button 00 @@ -42,51 +56,64 @@ ] |0200 + + ( theme ) + #0daf ,System/r STR2 + #02ff ,System/g STR2 + #035f ,System/b STR2 - ( theme ) #0daf =System/r #02ff =System/g #035f =System/b - ( vectors ) ,on-frame =Screen/vector + ( vectors ) + ,on-frame ,Screen/vector STR2 ( set origin ) - ~Screen/width 2/ =Screen/x - ~Screen/height 2/ =Screen/y - ,default_icn =Screen/addr - #31 =Screen/color - #2a =slime/color + ,Screen/width LDR2 2/ ,Screen/x STR2 + ,Screen/height LDR2 2/ ,Screen/y STR2 + ,default_icn ,Screen/addr STR2 + #31 ,Screen/color POK2 + #2a ,slime/color POK2 BRK @on-frame - #2a =slime/color - ,default_icn =Screen/addr + #2a ,slime/color POK2 + ,default_icn ,Screen/addr STR2 ( hold ctrl key to change slime color ) - ~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 + ,Controller/button PEK2 #0f AND + DUP #01 NEQ ^&no-ctrl JNZ #25 ,slime/color POK2 &no-ctrl + DUP #02 NEQ ^&no-alt JNZ #2f ,slime/color POK2 &no-alt POP - ( clear ) #30 =Screen/color + ( clear ) #30 ,Screen/color POK2 ( detect movement ) - ~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 - DUP #05 SFT #01 AND #01 NEQ ^$no-down JNZ - ( 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 - DUP #07 SFT #01 AND #01 NEQ ^$no-right JNZ - ( move ) ~Screen/x ++ =Screen/x ,right_icn =Screen/addr $no-right + ,Controller/button PEK2 #f0 AND + DUP #04 SFT #01 AND #01 NEQ ^&no-up JNZ + ( move ) + ,Screen/y LDR2 -- ,Screen/y STR2 + ,up_icn ,Screen/addr STR2 &no-up + DUP #05 SFT #01 AND #01 NEQ ^&no-down JNZ + ( move ) + ,Screen/y LDR2 ++ ,Screen/y STR2 + ,down_icn ,Screen/addr STR2 &no-down + DUP #06 SFT #01 AND #01 NEQ ^&no-left JNZ + ( move ) + ,Screen/x LDR2 -- ,Screen/x STR2 + ,left_icn ,Screen/addr STR2 &no-left + DUP #07 SFT #01 AND #01 NEQ ^&no-right JNZ + ( move ) + ,Screen/x LDR2 ++ ,Screen/x STR2 + ,right_icn ,Screen/addr STR2 &no-right POP ( draw face ) - #31 =Screen/color + #31 ,Screen/color POK2 ( draw slime ) - ,slime_icn =Screen/addr - ~slime/color =Screen/color + ,slime_icn ,Screen/addr STR2 + ,slime/color PEK2 ,Screen/color POK2 BRK diff --git a/src/assembler.c b/src/assembler.c index 0f61b2c..1004c61 100644 --- a/src/assembler.c +++ b/src/assembler.c @@ -13,6 +13,7 @@ WITH REGARD TO THIS SOFTWARE. #define WORDLENMAX 32 #define MACROMAX 64 +#define OFFSET 0x0200 typedef unsigned char Uint8; typedef signed char Sint8; @@ -26,14 +27,8 @@ typedef struct { typedef struct { char name[WORDLENMAX]; - unsigned int size; -} Map; - -typedef struct { - char name[WORDLENMAX]; - Uint8 refs, maps; - Uint16 addr, len; - Map map[16]; + Uint8 refs; + Uint16 addr; } Label; typedef struct { @@ -102,35 +97,15 @@ findmacro(char *name) } Label * -findlabel(char *s) +findlabel(char *name) { - int i, rng = scin(s, '.'); - char name[64]; - scpy(s, name, rng > 0 ? rng + 1 : 64); + int i; for(i = 0; i < p.llen; ++i) if(scmp(p.labels[i].name, name, 64)) return &p.labels[i]; return NULL; } -Uint16 -findlabeladdr(char *s) -{ - int i, o = 0; - char *param; - Label *l = findlabel(s); - if(scin(s, '.') < 1) - return l->addr; - param = s + scin(s, '.') + 1; - for(i = 0; i < l->maps; ++i) { - if(scmp(l->map[i].name, param, 64)) - return l->addr + o; - o += l->map[i].size; - } - printf("!!! Warning %s.%s\n", l->name, param); - return 0; -} - Uint8 findopcode(char *s) { @@ -194,7 +169,7 @@ makemacro(char *name, FILE *f) return error("Word too long", name); scpy(word, m->items[m->len++], 64); } - printf("New macro: %s(%d items)\n", m->name, m->len); + printf("New macro: %s, %d items\n", m->name, m->len); return 1; } @@ -208,13 +183,6 @@ 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; @@ -242,11 +210,9 @@ walktoken(char *w) if(findopcode(w) || scmp(w, "BRK", 4)) return 1; switch(w[0]) { - case '=': return 4 - (findlabel(w + 1) && findlabeladdr(w + 1) < 0x0100); /* POK/STR helper (lit addr(1/2) str) */ - case '~': return 4 - (findlabel(w + 1) && findlabeladdr(w + 1) < 0x0100); /* PEK/LDR helper (lit addr(1/2) ldr) */ - case ',': return 3; /* lit2 addr-hb addr-lb */ - case '.': return 2; /* addr-hb addr-lb */ - case '^': return 2; /* Relative jump: lit addr-offset */ + case ',': return 3; /* lit2 addr-hb addr-lb */ + case '.': return 2; /* addr-hb addr-lb */ + case '^': return 2; /* Relative jump: lit addr-offset */ case '#': return (slen(w + 1) == 4 ? 3 : 2); } if((m = findmacro(w))) { @@ -273,33 +239,11 @@ parsetoken(char *w) } pushbyte((Sint8)(l->addr - p.ptr - 3), 1); return ++l->refs; - } else if(w[0] == '=' && (l = findlabel(w + 1))) { - if(!l->len || l->len > 2) - return error("Invalid store helper", w); - if(findlabeladdr(w + 1) < 0x0100) { - pushbyte(findlabeladdr(w + 1), 1); - pushbyte(findopcode(l->len == 2 ? "STR" : "POK"), 0); - } else { - pushshort(findlabeladdr(w + 1), 1); - pushbyte(findopcode(l->len == 2 ? "STR2" : "POK2"), 0); - } - return ++l->refs; - } else if(w[0] == '~' && (l = findlabel(w + 1))) { - if(!l->len || l->len > 2) - return error("Invalid load helper", w); - if(findlabeladdr(w + 1) < 0x0100) { - pushbyte(findlabeladdr(w + 1), 1); - pushbyte(findopcode(l->len == 2 ? "LDR" : "PEK"), 0); - } else { - pushshort(findlabeladdr(w + 1), 1); - pushbyte(findopcode(l->len == 2 ? "LDR2" : "PEK2"), 0); - } - return ++l->refs; } else if(w[0] == '.' && (l = findlabel(w + 1))) { - pushshort(findlabeladdr(w + 1), 0); + pushshort(l->addr, 0); return ++l->refs; } else if(w[0] == ',' && (l = findlabel(w + 1))) { - pushshort(findlabeladdr(w + 1), 1); + pushshort(l->addr, 1); return ++l->refs; } else if((op = findopcode(w)) || scmp(w, "BRK", 4)) { pushbyte(op, 0); @@ -354,9 +298,6 @@ pass1(FILE *f) if(!makelabel(w + 1, addr)) return error("Pass1 failed", w); scpy(w + 1, scope, 64); - } else if(w[0] == '$') { - if(!makelabel(sublabel(subw, scope, w + 1), addr)) - return error("Pass1 failed", w); } else if(w[0] == '|') { if(shex(w + 1) < addr) return error("Memory Overwrite", w); @@ -375,15 +316,10 @@ pass2(FILE *f) char w[64], scope[64], subw[64]; printf("Pass 2\n"); 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] == ';') { - p.ptr += findlabel(w + 1)->len; - continue; - } if(w[0] == '|') { p.ptr = shex(w + 1); continue; @@ -392,7 +328,7 @@ pass2(FILE *f) scpy(w + 1, scope, 64); continue; } - if(w[1] == '$') + if(w[1] == '&') scpy(sublabel(subw, scope, w + 2), w + 1, 64); if(skipblock(w, &cbits, '[', ']')) { if(w[0] == '[' || w[0] == ']') { continue; } @@ -412,7 +348,7 @@ void cleanup(char *filename) { int i; - printf("Assembled %s(%0.2fkb), %d labels, %d macros.\n\n", filename, p.ptr / 1000.0, p.llen, p.mlen); + printf("Assembled %s(%0.2fkb), %d labels, %d macros.\n\n", filename, (p.ptr - OFFSET) / 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); @@ -431,7 +367,7 @@ main(int argc, char *argv[]) return !error("Open", "Failed"); if(!pass1(f) || !pass2(f)) return !error("Assembly", "Failed"); - fwrite(p.data, p.ptr, 1, fopen(argv[2], "wb")); + fwrite(p.data + OFFSET, p.ptr - OFFSET, 1, fopen(argv[2], "wb")); fclose(f); cleanup(argv[2]); return 0; diff --git a/src/uxn.c b/src/uxn.c index 077b91f..fd7288d 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 + LOAD_OFFSET, sizeof(u->ram.dat) - LOAD_OFFSET, 1, f); + fread(u->ram.dat + PAGE_PROGRAM, sizeof(u->ram.dat) - PAGE_PROGRAM, 1, f); printf("Uxn loaded[%s].\n", filepath); return 1; } diff --git a/src/uxn.h b/src/uxn.h index 49187b2..86adc7b 100644 --- a/src/uxn.h +++ b/src/uxn.h @@ -18,7 +18,7 @@ typedef signed short Sint16; #define PAGE_DEVICE 0x0100 #define PAGE_PROGRAM 0x0200 -#define LOAD_OFFSET 0x0000 +#define LOAD_OFFSET 0x0200 typedef struct { Uint8 ptr, error;