]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - sys/boot/i386/common/cons.c
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / sys / boot / i386 / common / cons.c
1 /*-
2  * Copyright (c) 1998 Robert Nordier
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are freely
6  * permitted provided that the above copyright notice and this
7  * paragraph and the following disclaimer are duplicated in all
8  * such forms.
9  *
10  * This software is provided "AS IS" and without any express or
11  * implied warranties, including, without limitation, the implied
12  * warranties of merchantability and fitness for a particular
13  * purpose.
14  */
15
16 #include <sys/cdefs.h>
17 __FBSDID("$FreeBSD$");
18
19 #include <sys/param.h>
20
21 #include <machine/psl.h>
22
23 #include <btxv86.h>
24
25 #include "lib.h"
26 #include "rbx.h"
27 #include "util.h"
28 #include "cons.h"
29
30 #define V86_ZR(x)       ((x) & PSL_Z)
31
32 #define SECOND          18      /* Circa that many ticks in a second. */
33
34 uint8_t ioctrl = IO_KEYBOARD;
35
36 void
37 putc(int c)
38 {
39
40         v86.ctl = V86_FLAGS;
41         v86.addr = 0x10;
42         v86.eax = 0xe00 | (c & 0xff);
43         v86.ebx = 0x7;
44         v86int();
45 }
46
47 void
48 xputc(int c)
49 {
50
51         if (ioctrl & IO_KEYBOARD)
52                 putc(c);
53         if (ioctrl & IO_SERIAL)
54                 sio_putc(c);
55 }
56
57 void
58 putchar(int c)
59 {
60
61         if (c == '\n')
62                 xputc('\r');
63         xputc(c);
64 }
65
66 int
67 getc(int fn)
68 {
69
70         /*
71          * The extra comparison against zero is an attempt to work around
72          * what appears to be a bug in QEMU and Bochs. Both emulators
73          * sometimes report a key-press with scancode one and ascii zero
74          * when no such key is pressed in reality. As far as I can tell,
75          * this only happens shortly after a reboot.
76          */
77         v86.ctl = V86_FLAGS;
78         v86.addr = 0x16;
79         v86.eax = fn << 8;
80         v86int();
81         return fn == 0 ? v86.eax & 0xff : (!V86_ZR(v86.efl) && (v86.eax & 0xff));
82 }
83
84 int
85 xgetc(int fn)
86 {
87
88         if (OPT_CHECK(RBX_NOINTR))
89                 return (0);
90         for (;;) {
91                 if (ioctrl & IO_KEYBOARD && getc(1))
92                         return (fn ? 1 : getc(0));
93                 if (ioctrl & IO_SERIAL && sio_ischar())
94                         return (fn ? 1 : sio_getc());
95                 if (fn)
96                         return (0);
97         }
98         /* NOTREACHED */
99 }
100
101 int
102 keyhit(unsigned int secs)
103 {
104         uint32_t t0, t1;
105
106         if (OPT_CHECK(RBX_NOINTR))
107                 return (0);
108         secs *= SECOND;
109         t0 = 0;
110         for (;;) {
111                 if (xgetc(1))
112                         return (1);
113                 if (secs > 0) {
114                         t1 = *(uint32_t *)PTOV(0x46c);
115                         if (!t0)
116                                 t0 = t1;
117                         if (t1 < t0 || t1 >= t0 + secs)
118                                 return (0);
119                 }
120         }
121         /* NOTREACHED */
122 }
123
124 void
125 getstr(char *cmdstr, size_t cmdstrsize)
126 {
127         char *s;
128         int c;
129
130         s = cmdstr;
131         for (;;) {
132                 switch (c = xgetc(0)) {
133                 case 0:
134                         break;
135                 case '\177':
136                 case '\b':
137                         if (s > cmdstr) {
138                                 s--;
139                                 printf("\b \b");
140                         }
141                         break;
142                 case '\n':
143                 case '\r':
144                         *s = 0;
145                         return;
146                 default:
147                         if (s - cmdstr < cmdstrsize - 1)
148                                 *s++ = c;
149                         putchar(c);
150                         break;
151                 }
152         }
153 }