Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/stand/i386/common/cons.c
34883 views
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/param.h>
17
18
#include <machine/psl.h>
19
20
#include <btxv86.h>
21
22
#include "stand.h"
23
24
#include "lib.h"
25
#include "rbx.h"
26
#include "cons.h"
27
28
#define SECOND 18 /* Circa that many ticks in a second. */
29
30
uint8_t ioctrl = IO_KEYBOARD;
31
32
void
33
putc(int c)
34
{
35
36
v86.ctl = V86_FLAGS;
37
v86.addr = 0x10;
38
v86.eax = 0xe00 | (c & 0xff);
39
v86.ebx = 0x7;
40
v86int();
41
}
42
43
void
44
xputc(int c)
45
{
46
47
if (ioctrl & IO_KEYBOARD)
48
putc(c);
49
if (ioctrl & IO_SERIAL)
50
sio_putc(c);
51
}
52
53
static void
54
getcursor(int *row, int *col)
55
{
56
v86.ctl = V86_FLAGS;
57
v86.addr = 0x10;
58
v86.eax = 0x300;
59
v86.ebx = 0x7;
60
v86int();
61
62
if (row != NULL)
63
*row = v86.edx >> 8;
64
if (col != NULL)
65
*col = v86.edx & 0xff;
66
}
67
68
void
69
putchar(int c)
70
{
71
int i, col;
72
73
switch (c) {
74
case '\n':
75
xputc('\r');
76
break;
77
case '\t':
78
col = 0;
79
getcursor(NULL, &col);
80
col = 8 - (col % 8);
81
for (i = 0; i < col; i++)
82
xputc(' ');
83
return;
84
}
85
xputc(c);
86
}
87
88
int
89
getc(int fn)
90
{
91
92
v86.ctl = V86_FLAGS;
93
v86.addr = 0x16;
94
v86.eax = fn << 8;
95
v86int();
96
97
if (fn == 0)
98
return (v86.eax);
99
100
if (V86_ZR(v86.efl))
101
return (0);
102
return (v86.eax);
103
}
104
105
int
106
xgetc(int fn)
107
{
108
109
if (OPT_CHECK(RBX_NOINTR))
110
return (0);
111
for (;;) {
112
if (ioctrl & IO_KEYBOARD && getc(1))
113
return (fn ? 1 : getc(0));
114
if (ioctrl & IO_SERIAL && sio_ischar())
115
return (fn ? 1 : sio_getc());
116
if (fn)
117
return (0);
118
}
119
/* NOTREACHED */
120
}
121
122
int
123
getchar(void)
124
{
125
126
return (xgetc(0) & 0xff);
127
}
128
129
int
130
keyhit(unsigned int secs)
131
{
132
uint32_t t0, t1, c;
133
134
if (OPT_CHECK(RBX_NOINTR))
135
return (0);
136
secs *= SECOND;
137
t0 = 0;
138
for (;;) {
139
/*
140
* The extra comparison is an attempt to work around
141
* what appears to be a bug in QEMU and Bochs. Both emulators
142
* sometimes report a key-press with scancode one and ascii zero
143
* when no such key is pressed in reality. As far as I can tell,
144
* this only happens shortly after a reboot.
145
*/
146
c = xgetc(1);
147
if (c != 0 && c != 0x0100)
148
return (1);
149
if (secs > 0) {
150
t1 = *(uint32_t *)PTOV(0x46c);
151
if (!t0)
152
t0 = t1;
153
if (t1 < t0 || t1 >= t0 + secs)
154
return (0);
155
}
156
}
157
/* NOTREACHED */
158
}
159
160
void
161
getstr(char *cmdstr, size_t cmdstrsize)
162
{
163
char *s;
164
int c;
165
166
s = cmdstr;
167
for (;;) {
168
c = xgetc(0);
169
170
/* Translate some extended codes. */
171
switch (c) {
172
case 0x5300: /* delete */
173
c = '\177';
174
break;
175
default:
176
c &= 0xff;
177
break;
178
}
179
180
switch (c) {
181
case '\177':
182
case '\b':
183
if (s > cmdstr) {
184
s--;
185
printf("\b \b");
186
}
187
break;
188
case '\n':
189
case '\r':
190
*s = 0;
191
return;
192
default:
193
if (c >= 0x20 && c <= 0x7e) {
194
if (s - cmdstr < cmdstrsize - 1)
195
*s++ = c;
196
putchar(c);
197
}
198
break;
199
}
200
}
201
}
202
203