int main(int argc, char **argv) { FILE *dskfile; char count[2], volname[21]; int i, result, fd; 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); } sleep(1); a2write(pifd, ORG, sizeof(online), online); a2call(pifd, ORG, &result); a2read(pifd, DATA_BUFFER, 16, volname); volname[(volname[0] & 0x0F) + 1] = '\0'; printf("Volume name:%s\n", volname + 1); strcat(volname + 1, ".PO"); a2write(pifd, ORG, sizeof(readblk), readblk); for (i = 0; i < 280; i++) { printf("Reading block #%d\r", i); fflush(stdout); count[0] = i; count[1] = i >> 8; a2write(pifd, BLOCK_NUM, 2, count); a2call(pifd, ORG, &result); a2read(pifd, DATA_BUFFER, 512, dsk[i]); } a2close(pifd); if ((dskfile = fopen(volname + 1, "wb"))) { fwrite(dsk, 1, 280*512, dskfile); fclose(dskfile); } return EXIT_SUCCESS; }
int main(int argc, char **argv) { struct termios oldtio,newtio; fd_set readset, openset; unsigned char iopkt[2]; int state = RUN, cin = 0; 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); } /* * Tell a2pid that we want Apple II character output. */ iopkt[0] = 0x98; write(pifd, iopkt, 1); /* * Are we running interactively? */ if (isatty(STDIN_FILENO)) { /* * 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) { 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); } 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 (iopkt[0] == 0x1B) { if (read(STDIN_FILENO, iopkt, 1) == 1) { if (iopkt[0] == 0x5B && read(STDIN_FILENO, iopkt, 1) == 1) { 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; break; } } } 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 /* * 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) { /* * 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; }