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