Housekeeping
This commit is contained in:
parent
d98e8d43a8
commit
7a9bc710e6
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
|
@ -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;
|
Loading…
Reference in New Issue