Browse code

Cleanup

neauoire authored on 08/02/2021 22:18:01
Showing 7 changed files
... ...
@@ -3,6 +3,5 @@
3 3
 *png~
4 4
 *gif~
5 5
 *bmp~
6
-uxn
7
-uxnasm
6
+/bin
8 7
 *.rom
9 8
\ No newline at end of file
10 9
similarity index 100%
11 10
rename from uxnasm.c
12 11
rename to assembler.c
... ...
@@ -1,20 +1,21 @@
1 1
 #!/bin/bash
2 2
 
3
-# format code
4
-clang-format -i uxnasm.c
5
-clang-format -i uxn.c
6
-clang-format -i cpu.h
7
-clang-format -i cpu.c
3
+# Create bin folder
4
+mkdir -p bin
8 5
 
9
-# remove old
10
-rm -f ./uxnasm
11
-rm -f ./uxn
6
+# Assembler
7
+clang-format -i assembler.c
8
+rm -f ./assembler
12 9
 rm -f ./boot.rom
10
+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 assembler.c -o bin/assembler
11
+./bin/assembler examples/hello.usm bin/boot.rom
13 12
 
14
-# debug(slow)
15
-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
16
-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 cpu.c uxn.c -o uxn
13
+# Emulator
14
+clang-format -i emulator.c
15
+clang-format -i uxn.h
16
+clang-format -i uxn.c
17
+rm -f ./uxn
18
+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 -o bin/emulator
17 19
 
18 20
 # run
19
-./uxnasm examples/hello.usm boot.rom
20
-./uxn boot.rom
21
+./bin/emulator bin/boot.rom
21 22
deleted file mode 100644
... ...
@@ -1,210 +0,0 @@
1
-#include <stdio.h>
2
-
3
-/*
4
-Copyright (c) 2021 Devine Lu Linvega
5
-
6
-Permission to use, copy, modify, and distribute this software for any
7
-purpose with or without fee is hereby granted, provided that the above
8
-copyright notice and this permission notice appear in all copies.
9
-
10
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
-WITH REGARD TO THIS SOFTWARE.
12
-*/
13
-
14
-#include "cpu.h"
15
-
16
-Cpu cpu;
17
-
18
-#pragma mark - Helpers
19
-
20
-void
21
-setflag(Uint8 *status, char flag, int b)
22
-{
23
-	if(b)
24
-		*status |= flag;
25
-	else
26
-		*status &= (~flag);
27
-}
28
-
29
-int
30
-getflag(Uint8 *status, char flag)
31
-{
32
-	return *status & flag;
33
-}
34
-
35
-#pragma mark - Operations
36
-
37
-/* clang-format off */
38
-
39
-Uint16 bytes2short(Uint8 a, Uint8 b) { return (a << 8) + b; }
40
-Uint16 mempeek16(Cpu *c, Uint16 s) { return (c->ram.dat[s] << 8) + (c->ram.dat[s+1] & 0xff); }
41
-void wspush8(Cpu *c, Uint8 b) { c->wst.dat[c->wst.ptr++] = b; }
42
-void wspush16(Cpu *c, Uint16 s) { wspush8(c,s >> 8); wspush8(c,s & 0xff); }
43
-Uint8 wspop8(Cpu *c) { return c->wst.dat[--c->wst.ptr]; }
44
-Uint16 wspop16(Cpu *c) { return wspop8(c) + (wspop8(c) << 8); }
45
-Uint8 wspeek8(Cpu *c, Uint8 o) { return c->wst.dat[c->wst.ptr - o]; }
46
-Uint16 wspeek16(Cpu *c, Uint8 o) { return bytes2short(c->wst.dat[c->wst.ptr - o], c->wst.dat[c->wst.ptr - o + 1]); }
47
-Uint16 rspop16(Cpu *c) { return c->rst.dat[--c->rst.ptr]; }
48
-void rspush16(Cpu *c, Uint16 a) { c->rst.dat[c->rst.ptr++] = a; }
49
-/* I/O */
50
-void op_brk(Cpu *c) { setflag(&c->status,FLAG_HALT, 1); }
51
-void op_lit(Cpu *c) { c->literal += c->ram.dat[c->ram.ptr++]; }
52
-void op_nop(Cpu *c) { (void)c; printf("NOP");}
53
-void op_ldr(Cpu *c) { wspush8(c, c->ram.dat[wspop16(c)]); }
54
-void op_str(Cpu *c) { c->ram.dat[wspop16(c)] = wspop8(c); }
55
-/* Logic */
56
-void op_jmp(Cpu *c) { c->ram.ptr = wspop16(c); }
57
-void op_jsr(Cpu *c) { rspush16(c, c->ram.ptr); c->ram.ptr = wspop16(c); }
58
-void op_rts(Cpu *c) {	c->ram.ptr = rspop16(c); }
59
-/* Stack */
60
-void op_pop(Cpu *c) { wspop8(c); }
61
-void op_dup(Cpu *c) { wspush8(c,wspeek8(c,1)); }
62
-void op_swp(Cpu *c) { Uint8 b = wspop8(c), a = wspop8(c); wspush8(c,b); wspush8(c,a); }
63
-void op_ovr(Cpu *c) { Uint8 a = wspeek8(c,2); wspush8(c,a); }
64
-void op_rot(Cpu *c) { Uint8 c1 = wspop8(c),b = wspop8(c),a = wspop8(c); wspush8(c,b); wspush8(c, c1); wspush8(c,a); }
65
-void op_and(Cpu *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,a & b); }
66
-void op_ora(Cpu *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,a | b); }
67
-void op_rol(Cpu *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,a << b); }
68
-/* Arithmetic */
69
-void op_add(Cpu *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b + a); }
70
-void op_sub(Cpu *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b - a); }
71
-void op_mul(Cpu *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b * a); }
72
-void op_div(Cpu *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b / a); }
73
-void op_equ(Cpu *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b == a); }
74
-void op_neq(Cpu *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b != a); }
75
-void op_gth(Cpu *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b > a); }
76
-void op_lth(Cpu *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b < a); }
77
-/* Stack(16-bits) */
78
-void op_pop16(Cpu *c) { wspop16(c); }
79
-void op_dup16(Cpu *c) { wspush16(c,wspeek16(c,2)); }
80
-void op_swp16(Cpu *c) { Uint16 b = wspop16(c), a = wspop16(c); wspush16(c,b); wspush16(c,a); }
81
-void op_ovr16(Cpu *c) { Uint16 a = wspeek16(c, 4); wspush16(c,a); }
82
-void op_rot16(Cpu *c) { Uint16 c1 = wspop16(c), b = wspop16(c), a = wspop16(c); wspush16(c,b); wspush16(c, c1); wspush16(c,a); }
83
-void op_and16(Cpu *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush16(c,a & b); }
84
-void op_ora16(Cpu *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush16(c,a | b); }
85
-void op_rol16(Cpu *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush16(c,a << b); }
86
-/* Arithmetic(16-bits) */
87
-void op_add16(Cpu *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush16(c,b + a); }
88
-void op_sub16(Cpu *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush16(c,b - a); }
89
-void op_mul16(Cpu *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush16(c,b * a); }
90
-void op_div16(Cpu *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush16(c,b / a); }
91
-void op_equ16(Cpu *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush8(c,b == a); }
92
-void op_neq16(Cpu *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush8(c,b != a); }
93
-void op_gth16(Cpu *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush8(c,b > a); }
94
-void op_lth16(Cpu *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush8(c,b < a); }
95
-
96
-void (*ops[])(Cpu *c) = {
97
-	op_brk, op_lit, op_nop, op_nop, op_nop, op_nop, op_ldr, op_str, 
98
-	op_jmp, op_jsr, op_nop, op_rts, op_nop, op_nop, op_nop, op_nop, 
99
-	op_pop, op_dup, op_swp, op_ovr, op_rot, op_and, op_ora, op_rol,
100
-	op_add, op_sub, op_mul, op_div, op_equ, op_neq, op_gth, op_lth,
101
-	op_pop16, op_dup16, op_swp16, op_ovr16, op_rot16, op_and16, op_ora16, op_rol16,
102
-	op_add16, op_sub16, op_mul16, op_div16, op_equ16, op_neq16, op_gth16, op_lth16
103
-};
104
-
105
-Uint8 opr[][2] = { 
106
-	{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {2,1}, {3,0},
107
-	{2,0}, {2,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
108
-	{1,0}, {1,2}, {2,2}, {3,3}, {3,3}, {2,1}, {2,1}, {2,1},
109
-	{2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1},
110
-	{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, /* TODO */
111
-	{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}  /* TODO */
112
-};
113
-
114
-/* clang-format on */
115
-
116
-int
117
-error(Cpu *c, char *name, int id)
118
-{
119
-	printf("Error: %s#%04x, at 0x%04x\n", name, id, c->counter);
120
-	return 0;
121
-}
122
-
123
-int
124
-doliteral(Cpu *c, Uint8 instr)
125
-{
126
-	if(c->wst.ptr >= 255)
127
-		return error(c, "Stack overflow", instr);
128
-	wspush8(c, instr);
129
-	c->literal--;
130
-	return 1;
131
-}
132
-
133
-int
134
-dodevices(Cpu *c) /* experimental */
135
-{
136
-	if(c->ram.dat[0xfff1]) {
137
-		printf("%c", c->ram.dat[0xfff1]);
138
-		c->ram.dat[0xfff1] = 0x00;
139
-	}
140
-	return 1;
141
-}
142
-
143
-int
144
-doopcode(Cpu *c, Uint8 instr)
145
-{
146
-	Uint8 op = instr & 0x1f;
147
-	setflag(&c->status, FLAG_SHORT, (instr >> 5) & 1);
148
-	setflag(&c->status, FLAG_SIGN, (instr >> 6) & 1); /* usused */
149
-	setflag(&c->status, FLAG_COND, (instr >> 7) & 1);
150
-	if(getflag(&c->status, FLAG_SHORT))
151
-		op += 16;
152
-	if(c->wst.ptr < opr[op][0])
153
-		return error(c, "Stack underflow", op);
154
-	if(c->wst.ptr + opr[op][1] - opr[op][0] >= 255)
155
-		return error(c, "Stack overflow", instr);
156
-	if(!getflag(&c->status, FLAG_COND) || (getflag(&c->status, FLAG_COND) && wspop8(c)))
157
-		(*ops[op])(c);
158
-	dodevices(c);
159
-	return 1;
160
-}
161
-
162
-int
163
-eval(Cpu *c)
164
-{
165
-	Uint8 instr = c->ram.dat[c->ram.ptr++];
166
-	if(c->literal > 0)
167
-		return doliteral(c, instr);
168
-	else
169
-		return doopcode(c, instr);
170
-	return 1;
171
-}
172
-
173
-int
174
-load(Cpu *c, char *filepath)
175
-{
176
-	FILE *f;
177
-	if(!(f = fopen(filepath, "rb")))
178
-		return error(c, "Missing input.", 0);
179
-	fread(c->ram.dat, sizeof(c->ram.dat), 1, f);
180
-	return 1;
181
-}
182
-
183
-void
184
-reset(Cpu *c)
185
-{
186
-	size_t i;
187
-	char *cptr = (char *)c;
188
-	for(i = 0; i < sizeof c; i++)
189
-		cptr[i] = 0;
190
-}
191
-
192
-int
193
-boot(Cpu *c)
194
-{
195
-	reset(c);
196
-	c->vreset = mempeek16(c, 0xfffa);
197
-	c->vframe = mempeek16(c, 0xfffc);
198
-	c->verror = mempeek16(c, 0xfffe);
199
-	/* eval reset */
200
-	c->ram.ptr = c->vreset;
201
-	setflag(&c->status, FLAG_HALT, 0);
202
-	while(!(c->status & FLAG_HALT) && eval(c))
203
-		c->counter++;
204
-	/* eval frame */
205
-	c->ram.ptr = c->vframe;
206
-	setflag(&c->status, FLAG_HALT, 0);
207
-	while(!(c->status & FLAG_HALT) && eval(c))
208
-		c->counter++;
209
-	return 1;
210
-}
211 0
new file mode 100644
... ...
@@ -0,0 +1,67 @@
1
+#include <stdio.h>
2
+#include "uxn.h"
3
+
4
+/*
5
+Copyright (c) 2021 Devine Lu Linvega
6
+
7
+Permission to use, copy, modify, and distribute this software for any
8
+purpose with or without fee is hereby granted, provided that the above
9
+copyright notice and this permission notice appear in all copies.
10
+
11
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
+WITH REGARD TO THIS SOFTWARE.
13
+*/
14
+
15
+void
16
+echos(Stack8 *s, Uint8 len, char *name)
17
+{
18
+	int i;
19
+	printf("\n%s\n", name);
20
+	for(i = 0; i < len; ++i) {
21
+		if(i % 16 == 0)
22
+			printf("\n");
23
+		printf("%02x%c", s->dat[i], s->ptr == i ? '<' : ' ');
24
+	}
25
+	printf("\n\n");
26
+}
27
+
28
+void
29
+echom(Memory *m, Uint8 len, char *name)
30
+{
31
+	int i;
32
+	printf("\n%s\n", name);
33
+	for(i = 0; i < len; ++i) {
34
+		if(i % 16 == 0)
35
+			printf("\n");
36
+		printf("%02x ", m->dat[i]);
37
+	}
38
+	printf("\n\n");
39
+}
40
+
41
+void
42
+echof(Uxn *c)
43
+{
44
+	printf("ended @ %d steps | hf: %x sf: %x sf: %x cf: %x\n",
45
+		c->counter,
46
+		getflag(&c->status, FLAG_HALT) != 0,
47
+		getflag(&c->status, FLAG_SHORT) != 0,
48
+		getflag(&c->status, FLAG_SIGN) != 0,
49
+		getflag(&c->status, FLAG_COND) != 0);
50
+}
51
+
52
+int
53
+main(int argc, char *argv[])
54
+{
55
+	Uxn cpu;
56
+	if(argc < 2)
57
+		return error(&cpu, "No input.", 0);
58
+	if(!load(&cpu, argv[1]))
59
+		return error(&cpu, "Load error", 0);
60
+	if(!boot(&cpu))
61
+		return error(&cpu, "Boot error", 0);
62
+	/* print result */
63
+	echos(&cpu.wst, 0x40, "stack");
64
+	echom(&cpu.ram, 0x40, "ram");
65
+	echof(&cpu);
66
+	return 0;
67
+}
... ...
@@ -1,5 +1,4 @@
1 1
 #include <stdio.h>
2
-#include "cpu.h"
3 2
 
4 3
 /*
5 4
 Copyright (c) 2021 Devine Lu Linvega
... ...
@@ -12,56 +11,200 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 11
 WITH REGARD TO THIS SOFTWARE.
13 12
 */
14 13
 
14
+#include "uxn.h"
15
+
16
+Uxn cpu;
17
+
18
+#pragma mark - Helpers
19
+
15 20
 void
16
-echos(Stack8 *s, Uint8 len, char *name)
21
+setflag(Uint8 *status, char flag, int b)
17 22
 {
18
-	int i;
19
-	printf("\n%s\n", name);
20
-	for(i = 0; i < len; ++i) {
21
-		if(i % 16 == 0)
22
-			printf("\n");
23
-		printf("%02x%c", s->dat[i], s->ptr == i ? '<' : ' ');
24
-	}
25
-	printf("\n\n");
23
+	if(b)
24
+		*status |= flag;
25
+	else
26
+		*status &= (~flag);
26 27
 }
27 28
 
28
-void
29
-echom(Memory *m, Uint8 len, char *name)
29
+int
30
+getflag(Uint8 *status, char flag)
31
+{
32
+	return *status & flag;
33
+}
34
+
35
+#pragma mark - Operations
36
+
37
+/* clang-format off */
38
+
39
+Uint16 bytes2short(Uint8 a, Uint8 b) { return (a << 8) + b; }
40
+Uint16 mempeek16(Uxn *c, Uint16 s) { return (c->ram.dat[s] << 8) + (c->ram.dat[s+1] & 0xff); }
41
+void wspush8(Uxn *c, Uint8 b) { c->wst.dat[c->wst.ptr++] = b; }
42
+void wspush16(Uxn *c, Uint16 s) { wspush8(c,s >> 8); wspush8(c,s & 0xff); }
43
+Uint8 wspop8(Uxn *c) { return c->wst.dat[--c->wst.ptr]; }
44
+Uint16 wspop16(Uxn *c) { return wspop8(c) + (wspop8(c) << 8); }
45
+Uint8 wspeek8(Uxn *c, Uint8 o) { return c->wst.dat[c->wst.ptr - o]; }
46
+Uint16 wspeek16(Uxn *c, Uint8 o) { return bytes2short(c->wst.dat[c->wst.ptr - o], c->wst.dat[c->wst.ptr - o + 1]); }
47
+Uint16 rspop16(Uxn *c) { return c->rst.dat[--c->rst.ptr]; }
48
+void rspush16(Uxn *c, Uint16 a) { c->rst.dat[c->rst.ptr++] = a; }
49
+/* I/O */
50
+void op_brk(Uxn *c) { setflag(&c->status,FLAG_HALT, 1); }
51
+void op_lit(Uxn *c) { c->literal += c->ram.dat[c->ram.ptr++]; }
52
+void op_nop(Uxn *c) { (void)c; printf("NOP");}
53
+void op_ldr(Uxn *c) { wspush8(c, c->ram.dat[wspop16(c)]); }
54
+void op_str(Uxn *c) { c->ram.dat[wspop16(c)] = wspop8(c); }
55
+/* Logic */
56
+void op_jmp(Uxn *c) { c->ram.ptr = wspop16(c); }
57
+void op_jsr(Uxn *c) { rspush16(c, c->ram.ptr); c->ram.ptr = wspop16(c); }
58
+void op_rts(Uxn *c) {	c->ram.ptr = rspop16(c); }
59
+/* Stack */
60
+void op_pop(Uxn *c) { wspop8(c); }
61
+void op_dup(Uxn *c) { wspush8(c,wspeek8(c,1)); }
62
+void op_swp(Uxn *c) { Uint8 b = wspop8(c), a = wspop8(c); wspush8(c,b); wspush8(c,a); }
63
+void op_ovr(Uxn *c) { Uint8 a = wspeek8(c,2); wspush8(c,a); }
64
+void op_rot(Uxn *c) { Uint8 c1 = wspop8(c),b = wspop8(c),a = wspop8(c); wspush8(c,b); wspush8(c, c1); wspush8(c,a); }
65
+void op_and(Uxn *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,a & b); }
66
+void op_ora(Uxn *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,a | b); }
67
+void op_rol(Uxn *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,a << b); }
68
+/* Arithmetic */
69
+void op_add(Uxn *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b + a); }
70
+void op_sub(Uxn *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b - a); }
71
+void op_mul(Uxn *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b * a); }
72
+void op_div(Uxn *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b / a); }
73
+void op_equ(Uxn *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b == a); }
74
+void op_neq(Uxn *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b != a); }
75
+void op_gth(Uxn *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b > a); }
76
+void op_lth(Uxn *c) { Uint8 a = wspop8(c), b = wspop8(c); wspush8(c,b < a); }
77
+/* Stack(16-bits) */
78
+void op_pop16(Uxn *c) { wspop16(c); }
79
+void op_dup16(Uxn *c) { wspush16(c,wspeek16(c,2)); }
80
+void op_swp16(Uxn *c) { Uint16 b = wspop16(c), a = wspop16(c); wspush16(c,b); wspush16(c,a); }
81
+void op_ovr16(Uxn *c) { Uint16 a = wspeek16(c, 4); wspush16(c,a); }
82
+void op_rot16(Uxn *c) { Uint16 c1 = wspop16(c), b = wspop16(c), a = wspop16(c); wspush16(c,b); wspush16(c, c1); wspush16(c,a); }
83
+void op_and16(Uxn *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush16(c,a & b); }
84
+void op_ora16(Uxn *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush16(c,a | b); }
85
+void op_rol16(Uxn *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush16(c,a << b); }
86
+/* Arithmetic(16-bits) */
87
+void op_add16(Uxn *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush16(c,b + a); }
88
+void op_sub16(Uxn *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush16(c,b - a); }
89
+void op_mul16(Uxn *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush16(c,b * a); }
90
+void op_div16(Uxn *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush16(c,b / a); }
91
+void op_equ16(Uxn *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush8(c,b == a); }
92
+void op_neq16(Uxn *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush8(c,b != a); }
93
+void op_gth16(Uxn *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush8(c,b > a); }
94
+void op_lth16(Uxn *c) { Uint16 a = wspop16(c), b = wspop16(c); wspush8(c,b < a); }
95
+
96
+void (*ops[])(Uxn *c) = {
97
+	op_brk, op_lit, op_nop, op_nop, op_nop, op_nop, op_ldr, op_str, 
98
+	op_jmp, op_jsr, op_nop, op_rts, op_nop, op_nop, op_nop, op_nop, 
99
+	op_pop, op_dup, op_swp, op_ovr, op_rot, op_and, op_ora, op_rol,
100
+	op_add, op_sub, op_mul, op_div, op_equ, op_neq, op_gth, op_lth,
101
+	op_pop16, op_dup16, op_swp16, op_ovr16, op_rot16, op_and16, op_ora16, op_rol16,
102
+	op_add16, op_sub16, op_mul16, op_div16, op_equ16, op_neq16, op_gth16, op_lth16
103
+};
104
+
105
+Uint8 opr[][2] = { 
106
+	{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {2,1}, {3,0},
107
+	{2,0}, {2,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0},
108
+	{1,0}, {1,2}, {2,2}, {3,3}, {3,3}, {2,1}, {2,1}, {2,1},
109
+	{2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1},
110
+	{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, /* TODO */
111
+	{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}  /* TODO */
112
+};
113
+
114
+/* clang-format on */
115
+
116
+int
117
+error(Uxn *c, char *name, int id)
118
+{
119
+	printf("Error: %s#%04x, at 0x%04x\n", name, id, c->counter);
120
+	return 0;
121
+}
122
+
123
+int
124
+doliteral(Uxn *c, Uint8 instr)
125
+{
126
+	if(c->wst.ptr >= 255)
127
+		return error(c, "Stack overflow", instr);
128
+	wspush8(c, instr);
129
+	c->literal--;
130
+	return 1;
131
+}
132
+
133
+int
134
+dodevices(Uxn *c) /* experimental */
30 135
 {
31
-	int i;
32
-	printf("\n%s\n", name);
33
-	for(i = 0; i < len; ++i) {
34
-		if(i % 16 == 0)
35
-			printf("\n");
36
-		printf("%02x ", m->dat[i]);
136
+	if(c->ram.dat[0xfff1]) {
137
+		printf("%c", c->ram.dat[0xfff1]);
138
+		c->ram.dat[0xfff1] = 0x00;
37 139
 	}
38
-	printf("\n\n");
140
+	return 1;
141
+}
142
+
143
+int
144
+doopcode(Uxn *c, Uint8 instr)
145
+{
146
+	Uint8 op = instr & 0x1f;
147
+	setflag(&c->status, FLAG_SHORT, (instr >> 5) & 1);
148
+	setflag(&c->status, FLAG_SIGN, (instr >> 6) & 1); /* usused */
149
+	setflag(&c->status, FLAG_COND, (instr >> 7) & 1);
150
+	if(getflag(&c->status, FLAG_SHORT))
151
+		op += 16;
152
+	if(c->wst.ptr < opr[op][0])
153
+		return error(c, "Stack underflow", op);
154
+	if(c->wst.ptr + opr[op][1] - opr[op][0] >= 255)
155
+		return error(c, "Stack overflow", instr);
156
+	if(!getflag(&c->status, FLAG_COND) || (getflag(&c->status, FLAG_COND) && wspop8(c)))
157
+		(*ops[op])(c);
158
+	dodevices(c);
159
+	return 1;
160
+}
161
+
162
+int
163
+eval(Uxn *c)
164
+{
165
+	Uint8 instr = c->ram.dat[c->ram.ptr++];
166
+	if(c->literal > 0)
167
+		return doliteral(c, instr);
168
+	else
169
+		return doopcode(c, instr);
170
+	return 1;
171
+}
172
+
173
+int
174
+load(Uxn *c, char *filepath)
175
+{
176
+	FILE *f;
177
+	if(!(f = fopen(filepath, "rb")))
178
+		return error(c, "Missing input.", 0);
179
+	fread(c->ram.dat, sizeof(c->ram.dat), 1, f);
180
+	return 1;
39 181
 }
40 182
 
41 183
 void
42
-echof(Cpu *c)
184
+reset(Uxn *c)
43 185
 {
44
-	printf("ended @ %d steps | hf: %x sf: %x sf: %x cf: %x\n",
45
-		c->counter,
46
-		getflag(&c->status, FLAG_HALT) != 0,
47
-		getflag(&c->status, FLAG_SHORT) != 0,
48
-		getflag(&c->status, FLAG_SIGN) != 0,
49
-		getflag(&c->status, FLAG_COND) != 0);
186
+	size_t i;
187
+	char *cptr = (char *)c;
188
+	for(i = 0; i < sizeof c; i++)
189
+		cptr[i] = 0;
50 190
 }
51 191
 
52 192
 int
53
-main(int argc, char *argv[])
193
+boot(Uxn *c)
54 194
 {
55
-	Cpu cpu;
56
-	if(argc < 2)
57
-		return error(&cpu, "No input.", 0);
58
-	if(!load(&cpu, argv[1]))
59
-		return error(&cpu, "Load error", 0);
60
-	if(!boot(&cpu))
61
-		return error(&cpu, "Boot error", 0);
62
-	/* print result */
63
-	echos(&cpu.wst, 0x40, "stack");
64
-	echom(&cpu.ram, 0x40, "ram");
65
-	echof(&cpu);
66
-	return 0;
195
+	reset(c);
196
+	c->vreset = mempeek16(c, 0xfffa);
197
+	c->vframe = mempeek16(c, 0xfffc);
198
+	c->verror = mempeek16(c, 0xfffe);
199
+	/* eval reset */
200
+	c->ram.ptr = c->vreset;
201
+	setflag(&c->status, FLAG_HALT, 0);
202
+	while(!(c->status & FLAG_HALT) && eval(c))
203
+		c->counter++;
204
+	/* eval frame */
205
+	c->ram.ptr = c->vframe;
206
+	setflag(&c->status, FLAG_HALT, 0);
207
+	while(!(c->status & FLAG_HALT) && eval(c))
208
+		c->counter++;
209
+	return 1;
67 210
 }
68 211
similarity index 90%
69 212
rename from cpu.h
70 213
rename to uxn.h
... ...
@@ -40,10 +40,10 @@ typedef struct {
40 40
 	Stack8 wst;
41 41
 	Stack16 rst;
42 42
 	Memory ram;
43
-} Cpu;
43
+} Uxn;
44 44
 
45 45
 void setflag(Uint8 *status, char flag, int b);
46 46
 int getflag(Uint8 *status, char flag);
47
-int error(Cpu *c, char *name, int id);
48
-int load(Cpu *c, char *filepath);
49
-int boot(Cpu *c);
47
+int error(Uxn *c, char *name, int id);
48
+int load(Uxn *c, char *filepath);
49
+int boot(Uxn *c);