commit 72d9c98f358c54d3d082ef61761ba768ba8a68c3
parent 588a0f8b923964635139ac570dece5f59405d3da
Author: neauoire <aliceffekt@gmail.com>
Date: Fri, 29 Jan 2021 17:49:10 -0800
*
Diffstat:
M | README.md | | | 56 | +++++++++++++++++++++++++------------------------------- |
M | build.sh | | | 6 | +++--- |
M | program.usm | | | 4 | ++-- |
M | uxnasm.c | | | 53 | ++++++++++++++++++++++++++++++++++++++--------------- |
4 files changed, 68 insertions(+), 51 deletions(-)
diff --git a/README.md b/README.md
@@ -8,34 +8,29 @@ A stack-based VM, written in ANSI C.
cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
```
-## OP Codes
+## Assembly Syntax
```
-VALUE OPCODE EXPLANATION
-0x00000000 NOP do nothing
-0x00000001 ADD pop a, pop b, push a + b
-0x00000002 SUB pop a, pop b, push a - b
-0x00000003 AND pop a, pop b, push a & b
-0x00000004 OR pop a, pop b, push a | b
-0x00000005 XOR pop a, pop b, push a ^ b
-0x00000006 NOT pop a, push !a
-0x00000007 IN read one byte from stdin, push as word on stack
-0x00000008 OUT pop one word and write to stream as one byte
-0x00000009 LOAD pop a, push word read from address a
-0x0000000A STOR pop a, pop b, write b to address a
-0x0000000B JMP pop a, goto a
-0x0000000C JZ pop a, pop b, if a == 0 goto b
-0x0000000D PUSH push next word
-0x0000000E DUP duplicate word on stack
-0x0000000F SWAP swap top two words on stack
-0x00000010 ROL3 rotate top three words on stack once left, (a b c) -> (b c a)
-0x00000011 OUTNUM pop one word and write to stream as number
-0x00000012 JNZ pop a, pop b, if a != 0 goto b
-0x00000013 DROP remove top of stack
-0x00000014 PUSHIP push a in IP stack
-0x00000015 POPIP pop IP stack to current IP, effectively performing a jump
-0x00000016 DROPIP pop IP, but do not jump
-0x00000017 COMPL pop a, push the complement of a
+: starting a definition
+& obtaining pointers
+( stack comments
+` inlining bytecodes
+' strings
+# numbers
+$ characters
+~ vector
+[ 12 34 ] real values
+< 12 34 > relative values
+( 12 34 ) deadzone
+```
+
+```
+;add-two JSR
+
+BRK
+
+:add-two
+ [ 2 ] ADD RTS
```
## Design
@@ -50,12 +45,11 @@ VALUE OPCODE EXPLANATION
### Assembly
-- `%25`, decimal
-- `#25`, hex
+#### Addressing
-```
-2 2 + $ef
-```
+- `label`, a named offset[TODO]
+- `literal`, a numeric value
+- `pointer`, pointer to an address[TODO]
### Assembler
diff --git a/build.sh b/build.sh
@@ -10,14 +10,14 @@ rm -f ./uxn
# debug(slow)
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 uxnasm.c -o uxnasm
-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 -o uxn
+# 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 -o uxn
# build(fast)
# cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
# Size
-echo "Size: $(du -sk ./uxn)"
+# echo "Size: $(du -sk ./uxn)"
# run
./uxnasm program.usm program.rom
-./uxn program.rom
+# ./uxn program.rom
diff --git a/program.usm b/program.usm
@@ -1 +1 @@
-#12 #34 add
-\ No newline at end of file
+LIT 25 26 LIT DUP ADD BRK
+\ No newline at end of file
diff --git a/uxnasm.c b/uxnasm.c
@@ -14,13 +14,14 @@ WITH REGARD TO THIS SOFTWARE.
#define PRGLEN 256
typedef unsigned char Uint8;
-typedef unsigned short Uint16;
typedef struct {
int ptr;
- Uint16 data[PRGLEN];
+ Uint8 data[PRGLEN];
} Program;
+char opcodes[][4] = {"BRK", "LIT", "DUP", "DRP", "SWP", "SLP", "PSH", "POP", "JMP", "JSR", "RST", "BEQ", "EQU", "NEQ", "LTH", "GTH"};
+
Program p;
#pragma mark - Helpers
@@ -35,6 +36,16 @@ scmp(char *a, char *b) /* string compare */
return 0;
}
+char *
+suca(char *s) /* string to uppercase */
+{
+ int i = 0;
+ char c;
+ while((c = s[i]))
+ s[i++] = c >= 'a' && c <= 'z' ? c - ('a' - 'A') : c;
+ return s;
+}
+
int
shex(char *s) /* string to num */
{
@@ -53,10 +64,27 @@ shex(char *s) /* string to num */
Uint8
getopcode(char *s)
{
- if(scmp(s, "add")) {
- return 0x01;
+ int i;
+ for(i = 0; i < 16; ++i)
+ if(scmp(opcodes[i], suca(s)))
+ return i;
+ return 0xff;
+}
+
+void
+echo(Uint8 *s, Uint8 len, Uint8 ptr, char *name)
+{
+ int i;
+ printf("%s\n", name);
+ for(i = 0; i < len; ++i) {
+ if(i % 16 == 0)
+ printf("\n");
+ if(ptr == i)
+ printf("[%02x]", s[i]);
+ else
+ printf(" %02x ", s[i]);
}
- return 0;
+ printf("\n");
}
void
@@ -64,16 +92,10 @@ pass1(FILE *f)
{
char word[64];
while(fscanf(f, "%s", word) == 1) {
- int lit = 0, val = 0;
- if(word[0] == '#') {
- lit = 0;
- val = shex(word + 1);
- } else {
- lit = 1;
- val = getopcode(word);
- }
- printf("#%d -> %s[%02x %02x]\n", p.ptr, word, lit, val);
- p.data[p.ptr++] = (val << 8) + (lit & 0xff);
+ int op = getopcode(word);
+ if(op == 0xff)
+ op = shex(word);
+ p.data[p.ptr++] = op;
}
}
@@ -95,5 +117,6 @@ main(int argc, char *argv[])
pass1(f);
fwrite(p.data, sizeof(p.data), 1, fopen(argv[2], "wb"));
fclose(f);
+ echo(p.data, 0x40, 0, "program");
return 0;
}