]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/boot/i386/common/cons.c
Copy stable/8 to releng/8.2 in preparation for FreeBSD-8.2 release.
[FreeBSD/releng/8.2.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.addr = 0x10;
41         v86.eax = 0xe00 | (c & 0xff);
42         v86.ebx = 0x7;
43         v86int();
44 }
45
46 void
47 xputc(int c)
48 {
49
50         if (ioctrl & IO_KEYBOARD)
51                 putc(c);
52         if (ioctrl & IO_SERIAL)
53                 sio_putc(c);
54 }
55
56 void
57 putchar(int c)
58 {
59
60         if (c == '\n')
61                 xputc('\r');
62         xputc(c);
63 }
64
65 int
66 getc(int fn)
67 {
68
69         /*
70          * The extra comparison against zero is an attempt to work around
71          * what appears to be a bug in QEMU and Bochs. Both emulators
72          * sometimes report a key-press with scancode one and ascii zero
73          * when no such key is pressed in reality. As far as I can tell,
74          * this only happens shortly after a reboot.
75          */
76         v86.ctl = V86_FLAGS;
77         v86.addr = 0x16;
78         v86.eax = fn << 8;
79         v86int();
80         return fn == 0 ? v86.eax & 0xff : (!V86_ZR(v86.efl) && (v86.eax & 0xff));
81 }
82
83 int
84 xgetc(int fn)
85 {
86
87         if (OPT_CHECK(RBX_NOINTR))
88                 return (0);
89         for (;;) {
90                 if (ioctrl & IO_KEYBOARD && getc(1))
91                         return (fn ? 1 : getc(0));
92                 if (ioctrl & IO_SERIAL && sio_ischar())
93                         return (fn ? 1 : sio_getc());
94                 if (fn)
95                         return (0);
96         }
97         /* NOTREACHED */
98 }
99
100 int
101 keyhit(unsigned int secs)
102 {
103         uint32_t t0, t1;
104
105         if (OPT_CHECK(RBX_NOINTR))
106                 return (0);
107         secs *= SECOND;
108         t0 = 0;
109         for (;;) {
110                 if (xgetc(1))
111                         return (1);
112                 if (secs > 0) {
113                         t1 = *(uint32_t *)PTOV(0x46c);
114                         if (!t0)
115                                 t0 = t1;
116                         if (t1 < t0 || t1 >= t0 + secs)
117                                 return (0);
118                 }
119         }
120         /* NOTREACHED */
121 }
122
123 void
124 getstr(char *cmdstr, size_t cmdstrsize)
125 {
126         char *s;
127         int c;
128
129         s = cmdstr;
130         for (;;) {
131                 switch (c = xgetc(0)) {
132                 case 0:
133                         break;
134                 case '\177':
135                 case '\b':
136                         if (s > cmdstr) {
137                                 s--;
138                                 printf("\b \b");
139                         }
140                         break;
141                 case '\n':
142                 case '\r':
143                         *s = 0;
144                         return;
145                 default:
146                         if (s - cmdstr < cmdstrsize - 1)
147                                 *s++ = c;
148                         putchar(c);
149                         break;
150                 }
151         }
152 }