mirror of
https://git.sr.ht/~rabbits/uxn
synced 2024-11-26 15:53:01 +00:00
Redesigned asm language a bit
This commit is contained in:
parent
8574d62a61
commit
17099c8ba9
11 changed files with 75 additions and 122 deletions
53
README.md
53
README.md
|
@ -24,18 +24,26 @@ evaluxn(u, u->vframe); /* Each frame
|
||||||
|
|
||||||
## Assembly Syntax
|
## Assembly Syntax
|
||||||
|
|
||||||
### Write
|
### Assign
|
||||||
|
|
||||||
- `;variable`, automatically assign an address to a label.
|
|
||||||
- `:const FFCF`, manually assign an address to a label.
|
|
||||||
- `@label`, assign the current address to a label.
|
- `@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.
|
||||||
|
|
||||||
### Read
|
### Read
|
||||||
|
|
||||||
- `,literal`, push label value to stack, prefixed with `LIT LEN`.
|
- `,literal`, push label value to stack, prefixed with `LIT LEN`.
|
||||||
- `.pointer`, push label value to stack.
|
- `.pointer`, push label value to stack.
|
||||||
- `+1234`, push positive lit signed value to stack.
|
|
||||||
- `-abcd`, push negative lit signed value to stack.
|
### 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).
|
||||||
|
|
||||||
### Special
|
### Special
|
||||||
|
|
||||||
|
@ -45,37 +53,30 @@ evaluxn(u, u->vframe); /* Each frame
|
||||||
|
|
||||||
### Operator modes
|
### Operator modes
|
||||||
|
|
||||||
- `,1234 ,0001 ADD2`, 16-bits operators have the short flag `2`.
|
- `#1234 #0001 ADD2`, 16-bits operators have the short flag `2`.
|
||||||
- `,12 ,11 GTH JMP?`, conditional operators have the cond flag `?`.
|
- `#12 #11 GTH JMP?`, conditional operators have the cond flag `?`.
|
||||||
- `+21 -03 MULS`, signed operators have the cond flag `S`.
|
- `+21 -03 MULS`, signed operators have the cond flag `S`.
|
||||||
|
|
||||||
```
|
```
|
||||||
( hello world )
|
:dev/w fff9 ( const write port )
|
||||||
|
;i 1 ( var iterator )
|
||||||
;iterator
|
|
||||||
|
|
||||||
|0100 @RESET
|
|0100 @RESET
|
||||||
|
|
||||||
@word1 "hello_world ( len: 0x0b )
|
#00 ,dev/w STR ( set dev/write to console )
|
||||||
|
|
||||||
@loop
|
@word1 "hello_world ( len: 0x0b )
|
||||||
,00 IOW ( write to device#0 )
|
|
||||||
,incr JSR ( increment itr )
|
@loop
|
||||||
,word1 ,strlen JSR ( get strlen )
|
IOW ( write to device#0 )
|
||||||
NEQ ,loop ROT JSR? ( loop != strlen )
|
,i LDR #01 ADD ,i STR ( increment itr )
|
||||||
|
,i LDR ( a = i )
|
||||||
|
,word1 ,strlen JSR ( b = string length )
|
||||||
|
NEQ ,loop ROT JSR? POP^ ( a != b ? loop )
|
||||||
|
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
@strlen
|
@strlen #0001 ADD2 LDR RTS
|
||||||
,0001 ADD^ LDR
|
|
||||||
RTS
|
|
||||||
|
|
||||||
@incr
|
|
||||||
,iterator LDR
|
|
||||||
,01 ADD
|
|
||||||
,iterator STR
|
|
||||||
,iterator LDR
|
|
||||||
RTS
|
|
||||||
|
|
||||||
|c000 @FRAME BRK
|
|c000 @FRAME BRK
|
||||||
|d000 @ERROR BRK
|
|d000 @ERROR BRK
|
||||||
|
|
22
assembler.c
22
assembler.c
|
@ -92,7 +92,7 @@ findlabel(char *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint8
|
Uint8
|
||||||
findoperator(char *s)
|
findopcode(char *s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < 0x20; ++i) {
|
for(i = 0; i < 0x20; ++i) {
|
||||||
|
@ -128,7 +128,7 @@ makelabel(char *name, Uint16 addr)
|
||||||
return error("Label duplicate", name);
|
return error("Label duplicate", name);
|
||||||
if(sihx(name))
|
if(sihx(name))
|
||||||
return error("Label name is hex number", name);
|
return error("Label name is hex number", name);
|
||||||
if(findoperator(name))
|
if(findopcode(name))
|
||||||
return error("Label name is invalid", name);
|
return error("Label name is invalid", name);
|
||||||
l = &labels[labelslen++];
|
l = &labels[labelslen++];
|
||||||
l->addr = addr;
|
l->addr = addr;
|
||||||
|
@ -174,20 +174,18 @@ pass1(FILE *f)
|
||||||
} else if(w[0] == ':') {
|
} else if(w[0] == ':') {
|
||||||
if(!makeconst(w + 1, f))
|
if(!makeconst(w + 1, f))
|
||||||
return error("Pass1 failed", w);
|
return error("Pass1 failed", w);
|
||||||
} else if(findoperator(w) || scmp(w, "BRK"))
|
} else if(findopcode(w) || scmp(w, "BRK"))
|
||||||
addr += 1;
|
addr += 1;
|
||||||
else {
|
else {
|
||||||
switch(w[0]) {
|
switch(w[0]) {
|
||||||
case '|': addr = shex(w + 1); break;
|
case '|': addr = shex(w + 1); break;
|
||||||
case '"': addr += slen(w + 1) + 2; break;
|
case '"': addr += slen(w + 1) + 2; break;
|
||||||
case '.': addr += 2; break;
|
case '.': addr += 2; break;
|
||||||
|
case ',': addr += 4; break;
|
||||||
case '+': /* signed positive */
|
case '+': /* signed positive */
|
||||||
case '-': /* signed negative */
|
case '-': /* signed negative */
|
||||||
case ',':
|
case '#': addr += (slen(w + 1) == 2 ? 2 : 4); break;
|
||||||
addr += (sihx(w + 1) && slen(w + 1) == 2 ? 1 : 2);
|
default: return error("Unknown label in first pass", w);
|
||||||
addr += (sihx(w + 1) ? slen(w + 1) / 2 : 2);
|
|
||||||
break;
|
|
||||||
default: return error("Unknown label", w);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,18 +205,18 @@ pass2(FILE *f)
|
||||||
if(cmnt(w, &skip)) continue;
|
if(cmnt(w, &skip)) continue;
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
if(w[0] == '|') p.ptr = shex(w + 1);
|
if(w[0] == '|') p.ptr = shex(w + 1);
|
||||||
|
else if((op = findopcode(w)) || scmp(w, "BRK")) pushbyte(op, 0);
|
||||||
else if(w[0] == ':') fscanf(f, "%s", w);
|
else if(w[0] == ':') fscanf(f, "%s", w);
|
||||||
else if(w[0] == ';') fscanf(f, "%s", w);
|
else if(w[0] == ';') fscanf(f, "%s", w);
|
||||||
|
else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 2) pushbyte(shex(w), 1);
|
||||||
|
else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 4) pushshort(shex(w), 1);
|
||||||
else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)shex(w + 1), 1);
|
else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)shex(w + 1), 1);
|
||||||
else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)shex(w + 1), 1);
|
else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)shex(w + 1), 1);
|
||||||
else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)(shex(w + 1) * -1), 1);
|
else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)(shex(w + 1) * -1), 1);
|
||||||
else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)(shex(w + 1) * -1), 1);
|
else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)(shex(w + 1) * -1), 1);
|
||||||
else if(w[0] == '"') pushtext(w + 1);
|
else if(w[0] == '"') pushtext(w + 1);
|
||||||
else if((l = findlabel(w + 1))) pushshort(l->addr, w[0] == ',');
|
else if((l = findlabel(w + 1))) pushshort(l->addr, w[0] == ',');
|
||||||
else if((op = findoperator(w)) || scmp(w, "BRK")) pushbyte(op, 0);
|
else return error("Unknown label in second pass", w);
|
||||||
else if(sihx(w + 1) && slen(w + 1) == 2) pushbyte(shex(w + 1), w[0] == ',');
|
|
||||||
else if(sihx(w + 1) && slen(w + 1) == 4) pushshort(shex(w + 1), w[0] == ',');
|
|
||||||
else return error("Unknown label", w);
|
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
2
build.sh
2
build.sh
|
@ -24,5 +24,5 @@ rm -f ./bin/emulator
|
||||||
cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxn.c emulator.c -L/usr/local/lib -lSDL2 -o bin/emulator
|
cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxn.c emulator.c -L/usr/local/lib -lSDL2 -o bin/emulator
|
||||||
|
|
||||||
# run
|
# run
|
||||||
./bin/assembler examples/draw.usm bin/boot.rom
|
./bin/assembler examples/pixels.usm bin/boot.rom
|
||||||
./bin/emulator bin/boot.rom
|
./bin/emulator bin/boot.rom
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
( benchmark )
|
|
||||||
|
|
||||||
|0100 @RESET
|
|
||||||
|
|
||||||
( arithmetic )
|
|
||||||
,12 ,34 ADD ,46 EQU #00 STR
|
|
||||||
,12 ,06 SUB ,0c EQU #01 STR
|
|
||||||
,12 ,06 MUL ,6c EQU #02 STR
|
|
||||||
,12 ,06 DIV ,03 EQU #03 STR
|
|
||||||
,12 ,12 EQU #04 STR
|
|
||||||
,12 ,13 NEQ #05 STR
|
|
||||||
,12 ,11 GTH #06 STR
|
|
||||||
,12 ,13 LTH #07 STR
|
|
||||||
|
|
||||||
( arithmetic 16-bit )
|
|
||||||
,1234 ,2345 ADD2 ,3579 EQU2 #08 STR
|
|
||||||
,1234 ,0123 SUB2 ,1111 EQU2 #09 STR
|
|
||||||
,1234 ,0102 MUL2 ,5868 EQU2 #0a STR
|
|
||||||
,5678 ,0100 DIV2 ,0056 EQU2 #0b STR
|
|
||||||
,1234 ,1234 EQU2 #0c STR
|
|
||||||
,1234 ,0123 NEQ2 #0d STR
|
|
||||||
,1234 ,1233 GTH2 #0e STR
|
|
||||||
,1234 ,1235 LTH2 #0f STR
|
|
||||||
|
|
||||||
BRK
|
|
||||||
|
|
||||||
@diff8 ( result of abs sub )
|
|
||||||
OVR OVR GTH ,diff8sub ROT JMP? POP2
|
|
||||||
SWP @diff8sub SUB
|
|
||||||
RTS
|
|
||||||
|
|
||||||
@diff16 ( result of abs sub16 )
|
|
||||||
OVR2 OVR2 GTH2 ,diff16sub ROT JMP? POP2
|
|
||||||
SWP2 @diff16sub SUB2
|
|
||||||
RTS
|
|
||||||
|
|
||||||
|c000 @FRAME BRK
|
|
||||||
|d000 @ERROR BRK
|
|
||||||
|FFFA .RESET .FRAME .ERROR
|
|
|
@ -6,4 +6,5 @@
|
||||||
|0100 @RESET BRK
|
|0100 @RESET BRK
|
||||||
|c000 @FRAME BRK
|
|c000 @FRAME BRK
|
||||||
|d000 @ERROR BRK
|
|d000 @ERROR BRK
|
||||||
|
|
||||||
|FFFA .RESET .FRAME .ERROR
|
|FFFA .RESET .FRAME .ERROR
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
|0100 @RESET
|
|0100 @RESET
|
||||||
|
|
||||||
,06 ,05 GTH ,there ROT JMP? POP2
|
#06 #05 GTH ,there ROT JMP? POP2
|
||||||
|
|
||||||
@here ( when lesser or equal )
|
@here ( when lesser or equal )
|
||||||
,ee
|
#ee
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
@there ( when greater )
|
@there ( when greater )
|
||||||
,ff
|
#ff
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
|c000 @FRAME BRK
|
|c000 @FRAME BRK
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
( fill rect x y w h )
|
( fill rect x y w h )
|
||||||
,0028 ,0038 ,0050 ,0030 ,linerect JSR
|
,0028 ,0038 ,0050 ,0030 ,linerect JSR
|
||||||
|
|
||||||
|
|
||||||
( positive )
|
( positive )
|
||||||
,01 ,color STR
|
,01 ,color STR
|
||||||
+0030 ,x0 STR2 +0040 ,y0 STR2
|
+0030 ,x0 STR2 +0040 ,y0 STR2
|
||||||
|
|
|
@ -5,21 +5,20 @@
|
||||||
|
|
||||||
|0100 @RESET
|
|0100 @RESET
|
||||||
|
|
||||||
,00 ,dev/w STR ( set dev/write to console )
|
#00 ,dev/w STR ( set dev/write to console )
|
||||||
|
|
||||||
@word1 "hello_world ( len: 0x0b )
|
@word1 "hello_world ( len: 0x0b )
|
||||||
|
|
||||||
@loop
|
@loop
|
||||||
IOW ( write to device#0 )
|
IOW ( write to device#0 )
|
||||||
,incr JSR ( increment itr )
|
,i LDR #01 ADD ,i STR ( increment itr )
|
||||||
,i LDR ( a = i )
|
,i LDR ( a = i )
|
||||||
,word1 ,strlen JSR ( b = string length )
|
,word1 ,strlen JSR ( b = string length )
|
||||||
NEQ ,loop ROT JSR? ( a != b ? loop )
|
NEQ ,loop ROT JSR? POP^ ( a != b ? loop )
|
||||||
|
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
@strlen ,0001 ADD2 LDR RTS
|
@strlen #0001 ADD2 LDR RTS
|
||||||
@incr ,i LDR ,01 ADD ,i STR RTS
|
|
||||||
|
|
||||||
|c000 @FRAME BRK
|
|c000 @FRAME BRK
|
||||||
|d000 @ERROR BRK
|
|d000 @ERROR BRK
|
||||||
|
|
|
@ -7,31 +7,29 @@
|
||||||
|
|
||||||
|0100 @RESET
|
|0100 @RESET
|
||||||
|
|
||||||
,01 ,dev/w STR ( set dev/write to screen )
|
#01 ,dev/w STR ( set dev/write to screen )
|
||||||
,01 ,color STR ( set color )
|
#01 ,color STR ( set color )
|
||||||
,0020 ,x STR2 ( set x-pos )
|
#0020 ,x STR2 ( set x-pos )
|
||||||
,0030 ,y STR2 ( set y-pos )
|
#0030 ,y STR2 ( set y-pos )
|
||||||
,01 ,alive STR ( set alive = true )
|
#01 ,alive STR ( set alive = true )
|
||||||
|
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
|c000 @FRAME
|
|c000 @FRAME
|
||||||
|
|
||||||
,alive LDR ,00 EQU BRK?
|
,alive LDR #00 EQU BRK?
|
||||||
,01 ,color LDR ,x LDR2 ,y LDR2 ,putpixel JSR
|
#01 ,color LDR ,x LDR2 ,y LDR2 ,putpixel JSR
|
||||||
,move JSR
|
,move JSR
|
||||||
|
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
@move
|
@move
|
||||||
,x LDR2 ,0001 ADD2 ,x STR2 ( incr x )
|
,x LDR2 #0001 ADD2 ,x STR2 ( incr x )
|
||||||
,x LDR2 ,0040 LTH2 RTS? ( if x > 60 )
|
,x LDR2 #0040 LTH2 RTS? ( if x > 60 )
|
||||||
,0020 ,x STR2 ( x = 0x0020 )
|
#0020 ,x STR2 ( x = 0x0020 )
|
||||||
,y LDR2 ,0001 ADD2 ,y STR2 ( incr y )
|
,y LDR2 #0001 ADD2 ,y STR2 ( incr y )
|
||||||
|
,y LDR2 #0050 LTH2 RTS? ( y > 50 )
|
||||||
,y LDR2 ,0050 LTH2 RTS? ( y > 50 )
|
#00 ,alive STR ( alive = 0 )
|
||||||
,00 ,alive STR ( alive = 0 )
|
|
||||||
|
|
||||||
RTS
|
RTS
|
||||||
|
|
||||||
@putpixel
|
@putpixel
|
||||||
|
|
|
@ -8,17 +8,16 @@
|
||||||
|0100 @RESET
|
|0100 @RESET
|
||||||
|
|
||||||
( set read/write to dev/screen )
|
( set read/write to dev/screen )
|
||||||
,01 DUP ,dev/r STR ,dev/w STR
|
#01 DUP ,dev/r STR ,dev/w STR
|
||||||
|
|
||||||
( load screen size )
|
( load screen size )
|
||||||
,00 IOR2 ,width STR2
|
#00 IOR2 ,width STR2
|
||||||
,02 IOR2 ,height STR2
|
#02 IOR2 ,height STR2
|
||||||
|
|
||||||
( draw pixel at screen center )
|
( draw pixel at screen center )
|
||||||
|
#0101
|
||||||
,0101
|
,width LDR2 #0002 DIV2
|
||||||
,width LDR2 ,0002 DIV2
|
,height LDR2 #0002 DIV2
|
||||||
,height LDR2 ,0002 DIV2
|
|
||||||
,putpixel JSR
|
,putpixel JSR
|
||||||
|
|
||||||
BRK
|
BRK
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
( my test file, junk )
|
( comment )
|
||||||
|
|
||||||
:dev/r fff8 ( std read port )
|
:const abcd
|
||||||
:dev/w fff9 ( std write port )
|
;byte 1
|
||||||
|
;short 2
|
||||||
;x 2
|
|
||||||
|
|
||||||
|0100 @RESET
|
|0100 @RESET
|
||||||
|
|
||||||
,00 ,dev/w STR ( set dev/write to console )
|
12 34 ADD
|
||||||
|
1234 0001 ADD2
|
||||||
+1234 -0012 ADDS2
|
|
||||||
|
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
|
|
||||||
|c000 @FRAME BRK
|
|c000 @FRAME BRK
|
||||||
|d000 @ERROR BRK
|
|d000 @ERROR BRK
|
||||||
|FFFA .RESET .FRAME .ERROR
|
|FFFA .RESET .FRAME .ERROR
|
||||||
|
|
Loading…
Reference in a new issue