]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - converter/xt_usb/matrix.c
473151cb32248d21e74e338851ef00e123ee15e0
[max/tmk_keyboard.git] / converter / xt_usb / matrix.c
1 /*
2 Copyright 2011 Jun Wako <wakojun@gmail.com>
3 Copyright 2016 Ethan Apodaca <papodaca@gmail.com>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <stdint.h>
20 #include <stdbool.h>
21 #include "action.h"
22 #include "print.h"
23 #include "util.h"
24 #include "debug.h"
25 #include "xt.h"
26 #include "matrix.h"
27
28
29 static void matrix_make(uint8_t code);
30 static void matrix_break(uint8_t code);
31
32 static uint8_t matrix[MATRIX_ROWS];
33 #define ROW(code)      (code>>3)
34 #define COL(code)      (code&0x07)
35
36
37 void matrix_init(void)
38 {
39     debug_enable = true;
40     xt_host_init();
41
42     // initialize matrix state: all keys off
43     for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
44
45     return;
46 }
47
48 // convert E0-escaped codes into unused area
49 static uint8_t move_e0code(uint8_t code) {
50     switch(code) {
51         // Original IBM XT keyboard has these keys
52         case 0x37: return 0x54; // Print Screen
53         case 0x46: return 0x55; // Ctrl + Pause
54         case 0x1C: return 0x6F; // Keypad Enter
55         case 0x35: return 0x7F; // Keypad /
56
57         // Any XT keyobard with these keys?
58         // http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
59         // https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
60         case 0x5B: return 0x5A; // Left  GUI
61         case 0x5C: return 0x5B; // Right GUI
62         case 0x5D: return 0x5C; // Application
63         case 0x5E: return 0x5D; // Power(not used)
64         case 0x5F: return 0x5E; // Sleep(not used)
65         case 0x63: return 0x5F; // Wake (not used)
66         case 0x48: return 0x60; // Up
67         case 0x4B: return 0x61; // Left
68         case 0x50: return 0x62; // Down
69         case 0x4D: return 0x63; // Right
70         case 0x52: return 0x71; // Insert
71         case 0x53: return 0x72; // Delete
72         case 0x47: return 0x74; // Home
73         case 0x4F: return 0x75; // End
74         case 0x49: return 0x77; // Home
75         case 0x51: return 0x78; // End
76         case 0x1D: return 0x7A; // Right Ctrl
77         case 0x38: return 0x7C; // Right Alt
78     }
79     return code;
80 }
81
82 uint8_t matrix_scan(void)
83 {
84     static enum {
85         INIT,
86         E0,
87         // Pause: E1 1D 45, E1 9D C5
88         E1,
89         E1_1D,
90         E1_9D,
91     } state = INIT;
92
93     uint8_t code = xt_host_recv();
94     if (!code) return 0;
95     xprintf("%02X ", code);
96     switch (state) {
97         case INIT:
98             switch (code) {
99                 case 0xE0:
100                     state = E0;
101                     break;
102                 case 0xE1:
103                     state = E1;
104                     break;
105                 default:
106                     if (code < 0x80)
107                         matrix_make(code);
108                     else
109                         matrix_break(code & 0x7F);
110                     break;
111             }
112             break;
113         case E0:
114             switch (code) {
115                 case 0x2A:
116                 case 0xAA:
117                 case 0x36:
118                 case 0xB6:
119                     //ignore fake shift
120                     state = INIT;
121                     break;
122                 default:
123                     if (code < 0x80)
124                         matrix_make(move_e0code(code));
125                     else
126                         matrix_break(move_e0code(code & 0x7F));
127                     state = INIT;
128                     break;
129             }
130             break;
131         case E1:
132             switch (code) {
133                 case 0x1D:
134                     state = E1_1D;
135                     break;
136                 case 0x9D:
137                     state = E1_9D;
138                     break;
139                 default:
140                     state = INIT;
141                     break;
142             }
143             break;
144         case E1_1D:
145             switch (code) {
146                 case 0x45:
147                     matrix_make(0x55);
148                     break;
149                 default:
150                     state = INIT;
151                     break;
152             }
153             break;
154         case E1_9D:
155             switch (code) {
156                 case 0x45:
157                     matrix_break(0x55);
158                     break;
159                 default:
160                     state = INIT;
161                     break;
162             }
163             break;
164         default:
165             state = INIT;
166     }
167     return 1;
168 }
169
170 inline
171 uint8_t matrix_get_row(uint8_t row)
172 {
173     return matrix[row];
174 }
175
176 inline
177 static void matrix_make(uint8_t code)
178 {
179     if (!matrix_is_on(ROW(code), COL(code))) {
180         matrix[ROW(code)] |= 1<<COL(code);
181     }
182 }
183
184 inline
185 static void matrix_break(uint8_t code)
186 {
187     if (matrix_is_on(ROW(code), COL(code))) {
188         matrix[ROW(code)] &= ~(1<<COL(code));
189     }
190 }
191
192 void matrix_clear(void)
193 {
194     for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
195 }
196
197 /*
198 XT Scancodes
199 ============
200 - http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
201 - https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
202
203 01-53: Normal codes used in original XT keyboard
204 54-7F: Not used in original XT keyboard
205
206         0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
207     50  -   -   -   -   *   *   x   x   x   x   *   *   *   *   *   *
208     60  *   *   *   *   x   x   x   x   x   x   x   x   x   x   x   *
209     70  x   *   *   x   *   *   x   *   *   x   *   x   *   x   x   *
210
211 -: codes existed in original XT keyboard
212 *: E0-escaped codes converted into unused code area(internal use in TMK)
213 x: Non-espcaped codes(not used in real keyboards probably, for CodeSet2-CodeSet1 translation purpose)
214
215 Usage in TMK:
216
217     00  reserved*
218     54  PrintScr*
219     55  Pause*
220     56  Euro2
221     57  F11
222     58  F12
223     59  Keypad =
224     5A  LGUI*
225     5B  RGUI*
226     5C  APP*
227     5D  reserved*
228     5E  reserved*
229     5F  reserved*
230     60  cursor*
231     61  cursor*
232     62  cursor*
233     63  cursor*
234     64  F13
235     65  F14
236     66  F15
237     67  F16
238     68  F17
239     69  F18
240     6A  F19
241     6B  F20
242     6C  F21
243     6D  F22
244     6E  F23
245     6F  Keypad Enter*
246     70  KANA
247     71  nav*
248     72  nav*
249     73  RO
250     74  nav*
251     75  nav*
252     76  F24
253     77  nav*
254     78  nav*
255     79  HENKAN
256     7A  RCTL*
257     7B  MUHENKAN
258     7C  RALT*
259     7D  JPY
260     7E  Keypad ,
261     7F  Keypad / *
262
263 */