1e24937ddSToomas Soome /*
2199767f8SToomas Soome * Copyright (c) 1998 Robert Nordier
3199767f8SToomas Soome * All rights reserved.
4199767f8SToomas Soome *
5199767f8SToomas Soome * Redistribution and use in source and binary forms are freely
6199767f8SToomas Soome * permitted provided that the above copyright notice and this
7199767f8SToomas Soome * paragraph and the following disclaimer are duplicated in all
8199767f8SToomas Soome * such forms.
9199767f8SToomas Soome *
10199767f8SToomas Soome * This software is provided "AS IS" and without any express or
11199767f8SToomas Soome * implied warranties, including, without limitation, the implied
12199767f8SToomas Soome * warranties of merchantability and fitness for a particular
13199767f8SToomas Soome * purpose.
14199767f8SToomas Soome */
15199767f8SToomas Soome
16199767f8SToomas Soome #include <sys/cdefs.h>
17199767f8SToomas Soome
18199767f8SToomas Soome #include <sys/param.h>
19199767f8SToomas Soome
20199767f8SToomas Soome #include <machine/psl.h>
21199767f8SToomas Soome
22199767f8SToomas Soome #include <btxv86.h>
23199767f8SToomas Soome
24199767f8SToomas Soome #include "lib.h"
25199767f8SToomas Soome #include "rbx.h"
26199767f8SToomas Soome #include "util.h"
27199767f8SToomas Soome #include "cons.h"
28199767f8SToomas Soome
29e24937ddSToomas Soome #define SECOND 18 /* Circa that many ticks in a second. */
30199767f8SToomas Soome
31199767f8SToomas Soome uint8_t ioctrl = IO_KEYBOARD;
32199767f8SToomas Soome
33199767f8SToomas Soome void
putc(int c)34199767f8SToomas Soome putc(int c)
35199767f8SToomas Soome {
36199767f8SToomas Soome
37199767f8SToomas Soome v86.ctl = V86_FLAGS;
38199767f8SToomas Soome v86.addr = 0x10;
39199767f8SToomas Soome v86.eax = 0xe00 | (c & 0xff);
40199767f8SToomas Soome v86.ebx = 0x7;
41199767f8SToomas Soome v86int();
42199767f8SToomas Soome }
43199767f8SToomas Soome
44199767f8SToomas Soome void
xputc(int c)45199767f8SToomas Soome xputc(int c)
46199767f8SToomas Soome {
47199767f8SToomas Soome
48199767f8SToomas Soome if (ioctrl & IO_KEYBOARD)
49199767f8SToomas Soome putc(c);
50199767f8SToomas Soome if (ioctrl & IO_SERIAL)
51199767f8SToomas Soome sio_putc(c);
52199767f8SToomas Soome }
53199767f8SToomas Soome
54e24937ddSToomas Soome static void
getcursor(int * row,int * col)55e24937ddSToomas Soome getcursor(int *row, int *col)
56e24937ddSToomas Soome {
57e24937ddSToomas Soome v86.ctl = V86_FLAGS;
58e24937ddSToomas Soome v86.addr = 0x10;
59e24937ddSToomas Soome v86.eax = 0x300;
60e24937ddSToomas Soome v86.ebx = 0x7;
61e24937ddSToomas Soome v86int();
62e24937ddSToomas Soome
63e24937ddSToomas Soome if (row != NULL)
64e24937ddSToomas Soome *row = v86.edx >> 8;
65e24937ddSToomas Soome if (col != NULL)
66e24937ddSToomas Soome *col = v86.edx & 0xff;
67e24937ddSToomas Soome }
68e24937ddSToomas Soome
69199767f8SToomas Soome void
putchar(int c)70199767f8SToomas Soome putchar(int c)
71199767f8SToomas Soome {
72e24937ddSToomas Soome int i, col;
73199767f8SToomas Soome
74e24937ddSToomas Soome switch (c) {
75e24937ddSToomas Soome case '\n':
76199767f8SToomas Soome xputc('\r');
77e24937ddSToomas Soome break;
78e24937ddSToomas Soome case '\t':
79e24937ddSToomas Soome col = 0;
80e24937ddSToomas Soome getcursor(NULL, &col);
81e24937ddSToomas Soome col = 8 - (col % 8);
82e24937ddSToomas Soome for (i = 0; i < col; i++)
83e24937ddSToomas Soome xputc(' ');
84e24937ddSToomas Soome return;
85e24937ddSToomas Soome }
86199767f8SToomas Soome xputc(c);
87199767f8SToomas Soome }
88199767f8SToomas Soome
89199767f8SToomas Soome int
getc(int fn)90199767f8SToomas Soome getc(int fn)
91199767f8SToomas Soome {
92199767f8SToomas Soome
93199767f8SToomas Soome v86.ctl = V86_FLAGS;
94199767f8SToomas Soome v86.addr = 0x16;
95199767f8SToomas Soome v86.eax = fn << 8;
96199767f8SToomas Soome v86int();
97fcd33422SToomas Soome
98fcd33422SToomas Soome if (fn == 0)
99fcd33422SToomas Soome return (v86.eax);
100fcd33422SToomas Soome
101fcd33422SToomas Soome if (V86_ZR(v86.efl))
102fcd33422SToomas Soome return (0);
103fcd33422SToomas Soome return (v86.eax);
104199767f8SToomas Soome }
105199767f8SToomas Soome
106199767f8SToomas Soome int
xgetc(int fn)107199767f8SToomas Soome xgetc(int fn)
108199767f8SToomas Soome {
109199767f8SToomas Soome
110199767f8SToomas Soome if (OPT_CHECK(RBX_NOINTR))
111199767f8SToomas Soome return (0);
112199767f8SToomas Soome for (;;) {
113199767f8SToomas Soome if (ioctrl & IO_KEYBOARD && getc(1))
114199767f8SToomas Soome return (fn ? 1 : getc(0));
115199767f8SToomas Soome if (ioctrl & IO_SERIAL && sio_ischar())
116199767f8SToomas Soome return (fn ? 1 : sio_getc());
117199767f8SToomas Soome if (fn)
118199767f8SToomas Soome return (0);
119199767f8SToomas Soome }
120199767f8SToomas Soome /* NOTREACHED */
121199767f8SToomas Soome }
122199767f8SToomas Soome
123199767f8SToomas Soome int
keyhit(unsigned int secs)124199767f8SToomas Soome keyhit(unsigned int secs)
125199767f8SToomas Soome {
126fcd33422SToomas Soome uint32_t t0, t1, c;
127199767f8SToomas Soome
128199767f8SToomas Soome if (OPT_CHECK(RBX_NOINTR))
129199767f8SToomas Soome return (0);
130199767f8SToomas Soome secs *= SECOND;
131199767f8SToomas Soome t0 = 0;
132199767f8SToomas Soome for (;;) {
133fcd33422SToomas Soome /*
134fcd33422SToomas Soome * The extra comparison is an attempt to work around
135fcd33422SToomas Soome * what appears to be a bug in QEMU and Bochs. Both emulators
136fcd33422SToomas Soome * sometimes report a key-press with scancode one and ascii zero
137fcd33422SToomas Soome * when no such key is pressed in reality. As far as I can tell,
138fcd33422SToomas Soome * this only happens shortly after a reboot.
139fcd33422SToomas Soome */
140fcd33422SToomas Soome c = xgetc(1);
141fcd33422SToomas Soome if (c != 0 && c != 0x0100)
142199767f8SToomas Soome return (1);
143199767f8SToomas Soome if (secs > 0) {
144199767f8SToomas Soome t1 = *(uint32_t *)PTOV(0x46c);
145199767f8SToomas Soome if (!t0)
146199767f8SToomas Soome t0 = t1;
147199767f8SToomas Soome if (t1 < t0 || t1 >= t0 + secs)
148199767f8SToomas Soome return (0);
149199767f8SToomas Soome }
150199767f8SToomas Soome }
151199767f8SToomas Soome /* NOTREACHED */
152199767f8SToomas Soome }
153199767f8SToomas Soome
154199767f8SToomas Soome void
getstr(char * cmdstr,size_t cmdstrsize)155199767f8SToomas Soome getstr(char *cmdstr, size_t cmdstrsize)
156199767f8SToomas Soome {
157199767f8SToomas Soome char *s;
158199767f8SToomas Soome int c;
159199767f8SToomas Soome
160199767f8SToomas Soome s = cmdstr;
161199767f8SToomas Soome for (;;) {
162fcd33422SToomas Soome c = xgetc(0);
163fcd33422SToomas Soome
164fcd33422SToomas Soome /* Translate some extended codes. */
165fcd33422SToomas Soome switch (c) {
166fcd33422SToomas Soome case 0x5300: /* delete */
167fcd33422SToomas Soome c = '\177';
168199767f8SToomas Soome break;
169fcd33422SToomas Soome default:
170fcd33422SToomas Soome c &= 0xff;
171fcd33422SToomas Soome break;
172fcd33422SToomas Soome }
173fcd33422SToomas Soome
174fcd33422SToomas Soome switch (c) {
175199767f8SToomas Soome case '\177':
176199767f8SToomas Soome case '\b':
177199767f8SToomas Soome if (s > cmdstr) {
178199767f8SToomas Soome s--;
179199767f8SToomas Soome printf("\b \b");
180199767f8SToomas Soome }
181199767f8SToomas Soome break;
182199767f8SToomas Soome case '\n':
183199767f8SToomas Soome case '\r':
184199767f8SToomas Soome *s = 0;
185199767f8SToomas Soome return;
186199767f8SToomas Soome default:
187fcd33422SToomas Soome if (c >= 0x20 && c <= 0x7e) {
188fcd33422SToomas Soome if (s - cmdstr < cmdstrsize - 1)
189fcd33422SToomas Soome *s++ = c;
190fcd33422SToomas Soome putchar(c);
191fcd33422SToomas Soome }
192199767f8SToomas Soome break;
193199767f8SToomas Soome }
194199767f8SToomas Soome }
195199767f8SToomas Soome }
196199767f8SToomas Soome
197199767f8SToomas Soome int
getchar(void)198199767f8SToomas Soome getchar(void)
199199767f8SToomas Soome {
200fcd33422SToomas Soome return (xgetc(0) & 0xff);
201199767f8SToomas Soome }
202