From 2aec13ef8344e84426006ee3eb802a968313d5c5 Mon Sep 17 00:00:00 2001 From: dschmenk Date: Wed, 5 Feb 2014 23:19:45 -0800 Subject: [PATCH] VSDRIVE functionality VSDRIVE functionality for ProDOS and SOS --- debian/changelog | 4 +- debian/postinst | 9 ++ share/{A2PI-1.3.PO => A2PI-1.4.PO} | Bin 143360 -> 143360 bytes share/BLANK.PO | Bin 0 -> 819200 bytes src/a2pid.c | 176 ++++++++++++++++++++++++++--- 5 files changed, 174 insertions(+), 15 deletions(-) rename share/{A2PI-1.3.PO => A2PI-1.4.PO} (75%) create mode 100755 share/BLANK.PO diff --git a/debian/changelog b/debian/changelog index 92a80df..6074cd0 100755 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,10 @@ -a2pi (0.1.8-0) unstable; urgency=low +a2pi (0.1.8-1) unstable; urgency=low * Fix FUSE create file function + * Add VSDRIVE functionality -- David Schmenk Tue, 04 Feb 2014 13:43:53 -0800 + a2pi (0.1.7-3) unstable; urgency=low * Adjust file permissions for FUSE driver to allow group access diff --git a/debian/postinst b/debian/postinst index 2a57cc0..887e791 100755 --- a/debian/postinst +++ b/debian/postinst @@ -58,6 +58,15 @@ case "$1" in sed 's/^#user_allow_other/user_allow_other/' /etc/fuse.conf.bak > /etc/fuse.conf fi # + # Set up VSDRIVEs + # + if [ ! -f /usr/share/a2pid/A2VD1.PO ] ; then + ln -s /usr/share/a2pid/A2PI-1.4.PO A2VD1.PO + fin + if [ ! -f /usr/share/a2pid/A2VD2.PO ] ; then + ln -s /usr/share/a2pid/BLANKDISK.PO A2VD2.PO + fin + # # Add schmenk.is-a-geek.com to apt sources # if [ "$(grep schmenk /etc/apt/sources.list)" = "" ] ; then diff --git a/share/A2PI-1.3.PO b/share/A2PI-1.4.PO similarity index 75% rename from share/A2PI-1.3.PO rename to share/A2PI-1.4.PO index 61a3a96d2049b6f6768ae8681472ff371efab223..95fa619eb4e1988836cc985868c8159c7f988791 100755 GIT binary patch delta 32960 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 diff --git a/share/BLANK.PO b/share/BLANK.PO new file mode 100755 index 0000000000000000000000000000000000000000..e77346dea83a52effdfc49d4b26469ab853e11dc GIT binary patch literal 819200 zcmeIxPe^4|90%~LPt7Y@8o{`jh6fF)V-VCv3K?e_^?BbL$I*hIjnXC}sa4QwTHHHW z6u4;PBDzUe=1CJzh#*jS6Vu=uhVk`}h?YYyA}ERZLsXbD1hbY_^7$P&960C4;rlt9 zrlCr%^u&kfpQ+{A-yV1^+O4pfOr$$;p?`C&P=Bg&e>wMV(B2r%CJN;j3bV;bQb=E1 zD=fViZdQM--(GH8e>mJY8ZP}2ZVZO+pX<2V{aZOqCd%j2p!R3w@uU#X#!*~~C*$$W z_~d3hR_;vZl4AbBu<}x4Zg-4jW3{%$-!BH8T}_?!`EpCWIg5JdAL+cX*wrXz#i-I& z>)3uSZHc3c&EdcU7uKR5n#1~!3*EN|wrlzN(`olwRNJXPxw#f4V|&whIY^@PNL-BP zHsjNKHyzr$>7&WU5ZHD=l@O*e?Ap1ebTzneW!FfTwPsF zzq@|vi)&w|-)^PXwk};x>tAnO-ufop-N|MKa>rT+S2y0QmLFU0xmy3{m!|rimBHC; zY~a3H%RsKZqyJbkoQ+4>*vnCroaji-W}`{p%HYOZ)%<$c=xYo&hAX+<<@!Q(HXG?k zW_F`Ko6RIsLqDC}eyGyYm|1MTGBcE)53{M>{HtO8MtUxuZtowuGQEAhw|!yz*2X*4 z?!N*>;I2R}xOK90VzPLz$LQgnLqTwNzR}ke1Z}}c+r0;@4~Rf>&~iYMh_N4mT+q6o zHa!PK!0$gG54q16O*;pp_8DIr0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly vK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5;&|5e~$sDh{5 literal 0 HcmV?d00001 diff --git a/src/a2pid.c b/src/a2pid.c index 9fab694..3d3b118 100755 --- a/src/a2pid.c +++ b/src/a2pid.c @@ -7,11 +7,13 @@ #include #include #include -#include #include +#include +#include #include #include #include +#include #include #include @@ -53,6 +55,10 @@ struct { int fd; int flags; } a2client[MAX_CLIENT]; +/* + * Virtual drive info + */ +int vdrivefd[2]; /* * ASCII to scancode conversion */ @@ -333,6 +339,121 @@ int keycode[256] = { #define STOP 1 #define RESET 2 volatile int state = RUN, isdaemon = FALSE; +void prlog(char *str) +{ + if (!isdaemon) + puts(str); +} +static void sig_bye(int signo) +{ + /* + * Exit gracefully + */ + state = STOP; +} +/*****************************************************************\ +* * +* VDRIVE commands * +* * +\*****************************************************************/ +int vdriveopen(char *path) +{ + char filename[256]; + strcpy(filename, path); + strcat(filename, "A2VD1.PO"); + //printf("vdrive: open %s\n", filename); + if ((vdrivefd[0] = open(filename, O_RDWR, 0)) < 0) + return 0; + strcpy(filename, path); + strcat(filename, "A2VD2.PO"); + //printf("vdrive: open %s\n", filename); + if ((vdrivefd[1] = open(filename, O_RDWR, 0)) < 0) + { + close(vdrivefd[0]); + return 0; + } + prlog("vdrive: opened successfully\n"); + return 1; +} +int vdriveclose(void) +{ + return close(vdrivefd[0]) | close(vdrivefd[1]); +} +unsigned int prodos_time(int year, int month, int day, int hour, int minute) +{ + if (year > 99) + year -= 100; + month += 1; + return (day & 0x1F) + | ((month & 0x0F) << 5) + | ((year & 0x7F) << 9) + | ((minute & 0x3F) << 16) + | ((hour & 0x1F) << 24); +} +void vdrivecmd(int fd, int command, int block, unsigned char crc_in) +{ + int i; + unsigned char crc_out = crc_in, block_buff[512]; + + if (command == 0x01 || command == 0x03 || command == 0x05) + { + //printf("vdrive: read block=%d from unit:%d\n", block, command >> 2); + block_buff[0] = 0xC5; + block_buff[1] = command; + block_buff[2] = block; + block_buff[3] = block >> 8; + write(fd, block_buff, 4); + if (command > 0x01) + { + unsigned char time_buff[4]; + /* + * Get ProDOS time. + */ + time_t now = time(NULL); + struct tm *tm = localtime(&now); + int ptime = prodos_time(tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min); + time_buff[0] = (unsigned char) ptime; + time_buff[1] = (unsigned char) (ptime >> 8); + time_buff[2] = (unsigned char) (ptime >> 16); + time_buff[3] = (unsigned char) (ptime >> 24); + write(fd, time_buff, 4); + crc_out ^= time_buff[0] ^ time_buff[1] ^ time_buff[2] ^ time_buff[3]; + } + lseek(vdrivefd[command >> 2], block * 512, 0); + write(fd, &crc_out, 1); + read(vdrivefd[command >> 2], block_buff, 512); + write(fd, block_buff, 512); + for (crc_out = i = 0; i < 512; i++) + crc_out ^= block_buff[i]; + write(fd, &crc_out, 1); + } + else if (command == 0x02 || command == 0x04) + { + //printf("vdrive: write block=%d to unit:%d\n", block, command >> 2); + for (crc_out = i = 0; i < 512; i++) + { + read(fd, &block_buff[i], 1); + crc_out ^= block_buff[i]; + } + lseek(vdrivefd[command >> 2], block * 512, 0); + read(fd, &crc_in, 1); + if (crc_in == crc_out) + write(vdrivefd[command >> 2], block_buff, 512); + block_buff[0] = 0xC5; + block_buff[1] = command; + block_buff[2] = block; + block_buff[3] = block >> 8; + block_buff[4] = crc_out; + write(fd, block_buff, 5); + } + else + state = RESET; // ??? What else to do ??? +} +/*****************************************************************\ +* * +* Input device handling * +* * +\*****************************************************************/ struct input_event evkey, evrelx, evrely, evsync; void sendkeycodedown(int fd, int code) @@ -454,6 +575,11 @@ void sendrelxy(int fd, int x, int y) write(fd, &evrely, sizeof(evrely)); write(fd, &evsync, sizeof(evsync)); } +/*****************************************************************\ +* * +* Request queue management * +* * +\*****************************************************************/ int writeword(int fd, int word, char ack) { char rwchar; @@ -469,11 +595,6 @@ int writeword(int fd, int word, char ack) } return FALSE; } -void prlog(char *str) -{ - if (!isdaemon) - puts(str); -} struct a2request *addreq(int a2fd, int clidx, int type, int addr, int count, char *buffer) { char rwchar; @@ -594,23 +715,22 @@ void flushreqs(int a2fd, int clidx, int status, int result) } } } -static void sig_bye(int signo) -{ - /* - * Exit gracefully - */ - state = STOP; -} +/*****************************************************************\ +* * +* Main entrypoint * +* * +\*****************************************************************/ void main(int argc, char **argv) { struct uinput_user_dev uidev; struct termios oldtio,newtio; unsigned char iopkt[16]; - int i, c, rdycnt; + int i, c, rdycnt, vdriveactive; int a2fd, kbdfd, moufd, srvfd, maxfd; struct sockaddr_in servaddr; fd_set readset, openset; char *devtty = "/dev/ttyAMA0"; /* default for Raspberry Pi */ + char *vdrivedir = "/usr/share/a2pi/"; /* default VDRIVE image directory */ /* * Parse arguments @@ -733,6 +853,10 @@ void main(int argc, char **argv) evrely.type = EV_REL; evrely.code = REL_Y; evsync.type = EV_SYN; + /* + * Get VDRIVE images. + */ + vdriveactive = vdriveopen(vdrivedir); /* * Open serial port. */ @@ -971,6 +1095,28 @@ reset: else state = RESET; break; + case 0xC5: /* virtual drive request */ + //printf("a2pid: vdrive request\n"); + if (vdriveactive) + { + newtio.c_cc[VMIN] = 1; /* blocking read until command packet received */ + tcsetattr(a2fd, TCSANOW, &newtio); + if (read(a2fd, &iopkt[3], 1) + read(a2fd, &iopkt[4], 1) == 2) + { + //printf("vdrive cmd:%02X blk:%d crc:%02X\n", iopkt[1], iopkt[2] | (iopkt[3] << 8), iopkt[4]); + if ((iopkt[0] ^ iopkt[1] ^ iopkt[2] ^ iopkt[3]) == iopkt[4]) + vdrivecmd(a2fd, iopkt[1], iopkt[2] | (iopkt[3] << 8), iopkt[4]); + else + prlog("vdrive: bad CRC\n"); + } + else + state = RESET; + newtio.c_cc[VMIN] = 3; /* blocking read until 3 chars received */ + tcsetattr(a2fd, TCSANOW, &newtio); + } + else + state = RESET; + break; default: prlog("a2pid: Unknown Event\n"); tcflush(a2fd, TCIFLUSH); @@ -1110,6 +1256,8 @@ reset: close(a2client[i].fd); if (state == RESET) goto reset; + if (vdriveactive) + vdriveclose(); shutdown(srvfd, SHUT_RDWR); close(srvfd); tcsetattr(a2fd, TCSANOW, &oldtio);