OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [m68k/] [atari/] [atakeyb.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1623 jcastillo
/*
2
 * linux/atari/atakeyb.c
3
 *
4
 * Atari Keyboard driver for 680x0 Linux
5
 *
6
 * This file is subject to the terms and conditions of the GNU General Public
7
 * License.  See the file COPYING in the main directory of this archive
8
 * for more details.
9
 */
10
 
11
/*
12
 * Atari support by Robert de Vries
13
 * enhanced by Bjoern Brauel and Roman Hodek
14
 */
15
 
16
#include <linux/sched.h>
17
#include <linux/interrupt.h>
18
#include <linux/errno.h>
19
#include <linux/keyboard.h>
20
#include <linux/delay.h>
21
#include <linux/timer.h>
22
#include <linux/kd.h>
23
#include <linux/random.h>
24
 
25
#include <asm/atariints.h>
26
#include <asm/atarihw.h>
27
#include <asm/atarikb.h>
28
#include <asm/atari_mouse.h>
29
#include <asm/atari_joystick.h>
30
#include <asm/irq.h>
31
 
32
extern int do_poke_blanked_console;
33
extern void process_keycode (int);
34
extern int ovsc_switchmode;
35
unsigned char mach_keyboard_type;
36
static void atakeyb_rep( unsigned long ignore );
37
extern unsigned int keymap_count;
38
 
39
/* Hook for MIDI serial driver */
40
void (*atari_MIDI_interrupt_hook) (void);
41
/* Hook for mouse driver */
42
void (*atari_mouse_interrupt_hook) (char *);
43
 
44
#define ATAKEY_CAPS     (58)
45
#define BREAK_MASK      (0x80)
46
 
47
/*
48
 * ++roman: The following changes were applied manually:
49
 *
50
 *  - The Alt (= Meta) key works in combination with Shift and
51
 *    Control, e.g. Alt+Shift+a sends Meta-A (0xc1), Alt+Control+A sends
52
 *    Meta-Ctrl-A (0x81) ...
53
 *
54
 *  - The parentheses on the keypad send '(' and ')' with all
55
 *    modifiers (as would do e.g. keypad '+'), but they cannot be used as
56
 *    application keys (i.e. sending Esc O c).
57
 *
58
 *  - HELP and UNDO are mapped to be F21 and F24, resp, that send the
59
 *    codes "\E[M" and "\E[P". (This is better than the old mapping to
60
 *    F11 and F12, because these codes are on Shift+F1/2 anyway.) This
61
 *    way, applications that allow their own keyboard mappings
62
 *    (e.g. tcsh, X Windows) can be configured to use them in the way
63
 *    the label suggests (providing help or undoing).
64
 *
65
 *  - Console switching is done with Alt+Fx (consoles 1..10) and
66
 *    Shift+Alt+Fx (consoles 11..20).
67
 *
68
 *  - The misc. special function implemented in the kernel are mapped
69
 *    to the following key combinations:
70
 *
71
 *      ClrHome          -> Home/Find
72
 *      Shift + ClrHome  -> End/Select
73
 *      Shift + Up       -> Page Up
74
 *      Shift + Down     -> Page Down
75
 *      Alt + Help       -> show system status
76
 *      Shift + Help     -> show memory info
77
 *      Ctrl + Help      -> show registers
78
 *      Ctrl + Alt + Del -> Reboot
79
 *      Alt + Undo       -> switch to last console
80
 *      Shift + Undo     -> send interrupt
81
 *      Alt + Insert     -> stop/start output (same as ^S/^Q)
82
 *      Alt + Up         -> Scroll back console (if implemented)
83
 *      Alt + Down       -> Scroll forward console (if implemented)
84
 *      Alt + CapsLock   -> NumLock
85
 *
86
 */
87
 
88
static u_short ataplain_map[NR_KEYS] = {
89
        0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
90
        0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf008, 0xf009,
91
        0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
92
        0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
93
        0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
94
        0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
95
        0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf200,
96
        0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
97
        0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf200, 0xf200, 0xf114,
98
        0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
99
        0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200,
100
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
101
        0xf200, 0xf121, 0xf11b, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf307,
102
        0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
103
        0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
104
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
105
};
106
 
107
static u_short atashift_map[NR_KEYS] = {
108
        0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
109
        0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf008, 0xf009,
110
        0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
111
        0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53,
112
        0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
113
        0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
114
        0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf200,
115
        0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e,
116
        0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf200, 0xf200, 0xf117,
117
        0xf118, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
118
        0xf119, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200,
119
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
120
        0xf200, 0xf205, 0xf203, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf307,
121
        0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
122
        0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
123
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
124
};
125
 
126
static u_short atactrl_map[NR_KEYS] = {
127
        0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
128
        0xf01f, 0xf07f, 0xf200, 0xf200, 0xf07f, 0xf200, 0xf008, 0xf200,
129
        0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
130
        0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013,
131
        0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
132
        0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016,
133
        0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf07f, 0xf700, 0xf200,
134
        0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
135
        0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf200, 0xf200, 0xf114,
136
        0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
137
        0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200,
138
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
139
        0xf200, 0xf121, 0xf202, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf307,
140
        0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
141
        0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
142
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
143
};
144
 
145
static u_short atashift_ctrl_map[NR_KEYS] = {
146
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
147
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf008, 0xf200,
148
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
149
        0xf200, 0xf200, 0xf200, 0xf200, 0xf201, 0xf702, 0xf200, 0xf200,
150
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
151
        0xf200, 0xf200, 0xf700, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
152
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf700, 0xf200,
153
        0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
154
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf117,
155
        0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
156
        0xf600, 0xf200, 0xf115, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
157
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
158
        0xf200, 0xf200, 0xf200, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf307,
159
        0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
160
        0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
161
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
162
};
163
 
164
static u_short ataalt_map[NR_KEYS] = {
165
        0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
166
        0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf808, 0xf809,
167
        0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
168
        0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873,
169
        0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b,
170
        0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876,
171
        0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf200,
172
        0xf703, 0xf820, 0xf208, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
173
        0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf200, 0xf200, 0xf114,
174
        0xf20b, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
175
        0xf20a, 0xf200, 0xf209, 0xf87f, 0xf200, 0xf200, 0xf200, 0xf200,
176
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
177
        0xf200, 0xf206, 0xf204, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf907,
178
        0xf908, 0xf909, 0xf904, 0xf905, 0xf906, 0xf901, 0xf902, 0xf903,
179
        0xf900, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
180
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
181
};
182
 
183
static u_short atashift_alt_map[NR_KEYS] = {
184
        0xf200, 0xf81b, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e,
185
        0xf826, 0xf82a, 0xf828, 0xf829, 0xf85f, 0xf82b, 0xf808, 0xf809,
186
        0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849,
187
        0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf201, 0xf702, 0xf841, 0xf853,
188
        0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf83a,
189
        0xf822, 0xf87e, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856,
190
        0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf83f, 0xf700, 0xf200,
191
        0xf703, 0xf820, 0xf207, 0xf50a, 0xf50b, 0xf50c, 0xf50d, 0xf50e,
192
        0xf50f, 0xf510, 0xf511, 0xf512, 0xf513, 0xf200, 0xf200, 0xf117,
193
        0xf118, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
194
        0xf119, 0xf200, 0xf115, 0xf87f, 0xf200, 0xf200, 0xf200, 0xf200,
195
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
196
        0xf200, 0xf200, 0xf200, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf307,
197
        0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
198
        0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
199
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
200
};
201
 
202
static u_short atactrl_alt_map[NR_KEYS] = {
203
        0xf200, 0xf200, 0xf200, 0xf800, 0xf81b, 0xf81c, 0xf81d, 0xf81e,
204
        0xf81f, 0xf87f, 0xf200, 0xf200, 0xf87f, 0xf200, 0xf808, 0xf200,
205
        0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
206
        0xf80f, 0xf810, 0xf81b, 0xf81d, 0xf201, 0xf702, 0xf801, 0xf813,
207
        0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
208
        0xf807, 0xf800, 0xf700, 0xf81c, 0xf81a, 0xf818, 0xf803, 0xf816,
209
        0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf87f, 0xf700, 0xf200,
210
        0xf703, 0xf800, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
211
        0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf200, 0xf200, 0xf114,
212
        0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
213
        0xf600, 0xf200, 0xf115, 0xf07f, 0xf200, 0xf200, 0xf200, 0xf200,
214
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
215
        0xf200, 0xf121, 0xf202, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf307,
216
        0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
217
        0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
218
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
219
};
220
 
221
static u_short atashift_ctrl_alt_map[NR_KEYS] = {
222
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
223
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf808, 0xf200,
224
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
225
        0xf200, 0xf200, 0xf200, 0xf200, 0xf201, 0xf702, 0xf200, 0xf200,
226
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
227
        0xf200, 0xf200, 0xf700, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
228
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf700, 0xf200,
229
        0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
230
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf117,
231
        0xf603, 0xf200, 0xf30b, 0xf601, 0xf200, 0xf602, 0xf30a, 0xf200,
232
        0xf600, 0xf200, 0xf115, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
233
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
234
        0xf200, 0xf200, 0xf200, 0xf028, 0xf029, 0xf30d, 0xf30c, 0xf307,
235
        0xf308, 0xf309, 0xf304, 0xf305, 0xf306, 0xf301, 0xf302, 0xf303,
236
        0xf300, 0xf310, 0xf30e, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
237
        0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200
238
};
239
 
240
typedef enum kb_state_t
241
{
242
    KEYBOARD, AMOUSE, RMOUSE, JOYSTICK, CLOCK, RESYNC
243
} KB_STATE_T;
244
 
245
#define IS_SYNC_CODE(sc)        ((sc) >= 0x04 && (sc) <= 0xfb)
246
 
247
typedef struct keyboard_state
248
{
249
    unsigned char  buf[6];
250
    int            len;
251
    KB_STATE_T     state;
252
} KEYBOARD_STATE;
253
 
254
KEYBOARD_STATE kb_state;
255
 
256
#define DEFAULT_KEYB_REP_DELAY  (HZ/4)
257
#define DEFAULT_KEYB_REP_RATE   (HZ/25)
258
 
259
/* These could be settable by some ioctl() in future... */
260
static unsigned int key_repeat_delay = DEFAULT_KEYB_REP_DELAY;
261
static unsigned int key_repeat_rate  = DEFAULT_KEYB_REP_RATE;
262
 
263
static unsigned char rep_scancode;
264
static struct timer_list atakeyb_rep_timer = { NULL, NULL, 0, 0, atakeyb_rep };
265
 
266
extern struct pt_regs *pt_regs;
267
 
268
static void atakeyb_rep( unsigned long ignore )
269
 
270
{
271
        pt_regs = NULL;
272
 
273
        /* Disable keyboard it for the time we call process_keycode(), else a race
274
         * in the keyboard tty queue may happen */
275
        atari_disable_irq( IRQ_MFP_ACIA );
276
        del_timer( &atakeyb_rep_timer );
277
 
278
        /* A keyboard int may have come in before we disabled the irq, so
279
         * double-check whether rep_scancode is still != 0 */
280
        if (rep_scancode) {
281
                atakeyb_rep_timer.expires = jiffies + key_repeat_rate;
282
                atakeyb_rep_timer.prev = atakeyb_rep_timer.next = NULL;
283
                add_timer( &atakeyb_rep_timer );
284
 
285
                process_keycode (rep_scancode);
286
        }
287
 
288
        atari_enable_irq( IRQ_MFP_ACIA );
289
}
290
 
291
 
292
/* ++roman: If a keyboard overrun happened, we can't tell in general how much
293
 * bytes have been lost and in which state of the packet structure we are now.
294
 * This usually causes keyboards bytes to be interpreted as mouse movements
295
 * and vice versa, which is very annoying. It seems better to throw away some
296
 * bytes (that are usually mouse bytes) than to misinterpret them. Therefor I
297
 * introduced the RESYNC state for IKBD data. In this state, the bytes up to
298
 * one that really looks like a key event (0x04..0xf2) or the start of a mouse
299
 * packet (0xf8..0xfb) are thrown away, but at most 2 bytes. This at least
300
 * speeds up the resynchronization of the event structure, even if maybe a
301
 * mouse movement is lost. However, nothing is perfect. For bytes 0x01..0x03,
302
 * it's really hard to decide whether they're mouse or keyboard bytes. Since
303
 * overruns usually occur when moving the Atari mouse rapidly, they're seen as
304
 * mouse bytes here. If this is wrong, only a make code of the keyboard gets
305
 * lost, which isn't too bad. Loosing a break code would be disastrous,
306
 * because then the keyboard repeat strikes...
307
 */
308
 
309
static void keyboard_interrupt(int irq, struct pt_regs *fp, void *dummy)
310
{
311
  u_char acia_stat;
312
  int scancode;
313
  int break_flag;
314
 
315
  /* save frame for register dump */
316
  pt_regs = (struct pt_regs *)fp;
317
 
318
 repeat:
319
  if (acia.mid_ctrl & ACIA_IRQ)
320
        if (atari_MIDI_interrupt_hook)
321
                atari_MIDI_interrupt_hook();
322
  acia_stat = acia.key_ctrl;
323
  /* check out if the interrupt came from this ACIA */
324
  if (!((acia_stat | acia.mid_ctrl) & ACIA_IRQ))
325
        return;
326
 
327
    if (acia_stat & ACIA_OVRN)
328
    {
329
        /* a very fast typist or a slow system, give a warning */
330
        /* ...happens often if interrupts were disabled for too long */
331
        printk( "Keyboard overrun\n" );
332
        scancode = acia.key_data;
333
        /* Turn off autorepeating in case a break code has been lost */
334
        del_timer( &atakeyb_rep_timer );
335
        rep_scancode = 0;
336
        if (IS_SYNC_CODE(scancode)) {
337
            /* This code seem already to be the start of a new packet or a
338
             * single keycode */
339
            kb_state.state = KEYBOARD;
340
            goto interpret_scancode;
341
        }
342
        else {
343
            /* Go to RESYNC state and skip this byte */
344
            kb_state.state = RESYNC;
345
            kb_state.len = 1; /* skip max. 1 another byte */
346
            goto repeat;
347
        }
348
    }
349
 
350
    if (acia_stat & ACIA_RDRF)  /* received a character */
351
    {
352
        scancode = acia.key_data;       /* get it or reset the ACIA, I'll get it! */
353
      interpret_scancode:
354
        switch (kb_state.state)
355
        {
356
          case KEYBOARD:
357
            switch (scancode)
358
            {
359
              case 0xF7:
360
                kb_state.state = AMOUSE;
361
                kb_state.len = 0;
362
                break;
363
 
364
              case 0xF8:
365
              case 0xF9:
366
              case 0xFA:
367
              case 0xFB:
368
                kb_state.state = RMOUSE;
369
                kb_state.len = 1;
370
                kb_state.buf[0] = scancode;
371
                break;
372
 
373
              case 0xFC:
374
                kb_state.state = CLOCK;
375
                kb_state.len = 0;
376
                break;
377
 
378
              case 0xFE:
379
              case 0xFF:
380
                kb_state.state = JOYSTICK;
381
                kb_state.len = 1;
382
                kb_state.buf[0] = scancode;
383
                break;
384
 
385
              default:
386
                break_flag = scancode & BREAK_MASK;
387
                scancode &= ~BREAK_MASK;
388
 
389
                if (break_flag) {
390
                    del_timer( &atakeyb_rep_timer );
391
                    rep_scancode = 0;
392
                }
393
                else {
394
                    del_timer( &atakeyb_rep_timer );
395
                    rep_scancode = scancode;
396
                    atakeyb_rep_timer.expires = jiffies + key_repeat_delay;
397
                    atakeyb_rep_timer.prev = atakeyb_rep_timer.next = NULL;
398
                    add_timer( &atakeyb_rep_timer );
399
                }
400
 
401
                process_keycode( break_flag | scancode );
402
                do_poke_blanked_console = 1;
403
                mark_bh(CONSOLE_BH);
404
                add_keyboard_randomness(scancode);
405
 
406
                break;
407
            }
408
            break;
409
 
410
          case AMOUSE:
411
            kb_state.buf[kb_state.len++] = scancode;
412
            if (kb_state.len == 5)
413
            {
414
                kb_state.state = KEYBOARD;
415
                /* not yet used */
416
                /* wake up someone waiting for this */
417
            }
418
            break;
419
 
420
          case RMOUSE:
421
            kb_state.buf[kb_state.len++] = scancode;
422
            if (kb_state.len == 3)
423
            {
424
                kb_state.state = KEYBOARD;
425
                if (atari_mouse_interrupt_hook)
426
                        atari_mouse_interrupt_hook(kb_state.buf);
427
            }
428
            break;
429
 
430
          case JOYSTICK:
431
            kb_state.buf[1] = scancode;
432
            kb_state.state = KEYBOARD;
433
            atari_joystick_interrupt(kb_state.buf);
434
            break;
435
 
436
          case CLOCK:
437
            kb_state.buf[kb_state.len++] = scancode;
438
            if (kb_state.len == 6)
439
            {
440
                kb_state.state = KEYBOARD;
441
                /* wake up someone waiting for this.
442
                   But will this ever be used, as Linux keeps its own time.
443
                   Perhaps for synchronization purposes? */
444
                /* wake_up_interruptible(&clock_wait); */
445
            }
446
            break;
447
 
448
          case RESYNC:
449
            if (kb_state.len <= 0 || IS_SYNC_CODE(scancode)) {
450
                kb_state.state = KEYBOARD;
451
                goto interpret_scancode;
452
            }
453
            kb_state.len--;
454
            break;
455
        }
456
    }
457
 
458
#ifdef KEYB_WRITE_INTERRUPT
459
    if (acia_stat & ACIA_TDRE)  /* transmit of character is finished */
460
    {
461
        if (kb_state.buf)
462
        {
463
            acia.key_data = *kb_state.buf++;
464
            kb_state.len--;
465
            if (kb_state.len == 0)
466
            {
467
                kb_state.buf = NULL;
468
                if (!kb_state.kernel_mode)
469
                        /* unblock something */;
470
            }
471
        }
472
    }
473
#endif
474
 
475
#if 0
476
    if (acia_stat & ACIA_CTS)
477
        /* cannot happen */;
478
#endif
479
 
480
    if (acia_stat & (ACIA_FE | ACIA_PE))
481
    {
482
        printk("Error in keyboard communication\n");
483
    }
484
 
485
    /* process_keycode() can take a lot of time, so check again if
486
         * some character arrived
487
         */
488
    goto repeat;
489
}
490
 
491
#ifdef KEYB_WRITE_INTERRUPT
492
void ikbd_write(const char *str, int len)
493
{
494
    u_char acia_stat;
495
 
496
    if (kb_stat.buf)
497
        /* wait */;
498
    acia_stat = acia.key_ctrl;
499
    if (acia_stat & ACIA_TDRE)
500
    {
501
        if (len != 1)
502
        {
503
            kb_stat.buf = str + 1;
504
            kb_stat.len = len - 1;
505
        }
506
        acia.key_data = *str;
507
        /* poll */
508
    }
509
}
510
#else
511
/*
512
 * I write to the keyboard without using interrupts, I poll instead.
513
 * This takes for the maximum length string allowed (7) at 7812.5 baud
514
 * 8 data 1 start 1 stop bit: 9.0 ms
515
 * If this takes too long for normal operation, interrupt driven writing
516
 * is the solution. (I made a feeble attempt in that direction but I
517
 * kept it simple for now.)
518
 */
519
void ikbd_write(const char *str, int len)
520
{
521
    u_char acia_stat;
522
 
523
    if ((len < 1) || (len > 7))
524
        panic("ikbd: maximum string length exceeded");
525
    while (len)
526
    {
527
        acia_stat = acia.key_ctrl;
528
        if (acia_stat & ACIA_TDRE)
529
        {
530
            acia.key_data = *str++;
531
            len--;
532
        }
533
    }
534
}
535
#endif
536
 
537
/* Reset (without touching the clock) */
538
void ikbd_reset(void)
539
{
540
    static const char cmd[2] = { 0x80, 0x01 };
541
 
542
    ikbd_write(cmd, 2);
543
 
544
    /* if all's well code 0xF1 is returned, else the break codes of
545
       all keys making contact */
546
}
547
 
548
/* Set mouse button action */
549
void ikbd_mouse_button_action(int mode)
550
{
551
    char cmd[2] = { 0x07, mode };
552
 
553
    ikbd_write(cmd, 2);
554
}
555
 
556
/* Set relative mouse position reporting */
557
void ikbd_mouse_rel_pos(void)
558
{
559
    static const char cmd[1] = { 0x08 };
560
 
561
    ikbd_write(cmd, 1);
562
}
563
 
564
/* Set absolute mouse position reporting */
565
void ikbd_mouse_abs_pos(int xmax, int ymax)
566
{
567
    char cmd[5] = { 0x09, xmax>>8, xmax&0xFF, ymax>>8, ymax&0xFF };
568
 
569
    ikbd_write(cmd, 5);
570
}
571
 
572
/* Set mouse keycode mode */
573
void ikbd_mouse_kbd_mode(int dx, int dy)
574
{
575
    char cmd[3] = { 0x0A, dx, dy };
576
 
577
    ikbd_write(cmd, 3);
578
}
579
 
580
/* Set mouse threshold */
581
void ikbd_mouse_thresh(int x, int y)
582
{
583
    char cmd[3] = { 0x0B, x, y };
584
 
585
    ikbd_write(cmd, 3);
586
}
587
 
588
/* Set mouse scale */
589
void ikbd_mouse_scale(int x, int y)
590
{
591
    char cmd[3] = { 0x0C, x, y };
592
 
593
    ikbd_write(cmd, 3);
594
}
595
 
596
/* Interrogate mouse position */
597
void ikbd_mouse_pos_get(int *x, int *y)
598
{
599
    static const char cmd[1] = { 0x0D };
600
 
601
    ikbd_write(cmd, 1);
602
 
603
    /* wait for returning bytes */
604
}
605
 
606
/* Load mouse position */
607
void ikbd_mouse_pos_set(int x, int y)
608
{
609
    char cmd[6] = { 0x0E, 0x00, x>>8, x&0xFF, y>>8, y&0xFF };
610
 
611
    ikbd_write(cmd, 6);
612
}
613
 
614
/* Set Y=0 at bottom */
615
void ikbd_mouse_y0_bot(void)
616
{
617
    static const char cmd[1] = { 0x0F };
618
 
619
    ikbd_write(cmd, 1);
620
}
621
 
622
/* Set Y=0 at top */
623
void ikbd_mouse_y0_top(void)
624
{
625
    static const char cmd[1] = { 0x10 };
626
 
627
    ikbd_write(cmd, 1);
628
}
629
 
630
/* Resume */
631
void ikbd_resume(void)
632
{
633
    static const char cmd[1] = { 0x11 };
634
 
635
    ikbd_write(cmd, 1);
636
}
637
 
638
/* Disable mouse */
639
void ikbd_mouse_disable(void)
640
{
641
    static const char cmd[1] = { 0x12 };
642
 
643
    ikbd_write(cmd, 1);
644
}
645
 
646
/* Pause output */
647
void ikbd_pause(void)
648
{
649
    static const char cmd[1] = { 0x13 };
650
 
651
    ikbd_write(cmd, 1);
652
}
653
 
654
/* Set joystick event reporting */
655
void ikbd_joystick_event_on(void)
656
{
657
    static const char cmd[1] = { 0x14 };
658
 
659
    ikbd_write(cmd, 1);
660
}
661
 
662
/* Set joystick interrogation mode */
663
void ikbd_joystick_event_off(void)
664
{
665
    static const char cmd[1] = { 0x15 };
666
 
667
    ikbd_write(cmd, 1);
668
}
669
 
670
/* Joystick interrogation */
671
void ikbd_joystick_get_state(void)
672
{
673
    static const char cmd[1] = { 0x16 };
674
 
675
    ikbd_write(cmd, 1);
676
}
677
 
678
#if 0
679
/* This disables all other ikbd activities !!!! */
680
/* Set joystick monitoring */
681
void ikbd_joystick_monitor(int rate)
682
{
683
    static const char cmd[2] = { 0x17, rate };
684
 
685
    ikbd_write(cmd, 2);
686
 
687
    kb_state.state = JOYSTICK_MONITOR;
688
}
689
#endif
690
 
691
/* some joystick routines not in yet (0x18-0x19) */
692
 
693
/* Disable joysticks */
694
void ikbd_joystick_disable(void)
695
{
696
    static const char cmd[1] = { 0x1A };
697
 
698
    ikbd_write(cmd, 1);
699
}
700
 
701
/* Time-of-day clock set */
702
void ikbd_clock_set(int year, int month, int day, int hour, int minute, int second)
703
{
704
    char cmd[7] = { 0x1B, year, month, day, hour, minute, second };
705
 
706
    ikbd_write(cmd, 7);
707
}
708
 
709
/* Interrogate time-of-day clock */
710
void ikbd_clock_get(int *year, int *month, int *day, int *hour, int *minute, int second)
711
{
712
    static const char cmd[1] = { 0x1C };
713
 
714
    ikbd_write(cmd, 1);
715
}
716
 
717
/* Memory load */
718
void ikbd_mem_write(int address, int size, char *data)
719
{
720
    panic("Attempt to write data into keyboard memory");
721
}
722
 
723
/* Memory read */
724
void ikbd_mem_read(int address, char data[6])
725
{
726
    char cmd[3] = { 0x21, address>>8, address&0xFF };
727
 
728
    ikbd_write(cmd, 3);
729
 
730
    /* receive data and put it in data */
731
}
732
 
733
/* Controller execute */
734
void ikbd_exec(int address)
735
{
736
    char cmd[3] = { 0x22, address>>8, address&0xFF };
737
 
738
    ikbd_write(cmd, 3);
739
}
740
 
741
/* Status inquiries (0x87-0x9A) not yet implemented */
742
 
743
/* Set the state of the caps lock led. */
744
void atari_kbd_leds (unsigned int leds)
745
{
746
    char cmd[6] = {32, 0, 4, 1, 254 + ((leds & 4) != 0), 0};
747
    ikbd_write(cmd, 6);
748
}
749
 
750
/*
751
 * The original code sometimes left the interrupt line of
752
 * the ACIAs low forever. I hope, it is fixed now.
753
 *
754
 * Martin Rogge, 20 Aug 1995
755
 */
756
 
757
int atari_keyb_init(void)
758
{
759
    /* setup key map */
760
    key_maps[0]  = ataplain_map;
761
    key_maps[1]  = atashift_map;
762
    key_maps[2]  = 0; /* ataaltgr_map */
763
    key_maps[4]  = atactrl_map;
764
    key_maps[5]  = atashift_ctrl_map;
765
    key_maps[8]  = ataalt_map;
766
    key_maps[9]  = atashift_alt_map;
767
    key_maps[12] = atactrl_alt_map;
768
    key_maps[13] = atashift_ctrl_alt_map;
769
    memcpy (plain_map, ataplain_map, sizeof(plain_map));
770
    keymap_count = 8;
771
 
772
    /* say that we don't have an AltGr key */
773
    mach_keyboard_type = KB_84;
774
 
775
    kb_state.state = KEYBOARD;
776
    kb_state.len = 0;
777
 
778
    add_isr(IRQ_MFP_ACIA, keyboard_interrupt, IRQ_TYPE_SLOW, NULL,
779
            "keyboard/mouse/MIDI");
780
 
781
    atari_turnoff_irq(IRQ_MFP_ACIA);
782
    do {
783
        acia.key_ctrl = ACIA_RESET;             /* reset ACIA */
784
        (void)acia.key_ctrl;
785
        (void)acia.key_data;
786
 
787
        acia.mid_ctrl = ACIA_RESET;             /* reset other ACIA */
788
        (void)acia.mid_ctrl;
789
        (void)acia.mid_data;
790
 
791
        /* divide 500kHz by 64 gives 7812.5 baud */
792
        /* 8 data no parity 1 start 1 stop bit */
793
        /* receive interrupt enabled */
794
#ifdef KEYB_WRITE_INTERRUPT
795
        /* RTS low, transmit interrupt enabled */
796
        if (ovsc_switchmode == 1)
797
            acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RHTIE|ACIA_RIE);
798
            /* switch on OverScan via keyboard ACIA */
799
        else
800
            acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RLTIE|ACIA_RIE);
801
#else
802
        /* RTS low, transmit interrupt disabled */
803
        if (ovsc_switchmode == 1)
804
            acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RHTID|ACIA_RIE);
805
        else
806
            acia.key_ctrl = (ACIA_DIV64|ACIA_D8N1S|ACIA_RLTID|ACIA_RIE);
807
#endif
808
 
809
        acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S;
810
    }
811
    /* make sure the interrupt line is up */
812
    while ((mfp.par_dt_reg & 0x10) == 0);
813
 
814
    /* enable ACIA Interrupts */
815
    mfp.active_edge &= ~0x10;
816
    atari_turnon_irq(IRQ_MFP_ACIA);
817
 
818
    ikbd_reset();
819
    ikbd_mouse_disable();
820
    ikbd_joystick_disable();
821
 
822
    atari_joystick_init();
823
 
824
    return 0;
825
}
826
 
827
 
828
int atari_kbdrate( struct kbd_repeat *k )
829
 
830
{
831
        if (k->delay > 0) {
832
                /* convert from msec to jiffies */
833
                key_repeat_delay = (k->delay * HZ + 500) / 1000;
834
                if (key_repeat_delay < 1)
835
                        key_repeat_delay = 1;
836
        }
837
        if (k->rate > 0) {
838
                key_repeat_rate = (k->rate * HZ + 500) / 1000;
839
                if (key_repeat_rate < 1)
840
                        key_repeat_rate = 1;
841
        }
842
 
843
        k->delay = key_repeat_delay * 1000 / HZ;
844
        k->rate  = key_repeat_rate  * 1000 / HZ;
845
 
846
        return( 0 );
847
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.