├── Makefile ├── Soarer.hid ├── Soarer.inc ├── SoarerReverse.sln ├── SoarerReverse.vcproj ├── Soarer_at2usb_v1.12_atmega32u4.asm ├── Soarer_at2usb_v1.12_atmega32u4.bin ├── Soarer_at2usb_v1.12_atmega32u4.lst ├── Soarer_at2usb_v1.12_atmega32u4.txt ├── hwdefs.h ├── intkeys.h ├── kbdtbls.h ├── m32U4def.inc ├── print.c ├── print.h ├── processing.c ├── processing.h ├── readme.txt ├── salloc.c ├── salloc.h ├── soarer.c ├── soarer.h ├── usb_comm.c └── usb_comm.h /Makefile: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonizoon/arakulas-soarers-converter/c32c5c882ea487889656bd893bdec62f70c7d2ee/Makefile -------------------------------------------------------------------------------- /Soarer.hid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonizoon/arakulas-soarers-converter/c32c5c882ea487889656bd893bdec62f70c7d2ee/Soarer.hid -------------------------------------------------------------------------------- /Soarer.inc: -------------------------------------------------------------------------------- 1 | db 5h, 1h ; USAGE_PAGE (Generic Desktop) 2 | db 9h, 6h ; USAGE (Keyboard) 3 | db a1h, 1h ; COLLECTION (Application) 4 | db 15h, 0h ; LOGICAL_MINIMUM (0) 5 | db 26h, ffh, 0h ; LOGICAL_MAXIMUM (255) 6 | db 95h, 8h ; REPORT_COUNT (8) 7 | db 75h, 8h ; REPORT_SIZE (8) 8 | db 81h, 3h ; INPUT (Cnst,Var,Abs) 9 | db c0h ; END_COLLECTION 10 | db 6h, 31h, ffh ; USAGE_PAGE (Not Defined) 11 | db 9h, 74h ; USAGE (Undefined) 12 | db a1h, 53h ; COLLECTION (VendorDefined) 13 | db 75h, 8h ; REPORT_SIZE (8) 14 | db 15h, 0h ; LOGICAL_MINIMUM (0) 15 | db 26h, ffh, 0h ; LOGICAL_MAXIMUM (255) 16 | db 95h, 20h ; REPORT_COUNT (32) 17 | db 9h, 75h ; USAGE (Undefined) 18 | db 81h, 2h ; INPUT (Data,Var,Abs) 19 | db c0h ; END_COLLECTION 20 | db 5h, 1h ; USAGE_PAGE (Generic Desktop) 21 | db 9h, 6h ; USAGE (Keyboard) 22 | db a1h, 1h ; COLLECTION (Application) 23 | db 85h, 1h ; REPORT_ID (1) 24 | db 75h, 1h ; REPORT_SIZE (1) 25 | db 95h, 8h ; REPORT_COUNT (8) 26 | db 5h, 7h ; USAGE_PAGE (Keyboard) 27 | db 19h, e0h ; USAGE_MINIMUM (Keyboard LeftControl) 28 | db 29h, e7h ; USAGE_MAXIMUM (Keyboard Right GUI) 29 | db 15h, 0h ; LOGICAL_MINIMUM (0) 30 | db 25h, 1h ; LOGICAL_MAXIMUM (1) 31 | db 81h, 2h ; INPUT (Data,Var,Abs) 32 | db 95h, 5h ; REPORT_COUNT (5) 33 | db 75h, 1h ; REPORT_SIZE (1) 34 | db 5h, 8h ; USAGE_PAGE (LEDs) 35 | db 19h, 1h ; USAGE_MINIMUM (Num Lock) 36 | db 29h, 5h ; USAGE_MAXIMUM (Kana) 37 | db 91h, 2h ; OUTPUT (Data,Var,Abs) 38 | db 95h, 1h ; REPORT_COUNT (1) 39 | db 75h, 3h ; REPORT_SIZE (3) 40 | db 91h, 3h ; OUTPUT (Cnst,Var,Abs) 41 | db 75h, 1h ; REPORT_SIZE (1) 42 | db 95h, 31h ; REPORT_COUNT (49) 43 | db 5h, 7h ; USAGE_PAGE (Keyboard) 44 | db 19h, 1h ; USAGE_MINIMUM (Keyboard ErrorRollOver) 45 | db 29h, 31h ; USAGE_MAXIMUM (Keyboard \ and |) 46 | db 15h, 0h ; LOGICAL_MINIMUM (0) 47 | db 25h, 1h ; LOGICAL_MAXIMUM (1) 48 | db 81h, 2h ; INPUT (Data,Var,Abs) 49 | db 95h, 1h ; REPORT_COUNT (1) 50 | db 75h, 1h ; REPORT_SIZE (1) 51 | db 81h, 3h ; INPUT (Cnst,Var,Abs) 52 | db 75h, 1h ; REPORT_SIZE (1) 53 | db 95h, 69h ; REPORT_COUNT (105) 54 | db 5h, 7h ; USAGE_PAGE (Keyboard) 55 | db 19h, 33h ; USAGE_MINIMUM (Keyboard ; and :) 56 | db 29h, 9bh ; USAGE_MAXIMUM (Keyboard Cancel) 57 | db 15h, 0h ; LOGICAL_MINIMUM (0) 58 | db 25h, 1h ; LOGICAL_MAXIMUM (1) 59 | db 81h, 2h ; INPUT (Data,Var,Abs) 60 | db 95h, 1h ; REPORT_COUNT (1) 61 | db 75h, 1h ; REPORT_SIZE (1) 62 | db 81h, 3h ; INPUT (Cnst,Var,Abs) 63 | db 75h, 1h ; REPORT_SIZE (1) 64 | db 95h, 8h ; REPORT_COUNT (8) 65 | db 5h, 7h ; USAGE_PAGE (Keyboard) 66 | db 19h, 9dh ; USAGE_MINIMUM (Keyboard Prior) 67 | db 29h, a4h ; USAGE_MAXIMUM (Keyboard ExSel) 68 | db 15h, 0h ; LOGICAL_MINIMUM (0) 69 | db 25h, 1h ; LOGICAL_MAXIMUM (1) 70 | db 81h, 2h ; INPUT (Data,Var,Abs) 71 | db 95h, 4h ; REPORT_COUNT (4) 72 | db 75h, 1h ; REPORT_SIZE (1) 73 | db 81h, 3h ; INPUT (Cnst,Var,Abs) 74 | db c0h ; END_COLLECTION 75 | db 5h, 1h ; USAGE_PAGE (Generic Desktop) 76 | db 9h, 80h ; USAGE (System Control) 77 | db a1h, 1h ; COLLECTION (Application) 78 | db 85h, 2h ; REPORT_ID (2) 79 | db 75h, 1h ; REPORT_SIZE (1) 80 | db 95h, 3h ; REPORT_COUNT (3) 81 | db 19h, 81h ; USAGE_MINIMUM (System Power Down) 82 | db 29h, 83h ; USAGE_MAXIMUM (System Wake Up) 83 | db 15h, 0h ; LOGICAL_MINIMUM (0) 84 | db 25h, 1h ; LOGICAL_MAXIMUM (1) 85 | db 81h, 2h ; INPUT (Data,Var,Abs) 86 | db 95h, 5h ; REPORT_COUNT (5) 87 | db 75h, 1h ; REPORT_SIZE (1) 88 | db 81h, 3h ; INPUT (Cnst,Var,Abs) 89 | db c0h ; END_COLLECTION 90 | db 5h, ch ; USAGE_PAGE (Consumer Devices) 91 | db 9h, 1h ; USAGE (Consumer Control) 92 | db a1h, 1h ; COLLECTION (Application) 93 | db 85h, 3h ; REPORT_ID (3) 94 | db 75h, 1h ; REPORT_SIZE (1) 95 | db 95h, 18h ; REPORT_COUNT (24) 96 | db 9h, b5h ; USAGE (Scan Next Track) 97 | db 9h, b6h ; USAGE (Scan Previous Track) 98 | db 9h, b7h ; USAGE (Stop) 99 | db 9h, cdh ; USAGE (Unassigned) 100 | db 9h, e2h ; USAGE (Mute) 101 | db 9h, e5h ; USAGE (Bass Boost) 102 | db 9h, e7h ; USAGE (Loudness) 103 | db 9h, e9h ; USAGE (Volume Up) 104 | db 9h, eah ; USAGE (Volume Down) 105 | db ah, 52h, 1h ; USAGE (Bass Increment) 106 | db ah, 53h, 1h ; USAGE (Bass Decrement) 107 | db ah, 54h, 1h ; USAGE (Treble Increment) 108 | db ah, 55h, 1h ; USAGE (Treble Decrement) 109 | db ah, 83h, 1h ; USAGE (AL Consumer Control Configuration) 110 | db ah, 8ah, 1h ; USAGE (AL Email Reader) 111 | db ah, 92h, 1h ; USAGE (AL Calculator) 112 | db ah, 94h, 1h ; USAGE (AL Local Machine Browser) 113 | db ah, 21h, 2h ; USAGE (AC Search) 114 | db ah, 23h, 2h ; USAGE (AC Home) 115 | db ah, 24h, 2h ; USAGE (AC Back) 116 | db ah, 25h, 2h ; USAGE (AC Forward) 117 | db ah, 26h, 2h ; USAGE (AC Stop) 118 | db ah, 27h, 2h ; USAGE (AC Refresh) 119 | db ah, 2ah, 2h ; USAGE (AC Bookmarks) 120 | db 15h, 0h ; LOGICAL_MINIMUM (0) 121 | db 25h, 1h ; LOGICAL_MAXIMUM (1) 122 | db 81h, 2h ; INPUT (Data,Var,Abs) 123 | db c0h ; END_COLLECTION 124 | db 6h, 99h, ffh ; USAGE_PAGE (Not Defined) 125 | db ah, 68h, 24h ; USAGE (Undefined) 126 | db a1h, 1h ; COLLECTION (Application) 127 | db 75h, 8h ; REPORT_SIZE (8) 128 | db 15h, 0h ; LOGICAL_MINIMUM (0) 129 | db 26h, ffh, 0h ; LOGICAL_MAXIMUM (255) 130 | db 95h, 40h ; REPORT_COUNT (64) 131 | db 9h, 1h ; USAGE (Undefined) 132 | db 81h, 2h ; INPUT (Data,Var,Abs) 133 | db 95h, 40h ; REPORT_COUNT (64) 134 | db 9h, 2h ; USAGE (Undefined) 135 | db 91h, 2h ; OUTPUT (Data,Var,Abs) 136 | db c0h ; END_COLLECTION 137 | -------------------------------------------------------------------------------- /SoarerReverse.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SoarerReverse", "SoarerReverse.vcproj", "{468D68D6-D8DC-437C-A3BA-1388D081336B}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | AdaFruit|Win32 = AdaFruit|Win32 9 | ProMicro|Win32 = ProMicro|Win32 10 | Teensy20|Win32 = Teensy20|Win32 11 | TeensyPP1|Win32 = TeensyPP1|Win32 12 | TeensyPP2|Win32 = TeensyPP2|Win32 13 | EndGlobalSection 14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 15 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.AdaFruit|Win32.ActiveCfg = AdaFruit|Win32 16 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.AdaFruit|Win32.Build.0 = AdaFruit|Win32 17 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.ProMicro|Win32.ActiveCfg = ProMicro|Win32 18 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.ProMicro|Win32.Build.0 = ProMicro|Win32 19 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.Teensy20|Win32.ActiveCfg = Teensy20|Win32 20 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.Teensy20|Win32.Build.0 = Teensy20|Win32 21 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.TeensyPP1|Win32.ActiveCfg = TeensyPP1|Win32 22 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.TeensyPP1|Win32.Build.0 = TeensyPP1|Win32 23 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.TeensyPP2|Win32.ActiveCfg = TeensyPP2|Win32 24 | {468D68D6-D8DC-437C-A3BA-1388D081336B}.TeensyPP2|Win32.Build.0 = TeensyPP2|Win32 25 | EndGlobalSection 26 | GlobalSection(SolutionProperties) = preSolution 27 | HideSolutionNode = FALSE 28 | EndGlobalSection 29 | EndGlobal 30 | -------------------------------------------------------------------------------- /SoarerReverse.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 25 | 38 | 39 | 45 | 58 | 59 | 65 | 78 | 79 | 85 | 98 | 99 | 105 | 118 | 119 | 120 | 121 | 122 | 123 | 128 | 131 | 132 | 135 | 136 | 139 | 140 | 143 | 144 | 147 | 148 | 149 | 154 | 157 | 158 | 161 | 162 | 165 | 166 | 169 | 170 | 173 | 174 | 177 | 178 | 181 | 182 | 185 | 186 | 187 | 192 | 193 | 196 | 199 | 200 | 203 | 204 | 207 | 208 | 211 | 212 | 213 | 216 | 219 | 220 | 223 | 224 | 227 | 228 | 231 | 232 | 235 | 236 | 239 | 240 | 243 | 244 | 247 | 248 | 251 | 252 | 253 | 256 | 257 | 260 | 261 | 262 | 263 | 264 | 265 | -------------------------------------------------------------------------------- /Soarer_at2usb_v1.12_atmega32u4.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antonizoon/arakulas-soarers-converter/c32c5c882ea487889656bd893bdec62f70c7d2ee/Soarer_at2usb_v1.12_atmega32u4.bin -------------------------------------------------------------------------------- /hwdefs.h: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* hwdefs.h : hardware definitions for the known HW configurations */ 3 | /*****************************************************************************/ 4 | 5 | #ifndef __hwdefs_h__ 6 | #define __hwdefs_h__ 7 | 8 | /* 9 | Currently supported configurations: 10 | 11 | LAYOUT_TEENSY_2 12 | =============== 13 | Teensy 2.0 14 | ATmega32U4 15 | Onboard LED PD6, Active High 16 | PS/2 Data PD0 17 | PS/2 Clock PD1 18 | PS/2 Reset PB7 19 | Caps Lock LED PF5 20 | Num Lock LED PF6 21 | Scroll Lock LED PF7 22 | Aux Key 1..5 PB0..PB4 23 | 24 | LAYOUT_PRO_MICRO 25 | ================ 26 | Pro Micro 27 | ATmega32U4 28 | Onboard LED PD5, Active Low 29 | PS/2 Data PD0 (Pin 3) 30 | PS/2 Clock PD1 (Pin 2) 31 | PS/2 Reset PB6 (Pin 10) 32 | Caps Lock LED PF5 (Pin A2) 33 | Num Lock LED PF6 (Pin A1) 34 | Scroll Lock LED PF7 (Pin A0) 35 | Aux Key 1..5 PB1..PB5 (Pins labeled 15,16,14,8,9) 36 | 37 | LAYOUT_ADAFRUIT 38 | =============== 39 | AdaFruit Breakout Board 40 | ATmega32U4 41 | Onboard LED PE6, Active High 42 | PS/2 Data PD0 43 | PS/2 Clock PD1 44 | PS/2 Reset PB7 45 | Caps Lock LED PF5 46 | Num Lock LED PF6 47 | Scroll Lock LED PF7 48 | Aux Key 1..5 PB0..PB4 49 | 50 | LAYOUT_TEENSYPP_1 51 | ================= 52 | Teensy++ 1.0 53 | AT90USB646 54 | Onboard LED PD6, Active Low 55 | PS/2 Data PD0 56 | PS/2 Clock PD1 57 | PS/2 Reset PB7 58 | Caps Lock LED PD3 59 | Num Lock LED PD4 60 | Scroll Lock LED PD5 61 | Aux Key 1..5 PB0..PB4 62 | 63 | LAYOUT_TEENSYPP_2 64 | ================= 65 | Teensy++ 2.0 66 | AT90USB1286 67 | Onboard LED PD6, Active High 68 | PS/2 Data PD0 69 | PS/2 Clock PD1 70 | PS/2 Reset PB7 71 | Caps Lock LED PD3 72 | Num Lock LED PD4 73 | Scroll Lock LED PD5 74 | Aux Key 1..5 PB0..PB4 75 | 76 | LAYOUT_16U4 77 | =========== 78 | Unknown 79 | ATMega16U4 80 | Currently exactly like LAYOUT_TEENSY_2 (just less Flash etc.) 81 | 82 | */ 83 | 84 | // LAYOUT_xxx may be passed in, but is overridden if it doesn't match the CPU 85 | // __AVR_ATmega16U4__ is always LAYOUT_16U4 86 | #if defined(LAYOUT_16U4) 87 | #undef LAYOUT_16U4 88 | #endif 89 | #define LAYOUT_16U4 !!defined(__AVR_ATmega16U4__) 90 | 91 | // __AVR_ATmega32U4__ may be Teensy 2.0 or Pro Micro 92 | #if !defined(__AVR_ATmega32U4__) 93 | #if defined(LAYOUT_PRO_MICRO) 94 | #undef LAYOUT_PRO_MICRO 95 | #endif 96 | #define LAYOUT_PRO_MICRO 0 97 | #if defined(LAYOUT_TEENSY_2) 98 | #undef LAYOUT_TEENSY_2 99 | #endif 100 | #define LAYOUT_TEENSY_2 0 101 | #if defined(LAYOUT_ADAFRUIT) 102 | #undef LAYOUT_ADAFRUIT 103 | #endif 104 | #define LAYOUT_ADAFRUIT 0 105 | #else 106 | // ATmega32U4 can be Teensy 2.0, Adafruit breakout board or Pro Micro; default to Teensy 2.0 107 | #if !defined(LAYOUT_PRO_MICRO) 108 | #define LAYOUT_PRO_MICRO 0 109 | #endif 110 | #if !defined(LAYOUT_ADAFRUIT) 111 | #define LAYOUT_ADAFRUIT 0 112 | #endif 113 | #if !defined(LAYOUT_TEENSY_2) 114 | #define LAYOUT_TEENSY_2 !(LAYOUT_PRO_MICRO | LAYOUT_ADAFRUIT) 115 | #endif 116 | // If both Pro Micro and Adafruit are passed in, use Pro Micro (debatable) 117 | #if LAYOUT_PRO_MICRO && LAYOUT_ADAFRUIT 118 | #undef LAYOUT_ADAFRUIT 119 | #define LAYOUT_ADAFRUIT 0 120 | #endif 121 | // If both Pro Micro/Adafruit and Teensy 2.0 are passed in, 122 | // use Pro Micro/Adafruit (more specialized) 123 | #if (LAYOUT_PRO_MICRO|LAYOUT_ADAFRUIT) && LAYOUT_TEENSY_2 124 | #undef LAYOUT_TEENSY_2 125 | #define LAYOUT_TEENSY_2 0 126 | #endif 127 | #endif 128 | 129 | // AT90USB646 is always treated as Teensy++ 1.0 130 | #if defined(LAYOUT_TEENSYPP_1) 131 | #undef LAYOUT_TEENSYPP_1 132 | #endif 133 | #define LAYOUT_TEENSYPP_1 !!defined(__AVR_AT90USB646__) 134 | 135 | // __AVR_AT90USB1286__ is always treated as Teensy++ 2.0 136 | #if defined(LAYOUT_TEENSYPP_2) 137 | #undef LAYOUT_TEENSYPP_2 138 | #endif 139 | #define LAYOUT_TEENSYPP_2 !!defined(__AVR_AT90USB1286__) 140 | 141 | // LAYOUT_16U4 is the same as LAYOUT_TEENSY_2 for the moment 142 | #if LAYOUT_16U4 143 | #undef LAYOUT_TEENSY_2 144 | #undef LAYOUT_16U4 145 | #define LAYOUT_TEENSY_2 1 146 | #endif 147 | 148 | #if LAYOUT_TEENSY_2 149 | /*****************************************************************************/ 150 | /* Teensy 2.0 Layout */ 151 | /*****************************************************************************/ 152 | // #pragma message("Compiling for Teensy 2.0") 153 | 154 | #define OBLED_CONFIG ( DDRD |= (1<> PIND0) & 1 ) 161 | #define KBDC_HIGH ( DDRD &= ~(1 << DDD1) , PORTD |= (1 << PORTD1) ) 162 | // maybe wrong order? 163 | #define KBDC_LOW ( DDRD |= (1 << DDD1) , PORTD &= ~(1 << PORTD1) ) 164 | #define KBDC_GET0 ( (PIND >> PIND1) & 1 ) 165 | #define KBDC_GET ( PIND & (1 << PIND1) ) 166 | #define KBDR_HIGH ( DDRB &= ~(1 << DDB7) , PORTB |= (1 << PORTB7) ) 167 | #define KBDR_LOW ( PORTB &= ~(1 << PORTB7) , DDRB |= (1 << DDB7) ) 168 | 169 | #define LLED_BITMASKD ( (1<> PIND0) & 1 ) 197 | #define KBDC_HIGH ( DDRD &= ~(1 << DDD1) , PORTD |= (1 << PORTD1) ) 198 | // maybe wrong order? 199 | #define KBDC_LOW ( DDRD |= (1 << DDD1) , PORTD &= ~(1 << PORTD1) ) 200 | #define KBDC_GET0 ( (PIND >> PIND1) & 1 ) 201 | #define KBDC_GET ( PIND & (1 << PIND1) ) 202 | #define KBDR_HIGH ( DDRB &= ~(1 << DDB6) , PORTB |= (1 << PORTB6) ) 203 | #define KBDR_LOW ( PORTB &= ~(1 << PORTB6) , DDRB |= (1 << DDB6) ) 204 | 205 | #define LLED_BITMASKD ( (1<> 1 ) 214 | 215 | #elif LAYOUT_ADAFRUIT 216 | /*****************************************************************************/ 217 | /* Adafruit Breakout Board Layout */ 218 | /*****************************************************************************/ 219 | // #pragma message("Compiling for AdaFruit") 220 | 221 | #define OBLED_CONFIG ( DDRE |= (1<> PIND0) & 1 ) 228 | #define KBDC_HIGH ( DDRD &= ~(1 << DDD1) , PORTD |= (1 << PORTD1) ) 229 | // maybe wrong order? 230 | #define KBDC_LOW ( DDRD |= (1 << DDD1) , PORTD &= ~(1 << PORTD1) ) 231 | #define KBDC_GET0 ( (PIND >> PIND1) & 1 ) 232 | #define KBDC_GET ( PIND & (1 << PIND1) ) 233 | #define KBDR_HIGH ( DDRB &= ~(1 << DDB7) , PORTB |= (1 << PORTB7) ) 234 | #define KBDR_LOW ( PORTB &= ~(1 << PORTB7) , DDRB |= (1 << DDB7) ) 235 | 236 | #define LLED_BITMASKD ( (1<> PIND0) & 1 ) 259 | #define KBDC_HIGH ( DDRD &= ~(1 << DDD1) , PORTD |= (1 << PORTD1) ) 260 | // maybe wrong order? 261 | #define KBDC_LOW ( DDRD |= (1 << DDD1) , PORTD &= ~(1 << PORTD1) ) 262 | #define KBDC_GET0 ( (PIND >> PIND1) & 1 ) 263 | #define KBDC_GET ( PIND & (1 << PIND1) ) 264 | #define KBDR_HIGH ( DDRB &= ~(1 << DDB7) , PORTB |= (1 << PORTB7) ) 265 | #define KBDR_LOW ( PORTB &= ~(1 << PORTB7) , DDRB |= (1 << DDB7) ) 266 | 267 | #define LLED_BITMASKD ( (1<> PIND0) & 1 ) 290 | #define KBDC_HIGH ( DDRD &= ~(1 << DDD1) , PORTD |= (1 << PORTD1) ) 291 | // maybe wrong order? 292 | #define KBDC_LOW ( DDRD |= (1 << DDD1) , PORTD &= ~(1 << PORTD1) ) 293 | #define KBDC_GET0 ( (PIND >> PIND1) & 1 ) 294 | #define KBDC_GET ( PIND & (1 << PIND1) ) 295 | #define KBDR_HIGH ( DDRB &= ~(1 << DDB7) , PORTB |= (1 << PORTB7) ) 296 | #define KBDR_LOW ( PORTB &= ~(1 << PORTB7) , DDRB |= (1 << DDB7) ) 297 | 298 | #define LLED_BITMASKD ( (1<> 8) & 255) 317 | 318 | // CPU Prescale 319 | #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) 320 | 321 | #define _NOP() do { __asm__ __volatile__ ("nop"); } while (0) 322 | 323 | #endif /* defined(__hwdefs_h__) */ 324 | -------------------------------------------------------------------------------- /intkeys.h: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* intkeys.h : internal key code names (modified HID code set 7 AKA HIDX) */ 3 | /*****************************************************************************/ 4 | 5 | #ifndef _intkeys_h_ 6 | #define _intkeys_h_ 7 | 8 | // special codes 9 | #define KEY_UNASSIGNED 0x00 // Unassigned 10 | #define KEY_OVERRUN_ERROR 0x01 // Overrun error 11 | #define KEY_POST_FAIL 0x02 // POST Fail 12 | #define KEY_ERROR_UNDEFINED 0x03 // ErrorUndefined 13 | // standard HID codes 14 | #define KEY_A 0x04 // a A 15 | #define KEY_B 0x05 // b B 16 | #define KEY_C 0x06 // c C 17 | #define KEY_D 0x07 // d D 18 | #define KEY_E 0x08 // e E 19 | #define KEY_F 0x09 // f F 20 | #define KEY_G 0x0A // g G 21 | #define KEY_H 0x0B // h H 22 | #define KEY_I 0x0C // i I 23 | #define KEY_J 0x0D // j J 24 | #define KEY_K 0x0E // k K 25 | #define KEY_L 0x0F // l L 26 | #define KEY_M 0x10 // m M 27 | #define KEY_N 0x11 // n N 28 | #define KEY_O 0x12 // o O 29 | #define KEY_P 0x13 // p P 30 | #define KEY_Q 0x14 // q Q 31 | #define KEY_R 0x15 // r R 32 | #define KEY_S 0x16 // s S 33 | #define KEY_T 0x17 // t T 34 | #define KEY_U 0x18 // u U 35 | #define KEY_V 0x19 // v V 36 | #define KEY_W 0x1A // w W 37 | #define KEY_X 0x1B // x X 38 | #define KEY_Y 0x1C // y Y 39 | #define KEY_Z 0x1D // z Z 40 | #define KEY_1 0x1E // 1 ! 41 | #define KEY_2 0x1F // 2 @ 42 | #define KEY_3 0x20 // 3 # 43 | #define KEY_4 0x21 // 4 $ 44 | #define KEY_5 0x22 // 5 % 45 | #define KEY_6 0x23 // 6 ^ 46 | #define KEY_7 0x24 // 7 & 47 | #define KEY_8 0x25 // 8 * 48 | #define KEY_9 0x26 // 9 ( 49 | #define KEY_0 0x27 // 0 ) 50 | #define KEY_ENTER 0x28 // Return 51 | #define KEY_ESC 0x29 // Escape 52 | #define KEY_BACKSPACE 0x2A // Backspace 53 | #define KEY_TAB 0x2B // Tab 54 | #define KEY_SPACE 0x2C // Space 55 | #define KEY_MINUS 0x2D // - _ 56 | #define KEY_EQUAL 0x2E // = + 57 | #define KEY_LEFT_BRACE 0x2F // [ { 58 | #define KEY_RIGHT_BRACE 0x30 // ] } 59 | #define KEY_BACKSLASH 0x31 // \ | 60 | #define KEY_EUROPE_1 0x32 // Europe 1 (use BACKSLASH instead) 61 | #define KEY_SEMICOLON 0x33 // ; : 62 | #define KEY_QUOTE 0x34 // ' " 63 | #define KEY_BACK_QUOTE 0x35 // ` ~ 64 | #define KEY_COMMA 0x36 // , < 65 | #define KEY_PERIOD 0x37 // . > 66 | #define KEY_SLASH 0x38 // / ? 67 | #define KEY_CAPS_LOCK 0x39 // Caps Lock 68 | #define KEY_F1 0x3A // F1 69 | #define KEY_F2 0x3B // F2 70 | #define KEY_F3 0x3C // F3 71 | #define KEY_F4 0x3D // F4 72 | #define KEY_F5 0x3E // F5 73 | #define KEY_F6 0x3F // F6 74 | #define KEY_F7 0x40 // F7 75 | #define KEY_F8 0x41 // F8 76 | #define KEY_F9 0x42 // F9 77 | #define KEY_F10 0x43 // F10 78 | #define KEY_F11 0x44 // F11 79 | #define KEY_F12 0x45 // F12 80 | #define KEY_PRINTSCREEN 0x46 // Print Screen 81 | #define KEY_SCROLL_LOCK 0x47 // Scroll Lock 82 | #define KEY_PAUSE 0x48 // Pause 83 | #define KEY_INSERT 0x49 // Insert 84 | #define KEY_HOME 0x4A // Home 85 | #define KEY_PAGE_UP 0x4B // Page Up 86 | #define KEY_DELETE 0x4C // Delete 87 | #define KEY_END 0x4D // End 88 | #define KEY_PAGE_DOWN 0x4E // Page Down 89 | #define KEY_RIGHT 0x4F // Right Arrow 90 | #define KEY_LEFT 0x50 // Left Arrow 91 | #define KEY_DOWN 0x51 // Down Arrow 92 | #define KEY_UP 0x52 // Up Arrow 93 | #define KEY_NUM_LOCK 0x53 // Num Lock 94 | #define KEY_PAD_SLASH 0x54 // Keypad / 95 | #define KEY_PAD_ASTERIX 0x55 // Keypad * 96 | #define KEY_PAD_MINUS 0x56 // Keypad - 97 | #define KEY_PAD_PLUS 0x57 // Keypad + 98 | #define KEY_PAD_ENTER 0x58 // Keypad Enter 99 | #define KEY_PAD_1 0x59 // Keypad 1 End 100 | #define KEY_PAD_2 0x5A // Keypad 2 Down 101 | #define KEY_PAD_3 0x5B // Keypad 3 PageDn 102 | #define KEY_PAD_4 0x5C // Keypad 4 Left 103 | #define KEY_PAD_5 0x5D // Keypad 5 104 | #define KEY_PAD_6 0x5E // Keypad 6 Right 105 | #define KEY_PAD_7 0x5F // Keypad 7 Home 106 | #define KEY_PAD_8 0x60 // Keypad 8 Up 107 | #define KEY_PAD_9 0x61 // Keypad 9 PageUp 108 | #define KEY_PAD_0 0x62 // Keypad 0 Insert 109 | #define KEY_PAD_PERIOD 0x63 // Keypad . Delete 110 | #define KEY_EUROPE_2 0x64 // Europe 2 111 | #define KEY_APP 0x65 // App (Windows Menu) 112 | #define KEY_POWER 0x66 // Keyboard Power 113 | #define KEY_PAD_EQUALS 0x67 // Keypad = 114 | #define KEY_F13 0x68 // F13 115 | #define KEY_F14 0x69 // F14 116 | #define KEY_F15 0x6A // F15 117 | #define KEY_F16 0x6B // F16 118 | #define KEY_F17 0x6C // F17 119 | #define KEY_F18 0x6D // F18 120 | #define KEY_F19 0x6E // F19 121 | #define KEY_F20 0x6F // F20 122 | #define KEY_F21 0x70 // F21 123 | #define KEY_F22 0x71 // F22 124 | #define KEY_F23 0x72 // F23 125 | #define KEY_F24 0x73 // F24 126 | #define KEY_EXECUTE 0x74 // Keyboard Execute 127 | #define KEY_HELP 0x75 // Keyboard Help 128 | #define KEY_MENU 0x76 // Keyboard Menu 129 | #define KEY_SELECT 0x77 // Keyboard Select 130 | #define KEY_STOP 0x78 // Keyboard Stop 131 | #define KEY_AGAIN 0x79 // Keyboard Again 132 | #define KEY_UNDO 0x7A // Keyboard Undo 133 | #define KEY_CUT 0x7B // Keyboard Cut 134 | #define KEY_COPY 0x7C // Keyboard Copy 135 | #define KEY_PASTE 0x7D // Keyboard Paste 136 | #define KEY_FIND 0x7E // Keyboard Find 137 | #define KEY_MUTE 0x7F // Keyboard Mute 138 | #define KEY_VOLUME_UP 0x80 // Keyboard Volume Up 139 | #define KEY_VOLUME_DOWN 0x81 // Keyboard Volume Dn 140 | #define KEY_LOCKING_CAPS_LOCK 0x82 // Keyboard Locking Caps Lock 141 | #define KEY_LOCKING_NUM_LOCK 0x83 // Keyboard Locking Num Lock 142 | #define KEY_LOCKING_SCROLL_LOCK 0x84 // Keyboard Locking Scroll Lock 143 | #define KEY_PAD_COMMA 0x85 // Keypad comma (Brazilian Keypad .) 144 | #define KEY_EQUAL_SIGN 0x86 // Keyboard Equal Sign 145 | #define KEY_INTERNATIONAL_1 0x87 // Keyboard Int'l 1 (Ro) 146 | #define KEY_INTERNATIONAL_2 0x88 // Keyboard Intl'2 (Katakana/Hiragana) 147 | #define KEY_INTERNATIONAL_3 0x89 // Keyboard Int'l 2 (Yen) 148 | #define KEY_INTERNATIONAL_4 0x8A // Keyboard Int'l 4 (Henkan) 149 | #define KEY_INTERNATIONAL_5 0x8B // Keyboard Int'l 5 (Muhenkan) 150 | #define KEY_INTERNATIONAL_6 0x8C // Keyboard Int'l 6 (PC9800 Keypad comma) 151 | #define KEY_INTERNATIONAL_7 0x8D // Keyboard Int'l 7 152 | #define KEY_INTERNATIONAL_8 0x8E // Keyboard Int'l 8 153 | #define KEY_INTERNATIONAL_9 0x8F // Keyboard Int'l 9 154 | #define KEY_LANG_1 0x90 // Keyboard Lang 1 (Hangul/English) 155 | #define KEY_LANG_2 0x91 // Keyboard Lang 2 (Hanja) 156 | #define KEY_LANG_3 0x92 // Keyboard Lang 3 (Katakana) 157 | #define KEY_LANG_4 0x93 // Keyboard Lang 4 (Hiragana) 158 | #define KEY_LANG_5 0x94 // Keyboard Lang 5 (Zenkaku/Hankaku) 159 | #define KEY_LANG_6 0x95 // Keyboard Lang 6 160 | #define KEY_LANG_7 0x96 // Keyboard Lang 7 161 | #define KEY_LANG_8 0x97 // Keyboard Lang 8 162 | #define KEY_LANG_9 0x98 // Keyboard Lang 9 163 | #define KEY_ALTERNATE_ERASE 0x99 // Keyboard Alternate Erase 164 | #define KEY_SYSREQ_ATTN 0x9A // Keyboard SysReq/Attention 165 | #define KEY_CANCEL 0x9B // Keyboard Cancel 166 | #define KEY_CLEAR 0x9C // Keyboard Clear (use DELETE instead) 167 | #define KEY_PRIOR 0x9D // Keyboard Prior 168 | #define KEY_RETURN 0x9E // Keyboard Return 169 | #define KEY_SEPARATOR 0x9F // Keyboard Separator 170 | #define KEY_OUT 0xA0 // Keyboard Out 171 | #define KEY_OPER 0xA1 // Keyboard Oper 172 | #define KEY_CLEAR_AGAIN 0xA2 // Keyboard Clear/Again 173 | #define KEY_CRSEL_PROPS 0xA3 // Keyboard CrSel/Props 174 | #define KEY_EXSEL 0xA4 // Keyboard ExSel 175 | // A5-A7 are invalid 176 | // Power code area 177 | #define KEY_SYSTEM_POWER 0xA8 // System Power 178 | #define KEY_SYSTEM_SLEEP 0xA9 // System Sleep 179 | #define KEY_SYSTEM_WAKE 0xAA // System Wake 180 | // Internal use area - must be remapped to appear on USB out 181 | #define KEY_AUX1 0xAB // Auxiliary key 1 182 | #define KEY_AUX2 0xAC // Auxiliary key 2 183 | #define KEY_AUX3 0xAD // Auxiliary key 3 184 | #define KEY_AUX4 0xAE // Auxiliary key 4 185 | #define KEY_AUX5 0xAF // Auxiliary key 5 186 | #define KEY_FAKE_01 0xB0 // legacy from earlier version? 187 | #define KEY_EXTRA_LALT 0xB1 // AT-F extra pad lhs of space 188 | #define KEY_EXTRA_PAD_PLUS 0xB2 // Term extra pad bottom of keypad + 189 | #define KEY_EXTRA_RALT 0xB3 // AT-F extra pad rhs of space 190 | #define KEY_EXTRA_EUROPE_2 0xB4 // AT-F extra pad lhs of enter 191 | #define KEY_EXTRA_BACKSLASH 0xB5 // AT-F extra pad top of enter 192 | #define KEY_EXTRA_INSERT 0xB6 // AT-F extra pad lhs of Insert 193 | #define KEY_EXTRA_F1 0xB7 // 122-key Terminal lhs F1 194 | #define KEY_EXTRA_F2 0xB8 // 122-key Terminal lhs F2 195 | #define KEY_EXTRA_F3 0xB9 // 122-key Terminal lhs F3 196 | #define KEY_EXTRA_F4 0xBA // 122-key Terminal lhs F4 197 | #define KEY_EXTRA_F5 0xBB // 122-key Terminal lhs F5 198 | #define KEY_EXTRA_F6 0xBC // 122-key Terminal lhs F6 199 | #define KEY_EXTRA_F7 0xBD // 122-key Terminal lhs F7 200 | #define KEY_EXTRA_F8 0xBE // 122-key Terminal lhs F8 201 | #define KEY_EXTRA_F9 0xBF // 122-key Terminal lhs F9 202 | #define KEY_EXTRA_F10 0xC0 // 122-key Terminal lhs F10 203 | #define KEY_FAKE_18 0xC1 // legacy from earlier version? 204 | #define KEY_EXTRA_SYSRQ 0xC2 // Sys Req (AT 84-key) 205 | // C3-CF unused 206 | #define KEY_FN1 0xD0 // Function layer key 1 207 | #define KEY_FN2 0xD1 // Function layer key 2 208 | #define KEY_FN3 0xD2 // Function layer key 3 209 | #define KEY_FN4 0xD3 // Function layer key 4 210 | #define KEY_FN5 0xD4 // Function layer key 5 211 | #define KEY_FN6 0xD5 // Function layer key 6 212 | #define KEY_FN7 0xD6 // Function layer key 7 213 | #define KEY_FN8 0xD7 // Function layer key 8 214 | #define KEY_SELECT_0 0xD8 // Select reset 215 | #define KEY_SELECT_1 0xD9 // Select 1 toggle 216 | #define KEY_SELECT_2 0xDA // Select 2 toggle 217 | #define KEY_SELECT_3 0xDB // Select 3 toggle 218 | #define KEY_SELECT_4 0xDC // Select 4 toggle 219 | #define KEY_SELECT_5 0xDD // Select 5 toggle 220 | #define KEY_SELECT_6 0xDE // Select 6 toggle 221 | #define KEY_SELECT_7 0xDF // Select 7 toggle 222 | // Modifier area 223 | #define KEY_LCTRL 0xE0 // Left Control 224 | #define KEY_LSHIFT 0xE1 // Left Shift 225 | #define KEY_LALT 0xE2 // Left Alt 226 | #define KEY_LGUI 0xE3 // Left GUI (Left Windows) 227 | #define KEY_RCTRL 0xE4 // Right Control 228 | #define KEY_RSHIFT 0xE5 // Right Shift 229 | #define KEY_RALT 0xE6 // Right Alt 230 | #define KEY_RGUI 0xE7 // Right GUI (Right Windows) 231 | // Multimedia area 232 | #define KEY_MEDIA_NEXT_TRACK 0xE8 // Scan Next Track 233 | #define KEY_MEDIA_PREV_TRACK 0xE9 // Scan Previous Track 234 | #define KEY_MEDIA_STOP 0xEA // Stop 235 | #define KEY_MEDIA_PLAY_PAUSE 0xEB // Play/ Pause 236 | #define KEY_MEDIA_MUTE 0xEC // Mute 237 | #define KEY_MEDIA_BASS_BOOST 0xED // Bass Boost 238 | #define KEY_MEDIA_LOUDNESS 0xEE // Loudness 239 | #define KEY_MEDIA_VOLUME_UP 0xEF // Volume Up 240 | #define KEY_MEDIA_VOLUME_DOWN 0xF0 // Volume Down 241 | #define KEY_MEDIA_BASS_UP 0xF1 // Bass Up 242 | #define KEY_MEDIA_BASS_DOWN 0xF2 // Bass Down 243 | #define KEY_MEDIA_TREBLE_UP 0xF3 // Treble Up 244 | #define KEY_MEDIA_TREBLE_DOWN 0xF4 // Treble Down 245 | #define KEY_MEDIA_MEDIA_SELECT 0xF5 // Media Select 246 | #define KEY_MEDIA_MAIL 0xF6 // Mail 247 | #define KEY_MEDIA_CALCULATOR 0xF7 // Calculator 248 | #define KEY_MEDIA_MY_COMPUTER 0xF8 // My Computer 249 | #define KEY_MEDIA_WWW_SEARCH 0xF9 // WWW Search 250 | #define KEY_MEDIA_WWW_HOME 0xFA // WWW Home 251 | #define KEY_MEDIA_WWW_BACK 0xFB // WWW Back 252 | #define KEY_MEDIA_WWW_FORWARD 0xFC // WWW Forward 253 | #define KEY_MEDIA_WWW_STOP 0xFD // WWW Stop 254 | #define KEY_MEDIA_WWW_REFRESH 0xFE // WWW Refresh 255 | #define KEY_MEDIA_WWW_FAVORITES 0xFF // WWW Favorites 256 | 257 | // Masks for the special areas 258 | #define KEY_AREA_MASK 0xF8 259 | #define IS_FN_KEY(keyid) (((keyid) & KEY_AREA_MASK) == KEY_FN1) 260 | #define IS_SELECT_KEY(keyid) (((keyid) & KEY_AREA_MASK) == KEY_SELECT_0) 261 | #define IS_MODIFIER_KEY(keyid) (((keyid) & KEY_AREA_MASK) == KEY_LCTRL) 262 | 263 | #endif /* defined _intkeys_h */ 264 | -------------------------------------------------------------------------------- /kbdtbls.h: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* kbdtbls.h : keyboard scan code to USB HID scan code translation tables */ 3 | /*****************************************************************************/ 4 | 5 | #include "intkeys.h" 6 | 7 | /*****************************************************************************/ 8 | /* Messages coming in from the keyboard */ 9 | /*****************************************************************************/ 10 | 11 | #define KBDM_BUFOVR 0x00 // Key detection error or buffer overrun 12 | #define KBDM_BATOK 0xaa // BAT returned OK 13 | #define KBDM_EXTENDED 0xe0 // Extended Key is coming in 14 | #define KBDM_EXTENDED2 0xe1 // Extended Key 2 (Pause) is coming in 15 | #define KBDM_ECHO 0xee // Response to ECHO command 16 | #define KBDM_BREAK 0xf0 // Break code coming in (if missing, it's a Make) 17 | #define KBDM_ACK 0xfa // Acknowledgement for a command from the host 18 | #define KBDM_ERR 0xfc // (BAT) Error 19 | #define KBDM_ERR2 0xfd // BAT Selftest Failed RC2 20 | #define KBDM_RESEND 0xfe // Keyboard requests resend 21 | #define KBDM_BUFOVR2 0xff // Key detection error or buffer overrun 22 | 23 | /*****************************************************************************/ 24 | /* Commands sent to AT/PS2 keyboards */ 25 | /*****************************************************************************/ 26 | 27 | #define ATCMD_RESET 0xff // reset request; ACK + BATOK after some time is expected 28 | #define ATCMD_RESEND 0xfe // resend request 29 | // The following 6 are only required to work in Scan code set 3: 30 | #define ATCMD_SETMK 0xfd // Set Key Type "Make" 31 | #define ATCMD_SETMKBK 0xfc // Set Key Type "Make/Break" (i.e., no repeat) 32 | #define ATCMD_SETTYPEM 0xfb // Set Key Type "Typematic" 33 | // The above 3 are followed by list of scan codes and an unused scan code to end the list; 34 | // the keyboard is expected to answer with KBDM_ACK to each 35 | #define ATCMD_SETASTD 0xfa // Set All Keys back to their default type 36 | #define ATCMD_SETAMK 0xf9 // Set All Keys Type "Make" 37 | #define ATCMD_SETAMKBK 0xf8 // Set All Keys Type "Make/Break" 38 | #define ATCMD_SETATYPEM 0xf7 // Set All Keys Type "Typematic" 39 | #define ATCMD_SETDEFAULT 0xf6 // Reset Keyboard to Default State 40 | #define ATCMD_DISABLE 0xf5 // Reset Keyboard to Default State and Disable scanning 41 | #define ATCMD_ENABLE 0xf4 // (Re-)Enable Scanning after it has been disabled 42 | #define ATCMD_SETRATE 0xf3 // Set Typematic rate/delay 43 | #define ATCMD_READID 0xf2 // Keyboard is expected to respond with its 2-byte ID (ACK before 1st byte) 44 | #define ATCMD_SCANSET 0xf0 // Set Scancode Set (<- ACK/Err -> [new set(1|2|3) <- ACK/Err | 0 <- ACK+current|Err]) 45 | #define ATCMD_ECHO 0xee // Send Echo (<- ECHO) 46 | #define ATCMD_SETLEDS 0xed // Set LED State (<- ACK -> Caps:2+Num:1+Scroll:0 <- ACK) 47 | 48 | /*****************************************************************************/ 49 | /* Known keyboard IDs */ 50 | /*****************************************************************************/ 51 | // gleaned from http://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html 52 | #define KBDID_AT 0xab83 // IBM AT 53 | #define KBDID_SKBD 0xab84 // Short Keyboard: IBM Space Saver, Thinkpad etc. 54 | #define KBDID_HCON 0xab85 // 122-key host-connected keyboard 55 | #define KBDID_122 0xab86 // PS/2-compatible 122-key keyboards 56 | #define KBDID_JAPG 0xab90 // "old Japanese 'G' keyboard" 57 | #define KBDID_JAPP 0xab91 // "old Japanese 'P' keyboard" 58 | #define KBDID_JAPA 0xab92 // "old Japanese 'A' keyboard" 59 | #define KBDID_IBM_RT 0xbfb0 // IBM RT PC keyboard (with "special" LED command) 60 | #define KBDID_TERM122 0xbfbf // 122-key IBM 1390876 without jumpers (can be reconfigured!) 61 | 62 | 63 | /*---------------------------------------------------------------------------*/ 64 | /* The rest is only relevant for the keyboard input handler */ 65 | /*---------------------------------------------------------------------------*/ 66 | 67 | #ifdef INCLUDE_KBD_TRANS_TABLES 68 | /*****************************************************************************/ 69 | /* keyboard codeset 1 -> HIDX translation table */ 70 | /*****************************************************************************/ 71 | // A_00ac 72 | uint8_t PROGMEM kbd_ttbl_set1[0x80] = 73 | { 74 | KEY_UNASSIGNED, KEY_ESC, KEY_1, KEY_2, // 00..03 75 | KEY_3, KEY_4, KEY_5, KEY_6, // 04..07 76 | KEY_7, KEY_8, KEY_9, KEY_0, // 08..0B 77 | KEY_MINUS, KEY_EQUAL, KEY_BACKSPACE, KEY_TAB, // 0C..0F 78 | KEY_Q, KEY_W, KEY_E, KEY_R, // 10..13 79 | KEY_T, KEY_Y, KEY_U, KEY_I, // 14..17 80 | KEY_O, KEY_P, KEY_LEFT_BRACE, KEY_RIGHT_BRACE, // 18..1B 81 | KEY_ENTER, KEY_LCTRL, KEY_A, KEY_S, // 1C..1F 82 | KEY_D, KEY_F, KEY_G, KEY_H, // 20..23 83 | KEY_J, KEY_K, KEY_L, KEY_SEMICOLON, // 24..27 84 | KEY_QUOTE, KEY_BACK_QUOTE, KEY_LSHIFT, KEY_BACKSLASH, // 28..2b 85 | KEY_Z, KEY_X, KEY_C, KEY_V, // 2c..2f 86 | KEY_B, KEY_N, KEY_M, KEY_COMMA, // 30..33 87 | KEY_PERIOD, KEY_SLASH, KEY_RSHIFT, KEY_PAD_ASTERIX, // 34..37 88 | KEY_LALT, KEY_SPACE, KEY_CAPS_LOCK, KEY_F1, // 38..3B 89 | KEY_F2, KEY_F3, KEY_F4, KEY_F5, // 3C..3F 90 | KEY_F6, KEY_F7, KEY_F8, KEY_F9, // 40..43 91 | KEY_F10, KEY_NUM_LOCK, KEY_SCROLL_LOCK, KEY_PAD_7, // 44..47 92 | KEY_PAD_8, KEY_PAD_9, KEY_PAD_MINUS, KEY_PAD_4, // 48..4B 93 | KEY_PAD_5, KEY_PAD_6, KEY_PAD_PLUS, KEY_PAD_1, // 4C..4F 94 | KEY_PAD_2, KEY_PAD_3, KEY_PAD_0, KEY_PAD_PERIOD, // 50..53 95 | KEY_EXTRA_SYSRQ, KEY_EXTRA_F8, KEY_EUROPE_2, KEY_F11, // 54..57 96 | KEY_F12, KEY_PAD_EQUALS, KEY_FAKE_01, KEY_EXTRA_PAD_PLUS, // 58..5B 97 | KEY_INTERNATIONAL_6, KEY_EXTRA_F1, KEY_EXTRA_F2, KEY_EXTRA_F3, // 5C..5F 98 | KEY_EXTRA_F4, KEY_EXTRA_F5, KEY_EXTRA_F6, KEY_EXTRA_F7, // 60..63 99 | KEY_F13, KEY_F14, KEY_F15, KEY_F16, // 64..67 100 | KEY_F17, KEY_F18, KEY_F19, KEY_F20, // 68..6B 101 | KEY_F21, KEY_F22, KEY_F23, KEY_FAKE_18, // 6C..6F 102 | KEY_INTERNATIONAL_2, KEY_EXTRA_LALT, KEY_EXTRA_RALT, KEY_INTERNATIONAL_1, // 70..73 103 | KEY_EXTRA_EUROPE_2, KEY_EXTRA_BACKSLASH, KEY_F24, KEY_LANG_4, // 74..77 104 | KEY_LANG_3, KEY_INTERNATIONAL_4, KEY_EXTRA_F9, KEY_INTERNATIONAL_5, // 78..7B 105 | KEY_EXTRA_INSERT, KEY_INTERNATIONAL_3, KEY_PAD_COMMA, KEY_EXTRA_F10 // 7C..7F 106 | }; 107 | 108 | /*****************************************************************************/ 109 | /* keyboard codeset 2 -> HIDX translation table */ 110 | /*****************************************************************************/ 111 | // A_012c 112 | uint8_t PROGMEM kbd_ttbl_set2[0x85] = 113 | { 114 | KEY_OVERRUN_ERROR, KEY_F9, KEY_UNASSIGNED, KEY_F5, // 00..03 115 | KEY_F3, KEY_F1, KEY_F2, KEY_F12, // 04..07 116 | KEY_F13, KEY_F10, KEY_F8, KEY_F6, // 08..0B 117 | KEY_F4, KEY_TAB, KEY_BACK_QUOTE, KEY_PAD_EQUALS, // 0C..0F 118 | KEY_F14, KEY_LALT, KEY_LSHIFT, KEY_INTERNATIONAL_2, // 10..13 119 | KEY_LCTRL, KEY_Q, KEY_1, KEY_FAKE_01, // 14..17 120 | KEY_F15, KEY_EXTRA_LALT, KEY_Z, KEY_S, // 18..1B 121 | KEY_A, KEY_W, KEY_2, KEY_EXTRA_PAD_PLUS, // 1C..1F 122 | KEY_F16, KEY_C, KEY_X, KEY_D, // 20..23 123 | KEY_E, KEY_4, KEY_3, KEY_INTERNATIONAL_6, // 24..27 124 | KEY_F17, KEY_SPACE, KEY_V, KEY_F, // 28..2B 125 | KEY_T, KEY_R, KEY_5, KEY_EXTRA_F1, // 2C..2F 126 | KEY_F18, KEY_N, KEY_B, KEY_H, // 30..33 127 | KEY_G, KEY_Y, KEY_6, KEY_EXTRA_F2, // 34..37 128 | KEY_F19, KEY_EXTRA_RALT, KEY_M, KEY_J, // 38..3B 129 | KEY_U, KEY_7, KEY_8, KEY_EXTRA_F3, // 3C..3F 130 | KEY_F20, KEY_COMMA, KEY_K, KEY_I, // 40..43 131 | KEY_O, KEY_0, KEY_9, KEY_EXTRA_F4, // 44..47 132 | KEY_F21, KEY_PERIOD, KEY_SLASH, KEY_L, // 48..4B 133 | KEY_SEMICOLON, KEY_P, KEY_MINUS, KEY_EXTRA_F5, // 4C..4F 134 | KEY_F22, KEY_INTERNATIONAL_1, KEY_QUOTE, KEY_EXTRA_EUROPE_2, // 50..53 135 | KEY_LEFT_BRACE, KEY_EQUAL, KEY_EXTRA_F6, KEY_F23, // 54..57 136 | KEY_CAPS_LOCK, KEY_RSHIFT, KEY_ENTER, KEY_RIGHT_BRACE, // 58..5B 137 | KEY_EXTRA_BACKSLASH, KEY_BACKSLASH, KEY_EXTRA_F7, KEY_F24, // 5C..5F 138 | KEY_EXTRA_F8, KEY_EUROPE_2, KEY_LANG_4, KEY_LANG_3, // 60..63 139 | KEY_INTERNATIONAL_4, KEY_EXTRA_F9, KEY_BACKSPACE, KEY_INTERNATIONAL_5, // 64..67 140 | KEY_EXTRA_INSERT, KEY_PAD_1, KEY_INTERNATIONAL_3, KEY_PAD_4, // 68..6B 141 | KEY_PAD_7, KEY_PAD_COMMA, KEY_EXTRA_F10, KEY_FAKE_18, // 6C..6F 142 | KEY_PAD_0, KEY_PAD_PERIOD, KEY_PAD_2, KEY_PAD_5, // 70..73 143 | KEY_PAD_6, KEY_PAD_8, KEY_ESC, KEY_NUM_LOCK, // 74..77 144 | KEY_F11, KEY_PAD_PLUS, KEY_PAD_3, KEY_PAD_MINUS, // 78..7B 145 | KEY_PAD_ASTERIX, KEY_PAD_9, KEY_SCROLL_LOCK, KEY_UNASSIGNED, // 7C..7F 146 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_F7, // 80..83 147 | KEY_EXTRA_SYSRQ // 84 148 | }; 149 | 150 | /*****************************************************************************/ 151 | /* keyboard codeset 4 (E0 + scan code) -> HIDX translation table */ 152 | /*****************************************************************************/ 153 | // A_01b1 154 | uint8_t PROGMEM kbd_ttbl_set2ex[0x7f] = 155 | { 156 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 00..03 157 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 04..07 158 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 08..0B 159 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 0C..0F 160 | KEY_MEDIA_WWW_SEARCH,KEY_RALT, KEY_UNASSIGNED, KEY_UNASSIGNED, // 10..13 161 | KEY_RCTRL, KEY_MEDIA_PREV_TRACK,KEY_UNASSIGNED, KEY_UNASSIGNED, // 14..17 162 | KEY_MEDIA_WWW_FAVORITES, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 18..1B 163 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_LGUI, // 1C..1F 164 | KEY_MEDIA_WWW_REFRESH,KEY_MEDIA_VOLUME_DOWN, KEY_UNASSIGNED, KEY_MEDIA_MUTE, // 20..23 165 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_RGUI, // 24..27 166 | KEY_MEDIA_WWW_STOP, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_MEDIA_CALCULATOR, // 28..2B 167 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_APP, // 2C..2F 168 | KEY_MEDIA_WWW_FORWARD, KEY_UNASSIGNED, KEY_MEDIA_VOLUME_UP, KEY_UNASSIGNED, // 30..33 169 | KEY_MEDIA_PLAY_PAUSE,KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_POWER, // 34..37 170 | KEY_MEDIA_WWW_BACK, KEY_UNASSIGNED, KEY_MEDIA_WWW_HOME, KEY_MEDIA_STOP, // 38..3B 171 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_SYSTEM_SLEEP, // 3C..3F 172 | KEY_MEDIA_MY_COMPUTER, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 40..43 173 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 44..47 174 | KEY_MEDIA_MAIL, KEY_UNASSIGNED, KEY_PAD_SLASH, KEY_UNASSIGNED, // 48..4B 175 | KEY_UNASSIGNED, KEY_MEDIA_NEXT_TRACK, KEY_UNASSIGNED, KEY_UNASSIGNED, // 4C..4F 176 | KEY_MEDIA_MEDIA_SELECT, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 50..53 177 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 54..57 178 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_PAD_ENTER, KEY_UNASSIGNED, // 58..5B 179 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_SYSTEM_WAKE, KEY_UNASSIGNED, // 5C..5F 180 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 60..63 181 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 64..67 182 | KEY_UNASSIGNED, KEY_END, KEY_UNASSIGNED, KEY_LEFT, // 68..6B 183 | KEY_HOME, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, // 6C..6F 184 | KEY_INSERT, KEY_DELETE, KEY_DOWN, KEY_UNASSIGNED, // 70..73 185 | KEY_RIGHT, KEY_UP, KEY_UNASSIGNED, KEY_UNASSIGNED, // 74..77 186 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_PAGE_DOWN, KEY_UNASSIGNED, // 78..7B 187 | KEY_PRINTSCREEN, KEY_PAGE_UP, KEY_PAUSE // 7C..7E 188 | }; 189 | 190 | /*****************************************************************************/ 191 | /* keyboard codeset 3 -> HIDX translation table */ 192 | /*****************************************************************************/ 193 | // A_0230 194 | uint8_t PROGMEM kbd_ttbl_set3[0x85] = 195 | { 196 | KEY_OVERRUN_ERROR, KEY_EXTRA_F9, KEY_UNASSIGNED, KEY_EXTRA_F5, // 00..03 197 | KEY_EXTRA_F3, KEY_EXTRA_F1, KEY_EXTRA_F2, KEY_F1, // 04..07 198 | KEY_F13, KEY_EXTRA_F10, KEY_EXTRA_F8, KEY_EXTRA_F6, // 08..0B 199 | KEY_EXTRA_F4, KEY_TAB, KEY_BACK_QUOTE, KEY_F2, // 0C..0F 200 | KEY_F14, KEY_LCTRL, KEY_LSHIFT, KEY_EUROPE_2, // 10..13 201 | KEY_CAPS_LOCK, KEY_Q, KEY_1, KEY_F3, // 14..17 202 | KEY_F15, KEY_LALT, KEY_Z, KEY_S, // 18..1B 203 | KEY_A, KEY_W, KEY_2, KEY_F4, // 1C..1F 204 | KEY_F16, KEY_C, KEY_X, KEY_D, // 20..23 205 | KEY_E, KEY_4, KEY_3, KEY_F5, // 24..27 206 | KEY_F17, KEY_SPACE, KEY_V, KEY_F, // 28..2B 207 | KEY_T, KEY_R, KEY_5, KEY_F6, // 2C..2F 208 | KEY_F18, KEY_N, KEY_B, KEY_H, // 30..33 209 | KEY_G, KEY_Y, KEY_6, KEY_F7, // 34..37 210 | KEY_F19, KEY_RALT, KEY_M, KEY_J, // 38..3B 211 | KEY_U, KEY_7, KEY_8, KEY_F8, // 3C..3F 212 | KEY_F20, KEY_COMMA, KEY_K, KEY_I, // 40..43 213 | KEY_O, KEY_0, KEY_9, KEY_F9, // 44..47 214 | KEY_F21, KEY_PERIOD, KEY_SLASH, KEY_L, // 48..4B 215 | KEY_SEMICOLON, KEY_P, KEY_MINUS, KEY_F10, // 4C..4F 216 | KEY_F22, KEY_INTERNATIONAL_1, KEY_QUOTE, KEY_EUROPE_1, // 50..53 217 | KEY_LEFT_BRACE, KEY_EQUAL, KEY_F11, KEY_F23, // 54..57 218 | KEY_RCTRL, KEY_RSHIFT, KEY_ENTER, KEY_RIGHT_BRACE, // 58..5B 219 | KEY_BACKSLASH, KEY_INTERNATIONAL_3, KEY_F12, KEY_F24, // 5C..5F 220 | KEY_DOWN, KEY_LEFT, KEY_LANG_4, KEY_UP, // 60..63 221 | KEY_DELETE, KEY_END, KEY_BACKSPACE, KEY_INSERT, // 64..67 222 | KEY_EXTRA_INSERT, KEY_PAD_1, KEY_RIGHT, KEY_PAD_4, // 68..6B 223 | KEY_PAD_7, KEY_PAGE_DOWN, KEY_HOME, KEY_PAGE_UP, // 6C..6F 224 | KEY_PAD_0, KEY_PAD_PERIOD, KEY_PAD_2, KEY_PAD_5, // 70..73 225 | KEY_PAD_6, KEY_PAD_8, KEY_ESC, KEY_NUM_LOCK, // 74..77 226 | KEY_EXTRA_PAD_PLUS, KEY_PAD_PLUS, KEY_PAD_3, KEY_PAD_MINUS, // 78..7B 227 | KEY_PAD_ASTERIX, KEY_PAD_9, KEY_SCROLL_LOCK, KEY_UNASSIGNED, // 7C..7F 228 | KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_UNASSIGNED, KEY_EXTRA_F7, // 80..83 229 | KEY_EXTRA_SYSRQ // 84 230 | }; 231 | #endif // defined(INCLUDE_KBD_TRANS_TABLES) 232 | -------------------------------------------------------------------------------- /m32U4def.inc: -------------------------------------------------------------------------------- 1 | ;***** THIS IS A MACHINE GENERATED FILE - DO NOT EDIT ******************** 2 | ;***** Created: 2011-02-09 12:03 ******* Source: ATmega32U4.xml ********** 3 | ;************************************************************************* 4 | ;* A P P L I C A T I O N N O T E F O R T H E A V R F A M I L Y 5 | ;* 6 | ;* Number : AVR000 7 | ;* File Name : "m32U4def.inc" 8 | ;* Title : Register/Bit Definitions for the ATmega32U4 9 | ;* Date : 2011-02-09 10 | ;* Version : 2.35 11 | ;* Support E-mail : avr@atmel.com 12 | ;* Target MCU : ATmega32U4 13 | ;* 14 | ;* DESCRIPTION 15 | ;* When including this file in the assembly program file, all I/O register 16 | ;* names and I/O register bit names appearing in the data book can be used. 17 | ;* In addition, the six registers forming the three data pointers X, Y and 18 | ;* Z have been assigned names XL - ZH. Highest RAM address for Internal 19 | ;* SRAM is also defined 20 | ;* 21 | ;* The Register names are represented by their hexadecimal address. 22 | ;* 23 | ;* The Register Bit names are represented by their bit number (0-7). 24 | ;* 25 | ;* Please observe the difference in using the bit names with instructions 26 | ;* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc" 27 | ;* (skip if bit in register set/cleared). The following example illustrates 28 | ;* this: 29 | ;* 30 | ;* in r16,PORTB ;read PORTB latch 31 | ;* sbr r16,(1< 27 | #include 28 | 29 | #include "hwdefs.h" 30 | #include "print.h" 31 | 32 | void print_P(const char *s) 33 | { 34 | char c; 35 | 36 | while (1) { 37 | c = pgm_read_byte(s++); 38 | if (!c) break; 39 | if (c == '\n') usb_debug_putchar('\r'); 40 | usb_debug_putchar(c); 41 | } 42 | } 43 | 44 | void phex1(unsigned char c) 45 | { 46 | usb_debug_putchar(c + ((c < 10) ? '0' : 'A' - 10)); 47 | } 48 | 49 | void phex(unsigned char c) 50 | { 51 | phex1(c >> 4); 52 | phex1(c & 15); 53 | } 54 | 55 | void phex16(unsigned int i) 56 | { 57 | phex(i >> 8); 58 | phex(i); 59 | } 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /print.h: -------------------------------------------------------------------------------- 1 | #ifndef print_h__ 2 | #define print_h__ 3 | 4 | #include 5 | #include "usb_comm.h" 6 | 7 | // this macro allows you to write print("some text") and 8 | // the string is automatically placed into flash memory :) 9 | #define print(s) print_P(PSTR(s)) 10 | #define pchar(c) usb_debug_putchar(c) 11 | 12 | void print_P(const char *s); 13 | void phex1(unsigned char c); 14 | void phex(unsigned char c); 15 | void phex16(unsigned int i); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /processing.h: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* processing.h : the processing part of Soarer's Converter */ 3 | /*****************************************************************************/ 4 | 5 | #ifndef _processing_h__ 6 | #define _processing_h__ 7 | 8 | #include 9 | 10 | #define PROTOCOL_VER 1 11 | #define PROTOCOL_SUBVER 0 12 | #define CODE_VER 1 13 | #define CODE_SUBVER 12 14 | #define SETTINGS_VER 1 15 | #define SETTINGS_SUBVER 1 16 | 17 | // Macro commands 18 | 19 | #define MCMD_PUSH_META 0x80 // PUSH_META modifier 20 | #define MCMD_PRESS 0x01 // PRESS 21 | #define MCMD_MAKE 0x02 // MAKE 22 | #define MCMD_BREAK 0x03 // BREAK 23 | #define MCMD_ASSIGN_META 0x04 // ASSIGN_META 24 | #define MCMD_SET_META 0x05 // SET_META 25 | #define MCMD_CLEAR_META 0x06 // CLEAR_META 26 | #define MCMD_TOGGLE_META 0x07 // TOGGLE_META 27 | #define MCMD_POP_META 0x08 // POP_META 28 | #define MCMD_POP_ALL_META 0x09 // POP_ALL_META 29 | #define MCMD_DELAY 0x0A // DELAY 30 | #define MCMD_CLEAR_ALL 0x0B // CLEAR_ALL 31 | #define MCMD_BOOT 0x0C // BOOT 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | void setup_proc_kbd(uint8_t keyboard_codeset, uint16_t keyboard_id); // A_2b22 38 | uint8_t get_forced_keyboard_type(void); // A_2b7e 39 | uint8_t setup_processing(void); // A_2e28 40 | void rawhid_comm(void); // A_2f98 41 | uint8_t get_keyboard_leds(void); // A_341c 42 | uint8_t get_keyboard_protocol(void); // A_3422 43 | void proc_eeprom_mem_init(void); // A_3428 44 | 45 | void reset_macroproc(void); // A_3430 46 | void queue_reset_usb_data(void); // A_3444 47 | void incoming_keybreak(uint8_t keyid); // A_344a 48 | void incoming_keymake(uint8_t keyid); // A_3488 49 | void queue_key(uint8_t unk1, uint8_t hidx); // A_34dc 50 | void empty_key_queue(void); // A_3552 51 | void macro_tick(void); // A_355c 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | 57 | #endif /* defined(_processing_h__) */ 58 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | EEPROM Layout: 2 | ============== 3 | 4 | Address Len Content 5 | 0000 2 "SC" 6 | 0002 2 Length of data area starting... somewhere yet undefined 7 | 0004 1 Settings version 8 | 0005 1 Settings sub-version (must be < 2) 9 | 0006 1 Predefined keyboard layout: 10 | Bits 0..3 : keyboard mode 11 | Bits 4..7: keyboard_codeset; if != 0 12 | (keyboard_codeset << 4) | keyboard_mode 13 | if keyboard_codeset is set, keyboard_mode is overruled: 14 | if keyboard_codeset == 1, keyboard mode is 2 else 1 15 | 0008 ? Start of configuration blocks 16 | 17 | Each configuration block starts with a header: 18 | 0000 1 Length 19 | 0001 1 Type Mask: 20 | Bit 2..0 : type (0=layers 1=remaps 2=macros) 21 | Bit 5..3 : select this is for(?check) 22 | Bit 6 : if set, header is followed by 1 byte bit set of codesets 23 | Bit 7 : if set, header (plus codesets byte if bit 6) 24 | is followed by 2 bytes keyboard ID 25 | 26 | Macro blocks contain a set of macros. Each macro has at least 5 bytes: 27 | 0000 1 HID code this is for 28 | 0001 1 Bit set of modifiers that must be set 29 | 0002 1 Bit set of modifiers that must be set OR clear 30 | (logic not completely understood yet - some additional mangling of upper nibble) 31 | 0003 1 Bit 0..5 : # macro commands for Make 32 | 0004 1 Bit 0..5 : # macro commands for Break 33 | Can contain a flag in bit 7; if set, 34 | the current modifier state is saved before executing the macro and restored afterwards. 35 | Can be suppressed by specifying norestoremeta. 36 | Soarer's scdis v1.10 has a bug here, BTW - it always shows "norestoremeta". 37 | This header is followed by (0003*2) bytes for the Make macro commands 38 | and (0003*2) bytes for the Break macro commands 39 | Each macro command consists of 2 bytes: 40 | 0000 1 macro command 41 | one of the following: 42 | 01 : PRESS 43 | 02 : MAKE 44 | 03 : BREAK 45 | 04 : ASSIGN_META 46 | 05 : SET_META 47 | 06 : CLEAR_META 48 | 07 : TOGGLE_META 49 | 08 : POP_META 50 | 09 : POP_ALL_META 51 | 0A : DELAY 52 | 0B : CLEAR_ALL 53 | 0C : BOOT 54 | 0001 1 argument (HID, modifier or other argument value, like delay in ms) 55 | 56 | Keyboard IDs (http://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html) 57 | ============ 58 | 59 | Keyboards do report an ID as a reply to the command f2. 60 | (An XT keyboard does not reply, an AT keyboard only replies with an ACK.) 61 | An MF2 AT keyboard reports ID ab 83. 62 | 63 | Many short keyboards, like IBM ThinkPads, and Spacesaver keyboards, send ab 84. 64 | 65 | Several 122-key keyboards are reported to send ab 86. 66 | Here translated and untranslated values coincide. 67 | (Reports mention "122-Key Enhanced Keyboard", "standard 122-key keyboard", 68 | "122 Key Mainframe Interactive (MFI) Keyboard", "122-Key Host Connected Keyboard".) 69 | 70 | John Elliott reports on his IBM 1390876 page that this keyboard returns bf bf: 71 | When sent an identify command (0xF2), the keyboard returns the byte sequence 0xBF 0xBF. 72 | However, this can be changed. 73 | On the keyboard PCB is a 12-pin header, marked as 6 pairs of pins (B2-B7). 74 | These correspond to bits 5-0 of the second byte of the keyboard ID. 75 | Shorting a pair of pins sets that bit to zero. 76 | So placing a jumper on the B2 pair will change the keyboard ID to 0xBF 0x9F. 77 | Adjacent to this header is a space on the circuit board for an identical header, 78 | marked as pins A2-A7. 79 | Presumably these would have the same effect on the first byte of the keyboard ID. 80 | 81 | David Monro reports ab 85 for a NCD N-97 keyboard. 82 | 83 | Tim Clarke reports ab 85 (instead of the usual ab 86) 84 | for the "122-Key Host Connect(ed) Keyboard". 85 | He also reports: Also, when playing with my KVM problems Belkin gave me a 86 | 105-key Windows keyboard which Id.s itself as 18ABh. 87 | 88 | Linux 2.5.25 kernel source has 0xaca1 for a "NCD Sun layout keyboard". 89 | It also mentions 0xab02 and 0xab7f, 90 | but these arise as (mistaken) back translations from ab 41 and ab 54. 91 | 92 | Ralph Brown's Interrupt list mentions "old Japanese 'G', 'P', 'A' keyboards", 93 | with keyboard IDs ab 90, ab 91, ab 92. 94 | Here translated and untranslated versions coincide. ID ab 90 was also mentioned above. 95 | -------------------------------------------------------------------------------- /salloc.c: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* salloc.c : Soarer's special(?) memory allocation routines */ 3 | /*****************************************************************************/ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "hwdefs.h" 10 | #include "salloc.h" 11 | 12 | // gleaned from avr-libc's stdlib_private.h 13 | #define STACK_POINTER() ((char *)AVR_STACK_POINTER_REG) 14 | #define HEAP_MARGIN 32 15 | 16 | /*****************************************************************************/ 17 | /* Global data */ 18 | /*****************************************************************************/ 19 | 20 | // provided by avr-gcc 21 | extern char __heap_start; 22 | extern char __heap_end; 23 | 24 | uint16_t data_0x0113 = 0x7fff; // 0x0113 UNUSED? 25 | char *__malloc_heap_end = &__heap_end; // 0x0115 26 | char *__brkval = &__heap_start; // 0x0117 27 | 28 | /*****************************************************************************/ 29 | /* memfree : returns amount of free memory */ 30 | /*****************************************************************************/ 31 | // A_164a 32 | int16_t memfree(void) 33 | { 34 | char *memend = __malloc_heap_end; 35 | if (memend == 0) 36 | memend = STACK_POINTER() - HEAP_MARGIN; 37 | return memend - __brkval; // &A_03ab 38 | } 39 | 40 | /*****************************************************************************/ 41 | /* memalloc : allocate a chunk of memory on the heap */ 42 | /*****************************************************************************/ 43 | // A_1670 44 | char *memalloc(int16_t nelem) 45 | { 46 | char *memend = __malloc_heap_end; 47 | char *retaddr; 48 | 49 | if (!memend) 50 | memend = STACK_POINTER() - HEAP_MARGIN; 51 | if (memend - __brkval < nelem) 52 | return 0; 53 | 54 | retaddr = __brkval; 55 | __brkval += nelem; 56 | return retaddr; 57 | } 58 | 59 | /*****************************************************************************/ 60 | /* memreset : reset memory allocation */ 61 | /*****************************************************************************/ 62 | // A_16b2 63 | char *memreset(void) 64 | { 65 | __brkval = &__heap_start; // 0x0117 = 0x03ab; 66 | return __brkval; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /salloc.h: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* salloc.h : Soarer's special(?) memory allocation routines */ 3 | /*****************************************************************************/ 4 | 5 | #ifndef _salloc_h__ 6 | #define _salloc_h__ 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | int16_t memfree(void); // A_164a 15 | char *memalloc(int16_t nelem); // A_1670 16 | char *memreset(void); // A_16b2 17 | 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif // defined(_salloc_h__) 24 | -------------------------------------------------------------------------------- /soarer.c: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* Soarer.c : reverse-engineered from Soarer's Converter V1.12 */ 3 | /*****************************************************************************/ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "hwdefs.h" 13 | #include "soarer.h" 14 | #include "salloc.h" 15 | #include "usb_comm.h" 16 | #include "print.h" 17 | #include "processing.h" 18 | 19 | /*****************************************************************************/ 20 | /* PS/2 definitions and scan code translation tables */ 21 | /*****************************************************************************/ 22 | 23 | #define INCLUDE_KBD_TRANS_TABLES 24 | #include "kbdtbls.h" 25 | 26 | /*****************************************************************************/ 27 | /* Global data for this module */ 28 | /*****************************************************************************/ 29 | 30 | uint8_t keyboard_codeset = 4; // 0x0100 31 | // a hot candidate for PROGMEM ... 32 | uint8_t const kbd_pauseseq[8] = // 0x0101 pause key definition 33 | { 0xe1, 0x14, 0x77, 0xe1, 0xf0, 0x14, 0xf0, 0x77 }; 34 | uint16_t keyboard_id = 0; // 0x120/0x121 35 | uint8_t kbd_breakcode = 0; // 0x0122 incoming scan code is preceded by BREAK (0xf0) 36 | uint8_t kbd_extended_scancode = 0; // 0x0123 incoming scan code is extended (E0 prefix) 37 | uint8_t kbd_extended2_scancode = 0; // 0x0124 incoming scan code is extended (E1 prefix = Pause) 38 | uint8_t prot_led_state = 0; // 0x0125 protocol / LED state 39 | uint8_t old_aux_key_bits = 0; // 0x0126 40 | uint8_t volatile aux_key_bits = 0; // 0x0127 41 | uint8_t keyboard_mode = 0; // 1 = AT/PS2, 2 = PC/XT, 3/4 forced // 0x0129 42 | uint8_t volatile kbd_rcvd_byte = 0; // 0x012a 43 | uint8_t volatile kbd_rcvd_state = 0; // 0x012b 44 | uint8_t volatile kbdcmd_to_send = 0; // 0x012e 45 | uint8_t volatile data_0x0133 = 0; // 0x0133 46 | uint32_t volatile timer0_counter = 0; // 0x0136 47 | uint16_t onboard_led_counter = 0; // 0x013a 48 | #ifdef OBLED2_CONFIG 49 | uint16_t onboard_led2_counter = 0; 50 | #endif 51 | 52 | /*****************************************************************************/ 53 | /* Necessary prototypes used only in the module */ 54 | /*****************************************************************************/ 55 | 56 | void setup_aux_key_handler(void); // A_0c5c 57 | uint8_t get_aux_key_bits(void); // A_0c92 58 | void setup_timer1(uint16_t counter); // A_0c98 59 | void set_kbd_reset_pin(uint8_t bHigh); // A_0ce2 60 | void disable_extint1(void); // A_0d3e 61 | void enable_extint1_rising(void); // A_0d4a 62 | void init_kbd(void); // A_129a 63 | uint8_t send_kbd_command(uint8_t cmd, uint8_t timeout); // A_133c 64 | uint8_t fetch_kbd_byte(uint8_t *addr, uint8_t timeout); // A_13de 65 | uint8_t get_kbd_byte(uint8_t timeout); // A_1492 66 | uint8_t send_kbd_command_with_parm(uint8_t command, uint8_t cmdparm); // A_14c6 67 | uint8_t send_kbd_command_without_parm(uint8_t command); // A_1538 68 | void act_onboard_led(uint16_t counter); // A_1586 69 | #ifdef OBLED2_CONFIG 70 | void act_onboard_led2(uint16_t counter); 71 | #else 72 | #define act_onboard_led2(a) 73 | #endif 74 | void setup_timer0(void); // A_1592 75 | 76 | /*****************************************************************************/ 77 | /* translate_scancode : translates incoming scan code based on kbd codeset */ 78 | /*****************************************************************************/ 79 | // A_0660 80 | uint8_t translate_scancode(uint8_t scancode, uint8_t bExtended) 81 | { 82 | switch (keyboard_codeset) 83 | { 84 | case 1: 85 | // A_067c 86 | if (scancode < sizeof(kbd_ttbl_set1)) 87 | return pgm_read_byte(kbd_ttbl_set1 + scancode); 88 | break; 89 | case 4: 90 | // A_069c 91 | if (bExtended) 92 | { 93 | if (scancode < sizeof(kbd_ttbl_set2ex)) 94 | return pgm_read_byte(kbd_ttbl_set2ex + scancode); 95 | else 96 | break; 97 | } 98 | // else fall thru to... 99 | case 2: 100 | // A_06b0 101 | if (scancode < sizeof(kbd_ttbl_set2)) 102 | return pgm_read_byte(kbd_ttbl_set2 + scancode); 103 | break; 104 | case 3: 105 | // A_068c 106 | if (scancode < sizeof(kbd_ttbl_set3)) 107 | return pgm_read_byte(kbd_ttbl_set3 + scancode); 108 | break; 109 | } 110 | return 0; 111 | } 112 | 113 | /*****************************************************************************/ 114 | /* reset_kbdinstate : */ 115 | /*****************************************************************************/ 116 | // A_06c4 117 | void reset_kbdinstate(void) 118 | { 119 | reset_macroproc(); 120 | queue_reset_usb_data(); 121 | kbd_breakcode = 0; /* reset state flags */ 122 | kbd_extended_scancode = 0; 123 | kbd_extended2_scancode = 0; 124 | } 125 | 126 | /*****************************************************************************/ 127 | /* set_kbd_leds : sets the Teensy's keyboard LEDs */ 128 | /*****************************************************************************/ 129 | // A_06da 130 | void set_kbd_leds(uint8_t ledbits) 131 | { 132 | if (get_keyboard_protocol()) 133 | LLED_ON(ledbits); 134 | else // if USB host set keybord protocol to 0 135 | LLED_OFF(ledbits); 136 | } 137 | 138 | /*****************************************************************************/ 139 | /* incoming_kbd_breakcode : translates a scan code and passes it on */ 140 | /*****************************************************************************/ 141 | // A_071e 142 | void incoming_kbd_breakcode(uint8_t scancode, uint8_t bExtended) 143 | { 144 | incoming_keybreak(translate_scancode(scancode, bExtended)); 145 | } 146 | 147 | /*****************************************************************************/ 148 | /* incoming_kbd_makecode : translates a scan code and passes it on */ 149 | /*****************************************************************************/ 150 | // A_0724 151 | void incoming_kbd_makecode(uint8_t scancode, uint8_t bExtended) 152 | { 153 | incoming_keymake(translate_scancode(scancode, bExtended)); 154 | } 155 | 156 | /*****************************************************************************/ 157 | /* send_aux_key_changes : if there are changes in the aux key states, send'em*/ 158 | /*****************************************************************************/ 159 | // A_072a 160 | uint8_t send_aux_key_changes(void) 161 | { 162 | uint8_t cur_aux_key_bits = get_aux_key_bits(); 163 | uint8_t chg_aux_key_bits = old_aux_key_bits ^ cur_aux_key_bits; 164 | int8_t i; 165 | 166 | if (!chg_aux_key_bits) 167 | return chg_aux_key_bits; 168 | 169 | // loop from auxkey_id=0xab..0xaf 170 | for (i = 0; i != 6; i++) 171 | { 172 | if ((chg_aux_key_bits >> i) & 1) 173 | { 174 | // internal IDs: $AB..$AF 175 | if ((cur_aux_key_bits >> i) & 1) 176 | //A_0778 177 | incoming_keybreak(KEY_AUX1 + i); 178 | else 179 | // A_0780 180 | incoming_keymake(KEY_AUX1 + i); 181 | } 182 | } 183 | 184 | old_aux_key_bits = cur_aux_key_bits; 185 | return 1; 186 | } 187 | 188 | /*****************************************************************************/ 189 | /* main : main program function */ 190 | /*****************************************************************************/ 191 | // A_07a6 192 | int main(void) 193 | { 194 | uint8_t kbd_reset_pin_reset = 0; // R3 195 | uint8_t keyboard_determined = 0; // R8 196 | uint32_t t0ct_start; // R10-13 197 | uint32_t t0ct_cur; 198 | uint8_t kbd_byte_fetched; 199 | uint8_t newline_after_wait; // R5 200 | uint8_t resend_requested; // R9 201 | uint8_t new_pled_state; // R16 202 | 203 | #if 1 204 | uint8_t fetched_kbd_byte; // R28[1] 205 | #else 206 | // in the original, there's the following code sequence here: 207 | rcall A_07cc ; 0x7cc 208 | A_07cc: 209 | push R0 210 | in R28, SPL 211 | in R29, SPH 212 | // i.e., call yourself and then do it again. 213 | // Presumably means "reserve 4 bytes on stack"... 214 | #endif 215 | 216 | // set for unscaled clock (16MHz on all of the supported configurations) 217 | CPU_PRESCALE(0); 218 | OBLED_CONFIG; 219 | #ifdef OBLED2_CONFIG 220 | OBLED2_CONFIG; 221 | #endif 222 | 223 | set_kbd_leds(0); // init keyboard LEDs to out 224 | set_kbd_leds(7); // set all attached keyboard LEDs on 225 | 226 | setup_timer0(); 227 | proc_eeprom_mem_init(); 228 | init_kbd(); 229 | setup_aux_key_handler(); 230 | reset_kbdinstate(); 231 | set_kbd_reset_pin(0); 232 | 233 | kbd_reset_pin_reset = 0; 234 | keyboard_determined = 0; 235 | resend_requested = 0; 236 | newline_after_wait = 0; 237 | t0ct_start = 0; 238 | 239 | // big fat main loop presumably starts here 240 | // A_080c 241 | while (1) 242 | { 243 | if (!kbd_reset_pin_reset) 244 | { 245 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 246 | t0ct_cur = timer0_counter; 247 | if (t0ct_cur > 500) 248 | { 249 | set_kbd_reset_pin(1); 250 | kbd_reset_pin_reset = 1; 251 | } 252 | } 253 | 254 | // A_0838 255 | if (!keyboard_determined) 256 | { 257 | // A_083e: 258 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 259 | t0ct_cur = timer0_counter; 260 | if (t0ct_cur > 3000) 261 | { 262 | // A_0860 263 | uint8_t forcedtype = get_forced_keyboard_type(); 264 | if (forcedtype & 0x0f) 265 | { 266 | keyboard_codeset = forcedtype >> 4; 267 | if (keyboard_codeset) 268 | { 269 | if (keyboard_codeset == 1) 270 | // A_0878 271 | keyboard_mode = 2; 272 | else 273 | // A_087e 274 | keyboard_mode = 1; 275 | } 276 | else 277 | // A_886 278 | keyboard_mode = forcedtype; 279 | } 280 | else 281 | { 282 | // A_0890 283 | keyboard_codeset = 0; 284 | keyboard_id = 0; 285 | // send echo (kbd is expected to respond with 0xee) 286 | if (send_kbd_command(ATCMD_ECHO, 50) == 2) 287 | { 288 | // A_08a8 289 | get_kbd_byte(50); // get and ignore the response 290 | keyboard_mode = 1; 291 | if (!keyboard_codeset) 292 | { 293 | // A_08bc 294 | // send "Read ID" command (kbd is expected to respond with KBDM_ACK 295 | // followed by 2 bytes ID, 0xab 0x83 being standard PS/2) 296 | // A_08c8 297 | if (send_kbd_command(ATCMD_READID, 50) == 2 && 298 | get_kbd_byte(50) == KBDM_ACK) 299 | { 300 | uint8_t kbdid1 /*R28+2*/, kbdid2 /*R28+3*/; 301 | 302 | // A_08d0 303 | if (fetch_kbd_byte(&kbdid1, 50) == 2) 304 | { 305 | // A_08dc 306 | if (fetch_kbd_byte(&kbdid2, 50) == 2) 307 | { 308 | // A_0900 309 | keyboard_id = ((uint16_t)(kbdid1) << 8) | kbdid2; 310 | // A_08ea 311 | // ABxx is an AT/PS2 variant, except for 312 | // 122-key host-connected keyboard (AB85) 313 | // (this, BTW, also covers the IBM AT keyboard (AB83), 314 | // which is really using codeset 2!) 315 | if (kbdid1 == 0xab && kbdid2 != 0x85) 316 | // A_08f4 317 | keyboard_codeset = 4; 318 | else 319 | // A_08fa 320 | keyboard_codeset = 3; 321 | } 322 | else 323 | { 324 | // A_0916: 325 | keyboard_codeset = 4; 326 | keyboard_id = kbdid1; // high part empty 327 | } 328 | } 329 | else 330 | // A_0924 331 | keyboard_codeset = 2; 332 | } 333 | } 334 | } 335 | else /* seems to be an XT keyboard */ 336 | { 337 | // A_092a 338 | keyboard_mode = 2; 339 | keyboard_codeset = 1; /* so use scan code set 1 */ 340 | } 341 | // A_0934 342 | if (!keyboard_codeset) /* in case of doubt */ 343 | keyboard_codeset = 4; /* treat it as normal PS/2 */ 344 | } 345 | 346 | // This seems to be the area where the EEPROM translation stuff is set up 347 | // A_0940 348 | setup_proc_kbd(keyboard_codeset, keyboard_id); 349 | setup_processing(); 350 | if (keyboard_mode == 2) // if PC/XT keyboard 351 | { 352 | // A_095c 353 | disable_extint1(); // switch to int on rising clock flank 354 | enable_extint1_rising(); 355 | } 356 | // A_0960 357 | if (keyboard_codeset == 3) // tell Terminal keyboards to send Make/Break 358 | // A_0968 359 | send_kbd_command_without_parm(ATCMD_SETAMKBK); 360 | // A_096c 361 | set_kbd_leds(0); // turn off keyboard LEDs 362 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 363 | t0ct_start = timer0_counter; 364 | #if 1 365 | print_P(PSTR("\n\nKeyboard ID: ")); 366 | #else 367 | usb_debug_putchar('\n'); 368 | usb_debug_putchar('\n'); 369 | print_P(PSTR("Keyboard ID: ")); 370 | #endif 371 | phex16(keyboard_id); 372 | #if 1 373 | print_P(PSTR("\nCode Set: ")); 374 | #else 375 | usb_debug_putchar('\n'); 376 | print_P(PSTR("Code Set: ")); 377 | #endif 378 | 379 | #if 1 380 | // 12 bytes less code than the original ... 381 | switch (keyboard_codeset) 382 | { 383 | case 1 : 384 | case 2 : 385 | case 3 : 386 | phex1(keyboard_codeset); 387 | break; 388 | case 4 : 389 | print_P(PSTR("2 (extended)")); 390 | break; 391 | default : 392 | print_P(PSTR("unknown")); 393 | break; 394 | } 395 | #else 396 | if (keyboard_codeset == 2) 397 | // A_09d4 398 | usb_debug_putchar('2'); 399 | else if (keyboard_codeset == 3) 400 | // A_09dc 401 | usb_debug_putchar('3'); 402 | else if (keyboard_codeset == 4) 403 | // A_09e0 404 | print_P(PSTR("2 (extended)")); 405 | else if (keyboard_codeset == 1) 406 | // A_09d0 407 | usb_debug_putchar('1'); 408 | else 409 | // A_09e6 410 | print_P(PSTR("unknown")); 411 | #endif 412 | //A_09ee 413 | if (keyboard_mode == 2) 414 | print_P(PSTR("\nMode: PC/XT\n\n")); 415 | else 416 | print_P(PSTR("\nMode: AT/PS2\n\n")); 417 | // A_0a04 418 | keyboard_determined = 1; 419 | } 420 | } 421 | 422 | // A_0a08: 423 | kbd_byte_fetched = fetch_kbd_byte(&fetched_kbd_byte, 0); 424 | #ifdef OBLED2_CONFIG // little "special" - blink LED2 on each incoming kbd byte 425 | if (kbd_byte_fetched == 2) 426 | act_onboard_led2(10); 427 | #endif 428 | if (keyboard_determined) 429 | { 430 | // A_0a16 431 | if (kbd_byte_fetched >= 2) 432 | { 433 | // A_0a1c 434 | if (kbd_byte_fetched == 2) 435 | { 436 | // A_0a22 437 | if (keyboard_codeset == 1) // if it's a PC/XT keyboard 438 | { 439 | // A_0a2c 440 | if (fetched_kbd_byte != 0xff) // buffer full? 441 | { 442 | // A_0a32 443 | if (fetched_kbd_byte & 0x80) 444 | incoming_kbd_breakcode(fetched_kbd_byte & 0x7f, 0); 445 | else 446 | // A_0a40 447 | incoming_kbd_makecode(fetched_kbd_byte, 0); 448 | } 449 | else 450 | { 451 | // A_0ace 452 | reset_kbdinstate(); 453 | // print_P(PSTR("!BF ")); 454 | act_onboard_led(5000); 455 | } 456 | // goto A_0b08; 457 | } 458 | else // if it's AT / PS/2 459 | { 460 | // A_0a46 461 | if (kbd_extended2_scancode) // if in pause key processing 462 | { 463 | // A_0a4e 464 | if (fetched_kbd_byte == kbd_pauseseq[kbd_extended2_scancode]) 465 | { 466 | // A_0a5c 467 | kbd_extended2_scancode++; 468 | if (kbd_extended2_scancode == 3) 469 | // A_0a68 470 | incoming_kbd_makecode(0x7e, 1); 471 | else if (kbd_extended2_scancode == 8) 472 | { 473 | // A_0a76 474 | // PAUSE has no typematic repeat or break, so treat it as 475 | // "released" once the PAUSE sequence is complete 476 | incoming_kbd_breakcode(0x7e, 1); 477 | kbd_extended2_scancode = 0; 478 | } 479 | } 480 | else 481 | { 482 | // A_0a82 483 | if (kbd_extended2_scancode >= 3) 484 | incoming_kbd_breakcode(0x7e, 1); 485 | kbd_extended2_scancode = 0; 486 | // in this special case, continue examining the incoming code 487 | goto kbdnopause; 488 | } 489 | } 490 | else 491 | { 492 | // A_0a90 493 | kbdnopause: // can't seem to get rid of this (see above) 494 | switch (fetched_kbd_byte) 495 | { 496 | case KBDM_BUFOVR : // Buffer overflow 497 | #if 1 // not in original 498 | case KBDM_BUFOVR2 : // Key detection error or buffer overrun 499 | #endif 500 | // A_0ace 501 | reset_kbdinstate(); 502 | // print_P(PSTR("!BO ")); 503 | act_onboard_led(5000); 504 | break; 505 | case KBDM_BATOK : // BAT finished OK 506 | break; 507 | case KBDM_EXTENDED : // extended scan code? 508 | // A_0ab8 509 | kbd_extended_scancode = 1; 510 | break; 511 | case KBDM_EXTENDED2 : // Pause key sequence start 512 | // A_0ac0: 513 | kbd_extended2_scancode = 1; 514 | break; 515 | #if 1 // not in original 516 | case KBDM_ECHO : // Response to ECHO command 517 | // should never come in... 518 | break; 519 | #endif 520 | case KBDM_BREAK : // break code coming in 521 | // A_0ab0 522 | kbd_breakcode = 1; 523 | break; 524 | #if 1 // not in original 525 | case KBDM_ACK : // Command Acknowledgement 526 | // should never come in... 527 | break; 528 | #endif 529 | case KBDM_ERR : // Keyboard returned an error! 530 | #if 1 // not in original 531 | case KBDM_ERR2 : 532 | #endif 533 | // A_0ac8 534 | // print_P(PSTR("!ER ")); 535 | act_onboard_led(10000); 536 | break; 537 | #if 1 // not in original, but SHOULD be... 538 | case KBDM_RESEND : // Resend last command byte 539 | break; 540 | #endif 541 | default : // any normal key 542 | // A_0ad8: 543 | if (kbd_breakcode) 544 | { 545 | // A_0ae0 546 | incoming_kbd_breakcode(fetched_kbd_byte, kbd_extended_scancode); 547 | kbd_breakcode = 0; 548 | kbd_extended_scancode = 0; 549 | } 550 | else 551 | { 552 | // A_0aee 553 | incoming_kbd_makecode(fetched_kbd_byte, kbd_extended_scancode); 554 | kbd_extended_scancode = 0; 555 | } 556 | break; 557 | } 558 | } 559 | } 560 | 561 | // A_0b08 562 | resend_requested = 0; 563 | } 564 | else // if (kbd_byte_fetched > 2) 565 | { 566 | // A_0afc 567 | send_kbd_command(ATCMD_RESEND, 50); // request resend of last byte 568 | resend_requested = 1; 569 | } 570 | 571 | // A_0b0a 572 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 573 | t0ct_start = timer0_counter; 574 | newline_after_wait = 1; 575 | } 576 | 577 | // A_0b26 578 | else if (!kbd_byte_fetched && !resend_requested) 579 | { 580 | // A_0b32 581 | new_pled_state = (get_keyboard_protocol() << 7) | get_keyboard_leds(); 582 | if (new_pled_state != prot_led_state) 583 | { 584 | // A_0b50 585 | uint8_t num_lock = new_pled_state & 1; 586 | uint8_t caps_lock = (new_pled_state >> 1) & 1; 587 | uint8_t scroll_lock = (new_pled_state >> 2) & 1; 588 | 589 | uint8_t numscrollbits; 590 | // special code for IBM RT PC keyboard with inverted Num/Caps LED pos 591 | if (keyboard_id == KBDID_IBM_RT) 592 | // A_0b7c 593 | numscrollbits = (num_lock << 2) | (caps_lock << 1) | scroll_lock; 594 | else 595 | // A_0b8c: 596 | numscrollbits = (caps_lock << 2) | (num_lock << 1) | scroll_lock; 597 | // A_0b9a: 598 | send_kbd_command_with_parm(ATCMD_SETLEDS, numscrollbits); 599 | set_kbd_leds((scroll_lock << 2) | (num_lock << 1) | caps_lock); 600 | prot_led_state = new_pled_state; 601 | } 602 | } 603 | // A_0c08 604 | if (send_aux_key_changes()) 605 | { 606 | // A_0bb4 607 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 608 | t0ct_start = timer0_counter; 609 | newline_after_wait = 1; 610 | } 611 | } 612 | // A_0bd0: 613 | if (newline_after_wait) 614 | { 615 | // A_0bd4: 616 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 617 | t0ct_cur = timer0_counter; 618 | if (t0ct_cur - t0ct_start >= 50) 619 | { 620 | usb_debug_putchar('\n'); 621 | newline_after_wait = 0; 622 | } 623 | } 624 | rawhid_comm(); 625 | } // end of big fat main loop 626 | } 627 | 628 | /*****************************************************************************/ 629 | /* TIMER3_COMPA_vect : Timer/Counter3 Compare Match A */ 630 | /*****************************************************************************/ 631 | // A_0c10 632 | ISR(TIMER3_COMPA_vect) 633 | { 634 | // ticks once per ms 635 | // aux key bits must be stable for 10ms to be counted 636 | static uint8_t aux_key_timercounter = 10; // 0x0109 637 | static uint8_t tmr_aux_key_bits = 0; // 0x0128 638 | 639 | uint8_t newauxkeys = AUXK_GET; // retrieve new aux key states 640 | if (newauxkeys != tmr_aux_key_bits) 641 | { 642 | tmr_aux_key_bits = newauxkeys; 643 | aux_key_timercounter = 10; 644 | } 645 | if (aux_key_timercounter) 646 | { 647 | if (!--aux_key_timercounter) 648 | aux_key_bits = tmr_aux_key_bits; 649 | } 650 | } 651 | 652 | /*****************************************************************************/ 653 | /* setup_aux_key_handler : sets up timer 3 for aux key checking */ 654 | /*****************************************************************************/ 655 | // A_0c5c 656 | void setup_aux_key_handler(void) 657 | { 658 | AUXK_CONFIG; // setup aux key port 659 | 660 | // Timer 3 ticks once per ms (F_CPU / 64 / 1000 = 250) 661 | TIMSK3 |= (1 << OCIE3A); 662 | OCR3AH = 0; 663 | OCR3AL = 250; 664 | TCCR3A = 0; 665 | TCCR3B = (1 << WGM32); 666 | TCCR3B |= (1 << CS31) | (1 << CS30); 667 | } 668 | 669 | /*****************************************************************************/ 670 | /* get_aux_key_bits : returns current state of the aux keys */ 671 | /*****************************************************************************/ 672 | // A_0c92 673 | uint8_t get_aux_key_bits(void) 674 | { 675 | return aux_key_bits; 676 | } 677 | 678 | /*****************************************************************************/ 679 | /* setup_timer1 : sets up timer/counter 1 for operation */ 680 | /*****************************************************************************/ 681 | // A_0c98 682 | void setup_timer1(uint16_t microseconds) 683 | { 684 | TCCR1B &= ~((1 << CS12)|(1 << CS11)|(1 << CS10)); // set timer 1 prescaler to 0 685 | TIMSK1 &= ~(1 << OCIE1A); // disable Timer/Counter1 Output Compare A Match interrupt 686 | TCNT1H = 0; // reset timer 1 counter 687 | TCNT1L = 0; 688 | TIFR1 = (1 << OCF1A); // clear Timer/Counter1 Output Compare A Match Flag 689 | if (microseconds) 690 | { 691 | // This works nicely at 16MHz, but would have to be changed for other speeds! 692 | microseconds *= 2; 693 | OCR1AH = (microseconds >> 8); // set up output compare value 694 | OCR1AL = (microseconds & 0xff); 695 | TIMSK1 |= (1 << OCIE1A); // enable Timer/Counter1 Output Compare A Match interrupt 696 | // This works nicely at 16MHz, but would have to be changed for other speeds! 697 | TCCR1B |= (1 << CS11); // Timer 1 Clock Source = Clock / 8 698 | } 699 | } 700 | 701 | /*****************************************************************************/ 702 | /* set_kbd_reset_pin : sets up the keyboard reset pin */ 703 | /*****************************************************************************/ 704 | // A_0ce2 705 | void set_kbd_reset_pin(uint8_t bHigh) 706 | { 707 | if (bHigh) 708 | KBDR_HIGH; 709 | else 710 | KBDR_LOW; 711 | } 712 | 713 | /*****************************************************************************/ 714 | /* set_kbd_data_pin : sets the keyboard Data pin */ 715 | /*****************************************************************************/ 716 | // A_0cf2 717 | void set_kbd_data_pin(uint8_t bHigh) 718 | { 719 | if (bHigh) 720 | KBDD_HIGH; 721 | else 722 | KBDD_LOW; 723 | } 724 | 725 | /*****************************************************************************/ 726 | /* set_kbd_clock_pin : sets the clock line and waits for it */ 727 | /*****************************************************************************/ 728 | // A_0d02 729 | uint8_t set_kbd_clock_pin(uint8_t bHigh) 730 | { 731 | uint8_t oldmask = EIMSK; /* remember current ext.int mask */ 732 | uint8_t i; 733 | 734 | EIMSK &= ~(1 << INT1); /* disable ext. interrupt 1 */ 735 | _NOP(); 736 | if (bHigh) /* if we need to set it to 1 */ 737 | // A_0d0e 738 | KBDC_HIGH; 739 | else /* if we need to set it to 0 */ 740 | // A_0d14 741 | KBDC_LOW; 742 | 743 | // A_0d18 744 | // wait until line is stable (?) 745 | for (i = 20; i > 0; i--) /* wait a little bit for it to happen*/ 746 | { 747 | if (KBDC_GET0 == bHigh) 748 | break; 749 | } 750 | // A_0d2c 751 | EIFR = (1 << INTF1); /* clear ext.int.1 interrupt flag */ 752 | if (oldmask & (1 << INT1)) /* if it was enabled before, */ 753 | EIMSK |= (1 << INT1); /* re-enable it */ 754 | else /* otherwise */ 755 | EIMSK &= ~(1 << INT1); /* disable ext.int.1 */ 756 | return EIMSK; /* pass back current ext.int.mask */ 757 | } 758 | 759 | /*****************************************************************************/ 760 | /* disable_extint1 : disable external interrrupt 1 */ 761 | /*****************************************************************************/ 762 | // A_0d3e 763 | void disable_extint1(void) 764 | { 765 | cli(); 766 | EIMSK &= ~(1 << INT1); /* disable ext. interrupt 1 */ 767 | EIFR = (1 << INTF1); /* clear ext.int.1 interrupt flag */ 768 | sei(); 769 | } 770 | 771 | /*****************************************************************************/ 772 | /* enable_extint1_rising : enable external interrupt 1 on RISING edge */ 773 | /*****************************************************************************/ 774 | // A_0d4a 775 | void enable_extint1_rising(void) 776 | { 777 | cli(); 778 | // The rising edge of INTn generates asynchronously an interrupt request. 779 | EICRA |= (1 << ISC11) | (1 << ISC10); /* set up ext. interrupt 1 */ 780 | EIMSK |= (1 << INT1); /* enable ext. interrupt 1 */ 781 | sei(); 782 | } 783 | 784 | /*****************************************************************************/ 785 | /* A_0d5c : */ 786 | /*****************************************************************************/ 787 | // A_0d5c 788 | uint8_t A_0d5c 789 | ( 790 | uint8_t cmode // 0=from IRQ1/init_kbd, 1=timer 1, 2=from send_kbd_command 791 | ) 792 | { 793 | static int8_t data_0x0111 = -1; // 0x0111 794 | static int8_t data_0x0112 = -1; // 0x0112 795 | uint8_t ps2clk; // PS/2 clock line state 796 | 797 | if (cmode) 798 | data_0x0112 = data_0x0111; 799 | ps2clk = KBDC_GET0; /* get PS/2 Clock line */ 800 | 801 | // R24 = data_0x0112; 802 | if (data_0x0112 == -1) 803 | // A_0d7c 804 | data_0x0112 = 1 ^ ps2clk; /* save inverted clock line */ 805 | 806 | // A_0d84 807 | switch (data_0x0112) 808 | { 809 | case 0 : 810 | // A_0d96 811 | if (!ps2clk) 812 | { 813 | // A_0dcc 814 | data_0x0112 = -1; 815 | return 4; 816 | } 817 | // A_0d9a 818 | setup_timer1(90); // set timer1 to 90 microseconds 819 | data_0x0111 = -2; 820 | data_0x0112 = 1; 821 | return 1; 822 | case 1 : 823 | // A_0dae 824 | if (ps2clk) 825 | { 826 | // A_0dcc 827 | data_0x0112 = -1; 828 | return 4; 829 | } 830 | // A_0db2 831 | setup_timer1(1000); // setup timer1 to 1 ms 832 | data_0x0111 = -1; 833 | data_0x0112 = 0; 834 | return 1; 835 | case -2 : 836 | // A_0dc8 837 | data_0x0112 = -1; 838 | return 2; 839 | default : 840 | // A_0d92 841 | return 1; 842 | } 843 | } 844 | 845 | /*****************************************************************************/ 846 | /* pcxt_clockin : called for keyboard mode PC/XT */ 847 | /*****************************************************************************/ 848 | // A_0dd6 849 | void pcxt_clockin(uint8_t timer1) 850 | { 851 | static int8_t read_pcxt_nextstate = -2; // 0x010a 852 | static int8_t read_pcxt_state = 1; // 0x010b 853 | static uint8_t read_pcxt_shiftin = 0; // 0x012c 854 | static uint8_t read_pcxt_bits = 0; // 0x012d 855 | uint8_t b = KBDD_GET0; /* get PD0 (PS/2 Data line) */ 856 | 857 | if (timer1) 858 | // A_0de0 859 | read_pcxt_state = read_pcxt_nextstate; 860 | 861 | // A_0de8 862 | switch (read_pcxt_state) 863 | { 864 | case -2: 865 | // A_0e7c 866 | b = 5; 867 | break; 868 | case 1 : 869 | // A_0e08 870 | read_pcxt_nextstate = -2; 871 | setup_timer1(1200); // setup timer1 to 1.2ms 872 | read_pcxt_bits = 0; 873 | read_pcxt_shiftin = 0; 874 | if (b) 875 | { 876 | // A_0e24 877 | read_pcxt_state = 2; 878 | return; 879 | } 880 | else 881 | b = 6; 882 | break; 883 | case 2 : 884 | // A_0e2c: 885 | read_pcxt_shiftin = (read_pcxt_shiftin >> 1) | (b << 7); // shift in data bit from the left 886 | if (++read_pcxt_bits != 8) 887 | return; 888 | // A_0e4c 889 | read_pcxt_nextstate = 3; 890 | setup_timer1(120); // set timer 1 to 120 microseconds 891 | read_pcxt_state = 3; 892 | return; 893 | case 3 : 894 | // A_0e5e: 895 | setup_timer1(0); 896 | kbd_rcvd_byte = read_pcxt_shiftin; 897 | b = 2; 898 | break; 899 | 900 | default: 901 | return; 902 | } 903 | 904 | // A_0e7e: 905 | setup_timer1(0); 906 | read_pcxt_state = 1; 907 | if (b != 2) 908 | // A_0e70 909 | { 910 | // print_P(PSTR("!RE ")); 911 | act_onboard_led(3000); 912 | } 913 | kbd_rcvd_state = b; 914 | } 915 | 916 | /*****************************************************************************/ 917 | /* atps2_clockout */ 918 | /*****************************************************************************/ 919 | // A_0e94 920 | uint8_t atps2_clockout 921 | ( 922 | uint8_t fromt1 /* flag whether called from timer 1 */ 923 | ) 924 | { 925 | static uint8_t atps2_write_parity = 1; // 0x010c 926 | static int8_t atps2_write_t1state = -1; // 0x010d 927 | static int8_t atps2_write_state = -1; // 0x010e 928 | static uint8_t atps2_write_shiftout = 0; // 0x012f 929 | static int8_t atps2_write_bits = 0; // 0x0130 930 | uint8_t curbit; // R16 931 | uint8_t rc; // R17 932 | 933 | /* To write out a byte, the following has to be done 934 | ( from http://www.computer-engineering.org/ps2protocol/ ) 935 | 1) Bring the Clock line low for at least 100 microseconds. 936 | 2) Bring the Data line low. 937 | 3) Release the Clock line. 938 | 4) Wait for the device to bring the Clock line low. 939 | 5) Set/reset the Data line to send the first data bit 940 | 6) Wait for the device to bring Clock high. 941 | 7) Wait for the device to bring Clock low. 942 | 8) Repeat steps 5-7 for the other seven data bits and the parity bit 943 | 9) Release the Data line. 944 | 10) Wait for the device to bring Data low. 945 | 11) Wait for the device to bring Clock low. 946 | 12) Wait for the device to release Data and Clock 947 | */ 948 | 949 | if (atps2_write_state == -1) // setup to state 2 950 | atps2_write_state = 2; 951 | if (fromt1) // if coming from timer, switch to t1 state 952 | atps2_write_state = atps2_write_t1state; 953 | 954 | switch (atps2_write_state) 955 | { 956 | // Obviously, no states 0/1 in this one... 957 | // Has encoded the expected clock line state in bit 0 958 | case 2: 959 | // 1) Bring clock line low and wait for 200microseconds 960 | // A_0f0a 961 | atps2_write_shiftout = kbdcmd_to_send; 962 | atps2_write_bits = 8; 963 | atps2_write_parity = 1; 964 | atps2_write_t1state = 3; 965 | setup_timer1(200); // setup timer1 to 0.2ms 966 | set_kbd_clock_pin(0); 967 | break; 968 | case 3 : 969 | // 2) Bring data line low 970 | // 3) release the clock line 971 | // 4) wait up to 20ms for the device to bring the lock line low 972 | // A_0f30 973 | set_kbd_data_pin(0); 974 | set_kbd_clock_pin(1); 975 | atps2_write_t1state = -2; 976 | setup_timer1(20000); // setup timer1 to 20ms 977 | // fall thru to... 978 | case 4 : 979 | // A_0f44 980 | // Expect clock line to be high after request start 981 | atps2_write_state = 5; 982 | break; 983 | case 5 : 984 | // Send one of the 8 data bits 985 | // A_0f48 986 | curbit = atps2_write_shiftout & 1; 987 | set_kbd_data_pin(curbit); 988 | atps2_write_shiftout >>= 1; 989 | atps2_write_parity ^= curbit; 990 | if (--atps2_write_bits) 991 | atps2_write_state = 4; 992 | else 993 | atps2_write_state = 6; 994 | break; 995 | case 6 : 996 | // Expect clock line to be high after one of the data bits 997 | // A_0f7a 998 | atps2_write_state = 7; 999 | break; 1000 | case 7: 1001 | // 8) send out the parity bit 1002 | // A_0f7e 1003 | set_kbd_data_pin(atps2_write_parity); 1004 | atps2_write_bits--; 1005 | atps2_write_state = 8; 1006 | break; 1007 | case 8 : 1008 | // Expect clock line to be high after the parity bit 1009 | // A_0f92 1010 | atps2_write_state = 9; 1011 | break; 1012 | case 9 : 1013 | // 9) Release data line 1014 | // A_0f96 1015 | set_kbd_data_pin(1); 1016 | atps2_write_bits--; 1017 | atps2_write_state = 10; 1018 | break; 1019 | case 10 : 1020 | // Expect clock line to be high after 9) 1021 | // A_0fa8 1022 | atps2_write_state = 11; 1023 | break; 1024 | case 11 : 1025 | // sending done 1026 | // A_0fb0 1027 | setup_timer1(0); // reset timeout counter 1028 | if (KBDD_GET0) // data line is expected to be low now 1029 | rc = 9; 1030 | else 1031 | rc = 2; 1032 | // A_0fcc 1033 | set_kbd_data_pin(1); // release data line 1034 | atps2_write_state = -1; 1035 | #if 0 1036 | usb_debug_putchar('>'); 1037 | phex(rc); 1038 | usb_debug_putchar(' '); 1039 | #endif 1040 | return rc; 1041 | case -2 : 1042 | // A_0fbe 1043 | // Something has gone wrong; the operation timed out 1044 | // atps2_write_bits is anything between 8 and -2 (0xfe) 1045 | rc = (atps2_write_bits << 4) | 0x05; 1046 | if (rc >= 2) // that is totally, totally BS IMO, since it's either <0 or >=5 1047 | { 1048 | set_kbd_data_pin(1); // release data line 1049 | atps2_write_state = -1; 1050 | return rc; 1051 | } 1052 | break; 1053 | } 1054 | 1055 | // A_0fd8 1056 | if (KBDC_GET0 == ((uint8_t)atps2_write_state & 1)) 1057 | return 1; 1058 | else 1059 | { 1060 | // A_0ff8 1061 | set_kbd_data_pin(1); 1062 | atps2_write_state = -1; 1063 | // print_P(PSTR("!WC ")); 1064 | act_onboard_led(3000); 1065 | return 4; 1066 | } 1067 | } 1068 | 1069 | /*****************************************************************************/ 1070 | /* atps2_clockin : clock line transition from high to low or timer 1 */ 1071 | /*****************************************************************************/ 1072 | // A_1016 1073 | uint8_t atps2_clockin(uint8_t bReset) 1074 | { 1075 | static uint8_t read_atps2_parity = 1; // 0x010f 1076 | static int8_t read_atps2_state = -1; // 0x0110 1077 | static uint8_t read_atps2_shiftin = 0; // 0x0131 1078 | static uint8_t read_atps2_bits = 0; // 0x0132 1079 | uint8_t ps2clk = KBDC_GET0; // R15 1080 | uint8_t ps2data = KBDD_GET0; // R16 PS/2 data line 1081 | 1082 | /* AT / PS/2 read logic 1083 | ( from http://www.computer-engineering.org/ps2protocol/ ) 1084 | 1085 | Bus idle state is high. When the keyboard wants to send information, 1086 | it first checks the Clock line to make sure it's at a high logic level. 1087 | If it's not, the host is inhibiting communication and the device must 1088 | buffer any to-be-sent data until the host releases Clock. 1089 | The Clock line must be continuously high for at least 50 microseconds 1090 | before the device can begin to transmit its data. 1091 | 1092 | The keyboard uses a serial protocol with 11-bit frames. These bits are: 1093 | 1094 | 1 start bit. This is always 0. 1095 | 8 data bits, least significant bit first. 1096 | 1 parity bit (odd parity). 1097 | 1 stop bit. This is always 1. 1098 | 1099 | The keyboard/mouse writes a bit on the Data line when Clock is high, 1100 | and it is read by the host when Clock is low. 1101 | 1102 | */ 1103 | 1104 | if (bReset) 1105 | { 1106 | read_atps2_state = -1; 1107 | return 5; 1108 | } 1109 | // A_102e 1110 | if (read_atps2_state == -1) 1111 | read_atps2_state = 1; 1112 | 1113 | // A_103c 1114 | //ps2data = KBDD_GET0; // PS/2 Data line 1115 | 1116 | switch (read_atps2_state) 1117 | { 1118 | case 1 : 1119 | // A_106c 1120 | setup_timer1(1200); // setup timer1 to 1.2ms 1121 | read_atps2_bits = 0; 1122 | read_atps2_shiftin = 0; 1123 | read_atps2_parity = 1; 1124 | if (ps2data) 1125 | { 1126 | // A_1132 1127 | setup_timer1(0); 1128 | read_atps2_state = -1; 1129 | return 6; 1130 | } 1131 | read_atps2_state = 4; 1132 | break; 1133 | case 4 : 1134 | // A_1086 1135 | read_atps2_state = 5; 1136 | break; 1137 | case 5 : 1138 | // A_108a 1139 | read_atps2_shiftin = (ps2data << 7) | (read_atps2_shiftin >> 1); // shift in new bit 1140 | read_atps2_parity ^= ps2data; 1141 | if (++read_atps2_bits == 8) 1142 | read_atps2_state = 6; 1143 | else 1144 | read_atps2_state = 4; 1145 | break; 1146 | case 6 : 1147 | // A_10c2 1148 | read_atps2_state = 7; 1149 | break; 1150 | case 7 : 1151 | // A_10c6 1152 | if (read_atps2_parity != ps2data) 1153 | { 1154 | // A_1132: 1155 | setup_timer1(0); 1156 | read_atps2_state = -1; 1157 | return 7; 1158 | } 1159 | read_atps2_state = 8; 1160 | break; 1161 | case 8 : 1162 | // A_10d6 1163 | read_atps2_state = 9; 1164 | break; 1165 | case 9 : 1166 | // A_10da 1167 | if (ps2data) 1168 | { 1169 | kbd_rcvd_byte = read_atps2_shiftin; 1170 | keyboard_mode = 1; 1171 | setup_timer1(0); 1172 | read_atps2_state = -1; 1173 | return 2; 1174 | } 1175 | else 1176 | { 1177 | // A_10f0 1178 | // print_P(PSTR("!DL ")); 1179 | act_onboard_led(3000); 1180 | setup_timer1(0); 1181 | read_atps2_state = -1; 1182 | return 8; 1183 | } 1184 | break; 1185 | } 1186 | 1187 | // A_10fa 1188 | if ((uint8_t)(read_atps2_state & 1) == ps2clk) 1189 | return 1; 1190 | else 1191 | { 1192 | // A_111a 1193 | read_atps2_state = -1; 1194 | // print_P(PSTR("!CE ")); 1195 | act_onboard_led(3000); 1196 | return 4; 1197 | } 1198 | } 1199 | 1200 | /*****************************************************************************/ 1201 | /* atps2_clock : called for keyboard modes 1,3,4 */ 1202 | /*****************************************************************************/ 1203 | // A_1142 1204 | void atps2_clock 1205 | ( 1206 | uint8_t cmode // 0=from IRQ1/init_kbd, 1=timed out, 2=from send_kbd_command 1207 | ) 1208 | { 1209 | static uint8_t data_0x0134 = 0; // 0x0134 1210 | static uint8_t data_0x0135 = 0; // 0x0135 1211 | uint8_t b; // little helper 1212 | 1213 | if (cmode == 2) // if called from send_kbd_command 1214 | { 1215 | if (keyboard_mode == 2) 1216 | { 1217 | data_0x0133 = 3; 1218 | return; 1219 | } 1220 | // A_1162 1221 | if (data_0x0135 == 1) 1222 | { 1223 | data_0x0135 = 3; 1224 | if (data_0x0133) 1225 | { 1226 | // print_P(PSTR("!X1 ")); 1227 | act_onboard_led(3000); 1228 | } 1229 | // A_117e 1230 | data_0x0133 = 1; 1231 | cmode = 0; 1232 | } 1233 | else 1234 | { 1235 | // A_1188 1236 | data_0x0134 = 1; 1237 | return; 1238 | } 1239 | } 1240 | 1241 | // A_1190 1242 | // R15 = 1; 1243 | // R13 = 2; 1244 | // R14 = 3; 1245 | 1246 | // A_119c 1247 | while (1) 1248 | { 1249 | switch (data_0x0135) 1250 | { 1251 | case 0 : 1252 | // A_11b4 1253 | b = A_0d5c(cmode); 1254 | if (b < 2) 1255 | return; 1256 | // A_11be 1257 | else if (b == 2) 1258 | { 1259 | // A_11c2 1260 | if (data_0x0134 != 0) 1261 | { 1262 | data_0x0134 = 0; 1263 | if (data_0x0133 != 0) 1264 | { 1265 | // print_P(PSTR("!X2 ")); 1266 | act_onboard_led(3000); 1267 | } 1268 | // A_11dc 1269 | data_0x0133 = 1; 1270 | data_0x0135 = 3; 1271 | cmode = 0; 1272 | } 1273 | else 1274 | { 1275 | // A_11e8 1276 | data_0x0135 = 1; 1277 | return; 1278 | } 1279 | } 1280 | break; 1281 | case 1 : 1282 | // A_11f0 1283 | if (KBDC_GET) // if PS/2 Clock line high 1284 | data_0x0135 = 0; 1285 | else 1286 | { 1287 | if (data_0x0133 != 0) 1288 | { 1289 | // print_P(PSTR("!X3 ")); 1290 | act_onboard_led(3000); 1291 | } 1292 | // A_1202 1293 | kbd_rcvd_state = 1; 1294 | data_0x0135 = 2; 1295 | } 1296 | break; 1297 | case 2 : 1298 | // A_120c 1299 | b = atps2_clockin(cmode); 1300 | if (b < 2) 1301 | return; 1302 | else if (b != 2) 1303 | { 1304 | // print_P(PSTR("!X4 ")); 1305 | act_onboard_led(3000); 1306 | } 1307 | // A_1220 1308 | kbd_rcvd_state = b; 1309 | data_0x0135 = 0; 1310 | break; 1311 | case 3 : 1312 | // A_1226 1313 | b = atps2_clockout(cmode); 1314 | if (b < 2) 1315 | return; 1316 | data_0x0133 = b; 1317 | data_0x0135 = 0; 1318 | break; 1319 | default : 1320 | return; 1321 | } 1322 | } 1323 | } 1324 | 1325 | /*****************************************************************************/ 1326 | /* INT1_vect : external interrupt request 1 */ 1327 | /*****************************************************************************/ 1328 | // A_1244 1329 | ISR(INT1_vect) 1330 | { 1331 | if (keyboard_mode == 2) /* if PC/XT keyboard attached */ 1332 | pcxt_clockin(0); 1333 | else /* if AT / PS/2 keyboard attached */ 1334 | atps2_clock(0); 1335 | } 1336 | 1337 | /*****************************************************************************/ 1338 | /* init_kbd : initializes external keyboard handling */ 1339 | /*****************************************************************************/ 1340 | // A_129a 1341 | void init_kbd(void) 1342 | { 1343 | cli(); /* disable interrupts */ 1344 | set_kbd_clock_pin(1); 1345 | set_kbd_data_pin(1); 1346 | TCCR1A = 0; // normal port operation 1347 | TCCR1B = (1 << WGM12); // Timer/Counter mode CTC 1348 | // The falling edge of INT1 generates asynchronously an interrupt request 1349 | EICRA = (EICRA & ~((1 << ISC11) | (1 << ISC10))) | (1 << ISC10); 1350 | // Allow External Interrupt 1 1351 | EIMSK |= (1 << INT1); 1352 | atps2_clock(0); 1353 | sei(); /* allow interrupts */ 1354 | } 1355 | 1356 | /*****************************************************************************/ 1357 | /* TIMER1_COMPA_vect : Timer/Counter1 Compare Match A */ 1358 | /*****************************************************************************/ 1359 | // A_12c4 1360 | ISR(TIMER1_COMPA_vect) 1361 | { 1362 | TCCR1B &= ~((1 << COM1C0) | (1 << WGM11) | (1 << WGM10)); 1363 | TIMSK1 &= ~(1 << OCIE1A); 1364 | _NOP(); 1365 | TCNT1H = 0; 1366 | TCNT1L = 0; 1367 | TIFR1 = (1 << OCF1A); 1368 | if (keyboard_mode == 2) /* if PC / XT keyboard attached */ 1369 | pcxt_clockin(1); 1370 | else /* if AT / PS/2 keyboard attached */ 1371 | atps2_clock(1); 1372 | } 1373 | 1374 | /*****************************************************************************/ 1375 | /* send_kbd_command : */ 1376 | /*****************************************************************************/ 1377 | // A_133c 1378 | uint8_t send_kbd_command(uint8_t cmd /*R24*/, uint8_t timeout/*R22*/) 1379 | { 1380 | uint32_t startcounter; // R14-17 1381 | uint8_t ret; 1382 | 1383 | if (keyboard_mode == 2) // not possible on PC/XT keyboards 1384 | return 0; 1385 | 1386 | act_onboard_led2(10); // little "special" - blink LED2 on each outgoing kbd byte 1387 | 1388 | // A1356 1389 | usb_debug_putchar('w'); 1390 | phex(cmd); 1391 | usb_debug_putchar(' '); 1392 | // A_1362 1393 | cli(); 1394 | kbdcmd_to_send = cmd; 1395 | data_0x0133 = 0; 1396 | atps2_clock(2); 1397 | sei(); 1398 | 1399 | // A_1372 1400 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 1401 | startcounter = timer0_counter; 1402 | 1403 | // A_13c2 1404 | while (data_0x0133 < 2) 1405 | { 1406 | if (timeout) 1407 | { 1408 | uint32_t now; 1409 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 1410 | now = timer0_counter; 1411 | // A_1392 1412 | if (now - startcounter > timeout) 1413 | return 10; 1414 | } 1415 | } 1416 | 1417 | // A_13ca 1418 | ret = data_0x0133; 1419 | data_0x0133 = 0; 1420 | return ret; 1421 | } 1422 | 1423 | /*****************************************************************************/ 1424 | /* fetch_kbd_byte : fetches a byte from PS/2 data line with timeout */ 1425 | /*****************************************************************************/ 1426 | // A_13de 1427 | uint8_t fetch_kbd_byte(uint8_t *addr, uint8_t timeout) 1428 | { 1429 | uint8_t b; // R13 1430 | uint32_t startcounter; 1431 | 1432 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 1433 | startcounter = timer0_counter; 1434 | 1435 | b = kbd_rcvd_state; 1436 | if (timeout) 1437 | { 1438 | while (b < 2) 1439 | { 1440 | uint32_t now; 1441 | ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 1442 | now = timer0_counter; 1443 | if (now - startcounter > timeout) 1444 | return b; 1445 | b = kbd_rcvd_state; 1446 | } 1447 | } 1448 | // A_144c 1449 | else if (b < 2) 1450 | return b; 1451 | 1452 | // A_1452 1453 | kbd_rcvd_state = 0; 1454 | if (b == 2) 1455 | { 1456 | usb_debug_putchar('r'); 1457 | phex(kbd_rcvd_byte); 1458 | usb_debug_putchar(' '); 1459 | if (addr) 1460 | *addr = kbd_rcvd_byte; 1461 | } 1462 | else 1463 | { 1464 | usb_debug_putchar('R'); 1465 | phex(b); 1466 | usb_debug_putchar(' '); 1467 | } 1468 | 1469 | return b; 1470 | } 1471 | 1472 | /*****************************************************************************/ 1473 | /* get_kbd_byte */ 1474 | /*****************************************************************************/ 1475 | // A_1492 1476 | uint8_t get_kbd_byte(uint8_t timeout) 1477 | { 1478 | uint8_t kbdbyte; // allocated on stack 1479 | uint8_t ret = fetch_kbd_byte(&kbdbyte, timeout); 1480 | if (ret != 2) 1481 | { 1482 | kbdbyte = 0; 1483 | usb_debug_putchar('R'); 1484 | usb_debug_putchar('1'); 1485 | phex(ret); 1486 | } 1487 | return kbdbyte; 1488 | } 1489 | 1490 | /*****************************************************************************/ 1491 | /* send_kbd_command_with_parm : sends a squence of 2 commands with ACK wait */ 1492 | /*****************************************************************************/ 1493 | // A_14c6 1494 | uint8_t send_kbd_command_with_parm(uint8_t command, uint8_t cmdparm) 1495 | { 1496 | uint8_t i; 1497 | uint8_t rc; 1498 | 1499 | if (keyboard_mode == 2) 1500 | return 0; 1501 | // A_14da: 1502 | for (i = 3; i > 0; i--) /* 3 tries */ 1503 | { 1504 | rc = send_kbd_command(command, 50); 1505 | if (rc == 2) 1506 | { 1507 | // A_14e8 1508 | rc = get_kbd_byte(50); 1509 | if (rc == KBDM_ACK) // if not an ACK 1510 | { 1511 | // A_14f2 1512 | rc = send_kbd_command(cmdparm, 50); 1513 | if (rc == 2) 1514 | { 1515 | // A_14fe 1516 | rc = get_kbd_byte(50); 1517 | if (rc == KBDM_ACK) 1518 | // A_1508 1519 | return 1; 1520 | else 1521 | { 1522 | // A_150c: 1523 | usb_debug_putchar('!'); 1524 | usb_debug_putchar('!'); 1525 | } 1526 | } 1527 | else 1528 | { 1529 | // A_1514 1530 | usb_debug_putchar('W'); 1531 | usb_debug_putchar('2'); 1532 | } 1533 | } 1534 | else 1535 | { 1536 | // A_150c: 1537 | usb_debug_putchar('!'); 1538 | usb_debug_putchar('!'); 1539 | } 1540 | } 1541 | else 1542 | { 1543 | // A_151c: 1544 | usb_debug_putchar('W'); 1545 | usb_debug_putchar('1'); 1546 | } 1547 | 1548 | // A_1524: 1549 | phex(rc); 1550 | } 1551 | return 0; 1552 | } 1553 | 1554 | /*****************************************************************************/ 1555 | /* send_kbd_command_without_parm : sends a single-byte AT/PS2 command */ 1556 | /*****************************************************************************/ 1557 | // A_1538 1558 | uint8_t send_kbd_command_without_parm(uint8_t command) 1559 | { 1560 | // R15 = command; 1561 | uint8_t i; // R16; 1562 | uint8_t rc; // R17; 1563 | if (keyboard_mode == 2) /* not for PC / XT keyboards */ 1564 | return 0; 1565 | 1566 | for (i = 3; i > 0; i--) 1567 | { 1568 | // A_154a: 1569 | rc = send_kbd_command(command, 50); 1570 | if (rc == 2) 1571 | { 1572 | // A_1556 1573 | rc = get_kbd_byte(50); 1574 | if (rc == KBDM_ACK) 1575 | return 1; 1576 | else 1577 | { 1578 | // A_1564 1579 | usb_debug_putchar('!'); 1580 | usb_debug_putchar('!'); 1581 | } 1582 | } 1583 | else 1584 | { 1585 | // A_156c 1586 | usb_debug_putchar('W'); 1587 | usb_debug_putchar('0'); 1588 | } 1589 | // A_1574 1590 | phex(rc); 1591 | } 1592 | 1593 | return 0; 1594 | } 1595 | 1596 | /*****************************************************************************/ 1597 | /* act_onboard_led : turns on the onboard LED */ 1598 | /*****************************************************************************/ 1599 | // A_1586 1600 | void act_onboard_led(uint16_t counter) 1601 | { 1602 | onboard_led_counter = counter; 1603 | OBLED_ON; 1604 | } 1605 | 1606 | /*****************************************************************************/ 1607 | /* act_onboard_led2 : turns on the onboard LED 2 */ 1608 | /*****************************************************************************/ 1609 | #ifdef OBLED2_CONFIG 1610 | void act_onboard_led2(uint16_t counter) 1611 | { 1612 | onboard_led2_counter = counter; 1613 | OBLED2_ON; 1614 | } 1615 | #endif 1616 | 1617 | /*****************************************************************************/ 1618 | /* setup_timer0 : */ 1619 | /*****************************************************************************/ 1620 | // A_1592 1621 | void setup_timer0(void) 1622 | { 1623 | TIMSK0 |= (1 << OCIE0A); // Enable Compare/Match A Interrupt 1624 | // (F_CPU / 64) / 1000 for 16MHz 1625 | OCR0A = 250; // With Prescaler/64, this gives 1 tick per ms 1626 | TCCR0A = (1 << WGM01); // Clear Timer on Compare Match mode 1627 | TCCR0B = 0; // Stop Timer 0 1628 | // Run Timer 0 with Prescaler/64 1629 | TCCR0B |= ((1 << CS00) | (1 << CS01)); 1630 | } 1631 | 1632 | /*****************************************************************************/ 1633 | /* TIMER0_COMPA_vect : Timer/Counter0 Compare Match A */ 1634 | /*****************************************************************************/ 1635 | // A_15ae 1636 | ISR(TIMER0_COMPA_vect) 1637 | { 1638 | // Ticks once per ms 1639 | static uint8_t volatile in_macro_tick = 0; // 0x013c recursion protection 1640 | 1641 | timer0_counter++; 1642 | // A_15f6 1643 | if (onboard_led_counter) 1644 | onboard_led_counter--; 1645 | else 1646 | OBLED_OFF; /* turn off onboard LED */ 1647 | 1648 | #ifdef OBLED2_CONFIG 1649 | if (onboard_led2_counter) 1650 | onboard_led2_counter--; 1651 | else 1652 | OBLED2_OFF; /* turn off onboard LED 2 */ 1653 | #endif 1654 | 1655 | // A_1610 1656 | if (in_macro_tick == 0) 1657 | { 1658 | in_macro_tick = 1; 1659 | sei(); 1660 | macro_tick(); 1661 | in_macro_tick = 0; 1662 | } 1663 | } 1664 | -------------------------------------------------------------------------------- /soarer.h: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* Soarer.h : main routine and support functions */ 3 | /*****************************************************************************/ 4 | 5 | #ifndef _soarer_h_ 6 | #define _soarer_h_ 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | extern uint32_t volatile timer0_counter; // 0x0136 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | 20 | #endif // defined _soarer_h_ 21 | -------------------------------------------------------------------------------- /usb_comm.h: -------------------------------------------------------------------------------- 1 | /*****************************************************************************/ 2 | /* usb_comm.h : USB communication handling for hardware USB AVRs */ 3 | /*****************************************************************************/ 4 | 5 | #ifndef _usb_comm_h__ 6 | #define _usb_comm_h__ 7 | 8 | #include 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | extern uint8_t keyboard_protocol; // 0x0119 15 | extern uint8_t volatile usb_suspended; // 0x013d 16 | extern uint8_t volatile usb_resuming; // 0x013e 17 | extern uint8_t keyboard_modifier_keys; // 0x0140 18 | extern uint8_t volatile keyboard_leds; // 0x0141 19 | 20 | 21 | uint8_t reset_usb_keyboard_data(void); // A_16c0 22 | void usb_init(void); // A_16ee // initialize everything 23 | void usb_remote_wakeup(void); // A_172a 24 | uint8_t usb_keyboard_press(uint8_t keyid); // A_174c 25 | uint8_t usb_keyboard_release(uint8_t keyid); // A_1848 26 | uint8_t usb_keyboard_send(uint8_t flagset); // A_192e 27 | int8_t usb_debug_putchar(uint8_t c); // A_1a62 // transmit a character 28 | 29 | int8_t usb_rawhid_recv(uint8_t *buffer, uint8_t timeout); // A_2254 30 | int8_t usb_rawhid_send(const uint8_t *buffer, uint8_t timeout); // A_22b0 31 | 32 | uint8_t usb_configured(void); // is the USB port configured 33 | void usb_debug_flush_output(void); // immediately transmit any buffered output 34 | 35 | #define USB_DEBUG_HID 36 | 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | 41 | #endif /* defined(_usb_comm_h__) */ 42 | --------------------------------------------------------------------------------