|
|
1.1 root 1: /* netboot
2: *
3: * kbd.c,v
4: * Revision 1.1 1993/07/08 16:04:00 brezak
5: * Diskless boot prom code from Jim McKim ([email protected])
6: *
7: * Revision 1.2 1993/06/30 20:16:13 mckim
8: * Clean up compiler error msg.
9: *
10: * Revision 1.1.1.1 1993/05/28 11:41:07 mckim
11: * Initial version.
12: *
13: *
14: * source in this file came from
15: * the original 386BSD boot blocks.
16: *
17: * Copyright (c) 1990 The Regents of the University of California.
18: * All rights reserved.
19: *
20: * This code is derived from software contributed to Berkeley by
21: * William Jolitz.
22: *
23: * Redistribution and use in source and binary forms, with or without
24: * modification, are permitted provided that the following conditions
25: * are met:
26: * 1. Redistributions of source code must retain the above copyright
27: * notice, this list of conditions and the following disclaimer.
28: * 2. Redistributions in binary form must reproduce the above copyright
29: * notice, this list of conditions and the following disclaimer in the
30: * documentation and/or other materials provided with the distribution.
31: * 3. All advertising materials mentioning features or use of this software
32: * must display the following acknowledgement:
33: * This product includes software developed by the University of
34: * California, Berkeley and its contributors.
35: * 4. Neither the name of the University nor the names of its contributors
36: * may be used to endorse or promote products derived from this software
37: * without specific prior written permission.
38: *
39: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
40: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
42: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
43: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
44: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
45: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
47: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
48: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49: * SUCH DAMAGE.
50: *
51: * @(#)kbd.c 7.4 (Berkeley) 5/4/91
52: */
53:
54: #include "proto.h"
55:
56: #define KBSTATP 0x64 /* kbd status port */
57: #define KBS_INP_BUF_FUL 0x02 /* kbd char ready */
58: #define KBDATAP 0x60 /* kbd data port */
59:
60: #define K_RDWR 0x60 /* keyboard data & cmds (read/write) */
61: #define K_STATUS 0x64 /* keyboard status */
62: #define K_CMD 0x64 /* keybd ctlr command (write-only) */
63:
64: #define K_OBUF_FUL 0x01 /* output buffer full */
65: #define K_IBUF_FUL 0x02 /* input buffer full */
66:
67: #define KC_CMD_WIN 0xd0 /* read output port */
68: #define KC_CMD_WOUT 0xd1 /* write output port */
69: #define KB_A20 0x9f /* enable A20,
70: enable output buffer full interrupt
71: enable data line
72: disable clock line */
73:
74: #define L 0x01 /* locking function */
75: #define SHF 0x02 /* keyboard shift */
76: #define ALT 0x04 /* alternate shift -- alternate chars */
77: #define NUM 0x08 /* numeric shift cursors vs. numeric */
78: #define CTL 0x10 /* control shift -- allows ctl function */
79: #define CPS 0x20 /* caps shift -- swaps case of letter */
80: #define ASCII 0x40 /* ascii code for this key */
81: #define STP 0x80 /* stop output */
82:
83: static u_char action[128] = {
84: 0, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 0- 7 */
85: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 8-15 */
86: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 16-23 */
87: ASCII, ASCII, ASCII, ASCII, ASCII, CTL, ASCII, ASCII, /* scan 24-31 */
88: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 32-39 */
89: ASCII, ASCII, SHF , ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 40-47 */
90: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, SHF, ASCII, /* scan 48-55 */
91: ALT, ASCII, CPS|L, 0, 0, ASCII, 0, 0, /* scan 56-63 */
92: 0, 0, 0, 0, 0, NUM|L, STP|L, ASCII, /* scan 64-71 */
93: ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, /* scan 72-79 */
94: ASCII, ASCII, ASCII, ASCII, 0, 0, 0, 0, /* scan 80-87 */
95: 0,0,0,0,0,0,0,0,
96: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
97: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
98:
99: static u_char unshift[128] = { /* no shift */
100: 0, 033 , '1' , '2' , '3' , '4' , '5' , '6' , /* scan 0- 7 */
101: '7' , '8' , '9' , '0' , '-' , '=' , 0177 ,'\t' , /* scan 8-15 */
102:
103: 'q' , 'w' , 'e' , 'r' , 't' , 'y' , 'u' , 'i' , /* scan 16-23 */
104: 'o' , 'p' , '[' , ']' , '\r' , CTL , 'a' , 's' , /* scan 24-31 */
105:
106: 'd' , 'f' , 'g' , 'h' , 'j' , 'k' , 'l' , ';' , /* scan 32-39 */
107: '\'' , '`' , SHF , '\\' , 'z' , 'x' , 'c' , 'v' , /* scan 40-47 */
108:
109: 'b' , 'n' , 'm' , ',' , '.' , '/' , SHF , '*', /* scan 48-55 */
110: ALT , ' ' , CPS|L, 0, 0, ' ' , 0, 0, /* scan 56-63 */
111:
112: 0, 0, 0, 0, 0, NUM|L, STP|L, '7', /* scan 64-71 */
113: '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */
114:
115: '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */
116: 0,0,0,0,0,0,0,0,
117: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
118: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
119:
120: static u_char shift[128] = { /* shift shift */
121: 0, 033 , '!' , '@' , '#' , '$' , '%' , '^' , /* scan 0- 7 */
122: '&' , '*' , '(' , ')' , '_' , '+' , 0177 ,'\t' , /* scan 8-15 */
123: 'Q' , 'W' , 'E' , 'R' , 'T' , 'Y' , 'U' , 'I' , /* scan 16-23 */
124: 'O' , 'P' , '[' , ']' , '\r' , CTL , 'A' , 'S' , /* scan 24-31 */
125: 'D' , 'F' , 'G' , 'H' , 'J' , 'K' , 'L' , ':' , /* scan 32-39 */
126: '"' , '~' , SHF , '|' , 'Z' , 'X' , 'C' , 'V' , /* scan 40-47 */
127: 'B' , 'N' , 'M' , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */
128: ALT , ' ' , CPS|L, 0, 0, ' ' , 0, 0, /* scan 56-63 */
129: 0, 0, 0, 0, 0, NUM|L, STP|L, '7', /* scan 64-71 */
130: '8', '9', '-', '4', '5', '6', '+', '1', /* scan 72-79 */
131: '2', '3', '0', '.', 0, 0, 0, 0, /* scan 80-87 */
132: 0,0,0,0,0,0,0,0,
133: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
134: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
135:
136: static u_char ctl[128] = { /* CTL shift */
137: 0, 033 , '!' , 000 , '#' , '$' , '%' , 036 , /* scan 0- 7 */
138: '&' , '*' , '(' , ')' , 037 , '+' , 034 ,'\177', /* scan 8-15 */
139: 021 , 027 , 005 , 022 , 024 , 031 , 025 , 011 , /* scan 16-23 */
140: 017 , 020 , 033 , 035 , '\r' , CTL , 001 , 013 , /* scan 24-31 */
141: 004 , 006 , 007 , 010 , 012 , 013 , 014 , ';' , /* scan 32-39 */
142: '\'' , '`' , SHF , 034 , 032 , 030 , 003 , 026 , /* scan 40-47 */
143: 002 , 016 , 015 , '<' , '>' , '?' , SHF , '*', /* scan 48-55 */
144: ALT , ' ' , CPS|L, 0, 0, ' ' , 0, 0, /* scan 56-63 */
145: CPS|L, 0, 0, 0, 0, 0, 0, 0, /* scan 64-71 */
146: 0, 0, 0, 0, 0, 0, 0, 0, /* scan 72-79 */
147: 0, 0, 0, 0, 0, 0, 0, 0, /* scan 80-87 */
148: 0, 0, 033, '7' , '4' , '1' , 0, NUM|L, /* scan 88-95 */
149: '8' , '5' , '2' , 0, STP|L, '9' , '6' , '3' , /*scan 96-103*/
150: '.' , 0, '*' , '-' , '+' , 0, 0, 0, /*scan 104-111*/
151: 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, } ;
152:
153: static u_char shfts, ctls, alts, caps, num, stp;
154: static u_char chr;
155: static int is_chr_queued = 0;
156:
157: static int
158: ProcessKbdEvent(void) {
159: /* Returns 1 if event result is an ascii char, 0 otherwise (or no event).
160: * As a side effect, it digests keyboard events and queues bona fide
161: * characters for subsequent reading.
162: */
163: u_char dt, brk, act;
164: if ((inb(KBSTATP) & 0x01) == 0)
165: return is_chr_queued;
166: dt = inb(KBDATAP);
167: brk = dt & 0x80;
168: dt = dt & 0x7f;
169:
170: act = action[dt];
171: if (act & SHF) {
172: if (brk)
173: shfts = 0;
174: else
175: shfts = 1;
176: }
177: if (act & ALT) {
178: if (brk)
179: alts = 0;
180: else
181: alts = 1;
182: }
183: if (act & NUM) {
184: if (act & L) {
185: if (!brk)
186: num ^= 1;
187: } else
188: if(brk)
189: num = 0;
190: else
191: num = 1;
192: }
193: if (act & CTL) {
194: if (brk)
195: ctls = 0;
196: else
197: ctls = 1;
198: }
199: if (act & CPS) {
200: if (act & L) {
201: if (!brk)
202: caps ^= 1;
203: } else
204: if (brk)
205: caps = 0;
206: else
207: caps = 1;
208: }
209: if (act & STP) {
210: if (act & L) {
211: if (!brk)
212: stp ^= 1;
213: } else
214: if (brk)
215: stp = 0;
216: else
217: stp = 1;
218: }
219: if (ctls && alts && dt == 83)
220: exit(1);
221: if ((act & ASCII) && !brk) {
222: if (shfts) {
223: chr = shift[dt];
224: } else {
225: if (ctls) {
226: chr = ctl[dt];
227: } else {
228: chr = unshift[dt];
229: }
230: }
231: if (caps && (chr >= 'a' && chr <= 'z')) {
232: chr -= 'a' - 'A' ;
233: }
234: is_chr_queued = 1;
235: }
236: return is_chr_queued;
237: }
238:
239: int
240: IsKbdCharReady(void) {
241: #ifdef USE_BIOS
242: int result;
243: asm("
244: push %%ebx
245: call _prot_to_real
246: mov $1, %%ax
247: int $0x16
248: setz %%bl
249: .byte 0x66
250: call _real_to_prot
251: movsbl %%bl, %0
252: pop %%ebx
253: " : "=g" (result));
254: return result;
255: #else
256: return ProcessKbdEvent();
257: #endif
258: }
259:
260: static int
261: scankbd(void) {
262:
263: #ifdef notdef
264: u_char c;
265: c = inb(KBDATAP);
266: if (c == 83) exit();
267: /*if (c == 0xaa) return (0);
268: if (c == 0xfa) return (0);*/
269:
270: if (bdt == 0) { bdt = c&0x7f; return(0); }
271:
272: if(odt) return(1);
273:
274: c &= 0x7f;
275:
276: if (bdt == c) return(0);
277: odt = c;
278: #endif
279: return 1;
280: }
281:
282: static void
283: kbdreset(void) {
284: u_char c;
285:
286: /* Enable interrupts and keyboard controller */
287: while (inb(KBSTATP)&2); outb(KBSTATP,0x60);
288: while (inb(KBSTATP)&2); outb(KBDATAP,0x4D);
289:
290: /* Start keyboard stuff RESET */
291: while (inb(KBSTATP)&2); /* wait input ready */
292: outb(KBDATAP,0xFF); /* RESET */
293:
294: while((c=inb(KBDATAP))!=0xFA) ;
295:
296: /* While we are here, defeat gatea20 */
297: while (inb(KBSTATP)&2); /* wait input ready */
298: outb(KBSTATP,0xd1);
299: while (inb(KBSTATP)&2); /* wait input ready */
300: outb(KBDATAP,0xdf);
301: while (inb(KBSTATP)&2); /* wait input ready */
302: inb(KBDATAP);
303: }
304:
305: /* TBD - what does this do?, used by ResetCpu() */
306: void
307: KbdWait(int n) {
308: int v;
309:
310: v = 0;
311: while(n-- && (v = scankbd()) == 0);
312: if (v) kbdreset();
313: }
314:
315: /*
316: * Gate A20 for high memory
317: */
318: u_char x_20 = KB_A20;
319:
320: void
321: gateA20(void) {
322: while (inb(K_STATUS) & K_IBUF_FUL);
323: while (inb(K_STATUS) & K_OBUF_FUL)
324: (void)inb(K_RDWR);
325:
326: outb(K_CMD, KC_CMD_WOUT);
327: while (inb(K_STATUS) & K_IBUF_FUL);
328: outb(K_RDWR, x_20);
329: while (inb(K_STATUS) & K_IBUF_FUL);
330: }
331:
332: int
333: getc(void) {
334: #ifdef USE_BIOS
335: int rslt;
336: asm("
337: push %%ebx
338: call _prot_to_real
339: movb $0x0, %%ah
340: sti
341: int $0x16
342: cli
343: movb %%al, %%bl
344: .byte 0x66
345: call _real_to_prot
346: xor %%eax, %%eax
347: movb %%bl, %0
348: pop %%ebx
349: " : "=g" (rslt));
350: return rslt;
351: #else
352: while (!is_chr_queued) {
353: ProcessKbdEvent();
354: }
355: is_chr_queued = 0;
356: return chr;
357: #endif
358: }
359:
360: int
361: getchar(void) {
362: int c;
363:
364: if ((c=getc()) == '\r')
365: c = '\n';
366: if (c == '\b') {
367: putchar('\b');
368: putchar(' ');
369: }
370: putchar(c);
371: return c;
372: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.