mirror of
https://github.com/dschmenk/apple2pi.git
synced 2025-02-19 18:31:32 +00:00
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:
parent
5559e82d68
commit
3effdc6773
BIN
src/A2PI.PO
BIN
src/A2PI.PO
Binary file not shown.
@ -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)
|
||||
|
||||
|
49
src/a2pid.c
49
src/a2pid.c
@ -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
83
src/a2term.c
Executable 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user