#include #include #define THRESHOLD 100 // Small busy-waiting loop void wait(){ unsigned int i; for (i=0; i<7; i++); } // Reads bytes produced by 4021-IC void readPads(char *left, char *right){ char i; // Load new inputs into parallel ports of 4021-IC on Nintendo controllers T2 = 1; // Bring PL high wait(); // until stable T2 = 0; // Latch the inputs on the falling edge // Retrive values. Logical clock clocks bits out of 4021-IC into 8051 for(i=0; i<8; i++){ wait(); T2_EX = 0; // bring logical clock low *left = *left<<1; *left |= P0_0; // read the next bit *right = *right<<1; *right |= P0_1; // read the next bit T2_EX = 1; // bring logical clock high } } // Look-up table to convert the combination of bytes from the left and right 8-directional pads // to character, when the Shift button is OFF code char LookUp[8][8]={{0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68}, {0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70}, {0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78}, {0x79,0x7A,0x39,0x30,0x2D,0x3D,0x3B,0x27}, {0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, {0xFF,0xFF,0x20,0xFF,0x10,0xFF,0x08,0xFF}, {0x60,0x2C,0x2E,0x2F,0x5D,0x5B,0x5C,0xFF}}; // Look-up table to convert the combination of bytes from the left and right 8-directional pads // to character, when the Shift button is ON code char ShftLookUp[8][8]={{0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48}, {0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50}, {0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58}, {0x59,0x5A,0x28,0x29,0x5F,0x2B,0x3A,0x22}, {0x21,0x40,0x23,0x24,0x25,0x5E,0x26,0x2A}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, {0x7E,0x3C,0x3E,0x3F,0x7D,0x7B,0x7C,0xFF}}; // Convert the combination of bytes from the left and right 8-directional pads to character char decode(char left, char right){ char rtnVal = 0; // return value char dirLeft, dirRight; // intermediate values char shift = 0; // state of the shift button shift = ~left & 0x80; // get the status of the Shift left = left & 0x0F; // cut off unneeded bits right = right & 0x0F; // cut off unneeded bits // convert bytes from 4021-Ic into intermediate values switch (left){ case 7: dirLeft = 2; break; case 6: dirLeft = 3; break; case 14: dirLeft = 4; break; case 10: dirLeft = 5; break; case 11: dirLeft = 6; break; case 9: dirLeft = 7; break; case 13: dirLeft = 0; break; case 5: dirLeft = 1; break; default: dirLeft = 8; } switch (right){ case 7: dirRight = 2; break; case 6: dirRight = 3; break; case 14: dirRight = 4; break; case 10: dirRight = 5; break; case 11: dirRight = 6; break; case 9: dirRight = 7; break; case 13: dirRight = 0; break; case 5: dirRight = 1; break; default: dirRight = 8; } // sanity check if (dirLeft > 7 || dirRight > 7) return 0; // get the char value out of look-up tables depending on if the Shift is on or off if (shift){ rtnVal = ShftLookUp[dirLeft][dirRight]; } else { rtnVal = LookUp[dirLeft][dirRight]; } return rtnVal; } void main(){ unsigned int counter, // Counts number of times with same input counter2, // counts number of times char left, // input from left pad right, // input from right pad oldOut, // Ascii decode output newOut; // new ascii value bit flag; // set up for serial communications SCON = 0x52; /* SCON */ TMOD = 0x20; /* TMOD */ TCON = 0x69; /* TCON */ TH1 = 0x98; /* TH1 */ // setup serial port hdw to 19.2K Baud @32 MHz while (1){ flag = (flag) ? 0:1; P1_2 = flag; readPads(&left, &right); // Get current values from left and right game pads newOut = decode(left, right); // Translate values to ASCII if (newOut == oldOut){ counter++; if (counter > THRESHOLD){ // Make sure the value is steady before changing it // Send output char to 8051's parallel port P2 to be able // to connect it to GPIO port of a CerfBoard (other project) P2 = oldOut; // Output the character once and delay // before autorepeating if user keeps holding the keys counter2++; if(counter2 == 1 || counter2 >= 4){ SBUF = oldOut; } } }else{ // the different character has been input P2 = 0; counter = 0; counter2 = 0; oldOut = newOut; } } }