From 17099c8ba91c2b344dd604f9439a7f7c7801a2d9 Mon Sep 17 00:00:00 2001 From: neauoire Date: Sat, 13 Feb 2021 13:21:05 -0800 Subject: [PATCH] Redesigned asm language a bit --- README.md | 53 +++++++++++++++++++++--------------------- assembler.c | 22 ++++++++---------- build.sh | 2 +- examples/benchmark.usm | 39 ------------------------------- examples/blank.usm | 1 + examples/condjump.usm | 6 ++--- examples/draw.usm | 1 - examples/hello.usm | 17 +++++++------- examples/pixels.usm | 28 +++++++++++----------- examples/screen.usm | 13 +++++------ examples/test.usm | 15 +++++------- 11 files changed, 75 insertions(+), 122 deletions(-) delete mode 100644 examples/benchmark.usm diff --git a/README.md b/README.md index ed1be23..3e50d4c 100644 --- a/README.md +++ b/README.md @@ -24,18 +24,26 @@ evaluxn(u, u->vframe); /* Each frame ## 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. +- `;variable 2`, assign an address to a label automatically. +- `:const 1a2b`, assign an address to a label manually. ### Read - `,literal`, push label value to stack, prefixed with `LIT LEN`. - `.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 @@ -45,37 +53,30 @@ evaluxn(u, u->vframe); /* Each frame ### Operator modes -- `,1234 ,0001 ADD2`, 16-bits operators have the short flag `2`. -- `,12 ,11 GTH JMP?`, conditional operators have the cond flag `?`. +- `#1234 #0001 ADD2`, 16-bits operators have the short flag `2`. +- `#12 #11 GTH JMP?`, conditional operators have the cond flag `?`. - `+21 -03 MULS`, signed operators have the cond flag `S`. ``` -( hello world ) - -;iterator +:dev/w fff9 ( const write port ) +;i 1 ( var iterator ) |0100 @RESET -@word1 "hello_world ( len: 0x0b ) + #00 ,dev/w STR ( set dev/write to console ) -@loop - ,00 IOW ( write to device#0 ) - ,incr JSR ( increment itr ) - ,word1 ,strlen JSR ( get strlen ) - NEQ ,loop ROT JSR? ( loop != strlen ) + @word1 "hello_world ( len: 0x0b ) + + @loop + IOW ( write to device#0 ) + ,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 -@strlen - ,0001 ADD^ LDR - RTS - -@incr - ,iterator LDR - ,01 ADD - ,iterator STR - ,iterator LDR - RTS +@strlen #0001 ADD2 LDR RTS |c000 @FRAME BRK |d000 @ERROR BRK diff --git a/assembler.c b/assembler.c index ade902e..192933a 100644 --- a/assembler.c +++ b/assembler.c @@ -92,7 +92,7 @@ findlabel(char *s) } Uint8 -findoperator(char *s) +findopcode(char *s) { int i; for(i = 0; i < 0x20; ++i) { @@ -128,7 +128,7 @@ makelabel(char *name, Uint16 addr) return error("Label duplicate", name); if(sihx(name)) return error("Label name is hex number", name); - if(findoperator(name)) + if(findopcode(name)) return error("Label name is invalid", name); l = &labels[labelslen++]; l->addr = addr; @@ -174,20 +174,18 @@ pass1(FILE *f) } else if(w[0] == ':') { if(!makeconst(w + 1, f)) return error("Pass1 failed", w); - } else if(findoperator(w) || scmp(w, "BRK")) + } else if(findopcode(w) || scmp(w, "BRK")) addr += 1; else { switch(w[0]) { case '|': addr = shex(w + 1); break; case '"': addr += slen(w + 1) + 2; break; case '.': addr += 2; break; + case ',': addr += 4; break; case '+': /* signed positive */ case '-': /* signed negative */ - case ',': - addr += (sihx(w + 1) && slen(w + 1) == 2 ? 1 : 2); - addr += (sihx(w + 1) ? slen(w + 1) / 2 : 2); - break; - default: return error("Unknown label", w); + case '#': addr += (slen(w + 1) == 2 ? 2 : 4); break; + default: return error("Unknown label in first pass", w); } } } @@ -207,18 +205,18 @@ pass2(FILE *f) if(cmnt(w, &skip)) continue; /* clang-format off */ 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] == '#' && 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) == 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) == 4) pushshort((Sint16)(shex(w + 1) * -1), 1); else if(w[0] == '"') pushtext(w + 1); else if((l = findlabel(w + 1))) pushshort(l->addr, w[0] == ','); - else if((op = findoperator(w)) || scmp(w, "BRK")) pushbyte(op, 0); - 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); + else return error("Unknown label in second pass", w); /* clang-format on */ } return 1; diff --git a/build.sh b/build.sh index 005ccd6..3763040 100755 --- a/build.sh +++ b/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 # run -./bin/assembler examples/draw.usm bin/boot.rom +./bin/assembler examples/pixels.usm bin/boot.rom ./bin/emulator bin/boot.rom diff --git a/examples/benchmark.usm b/examples/benchmark.usm deleted file mode 100644 index 3662c23..0000000 --- a/examples/benchmark.usm +++ /dev/null @@ -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 diff --git a/examples/blank.usm b/examples/blank.usm index ee7a26a..4f2fc76 100644 --- a/examples/blank.usm +++ b/examples/blank.usm @@ -6,4 +6,5 @@ |0100 @RESET BRK |c000 @FRAME BRK |d000 @ERROR BRK + |FFFA .RESET .FRAME .ERROR diff --git a/examples/condjump.usm b/examples/condjump.usm index e4df4a3..a771687 100644 --- a/examples/condjump.usm +++ b/examples/condjump.usm @@ -2,14 +2,14 @@ |0100 @RESET -,06 ,05 GTH ,there ROT JMP? POP2 +#06 #05 GTH ,there ROT JMP? POP2 @here ( when lesser or equal ) - ,ee + #ee BRK @there ( when greater ) - ,ff + #ff BRK |c000 @FRAME BRK diff --git a/examples/draw.usm b/examples/draw.usm index 0269d64..5d27624 100644 --- a/examples/draw.usm +++ b/examples/draw.usm @@ -39,7 +39,6 @@ ( fill rect x y w h ) ,0028 ,0038 ,0050 ,0030 ,linerect JSR - ( positive ) ,01 ,color STR +0030 ,x0 STR2 +0040 ,y0 STR2 diff --git a/examples/hello.usm b/examples/hello.usm index 7ef26c3..68387ad 100644 --- a/examples/hello.usm +++ b/examples/hello.usm @@ -5,21 +5,20 @@ |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 - IOW ( write to device#0 ) - ,incr JSR ( increment itr ) - ,i LDR ( a = i ) - ,word1 ,strlen JSR ( b = string length ) - NEQ ,loop ROT JSR? ( a != b ? loop ) + IOW ( write to device#0 ) + ,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 -@strlen ,0001 ADD2 LDR RTS -@incr ,i LDR ,01 ADD ,i STR RTS +@strlen #0001 ADD2 LDR RTS |c000 @FRAME BRK |d000 @ERROR BRK diff --git a/examples/pixels.usm b/examples/pixels.usm index 5282cb5..148e8f0 100644 --- a/examples/pixels.usm +++ b/examples/pixels.usm @@ -7,31 +7,29 @@ |0100 @RESET - ,01 ,dev/w STR ( set dev/write to screen ) - ,01 ,color STR ( set color ) - ,0020 ,x STR2 ( set x-pos ) - ,0030 ,y STR2 ( set y-pos ) - ,01 ,alive STR ( set alive = true ) + #01 ,dev/w STR ( set dev/write to screen ) + #01 ,color STR ( set color ) + #0020 ,x STR2 ( set x-pos ) + #0030 ,y STR2 ( set y-pos ) + #01 ,alive STR ( set alive = true ) BRK |c000 @FRAME - ,alive LDR ,00 EQU BRK? - ,01 ,color LDR ,x LDR2 ,y LDR2 ,putpixel JSR + ,alive LDR #00 EQU BRK? + #01 ,color LDR ,x LDR2 ,y LDR2 ,putpixel JSR ,move JSR BRK @move - ,x LDR2 ,0001 ADD2 ,x STR2 ( incr x ) - ,x LDR2 ,0040 LTH2 RTS? ( if x > 60 ) - ,0020 ,x STR2 ( x = 0x0020 ) - ,y LDR2 ,0001 ADD2 ,y STR2 ( incr y ) - - ,y LDR2 ,0050 LTH2 RTS? ( y > 50 ) - ,00 ,alive STR ( alive = 0 ) - + ,x LDR2 #0001 ADD2 ,x STR2 ( incr x ) + ,x LDR2 #0040 LTH2 RTS? ( if x > 60 ) + #0020 ,x STR2 ( x = 0x0020 ) + ,y LDR2 #0001 ADD2 ,y STR2 ( incr y ) + ,y LDR2 #0050 LTH2 RTS? ( y > 50 ) + #00 ,alive STR ( alive = 0 ) RTS @putpixel diff --git a/examples/screen.usm b/examples/screen.usm index a5322b6..b9ba159 100644 --- a/examples/screen.usm +++ b/examples/screen.usm @@ -8,17 +8,16 @@ |0100 @RESET ( 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 ) - ,00 IOR2 ,width STR2 - ,02 IOR2 ,height STR2 + #00 IOR2 ,width STR2 + #02 IOR2 ,height STR2 ( draw pixel at screen center ) - - ,0101 - ,width LDR2 ,0002 DIV2 - ,height LDR2 ,0002 DIV2 + #0101 + ,width LDR2 #0002 DIV2 + ,height LDR2 #0002 DIV2 ,putpixel JSR BRK diff --git a/examples/test.usm b/examples/test.usm index db2f3db..55b48e6 100644 --- a/examples/test.usm +++ b/examples/test.usm @@ -1,19 +1,16 @@ -( my test file, junk ) +( comment ) -:dev/r fff8 ( std read port ) -:dev/w fff9 ( std write port ) - -;x 2 +:const abcd +;byte 1 +;short 2 |0100 @RESET - ,00 ,dev/w STR ( set dev/write to console ) - - +1234 -0012 ADDS2 + 12 34 ADD + 1234 0001 ADD2 BRK - |c000 @FRAME BRK |d000 @ERROR BRK |FFFA .RESET .FRAME .ERROR