Browse code

Starting 16bits mode

neauoire authored on 04/02/2021 20:22:08
Showing 5 changed files
... ...
@@ -10,13 +10,27 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
10 10
 
11 11
 ## Assembly Syntax
12 12
 
13
-- `;variable`, a named address(zero-page)
14
-- `:label`, a named address
15
-- `.pointer`, a pointer to a label
16
-- `@0010`, a position in the program
13
+### Write
14
+
15
+- `;variable`, set a name to address on the zero-page
16
+- `:label`, set a name to an address
17
+
18
+### Read
19
+
20
+- `,literal`, get a literal pointer
21
+- `.pointer`, get a raw pointer
22
+
23
+### Special
24
+
25
+- `@0010`, move to position in the program
26
+- `( comment )`
17 27
 
18 28
 ```
19
-< conditionals >
29
+( comment )
30
+
31
+;variable1
32
+;variable2
33
+;variable3
20 34
 
21 35
 .there ( 0a 05 GTH ) JMC
22 36
 
... ...
@@ -1,13 +1,3 @@
1
-< conditionals >
1
+( comment )
2 2
 
3
-.there ( 0a 05 GTH ) JMC
4
-
5
-:here
6
-	< when not equal >
7
-	ee
8
-	BRK
9
-
10
-:there
11
-	< when is equal >
12
-	ff
13
-	BRK
3
+,abcd ,ef STR
14 4
\ No newline at end of file
15 5
new file mode 100644
... ...
@@ -0,0 +1,11 @@
1
+< vectors >
2
+
3
+:RESET BRK
4
+:FRAME BRK
5
+:ERROR BRK
6
+
7
+@FFFA < vectors >
8
+
9
+.RESET
10
+.FRAME
11
+.ERROR
0 12
\ No newline at end of file
... ...
@@ -74,6 +74,13 @@ echo(Stack *s, Uint8 len, char *name)
74 74
 
75 75
 void wspush(Uint8 v) { cpu.wst.dat[cpu.wst.ptr++] = v; }
76 76
 Uint8 wspop(void) { return cpu.wst.dat[--cpu.wst.ptr]; }
77
+Uint16 wspop16(void) { 
78
+
79
+	Uint8 a = cpu.wst.dat[--cpu.wst.ptr];
80
+	Uint8 b = cpu.wst.dat[--cpu.wst.ptr];
81
+	return a + (b << 8); 
82
+
83
+}
77 84
 Uint8 wspeek(void) { return cpu.wst.dat[cpu.wst.ptr - 1]; }
78 85
 void rspush(Uint8 v) { cpu.rst.dat[cpu.rst.ptr++] = v; }
79 86
 Uint8 rspop(void) { return cpu.rst.dat[--cpu.rst.ptr]; }
... ...
@@ -102,17 +109,27 @@ void op_add() { wspush(wspop() + wspop()); }
102 109
 void op_sub() { wspush(wspop() - wspop()); }
103 110
 void op_mul() { wspush(wspop() * wspop()); }
104 111
 void op_div() { wspush(wspop() / wspop()); }
112
+void op_ldr() {  }
113
+void op_str() { 
114
+
115
+	Uint8 b = wspop();
116
+	Uint16 addr = wspop16();
117
+	printf("store: %02x @ %04x\n", b, addr);
118
+}
105 119
 
106 120
 void (*ops[])(void) = {
107 121
 	op_brk, op_rts, op_lit, op_drp, op_dup, op_swp, op_ovr, op_rot, 
108 122
 	op_jmu, op_jsu, op_jmc, op_jsc, op_equ, op_neq, op_gth, op_lth, 
109
-	op_and, op_ora, op_rol, op_ror, op_add, op_sub, op_mul, op_div};
123
+	op_and, op_ora, op_rol, op_ror, op_add, op_sub, op_mul, op_div,
124
+	op_ldr, op_str, op_brk, op_brk, op_brk, op_brk, op_brk, op_brk
125
+};
110 126
 
111 127
 Uint8 opr[][2] = {
112 128
 	{0,0}, {0,0}, {0,0}, {1,0}, {0,1}, {1,1}, {0,1}, {3,3},
113 129
 	{2,0}, {2,0}, {2,0}, {2,0}, {2,1}, {2,1}, {2,1}, {2,1},
114 130
 	{1,0}, {1,0}, {1,0}, {1,0}, {2,1}, {0,0}, {0,0}, {0,0},
115
-	{2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}
131
+	{2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1},
132
+	{3,1}, {3,1}
116 133
 };
117 134
 
118 135
 /* clang-format on */
... ...
@@ -155,7 +172,7 @@ eval()
155 172
 		cpu.literal--;
156 173
 		return 1;
157 174
 	}
158
-	if(instr < 24) {
175
+	if(instr < 32) {
159 176
 		if(cpu.wst.ptr < opr[instr][0])
160 177
 			return error("Stack underflow");
161 178
 		/* TODO stack overflow */
... ...
@@ -11,19 +11,17 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 11
 WITH REGARD TO THIS SOFTWARE.
12 12
 */
13 13
 
14
-#define PRGLEN 256
15
-#define LABELIDLEN 32
16
-
17 14
 typedef unsigned char Uint8;
15
+typedef unsigned short Uint16;
18 16
 
19 17
 typedef struct {
20 18
 	int ptr;
21
-	Uint8 data[PRGLEN];
19
+	Uint8 data[65536];
22 20
 } Program;
23 21
 
24 22
 typedef struct {
25
-	Uint8 addr;
26
-	char name[LABELIDLEN];
23
+	Uint16 addr;
24
+	char name[64];
27 25
 } Label;
28 26
 
29 27
 int labelslen;
... ...
@@ -34,7 +32,9 @@ Label labels[256];
34 32
 char opcodes[][4] = {
35 33
 	"BRK", "RTS", "LIT", "POP", "DUP", "SWP", "OVR", "ROT",
36 34
 	"JMU", "JSU", "JMC", "JSC", "EQU", "NEQ", "GTH", "LTH",
37
-	"AND", "ORA", "ROL", "ROR", "ADD", "SUB", "MUL", "DIV"};
35
+	"AND", "ORA", "ROL", "ROR", "ADD", "SUB", "MUL", "DIV",
36
+	"LDR", "STR", "---", "---", "---", "---", "---", "---"
37
+};
38 38
 
39 39
 /* clang-format on */
40 40
 
... ...
@@ -82,7 +82,7 @@ suca(char *s) /* string to uppercase */
82 82
 }
83 83
 
84 84
 int
85
-sihx(char *s)
85
+sihx(char *s) /* string is hexadecimal */
86 86
 {
87 87
 	int i = 0;
88 88
 	char c;
... ...
@@ -107,57 +107,66 @@ shex(char *s) /* string to num */
107 107
 	return n;
108 108
 }
109 109
 
110
-#pragma mark - Parser
110
+int
111
+ismarker(char *w)
112
+{
113
+	return w[0] == '[' || w[0] == ']' || w[0] == '{' || w[0] == '}';
114
+}
111 115
 
112
-void
113
-pushprg(Uint8 hex)
116
+int
117
+iscomment(char *w, int *skip)
114 118
 {
115
-	p.data[p.ptr++] = hex;
119
+	if(w[0] == ')') {
120
+		*skip = 0;
121
+		return 1;
122
+	}
123
+	if(w[0] == '(') *skip = 1;
124
+	if(*skip) return 1;
125
+	return 0;
116 126
 }
117 127
 
128
+#pragma mark - I/O
129
+
118 130
 void
119
-pushlabel(Label *l)
131
+pushbyte(Uint8 b, int lit)
120 132
 {
121
-	pushprg(0x02);
122
-	pushprg(0x01);
123
-	pushprg(l->addr);
133
+	if(lit) {
134
+		pushbyte(0x02, 0);
135
+		pushbyte(0x01, 0);
136
+	}
137
+	p.data[p.ptr++] = b;
124 138
 }
125 139
 
126 140
 void
127
-pushliteral(char *w)
141
+pushshort(Uint16 s, int lit)
128 142
 {
129
-	int len = slen(w) / 2, value = shex(w);
130
-	pushprg(0x02);
131
-	pushprg(len);
132
-	switch(len) {
133
-	case 1:
134
-		pushprg(value);
135
-		break;
136
-	case 2:
137
-		pushprg(value >> 8);
138
-		pushprg(value);
139
-		break;
140
-	case 3:
141
-		pushprg(value >> 16);
142
-		pushprg(value >> 8);
143
-		pushprg(value);
144
-		break;
143
+	if(lit) {
144
+		pushbyte(0x02, 0);
145
+		pushbyte(0x02, 0);
145 146
 	}
147
+	pushbyte((s >> 8) & 0xff, 0);
148
+	pushbyte(s & 0xff, 0);
146 149
 }
147 150
 
148
-void
149
-addlabel(char *id, Uint8 addr)
151
+#pragma mark - Parser
152
+
153
+Uint8
154
+findop(char *s)
150 155
 {
151
-	Label *l = &labels[labelslen++];
152
-	scpy(suca(id), l->name, LABELIDLEN);
153
-	l->addr = addr;
154
-	printf("New label: %s[0x%02x]\n", l->name, l->addr);
156
+	int i;
157
+	for(i = 0; i < 32; ++i)
158
+		if(scmp(opcodes[i], s))
159
+			return i;
160
+	return 0;
155 161
 }
156 162
 
157 163
 void
158
-addconst(char *id, Uint8 value)
164
+makelabel(char *id, Uint8 addr)
159 165
 {
160
-	printf("New const: %s[%02x]\n", id, value);
166
+	Label *l = &labels[labelslen++];
167
+	scpy(suca(id), l->name, 64);
168
+	l->addr = addr;
169
+	printf("New label: %s[0x%02x]\n", l->name, l->addr);
161 170
 }
162 171
 
163 172
 Label *
... ...
@@ -170,94 +179,72 @@ findlabel(char *s)
170 179
 	return NULL;
171 180
 }
172 181
 
173
-Uint8
174
-findop(char *s)
175
-{
176
-	int i;
177
-	for(i = 0; i < 24; ++i)
178
-		if(scmp(opcodes[i], s))
179
-			return i;
180
-	return 0;
181
-}
182
-
183
-int
184
-ismarker(char *w)
185
-{
186
-	return w[0] == '(' || w[0] == ')' || w[0] == '{' || w[0] == '}';
187
-}
182
+#pragma mark - Parser
188 183
 
189 184
 int
190
-iscomment(char *w, int *skip)
185
+error(char *name, char *id)
191 186
 {
192
-	if(w[0] == '>') {
193
-		*skip = 0;
194
-		return 1;
195
-	}
196
-	if(w[0] == '<') *skip = 1;
197
-	if(*skip) return 1;
187
+	printf("Error: %s - %s\n", name, id);
198 188
 	return 0;
199 189
 }
200 190
 
201 191
 int
202
-getlength(char *w)
203
-{
204
-	if(findop(w) || scmp(w, "BRK")) return 1;
205
-	if(w[0] == '.') return 3;
206
-	if(w[0] == ':') return 0;
207
-	if(w[0] == ';') return 0;
208
-	if(w[0] == '@') return 0;
209
-	if(sihx(w)) { return slen(w) / 2 + 2; }
210
-	if(ismarker(w)) return 0;
211
-	printf("Unknown length %s\n", w);
212
-	return 0;
213
-}
214
-
215
-void
216 192
 pass1(FILE *f)
217 193
 {
218
-	int skip = 0;
219
-	int addr = 0;
220
-	int vars = 0;
221
-	char word[64];
222
-	while(fscanf(f, "%s", word) == 1) {
223
-		if(iscomment(word, &skip)) continue;
224
-		if(word[0] == ':') addlabel(word + 1, addr);
225
-		if(word[0] == ';') addlabel(word + 1, vars++);
226
-		addr += getlength(word);
194
+	int skip = 0, addr = 0, vars = 0;
195
+	char w[64];
196
+	while(fscanf(f, "%s", w) == 1) {
197
+		if(iscomment(w, &skip)) continue;
198
+		if(w[0] == ':') makelabel(w + 1, addr);
199
+		if(w[0] == ';') makelabel(w + 1, vars++);
200
+		/* move addr ptr */
201
+		if(findop(w) || scmp(w, "BRK"))
202
+			addr += 1;
203
+		else if(w[0] == '@')
204
+			addr += 0;
205
+		else if(w[0] == ':')
206
+			addr += 0;
207
+		else if(w[0] == ';')
208
+			addr += 0;
209
+		else if(w[0] == '.')
210
+			addr += 2;
211
+		else if(w[0] == ',')
212
+			addr += 4;
213
+		else if(ismarker(w))
214
+			addr += 0;
215
+		else
216
+			return error("Unknown label(pass1)", w);
227 217
 	}
228 218
 	rewind(f);
219
+	return 1;
229 220
 }
230 221
 
231
-void
222
+int
232 223
 pass2(FILE *f)
233 224
 {
234 225
 	int skip = 0;
235
-	char word[64];
236
-	while(fscanf(f, "%s", word) == 1) {
226
+	char w[64];
227
+	while(fscanf(f, "%s", w) == 1) {
237 228
 		Uint8 op = 0;
238 229
 		Label *l;
239
-		if(word[0] == ':') continue;
240
-		if(word[0] == ';') continue;
241
-		suca(word);
242
-		if(iscomment(word, &skip) || ismarker(word)) continue;
243
-		if(word[0] == '@')
244
-			p.ptr = shex(word + 1);
245
-		else if((op = findop(word)) || scmp(word, "BRK"))
246
-			pushprg(op);
247
-		else if((l = findlabel(word + 1)))
248
-			pushlabel(l);
249
-		else if(sihx(word))
250
-			pushliteral(word);
230
+		if(w[0] == ':') continue;
231
+		if(w[0] == ';') continue;
232
+		suca(w);
233
+		if(iscomment(w, &skip) || ismarker(w)) continue;
234
+		if(w[0] == '@')
235
+			p.ptr = shex(w + 1);
236
+		else if((op = findop(w)) || scmp(w, "BRK"))
237
+			pushbyte(op, 0);
238
+		else if((l = findlabel(w + 1)))
239
+			pushshort(l->addr, w[0] == ',');
240
+		else if(sihx(w + 1) && slen(w + 1) == 2)
241
+			pushbyte(shex(w + 1), w[0] == ',');
242
+		else if(sihx(w + 1) && slen(w + 1) == 4)
243
+			pushshort(shex(w + 1), w[0] == ',');
251 244
 		else
252
-			printf("Unknown label: %s\n", word);
245
+			return error("Unknown label(pass2)", w);
253 246
 	}
254
-}
255
-
256
-int
257
-error(char *name)
258
-{
259
-	printf("Error: %s\n", name);
260
-	return 0;
247
+	return 1;
261 248
 }
262 249
 
263 250
 int
... ...
@@ -265,11 +252,11 @@ main(int argc, char *argv[])
265 252
 {
266 253
 	FILE *f;
267 254
 	if(argc < 3)
268
-		return error("No input.");
255
+		return error("Input", "Missing");
269 256
 	if(!(f = fopen(argv[1], "r")))
270
-		return error("Missing input.");
271
-	pass1(f);
272
-	pass2(f);
257
+		return error("Open", "Failed");
258
+	if(!pass1(f) || !pass2(f))
259
+		return error("Assembly", "Failed");
273 260
 	fwrite(p.data, sizeof(p.data), 1, fopen(argv[2], "wb"));
274 261
 	fclose(f);
275 262
 	return 0;