commit 9d88934

Devine Lu Linvega  ·  2023-02-02 16:45:03 +0000 UTC
parent 7603ddf
Simplified system loading
8 files changed,  +65, -67
+0, -0
+1, -1
1@@ -4,7 +4,7 @@
2 #include "datetime.h"
3 
4 /*
5-Copyright (c) 2021 Devine Lu Linvega, Andrew Alderwick
6+Copyright (c) 2021-2023 Devine Lu Linvega, Andrew Alderwick
7 
8 Permission to use, copy, modify, and distribute this software for any
9 purpose with or without fee is hereby granted, provided that the above
+16, -20
 1@@ -8,6 +8,11 @@
 2 #include <sys/stat.h>
 3 #include <unistd.h>
 4 
 5+#ifdef _WIN32
 6+#include <libiberty/libiberty.h>
 7+#define realpath(s, dummy) lrealpath(s)
 8+#endif
 9+
10 #ifndef PATH_MAX
11 #define PATH_MAX 4096
12 #endif
13@@ -16,7 +21,7 @@
14 #include "file.h"
15 
16 /*
17-Copyright (c) 2021 Devine Lu Linvega, Andrew Alderwick
18+Copyright (c) 2021-2023 Devine Lu Linvega, Andrew Alderwick
19 
20 Permission to use, copy, modify, and distribute this software for any
21 purpose with or without fee is hereby granted, provided that the above
22@@ -84,14 +89,17 @@ file_read_dir(UxnFile *c, char *dest, Uint16 len)
23 			continue;
24 		if(strcmp(c->de->d_name, "..") == 0) {
25 			/* hide "sandbox/.." */
26-			char cwd[PATH_MAX] = {'\0'}, t[PATH_MAX] = {'\0'};
27+			char cwd[PATH_MAX] = {'\0'}, *t;
28 			/* Note there's [currently] no way of chdir()ing from uxn, so $PWD
29 			 * is always the sandbox top level. */
30 			getcwd(cwd, sizeof(cwd));
31 			/* We already checked that c->current_filename exists so don't need a wrapper. */
32-			realpath(c->current_filename, t);
33-			if(strcmp(cwd, t) == 0)
34+			t = realpath(c->current_filename, NULL);
35+			if(strcmp(cwd, t) == 0) {
36+				free(t);
37 				continue;
38+			}
39+			free(t);
40 		}
41 		if(strlen(c->current_filename) + 1 + strlen(c->de->d_name) < sizeof(pathname))
42 			sprintf(pathname, "%s/%s", c->current_filename, c->de->d_name);
43@@ -108,7 +116,7 @@ file_read_dir(UxnFile *c, char *dest, Uint16 len)
44 static char *
45 retry_realpath(const char *file_name)
46 {
47-	char r[PATH_MAX] = {'\0'}, p[PATH_MAX] = {'\0'}, *x;
48+	char *r, p[PATH_MAX] = {'\0'}, *x;
49 	if(file_name == NULL) {
50 		errno = EINVAL;
51 		return NULL;
52@@ -123,7 +131,7 @@ retry_realpath(const char *file_name)
53 		strcat(p, "/"); /* TODO: use a macro instead of '/' for the path delimiter */
54 	}
55 	strcat(p, file_name);
56-	while(realpath(p, r) == NULL) {
57+	while((r = realpath(p, NULL)) == NULL) {
58 		if(errno != ENOENT)
59 			return NULL;
60 		x = strrchr(p, '/'); /* TODO: path delimiter macro */
61@@ -132,7 +140,7 @@ retry_realpath(const char *file_name)
62 		else
63 			return NULL;
64 	}
65-	return strdup(r);
66+	return r;
67 }
68 
69 static void
70@@ -168,7 +176,7 @@ file_init(UxnFile *c, char *filename, size_t max_len, int override_sandbox)
71 }
72 
73 static Uint16
74-file_read(UxnFile *c, void *dest, Uint16 len)
75+file_read(UxnFile *c, void *dest, int len)
76 {
77 	if(c->outside_sandbox) return 0;
78 	if(c->state != FILE_READ && c->state != DIR_READ) {
79@@ -278,15 +286,3 @@ file_dei(Uint8 id, Uint8 *d, Uint8 port)
80 	}
81 	return d[port];
82 }
83-
84-/* Boot */
85-
86-int
87-load_rom(Uxn *u, char *filename)
88-{
89-	int ret;
90-	file_init(uxn_file, filename, strlen(filename) + 1, 1);
91-	ret = file_read(uxn_file, &u->ram[PAGE_PROGRAM], 0x10000 - PAGE_PROGRAM);
92-	reset(uxn_file);
93-	return ret;
94-}
+0, -1
1@@ -14,4 +14,3 @@ WITH REGARD TO THIS SOFTWARE.
2 
3 void file_deo(Uint8 id, Uint8 *ram, Uint8 *d, Uint8 port);
4 Uint8 file_dei(Uint8 id, Uint8 *d, Uint8 port);
5-int load_rom(Uxn *u, char *filename);
+38, -30
 1@@ -39,37 +39,10 @@ system_inspect(Uxn *u)
 2 	system_print(u->rst, "rst");
 3 }
 4 
 5-int
 6-uxn_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr)
 7-{
 8-	Uint8 *d = &u->dev[0x00];
 9-	Uint16 handler = GETVEC(d);
10-	if(handler) {
11-		u->wst->ptr = 4;
12-		u->wst->dat[0] = addr >> 0x8;
13-		u->wst->dat[1] = addr & 0xff;
14-		u->wst->dat[2] = instr;
15-		u->wst->dat[3] = err;
16-		return uxn_eval(u, handler);
17-	} else {
18-		system_inspect(u);
19-		fprintf(stderr, "%s %s, by %02x at 0x%04x.\n", (instr & 0x40) ? "Return-stack" : "Working-stack", errors[err - 1], instr, addr);
20-	}
21-	return 0;
22-}
23-
24-/* MMU */
25-
26-Uint8 *
27-mmu_init(Mmu *m, Uint16 pages)
28-{
29-	m->length = pages;
30-	m->pages = (Uint8 *)calloc(0x10000 * pages, sizeof(Uint8));
31-	return m->pages;
32-}
33+/* RAM */
34 
35 void
36-mmu_eval(Uint8 *ram, Uint16 addr)
37+system_cmd(Uint8 *ram, Uint16 addr)
38 {
39 	Uint16 a = addr, i = 0;
40 	Uint8 o = ram[a++];
41@@ -82,6 +55,20 @@ mmu_eval(Uint8 *ram, Uint16 addr)
42 	}
43 }
44 
45+int
46+system_load(Uxn *u, char *filename)
47+{
48+	int l, i = 0;
49+	FILE *f = fopen(filename, "rb");
50+	if(!f)
51+		return 0;
52+	l = fread(&u->ram[PAGE_PROGRAM], 1, 0x10000 - PAGE_PROGRAM, f);
53+	while(l && ++i < RAM_PAGES)
54+		l = fread(u->ram + 0x10000 * i, 1, 0x10000, f);
55+	fclose(f);
56+	return 1;
57+}
58+
59 /* IO */
60 
61 void
62@@ -91,10 +78,31 @@ system_deo(Uxn *u, Uint8 *d, Uint8 port)
63 	switch(port) {
64 	case 0x3:
65 		PEKDEV(a, 0x2);
66-		mmu_eval(u->ram, a);
67+		system_cmd(u->ram, a);
68 		break;
69 	case 0xe:
70 		if(u->wst->ptr || u->rst->ptr) system_inspect(u);
71 		break;
72 	}
73 }
74+
75+/* Error */
76+
77+int
78+uxn_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr)
79+{
80+	Uint8 *d = &u->dev[0x00];
81+	Uint16 handler = GETVEC(d);
82+	if(handler) {
83+		u->wst->ptr = 4;
84+		u->wst->dat[0] = addr >> 0x8;
85+		u->wst->dat[1] = addr & 0xff;
86+		u->wst->dat[2] = instr;
87+		u->wst->dat[3] = err;
88+		return uxn_eval(u, handler);
89+	} else {
90+		system_inspect(u);
91+		fprintf(stderr, "%s %s, by %02x at 0x%04x.\n", (instr & 0x40) ? "Return-stack" : "Working-stack", errors[err - 1], instr, addr);
92+	}
93+	return 0;
94+}
+4, -7
 1@@ -9,11 +9,8 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 2 WITH REGARD TO THIS SOFTWARE.
 3 */
 4 
 5-void system_inspect(Uxn *u);
 6-void system_deo(Uxn *u, Uint8 *d, Uint8 port);
 7-
 8-typedef struct {
 9-	Uint8 length, *pages;
10-} Mmu;
11+#define RAM_PAGES 0x10
12 
13-Uint8 *mmu_init(Mmu *m, Uint16 pages);
14+int system_load(Uxn *u, char *filename);
15+void system_deo(Uxn *u, Uint8 *d, Uint8 port);
16+void system_inspect(Uxn *u);
+2, -3
 1@@ -108,7 +108,7 @@ emu_draw(void)
 2 static int
 3 emu_start(Uxn *u, char *rom)
 4 {
 5-	if(!load_rom(u, rom))
 6+	if(!system_load(u, rom))
 7 		return 0;
 8 	if(!uxn_screen.width || !uxn_screen.height)
 9 		screen_resize(&uxn_screen, WIDTH, HEIGHT);
10@@ -225,7 +225,6 @@ int
11 main(int argc, char **argv)
12 {
13 	Uxn u;
14-	Mmu m;
15 	int i;
16 	char expirations[8];
17 	struct pollfd fds[2];
18@@ -233,7 +232,7 @@ main(int argc, char **argv)
19 	if(argc < 2)
20 		return emu_error("Usage", "uxn11 game.rom args");
21 	rom_path = argv[1];
22-	if(!uxn_boot(&u, mmu_init(&m, 16), emu_dei, emu_deo))
23+	if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)), emu_dei, emu_deo))
24 		return emu_error("Boot", "Failed");
25 	/* start sequence */
26 	if(!emu_start(&u, rom_path))
+4, -5
 1@@ -37,8 +37,8 @@ console_input(Uxn *u, char c)
 2 static void
 3 console_deo(Uint8 *d, Uint8 port)
 4 {
 5-	FILE *fd = port == 0x8 ? stdout : port == 0x9 ? stderr
 6-												  : 0;
 7+	FILE *fd = port == 0x8 ? stdout : port == 0x9 ? stderr :
 8+													0;
 9 	if(fd) {
10 		fputc(d[port], fd);
11 		fflush(fd);
12@@ -78,12 +78,11 @@ main(int argc, char **argv)
13 {
14 	Uxn u;
15 	int i;
16-	Mmu mmu;
17 	if(argc < 2)
18 		return emu_error("Usage", "uxncli game.rom args");
19-	if(!uxn_boot(&u, mmu_init(&mmu, 16), emu_dei, emu_deo))
20+	if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)), emu_dei, emu_deo))
21 		return emu_error("Boot", "Failed");
22-	if(!load_rom(&u, argv[1]))
23+	if(!system_load(&u, argv[1]))
24 		return emu_error("Load", "Failed");
25 	if(!uxn_eval(&u, PAGE_PROGRAM))
26 		return emu_error("Init", "Failed");