mirror of
https://github.com/dschmenk/apple2pi.git
synced 2024-11-27 17:51:42 +00:00
Bug fixes and joystick drivers!
This commit is contained in:
parent
786e79a756
commit
61a5a50024
12
src/11-joy.conf
Executable file
12
src/11-joy.conf
Executable file
@ -0,0 +1,12 @@
|
||||
#
|
||||
# Make sure joysticks don't control the mouse
|
||||
#
|
||||
|
||||
Section "InputClass"
|
||||
Identifier "evdev joystick catchall"
|
||||
MatchIsJoystick "off"
|
||||
MatchDevicePath "/dev/input/event*"
|
||||
Driver "evdev"
|
||||
Option "StartMouseEnabled" "False"
|
||||
Option "StartKeysEnabled" "False"
|
||||
EndSection
|
BIN
src/A2PI.PO
BIN
src/A2PI.PO
Binary file not shown.
@ -1,4 +1,4 @@
|
||||
BIN=a2serclk a2pid a2mon a2term dskread dskwrite bintomon bload brun text2merlin merlin2text
|
||||
BIN= a2serclk a2pid a2joy a2joymou a2mon a2term dskread dskwrite bintomon bload brun text2merlin merlin2text
|
||||
all: $(BIN)
|
||||
|
||||
fusea2pi: fusea2pi.c a2lib.c
|
||||
|
177
src/a2joy.c
Executable file
177
src/a2joy.c
Executable file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright 2013, David Schmenk
|
||||
*/
|
||||
#include "a2lib.c"
|
||||
#include <fcntl.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/uinput.h>
|
||||
#include <signal.h>
|
||||
#define FALSE 0
|
||||
#define TRUE (!FALSE)
|
||||
#define POLL_HZ 20 /* must be greater than 1 */
|
||||
struct timespec tv;
|
||||
struct input_event evkey, evabsx, evabsy, evsync;
|
||||
#define BTTN_IO 0xC061
|
||||
#define READGP0 0x380
|
||||
#define READGP1 0x388
|
||||
char readgp[] = {
|
||||
0xA2, 0x00, // LDX #PADDLE
|
||||
0x78, // SEI
|
||||
0x20, 0x1E, 0xFB, // JSR PREAD
|
||||
0x98, // TYA
|
||||
0x60, // RTS
|
||||
};
|
||||
/*
|
||||
* Error handling.
|
||||
*/
|
||||
int isdebug, stop = FALSE;
|
||||
#define prdbg(s) do{if(isdebug)fprintf(stderr,(s));}while(0)
|
||||
#define die(str, args...) do { \
|
||||
prdbg(str); \
|
||||
exit(-1); \
|
||||
} while(0)
|
||||
static void sig_bye(int signo)
|
||||
{
|
||||
stop = TRUE;
|
||||
}
|
||||
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
struct uinput_user_dev uidev;
|
||||
int a2fd, joyfd, absx, absy, gptoggle;
|
||||
unsigned char prevbttns[2], bttns[2];
|
||||
|
||||
int pifd = a2open("127.0.0.1");
|
||||
if (pifd < 0)
|
||||
{
|
||||
perror("Unable to connect to Apple II Pi");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
/*
|
||||
* Are we running debug?
|
||||
*/
|
||||
if ((argc > 1) && (strcmp(argv[1], "-D") == 0))
|
||||
{
|
||||
isdebug = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (daemon(0, 0) != 0)
|
||||
die("a2joy: daemon() failure");
|
||||
isdebug = FALSE;
|
||||
}
|
||||
/*
|
||||
* Create joystick input device
|
||||
*/
|
||||
prdbg("a2joy: Create joystick input device\n");
|
||||
joyfd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
|
||||
if (joyfd < 0)
|
||||
die("error: uinput open");
|
||||
if (ioctl(joyfd, UI_SET_EVBIT, EV_KEY) < 0)
|
||||
die("error: uinput ioctl EV_KEY");
|
||||
if (ioctl(joyfd, UI_SET_KEYBIT, BTN_TRIGGER) < 0)
|
||||
die("error: uinput ioctl BTN_LEFT");
|
||||
if (ioctl(joyfd, UI_SET_KEYBIT, BTN_THUMB) < 0)
|
||||
die("error: uinput ioctl BTN_RIGHT");
|
||||
if (ioctl(joyfd, UI_SET_EVBIT, EV_ABS) < 0)
|
||||
die("error: ioctl EV_ABS");
|
||||
if (ioctl(joyfd, UI_SET_ABSBIT, ABS_X) < 0)
|
||||
die("error: ioctl ABS_X");
|
||||
if (ioctl(joyfd, UI_SET_ABSBIT, ABS_Y) < 0)
|
||||
die("error: ioctl ABS_Y");
|
||||
if (ioctl(joyfd, UI_SET_EVBIT, EV_SYN) < 0)
|
||||
die("error: ioctl EV_SYN");
|
||||
bzero(&uidev, sizeof(uidev));
|
||||
snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "Apple2 Pi Joystick");
|
||||
uidev.id.bustype = BUS_RS232;
|
||||
uidev.id.vendor = 0x05ac; /* apple */
|
||||
uidev.id.product = 0x2e;
|
||||
uidev.id.version = 1;
|
||||
uidev.absmax[0] = 255;
|
||||
uidev.absmin[0] = 0;
|
||||
uidev.absfuzz[0] = 0;
|
||||
uidev.absflat[0] = 0;
|
||||
uidev.absmax[1] = 255;
|
||||
uidev.absmin[1] = 0;
|
||||
uidev.absfuzz[1] = 0;
|
||||
uidev.absflat[1] = 0;
|
||||
write(joyfd, &uidev, sizeof(uidev));
|
||||
if (ioctl(joyfd, UI_DEV_CREATE) < 0)
|
||||
die("error: ioctl DEV_CREATE");
|
||||
/*
|
||||
* Initialize event structures.
|
||||
*/
|
||||
bzero(&evkey, sizeof(evkey));
|
||||
bzero(&evsync, sizeof(evsync));
|
||||
bzero(&evabsx, sizeof(evabsx));
|
||||
bzero(&evabsy, sizeof(evabsy));
|
||||
evkey.type = EV_KEY;
|
||||
evabsx.type = EV_ABS;
|
||||
evabsx.code = ABS_X;
|
||||
evabsy.type = EV_ABS;
|
||||
evabsy.code = ABS_Y;
|
||||
evsync.type = EV_SYN;
|
||||
/*
|
||||
* Add signal handlers.
|
||||
*/
|
||||
if (signal(SIGINT, sig_bye) == SIG_ERR)
|
||||
die("signal");
|
||||
if (signal(SIGHUP, sig_bye) == SIG_ERR)
|
||||
die("signal");
|
||||
/*
|
||||
* Set poll rate.
|
||||
*/
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_nsec = isdebug ? 1E+9/2 : 1E+9/POLL_HZ;
|
||||
/*
|
||||
* Download 6502 code.
|
||||
*/
|
||||
readgp[1] = 0;
|
||||
a2write(pifd, READGP0, sizeof(readgp), readgp);
|
||||
readgp[1] = 1;
|
||||
a2write(pifd, READGP1, sizeof(readgp), readgp);
|
||||
a2call(pifd, READGP0, &evabsx.value);
|
||||
a2read(pifd, BTTN_IO, 2, prevbttns);
|
||||
a2call(pifd, READGP1, &evabsy.value);
|
||||
gptoggle = 0;
|
||||
/*
|
||||
* Poll joystick loop.
|
||||
*/
|
||||
prdbg("a2joy: Enter poll loop\n");
|
||||
while (!stop)
|
||||
{
|
||||
if (gptoggle)
|
||||
a2quickcall(pifd, READGP0, &absx);
|
||||
else
|
||||
a2quickcall(pifd, READGP1, &absy);
|
||||
a2read(pifd, BTTN_IO, 2, bttns);
|
||||
gptoggle ^= 1;
|
||||
if (isdebug) fprintf(stderr, "a2joy (%d, %d) [%d %d]\n", absx, absy, bttns[0] >> 7, bttns[1] >> 7);
|
||||
evabsx.value = absx;
|
||||
evabsy.value = absy;
|
||||
write(joyfd, &evabsx, sizeof(evabsx));
|
||||
write(joyfd, &evabsy, sizeof(evabsy));
|
||||
write(joyfd, &evsync, sizeof(evsync));
|
||||
if ((bttns[0] & 0x80) != prevbttns[0])
|
||||
{
|
||||
prevbttns[0] = bttns[0] & 0x80;
|
||||
evkey.code = BTN_TRIGGER;
|
||||
evkey.value = bttns[0] >> 7;
|
||||
write(joyfd, &evkey, sizeof(evkey));
|
||||
write(joyfd, &evsync, sizeof(evsync));
|
||||
}
|
||||
if ((bttns[1] & 0x80) != prevbttns[1])
|
||||
{
|
||||
prevbttns[1] = bttns[1] & 0x80;
|
||||
evkey.code = BTN_THUMB;
|
||||
evkey.value = bttns[1] >> 7;
|
||||
write(joyfd, &evkey, sizeof(evkey));
|
||||
write(joyfd, &evsync, sizeof(evsync));
|
||||
}
|
||||
nanosleep(&tv, NULL);
|
||||
}
|
||||
a2close(pifd);
|
||||
ioctl(joyfd, UI_DEV_DESTROY);
|
||||
close(joyfd);
|
||||
prdbg("\na2joy: Exit\n");
|
||||
}
|
190
src/a2joymou.c
Executable file
190
src/a2joymou.c
Executable file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright 2013, David Schmenk
|
||||
*/
|
||||
#include "a2lib.c"
|
||||
#include <fcntl.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/uinput.h>
|
||||
#include <signal.h>
|
||||
#define FALSE 0
|
||||
#define TRUE (!FALSE)
|
||||
#define POLL_HZ 30 /* must be greater than 1 */
|
||||
struct timespec tv;
|
||||
struct input_event evkey, evrelx, evrely, evsync;
|
||||
#define BTTN_IO 0xC061
|
||||
#define READGP0 0x380
|
||||
#define READGP1 0x388
|
||||
char readgp[] = {
|
||||
0xA2, 0x00, // LDX #PADDLE
|
||||
0x78, // SEI
|
||||
0x20, 0x1E, 0xFB, // JSR PREAD
|
||||
0x98, // TYA
|
||||
0x60, // RTS
|
||||
};
|
||||
int accel[20] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 7, 9, 10};
|
||||
/*
|
||||
* Error handling.
|
||||
*/
|
||||
int isdebug, stop = FALSE;
|
||||
#define prdbg(s) do{if(isdebug)fprintf(stderr,(s));}while(0)
|
||||
#define die(str, args...) do { \
|
||||
prdbg(str); \
|
||||
exit(-1); \
|
||||
} while(0)
|
||||
static void sig_bye(int signo)
|
||||
{
|
||||
stop = TRUE;
|
||||
}
|
||||
|
||||
void main(int argc, char **argv)
|
||||
{
|
||||
struct uinput_user_dev uidev;
|
||||
int a2fd, joyfd, relx, rely, cntrx, cntry, gptoggle;
|
||||
unsigned char prevbttns[2], bttns[2];
|
||||
|
||||
int pifd = a2open("127.0.0.1");
|
||||
if (pifd < 0)
|
||||
{
|
||||
perror("Unable to connect to Apple II Pi");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
/*
|
||||
* Are we running debug?
|
||||
*/
|
||||
if ((argc > 1) && (strcmp(argv[1], "-D") == 0))
|
||||
{
|
||||
isdebug = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (daemon(0, 0) != 0)
|
||||
die("a2joy: daemon() failure");
|
||||
isdebug = FALSE;
|
||||
}
|
||||
/*
|
||||
* Create joystick input device
|
||||
*/
|
||||
prdbg("a2joy: Create joystick input device\n");
|
||||
joyfd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
|
||||
if (joyfd < 0)
|
||||
die("error: uinput open");
|
||||
if (ioctl(joyfd, UI_SET_EVBIT, EV_KEY) < 0)
|
||||
die("error: uinput ioctl EV_KEY");
|
||||
if (ioctl(joyfd, UI_SET_KEYBIT, BTN_LEFT) < 0)
|
||||
die("error: uinput ioctl BTN_LEFT");
|
||||
if (ioctl(joyfd, UI_SET_KEYBIT, BTN_RIGHT) < 0)
|
||||
die("error: uinput ioctl BTN_RIGHT");
|
||||
if (ioctl(joyfd, UI_SET_EVBIT, EV_REL) < 0)
|
||||
die("error: ioctl EV_rel");
|
||||
if (ioctl(joyfd, UI_SET_RELBIT, REL_X) < 0)
|
||||
die("error: ioctl rel_X");
|
||||
if (ioctl(joyfd, UI_SET_RELBIT, REL_Y) < 0)
|
||||
die("error: ioctl rel_Y");
|
||||
if (ioctl(joyfd, UI_SET_EVBIT, EV_SYN) < 0)
|
||||
die("error: ioctl EV_SYN");
|
||||
bzero(&uidev, sizeof(uidev));
|
||||
snprintf(uidev.name, UINPUT_MAX_NAME_SIZE, "Apple2 Pi Joystick");
|
||||
uidev.id.bustype = BUS_RS232;
|
||||
uidev.id.vendor = 0x05ac; /* apple */
|
||||
uidev.id.product = 0x2e;
|
||||
uidev.id.version = 1;
|
||||
write(joyfd, &uidev, sizeof(uidev));
|
||||
if (ioctl(joyfd, UI_DEV_CREATE) < 0)
|
||||
die("error: ioctl DEV_CREATE");
|
||||
/*
|
||||
* Initialize event structures.
|
||||
*/
|
||||
bzero(&evkey, sizeof(evkey));
|
||||
bzero(&evsync, sizeof(evsync));
|
||||
bzero(&evrelx, sizeof(evrelx));
|
||||
bzero(&evrely, sizeof(evrely));
|
||||
evkey.type = EV_KEY;
|
||||
evrelx.type = EV_REL;
|
||||
evrelx.code = REL_X;
|
||||
evrely.type = EV_REL;
|
||||
evrely.code = REL_Y;
|
||||
evsync.type = EV_SYN;
|
||||
/*
|
||||
* Add signal handlers.
|
||||
*/
|
||||
if (signal(SIGINT, sig_bye) == SIG_ERR)
|
||||
die("signal");
|
||||
if (signal(SIGHUP, sig_bye) == SIG_ERR)
|
||||
die("signal");
|
||||
/*
|
||||
* Set poll rate.
|
||||
*/
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_nsec = isdebug ? 1E+9/2 : 1E+9/POLL_HZ;
|
||||
/*
|
||||
* Download 6502 code.
|
||||
*/
|
||||
readgp[1] = 0;
|
||||
a2write(pifd, READGP0, sizeof(readgp), readgp);
|
||||
readgp[1] = 1;
|
||||
a2write(pifd, READGP1, sizeof(readgp), readgp);
|
||||
evrelx.value = 0;
|
||||
evrely.value = 0;
|
||||
a2quickcall(pifd, READGP0, &cntrx);
|
||||
a2read(pifd, BTTN_IO, 2, prevbttns);
|
||||
a2quickcall(pifd, READGP1, &cntry);
|
||||
gptoggle = 0;
|
||||
/*
|
||||
* Poll joystick loop.
|
||||
*/
|
||||
prdbg("a2joymou: Enter poll loop\n");
|
||||
while (!stop)
|
||||
{
|
||||
if (gptoggle)
|
||||
{
|
||||
a2quickcall(pifd, READGP0, &relx);
|
||||
if (relx >= cntrx + 20)
|
||||
evrelx.value = (relx - cntrx) / 2;
|
||||
else if (relx >= cntrx)
|
||||
evrelx.value = accel[relx - cntrx];
|
||||
else if (relx <= cntrx - 20)
|
||||
evrelx.value = (relx - cntrx) / 2;
|
||||
else
|
||||
evrelx.value = -accel[cntrx - relx];
|
||||
}
|
||||
else
|
||||
{
|
||||
a2quickcall(pifd, READGP1, &rely);
|
||||
if (rely >= cntry + 20)
|
||||
evrely.value = (rely - cntry) / 2;
|
||||
else if (rely >= cntry)
|
||||
evrely.value = accel[rely - cntry];
|
||||
else if (rely <= cntry - 20)
|
||||
evrely.value = (rely - cntry) / 2;
|
||||
else
|
||||
evrely.value = -accel[cntry - rely];
|
||||
}
|
||||
a2read(pifd, BTTN_IO, 2, bttns);
|
||||
gptoggle ^= 1;
|
||||
if (isdebug) fprintf(stderr, "a2joymou (%d, %d) [%d %d]\n", relx, rely, bttns[0] >> 7, bttns[1] >> 7);
|
||||
write(joyfd, &evrelx, sizeof(evrelx));
|
||||
write(joyfd, &evrely, sizeof(evrely));
|
||||
write(joyfd, &evsync, sizeof(evsync));
|
||||
if ((bttns[0] & 0x80) != prevbttns[0])
|
||||
{
|
||||
prevbttns[0] = bttns[0] & 0x80;
|
||||
evkey.code = BTN_LEFT;
|
||||
evkey.value = bttns[0] >> 7;
|
||||
write(joyfd, &evkey, sizeof(evkey));
|
||||
write(joyfd, &evsync, sizeof(evsync));
|
||||
}
|
||||
if ((bttns[1] & 0x80) != prevbttns[1])
|
||||
{
|
||||
prevbttns[1] = bttns[1] & 0x80;
|
||||
evkey.code = BTN_RIGHT;
|
||||
evkey.value = bttns[1] >> 7;
|
||||
write(joyfd, &evkey, sizeof(evkey));
|
||||
write(joyfd, &evsync, sizeof(evsync));
|
||||
}
|
||||
nanosleep(&tv, NULL);
|
||||
}
|
||||
a2close(pifd);
|
||||
ioctl(joyfd, UI_DEV_DESTROY);
|
||||
close(joyfd);
|
||||
prdbg("\na2joymou: Exit\n");
|
||||
}
|
12
src/a2lib.c
12
src/a2lib.c
@ -76,6 +76,18 @@ int a2write(int fd, int address, int count, char *buffer)
|
||||
return ((unsigned char)writepkt[0] == 0x9E);
|
||||
}
|
||||
int a2call(int fd, int address, int *result)
|
||||
{
|
||||
char callpkt[4];
|
||||
callpkt[0] = 0x9A; // call with keyboard flush
|
||||
callpkt[1] = address;
|
||||
callpkt[2] = address >> 8;
|
||||
write(fd, callpkt, 3);
|
||||
read(fd, callpkt, 2);
|
||||
if (result)
|
||||
*result = (unsigned char)callpkt[1];
|
||||
return ((unsigned char)callpkt[0] == 0x9E);
|
||||
}
|
||||
int a2quickcall(int fd, int address, int *result)
|
||||
{
|
||||
char callpkt[4];
|
||||
callpkt[0] = 0x94; // call
|
||||
|
54
src/a2pid.c
54
src/a2pid.c
@ -186,11 +186,11 @@ int keycode[256] = {
|
||||
KEY_X, // x code 78
|
||||
KEY_Y, // y code 79
|
||||
KEY_Z, // z code 7A
|
||||
MOD_SHIFT | KEY_LEFTBRACE, // { code 7B
|
||||
MOD_SHIFT | KEY_BACKSLASH, // | code 7C
|
||||
MOD_SHIFT | KEY_RIGHTBRACE, // } code 7D
|
||||
MOD_SHIFT | KEY_GRAVE, // ~ code 7E
|
||||
KEY_BACKSPACE, // BS code 7F
|
||||
MOD_SHIFT | KEY_LEFTBRACE, // { code 7B
|
||||
MOD_SHIFT | KEY_BACKSLASH, // | code 7C
|
||||
MOD_SHIFT | KEY_RIGHTBRACE, // } code 7D
|
||||
MOD_SHIFT | KEY_GRAVE, // ~ code 7E
|
||||
KEY_BACKSPACE, // BS code 7F
|
||||
/*
|
||||
* w/ closed apple scancodes
|
||||
*/
|
||||
@ -323,6 +323,7 @@ int keycode[256] = {
|
||||
MOD_SHIFT | KEY_GRAVE, // ~ code 7E
|
||||
KEY_DELETE // DELETE code 7F
|
||||
};
|
||||
#define KEYCODE_MAX 0x10000
|
||||
#define RUN 0
|
||||
#define STOP 1
|
||||
#define RESET 2
|
||||
@ -400,18 +401,18 @@ void sendkey(int fd, int mod, int key)
|
||||
}
|
||||
else
|
||||
{
|
||||
sendkeycodedown(fd, code);
|
||||
if (!(key & KEY_PRESS))
|
||||
/*
|
||||
* missed a key down event
|
||||
* already synthesized one
|
||||
*/
|
||||
sendkeycodeup(fd, code);
|
||||
if (code != -prevkeycode) /* key may have been released before client call */
|
||||
{
|
||||
sendkeycodedown(fd, code);
|
||||
if (!(key & KEY_PRESS))
|
||||
/*
|
||||
* missed a key down event
|
||||
* already synthesized one
|
||||
*/
|
||||
sendkeycodeup(fd, code);
|
||||
}
|
||||
}
|
||||
prevkeycode = (key & KEY_PRESS) ? code : -1;
|
||||
}
|
||||
void flushkey(int fd)
|
||||
{
|
||||
prevkeycode = (key & KEY_PRESS) ? code : -KEYCODE_MAX;
|
||||
}
|
||||
void sendbttn(int fd, int mod, int bttn)
|
||||
{
|
||||
@ -880,21 +881,22 @@ reset:
|
||||
else
|
||||
state = RESET;
|
||||
break;
|
||||
case 0x9A: /* acknowledge call with keyboard flush*/
|
||||
if (prevkeycode >= 0) /* flush keyboard if going away for awhile */
|
||||
{
|
||||
sendkeycodeup(kbdfd, prevkeycode);
|
||||
prevkeycode = -prevkeycode;
|
||||
}
|
||||
case 0x94: /* acknowledge call */
|
||||
if (a2reqlist) /* better have an outstanding request */
|
||||
{
|
||||
//printf("a2pid: call address 0x%04X\n", a2reqlist->addr);
|
||||
newtio.c_cc[VMIN] = 1; /* blocking read until 1 char received */
|
||||
tcsetattr(a2fd, TCSANOW, &newtio);
|
||||
if (!writeword(a2fd, a2reqlist->addr, 0x95))
|
||||
if (!writeword(a2fd, a2reqlist->addr, iopkt[0] + 1))
|
||||
state = RESET;
|
||||
newtio.c_cc[VMIN] = 3; /* blocking read until 3 chars received */
|
||||
tcsetattr(a2fd, TCSANOW, &newtio);
|
||||
if (prevkeycode >= 0)
|
||||
{
|
||||
sendkeycodeup(kbdfd, prevkeycode);
|
||||
prevkeycode = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
state = RESET;
|
||||
@ -917,6 +919,7 @@ reset:
|
||||
for (i = 0; i < MAX_CLIENT; i++)
|
||||
if (a2client[i].flags & CLIENT_COUT)
|
||||
write(a2client[i].fd, iopkt, 2);
|
||||
|
||||
break;
|
||||
case 0x9E: /* request complete ok */
|
||||
case 0x9F: /* request complete error */
|
||||
@ -1033,10 +1036,11 @@ reset:
|
||||
}
|
||||
break;
|
||||
case 0x94: /* call */
|
||||
if (read(a2client[i].fd, iopkt, 2) == 2)
|
||||
case 0x9A: /* call with keyboard flush */
|
||||
if (read(a2client[i].fd, iopkt + 1, 2) == 2)
|
||||
{
|
||||
addr = (unsigned char)iopkt[0] | ((unsigned char)iopkt[1] << 8);
|
||||
addreq(a2fd, i, 0x94, addr, 0, NULL);
|
||||
addr = (unsigned char)iopkt[1] | ((unsigned char)iopkt[2] << 8);
|
||||
addreq(a2fd, i, iopkt[0], addr, 0, NULL);
|
||||
}
|
||||
break;
|
||||
case 0x96: /* send input char to Apple II */
|
||||
|
@ -956,7 +956,6 @@ static int a2pi_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
||||
/*
|
||||
* Root directory, fill with volume names.
|
||||
*/
|
||||
memset(&straw, 0, sizeof(struct stat));
|
||||
unix_stat(&stentry, 0x0F, 0xC3, 0, 0, 0, 0);
|
||||
filler(buf, ".", &stentry, 0);
|
||||
filler(buf, "..", &stentry, 0);
|
||||
@ -969,17 +968,22 @@ static int a2pi_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
|
||||
strncpy(filename, volumes + i + 1, l);
|
||||
filename[l] = '\0';
|
||||
filler(buf, filename, &stentry, 0);
|
||||
}
|
||||
memset(&straw, 0, sizeof(struct stat));
|
||||
for (i = 0; i < 16; i++)
|
||||
if (volblks[i] > 0)
|
||||
{
|
||||
/*
|
||||
* Add volume raw device.
|
||||
* Add raw device.
|
||||
*/
|
||||
slot = (volumes[i] >> 4) & 0x07;
|
||||
drive = (volumes[i] >> 7) & 0x01;
|
||||
slot = i & 0x07;
|
||||
drive = (i >> 3) & 0x01;
|
||||
strcpy(filename, "s0d0.po");
|
||||
filename[1] = slot + '0';
|
||||
filename[3] = drive + '1';
|
||||
straw.st_mode = S_IFREG | 0644;
|
||||
straw.st_nlink = 1;
|
||||
straw.st_blocks = volblks[slot | (drive << 3)];
|
||||
straw.st_blocks = volblks[i];
|
||||
straw.st_size = straw.st_blocks * 512;
|
||||
filler(buf, filename, &straw, 0);
|
||||
}
|
||||
@ -1342,6 +1346,13 @@ int main(int argc, char *argv[])
|
||||
prodos_get_file_info(volpath, &access, &type, &aux, &storage, &numblks, &mod, &create);
|
||||
volblks[volumes[i] >> 4] = aux;
|
||||
}
|
||||
/*
|
||||
* Always add 5 1/4 floppy raw devices.
|
||||
*/
|
||||
if (volblks[0x06] == 0)
|
||||
volblks[0x06] = 280;
|
||||
if (volblks[0x0E] == 0)
|
||||
volblks[0x0E] = 280;
|
||||
umask(0);
|
||||
return fuse_main(argc, argv, &a2pi_oper, NULL);
|
||||
}
|
||||
|
@ -24,4 +24,14 @@ if [ -f /etc/rc.local ] ; then
|
||||
sed -e '/^exit/i\# Start Apple II Pi' -e '/^exit/i\/usr/local/bin/a2serclk' -e '/^exit/i\/usr/local/bin/a2pid --daemon' /etc/rc.local.bak > /etc/rc.local
|
||||
chmod +x /etc/rc.local
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
#
|
||||
# Disable joystick as a mouse in X
|
||||
#
|
||||
cp 11-joy.conf /usr/share/X11/xorg.conf.d
|
||||
#
|
||||
# Create link to new joystick driver for gsportx
|
||||
#
|
||||
if [ ! -e /dev/js0 ] ; then
|
||||
ln -s /dev/input/js0 /dev/js0
|
||||
fi
|
||||
|
Loading…
Reference in New Issue
Block a user