//Leonardo & ProMicroの場合 #define SERIAL Serial1 //ProMiniの場合 //#define SERIAL Serial #define RST 4 //リセット要求 #define RDY 5 //送信可能 #define RXD 1 //データ送信 #define RTY 6 //再送要求 //キーボード #define DATA 8 #define CLOCK 2 //割り込みに使用 #define BUFFER_SIZE 32 static volatile uint8_t keyBuffer[BUFFER_SIZE]; static volatile uint8_t head, tail; uint8_t ps2code; bool keybreak; void setup() { pinMode(RST, INPUT); pinMode(RDY, INPUT); //pinMode(RXD, OUTPUT); pinMode(RTY, INPUT); pinMode(CLOCK, INPUT_PULLUP); pinMode(DATA, INPUT_PULLUP); //ハードウェアシリアル初期化 //19.2kbps 8ビット 奇数パリティ ストップビット1ビット SERIAL.begin(19200, SERIAL_8O1); SERIAL.write(0); //何故か必要 head = 0; tail = 0; keybreak = false; attachInterrupt(digitalPinToInterrupt(CLOCK), keyCodeInt, FALLING); } void loop() { //PC98の状態 while(digitalRead(RDY) == HIGH) //送信不可 delayMicroseconds(1); if(digitalRead(RTY) == LOW) //再送要求 SERIAL.write(0); //ダミーデータ if(digitalRead(RST) == LOW) //リセット要求 delayMicroseconds(30); ps2code = getKeyCode(); switch(ps2code) { case 0xF0: //キーリリース keybreak = true; break; case 0x77: //Num Lock if(keybreak) { SERIAL.write(0x3F | 0x80); keybreak = false; } else SERIAL.write(0x3F); //HELP break; case 0x4A: //'/'(E0 4A) if(keybreak) { SERIAL.write(0x41 | 0x80); keybreak = false; } else SERIAL.write(0x41); break; case 0x7C: //* if(keybreak) { SERIAL.write(0x45 | 0x80); keybreak = false; } else SERIAL.write(0x45); break; case 0x7B: //- if(keybreak) { SERIAL.write(0x40 | 0x80); keybreak = false; } else SERIAL.write(0x40); break; case 0x79: //+ if(keybreak) { SERIAL.write(0x49 | 0x80); keybreak = false; } else SERIAL.write(0x49); break; case 0x6C: //7 if(keybreak) { SERIAL.write(0x42 | 0x80); keybreak = false; } else SERIAL.write(0x42); break; case 0x75: //8 if(keybreak) { SERIAL.write(0x43 | 0x80); keybreak = false; } else SERIAL.write(0x43); break; case 0x7D: //9 if(keybreak) { SERIAL.write(0x44 | 0x80); keybreak = false; } else SERIAL.write(0x44); break; case 0x6B: //4 if(keybreak) { SERIAL.write(0x46 | 0x80); keybreak = false; } else SERIAL.write(0x46); break; case 0x73: //5 if(keybreak) { SERIAL.write(0x47 | 0x80); keybreak = false; } else SERIAL.write(0x47); break; case 0x74: //6 if(keybreak) { SERIAL.write(0x48 | 0x80); keybreak = false; } else SERIAL.write(0x48); break; case 0x69: //1 if(keybreak) { SERIAL.write(0x4A | 0x80); keybreak = false; } else SERIAL.write(0x4A); break; case 0x72: //2 if(keybreak) { SERIAL.write(0x4B | 0x80); keybreak = false; } else SERIAL.write(0x4B); break; case 0x7A: //3 if(keybreak) { SERIAL.write(0x4C | 0x80); keybreak = false; } else SERIAL.write(0x4C); break; case 0x70: //0 if(keybreak) { SERIAL.write(0x4E | 0x80); keybreak = false; } else SERIAL.write(0x4E); break; case 0x71: //. if(keybreak) { SERIAL.write(0x50 | 0x80); keybreak = false; } else SERIAL.write(0x50); break; case 0x5A: //Enter(E0 5A) if(keybreak) { SERIAL.write(0x1C | 0x80); keybreak = false; } else SERIAL.write(0x1C); break; } } //キーコードのバッファからコードを取り出す static inline uint8_t getKeyCode(void) { uint8_t ret; if (head == tail) return 0; ret = keyBuffer[head++]; if (head == BUFFER_SIZE) { head = 0; } return ret; } //キーボードからキーコードを受け取る(割り込みエントリ) void keyCodeInt(void) { static uint8_t past = 0; static uint8_t counter = 0; static uint8_t code; static uint8_t parity; uint8_t now, onebit, p; onebit = digitalRead(DATA); now = millis(); if (now - past > 250) counter = 0; past = now; switch (counter++) { case 0: //スタートビット code = 0; parity = 0; break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: code |= onebit << counter - 2; parity += onebit; break; case 9: if (onebit == (~parity & 1)) { //キーバッファにコードを入れる p = tail; keyBuffer[p++] = code; if (p == BUFFER_SIZE) p = 0; if (p == head) p = tail; else tail = p; } break; case 10: //ストップビット counter = 0; break; } }