]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - converter/xt_usb/matrix.c
fe4eebf3e1bde471a4abeabbd6ed0ad957f229a2
[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 0x00;
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   *   *   *   o   o   o
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 o: reserved
215
216 Usage in TMK:
217
218     00  (reserved) DO NOT USE
219     54  PrintScr*
220     55  Pause*
221     56  Euro2
222     57  F11
223     58  F12
224     59  Keypad =
225     5A  LGUI*
226     5B  RGUI*
227     5C  APP*
228     5D  (reserved)
229     5E  (reserved)
230     5F  (reserved)
231     60  cursor*
232     61  cursor*
233     62  cursor*
234     63  cursor*
235     64  F13
236     65  F14
237     66  F15
238     67  F16
239     68  F17
240     69  F18
241     6A  F19
242     6B  F20
243     6C  F21
244     6D  F22
245     6E  F23
246     6F  Keypad Enter*
247     70  KANA
248     71  nav*
249     72  nav*
250     73  RO
251     74  nav*
252     75  nav*
253     76  F24
254     77  nav*
255     78  nav*
256     79  HENKAN
257     7A  RCTL*
258     7B  MUHENKAN
259     7C  RALT*
260     7D  JPY
261     7E  Keypad ,
262     7F  Keypad / *
263
264 */