Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / drivers / adb_kbd.c
1 /*
2  *
3  * Open Hack'Ware BIOS ADB keyboard support, ported to OpenBIOS
4  *
5  *  Copyright (c) 2005 Jocelyn Mayer
6  *  Copyright (c) 2005 Stefan Reinauer
7  *
8  *   This program is free software; you can redistribute it and/or
9  *   modify it under the terms of the GNU General Public License V2
10  *   as published by the Free Software Foundation
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, write to the Free Software
19  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
20  */
21
22 #include "config.h"
23 #include "libopenbios/bindings.h"
24 #include "libc/byteorder.h"
25 #include "libc/vsprintf.h"
26 #include "kbd.h"
27
28 #include "adb_bus.h"
29 #include "adb_kbd.h"
30
31 DECLARE_UNNAMED_NODE( keyboard, INSTALL_OPEN, sizeof(int));
32
33 static void
34 keyboard_open(int *idx)
35 {
36         RET(-1);
37 }
38
39 static void
40 keyboard_close(int *idx)
41 {
42 }
43
44 static void keyboard_read(void);
45 static void keyboard_getkeymap(void);
46
47 NODE_METHODS( keyboard ) = {
48         { "open",               keyboard_open           },
49         { "close",              keyboard_close          },
50         { "read",               keyboard_read           },
51         { "get-key-map",        keyboard_getkeymap      },
52 };
53
54 /* VT100 escape sequences */
55
56 enum {
57         KEY_UP = 0, KEY_DOWN, KEY_RIGHT, KEY_LEFT, KEY_PAGE_UP, KEY_PAGE_DOWN,
58         KEY_DELETE, KEY_HOME, KEY_END, KEY_HELP,
59         KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8,
60         KEY_F9, KEY_F10, KEY_F11, KEY_F12, KEY_F13, KEY_F14, KEY_F15, KEY_F16
61 };
62
63 #define ADB_MAX_SEQUENCE_LEN    16
64
65 static const char *ADB_sequences[] = {
66         [KEY_UP] = "A[\e",
67         [KEY_DOWN] = "B[\e",
68         [KEY_RIGHT] = "C[\e",
69         [KEY_LEFT] = "D[\e",
70         [KEY_PAGE_UP] = "~5[\e",
71         [KEY_PAGE_DOWN] = "~6[\e",
72         [KEY_DELETE] = "~3[\e",
73         [KEY_HOME] = "HO\e",
74         [KEY_END] = "FO\e",
75         [KEY_HELP] = "~2[\e",
76         [KEY_F1] = "PO\e",
77         [KEY_F2] = "QO\e",
78         [KEY_F3] = "RO\e",
79         [KEY_F4] = "SO\e",
80         [KEY_F5] = "~15[\e",
81         [KEY_F6] = "~17[\e",
82         [KEY_F7] = "~18[\e",
83         [KEY_F8] = "~19[\e",
84         [KEY_F9] = "~20[\e",
85         [KEY_F10] = "~21[\e",
86         [KEY_F11] = "~23[\e",
87         [KEY_F12] = "~24[\e",
88         [KEY_F13] = "~25[\e",
89         [KEY_F14] = "~26[\e",
90         [KEY_F15] = "~28[\e",
91         [KEY_F15] = "~29[\e",
92 };
93
94 /* ADB US keyboard translation map */
95
96 static const keymap_t ADB_kbd_us[] = {
97     /* 0x00 */
98     { KBD_SH_CAPS, { 0x61, 0x41, 0x01,   -1,   -1,   -1,   -1,   -1,
99                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
100                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
101                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
102     { KBD_SH_CAPS, { 0x73, 0x53, 0x13,   -1,   -1,   -1,   -1,   -1,
103                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
104                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
105                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
106     { KBD_SH_CAPS, { 0x64, 0x44, 0x04,   -1,   -1,   -1,   -1,   -1,
107                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
108                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
109                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
110     { KBD_SH_CAPS, { 0x66, 0x46, 0x06,   -1,   -1,   -1,   -1,   -1,
111                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
112                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
113                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
114     { KBD_SH_CAPS, { 0x68, 0x48, 0x08,   -1,   -1,   -1,   -1,   -1,
115                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
116                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
117                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
118     { KBD_SH_CAPS, { 0x67, 0x47, 0x07,   -1,   -1,   -1,   -1,   -1,
119                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
120                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
121                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
122     { KBD_SH_CAPS, { 0x7A, 0x5A, 0x1A,   -1,   -1,   -1,   -1,   -1,
123                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
124                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
125                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
126     { KBD_SH_CAPS, { 0x78, 0x58, 0x18,   -1,   -1,   -1,   -1,   -1,
127                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
128                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
129                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
130     /* 0x08 */
131     { KBD_SH_CAPS, { 0x63, 0x43, 0x03,   -1,   -1,   -1,   -1,   -1,
132                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
133                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
134                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
135     { KBD_SH_CAPS, { 0x76, 0x56, 0x16,   -1,   -1,   -1,   -1,   -1,
136                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
137                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
138                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
139     { KBD_SH_CAPS, { 0x60, 0x40, 0x00,   -1,   -1,   -1,   -1,   -1, /* ? */
140                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
141                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
142                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
143     { KBD_SH_CAPS, { 0x62, 0x42, 0x02,   -1,   -1,   -1,   -1,   -1,
144                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
145                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
146                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
147     { KBD_SH_CAPS, { 0x71, 0x51, 0x11,   -1,   -1,   -1,   -1,   -1,
148                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
149                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
150                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
151     { KBD_SH_CAPS, { 0x77, 0x57, 0x17,   -1,   -1,   -1,   -1,   -1,
152                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
153                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
154                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
155     { KBD_SH_CAPS, { 0x65, 0x45, 0x05,   -1,   -1,   -1,   -1,   -1,
156                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
157                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
158                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
159     { KBD_SH_CAPS, { 0x72, 0x52, 0x12,   -1,   -1,   -1,   -1,   -1,
160                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
161                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
162                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
163     /* 0x10 */
164     { KBD_SH_CAPS, { 0x79, 0x59, 0x19,   -1,   -1,   -1,   -1,   -1,
165                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
166                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
167                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
168     { KBD_SH_CAPS, { 0x74, 0x54, 0x14,   -1,   -1,   -1,   -1,   -1,
169                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
170                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
171                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
172     { KBD_SH_CAPS, { 0x31, 0x21,   -1,   -1,   -1,   -1,   -1,   -1,
173                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
174                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
175                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
176     { KBD_SH_CAPS, { 0x32, 0x40, 0x00,   -1,   -1,   -1,   -1,   -1,
177                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
178                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
179                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
180     { KBD_SH_CAPS, { 0x33, 0x23,   -1,   -1,   -1,   -1,   -1,   -1,
181                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
182                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
183                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
184     { KBD_SH_CAPS, { 0x34, 0x24,   -1,   -1,   -1,   -1,   -1,   -1,
185                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
186                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
187                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
188     { KBD_SH_CAPS, { 0x36, 0x5E, 0x1E,   -1,   -1,   -1,   -1,   -1,
189                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
190                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
191                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
192     { KBD_SH_CAPS, { 0x35, 0x25,   -1,   -1,   -1,   -1,   -1,   -1,
193                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
194                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
195                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
196     /* 0x18 */
197     { KBD_SH_CAPS, { 0x3D, 0x2B,   -1,   -1,   -1,   -1,   -1,   -1,
198                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
199                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
200                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
201     { KBD_SH_CAPS, { 0x39, 0x28,   -1,   -1,   -1,   -1,   -1,   -1,
202                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
203                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
204                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
205     { KBD_SH_CAPS, { 0x37, 0x26,   -1,   -1,   -1,   -1,   -1,   -1,
206                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
207                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
208                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
209     { KBD_SH_CAPS, { 0x2D, 0x5F, 0x1F,   -1,   -1,   -1,   -1,   -1,
210                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
211                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
212                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
213     { KBD_SH_CAPS, { 0x38, 0x2A,   -1,   -1,   -1,   -1,   -1,   -1,
214                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
215                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
216                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
217     { KBD_SH_CAPS, { 0x30, 0x29,   -1,   -1,   -1,   -1,   -1,   -1,
218                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
219                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
220                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
221     { KBD_SH_CAPS, { 0x5D, 0x7D,   -1,   -1,   -1,   -1,   -1,   -1,
222                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
223                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
224                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
225     { KBD_SH_CAPS, { 0x6F, 0x4F, 0x0F,   -1,   -1,   -1,   -1,   -1,
226                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
227                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
228                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
229     /* 0x20 */
230     { KBD_SH_CAPS, { 0x75, 0x55, 0x15,   -1,   -1,   -1,   -1,   -1,
231                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
232                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
233                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
234     { KBD_SH_CAPS, { 0x5B, 0x7B,   -1,   -1,   -1,   -1,   -1,   -1,
235                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
236                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
237                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
238     { KBD_SH_CAPS, { 0x69, 0x49, 0x09,   -1,   -1,   -1,   -1,   -1,
239                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
240                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
241                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
242     { KBD_SH_CAPS, { 0x70, 0x50, 0x10,   -1,   -1,   -1,   -1,   -1,
243                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
244                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
245                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
246     { KBD_MOD_MAP(0x0D), },
247     { KBD_SH_CAPS, { 0x6C, 0x4C, 0x0C,   -1,   -1,   -1,   -1,   -1,
248                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
249                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
250                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
251     { KBD_SH_CAPS, { 0x6A, 0x4A, 0x0A,   -1,   -1,   -1,   -1,   -1,
252                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
253                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
254                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
255     { KBD_SH_CAPS, { 0x27, 0x22,   -1,   -1,   -1,   -1,   -1,   -1,
256                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
257                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
258                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
259     /* 0x28 */
260     { KBD_SH_CAPS, { 0x6B, 0x4B, 0x0B,   -1,   -1,   -1,   -1,   -1,
261                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
262                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
263                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
264     { KBD_SH_CAPS, { 0x3B, 0x3A,   -1,   -1,   -1,   -1,   -1,   -1,
265                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
266                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
267                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
268     { KBD_SH_CAPS, { 0x5C, 0x7C,   -1,   -1,   -1,   -1,   -1,   -1,
269                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
270                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
271                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
272     { KBD_SH_CAPS, { 0x2C, 0x3C,   -1,   -1,   -1,   -1,   -1,   -1,
273                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
274                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
275                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
276     { KBD_SH_CAPS, { 0x2F, 0x3F,   -1,   -1,   -1,   -1,   -1,   -1,
277                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
278                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
279                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
280     { KBD_SH_CAPS, { 0x6E, 0x4E, 0x0E,   -1,   -1,   -1,   -1,   -1,
281                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
282                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
283                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
284     { KBD_SH_CAPS, { 0x6D, 0x4D, 0x0D,   -1,   -1,   -1,   -1,   -1,
285                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
286                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
287                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
288     { KBD_SH_CAPS, { 0x2E, 0x3E,   -1,   -1,   -1,   -1,   -1,   -1,
289                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
290                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
291                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
292     /* 0x30 : tab */
293     { KBD_MOD_MAP(0x09), },
294     /* 0x31 : space */
295     { KBD_MOD_MAP(0x20), },
296     /* 0x32 : '<' '>' */
297     { KBD_SH_CAPS, { 0x3C, 0x3E,   -1,   -1,   -1,   -1,   -1,   -1, /* ? */
298                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
299                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
300                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
301     /* 0x33 : backspace */
302     { KBD_MOD_MAP(0x08), },
303     { KBD_MAP_NONE, },
304     /* 0x35 : ESC */
305     { KBD_MOD_MAP(0x1B), },
306     /* 0x36 : control */
307     { KBD_MOD_MAP_LCTRL, },
308     /* 0x37 : command */
309     { KBD_MOD_MAP_LCMD,   },
310     /* 0x38 : left shift */
311     { KBD_MOD_MAP_LSHIFT, },
312     /* 0x39 : caps-lock */
313     { KBD_MOD_MAP_CAPS,   },
314     /* 0x3A : option */
315     { KBD_MOD_MAP_LOPT,   },
316     /* 0x3B : left */
317     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_LEFT)), },
318     /* 0x3C : right */
319     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_RIGHT)), },
320     /* 0x3D : down */
321     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_DOWN)), },
322     /* 0x3E : up */
323     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_UP)), },
324     { KBD_MAP_NONE, },
325     /* 0x40 */
326     { KBD_MAP_NONE, },
327     { KBD_SH_NUML, { 0x7F, 0x2E,   -1,   -1,   -1,   -1,   -1,   -1,
328                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
329                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
330                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
331     { KBD_MAP_NONE, },
332     { KBD_SH_NONE, { 0x2A, 0x2A,   -1,   -1,   -1,   -1,   -1,   -1,
333                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
334                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
335                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
336     { KBD_MAP_NONE, },
337     { KBD_SH_NONE, { 0x2B, 0x2B,   -1,   -1,   -1,   -1,   -1,   -1,
338                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
339                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
340                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
341     { KBD_MAP_NONE, },
342     { KBD_MOD_MAP(0x7F), },
343     /* 0x48 */
344     { KBD_MAP_NONE, },
345     { KBD_MAP_NONE, },
346     { KBD_MAP_NONE, },
347     { KBD_SH_NONE, { 0x2F, 0x2F,   -1,   -1,   -1,   -1,   -1,   -1,
348                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
349                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
350                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
351     { KBD_MOD_MAP(0x0D), },
352     { KBD_MAP_NONE, },
353     { KBD_SH_NONE, { 0x2D, 0x2D,   -1,   -1,   -1,   -1,   -1,   -1,
354                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
355                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
356                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
357     { KBD_MAP_NONE, },
358     /* 0x50 */
359     { KBD_MAP_NONE, },
360     { KBD_SH_NONE, { 0x3D, 0x3D,   -1,   -1,   -1,   -1,   -1,   -1,
361                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
362                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
363                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
364     { KBD_SH_NUML, {   -1, 0x30,   -1,   -1,   -1,   -1,   -1,   -1,
365                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
366                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
367                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
368     { KBD_SH_NUML, {   -1, 0x31,   -1,   -1,   -1,   -1,   -1,   -1,
369                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
370                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
371                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
372     { KBD_SH_NUML, {   -1, 0x32,   -1,   -1,   -1,   -1,   -1,   -1,
373                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
374                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
375                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
376     { KBD_SH_NUML, {   -1, 0x33,   -1,   -1,   -1,   -1,   -1,   -1,
377                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
378                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
379                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
380     { KBD_SH_NUML, {   -1, 0x34,   -1,   -1,   -1,   -1,   -1,   -1,
381                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
382                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
383                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
384     { KBD_SH_NUML, {   -1, 0x35,   -1,   -1,   -1,   -1,   -1,   -1,
385                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
386                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
387                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
388     /* 0x58 */
389     { KBD_SH_NUML, {   -1, 0x36,   -1,   -1,   -1,   -1,   -1,   -1,
390                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
391                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
392                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
393     { KBD_SH_NUML, {   -1, 0x37,   -1,   -1,   -1,   -1,   -1,   -1,
394                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
395                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
396                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
397     { KBD_MAP_NONE, },
398     { KBD_SH_NUML, {   -1, 0x38,   -1,   -1,   -1,   -1,   -1,   -1,
399                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
400                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
401                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
402     { KBD_SH_NUML, {   -1, 0x39,   -1,   -1,   -1,   -1,   -1,   -1,
403                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
404                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
405                        -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, }, },
406     { KBD_MAP_NONE, },
407     { KBD_MOD_MAP(0x2F), },
408     { KBD_MAP_NONE, },
409     /* 0x60 : F5 */
410     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F5)), },
411     /* 0x61 : F6 */
412     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F6)), },
413     /* 0x62 : F7 */
414     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F7)), },
415     /* 0x63 : F3 */
416     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F3)), },
417     /* 0x64 : F8 */
418     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F8)), },
419     /* 0x65 : F9 */
420     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F9)), },
421     { KBD_MAP_NONE, },
422     /* 0x67 : F11 */
423     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F11)), },
424     /* 0x68 */
425     { KBD_MAP_NONE, },
426     /* 0x69 : F13 */
427     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F13)), },
428     { KBD_MAP_NONE, },
429     /* 0x6B : F14 */
430     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F14)), },
431     { KBD_MAP_NONE, },
432     /* 0x6D : F10 */
433     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F10)), },
434     { KBD_MAP_NONE, },
435     /* 0x6F : F12 */
436     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F12)), },
437     /* 0x70 */
438     { KBD_MAP_NONE, },
439     /* 0x71 : F15 */
440     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F15)), },
441     /* 0x72 : help */
442     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_HELP)), },
443     /* 0x73 : home */
444     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_HOME)), },
445     /* 0x74 : page up */
446     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_PAGE_UP)), },
447     /* 0x75 : del */
448     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_DELETE)), },
449     /* 0x76 : F4 */
450     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F4)), },
451     /* 0x77 : end */
452     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_END)), },
453     /* 0x78 : F2 */
454     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F2)), },
455     /* 0x79 : page down */
456     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_PAGE_UP)), },
457     /* 0x7A : F1 */
458     { KBD_MOD_MAP(KBD_SEQUENCE(KEY_F1)), },
459     /* 0x7B : right shift */
460     { KBD_MOD_MAP_RSHIFT, },
461     /* 0x7C : right option */
462     { KBD_MOD_MAP_ROPT,   },
463     /* 0x7D : right control */
464     { KBD_MOD_MAP_RCTRL, },
465     { KBD_MAP_NONE, },
466     /* 0x7F : power */
467     { KBD_MAP_NONE, },
468 };
469
470 typedef struct adb_kbd_t adb_kbd_t;
471 struct adb_kbd_t {
472     kbd_t kbd;
473     int next_key;
474     char sequence[ADB_MAX_SEQUENCE_LEN];
475     int len;
476     char keytable[32];
477 };
478
479 static adb_dev_t *my_adb_dev = NULL;
480
481 static int adb_kbd_read (void *private)
482 {
483     uint8_t buffer[ADB_BUF_SIZE];
484     adb_dev_t *dev = private;
485     adb_kbd_t *kbd;
486     int key;
487     int ret;
488
489     kbd = dev->state;
490
491     if (kbd->len > 0) {
492         ret = kbd->sequence[kbd->len-- - 1];
493         ADB_DPRINTF("Buffered %d (%02x)\n", ret, ret);
494         return ret;
495     }
496
497     /* Get saved state */
498     ret = -1;
499     for (key = -1; key == -1; ) {
500         if (kbd->next_key != -1) {
501             key = kbd->next_key;
502             kbd->next_key = -1;
503         } else {
504             if (adb_reg_get(dev, 0, buffer) != 2)
505                 break;
506             kbd->next_key = buffer[1] == 0xFF ? -1 : buffer[1];
507             key = buffer[0];
508         }
509         ret = kbd_translate_key(&kbd->kbd, key & 0x7F, key >> 7, kbd->sequence);
510         if (ret > 0) {
511                 kbd->len = ret;
512                 ret = kbd->sequence[kbd->len-- - 1];
513         }
514                 
515         ADB_DPRINTF("Translated %d (%02x) into %d (%02x)\n",
516                     key, key, ret, ret);
517     }
518
519     return ret;
520 }
521
522
523 void *adb_kbd_new (char *path, void *private)
524 {
525         char buf[64];
526         int props[1];
527         phandle_t ph, aliases;
528     adb_kbd_t *kbd;
529     adb_dev_t *dev = private;
530     kbd = (adb_kbd_t*)malloc(sizeof(adb_kbd_t));
531     if (kbd != NULL) {
532         memset(kbd, 0, sizeof(adb_kbd_t));
533         kbd_set_keymap(&kbd->kbd, sizeof(ADB_kbd_us) / sizeof(keymap_t),
534                         ADB_kbd_us, ADB_sequences);
535         kbd->next_key = -1;
536         kbd->len = 0;
537         
538         /* Debugging BootX: the lines below force get-key-map to report that
539          * cmd-V is being held down, which forces BootX to run in verbose mode
540          * for debugging.
541          *
542          * TODO: if we can find a mapping between the get-key-map bitmap and
543          * ADB scancodes, the keyboard driver should be altered to update this
544          * accordingly.
545          */
546         
547         /*
548         kbd->keytable[3] = 0x40;
549         kbd->keytable[28] = 0x10;
550         */
551         
552         dev->state = kbd;
553         my_adb_dev = dev;
554     }
555
556         snprintf(buf, sizeof(buf), "%s/keyboard", path);
557         REGISTER_NAMED_NODE( keyboard, buf);
558
559         ph = find_dev(buf);
560
561         set_property(ph, "device_type", "keyboard", 9);
562         props[0] = __cpu_to_be32(dev->addr);
563         set_property(ph, "reg", (char *)&props, sizeof(props));
564
565         aliases = find_dev("/aliases");
566         set_property(aliases, "adb-keyboard", buf, strlen(buf) + 1);
567
568     return kbd;
569 }
570
571 /* ( addr len -- actual ) */
572 static void keyboard_read(void)
573 {
574         char *addr;
575         int len, key, i;
576         len=POP();
577         addr=(char *)cell2pointer(POP());
578
579         for (i = 0; i < len; i++) {
580                 key = adb_kbd_read(my_adb_dev);
581                 if (key == -1 || key == -2)
582                         break;
583                 *addr++ = (char)key;
584         }
585         PUSH(i);
586 }
587
588 /* ( -- keymap ) (?) */
589 /* should return a pointer to an array with 32 bytes (256 bits) */
590 static void keyboard_getkeymap(void)
591 {
592         adb_kbd_t *kbd = my_adb_dev->state;
593         
594         PUSH( pointer2cell(kbd->keytable) );
595 }