Implementing better macros
This commit is contained in:
parent
e865be5d88
commit
fd883dc4c8
83
assembler.c
83
assembler.c
|
@ -24,17 +24,17 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Uint8 len, length[16], size, refs;
|
Uint8 len, length[16], size, refs;
|
||||||
char name[64], params[16][64];
|
char name[64], params[16][64];
|
||||||
} Macro;
|
} Template;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Uint8 len, offset, refs;
|
Uint8 len, offset, refs;
|
||||||
Uint16 addr;
|
Uint16 addr;
|
||||||
char name[64];
|
char name[64];
|
||||||
Macro *macro;
|
Template *template;
|
||||||
} Label;
|
} Label;
|
||||||
|
|
||||||
int macroslen;
|
int templateslen;
|
||||||
Macro macros[256];
|
Template templates[256];
|
||||||
|
|
||||||
int labelslen;
|
int labelslen;
|
||||||
Label labels[256];
|
Label labels[256];
|
||||||
|
@ -91,13 +91,13 @@ pushtext(char *s, int lit)
|
||||||
pushbyte(c, 0);
|
pushbyte(c, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Macro *
|
Template *
|
||||||
findmacro(char *s)
|
findtemplate(char *s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < macroslen; ++i)
|
for(i = 0; i < templateslen; ++i)
|
||||||
if(scmp(macros[i].name, s, 64))
|
if(scmp(templates[i].name, s, 64))
|
||||||
return ¯os[i];
|
return &templates[i];
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,12 +122,12 @@ findlabeladdr(char *s)
|
||||||
if(scin(s, '.') < 1)
|
if(scin(s, '.') < 1)
|
||||||
return l->addr;
|
return l->addr;
|
||||||
param = s + scin(s, '.') + 1;
|
param = s + scin(s, '.') + 1;
|
||||||
for(i = 0; i < l->macro->len; ++i) {
|
for(i = 0; i < l->template->len; ++i) {
|
||||||
if(scmp(l->macro->params[i], param, 64))
|
if(scmp(l->template->params[i], param, 64))
|
||||||
return l->addr + o;
|
return l->addr + o;
|
||||||
o += l->macro->length[i];
|
o += l->template->length[i];
|
||||||
}
|
}
|
||||||
printf("!!! Warning %s.%s[%s]\n", l->name, param, l->macro->name);
|
printf("!!! Warning %s.%s[%s]\n", l->name, param, l->template->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,10 +140,10 @@ findlabellen(char *s)
|
||||||
if(scin(s, '.') < 1)
|
if(scin(s, '.') < 1)
|
||||||
return l->len;
|
return l->len;
|
||||||
param = s + scin(s, '.') + 1;
|
param = s + scin(s, '.') + 1;
|
||||||
for(i = 0; i < l->macro->len; ++i)
|
for(i = 0; i < l->template->len; ++i)
|
||||||
if(scmp(l->macro->params[i], param, 64))
|
if(scmp(l->template->params[i], param, 64))
|
||||||
return l->macro->length[i];
|
return l->template->length[i];
|
||||||
printf("!!! Warning %s.%s[%s]\n", l->name, param, l->macro->name);
|
printf("!!! Warning %s.%s[%s]\n", l->name, param, l->template->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,18 +186,18 @@ error(char *name, char *id)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
makemacro(char *name, FILE *f)
|
maketemplate(char *name, FILE *f)
|
||||||
{
|
{
|
||||||
Uint8 mode = 0;
|
Uint8 mode = 0;
|
||||||
Macro *m;
|
Template *m;
|
||||||
char wv[64];
|
char wv[64];
|
||||||
if(findmacro(name))
|
if(findtemplate(name))
|
||||||
return error("Macro duplicate", name);
|
return error("Template duplicate", name);
|
||||||
if(sihx(name) && slen(name) % 2 == 0)
|
if(sihx(name) && slen(name) % 2 == 0)
|
||||||
return error("Macro name is hex number", name);
|
return error("Template name is hex number", name);
|
||||||
if(findopcode(name))
|
if(findopcode(name))
|
||||||
return error("Macro name is invalid", name);
|
return error("Template name is invalid", name);
|
||||||
m = ¯os[macroslen++];
|
m = &templates[templateslen++];
|
||||||
scpy(name, m->name, 64);
|
scpy(name, m->name, 64);
|
||||||
while(fscanf(f, "%s", wv)) {
|
while(fscanf(f, "%s", wv)) {
|
||||||
if(wv[0] == '{')
|
if(wv[0] == '{')
|
||||||
|
@ -213,12 +213,12 @@ makemacro(char *name, FILE *f)
|
||||||
}
|
}
|
||||||
mode = !mode;
|
mode = !mode;
|
||||||
}
|
}
|
||||||
printf("New macro: %s[%d:%d]\n", name, m->len, m->size);
|
printf("New template: %s[%d:%d]\n", name, m->len, m->size);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
makelabel(char *name, Uint16 addr, Uint8 len, Macro *m)
|
makelabel(char *name, Uint16 addr, Uint8 len, Template *m)
|
||||||
{
|
{
|
||||||
Label *l;
|
Label *l;
|
||||||
if(findlabel(name))
|
if(findlabel(name))
|
||||||
|
@ -233,35 +233,27 @@ makelabel(char *name, Uint16 addr, Uint8 len, Macro *m)
|
||||||
l->refs = 0;
|
l->refs = 0;
|
||||||
scpy(name, l->name, 64);
|
scpy(name, l->name, 64);
|
||||||
if(m)
|
if(m)
|
||||||
l->macro = m;
|
l->template = m;
|
||||||
printf("New label: %s, at 0x%04x[%d]\n", l->name, l->addr, l->len);
|
printf("New label: %s, at 0x%04x[%d]\n", l->name, l->addr, l->len);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
makeconst(char *id, FILE *f)
|
|
||||||
{
|
|
||||||
char wv[64];
|
|
||||||
fscanf(f, "%s", wv);
|
|
||||||
return makelabel(id, shex(wv), 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
makevariable(char *id, Uint16 *addr, FILE *f)
|
makevariable(char *id, Uint16 *addr, FILE *f)
|
||||||
{
|
{
|
||||||
char wv[64];
|
char wv[64];
|
||||||
Uint16 origin;
|
Uint16 origin;
|
||||||
Uint8 len;
|
Uint8 len;
|
||||||
Macro *m = NULL;
|
Template *m = NULL;
|
||||||
fscanf(f, "%s", wv);
|
fscanf(f, "%s", wv);
|
||||||
origin = *addr;
|
origin = *addr;
|
||||||
if(sihx(wv))
|
if(sihx(wv))
|
||||||
len = shex(wv);
|
len = shex(wv);
|
||||||
else if((m = findmacro(wv))) {
|
else if((m = findtemplate(wv))) {
|
||||||
len = m->size;
|
len = m->size;
|
||||||
m->refs++;
|
m->refs++;
|
||||||
} else
|
} else
|
||||||
return error("Invalid macro", wv);
|
return error("Invalid template", wv);
|
||||||
*addr += len;
|
*addr += len;
|
||||||
return makelabel(id, origin, len, m);
|
return makelabel(id, origin, len, m);
|
||||||
}
|
}
|
||||||
|
@ -305,10 +297,7 @@ pass1(FILE *f)
|
||||||
if(!makevariable(w + 1, &addr, f))
|
if(!makevariable(w + 1, &addr, f))
|
||||||
return error("Pass1 failed", w);
|
return error("Pass1 failed", w);
|
||||||
} else if(w[0] == '&') {
|
} else if(w[0] == '&') {
|
||||||
if(!makemacro(w + 1, f))
|
if(!maketemplate(w + 1, f))
|
||||||
return error("Pass1 failed", w);
|
|
||||||
} else if(w[0] == ':') {
|
|
||||||
if(!makeconst(w + 1, f))
|
|
||||||
return error("Pass1 failed", w);
|
return error("Pass1 failed", w);
|
||||||
} else if(findopcode(w) || scmp(w, "BRK", 4))
|
} else if(findopcode(w) || scmp(w, "BRK", 4))
|
||||||
addr += 1;
|
addr += 1;
|
||||||
|
@ -338,7 +327,7 @@ pass1(FILE *f)
|
||||||
int
|
int
|
||||||
pass2(FILE *f)
|
pass2(FILE *f)
|
||||||
{
|
{
|
||||||
int ccmnt = 0, cbits = 0, cmacro = 0;
|
int ccmnt = 0, cbits = 0, ctemplate = 0;
|
||||||
char w[64], scope[64], subw[64];
|
char w[64], scope[64], subw[64];
|
||||||
printf("Pass 2\n");
|
printf("Pass 2\n");
|
||||||
while(fscanf(f, "%s", w) == 1) {
|
while(fscanf(f, "%s", w) == 1) {
|
||||||
|
@ -355,7 +344,7 @@ pass2(FILE *f)
|
||||||
scpy(subw, w + 1, 64);
|
scpy(subw, w + 1, 64);
|
||||||
}
|
}
|
||||||
if(skipblock(w, &ccmnt, '(', ')')) continue;
|
if(skipblock(w, &ccmnt, '(', ')')) continue;
|
||||||
if(skipblock(w, &cmacro, '{', '}')) continue;
|
if(skipblock(w, &ctemplate, '{', '}')) continue;
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
if(skipblock(w, &cbits, '[', ']')) {
|
if(skipblock(w, &cbits, '[', ']')) {
|
||||||
if(w[0] == '[' || w[0] == ']') { continue; }
|
if(w[0] == '[' || w[0] == ']') { continue; }
|
||||||
|
@ -395,9 +384,9 @@ cleanup(void)
|
||||||
for(i = 0; i < labelslen; ++i)
|
for(i = 0; i < labelslen; ++i)
|
||||||
if(!labels[i].refs)
|
if(!labels[i].refs)
|
||||||
printf("--- Unused label: %s\n", labels[i].name);
|
printf("--- Unused label: %s\n", labels[i].name);
|
||||||
for(i = 0; i < macroslen; ++i)
|
for(i = 0; i < templateslen; ++i)
|
||||||
if(!macros[i].refs)
|
if(!templates[i].refs)
|
||||||
printf("--- Unused macro: %s\n", macros[i].name);
|
printf("--- Unused template: %s\n", templates[i].name);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
2
build.sh
2
build.sh
|
@ -21,4 +21,4 @@ cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werr
|
||||||
|
|
||||||
# run
|
# run
|
||||||
./bin/assembler projects/software/left.usm bin/boot.rom
|
./bin/assembler projects/software/left.usm bin/boot.rom
|
||||||
./bin/emulator bin/boot.rom
|
# ./bin/emulator bin/boot.rom
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
- Double-click select word
|
- Double-click select word
|
||||||
- Right-click find next instance of selection
|
- Right-click find next instance of selection
|
||||||
- Draw tab characters
|
- Draw tab characters
|
||||||
|
- Don't redraw if nothing has changed
|
||||||
|
- Input on selection should erase selection range
|
||||||
|
- Erase on selection should erase selection range
|
||||||
- Scrollbar
|
- Scrollbar
|
||||||
- Don't scroll past oef
|
- Don't scroll past oef
|
||||||
- Hor scroll
|
- Hor scroll
|
||||||
|
@ -33,7 +36,6 @@
|
||||||
;i 2 ;j 2 ;k 1 ;l 1 ;addr 2
|
;i 2 ;j 2 ;k 1 ;l 1 ;addr 2
|
||||||
|
|
||||||
;selection Range2d ;position Point2d ;scroll Point2d
|
;selection Range2d ;position Point2d ;scroll Point2d
|
||||||
|
|
||||||
;pt Point2d ;mouse Point2d ;touch Touch2d
|
;pt Point2d ;mouse Point2d ;touch Touch2d
|
||||||
;textarea Textarea2d
|
;textarea Textarea2d
|
||||||
;label Label2d ( remove )
|
;label Label2d ( remove )
|
||||||
|
@ -42,7 +44,6 @@
|
||||||
|
|
||||||
( load file )
|
( load file )
|
||||||
,filepath ,load-file JSR2
|
,filepath ,load-file JSR2
|
||||||
|
|
||||||
( place textarea )
|
( place textarea )
|
||||||
#0018 =textarea.x1 ~SCRN.height #0008 SUB2 =textarea.y2
|
#0018 =textarea.x1 ~SCRN.height #0008 SUB2 =textarea.y2
|
||||||
|
|
||||||
|
@ -72,11 +73,11 @@ BRK
|
||||||
,no-ctrl-left ~CTRL #40 NEQ JMP2? POP2
|
,no-ctrl-left ~CTRL #40 NEQ JMP2? POP2
|
||||||
( clamp ) ,no-ctrl-left ~selection.from ,document.body EQU2 JMP2? POP2
|
( clamp ) ,no-ctrl-left ~selection.from ,document.body EQU2 JMP2? POP2
|
||||||
~selection.from #0001 SUB2 DUP2 =selection.from #0001 ADD2 =selection.to
|
~selection.from #0001 SUB2 DUP2 =selection.from #0001 ADD2 =selection.to
|
||||||
,clamp-selection JSR2,follow-selection JSR2 ,redraw JSR2 ,ctrl-end JMP2
|
,clamp-selection JSR2 ,follow-selection JSR2 ,redraw JSR2 ,ctrl-end JMP2
|
||||||
@no-ctrl-left
|
@no-ctrl-left
|
||||||
,no-ctrl-right ~CTRL #80 NEQ JMP2? POP2
|
,no-ctrl-right ~CTRL #80 NEQ JMP2? POP2
|
||||||
~selection.from #0001 ADD2 DUP2 =selection.from #0001 ADD2 =selection.to
|
~selection.from #0001 ADD2 DUP2 =selection.from #0001 ADD2 =selection.to
|
||||||
,clamp-selection JSR2,follow-selection JSR2 ,redraw JSR2 ,ctrl-end JMP2
|
,clamp-selection JSR2 ,follow-selection JSR2 ,redraw JSR2 ,ctrl-end JMP2
|
||||||
@no-ctrl-right
|
@no-ctrl-right
|
||||||
( alt )
|
( alt )
|
||||||
,no-alt ~CTRL #0f AND #02 NEQ JMP2? POP2
|
,no-alt ~CTRL #0f AND #02 NEQ JMP2? POP2
|
||||||
|
@ -119,27 +120,33 @@ BRK
|
||||||
|
|
||||||
( keys )
|
( keys )
|
||||||
|
|
||||||
,keys-end ~KEYS #00 EQU JMP2? POP2
|
,no-keys ~KEYS #00 EQU JMP2? POP2
|
||||||
|
|
||||||
,no-backspace ~KEYS #08 NEQ JMP2? POP2
|
,$no-backspace ~KEYS #08 NEQ JMP2? POP2
|
||||||
( erase )
|
( erase )
|
||||||
~selection.to ~selection.from SUB2 ,shift-left JSR2
|
,$erase-multiple ~selection.to ~selection.from SUB2 #0001 NEQ2 JMP2? POP2
|
||||||
|
$erase-single
|
||||||
|
~selection.to ~selection.from SUB2 ,shift-left JSR2
|
||||||
|
,$erase-end JMP2
|
||||||
|
$erase-multiple
|
||||||
|
~selection.from #0001 ADD2 =selection.from
|
||||||
|
~selection.to ~selection.from SUB2 #0001 ADD2 ,shift-left JSR2
|
||||||
|
$erase-end
|
||||||
~selection.from #0001 SUB2 =selection.from
|
~selection.from #0001 SUB2 =selection.from
|
||||||
~selection.from #0001 ADD2 =selection.to
|
,$keys-end JMP2
|
||||||
( release ) #00 =KEYS
|
$no-backspace
|
||||||
,redraw JSR2
|
|
||||||
,keys-end JMP2
|
|
||||||
@no-backspace
|
|
||||||
|
|
||||||
( insert )
|
( insert )
|
||||||
~selection.to ~selection.from SUB2 ,shift-right JSR2
|
~selection.to ~selection.from SUB2 ,shift-right JSR2
|
||||||
~KEYS ~selection.from STR
|
~KEYS ~selection.from STR
|
||||||
~selection.from #0001 ADD2 =selection.from
|
~selection.from #0001 ADD2 =selection.from
|
||||||
~selection.from #0001 ADD2 =selection.to
|
|
||||||
( release ) #00 =KEYS
|
|
||||||
,redraw JSR2
|
|
||||||
|
|
||||||
@keys-end
|
$keys-end
|
||||||
|
~selection.from #0001 ADD2 =selection.to
|
||||||
|
( release ) #00 =KEYS
|
||||||
|
,redraw JSR2
|
||||||
|
|
||||||
|
@no-keys
|
||||||
|
|
||||||
( mouse )
|
( mouse )
|
||||||
|
|
||||||
|
@ -532,7 +539,7 @@ RTS
|
||||||
( draw ) #01
|
( draw ) #01
|
||||||
~i ~selection.from #0001 SUB2 GTH2
|
~i ~selection.from #0001 SUB2 GTH2
|
||||||
~i ~selection.to LTH2 #0101 EQU2
|
~i ~selection.to LTH2 #0101 EQU2
|
||||||
#05 MUL ADD =SPRT.color
|
#05 MUL ADD ~i ~selection.from EQU2 ADD =SPRT.color
|
||||||
|
|
||||||
,$no-linebreak ~i LDR #0a NEQ ~i LDR #0d NEQ #0101 EQU2 JMP2? POP2
|
,$no-linebreak ~i LDR #0a NEQ ~i LDR #0d NEQ #0101 EQU2 JMP2? POP2
|
||||||
( draw linebreak )
|
( draw linebreak )
|
||||||
|
@ -578,10 +585,10 @@ RTS
|
||||||
#0000 =SPRT.y
|
#0000 =SPRT.y
|
||||||
,scrollbar_bg =SPRT.addr
|
,scrollbar_bg =SPRT.addr
|
||||||
|
|
||||||
$loop
|
$loop NOP
|
||||||
( draw ) #08 =SPRT.color
|
( draw ) #08 =SPRT.color
|
||||||
( incr ) ~SPRT.y #0008 ADD2 =SPRT.y
|
( incr ) ~SPRT.y #0008 ADD2 =SPRT.y
|
||||||
,$loop ~SPRT.y ~SCRN.height LTH2 JMP2? POP2
|
~SPRT.y ~SCRN.height LTH2 ^$loop MUL JMPS
|
||||||
|
|
||||||
#0000 =SPRT.y
|
#0000 =SPRT.y
|
||||||
,arrowup_icn =SPRT.addr
|
,arrowup_icn =SPRT.addr
|
||||||
|
|
Loading…
Reference in New Issue