mirror of
https://git.sr.ht/~rabbits/uxn
synced 2025-01-05 15:11:18 +00:00
(uxnasm) Merged ref resolution functions
This commit is contained in:
parent
a252da617c
commit
5801d4fc9f
1 changed files with 51 additions and 59 deletions
68
src/uxnasm.c
68
src/uxnasm.c
|
@ -30,7 +30,7 @@ typedef struct {
|
||||||
static int ptr, length;
|
static int ptr, length;
|
||||||
static char token[0x40], scope[0x40], sublabel[0x80], lambda[0x05];
|
static char token[0x40], scope[0x40], sublabel[0x80], lambda[0x05];
|
||||||
static char dict[0x10000], *dictnext = dict;
|
static char dict[0x10000], *dictnext = dict;
|
||||||
static Uint8 data[0x10000], lambda_stack[0x100], lambda_ptr, lambda_len;
|
static Uint8 rom[0x10000], lambda_stack[0x100], lambda_ptr, lambda_len;
|
||||||
static Uint16 label_len, refs_len, macro_len;
|
static Uint16 label_len, refs_len, macro_len;
|
||||||
static Item labels[0x400], refs[0x1000], macros[0x100];
|
static Item labels[0x400], refs[0x1000], macros[0x100];
|
||||||
|
|
||||||
|
@ -209,22 +209,6 @@ makelambda(int id)
|
||||||
return lambda;
|
return lambda;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
makepad(char *w)
|
|
||||||
{
|
|
||||||
Item *l;
|
|
||||||
int rel = w[0] == '$' ? ptr : 0;
|
|
||||||
if(sihx(w + 1)) {
|
|
||||||
ptr = shex(w + 1) + rel;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if((l = findlabel(w + 1))) {
|
|
||||||
ptr = l->addr + rel;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
addref(char *label, char rune, Uint16 addr)
|
addref(char *label, char rune, Uint16 addr)
|
||||||
{
|
{
|
||||||
|
@ -244,6 +228,22 @@ addref(char *label, char rune, Uint16 addr)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
writepad(char *w)
|
||||||
|
{
|
||||||
|
Item *l;
|
||||||
|
int rel = w[0] == '$' ? ptr : 0;
|
||||||
|
if(sihx(w + 1)) {
|
||||||
|
ptr = shex(w + 1) + rel;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if((l = findlabel(w + 1))) {
|
||||||
|
ptr = l->addr + rel;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
writebyte(Uint8 b, Context *ctx)
|
writebyte(Uint8 b, Context *ctx)
|
||||||
{
|
{
|
||||||
|
@ -253,7 +253,7 @@ writebyte(Uint8 b, Context *ctx)
|
||||||
return error_asm("Writing outside memory");
|
return error_asm("Writing outside memory");
|
||||||
else if(ptr < length)
|
else if(ptr < length)
|
||||||
return error_asm("Writing rewind");
|
return error_asm("Writing rewind");
|
||||||
data[ptr++] = b;
|
rom[ptr++] = b;
|
||||||
length = ptr;
|
length = ptr;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -300,6 +300,9 @@ parse(char *w, FILE *f, Context *ctx)
|
||||||
{
|
{
|
||||||
Item *m;
|
Item *m;
|
||||||
switch(w[0]) {
|
switch(w[0]) {
|
||||||
|
case '$':
|
||||||
|
case '|': return !writepad(w) ? error_asm("Invalid padding") : 1;
|
||||||
|
case '"': return !writestring(w + 1, ctx) ? error_asm("Invalid string") : 1;
|
||||||
case '(': return !walkcomment(f, ctx) ? error_asm("Invalid comment") : 1;
|
case '(': return !walkcomment(f, ctx) ? error_asm("Invalid comment") : 1;
|
||||||
case '~': return !makeinclude(w + 1) ? error_asm("Invalid include") : 1;
|
case '~': return !makeinclude(w + 1) ? error_asm("Invalid include") : 1;
|
||||||
case '%': return !makemacro(w + 1, f, ctx) ? error_asm("Invalid macro") : 1;
|
case '%': return !makemacro(w + 1, f, ctx) ? error_asm("Invalid macro") : 1;
|
||||||
|
@ -316,9 +319,6 @@ parse(char *w, FILE *f, Context *ctx)
|
||||||
case ';': return addref(w + 1, w[0], ptr + 1) && writebyte(findopcode("LIT2"), ctx) && writeshort(0xffff);
|
case ';': return addref(w + 1, w[0], ptr + 1) && writebyte(findopcode("LIT2"), ctx) && writeshort(0xffff);
|
||||||
case '?': return addref(w + 1, w[0], ptr + 1) && writebyte(0x20, ctx) && writeshort(0xffff);
|
case '?': return addref(w + 1, w[0], ptr + 1) && writebyte(0x20, ctx) && writeshort(0xffff);
|
||||||
case '!': return addref(w + 1, w[0], ptr + 1) && writebyte(0x40, ctx) && writeshort(0xffff);
|
case '!': return addref(w + 1, w[0], ptr + 1) && writebyte(0x40, ctx) && writeshort(0xffff);
|
||||||
case '"': return !writestring(w + 1, ctx) ? error_asm("Invalid string") : 1;
|
|
||||||
case '$':
|
|
||||||
case '|': return !makepad(w) ? error_asm("Invalid padding") : 1;
|
|
||||||
case '[':
|
case '[':
|
||||||
case ']': return 1;
|
case ']': return 1;
|
||||||
}
|
}
|
||||||
|
@ -332,17 +332,19 @@ parse(char *w, FILE *f, Context *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
writeref(Item *r)
|
resolve(void)
|
||||||
{
|
{
|
||||||
int rel;
|
int i, rel;
|
||||||
Uint8 *rom = data + r->addr;
|
for(i = 0; i < refs_len; i++) {
|
||||||
Item *l = findlabel(r->name);
|
Item *r = &refs[i], *l = findlabel(r->name);
|
||||||
if(!l) return 0;
|
Uint8 *rom = rom + r->addr;
|
||||||
|
if(!l)
|
||||||
|
return error_top("Unknown reference", r->name);
|
||||||
switch(r->rune) {
|
switch(r->rune) {
|
||||||
case '_':
|
case '_':
|
||||||
case ',':
|
case ',':
|
||||||
*rom = rel = l->addr - r->addr - 2;
|
*rom = rel = l->addr - r->addr - 2;
|
||||||
if((Sint8)data[r->addr] != rel)
|
if((Sint8)rom[r->addr] != rel)
|
||||||
return error_top("Relative reference is too far", r->name);
|
return error_top("Relative reference is too far", r->name);
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
|
@ -362,16 +364,6 @@ writeref(Item *r)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
l->refs++;
|
l->refs++;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
resolve(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < refs_len; i++) {
|
|
||||||
Item *r = &refs[i];
|
|
||||||
if(!writeref(r)) return error_top("Unknown reference", r->name);
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -424,7 +416,7 @@ main(int argc, char *argv[])
|
||||||
if(!(dst = fopen(argv[2], "wb"))) return !error_top("Invalid Output", argv[2]);
|
if(!(dst = fopen(argv[2], "wb"))) return !error_top("Invalid Output", argv[2]);
|
||||||
if(length <= PAGE) return !error_top("Assembly", "Output rom is empty.");
|
if(length <= PAGE) return !error_top("Assembly", "Output rom is empty.");
|
||||||
review(argv[2]);
|
review(argv[2]);
|
||||||
fwrite(data + PAGE, length - PAGE, 1, dst);
|
fwrite(rom + PAGE, length - PAGE, 1, dst);
|
||||||
writesym(argv[2]);
|
writesym(argv[2]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Loading…
Reference in a new issue