neauoire authored on 30/01/2021 01:49:10
Showing 4 changed files
... ...
@@ -8,34 +8,29 @@ A stack-based VM, written in ANSI C.
8 8
 cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
9 9
 ```
10 10
 
11
-## OP Codes
11
+## Assembly Syntax
12 12
 
13 13
 ```
14
-VALUE       OPCODE  EXPLANATION
15
-0x00000000  NOP     do nothing
16
-0x00000001  ADD     pop a, pop b, push a + b
17
-0x00000002  SUB     pop a, pop b, push a - b
18
-0x00000003  AND     pop a, pop b, push a & b
19
-0x00000004  OR      pop a, pop b, push a | b
20
-0x00000005  XOR     pop a, pop b, push a ^ b
21
-0x00000006  NOT     pop a, push !a
22
-0x00000007  IN      read one byte from stdin, push as word on stack
23
-0x00000008  OUT     pop one word and write to stream as one byte
24
-0x00000009  LOAD    pop a, push word read from address a
25
-0x0000000A  STOR    pop a, pop b, write b to address a
26
-0x0000000B  JMP     pop a, goto a
27
-0x0000000C  JZ      pop a, pop b, if a == 0 goto b
28
-0x0000000D  PUSH    push next word
29
-0x0000000E  DUP     duplicate word on stack
30
-0x0000000F  SWAP    swap top two words on stack
31
-0x00000010  ROL3    rotate top three words on stack once left, (a b c) -> (b c a)
32
-0x00000011  OUTNUM  pop one word and write to stream as number
33
-0x00000012  JNZ     pop a, pop b, if a != 0 goto b
34
-0x00000013  DROP    remove top of stack
35
-0x00000014  PUSHIP  push a in IP stack
36
-0x00000015  POPIP   pop IP stack to current IP, effectively performing a jump
37
-0x00000016  DROPIP  pop IP, but do not jump
38
-0x00000017  COMPL   pop a, push the complement of a
14
+: 	starting a definition
15
+& 	obtaining pointers
16
+( 	stack comments
17
+` 	inlining bytecodes
18
+' 	strings
19
+# 	numbers
20
+$ 	characters
21
+~   vector
22
+[ 12 34 ] real values
23
+< 12 34 > relative values
24
+( 12 34 ) deadzone
25
+```
26
+
27
+```
28
+;add-two JSR
29
+
30
+BRK
31
+
32
+:add-two
33
+	[ 2 ] ADD RTS
39 34
 ```
40 35
 
41 36
 ## Design
... ...
@@ -50,12 +45,11 @@ VALUE       OPCODE  EXPLANATION
50 45
 
51 46
 ### Assembly
52 47
 
53
-- `%25`, decimal
54
-- `#25`, hex
48
+#### Addressing 
55 49
 
56
-```
57
-2 2 + $ef
58
-```
50
+- `label`, a named offset[TODO]
51
+- `literal`, a numeric value
52
+- `pointer`, pointer to an address[TODO]
59 53
 
60 54
 ### Assembler
61 55
 
... ...
@@ -10,14 +10,14 @@ rm -f ./uxn
10 10
 
11 11
 # debug(slow)
12 12
 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
13
-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
13
+# 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
14 14
 
15 15
 # build(fast)
16 16
 # cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
17 17
 
18 18
 # Size
19
-echo "Size: $(du -sk ./uxn)"
19
+# echo "Size: $(du -sk ./uxn)"
20 20
 
21 21
 # run
22 22
 ./uxnasm program.usm program.rom
23
-./uxn program.rom
23
+# ./uxn program.rom
... ...
@@ -1 +1 @@
1
-#12 #34 add 
2 1
\ No newline at end of file
2
+LIT 25 26 LIT DUP ADD BRK
3 3
\ No newline at end of file
... ...
@@ -14,13 +14,14 @@ WITH REGARD TO THIS SOFTWARE.
14 14
 #define PRGLEN 256
15 15
 
16 16
 typedef unsigned char Uint8;
17
-typedef unsigned short Uint16;
18 17
 
19 18
 typedef struct {
20 19
 	int ptr;
21
-	Uint16 data[PRGLEN];
20
+	Uint8 data[PRGLEN];
22 21
 } Program;
23 22
 
23
+char opcodes[][4] = {"BRK", "LIT", "DUP", "DRP", "SWP", "SLP", "PSH", "POP", "JMP", "JSR", "RST", "BEQ", "EQU", "NEQ", "LTH", "GTH"};
24
+
24 25
 Program p;
25 26
 
26 27
 #pragma mark - Helpers
... ...
@@ -35,6 +36,16 @@ scmp(char *a, char *b) /* string compare */
35 36
 	return 0;
36 37
 }
37 38
 
39
+char *
40
+suca(char *s) /* string to uppercase */
41
+{
42
+	int i = 0;
43
+	char c;
44
+	while((c = s[i]))
45
+		s[i++] = c >= 'a' && c <= 'z' ? c - ('a' - 'A') : c;
46
+	return s;
47
+}
48
+
38 49
 int
39 50
 shex(char *s) /* string to num */
40 51
 {
... ...
@@ -53,10 +64,27 @@ shex(char *s) /* string to num */
53 64
 Uint8
54 65
 getopcode(char *s)
55 66
 {
56
-	if(scmp(s, "add")) {
57
-		return 0x01;
67
+	int i;
68
+	for(i = 0; i < 16; ++i)
69
+		if(scmp(opcodes[i], suca(s)))
70
+			return i;
71
+	return 0xff;
72
+}
73
+
74
+void
75
+echo(Uint8 *s, Uint8 len, Uint8 ptr, char *name)
76
+{
77
+	int i;
78
+	printf("%s\n", name);
79
+	for(i = 0; i < len; ++i) {
80
+		if(i % 16 == 0)
81
+			printf("\n");
82
+		if(ptr == i)
83
+			printf("[%02x]", s[i]);
84
+		else
85
+			printf(" %02x ", s[i]);
58 86
 	}
59
-	return 0;
87
+	printf("\n");
60 88
 }
61 89
 
62 90
 void
... ...
@@ -64,16 +92,10 @@ pass1(FILE *f)
64 92
 {
65 93
 	char word[64];
66 94
 	while(fscanf(f, "%s", word) == 1) {
67
-		int lit = 0, val = 0;
68
-		if(word[0] == '#') {
69
-			lit = 0;
70
-			val = shex(word + 1);
71
-		} else {
72
-			lit = 1;
73
-			val = getopcode(word);
74
-		}
75
-		printf("#%d -> %s[%02x %02x]\n", p.ptr, word, lit, val);
76
-		p.data[p.ptr++] = (val << 8) + (lit & 0xff);
95
+		int op = getopcode(word);
96
+		if(op == 0xff)
97
+			op = shex(word);
98
+		p.data[p.ptr++] = op;
77 99
 	}
78 100
 }
79 101
 
... ...
@@ -95,5 +117,6 @@ main(int argc, char *argv[])
95 117
 	pass1(f);
96 118
 	fwrite(p.data, sizeof(p.data), 1, fopen(argv[2], "wb"));
97 119
 	fclose(f);
120
+	echo(p.data, 0x40, 0, "program");
98 121
 	return 0;
99 122
 }