FUSE fixes and updates for virtual drives
This commit is contained in:
parent
2aec13ef83
commit
d8bf70b34d
|
@ -1,4 +1,4 @@
|
|||
a2pi (0.1.8-1) unstable; urgency=low
|
||||
a2pi (0.1.8-2) unstable; urgency=low
|
||||
|
||||
* Fix FUSE create file function
|
||||
* Add VSDRIVE functionality
|
||||
|
|
|
@ -60,12 +60,12 @@ case "$1" in
|
|||
#
|
||||
# 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
|
||||
if [ ! -e /usr/share/a2pi/A2VD1.PO ] ; then
|
||||
ln -s /usr/share/a2pi/A2PI-1.4.PO /usr/share/a2pi/A2VD1.PO
|
||||
fi
|
||||
if [ ! -e /usr/share/a2pi/A2VD2.PO ] ; then
|
||||
ln -s /usr/share/a2pi/BLANK.PO /usr/share/a2pi/A2VD2.PO
|
||||
fi
|
||||
#
|
||||
# Add schmenk.is-a-geek.com to apt sources
|
||||
#
|
||||
|
|
|
@ -7,7 +7,7 @@ else
|
|||
BINDIR=$(DESTDIR)/usr/bin
|
||||
SHAREDIR=$(DESTDIR)/usr/share/a2pi
|
||||
endif
|
||||
BIN=a2joy a2joymou a2joypad a2mon a2term fusea2pi dskread dskwrite bload brun
|
||||
BIN=a2joy a2joymou a2joypad a2mon a2term fusea2pi a2pidcmd dskread dskwrite bload brun
|
||||
SBIN=a2pid
|
||||
A2PIDEFS=-DSETSERCLK
|
||||
|
||||
|
@ -25,6 +25,7 @@ clean:
|
|||
install:
|
||||
-mkdir -p $(BINDIR)
|
||||
cp $(BIN) a2mount $(BINDIR)
|
||||
cp $(BIN) a2setvd $(BINDIR)
|
||||
-mkdir -p $(SBINDIR)
|
||||
cp $(SBIN) $(SBINDIR)
|
||||
-mkdir -p $(SHAREDIR)
|
||||
|
|
144
src/a2pid.c
144
src/a2pid.c
|
@ -363,38 +363,27 @@ int vdriveopen(char *path)
|
|||
strcat(filename, "A2VD1.PO");
|
||||
//printf("vdrive: open %s\n", filename);
|
||||
if ((vdrivefd[0] = open(filename, O_RDWR, 0)) < 0)
|
||||
return 0;
|
||||
vdrivefd[0] = 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;
|
||||
vdrivefd[1] = 0;
|
||||
return vdrivefd[0] + vdrivefd[1];
|
||||
}
|
||||
prlog("vdrive: opened successfully\n");
|
||||
return 1;
|
||||
}
|
||||
int vdriveclose(void)
|
||||
void vdriveclose(void)
|
||||
{
|
||||
return close(vdrivefd[0]) | close(vdrivefd[1]);
|
||||
if (vdrivefd[0]) close(vdrivefd[0]);
|
||||
if (vdrivefd[1]) close(vdrivefd[1]);
|
||||
vdrivefd[0] = vdrivefd[1] = 0;
|
||||
}
|
||||
unsigned int prodos_time(int year, int month, int day, int hour, int minute)
|
||||
void vdrivecmd(int afd, int command, int block, unsigned char crc_in)
|
||||
{
|
||||
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];
|
||||
int i, vfd = vdrivefd[command >> 2];
|
||||
unsigned char block_buff[512], crc_out = 0xC5 ^ command ^ block ^ (block >> 8);
|
||||
|
||||
if (crc_in != crc_out)
|
||||
prlog("vdrive: CRC mismatch!\n");
|
||||
if (command == 0x01 || command == 0x03 || command == 0x05)
|
||||
{
|
||||
//printf("vdrive: read block=%d from unit:%d\n", block, command >> 2);
|
||||
|
@ -402,7 +391,7 @@ void vdrivecmd(int fd, int command, int block, unsigned char crc_in)
|
|||
block_buff[1] = command;
|
||||
block_buff[2] = block;
|
||||
block_buff[3] = block >> 8;
|
||||
write(fd, block_buff, 4);
|
||||
write(afd, block_buff, 4);
|
||||
if (command > 0x01)
|
||||
{
|
||||
unsigned char time_buff[4];
|
||||
|
@ -411,40 +400,50 @@ void vdrivecmd(int fd, int command, int block, unsigned char crc_in)
|
|||
*/
|
||||
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);
|
||||
int ptime = (tm->tm_mday & 0x1F)
|
||||
| (((tm->tm_mon + 1) & 0x0F) << 5)
|
||||
| (((tm->tm_year - 100) & 0x7F) << 9)
|
||||
| ((tm->tm_min & 0x3F) << 16)
|
||||
| ((tm->tm_hour & 0x1F) << 24);
|
||||
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);
|
||||
write(afd, 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);
|
||||
write(afd, &crc_out, 1);
|
||||
if (vfd)
|
||||
{
|
||||
lseek(vfd, block * 512, 0);
|
||||
read(vfd, block_buff, 512);
|
||||
}
|
||||
write(afd, block_buff, 512);
|
||||
for (crc_out = i = 0; i < 512; i++)
|
||||
crc_out ^= block_buff[i];
|
||||
write(fd, &crc_out, 1);
|
||||
write(afd, &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);
|
||||
read(afd, &block_buff[i], 1);
|
||||
crc_out ^= block_buff[i];
|
||||
}
|
||||
lseek(vdrivefd[command >> 2], block * 512, 0);
|
||||
read(fd, &crc_in, 1);
|
||||
if (vfd)
|
||||
{
|
||||
lseek(vfd, block * 512, 0);
|
||||
read(afd, &crc_in, 1);
|
||||
}
|
||||
if (crc_in == crc_out)
|
||||
write(vdrivefd[command >> 2], block_buff, 512);
|
||||
write(vfd, 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);
|
||||
write(afd, block_buff, 5);
|
||||
}
|
||||
else
|
||||
state = RESET; // ??? What else to do ???
|
||||
|
@ -509,8 +508,7 @@ void sendkeycodeup(int fd, int code)
|
|||
static int prevkeycode = -1;
|
||||
void sendkey(int fd, int mod, int key)
|
||||
{
|
||||
int code = keycode[(mod & MOD_FN) | (key & KEY_ASCII)]
|
||||
| ((mod << 8) & MOD_ALT);
|
||||
int code = keycode[(mod & MOD_FN) | (key & KEY_ASCII)] | ((mod << 8) & MOD_ALT);
|
||||
|
||||
if (prevkeycode >= 0)
|
||||
{
|
||||
|
@ -544,8 +542,7 @@ void sendbttn(int fd, int mod, int bttn)
|
|||
|
||||
if (bttn)
|
||||
{
|
||||
lastbtn =
|
||||
evkey.code = (mod == 0) ? BTN_LEFT
|
||||
lastbtn = evkey.code = (mod == 0) ? BTN_LEFT
|
||||
: (mod & 0x40) ? BTN_RIGHT
|
||||
: BTN_MIDDLE;
|
||||
evkey.value = 1;
|
||||
|
@ -857,6 +854,28 @@ void main(int argc, char **argv)
|
|||
* Get VDRIVE images.
|
||||
*/
|
||||
vdriveactive = vdriveopen(vdrivedir);
|
||||
/*
|
||||
* Open socket.
|
||||
*/
|
||||
prlog("a2pid: Open server socket\n");
|
||||
bzero(&servaddr, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_port = htons(6551);
|
||||
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
srvfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (srvfd < 0)
|
||||
die("error: socket create");
|
||||
if (bind(srvfd,(struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
|
||||
die("error: bind socket");
|
||||
if (listen(srvfd, MAX_CLIENT - 1) < 0)
|
||||
die("error: listen socket");
|
||||
#if defined(SETSERCLK) && defined(__ARMEL__)
|
||||
/*
|
||||
* Initialize ACIA clock for Apple II Pi card
|
||||
*/
|
||||
gpclk(271); /* divisor for ~1.8 MHz => (500/271) MHz */
|
||||
sleep(1); /* give clock chance to settle down */
|
||||
#endif
|
||||
/*
|
||||
* Open serial port.
|
||||
*/
|
||||
|
@ -875,13 +894,6 @@ void main(int argc, char **argv)
|
|||
newtio.c_cc[VMIN] = 1; /* blocking read until 1 char received */
|
||||
tcsetattr(a2fd, TCSANOW, &newtio);
|
||||
prlog("a2pid: Waiting to connect to Apple II...\n");
|
||||
#if defined(SETSERCLK) && defined(__ARMEL__)
|
||||
/*
|
||||
* Initialize ACIA clock for Apple II Pi card
|
||||
*/
|
||||
gpclk(271); /* divisor for ~1.8 MHz => (500/271) MHz */
|
||||
sleep(1); /* give clock chance to settle down */
|
||||
#endif
|
||||
iopkt[0] = 0x80; /* request re-sync if Apple II already running */
|
||||
write(a2fd, iopkt, 1);
|
||||
if (read(a2fd, iopkt, 1) == 1)
|
||||
|
@ -905,21 +917,6 @@ void main(int argc, char **argv)
|
|||
}
|
||||
newtio.c_cc[VMIN] = 3; /* blocking read until 3 chars received */
|
||||
tcsetattr(a2fd, TCSANOW, &newtio);
|
||||
/*
|
||||
* Open socket.
|
||||
*/
|
||||
prlog("a2pid: Open server socket\n");
|
||||
bzero(&servaddr, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_port = htons(6551);
|
||||
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
srvfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (srvfd < 0)
|
||||
die("error: socket create");
|
||||
if (bind(srvfd,(struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
|
||||
die("error: bind socket");
|
||||
if (listen(srvfd, MAX_CLIENT - 1) < 0)
|
||||
die("error: listen socket");
|
||||
/*
|
||||
* Come basck here on RESET.
|
||||
*/
|
||||
|
@ -1097,25 +1094,19 @@ 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;
|
||||
if (a2reqlist) /* resend last request */
|
||||
write(a2fd, &a2reqlist->type, 1);
|
||||
break;
|
||||
default:
|
||||
prlog("a2pid: Unknown Event\n");
|
||||
|
@ -1226,6 +1217,18 @@ reset:
|
|||
case 0x98: /* get output chars from Apple II */
|
||||
a2client[i].flags |= CLIENT_COUT;
|
||||
break;
|
||||
case 0xC0: /* reconnect VDRIVEs */
|
||||
vdriveclose();
|
||||
vdriveactive = vdriveopen(vdrivedir);
|
||||
iopkt[0]++; /* ack */
|
||||
write(a2client[i].fd, iopkt, 1);
|
||||
break;
|
||||
case 0xC2: /* disconnect VDRIVEs */
|
||||
vdriveclose();
|
||||
vdriveactive = 0;
|
||||
iopkt[0]++; /* ack */
|
||||
write(a2client[i].fd, iopkt, 1);
|
||||
break;
|
||||
case 0xFF: /* close */
|
||||
a2client[i].flags = CLIENT_CLOSING;
|
||||
break;
|
||||
|
@ -1256,7 +1259,6 @@ reset:
|
|||
close(a2client[i].fd);
|
||||
if (state == RESET)
|
||||
goto reset;
|
||||
if (vdriveactive)
|
||||
vdriveclose();
|
||||
shutdown(srvfd, SHUT_RDWR);
|
||||
close(srvfd);
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#include "a2lib.c"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
unsigned char cmd, ack;
|
||||
int pifd = a2open(argc > 3 ? argv[3] : "127.0.0.1");
|
||||
if (pifd < 0)
|
||||
{
|
||||
perror("Unable to connect to Apple II Pi");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (argc < 2)
|
||||
{
|
||||
perror("Usage: a2picmd <cmd>\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
cmd = (int)strtol(argv[1], NULL, 0); /* treat command as value */
|
||||
write(pifd, &cmd, 1);
|
||||
read(pifd, &ack, 1);
|
||||
a2close(pifd);
|
||||
return ack == (cmd + 1);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
a2pidcmd 0xC2
|
||||
rm /usr/share/a2pi/A2VD$1.PO
|
||||
ln -s $2 /usr/share/a2pi/A2VD$1.PO
|
||||
a2pidcmd 0xC0
|
||||
|
|
@ -1036,7 +1036,7 @@ static int a2pi_mkdir(const char *path, mode_t mode)
|
|||
return -EACCES;
|
||||
A2PI_WAIT;
|
||||
cachepath[0] = '\0';
|
||||
err = prodos_map_errno(prodos_create(prodos_path(path, NULL, NULL, NULL), 0xE3, 0x0F, 0, 0));
|
||||
err = prodos_map_errno(prodos_create(prodos_path(path, NULL, NULL, NULL), 0xC3, 0x0F, 0, 0));
|
||||
A2PI_RELEASE;
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue