mirror of
https://github.com/dschmenk/apple2pi.git
synced 2024-06-02 03:41:32 +00:00
FUSE fixes and updates for virtual drives
This commit is contained in:
parent
2aec13ef83
commit
d8bf70b34d
2
debian/changelog
vendored
2
debian/changelog
vendored
|
@ -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
|
* Fix FUSE create file function
|
||||||
* Add VSDRIVE functionality
|
* Add VSDRIVE functionality
|
||||||
|
|
12
debian/postinst
vendored
12
debian/postinst
vendored
|
@ -60,12 +60,12 @@ case "$1" in
|
||||||
#
|
#
|
||||||
# Set up VSDRIVEs
|
# Set up VSDRIVEs
|
||||||
#
|
#
|
||||||
if [ ! -f /usr/share/a2pid/A2VD1.PO ] ; then
|
if [ ! -e /usr/share/a2pi/A2VD1.PO ] ; then
|
||||||
ln -s /usr/share/a2pid/A2PI-1.4.PO A2VD1.PO
|
ln -s /usr/share/a2pi/A2PI-1.4.PO /usr/share/a2pi/A2VD1.PO
|
||||||
fin
|
fi
|
||||||
if [ ! -f /usr/share/a2pid/A2VD2.PO ] ; then
|
if [ ! -e /usr/share/a2pi/A2VD2.PO ] ; then
|
||||||
ln -s /usr/share/a2pid/BLANKDISK.PO A2VD2.PO
|
ln -s /usr/share/a2pi/BLANK.PO /usr/share/a2pi/A2VD2.PO
|
||||||
fin
|
fi
|
||||||
#
|
#
|
||||||
# Add schmenk.is-a-geek.com to apt sources
|
# Add schmenk.is-a-geek.com to apt sources
|
||||||
#
|
#
|
||||||
|
|
|
@ -7,7 +7,7 @@ else
|
||||||
BINDIR=$(DESTDIR)/usr/bin
|
BINDIR=$(DESTDIR)/usr/bin
|
||||||
SHAREDIR=$(DESTDIR)/usr/share/a2pi
|
SHAREDIR=$(DESTDIR)/usr/share/a2pi
|
||||||
endif
|
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
|
SBIN=a2pid
|
||||||
A2PIDEFS=-DSETSERCLK
|
A2PIDEFS=-DSETSERCLK
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ clean:
|
||||||
install:
|
install:
|
||||||
-mkdir -p $(BINDIR)
|
-mkdir -p $(BINDIR)
|
||||||
cp $(BIN) a2mount $(BINDIR)
|
cp $(BIN) a2mount $(BINDIR)
|
||||||
|
cp $(BIN) a2setvd $(BINDIR)
|
||||||
-mkdir -p $(SBINDIR)
|
-mkdir -p $(SBINDIR)
|
||||||
cp $(SBIN) $(SBINDIR)
|
cp $(SBIN) $(SBINDIR)
|
||||||
-mkdir -p $(SHAREDIR)
|
-mkdir -p $(SHAREDIR)
|
||||||
|
|
146
src/a2pid.c
146
src/a2pid.c
|
@ -363,38 +363,27 @@ int vdriveopen(char *path)
|
||||||
strcat(filename, "A2VD1.PO");
|
strcat(filename, "A2VD1.PO");
|
||||||
//printf("vdrive: open %s\n", filename);
|
//printf("vdrive: open %s\n", filename);
|
||||||
if ((vdrivefd[0] = open(filename, O_RDWR, 0)) < 0)
|
if ((vdrivefd[0] = open(filename, O_RDWR, 0)) < 0)
|
||||||
return 0;
|
vdrivefd[0] = 0;
|
||||||
strcpy(filename, path);
|
strcpy(filename, path);
|
||||||
strcat(filename, "A2VD2.PO");
|
strcat(filename, "A2VD2.PO");
|
||||||
//printf("vdrive: open %s\n", filename);
|
//printf("vdrive: open %s\n", filename);
|
||||||
if ((vdrivefd[1] = open(filename, O_RDWR, 0)) < 0)
|
if ((vdrivefd[1] = open(filename, O_RDWR, 0)) < 0)
|
||||||
{
|
vdrivefd[1] = 0;
|
||||||
close(vdrivefd[0]);
|
return vdrivefd[0] + vdrivefd[1];
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
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)
|
int i, vfd = vdrivefd[command >> 2];
|
||||||
year -= 100;
|
unsigned char block_buff[512], crc_out = 0xC5 ^ command ^ block ^ (block >> 8);
|
||||||
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 (crc_in != crc_out)
|
||||||
|
prlog("vdrive: CRC mismatch!\n");
|
||||||
if (command == 0x01 || command == 0x03 || command == 0x05)
|
if (command == 0x01 || command == 0x03 || command == 0x05)
|
||||||
{
|
{
|
||||||
//printf("vdrive: read block=%d from unit:%d\n", block, command >> 2);
|
//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[1] = command;
|
||||||
block_buff[2] = block;
|
block_buff[2] = block;
|
||||||
block_buff[3] = block >> 8;
|
block_buff[3] = block >> 8;
|
||||||
write(fd, block_buff, 4);
|
write(afd, block_buff, 4);
|
||||||
if (command > 0x01)
|
if (command > 0x01)
|
||||||
{
|
{
|
||||||
unsigned char time_buff[4];
|
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);
|
time_t now = time(NULL);
|
||||||
struct tm *tm = localtime(&now);
|
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[0] = (unsigned char) ptime;
|
||||||
time_buff[1] = (unsigned char) (ptime >> 8);
|
time_buff[1] = (unsigned char) (ptime >> 8);
|
||||||
time_buff[2] = (unsigned char) (ptime >> 16);
|
time_buff[2] = (unsigned char) (ptime >> 16);
|
||||||
time_buff[3] = (unsigned char) (ptime >> 24);
|
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];
|
crc_out ^= time_buff[0] ^ time_buff[1] ^ time_buff[2] ^ time_buff[3];
|
||||||
}
|
}
|
||||||
lseek(vdrivefd[command >> 2], block * 512, 0);
|
write(afd, &crc_out, 1);
|
||||||
write(fd, &crc_out, 1);
|
if (vfd)
|
||||||
read(vdrivefd[command >> 2], block_buff, 512);
|
{
|
||||||
write(fd, block_buff, 512);
|
lseek(vfd, block * 512, 0);
|
||||||
|
read(vfd, block_buff, 512);
|
||||||
|
}
|
||||||
|
write(afd, block_buff, 512);
|
||||||
for (crc_out = i = 0; i < 512; i++)
|
for (crc_out = i = 0; i < 512; i++)
|
||||||
crc_out ^= block_buff[i];
|
crc_out ^= block_buff[i];
|
||||||
write(fd, &crc_out, 1);
|
write(afd, &crc_out, 1);
|
||||||
}
|
}
|
||||||
else if (command == 0x02 || command == 0x04)
|
else if (command == 0x02 || command == 0x04)
|
||||||
{
|
{
|
||||||
//printf("vdrive: write block=%d to unit:%d\n", block, command >> 2);
|
//printf("vdrive: write block=%d to unit:%d\n", block, command >> 2);
|
||||||
for (crc_out = i = 0; i < 512; i++)
|
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];
|
crc_out ^= block_buff[i];
|
||||||
}
|
}
|
||||||
lseek(vdrivefd[command >> 2], block * 512, 0);
|
if (vfd)
|
||||||
read(fd, &crc_in, 1);
|
{
|
||||||
|
lseek(vfd, block * 512, 0);
|
||||||
|
read(afd, &crc_in, 1);
|
||||||
|
}
|
||||||
if (crc_in == crc_out)
|
if (crc_in == crc_out)
|
||||||
write(vdrivefd[command >> 2], block_buff, 512);
|
write(vfd, block_buff, 512);
|
||||||
block_buff[0] = 0xC5;
|
block_buff[0] = 0xC5;
|
||||||
block_buff[1] = command;
|
block_buff[1] = command;
|
||||||
block_buff[2] = block;
|
block_buff[2] = block;
|
||||||
block_buff[3] = block >> 8;
|
block_buff[3] = block >> 8;
|
||||||
block_buff[4] = crc_out;
|
block_buff[4] = crc_out;
|
||||||
write(fd, block_buff, 5);
|
write(afd, block_buff, 5);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
state = RESET; // ??? What else to do ???
|
state = RESET; // ??? What else to do ???
|
||||||
|
@ -509,8 +508,7 @@ void sendkeycodeup(int fd, int code)
|
||||||
static int prevkeycode = -1;
|
static int prevkeycode = -1;
|
||||||
void sendkey(int fd, int mod, int key)
|
void sendkey(int fd, int mod, int key)
|
||||||
{
|
{
|
||||||
int code = keycode[(mod & MOD_FN) | (key & KEY_ASCII)]
|
int code = keycode[(mod & MOD_FN) | (key & KEY_ASCII)] | ((mod << 8) & MOD_ALT);
|
||||||
| ((mod << 8) & MOD_ALT);
|
|
||||||
|
|
||||||
if (prevkeycode >= 0)
|
if (prevkeycode >= 0)
|
||||||
{
|
{
|
||||||
|
@ -544,8 +542,7 @@ void sendbttn(int fd, int mod, int bttn)
|
||||||
|
|
||||||
if (bttn)
|
if (bttn)
|
||||||
{
|
{
|
||||||
lastbtn =
|
lastbtn = evkey.code = (mod == 0) ? BTN_LEFT
|
||||||
evkey.code = (mod == 0) ? BTN_LEFT
|
|
||||||
: (mod & 0x40) ? BTN_RIGHT
|
: (mod & 0x40) ? BTN_RIGHT
|
||||||
: BTN_MIDDLE;
|
: BTN_MIDDLE;
|
||||||
evkey.value = 1;
|
evkey.value = 1;
|
||||||
|
@ -576,7 +573,7 @@ void sendrelxy(int fd, int x, int y)
|
||||||
write(fd, &evsync, sizeof(evsync));
|
write(fd, &evsync, sizeof(evsync));
|
||||||
}
|
}
|
||||||
/*****************************************************************\
|
/*****************************************************************\
|
||||||
* *
|
* *
|
||||||
* Request queue management *
|
* Request queue management *
|
||||||
* *
|
* *
|
||||||
\*****************************************************************/
|
\*****************************************************************/
|
||||||
|
@ -857,6 +854,28 @@ void main(int argc, char **argv)
|
||||||
* Get VDRIVE images.
|
* Get VDRIVE images.
|
||||||
*/
|
*/
|
||||||
vdriveactive = vdriveopen(vdrivedir);
|
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.
|
* Open serial port.
|
||||||
*/
|
*/
|
||||||
|
@ -875,13 +894,6 @@ void main(int argc, char **argv)
|
||||||
newtio.c_cc[VMIN] = 1; /* blocking read until 1 char received */
|
newtio.c_cc[VMIN] = 1; /* blocking read until 1 char received */
|
||||||
tcsetattr(a2fd, TCSANOW, &newtio);
|
tcsetattr(a2fd, TCSANOW, &newtio);
|
||||||
prlog("a2pid: Waiting to connect to Apple II...\n");
|
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 */
|
iopkt[0] = 0x80; /* request re-sync if Apple II already running */
|
||||||
write(a2fd, iopkt, 1);
|
write(a2fd, iopkt, 1);
|
||||||
if (read(a2fd, iopkt, 1) == 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 */
|
newtio.c_cc[VMIN] = 3; /* blocking read until 3 chars received */
|
||||||
tcsetattr(a2fd, TCSANOW, &newtio);
|
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.
|
* Come basck here on RESET.
|
||||||
*/
|
*/
|
||||||
|
@ -1097,25 +1094,19 @@ reset:
|
||||||
break;
|
break;
|
||||||
case 0xC5: /* virtual drive request */
|
case 0xC5: /* virtual drive request */
|
||||||
//printf("a2pid: vdrive request\n");
|
//printf("a2pid: vdrive request\n");
|
||||||
if (vdriveactive)
|
|
||||||
{
|
|
||||||
newtio.c_cc[VMIN] = 1; /* blocking read until command packet received */
|
newtio.c_cc[VMIN] = 1; /* blocking read until command packet received */
|
||||||
tcsetattr(a2fd, TCSANOW, &newtio);
|
tcsetattr(a2fd, TCSANOW, &newtio);
|
||||||
if (read(a2fd, &iopkt[3], 1) + read(a2fd, &iopkt[4], 1) == 2)
|
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]);
|
//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]);
|
vdrivecmd(a2fd, iopkt[1], iopkt[2] | (iopkt[3] << 8), iopkt[4]);
|
||||||
else
|
|
||||||
prlog("vdrive: bad CRC\n");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
state = RESET;
|
state = RESET;
|
||||||
newtio.c_cc[VMIN] = 3; /* blocking read until 3 chars received */
|
newtio.c_cc[VMIN] = 3; /* blocking read until 3 chars received */
|
||||||
tcsetattr(a2fd, TCSANOW, &newtio);
|
tcsetattr(a2fd, TCSANOW, &newtio);
|
||||||
}
|
if (a2reqlist) /* resend last request */
|
||||||
else
|
write(a2fd, &a2reqlist->type, 1);
|
||||||
state = RESET;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
prlog("a2pid: Unknown Event\n");
|
prlog("a2pid: Unknown Event\n");
|
||||||
|
@ -1226,6 +1217,18 @@ reset:
|
||||||
case 0x98: /* get output chars from Apple II */
|
case 0x98: /* get output chars from Apple II */
|
||||||
a2client[i].flags |= CLIENT_COUT;
|
a2client[i].flags |= CLIENT_COUT;
|
||||||
break;
|
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 */
|
case 0xFF: /* close */
|
||||||
a2client[i].flags = CLIENT_CLOSING;
|
a2client[i].flags = CLIENT_CLOSING;
|
||||||
break;
|
break;
|
||||||
|
@ -1256,7 +1259,6 @@ reset:
|
||||||
close(a2client[i].fd);
|
close(a2client[i].fd);
|
||||||
if (state == RESET)
|
if (state == RESET)
|
||||||
goto reset;
|
goto reset;
|
||||||
if (vdriveactive)
|
|
||||||
vdriveclose();
|
vdriveclose();
|
||||||
shutdown(srvfd, SHUT_RDWR);
|
shutdown(srvfd, SHUT_RDWR);
|
||||||
close(srvfd);
|
close(srvfd);
|
||||||
|
|
22
src/a2pidcmd.c
Executable file
22
src/a2pidcmd.c
Executable file
|
@ -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);
|
||||||
|
}
|
6
src/a2setvd
Executable file
6
src/a2setvd
Executable file
|
@ -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;
|
return -EACCES;
|
||||||
A2PI_WAIT;
|
A2PI_WAIT;
|
||||||
cachepath[0] = '\0';
|
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;
|
A2PI_RELEASE;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user