// PS/2 #define DATA 3 #define CLOCK 4 //NES #define NCLOCK 2 //青(4) #define NLATCH 1 //黄(3) #define NDATA 0 //緑(2) #define WAIT 25 #define TIMER 96 //A B SELECT START UP DOWN LEFT RIGHT //X Z Enter Space Num8 Num2 Num4 Num6 uint8_t keymap[] = {0x22, 0x1A, 0x5A, 0x29, 0x75, 0x72, 0x6B, 0x74}; uint8_t joyData[8]; uint8_t reptime[8]; uint8_t padStatus; void setup() { pinMode(CLOCK, OUTPUT); pinMode(DATA, OUTPUT); digitalWrite(CLOCK, HIGH); digitalWrite(DATA, HIGH); pinMode(NLATCH, OUTPUT); pinMode(NCLOCK, OUTPUT); pinMode(NDATA, INPUT); padStatus = 0xff; for(int i=0; i<8; i++) { joyData[i] = 1; reptime[i] = TIMER; } } void loop() { uint8_t kin; padStatus = nesPad(); { for(int i=0; i<8; i++) { kin = (padStatus >> i) & 1; if(kin != joyData[i]) { if(kin == 0) //キーを押した { sendKeyCode(keymap[i]); //メモリ節約のためdelayMicroseconds()に統一 delayMicroseconds(200000); sendKeyCode(0xF0); sendKeyCode(keymap[i]); } else //キーを離した { reptime[i] = TIMER; } joyData[i] = kin; } else { if(kin == 0) //キーは押しっぱなし { if(reptime[i] == 0) { sendKeyCode(keymap[i]); delayMicroseconds(20000); sendKeyCode(0xF0); sendKeyCode(keymap[i]); } else --reptime[i]; } } } } } void sendClock() { digitalWrite(CLOCK, LOW); //クロック delayMicroseconds(WAIT); digitalWrite(CLOCK, HIGH); delayMicroseconds(WAIT); } //PCにキーコードを送る void sendKeyCode(uint8_t code) { uint8_t onebit, parity = 0; if(digitalRead(CLOCK) == LOW) //PCがキーボードの通信を禁止 return; if(digitalRead(DATA) == LOW) //PCからの送信要求 return; digitalWrite(DATA, LOW); //スタートビット sendClock(); //コードを1バイト送る for(int i = 0; i < 8; i++) { onebit = (code >> i) & 1; digitalWrite(DATA, onebit); sendClock(); parity += onebit; } digitalWrite(DATA, ~parity & 1); //パリティビット sendClock(); digitalWrite(DATA, HIGH); sendClock(); return; } uint8_t nesPad() { byte data; digitalWrite(NLATCH, LOW); digitalWrite(NCLOCK, LOW); digitalWrite(NLATCH, HIGH); delayMicroseconds(12); digitalWrite(NLATCH, LOW); for(int i=0; i<8; i++) { bitWrite(data, i, digitalRead(NDATA)); digitalWrite(NCLOCK, HIGH); delayMicroseconds(12); digitalWrite(NCLOCK, LOW); delayMicroseconds(12); } return data; }