Use Apple II I/O vectors for hooking in client functionality

Can now have an Apple II console from Linux!
This commit is contained in:
dschmenk 2013-08-24 21:52:44 -07:00
parent 5559e82d68
commit 3effdc6773
4 changed files with 126 additions and 8 deletions

Binary file not shown.

View File

@ -1,4 +1,4 @@
BIN=a2serclk a2pid a2mon dskread dskwrite bintomon bload brun
BIN=a2serclk a2pid a2mon a2term dskread dskwrite bintomon bload brun
all: $(BIN)

View File

@ -453,7 +453,7 @@ void prlog(char *str)
}
struct a2request *addreq(int a2fd, int reqfd, int type, int addr, int count, char *buffer)
{
char rwchar;
char rwchar;
struct a2request *a2req = a2reqfree;
if (a2req == NULL)
a2req = malloc(sizeof(struct a2request));
@ -557,8 +557,8 @@ void main(int argc, char **argv)
struct uinput_user_dev uidev;
struct termios oldtio,newtio;
unsigned char iopkt[16];
int i, c, lastbtn;
int a2fd, kbdfd, moufd, srvfd, reqfd, maxfd;
int i, c, lastbtn, cout;
int a2fd, kbdfd, moufd, srvfd, reqfd, coutfd, maxfd;
struct sockaddr_in servaddr;
fd_set readset, openset;
char *devtty = "/dev/ttyAMA0"; /* default for Raspberry Pi */
@ -737,7 +737,8 @@ void main(int argc, char **argv)
*/
reset:
state = RUN;
reqfd = 0;
cout = -1;
reqfd = coutfd = 0;
FD_ZERO(&openset);
FD_SET(a2fd, &openset);
FD_SET(srvfd, &openset);
@ -758,7 +759,7 @@ reset:
{
if (read(a2fd, iopkt, 3) == 3)
{
// printf("a2pi: Event [0x%02X] [0x%02X] [0x%02X]\n", iopkt[0], iopkt[1], iopkt[2]);
//printf("a2pi: Event [0x%02X] [0x%02X] [0x%02X]\n", iopkt[0], iopkt[1], iopkt[2]);
switch (iopkt[0])
{
case 0x80: /* sync */
@ -850,6 +851,26 @@ reset:
else
state = RESET;
break;
case 0x96: /* send input char to Apple II */
if (a2reqlist) /* better have an outstanding request */
{
//printf("a2pid: call address 0x%04X\n", a2reqlist->addr);
newtio.c_cc[VMIN] = 1; /* blocking read until 1 char received */
tcsetattr(a2fd, TCSANOW, &newtio);
if (!writeword(a2fd, a2reqlist->addr, 0x97))
state = RESET;
newtio.c_cc[VMIN] = 3; /* blocking read until 3 chars received */
tcsetattr(a2fd, TCSANOW, &newtio);
}
else
state = RESET;
break;
case 0x98: /* get output char from Apple II */
if (coutfd)
write(coutfd, iopkt, 2);
else
cout = iopkt[1];
break;
case 0x9E: /* request complete ok */
case 0x9F: /* request complete error */
if (a2reqlist) /* better have an outstanding request */
@ -951,11 +972,25 @@ reset:
addreq(a2fd, reqfd, 0x94, addr, 0, NULL);
}
break;
case 0x96: /* send input char to Apple II */
if (read(reqfd, iopkt, 1) == 1)
addreq(a2fd, reqfd, 0x96, iopkt[0], 0, NULL);
break;
case 0x98: /* get output chars from Apple II */
if (cout >= 0)
{
iopkt[1] = cout;
write(reqfd, iopkt, 2);
cout = -1;
}
coutfd = reqfd;
break;
case 0xFF: /* close */
FD_CLR(reqfd, &openset);
close(reqfd);
reqfd = 0;
maxfd = a2fd > srvfd ? a2fd : srvfd;
reqfd = 0;
coutfd = 0;
maxfd = a2fd > srvfd ? a2fd : srvfd;
break;
default:
prlog("a2pid: Unknown Request\n");

83
src/a2term.c Executable file
View File

@ -0,0 +1,83 @@
#include "a2lib.c"
#include <termios.h>
#define RUN 0
#define STOP 1
int a2cin(int fd, char cin)
{
unsigned char cinpkt[2];
cinpkt[0] = 0x96; // keyboard input
cinpkt[1] = cin;
write(fd, cinpkt, 2);
read(fd, cinpkt, 2);
return (cinpkt[0] == 0x9E);
}
int main(int argc, char **argv)
{
struct termios oldtio,newtio;
fd_set readset, openset;
unsigned char iopkt[2];
int state = RUN;
int pifd = a2open(argc > 1 ? argv[1] : "127.0.0.1");
if (pifd < 0)
{
perror("Unable to connect to Apple II Pi");
exit(EXIT_FAILURE);
}
tcgetattr(STDIN_FILENO, &oldtio); /* save current port settings */
bzero(&newtio, sizeof(newtio));
newtio.c_cflag = /*BAUDRATE | CRTSCTS |*/ CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
newtio.c_lflag = 0; /* set input mode (non-canonical, no echo,...) */
newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
newtio.c_cc[VMIN] = 1; /* blocking read until 1 char received */
tcsetattr(STDIN_FILENO, TCSANOW, &newtio);
FD_ZERO(&openset);
FD_SET(pifd, &openset);
FD_SET(STDIN_FILENO, &openset);
/*
* Tell a2pid that we want Apple II character output.
*/
iopkt[0] = 0x98;
write(pifd, iopkt, 1);
/*
* Event loop
*/
while (state == RUN)
{
memcpy(&readset, &openset, sizeof(openset));
if (select(pifd + 1, &readset, NULL, NULL, NULL) > 0)
{
/*
* Apple II character output.
*/
if (FD_ISSET(pifd, &readset))
{
if (read(pifd, iopkt, 2) == 2)
{
if (iopkt[0] == 0x98)
{
putchar(iopkt[1] & 0x7F);
if (iopkt[1] == 0x8D)
putchar('\n');
fflush(stdout);
}
}
}
if (FD_ISSET(STDIN_FILENO, &readset))
{
if (read(STDIN_FILENO, iopkt, 1) == 1)
{
if (iopkt[0] == 0x1B)
state = STOP;
else
a2cin(pifd, iopkt[0] | 0x80);
}
}
}
}
tcsetattr(STDIN_FILENO, TCSANOW, &oldtio);
a2close(pifd);
return EXIT_SUCCESS;
}