Академический Документы
Профессиональный Документы
Культура Документы
9 */
/* (c) Earle F. Philhower, III */
/* See http://www.ziplabel.com/dpadpro for more information */
#define OUTP(a,b) {int aa; for (aa=0; aa<3; aa++) _outp((a), (b));}
#define OUTPS(a,b) {int i; for (i=0; i<8; i++) _outp((a),(b)); }
#define SNES_PWR (128+64+32+16+8)
#define SNES_CLK 1 // base+0
#define SNES_LAT 2 // base+0
#define SIN (negate?((_inp(base+1)&snes_din)?1:0):((_inp(base+1)&snes_din)?0:1))
#define SNESIT(a) {if (snesdelay==3) {int i; for (i=0; i<3; i++) _outp(base, (a));}
else {int i; for (i=0; i<snesdelay; i++) _outp(base, (a));} }
typedef struct {
char dn;
char up;
char lf;
char rt;
char start, select, box, cross, circle, triangle;
char r1, l1, r2, l2, r3, l3;
char lx, ly, rx, ry;
} myPSX;
} myTGFX;
typedef struct {
char dn;
char up;
char lf;
char rt;
char a, b, z, start, l, r;
char cdn;
char cup;
char clf;
char crt;
char x, y;
} myN64;
void ScanN64(myN64 *n64, int base, int id, int snes_din, int negate)
{
int i;
DWORD data;
static myN64 last[6];
unsigned char on, off;
unsigned short shtb;
static unsigned char idon[5] = {0x00, 0xfe /*D0*/, 0xfb /*D2*/, 0xf7 /*D3*/,
0xef /*D4*/};
_disable(); //sti
//mov dx, [shtb]
//mov bl, [on]
//mov al,0ffh
_outp( shtb, 0xff ); //out dx,al
//mov al,bl
for (i=0; i<7; i++)
{
_outp( shtb, on ); //out dx,al
_outp( shtb, on ); //out dx,al
_outp( shtb, on ); //out dx,al
_outp( shtb, on ); //out dx,al
_outp( shtb, on ); //out dx,al
_outp( shtb, on ); //out dx,al
_outp( shtb, on ); //out dx,al
//mov al,0ffh
_outp( shtb, off ); //out dx,al
_outp( shtb, off ); //out dx,al ; ready bit 0
}
for (i=7; i<9; i++)
{
_outp( shtb, on ); //out dx,al
_outp( shtb, on ); //out dx,al
//mov al,0ffh
}
_enable(); //cli
data = 0;
for (i=0; i<32; i++)
{
data <<= 1;
_outp( base, 0xfd );
_outp( base, 0xfd );
_outp( base, 0xfd );
data |= (SIN)?0:1;
_outp( base, 0xff );
_outp( base, 0xff );
_outp( base, 0xff );
}
if (id==1)
{
sel2 = th1;
sel1 = tr1;
sel0 = tl1;
gnd = gnd1;
} else
{
sel2 = th2;
sel1 = tr2;
sel0 = tl2;
gnd = gnd2;
}
if (!analog)
{
OUTP( base, pwr+sel2+sel1+sel0 );
s0=_inp(base+1);
saturn->rt = NEG(ad[0],r);
saturn->lf = NEG(ad[0],l);
saturn->dn = NEG(ad[0],d);
saturn->up = POS(ad[0],u);
saturn->start = NEG(ad[1],r);
saturn->a = NEG(ad[1],l);
saturn->c = NEG(ad[1],d);
saturn->b = POS(ad[1],u);
saturn->r = NEG(ad[2],r);
saturn->x = NEG(ad[2],l);
saturn->y = NEG(ad[2],d);
saturn->z = POS(ad[2],u);
saturn->l = NEG(ad[3],r);
saturn->a1 = NEG(ad[3],l);
saturn->a2 = NEG(ad[3],d);
saturn->a3 = POS(ad[3],u);
if (!joy[curJoy].power)
OUTP(base,0); //power down gamepad
OUTP(base+2, 0x0c);
OUTP(base, 254); // Power up, select=0
s0 = _inp(base+1);
OUTP(base, 255); // Power up, select=1
s1 = _inp(base+1);
c = _inp(base+2);
if (joy[curJoy].name==GENESIS6)
{
_outp(base, 254); // sel=0;
_outp(base, 254); // sel=0;
_outp(base, 255); // sel=1;
_outp(base, 255); // sel=1;
_outp(base, 254); // sel=0;
_outp(base, 254); // sel=0;
_outp(base, 255); // sel=1;
_outp(base, 255); // sel=1;
s2=_inp(base+1);
c2=_inp(base+2);
}
if (!joy[curJoy].power)
OUTP(base, 0); // Power down joystick
genesis->dn = (c&2)?1:0;
genesis->up = (c&1)?1:0;
genesis->lf = (s1&64)?0:1;
genesis->rt = (s1&128)?1:0;
genesis->a = (s0&32)?0:1;
genesis->b = (s1&32)?0:1;
genesis->c = (s1&16)?0:1;
genesis->start = (s0&16)?0:1;
if (joy[curJoy].name==GENESIS6)
{
genesis->z = (c2&1)?1:0;
genesis->y = (c2&2)?1:0;
genesis->x = (s2&64)?0:1;
genesis->md = (s2&128)?1:0;
}
}
// Atari IBM
//up 1 1 (c0-)
//dn 2 14 (c1-)
//lf 3 16 (c2+)
//rt 4 17 (c3-)
//btn 6 11 (s7-) (connect 11 to 4p7R to 2 (d0), drive d0 1)
//btn2 9 12 (s5+) (connect 12 to 4p7R to 3 (d1), drive d1
1)
//gnd 8 18
OUTP(base+2, 4); //All C's high, disconnected
OUTP(base, 2+1); // Power joy button sensor
c = _inp(base+1);
atari->btn = (c & 128)?1:0;
atari->btn2 = two?((c & 32)?0:1):0;
if (!joy[curJoy].power)
OUTP(base, 0); // Power down joy button sensor
c=_inp(base+2);
atari->up = (c&1)?1:0;
atari->dn = (c&2)?1:0;
atari->lf = (c&4)?0:1;
atari->rt = (c&8)?1:0;
}
SNESIT(SNES_PWR);
SNESIT(SNES_PWR+SNES_CLK);
SNESIT(SNES_PWR);
if (joy[curJoy].name==NES)
snes->a = SIN;
else
snes->y = SIN;
SNESIT(SNES_PWR);
SNESIT(SNES_PWR+SNES_CLK);
SNESIT(SNES_PWR);
snes->sel = SIN;
SNESIT(SNES_PWR);
SNESIT(SNES_PWR+SNES_CLK);
SNESIT(SNES_PWR);
snes->start = SIN;
SNESIT(SNES_PWR);
SNESIT(SNES_PWR+SNES_CLK);
SNESIT(SNES_PWR);
snes->up = SIN;
SNESIT(SNES_PWR);
SNESIT(SNES_PWR+SNES_CLK);
SNESIT(SNES_PWR);
snes->dn = SIN;
SNESIT(SNES_PWR);
SNESIT(SNES_PWR+SNES_CLK);
SNESIT(SNES_PWR);
snes->lf = SIN;
SNESIT(SNES_PWR);
SNESIT(SNES_PWR+SNES_CLK);
SNESIT(SNES_PWR);
snes->rt = SIN;
if (joy[curJoy].name==SNES || joy[curJoy].name==VBOY)
{
SNESIT(SNES_PWR);
SNESIT(SNES_PWR+SNES_CLK);
SNESIT(SNES_PWR);
snes->a = SIN;
SNESIT(SNES_PWR);
SNESIT(SNES_PWR+SNES_CLK);
SNESIT(SNES_PWR);
snes->x = SIN;
SNESIT(SNES_PWR);
SNESIT(SNES_PWR+SNES_CLK);
SNESIT(SNES_PWR);
snes->l = SIN;
SNESIT(SNES_PWR);
SNESIT(SNES_PWR+SNES_CLK);
SNESIT(SNES_PWR);
snes->r = SIN;
}
if (joy[curJoy].name==VBOY)
{
SNESIT(SNES_PWR);
SNESIT(SNES_PWR+SNES_CLK);
SNESIT(SNES_PWR);
snes->vba = SIN;
SNESIT(SNES_PWR);
SNESIT(SNES_PWR+SNES_CLK);
SNESIT(SNES_PWR);
snes->vbb = SIN;
}
if (!joy[curJoy].power)
OUTP(base, 0); // Power it down
}
void ScanJag(myJAG *jag, int base)
{
int r4, r4p, r3, r2, r1;
OUTP(base, 255-8);
OUTP(base+2, 4);
r4 = _inp(base+1);
jag->dn = (r4 & 16)?0:1;
jag->up = (r4 & 8)?0:1;
jag->lf = (r4 & 32)?0:1;
jag->rt = (r4 & 128)?1:0;
jag->a = (r4 & 64)?0:1;
r4p = _inp(base+2);
jag->pause = (r4p&2)?1:0;
OUTP(base, 255-4);
r3 = _inp(base+1);
jag->b = (r3 & 64)?0:1;
jag->kp[1] = (r3 & 128)?1:0;
jag->kp[4] = (r3 & 32)?0:1;
jag->kp[7] = (r3 & 16)?0:1;
jag->kp[10]= (r3 & 8)?0:1;
OUTP(base, 255-2);
r2 = _inp(base+1);
jag->c = (r2 & 64)?0:1;
jag->kp[2] = (r2 & 128)?1:0;
jag->kp[5] = (r2 & 32)?0:1;
jag->kp[8] = (r2 & 16)?0:1;
jag->kp[0] = (r2 & 8)?0:1;
OUTP(base, 255-1);
r1 = _inp(base+1);
jag->opt = (r1 & 64)?0:1;
jag->kp[3] = (r1 & 128)?1:0;
jag->kp[6] = (r1 & 32)?0:1;
jag->kp[9] = (r1 & 16)?0:1;
jag->kp[11]= (r1 & 8)?0:1;
}
// =========================
// | o o o | o o o | o o o | Controller plug
// \_____________________/
// 1 2 3 4 5 6 7 8 9
//
// Controller Parallel
// 1 - Data 10(pad1),13(pad2)
// 2 - Command 2
// 3 - 9V(shock) +9V battery terminal
// 4 - GND 18 , also -9V battery terminal
// 5 - V+ 6,7,8,9 through diodes
// 6 - ATT 3
// 7 - Clock 4
// 9 - ack 12(pad1), 15(pad2)
_outp(base+0, p0);
}
if (multitap)
attval = attary[id];
else
attval = att;
p0 |= power;
if (i)
p0 |= attval;
else
p0 &= ~attval;
_outp(base+0, p0);
}
_outp(base+0, p0);
}
if (_inp(base+1)&data)
return 1;
else
return 0;
}
int Ack(int id, int base)
{
unsigned char ack;
if (multitap)
ack = 0x20;
else
{
if (id==1) ack = 0x20;
else ack = 0x08;
}
if (_inp(base+1)&ack)
return 1;
else
return 0;
}
unsigned char SendByte(unsigned char byte, int wait, int id, int base)
{
int i,j; //,k;
unsigned char data;
data=0;
for (i=0; i<8; i++)
{
Slow(base);
Cmd(byte&(1<<i), base);
Clk(0, base);
Slow(base);
data |= (Dat(id, base)?(1<<i):0); // Moved prior to clock rising edge
Clk(1, base);
}
// Wait for ACK;
for(j=0; wait && j<30 && Ack(id, base); j++);
// for(k=0; wait && k<30 && !Ack(id, base); k++);
// if (j==300 || k==300) data=0;
return data;
}
ShockString[3][3] = (int)small;
ShockString[3][4] = (int)big;
for (i=0; i<4; i++)
{
Slow(base);
Slow(base);
Slow(base);
SendPSXString( ShockString[i], id, base );
}
}
Slow(base);
Slow(base);
Sel(1, id, base);
Cmd(1,base);
Clk(1,base);
Slow(base);
psx->lf = data[3]&0x80?0:1;
psx->dn = data[3]&0x40?0:1;
psx->rt = data[3]&0x20?0:1;
psx->up = data[3]&0x10?0:1;
psx->start = data[3]&0x08?0:1;
psx->select = data[3]&0x01?0:1;
psx->cross = data[4]&0x40?0:1;
psx->circle = data[4]&0x20?0:1;
psx->l2 = data[4]&0x01?0:1;
psx->r3 = data[3]&0x04?0:1;
psx->l3 = data[3]&0x02?0:1;
if (data[1]!=0x41) {
psx->rx = data[5];
psx->ry = data[6];
psx->lx = data[7];
psx->ly = data[8];
} else {
psx->lx = psx->rx = psx->lf?(MINJOY/256):(psx->rt?(MAXJOY/256):
(MIDJOY/256));
psx->ly = psx->ry = psx->up?(MINJOY/256):(psx->dn?(MAXJOY/256):
(MIDJOY/256));
}
switch (data[1]) {
case 0x73: //analog red mode
case 0x53: //analog green mode
psx->l1 = data[4]&0x04?0:1;
psx->r1 = data[4]&0x08?0:1;
psx->triangle = data[4]&0x10?0:1;
psx->r2 = data[4]&0x02?0:1;
psx->box = data[4]&0x80?0:1;
break;
default:
psx->box = data[4]&0x80?0:1;
psx->triangle = data[4]&0x10?0:1;
psx->r1 = data[4]&0x08?0:1;
psx->l1 = data[4]&0x04?0:1;
psx->r2 = data[4]&0x02?0:1;
break;
}
return data[1];
}