]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - converter/xt_usb/matrix.c
ibmpc_usb: Add Z-150 AT support
[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                     state = INIT;
148                     break;
149                 default:
150                     state = INIT;
151                     break;
152             }
153             break;
154         case E1_9D:
155             switch (code) {
156                 case 0xC5:
157                     matrix_break(0x55);
158                     state = INIT;
159                     break;
160                 default:
161                     state = INIT;
162                     break;
163             }
164             break;
165         default:
166             state = INIT;
167     }
168     return 1;
169 }
170
171 inline
172 uint8_t matrix_get_row(uint8_t row)
173 {
174     return matrix[row];
175 }
176
177 inline
178 static void matrix_make(uint8_t code)
179 {
180     if (!matrix_is_on(ROW(code), COL(code))) {
181         matrix[ROW(code)] |= 1<<COL(code);
182     }
183 }
184
185 inline
186 static void matrix_break(uint8_t code)
187 {
188     if (matrix_is_on(ROW(code), COL(code))) {
189         matrix[ROW(code)] &= ~(1<<COL(code));
190     }
191 }
192
193 void matrix_clear(void)
194 {
195     for (uint8_t i=0; i < MATRIX_ROWS; i++) matrix[i] = 0x00;
196 }
197
198 /*
199 XT Scancodes
200 ============
201 - http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
202 - https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc
203
204 01-53: Normal codes used in original XT keyboard
205 54-7F: Not used in original XT keyboard
206
207         0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
208     50  -   -   -   -   *   *   x   x   x   x   *   *   *   o   o   o
209     60  *   *   *   *   x   x   x   x   x   x   x   x   x   x   x   *
210     70  x   *   *   x   *   *   x   *   *   x   *   x   *   x   x   *
211
212 -: codes existed in original XT keyboard
213 *: E0-escaped codes converted into unused code area(internal use in TMK)
214 x: Non-espcaped codes(not used in real keyboards probably, for CodeSet2-CodeSet1 translation purpose)
215 o: reserved
216
217 Usage in TMK:
218
219     00  (reserved) DO NOT USE
220     54  PrintScr*
221     55  Pause*
222     56  Euro2
223     57  F11
224     58  F12
225     59  Keypad =
226     5A  LGUI*
227     5B  RGUI*
228     5C  APP*
229     5D  (reserved)
230     5E  (reserved)
231     5F  (reserved)
232     60  cursor*
233     61  cursor*
234     62  cursor*
235     63  cursor*
236     64  F13
237     65  F14
238     66  F15
239     67  F16
240     68  F17
241     69  F18
242     6A  F19
243     6B  F20
244     6C  F21
245     6D  F22
246     6E  F23
247     6F  Keypad Enter*
248     70  KANA
249     71  nav*
250     72  nav*
251     73  RO
252     74  nav*
253     75  nav*
254     76  F24
255     77  nav*
256     78  nav*
257     79  HENKAN
258     7A  RCTL*
259     7B  MUHENKAN
260     7C  RALT*
261     7D  JPY
262     7E  Keypad ,
263     7F  Keypad / *
264
265 */