mirror of
https://git.sr.ht/~rabbits/uxn
synced 2024-11-26 15:53:01 +00:00
Started implementing structs everywhere
This commit is contained in:
parent
15bab0f74a
commit
720fc2f80b
8 changed files with 80 additions and 103 deletions
59
README.md
59
README.md
|
@ -24,33 +24,24 @@ evaluxn(u, u->vframe); /* Each frame
|
|||
|
||||
## Assembly Syntax
|
||||
|
||||
### Assign
|
||||
|
||||
- `ADD`, an opcode.
|
||||
- `@label`, assign the current address to a label.
|
||||
- `;variable 2`, assign an address to a label automatically.
|
||||
- `:const 1a2b`, assign an address to a label manually.
|
||||
- `¯o { x 2 y 2 }`, define a macro named `macro`.
|
||||
|
||||
### Write
|
||||
|
||||
- `ADD`, an opcode.
|
||||
- `#1a`, a literal byte.
|
||||
- `#12ef`, a literal short.
|
||||
- `+1a`, a literal signed byte.
|
||||
- `+12ef`, a literal signed short.
|
||||
- `-1a`, a literal signed byte(negative).
|
||||
- `-12ef`, a literal signed short(negative).
|
||||
- `.ab`, a raw byte in memory.
|
||||
- `.abcd`, a raw short in memory.
|
||||
- `#1a`, a literal byte/short.
|
||||
- `+1a`, a literal signed byte/short.
|
||||
- `-1a`, a literal signed byte/short(negative).
|
||||
- `.ab`, a raw byte/short in memory.
|
||||
- `,literal`, push label address to stack, prefixed with `LIT LEN`.
|
||||
|
||||
### Special
|
||||
|
||||
- `( comment )`, toggle parsing on/off.
|
||||
- `|0010`, move to position in the program.
|
||||
- `"hello`, push literal bytes for word "hello".
|
||||
- `=label`, helper to STR, equivalent to `,label STR`, or `label STR2`.
|
||||
- `~label`, helper to LDR, equivalent to `,label LDR2`, or `,label LDR2`.
|
||||
- `|0010`, move to position in the program.
|
||||
- `<23`, move the program position `23` bytes backward.
|
||||
- `>12`, move the program position `12` bytes forward.
|
||||
- `( comment )`, toggle parsing on/off.
|
||||
- `[ 0123 abcd ]`, write shorts to memory.
|
||||
- `[ Hello World ]`, write text to memory.
|
||||
|
||||
### Operator modes
|
||||
|
||||
|
@ -60,25 +51,33 @@ evaluxn(u, u->vframe); /* Each frame
|
|||
- `ADDS2?`, modes can be combined.
|
||||
|
||||
```
|
||||
( comment )
|
||||
( hello world )
|
||||
|
||||
:dev/w fff9 ( const write port )
|
||||
|
||||
|0100 @RESET
|
||||
|
||||
,string ( add string pointer to stack )
|
||||
@loop
|
||||
DUP2 LDR IOW ( write pointer value to console )
|
||||
#0001 ADD2 ( increment string pointer )
|
||||
DUP2 LDR #00 NEQ ,loop ROT JMP? POP2 ( while *ptr!=0 goto loop )
|
||||
|
||||
#00 =dev/w ( set dev/write to console )
|
||||
,text1 ,print-label JSR ( print to console )
|
||||
|
||||
BRK
|
||||
|
||||
@string " Hello World " ( add string to memory )
|
||||
@print-label ( text )
|
||||
|
||||
|c000 @FRAME BRK
|
||||
|d000 @ERROR BRK
|
||||
@cliloop
|
||||
DUP2 LDR IOW ( write pointer value to console )
|
||||
#0001 ADD2 ( increment string pointer )
|
||||
DUP2 LDR #00 NEQ ,cliloop ROT JMP? POP2 ( while *ptr!=0 goto loop )
|
||||
POP2
|
||||
|
||||
RTS
|
||||
|
||||
@text1 [ Hello World ] <1 .00 ( add text to memory, return 1 byte, add null byte )
|
||||
|
||||
|c000 @FRAME
|
||||
|d000 @ERROR
|
||||
|
||||
|FFF0 [ f3f0 f30b f30a ] ( palette )
|
||||
|FFFA .RESET .FRAME .ERROR
|
||||
```
|
||||
|
||||
|
|
70
assembler.c
70
assembler.c
|
@ -80,6 +80,18 @@ pushshort(Uint16 s, int lit)
|
|||
pushbyte(s & 0xff, 0);
|
||||
}
|
||||
|
||||
void
|
||||
pushtext(char *s, int lit)
|
||||
{
|
||||
int i = 0;
|
||||
char c;
|
||||
if(lit)
|
||||
pushbyte(0x22, 0);
|
||||
while((c = s[i++]))
|
||||
pushbyte(c, 0);
|
||||
pushbyte(' ', 0);
|
||||
}
|
||||
|
||||
Macro *
|
||||
findmacro(char *s)
|
||||
{
|
||||
|
@ -253,54 +265,20 @@ skipblock(char *w, int *cap, char a, char b)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
skipstring(char *w, int *cap, Uint16 *addr)
|
||||
{
|
||||
if(w[0] == '"') {
|
||||
if(*cap)
|
||||
*addr += 1;
|
||||
*cap = !(*cap);
|
||||
return 1;
|
||||
}
|
||||
if(*cap) {
|
||||
*addr += slen(w) + 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
capturestring(char *w, int *cap)
|
||||
{
|
||||
if(w[0] == '"') {
|
||||
if(*cap)
|
||||
pushbyte(0x00, 0);
|
||||
*cap = !(*cap);
|
||||
return 1;
|
||||
}
|
||||
if(*cap) {
|
||||
int i;
|
||||
for(i = 0; i < slen(w); ++i)
|
||||
pushbyte(w[i], 0);
|
||||
pushbyte(' ', 0);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pass1(FILE *f)
|
||||
{
|
||||
int ccmnt = 0, cstrg = 0, cbits = 0;
|
||||
int ccmnt = 0, cbits = 0;
|
||||
Uint16 addr = 0;
|
||||
char w[64];
|
||||
printf("Pass 1\n");
|
||||
while(fscanf(f, "%s", w) == 1) {
|
||||
if(skipblock(w, &ccmnt, '(', ')')) continue;
|
||||
if(skipstring(w, &cstrg, &addr)) continue;
|
||||
if(skipblock(w, &cbits, '[', ']'))
|
||||
addr += w[0] != '[' && w[0] != ']' ? 2 : 0;
|
||||
else if(w[0] == '@') {
|
||||
if(skipblock(w, &cbits, '[', ']')) {
|
||||
if(w[0] == '[' || w[0] == ']')
|
||||
continue;
|
||||
addr += sihx(w) ? 2 : slen(w) + 1;
|
||||
} else if(w[0] == '@') {
|
||||
if(!makelabel(w + 1, addr, 0, NULL))
|
||||
return error("Pass1 failed", w);
|
||||
} else if(w[0] == ';') {
|
||||
|
@ -317,6 +295,8 @@ pass1(FILE *f)
|
|||
else {
|
||||
switch(w[0]) {
|
||||
case '|': addr = shex(w + 1); break;
|
||||
case '<': addr -= shex(w + 1); break;
|
||||
case '>': addr += shex(w + 1); break;
|
||||
case '=': addr += 4; break; /* STR helper */
|
||||
case '~': addr += 4; break; /* LDR helper */
|
||||
case ',': addr += 3; break;
|
||||
|
@ -335,7 +315,7 @@ pass1(FILE *f)
|
|||
int
|
||||
pass2(FILE *f)
|
||||
{
|
||||
int ccmnt = 0, cstrg = 0, cbits = 0, cmacro = 0;
|
||||
int ccmnt = 0, cbits = 0, cmacro = 0;
|
||||
char w[64];
|
||||
printf("Pass 2\n");
|
||||
while(fscanf(f, "%s", w) == 1) {
|
||||
|
@ -345,10 +325,14 @@ pass2(FILE *f)
|
|||
if(w[0] == '&') continue;
|
||||
if(skipblock(w, &ccmnt, '(', ')')) continue;
|
||||
if(skipblock(w, &cmacro, '{', '}')) continue;
|
||||
if(capturestring(w, &cstrg)) continue;
|
||||
/* clang-format off */
|
||||
if(skipblock(w, &cbits, '[', ']')) { if(w[0] != '[' && w[0] != ']') { pushshort(shex(w), 0); } }
|
||||
if(skipblock(w, &cbits, '[', ']')) {
|
||||
if(w[0] == '[' || w[0] == ']') { continue; }
|
||||
if(slen(w) == 4 && sihx(w)) pushshort(shex(w), 0); else pushtext(w, 0);
|
||||
}
|
||||
else if(w[0] == '|') p.ptr = shex(w + 1);
|
||||
else if(w[0] == '<') p.ptr -= shex(w + 1);
|
||||
else if(w[0] == '>') p.ptr += shex(w + 1);
|
||||
else if((op = findopcode(w)) || scmp(w, "BRK", 4)) pushbyte(op, 0);
|
||||
else if(w[0] == ':') fscanf(f, "%s", w);
|
||||
else if(w[0] == ';') fscanf(f, "%s", w);
|
||||
|
|
|
@ -2,15 +2,9 @@
|
|||
|
||||
:dev/w fff9 ( const write port )
|
||||
|
||||
;x1 2 ;y1 2
|
||||
|
||||
;x 2 ;y 2 ;color 1
|
||||
|
||||
|0100 @RESET
|
||||
|
||||
#02 =dev/w
|
||||
|
||||
#01 =color
|
||||
#00 ,icon #0040 #0040 ,draw-sprite JSR
|
||||
#01 ,icon #0048 #0040 ,draw-sprite JSR
|
||||
#02 ,icon #0050 #0040 ,draw-sprite JSR
|
||||
|
|
|
@ -2,27 +2,24 @@
|
|||
|
||||
:dev/w fff9 ( const write port )
|
||||
|
||||
;x 2 ;y 2 ;color 1
|
||||
|
||||
|0100 @RESET
|
||||
|
||||
( set dev/write to console )
|
||||
#00 =dev/w
|
||||
( print to console )
|
||||
,text ,displaycli JSR
|
||||
#00 =dev/w ( set dev/write to console )
|
||||
,text1 ,print-label JSR ( print to console )
|
||||
|
||||
BRK
|
||||
|
||||
@displaycli
|
||||
@print-label ( text )
|
||||
|
||||
@cliloop
|
||||
DUP2 LDR IOW ( write pointer value to console )
|
||||
#0001 ADD2 ( increment string pointer )
|
||||
DUP2 LDR #00 NEQ ,cliloop ROT JMP? POP2 ( while *ptr!=0 goto loop )
|
||||
POP2
|
||||
|
||||
RTS
|
||||
RTS
|
||||
|
||||
@text " Hello World " ( add characters to memory )
|
||||
@text1 [ Hello World ] <1 .00 ( add text to memory, return 1 byte, add null byte )
|
||||
|
||||
|c000 @FRAME
|
||||
|d000 @ERROR
|
||||
|
|
|
@ -3,15 +3,18 @@
|
|||
:dev/r fff8 ( const read port )
|
||||
:dev/w fff9 ( const write port )
|
||||
|
||||
;x 2 ;y 2 ;sprite 2
|
||||
&Point2d { x 2 y 2 }
|
||||
|
||||
;pos Point2d
|
||||
;sprite 2
|
||||
|
||||
|0100 @RESET
|
||||
|
||||
#03 =dev/r ( set dev/read to controller )
|
||||
#02 =dev/w ( set dev/write to sprite )
|
||||
#0080 =x #0040 =y ( origin )
|
||||
#0080 =pos.x #0040 =pos.y ( origin )
|
||||
|
||||
#12 ,up_icn ~x ~y ,draw-sprite JSR
|
||||
#12 ,up_icn ~pos.x ~pos.y ,draw-sprite JSR
|
||||
|
||||
BRK
|
||||
|
||||
|
@ -23,22 +26,22 @@ BRK
|
|||
|
||||
#00 IOR #10 NEQ ,next1 ROT JMP? POP2
|
||||
,up_icn =sprite
|
||||
~y #0001 SUB2 =y
|
||||
~pos.y #0001 SUB2 =pos.y
|
||||
@next1
|
||||
#00 IOR #20 NEQ ,next2 ROT JMP? POP2
|
||||
,down_icn =sprite
|
||||
~y #0001 ADD2 =y
|
||||
~pos.y #0001 ADD2 =pos.y
|
||||
@next2
|
||||
#00 IOR #40 NEQ ,next3 ROT JMP? POP2
|
||||
,left_icn =sprite
|
||||
~x #0001 SUB2 =x
|
||||
~pos.x #0001 SUB2 =pos.x
|
||||
@next3
|
||||
#00 IOR #80 NEQ ,end ROT JMP? POP2
|
||||
,right_icn =sprite
|
||||
~x #0001 ADD2 =x
|
||||
~pos.x #0001 ADD2 =pos.x
|
||||
@end
|
||||
( redraw )
|
||||
#13 ~sprite ~x ~y ,draw-sprite JSR
|
||||
#13 ~sprite ~pos.x ~pos.y ,draw-sprite JSR
|
||||
|
||||
BRK
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
BRK
|
||||
|
||||
@text " Hello World " ( add string to memory )
|
||||
@text [ Hello World ] <1 .00 ( add characters to memory )
|
||||
|
||||
@draw-label ( x1 y1 text )
|
||||
=y1 =x1
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#ff =red.r
|
||||
~red.r
|
||||
|
||||
( short mode )_
|
||||
( short mode )
|
||||
#1234 =rc1.x
|
||||
#abcd =rc1.height
|
||||
~rc1.height
|
||||
|
|
|
@ -134,11 +134,11 @@ RTS
|
|||
@checkoff_icn [ 7e81 8181 8181 817e ]
|
||||
@checkon_icn [ 7e81 99bd bd99 817e ]
|
||||
|
||||
@text1 " Planet " ( add string to memory )
|
||||
@text2 " To Jupiter "
|
||||
@text3 " To Neptune "
|
||||
@text4 " To Nereid "
|
||||
@text5 " Theme "
|
||||
@text1 [ Planet ] <1 .00 ( add string to memory )
|
||||
@text2 [ To Jupiter ] <1 .00
|
||||
@text3 [ To Neptune ] <1 .00
|
||||
@text4 [ To Nereid ] <1 .00
|
||||
@text5 [ Theme ] <1 .00
|
||||
|
||||
@font ( spectrum-zx font )
|
||||
[
|
||||
|
|
Loading…
Reference in a new issue