... | ... |
@@ -31,7 +31,7 @@ Program p; |
31 | 31 |
/* clang-format off */ |
32 | 32 |
|
33 | 33 |
char ops[][4] = { |
34 |
- "BRK", "LIT", "---", "---", "PEK", "POK", "LDR", "STR", |
|
34 |
+ "BRK", "LIT", "---", "---", "IOR", "IOW", "LDR", "STR", |
|
35 | 35 |
"JMP", "JSR", "RTI", "RTS", "---", "---", "---", "---", |
36 | 36 |
"POP", "DUP", "SWP", "OVR", "ROT", "AND", "ORA", "ROL", |
37 | 37 |
"ADD", "SUB", "MUL", "DIV", "EQU", "NEQ", "GTH", "LTH" |
... | ... |
@@ -8,19 +8,21 @@ clang-format -i assembler.c |
8 | 8 |
rm -f ./bin/assembler |
9 | 9 |
rm -f ./bin/boot.rom |
10 | 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 |
|
12 | 11 |
|
13 |
-# Cli |
|
14 |
-clang-format -i cli.c |
|
12 |
+# Core |
|
15 | 13 |
clang-format -i uxn.h |
16 | 14 |
clang-format -i uxn.c |
15 |
+ |
|
16 |
+# Cli |
|
17 |
+clang-format -i cli.c |
|
17 | 18 |
rm -f ./bin/cli |
18 | 19 |
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 cli.c -o bin/cli |
19 | 20 |
|
20 | 21 |
# Emulator |
21 |
-# clang-format -i emulator.c |
|
22 |
+clang-format -i emulator.c |
|
22 | 23 |
# rm -f ./bin/emulator |
23 | 24 |
# 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 -L/usr/local/lib -lSDL2 -o bin/emulator |
24 | 25 |
|
25 | 26 |
# run |
27 |
+./bin/assembler examples/hello.usm bin/boot.rom |
|
26 | 28 |
./bin/cli bin/boot.rom |
... | ... |
@@ -20,19 +20,19 @@ error(char *msg, const char *err) |
20 | 20 |
return 0; |
21 | 21 |
} |
22 | 22 |
|
23 |
-void |
|
24 |
-console_onread(Uint8 *b) |
|
23 |
+Uint8 |
|
24 |
+console_onread(Uint8 b) |
|
25 | 25 |
{ |
26 | 26 |
(void)b; |
27 |
+ return 0; |
|
27 | 28 |
} |
28 | 29 |
|
29 |
-void |
|
30 |
-console_onwrite(Uint8 *b) |
|
30 |
+Uint8 |
|
31 |
+console_onwrite(Uint8 b) |
|
31 | 32 |
{ |
32 |
- if(b) { |
|
33 |
- printf("%c", *b); |
|
34 |
- *b = 0x00; |
|
35 |
- } |
|
33 |
+ if(b) |
|
34 |
+ printf("%c", b); |
|
35 |
+ return 0; |
|
36 | 36 |
} |
37 | 37 |
|
38 | 38 |
void |
... | ... |
@@ -64,7 +64,7 @@ echom(Memory *m, Uint16 len, char *name) |
64 | 64 |
void |
65 | 65 |
echof(Uxn *c) |
66 | 66 |
{ |
67 |
- printf("ended @ %d steps | hf: %x sf: %x sf: %x cf: %x\n", |
|
67 |
+ printf("\nEnded @ %d steps | hf: %x sf: %x sf: %x cf: %x\n", |
|
68 | 68 |
c->counter, |
69 | 69 |
getflag(&c->status, FLAG_HALT) != 0, |
70 | 70 |
getflag(&c->status, FLAG_SHORT) != 0, |
... | ... |
@@ -82,14 +82,14 @@ main(int argc, char **argv) |
82 | 82 |
return error("Boot", "Failed"); |
83 | 83 |
if(!loaduxn(&u, argv[1])) |
84 | 84 |
return error("Load", "Failed"); |
85 |
- portuxn(&u, 0xfff0, 0xfff1, console_onread, console_onwrite); |
|
85 |
+ portuxn(&u, "console", console_onread, console_onwrite); |
|
86 | 86 |
evaluxn(&u, u.vreset); |
87 | 87 |
evaluxn(&u, u.vframe); |
88 |
- |
|
89 |
-/* |
|
88 |
+ |
|
89 |
+ /* |
|
90 | 90 |
echos(&u.wst, 0x40, "stack"); |
91 | 91 |
echom(&u.ram, 0x40, "ram"); |
92 |
- echof(&u); |
|
93 | 92 |
*/ |
93 |
+ echof(&u); |
|
94 | 94 |
return 0; |
95 | 95 |
} |
... | ... |
@@ -150,13 +150,33 @@ dokey(SDL_Event *event) |
150 | 150 |
#pragma mark - Devices |
151 | 151 |
|
152 | 152 |
void |
153 |
-console_onread(void) |
|
153 |
+console_onread(Uint8 *b) |
|
154 | 154 |
{ |
155 |
+ (void)b; |
|
155 | 156 |
} |
156 | 157 |
|
157 | 158 |
void |
158 |
-console_onwrite(void) |
|
159 |
+console_onwrite(Uint8 *b) |
|
159 | 160 |
{ |
161 |
+ if(b) { |
|
162 |
+ printf("%c", *b); |
|
163 |
+ fflush(stdout); |
|
164 |
+ *b = 0x00; |
|
165 |
+ } |
|
166 |
+} |
|
167 |
+ |
|
168 |
+Uint8 ppumem[5]; |
|
169 |
+ |
|
170 |
+void |
|
171 |
+ppur(Uint8 *b) |
|
172 |
+{ |
|
173 |
+} |
|
174 |
+ |
|
175 |
+void |
|
176 |
+ppuw(Uint8 *b) |
|
177 |
+{ |
|
178 |
+ |
|
179 |
+ printf("%02x\n", *b); |
|
160 | 180 |
} |
161 | 181 |
|
162 | 182 |
int |
... | ... |
@@ -201,7 +221,8 @@ main(int argc, char **argv) |
201 | 221 |
if(!init()) |
202 | 222 |
return error("Init", "Failed"); |
203 | 223 |
|
204 |
- portuxn(&u, 0xfff0, 0xfff1, console_onread, console_onwrite); |
|
224 |
+ portuxn(&u, 0xfff0, console_onread, console_onwrite); |
|
225 |
+ portuxn(&u, 0xfff2, ppur, ppuw); |
|
205 | 226 |
|
206 | 227 |
start(&u); |
207 | 228 |
|
... | ... |
@@ -1,15 +1,13 @@ |
1 | 1 |
( hello world ) |
2 | 2 |
|
3 | 3 |
;iterator |
4 |
-:dev1r FFF0 |
|
5 |
-:dev1w FFF1 |
|
6 | 4 |
|
7 | 5 |
|0100 @RESET |
8 | 6 |
|
9 | 7 |
@word1 "hello_word ( len: 0x0b ) |
10 | 8 |
|
11 | 9 |
@loop |
12 |
- ,dev1w STR ( write to stdout ) |
|
10 |
+ ,00 IOW ( write to device#0 ) |
|
13 | 11 |
,incr JSR ( increment itr ) |
14 | 12 |
,word1 ,strlen JSR ( get strlen ) |
15 | 13 |
NEQ ,loop ROT JSR? ( loop != strlen ) |
16 | 14 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,20 @@ |
1 |
+( hello world ) |
|
2 |
+ |
|
3 |
+:stdr FFF0 |
|
4 |
+:stdw FFF1 |
|
5 |
+:ppur FFF2 |
|
6 |
+:ppuw FFF3 |
|
7 |
+ |
|
8 |
+|0100 @RESET |
|
9 |
+ |
|
10 |
+ ,11 ,ppuw STR ( x0 ) |
|
11 |
+ ,23 ,ppuw STR ( x1 ) |
|
12 |
+ ,12 ,ppuw STR ( y0 ) |
|
13 |
+ ,34 ,ppuw STR ( y1 ) |
|
14 |
+ ,01 ,ppuw STR ( clr ) |
|
15 |
+ |
|
16 |
+BRK |
|
17 |
+ |
|
18 |
+|c000 @FRAME BRK |
|
19 |
+|d000 @ERROR BRK |
|
20 |
+|FFFA .RESET .FRAME .ERROR |
... | ... |
@@ -33,8 +33,10 @@ Uint16 mempeek16(Uxn *u, Uint16 s) { return (u->ram.dat[s] << 8) + (u->ram.dat[s |
33 | 33 |
void op_brk(Uxn *u) { setflag(&u->status,FLAG_HALT, 1); } |
34 | 34 |
void op_lit(Uxn *u) { u->literal += u->ram.dat[u->ram.ptr++]; } |
35 | 35 |
void op_nop(Uxn *u) { printf("NOP"); (void)u; } |
36 |
-void op_ldr(Uxn *u) { wspush8(u, u->ram.dat[wspop16(u)]); } |
|
37 |
-void op_str(Uxn *u) { u->ram.dat[wspop16(u)] = wspop8(u); } |
|
36 |
+void op_ior(Uxn *u) { Uint8 devid = wspop8(u); Uint8 devop = wspop8(u); Device *dev = &u->dev[devid]; if(dev) wspush8(u, dev->rfn(devop)); } |
|
37 |
+void op_iow(Uxn *u) { Uint8 devid = wspop8(u); Uint8 devop = wspop8(u); Device *dev = &u->dev[devid]; if(dev) dev->wfn(devop); } |
|
38 |
+void op_ldr(Uxn *u) { Uint16 a = wspop16(u); wspush8(u, u->ram.dat[a]); } |
|
39 |
+void op_str(Uxn *u) { Uint16 a = wspop16(u); Uint8 b = wspop8(u); u->ram.dat[a] = b; } |
|
38 | 40 |
/* Logic */ |
39 | 41 |
void op_jmp(Uxn *u) { u->ram.ptr = wspop16(u); } |
40 | 42 |
void op_jsr(Uxn *u) { u->rst.dat[u->rst.ptr++] = u->ram.ptr; u->ram.ptr = wspop16(u); } |
... | ... |
@@ -77,7 +79,7 @@ void op_gth16(Uxn *u) { Uint16 a = wspop16(u), b = wspop16(u); wspush8(u, b > a) |
77 | 79 |
void op_lth16(Uxn *u) { Uint16 a = wspop16(u), b = wspop16(u); wspush8(u, b < a); } |
78 | 80 |
|
79 | 81 |
void (*ops[])(Uxn *u) = { |
80 |
- op_brk, op_lit, op_nop, op_nop, op_nop, op_nop, op_ldr, op_str, |
|
82 |
+ op_brk, op_lit, op_nop, op_nop, op_ior, op_iow, op_ldr, op_str, |
|
81 | 83 |
op_jmp, op_jsr, op_nop, op_rts, op_nop, op_nop, op_nop, op_nop, |
82 | 84 |
op_pop, op_dup, op_swp, op_ovr, op_rot, op_and, op_ora, op_rol, |
83 | 85 |
op_add, op_sub, op_mul, op_div, op_equ, op_neq, op_gth, op_lth, |
... | ... |
@@ -86,7 +88,7 @@ void (*ops[])(Uxn *u) = { |
86 | 88 |
}; |
87 | 89 |
|
88 | 90 |
Uint8 opr[][2] = { |
89 |
- {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {2,1}, {3,0}, |
|
91 |
+ {0,0}, {0,0}, {0,0}, {0,0}, {2,1}, {2,0}, {2,1}, {3,0}, |
|
90 | 92 |
{2,0}, {2,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, |
91 | 93 |
{1,0}, {1,2}, {2,2}, {3,3}, {3,3}, {2,1}, {2,1}, {2,1}, |
92 | 94 |
{2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, {2,1}, |
... | ... |
@@ -113,17 +115,6 @@ lituxn(Uxn *u, Uint8 instr) |
113 | 115 |
return 1; |
114 | 116 |
} |
115 | 117 |
|
116 |
-int |
|
117 |
-devuxn(Uxn *u) |
|
118 |
-{ |
|
119 |
- int i; |
|
120 |
- for(i = 0; i < u->devices; ++i) { |
|
121 |
- u->dev[i].wfn(&u->ram.dat[u->dev[i].w]); |
|
122 |
- u->dev[i].rfn(&u->ram.dat[u->dev[i].r]); |
|
123 |
- } |
|
124 |
- return 1; |
|
125 |
-} |
|
126 |
- |
|
127 | 118 |
int |
128 | 119 |
opcuxn(Uxn *u, Uint8 instr) |
129 | 120 |
{ |
... | ... |
@@ -139,7 +130,6 @@ opcuxn(Uxn *u, Uint8 instr) |
139 | 130 |
return haltuxn(u, "Stack overflow", instr); |
140 | 131 |
if(!getflag(&u->status, FLAG_COND) || (getflag(&u->status, FLAG_COND) && wspop8(u))) |
141 | 132 |
(*ops[op])(u); |
142 |
- devuxn(u); |
|
143 | 133 |
return 1; |
144 | 134 |
} |
145 | 135 |
|
... | ... |
@@ -197,13 +187,11 @@ loaduxn(Uxn *u, char *filepath) |
197 | 187 |
/* to start: evaluxn(u, u->vreset); */ |
198 | 188 |
|
199 | 189 |
int |
200 |
-portuxn(Uxn *u, Uint16 r, Uint16 w, void (*onread)(Uint8 *), void (*onwrite)(Uint8 *)) |
|
190 |
+portuxn(Uxn *u, char *name, Uint8 (*onread)(Uint8), Uint8 (*onwrite)(Uint8)) |
|
201 | 191 |
{ |
202 | 192 |
Device *d = &u->dev[u->devices++]; |
203 |
- d->r = r; |
|
204 |
- d->w = w; |
|
205 | 193 |
d->rfn = onread; |
206 | 194 |
d->wfn = onwrite; |
207 |
- printf("Created device: #%d, at r:%04x w:%04x\n", u->devices, r, w); |
|
195 |
+ printf("Device#%d: %s \n", u->devices, name); |
|
208 | 196 |
return 1; |
209 | 197 |
} |
... | ... |
@@ -35,9 +35,9 @@ typedef struct { |
35 | 35 |
} Memory; |
36 | 36 |
|
37 | 37 |
typedef struct { |
38 |
- Uint16 r, w; |
|
39 |
- void (*rfn)(Uint8 *); |
|
40 |
- void (*wfn)(Uint8 *); |
|
38 |
+ Uint16 index; |
|
39 |
+ Uint8 (*rfn)(Uint8); |
|
40 |
+ Uint8 (*wfn)(Uint8); |
|
41 | 41 |
} Device; |
42 | 42 |
|
43 | 43 |
typedef struct { |
... | ... |
@@ -46,7 +46,7 @@ typedef struct { |
46 | 46 |
Stack8 wst; |
47 | 47 |
Stack16 rst; |
48 | 48 |
Memory ram; |
49 |
- Device dev[64]; |
|
49 |
+ Device dev[256]; |
|
50 | 50 |
} Uxn; |
51 | 51 |
|
52 | 52 |
void setflag(Uint8 *status, char flag, int b); |
... | ... |
@@ -54,4 +54,4 @@ int getflag(Uint8 *status, char flag); |
54 | 54 |
int loaduxn(Uxn *c, char *filepath); |
55 | 55 |
int bootuxn(Uxn *c); |
56 | 56 |
int evaluxn(Uxn *u, Uint16 vec); |
57 |
-int portuxn(Uxn *u, Uint16 r, Uint16 w, void (*onread)(Uint8 *), void (*onwrite)(Uint8 *)); |
|
57 |
+int portuxn(Uxn *u, char *name, Uint8 (*onread)(Uint8), Uint8 (*onwrite)(Uint8)); |