Deleted Added
full compact
vidconsole.c (145069) vidconsole.c (146011)
1/*
1/*-
2 * Copyright (c) 1998 Michael Smith (msmith@freebsd.org)
3 * Copyright (c) 1997 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp
28 */
29
30#include <sys/cdefs.h>
2 * Copyright (c) 1998 Michael Smith (msmith@freebsd.org)
3 * Copyright (c) 1997 Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * Id: probe_keyboard.c,v 1.13 1997/06/09 05:10:55 bde Exp
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/boot/pc98/libpc98/vidconsole.c 145069 2005-04-14 14:12:54Z nyan $");
31__FBSDID("$FreeBSD: head/sys/boot/pc98/libpc98/vidconsole.c 146011 2005-05-08 14:17:28Z nyan $");
32
33#include <stand.h>
34#include <bootstrap.h>
35#include <btxv86.h>
36#include <machine/psl.h>
32
33#include <stand.h>
34#include <bootstrap.h>
35#include <btxv86.h>
36#include <machine/psl.h>
37#ifdef PC98
38#include <machine/cpufunc.h>
37#include <machine/cpufunc.h>
39#endif
40#include "libi386.h"
41
42#if KEYBOARD_PROBE
43#include <machine/cpufunc.h>
44
45static int probe_keyboard(void);
46#endif
47static void vidc_probe(struct console *cp);
48static int vidc_init(int arg);
49static void vidc_putchar(int c);
50static int vidc_getchar(void);
51static int vidc_ischar(void);
52
53static int vidc_started;
54
55#ifdef TERM_EMU
56#define MAXARGS 8
57#define DEFAULT_FGCOLOR 7
58#define DEFAULT_BGCOLOR 0
59
60void end_term(void);
61void bail_out(int c);
62void vidc_term_emu(int c);
63void get_pos(void);
64void curs_move(int x, int y);
65void write_char(int c, int fg, int bg);
66void scroll_up(int rows, int fg, int bg);
67void CD(void);
68void CM(void);
69void HO(void);
70
71static int args[MAXARGS], argc;
72static int fg_c, bg_c, curx, cury;
73static int esc;
74#endif
75
38#include "libi386.h"
39
40#if KEYBOARD_PROBE
41#include <machine/cpufunc.h>
42
43static int probe_keyboard(void);
44#endif
45static void vidc_probe(struct console *cp);
46static int vidc_init(int arg);
47static void vidc_putchar(int c);
48static int vidc_getchar(void);
49static int vidc_ischar(void);
50
51static int vidc_started;
52
53#ifdef TERM_EMU
54#define MAXARGS 8
55#define DEFAULT_FGCOLOR 7
56#define DEFAULT_BGCOLOR 0
57
58void end_term(void);
59void bail_out(int c);
60void vidc_term_emu(int c);
61void get_pos(void);
62void curs_move(int x, int y);
63void write_char(int c, int fg, int bg);
64void scroll_up(int rows, int fg, int bg);
65void CD(void);
66void CM(void);
67void HO(void);
68
69static int args[MAXARGS], argc;
70static int fg_c, bg_c, curx, cury;
71static int esc;
72#endif
73
76#ifdef PC98
77static unsigned short *crtat, *Crtat;
78static int row = 25, col = 80;
79#ifdef TERM_EMU
80static u_int8_t ibmpc_to_pc98[256] = {
81 0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1,
82 0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9,
83 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
84 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
85 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
86 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
87 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
88 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
89 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
90 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
91 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
92 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
93 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
94 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
95 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
96 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
97
98 0x03, 0x23, 0x83, 0xa3, 0x43, 0x63, 0xc3, 0xe3,
99 0x0b, 0x2b, 0x8b, 0xab, 0x4b, 0x6b, 0xcb, 0xeb,
100 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
101 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
102 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
103 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
104 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
105 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
106 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
107 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
108 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
109 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
110 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
111 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
112 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
113 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
114};
115#define at2pc98(fg_at, bg_at) ibmpc_to_pc98[((bg_at) << 4) | (fg_at)]
116#endif /* TERM_EMU */
74static unsigned short *crtat, *Crtat;
75static int row = 25, col = 80;
76#ifdef TERM_EMU
77static u_int8_t ibmpc_to_pc98[256] = {
78 0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1,
79 0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9,
80 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
81 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
82 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
83 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
84 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
85 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
86 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
87 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
88 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
89 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65,
90 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
91 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
92 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
93 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5,
94
95 0x03, 0x23, 0x83, 0xa3, 0x43, 0x63, 0xc3, 0xe3,
96 0x0b, 0x2b, 0x8b, 0xab, 0x4b, 0x6b, 0xcb, 0xeb,
97 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
98 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
99 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
100 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
101 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
102 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
103 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
104 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
105 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
106 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
107 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
108 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
109 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
110 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef,
111};
112#define at2pc98(fg_at, bg_at) ibmpc_to_pc98[((bg_at) << 4) | (fg_at)]
113#endif /* TERM_EMU */
117#endif /* PC98 */
118
119struct console vidconsole = {
120 "vidconsole",
121 "internal video/keyboard",
122 0,
123 vidc_probe,
124 vidc_init,
125 vidc_putchar,
126 vidc_getchar,
127 vidc_ischar
128};
129
130static void
131vidc_probe(struct console *cp)
132{
133
134 /* look for a keyboard */
135#if KEYBOARD_PROBE
136 if (probe_keyboard())
137#endif
138 {
139
140 cp->c_flags |= C_PRESENTIN;
141 }
142
143 /* XXX for now, always assume we can do BIOS screen output */
144 cp->c_flags |= C_PRESENTOUT;
145}
146
147static int
148vidc_init(int arg)
149{
114
115struct console vidconsole = {
116 "vidconsole",
117 "internal video/keyboard",
118 0,
119 vidc_probe,
120 vidc_init,
121 vidc_putchar,
122 vidc_getchar,
123 vidc_ischar
124};
125
126static void
127vidc_probe(struct console *cp)
128{
129
130 /* look for a keyboard */
131#if KEYBOARD_PROBE
132 if (probe_keyboard())
133#endif
134 {
135
136 cp->c_flags |= C_PRESENTIN;
137 }
138
139 /* XXX for now, always assume we can do BIOS screen output */
140 cp->c_flags |= C_PRESENTOUT;
141}
142
143static int
144vidc_init(int arg)
145{
150 int i;
151#ifdef PC98
152 int hw_cursor;
153#endif
146 int i, hw_cursor;
154
155 if (vidc_started && arg == 0)
156 return (0);
157 vidc_started = 1;
147
148 if (vidc_started && arg == 0)
149 return (0);
150 vidc_started = 1;
158#ifdef PC98
159 Crtat = (unsigned short *)PTOV(0xA0000);
160 while ((inb(0x60) & 0x04) == 0)
161 ;
162 outb(0x62, 0xe0);
163 while ((inb(0x60) & 0x01) == 0)
164 ;
165 hw_cursor = inb(0x62);
166 hw_cursor |= (inb(0x62) << 8);
167 inb(0x62);
168 inb(0x62);
169 inb(0x62);
170 crtat = Crtat + hw_cursor;
151 Crtat = (unsigned short *)PTOV(0xA0000);
152 while ((inb(0x60) & 0x04) == 0)
153 ;
154 outb(0x62, 0xe0);
155 while ((inb(0x60) & 0x01) == 0)
156 ;
157 hw_cursor = inb(0x62);
158 hw_cursor |= (inb(0x62) << 8);
159 inb(0x62);
160 inb(0x62);
161 inb(0x62);
162 crtat = Crtat + hw_cursor;
171#endif
172#ifdef TERM_EMU
173 /* Init terminal emulator */
174 end_term();
175 get_pos();
176 curs_move(curx, cury);
177 fg_c = DEFAULT_FGCOLOR;
178 bg_c = DEFAULT_BGCOLOR;
179#endif
180 for (i = 0; i < 10 && vidc_ischar(); i++)
181 (void)vidc_getchar();
182 return (0); /* XXX reinit? */
183}
184
163#ifdef TERM_EMU
164 /* Init terminal emulator */
165 end_term();
166 get_pos();
167 curs_move(curx, cury);
168 fg_c = DEFAULT_FGCOLOR;
169 bg_c = DEFAULT_BGCOLOR;
170#endif
171 for (i = 0; i < 10 && vidc_ischar(); i++)
172 (void)vidc_getchar();
173 return (0); /* XXX reinit? */
174}
175
185#ifdef PC98
186static void
187beep(void)
188{
189
190 outb(0x37, 6);
191 delay(40000);
192 outb(0x37, 7);
193}
176static void
177beep(void)
178{
179
180 outb(0x37, 6);
181 delay(40000);
182 outb(0x37, 7);
183}
194#endif
195
196#if 0
197static void
198vidc_biosputchar(int c)
199{
184
185#if 0
186static void
187vidc_biosputchar(int c)
188{
200#ifdef PC98
201 unsigned short *cp;
202 int i, pos;
203
204#ifdef TERM_EMU
205 *crtat = (c == 0x5c ? 0xfc : c);
206 *(crtat + 0x1000) = at2pc98(fg, bg);
207#else
208 switch(c) {
209 case '\b':
210 crtat--;
211 break;
212 case '\r':
213 crtat -= (crtat - Crtat) % col;
214 break;
215 case '\n':
216 crtat += col;
217 break;
218 default:
219 *crtat = (c == 0x5c ? 0xfc : c);
220 *(crtat++ + 0x1000) = 0xe1;
221 break;
222 }
223
224 if (crtat >= Crtat + col * row) {
225 cp = Crtat;
226 for (i = 1; i < row; i++) {
227 bcopy((void *)(cp + col), (void *)cp, col * 2);
228 cp += col;
229 }
230 for (i = 0; i < col; i++) {
231 *cp++ = ' ';
232 }
233 crtat -= col;
234 }
235 pos = crtat - Crtat;
236 while ((inb(0x60) & 0x04) == 0) {}
237 outb(0x62, 0x49);
238 outb(0x60, pos & 0xff);
239 outb(0x60, pos >> 8);
240#endif
189 unsigned short *cp;
190 int i, pos;
191
192#ifdef TERM_EMU
193 *crtat = (c == 0x5c ? 0xfc : c);
194 *(crtat + 0x1000) = at2pc98(fg, bg);
195#else
196 switch(c) {
197 case '\b':
198 crtat--;
199 break;
200 case '\r':
201 crtat -= (crtat - Crtat) % col;
202 break;
203 case '\n':
204 crtat += col;
205 break;
206 default:
207 *crtat = (c == 0x5c ? 0xfc : c);
208 *(crtat++ + 0x1000) = 0xe1;
209 break;
210 }
211
212 if (crtat >= Crtat + col * row) {
213 cp = Crtat;
214 for (i = 1; i < row; i++) {
215 bcopy((void *)(cp + col), (void *)cp, col * 2);
216 cp += col;
217 }
218 for (i = 0; i < col; i++) {
219 *cp++ = ' ';
220 }
221 crtat -= col;
222 }
223 pos = crtat - Crtat;
224 while ((inb(0x60) & 0x04) == 0) {}
225 outb(0x62, 0x49);
226 outb(0x60, pos & 0xff);
227 outb(0x60, pos >> 8);
228#endif
241#else
242
243 v86.ctl = 0;
244 v86.addr = 0x10;
245 v86.eax = 0xe00 | (c & 0xff);
246 v86.ebx = 0x7;
247 v86int();
248#endif
249}
250#endif
251
252static void
253vidc_rawputchar(int c)
254{
255 int i;
256
257 if (c == '\t')
258 /* lame tab expansion */
259 for (i = 0; i < 8; i++)
260 vidc_rawputchar(' ');
261 else {
229}
230#endif
231
232static void
233vidc_rawputchar(int c)
234{
235 int i;
236
237 if (c == '\t')
238 /* lame tab expansion */
239 for (i = 0; i < 8; i++)
240 vidc_rawputchar(' ');
241 else {
262#if !defined(TERM_EMU) && !defined(PC98)
263 vidc_biosputchar(c);
264#else
265 /* Emulate AH=0eh (teletype output) */
266 switch(c) {
267 case '\a':
242 /* Emulate AH=0eh (teletype output) */
243 switch(c) {
244 case '\a':
268#ifdef PC98
269 beep();
245 beep();
270#else
271 vidc_biosputchar(c);
272#endif
273 return;
274 case '\r':
275 curx = 0;
276 curs_move(curx, cury);
277 return;
278 case '\n':
279 cury++;
280 if (cury > 24) {
281 scroll_up(1, fg_c, bg_c);
282 cury--;
283 } else {
284 curs_move(curx, cury);
285 }
286 return;
287 case '\b':
288 if (curx > 0) {
289 curx--;
290 curs_move(curx, cury);
291 /* write_char(' ', fg_c, bg_c); XXX destructive(!) */
292 return;
293 }
294 return;
295 default:
296 write_char(c, fg_c, bg_c);
297 curx++;
298 if (curx > 79) {
299 curx = 0;
300 cury++;
301 }
302 if (cury > 24) {
303 curx = 0;
304 scroll_up(1, fg_c, bg_c);
305 cury--;
306 }
307 }
308 curs_move(curx, cury);
246 return;
247 case '\r':
248 curx = 0;
249 curs_move(curx, cury);
250 return;
251 case '\n':
252 cury++;
253 if (cury > 24) {
254 scroll_up(1, fg_c, bg_c);
255 cury--;
256 } else {
257 curs_move(curx, cury);
258 }
259 return;
260 case '\b':
261 if (curx > 0) {
262 curx--;
263 curs_move(curx, cury);
264 /* write_char(' ', fg_c, bg_c); XXX destructive(!) */
265 return;
266 }
267 return;
268 default:
269 write_char(c, fg_c, bg_c);
270 curx++;
271 if (curx > 79) {
272 curx = 0;
273 cury++;
274 }
275 if (cury > 24) {
276 curx = 0;
277 scroll_up(1, fg_c, bg_c);
278 cury--;
279 }
280 }
281 curs_move(curx, cury);
309#endif
310 }
311}
312
313#ifdef TERM_EMU
314
315/* Get cursor position on the screen. Result is in edx. Sets
316 * curx and cury appropriately.
317 */
318void
319get_pos(void)
320{
282 }
283}
284
285#ifdef TERM_EMU
286
287/* Get cursor position on the screen. Result is in edx. Sets
288 * curx and cury appropriately.
289 */
290void
291get_pos(void)
292{
321#ifdef PC98
322 int pos = crtat - Crtat;
323
324 curx = pos % col;
325 cury = pos / col;
293 int pos = crtat - Crtat;
294
295 curx = pos % col;
296 cury = pos / col;
326#else
327
328 v86.ctl = 0;
329 v86.addr = 0x10;
330 v86.eax = 0x0300;
331 v86.ebx = 0x0;
332 v86int();
333 curx = v86.edx & 0x00ff;
334 cury = (v86.edx & 0xff00) >> 8;
335#endif
336}
337
338/* Move cursor to x rows and y cols (0-based). */
339void
340curs_move(int x, int y)
341{
297}
298
299/* Move cursor to x rows and y cols (0-based). */
300void
301curs_move(int x, int y)
302{
342#ifdef PC98
343 int pos;
344
345 pos = x + y * col;
346 crtat = Crtat + pos;
347 pos = crtat - Crtat;
348 while((inb(0x60) & 0x04) == 0) {}
349 outb(0x62, 0x49);
350 outb(0x60, pos & 0xff);
351 outb(0x60, pos >> 8);
352 curx = x;
353 cury = y;
354#define isvisible(c) (((c) >= 32) && ((c) < 255))
355 if (!isvisible(*crtat & 0x00ff)) {
356 write_char(' ', fg_c, bg_c);
357 }
303 int pos;
304
305 pos = x + y * col;
306 crtat = Crtat + pos;
307 pos = crtat - Crtat;
308 while((inb(0x60) & 0x04) == 0) {}
309 outb(0x62, 0x49);
310 outb(0x60, pos & 0xff);
311 outb(0x60, pos >> 8);
312 curx = x;
313 cury = y;
314#define isvisible(c) (((c) >= 32) && ((c) < 255))
315 if (!isvisible(*crtat & 0x00ff)) {
316 write_char(' ', fg_c, bg_c);
317 }
358#else
359
360 v86.ctl = 0;
361 v86.addr = 0x10;
362 v86.eax = 0x0200;
363 v86.ebx = 0x0;
364 v86.edx = ((0x00ff & y) << 8) + (0x00ff & x);
365 v86int();
366 curx = x;
367 cury = y;
368 /* If there is ctrl char at this position, cursor would be invisible.
369 * Make it a space instead.
370 */
371 v86.ctl = 0;
372 v86.addr = 0x10;
373 v86.eax = 0x0800;
374 v86.ebx = 0x0;
375 v86int();
376#define isvisible(c) (((c) >= 32) && ((c) < 255))
377 if (!isvisible(v86.eax & 0x00ff)) {
378 write_char(' ', fg_c, bg_c);
379 }
380#endif
381}
382
383/* Scroll up the whole window by a number of rows. If rows==0,
384 * clear the window. fg and bg are attributes for the new lines
385 * inserted in the window.
386 */
387void
388scroll_up(int rows, int fgcol, int bgcol)
389{
318}
319
320/* Scroll up the whole window by a number of rows. If rows==0,
321 * clear the window. fg and bg are attributes for the new lines
322 * inserted in the window.
323 */
324void
325scroll_up(int rows, int fgcol, int bgcol)
326{
390#ifdef PC98
391 unsigned short *cp;
392 int i;
393
394 if (rows == 0)
395 rows = 25;
396 cp = Crtat;
397 for (i = rows; i < row; i++) {
398 bcopy((void *)(cp + col), (void *)cp, col * 2);
399 cp += col;
400 }
401 for (i = 0; i < col; i++) {
402 *(cp + 0x1000) = at2pc98(fgcol, bgcol);
403 *cp++ = ' ';
404 }
327 unsigned short *cp;
328 int i;
329
330 if (rows == 0)
331 rows = 25;
332 cp = Crtat;
333 for (i = rows; i < row; i++) {
334 bcopy((void *)(cp + col), (void *)cp, col * 2);
335 cp += col;
336 }
337 for (i = 0; i < col; i++) {
338 *(cp + 0x1000) = at2pc98(fgcol, bgcol);
339 *cp++ = ' ';
340 }
405#else
406
407 if (rows == 0)
408 rows = 25;
409 v86.ctl = 0;
410 v86.addr = 0x10;
411 v86.eax = 0x0600 + (0x00ff & rows);
412 v86.ebx = (bgcol << 12) + (fgcol << 8);
413 v86.ecx = 0x0;
414 v86.edx = 0x184f;
415 v86int();
416#endif
417}
418
419/* Write character and attribute at cursor position. */
420void
421write_char(int c, int fgcol, int bgcol)
422{
423
341}
342
343/* Write character and attribute at cursor position. */
344void
345write_char(int c, int fgcol, int bgcol)
346{
347
424#ifdef PC98
425 *crtat = (c == 0x5c ? 0xfc : (c & 0xff));
426 *(crtat + 0x1000) = at2pc98(fgcol, bgcol);
348 *crtat = (c == 0x5c ? 0xfc : (c & 0xff));
349 *(crtat + 0x1000) = at2pc98(fgcol, bgcol);
427#else
428 v86.ctl = 0;
429 v86.addr = 0x10;
430 v86.eax = 0x0900 + (0x00ff & c);
431 v86.ebx = (bgcol << 4) + fgcol;
432 v86.ecx = 0x1;
433 v86int();
434#endif
435}
436
437/**************************************************************/
438/*
439 * Screen manipulation functions. They use accumulated data in
440 * args[] and argc variables.
441 *
442 */
443
444/* Clear display from current position to end of screen */
445void
446CD(void)
447{
350}
351
352/**************************************************************/
353/*
354 * Screen manipulation functions. They use accumulated data in
355 * args[] and argc variables.
356 *
357 */
358
359/* Clear display from current position to end of screen */
360void
361CD(void)
362{
448#ifdef PC98
449 int pos;
450
451 get_pos();
452 for (pos = 0; crtat + pos <= Crtat + col * row; pos++) {
453 *(crtat + pos) = ' ';
454 *(crtat + pos + 0x1000) = at2pc98(fg_c, bg_c);
455 }
456 end_term();
363 int pos;
364
365 get_pos();
366 for (pos = 0; crtat + pos <= Crtat + col * row; pos++) {
367 *(crtat + pos) = ' ';
368 *(crtat + pos + 0x1000) = at2pc98(fg_c, bg_c);
369 }
370 end_term();
457#else
458
459 get_pos();
460 if (curx > 0) {
461 v86.ctl = 0;
462 v86.addr = 0x10;
463 v86.eax = 0x0600;
464 v86.ebx = (bg_c << 4) + fg_c;
465 v86.ecx = (cury << 8) + curx;
466 v86.edx = (cury << 8) + 79;
467 v86int();
468 if (++cury > 24) {
469 end_term();
470 return;
471 }
472 }
473 v86.ctl = 0;
474 v86.addr = 0x10;
475 v86.eax = 0x0600;
476 v86.ebx = (bg_c << 4) + fg_c;
477 v86.ecx = (cury << 8) + 0;
478 v86.edx = (24 << 8) + 79;
479 v86int();
480 end_term();
481#endif
482}
483
484/* Absolute cursor move to args[0] rows and args[1] columns
485 * (the coordinates are 1-based).
486 */
487void
488CM(void)
489{
490
491 if (args[0] > 0)
492 args[0]--;
493 if (args[1] > 0)
494 args[1]--;
495 curs_move(args[1], args[0]);
496 end_term();
497}
498
499/* Home cursor (left top corner) */
500void
501HO(void)
502{
503
504 argc = 1;
505 args[0] = args[1] = 1;
506 CM();
507}
508
509/* Clear internal state of the terminal emulation code */
510void
511end_term(void)
512{
513
514 esc = 0;
515 argc = -1;
516}
517
518/* Gracefully exit ESC-sequence processing in case of misunderstanding */
519void
520bail_out(int c)
521{
522 char buf[16], *ch;
523 int i;
524
525 if (esc) {
526 vidc_rawputchar('\033');
527 if (esc != '\033')
528 vidc_rawputchar(esc);
529 for (i = 0; i <= argc; ++i) {
530 sprintf(buf, "%d", args[i]);
531 ch = buf;
532 while (*ch)
533 vidc_rawputchar(*ch++);
534 }
535 }
536 vidc_rawputchar(c);
537 end_term();
538}
539
540static void
541get_arg(int c)
542{
543
544 if (argc < 0)
545 argc = 0;
546 args[argc] *= 10;
547 args[argc] += c - '0';
548}
549
550/* Emulate basic capabilities of cons25 terminal */
551void
552vidc_term_emu(int c)
553{
554 static int ansi_col[] = {
555 0, 4, 2, 6, 1, 5, 3, 7,
556 };
557 int t;
558 int i;
559
560 switch (esc) {
561 case 0:
562 switch (c) {
563 case '\033':
564 esc = c;
565 break;
566 default:
567 vidc_rawputchar(c);
568 break;
569 }
570 break;
571
572 case '\033':
573 switch (c) {
574 case '[':
575 esc = c;
576 args[0] = 0;
577 argc = -1;
578 break;
579 default:
580 bail_out(c);
581 break;
582 }
583 break;
584
585 case '[':
586 switch (c) {
587 case ';':
588 if (argc < 0) /* XXX */
589 argc = 0;
590 else if (argc + 1 >= MAXARGS)
591 bail_out(c);
592 else
593 args[++argc] = 0;
594 break;
595 case 'H':
596 if (argc < 0)
597 HO();
598 else if (argc == 1)
599 CM();
600 else
601 bail_out(c);
602 break;
603 case 'J':
604 if (argc < 0)
605 CD();
606 else
607 bail_out(c);
608 break;
609 case 'm':
610 if (argc < 0) {
611 fg_c = DEFAULT_FGCOLOR;
612 bg_c = DEFAULT_BGCOLOR;
613 }
614 for (i = 0; i <= argc; ++i) {
615 switch (args[i]) {
616 case 0: /* back to normal */
617 fg_c = DEFAULT_FGCOLOR;
618 bg_c = DEFAULT_BGCOLOR;
619 break;
620 case 1: /* bold */
621 fg_c |= 0x8;
622 break;
623 case 4: /* underline */
624 case 5: /* blink */
625 bg_c |= 0x8;
626 break;
627 case 7: /* reverse */
628 t = fg_c;
629 fg_c = bg_c;
630 bg_c = t;
631 break;
632 case 30: case 31: case 32: case 33:
633 case 34: case 35: case 36: case 37:
634 fg_c = ansi_col[args[i] - 30];
635 break;
636 case 39: /* normal */
637 fg_c = DEFAULT_FGCOLOR;
638 break;
639 case 40: case 41: case 42: case 43:
640 case 44: case 45: case 46: case 47:
641 bg_c = ansi_col[args[i] - 40];
642 break;
643 case 49: /* normal */
644 bg_c = DEFAULT_BGCOLOR;
645 break;
646 }
647 }
648 end_term();
649 break;
650 default:
651 if (isdigit(c))
652 get_arg(c);
653 else
654 bail_out(c);
655 break;
656 }
657 break;
658
659 default:
660 bail_out(c);
661 break;
662 }
663}
664#endif
665
666static void
667vidc_putchar(int c)
668{
669#ifdef TERM_EMU
670 vidc_term_emu(c);
671#else
672 vidc_rawputchar(c);
673#endif
674}
675
676static int
677vidc_getchar(void)
678{
679
680 if (vidc_ischar()) {
681 v86.ctl = 0;
371}
372
373/* Absolute cursor move to args[0] rows and args[1] columns
374 * (the coordinates are 1-based).
375 */
376void
377CM(void)
378{
379
380 if (args[0] > 0)
381 args[0]--;
382 if (args[1] > 0)
383 args[1]--;
384 curs_move(args[1], args[0]);
385 end_term();
386}
387
388/* Home cursor (left top corner) */
389void
390HO(void)
391{
392
393 argc = 1;
394 args[0] = args[1] = 1;
395 CM();
396}
397
398/* Clear internal state of the terminal emulation code */
399void
400end_term(void)
401{
402
403 esc = 0;
404 argc = -1;
405}
406
407/* Gracefully exit ESC-sequence processing in case of misunderstanding */
408void
409bail_out(int c)
410{
411 char buf[16], *ch;
412 int i;
413
414 if (esc) {
415 vidc_rawputchar('\033');
416 if (esc != '\033')
417 vidc_rawputchar(esc);
418 for (i = 0; i <= argc; ++i) {
419 sprintf(buf, "%d", args[i]);
420 ch = buf;
421 while (*ch)
422 vidc_rawputchar(*ch++);
423 }
424 }
425 vidc_rawputchar(c);
426 end_term();
427}
428
429static void
430get_arg(int c)
431{
432
433 if (argc < 0)
434 argc = 0;
435 args[argc] *= 10;
436 args[argc] += c - '0';
437}
438
439/* Emulate basic capabilities of cons25 terminal */
440void
441vidc_term_emu(int c)
442{
443 static int ansi_col[] = {
444 0, 4, 2, 6, 1, 5, 3, 7,
445 };
446 int t;
447 int i;
448
449 switch (esc) {
450 case 0:
451 switch (c) {
452 case '\033':
453 esc = c;
454 break;
455 default:
456 vidc_rawputchar(c);
457 break;
458 }
459 break;
460
461 case '\033':
462 switch (c) {
463 case '[':
464 esc = c;
465 args[0] = 0;
466 argc = -1;
467 break;
468 default:
469 bail_out(c);
470 break;
471 }
472 break;
473
474 case '[':
475 switch (c) {
476 case ';':
477 if (argc < 0) /* XXX */
478 argc = 0;
479 else if (argc + 1 >= MAXARGS)
480 bail_out(c);
481 else
482 args[++argc] = 0;
483 break;
484 case 'H':
485 if (argc < 0)
486 HO();
487 else if (argc == 1)
488 CM();
489 else
490 bail_out(c);
491 break;
492 case 'J':
493 if (argc < 0)
494 CD();
495 else
496 bail_out(c);
497 break;
498 case 'm':
499 if (argc < 0) {
500 fg_c = DEFAULT_FGCOLOR;
501 bg_c = DEFAULT_BGCOLOR;
502 }
503 for (i = 0; i <= argc; ++i) {
504 switch (args[i]) {
505 case 0: /* back to normal */
506 fg_c = DEFAULT_FGCOLOR;
507 bg_c = DEFAULT_BGCOLOR;
508 break;
509 case 1: /* bold */
510 fg_c |= 0x8;
511 break;
512 case 4: /* underline */
513 case 5: /* blink */
514 bg_c |= 0x8;
515 break;
516 case 7: /* reverse */
517 t = fg_c;
518 fg_c = bg_c;
519 bg_c = t;
520 break;
521 case 30: case 31: case 32: case 33:
522 case 34: case 35: case 36: case 37:
523 fg_c = ansi_col[args[i] - 30];
524 break;
525 case 39: /* normal */
526 fg_c = DEFAULT_FGCOLOR;
527 break;
528 case 40: case 41: case 42: case 43:
529 case 44: case 45: case 46: case 47:
530 bg_c = ansi_col[args[i] - 40];
531 break;
532 case 49: /* normal */
533 bg_c = DEFAULT_BGCOLOR;
534 break;
535 }
536 }
537 end_term();
538 break;
539 default:
540 if (isdigit(c))
541 get_arg(c);
542 else
543 bail_out(c);
544 break;
545 }
546 break;
547
548 default:
549 bail_out(c);
550 break;
551 }
552}
553#endif
554
555static void
556vidc_putchar(int c)
557{
558#ifdef TERM_EMU
559 vidc_term_emu(c);
560#else
561 vidc_rawputchar(c);
562#endif
563}
564
565static int
566vidc_getchar(void)
567{
568
569 if (vidc_ischar()) {
570 v86.ctl = 0;
682#ifdef PC98
683 v86.addr = 0x18;
571 v86.addr = 0x18;
684#else
685 v86.addr = 0x16;
686#endif
687 v86.eax = 0x0;
688 v86int();
689 return (v86.eax & 0xff);
690 } else {
691 return (-1);
692 }
693}
694
695static int
696vidc_ischar(void)
697{
698
572 v86.eax = 0x0;
573 v86int();
574 return (v86.eax & 0xff);
575 } else {
576 return (-1);
577 }
578}
579
580static int
581vidc_ischar(void)
582{
583
699#ifdef PC98
700 v86.ctl = 0;
701 v86.addr = 0x18;
702 v86.eax = 0x100;
703 v86int();
704 return ((v86.ebx >> 8) & 0x1);
584 v86.ctl = 0;
585 v86.addr = 0x18;
586 v86.eax = 0x100;
587 v86int();
588 return ((v86.ebx >> 8) & 0x1);
705#else
706 v86.ctl = V86_FLAGS;
707 v86.addr = 0x16;
708 v86.eax = 0x100;
709 v86int();
710 return (!(v86.efl & PSL_Z));
711#endif
712}
713
714#if KEYBOARD_PROBE
589}
590
591#if KEYBOARD_PROBE
715
716#ifdef PC98
717static int
718probe_keyboard(void)
719{
720 return (*(u_char *)PTOV(0xA1481) & 0x48);
721}
592static int
593probe_keyboard(void)
594{
595 return (*(u_char *)PTOV(0xA1481) & 0x48);
596}
722#else /* PC98 */
723#define PROBE_MAXRETRY 5
724#define PROBE_MAXWAIT 400
725#define IO_DUMMY 0x84
726#define IO_KBD 0x060 /* 8042 Keyboard */
727
728/* selected defines from kbdio.h */
729#define KBD_STATUS_PORT 4 /* status port, read */
730#define KBD_DATA_PORT 0 /* data port, read/write
731 * also used as keyboard command
732 * and mouse command port
733 */
734#define KBDC_ECHO 0x00ee
735#define KBDS_ANY_BUFFER_FULL 0x0001
736#define KBDS_INPUT_BUFFER_FULL 0x0002
737#define KBD_ECHO 0x00ee
738
739/* 7 microsec delay necessary for some keyboard controllers */
740static void
741delay7(void)
742{
743 /*
744 * I know this is broken, but no timer is available yet at this stage...
745 * See also comments in `delay1ms()'.
746 */
747 inb(IO_DUMMY); inb(IO_DUMMY);
748 inb(IO_DUMMY); inb(IO_DUMMY);
749 inb(IO_DUMMY); inb(IO_DUMMY);
750}
751
752/*
753 * This routine uses an inb to an unused port, the time to execute that
754 * inb is approximately 1.25uS. This value is pretty constant across
755 * all CPU's and all buses, with the exception of some PCI implentations
756 * that do not forward this I/O address to the ISA bus as they know it
757 * is not a valid ISA bus address, those machines execute this inb in
758 * 60 nS :-(.
759 *
760 */
761static void
762delay1ms(void)
763{
764 int i = 800;
765 while (--i >= 0)
766 (void)inb(0x84);
767}
768
769/*
770 * We use the presence/absence of a keyboard to determine whether the internal
771 * console can be used for input.
772 *
773 * Perform a simple test on the keyboard; issue the ECHO command and see
774 * if the right answer is returned. We don't do anything as drastic as
775 * full keyboard reset; it will be too troublesome and take too much time.
776 */
777static int
778probe_keyboard(void)
779{
780 int retry = PROBE_MAXRETRY;
781 int wait;
782 int i;
783
784 while (--retry >= 0) {
785 /* flush any noise */
786 while (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) {
787 delay7();
788 inb(IO_KBD + KBD_DATA_PORT);
789 delay1ms();
790 }
791
792 /* wait until the controller can accept a command */
793 for (wait = PROBE_MAXWAIT; wait > 0; --wait) {
794 if (((i = inb(IO_KBD + KBD_STATUS_PORT))
795 & (KBDS_INPUT_BUFFER_FULL | KBDS_ANY_BUFFER_FULL)) == 0)
796 break;
797 if (i & KBDS_ANY_BUFFER_FULL) {
798 delay7();
799 inb(IO_KBD + KBD_DATA_PORT);
800 }
801 delay1ms();
802 }
803 if (wait <= 0)
804 continue;
805
806 /* send the ECHO command */
807 outb(IO_KBD + KBD_DATA_PORT, KBDC_ECHO);
808
809 /* wait for a response */
810 for (wait = PROBE_MAXWAIT; wait > 0; --wait) {
811 if (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL)
812 break;
813 delay1ms();
814 }
815 if (wait <= 0)
816 continue;
817
818 delay7();
819 i = inb(IO_KBD + KBD_DATA_PORT);
820#ifdef PROBE_KBD_BEBUG
821 printf("probe_keyboard: got 0x%x.\n", i);
822#endif
823 if (i == KBD_ECHO) {
824 /* got the right answer */
825 return (0);
826 }
827 }
828
829 return (1);
830}
831#endif /* PC98 */
832#endif /* KEYBOARD_PROBE */
597#endif /* KEYBOARD_PROBE */