| ... | ... |
@@ -5,17 +5,22 @@ mkdir -p bin |
| 5 | 5 |
|
| 6 | 6 |
# Assembler |
| 7 | 7 |
clang-format -i assembler.c |
| 8 |
-rm -f ./assembler |
|
| 9 |
-rm -f ./boot.rom |
|
| 8 |
+rm -f ./bin/assembler |
|
| 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 | 11 |
./bin/assembler examples/hello.usm bin/boot.rom |
| 12 | 12 |
|
| 13 |
-# Emulator |
|
| 14 |
-clang-format -i emulator.c |
|
| 13 |
+# Cli |
|
| 14 |
+clang-format -i cli.c |
|
| 15 | 15 |
clang-format -i uxn.h |
| 16 | 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 -L/usr/local/lib -lSDL2 -o bin/emulator |
|
| 17 |
+rm -f ./bin/cli |
|
| 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 cli.c -o bin/cli |
|
| 19 |
+ |
|
| 20 |
+# Emulator |
|
| 21 |
+# clang-format -i emulator.c |
|
| 22 |
+# rm -f ./bin/emulator |
|
| 23 |
+# 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 |
|
| 19 | 24 |
|
| 20 | 25 |
# run |
| 21 |
-./bin/emulator bin/boot.rom |
|
| 26 |
+./bin/cli bin/boot.rom |
| 22 | 27 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,94 @@ |
| 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 "uxn.h" |
|
| 15 |
+ |
|
| 16 |
+int |
|
| 17 |
+error(char *msg, const char *err) |
|
| 18 |
+{
|
|
| 19 |
+ printf("Error %s: %s\n", msg, err);
|
|
| 20 |
+ return 0; |
|
| 21 |
+} |
|
| 22 |
+ |
|
| 23 |
+void |
|
| 24 |
+console_onread(void) |
|
| 25 |
+{
|
|
| 26 |
+} |
|
| 27 |
+ |
|
| 28 |
+void |
|
| 29 |
+console_onwrite(void) |
|
| 30 |
+{
|
|
| 31 |
+} |
|
| 32 |
+ |
|
| 33 |
+void |
|
| 34 |
+echos(Stack8 *s, Uint8 len, char *name) |
|
| 35 |
+{
|
|
| 36 |
+ int i; |
|
| 37 |
+ printf("\n%s\n", name);
|
|
| 38 |
+ for(i = 0; i < len; ++i) {
|
|
| 39 |
+ if(i % 16 == 0) |
|
| 40 |
+ printf("\n");
|
|
| 41 |
+ printf("%02x%c", s->dat[i], s->ptr == i ? '<' : ' ');
|
|
| 42 |
+ } |
|
| 43 |
+ printf("\n\n");
|
|
| 44 |
+} |
|
| 45 |
+ |
|
| 46 |
+void |
|
| 47 |
+echom(Memory *m, Uint16 len, char *name) |
|
| 48 |
+{
|
|
| 49 |
+ int i; |
|
| 50 |
+ printf("\n%s\n", name);
|
|
| 51 |
+ for(i = 0; i < len; ++i) {
|
|
| 52 |
+ if(i % 16 == 0) |
|
| 53 |
+ printf("\n");
|
|
| 54 |
+ printf("%02x ", m->dat[i]);
|
|
| 55 |
+ } |
|
| 56 |
+ printf("\n\n");
|
|
| 57 |
+} |
|
| 58 |
+ |
|
| 59 |
+void |
|
| 60 |
+echof(Uxn *c) |
|
| 61 |
+{
|
|
| 62 |
+ printf("ended @ %d steps | hf: %x sf: %x sf: %x cf: %x\n",
|
|
| 63 |
+ c->counter, |
|
| 64 |
+ getflag(&c->status, FLAG_HALT) != 0, |
|
| 65 |
+ getflag(&c->status, FLAG_SHORT) != 0, |
|
| 66 |
+ getflag(&c->status, FLAG_SIGN) != 0, |
|
| 67 |
+ getflag(&c->status, FLAG_COND) != 0); |
|
| 68 |
+} |
|
| 69 |
+ |
|
| 70 |
+Uxn u; |
|
| 71 |
+ |
|
| 72 |
+int |
|
| 73 |
+main(int argc, char **argv) |
|
| 74 |
+{
|
|
| 75 |
+ if(argc < 2) |
|
| 76 |
+ return error("Input", "Missing");
|
|
| 77 |
+ if(!bootuxn(&u)) |
|
| 78 |
+ return error("Boot", "Failed");
|
|
| 79 |
+ if(!loaduxn(&u, argv[1])) |
|
| 80 |
+ return error("Load", "Failed");
|
|
| 81 |
+ |
|
| 82 |
+ portuxn(&u, 0xfff0, 0xfff1, console_onread, console_onwrite); |
|
| 83 |
+ |
|
| 84 |
+ printf("VRESET\n");
|
|
| 85 |
+ evaluxn(&u, u.vreset); |
|
| 86 |
+ printf("VFRAME\n");
|
|
| 87 |
+ evaluxn(&u, u.vframe); |
|
| 88 |
+ |
|
| 89 |
+ echos(&u.wst, 0x40, "stack"); |
|
| 90 |
+ echom(&u.ram, 0x40, "ram"); |
|
| 91 |
+ echof(&u); |
|
| 92 |
+ |
|
| 93 |
+ return 0; |
|
| 94 |
+} |
| ... | ... |
@@ -137,14 +137,26 @@ void |
| 137 | 137 |
domouse(SDL_Event *event) |
| 138 | 138 |
{
|
| 139 | 139 |
(void)event; |
| 140 |
- printf("mouse\n");
|
|
| 140 |
+ /* printf("mouse\n"); */
|
|
| 141 | 141 |
} |
| 142 | 142 |
|
| 143 | 143 |
void |
| 144 | 144 |
dokey(SDL_Event *event) |
| 145 | 145 |
{
|
| 146 | 146 |
(void)event; |
| 147 |
- printf("key\n");
|
|
| 147 |
+ /* printf("key\n"); */
|
|
| 148 |
+} |
|
| 149 |
+ |
|
| 150 |
+#pragma mark - Devices |
|
| 151 |
+ |
|
| 152 |
+void |
|
| 153 |
+console_onread(void) |
|
| 154 |
+{
|
|
| 155 |
+} |
|
| 156 |
+ |
|
| 157 |
+void |
|
| 158 |
+console_onwrite(void) |
|
| 159 |
+{
|
|
| 148 | 160 |
} |
| 149 | 161 |
|
| 150 | 162 |
int |
| ... | ... |
@@ -175,11 +187,11 @@ start(Uxn *u) |
| 175 | 187 |
} |
| 176 | 188 |
} |
| 177 | 189 |
|
| 190 |
+Uxn u; |
|
| 191 |
+ |
|
| 178 | 192 |
int |
| 179 | 193 |
main(int argc, char **argv) |
| 180 | 194 |
{
|
| 181 |
- Uxn u; |
|
| 182 |
- |
|
| 183 | 195 |
if(argc < 2) |
| 184 | 196 |
return error("Input", "Missing");
|
| 185 | 197 |
if(!bootuxn(&u)) |
| ... | ... |
@@ -189,6 +201,8 @@ main(int argc, char **argv) |
| 189 | 201 |
if(!init()) |
| 190 | 202 |
return error("Init", "Failed");
|
| 191 | 203 |
|
| 204 |
+ portuxn(&u, 0xfff0, 0xfff1, console_onread, console_onwrite); |
|
| 205 |
+ |
|
| 192 | 206 |
start(&u); |
| 193 | 207 |
|
| 194 | 208 |
echos(&u.wst, 0x40, "stack"); |
| ... | ... |
@@ -103,26 +103,6 @@ haltuxn(Uxn *u, char *name, int id) |
| 103 | 103 |
return 0; |
| 104 | 104 |
} |
| 105 | 105 |
|
| 106 |
-void |
|
| 107 |
-inituxn(Uxn *u) |
|
| 108 |
-{
|
|
| 109 |
- size_t i; |
|
| 110 |
- char *cptr = (char *)u; |
|
| 111 |
- for(i = 0; i < sizeof u; i++) |
|
| 112 |
- cptr[i] = 0; |
|
| 113 |
-} |
|
| 114 |
- |
|
| 115 |
-int |
|
| 116 |
-loaduxn(Uxn *u, char *filepath) |
|
| 117 |
-{
|
|
| 118 |
- FILE *f; |
|
| 119 |
- if(!(f = fopen(filepath, "rb"))) |
|
| 120 |
- return haltuxn(u, "Missing input.", 0); |
|
| 121 |
- fread(u->ram.dat, sizeof(u->ram.dat), 1, f); |
|
| 122 |
- printf("Uxn Loaded: %s\n", filepath);
|
|
| 123 |
- return 1; |
|
| 124 |
-} |
|
| 125 |
- |
|
| 126 | 106 |
int |
| 127 | 107 |
lituxn(Uxn *u, Uint8 instr) |
| 128 | 108 |
{
|
| ... | ... |
@@ -136,9 +116,13 @@ lituxn(Uxn *u, Uint8 instr) |
| 136 | 116 |
int |
| 137 | 117 |
devuxn(Uxn *u) /* experimental */ |
| 138 | 118 |
{
|
| 139 |
- if(u->ram.dat[0xfff1]) {
|
|
| 140 |
- printf("%c", u->ram.dat[0xfff1]);
|
|
| 141 |
- u->ram.dat[0xfff1] = 0x00; |
|
| 119 |
+ int i; |
|
| 120 |
+ for(i = 0; i < u->devices; ++i) {
|
|
| 121 |
+ Uint16 addr = u->dev[i].w; |
|
| 122 |
+ if(u->ram.dat[addr]) {
|
|
| 123 |
+ printf("%c", u->ram.dat[addr]);
|
|
| 124 |
+ u->ram.dat[addr] = 0; |
|
| 125 |
+ } |
|
| 142 | 126 |
} |
| 143 | 127 |
return 1; |
| 144 | 128 |
} |
| ... | ... |
@@ -162,31 +146,65 @@ opcuxn(Uxn *u, Uint8 instr) |
| 162 | 146 |
return 1; |
| 163 | 147 |
} |
| 164 | 148 |
|
| 149 |
+int |
|
| 150 |
+parse(Uxn *u) /* TODO: Rename */ |
|
| 151 |
+{
|
|
| 152 |
+ Uint8 instr = u->ram.dat[u->ram.ptr++]; |
|
| 153 |
+ u->counter++; |
|
| 154 |
+ if(u->literal > 0) |
|
| 155 |
+ return lituxn(u, instr); |
|
| 156 |
+ else |
|
| 157 |
+ return opcuxn(u, instr); |
|
| 158 |
+} |
|
| 159 |
+ |
|
| 165 | 160 |
int |
| 166 | 161 |
evaluxn(Uxn *u, Uint16 vec) |
| 167 | 162 |
{
|
| 168 | 163 |
u->ram.ptr = vec; |
| 169 | 164 |
setflag(&u->status, FLAG_HALT, 0); |
| 170 |
- while(!(u->status & FLAG_HALT)) {
|
|
| 171 |
- Uint8 instr = u->ram.dat[u->ram.ptr++]; |
|
| 172 |
- u->counter++; |
|
| 173 |
- if(u->literal > 0) |
|
| 174 |
- return lituxn(u, instr); |
|
| 175 |
- else |
|
| 176 |
- return opcuxn(u, instr); |
|
| 177 |
- } |
|
| 165 |
+ while(!(u->status & FLAG_HALT) && parse(u)) |
|
| 166 |
+ ; |
|
| 178 | 167 |
return 1; |
| 179 | 168 |
} |
| 180 | 169 |
|
| 181 | 170 |
int |
| 182 | 171 |
bootuxn(Uxn *u) |
| 183 | 172 |
{
|
| 184 |
- inituxn(u); |
|
| 173 |
+ size_t i; |
|
| 174 |
+ char *cptr = (char *)u; |
|
| 175 |
+ for(i = 0; i < sizeof u; i++) |
|
| 176 |
+ cptr[i] = 0; |
|
| 177 |
+ return 1; |
|
| 178 |
+} |
|
| 179 |
+ |
|
| 180 |
+int |
|
| 181 |
+loaduxn(Uxn *u, char *filepath) |
|
| 182 |
+{
|
|
| 183 |
+ FILE *f; |
|
| 184 |
+ if(!(f = fopen(filepath, "rb"))) |
|
| 185 |
+ return haltuxn(u, "Missing input.", 0); |
|
| 186 |
+ fread(u->ram.dat, sizeof(u->ram.dat), 1, f); |
|
| 185 | 187 |
u->vreset = mempeek16(u, 0xfffa); |
| 186 | 188 |
u->vframe = mempeek16(u, 0xfffc); |
| 187 | 189 |
u->verror = mempeek16(u, 0xfffe); |
| 188 |
- printf("Uxn Ready.\n");
|
|
| 190 |
+ printf("Uxn loaded[%s] vrst:%04x vfrm:%04x verr:%04x.\n",
|
|
| 191 |
+ filepath, |
|
| 192 |
+ u->vreset, |
|
| 193 |
+ u->vframe, |
|
| 194 |
+ u->verror); |
|
| 189 | 195 |
return 1; |
| 190 | 196 |
} |
| 191 | 197 |
|
| 192 | 198 |
/* to start: evaluxn(u, u->vreset); */ |
| 199 |
+ |
|
| 200 |
+int |
|
| 201 |
+portuxn(Uxn *u, Uint16 r, Uint16 w, void (*onread)(), void (*onwrite)()) |
|
| 202 |
+{
|
|
| 203 |
+ Device *d = &u->dev[u->devices++]; |
|
| 204 |
+ d->r = r; |
|
| 205 |
+ d->w = w; |
|
| 206 |
+ d->rfn = onread; |
|
| 207 |
+ d->wfn = onwrite; |
|
| 208 |
+ printf("Created device: #%d, at r:%04x w:%04x\n", u->devices, r, w);
|
|
| 209 |
+ return 1; |
|
| 210 |
+} |
| ... | ... |
@@ -35,15 +35,23 @@ typedef struct {
|
| 35 | 35 |
} Memory; |
| 36 | 36 |
|
| 37 | 37 |
typedef struct {
|
| 38 |
- Uint8 literal, status; |
|
| 38 |
+ Uint16 r, w; |
|
| 39 |
+ void (*rfn)(void); |
|
| 40 |
+ void (*wfn)(void); |
|
| 41 |
+} Device; |
|
| 42 |
+ |
|
| 43 |
+typedef struct {
|
|
| 44 |
+ Uint8 literal, status, devices; |
|
| 39 | 45 |
Uint16 counter, vreset, vframe, verror; |
| 40 | 46 |
Stack8 wst; |
| 41 | 47 |
Stack16 rst; |
| 42 | 48 |
Memory ram; |
| 49 |
+ Device dev[64]; |
|
| 43 | 50 |
} Uxn; |
| 44 | 51 |
|
| 45 | 52 |
void setflag(Uint8 *status, char flag, int b); |
| 46 | 53 |
int getflag(Uint8 *status, char flag); |
| 47 | 54 |
int loaduxn(Uxn *c, char *filepath); |
| 48 | 55 |
int bootuxn(Uxn *c); |
| 49 |
-int evaluxn(Uxn *u, Uint16 vec); |
|
| 50 | 56 |
\ No newline at end of file |
| 57 |
+int evaluxn(Uxn *u, Uint16 vec); |
|
| 58 |
+int portuxn(Uxn *u, Uint16 r, Uint16 w, void (*onread)(), void (*onwrite)()); |