/* * grip_gpp_read_packet() reads a Gravis GamePad Pro packet.
*/
staticint grip_gpp_read_packet(struct gameport *gameport, int shift, unsignedint *data)
{ unsignedlong flags; unsignedchar u, v; unsignedint t; int i;
int strobe = gameport_time(gameport, GRIP_STROBE_GPP);
data[0] = 0;
t = strobe;
i = 0;
local_irq_save(flags);
v = gameport_read(gameport) >> shift;
do {
t--;
u = v; v = (gameport_read(gameport) >> shift) & 3; if (~v & u & 1) {
data[0] |= (v >> 1) << i++;
t = strobe;
}
} while (i < GRIP_LENGTH_GPP && t > 0);
local_irq_restore(flags);
if (i < GRIP_LENGTH_GPP) return -1;
for (i = 0; i < GRIP_LENGTH_GPP && (data[0] & 0xfe4210) ^ 0x7c0000; i++)
data[0] = data[0] >> 1 | (data[0] & 1) << (GRIP_LENGTH_GPP - 1);
return -(i == GRIP_LENGTH_GPP);
}
/* * grip_xt_read_packet() reads a Gravis Xterminator packet.
*/
staticint grip_xt_read_packet(struct gameport *gameport, int shift, unsignedint *data)
{ unsignedint i, j, buf, crc; unsignedchar u, v, w; unsignedlong flags; unsignedint t; char status;
int strobe = gameport_time(gameport, GRIP_STROBE_XT);
data[0] = data[1] = data[2] = data[3] = 0;
status = buf = i = j = 0;
t = strobe;
local_irq_save(flags);
v = w = (gameport_read(gameport) >> shift) & 3;
do {
t--;
u = (gameport_read(gameport) >> shift) & 3;
if (u ^ v) {
if ((u ^ v) & 1) {
buf = (buf << 1) | (u >> 1);
t = strobe;
i++;
} else
if ((((u ^ v) & (v ^ w)) >> 1) & ~(u | v | w) & 1) { if (i == 20) {
crc = buf ^ (buf >> 7) ^ (buf >> 14); if (!((crc ^ (0x25cb9e70 >> ((crc >> 2) & 0x1c))) & 0xf)) {
data[buf >> 18] = buf >> 4;
status |= 1 << (buf >> 18);
}
j++;
}
t = strobe;
buf = 0;
i = 0;
}
w = v;
v = u;
}
} while (status != 0xf && i < GRIP_MAX_BITS_XT && j < GRIP_MAX_CHUNKS_XT && t > 0);
local_irq_restore(flags);
return -(status != 0xf);
}
/* * grip_timer() repeatedly polls the joysticks and generates events.
*/
staticvoid grip_poll(struct gameport *gameport)
{ struct grip *grip = gameport_get_drvdata(gameport); unsignedint data[GRIP_LENGTH_XT]; struct input_dev *dev; int i, j;
for (i = 0; i < 2; i++) {
dev = grip->dev[i]; if (!dev) continue;
grip->reads++;
switch (grip->mode[i]) {
case GRIP_MODE_GPP:
if (grip_gpp_read_packet(grip->gameport, (i << 1) + 4, data)) {
grip->bads++; break;
}
for (i = 0; i < 2; i++) if (grip->dev[i])
input_unregister_device(grip->dev[i]);
gameport_close(gameport);
gameport_set_drvdata(gameport, NULL);
kfree(grip);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.