Housekeeping

This commit is contained in:
neauoire 2023-11-11 09:50:19 -08:00
parent d98e8d43a8
commit 7a9bc710e6
8 changed files with 43 additions and 57 deletions

View File

@ -1,6 +1,6 @@
# Uxn11 # Uxn11
An emulator for the [Uxn stack-machine](https://wiki.xxiivv.com/site/uxn.html), written in ANSI C. An emulator for the [Uxn stack-machine](https://wiki.xxiivv.com/site/uxn.html), written in ANSI C. The emulator contains a few linux specific utilities in the Console device to allow for it to interface with the unix systems.
## Building ## Building
@ -37,7 +37,7 @@ bin/uxnemu bin/polycat.rom arg1 arg2
The file device is _sandboxed_, meaning that it should not be able to read or write outside of the working directory. The file device is _sandboxed_, meaning that it should not be able to read or write outside of the working directory.
- `00` system - `00` system
- `10` console - `10` console(+)
- `20` screen - `20` screen
- `80` controller - `80` controller
- `90` mouse - `90` mouse

View File

@ -41,35 +41,38 @@ static int from_child_fd[2];
static int saved_in; static int saved_in;
static int saved_out; static int saved_out;
struct winsize ws = {24, 80, 8, 12};
static void static void
parse_args(Uint8 *d, Uxn *u) parse_args(Uxn *u, Uint8 *d)
{ {
int addr = (d[0x3] << 8) | d[0x4]; Uint8 *port_addr = d + 0x3;
int addr = PEEK2(port_addr);
char *pos = (char *)&u->ram[addr]; char *pos = (char *)&u->ram[addr];
int i = 0; int i = 0;
do { do {
fork_args[i++] = pos; fork_args[i++] = pos;
while (*pos != 0) pos++; while(*pos != 0) pos++;
pos++; pos++;
} while (*pos != '\0'); } while(*pos != '\0');
fork_args[i] = NULL; fork_args[i] = NULL;
} }
/* call after we're sure the process has exited */ /* call after we're sure the process has exited */
static void static void
clean_after_child() clean_after_child(void)
{ {
child_pid = 0; child_pid = 0;
if (child_mode >= 0x80) { if(child_mode >= 0x80) {
close(pty_fd); close(pty_fd);
dup2(saved_in, 0); dup2(saved_in, 0);
dup2(saved_out, 1); dup2(saved_out, 1);
} else { } else {
if (child_mode & 0x01) { if(child_mode & 0x01) {
close(to_child_fd[1]); close(to_child_fd[1]);
dup2(saved_out, 1); dup2(saved_out, 1);
} }
if (child_mode & 0x06) { if(child_mode & 0x06) {
close(from_child_fd[0]); close(from_child_fd[0]);
dup2(saved_in, 0); dup2(saved_in, 0);
} }
@ -99,14 +102,14 @@ console_listen(Uxn *u, int i, int argc, char **argv)
} }
static void static void
start_fork_pty(Uint8 *d, Uxn *u) start_fork_pty(Uint8 *d)
{ {
int fd = -1; int fd = -1;
pid_t pid = forkpty(&fd, NULL, NULL, NULL); pid_t pid = forkpty(&fd, NULL, NULL, NULL);
if (pid < 0) { /* failure */ if(pid < 0) { /* failure */
d[0x6] = 0xff; d[0x6] = 0xff;
fprintf(stderr, "fork failure\n"); fprintf(stderr, "fork failure\n");
} else if (pid == 0) { /* child */ } else if(pid == 0) { /* child */
setenv("TERM", "ansi", 1); setenv("TERM", "ansi", 1);
execvp(fork_args[0], fork_args); execvp(fork_args[0], fork_args);
d[0x6] = 0xff; d[0x6] = 0xff;
@ -114,7 +117,6 @@ start_fork_pty(Uint8 *d, Uxn *u)
} else { /*parent*/ } else { /*parent*/
child_pid = pid; child_pid = pid;
pty_fd = fd; pty_fd = fd;
struct winsize ws = {24, 80, 8, 12};
ioctl(fd, TIOCSWINSZ, &ws); ioctl(fd, TIOCSWINSZ, &ws);
saved_in = dup(0); saved_in = dup(0);
saved_out = dup(1); saved_out = dup(1);
@ -124,20 +126,20 @@ start_fork_pty(Uint8 *d, Uxn *u)
} }
static void static void
start_fork_pipe(Uint8 *d, Uxn *u) start_fork_pipe(Uint8 *d)
{ {
if (child_mode & 0x01) { if(child_mode & 0x01) {
/* parent writes to child's stdin */ /* parent writes to child's stdin */
if (pipe(to_child_fd) == -1) { if(pipe(to_child_fd) == -1) {
d[0x6] = 0xff; d[0x6] = 0xff;
fprintf(stderr, "pipe error: to child\n"); fprintf(stderr, "pipe error: to child\n");
return; return;
} }
} }
if (child_mode & 0x06) { if(child_mode & 0x06) {
/* parent reads from child's stdout and/or stderr */ /* parent reads from child's stdout and/or stderr */
if (pipe(from_child_fd) == -1) { if(pipe(from_child_fd) == -1) {
d[0x6] = 0xff; d[0x6] = 0xff;
fprintf(stderr, "pipe error: from child\n"); fprintf(stderr, "pipe error: from child\n");
return; return;
@ -145,17 +147,17 @@ start_fork_pipe(Uint8 *d, Uxn *u)
} }
pid_t pid = fork(); pid_t pid = fork();
if (pid < 0) { /* failure */ if(pid < 0) { /* failure */
d[0x6] = 0xff; d[0x6] = 0xff;
fprintf(stderr, "fork failure\n"); fprintf(stderr, "fork failure\n");
} else if (pid == 0) { /* child */ } else if(pid == 0) { /* child */
if (child_mode & 0x01) { if(child_mode & 0x01) {
dup2(to_child_fd[0], 0); dup2(to_child_fd[0], 0);
close(to_child_fd[1]); close(to_child_fd[1]);
} }
if (child_mode & 0x06) { if(child_mode & 0x06) {
if (child_mode & 0x02) dup2(from_child_fd[1], 1); if(child_mode & 0x02) dup2(from_child_fd[1], 1);
if (child_mode & 0x04) dup2(from_child_fd[1], 2); if(child_mode & 0x04) dup2(from_child_fd[1], 2);
close(from_child_fd[0]); close(from_child_fd[0]);
} }
execvp(fork_args[0], fork_args); execvp(fork_args[0], fork_args);
@ -163,12 +165,12 @@ start_fork_pipe(Uint8 *d, Uxn *u)
fprintf(stderr, "exec failure\n"); fprintf(stderr, "exec failure\n");
} else { /*parent*/ } else { /*parent*/
child_pid = pid; child_pid = pid;
if (child_mode & 0x01) { if(child_mode & 0x01) {
saved_out = dup(1); saved_out = dup(1);
dup2(to_child_fd[1], 1); dup2(to_child_fd[1], 1);
close(to_child_fd[0]); close(to_child_fd[0]);
} }
if (child_mode & 0x06) { if(child_mode & 0x06) {
saved_in = dup(0); saved_in = dup(0);
dup2(from_child_fd[0], 0); dup2(from_child_fd[0], 0);
close(from_child_fd[1]); close(from_child_fd[1]);
@ -179,10 +181,10 @@ start_fork_pipe(Uint8 *d, Uxn *u)
static void static void
kill_child(Uint8 *d) kill_child(Uint8 *d)
{ {
if (child_pid) { if(child_pid) {
kill(child_pid, 9); kill(child_pid, 9);
int wstatus; int wstatus;
if (waitpid(child_pid, &wstatus, 0)) { if(waitpid(child_pid, &wstatus, 0)) {
d[0x6] = 1; d[0x6] = 1;
d[0x7] = WEXITSTATUS(wstatus); d[0x7] = WEXITSTATUS(wstatus);
clean_after_child(); clean_after_child();
@ -196,12 +198,11 @@ start_fork(Uxn *u, Uint8 *d)
fflush(stderr); fflush(stderr);
kill_child(d); kill_child(d);
child_mode = d[0x5]; child_mode = d[0x5];
parse_args(d, u); parse_args(u, d);
if (child_mode >= 0x80) { if(child_mode >= 0x80)
start_fork_pty(d, u); start_fork_pty(d);
} else { else
start_fork_pipe(d, u); start_fork_pipe(d);
}
} }
Uint8 Uint8
@ -211,9 +212,9 @@ console_dei(Uxn *u, Uint8 addr)
switch(port) { switch(port) {
case 0x6: case 0x6:
case 0x7: case 0x7:
if (child_pid) { if(child_pid) {
int wstatus; int wstatus;
if (waitpid(child_pid, &wstatus, WNOHANG)) { if(waitpid(child_pid, &wstatus, WNOHANG)) {
d[0x6] = 1; d[0x6] = 1;
d[0x7] = WEXITSTATUS(wstatus); d[0x7] = WEXITSTATUS(wstatus);
clean_after_child(); clean_after_child();

View File

@ -10,8 +10,6 @@ WITH REGARD TO THIS SOFTWARE.
*/ */
#define CONSOLE_VERSION 1 #define CONSOLE_VERSION 1
#define CONSOLE_DEIMASK 0x0000
#define CONSOLE_DEOMASK 0x0300
#define CONSOLE_STD 0x1 #define CONSOLE_STD 0x1
#define CONSOLE_ARG 0x2 #define CONSOLE_ARG 0x2

View File

@ -10,8 +10,6 @@ WITH REGARD TO THIS SOFTWARE.
*/ */
#define CONTROL_VERSION 1 #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);

View File

@ -10,7 +10,5 @@ WITH REGARD TO THIS SOFTWARE.
*/ */
#define DATETIME_VERSION 1 #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

@ -10,8 +10,6 @@ WITH REGARD TO THIS SOFTWARE.
*/ */
#define LINK_VERSION 1 #define LINK_VERSION 1
#define LINK_DEIMASK 0x0000
#define LINK_DEOMASK 0xaaaa
Uint8 link_dei(Uxn *u, Uint8 addr); Uint8 link_dei(Uxn *u, Uint8 addr);
void link_deo(Uint8 *ram, Uint8 *d, Uint8 port); void link_deo(Uint8 *ram, Uint8 *d, Uint8 port);

View File

@ -10,8 +10,6 @@ WITH REGARD TO THIS SOFTWARE.
*/ */
#define SCREEN_VERSION 1 #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;
@ -19,14 +17,13 @@ typedef struct UxnScreen {
Uint8 *fg, *bg; Uint8 *fg, *bg;
} UxnScreen; } UxnScreen;
extern UxnScreen uxn_screen;
extern int emu_resize(int width, int height);
void screen_fill(Uint8 *layer, int x1, int y1, int x2, int y2, int color); void screen_fill(Uint8 *layer, int x1, int y1, int x2, int y2, int color);
void screen_palette(Uint8 *addr); void screen_palette(Uint8 *addr);
void screen_resize(Uint16 width, Uint16 height); void screen_resize(Uint16 width, Uint16 height);
void screen_change(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2); void screen_change(Uint16 x1, Uint16 y1, Uint16 x2, Uint16 y2);
void screen_redraw(Uxn *u); void screen_redraw(Uxn *u);
Uint8 screen_dei(Uxn *u, Uint8 addr); Uint8 screen_dei(Uxn *u, Uint8 addr);
void screen_deo(Uint8 *ram, Uint8 *d, Uint8 port); void screen_deo(Uint8 *ram, Uint8 *d, Uint8 port);
extern UxnScreen uxn_screen;
extern int emu_resize(int width, int height);

View File

@ -10,18 +10,14 @@ WITH REGARD TO THIS SOFTWARE.
*/ */
#define SYSTEM_VERSION 2 #define SYSTEM_VERSION 2
#define SYSTEM_DEIMASK 0x0030
#define SYSTEM_DEOMASK 0xff38
#define RAM_PAGES 0x10 #define RAM_PAGES 0x10
extern char *boot_rom;
void system_reboot(Uxn *u, char *rom, int soft); void system_reboot(Uxn *u, char *rom, int soft);
void system_inspect(Uxn *u); void system_inspect(Uxn *u);
int system_version(char *emulator, char *date); int system_version(char *emulator, char *date);
int system_error(char *msg, const char *err); int system_error(char *msg, const char *err);
int system_init(Uxn *u, Uint8 *ram, char *rom); int system_init(Uxn *u, Uint8 *ram, char *rom);
Uint8 system_dei(Uxn *u, Uint8 addr); Uint8 system_dei(Uxn *u, Uint8 addr);
void system_deo(Uxn *u, Uint8 *d, Uint8 port); void system_deo(Uxn *u, Uint8 *d, Uint8 port);
extern char *boot_rom;