1 /* pro_lk201.c: keyboard
2 
3    Copyright (c) 1997-2003, Tarik Isani (xhomer@isani.org)
4 
5    This file is part of Xhomer.
6 
7    Xhomer is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License version 2
9    as published by the Free Software Foundation.
10 
11    Xhomer is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with Xhomer; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20 
21 
22 /* TBD:
23 		-MANY keyboard commands are ignored
24 		-only PF1..4 (ctrl-F1..F4) are implemented on keypad
25 */
26 
27 #ifdef PRO
28 #include "pdp11_defs.h"
29 #include "pro_lk201.h"
30 
31 #define	PRO_LK201_FIFO_DEPTH	1024
32 
33 /* Keyboard code entry points */
34 
35 struct sercall pro_lk201 = {&pro_lk201_get, &pro_lk201_put,
36 	                    &pro_lk201_ctrl_get, &pro_lk201_ctrl_put,
37 	                    &pro_lk201_reset, &pro_lk201_exit};
38 
39 LOCAL int	pro_lk201_shift;	/* Tracks whether shift key is depressed */
40 LOCAL int	pro_lk201_ctrl;		/* Tracks whether ctrl key is depressed */
41 LOCAL int	pro_lk201_locked;	/* Tracks whether keyboard is locked */
42 LOCAL int	pro_lk201_bell_dis;	/* Tracks whether bell is disabled */
43 LOCAL int	pro_lk201_click_dis;	/* Tracks whether keyclick is disabled */
44 LOCAL int	pro_lk201_param;	/* Tracks whether next received byte is command or parameter */
45 LOCAL int	pro_lk201_last_cmd;	/* Stores last command */
46 
47 LOCAL int	pro_lk201_fifo_h;
48 LOCAL int	pro_lk201_fifo_t;
49 LOCAL int	pro_lk201_fifo[PRO_LK201_FIFO_DEPTH];
50 
51 
52 /* Put character in keyboard FIFO */
53 
pro_lk201_fifo_put(int key)54 LOCAL void pro_lk201_fifo_put (int key)
55 {
56 	/* XXX First check if FIFO is full */
57 
58 	pro_lk201_fifo[pro_lk201_fifo_h] = key;
59 	pro_lk201_fifo_h++;
60 	if (pro_lk201_fifo_h == PRO_LK201_FIFO_DEPTH)
61 	  pro_lk201_fifo_h = 0;
62 }
63 
64 
65 /* Get character from keyboard FIFO */
66 
pro_lk201_fifo_get()67 LOCAL int pro_lk201_fifo_get ()
68 {
69 	int key;
70 
71 	/* Check if FIFO is empty */
72 
73 	if (pro_lk201_fifo_h == pro_lk201_fifo_t)
74 	  key = PRO_NOCHAR;
75 	else
76 	{
77 	  key = pro_lk201_fifo[pro_lk201_fifo_t];
78 	  pro_lk201_fifo_t++;
79 	  if (pro_lk201_fifo_t == PRO_LK201_FIFO_DEPTH)
80 	    pro_lk201_fifo_t = 0;
81 	}
82 
83 	return key;
84 }
85 
86 
87 /* Get character from keyboard */
88 
pro_lk201_get(int dev)89 int pro_lk201_get (int dev)
90 {
91 int	key;
92 
93 	if (pro_lk201_locked == 0)
94 	{
95 	  key = pro_lk201_fifo_get();
96 
97 	  if (key == PRO_NOCHAR)
98 	  {
99 	    key = pro_keyboard_get();
100 
101 	    if (key != PRO_NOCHAR)
102 	    {
103 	      if (key == PRO_LK201_SHIFT)
104 	        pro_lk201_shift = 1;
105 	      else if (key == PRO_LK201_CTRL)
106 	        pro_lk201_ctrl = 1;
107 	      else if (key == PRO_LK201_ALLUPS)
108 	      {
109 	        pro_lk201_shift = 0;
110 	        pro_lk201_ctrl = 0;
111 	      }
112 	      else if ((key == PRO_LK201_PERIOD) && (pro_lk201_shift == 1))
113 	        key = PRO_LK201_LT;
114 	      else if ((key == PRO_LK201_COMMA) && (pro_lk201_shift == 1))
115 	      {
116 	        key = PRO_LK201_ALLUPS;
117 	        pro_lk201_fifo_put(PRO_LK201_LT);
118 	        pro_lk201_fifo_put(PRO_LK201_SHIFT);
119 	      }
120 	      else if ((key == PRO_LK201_PRINT) && (pro_lk201_ctrl == 1))
121 	      {
122 	        key = PRO_LK201_ALLUPS;
123 	        pro_lk201_fifo_put(PRO_LK201_PF1);
124 	        pro_lk201_fifo_put(PRO_LK201_CTRL);
125 	      }
126 	      else if ((key == PRO_LK201_SETUP) && (pro_lk201_ctrl == 1))
127 	      {
128 	        key = PRO_LK201_ALLUPS;
129 	        pro_lk201_fifo_put(PRO_LK201_PF2);
130 	        pro_lk201_fifo_put(PRO_LK201_CTRL);
131 	      }
132 	      else if ((key == PRO_LK201_FFOUR) && (pro_lk201_ctrl == 1))
133 	      {
134 	        key = PRO_LK201_ALLUPS;
135 	        pro_lk201_fifo_put(PRO_LK201_PF3);
136 	        pro_lk201_fifo_put(PRO_LK201_CTRL);
137 	      }
138 	      else if ((key == PRO_LK201_BREAK) && (pro_lk201_ctrl == 1))
139 	      {
140 	        key = PRO_LK201_ALLUPS;
141 	        pro_lk201_fifo_put(PRO_LK201_PF4);
142 	        pro_lk201_fifo_put(PRO_LK201_CTRL);
143 	      }
144 	      else if ((key == PRO_LK201_INT) && (pro_lk201_ctrl == 1))
145 	      {
146 	        key = PRO_LK201_ALLUPS;
147 	        pro_lk201_fifo_put(PRO_LK201_F17);
148 	        pro_lk201_fifo_put(PRO_LK201_CTRL);
149 	      }
150 	      else if ((key == PRO_LK201_RESUME) && (pro_lk201_ctrl == 1))
151 	      {
152 	        key = PRO_LK201_ALLUPS;
153 	        pro_lk201_fifo_put(PRO_LK201_F18);
154 	        pro_lk201_fifo_put(PRO_LK201_CTRL);
155 	      }
156 	      else if ((key == PRO_LK201_CANCEL) && (pro_lk201_ctrl == 1))
157 	      {
158 	        key = PRO_LK201_ALLUPS;
159 	        pro_lk201_fifo_put(PRO_LK201_F19);
160 	        pro_lk201_fifo_put(PRO_LK201_CTRL);
161 	      }
162 	      else if ((key == PRO_LK201_MAIN) && (pro_lk201_ctrl == 1))
163 	      {
164 	        key = PRO_LK201_ALLUPS;
165 	        pro_lk201_fifo_put(PRO_LK201_F20);
166 	        pro_lk201_fifo_put(PRO_LK201_CTRL);
167 	      }
168 
169 	    }
170 	  }
171 
172 /* XXX
173 	  if (key != PRO_NOCHAR) printf("%d\r\n", key);
174 */
175 	}
176 	else
177 	  key = PRO_NOCHAR;
178 
179 	return key;
180 }
181 
182 
183 /* Send character to keyboard */
184 
pro_lk201_put(int dev,int key)185 int pro_lk201_put (int dev, int key)
186 {
187 	if (pro_lk201_param == 0)
188 	{
189 	  pro_lk201_last_cmd = PRO_LK201_NOCMD;
190 
191 	  switch(key)
192 	  {
193 	    case PRO_LK201_UNLCK:
194 	      pro_lk201_locked = 0;
195 	      break;
196 
197 	    case PRO_LK201_LCK:
198 	      pro_lk201_locked = 1;
199 
200 	      /* Acknowledge keyboard locked command */
201 
202 	      pro_lk201_fifo_put(PRO_LK201_LCK_ACK);
203 	      break;
204 
205 	    case PRO_LK201_CLICK_E:
206 	      pro_lk201_click_dis = 0;
207 	      pro_keyboard_click_on();
208 	      break;
209 
210 	    case PRO_LK201_CLICK_D:
211 	      pro_lk201_click_dis = 1;
212 	      pro_keyboard_click_off();
213 	      break;
214 
215 	    case PRO_LK201_BELL_D:
216 	      pro_lk201_bell_dis = 1;
217 	      break;
218 
219 	    case PRO_LK201_BELL:
220 	      if (pro_lk201_bell_dis == 0)
221 	        pro_keyboard_bell();
222 	      break;
223 
224 	    case PRO_LK201_AUTO_D:
225 	      pro_keyboard_auto_off();
226 	      break;
227 
228 	    case PRO_LK201_AUTO_E:
229 	      pro_keyboard_auto_on();
230 	      break;
231 
232 	    case PRO_LK201_ID:
233 	      /* Send firmware and hardware IDs */
234 
235 	      pro_lk201_fifo_put(PRO_LK201_IDF);
236 	      pro_lk201_fifo_put(PRO_LK201_IDH);
237 	      break;
238 
239 	    case PRO_LK201_PWRUP:
240 	      /* Send firmware and hardware IDs, error codes */
241 
242 	      pro_lk201_fifo_put(PRO_LK201_IDF);
243 	      pro_lk201_fifo_put(PRO_LK201_IDH);
244 	      pro_lk201_fifo_put(PRO_LK201_NOERR);
245 	      pro_lk201_fifo_put(PRO_LK201_NOERR);
246 	      break;
247 
248 	    case PRO_LK201_DECTOUCH:
249 	      /* XXX undocumented DECtouch query command */
250 
251 	      pro_lk201_fifo_put(PRO_LK201_KB);
252 	      break;
253 
254 	    default:
255 	      /* Save potential command for when its parameter is received */
256 
257 	      pro_lk201_last_cmd = key;
258 	      break;
259 	  }
260 	}
261 	else
262 	{
263 	  switch(pro_lk201_last_cmd)
264 	  {
265 	    case PRO_LK201_BELL_E:
266 	      pro_lk201_bell_dis = 0;
267 	      pro_keyboard_bell_vol(key & PRO_LK201_VOL);
268 	      pro_lk201_last_cmd = PRO_LK201_NOCMD;
269 	      break;
270 
271 	    default:
272 	      break;
273 	  }
274 	}
275 
276 	/* Determine whether next byte will be a command or a parameter */
277 
278 	if ((key & PRO_LK201_PARAMS) != 0)
279 	  pro_lk201_param = 0;
280 	else
281 	  pro_lk201_param = 1;
282 
283 /* XXX
284 	printf("Keyboard received code %d\r\n", key);
285 */
286 
287 	return PRO_SUCCESS;
288 }
289 
290 
291 /* Return serial line parameters */
292 
pro_lk201_ctrl_get(int dev,struct serctrl * sctrl)293 void pro_lk201_ctrl_get (int dev, struct serctrl *sctrl)
294 {
295 	/* DSR is hardwired high */
296 
297 	sctrl->dsr = 1;
298 }
299 
300 
301 /* Set serial line parameters */
302 
pro_lk201_ctrl_put(int dev,struct serctrl * sctrl)303 void pro_lk201_ctrl_put (int dev, struct serctrl *sctrl)
304 {
305 }
306 
307 
308 /* Reset keyboard */
309 
pro_lk201_reset(int dev,int portnum)310 void pro_lk201_reset (int dev, int portnum)
311 {
312 	pro_lk201_shift = 0;
313 	pro_lk201_ctrl = 0;
314 	pro_lk201_locked = 0;
315 	pro_lk201_bell_dis = 0;
316 	pro_lk201_click_dis = 0;
317 	pro_lk201_param = 0;
318 	pro_lk201_last_cmd = PRO_LK201_NOCMD;
319 
320 	pro_lk201_fifo_h = 0;
321 	pro_lk201_fifo_t = 0;
322 }
323 
324 
325 /* Exit routine */
326 
pro_lk201_exit(int dev)327 void pro_lk201_exit (int dev)
328 {
329 }
330 #endif
331