... | ... |
@@ -117,11 +117,9 @@ echo "Assembling(asma).." |
117 | 117 |
if [ $norun = 1 ]; then exit; fi |
118 | 118 |
|
119 | 119 |
echo "Assembling(piano).." |
120 |
-bin/uxncli bin/asma.rom projects/software/piano.tal bin/piano.rom 2> bin/piano.log |
|
120 |
+./bin/uxnasm projects/software/piano.tal bin/piano.rom 2> bin/piano.log |
|
121 | 121 |
|
122 | 122 |
echo "Running.." |
123 |
-cd bin |
|
124 |
-./uxnemu piano.rom |
|
123 |
+./bin/uxnemu bin/piano.rom |
|
125 | 124 |
|
126 | 125 |
echo "Done." |
127 |
-cd .. |
... | ... |
@@ -4,8 +4,7 @@ |
4 | 4 |
#include "datetime.h" |
5 | 5 |
|
6 | 6 |
/* |
7 |
-Copyright (c) 2021 Devine Lu Linvega |
|
8 |
-Copyright (c) 2021 Andrew Alderwick |
|
7 |
+Copyright (c) 2021 Devine Lu Linvega, Andrew Alderwick |
|
9 | 8 |
|
10 | 9 |
Permission to use, copy, modify, and distribute this software for any |
11 | 10 |
purpose with or without fee is hereby granted, provided that the above |
... | ... |
@@ -16,7 +15,7 @@ WITH REGARD TO THIS SOFTWARE. |
16 | 15 |
*/ |
17 | 16 |
|
18 | 17 |
Uint8 |
19 |
-datetime_dei(Device *d, Uint8 port) |
|
18 |
+datetime_dei(Uint8 *d, Uint8 port) |
|
20 | 19 |
{ |
21 | 20 |
time_t seconds = time(NULL); |
22 | 21 |
struct tm zt = {0}; |
... | ... |
@@ -35,6 +34,6 @@ datetime_dei(Device *d, Uint8 port) |
35 | 34 |
case 0x8: return t->tm_yday >> 8; |
36 | 35 |
case 0x9: return t->tm_yday; |
37 | 36 |
case 0xa: return t->tm_isdst; |
38 |
- default: return d->dat[port]; |
|
37 |
+ default: return d[port]; |
|
39 | 38 |
} |
40 | 39 |
} |
... | ... |
@@ -1,6 +1,5 @@ |
1 | 1 |
/* |
2 |
-Copyright (c) 2021 Devine Lu Linvega |
|
3 |
-Copyright (c) 2021 Andrew Alderwick |
|
2 |
+Copyright (c) 2021 Devine Lu Linvega, Andrew Alderwick |
|
4 | 3 |
|
5 | 4 |
Permission to use, copy, modify, and distribute this software for any |
6 | 5 |
purpose with or without fee is hereby granted, provided that the above |
... | ... |
@@ -10,4 +9,4 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
10 | 9 |
WITH REGARD TO THIS SOFTWARE. |
11 | 10 |
*/ |
12 | 11 |
|
13 |
-Uint8 datetime_dei(Device *d, Uint8 port); |
|
12 |
+Uint8 datetime_dei(Uint8 *d, Uint8 port); |
... | ... |
@@ -1,15 +1,22 @@ |
1 |
+#define _XOPEN_SOURCE 500 |
|
1 | 2 |
#include <stdio.h> |
2 | 3 |
#include <dirent.h> |
4 |
+#include <errno.h> |
|
5 |
+#include <limits.h> |
|
3 | 6 |
#include <string.h> |
7 |
+#include <stdlib.h> |
|
4 | 8 |
#include <sys/stat.h> |
5 | 9 |
#include <unistd.h> |
6 | 10 |
|
11 |
+#ifndef PATH_MAX |
|
12 |
+#define PATH_MAX 4096 |
|
13 |
+#endif |
|
14 |
+ |
|
7 | 15 |
#include "../uxn.h" |
8 | 16 |
#include "file.h" |
9 | 17 |
|
10 | 18 |
/* |
11 |
-Copyright (c) 2021 Devine Lu Linvega |
|
12 |
-Copyright (c) 2021 Andrew Alderwick |
|
19 |
+Copyright (c) 2021 Devine Lu Linvega, Andrew Alderwick |
|
13 | 20 |
|
14 | 21 |
Permission to use, copy, modify, and distribute this software for any |
15 | 22 |
purpose with or without fee is hereby granted, provided that the above |
... | ... |
@@ -28,6 +35,7 @@ typedef struct { |
28 | 35 |
FILE_READ, |
29 | 36 |
FILE_WRITE, |
30 | 37 |
DIR_READ } state; |
38 |
+ int outside_sandbox; |
|
31 | 39 |
} UxnFile; |
32 | 40 |
|
33 | 41 |
static UxnFile uxn_file[POLYFILEY]; |
... | ... |
@@ -45,6 +53,7 @@ reset(UxnFile *c) |
45 | 53 |
} |
46 | 54 |
c->de = NULL; |
47 | 55 |
c->state = IDLE; |
56 |
+ c->outside_sandbox = 0; |
|
48 | 57 |
} |
49 | 58 |
|
50 | 59 |
static Uint16 |
... | ... |
@@ -66,13 +75,24 @@ get_entry(char *p, Uint16 len, const char *pathname, const char *basename, int f |
66 | 75 |
static Uint16 |
67 | 76 |
file_read_dir(UxnFile *c, char *dest, Uint16 len) |
68 | 77 |
{ |
69 |
- static char pathname[4356]; |
|
78 |
+ static char pathname[4352]; |
|
70 | 79 |
char *p = dest; |
71 | 80 |
if(c->de == NULL) c->de = readdir(c->dir); |
72 | 81 |
for(; c->de != NULL; c->de = readdir(c->dir)) { |
73 | 82 |
Uint16 n; |
74 | 83 |
if(c->de->d_name[0] == '.' && c->de->d_name[1] == '\0') |
75 | 84 |
continue; |
85 |
+ if(strcmp(c->de->d_name, "..") == 0) { |
|
86 |
+ /* hide "sandbox/.." */ |
|
87 |
+ char cwd[PATH_MAX] = {'\0'}, t[PATH_MAX] = {'\0'}; |
|
88 |
+ /* Note there's [currently] no way of chdir()ing from uxn, so $PWD |
|
89 |
+ * is always the sandbox top level. */ |
|
90 |
+ getcwd(cwd, sizeof(cwd)); |
|
91 |
+ /* We already checked that c->current_filename exists so don't need a wrapper. */ |
|
92 |
+ realpath(c->current_filename, t); |
|
93 |
+ if(strcmp(cwd, t) == 0) |
|
94 |
+ continue; |
|
95 |
+ } |
|
76 | 96 |
if(strlen(c->current_filename) + 1 + strlen(c->de->d_name) < sizeof(pathname)) |
77 | 97 |
sprintf(pathname, "%s/%s", c->current_filename, c->de->d_name); |
78 | 98 |
else |
... | ... |
@@ -85,16 +105,62 @@ file_read_dir(UxnFile *c, char *dest, Uint16 len) |
85 | 105 |
return p - dest; |
86 | 106 |
} |
87 | 107 |
|
108 |
+static char * |
|
109 |
+retry_realpath(const char *file_name) |
|
110 |
+{ |
|
111 |
+ char r[PATH_MAX] = {'\0'}, p[PATH_MAX] = {'\0'}, *x; |
|
112 |
+ if(file_name == NULL) { |
|
113 |
+ errno = EINVAL; |
|
114 |
+ return NULL; |
|
115 |
+ } else if(strlen(file_name) >= PATH_MAX) { |
|
116 |
+ errno = ENAMETOOLONG; |
|
117 |
+ return NULL; |
|
118 |
+ } |
|
119 |
+ if(file_name[0] != '/') { |
|
120 |
+ /* TODO: use a macro instead of '/' for absolute path first character so that other systems can work */ |
|
121 |
+ /* if a relative path, prepend cwd */ |
|
122 |
+ getcwd(p, sizeof(p)); |
|
123 |
+ strcat(p, "/"); /* TODO: use a macro instead of '/' for the path delimiter */ |
|
124 |
+ } |
|
125 |
+ strcat(p, file_name); |
|
126 |
+ while(realpath(p, r) == NULL) { |
|
127 |
+ if(errno != ENOENT) |
|
128 |
+ return NULL; |
|
129 |
+ x = strrchr(p, '/'); /* TODO: path delimiter macro */ |
|
130 |
+ if(x) |
|
131 |
+ *x = '\0'; |
|
132 |
+ else |
|
133 |
+ return NULL; |
|
134 |
+ } |
|
135 |
+ return strdup(r); |
|
136 |
+} |
|
137 |
+ |
|
138 |
+static void |
|
139 |
+file_check_sandbox(UxnFile *c) |
|
140 |
+{ |
|
141 |
+ char *x, *rp, cwd[PATH_MAX] = {'\0'}; |
|
142 |
+ x = getcwd(cwd, sizeof(cwd)); |
|
143 |
+ rp = retry_realpath(c->current_filename); |
|
144 |
+ if(rp == NULL || (x && strncmp(cwd, rp, strlen(cwd)) != 0)) { |
|
145 |
+ c->outside_sandbox = 1; |
|
146 |
+ fprintf(stderr, "file warning: blocked attempt to access %s outside of sandbox\n", c->current_filename); |
|
147 |
+ } |
|
148 |
+ free(rp); |
|
149 |
+} |
|
150 |
+ |
|
88 | 151 |
static Uint16 |
89 |
-file_init(UxnFile *c, char *filename, size_t max_len) |
|
152 |
+file_init(UxnFile *c, char *filename, size_t max_len, int override_sandbox) |
|
90 | 153 |
{ |
91 | 154 |
char *p = c->current_filename; |
92 | 155 |
size_t len = sizeof(c->current_filename); |
93 | 156 |
reset(c); |
94 | 157 |
if(len > max_len) len = max_len; |
95 | 158 |
while(len) { |
96 |
- if((*p++ = *filename++) == '\0') |
|
159 |
+ if((*p++ = *filename++) == '\0') { |
|
160 |
+ if(!override_sandbox) /* override sandbox for loading roms */ |
|
161 |
+ file_check_sandbox(c); |
|
97 | 162 |
return 0; |
163 |
+ } |
|
98 | 164 |
len--; |
99 | 165 |
} |
100 | 166 |
c->current_filename[0] = '\0'; |
... | ... |
@@ -104,6 +170,7 @@ file_init(UxnFile *c, char *filename, size_t max_len) |
104 | 170 |
static Uint16 |
105 | 171 |
file_read(UxnFile *c, void *dest, Uint16 len) |
106 | 172 |
{ |
173 |
+ if(c->outside_sandbox) return 0; |
|
107 | 174 |
if(c->state != FILE_READ && c->state != DIR_READ) { |
108 | 175 |
reset(c); |
109 | 176 |
if((c->dir = opendir(c->current_filename)) != NULL) |
... | ... |
@@ -122,6 +189,7 @@ static Uint16 |
122 | 189 |
file_write(UxnFile *c, void *src, Uint16 len, Uint8 flags) |
123 | 190 |
{ |
124 | 191 |
Uint16 ret = 0; |
192 |
+ if(c->outside_sandbox) return 0; |
|
125 | 193 |
if(c->state != FILE_WRITE) { |
126 | 194 |
reset(c); |
127 | 195 |
if((c->f = fopen(c->current_filename, (flags & 0x01) ? "ab" : "wb")) != NULL) |
... | ... |
@@ -138,6 +206,7 @@ static Uint16 |
138 | 206 |
file_stat(UxnFile *c, void *dest, Uint16 len) |
139 | 207 |
{ |
140 | 208 |
char *basename = strrchr(c->current_filename, '/'); |
209 |
+ if(c->outside_sandbox) return 0; |
|
141 | 210 |
if(basename != NULL) |
142 | 211 |
basename++; |
143 | 212 |
else |
... | ... |
@@ -148,72 +217,66 @@ file_stat(UxnFile *c, void *dest, Uint16 len) |
148 | 217 |
static Uint16 |
149 | 218 |
file_delete(UxnFile *c) |
150 | 219 |
{ |
151 |
- return unlink(c->current_filename); |
|
152 |
-} |
|
153 |
- |
|
154 |
-static UxnFile * |
|
155 |
-file_instance(Device *d) |
|
156 |
-{ |
|
157 |
- return &uxn_file[d - &d->u->devold[DEV_FILE0]]; |
|
220 |
+ return c->outside_sandbox ? 0 : unlink(c->current_filename); |
|
158 | 221 |
} |
159 | 222 |
|
160 | 223 |
/* IO */ |
161 | 224 |
|
162 | 225 |
void |
163 |
-file_deo(Device *d, Uint8 port) |
|
226 |
+file_deo(Uint8 id, Uint8 *ram, Uint8 *d, Uint8 port) |
|
164 | 227 |
{ |
165 |
- UxnFile *c = file_instance(d); |
|
228 |
+ UxnFile *c = &uxn_file[id]; |
|
166 | 229 |
Uint16 addr, len, res; |
167 | 230 |
switch(port) { |
168 | 231 |
case 0x5: |
169 |
- DEVPEEK16(addr, 0x4); |
|
170 |
- DEVPEEK16(len, 0xa); |
|
232 |
+ PEKDEV(addr, 0x4); |
|
233 |
+ PEKDEV(len, 0xa); |
|
171 | 234 |
if(len > 0x10000 - addr) |
172 | 235 |
len = 0x10000 - addr; |
173 |
- res = file_stat(c, &d->u->ram[addr], len); |
|
174 |
- DEVPOKE16(0x2, res); |
|
236 |
+ res = file_stat(c, &ram[addr], len); |
|
237 |
+ POKDEV(0x2, res); |
|
175 | 238 |
break; |
176 | 239 |
case 0x6: |
177 | 240 |
res = file_delete(c); |
178 |
- DEVPOKE16(0x2, res); |
|
241 |
+ POKDEV(0x2, res); |
|
179 | 242 |
break; |
180 | 243 |
case 0x9: |
181 |
- DEVPEEK16(addr, 0x8); |
|
182 |
- res = file_init(c, (char *)&d->u->ram[addr], 0x10000 - addr); |
|
183 |
- DEVPOKE16(0x2, res); |
|
244 |
+ PEKDEV(addr, 0x8); |
|
245 |
+ res = file_init(c, (char *)&ram[addr], 0x10000 - addr, 0); |
|
246 |
+ POKDEV(0x2, res); |
|
184 | 247 |
break; |
185 | 248 |
case 0xd: |
186 |
- DEVPEEK16(addr, 0xc); |
|
187 |
- DEVPEEK16(len, 0xa); |
|
249 |
+ PEKDEV(addr, 0xc); |
|
250 |
+ PEKDEV(len, 0xa); |
|
188 | 251 |
if(len > 0x10000 - addr) |
189 | 252 |
len = 0x10000 - addr; |
190 |
- res = file_read(c, &d->u->ram[addr], len); |
|
191 |
- DEVPOKE16(0x2, res); |
|
253 |
+ res = file_read(c, &ram[addr], len); |
|
254 |
+ POKDEV(0x2, res); |
|
192 | 255 |
break; |
193 | 256 |
case 0xf: |
194 |
- DEVPEEK16(addr, 0xe); |
|
195 |
- DEVPEEK16(len, 0xa); |
|
257 |
+ PEKDEV(addr, 0xe); |
|
258 |
+ PEKDEV(len, 0xa); |
|
196 | 259 |
if(len > 0x10000 - addr) |
197 | 260 |
len = 0x10000 - addr; |
198 |
- res = file_write(c, &d->u->ram[addr], len, d->dat[0x7]); |
|
199 |
- DEVPOKE16(0x2, res); |
|
261 |
+ res = file_write(c, &ram[addr], len, d[0x7]); |
|
262 |
+ POKDEV(0x2, res); |
|
200 | 263 |
break; |
201 | 264 |
} |
202 | 265 |
} |
203 | 266 |
|
204 | 267 |
Uint8 |
205 |
-file_dei(Device *d, Uint8 port) |
|
268 |
+file_dei(Uint8 id, Uint8 *d, Uint8 port) |
|
206 | 269 |
{ |
207 |
- UxnFile *c = file_instance(d); |
|
270 |
+ UxnFile *c = &uxn_file[id]; |
|
208 | 271 |
Uint16 res; |
209 | 272 |
switch(port) { |
210 | 273 |
case 0xc: |
211 | 274 |
case 0xd: |
212 |
- res = file_read(c, &d->dat[port], 1); |
|
213 |
- DEVPOKE16(0x2, res); |
|
275 |
+ res = file_read(c, &d[port], 1); |
|
276 |
+ POKDEV(0x2, res); |
|
214 | 277 |
break; |
215 | 278 |
} |
216 |
- return d->dat[port]; |
|
279 |
+ return d[port]; |
|
217 | 280 |
} |
218 | 281 |
|
219 | 282 |
/* Boot */ |
... | ... |
@@ -222,7 +285,7 @@ int |
222 | 285 |
load_rom(Uxn *u, char *filename) |
223 | 286 |
{ |
224 | 287 |
int ret; |
225 |
- file_init(uxn_file, filename, strlen(filename) + 1); |
|
288 |
+ file_init(uxn_file, filename, strlen(filename) + 1, 1); |
|
226 | 289 |
ret = file_read(uxn_file, &u->ram[PAGE_PROGRAM], 0x10000 - PAGE_PROGRAM); |
227 | 290 |
reset(uxn_file); |
228 | 291 |
return ret; |
... | ... |
@@ -1,6 +1,5 @@ |
1 | 1 |
/* |
2 |
-Copyright (c) 2021 Devine Lu Linvega |
|
3 |
-Copyright (c) 2021 Andrew Alderwick |
|
2 |
+Copyright (c) 2021 Devine Lu Linvega, Andrew Alderwick |
|
4 | 3 |
|
5 | 4 |
Permission to use, copy, modify, and distribute this software for any |
6 | 5 |
purpose with or without fee is hereby granted, provided that the above |
... | ... |
@@ -13,6 +12,6 @@ WITH REGARD TO THIS SOFTWARE. |
13 | 12 |
#define POLYFILEY 2 |
14 | 13 |
#define DEV_FILE0 0xa |
15 | 14 |
|
16 |
-void file_deo(Device *d, Uint8 port); |
|
17 |
-Uint8 file_dei(Device *d, Uint8 port); |
|
15 |
+void file_deo(Uint8 id, Uint8 *ram, Uint8 *d, Uint8 port); |
|
16 |
+Uint8 file_dei(Uint8 id, Uint8 *d, Uint8 port); |
|
18 | 17 |
int load_rom(Uxn *u, char *filename); |
... | ... |
@@ -132,14 +132,14 @@ screen_mono(UxnScreen *p, Uint32 *pixels) |
132 | 132 |
/* IO */ |
133 | 133 |
|
134 | 134 |
Uint8 |
135 |
-screen_dei(Device *d, Uint8 port) |
|
135 |
+screen_dei(Uint8 *d, Uint8 port) |
|
136 | 136 |
{ |
137 | 137 |
switch(port) { |
138 | 138 |
case 0x2: return uxn_screen.width >> 8; |
139 | 139 |
case 0x3: return uxn_screen.width; |
140 | 140 |
case 0x4: return uxn_screen.height >> 8; |
141 | 141 |
case 0x5: return uxn_screen.height; |
142 |
- default: return d->dat[port]; |
|
142 |
+ default: return d[port]; |
|
143 | 143 |
} |
144 | 144 |
} |
145 | 145 |
|
... | ... |
@@ -31,6 +31,6 @@ void screen_clear(UxnScreen *p, Layer *layer); |
31 | 31 |
void screen_redraw(UxnScreen *p, Uint32 *pixels); |
32 | 32 |
void screen_mono(UxnScreen *p, Uint32 *pixels); |
33 | 33 |
|
34 |
-Uint8 screen_dei(Device *d, Uint8 port); |
|
34 |
+Uint8 screen_dei(Uint8 *d, Uint8 port); |
|
35 | 35 |
void screen_deo(Device *d, Uint8 port); |
36 | 36 |
int clamp(int val, int min, int max); |
... | ... |
@@ -15,13 +15,9 @@ WITH REGARD TO THIS SOFTWARE. |
15 | 15 |
*/ |
16 | 16 |
|
17 | 17 |
static const char *errors[] = { |
18 |
- "Working-stack underflow", |
|
19 |
- "Return-stack underflow", |
|
20 |
- "Working-stack overflow", |
|
21 |
- "Return-stack overflow", |
|
22 |
- "Working-stack division by zero", |
|
23 |
- "Return-stack division by zero", |
|
24 |
- "Execution timeout"}; |
|
18 |
+ "underflow", |
|
19 |
+ "overflow", |
|
20 |
+ "division by zero"}; |
|
25 | 21 |
|
26 | 22 |
static void |
27 | 23 |
system_print(Stack *s, char *name) |
... | ... |
@@ -38,37 +34,37 @@ system_print(Stack *s, char *name) |
38 | 34 |
void |
39 | 35 |
system_inspect(Uxn *u) |
40 | 36 |
{ |
41 |
- system_print(&u->wst, "wst"); |
|
42 |
- system_print(&u->rst, "rst"); |
|
37 |
+ system_print(u->wst, "wst"); |
|
38 |
+ system_print(u->rst, "rst"); |
|
43 | 39 |
} |
44 | 40 |
|
45 | 41 |
int |
46 |
-uxn_halt(Uxn *u, Uint8 error, Uint16 addr) |
|
42 |
+uxn_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr) |
|
47 | 43 |
{ |
48 |
- system_inspect(u); |
|
49 |
- fprintf(stderr, "Halted: %s#%04x, at 0x%04x\n", errors[error], u->ram[addr], addr); |
|
44 |
+ Uint8 *d = &u->dev[0x00]; |
|
45 |
+ if(instr & 0x40) |
|
46 |
+ u->rst->err = err; |
|
47 |
+ else |
|
48 |
+ u->wst->err = err; |
|
49 |
+ if(GETVEC(d)) |
|
50 |
+ uxn_eval(u, GETVEC(d)); |
|
51 |
+ else { |
|
52 |
+ system_inspect(u); |
|
53 |
+ fprintf(stderr, "%s %s, by %02x at 0x%04x.\n", (instr & 0x40) ? "Return-stack" : "Working-stack", errors[err - 1], instr, addr); |
|
54 |
+ } |
|
50 | 55 |
return 0; |
51 | 56 |
} |
52 | 57 |
|
53 | 58 |
/* IO */ |
54 | 59 |
|
55 |
-Uint8 |
|
56 |
-system_dei(Device *d, Uint8 port) |
|
57 |
-{ |
|
58 |
- switch(port) { |
|
59 |
- case 0x2: return d->u->wst.ptr; |
|
60 |
- case 0x3: return d->u->rst.ptr; |
|
61 |
- default: return d->dat[port]; |
|
62 |
- } |
|
63 |
-} |
|
64 |
- |
|
65 | 60 |
void |
66 |
-system_deo(Device *d, Uint8 port) |
|
61 |
+system_deo(Uxn *u, Uint8 *d, Uint8 port) |
|
67 | 62 |
{ |
68 | 63 |
switch(port) { |
69 |
- case 0x2: d->u->wst.ptr = d->dat[port]; break; |
|
70 |
- case 0x3: d->u->rst.ptr = d->dat[port]; break; |
|
71 |
- case 0xe: system_inspect(d->u); break; |
|
72 |
- default: system_deo_special(d, port); |
|
64 |
+ case 0x2: u->wst = (Stack *)(u->ram + (d[port] ? (d[port] * 0x100) : 0x10000)); break; |
|
65 |
+ case 0x3: u->rst = (Stack *)(u->ram + (d[port] ? (d[port] * 0x100) : 0x10100)); break; |
|
66 |
+ case 0xe: |
|
67 |
+ if(u->wst->ptr || u->rst->ptr) system_inspect(u); |
|
68 |
+ break; |
|
73 | 69 |
} |
74 | 70 |
} |
... | ... |
@@ -9,13 +9,5 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
9 | 9 |
WITH REGARD TO THIS SOFTWARE. |
10 | 10 |
*/ |
11 | 11 |
|
12 |
-typedef struct SystemDevice { |
|
13 |
- Device device; |
|
14 |
- struct UxnScreen *screen; |
|
15 |
-} SystemDevice; |
|
16 |
- |
|
17 | 12 |
void system_inspect(Uxn *u); |
18 |
- |
|
19 |
-Uint8 system_dei(Device *d, Uint8 port); |
|
20 |
-void system_deo(Device *d, Uint8 port); |
|
21 |
-void system_deo_special(Device *d, Uint8 port); |
|
13 |
+void system_deo(Uxn *u, Uint8 *d, Uint8 port); |
... | ... |
@@ -31,6 +31,9 @@ WITH REGARD TO THIS SOFTWARE. |
31 | 31 |
#define DEVW8OLD(x, y) { dev->dat[(x) & 0xf] = y; dev->deo(dev, (x) & 0x0f); } |
32 | 32 |
#define DEVWOLD(d, x, y) { dev = (d); if(bs) { DEVW8OLD((x), (y) >> 8); DEVW8OLD((x) + 1, (y)); } else { DEVW8OLD((x), (y)) } } |
33 | 33 |
|
34 |
+#define DEVR(o, x) { o = u->dei(u, x); if (bs) o = (o << 8) + u->dei(u, ((x) + 1) & 0xFF); } |
|
35 |
+#define DEVW(x, y) { if (bs) { u->deo(u, (x), (y) >> 8); u->deo(u, ((x) + 1) & 0xFF, (y)); } else { u->deo(u, x, (y)); } } |
|
36 |
+ |
|
34 | 37 |
#define WARP(x) { if(bs) pc = (x); else pc += (Sint8)(x); } |
35 | 38 |
#define LIMIT 0x40000 /* around 3 ms */ |
36 | 39 |
|
... | ... |
@@ -41,21 +44,16 @@ uxn_eval(Uxn *u, Uint16 pc) |
41 | 44 |
unsigned int limit = LIMIT; |
42 | 45 |
Uint8 kptr, *sp; |
43 | 46 |
Stack *src, *dst; |
44 |
- Device *dev; |
|
45 | 47 |
if(!pc || u->devold[0].dat[0xf]) return 0; |
46 | 48 |
while((instr = u->ram[pc++])) { |
47 | 49 |
if(!limit--) { |
48 |
- if(!uxn_interrupt()) { |
|
49 |
- errcode = 6; |
|
50 |
- goto timeout; |
|
51 |
- } |
|
52 | 50 |
limit = LIMIT; |
53 | 51 |
} |
54 | 52 |
/* Return Mode */ |
55 | 53 |
if(instr & 0x40) { |
56 |
- src = &u->rst; dst = &u->wst; |
|
54 |
+ src = u->rst; dst = u->wst; |
|
57 | 55 |
} else { |
58 |
- src = &u->wst; dst = &u->rst; |
|
56 |
+ src = u->wst; dst = u->rst; |
|
59 | 57 |
} |
60 | 58 |
/* Keep Mode */ |
61 | 59 |
if(instr & 0x80) { |
... | ... |
@@ -92,8 +90,8 @@ uxn_eval(Uxn *u, Uint16 pc) |
92 | 90 |
case 0x13: /* STR */ POP8(a) POP(b) c = pc + (Sint8)a; POKE(c, b) break; |
93 | 91 |
case 0x14: /* LDA */ POP16(a) PEEK(b, a) PUSH(src, b) break; |
94 | 92 |
case 0x15: /* STA */ POP16(a) POP(b) POKE(a, b) break; |
95 |
- case 0x16: /* DEI */ POP8(a) DEVROLD(b, &u->devold[a >> 4], a) PUSH(src, b) break; |
|
96 |
- case 0x17: /* DEO */ POP8(a) POP(b) DEVWOLD(&u->devold[a >> 4], a, b) break; |
|
93 |
+ case 0x16: /* DEI */ POP8(a) DEVR(b, a) PUSH(src, b) break; |
|
94 |
+ case 0x17: /* DEO */ POP8(a) POP(b) DEVW(a, b) break; |
|
97 | 95 |
/* Arithmetic */ |
98 | 96 |
case 0x18: /* ADD */ POP(a) POP(b) PUSH(src, b + a) break; |
99 | 97 |
case 0x19: /* SUB */ POP(a) POP(b) PUSH(src, b - a) break; |
... | ... |
@@ -106,13 +104,8 @@ uxn_eval(Uxn *u, Uint16 pc) |
106 | 104 |
} |
107 | 105 |
} |
108 | 106 |
return 1; |
109 |
- |
|
110 | 107 |
err: |
111 |
- /* set 1 in errcode if it involved the return stack instead of the working stack */ |
|
112 |
- /* (stack overflow & ( opcode was STH / JSR )) ^ Return Mode */ |
|
113 |
- errcode |= ((errcode >> 1 & ((instr & 0x1e) == 0x0e)) ^ instr >> 6) & 1; |
|
114 |
-timeout: |
|
115 |
- return uxn_halt(u, errcode, pc - 1); |
|
108 |
+ return uxn_halt(u, instr, errcode, pc - 1); |
|
116 | 109 |
} |
117 | 110 |
|
118 | 111 |
/* clang-format on */ |
... | ... |
@@ -125,6 +118,8 @@ uxn_boot(Uxn *u, Uint8 *ram, Dei *dei, Deo *deo) |
125 | 118 |
for(i = 0; i < sizeof(*u); i++) |
126 | 119 |
cptr[i] = 0x00; |
127 | 120 |
u->ram = ram; |
121 |
+ u->wst = (Stack *)(ram + 0x10000); |
|
122 |
+ u->rst = (Stack *)(ram + 0x10100); |
|
128 | 123 |
u->dev = (Uint8 *)(ram + 0x10200); |
129 | 124 |
u->dei = dei; |
130 | 125 |
u->deo = deo; |
... | ... |
@@ -20,13 +20,25 @@ typedef unsigned int Uint32; |
20 | 20 |
|
21 | 21 |
#define PAGE_PROGRAM 0x0100 |
22 | 22 |
|
23 |
-/* clang-format off */ |
|
24 |
- |
|
25 |
-#define DEVPEEK16(o, x) { (o) = (d->dat[(x)] << 8) + d->dat[(x) + 1]; } |
|
26 |
-#define DEVPOKE16(x, y) { d->dat[(x)] = (y) >> 8; d->dat[(x) + 1] = (y); } |
|
23 |
+#define DEVPEEK16(o, x) \ |
|
24 |
+ { \ |
|
25 |
+ (o) = (d->dat[(x)] << 8) + d->dat[(x) + 1]; \ |
|
26 |
+ } |
|
27 |
+#define DEVPOKE16(x, y) \ |
|
28 |
+ { \ |
|
29 |
+ d->dat[(x)] = (y) >> 8; \ |
|
30 |
+ d->dat[(x) + 1] = (y); \ |
|
31 |
+ } |
|
27 | 32 |
#define GETVECTOR(d) ((d)->dat[0] << 8 | (d)->dat[1]) |
28 | 33 |
|
29 |
-/* new macros */ |
|
34 |
+typedef struct Device { |
|
35 |
+ struct Uxn *u; |
|
36 |
+ Uint8 dat[16]; |
|
37 |
+ Uint8 (*dei)(struct Device *d, Uint8); |
|
38 |
+ void (*deo)(struct Device *d, Uint8); |
|
39 |
+} Device; |
|
40 |
+ |
|
41 |
+/* clang-format off */ |
|
30 | 42 |
|
31 | 43 |
#define GETVEC(d) ((d)[0] << 8 | (d)[1]) |
32 | 44 |
#define POKDEV(x, y) { d[(x)] = (y) >> 8; d[(x) + 1] = (y); } |
... | ... |
@@ -35,19 +47,12 @@ typedef unsigned int Uint32; |
35 | 47 |
/* clang-format on */ |
36 | 48 |
|
37 | 49 |
typedef struct { |
38 |
- Uint8 ptr, dat[255]; |
|
50 |
+ Uint8 dat[254], err, ptr; |
|
39 | 51 |
} Stack; |
40 | 52 |
|
41 |
-typedef struct Device { |
|
42 |
- struct Uxn *u; |
|
43 |
- Uint8 dat[16]; |
|
44 |
- Uint8 (*dei)(struct Device *d, Uint8); |
|
45 |
- void (*deo)(struct Device *d, Uint8); |
|
46 |
-} Device; |
|
47 |
- |
|
48 | 53 |
typedef struct Uxn { |
49 | 54 |
Uint8 *ram, *dev; |
50 |
- Stack wst, rst; |
|
55 |
+ Stack *wst, *rst; |
|
51 | 56 |
Device devold[16]; |
52 | 57 |
Uint8 (*dei)(struct Uxn *u, Uint8 addr); |
53 | 58 |
void (*deo)(struct Uxn *u, Uint8 addr, Uint8 value); |
... | ... |
@@ -58,7 +63,9 @@ typedef void Deo(Uxn *u, Uint8 addr, Uint8 value); |
58 | 63 |
|
59 | 64 |
int uxn_boot(Uxn *u, Uint8 *ram, Dei *dei, Deo *deo); |
60 | 65 |
int uxn_eval(Uxn *u, Uint16 pc); |
61 |
-int uxn_interrupt(void); |
|
62 |
-int uxn_halt(Uxn *u, Uint8 error, Uint16 addr); |
|
66 |
+int uxn_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr); |
|
67 |
+ |
|
68 |
+/* TODO: remove */ |
|
69 |
+ |
|
63 | 70 |
Device *uxn_port(Uxn *u, Uint8 id, Uint8 (*deifn)(Device *, Uint8), void (*deofn)(Device *, Uint8)); |
64 | 71 |
#endif /* UXN_UXN_H */ |
... | ... |
@@ -17,102 +17,60 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
17 | 17 |
WITH REGARD TO THIS SOFTWARE. |
18 | 18 |
*/ |
19 | 19 |
|
20 |
+#define SUPPORT 0x1c03 /* devices mask */ |
|
21 |
+ |
|
20 | 22 |
static int |
21 |
-error(char *msg, const char *err) |
|
23 |
+emu_error(char *msg, const char *err) |
|
22 | 24 |
{ |
23 | 25 |
fprintf(stderr, "Error %s: %s\n", msg, err); |
24 | 26 |
return 0; |
25 | 27 |
} |
26 | 28 |
|
27 |
-static Uint8 |
|
28 |
-emu_dei(Uxn *u, Uint8 addr) |
|
29 |
-{ |
|
30 |
- return 0; |
|
31 |
-} |
|
32 |
- |
|
33 |
-static void |
|
34 |
-emu_deo(Uxn *u, Uint8 addr, Uint8 v) |
|
35 |
-{ |
|
36 |
-} |
|
37 |
- |
|
38 |
-void |
|
39 |
-system_deo_special(Device *d, Uint8 port) |
|
29 |
+static int |
|
30 |
+console_input(Uxn *u, char c) |
|
40 | 31 |
{ |
41 |
- (void)d; |
|
42 |
- (void)port; |
|
32 |
+ Uint8 *d = &u->dev[0x10]; |
|
33 |
+ d[0x02] = c; |
|
34 |
+ return uxn_eval(u, GETVEC(d)); |
|
43 | 35 |
} |
44 | 36 |
|
45 | 37 |
static void |
46 |
-console_deo(Device *d, Uint8 port) |
|
38 |
+console_deo(Uint8 *d, Uint8 port) |
|
47 | 39 |
{ |
48 |
- FILE *fd = port == 0x8 ? stdout : port == 0x9 ? stderr |
|
49 |
- : 0; |
|
40 |
+ FILE *fd = port == 0x8 ? stdout : port == 0x9 ? stderr : |
|
41 |
+ 0; |
|
50 | 42 |
if(fd) { |
51 |
- fputc(d->dat[port], fd); |
|
43 |
+ fputc(d[port], fd); |
|
52 | 44 |
fflush(fd); |
53 | 45 |
} |
54 | 46 |
} |
55 | 47 |
|
56 | 48 |
static Uint8 |
57 |
-nil_dei(Device *d, Uint8 port) |
|
58 |
-{ |
|
59 |
- return d->dat[port]; |
|
60 |
-} |
|
61 |
- |
|
62 |
-static void |
|
63 |
-nil_deo(Device *d, Uint8 port) |
|
64 |
-{ |
|
65 |
- (void)d; |
|
66 |
- (void)port; |
|
67 |
-} |
|
68 |
- |
|
69 |
-static int |
|
70 |
-console_input(Uxn *u, char c) |
|
49 |
+emu_dei(Uxn *u, Uint8 addr) |
|
71 | 50 |
{ |
72 |
- Device *d = &u->devold[1]; |
|
73 |
- d->dat[0x2] = c; |
|
74 |
- return uxn_eval(u, GETVECTOR(d)); |
|
51 |
+ Uint8 p = addr & 0x0f, d = addr & 0xf0; |
|
52 |
+ switch(d) { |
|
53 |
+ case 0xa0: return file_dei(0, &u->dev[d], p); |
|
54 |
+ case 0xb0: return file_dei(1, &u->dev[d], p); |
|
55 |
+ case 0xc0: return datetime_dei(&u->dev[d], p); |
|
56 |
+ } |
|
57 |
+ return u->dev[addr]; |
|
75 | 58 |
} |
76 | 59 |
|
77 | 60 |
static void |
78 |
-run(Uxn *u) |
|
61 |
+emu_deo(Uxn *u, Uint8 addr, Uint8 v) |
|
79 | 62 |
{ |
80 |
- Device *d = &u->devold[0]; |
|
81 |
- while(!d->dat[0xf]) { |
|
82 |
- int c = fgetc(stdin); |
|
83 |
- if(c != EOF) |
|
84 |
- console_input(u, (Uint8)c); |
|
63 |
+ Uint8 p = addr & 0x0f, d = addr & 0xf0; |
|
64 |
+ Uint16 mask = 0x1 << (d >> 4); |
|
65 |
+ u->dev[addr] = v; |
|
66 |
+ switch(d) { |
|
67 |
+ case 0x00: system_deo(u, &u->dev[d], p); break; |
|
68 |
+ case 0x10: console_deo(&u->dev[d], p); break; |
|
69 |
+ case 0xa0: file_deo(0, u->ram, &u->dev[d], p); break; |
|
70 |
+ case 0xb0: file_deo(1, u->ram, &u->dev[d], p); break; |
|
85 | 71 |
} |
86 |
-} |
|
87 |
- |
|
88 |
-int |
|
89 |
-uxn_interrupt(void) |
|
90 |
-{ |
|
91 |
- return 1; |
|
92 |
-} |
|
93 |
- |
|
94 |
-static int |
|
95 |
-start(Uxn *u) |
|
96 |
-{ |
|
97 |
- if(!uxn_boot(u, (Uint8 *)calloc(0x10300, sizeof(Uint8)), emu_dei, emu_deo)) |
|
98 |
- return error("Boot", "Failed"); |
|
99 |
- /* system */ uxn_port(u, 0x0, system_dei, system_deo); |
|
100 |
- /* console */ uxn_port(u, 0x1, nil_dei, console_deo); |
|
101 |
- /* empty */ uxn_port(u, 0x2, nil_dei, nil_deo); |
|
102 |
- /* empty */ uxn_port(u, 0x3, nil_dei, nil_deo); |
|
103 |
- /* empty */ uxn_port(u, 0x4, nil_dei, nil_deo); |
|
104 |
- /* empty */ uxn_port(u, 0x5, nil_dei, nil_deo); |
|
105 |
- /* empty */ uxn_port(u, 0x6, nil_dei, nil_deo); |
|
106 |
- /* empty */ uxn_port(u, 0x7, nil_dei, nil_deo); |
|
107 |
- /* empty */ uxn_port(u, 0x8, nil_dei, nil_deo); |
|
108 |
- /* empty */ uxn_port(u, 0x9, nil_dei, nil_deo); |
|
109 |
- /* file0 */ uxn_port(u, 0xa, file_dei, file_deo); |
|
110 |
- /* file1 */ uxn_port(u, 0xb, file_dei, file_deo); |
|
111 |
- /* datetime */ uxn_port(u, 0xc, datetime_dei, nil_deo); |
|
112 |
- /* empty */ uxn_port(u, 0xd, nil_dei, nil_deo); |
|
113 |
- /* empty */ uxn_port(u, 0xe, nil_dei, nil_deo); |
|
114 |
- /* empty */ uxn_port(u, 0xf, nil_dei, nil_deo); |
|
115 |
- return 1; |
|
72 |
+ if(p == 0x01 && !(SUPPORT & mask)) |
|
73 |
+ fprintf(stderr, "Warning: Incompatible emulation, device: %02x.\n", d); |
|
116 | 74 |
} |
117 | 75 |
|
118 | 76 |
int |
... | ... |
@@ -121,19 +79,22 @@ main(int argc, char **argv) |
121 | 79 |
Uxn u; |
122 | 80 |
int i; |
123 | 81 |
if(argc < 2) |
124 |
- return error("Usage", "uxncli game.rom args"); |
|
125 |
- if(!start(&u)) |
|
126 |
- return error("Start", "Failed"); |
|
82 |
+ return emu_error("Usage", "uxncli game.rom args"); |
|
83 |
+ if(!uxn_boot(&u, (Uint8 *)calloc(0x10300, sizeof(Uint8)), emu_dei, emu_deo)) |
|
84 |
+ return emu_error("Boot", "Failed"); |
|
127 | 85 |
if(!load_rom(&u, argv[1])) |
128 |
- return error("Load", "Failed"); |
|
129 |
- fprintf(stderr, "Loaded %s\n", argv[1]); |
|
86 |
+ return emu_error("Load", "Failed"); |
|
130 | 87 |
if(!uxn_eval(&u, PAGE_PROGRAM)) |
131 |
- return error("Init", "Failed"); |
|
88 |
+ return emu_error("Init", "Failed"); |
|
132 | 89 |
for(i = 2; i < argc; i++) { |
133 | 90 |
char *p = argv[i]; |
134 | 91 |
while(*p) console_input(&u, *p++); |
135 | 92 |
console_input(&u, '\n'); |
136 | 93 |
} |
137 |
- run(&u); |
|
94 |
+ while(!u.dev[0x0f]) { |
|
95 |
+ int c = fgetc(stdin); |
|
96 |
+ if(c != EOF) |
|
97 |
+ console_input(&u, (Uint8)c); |
|
98 |
+ } |
|
138 | 99 |
return 0; |
139 | 100 |
} |
... | ... |
@@ -63,6 +63,25 @@ error(char *msg, const char *err) |
63 | 63 |
return 0; |
64 | 64 |
} |
65 | 65 |
|
66 |
+static int |
|
67 |
+console_input(Uxn *u, char c) |
|
68 |
+{ |
|
69 |
+ Uint8 *d = &u->dev[0x10]; |
|
70 |
+ d[0x02] = c; |
|
71 |
+ return uxn_eval(u, GETVEC(d)); |
|
72 |
+} |
|
73 |
+ |
|
74 |
+static void |
|
75 |
+console_deo(Uint8 *d, Uint8 port) |
|
76 |
+{ |
|
77 |
+ FILE *fd = port == 0x8 ? stdout : port == 0x9 ? stderr |
|
78 |
+ : 0; |
|
79 |
+ if(fd) { |
|
80 |
+ fputc(d[port], fd); |
|
81 |
+ fflush(fd); |
|
82 |
+ } |
|
83 |
+} |
|
84 |
+ |
|
66 | 85 |
#pragma mark - Generics |
67 | 86 |
|
68 | 87 |
static void |
... | ... |
@@ -179,12 +198,34 @@ init(void) |
179 | 198 |
static Uint8 |
180 | 199 |
emu_dei(Uxn *u, Uint8 addr) |
181 | 200 |
{ |
201 |
+ Uint8 p = addr & 0x0f, d = addr & 0xf0; |
|
202 |
+ switch(d) { |
|
203 |
+ case 0x20: return screen_dei(&u->dev[d], p); |
|
204 |
+ case 0xa0: return file_dei(0, &u->dev[d], p); |
|
205 |
+ case 0xb0: return file_dei(1, &u->dev[d], p); |
|
206 |
+ case 0xc0: return datetime_dei(&u->dev[d], p); |
|
207 |
+ } |
|
208 |
+ return u->dev[addr]; |
|
182 | 209 |
return 0; |
183 | 210 |
} |
184 | 211 |
|
185 | 212 |
static void |
186 | 213 |
emu_deo(Uxn *u, Uint8 addr, Uint8 v) |
187 | 214 |
{ |
215 |
+Uint8 p = addr & 0x0f, d = addr & 0xf0; |
|
216 |
+ Uint16 mask = 0x1 << (d >> 4); |
|
217 |
+ u->dev[addr] = v; |
|
218 |
+ switch(d) { |
|
219 |
+ case 0x00: |
|
220 |
+ system_deo(u, &u->dev[d], p); |
|
221 |
+ if(p > 0x7 && p < 0xe) |
|
222 |
+ screen_palette(&uxn_screen, &u->dev[0x8]); |
|
223 |
+ break; |
|
224 |
+ case 0x10: console_deo(&u->dev[d], p); break; |
|
225 |
+ /* case 0x20: screen_deo(u->ram, &u->dev[d], p); break; */ |
|
226 |
+ case 0xa0: file_deo(0, u->ram, &u->dev[d], p); break; |
|
227 |
+ case 0xb0: file_deo(1, u->ram, &u->dev[d], p); break; |
|
228 |
+ } |
|
188 | 229 |
} |
189 | 230 |
|
190 | 231 |
void |
... | ... |
@@ -194,17 +235,6 @@ system_deo_special(Device *d, Uint8 port) |
194 | 235 |
screen_palette(&uxn_screen, &d->dat[0x8]); |
195 | 236 |
} |
196 | 237 |
|
197 |
-static void |
|
198 |
-console_deo(Device *d, Uint8 port) |
|
199 |
-{ |
|
200 |
- FILE *fd = port == 0x8 ? stdout : port == 0x9 ? stderr |
|
201 |
- : 0; |
|
202 |
- if(fd) { |
|
203 |
- fputc(d->dat[port], fd); |
|
204 |
- fflush(fd); |
|
205 |
- } |
|
206 |
-} |
|
207 |
- |
|
208 | 238 |
static Uint8 |
209 | 239 |
audio_dei(Device *d, Uint8 port) |
210 | 240 |
{ |
... | ... |
@@ -230,19 +260,6 @@ audio_deo(Device *d, Uint8 port) |
230 | 260 |
} |
231 | 261 |
} |
232 | 262 |
|
233 |
-static Uint8 |
|
234 |
-nil_dei(Device *d, Uint8 port) |
|
235 |
-{ |
|
236 |
- return d->dat[port]; |
|
237 |
-} |
|
238 |
- |
|
239 |
-static void |
|
240 |
-nil_deo(Device *d, Uint8 port) |
|
241 |
-{ |
|
242 |
- (void)d; |
|
243 |
- (void)port; |
|
244 |
-} |
|
245 |
- |
|
246 | 263 |
/* Boot */ |
247 | 264 |
|
248 | 265 |
static int |
... | ... |
@@ -264,26 +281,10 @@ static int |
264 | 281 |
start(Uxn *u, char *rom) |
265 | 282 |
{ |
266 | 283 |
free(u->ram); |
267 |
- if(!uxn_boot(u, calloc(0x10300, 1), emu_dei, emu_deo)) |
|
284 |
+ if(!uxn_boot(u, (Uint8 *)calloc(0x10300, sizeof(Uint8)), emu_dei, emu_deo)) |
|
268 | 285 |
return error("Boot", "Failed to start uxn."); |
269 | 286 |
if(!load(u, rom)) |
270 | 287 |
return error("Boot", "Failed to load rom."); |
271 |
- /* system */ uxn_port(u, 0x0, system_dei, system_deo); |
|
272 |
- /* console */ uxn_port(u, 0x1, nil_dei, console_deo); |
|
273 |
- /* screen */ devscreen = uxn_port(u, 0x2, screen_dei, screen_deo); |
|
274 |
- /* audio0 */ devaudio0 = uxn_port(u, 0x3, audio_dei, audio_deo); |
|
275 |
- /* audio1 */ uxn_port(u, 0x4, audio_dei, audio_deo); |
|
276 |
- /* audio2 */ uxn_port(u, 0x5, audio_dei, audio_deo); |
|
277 |
- /* audio3 */ uxn_port(u, 0x6, audio_dei, audio_deo); |
|
278 |
- /* unused */ uxn_port(u, 0x7, nil_dei, nil_deo); |
|
279 |
- /* control */ uxn_port(u, 0x8, nil_dei, nil_deo); |
|
280 |
- /* mouse */ uxn_port(u, 0x9, nil_dei, nil_deo); |
|
281 |
- /* file0 */ uxn_port(u, 0xa, file_dei, file_deo); |
|
282 |
- /* file1 */ uxn_port(u, 0xb, file_dei, file_deo); |
|
283 |
- /* datetime */ uxn_port(u, 0xc, datetime_dei, nil_deo); |
|
284 |
- /* unused */ uxn_port(u, 0xd, nil_dei, nil_deo); |
|
285 |
- /* unused */ uxn_port(u, 0xe, nil_dei, nil_deo); |
|
286 |
- /* unused */ uxn_port(u, 0xf, nil_dei, nil_deo); |
|
287 | 288 |
exec_deadline = SDL_GetPerformanceCounter() + deadline_interval; |
288 | 289 |
if(!uxn_eval(u, PAGE_PROGRAM)) |
289 | 290 |
return error("Boot", "Failed to start rom."); |
... | ... |
@@ -383,14 +384,6 @@ do_shortcut(Uxn *u, SDL_Event *event) |
383 | 384 |
} |
384 | 385 |
} |
385 | 386 |
|
386 |
-static int |
|
387 |
-console_input(Uxn *u, char c) |
|
388 |
-{ |
|
389 |
- Device *d = &u->devold[1]; |
|
390 |
- d->dat[0x2] = c; |
|
391 |
- return uxn_eval(u, GETVECTOR(d)); |
|
392 |
-} |
|
393 |
- |
|
394 | 387 |
static int |
395 | 388 |
handle_events(Uxn *u) |
396 | 389 |
{ |
... | ... |
@@ -408,8 +401,8 @@ handle_events(Uxn *u) |
408 | 401 |
} |
409 | 402 |
/* Audio */ |
410 | 403 |
else if(event.type >= audio0_event && event.type < audio0_event + POLYPHONY) { |
411 |
- Device *d = devaudio0 + (event.type - audio0_event); |
|
412 |
- uxn_eval(u, GETVECTOR(d)); |
|
404 |
+ /* Device *d = devaudio0 + (event.type - audio0_event); |
|
405 |
+ uxn_eval(u, GETVECTOR(d)); */ |
|
413 | 406 |
} |
414 | 407 |
/* Mouse */ |
415 | 408 |
else if(event.type == SDL_MOUSEMOTION) |
... | ... |
@@ -467,7 +460,7 @@ run(Uxn *u) |
467 | 460 |
exec_deadline = now + deadline_interval; |
468 | 461 |
if(!handle_events(u)) |
469 | 462 |
return 0; |
470 |
- uxn_eval(u, GETVECTOR(devscreen)); |
|
463 |
+ uxn_eval(u, GETVEC(&u->dev[0x20])); |
|
471 | 464 |
if(uxn_screen.fg.changed || uxn_screen.bg.changed) |
472 | 465 |
redraw(); |
473 | 466 |
now = SDL_GetPerformanceCounter(); |
... | ... |
@@ -479,12 +472,6 @@ run(Uxn *u) |
479 | 472 |
return error("SDL_WaitEvent", SDL_GetError()); |
480 | 473 |
} |
481 | 474 |
|
482 |
-int |
|
483 |
-uxn_interrupt(void) |
|
484 |
-{ |
|
485 |
- return !SDL_QuitRequested(); |
|
486 |
-} |
|
487 |
- |
|
488 | 475 |
int |
489 | 476 |
main(int argc, char **argv) |
490 | 477 |
{ |