/* DirectPad Pro Joystick Scanning Code - V4.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 mySNES { char dn; char up; char lf; char rt; char a, b; char x, y; char l, r; char sel, start; char vba, vbb; } mySNES; typedef struct myJAG { char dn; char up; char lf; char rt; char a, b, c, d; char pause; char opt; char kp[12]; } myJAG; 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; typedef struct myTGFX { char dn; char up; char lf; char rt; char f1, f2, f3, f4, f5; } myTGFX; typedef struct mySATURN { char dn; char up; char lf; char rt; char a, b, c; char x, y, z; char start; char r,l; char a1, a2, a3; char ax, ay, az; } mySATURN; typedef struct myGENESIS { char dn; char up; char lf; char rt; char a, b, c; char start; char x, y, z, md; } myGENESIS; typedef struct myATARI { char up; char dn; char lf; char rt; char btn; char btn2; } myATARI; 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*/}; shtb = (unsigned short)base; off = 0xff; on = idon[id]; _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 // Super-dooper extended timing // _outp( shtb, off ); //out dx,al // _outp( shtb, off ); //out dx,al } for (i=7; i<9; i++) { _outp( shtb, on ); //out dx,al _outp( shtb, on ); //out dx,al //mov al,0ffh // Super-dooper extended timing // _outp( shtb, on ); //out dx,al // _outp( shtb, on ); //out dx,al _outp( shtb, off ); //out dx,al _outp( shtb, off ); //out dx,al _outp( shtb, off ); //out dx,al _outp( shtb, off ); //out dx,al _outp( shtb, off ); //out dx,al _outp( shtb, off ); //out dx,al _outp( shtb, off ); //out dx,al ; ready bit 7 //mov al,bl } _enable(); //cli for (i=0; i<0x90; i++) _outp( base, 0xff ); 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 (((data>>23)&1)||((data>>22)&1)) // failed comm *n64 = last[id]; else { n64->a = (char)((data>>31) & 1); n64->b = (char)((data>>30) & 1); n64->z = (char)((data>>29) & 1); n64->start = (char)((data>>28) & 1); n64->up = (char)((data>>27) & 1); n64->dn = (char)((data>>26) & 1); n64->lf = (char)((data>>25) & 1); n64->rt = (char)((data>>24) & 1); n64->l = (char)((data>>21) & 1); n64->r = (char)((data>>20) & 1); n64->cup = (char)((data>>19) & 1); n64->cdn = (char)((data>>18) & 1); n64->clf = (char)((data>>17) & 1); n64->crt = (char)((data>>16) & 1); n64->x = (char)((data>>8) & 0xff); n64->y = (char)(data & 0xff); n64->y = - n64->y; last[id] = *n64; } } void ScanTGFX( myTGFX *tgfx, int num, int base ) { int k, l; OUTP( base+2, 0x04 ); // 4 extra inputs OUTP( base, 0xff ); // all out high OUTP( base, 0xff-( 1 << (7-num) ) ); k = _inp( base+1 ); l = _inp( base+2 ); tgfx->up = (k&16)?0:1; tgfx->dn = (k&32)?0:1; tgfx->lf = (k&64)?0:1; tgfx->rt = (k&128)?1:0; tgfx->f1 = (k&8)?0:1; tgfx->f2 = (l&2)?1:0; tgfx->f3 = (l&4)?0:1; tgfx->f4 = (l&1)?1:0; tgfx->f5 = (l&8)?1:0; } void ScanSaturn(mySATURN *saturn, int analog, int id, int base) { const unsigned char tl1 = 4; const unsigned char tr1 = 2; // pad 1 const unsigned char th1 = 1; // pad 1 const unsigned char gnd1 = 64;// pad 1 const unsigned char tl2 = 4; const unsigned char tr2 = 32; // pad 2 const unsigned char th2 = 16; // pad 2 const unsigned char gnd2 =128;// pad 2 const unsigned char r = 16; const unsigned char l = 32; const unsigned char d = 64; const unsigned char u = 128; // inverted! int s0, s1, s2, s3; int sel2, sel1, sel0, gnd; int ad[10]; unsigned char pwr; if (id==1) { sel2 = th1; sel1 = tr1; sel0 = tl1; gnd = gnd1; } else { sel2 = th2; sel1 = tr2; sel0 = tl2; gnd = gnd2; } pwr = 255 - (gnd + sel2 + sel1 + sel0); if (!analog) { OUTP( base, pwr+sel2+sel1+sel0 ); s0=_inp(base+1); OUTP( base, pwr +sel1+sel0 ); s1=_inp(base+1); OUTP( base, pwr+sel2 +sel0 ); s2=_inp(base+1); OUTP( base, pwr +sel0 ); s3=_inp(base+1); saturn->l = NEG(s0, r); saturn->rt = NEG(s1, r); saturn->lf = NEG(s1, l); saturn->dn = NEG(s1, d); saturn->up = POS(s1, u); saturn->start = NEG(s2, r); saturn->a = NEG(s2, l); saturn->c = NEG(s2, d); saturn->b = POS(s2, u); saturn->r = NEG(s3, r); saturn->x = NEG(s3, l); saturn->y = NEG(s3, d); saturn->z = POS(s3, u); } else { OUTPS( base, pwr+sel2+sel1+sel0 ); // 1st data OUTPS( base, pwr +sel1+sel0 ); // 2nd data OUTPS( base, pwr +sel0 ); OUTPS( base, pwr ); // 3rd OUTPS( base, pwr +sel1 ); OUTPS( base, pwr +sel1+sel0 ); // 4th OUTPS( base, pwr +sel0 ); OUTPS( base, pwr ); // 5th ad[0] = _inp(base+1); OUTPS( base, pwr +sel1 ); OUTPS( base, pwr +sel1+sel0 ); // 6th ad[1] = _inp(base+1); OUTPS( base, pwr +sel0 ); OUTPS( base, pwr ); // 7th ad[2] = _inp(base+1); OUTPS( base, pwr +sel1 ); OUTPS( base, pwr +sel1+sel0 ); // 8th ad[3] = _inp(base+1); OUTPS( base, pwr +sel0 ); OUTPS( base, pwr ); // 9th ad[4] = _inp(base+1); OUTPS( base, pwr +sel1 ); OUTPS( base, pwr +sel1+sel0 ); // 10th ad[5] = _inp(base+1); OUTPS( base, pwr +sel0 ); OUTPS( base, pwr ); // 11th ad[6] = _inp(base+1); OUTPS( base, pwr +sel1 ); OUTPS( base, pwr +sel1+sel0 ); // 12th ad[7] = _inp(base+1); OUTPS( base, pwr +sel0 ); OUTPS( base, pwr ); // 13th ad[8] = _inp(base+1); OUTPS( base, pwr +sel1 ); OUTPS( base, pwr +sel1+sel0 ); // 14th ad[9] = _inp(base+1); OUTPS( base, pwr +sel0 ); OUTPS( base, pwr ); // 15th OUTPS( base, pwr +sel1 ); OUTPS( base, pwr +sel1+sel0 ); // 16th OUTPS( base, pwr+sel2+sel1+sel0 ); 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); saturn->ax = POS(ad[4],r)*128 + POS(ad[4],l)*64 + POS(ad[4],d)*32 + NEG(ad[4],u)*16 + POS(ad[5],r)*8 + POS(ad[5],l)*4 + POS(ad[5],d)*2 + NEG(ad[5],u)*1; saturn->ay = POS(ad[6],r)*128 + POS(ad[6],l)*64 + POS(ad[6],d)*32 + NEG(ad[6],u)*16 + POS(ad[7],r)*8 + POS(ad[7],l)*4 + POS(ad[7],d)*2 + NEG(ad[7],u)*1; saturn->az = POS(ad[8],r)*128 + POS(ad[8],l)*64 + POS(ad[8],d)*32 + NEG(ad[8],u)*16 + POS(ad[9],r)*8 + POS(ad[9],l)*4 + POS(ad[9],d)*2 + NEG(ad[9],u)*1; } if (!joy[curJoy].power) OUTP(base,0); //power down gamepad } void ScanGenesis( myGENESIS *genesis, int base ) { int s0, s1, s2, c, c2; 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; } } void ScanAtari( myATARI *atari, int base, int two ) { int c; // 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; } void ScanSNES(mySNES *snes, int base, int snes_din, int negate) { SNESIT(SNES_PWR+SNES_CLK); // Power up! SNESIT(SNES_PWR+SNES_LAT+SNES_CLK); // Latch it! SNESIT(SNES_PWR+SNES_CLK); SNESIT(SNES_PWR); snes->b = SIN; 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) unsigned char p0 = 0xf8+4+2+1; void Clk(int i, int base) { const clk=0x04; // Bit 3 Base+0 (parallel port) if (i) p0 |= clk; else p0 &= ~clk; _outp(base+0, p0); } void Sel(int i, int id, int base) { const power=0xf8; // Bits 3-7 Base+0 (parallel port) const att=0x02; // Bit 2 Base+0 (parallel port) unsigned char attary[] = { 0, 0x02, 0x08, 0x10, 0x20, 0x40 }; unsigned char attval; if (multitap) attval = attary[id]; else attval = att; p0 |= power; if (i) p0 |= attval; else p0 &= ~attval; _outp(base+0, p0); } void Cmd(int i, int base) { const cmd=0x01; // Bit 1 Base+0 (parallel port) if (i) p0 |= cmd; else p0 &= ~cmd; _outp(base+0, p0); } int Dat(int id, int base) { unsigned char data; if (multitap) data = 0x40; else { if (id==1) data = 0x40; else data = 0x10; } 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; } void Slow(int base) { int i; if (psxdelay==3) { for (i=0; i<3; i++) _outp(base+0, p0); } else { for (i=0; i<psxdelay; i++) _outp(base+0, p0); } } 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; } void SendPSXString( int string[], int id, int base ) { int i; Sel(1, id, base); Clk(1, base); Cmd(1, base); Slow(base); Slow(base); Slow(base); Slow(base); Sel(0, id, base); Slow(base); Slow(base); Slow(base); for (i=0; string[i+1]!=-1; i++) SendByte((unsigned char)string[i],1,id,base); SendByte((unsigned char)string[i],0,id,base); Slow(base); Sel(1, id, base); Cmd(1,base); Clk(1,base); Slow(base); Slow(base); } void Shock(long id, long base, long small, long big) { int i; static int ShockString[4][12]= { {0x01, 0x43, 0x00, 0x01, 0x00, 0x01, -1}, {0x01, 0x4d, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, -1}, {0x01, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -1}, {0x01, 0x42, 0x00, 0xff, 0xff, 0x01, -1 } }; 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 ); } } int ScanPSX( myPSX *psx, int base, int id ) { extern void ForceFeedback( DWORD dwDeviceID, int controller, int base, int always, myPSX *psx ); unsigned char data[10]; Sel(1, id, base); Clk(1,base); Cmd(1,base); Slow(base); Slow(base); Slow(base); Slow(base); Slow(base); Sel(0, id, base); Slow(base); Slow(base); Slow(base); Slow(base); data[0]=SendByte(0x01,1,id,base); data[1]=SendByte(0x42,1,id,base); if (data[1]==0x41) { data[2]=SendByte(0x00,1,id,base); data[3]=SendByte(0x00,1,id,base); data[4]=SendByte(0x00,0,id,base); } else if (data[1]==0x53) { data[2]=SendByte(0x00,1,id,base); data[3]=SendByte(0x00,1,id,base); data[4]=SendByte(0x00,1,id,base); data[5]=SendByte(0x00,1,id,base); data[6]=SendByte(0x00,1,id,base); data[7]=SendByte(0x00,1,id,base); data[8]=SendByte(0x00,0,id,base); } else if (data[1]==0x73 || data[1]==0x23) { data[2]=SendByte(0x00,1,id,base); data[3]=SendByte(0x00,1,id,base); data[4]=SendByte(0x00,1,id,base); data[5]=SendByte(0x00,1,id,base); data[6]=SendByte(0x00,1,id,base); data[7]=SendByte(0x00,1,id,base); data[8]=SendByte(0x00,1,id,base); data[9]=SendByte(0x00,0,id,base); } else { data[1] = 0; data[2] = 0; data[3] = 255; data[4] = 255; data[5] = 128; data[6] = 128; data[7] = 128; data[8] = 128; data[9] = 0; } 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; } ForceFeedback( curJoy-1, id, base, 0, psx ); return data[1]; }Download Driver Pack
After your driver has been downloaded, follow these simple steps to install it.
Expand the archive file (if the download file is in zip or rar format).
If the expanded file has an .exe extension, double click it and follow the installation instructions.
Otherwise, open Device Manager by right-clicking the Start menu and selecting Device Manager.
Find the device and model you want to update in the device list.
Double-click on it to open the Properties dialog box.
From the Properties dialog box, select the Driver tab.
Click the Update Driver button, then follow the instructions.
Very important: You must reboot your system to ensure that any driver updates have taken effect.
For more help, visit our Driver Support section for step-by-step videos on how to install drivers for every file type.