]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - converter/xt_usb/matrix.c
ibmpc_usb: Update prebuilt firmware hex files
[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 doesn't use E0-codes probably
52         // Some XT compatilble keyobards need these keys?
53         // http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
54         // https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
55         case 0x37: return 0x54; // Print Screen
56         case 0x46: return 0x55; // Ctrl + Pause
57         case 0x1C: return 0x6F; // Keypad Enter
58         case 0x35: return 0x7F; // Keypad /
59         case 0x5B: return 0x5A; // Left  GUI
60         case 0x5C: return 0x5B; // Right GUI
61         case 0x5D: return 0x5C; // Application
62         case 0x5E: return 0x5D; // Power(not used)
63         case 0x5F: return 0x5E; // Sleep(not used)
64         case 0x63: return 0x5F; // Wake (not used)
65         case 0x48: return 0x60; // Up
66         case 0x4B: return 0x61; // Left
67         case 0x50: return 0x62; // Down
68         case 0x4D: return 0x63; // Right
69         case 0x52: return 0x71; // Insert
70         case 0x53: return 0x72; // Delete
71         case 0x47: return 0x74; // Home
72         case 0x4F: return 0x75; // End
73         case 0x49: return 0x77; // Home
74         case 0x51: return 0x78; // End
75         case 0x1D: return 0x7A; // Right Ctrl
76         case 0x38: return 0x7C; // Right Alt
77     }
78     return 0x00;
79 }
80
81 uint8_t matrix_scan(void)
82 {
83     static enum {
84         INIT,
85         E0,
86         // Pause: E1 1D 45, E1 9D C5
87         E1,
88         E1_1D,
89         E1_9D,
90     } state = INIT;
91
92     uint8_t code = xt_host_recv();
93     if (!code) return 0;
94     dprintf("%02X ", code);
95     switch (state) {
96         case INIT:
97             switch (code) {
98                 case 0xE0:
99                     state = E0;
100                     break;
101                 case 0xE1:
102                     state = E1;
103                     break;
104                 default:
105                     if (code < 0x80)
106                         matrix_make(code);
107                     else
108                         matrix_break(code & 0x7F);
109                     break;
110             }
111             break;
112         case E0:
113             switch (code) {
114                 case 0x2A:
115                 case 0xAA:
116                 case 0x36:
117                 case 0xB6:
118                     //ignore fake shift
119                     state = INIT;
120                     break;
121                 default:
122                     if (code < 0x80)
123                         matrix_make(move_e0code(code));
124                     else
125                         matrix_break(move_e0code(code & 0x7F));
126                     state = INIT;
127                     break;
128             }
129             break;
130         case E1:
131             switch (code) {
132                 case 0x1D:
133                     state = E1_1D;
134                     break;
135                 case 0x9D:
136                     state = E1_9D;
137                     break;
138                 default:
139                     state = INIT;
140                     break;
141             }
142             break;
143         case E1_1D:
144             switch (code) {
145                 case 0x45:
146                     matrix_make(0x55);
147                     break;
148                 default:
149                     state = INIT;
150                     break;
151             }
152             break;
153         case E1_9D:
154             switch (code) {
155                 case 0x45:
156                     matrix_break(0x55);
157                     break;
158                 default:
159                     state = INIT;
160                     break;
161             }
162             break;
163         default:
164             state = INIT;
165     }
166     return 1;
167 }
168
169 inline
170 uint8_t matrix_get_row(uint8_t row)
171 {
172     return matrix[row];
173 }
174
175 inline
176 static void matrix_make(uint8_t code)
177 {
178     if (!matrix_is_on(ROW(code), COL(code))) {
179         matrix[ROW(code)] |= 1<<COL(code);
180     }
181 }
182
183 inline
184 static void matrix_break(uint8_t code)
185 {
186     if (matrix_is_on(ROW(code), COL(code))) {
187         matrix[ROW(code)] &= ~(1<<COL(code));
188     }
189 }
190
191 void matrix_clear(void)
192 {
193     for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
194 }
195
196 /*
197 XT Scancodes
198 ============
199 - http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
200 - https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
201
202 01-53: Normal codes used in original XT keyboard
203 54-7F: Not used in original XT keyboard
204
205         0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
206     50  -   -   -   -   *   *   x   x   x   x   *   *   *   o   o   o
207     60  *   *   *   *   x   x   x   x   x   x   x   x   x   x   x   *
208     70  x   *   *   x   *   *   x   *   *   x   *   x   *   x   x   *
209
210 -: codes existed in original XT keyboard
211 *: E0-escaped codes converted into unused code area(internal use in TMK)
212 x: Non-espcaped codes(not used in real keyboards probably, for CodeSet2-CodeSet1 translation purpose)
213 o: reserved
214
215 Usage in TMK:
216
217     00  (reserved) DO NOT USE
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 */