|
|
1.1 root 1: #include <jerq.h>
2: #include "queue.h"
3: #include <kbd.h>
4: #include <setup.h>
5:
6: #define ESC '\033'
7: #define ESCB 0200
8: #define DEL '\177'
9: #define K_KEY 0
10: #define K_CHAR 1
11:
12: /*
13: * Note that the keypad keys send what they say.
14: * the arrows send 'escape [' followed by A, B, C, D, H, except for HOME DOWN,
15: * which sends (ugh) esc [ 70;0H. Clear sends esc[0J,
16: * Break, disconnect, and the pf keys send codes 0x80 through 0x89 respectively.
17: * If you want to tell the keypad numbers from the real ones, work in raw.
18: * The keytab table has been drastically extended for the TTYKBD and
19: * a binary search is now used. Why could'nt they generate sane codes!!
20: * WARNING, the keytab entries must be sorted into ascending order!
21: * For any ordinary "key", char c is sent. The arrow keys or 0x80 with
22: * the ascii letter needed to send, except for HOME DOWN. HOME DOWN
23: * and Clear are done by 0x8a and 0x8b, respectively, and break,
24: * disconnect and pfkeys are entered as shown above.
25: */
26:
27: unsigned char keytab[][2] = {
28: 0x8f, 0x81, /* shifted key 42, discon */
29: 0x90, ESCB | 'B', /* shifted key 109, down arrow */
30: 0x91, ESCB | 'H', /* shifted key 97, left-up arrow */
31: 0x92, ESCB | 'A', /* shifted key 98, up arrow */
32: 0x93, ESCB | 0xa, /* shifted key 99, home down arrow */
33: 0x94, '4', /* shifted key 79, 4 */
34: 0x95, '5', /* shifted key 80, 5 */
35: 0x96, '6', /* shifted key 81, 6 */
36: 0x97, '7', /* shifted key 60, 7 */
37: 0x98, '8', /* shifted key 61, 8 */
38: 0x99, '9', /* shifted key 62, 9 */
39: 0x9a, ESCB | 'D', /* shifted key 108, left arrow */
40: 0x9b, ESCB | 'C', /* shifted key 110, right arrow */
41: 0xaf, 0x80, /* unshifted key 42, break */
42: 0xb0, '\0', /* control key 35, ignored */
43: 0xb1, '\0', /* control key 26, ignored */
44: 0xb3, '\0', /* control key 28, ignored */
45: 0xb4, '\0', /* control key 29, ignored */
46: 0xb5, '\0', /* control key 30, ignored */
47: 0xb6, '\012', /* unshifted key 96, line-feed */
48: 0xb7, '\0', /* control key 32, ignored */
49: 0xb8, '\0', /* control key 33, ignored */
50: 0xb9, '\0', /* control key 34, ignored */
51: 0xba, '\0', /* control key 27, ignored */
52: 0xbb, '\0', /* control key 75, ignored */
53: 0xbc, '\0', /* control key 31, ignored */
54: 0xbd, '\0', /* control key 37, ignored */
55: 0xbe, '\0', /* control key 59, ignored */
56: 0xbf, '\0', /* control key 36, ignored */
57: 0xc0, ESCB | 'H', /* unshifted key 97, left-up arrow */
58: 0xc1, ESCB | 'A', /* unshifted key 98, up arrow */
59: 0xc2, ESCB | 'B', /* unshifted key 109, down arrow */
60: 0xc3, ESCB | 'C', /* unshifted key 110, right arrow */
61: 0xc4, ESCB | 'D', /* unshifted key 108, left arrow */
62: 0xc6, ESCB | 0xa, /* unshifted key 99, home down arrow */
63: 0xc7, '\r', /* shifted key 77, return */
64: 0xc8, ESCB | 2, /* shifted key 3, f1 */
65: 0xc9, ESCB | 3, /* shifted key 4, f2 */
66: 0xca, ESCB | 4, /* shifted key 5, f3 */
67: 0xcb, ESCB | 5, /* shifted key 8, f4 */
68: 0xcc, ESCB | 6, /* shifted key 9, f5 */
69: 0xcd, ESCB | 7, /* shifted key 12, f6 */
70: 0xce, ESCB | 8, /* shifted key 13, f7 */
71: 0xcf, ESCB | 9, /* shifted key 14, f8 */
72: 0xd0, '\t', /* unshifted key 45, tab */
73: 0xd1, '\b', /* shifted key 38, bs */
74: 0xd2, '7', /* unshifted key 60, 7 */
75: 0xd3, '4', /* unshifted key 79, 4 */
76: 0xd4, '8', /* unshifted key 61, 8 */
77: 0xd5, '5', /* unshifted key 80, 5 */
78: 0xd6, '9', /* unshifted key 62, 9 */
79: 0xd7, '6', /* unshifted key 81, 6 */
80: 0xde, DEL, /* shifted key 39, del */
81: 0xe2, '\0', /* control key 76, */
82: 0xe3, ESC, /* unshifted key 25, esc */
83: 0xe5, ESCB | 0xb, /* unshifted key 40, clr */
84: 0xe7, '\r', /* unshifted key 77, return */
85: 0xe8, ESCB | 2, /* unshifted key 3, f1 */
86: 0xe9, ESCB | 3, /* unshifted key 4, f2 */
87: 0xea, ESCB | 4, /* unshifted key 5, f3 */
88: 0xeb, ESCB | 5, /* unshifted key 8, f4 */
89: 0xec, ESCB | 6, /* unshifted key 9, f5 */
90: 0xed, ESCB | 7, /* unshifted key 12, f6 */
91: 0xee, ESCB | 8, /* unshifted key 13, f7 */
92: 0xef, ESCB | 9, /* unshifted key 14, f8 */
93: 0xf0, '\t', /* shifted key 45, tab */
94: 0xf1, '\b', /* unshifted key 38, bs */
95: 0xf2, '\0', /* shifted key 107, num-lock */
96: 0xf3, ESC, /* shifted key 25, esc */
97: 0xf5, ESCB | 0xc, /* shifted key 40, local clear functin */
98: 0xf6, '\n', /* shifted key 96, line-feed */
99: 0xfe, DEL, /* unshifted key 39, del */
100: };
101:
102:
103: int kbdrepeat, rptcount, kbdstatus, dispstatus;
104:
105: /* lookup table for translating when keyboard uses numeric lock */
106: unsigned char numlocktab[7] = {'1','2','0','.','-',0xc5,'3'};
107:
108: kbdchar()
109: {
110: return qgetc(&KBDQUEUE);
111: }
112:
113:
114: kbdinit()
115: {
116: /* init the keyboard */
117: DUART->b_cmnd = RESET_RECV | DIS_TX | DIS_RX;
118: DUART->b_cmnd = RESET_TRANS;
119: DUART->b_cmnd = RESET_ERR;
120: DUART->b_cmnd = RESET_MR;
121: DUART->mr1_2b = CHAR_ERR | PAR_ENB | EVN_PAR | CBITS8;
122: DUART->mr1_2b = NRML_MOD | ONEP000SB;
123: DUART->b_sr_csr = BD4800BPS;
124: DUART->b_cmnd = RESET_MR | ENB_TX | ENB_RX;
125: DUART->scc_ropbc = 0x08; /* set output pins for kbd tx port*/
126: /* turn chirps on/off depending on BRAM */
127:
128: if (VALKEYTONE)
129: kbdstatus = 0; /* no chirp */
130: else
131: kbdstatus = TTY_CHIRP; /* chirp, chirp */
132: DUART->b_data = kbdstatus | 0x02; /* request status */
133: }
134:
135: auto2()
136: {
137: register i;
138: register start, end;
139: Point setupcur;
140: char s;
141: char c;
142: extern int blocked, ublocked;
143:
144: /* don't actually set the repeat bit until the character after the control code */
145:
146: s = DUART->b_sr_csr;
147: c = DUART->b_data;
148:
149: if (s & (FRM_ERR | OVR_RUN))
150: return; /* framing error or overrun error */
151:
152: if (s & PAR_ERR) {
153: /* parity error indicates this is a control word */
154: /* see what state caps lock is in */
155: checkbram();
156: VALCAPS = (c & 0x4) ? 0 : 1; /* set the caps lock flag */
157: caps_msg();
158: setbram(); /* must adjust checksum */
159: if (c & 0x10) {
160: /* turn repeat off */
161: kbdrepeat = 0;
162: rptcount = 0;
163: }
164: else { /* turn repeat on, the next character is to be repeated */
165: kbdrepeat = RPTON;
166: }
167: return;
168: }
169:
170: rptcount = 0; /* new charcter so restart repeat timer */
171: if (c & 0x80) {
172: switch (c & 0xff) {
173: case 0xb2: /* numeric lock toggle */
174: case 0xf2:
175: if(kbdrepeat & RPTON) {
176: kbdrepeat = 0; /* don't want to repeat */
177: return;
178: }
179: checkbram();
180: VALNUM = 1 - VALNUM;
181: setbram();
182: num_msg();
183: return;
184: case 0x8e: /* un/shited key 41, selftest */
185: test32(1);
186: asm(" JMP reboot");
187: case 0xae: /* setup */
188: if(kbdrepeat & RPTON) {
189: kbdrepeat = 0; /* don't want to repeat */
190: return;
191: }
192: if(!ublocked && !blocked && !VALDWNLDFLAG)
193: sendchar(0x13); /* ^S */
194: setupdisplay();
195: if(!ublocked && !blocked && !VALDWNLDFLAG)
196: sendchar(0x11); /* ^Q */
197: return;
198: }
199: if ((VALNUM) && (c >= 0xc0) && (c <= 0xc6)) {
200: /* what fun: software lookup of numeric */
201: /* locked values... why burden the hardware */
202: c = numlocktab[c - 0xc0];
203: qputc(&KBDQUEUE, (int)c);
204: if((kbdrepeat & RPTMASK) == RPTON) {
205: kbdrepeat = RPTHAVECHR | RPTON;
206: kbdrepeat += (c & 0xff);
207: }
208: return;
209: }
210:
211: i = keytabsearch(c);
212: /*
213: * here either keytab[i][K_KEY] == c, or c is not in the table
214: * If c is not in the table, there is an error somewhere, so ring the bell
215: */
216: if (c == keytab[i][K_KEY]) {
217: if(((c = (keytab[i][K_CHAR]) & 0xff) >= 0x80) && (c <= 0x89)) /* pfkey, break, disconnect, clear */
218: {
219: if(kbdrepeat & RPTON) {
220: kbdrepeat = 0; /* don't want to repeat */
221: return;
222: }
223: qputc( &KBDQUEUE, c );
224: return;
225: }
226: kchkchar(c);
227: if ((kbdrepeat & RPTMASK) == RPTON) {
228: /* this is it! */
229: kbdrepeat = RPTHAVECHR | RPTON | RPTLOOKUP;
230: kbdrepeat += i;
231: }
232: }
233: else {
234: ringbell();
235: }
236: }
237: else {
238: qputc(&KBDQUEUE, (int)c);
239: if((kbdrepeat & RPTMASK) == RPTON) {
240: kbdrepeat = RPTHAVECHR | RPTON;
241: kbdrepeat += (c & 0xff);
242: }
243: }
244: }
245:
246:
247:
248: kchkchar(c)
249: register char c;
250: {
251: switch (c & 0xff) {
252: case 0x8a: /* HOME DOWN */
253: qputstr( &KBDQUEUE, "\033[70;1H");
254: break;
255: case 0x8b: /* CLEAR */
256: if(kbdrepeat & RPTON) { /* turn off repeat */
257: kbdrepeat = 0;
258: return;
259: }
260: qputstr( &KBDQUEUE, "\033[2J");
261: break;
262: case 0x8c: /* local clear function */
263: if(kbdrepeat & RPTON) {
264: kbdrepeat = 0;
265: return;
266: }
267: else
268: qputc(&KBDQUEUE, c);
269: break;
270: case 0x80 | 'A':
271: case 0x80 | 'B':
272: case 0x80 | 'C':
273: case 0x80 | 'D':
274: case 0x80 | 'H':
275: qputstr( &KBDQUEUE, "\033[");
276: qputc( &KBDQUEUE, c & 0x7f);
277: break;
278: default:
279: if (c != '\0')
280: qputc(&KBDQUEUE, (int)c);
281: }
282: }
283:
284:
285: kbdrpt()
286: {
287: char c;
288:
289: if (kbdrepeat & RPTLOOKUP) {
290: if ((c = keytab[kbdrepeat & 0xff][K_CHAR]) & 0x80) {
291: kchkchar(c);
292: }
293: else if (c != '\0') {
294: qputc(&KBDQUEUE, (int)c);
295: }
296: }
297: else {
298: qputc(&KBDQUEUE, kbdrepeat & 0xff);
299: }
300: }
301:
302:
303:
304: kgetc()
305: {
306: register int c;
307: register char s;
308: register start, end, i;
309:
310: if(KBDQUEUE.c_cc > 0)
311: return(qgetc(&KBDQUEUE));
312:
313: while ((s = (DUART->b_sr_csr & (RCV_RDY | FRM_ERR | PAR_ERR | OVR_RUN | RCVD_BRK))) == 0)
314: aciapaws(); /* so we don't overload stupid part */
315:
316: if (!(s & RCV_RDY))
317: return(-1);
318: c = DUART->b_data;
319: if ((s & (FRM_ERR | PAR_ERR | OVR_RUN | RCVD_BRK)) == 0) /* just a char */
320: {
321: if(kbdrepeat & RPTON) {
322: kbdrepeat = 0; /* turn off repeat */
323: return(-1);
324: }
325: if (c & 0x80) {
326: switch (c & 0xff) {
327: case 0x8e: /* un/shited key 41, selftest */
328: test32(1);
329: case 0x8f: /* shift break (disconnect) reboot the terminal */
330: sendchar(0x11); /* cntl-Q */
331: asm(" JMP reboot");
332: case 0xae: /* setup */
333: case 0xc3: /* right-arrow */
334: case 0xc4: /* left-arrow */
335: return(c);
336: case 0xb2:
337: case 0xf2: /* num lock key */
338: VALNUM= 1 - VALNUM;
339: setbram();
340: num_setup();
341: return(-1);
342: }
343: i = keytabsearch(c);
344: /*
345: * here either keytab[i][K_KEY] == c, or c is not in the table
346: * If c is not in the table, there is an error somewhere, so ring the bell
347: */
348: if (c == keytab[i][K_KEY]) {
349: if (((c = keytab[i][K_CHAR]) & 0xff) <= 0x89 ) /* pfkey, break, disconnect */
350: return(c);
351: kchkchar(c);
352: return(-1);
353: }
354: }
355: else
356: return(c);
357: }
358: else if ((s & PAR_ERR) && (s & RCV_RDY))
359: {
360: VALCAPS = (c & 0x4) ? 0 : 1; /* set the caps lock flag */
361: cap_setup();
362: setbram(); /* fix checksum */
363: if(c & 0x10) {
364: /* not repeating anything */
365: kbdrepeat = 0;
366: rptcount = 0;
367: }
368: else {
369: /*
370: * the keyboard will send us a character to repeat
371: * since we dont repeat in setup, throw the next
372: * character away.
373: */
374: kbdrepeat = RPTON;
375: }
376: }
377: return(-1);
378: }
379:
380: keytabsearch(c) /* search keytab[] for char c */
381: unsigned char c;
382: {
383: register int start, end, i;
384: /*
385: * Assume start, end and i are indexes into keytab,
386: * an array of two element structures. The elements are:
387: * keytab[][2], the two elements are:
388: * char key;
389: * char c; /* the char to send, 0 - not sent
390: * }
391: */
392:
393: start = 0;
394: end = sizeof(keytab) / sizeof(keytab[0]);
395: for (i = (start + end) / 2;
396: (keytab[i][K_KEY] != c) && (start <= end);
397: i = (start + end) / 2)
398: if (c > keytab[i][K_KEY])
399: start = i + 1;
400: else
401: end = i - 1;
402:
403: return (i);
404: /*
405: * here either keytab[i][K_KEY] == c, or c is not in the table
406: * If c is not in the table, there is an error somewhere, so ring the bell
407: * (bell gets rung by caller)
408: */
409: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.