Version 1

This commit is contained in:
neauoire 2023-08-08 16:26:13 -07:00
parent 9fd8b1709e
commit 1355d7813e
16 changed files with 166 additions and 77 deletions

View File

@ -2,7 +2,7 @@
RELEASE_FLAGS="-DNDEBUG -O2 -g0 -s" RELEASE_FLAGS="-DNDEBUG -O2 -g0 -s"
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" 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"
CORE_DEVICES="src/uxn.c src/devices/system.c src/devices/file.c src/devices/datetime.c -lpthread" CORE_DEVICES="src/uxn.c src/devices/system.c src/devices/console.c src/devices/file.c src/devices/datetime.c -lpthread"
EMU_INC="${CORE_DEVICES} src/devices/screen.c src/devices/controller.c src/devices/mouse.c src/uxn11.c -o bin/uxn11 -lX11" EMU_INC="${CORE_DEVICES} src/devices/screen.c src/devices/controller.c src/devices/mouse.c src/uxn11.c -o bin/uxn11 -lX11"
CLI_INC="${CORE_DEVICES} src/uxncli.c -o bin/uxncli" CLI_INC="${CORE_DEVICES} src/uxncli.c -o bin/uxncli"
@ -36,7 +36,7 @@ fi
if [ "${1}" = '--install' ]; if [ "${1}" = '--install' ];
then then
cp bin/uxn11 bin/uxnemu cp bin/uxn11 bin/uxn11
cp bin/uxnemu bin/uxnasm bin/uxncli $HOME/bin/ cp bin/uxnemu bin/uxnasm bin/uxncli $HOME/bin/
fi fi
@ -46,6 +46,16 @@ fi
if [ "${1}" = '--norun' ]; then exit; fi if [ "${1}" = '--norun' ]; then exit; fi
# Test usage
./bin/uxncli
./bin/uxn11
# Test version
./bin/uxncli -v
./bin/uxn11 -v
# bin/uxnasm etc/mouse.tal bin/res.rom # bin/uxnasm etc/mouse.tal bin/res.rom
bin/uxnasm etc/pict.tal bin/res.rom bin/uxnasm etc/pict.tal bin/res.rom
bin/uxn11 bin/res.rom bin/uxn11 bin/res.rom

40
src/devices/console.c Normal file
View File

@ -0,0 +1,40 @@
#include <stdio.h>
#include <stdlib.h>
#include "../uxn.h"
#include "console.h"
/*
Copyright (c) 2022-2023 Devine Lu Linvega, Andrew Alderwick
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
int
console_input(Uxn *u, char c, int type)
{
Uint8 *d = &u->dev[0x10];
d[0x2] = c;
d[0x7] = type;
return uxn_eval(u, PEEK2(d));
}
void
console_deo(Uint8 *d, Uint8 port)
{
switch(port) {
case 0x8:
fputc(d[port], stdout);
fflush(stdout);
return;
case 0x9:
fputc(d[port], stderr);
fflush(stderr);
return;
}
}

22
src/devices/console.h Normal file
View File

@ -0,0 +1,22 @@
/*
Copyright (c) 2021 Devine Lu Linvega, Andrew Alderwick
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE.
*/
#define CONSOLE_VERSION 1
#define CONSOLE_DEIMASK 0x0000
#define CONSOLE_DEOMASK 0x0300
#define CONSOLE_STD 0x1
#define CONSOLE_ARG 0x2
#define CONSOLE_EOA 0x3
#define CONSOLE_END 0x4
int console_input(Uxn *u, char c, int type);
void console_deo(Uint8 *d, Uint8 port);

View File

@ -2,7 +2,7 @@
#include "controller.h" #include "controller.h"
/* /*
Copyright (c) 2021 Devine Lu Linvega, Andrew Alderwick Copyright (c) 2021-2023 Devine Lu Linvega, Andrew Alderwick
Permission to use, copy, modify, and distribute this software for any Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above

View File

@ -9,6 +9,10 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE. WITH REGARD TO THIS SOFTWARE.
*/ */
#define CONTROL_VERSION 1
#define CONTROL_DEIMASK 0x0000
#define CONTROL_DEOMASK 0x0000
void controller_down(Uxn *u, Uint8 *d, Uint8 mask); void controller_down(Uxn *u, Uint8 *d, Uint8 mask);
void controller_up(Uxn *u, Uint8 *d, Uint8 mask); void controller_up(Uxn *u, Uint8 *d, Uint8 mask);
void controller_key(Uxn *u, Uint8 *d, Uint8 key); void controller_key(Uxn *u, Uint8 *d, Uint8 key);

View File

@ -9,4 +9,8 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE. WITH REGARD TO THIS SOFTWARE.
*/ */
#define DATETIME_VERSION 1
#define DATETIME_DEIMASK 0x07ff
#define DATETIME_DEOMASK 0x0000
Uint8 datetime_dei(Uxn *u, Uint8 addr); Uint8 datetime_dei(Uxn *u, Uint8 addr);

View File

@ -126,10 +126,11 @@ static char *
retry_realpath(const char *file_name) retry_realpath(const char *file_name)
{ {
char *r, p[PATH_MAX] = {'\0'}, *x; char *r, p[PATH_MAX] = {'\0'}, *x;
int fnlen;
if(file_name == NULL) { if(file_name == NULL) {
errno = EINVAL; errno = EINVAL;
return NULL; return NULL;
} else if(strlen(file_name) >= PATH_MAX) { } else if((fnlen = strlen(file_name)) >= PATH_MAX) {
errno = ENAMETOOLONG; errno = ENAMETOOLONG;
return NULL; return NULL;
} }
@ -137,6 +138,10 @@ retry_realpath(const char *file_name)
/* TODO: use a macro instead of '/' for absolute path first character so that other systems can work */ /* TODO: use a macro instead of '/' for absolute path first character so that other systems can work */
/* if a relative path, prepend cwd */ /* if a relative path, prepend cwd */
getcwd(p, sizeof(p)); getcwd(p, sizeof(p));
if(strlen(p) + strlen(DIR_SEP_STR) + fnlen >= PATH_MAX) {
errno = ENAMETOOLONG;
return NULL;
}
strcat(p, DIR_SEP_STR); /* TODO: use a macro instead of '/' for the path delimiter */ strcat(p, DIR_SEP_STR); /* TODO: use a macro instead of '/' for the path delimiter */
} }
strcat(p, file_name); strcat(p, file_name);

View File

@ -9,6 +9,10 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE. WITH REGARD TO THIS SOFTWARE.
*/ */
#define FILE_VERSION 1
#define FILE_DEIMASK 0x0000
#define FILE_DEOMASK 0xa260
#define POLYFILEY 2 #define POLYFILEY 2
#define DEV_FILE0 0xa #define DEV_FILE0 0xa

View File

@ -9,6 +9,10 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE. WITH REGARD TO THIS SOFTWARE.
*/ */
#define MOUSE_VERSION 1
#define MOUSE_DEIMASK 0x0000
#define MOUSE_DEOMASK 0x0000
void mouse_down(Uxn *u, Uint8 *d, Uint8 mask); void mouse_down(Uxn *u, Uint8 *d, Uint8 mask);
void mouse_up(Uxn *u, Uint8 *d, Uint8 mask); void mouse_up(Uxn *u, Uint8 *d, Uint8 mask);
void mouse_pos(Uxn *u, Uint8 *d, Uint16 x, Uint16 y); void mouse_pos(Uxn *u, Uint8 *d, Uint16 x, Uint16 y);

View File

@ -1,6 +1,5 @@
/* /*
Copyright (c) 2021 Devine Lu Linvega Copyright (c) 2021 Devine Lu Linvega, Andrew Alderwick
Copyright (c) 2021 Andrew Alderwick
Permission to use, copy, modify, and distribute this software for any Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@ -10,6 +9,10 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE. WITH REGARD TO THIS SOFTWARE.
*/ */
#define SCREEN_VERSION 1
#define SCREEN_DEIMASK 0x003c
#define SCREEN_DEOMASK 0xc028
typedef struct UxnScreen { typedef struct UxnScreen {
int width, height, x1, y1, x2, y2; int width, height, x1, y1, x2, y2;
Uint32 palette[4], *pixels; Uint32 palette[4], *pixels;

View File

@ -1,6 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <pthread.h>
#include "../uxn.h" #include "../uxn.h"
#include "system.h" #include "system.h"
@ -75,33 +74,24 @@ system_inspect(Uxn *u)
system_print(&u->rst, "rst"); system_print(&u->rst, "rst");
} }
static Uint8 *global_ram, friends_count = 0; void
static Uint16 friends_tasks[MAX_FRIENDS]; system_connect(Uint8 device, Uint8 ver, Uint16 dei, Uint16 deo)
static pthread_t friends[MAX_FRIENDS];
static void *
friend_task(void *vector)
{ {
Uxn friend; dev_vers[device] = ver;
uxn_boot(&friend, global_ram); dei_mask[device] = dei;
uxn_eval(&friend, *((Uint16 *)vector)); deo_mask[device] = deo;
return NULL;
} }
static void int
system_friend(Uint8 *ram, Uint16 task) system_version(char *name, char *date)
{ {
if(!task) { int i;
while(friends_count) printf("%s, %s.\n", name, date);
pthread_join(friends[--friends_count], NULL); printf("Device Version Dei Deo\n");
} else if(friends_count >= MAX_FRIENDS) { for(i = 0; i < 0x10; i++)
system_error("friends", "Too many threads"); if(dev_vers[i])
} else { printf("%6x %7d %04x %04x\n", i, dev_vers[i], dei_mask[i], deo_mask[i]);
global_ram = ram; return 0;
friends_tasks[friends_count] = task;
pthread_create(&friends[friends_count], NULL, friend_task, (void *)&friends_tasks[friends_count]);
friends_count++;
}
} }
/* IO */ /* IO */
@ -114,7 +104,11 @@ system_deo(Uxn *u, Uint8 *d, Uint8 port)
system_cmd(u->ram, PEEK2(d + 2)); system_cmd(u->ram, PEEK2(d + 2));
break; break;
case 0x5: case 0x5:
system_friend(u->ram, PEEK2(d + 4)); if(PEEK2(d + 4)) {
Uxn friend;
uxn_boot(&friend, u->ram);
uxn_eval(&friend, PEEK2(d + 4));
}
break; break;
case 0xe: case 0xe:
system_inspect(u); system_inspect(u);
@ -142,29 +136,3 @@ emu_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr)
} }
return 0; return 0;
} }
/* Console */
int
console_input(Uxn *u, char c, int type)
{
Uint8 *d = &u->dev[0x10];
d[0x2] = c;
d[0x7] = type;
return uxn_eval(u, PEEK2(d));
}
void
console_deo(Uint8 *d, Uint8 port)
{
switch(port) {
case 0x8:
fputc(d[port], stdout);
fflush(stdout);
return;
case 0x9:
fputc(d[port], stderr);
fflush(stderr);
return;
}
}

View File

@ -9,17 +9,15 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE. WITH REGARD TO THIS SOFTWARE.
*/ */
#define SYSTEM_VERSION 1
#define SYSTEM_DEIMASK 0x0000
#define SYSTEM_DEOMASK 0xff28
#define RAM_PAGES 0x10 #define RAM_PAGES 0x10
#define MAX_FRIENDS 0x10
#define CONSOLE_STD 0x1
#define CONSOLE_ARG 0x2
#define CONSOLE_EOA 0x3
#define CONSOLE_END 0x4
void system_connect(Uint8 device, Uint8 ver, Uint16 dei, Uint16 deo);
int system_version(char *emulator, char *date);
int system_load(Uxn *u, char *filename); int system_load(Uxn *u, char *filename);
void system_inspect(Uxn *u); void system_inspect(Uxn *u);
int system_error(char *msg, const char *err); int system_error(char *msg, const char *err);
void system_deo(Uxn *u, Uint8 *d, Uint8 port); void system_deo(Uxn *u, Uint8 *d, Uint8 port);
int console_input(Uxn *u, char c, int type);
void console_deo(Uint8 *d, Uint8 port);

View File

@ -95,4 +95,5 @@ uxn_boot(Uxn *u, Uint8 *ram)
cptr[i] = 0; cptr[i] = 0;
u->ram = ram; u->ram = ram;
return 1; return 1;
} }

View File

@ -9,8 +9,6 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE. WITH REGARD TO THIS SOFTWARE.
*/ */
#define PAGE_PROGRAM 0x0100
/* clang-format off */ /* clang-format off */
#define POKE2(d, v) { (d)[0] = (v) >> 8; (d)[1] = (v); } #define POKE2(d, v) { (d)[0] = (v) >> 8; (d)[1] = (v); }
@ -20,6 +18,8 @@ WITH REGARD TO THIS SOFTWARE.
/* clang-format on */ /* clang-format on */
#define PAGE_PROGRAM 0x0100
typedef unsigned char Uint8; typedef unsigned char Uint8;
typedef signed char Sint8; typedef signed char Sint8;
typedef unsigned short Uint16; typedef unsigned short Uint16;
@ -42,8 +42,7 @@ typedef struct Uxn {
extern Uint8 emu_dei(Uxn *u, Uint8 addr); extern Uint8 emu_dei(Uxn *u, Uint8 addr);
extern void emu_deo(Uxn *u, Uint8 addr); extern void emu_deo(Uxn *u, Uint8 addr);
extern int emu_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr); extern int emu_halt(Uxn *u, Uint8 instr, Uint8 err, Uint16 addr);
extern Uint16 dei_mask[]; extern Uint16 dev_vers[0x10], dei_mask[0x10], deo_mask[0x10];
extern Uint16 deo_mask[];
/* built-ins */ /* built-ins */

View File

@ -9,6 +9,7 @@
#include "uxn.h" #include "uxn.h"
#include "devices/system.h" #include "devices/system.h"
#include "devices/console.h"
#include "devices/screen.h" #include "devices/screen.h"
#include "devices/controller.h" #include "devices/controller.h"
#include "devices/mouse.h" #include "devices/mouse.h"
@ -39,8 +40,7 @@ char *rom_path;
#define SCALE 1 #define SCALE 1
#define CONINBUFSIZE 256 #define CONINBUFSIZE 256
Uint16 deo_mask[] = {0xff28, 0x0300, 0xc028, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x0000, 0x0000, 0xa260, 0xa260, 0x0000, 0x0000, 0x0000, 0x0000}; Uint16 dev_vers[0x10], dei_mask[0x10], deo_mask[0x10];
Uint16 dei_mask[] = {0x0000, 0x0000, 0x003c, 0x0014, 0x0014, 0x0014, 0x0014, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07ff, 0x0000, 0x0000, 0x0000};
static int static int
clamp(int val, int min, int max) clamp(int val, int min, int max)
@ -201,13 +201,28 @@ int
main(int argc, char **argv) main(int argc, char **argv)
{ {
Uxn u; Uxn u;
int i, n; int i = 1, n;
char expirations[8]; char expirations[8];
char coninp[CONINBUFSIZE]; char coninp[CONINBUFSIZE];
struct pollfd fds[3]; struct pollfd fds[3];
static const struct itimerspec screen_tspec = {{0, 16666666}, {0, 16666666}}; static const struct itimerspec screen_tspec = {{0, 16666666}, {0, 16666666}};
if(argc < 2) if(i == argc)
return system_error("usage", "uxn11 file.rom [args...]"); return system_error("usage", "uxn11 [-v][-2x][-3x] file.rom [args...]");
/* Connect Varvara */
system_connect(0x0, SYSTEM_VERSION, SYSTEM_DEIMASK, SYSTEM_DEOMASK);
system_connect(0x1, CONSOLE_VERSION, CONSOLE_DEIMASK, CONSOLE_DEOMASK);
system_connect(0x2, SCREEN_VERSION, SCREEN_DEIMASK, SCREEN_DEOMASK);
system_connect(0x8, CONTROL_VERSION, CONTROL_DEIMASK, CONTROL_DEOMASK);
system_connect(0x9, MOUSE_VERSION, MOUSE_DEIMASK, MOUSE_DEOMASK);
system_connect(0xa, FILE_VERSION, FILE_DEIMASK, FILE_DEOMASK);
system_connect(0xb, FILE_VERSION, FILE_DEIMASK, FILE_DEOMASK);
system_connect(0xc, DATETIME_VERSION, DATETIME_DEIMASK, DATETIME_DEOMASK);
/* Read flags */
if(argv[i][0] == '-' && argv[i][1] == 'v')
return system_version("Uxn11 - Graphical Varvara Emulator", "8 Aug 2023");
rom_path = argv[1]; rom_path = argv[1];
if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)))) if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8))))
return system_error("boot", "Failed"); return system_error("boot", "Failed");

View File

@ -3,6 +3,7 @@
#include "uxn.h" #include "uxn.h"
#include "devices/system.h" #include "devices/system.h"
#include "devices/console.h"
#include "devices/file.h" #include "devices/file.h"
#include "devices/datetime.h" #include "devices/datetime.h"
@ -17,8 +18,7 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE. WITH REGARD TO THIS SOFTWARE.
*/ */
Uint16 deo_mask[] = {0xc028, 0x0300, 0xc028, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x0000, 0x0000, 0xa260, 0xa260, 0x0000, 0x0000, 0x0000, 0x0000}; Uint16 dev_vers[0x10], dei_mask[0x10], deo_mask[0x10];
Uint16 dei_mask[] = {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x07ff, 0x0000, 0x0000, 0x0000};
Uint8 Uint8
emu_dei(Uxn *u, Uint8 addr) emu_dei(Uxn *u, Uint8 addr)
@ -47,11 +47,23 @@ main(int argc, char **argv)
Uxn u; Uxn u;
int i = 1; int i = 1;
if(i == argc) if(i == argc)
return system_error("usage", "uxncli file.rom [args..]"); return system_error("usage", "uxncli [-v] file.rom [args..]");
/* Connect Varvara */
system_connect(0x0, SYSTEM_VERSION, SYSTEM_DEIMASK, SYSTEM_DEOMASK);
system_connect(0x1, CONSOLE_VERSION, CONSOLE_DEIMASK, CONSOLE_DEOMASK);
system_connect(0xa, FILE_VERSION, FILE_DEIMASK, FILE_DEOMASK);
system_connect(0xb, FILE_VERSION, FILE_DEIMASK, FILE_DEOMASK);
system_connect(0xc, DATETIME_VERSION, DATETIME_DEIMASK, DATETIME_DEOMASK);
/* Read flags */
if(argv[i][0] == '-' && argv[i][1] == 'v')
return system_version("Uxncli - Console Varvara Emulator", "8 Aug 2023");
/* Continue.. */
if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)))) if(!uxn_boot(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8))))
return system_error("Boot", "Failed"); return system_error("Boot", "Failed");
/* Load rom */
if(!system_load(&u, argv[i++])) if(!system_load(&u, argv[i++]))
return system_error("Load", "Failed"); return system_error("Load", "Failed");
/* Game Loop */
u.dev[0x17] = argc - i; u.dev[0x17] = argc - i;
if(uxn_eval(&u, PAGE_PROGRAM)) { if(uxn_eval(&u, PAGE_PROGRAM)) {
for(; i < argc; i++) { for(; i < argc; i++) {