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