* Copyright (c) 1990 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* William Jolitz and Don Ahn.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* from: @(#)pccons.c 5.11 (Berkeley) 5/21/91
* code to work keyboard & display for PC-style console
#include "i386/isa/isa_device.h"
#include "i386/isa/icu.h"
#include "i386/i386/cons.h"
#include "i386/isa/isa.h"
#include "i386/isa/ic/i8042.h"
#include "i386/isa/kbd.h"
#include "machine/pc/display.h"
#ifdef XSERVER /* 15 Aug 92*/
#define CSF_ACTIVE 0x1 /* timeout active */
#define CSF_POLLING 0x2 /* polling for input */
char cs_lastc
; /* last char sent */
int cs_timo
; /* timeouts since interrupt */
u_long cs_wedgecnt
; /* times restarted */
#define KBDF_ACTIVE 0x1 /* timeout active */
#define KBDF_POLLING 0x2 /* polling for input */
#define KBDF_RAW 0x4 /* pass thru scan codes for input */
char kbd_lastc
; /* last char sent */
static struct video_state
{
char esc
; /* seen escape */
char ebrac
; /* seen escape bracket */
char eparm
; /* seen escape and parameters */
char so
; /* in standout mode? */
int cx
; /* "x" parameter */
int cy
; /* "y" parameter */
int row
, col
; /* current cursor position */
int nrow
, ncol
; /* current screen geometry */
char fg_at
, bg_at
; /* normal attributes */
char so_at
; /* standout attribute */
char kern_fg_at
, kern_bg_at
;
char color
; /* color or mono display */
int pcprobe(), pcattach();
struct isa_driver pcdriver
= {
/* block cursor so wfj does not go blind on laptop hunting for
the verdamnt cursor -wfj */
#define MONO_BUF (KERNBASE + 0xB0000)
#define CGA_BUF (KERNBASE + 0xB8000)
#define IOPHYSMEM 0xA0000
static unsigned int addr_6845
= MONO_BASE
;
u_short
*Crtat
= (u_short
*)MONO_BUF
;
* We check the console periodically to make sure
* that it hasn't wedged. Unfortunately, if an XOFF
* is typed on the console, that can't be distinguished
* from more catastrophic failure.
#define CN_TIMERVAL (hz) /* frequency at which to check cons */
#define CN_TIMO (2*60) /* intervals to allow for output char */
extern pcopen(dev_t
, int, int, struct proc
*);
* Wait for CP to accept last CP command sent
* before setting up next command.
#define waitforlast(timo) { \
uncache((char *)&pclast->cp_unit); \
while ((pclast->cp_unit&CPTAKE) == 0 && --(timo)); \
* Pass command to keyboard controller (8042)
static int kbc_8042cmd(val
)
timeo
= 100000; /* > 100 msec */
while (inb(KBSTATP
) & KBS_IBF
)
* Pass command to keyboard itself
timeo
= 100000; /* > 100 msec */
while (inb(KBSTATP
) & KBS_IBF
)
* Read response from keyboard
timeo
= 500000; /* > 500 msec (KBR_RSTDONE requires 87) */
while (!(inb(KBSTATP
) & KBS_DIB
))
return ((u_char
) inb(KBDATAP
));
* these are both bad jokes
/* Enable interrupts and keyboard, etc. */
if (kbc_8042cmd(K_LDCMDBYTE
) != 0)
printf("Timeout specifying load of keyboard command byte\n");
if (kbd_cmd(CMDBYTE
) != 0)
printf("Timeout writing keyboard command byte\n");
* Discard any stale keyboard activity. The 0.1 boot code isn't
* very careful and sometimes leaves a KBR_RESEND.
while (inb(KBSTATP
) & KBS_DIB
)
/* Start keyboard reset */
if (kbd_cmd(KBC_RESET
) != 0)
printf("Timeout for keyboard reset command\n");
/* Wait for the first response to reset and handle retries */
while ((response
= kbd_response()) != KBR_ACK
) {
printf("Timeout for keyboard reset ack byte #1\n");
if (response
== KBR_RESEND
) {
printf("KEYBOARD disconnected: RECONNECT\n");
if (kbd_cmd(KBC_RESET
) != 0)
printf("Timeout for keyboard reset command\n");
* Other responses are harmless. They may occur for new
/* Wait for the second response to reset */
while ((response
= kbd_response()) != KBR_RSTDONE
) {
printf("Timeout for keyboard reset ack byte #2\n");
* If KBR_RSTDONE never arrives, the loop will
* finish here unless the keyboard babbles or
u_short
*cp
= Crtat
+ (CGA_BUF
-MONO_BUF
)/CHR
;
printf("pc%d: type monochrome\n",dev
->id_unit
);
else printf("pc%d: type color\n",dev
->id_unit
);
pcopen(dev_t dev
, int flag
, int mode
, struct proc
*p
)
pcopen(dev
, flag
, mode
, p
)
if ((tp
->t_state
& TS_ISOPEN
) == 0) {
tp
->t_iflag
= TTYDEF_IFLAG
;
tp
->t_oflag
= TTYDEF_OFLAG
;
tp
->t_cflag
= TTYDEF_CFLAG
;
tp
->t_lflag
= TTYDEF_LFLAG
;
tp
->t_ispeed
= tp
->t_ospeed
= TTYDEF_SPEED
;
pcparam(tp
, &tp
->t_termios
);
} else if (tp
->t_state
&TS_XCLUDE
&& p
->p_ucred
->cr_uid
!= 0)
tp
->t_state
|= TS_CARR_ON
;
return ((*linesw
[tp
->t_line
].l_open
)(dev
, tp
));
pcclose(dev
, flag
, mode
, p
)
(*linesw
[pccons
.t_line
].l_close
)(&pccons
, flag
);
return ((*linesw
[pccons
.t_line
].l_read
)(&pccons
, uio
, flag
));
return ((*linesw
[pccons
.t_line
].l_write
)(&pccons
, uio
, flag
));
* Got a console receive interrupt -
* the console processor wants to give us a character.
* Catch the character, and see who it goes to.
if (pcconsoftc
.cs_flags
& CSF_POLLING
)
if (kdbrintr(c
, &pccons
))
#ifdef XSERVER /* 15 Aug 92*/
/* send at least one character, because cntl-space is a null */
(*linesw
[pccons
.t_line
].l_rint
)(*cp
++ & 0xff, &pccons
);
(*linesw
[pccons
.t_line
].l_rint
)(*cp
++ & 0xff, &pccons
);
#ifdef XSERVER /* 15 Aug 92*/
#define CONSOLE_X_MODE_ON _IO('t',121)
#define CONSOLE_X_MODE_OFF _IO('t',122)
#define CONSOLE_X_BELL _IOW('t',123,int[2])
pcioctl(dev
, cmd
, data
, flag
)
register struct tty
*tp
= &pccons
;
#ifdef XSERVER /* 15 Aug 92*/
if (cmd
== CONSOLE_X_MODE_ON
) {
} else if (cmd
== CONSOLE_X_MODE_OFF
) {
} else if (cmd
== CONSOLE_X_BELL
) {
/* if set, data is a pointer to a length 2 array of
integers. data[0] is the pitch in Hz and data[1]
is the duration in msec. */
sysbeep(1187500/ ((int*)data
)[0],
((int*)data
)[1] * hz
/ 3000);
error
= (*linesw
[tp
->t_line
].l_ioctl
)(tp
, cmd
, data
, flag
);
error
= ttioctl(tp
, cmd
, data
, flag
);
* Got a console transmission interrupt -
* the console processor wants another character.
pccons
.t_state
&= ~TS_BUSY
;
(*linesw
[pccons
.t_line
].l_start
)(&pccons
);
if (tp
->t_state
& (TS_TIMEOUT
|TS_BUSY
|TS_TTSTOP
))
if (RB_LEN(&tp
->t_out
) <= tp
->t_lowat
) {
if (tp
->t_state
&TS_ASLEEP
) {
tp
->t_state
&= ~TS_ASLEEP
;
wakeup((caddr_t
)&tp
->t_out
);
selwakeup(tp
->t_wsel
, tp
->t_state
& TS_WCOLL
);
tp
->t_state
&= ~TS_WCOLL
;
if (RB_LEN(&tp
->t_out
) == 0)
tp
->t_state
|= TS_BUSY
; /* 21 Aug 92*/
tp
->t_state
&= ~TS_BUSY
; /* 21 Aug 92*/
/* locate the major number */
for (maj
= 0; maj
< nchrdev
; maj
++)
if (cdevsw
[maj
].d_open
== pcopen
)
/* initialize required fields */
cp
->cn_dev
= makedev(maj
, 0);
cp
->cn_pri
= CN_INTERNAL
;
* For now, don't screw with it.
* Print a character on console.
/*if (c=='\n') getchar();*/
#ifdef XSERVER /* 15 Aug 92*/
s
= spltty(); /* block pcrint while we poll */
if (*cp
== '\r') return('\n');
#ifdef XSERVER /* 15 Aug 92*/
register struct termios
*t
;
register int cflag
= t
->c_cflag
;
tp
->t_ispeed
= t
->c_ispeed
;
tp
->t_ospeed
= t
->c_ospeed
;
* Turn input polling on/off (used by debugger).
* reassigns cursor position, updated by the rescheduling clock
* which is a index (0-1999) into the text area. Note that the
* cursor is a "foreground" character, it's color determined by
* the fg_at attribute. Thus if fg_at is left as 0, (FG_BLACK),
* as when a portion of screen memory is 0, the cursor may dissappear.
static u_short
*crtat
= 0;
{ int pos
= crtat
- Crtat
;
#ifdef XSERVER /* 15 Aug 92*/
outb(addr_6845
+1, pos
>> 8);
timeout(cursor
, 0, hz
/10);
#ifdef XSERVER /* 15 Aug 92*/
static u_char shift_down
, ctrl_down
, alt_down
, caps
, num
, scroll
;
{ char *cp = (char *)crtat; *cp++ = (c); *cp = (at); crtat++; vs.col++; }
/* translate ANSI color codes to standard pc ones */
static char fgansitopc
[] =
{ FG_BLACK
, FG_RED
, FG_GREEN
, FG_BROWN
, FG_BLUE
,
FG_MAGENTA
, FG_CYAN
, FG_LIGHTGREY
};
static char bgansitopc
[] =
{ BG_BLACK
, BG_RED
, BG_GREEN
, BG_BROWN
, BG_BLUE
,
BG_MAGENTA
, BG_CYAN
, BG_LIGHTGREY
};
* sput has support for emulation of the 'pc3' termcap entry.
* if ka, use kernel attributes.
int sc
= 1; /* do scroll check */
#ifdef XSERVER /* 15 Aug 92*/
u_short
volatile *cp
= Crtat
+ (CGA_BUF
-MONO_BUF
)/CHR
;
* Crtat initialized to point to MONO buffer if not present
* change to CGA_BUF offset ONLY ADD the difference since
* locore.s adds in the remapped offset at the right time
Crtat
= Crtat
+ (CGA_BUF
-MONO_BUF
)/CHR
;
/* Extract cursor location */
cursorat
= inb(addr_6845
+1)<<8 ;
cursorat
|= inb(addr_6845
+1);
crtat
= Crtat
+ cursorat
;
vs
.kern_fg_at
= FG_UNDERLINE
;
vs
.so_at
= FG_BLACK
| BG_LIGHTGREY
;
vs
.kern_fg_at
= FG_LIGHTGREY
;
vs
.so_at
= FG_YELLOW
| BG_BLACK
;
vs
.kern_bg_at
= BG_BLACK
;
fillw(((vs
.bg_at
|vs
.fg_at
)<<8)|' ', crtat
, COL
*ROW
-cursorat
);
/* which attributes do we use? */
vs
.esc
= 1; vs
.ebrac
= 0; vs
.eparm
= 0;
inccol
= (8 - vs
.col
% 8); /* non-destructive tab */
if (vs
.col
< 0) vs
.col
+= vs
.ncol
; /* non-destructive backspace */
crtat
-= (crtat
- Crtat
) % vs
.ncol
; vs
.col
= 0;
vs
.esc
= 0; vs
.ebrac
= 0; vs
.eparm
= 0;
case 'A': /* back cx rows */
if (vs
.cx
<= 0) vs
.cx
= 1;
pos
+= vs
.nrow
* vs
.ncol
;
sc
= vs
.esc
= vs
.ebrac
= vs
.eparm
= 0;
case 'B': /* down cx rows */
if (vs
.cx
<= 0) vs
.cx
= 1;
if (pos
>= vs
.nrow
* vs
.ncol
)
pos
-= vs
.nrow
* vs
.ncol
;
sc
= vs
.esc
= vs
.ebrac
= vs
.eparm
= 0;
case 'C': /* right cursor */
pos
+= vs
.cx
; vs
.col
+= vs
.cx
;
pos
-= vs
.ncol
; /* cursor stays on same line */
sc
= vs
.esc
= vs
.ebrac
= vs
.eparm
= 0;
case 'D': /* left cursor */
pos
-= vs
.cx
; vs
.col
-= vs
.cx
;
pos
+= vs
.ncol
; /* cursor stays on same line */
sc
= vs
.esc
= vs
.ebrac
= vs
.eparm
= 0;
case 'J': /* Clear ... */
/* ... to end of display */
Crtat
+ vs
.ncol
* vs
.nrow
- crtat
);
/* ... to next location */
vs
.esc
= 0; vs
.ebrac
= 0; vs
.eparm
= 0;
case 'K': /* Clear line ... */
vs
.ncol
- (crtat
- Crtat
) % vs
.ncol
);
/* ... beginning to next */
crtat
- (crtat
- Crtat
) % vs
.ncol
,
((crtat
- Crtat
) % vs
.ncol
) + 1);
crtat
- (crtat
- Crtat
) % vs
.ncol
,
vs
.esc
= 0; vs
.ebrac
= 0; vs
.eparm
= 0;
case 'f': /* in system V consoles */
case 'H': /* Cursor move */
if ((!vs
.cx
)||(!vs
.cy
)) {
crtat
= Crtat
+ (vs
.cx
- 1) * vs
.ncol
+ vs
.cy
- 1;
vs
.esc
= 0; vs
.ebrac
= 0; vs
.eparm
= 0;
case 'S': /* scroll up cx lines */
if (vs
.cx
<= 0) vs
.cx
= 1;
bcopy(Crtat
+vs
.ncol
*vs
.cx
, Crtat
, vs
.ncol
*(vs
.nrow
-vs
.cx
)*CHR
);
fillw((at
<<8)+' ', Crtat
+vs
.ncol
*(vs
.nrow
-vs
.cx
), vs
.ncol
*vs
.cx
);
/* crtat -= vs.ncol*vs.cx; /* XXX */
vs
.esc
= 0; vs
.ebrac
= 0; vs
.eparm
= 0;
case 'T': /* scroll down cx lines */
if (vs
.cx
<= 0) vs
.cx
= 1;
bcopy(Crtat
, Crtat
+vs
.ncol
*vs
.cx
, vs
.ncol
*(vs
.nrow
-vs
.cx
)*CHR
);
fillw((at
<<8)+' ', Crtat
, vs
.ncol
*vs
.cx
);
/* crtat += vs.ncol*vs.cx; /* XXX */
vs
.esc
= 0; vs
.ebrac
= 0; vs
.eparm
= 0;
case ';': /* Switch params in cursor def */
vs
.so_at
= (vs
.cx
& 0x0f) | ((vs
.cy
& 0x0f) << 4);
vs
.esc
= 0; vs
.ebrac
= 0; vs
.eparm
= 0;
case 'x': /* set attributes */
/* reset to normal attributes */
fg_at
= vs
.color
? FG_LIGHTGREY
: FG_UNDERLINE
;
bg_at
= bgansitopc
[vs
.cy
& 7];
fg_at
= fgansitopc
[vs
.cy
& 7];
vs
.esc
= 0; vs
.ebrac
= 0; vs
.eparm
= 0;
default: /* Only numbers valid here */
if ((c
>= '0')&&(c
<= '9')) {
vs
.esc
= 0; vs
.ebrac
= 0; vs
.eparm
= 0;
} else if (c
== 'c') { /* Clear screen & home */
fillw((at
<< 8) + ' ', Crtat
, vs
.ncol
*vs
.nrow
);
crtat
= Crtat
; vs
.col
= 0;
vs
.esc
= 0; vs
.ebrac
= 0; vs
.eparm
= 0;
} else if (c
== '[') { /* Start ESC [ sequence */
vs
.ebrac
= 1; vs
.cx
= 0; vs
.cy
= 0; vs
.eparm
= 0;
} else { /* Invalid, clear state */
vs
.esc
= 0; vs
.ebrac
= 0; vs
.eparm
= 0;
if (vs
.col
>= vs
.ncol
) vs
.col
= 0;
if (sc
&& crtat
>= Crtat
+vs
.ncol
*vs
.nrow
) { /* scroll check */
if (openf
) do (void)sgetc(1); while (scroll
);
bcopy(Crtat
+vs
.ncol
, Crtat
, vs
.ncol
*(vs
.nrow
-1)*CHR
);
fillw ((at
<< 8) + ' ', Crtat
+ vs
.ncol
*(vs
.nrow
-1),
unsigned __debug
= 0; /*0xffe */
static char scantokey
[] = {
static char extscantokey
[] = {
#define CODE_SIZE 4 /* Use a max of 4 for now... */
#define SHIFT 0x0002 /* keyboard shift */
#define ALT 0x0004 /* alternate shift -- alternate chars */
#define NUM 0x0008 /* numeric shift cursors vs. numeric */
#define CTL 0x0010 /* control shift -- allows ctl function */
#define CAPS 0x0020 /* caps shift -- swaps case of letter */
#define ASCII 0x0040 /* ascii code for this key */
#define SCROLL 0x0080 /* stop output */
#define FUNC 0x0100 /* function key */
#define KP 0x0200 /* Keypad keys */
#define NONE 0x0400 /* no function */
static Scan_def scan_codes
[] =
NONE
, "", "", "", /* 0 unused */
ASCII
, "\033", "\033", "\033", /* 1 ESCape */
ASCII
, "1", "!", "!", /* 2 1 */
ASCII
, "2", "@", "\000", /* 3 2 */
ASCII
, "3", "#", "#", /* 4 3 */
ASCII
, "4", "$", "$", /* 5 4 */
ASCII
, "5", "%", "%", /* 6 5 */
ASCII
, "6", "^", "\036", /* 7 6 */
ASCII
, "7", "&", "&", /* 8 7 */
ASCII
, "8", "*", "\010", /* 9 8 */
ASCII
, "9", "(", "(", /* 10 9 */
ASCII
, "0", ")", ")", /* 11 0 */
ASCII
, "-", "_", "\037", /* 12 - */
ASCII
, "=", "+", "+", /* 13 = */
ASCII
, "\177", "\177", "\010", /* 14 backspace */
ASCII
, "\t", "\177\t", "\t", /* 15 tab */
ASCII
, "q", "Q", "\021", /* 16 q */
ASCII
, "w", "W", "\027", /* 17 w */
ASCII
, "e", "E", "\005", /* 18 e */
ASCII
, "r", "R", "\022", /* 19 r */
ASCII
, "t", "T", "\024", /* 20 t */
ASCII
, "y", "Y", "\031", /* 21 y */
ASCII
, "u", "U", "\025", /* 22 u */
ASCII
, "i", "I", "\011", /* 23 i */
ASCII
, "o", "O", "\017", /* 24 o */
ASCII
, "p", "P", "\020", /* 25 p */
ASCII
, "[", "{", "\033", /* 26 [ */
ASCII
, "]", "}", "\035", /* 27 ] */
ASCII
, "\r", "\r", "\n", /* 28 return */
CTL
, "", "", "", /* 29 control */
ASCII
, "a", "A", "\001", /* 30 a */
ASCII
, "s", "S", "\023", /* 31 s */
ASCII
, "d", "D", "\004", /* 32 d */
ASCII
, "f", "F", "\006", /* 33 f */
ASCII
, "g", "G", "\007", /* 34 g */
ASCII
, "h", "H", "\010", /* 35 h */
ASCII
, "j", "J", "\n", /* 36 j */
ASCII
, "k", "K", "\013", /* 37 k */
ASCII
, "l", "L", "\014", /* 38 l */
ASCII
, ";", ":", ";", /* 39 ; */
ASCII
, "'", "\"", "'", /* 40 ' */
ASCII
, "`", "~", "`", /* 41 ` */
SHIFT
, "", "", "", /* 42 shift */
ASCII
, "\\", "|", "\034", /* 43 \ */
ASCII
, "z", "Z", "\032", /* 44 z */
ASCII
, "x", "X", "\030", /* 45 x */
ASCII
, "c", "C", "\003", /* 46 c */
ASCII
, "v", "V", "\026", /* 47 v */
ASCII
, "b", "B", "\002", /* 48 b */
ASCII
, "n", "N", "\016", /* 49 n */
ASCII
, "m", "M", "\r", /* 50 m */
ASCII
, ",", "<", "<", /* 51 , */
ASCII
, ".", ">", ">", /* 52 . */
ASCII
, "/", "?", "\177", /* 53 / */
SHIFT
, "", "", "", /* 54 shift */
KP
, "*", "*", "*", /* 55 kp * */
ALT
, "", "", "", /* 56 alt */
ASCII
, " ", " ", " ", /* 57 space */
CAPS
, "", "", "", /* 58 caps */
FUNC
, "\033[M", "\033[Y", "\033[k", /* 59 f1 */
FUNC
, "\033[N", "\033[Z", "\033[l", /* 60 f2 */
FUNC
, "\033[O", "\033[a", "\033[m", /* 61 f3 */
FUNC
, "\033[P", "\033[b", "\033[n", /* 62 f4 */
FUNC
, "\033[Q", "\033[c", "\033[o", /* 63 f5 */
FUNC
, "\033[R", "\033[d", "\033[p", /* 64 f6 */
FUNC
, "\033[S", "\033[e", "\033[q", /* 65 f7 */
FUNC
, "\033[T", "\033[f", "\033[r", /* 66 f8 */
FUNC
, "\033[U", "\033[g", "\033[s", /* 67 f9 */
FUNC
, "\033[V", "\033[h", "\033[t", /* 68 f10 */
NUM
, "", "", "", /* 69 num lock */
SCROLL
, "", "", "", /* 70 scroll lock */
KP
, "7", "\033[H", "7", /* 71 kp 7 */
KP
, "8", "\033[A", "8", /* 72 kp 8 */
KP
, "9", "\033[I", "9", /* 73 kp 9 */
KP
, "-", "-", "-", /* 74 kp - */
KP
, "4", "\033[D", "4", /* 75 kp 4 */
KP
, "5", "\033[E", "5", /* 76 kp 5 */
KP
, "6", "\033[C", "6", /* 77 kp 6 */
KP
, "+", "+", "+", /* 78 kp + */
KP
, "1", "\033[F", "1", /* 79 kp 1 */
KP
, "2", "\033[B", "2", /* 80 kp 2 */
KP
, "3", "\033[G", "3", /* 81 kp 3 */
KP
, "0", "\033[L", "0", /* 82 kp 0 */
KP
, ".", "\177", ".", /* 83 kp . */
NONE
, "", "", "", /* 84 0 */
NONE
, "100", "", "", /* 85 0 */
NONE
, "101", "", "", /* 86 0 */
FUNC
, "\033[W", "\033[i", "\033[u", /* 87 f11 */
FUNC
, "\033[X", "\033[j", "\033[v", /* 88 f12 */
NONE
, "102", "", "", /* 89 0 */
NONE
, "103", "", "", /* 90 0 */
NONE
, "", "", "", /* 91 0 */
NONE
, "", "", "", /* 92 0 */
NONE
, "", "", "", /* 93 0 */
NONE
, "", "", "", /* 94 0 */
NONE
, "", "", "", /* 95 0 */
NONE
, "", "", "", /* 96 0 */
NONE
, "", "", "", /* 97 0 */
NONE
, "", "", "", /* 98 0 */
NONE
, "", "", "", /* 99 0 */
NONE
, "", "", "", /* 100 */
NONE
, "", "", "", /* 101 */
NONE
, "", "", "", /* 102 */
NONE
, "", "", "", /* 103 */
NONE
, "", "", "", /* 104 */
NONE
, "", "", "", /* 105 */
NONE
, "", "", "", /* 106 */
NONE
, "", "", "", /* 107 */
NONE
, "", "", "", /* 108 */
NONE
, "", "", "", /* 109 */
NONE
, "", "", "", /* 110 */
NONE
, "", "", "", /* 111 */
NONE
, "", "", "", /* 112 */
NONE
, "", "", "", /* 113 */
NONE
, "", "", "", /* 114 */
NONE
, "", "", "", /* 115 */
NONE
, "", "", "", /* 116 */
NONE
, "", "", "", /* 117 */
NONE
, "", "", "", /* 118 */
NONE
, "", "", "", /* 119 */
NONE
, "", "", "", /* 120 */
NONE
, "", "", "", /* 121 */
NONE
, "", "", "", /* 122 */
NONE
, "", "", "", /* 123 */
NONE
, "", "", "", /* 124 */
NONE
, "", "", "", /* 125 */
NONE
, "", "", "", /* 126 */
NONE
, "", "", "", /* 127 */
if (kbd_cmd(KBC_STSIND
) != 0) {
printf("Timeout for keyboard LED command\n");
* XXX This is quite questionable, but seems to fix
* some keyboard controllers need some time after they
* get a command. Without this the keyboard 'hangs'.
* This seems to be the only place where two commands
* are just one behind another.
if (kbd_cmd(scroll
| (num
<< 1) | (caps
<< 2)) != 0)
printf("Timeout for keyboard LED data\n");
else if ((response
= kbd_response()) < 0)
printf("Timeout for keyboard LED ack\n");
else if (response
!= KBR_ACK
)
printf("Unexpected keyboard LED ack %d\n", response
);
* Skip waiting for and checking the response. The waiting
* would be too long (about 3 msec) and the checking might eat
* fresh keystrokes. The waiting should be done using timeout()
* and the checking should be done in the interrupt handler.
* sgetc(noblock): get characters from the keyboard. If
* noblock == 0 wait until a key is gotten. Otherwise return a
* if no characters are present 0.
static u_char extended
= 0;
* First see if there is something in the keyboard port
#ifdef XSERVER /* 15 Aug 92*/
if (inb(KBSTATP
) & KBS_DIB
) {
/* switch the caps lock and control keys */
switch (scan_codes
[dt
].type
)
if (inb(KBSTATP
) & KBS_DIB
) {
/* switch the caps lock and control keys */
#ifdef XSERVER /* 15 Aug 92*/
if ((dt
== 1) && ctrl_down
&& alt_down
) {
dt
|= 0x80; /* discard esc (ddb discarded ctrl-alt) */
switch (scan_codes
[dt
].type
)
switch (scan_codes
[dt
].type
)
#ifdef XSERVER /* 15 Aug 92*/
* 18 Sep 92 Terry Lambert I find that this behaviour is questionable --
* I believe that this should be conditional on
* the value of pc_xmode rather than always
* done. In particular, "case NONE" seems to
* not cause a scancode return. This may
* invalidate alt-"=" and alt-"-" as well as the
* F11 and F12 keys, and some keys on lap-tops,
* Especially Toshibal T1100 and Epson Equity 1
* and Equity 1+ when not in pc_xmode.
/* control has highest priority */
capchar
[0] = scan_codes
[dt
].ctrl
[0];
capchar
[0] = scan_codes
[dt
].shift
[0];
capchar
[0] = scan_codes
[dt
].unshift
[0];
if (caps
&& (capchar
[0] >= 'a'
capchar
[0] = capchar
[0] - ('a' - 'A');
more_chars
= scan_codes
[dt
].shift
;
more_chars
= scan_codes
[dt
].ctrl
;
more_chars
= scan_codes
[dt
].unshift
;
#ifndef XSERVER /* 15 Aug 92*/
if (caps
&& more_chars
[1] == 0
&& more_chars
[0] <= 'z')) {
capchar
[0] = *more_chars
- ('a' - 'A');
if (shift_down
|| ctrl_down
|| !num
|| extended
)
more_chars
= scan_codes
[dt
].shift
;
more_chars
= scan_codes
[dt
].unshift
;
#ifdef XSERVER /* 15 Aug 92*/
#ifdef XSERVER /* 15 Aug 92*/
pcconsoftc
.cs_flags
|= CSF_POLLING
;
pcconsoftc
.cs_flags
&= ~CSF_POLLING
;
default: if (thechar
>= ' ')
sput('^', 1) ; sput('C', 1) ; sput('\r', 1) ; sput('\n', 1) ;
sput('^', 1) ; sput('D', 1) ; sput('\r', 1) ; sput('\n', 1) ;
#include "machine/stdarg.h"
dprintf(unsigned flgs
, const char *fmt
, ...)
dprintf(flgs
, fmt
/*, va_alist */)
{ extern unsigned __debug
;
if((flgs
&__debug
) > DPAUSE
) {
__color
= ffs(flgs
&__debug
)+1;
kprintf(fmt
, 1, (struct tty
*)0, ap
);
if (flgs
&DPAUSE
|| nrow
%24 == 23) {
if (nrow
%24 == 23) nrow
= 0;
/* -hv- 22-Apr-93: to make init_main more portable */
/* reset to normal attributes */
/* we are in kernel mode */
vs
.fg_at
= vs
.color
? FG_LIGHTGREY
: FG_UNDERLINE
;
int pcmmap(dev_t dev
, int offset
, int nprot
)
return i386_btop((0xa0000 + offset
));
#ifdef XSERVER /* 15 Aug 92*/
#include "machine/frame.h"
fp
= (struct syscframe
*)curproc
->p_regs
;
fp
->sf_eflags
|= PSL_IOPL
;
fp
= (struct syscframe
*)curproc
->p_regs
;
fp
->sf_eflags
&= ~PSL_IOPL
;
* EOF -- File has not been truncated