diff --git a/.gitignore b/.gitignore index e43b0f9..94f1119 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .DS_Store +.vscode diff --git a/SmartyKit 1 basic drivers/SmartyKit1_KeyboardDriverBasic/SmartyKit1_KeyboardDriverBasic.ino b/SmartyKit 1 basic drivers/SmartyKit1_KeyboardDriverBasic/SmartyKit1_KeyboardDriverBasic.ino index 7408ab3..acfdab2 100644 --- a/SmartyKit 1 basic drivers/SmartyKit1_KeyboardDriverBasic/SmartyKit1_KeyboardDriverBasic.ino +++ b/SmartyKit 1 basic drivers/SmartyKit1_KeyboardDriverBasic/SmartyKit1_KeyboardDriverBasic.ino @@ -15,7 +15,8 @@ along with this program. If not, see . */ -#include "PS2Keyboard.h" +#include +#include // Keyboard Driver pins connections: // D0 & D1 – reserved for Serial connection @@ -27,92 +28,96 @@ // A4 -> Low-rate clock output for CPU CLK input // A5 -> Low-rate clock output for indicating LED connection -const int PS2Socket_Data = 2; -const int CPUreadsKeyboardPin = 3; -const int PS2Socket_Clk = 4; +#define PS2KEYBOARDCLOCK_PIN 2 +#define KEYBOARD_RD_PIN 3 +#define PS2KEYBOARD_DATA_PIN 4 +#define KEYBOARD_BIT7_PIN 5 +const int KeyboardPort[8] = {6, 7, 8, 9, 10, 11, 12, 13}; -const int KeyboardBIT7pin = 5; // -const int DataBus[8] = {6, 7, 8, 9, 10, 11, 12, 13}; -static boolean BIT7flag = false; -static boolean autoMode = true; //run pre-set command or wait for user input from PS/2 keyboard +static boolean autoMode = false; //run pre-set command or wait for user input from PS/2 keyboard static boolean autoCommandSent = false; // run pre-set command only once after reboot of Keyboard controller //low-rate clock for tests on A4-A5 -#define CLOCK A4 -#define LED A5 -int lowRateClockPeriod = 10; //10 milliseconds = 100 times per second (100 Hz) +#define LORATE_CLOCK_PIN A4 +#define LORATE_CLOCK_LED_PIN A5 -//#define _WITH_SERIAL_ -#define _WITH_PS2_ +//10 milliseconds = 100 times per second (100 Hz) +#define LORATE_CLOCK_PERIOD_MILLIS 100 -#ifdef _WITH_PS2_ -PS2Keyboard keyboard; -#endif +PS2KeyAdvanced keyboard; +PS2KeyMap keymap; void setup() { - pinMode(CLOCK, OUTPUT); - pinMode(LED, OUTPUT); + pinMode(LORATE_CLOCK_PIN, OUTPUT); + pinMode(LORATE_CLOCK_LED_PIN, OUTPUT); - pinMode(CPUreadsKeyboardPin, INPUT_PULLUP); - - for (int count = 1; count <= 8; count++) { - pinMode(DataBus[count-1], OUTPUT); - }; - pinMode(KeyboardBIT7pin, OUTPUT); - KeyboardBIT7_Disable(); + pinMode(KEYBOARD_RD_PIN, INPUT_PULLUP); + for (int bit = 0; bit < 8; bit++) { + pinMode(KeyboardPort[bit], OUTPUT); + } + pinMode(KEYBOARD_BIT7_PIN, OUTPUT); + digitalWrite(KEYBOARD_BIT7_PIN, LOW); + + Serial.begin(9600); + Serial.println("SmartyKit 1 PS2 Keyboard is ready..."); + if (autoMode) delay(7500); //for start without Keyboard connected else delay(500); -#ifdef _WITH_PS2_ - keyboard.begin(PS2Socket_Clk, PS2Socket_Data); -#endif - attachInterrupt(1, cpuReadsKeyboard, FALLING); + keyboard.begin(PS2KEYBOARD_DATA_PIN, PS2KEYBOARDCLOCK_PIN); + keyboard.echo(); + delay( 6 ); + uint16_t scan_code = keyboard.read(); -#ifdef _WITH_SERIAL_ - Serial.begin(9600); - Serial.println("SmartyKit 1 Serial Keyboard is ready..."); - #endif + if( (scan_code & 0xff) == PS2_KEY_ECHO || (scan_code & 0xff) == PS2_KEY_BAT || (scan_code & 0xff) == 0xe8 ) + Serial.println( "Keyboard OK.." ); // Response was Echo or power up + else + if ((scan_code & 0xff) == 0) + { + Serial.println( "Keyboard Not Found" ); + } + else + { + Serial.print( "Invalid Code received of 0x" ); + Serial.println(scan_code, HEX); + } + + keyboard.setNoBreak(1); + keyboard.setNoRepeat(1); + keymap.selectMap((char *)"UK"); + attachInterrupt(digitalPinToInterrupt(KEYBOARD_RD_PIN), cpuReadsKeyboard, FALLING); } void cpuReadsKeyboard(void) { - KeyboardBIT7_Disable(); -} - -void KeyboardBIT7_Enable() -{ - digitalWrite(KeyboardBIT7pin, HIGH); - BIT7flag = true; -} -void KeyboardBIT7_Disable() -{ - digitalWrite(KeyboardBIT7pin, LOW); - BIT7flag = false; + digitalWrite(KEYBOARD_BIT7_PIN, LOW); } void sendCharToKeyboardPort(char c) -{ - while(BIT7flag == true) //wait untill the previous char is read by CPU - delay(5); - - for (int count = 1; count <= 8 ; count++) +{ + if (c == '\r') + Serial.println(); + else + Serial.print(c); + + for (int bit = 0; bit < 8 ; bit++) { - if (c & (1 << (count-1))) - digitalWrite(DataBus[count-1], HIGH); - else - digitalWrite(DataBus[count-1], LOW); + if (c & (1 << (bit))) + digitalWrite(KeyboardPort[bit], HIGH); + else + digitalWrite(KeyboardPort[bit], LOW); } - digitalWrite(DataBus[7], HIGH); - KeyboardBIT7_Enable(); + digitalWrite(KeyboardPort[7], HIGH); + digitalWrite(KEYBOARD_BIT7_PIN, HIGH); } -void loop() { - +void loop() +{ //run pre-set command in auto-mode when PS/2 keyboard is not connected //only once after reboot of Keyboard controller if (autoMode && !autoCommandSent) @@ -121,55 +126,58 @@ void loop() { runAutoModeCommand(); } -#ifdef _WITH_PS2_ //check PS2 input - if (keyboard.available()) { - char c = keyboard.read(); + if (!digitalRead(KEYBOARD_BIT7_PIN) && keyboard.available()) + { + uint16_t scan_code = keymap.remapKey(keyboard.read()); + char c = scan_code & 0xff; + + Serial.print(":0x"); + Serial.print(scan_code, HEX); + Serial.print(":"); - if (c == PS2_TAB) - runCommand(); - //process Backspace, Left Arrow, Delete as Apple I backspace '_' - if (c == PS2_BACKSPACE) { - c = '_'; - } else if (c == PS2_LEFTARROW) { - c = '_'; - } else if (c == PS2_DELETE) { - c = '_'; + switch (c) + { + case PS2_KEY_TAB: + runCommand(); + break; + case PS2_KEY_BS: + case PS2_KEY_DELETE: + case PS2_KEY_L_ARROW: + c = '_'; + break; + case PS2_KEY_ENTER: + c = '\r'; + break; + case PS2_KEY_SPACE: + c = ' '; + break; } - int scan_code = (int)c; //make all symbols uppercase (from 'a' (ASCII code 0x61) to 'z' (ASCII code 0x7A)) //as in original Apple-1 - if (scan_code >= 0x61 && scan_code <= 0x7A) - scan_code -= 0x20; - c = (char) scan_code; + c = toupper(c); //print c to Keyboard Port to be read by CPU sendCharToKeyboardPort(c); - #ifdef _WITH_SERIAL_ - Serial.print(c); - if (c == '\r') - Serial.println(); - #endif } -#endif //low-rate clock - digitalWrite(CLOCK, HIGH); - digitalWrite(LED, HIGH); - delay(lowRateClockPeriod); // wait for a lowRateClockPeriod - digitalWrite(CLOCK, LOW); - digitalWrite(LED, LOW); - delay(lowRateClockPeriod); // wait for a lowRateClockPeriod + digitalWrite(LORATE_CLOCK_PIN, HIGH); + digitalWrite(LORATE_CLOCK_LED_PIN, HIGH); + delay(LORATE_CLOCK_PERIOD_MILLIS); // wait for a LORATE_CLOCK_PERIOD_MILLIS + digitalWrite(LORATE_CLOCK_PIN, LOW); + digitalWrite(LORATE_CLOCK_LED_PIN, LOW); + delay(LORATE_CLOCK_PERIOD_MILLIS); // wait for a LORATE_CLOCK_PERIOD_MILLIS } //running pre-set Woz OS command for auto mode void runAutoModeCommand() { - const int CMD_COUNT = 1; + const int cmd_count = 1; String cmd1 = String("F000R\r"); // Woz face demo program at $F000 String commands[] = {cmd1}; - for (int i = 0; i < CMD_COUNT; i++) + for (int i = 0; i < cmd_count; i++) for (int j = 0; j < commands[i].length(); j++) { char c = commands[i].charAt(j); @@ -179,17 +187,16 @@ void runAutoModeCommand() //running pre-set Woz OS command (drawing 8x8 pixel art) void runCommand() { - const int CMD_COUNT = 4; + const int cmd_count = 4; String cmd1 = String("1111: 88 A8 50\r"); String cmd2 = String(":07 61 92\r"); String cmd3 = String(":94 67\r"); String cmd4 = String("FC00R\r"); String commands[] = {cmd1, cmd2, cmd3, cmd4}; - for (int i = 0; i < CMD_COUNT; i++) + for (int i = 0; i < cmd_count; i++) for (int j = 0; j < commands[i].length(); j++) { char c = commands[i].charAt(j); sendCharToKeyboardPort(c); } - }