Browse code

Added return stack

neauoire authored on 31/01/2021 05:31:49
Showing 4 changed files
... ...
@@ -10,6 +10,10 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
10 10
 
11 11
 ## Assembly Syntax
12 12
 
13
+- `:label`, a named offset
14
+- `+literal`, a numeric value
15
+- `.pointer`, pointer to a label
16
+
13 17
 ```
14 18
 < comment >
15 19
 
... ...
@@ -30,31 +34,16 @@ $01 < pointer8 >
30 34
 :label ADD RTS
31 35
 ```
32 36
 
33
-## Design
34
-
35
-### CPU
36
-
37
-- Build stack with pointer
38
-- Print stack
39
-- Build memory
40
-
41
-### PPU
42
-
43
-### Assembly
44
-
45
-#### Addressing 
46
-
47
-- `label`, a named offset[TODO]
48
-- `literal`, a numeric value
49
-- `pointer`, pointer to an address[TODO]
50
-
51
-### Assembler
52
-
53
-
54
-### Emulator
55
-
56
-- SDL Layer
37
+## TODOs
57 38
 
39
+- Implement addressing
40
+- Implement 16 bits operations
41
+- Jumps should be relative
42
+- Catch overflow/underflow
43
+- Implement literals like `[2]`, and `[ 2 3 ]`.
44
+- Audo-detect literals length.
45
+- SDL Layer Emulator
46
+- Build PPU
58 47
 
59 48
 ## Refs
60 49
 
... ...
@@ -1,5 +1,18 @@
1 1
 < comment >
2 2
 
3
-[3 1 2 3 ] pop dup swp ovr rot 
3
+.deep JSR [4 6 7 8 9 ] BRK
4 4
 
5
-brk
5
+:deep
6
+	[2 1 2 ] 
7
+	.deeper JSR 
8
+	RTS
9
+
10
+:deeper
11
+	[3 3 4 5 ] 
12
+	.deeperyet JSR
13
+	RTS
14
+
15
+:deeperyet
16
+	[2 aa bb ]
17
+	RTS
18
+	
6 19
\ No newline at end of file
... ...
@@ -24,8 +24,9 @@ typedef struct {
24 24
 	Uint8 literal;
25 25
 	Uint8 status, counter;
26 26
 	Uint8 memory[STACK_DEPTH];
27
-	Uint8 mptr, sptr;
27
+	Uint8 mptr, sptr, rsptr;
28 28
 	Uint8 stack[STACK_DEPTH];
29
+	Uint8 rstack[STACK_DEPTH];
29 30
 	Uint8 address[STACK_DEPTH];
30 31
 } Computer;
31 32
 
... ...
@@ -61,20 +62,66 @@ echo(Uint8 *s, Uint8 len, char *name)
61 62
 	printf("\n\n");
62 63
 }
63 64
 
64
-#pragma mark - Operations
65
+void
66
+spush(Uint8 v)
67
+{
68
+	cpu.stack[cpu.sptr++] = v;
69
+}
70
+
71
+Uint8
72
+spop(void)
73
+{
74
+	return cpu.stack[--cpu.sptr];
75
+}
65 76
 
66 77
 void
67
-op_push(Uint8 *s, Uint8 *ptr, Uint8 v)
78
+rspush(Uint8 v)
68 79
 {
69
-	s[(*ptr)++] = v;
80
+	cpu.rstack[cpu.rsptr++] = v;
70 81
 }
71 82
 
72 83
 Uint8
73
-op_pop(Uint8 *s, Uint8 *ptr)
84
+rspop(void)
74 85
 {
75
-	return s[--*ptr];
86
+	return cpu.rstack[--cpu.rsptr];
76 87
 }
77 88
 
89
+#pragma mark - Operations
90
+
91
+/* clang-format off */
92
+
93
+void op_brk() { setflag(FLAG_HALT, 1); }
94
+void op_lit() { cpu.literal += cpu.memory[cpu.mptr++]; }
95
+void op_nop() { }
96
+void op_drp() { spop(); }
97
+void op_dup() { spush(cpu.stack[cpu.sptr - 1]); }
98
+void op_swp() { Uint8 b = spop(), a = spop(); spush(b); spush(a); }
99
+void op_ovr() { spush(cpu.stack[cpu.sptr - 2]); }
100
+void op_rot() { Uint8 c = spop(),b = spop(),a = spop(); spush(b); spush(c); spush(a); }
101
+void op_jmp() { cpu.mptr = spop(); }
102
+void op_jsr() { rspush(cpu.mptr); cpu.mptr = spop(); }
103
+void op_jeq() { if(getflag(FLAG_ZERO)) cpu.mptr = spop(); }
104
+void op_rts() {	cpu.mptr = rspop(); }
105
+void op_equ() { setflag(FLAG_ZERO, spop() == spop()); }
106
+void op_neq() { setflag(FLAG_ZERO, spop() != spop()); }
107
+void op_lth() {	setflag(FLAG_ZERO, spop() < spop()); }
108
+void op_gth() {	setflag(FLAG_ZERO, spop() > spop()); }
109
+void op_and() {	spush(spop() & spop()); }
110
+void op_ora() {	spush(spop() | spop()); }
111
+void op_rol() { spush(spop() << 1); }
112
+void op_ror() { spush(spop() >> 1); }
113
+void op_add() { spush(spop() + spop()); }
114
+void op_sub() { spush(spop() - spop()); }
115
+void op_mul() { spush(spop() * spop()); }
116
+void op_div() { spush(spop() / spop()); }
117
+
118
+void (*ops[])(void) = {
119
+	op_brk, op_lit, op_nop, op_drp, op_dup, op_swp, op_ovr, op_rot, 
120
+	op_jmp, op_jsr, op_jeq, op_rts, op_equ, op_neq, op_gth, op_lth, 
121
+	op_and, op_ora, op_rol, op_ror, op_add, op_sub, op_mul, op_div};
122
+
123
+/* clang-format on */
124
+
78 125
 void
79 126
 reset(void)
80 127
 {
... ...
@@ -105,42 +152,13 @@ void
105 152
 eval()
106 153
 {
107 154
 	Uint8 instr = cpu.memory[cpu.mptr++];
108
-	Uint8 a, b, c;
109 155
 	if(cpu.literal > 0) {
110
-		printf("push: %02x[%d](%d)\n", instr, cpu.literal, cpu.sptr);
111
-		op_push(cpu.stack, &cpu.sptr, instr);
156
+		spush(instr);
112 157
 		cpu.literal--;
113 158
 		return;
114 159
 	}
115
-	switch(instr) {
116
-	case 0x0: setflag(FLAG_HALT, 1); break;
117
-	case 0x1: cpu.literal += cpu.memory[cpu.mptr++]; break;
118
-	case 0x2: printf("??\n"); break;
119
-	case 0x3: /* pop */
120
-		op_pop(cpu.stack, &cpu.sptr);
121
-		break;
122
-	case 0x4: /* dup */
123
-		op_push(cpu.stack, &cpu.sptr, cpu.stack[cpu.sptr - 1]);
124
-		break;
125
-	case 0x5: /* swp */
126
-		b = op_pop(cpu.stack, &cpu.sptr);
127
-		a = op_pop(cpu.stack, &cpu.sptr);
128
-		op_push(cpu.stack, &cpu.sptr, b);
129
-		op_push(cpu.stack, &cpu.sptr, a);
130
-		break;
131
-	case 0x6: /* ovr */
132
-		op_push(cpu.stack, &cpu.sptr, cpu.stack[cpu.sptr - 2]);
133
-		break;
134
-	case 0x7: /* rot */
135
-		c = op_pop(cpu.stack, &cpu.sptr);
136
-		b = op_pop(cpu.stack, &cpu.sptr);
137
-		a = op_pop(cpu.stack, &cpu.sptr);
138
-		op_push(cpu.stack, &cpu.sptr, b);
139
-		op_push(cpu.stack, &cpu.sptr, c);
140
-		op_push(cpu.stack, &cpu.sptr, a);
141
-		break;
142
-	default: printf("Unknown instruction: #%02x\n", instr);
143
-	}
160
+	if(instr < 24)
161
+		(*ops[instr])();
144 162
 }
145 163
 
146 164
 void
... ...
@@ -12,6 +12,7 @@ WITH REGARD TO THIS SOFTWARE.
12 12
 */
13 13
 
14 14
 #define PRGLEN 256
15
+#define LABELIDLEN 32
15 16
 
16 17
 typedef unsigned char Uint8;
17 18
 
... ...
@@ -20,7 +21,13 @@ typedef struct {
20 21
 	Uint8 data[PRGLEN];
21 22
 } Program;
22 23
 
23
-char labels[256][16];
24
+typedef struct {
25
+	Uint8 addr;
26
+	char name[LABELIDLEN];
27
+} Label;
28
+
29
+int labelslen;
30
+Label labels[256];
24 31
 
25 32
 char opcodes[][4] = {
26 33
 	"BRK",
... ...
@@ -40,6 +47,14 @@ char opcodes[][4] = {
40 47
 	"NEQ",
41 48
 	"LTH",
42 49
 	"GTH",
50
+	"---",
51
+	"---",
52
+	"---",
53
+	"---",
54
+	"ADD",
55
+	"SUB",
56
+	"MUL",
57
+	"DIV"
43 58
 	/* */};
44 59
 
45 60
 Program p;
... ...
@@ -56,6 +71,16 @@ scmp(char *a, char *b) /* string compare */
56 71
 	return 0;
57 72
 }
58 73
 
74
+char *
75
+scpy(char *src, char *dst, int len) /* string copy */
76
+{
77
+	int i = 0;
78
+	while((dst[i] = src[i]) && i < len - 2)
79
+		i++;
80
+	dst[i + 1] = '\0';
81
+	return dst;
82
+}
83
+
59 84
 char *
60 85
 suca(char *s) /* string to uppercase */
61 86
 {
... ...
@@ -72,7 +97,7 @@ sihx(char *s)
72 97
 	int i = 0;
73 98
 	char c;
74 99
 	while((c = s[i++]))
75
-		if(!(c >= '0' && c <= '9') && !(c >= 'A' && c <= 'F'))
100
+		if(!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F'))
76 101
 			return 0;
77 102
 	return 1;
78 103
 }
... ...
@@ -87,6 +112,8 @@ shex(char *s) /* string to num */
87 112
 			n = n * 16 + (c - '0');
88 113
 		else if(c >= 'A' && c <= 'F')
89 114
 			n = n * 16 + 10 + (c - 'A');
115
+		else if(c >= 'a' && c <= 'f')
116
+			n = n * 16 + 10 + (c - 'f');
90 117
 	return n;
91 118
 }
92 119
 
... ...
@@ -101,7 +128,10 @@ addprg(Uint8 hex)
101 128
 void
102 129
 addlabel(char *id, Uint8 addr)
103 130
 {
104
-	printf("new label: %s=%02x\n", id, addr);
131
+	Label *l = &labels[labelslen++];
132
+	scpy(suca(id), l->name, LABELIDLEN);
133
+	l->addr = addr;
134
+	printf("new label: %s=%02x\n", l->name, l->addr);
105 135
 }
106 136
 
107 137
 void
... ...
@@ -110,16 +140,39 @@ addconst(char *id, Uint8 value)
110 140
 	printf("new const: %s=%02x\n", id, value);
111 141
 }
112 142
 
143
+Label *
144
+findlabel(char *s)
145
+{
146
+	int i;
147
+	for(i = 0; i < labelslen; ++i)
148
+		if(scmp(labels[i].name, s))
149
+			return &labels[i];
150
+	return NULL;
151
+}
152
+
113 153
 Uint8
114 154
 findop(char *s)
115 155
 {
116 156
 	int i;
117
-	for(i = 0; i < 16; ++i)
157
+	for(i = 0; i < 24; ++i)
118 158
 		if(scmp(opcodes[i], s))
119 159
 			return i;
120 160
 	return 0;
121 161
 }
122 162
 
163
+int
164
+getlength(char *w)
165
+{
166
+	if(findop(w) || scmp(w, "BRK")) return 1;
167
+	if(w[0] == '.') return 3;
168
+	if(w[0] == ':') return 0;
169
+	if(w[0] == '[') return 2;
170
+	if(sihx(w)) return 1;
171
+	if(w[0] == ']') return 0;
172
+	printf("Unknown length %s\n", w);
173
+	return 0;
174
+}
175
+
123 176
 int
124 177
 comment(char *w, int *skip)
125 178
 {
... ...
@@ -136,10 +189,12 @@ void
136 189
 pass1(FILE *f)
137 190
 {
138 191
 	int skip = 0;
192
+	int addr = 0;
139 193
 	char word[64];
140 194
 	while(fscanf(f, "%s", word) == 1) {
141
-		if(comment(word, &skip))
142
-			continue;
195
+		if(comment(word, &skip)) continue;
196
+		if(word[0] == ':') addlabel(word + 1, addr);
197
+		addr += getlength(word);
143 198
 	}
144 199
 	rewind(f);
145 200
 }
... ...
@@ -151,6 +206,8 @@ pass2(FILE *f)
151 206
 	char word[64];
152 207
 	while(fscanf(f, "%s", word) == 1) {
153 208
 		Uint8 op;
209
+		Label *l;
210
+		if(word[0] == ':') continue;
154 211
 		suca(word);
155 212
 		if(comment(word, &skip)) continue;
156 213
 		if(word[0] == ']') continue;
... ...
@@ -167,7 +224,11 @@ pass2(FILE *f)
167 224
 			addprg(shex(word));
168 225
 		else if(scmp(word, "BRK"))
169 226
 			addprg(0x00);
170
-		else
227
+		else if((l = findlabel(word + 1))) {
228
+			addprg(0x01);
229
+			addprg(1);
230
+			addprg(l->addr);
231
+		} else
171 232
 			printf("unknown: %s\n", word);
172 233
 	}
173 234
 }