/* 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>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; ilf = 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]; }