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