commit 1355d78

neauoire  ·  2023-08-08 23:26:13 +0000 UTC
parent 9fd8b17
Version 1
16 files changed,  +166, -77
+12, -2
 1@@ -2,7 +2,7 @@
 2 
 3 RELEASE_FLAGS="-DNDEBUG -O2 -g0 -s"
 4 DEBUG_FLAGS="-std=c89 -D_POSIX_C_SOURCE=199309L -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"
 5-CORE_DEVICES="src/uxn.c src/devices/system.c src/devices/file.c src/devices/datetime.c -lpthread"
 6+CORE_DEVICES="src/uxn.c src/devices/system.c src/devices/console.c src/devices/file.c src/devices/datetime.c -lpthread"
 7 EMU_INC="${CORE_DEVICES} src/devices/screen.c src/devices/controller.c src/devices/mouse.c src/uxn11.c -o bin/uxn11 -lX11"
 8 CLI_INC="${CORE_DEVICES} src/uxncli.c -o bin/uxncli"
 9 
10@@ -36,7 +36,7 @@ fi
11 
12 if [ "${1}" = '--install' ];
13 then
14-	cp bin/uxn11 bin/uxnemu
15+	cp bin/uxn11 bin/uxn11
16 	cp bin/uxnemu bin/uxnasm bin/uxncli $HOME/bin/
17 fi
18 
19@@ -46,6 +46,16 @@ fi
20 
21 if [ "${1}" = '--norun' ]; then exit; fi
22 
23+# Test usage
24+
25+./bin/uxncli
26+./bin/uxn11
27+
28+# Test version
29+
30+./bin/uxncli -v
31+./bin/uxn11 -v
32+
33 # bin/uxnasm etc/mouse.tal bin/res.rom
34 bin/uxnasm etc/pict.tal bin/res.rom
35 bin/uxn11 bin/res.rom
+40, -0
 1@@ -0,0 +1,40 @@
 2+#include <stdio.h>
 3+#include <stdlib.h>
 4+
 5+#include "../uxn.h"
 6+#include "console.h"
 7+
 8+/*
 9+Copyright (c) 2022-2023 Devine Lu Linvega, Andrew Alderwick
10+
11+Permission to use, copy, modify, and distribute this software for any
12+purpose with or without fee is hereby granted, provided that the above
13+copyright notice and this permission notice appear in all copies.
14+
15+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
16+WITH REGARD TO THIS SOFTWARE.
17+*/
18+
19+int
20+console_input(Uxn *u, char c, int type)
21+{
22+	Uint8 *d = &u->dev[0x10];
23+	d[0x2] = c;
24+	d[0x7] = type;
25+	return uxn_eval(u, PEEK2(d));
26+}
27+
28+void
29+console_deo(Uint8 *d, Uint8 port)
30+{
31+	switch(port) {
32+	case 0x8:
33+		fputc(d[port], stdout);
34+		fflush(stdout);
35+		return;
36+	case 0x9:
37+		fputc(d[port], stderr);
38+		fflush(stderr);
39+		return;
40+	}
41+}
+22, -0
 1@@ -0,0 +1,22 @@
 2+/*
 3+Copyright (c) 2021 Devine Lu Linvega, Andrew Alderwick
 4+
 5+Permission to use, copy, modify, and distribute this software for any
 6+purpose with or without fee is hereby granted, provided that the above
 7+copyright notice and this permission notice appear in all copies.
 8+
 9+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10+WITH REGARD TO THIS SOFTWARE.
11+*/
12+
13+#define CONSOLE_VERSION 1
14+#define CONSOLE_DEIMASK 0x0000
15+#define CONSOLE_DEOMASK 0x0300
16+
17+#define CONSOLE_STD 0x1
18+#define CONSOLE_ARG 0x2
19+#define CONSOLE_EOA 0x3
20+#define CONSOLE_END 0x4
21+
22+int console_input(Uxn *u, char c, int type);
23+void console_deo(Uint8 *d, Uint8 port);
+1, -1
1@@ -2,7 +2,7 @@
2 #include "controller.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
+4, -0
 1@@ -9,6 +9,10 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 2 WITH REGARD TO THIS SOFTWARE.
 3 */
 4 
 5+#define CONTROL_VERSION 1
 6+#define CONTROL_DEIMASK 0x0000
 7+#define CONTROL_DEOMASK 0x0000
 8+
 9 void controller_down(Uxn *u, Uint8 *d, Uint8 mask);
10 void controller_up(Uxn *u, Uint8 *d, Uint8 mask);
11 void controller_key(Uxn *u, Uint8 *d, Uint8 key);
+4, -0
1@@ -9,4 +9,8 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
2 WITH REGARD TO THIS SOFTWARE.
3 */
4 
5+#define DATETIME_VERSION 1
6+#define DATETIME_DEIMASK 0x07ff
7+#define DATETIME_DEOMASK 0x0000
8+
9 Uint8 datetime_dei(Uxn *u, Uint8 addr);
+6, -1
 1@@ -126,10 +126,11 @@ static char *
 2 retry_realpath(const char *file_name)
 3 {
 4 	char *r, p[PATH_MAX] = {'\0'}, *x;
 5+	int fnlen;
 6 	if(file_name == NULL) {
 7 		errno = EINVAL;
 8 		return NULL;
 9-	} else if(strlen(file_name) >= PATH_MAX) {
10+	} else if((fnlen = strlen(file_name)) >= PATH_MAX) {
11 		errno = ENAMETOOLONG;
12 		return NULL;
13 	}
14@@ -137,6 +138,10 @@ retry_realpath(const char *file_name)
15 		/* TODO: use a macro instead of '/' for absolute path first character so that other systems can work */
16 		/* if a relative path, prepend cwd */
17 		getcwd(p, sizeof(p));
18+		if(strlen(p) + strlen(DIR_SEP_STR) + fnlen >= PATH_MAX) {
19+			errno = ENAMETOOLONG;
20+			return NULL;
21+		}
22 		strcat(p, DIR_SEP_STR); /* TODO: use a macro instead of '/' for the path delimiter */
23 	}
24 	strcat(p, file_name);
+4, -0
 1@@ -9,6 +9,10 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 2 WITH REGARD TO THIS SOFTWARE.
 3 */
 4 
 5+#define FILE_VERSION 1
 6+#define FILE_DEIMASK 0x0000
 7+#define FILE_DEOMASK 0xa260
 8+
 9 #define POLYFILEY 2
10 #define DEV_FILE0 0xa
11 
+4, -0
 1@@ -9,6 +9,10 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 2 WITH REGARD TO THIS SOFTWARE.
 3 */
 4 
 5+#define MOUSE_VERSION 1
 6+#define MOUSE_DEIMASK 0x0000
 7+#define MOUSE_DEOMASK 0x0000
 8+
 9 void mouse_down(Uxn *u, Uint8 *d, Uint8 mask);
10 void mouse_up(Uxn *u, Uint8 *d, Uint8 mask);
11 void mouse_pos(Uxn *u, Uint8 *d, Uint16 x, Uint16 y);
+5, -2
 1@@ -1,6 +1,5 @@
 2 /*
 3-Copyright (c) 2021 Devine Lu Linvega
 4-Copyright (c) 2021 Andrew Alderwick
 5+Copyright (c) 2021 Devine Lu Linvega, Andrew Alderwick
 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@@ -10,6 +9,10 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 WITH REGARD TO THIS SOFTWARE.
11 */
12 
13+#define SCREEN_VERSION 1
14+#define SCREEN_DEIMASK 0x003c
15+#define SCREEN_DEOMASK 0xc028
16+
17 typedef struct UxnScreen {
18 	int width, height, x1, y1, x2, y2;
19 	Uint32 palette[4], *pixels;
+19, -51
 1@@ -1,6 +1,5 @@
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4-#include <pthread.h>
 5 
 6 #include "../uxn.h"
 7 #include "system.h"
 8@@ -75,33 +74,24 @@ system_inspect(Uxn *u)
 9 	system_print(&u->rst, "rst");
10 }
11 
12-static Uint8 *global_ram, friends_count = 0;
13-static Uint16 friends_tasks[MAX_FRIENDS];
14-static pthread_t friends[MAX_FRIENDS];
15-
16-static void *
17-friend_task(void *vector)
18+void
19+system_connect(Uint8 device, Uint8 ver, Uint16 dei, Uint16 deo)
20 {
21-	Uxn friend;
22-	uxn_boot(&friend, global_ram);
23-	uxn_eval(&friend, *((Uint16 *)vector));
24-	return NULL;
25+	dev_vers[device] = ver;
26+	dei_mask[device] = dei;
27+	deo_mask[device] = deo;
28 }
29 
30-static void
31-system_friend(Uint8 *ram, Uint16 task)
32+int
33+system_version(char *name, char *date)
34 {
35-	if(!task) {
36-		while(friends_count)
37-			pthread_join(friends[--friends_count], NULL);
38-	} else if(friends_count >= MAX_FRIENDS) {
39-		system_error("friends", "Too many threads");
40-	} else {
41-		global_ram = ram;
42-		friends_tasks[friends_count] = task;
43-		pthread_create(&friends[friends_count], NULL, friend_task, (void *)&friends_tasks[friends_count]);
44-		friends_count++;
45-	}
46+	int i;
47+	printf("%s, %s.\n", name, date);
48+	printf("Device Version Dei  Deo\n");
49+	for(i = 0; i < 0x10; i++)
50+		if(dev_vers[i])
51+			printf("%6x %7d %04x %04x\n", i, dev_vers[i], dei_mask[i], deo_mask[i]);
52+	return 0;
53 }
54 
55 /* IO */
56@@ -114,7 +104,11 @@ system_deo(Uxn *u, Uint8 *d, Uint8 port)
57 		system_cmd(u->ram, PEEK2(d + 2));
58 		break;
59 	case 0x5:
60-		system_friend(u->ram, PEEK2(d + 4));
61+		if(PEEK2(d + 4)) {
62+			Uxn friend;
63+			uxn_boot(&friend, u->ram);
64+			uxn_eval(&friend, PEEK2(d + 4));
65+		}
66 		break;
67 	case 0xe:
68 		system_inspect(u);
69@@ -142,29 +136,3 @@ emu_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr)
70 	}
71 	return 0;
72 }
73-
74-/* Console */
75-
76-int
77-console_input(Uxn *u, char c, int type)
78-{
79-	Uint8 *d = &u->dev[0x10];
80-	d[0x2] = c;
81-	d[0x7] = type;
82-	return uxn_eval(u, PEEK2(d));
83-}
84-
85-void
86-console_deo(Uint8 *d, Uint8 port)
87-{
88-	switch(port) {
89-	case 0x8:
90-		fputc(d[port], stdout);
91-		fflush(stdout);
92-		return;
93-	case 0x9:
94-		fputc(d[port], stderr);
95-		fflush(stderr);
96-		return;
97-	}
98-}
+6, -8
 1@@ -9,17 +9,15 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 2 WITH REGARD TO THIS SOFTWARE.
 3 */
 4 
 5-#define RAM_PAGES 0x10
 6-#define MAX_FRIENDS 0x10
 7+#define SYSTEM_VERSION 1
 8+#define SYSTEM_DEIMASK 0x0000
 9+#define SYSTEM_DEOMASK 0xff28
10 
11-#define CONSOLE_STD 0x1
12-#define CONSOLE_ARG 0x2
13-#define CONSOLE_EOA 0x3
14-#define CONSOLE_END 0x4
15+#define RAM_PAGES 0x10
16 
17+void system_connect(Uint8 device, Uint8 ver, Uint16 dei, Uint16 deo);
18+int system_version(char *emulator, char *date);
19 int system_load(Uxn *u, char *filename);
20 void system_inspect(Uxn *u);
21 int system_error(char *msg, const char *err);
22 void system_deo(Uxn *u, Uint8 *d, Uint8 port);
23-int console_input(Uxn *u, char c, int type);
24-void console_deo(Uint8 *d, Uint8 port);
+1, -0
1@@ -95,4 +95,5 @@ uxn_boot(Uxn *u, Uint8 *ram)
2 		cptr[i] = 0;
3 	u->ram = ram;
4 	return 1;
5+
6 }
+3, -4
 1@@ -9,8 +9,6 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 2 WITH REGARD TO THIS SOFTWARE.
 3 */
 4 
 5-#define PAGE_PROGRAM 0x0100
 6-
 7 /* clang-format off */
 8 
 9 #define POKE2(d, v) { (d)[0] = (v) >> 8; (d)[1] = (v); }
10@@ -20,6 +18,8 @@ WITH REGARD TO THIS SOFTWARE.
11 
12 /* clang-format on */
13 
14+#define PAGE_PROGRAM 0x0100
15+
16 typedef unsigned char Uint8;
17 typedef signed char Sint8;
18 typedef unsigned short Uint16;
19@@ -42,8 +42,7 @@ typedef struct Uxn {
20 extern Uint8 emu_dei(Uxn *u, Uint8 addr);
21 extern void emu_deo(Uxn *u, Uint8 addr);
22 extern int emu_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr);
23-extern Uint16 dei_mask[];
24-extern Uint16 deo_mask[];
25+extern Uint16 dev_vers[0x10], dei_mask[0x10], deo_mask[0x10];
26 
27 /* built-ins */
28 
+20, -5
 1@@ -9,6 +9,7 @@
 2 
 3 #include "uxn.h"
 4 #include "devices/system.h"
 5+#include "devices/console.h"
 6 #include "devices/screen.h"
 7 #include "devices/controller.h"
 8 #include "devices/mouse.h"
 9@@ -39,8 +40,7 @@ char *rom_path;
10 #define SCALE 1
11 #define CONINBUFSIZE 256
12 
13-Uint16 deo_mask[] = {0xff28, 0x0300, 0xc028, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x0000, 0x0000, 0xa260, 0xa260, 0x0000, 0x0000, 0x0000, 0x0000};
14-Uint16 dei_mask[] = {0x0000, 0x0000, 0x003c, 0x0014, 0x0014, 0x0014, 0x0014, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07ff, 0x0000, 0x0000, 0x0000};
15+Uint16 dev_vers[0x10], dei_mask[0x10], deo_mask[0x10];
16 
17 static int
18 clamp(int val, int min, int max)
19@@ -201,13 +201,28 @@ int
20 main(int argc, char **argv)
21 {
22 	Uxn u;
23-	int i, n;
24+	int i = 1, n;
25 	char expirations[8];
26 	char coninp[CONINBUFSIZE];
27 	struct pollfd fds[3];
28 	static const struct itimerspec screen_tspec = {{0, 16666666}, {0, 16666666}};
29-	if(argc < 2)
30-		return system_error("usage", "uxn11 file.rom [args...]");
31+	if(i == argc)
32+		return system_error("usage", "uxn11 [-v][-2x][-3x] file.rom [args...]");
33+	/* Connect Varvara */
34+	system_connect(0x0, SYSTEM_VERSION, SYSTEM_DEIMASK, SYSTEM_DEOMASK);
35+	system_connect(0x1, CONSOLE_VERSION, CONSOLE_DEIMASK, CONSOLE_DEOMASK);
36+	system_connect(0x2, SCREEN_VERSION, SCREEN_DEIMASK, SCREEN_DEOMASK);
37+	system_connect(0x8, CONTROL_VERSION, CONTROL_DEIMASK, CONTROL_DEOMASK);
38+	system_connect(0x9, MOUSE_VERSION, MOUSE_DEIMASK, MOUSE_DEOMASK);
39+	system_connect(0xa, FILE_VERSION, FILE_DEIMASK, FILE_DEOMASK);
40+	system_connect(0xb, FILE_VERSION, FILE_DEIMASK, FILE_DEOMASK);
41+	system_connect(0xc, DATETIME_VERSION, DATETIME_DEIMASK, DATETIME_DEOMASK);
42+	/* Read flags */
43+	if(argv[i][0] == '-' && argv[i][1] == 'v')
44+		return system_version("Uxn11 - Graphical Varvara Emulator", "8 Aug 2023");
45+
46+
47+
48 	rom_path = argv[1];
49 	if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8))))
50 		return system_error("boot", "Failed");
+15, -3
 1@@ -3,6 +3,7 @@
 2 
 3 #include "uxn.h"
 4 #include "devices/system.h"
 5+#include "devices/console.h"
 6 #include "devices/file.h"
 7 #include "devices/datetime.h"
 8 
 9@@ -17,8 +18,7 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 WITH REGARD TO THIS SOFTWARE.
11 */
12 
13-Uint16 deo_mask[] = {0xc028, 0x0300, 0xc028, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x0000, 0x0000, 0xa260, 0xa260, 0x0000, 0x0000, 0x0000, 0x0000};
14-Uint16 dei_mask[] = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07ff, 0x0000, 0x0000, 0x0000};
15+Uint16 dev_vers[0x10], dei_mask[0x10], deo_mask[0x10];
16 
17 Uint8
18 emu_dei(Uxn *u, Uint8 addr)
19@@ -47,11 +47,23 @@ main(int argc, char **argv)
20 	Uxn u;
21 	int i = 1;
22 	if(i == argc)
23-		return system_error("usage", "uxncli file.rom [args..]");
24+		return system_error("usage", "uxncli [-v] file.rom [args..]");
25+	/* Connect Varvara */
26+	system_connect(0x0, SYSTEM_VERSION, SYSTEM_DEIMASK, SYSTEM_DEOMASK);
27+	system_connect(0x1, CONSOLE_VERSION, CONSOLE_DEIMASK, CONSOLE_DEOMASK);
28+	system_connect(0xa, FILE_VERSION, FILE_DEIMASK, FILE_DEOMASK);
29+	system_connect(0xb, FILE_VERSION, FILE_DEIMASK, FILE_DEOMASK);
30+	system_connect(0xc, DATETIME_VERSION, DATETIME_DEIMASK, DATETIME_DEOMASK);
31+	/* Read flags */
32+	if(argv[i][0] == '-' && argv[i][1] == 'v')
33+		return system_version("Uxncli - Console Varvara Emulator", "8 Aug 2023");
34+	/* Continue.. */
35 	if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8))))
36 		return system_error("Boot", "Failed");
37+	/* Load rom */
38 	if(!system_load(&u, argv[i++]))
39 		return system_error("Load", "Failed");
40+	/* Game Loop */
41 	u.dev[0x17] = argc - i;
42 	if(uxn_eval(&u, PAGE_PROGRAM)) {
43 		for(; i < argc; i++) {