diff --git a/src/a2pid.c b/src/a2pid.c index 557c190..6f2aa4f 100755 --- a/src/a2pid.c +++ b/src/a2pid.c @@ -759,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: A2 Event [0x%02X] [0x%02X] [0x%02X]\n", iopkt[0], iopkt[1], iopkt[2]); switch (iopkt[0]) { case 0x80: /* sync */ @@ -925,7 +925,7 @@ reset: char *databuf; if (read(reqfd, iopkt, 1) == 1) { - // printf("a2pi: Request [0x%02X]\n", iopkt[0]); + // printf("a2pi: Client Request [0x%02X]\n", iopkt[0]); switch (iopkt[0]) { case 0x90: /* read bytes */ diff --git a/src/a2term.c b/src/a2term.c index f786e28..48d8def 100755 --- a/src/a2term.c +++ b/src/a2term.c @@ -22,104 +22,171 @@ int main(int argc, char **argv) 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 + * Are we running interactively? */ - while (state == RUN) + if (isatty(STDIN_FILENO)) { - memcpy(&readset, &openset, sizeof(openset)); - if (select(pifd + 1, &readset, NULL, NULL, NULL) > 0) + /* + * Give a little instruction to the user. + */ + fprintf(stderr, "\nPress ESC-Q to quit, ESC-ESC sends \'ESCAPE\'.\n\n"); + fprintf(stderr, "Warning: Do NOT 'BYE' out of AppleSoft or run a system program.\n"); + fprintf(stderr, "Apple II Pi client will be disabled and you will lose keyboard and mouse.\n"); + /* + * Change input setting to work better as a terminal. + */ + 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); + /* + * Start off with a carriage return. + */ + cin = 0x8D; + a2cin(pifd, cin); + /* + * Prepare for select(). + */ + FD_ZERO(&openset); + FD_SET(pifd, &openset); + FD_SET(STDIN_FILENO, &openset); + /* + * Event loop + */ + while (state == RUN) { - /* - * Apple II character output. - */ - if (FD_ISSET(pifd, &readset)) + memcpy(&readset, &openset, sizeof(openset)); + if (select(pifd + 1, &readset, NULL, NULL, NULL) > 0) { - if (read(pifd, iopkt, 2) == 2) + /* + * Apple II character output. + */ + if (FD_ISSET(pifd, &readset)) { - if (iopkt[0] == 0x98) + if (read(pifd, iopkt, 2) == 2) { - putchar(iopkt[1] & 0x7F); - if (iopkt[1] == 0x8D) - putchar('\n'); - fflush(stdout); - } - else if (iopkt[0] == 0x9E) - { - if (iopkt[1] == cin) - cin = 0; - else + if (iopkt[0] == 0x98) { - fprintf(stderr, "\nInput character mismatch!\n"); - state = STOP; + putchar(iopkt[1] & 0x7F); + if (iopkt[1] == 0x8D) + putchar('\n'); + fflush(stdout); + } + else if (iopkt[0] == 0x9E) + { + if (iopkt[1] == cin) + cin = 0; + else + { + fprintf(stderr, "\nInput character mismatch!\n"); + state = STOP; + } } } + else + /* + * Some kind of client/server error. + */ + state = STOP; } - } - if (FD_ISSET(STDIN_FILENO, &readset)) - { - if (read(STDIN_FILENO, iopkt, 1) == 1) + if (FD_ISSET(STDIN_FILENO, &readset)) { - if (iopkt[0] == 0x1B) + if (read(STDIN_FILENO, iopkt, 1) == 1) { - if (read(STDIN_FILENO, iopkt, 1) == 1) + if (iopkt[0] == 0x1B) { - if (iopkt[0] == 0x5B && read(STDIN_FILENO, iopkt, 1) == 1) + if (read(STDIN_FILENO, iopkt, 1) == 1) { - switch (iopkt[0]) + if (iopkt[0] == 0x5B && read(STDIN_FILENO, iopkt, 1) == 1) { - case 0x44: // left arrow - iopkt[0] = 0x88; - break; - case 0x43: // right arrow - iopkt[0] = 0x95; - break; - case 0x42: // down arrow - iopkt[0] = 0x8A; - break; - case 0x41: // up arrow - iopkt[0] = 0x9B; - break; - default: - iopkt[0] = 0xA0; + switch (iopkt[0]) + { + case 0x44: // left arrow + iopkt[0] = 0x88; + break; + case 0x43: // right arrow + iopkt[0] = 0x95; + break; + case 0x42: // down arrow + iopkt[0] = 0x8A; + break; + case 0x41: // up arrow + iopkt[0] = 0x9B; + break; + default: + iopkt[0] = 0xA0; + } + } + else if (iopkt[0] == 'q' || iopkt[0] == 'Q') + { + cin = 0x1B; + state = STOP; } } - else if (iopkt[0] == 'q' || iopkt[0] == 'Q') - state = STOP; } + else if (iopkt[0] == 0x7F) + iopkt[0] = 0x88; + if (cin == 0) + { + cin = iopkt[0] | 0x80; + a2cin(pifd, cin); + } + /* + * else drop the character (we are interactive) + */ } - else if (iopkt[0] == 0x7F) - iopkt[0] = 0x88; - if (cin == 0) - { - cin= iopkt[0] | 0x80; - a2cin(pifd, cin); - } + else + /* + * stdin probably closed. + */ + state = STOP; + } + } + } + } + else + { + /* + * Copy STDIN making sure to not drop characters. + */ + while (read(STDIN_FILENO, &cin, 1) == 1) + { + if (cin == '\n') + cin = 0x0D; + cin |= 0x80; + a2cin(pifd, cin); + while (read(pifd, iopkt, 2) == 2) + { + if (iopkt[0] == 0x98) + { /* - * else drop the character! + * Echo output. */ + putchar(iopkt[1] == 0x8D ? '\n' : iopkt[1] & 0x7F); + } + else if (iopkt[0] == 0x9E) + { + if (iopkt[1] == cin) + break; + else + fprintf(stderr, "\nInput character mismatch!\n"); } } } } tcsetattr(STDIN_FILENO, TCSANOW, &oldtio); a2close(pifd); + fprintf(stderr, "\n"); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/src/execfile b/src/execfile new file mode 100755 index 0000000..67f59ce --- /dev/null +++ b/src/execfile @@ -0,0 +1,7 @@ +NEW +10 FOR I = 1 TO 10 +20 PRINT "HELLO, WORLD";I +30 NEXT I +LIST +RUN +