Home | History | Annotate | Line # | Download | only in dev
pccons.c revision 1.25
      1  1.25       scw /*	$NetBSD: pccons.c,v 1.25 2001/05/02 10:32:21 scw Exp $	*/
      2  1.14      soda /*	$OpenBSD: pccons.c,v 1.22 1999/01/30 22:39:37 imp Exp $	*/
      3  1.13      soda /*	NetBSD: pccons.c,v 1.89 1995/05/04 19:35:20 cgd Exp	*/
      4  1.13      soda /*	NetBSD: pms.c,v 1.21 1995/04/18 02:25:18 mycroft Exp	*/
      5   1.1  jonathan 
      6   1.1  jonathan /*-
      7  1.11   mycroft  * Copyright (c) 1993, 1994, 1995 Charles M. Hannum.  All rights reserved.
      8   1.1  jonathan  * Copyright (c) 1990 The Regents of the University of California.
      9   1.1  jonathan  * All rights reserved.
     10   1.1  jonathan  *
     11   1.1  jonathan  * This code is derived from software contributed to Berkeley by
     12   1.1  jonathan  * William Jolitz and Don Ahn.
     13   1.1  jonathan  *
     14  1.11   mycroft  * Copyright (c) 1994 Charles M. Hannum.
     15   1.1  jonathan  * Copyright (c) 1992, 1993 Erik Forsberg.
     16   1.1  jonathan  *
     17   1.1  jonathan  * Redistribution and use in source and binary forms, with or without
     18   1.1  jonathan  * modification, are permitted provided that the following conditions
     19   1.1  jonathan  * are met:
     20   1.1  jonathan  * 1. Redistributions of source code must retain the above copyright
     21   1.1  jonathan  *    notice, this list of conditions and the following disclaimer.
     22   1.1  jonathan  * 2. Redistributions in binary form must reproduce the above copyright
     23   1.1  jonathan  *    notice, this list of conditions and the following disclaimer in the
     24   1.1  jonathan  *    documentation and/or other materials provided with the distribution.
     25   1.1  jonathan  * 3. All advertising materials mentioning features or use of this software
     26   1.1  jonathan  *    must display the following acknowledgement:
     27   1.1  jonathan  *	This product includes software developed by the University of
     28   1.1  jonathan  *	California, Berkeley and its contributors.
     29   1.1  jonathan  * 4. Neither the name of the University nor the names of its contributors
     30   1.1  jonathan  *    may be used to endorse or promote products derived from this software
     31   1.1  jonathan  *    without specific prior written permission.
     32   1.1  jonathan  *
     33   1.1  jonathan  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     34   1.1  jonathan  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     35   1.1  jonathan  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     36   1.1  jonathan  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     37   1.1  jonathan  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     38   1.1  jonathan  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     39   1.1  jonathan  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     40   1.1  jonathan  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     41   1.1  jonathan  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     42   1.1  jonathan  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     43   1.1  jonathan  * SUCH DAMAGE.
     44   1.1  jonathan  *
     45   1.1  jonathan  *	@(#)pccons.c	5.11 (Berkeley) 5/21/91
     46   1.1  jonathan  */
     47   1.1  jonathan 
     48   1.1  jonathan /*
     49   1.1  jonathan  * code to work keyboard & display for PC-style console
     50   1.1  jonathan  */
     51   1.1  jonathan 
     52  1.14      soda #include "opt_ddb.h"
     53  1.14      soda 
     54   1.1  jonathan #include <sys/param.h>
     55   1.1  jonathan #include <sys/systm.h>
     56   1.1  jonathan #include <sys/ioctl.h>
     57   1.1  jonathan #include <sys/proc.h>
     58   1.1  jonathan #include <sys/user.h>
     59   1.1  jonathan #include <sys/select.h>
     60   1.1  jonathan #include <sys/tty.h>
     61   1.1  jonathan #include <sys/uio.h>
     62   1.1  jonathan #include <sys/callout.h>
     63   1.1  jonathan #include <sys/syslog.h>
     64   1.1  jonathan #include <sys/device.h>
     65   1.8  jonathan #include <sys/poll.h>
     66  1.13      soda #include <sys/conf.h>
     67  1.13      soda #include <sys/vnode.h>
     68  1.13      soda #include <sys/fcntl.h>
     69  1.13      soda #include <sys/kernel.h>
     70  1.13      soda #include <sys/kcore.h>
     71   1.1  jonathan 
     72   1.1  jonathan #include <dev/cons.h>
     73   1.1  jonathan 
     74   1.1  jonathan #include <machine/cpu.h>
     75   1.1  jonathan #include <machine/pio.h>
     76   1.1  jonathan #include <machine/autoconf.h>
     77   1.7  jonathan #include <machine/bus.h>
     78   1.1  jonathan #include <machine/display.h>
     79   1.1  jonathan #include <machine/pccons.h>
     80  1.13      soda #include <arc/arc/arctype.h>
     81  1.13      soda #include <arc/arc/arcbios.h>
     82  1.23        ur #include <arc/jazz/pica.h>
     83  1.13      soda #include <arc/dti/desktech.h>
     84  1.23        ur #include <arc/jazz/jazziovar.h>
     85   1.1  jonathan 
     86   1.1  jonathan #include <dev/isa/isavar.h>
     87  1.13      soda #include <machine/isa_machdep.h>
     88   1.1  jonathan #include <machine/kbdreg.h>
     89   1.1  jonathan 
     90  1.13      soda #include <dev/cons.h>
     91  1.13      soda 
     92  1.20      soda #include "pc.h"
     93  1.20      soda 
     94   1.1  jonathan #define	XFREE86_BUG_COMPAT
     95   1.1  jonathan 
     96   1.1  jonathan #ifndef BEEP_FREQ
     97   1.1  jonathan #define BEEP_FREQ 1600
     98   1.1  jonathan #endif
     99   1.1  jonathan #ifndef BEEP_TIME
    100   1.1  jonathan #define BEEP_TIME (hz/5)
    101   1.1  jonathan #endif
    102   1.1  jonathan 
    103   1.1  jonathan #define PCBURST 128
    104   1.1  jonathan 
    105   1.1  jonathan static u_short *Crtat;			/* pointer to backing store */
    106   1.1  jonathan static u_short *crtat;			/* pointer to current char */
    107   1.1  jonathan static u_char async, kernel, polling;	/* Really, you don't want to know. */
    108   1.1  jonathan static u_char lock_state = 0x00,	/* all off */
    109   1.1  jonathan 	      old_lock_state = 0xff,
    110   1.1  jonathan 	      typematic_rate = 0xff,	/* don't update until set by user */
    111   1.1  jonathan 	      old_typematic_rate = 0xff;
    112   1.1  jonathan static u_short cursor_shape = 0xffff,	/* don't update until set by user */
    113   1.1  jonathan 	       old_cursor_shape = 0xffff;
    114  1.13      soda static pccons_keymap_t scan_codes[KB_NUM_KEYS];/* keyboard translation table */
    115   1.1  jonathan int pc_xmode = 0;
    116   1.1  jonathan 
    117  1.13      soda cdev_decl(pc);
    118  1.13      soda 
    119   1.1  jonathan /*
    120   1.1  jonathan  *  Keyboard output queue.
    121   1.1  jonathan  */
    122   1.1  jonathan int	kb_oq_put = 0;
    123   1.1  jonathan int	kb_oq_get = 0;
    124   1.1  jonathan u_char	kb_oq[8];
    125   1.1  jonathan 
    126   1.1  jonathan #define	PCUNIT(x)	(minor(x))
    127   1.1  jonathan 
    128   1.1  jonathan static struct video_state {
    129   1.1  jonathan 	int 	cx, cy;		/* escape parameters */
    130   1.1  jonathan 	int 	row, col;	/* current cursor position */
    131   1.1  jonathan 	int 	nrow, ncol, nchr;	/* current screen geometry */
    132  1.13      soda 	int	offset;		/* Saved cursor pos */
    133   1.1  jonathan 	u_char	state;		/* parser state */
    134   1.1  jonathan #define	VSS_ESCAPE	1
    135   1.1  jonathan #define	VSS_EBRACE	2
    136   1.1  jonathan #define	VSS_EPARAM	3
    137   1.1  jonathan 	char	so;		/* in standout mode? */
    138   1.1  jonathan 	char	color;		/* color or mono display */
    139   1.1  jonathan 	char	at;		/* normal attributes */
    140   1.1  jonathan 	char	so_at;		/* standout attributes */
    141   1.1  jonathan } vs;
    142   1.1  jonathan 
    143   1.1  jonathan struct pc_softc {
    144   1.1  jonathan 	struct	device sc_dev;
    145   1.1  jonathan 	struct	tty *sc_tty;
    146   1.1  jonathan };
    147   1.1  jonathan 
    148  1.13      soda struct opms_softc {		/* driver status information */
    149   1.1  jonathan 	struct device sc_dev;
    150   1.1  jonathan 
    151   1.1  jonathan 	struct clist sc_q;
    152   1.1  jonathan 	struct selinfo sc_rsel;
    153   1.1  jonathan 	u_char sc_state;	/* mouse driver state */
    154   1.1  jonathan #define	PMS_OPEN	0x01	/* device is open */
    155   1.1  jonathan #define	PMS_ASLP	0x02	/* waiting for mouse data */
    156   1.1  jonathan 	u_char sc_status;	/* mouse button status */
    157   1.1  jonathan 	int sc_x, sc_y;		/* accumulated motion in the X,Y axis */
    158   1.1  jonathan };
    159   1.1  jonathan 
    160  1.17   thorpej static struct callout async_update_ch = CALLOUT_INITIALIZER;
    161  1.17   thorpej 
    162  1.13      soda int pcprobe __P((struct device *, struct cfdata *, void *));
    163   1.1  jonathan void pcattach __P((struct device *, struct device *, void *));
    164   1.1  jonathan int pcintr __P((void *));
    165  1.13      soda void pc_xmode_on __P((void));
    166  1.13      soda void pc_xmode_off __P((void));
    167  1.13      soda static u_char kbc_get8042cmd __P((void));
    168  1.13      soda static int kbc_put8042cmd __P((u_char));
    169  1.13      soda int kbc_8042sysreset __P((void));
    170  1.13      soda int kbd_cmd __P((u_char, u_char));
    171  1.13      soda static __inline int kbd_wait_output __P((void));
    172  1.13      soda static __inline int kbd_wait_input __P((void));
    173  1.13      soda static __inline void kbd_flush_input __P((void));
    174  1.13      soda void set_cursor_shape __P((void));
    175  1.13      soda void get_cursor_shape __P((void));
    176  1.13      soda void async_update __P((void));
    177  1.13      soda void do_async_update __P((u_char));;
    178  1.13      soda 
    179  1.13      soda void pccnattach __P((void));
    180  1.13      soda void pccnputc __P((dev_t, int c));
    181  1.13      soda int pccngetc __P((dev_t));
    182  1.13      soda void pccnpollc __P((dev_t, int));
    183   1.1  jonathan 
    184  1.13      soda extern struct cfdriver pc_cd;
    185  1.13      soda 
    186  1.23        ur struct cfattach pc_jazzio_ca = {
    187  1.13      soda 	 sizeof(struct pc_softc), pcprobe, pcattach
    188   1.2   thorpej };
    189   1.2   thorpej 
    190  1.13      soda struct cfattach pc_isa_ca = {
    191  1.13      soda 	 sizeof(struct pc_softc), pcprobe, pcattach
    192  1.13      soda };
    193  1.20      soda 
    194  1.13      soda int opmsprobe __P((struct device *, struct cfdata *, void *));
    195  1.13      soda void opmsattach __P((struct device *, struct device *, void *));
    196  1.13      soda int opmsintr __P((void *));
    197   1.1  jonathan 
    198  1.20      soda #if NOPMS > 0
    199  1.13      soda struct cfattach opms_ca = {
    200  1.13      soda 	sizeof(struct opms_softc), opmsprobe, opmsattach
    201  1.13      soda };
    202  1.20      soda #endif
    203   1.1  jonathan 
    204  1.13      soda extern struct cfdriver opms_cd;
    205   1.2   thorpej 
    206   1.1  jonathan #define	PMSUNIT(dev)	(minor(dev))
    207   1.1  jonathan 
    208   1.1  jonathan #define	CHR		2
    209   1.1  jonathan 
    210  1.13      soda static unsigned int addr_6845;
    211  1.13      soda static unsigned int mono_base = 0x3b4;
    212  1.13      soda static unsigned int mono_buf = 0xb0000;
    213  1.13      soda static unsigned int cga_base = 0x3d4;
    214  1.13      soda static unsigned int cga_buf = 0xb8000;
    215  1.13      soda static unsigned int kbd_cmdp = 0x64;
    216  1.13      soda static unsigned int kbd_datap = 0x60;
    217   1.1  jonathan 
    218   1.1  jonathan char *sget __P((void));
    219   1.1  jonathan void sput __P((u_char *, int));
    220   1.1  jonathan 
    221  1.13      soda void	pcstart __P((struct tty *));
    222  1.13      soda int	pcparam __P((struct tty *, struct termios *));
    223  1.13      soda static __inline void wcopy __P((void *, void *, u_int));
    224  1.20      soda void	pcinithandle __P((void));
    225  1.13      soda 
    226  1.13      soda extern void fillw __P((int, u_int16_t *, int));
    227   1.1  jonathan 
    228   1.1  jonathan #define	KBD_DELAY \
    229   1.1  jonathan 		DELAY(10);
    230   1.1  jonathan 
    231  1.20      soda void
    232  1.20      soda pcinithandle()
    233  1.20      soda {
    234  1.20      soda 	static int initialized = 0;
    235  1.20      soda 
    236  1.20      soda 	if (initialized)
    237  1.20      soda 		return;
    238  1.20      soda 	initialized = 1;
    239  1.20      soda 
    240  1.20      soda 	switch (cputype) {
    241  1.20      soda 
    242  1.20      soda 	case ACER_PICA_61:
    243  1.20      soda 	case NEC_R96: /* XXX - not really confirmed */
    244  1.20      soda 		mono_base += PICA_V_LOCAL_VIDEO_CTRL;
    245  1.20      soda 		mono_buf += PICA_V_LOCAL_VIDEO;
    246  1.20      soda 		cga_base += PICA_V_LOCAL_VIDEO_CTRL;
    247  1.20      soda 		cga_buf += PICA_V_LOCAL_VIDEO;
    248  1.20      soda 	case MAGNUM:
    249  1.20      soda 	case NEC_R94:
    250  1.20      soda 	case NEC_RAx94:
    251  1.20      soda 	case NEC_RD94:
    252  1.24   tsutsui 	case NEC_JC94:
    253  1.20      soda 		kbd_cmdp = PICA_SYS_KBD + 0x61;
    254  1.20      soda 		kbd_datap = PICA_SYS_KBD + 0x60;
    255  1.20      soda 		break;
    256  1.20      soda 
    257  1.20      soda 	case DESKSTATION_TYNE:
    258  1.20      soda 		bus_space_map(&arc_bus_io, mono_base, 2, 0, &mono_base);
    259  1.20      soda 		bus_space_map(&arc_bus_mem, mono_buf, 0x20000, 0, &mono_buf);
    260  1.20      soda 		bus_space_map(&arc_bus_io, cga_base, 2, 0, &cga_base);
    261  1.20      soda 		bus_space_map(&arc_bus_mem, cga_buf, 0x20000, 0, &cga_buf);
    262  1.20      soda 		bus_space_map(&arc_bus_io, 0x64, 1, 0, &kbd_cmdp);
    263  1.20      soda 		bus_space_map(&arc_bus_io, 0x60, 1, 0, &kbd_datap);
    264  1.20      soda 		break;
    265  1.20      soda 
    266  1.20      soda 	case DESKSTATION_RPC44:
    267  1.20      soda 		bus_space_map(&arc_bus_io, mono_base, 2, 0, &mono_base);
    268  1.20      soda 		bus_space_map(&arc_bus_mem, mono_buf, 0x20000, 0, &mono_buf);
    269  1.20      soda 		bus_space_map(&arc_bus_io, cga_base, 2, 0, &cga_base);
    270  1.20      soda 		bus_space_map(&arc_bus_mem, 0xa0000, 0x20000, 0, &cga_buf);
    271  1.20      soda 		bus_space_map(&arc_bus_io, 0x64, 1, 0, &kbd_cmdp);
    272  1.20      soda 		bus_space_map(&arc_bus_io, 0x60, 1, 0, &kbd_datap);
    273  1.20      soda 		break;
    274  1.20      soda 
    275  1.20      soda 	case SNI_RM200:
    276  1.20      soda 		bus_space_map(&arc_bus_io, mono_base, 2, 0, &mono_base);
    277  1.20      soda 		bus_space_map(&arc_bus_mem, mono_buf, 0x20000, 0, &mono_buf);
    278  1.20      soda 		bus_space_map(&arc_bus_io, cga_base, 2, 0, &cga_base);
    279  1.20      soda 		bus_space_map(&arc_bus_mem, cga_buf, 0x20000, 0, &cga_buf);
    280  1.20      soda 		bus_space_map(&arc_bus_io, 0x64, 1, 0, &kbd_cmdp);
    281  1.20      soda 		bus_space_map(&arc_bus_io, 0x60, 1, 0, &kbd_datap);
    282  1.20      soda 		break;
    283  1.20      soda 	}
    284  1.20      soda }
    285  1.20      soda 
    286  1.13      soda /*
    287  1.13      soda  * bcopy variant that only moves word-aligned 16-bit entities,
    288  1.13      soda  * for stupid VGA cards.  cnt is required to be an even vale.
    289  1.13      soda  */
    290  1.13      soda static __inline void
    291  1.13      soda wcopy(src, tgt, cnt)
    292  1.13      soda 	void *src, *tgt;
    293  1.13      soda 	u_int cnt;
    294  1.13      soda {
    295  1.13      soda 	u_int16_t *from = src;
    296  1.13      soda 	u_int16_t *to = tgt;
    297  1.13      soda 
    298  1.13      soda 	cnt >>= 1;
    299  1.13      soda 	if (to < from || to >= from + cnt)
    300  1.13      soda 		while(cnt--)
    301  1.13      soda 			*to++ = *from++;
    302  1.13      soda 	else {
    303  1.13      soda 		to += cnt;
    304  1.13      soda 		from += cnt;
    305  1.13      soda 		while(cnt--)
    306  1.13      soda 			*--to = *--from;
    307  1.13      soda 	}
    308  1.13      soda }
    309  1.13      soda 
    310  1.13      soda static __inline int
    311   1.1  jonathan kbd_wait_output()
    312   1.1  jonathan {
    313   1.1  jonathan 	u_int i;
    314   1.1  jonathan 
    315   1.1  jonathan 	for (i = 100000; i; i--)
    316  1.13      soda 		if ((inb(kbd_cmdp) & KBS_IBF) == 0) {
    317   1.1  jonathan 			KBD_DELAY;
    318   1.1  jonathan 			return 1;
    319   1.1  jonathan 		}
    320   1.1  jonathan 	return 0;
    321   1.1  jonathan }
    322   1.1  jonathan 
    323  1.13      soda static __inline int
    324   1.1  jonathan kbd_wait_input()
    325   1.1  jonathan {
    326   1.1  jonathan 	u_int i;
    327   1.1  jonathan 
    328   1.1  jonathan 	for (i = 100000; i; i--)
    329  1.13      soda 		if ((inb(kbd_cmdp) & KBS_DIB) != 0) {
    330   1.1  jonathan 			KBD_DELAY;
    331   1.1  jonathan 			return 1;
    332   1.1  jonathan 		}
    333   1.1  jonathan 	return 0;
    334   1.1  jonathan }
    335   1.1  jonathan 
    336  1.13      soda static __inline void
    337   1.1  jonathan kbd_flush_input()
    338   1.1  jonathan {
    339   1.1  jonathan 	u_char c;
    340   1.1  jonathan 
    341  1.13      soda 	while ((c = inb(kbd_cmdp)) & 0x03)
    342   1.1  jonathan 		if ((c & KBS_DIB) == KBS_DIB) {
    343   1.1  jonathan 			/* XXX - delay is needed to prevent some keyboards from
    344   1.1  jonathan 			   wedging when the system boots */
    345   1.1  jonathan 			delay(6);
    346  1.13      soda 			(void) inb(kbd_datap);
    347   1.1  jonathan 		}
    348   1.1  jonathan }
    349   1.1  jonathan 
    350   1.1  jonathan 
    351  1.13      soda 
    352  1.13      soda /*
    353  1.13      soda  * Pass system reset command  to keyboard controller (8042).
    354  1.13      soda  */
    355  1.13      soda int
    356  1.13      soda kbc_8042sysreset()
    357  1.13      soda {
    358  1.13      soda 
    359  1.20      soda 	pcinithandle();
    360  1.20      soda 
    361  1.13      soda 	if (!kbd_wait_output())
    362  1.13      soda 		return 0;
    363  1.13      soda 	outb(kbd_cmdp, 0xd1);
    364  1.13      soda 	if (!kbd_wait_output())
    365  1.13      soda 		return 0;
    366  1.13      soda 	outb(kbd_datap, 0);		/* ZAP */
    367  1.13      soda 	return 1;
    368  1.13      soda }
    369  1.13      soda 
    370   1.1  jonathan #if 1
    371   1.1  jonathan /*
    372   1.1  jonathan  * Get the current command byte.
    373   1.1  jonathan  */
    374   1.1  jonathan static u_char
    375   1.1  jonathan kbc_get8042cmd()
    376   1.1  jonathan {
    377   1.1  jonathan 
    378   1.1  jonathan 	if (!kbd_wait_output())
    379   1.1  jonathan 		return -1;
    380  1.13      soda 	outb(kbd_cmdp, K_RDCMDBYTE);
    381   1.1  jonathan 	if (!kbd_wait_input())
    382   1.1  jonathan 		return -1;
    383  1.13      soda 	return inb(kbd_datap);
    384   1.1  jonathan }
    385   1.1  jonathan #endif
    386   1.1  jonathan 
    387   1.1  jonathan /*
    388   1.1  jonathan  * Pass command byte to keyboard controller (8042).
    389   1.1  jonathan  */
    390   1.1  jonathan static int
    391   1.1  jonathan kbc_put8042cmd(val)
    392   1.1  jonathan 	u_char val;
    393   1.1  jonathan {
    394   1.1  jonathan 
    395   1.1  jonathan 	if (!kbd_wait_output())
    396   1.1  jonathan 		return 0;
    397  1.13      soda 	outb(kbd_cmdp, K_LDCMDBYTE);
    398   1.1  jonathan 	if (!kbd_wait_output())
    399   1.1  jonathan 		return 0;
    400  1.13      soda 	outb(kbd_datap, val);
    401   1.1  jonathan 	return 1;
    402   1.1  jonathan }
    403   1.1  jonathan 
    404   1.1  jonathan /*
    405   1.1  jonathan  * Pass command to keyboard itself
    406   1.1  jonathan  */
    407   1.1  jonathan int
    408   1.1  jonathan kbd_cmd(val, polling)
    409   1.1  jonathan 	u_char val;
    410   1.1  jonathan 	u_char polling;
    411   1.1  jonathan {
    412   1.1  jonathan 	u_int retries = 3;
    413   1.1  jonathan 	register u_int i;
    414   1.1  jonathan 
    415   1.1  jonathan 	if(!polling) {
    416   1.1  jonathan 		i = spltty();
    417   1.1  jonathan 		if(kb_oq_get == kb_oq_put) {
    418  1.13      soda 			outb(kbd_datap, val);
    419   1.1  jonathan 		}
    420   1.1  jonathan 		kb_oq[kb_oq_put] = val;
    421   1.1  jonathan 		kb_oq_put = (kb_oq_put + 1) & 7;
    422   1.1  jonathan 		splx(i);
    423   1.1  jonathan 		return(1);
    424   1.1  jonathan 	}
    425   1.1  jonathan 	else do {
    426   1.1  jonathan 		if (!kbd_wait_output())
    427   1.1  jonathan 			return 0;
    428  1.13      soda 		outb(kbd_datap, val);
    429   1.1  jonathan 		for (i = 100000; i; i--) {
    430  1.13      soda 			if (inb(kbd_cmdp) & KBS_DIB) {
    431   1.1  jonathan 				register u_char c;
    432   1.1  jonathan 
    433   1.1  jonathan 				KBD_DELAY;
    434  1.13      soda 				c = inb(kbd_datap);
    435   1.1  jonathan 				if (c == KBR_ACK || c == KBR_ECHO) {
    436   1.1  jonathan 					return 1;
    437   1.1  jonathan 				}
    438   1.1  jonathan 				if (c == KBR_RESEND) {
    439   1.1  jonathan 					break;
    440   1.1  jonathan 				}
    441   1.1  jonathan #ifdef DIAGNOSTIC
    442   1.6  christos 				printf("kbd_cmd: input char %x lost\n", c);
    443   1.1  jonathan #endif
    444   1.1  jonathan 			}
    445   1.1  jonathan 		}
    446   1.1  jonathan 	} while (--retries);
    447   1.1  jonathan 	return 0;
    448   1.1  jonathan }
    449   1.1  jonathan 
    450   1.1  jonathan void
    451   1.1  jonathan set_cursor_shape()
    452   1.1  jonathan {
    453   1.1  jonathan 	register int iobase = addr_6845;
    454   1.1  jonathan 
    455   1.1  jonathan 	outb(iobase, 10);
    456   1.1  jonathan 	outb(iobase+1, cursor_shape >> 8);
    457   1.1  jonathan 	outb(iobase, 11);
    458   1.1  jonathan 	outb(iobase+1, cursor_shape);
    459   1.1  jonathan 	old_cursor_shape = cursor_shape;
    460   1.1  jonathan }
    461   1.1  jonathan 
    462   1.1  jonathan void
    463   1.1  jonathan get_cursor_shape()
    464   1.1  jonathan {
    465   1.1  jonathan 	register int iobase = addr_6845;
    466   1.1  jonathan 
    467   1.1  jonathan 	outb(iobase, 10);
    468   1.1  jonathan 	cursor_shape = inb(iobase+1) << 8;
    469   1.1  jonathan 	outb(iobase, 11);
    470   1.1  jonathan 	cursor_shape |= inb(iobase+1);
    471   1.1  jonathan 
    472   1.1  jonathan 	/*
    473   1.1  jonathan 	 * real 6845's, as found on, MDA, Hercules or CGA cards, do
    474   1.1  jonathan 	 * not support reading the cursor shape registers. the 6845
    475   1.1  jonathan 	 * tri-states it's data bus. This is _normally_ read by the
    476   1.1  jonathan 	 * cpu as either 0x00 or 0xff.. in which case we just use
    477   1.1  jonathan 	 * a line cursor.
    478   1.1  jonathan 	 */
    479   1.1  jonathan 	if (cursor_shape == 0x0000 || cursor_shape == 0xffff)
    480   1.1  jonathan 		cursor_shape = 0x0b10;
    481   1.1  jonathan 	else
    482   1.1  jonathan 		cursor_shape &= 0x1f1f;
    483   1.1  jonathan }
    484   1.1  jonathan 
    485   1.1  jonathan void
    486   1.1  jonathan do_async_update(poll)
    487   1.1  jonathan 	u_char poll;
    488   1.1  jonathan {
    489   1.1  jonathan 	int pos;
    490   1.1  jonathan 	static int old_pos = -1;
    491   1.1  jonathan 
    492   1.1  jonathan 	async = 0;
    493   1.1  jonathan 
    494   1.1  jonathan 	if (lock_state != old_lock_state) {
    495   1.1  jonathan 		old_lock_state = lock_state;
    496   1.1  jonathan 		if (!kbd_cmd(KBC_MODEIND, poll) ||
    497   1.1  jonathan 		    !kbd_cmd(lock_state, poll)) {
    498   1.6  christos 			printf("pc: timeout updating leds\n");
    499   1.1  jonathan 			(void) kbd_cmd(KBC_ENABLE, poll);
    500   1.1  jonathan 		}
    501   1.1  jonathan 	}
    502   1.1  jonathan 	if (typematic_rate != old_typematic_rate) {
    503   1.1  jonathan 		old_typematic_rate = typematic_rate;
    504   1.1  jonathan 		if (!kbd_cmd(KBC_TYPEMATIC, poll) ||
    505   1.1  jonathan 		    !kbd_cmd(typematic_rate, poll)) {
    506   1.6  christos 			printf("pc: timeout updating typematic rate\n");
    507   1.1  jonathan 			(void) kbd_cmd(KBC_ENABLE, poll);
    508   1.1  jonathan 		}
    509   1.1  jonathan 	}
    510   1.1  jonathan 
    511   1.1  jonathan 	if (pc_xmode > 0)
    512   1.1  jonathan 		return;
    513   1.1  jonathan 
    514   1.1  jonathan 	pos = crtat - Crtat;
    515   1.1  jonathan 	if (pos != old_pos) {
    516   1.1  jonathan 		register int iobase = addr_6845;
    517   1.1  jonathan 		outb(iobase, 14);
    518   1.1  jonathan 		outb(iobase+1, pos >> 8);
    519   1.1  jonathan 		outb(iobase, 15);
    520   1.1  jonathan 		outb(iobase+1, pos);
    521   1.1  jonathan 		old_pos = pos;
    522   1.1  jonathan 	}
    523   1.1  jonathan 	if (cursor_shape != old_cursor_shape)
    524   1.1  jonathan 		set_cursor_shape();
    525   1.1  jonathan }
    526   1.1  jonathan 
    527   1.1  jonathan void
    528   1.1  jonathan async_update()
    529   1.1  jonathan {
    530   1.1  jonathan 
    531   1.1  jonathan 	if (kernel || polling) {
    532   1.1  jonathan 		if (async)
    533  1.17   thorpej 			callout_stop(&async_update_ch);
    534   1.1  jonathan 		do_async_update(1);
    535   1.1  jonathan 	} else {
    536   1.1  jonathan 		if (async)
    537   1.1  jonathan 			return;
    538   1.1  jonathan 		async = 1;
    539  1.17   thorpej 		callout_reset(&async_update_ch, 1,
    540  1.17   thorpej 		    (void(*)(void *))do_async_update, NULL);
    541   1.1  jonathan 	}
    542   1.1  jonathan }
    543   1.1  jonathan 
    544   1.1  jonathan /*
    545   1.1  jonathan  * these are both bad jokes
    546   1.1  jonathan  */
    547   1.1  jonathan int
    548  1.13      soda pcprobe(parent, match, aux)
    549   1.1  jonathan 	struct device *parent;
    550  1.13      soda 	struct cfdata *match;
    551  1.13      soda 	void *aux;
    552   1.1  jonathan {
    553  1.23        ur 	struct jazzio_attach_args *ja = aux;
    554   1.1  jonathan 	u_int i;
    555   1.1  jonathan 
    556   1.1  jonathan 	/* Make shure we're looking for this type of device */
    557  1.13      soda 	if(!strcmp((parent)->dv_cfdata->cf_driver->cd_name, "pica")) {
    558  1.23        ur 		if (strcmp(ja->ja_name, "pckbd") != 0)
    559  1.13      soda 			return(0);
    560  1.20      soda 
    561  1.20      soda 		switch (cputype) { /* XXX ick */
    562  1.20      soda 		case ACER_PICA_61:
    563  1.20      soda 		case NEC_R96: /* XXX - not really confirmed */
    564  1.20      soda 			break;
    565  1.20      soda 		default:
    566  1.20      soda 			return (0);
    567  1.20      soda 		}
    568  1.20      soda 	} else { /* ISA */
    569  1.20      soda 		switch (cputype) { /* XXX ick */
    570  1.20      soda 		case DESKSTATION_RPC44:
    571  1.20      soda 		case DESKSTATION_TYNE:
    572  1.20      soda 			break;
    573  1.20      soda 		default:
    574  1.20      soda 			return (0);
    575  1.20      soda 		}
    576  1.13      soda 	}
    577   1.1  jonathan 
    578  1.20      soda 	pcinithandle();
    579  1.20      soda 
    580   1.1  jonathan 	/* Enable interrupts and keyboard, etc. */
    581   1.1  jonathan 	if (!kbc_put8042cmd(CMDBYTE)) {
    582  1.13      soda 		printf("pcprobe: command error\n");
    583   1.1  jonathan 		return 0;
    584   1.1  jonathan 	}
    585   1.1  jonathan 
    586   1.1  jonathan #if 1
    587   1.1  jonathan 	/* Flush any garbage. */
    588   1.1  jonathan 	kbd_flush_input();
    589   1.1  jonathan 	/* Reset the keyboard. */
    590   1.1  jonathan 	if (!kbd_cmd(KBC_RESET, 1)) {
    591  1.13      soda 		printf("pcprobe: reset error %d\n", 1);
    592   1.1  jonathan 		goto lose;
    593   1.1  jonathan 	}
    594   1.1  jonathan 	for (i = 600000; i; i--)
    595  1.13      soda 		if ((inb(kbd_cmdp) & KBS_DIB) != 0) {
    596   1.1  jonathan 			KBD_DELAY;
    597   1.1  jonathan 			break;
    598   1.1  jonathan 		}
    599  1.13      soda 	if (i == 0 || inb(kbd_datap) != KBR_RSTDONE) {
    600  1.13      soda 		printf("pcprobe: reset error %d\n", 2);
    601   1.1  jonathan 		goto lose;
    602   1.1  jonathan 	}
    603   1.1  jonathan 	/*
    604   1.1  jonathan 	 * Some keyboards seem to leave a second ack byte after the reset.
    605   1.1  jonathan 	 * This is kind of stupid, but we account for them anyway by just
    606   1.1  jonathan 	 * flushing the buffer.
    607   1.1  jonathan 	 */
    608   1.1  jonathan 	kbd_flush_input();
    609   1.1  jonathan 	/* Just to be sure. */
    610   1.1  jonathan 	if (!kbd_cmd(KBC_ENABLE, 1)) {
    611  1.13      soda 		printf("pcprobe: reset error %d\n", 3);
    612   1.1  jonathan 		goto lose;
    613   1.1  jonathan 	}
    614   1.1  jonathan 
    615   1.1  jonathan 	/*
    616   1.1  jonathan 	 * Some keyboard/8042 combinations do not seem to work if the keyboard
    617   1.1  jonathan 	 * is set to table 1; in fact, it would appear that some keyboards just
    618   1.1  jonathan 	 * ignore the command altogether.  So by default, we use the AT scan
    619   1.1  jonathan 	 * codes and have the 8042 translate them.  Unfortunately, this is
    620   1.1  jonathan 	 * known to not work on some PS/2 machines.  We try desparately to deal
    621   1.1  jonathan 	 * with this by checking the (lack of a) translate bit in the 8042 and
    622   1.1  jonathan 	 * attempting to set the keyboard to XT mode.  If this all fails, well,
    623   1.1  jonathan 	 * tough luck.
    624   1.1  jonathan 	 *
    625   1.1  jonathan 	 * XXX It would perhaps be a better choice to just use AT scan codes
    626   1.1  jonathan 	 * and not bother with this.
    627   1.1  jonathan 	 */
    628   1.1  jonathan 	if (kbc_get8042cmd() & KC8_TRANS) {
    629   1.1  jonathan 		/* The 8042 is translating for us; use AT codes. */
    630   1.1  jonathan 		if (!kbd_cmd(KBC_SETTABLE, 1) || !kbd_cmd(2, 1)) {
    631  1.13      soda 			printf("pcprobe: reset error %d\n", 4);
    632   1.1  jonathan 			goto lose;
    633   1.1  jonathan 		}
    634   1.1  jonathan 	} else {
    635   1.1  jonathan 		/* Stupid 8042; set keyboard to XT codes. */
    636   1.1  jonathan 		if (!kbd_cmd(KBC_SETTABLE, 1) || !kbd_cmd(1, 1)) {
    637  1.13      soda 			printf("pcprobe: reset error %d\n", 5);
    638   1.1  jonathan 			goto lose;
    639   1.1  jonathan 		}
    640   1.1  jonathan 	}
    641   1.1  jonathan 
    642   1.1  jonathan lose:
    643   1.1  jonathan 	/*
    644  1.13      soda 	 * Technically, we should probably fail the probe.  But we'll be nice
    645   1.1  jonathan 	 * and allow keyboard-less machines to boot with the console.
    646   1.1  jonathan 	 */
    647   1.1  jonathan #endif
    648   1.1  jonathan 
    649   1.1  jonathan 	return 1;
    650   1.1  jonathan }
    651   1.1  jonathan 
    652   1.1  jonathan void
    653   1.1  jonathan pcattach(parent, self, aux)
    654   1.1  jonathan 	struct device *parent, *self;
    655   1.1  jonathan 	void *aux;
    656   1.1  jonathan {
    657  1.23        ur 	struct jazzio_attach_args *ja = aux;
    658  1.13      soda 	struct isa_attach_args *ia = aux;
    659   1.1  jonathan 	struct pc_softc *sc = (void *)self;
    660   1.1  jonathan 
    661   1.6  christos 	printf(": %s\n", vs.color ? "color" : "mono");
    662   1.1  jonathan 	do_async_update(1);
    663   1.1  jonathan 
    664  1.20      soda 	switch (cputype) {
    665  1.13      soda 	case ACER_PICA_61:
    666  1.18      soda 	case NEC_R96:
    667  1.23        ur 		jazzio_intr_establish(ja->ja_intr, pcintr, (void *)(long)sc);
    668  1.13      soda 		break;
    669  1.13      soda 	case DESKSTATION_RPC44:                     /* XXX ick */
    670  1.13      soda 	case DESKSTATION_TYNE:
    671  1.13      soda 		isa_intr_establish(ia->ia_ic, ia->ia_irq, 1,
    672  1.13      soda 			2, pcintr, sc);			/*XXX ick */
    673  1.13      soda 		break;
    674  1.13      soda 	}
    675   1.1  jonathan }
    676   1.1  jonathan 
    677   1.1  jonathan int
    678   1.1  jonathan pcopen(dev, flag, mode, p)
    679   1.1  jonathan 	dev_t dev;
    680   1.1  jonathan 	int flag, mode;
    681   1.1  jonathan 	struct proc *p;
    682   1.1  jonathan {
    683   1.1  jonathan 	struct pc_softc *sc;
    684   1.1  jonathan 	int unit = PCUNIT(dev);
    685   1.1  jonathan 	struct tty *tp;
    686   1.1  jonathan 
    687   1.2   thorpej 	if (unit >= pc_cd.cd_ndevs)
    688   1.1  jonathan 		return ENXIO;
    689   1.2   thorpej 	sc = pc_cd.cd_devs[unit];
    690   1.1  jonathan 	if (sc == 0)
    691   1.1  jonathan 		return ENXIO;
    692   1.1  jonathan 
    693   1.1  jonathan 	if (!sc->sc_tty) {
    694   1.1  jonathan 		tp = sc->sc_tty = ttymalloc();
    695   1.1  jonathan 	}
    696   1.1  jonathan 	else {
    697   1.1  jonathan 		tp = sc->sc_tty;
    698   1.1  jonathan 	}
    699   1.1  jonathan 
    700   1.1  jonathan 	tp->t_oproc = pcstart;
    701   1.1  jonathan 	tp->t_param = pcparam;
    702   1.1  jonathan 	tp->t_dev = dev;
    703   1.1  jonathan 	if ((tp->t_state & TS_ISOPEN) == 0) {
    704   1.1  jonathan 		ttychars(tp);
    705   1.1  jonathan 		tp->t_iflag = TTYDEF_IFLAG;
    706   1.1  jonathan 		tp->t_oflag = TTYDEF_OFLAG;
    707   1.1  jonathan 		tp->t_cflag = TTYDEF_CFLAG;
    708   1.1  jonathan 		tp->t_lflag = TTYDEF_LFLAG;
    709   1.1  jonathan 		tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
    710   1.1  jonathan 		pcparam(tp, &tp->t_termios);
    711   1.1  jonathan 		ttsetwater(tp);
    712   1.1  jonathan 	} else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
    713   1.1  jonathan 		return EBUSY;
    714   1.1  jonathan 	tp->t_state |= TS_CARR_ON;
    715   1.1  jonathan 
    716  1.22       eeh 	return ((*tp->t_linesw->l_open)(dev, tp));
    717   1.1  jonathan }
    718   1.1  jonathan 
    719   1.1  jonathan int
    720   1.1  jonathan pcclose(dev, flag, mode, p)
    721   1.1  jonathan 	dev_t dev;
    722   1.1  jonathan 	int flag, mode;
    723   1.1  jonathan 	struct proc *p;
    724   1.1  jonathan {
    725   1.2   thorpej 	struct pc_softc *sc = pc_cd.cd_devs[PCUNIT(dev)];
    726   1.1  jonathan 	struct tty *tp = sc->sc_tty;
    727   1.1  jonathan 
    728  1.22       eeh 	(*tp->t_linesw->l_close)(tp, flag);
    729   1.1  jonathan 	ttyclose(tp);
    730   1.1  jonathan #ifdef notyet /* XXX */
    731   1.1  jonathan 	ttyfree(tp);
    732   1.1  jonathan #endif
    733   1.1  jonathan 	return(0);
    734   1.1  jonathan }
    735   1.1  jonathan 
    736   1.1  jonathan int
    737   1.1  jonathan pcread(dev, uio, flag)
    738   1.1  jonathan 	dev_t dev;
    739   1.1  jonathan 	struct uio *uio;
    740   1.1  jonathan 	int flag;
    741   1.1  jonathan {
    742   1.2   thorpej 	struct pc_softc *sc = pc_cd.cd_devs[PCUNIT(dev)];
    743   1.1  jonathan 	struct tty *tp = sc->sc_tty;
    744   1.1  jonathan 
    745  1.22       eeh 	return ((*tp->t_linesw->l_read)(tp, uio, flag));
    746   1.1  jonathan }
    747   1.1  jonathan 
    748   1.1  jonathan int
    749   1.1  jonathan pcwrite(dev, uio, flag)
    750   1.1  jonathan 	dev_t dev;
    751   1.1  jonathan 	struct uio *uio;
    752   1.1  jonathan 	int flag;
    753   1.1  jonathan {
    754   1.2   thorpej 	struct pc_softc *sc = pc_cd.cd_devs[PCUNIT(dev)];
    755   1.1  jonathan 	struct tty *tp = sc->sc_tty;
    756   1.1  jonathan 
    757  1.22       eeh 	return ((*tp->t_linesw->l_write)(tp, uio, flag));
    758  1.25       scw }
    759  1.25       scw 
    760  1.25       scw int
    761  1.25       scw pcpoll(dev, events, p)
    762  1.25       scw 	dev_t dev;
    763  1.25       scw 	int events;
    764  1.25       scw 	struct proc *p;
    765  1.25       scw {
    766  1.25       scw 	struct pc_softc *sc = pc_cd.cd_devs[PCUNIT(dev)];
    767  1.25       scw 	struct tty *tp = sc->sc_tty;
    768  1.25       scw 
    769  1.25       scw 	return ((*tp->t_linesw->l_poll)(tp, events, p));
    770   1.1  jonathan }
    771   1.1  jonathan 
    772   1.1  jonathan struct tty *
    773   1.1  jonathan pctty(dev)
    774   1.1  jonathan 	dev_t dev;
    775   1.1  jonathan {
    776   1.2   thorpej 	struct pc_softc *sc = pc_cd.cd_devs[PCUNIT(dev)];
    777   1.1  jonathan 	struct tty *tp = sc->sc_tty;
    778   1.1  jonathan 
    779   1.1  jonathan 	return (tp);
    780   1.1  jonathan }
    781   1.1  jonathan 
    782   1.1  jonathan /*
    783   1.1  jonathan  * Got a console receive interrupt -
    784   1.1  jonathan  * the console processor wants to give us a character.
    785   1.1  jonathan  * Catch the character, and see who it goes to.
    786   1.1  jonathan  */
    787   1.1  jonathan int
    788   1.1  jonathan pcintr(arg)
    789   1.1  jonathan 	void *arg;
    790   1.1  jonathan {
    791   1.1  jonathan 	struct pc_softc *sc = arg;
    792   1.1  jonathan 	register struct tty *tp = sc->sc_tty;
    793   1.1  jonathan 	u_char *cp;
    794   1.1  jonathan 
    795  1.13      soda 	if ((inb(kbd_cmdp) & KBS_DIB) == 0)
    796   1.1  jonathan 		return 0;
    797   1.1  jonathan 	if (polling)
    798   1.1  jonathan 		return 1;
    799   1.1  jonathan 	do {
    800   1.1  jonathan 		cp = sget();
    801   1.1  jonathan 		if (!tp || (tp->t_state & TS_ISOPEN) == 0)
    802   1.1  jonathan 			return 1;
    803   1.1  jonathan 		if (cp)
    804   1.1  jonathan 			do
    805  1.22       eeh 				(*tp->t_linesw->l_rint)(*cp++, tp);
    806   1.1  jonathan 			while (*cp);
    807  1.13      soda 	} while (inb(kbd_cmdp) & KBS_DIB);
    808   1.1  jonathan 	return 1;
    809   1.1  jonathan }
    810   1.1  jonathan 
    811   1.1  jonathan int
    812   1.1  jonathan pcioctl(dev, cmd, data, flag, p)
    813   1.1  jonathan 	dev_t dev;
    814   1.1  jonathan 	u_long cmd;
    815   1.1  jonathan 	caddr_t data;
    816   1.1  jonathan 	int flag;
    817   1.1  jonathan 	struct proc *p;
    818   1.1  jonathan {
    819   1.2   thorpej 	struct pc_softc *sc = pc_cd.cd_devs[PCUNIT(dev)];
    820   1.1  jonathan 	struct tty *tp = sc->sc_tty;
    821   1.1  jonathan 	int error;
    822   1.1  jonathan 
    823  1.22       eeh 	error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, p);
    824   1.1  jonathan 	if (error >= 0)
    825   1.1  jonathan 		return error;
    826   1.1  jonathan 	error = ttioctl(tp, cmd, data, flag, p);
    827   1.1  jonathan 	if (error >= 0)
    828   1.1  jonathan 		return error;
    829   1.1  jonathan 
    830   1.1  jonathan 	switch (cmd) {
    831   1.1  jonathan 	case CONSOLE_X_MODE_ON:
    832   1.1  jonathan 		pc_xmode_on();
    833   1.1  jonathan 		return 0;
    834   1.1  jonathan 	case CONSOLE_X_MODE_OFF:
    835   1.1  jonathan 		pc_xmode_off();
    836   1.1  jonathan 		return 0;
    837   1.1  jonathan 	case CONSOLE_X_BELL:
    838   1.1  jonathan 		/*
    839   1.1  jonathan 		 * If set, data is a pointer to a length 2 array of
    840   1.1  jonathan 		 * integers.  data[0] is the pitch in Hz and data[1]
    841   1.1  jonathan 		 * is the duration in msec.
    842   1.1  jonathan 		 */
    843   1.1  jonathan 		if (data)
    844   1.1  jonathan 			sysbeep(((int*)data)[0],
    845   1.1  jonathan 				(((int*)data)[1] * hz) / 1000);
    846   1.1  jonathan 		else
    847   1.1  jonathan 			sysbeep(BEEP_FREQ, BEEP_TIME);
    848   1.1  jonathan 		return 0;
    849   1.1  jonathan 	case CONSOLE_SET_TYPEMATIC_RATE: {
    850   1.1  jonathan  		u_char	rate;
    851   1.1  jonathan 
    852   1.1  jonathan  		if (!data)
    853   1.1  jonathan 			return EINVAL;
    854   1.1  jonathan 		rate = *((u_char *)data);
    855   1.1  jonathan 		/*
    856   1.1  jonathan 		 * Check that it isn't too big (which would cause it to be
    857   1.1  jonathan 		 * confused with a command).
    858   1.1  jonathan 		 */
    859   1.1  jonathan 		if (rate & 0x80)
    860   1.1  jonathan 			return EINVAL;
    861   1.1  jonathan 		typematic_rate = rate;
    862   1.1  jonathan 		async_update();
    863   1.1  jonathan 		return 0;
    864   1.1  jonathan  	}
    865  1.13      soda 	case CONSOLE_SET_KEYMAP: {
    866  1.13      soda 		pccons_keymap_t *map = (pccons_keymap_t *) data;
    867  1.13      soda 		int i;
    868  1.13      soda 
    869  1.13      soda 		if (!data)
    870  1.13      soda 			return EINVAL;
    871  1.13      soda 		for (i = 0; i < KB_NUM_KEYS; i++)
    872  1.13      soda 			if (map[i].unshift[KB_CODE_SIZE-1] ||
    873  1.13      soda 			    map[i].shift[KB_CODE_SIZE-1] ||
    874  1.13      soda 			    map[i].ctl[KB_CODE_SIZE-1] ||
    875  1.13      soda 			    map[i].altgr[KB_CODE_SIZE-1] ||
    876  1.13      soda 			    map[i].shift_altgr[KB_CODE_SIZE-1])
    877  1.13      soda 				return EINVAL;
    878  1.13      soda 
    879  1.13      soda 		bcopy(data, scan_codes, sizeof(pccons_keymap_t[KB_NUM_KEYS]));
    880  1.13      soda 		return 0;
    881  1.13      soda 	}
    882  1.13      soda 	case CONSOLE_GET_KEYMAP:
    883  1.13      soda 		if (!data)
    884  1.13      soda 			return EINVAL;
    885  1.13      soda 		bcopy(scan_codes, data, sizeof(pccons_keymap_t[KB_NUM_KEYS]));
    886  1.13      soda 		return 0;
    887  1.13      soda 
    888   1.1  jonathan 	default:
    889   1.1  jonathan 		return ENOTTY;
    890   1.1  jonathan 	}
    891   1.1  jonathan 
    892   1.1  jonathan #ifdef DIAGNOSTIC
    893   1.1  jonathan 	panic("pcioctl: impossible");
    894   1.1  jonathan #endif
    895   1.1  jonathan }
    896   1.1  jonathan 
    897   1.1  jonathan void
    898   1.1  jonathan pcstart(tp)
    899   1.1  jonathan 	struct tty *tp;
    900   1.1  jonathan {
    901   1.1  jonathan 	struct clist *cl;
    902  1.13      soda 	int s, len;
    903   1.1  jonathan 	u_char buf[PCBURST];
    904   1.1  jonathan 
    905   1.1  jonathan 	s = spltty();
    906   1.1  jonathan 	if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
    907   1.1  jonathan 		goto out;
    908   1.1  jonathan 	tp->t_state |= TS_BUSY;
    909   1.1  jonathan 	splx(s);
    910   1.1  jonathan 	/*
    911   1.1  jonathan 	 * We need to do this outside spl since it could be fairly
    912   1.1  jonathan 	 * expensive and we don't want our serial ports to overflow.
    913   1.1  jonathan 	 */
    914   1.1  jonathan 	cl = &tp->t_outq;
    915   1.1  jonathan 	len = q_to_b(cl, buf, PCBURST);
    916   1.1  jonathan 	sput(buf, len);
    917   1.1  jonathan 	s = spltty();
    918   1.1  jonathan 	tp->t_state &= ~TS_BUSY;
    919   1.1  jonathan 	if (cl->c_cc) {
    920   1.1  jonathan 		tp->t_state |= TS_TIMEOUT;
    921  1.17   thorpej 		callout_reset(&tp->t_rstrt_ch, 1, ttrstrt, tp);
    922   1.1  jonathan 	}
    923   1.1  jonathan 	if (cl->c_cc <= tp->t_lowat) {
    924   1.1  jonathan 		if (tp->t_state & TS_ASLEEP) {
    925   1.1  jonathan 			tp->t_state &= ~TS_ASLEEP;
    926   1.1  jonathan 			wakeup(cl);
    927   1.1  jonathan 		}
    928   1.1  jonathan 		selwakeup(&tp->t_wsel);
    929   1.1  jonathan 	}
    930   1.1  jonathan out:
    931   1.1  jonathan 	splx(s);
    932   1.1  jonathan }
    933   1.1  jonathan 
    934   1.1  jonathan void
    935   1.1  jonathan pcstop(tp, flag)
    936   1.1  jonathan 	struct tty *tp;
    937   1.1  jonathan 	int flag;
    938   1.1  jonathan {
    939   1.1  jonathan }
    940   1.1  jonathan 
    941  1.13      soda /* ARGSUSED */
    942   1.1  jonathan void
    943  1.13      soda pccnattach()
    944   1.1  jonathan {
    945   1.1  jonathan 	int maj;
    946  1.13      soda 	static struct consdev pccons = {
    947  1.16   thorpej 		NULL, NULL, pccngetc, pccnputc, pccnpollc, NULL,
    948  1.16   thorpej 		    NODEV, CN_NORMAL
    949  1.13      soda 	};
    950  1.13      soda 
    951  1.13      soda 	/*
    952  1.13      soda 	 * For now, don't screw with it.
    953  1.13      soda 	 */
    954  1.13      soda 	/* crtat = 0; */
    955  1.20      soda 	pcinithandle();
    956  1.20      soda 
    957  1.20      soda 	switch (cputype) {
    958  1.13      soda 
    959  1.13      soda 	case ACER_PICA_61:
    960  1.18      soda 	case NEC_R96: /* XXX - not really confirmed */
    961  1.13      soda 		break;
    962  1.13      soda 
    963  1.13      soda 	case DESKSTATION_TYNE:
    964  1.18      soda 		outb(arc_bus_io.bs_vbase + 0x3ce, 6);	/* Correct video mode */
    965  1.18      soda 		outb(arc_bus_io.bs_vbase + 0x3cf,
    966  1.18      soda 			inb(arc_bus_io.bs_vbase + 0x3cf) | 0xc);
    967  1.13      soda 		kbc_put8042cmd(CMDBYTE);		/* Want XT codes.. */
    968  1.13      soda 		break;
    969  1.13      soda 
    970  1.13      soda 	case DESKSTATION_RPC44:
    971  1.13      soda 		kbc_put8042cmd(CMDBYTE);		/* Want XT codes.. */
    972  1.13      soda 		break;
    973  1.14      soda 
    974  1.14      soda 	case SNI_RM200:
    975  1.14      soda 		break;
    976  1.13      soda 	}
    977   1.1  jonathan 
    978   1.1  jonathan 	/* locate the major number */
    979   1.1  jonathan 	for (maj = 0; maj < nchrdev; maj++)
    980   1.1  jonathan 		if (cdevsw[maj].d_open == pcopen)
    981   1.1  jonathan 			break;
    982  1.13      soda 	pccons.cn_dev = makedev(maj, 0);
    983   1.1  jonathan 
    984  1.13      soda 	cn_tab = &pccons;
    985   1.1  jonathan }
    986   1.1  jonathan 
    987   1.1  jonathan /* ARGSUSED */
    988   1.1  jonathan void
    989   1.1  jonathan pccnputc(dev, c)
    990   1.1  jonathan 	dev_t dev;
    991  1.13      soda 	int c;
    992   1.1  jonathan {
    993  1.15      soda 	u_char cc, oldkernel = kernel;
    994   1.1  jonathan 
    995   1.1  jonathan 	kernel = 1;
    996  1.15      soda 	if (c == '\n') {
    997   1.1  jonathan 		sput("\r\n", 2);
    998  1.15      soda 	} else {
    999  1.15      soda 		cc = c;
   1000  1.15      soda 		sput(&cc, 1);
   1001  1.15      soda 	}
   1002   1.1  jonathan 	kernel = oldkernel;
   1003   1.1  jonathan }
   1004   1.1  jonathan 
   1005   1.1  jonathan /* ARGSUSED */
   1006  1.13      soda int
   1007   1.1  jonathan pccngetc(dev)
   1008   1.1  jonathan 	dev_t dev;
   1009   1.1  jonathan {
   1010   1.1  jonathan 	register char *cp;
   1011   1.1  jonathan 
   1012   1.1  jonathan 	if (pc_xmode > 0)
   1013   1.1  jonathan 		return 0;
   1014   1.1  jonathan 
   1015   1.1  jonathan 	do {
   1016   1.1  jonathan 		/* wait for byte */
   1017  1.13      soda 		while ((inb(kbd_cmdp) & KBS_DIB) == 0);
   1018   1.1  jonathan 		/* see if it's worthwhile */
   1019   1.1  jonathan 		cp = sget();
   1020   1.1  jonathan 	} while (!cp);
   1021   1.1  jonathan 	if (*cp == '\r')
   1022   1.1  jonathan 		return '\n';
   1023   1.1  jonathan 	return *cp;
   1024   1.1  jonathan }
   1025   1.1  jonathan 
   1026   1.1  jonathan void
   1027   1.1  jonathan pccnpollc(dev, on)
   1028   1.1  jonathan 	dev_t dev;
   1029   1.1  jonathan 	int on;
   1030   1.1  jonathan {
   1031   1.1  jonathan 
   1032   1.1  jonathan 	polling = on;
   1033   1.1  jonathan 	if (!on) {
   1034   1.1  jonathan 		int unit;
   1035   1.1  jonathan 		struct pc_softc *sc;
   1036   1.1  jonathan 		int s;
   1037   1.1  jonathan 
   1038   1.1  jonathan 		/*
   1039   1.1  jonathan 		 * If disabling polling on a device that's been configured,
   1040   1.1  jonathan 		 * make sure there are no bytes left in the FIFO, holding up
   1041   1.1  jonathan 		 * the interrupt line.  Otherwise we won't get any further
   1042   1.1  jonathan 		 * interrupts.
   1043   1.1  jonathan 		 */
   1044   1.1  jonathan 		unit = PCUNIT(dev);
   1045   1.2   thorpej 		if (pc_cd.cd_ndevs > unit) {
   1046   1.2   thorpej 			sc = pc_cd.cd_devs[unit];
   1047   1.1  jonathan 			if (sc != 0) {
   1048   1.1  jonathan 				s = spltty();
   1049   1.1  jonathan 				pcintr(sc);
   1050   1.1  jonathan 				splx(s);
   1051   1.1  jonathan 			}
   1052   1.1  jonathan 		}
   1053   1.1  jonathan 	}
   1054   1.1  jonathan }
   1055   1.1  jonathan 
   1056   1.1  jonathan /*
   1057   1.1  jonathan  * Set line parameters.
   1058   1.1  jonathan  */
   1059   1.1  jonathan int
   1060   1.1  jonathan pcparam(tp, t)
   1061   1.1  jonathan 	struct tty *tp;
   1062   1.1  jonathan 	struct termios *t;
   1063   1.1  jonathan {
   1064   1.1  jonathan 
   1065   1.1  jonathan 	tp->t_ispeed = t->c_ispeed;
   1066   1.1  jonathan 	tp->t_ospeed = t->c_ospeed;
   1067   1.1  jonathan 	tp->t_cflag = t->c_cflag;
   1068   1.1  jonathan 	return 0;
   1069   1.1  jonathan }
   1070   1.1  jonathan 
   1071   1.1  jonathan #define	wrtchar(c, at) do {\
   1072   1.1  jonathan 	char *cp = (char *)crtat; *cp++ = (c); *cp = (at); crtat++; vs.col++; \
   1073   1.1  jonathan } while (0)
   1074   1.1  jonathan 
   1075   1.1  jonathan /* translate ANSI color codes to standard pc ones */
   1076   1.1  jonathan static char fgansitopc[] = {
   1077   1.1  jonathan 	FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
   1078   1.1  jonathan 	FG_MAGENTA, FG_CYAN, FG_LIGHTGREY
   1079   1.1  jonathan };
   1080   1.1  jonathan 
   1081   1.1  jonathan static char bgansitopc[] = {
   1082   1.1  jonathan 	BG_BLACK, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
   1083   1.1  jonathan 	BG_MAGENTA, BG_CYAN, BG_LIGHTGREY
   1084   1.1  jonathan };
   1085   1.1  jonathan 
   1086   1.1  jonathan static u_char iso2ibm437[] =
   1087   1.1  jonathan {
   1088   1.1  jonathan             0,     0,     0,     0,     0,     0,     0,     0,
   1089   1.1  jonathan             0,     0,     0,     0,     0,     0,     0,     0,
   1090   1.1  jonathan             0,     0,     0,     0,     0,     0,     0,     0,
   1091   1.1  jonathan             0,     0,     0,     0,     0,     0,     0,     0,
   1092   1.1  jonathan          0xff,  0xad,  0x9b,  0x9c,     0,  0x9d,     0,  0x40,
   1093   1.1  jonathan          0x6f,  0x63,  0x61,  0xae,     0,     0,     0,     0,
   1094   1.1  jonathan          0xf8,  0xf1,  0xfd,  0x33,     0,  0xe6,     0,  0xfa,
   1095   1.1  jonathan             0,  0x31,  0x6f,  0xaf,  0xac,  0xab,     0,  0xa8,
   1096   1.1  jonathan          0x41,  0x41,  0x41,  0x41,  0x8e,  0x8f,  0x92,  0x80,
   1097   1.1  jonathan          0x45,  0x90,  0x45,  0x45,  0x49,  0x49,  0x49,  0x49,
   1098   1.1  jonathan          0x81,  0xa5,  0x4f,  0x4f,  0x4f,  0x4f,  0x99,  0x4f,
   1099   1.1  jonathan          0x4f,  0x55,  0x55,  0x55,  0x9a,  0x59,     0,  0xe1,
   1100   1.1  jonathan          0x85,  0xa0,  0x83,  0x61,  0x84,  0x86,  0x91,  0x87,
   1101   1.1  jonathan          0x8a,  0x82,  0x88,  0x89,  0x8d,  0xa1,  0x8c,  0x8b,
   1102   1.1  jonathan             0,  0xa4,  0x95,  0xa2,  0x93,  0x6f,  0x94,  0x6f,
   1103   1.1  jonathan          0x6f,  0x97,  0xa3,  0x96,  0x81,  0x98,     0,     0
   1104   1.1  jonathan };
   1105   1.1  jonathan 
   1106   1.1  jonathan /*
   1107   1.1  jonathan  * `pc3' termcap emulation.
   1108   1.1  jonathan  */
   1109   1.1  jonathan void
   1110   1.1  jonathan sput(cp, n)
   1111   1.1  jonathan 	u_char *cp;
   1112   1.1  jonathan 	int n;
   1113   1.1  jonathan {
   1114   1.1  jonathan 	u_char c, scroll = 0;
   1115   1.1  jonathan 
   1116   1.1  jonathan 	if (pc_xmode > 0)
   1117   1.1  jonathan 		return;
   1118   1.1  jonathan 
   1119   1.1  jonathan 	if (crtat == 0) {
   1120  1.13      soda 		volatile u_short *cp;
   1121   1.1  jonathan 		u_short was;
   1122   1.1  jonathan 		unsigned cursorat;
   1123   1.1  jonathan 
   1124  1.13      soda 		cp = (volatile u_short *)cga_buf;
   1125   1.1  jonathan 		was = *cp;
   1126  1.13      soda 		*cp = (volatile u_short) 0xA55A;
   1127   1.1  jonathan 		if (*cp != 0xA55A) {
   1128  1.13      soda 			cp = (volatile u_short *)mono_buf;
   1129  1.13      soda 			addr_6845 = mono_base;
   1130   1.1  jonathan 			vs.color = 0;
   1131   1.1  jonathan 		} else {
   1132   1.1  jonathan 			*cp = was;
   1133  1.13      soda 			addr_6845 = cga_base;
   1134   1.1  jonathan 			vs.color = 1;
   1135   1.1  jonathan 		}
   1136   1.1  jonathan 
   1137   1.1  jonathan #ifdef FAT_CURSOR
   1138   1.1  jonathan 		cursor_shape = 0x0012;
   1139   1.1  jonathan #else
   1140   1.1  jonathan 		get_cursor_shape();
   1141   1.1  jonathan #endif
   1142   1.1  jonathan 
   1143  1.13      soda 		bios_display_info(&vs.col, &vs.row, &vs.ncol, &vs.nrow);
   1144  1.13      soda 		vs.nchr = vs.ncol * vs.nrow;
   1145  1.13      soda 		vs.col--;
   1146  1.13      soda 		vs.row--;
   1147  1.13      soda 		cursorat = vs.ncol * vs.row + vs.col;
   1148  1.13      soda 		vs.at = FG_LIGHTGREY | BG_BLACK;
   1149  1.13      soda 
   1150   1.1  jonathan 		Crtat = (u_short *)cp;
   1151  1.13      soda 		crtat = Crtat + cursorat;
   1152   1.1  jonathan 
   1153   1.1  jonathan 		if (vs.color == 0)
   1154   1.1  jonathan 			vs.so_at = FG_BLACK | BG_LIGHTGREY;
   1155   1.1  jonathan 		else
   1156   1.1  jonathan 			vs.so_at = FG_YELLOW | BG_BLACK;
   1157   1.1  jonathan 
   1158   1.1  jonathan 		fillw((vs.at << 8) | ' ', crtat, vs.nchr - cursorat);
   1159   1.1  jonathan 	}
   1160   1.1  jonathan 
   1161   1.1  jonathan 	while (n--) {
   1162   1.1  jonathan 		if (!(c = *cp++))
   1163   1.1  jonathan 			continue;
   1164   1.1  jonathan 
   1165   1.1  jonathan 		switch (c) {
   1166   1.1  jonathan 		case 0x1B:
   1167   1.1  jonathan 			if (vs.state >= VSS_ESCAPE) {
   1168   1.1  jonathan 				wrtchar(c, vs.so_at);
   1169   1.1  jonathan 				vs.state = 0;
   1170   1.1  jonathan 				goto maybe_scroll;
   1171   1.1  jonathan 			} else
   1172   1.1  jonathan 				vs.state = VSS_ESCAPE;
   1173   1.1  jonathan 			break;
   1174   1.1  jonathan 
   1175  1.13      soda 		case 0x9B:	/* CSI */
   1176  1.13      soda 			vs.cx = vs.cy = 0;
   1177  1.13      soda 			vs.state = VSS_EBRACE;
   1178  1.13      soda 			break;
   1179  1.13      soda 
   1180   1.1  jonathan 		case '\t': {
   1181   1.1  jonathan 			int inccol = 8 - (vs.col & 7);
   1182   1.1  jonathan 			crtat += inccol;
   1183   1.1  jonathan 			vs.col += inccol;
   1184   1.1  jonathan 		}
   1185   1.1  jonathan 		maybe_scroll:
   1186  1.13      soda 			if (vs.col >= vs.ncol) {
   1187  1.13      soda 				vs.col -= vs.ncol;
   1188   1.1  jonathan 				scroll = 1;
   1189   1.1  jonathan 			}
   1190   1.1  jonathan 			break;
   1191   1.1  jonathan 
   1192  1.13      soda 		case '\b':
   1193   1.1  jonathan 			if (crtat <= Crtat)
   1194   1.1  jonathan 				break;
   1195   1.1  jonathan 			--crtat;
   1196   1.1  jonathan 			if (--vs.col < 0)
   1197  1.13      soda 				vs.col += vs.ncol;	/* non-destructive backspace */
   1198   1.1  jonathan 			break;
   1199   1.1  jonathan 
   1200   1.1  jonathan 		case '\r':
   1201   1.1  jonathan 			crtat -= vs.col;
   1202   1.1  jonathan 			vs.col = 0;
   1203   1.1  jonathan 			break;
   1204   1.1  jonathan 
   1205   1.1  jonathan 		case '\n':
   1206   1.1  jonathan 			crtat += vs.ncol;
   1207   1.1  jonathan 			scroll = 1;
   1208   1.1  jonathan 			break;
   1209   1.1  jonathan 
   1210   1.1  jonathan 		default:
   1211   1.1  jonathan 			switch (vs.state) {
   1212   1.1  jonathan 			case 0:
   1213   1.1  jonathan 				if (c == '\a')
   1214   1.1  jonathan 					sysbeep(BEEP_FREQ, BEEP_TIME);
   1215   1.1  jonathan 				else {
   1216   1.1  jonathan 					/*
   1217   1.1  jonathan 					 * If we're outputting multiple printed
   1218   1.1  jonathan 					 * characters, just blast them to the
   1219   1.1  jonathan 					 * screen until we reach the end of the
   1220   1.1  jonathan 					 * buffer or a control character.  This
   1221   1.1  jonathan 					 * saves time by short-circuiting the
   1222   1.1  jonathan 					 * switch.
   1223   1.1  jonathan 					 * If we reach the end of the line, we
   1224   1.1  jonathan 					 * break to do a scroll check.
   1225   1.1  jonathan 					 */
   1226   1.1  jonathan 					for (;;) {
   1227   1.1  jonathan 						if (c & 0x80)
   1228   1.1  jonathan 							c = iso2ibm437[c&0x7f];
   1229   1.1  jonathan 
   1230   1.1  jonathan 						if (vs.so)
   1231   1.1  jonathan 							wrtchar(c, vs.so_at);
   1232   1.1  jonathan 						else
   1233   1.1  jonathan 							wrtchar(c, vs.at);
   1234   1.1  jonathan 						if (vs.col >= vs.ncol) {
   1235   1.1  jonathan 							vs.col = 0;
   1236   1.1  jonathan 							scroll = 1;
   1237   1.1  jonathan 							break;
   1238   1.1  jonathan 						}
   1239   1.1  jonathan 						if (!n || (c = *cp) < ' ')
   1240   1.1  jonathan 							break;
   1241   1.1  jonathan 						n--, cp++;
   1242   1.1  jonathan 					}
   1243   1.1  jonathan 				}
   1244   1.1  jonathan 				break;
   1245   1.1  jonathan 			case VSS_ESCAPE:
   1246  1.13      soda 				switch (c) {
   1247  1.13      soda 					case '[': /* Start ESC [ sequence */
   1248  1.13      soda 						vs.cx = vs.cy = 0;
   1249  1.13      soda 						vs.state = VSS_EBRACE;
   1250  1.13      soda 						break;
   1251  1.13      soda 					case 'c': /* Create screen & home */
   1252  1.13      soda 						fillw((vs.at << 8) | ' ',
   1253  1.13      soda 						    Crtat, vs.nchr);
   1254  1.13      soda 						crtat = Crtat;
   1255  1.13      soda 						vs.col = 0;
   1256  1.13      soda 						vs.state = 0;
   1257  1.13      soda 						break;
   1258  1.13      soda 					case '7': /* save cursor pos */
   1259  1.13      soda 						vs.offset = crtat - Crtat;
   1260  1.13      soda 						vs.state = 0;
   1261  1.13      soda 						break;
   1262  1.13      soda 					case '8': /* restore cursor pos */
   1263  1.13      soda 						crtat = Crtat + vs.offset;
   1264  1.13      soda 						vs.row = vs.offset / vs.ncol;
   1265  1.13      soda 						vs.col = vs.offset % vs.ncol;
   1266  1.13      soda 						vs.state = 0;
   1267  1.13      soda 						break;
   1268  1.13      soda 					default: /* Invalid, clear state */
   1269  1.13      soda 						wrtchar(c, vs.so_at);
   1270  1.13      soda 						vs.state = 0;
   1271  1.13      soda 						goto maybe_scroll;
   1272   1.1  jonathan 				}
   1273   1.1  jonathan 				break;
   1274  1.13      soda 
   1275   1.1  jonathan 			default: /* VSS_EBRACE or VSS_EPARAM */
   1276   1.1  jonathan 				switch (c) {
   1277   1.1  jonathan 					int pos;
   1278   1.1  jonathan 				case 'm':
   1279   1.1  jonathan 					if (!vs.cx)
   1280   1.1  jonathan 						vs.so = 0;
   1281   1.1  jonathan 					else
   1282   1.1  jonathan 						vs.so = 1;
   1283   1.1  jonathan 					vs.state = 0;
   1284   1.1  jonathan 					break;
   1285   1.1  jonathan 				case 'A': { /* back cx rows */
   1286   1.1  jonathan 					int cx = vs.cx;
   1287   1.1  jonathan 					if (cx <= 0)
   1288   1.1  jonathan 						cx = 1;
   1289   1.1  jonathan 					else
   1290   1.1  jonathan 						cx %= vs.nrow;
   1291   1.1  jonathan 					pos = crtat - Crtat;
   1292   1.1  jonathan 					pos -= vs.ncol * cx;
   1293   1.1  jonathan 					if (pos < 0)
   1294   1.1  jonathan 						pos += vs.nchr;
   1295   1.1  jonathan 					crtat = Crtat + pos;
   1296   1.1  jonathan 					vs.state = 0;
   1297   1.1  jonathan 					break;
   1298   1.1  jonathan 				}
   1299   1.1  jonathan 				case 'B': { /* down cx rows */
   1300   1.1  jonathan 					int cx = vs.cx;
   1301   1.1  jonathan 					if (cx <= 0)
   1302   1.1  jonathan 						cx = 1;
   1303   1.1  jonathan 					else
   1304   1.1  jonathan 						cx %= vs.nrow;
   1305   1.1  jonathan 					pos = crtat - Crtat;
   1306   1.1  jonathan 					pos += vs.ncol * cx;
   1307   1.1  jonathan 					if (pos >= vs.nchr)
   1308   1.1  jonathan 						pos -= vs.nchr;
   1309   1.1  jonathan 					crtat = Crtat + pos;
   1310   1.1  jonathan 					vs.state = 0;
   1311   1.1  jonathan 					break;
   1312   1.1  jonathan 				}
   1313   1.1  jonathan 				case 'C': { /* right cursor */
   1314   1.1  jonathan 					int cx = vs.cx,
   1315   1.1  jonathan 					    col = vs.col;
   1316   1.1  jonathan 					if (cx <= 0)
   1317   1.1  jonathan 						cx = 1;
   1318   1.1  jonathan 					else
   1319   1.1  jonathan 						cx %= vs.ncol;
   1320   1.1  jonathan 					pos = crtat - Crtat;
   1321   1.1  jonathan 					pos += cx;
   1322   1.1  jonathan 					col += cx;
   1323   1.1  jonathan 					if (col >= vs.ncol) {
   1324   1.1  jonathan 						pos -= vs.ncol;
   1325   1.1  jonathan 						col -= vs.ncol;
   1326   1.1  jonathan 					}
   1327   1.1  jonathan 					vs.col = col;
   1328   1.1  jonathan 					crtat = Crtat + pos;
   1329   1.1  jonathan 					vs.state = 0;
   1330   1.1  jonathan 					break;
   1331   1.1  jonathan 				}
   1332   1.1  jonathan 				case 'D': { /* left cursor */
   1333   1.1  jonathan 					int cx = vs.cx,
   1334   1.1  jonathan 					    col = vs.col;
   1335   1.1  jonathan 					if (cx <= 0)
   1336   1.1  jonathan 						cx = 1;
   1337   1.1  jonathan 					else
   1338   1.1  jonathan 						cx %= vs.ncol;
   1339   1.1  jonathan 					pos = crtat - Crtat;
   1340   1.1  jonathan 					pos -= cx;
   1341   1.1  jonathan 					col -= cx;
   1342   1.1  jonathan 					if (col < 0) {
   1343   1.1  jonathan 						pos += vs.ncol;
   1344   1.1  jonathan 						col += vs.ncol;
   1345   1.1  jonathan 					}
   1346   1.1  jonathan 					vs.col = col;
   1347   1.1  jonathan 					crtat = Crtat + pos;
   1348   1.1  jonathan 					vs.state = 0;
   1349   1.1  jonathan 					break;
   1350   1.1  jonathan 				}
   1351   1.1  jonathan 				case 'J': /* Clear ... */
   1352   1.1  jonathan 					switch (vs.cx) {
   1353   1.1  jonathan 					case 0:
   1354   1.1  jonathan 						/* ... to end of display */
   1355  1.13      soda 						fillw((vs.at << 8) | ' ',
   1356  1.13      soda 						    crtat,
   1357   1.1  jonathan 						    Crtat + vs.nchr - crtat);
   1358   1.1  jonathan 						break;
   1359   1.1  jonathan 					case 1:
   1360   1.1  jonathan 						/* ... to next location */
   1361  1.13      soda 						fillw((vs.at << 8) | ' ',
   1362  1.13      soda 						    Crtat,
   1363   1.1  jonathan 						    crtat - Crtat + 1);
   1364   1.1  jonathan 						break;
   1365   1.1  jonathan 					case 2:
   1366   1.1  jonathan 						/* ... whole display */
   1367  1.13      soda 						fillw((vs.at << 8) | ' ',
   1368  1.13      soda 						    Crtat,
   1369   1.1  jonathan 						    vs.nchr);
   1370   1.1  jonathan 						break;
   1371   1.1  jonathan 					}
   1372   1.1  jonathan 					vs.state = 0;
   1373   1.1  jonathan 					break;
   1374   1.1  jonathan 				case 'K': /* Clear line ... */
   1375   1.1  jonathan 					switch (vs.cx) {
   1376   1.1  jonathan 					case 0:
   1377   1.1  jonathan 						/* ... current to EOL */
   1378  1.13      soda 						fillw((vs.at << 8) | ' ',
   1379  1.13      soda 						    crtat,
   1380   1.1  jonathan 						    vs.ncol - vs.col);
   1381   1.1  jonathan 						break;
   1382   1.1  jonathan 					case 1:
   1383   1.1  jonathan 						/* ... beginning to next */
   1384   1.1  jonathan 						fillw((vs.at << 8) | ' ',
   1385   1.1  jonathan 						    crtat - vs.col,
   1386   1.1  jonathan 						    vs.col + 1);
   1387   1.1  jonathan 						break;
   1388   1.1  jonathan 					case 2:
   1389   1.1  jonathan 						/* ... entire line */
   1390   1.1  jonathan 						fillw((vs.at << 8) | ' ',
   1391   1.1  jonathan 						    crtat - vs.col, vs.ncol);
   1392   1.1  jonathan 						break;
   1393   1.1  jonathan 					}
   1394   1.1  jonathan 					vs.state = 0;
   1395   1.1  jonathan 					break;
   1396   1.1  jonathan 				case 'f': /* in system V consoles */
   1397   1.1  jonathan 				case 'H': { /* Cursor move */
   1398   1.1  jonathan 					int cx = vs.cx,
   1399   1.1  jonathan 					    cy = vs.cy;
   1400   1.1  jonathan 					if (!cx || !cy) {
   1401   1.1  jonathan 						crtat = Crtat;
   1402   1.1  jonathan 						vs.col = 0;
   1403   1.1  jonathan 					} else {
   1404   1.1  jonathan 						if (cx > vs.nrow)
   1405   1.1  jonathan 							cx = vs.nrow;
   1406   1.1  jonathan 						if (cy > vs.ncol)
   1407   1.1  jonathan 							cy = vs.ncol;
   1408   1.1  jonathan 						crtat = Crtat +
   1409   1.1  jonathan 						    (cx - 1) * vs.ncol + cy - 1;
   1410   1.1  jonathan 						vs.col = cy - 1;
   1411   1.1  jonathan 					}
   1412   1.1  jonathan 					vs.state = 0;
   1413   1.1  jonathan 					break;
   1414   1.1  jonathan 				}
   1415   1.1  jonathan 				case 'M': { /* delete cx rows */
   1416   1.1  jonathan 					u_short *crtAt = crtat - vs.col;
   1417   1.1  jonathan 					int cx = vs.cx,
   1418   1.1  jonathan 					    row = (crtAt - Crtat) / vs.ncol,
   1419   1.1  jonathan 					    nrow = vs.nrow - row;
   1420   1.1  jonathan 					if (cx <= 0)
   1421   1.1  jonathan 						cx = 1;
   1422   1.1  jonathan 					else if (cx > nrow)
   1423   1.1  jonathan 						cx = nrow;
   1424   1.1  jonathan 					if (cx < nrow)
   1425  1.13      soda #ifdef PCCONS_FORCE_WORD
   1426  1.13      soda 						wcopy(crtAt + vs.ncol * cx,
   1427  1.13      soda 						    crtAt, vs.ncol * (nrow -
   1428  1.13      soda 						    cx) * CHR);
   1429  1.13      soda #else
   1430   1.1  jonathan 						bcopy(crtAt + vs.ncol * cx,
   1431   1.1  jonathan 						    crtAt, vs.ncol * (nrow -
   1432   1.1  jonathan 						    cx) * CHR);
   1433  1.13      soda #endif
   1434   1.1  jonathan 					fillw((vs.at << 8) | ' ',
   1435   1.1  jonathan 					    crtAt + vs.ncol * (nrow - cx),
   1436   1.1  jonathan 					    vs.ncol * cx);
   1437   1.1  jonathan 					vs.state = 0;
   1438   1.1  jonathan 					break;
   1439   1.1  jonathan 				}
   1440   1.1  jonathan 				case 'S': { /* scroll up cx lines */
   1441   1.1  jonathan 					int cx = vs.cx;
   1442   1.1  jonathan 					if (cx <= 0)
   1443   1.1  jonathan 						cx = 1;
   1444   1.1  jonathan 					else if (cx > vs.nrow)
   1445   1.1  jonathan 						cx = vs.nrow;
   1446   1.1  jonathan 					if (cx < vs.nrow)
   1447  1.13      soda #ifdef PCCONS_FORCE_WORD
   1448  1.13      soda 						wcopy(Crtat + vs.ncol * cx,
   1449  1.13      soda 						    Crtat, vs.ncol * (vs.nrow -
   1450  1.13      soda 						    cx) * CHR);
   1451  1.13      soda #else
   1452   1.1  jonathan 						bcopy(Crtat + vs.ncol * cx,
   1453   1.1  jonathan 						    Crtat, vs.ncol * (vs.nrow -
   1454   1.1  jonathan 						    cx) * CHR);
   1455  1.13      soda #endif
   1456   1.1  jonathan 					fillw((vs.at << 8) | ' ',
   1457   1.1  jonathan 					    Crtat + vs.ncol * (vs.nrow - cx),
   1458   1.1  jonathan 					    vs.ncol * cx);
   1459  1.13      soda 					/* crtat -= vs.ncol * cx; XXX */
   1460   1.1  jonathan 					vs.state = 0;
   1461   1.1  jonathan 					break;
   1462   1.1  jonathan 				}
   1463   1.1  jonathan 				case 'L': { /* insert cx rows */
   1464   1.1  jonathan 					u_short *crtAt = crtat - vs.col;
   1465   1.1  jonathan 					int cx = vs.cx,
   1466   1.1  jonathan 					    row = (crtAt - Crtat) / vs.ncol,
   1467   1.1  jonathan 					    nrow = vs.nrow - row;
   1468   1.1  jonathan 					if (cx <= 0)
   1469   1.1  jonathan 						cx = 1;
   1470   1.1  jonathan 					else if (cx > nrow)
   1471   1.1  jonathan 						cx = nrow;
   1472   1.1  jonathan 					if (cx < nrow)
   1473  1.13      soda #ifdef PCCONS_FORCE_WORD
   1474  1.13      soda 						wcopy(crtAt,
   1475  1.13      soda 						    crtAt + vs.ncol * cx,
   1476  1.13      soda 						    vs.ncol * (nrow - cx) *
   1477  1.13      soda 						    CHR);
   1478  1.13      soda #else
   1479   1.1  jonathan 						bcopy(crtAt,
   1480   1.1  jonathan 						    crtAt + vs.ncol * cx,
   1481   1.1  jonathan 						    vs.ncol * (nrow - cx) *
   1482   1.1  jonathan 						    CHR);
   1483  1.13      soda #endif
   1484   1.1  jonathan 					fillw((vs.at << 8) | ' ', crtAt,
   1485   1.1  jonathan 					    vs.ncol * cx);
   1486   1.1  jonathan 					vs.state = 0;
   1487   1.1  jonathan 					break;
   1488   1.1  jonathan 				}
   1489   1.1  jonathan 				case 'T': { /* scroll down cx lines */
   1490   1.1  jonathan 					int cx = vs.cx;
   1491   1.1  jonathan 					if (cx <= 0)
   1492   1.1  jonathan 						cx = 1;
   1493   1.1  jonathan 					else if (cx > vs.nrow)
   1494   1.1  jonathan 						cx = vs.nrow;
   1495   1.1  jonathan 					if (cx < vs.nrow)
   1496  1.13      soda #ifdef PCCONS_FORCE_WORD
   1497  1.13      soda 						wcopy(Crtat,
   1498  1.13      soda 						    Crtat + vs.ncol * cx,
   1499  1.13      soda 						    vs.ncol * (vs.nrow - cx) *
   1500  1.13      soda 						    CHR);
   1501  1.13      soda #else
   1502   1.1  jonathan 						bcopy(Crtat,
   1503   1.1  jonathan 						    Crtat + vs.ncol * cx,
   1504   1.1  jonathan 						    vs.ncol * (vs.nrow - cx) *
   1505   1.1  jonathan 						    CHR);
   1506  1.13      soda #endif
   1507   1.1  jonathan 					fillw((vs.at << 8) | ' ', Crtat,
   1508   1.1  jonathan 					    vs.ncol * cx);
   1509  1.13      soda 					/* crtat += vs.ncol * cx; XXX */
   1510   1.1  jonathan 					vs.state = 0;
   1511   1.1  jonathan 					break;
   1512   1.1  jonathan 				}
   1513   1.1  jonathan 				case ';': /* Switch params in cursor def */
   1514   1.1  jonathan 					vs.state = VSS_EPARAM;
   1515   1.1  jonathan 					break;
   1516   1.1  jonathan 				case 'r':
   1517   1.1  jonathan 					vs.so_at = (vs.cx & FG_MASK) |
   1518   1.1  jonathan 					    ((vs.cy << 4) & BG_MASK);
   1519   1.1  jonathan 					vs.state = 0;
   1520   1.1  jonathan 					break;
   1521  1.13      soda 				case 's': /* save cursor pos */
   1522  1.13      soda 					vs.offset = crtat - Crtat;
   1523  1.13      soda 					vs.state = 0;
   1524  1.13      soda 					break;
   1525  1.13      soda 				case 'u': /* restore cursor pos */
   1526  1.13      soda 					crtat = Crtat + vs.offset;
   1527  1.13      soda 					vs.row = vs.offset / vs.ncol;
   1528  1.13      soda 					vs.col = vs.offset % vs.ncol;
   1529  1.13      soda 					vs.state = 0;
   1530  1.13      soda 					break;
   1531   1.1  jonathan 				case 'x': /* set attributes */
   1532   1.1  jonathan 					switch (vs.cx) {
   1533   1.1  jonathan 					case 0:
   1534   1.1  jonathan 						vs.at = FG_LIGHTGREY | BG_BLACK;
   1535   1.1  jonathan 						break;
   1536   1.1  jonathan 					case 1:
   1537   1.1  jonathan 						/* ansi background */
   1538   1.1  jonathan 						if (!vs.color)
   1539   1.1  jonathan 							break;
   1540   1.1  jonathan 						vs.at &= FG_MASK;
   1541   1.1  jonathan 						vs.at |= bgansitopc[vs.cy & 7];
   1542   1.1  jonathan 						break;
   1543   1.1  jonathan 					case 2:
   1544   1.1  jonathan 						/* ansi foreground */
   1545   1.1  jonathan 						if (!vs.color)
   1546   1.1  jonathan 							break;
   1547   1.1  jonathan 						vs.at &= BG_MASK;
   1548   1.1  jonathan 						vs.at |= fgansitopc[vs.cy & 7];
   1549   1.1  jonathan 						break;
   1550   1.1  jonathan 					case 3:
   1551   1.1  jonathan 						/* pc text attribute */
   1552   1.1  jonathan 						if (vs.state >= VSS_EPARAM)
   1553   1.1  jonathan 							vs.at = vs.cy;
   1554   1.1  jonathan 						break;
   1555   1.1  jonathan 					}
   1556   1.1  jonathan 					vs.state = 0;
   1557   1.1  jonathan 					break;
   1558   1.1  jonathan 
   1559   1.1  jonathan 				default: /* Only numbers valid here */
   1560   1.1  jonathan 					if ((c >= '0') && (c <= '9')) {
   1561   1.1  jonathan 						if (vs.state >= VSS_EPARAM) {
   1562   1.1  jonathan 							vs.cy *= 10;
   1563   1.1  jonathan 							vs.cy += c - '0';
   1564   1.1  jonathan 						} else {
   1565   1.1  jonathan 							vs.cx *= 10;
   1566   1.1  jonathan 							vs.cx += c - '0';
   1567   1.1  jonathan 						}
   1568   1.1  jonathan 					} else
   1569   1.1  jonathan 						vs.state = 0;
   1570   1.1  jonathan 					break;
   1571   1.1  jonathan 				}
   1572   1.1  jonathan 				break;
   1573   1.1  jonathan 			}
   1574   1.1  jonathan 		}
   1575   1.1  jonathan 		if (scroll) {
   1576   1.1  jonathan 			scroll = 0;
   1577   1.1  jonathan 			/* scroll check */
   1578   1.1  jonathan 			if (crtat >= Crtat + vs.nchr) {
   1579   1.1  jonathan 				if (!kernel) {
   1580   1.1  jonathan 					int s = spltty();
   1581  1.13      soda 					if (lock_state & KB_SCROLL)
   1582  1.13      soda 						tsleep(&lock_state,
   1583   1.1  jonathan 						    PUSER, "pcputc", 0);
   1584   1.1  jonathan 					splx(s);
   1585   1.1  jonathan 				}
   1586  1.13      soda #if PCCONS_FORCE_WORD
   1587  1.13      soda 				wcopy(Crtat + vs.ncol, Crtat,
   1588  1.13      soda 				    (vs.nchr - vs.ncol) * CHR);
   1589  1.13      soda #else
   1590   1.1  jonathan 				bcopy(Crtat + vs.ncol, Crtat,
   1591   1.1  jonathan 				    (vs.nchr - vs.ncol) * CHR);
   1592  1.13      soda #endif
   1593   1.1  jonathan 				fillw((vs.at << 8) | ' ',
   1594  1.13      soda 				    Crtat + vs.nchr - vs.ncol,
   1595  1.13      soda 				    vs.ncol);
   1596   1.1  jonathan 				crtat -= vs.ncol;
   1597   1.1  jonathan 			}
   1598   1.1  jonathan 		}
   1599   1.1  jonathan 	}
   1600   1.1  jonathan 	async_update();
   1601   1.1  jonathan }
   1602   1.1  jonathan 
   1603  1.13      soda /* the unshifted code for KB_SHIFT keys is used by X to distinguish between
   1604  1.13      soda    left and right shift when reading the keyboard map */
   1605  1.13      soda static pccons_keymap_t	scan_codes[KB_NUM_KEYS] = {
   1606  1.13      soda /*  type       unshift   shift     control   altgr     shift_altgr scancode */
   1607  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 0 unused */
   1608  1.13      soda   { KB_ASCII,  "\033",   "\033",   "\033",   "",       ""}, /* 1 ESCape */
   1609  1.13      soda   { KB_ASCII,  "1",      "!",      "!",      "",       ""}, /* 2 1 */
   1610  1.13      soda   { KB_ASCII,  "2",      "@",      "\000",   "",       ""}, /* 3 2 */
   1611  1.13      soda   { KB_ASCII,  "3",      "#",      "#",      "",       ""}, /* 4 3 */
   1612  1.13      soda   { KB_ASCII,  "4",      "$",      "$",      "",       ""}, /* 5 4 */
   1613  1.13      soda   { KB_ASCII,  "5",      "%",      "%",      "",       ""}, /* 6 5 */
   1614  1.13      soda   { KB_ASCII,  "6",      "^",      "\036",   "",       ""}, /* 7 6 */
   1615  1.13      soda   { KB_ASCII,  "7",      "&",      "&",      "",       ""}, /* 8 7 */
   1616  1.13      soda   { KB_ASCII,  "8",      "*",      "\010",   "",       ""}, /* 9 8 */
   1617  1.13      soda   { KB_ASCII,  "9",      "(",      "(",      "",       ""}, /* 10 9 */
   1618  1.13      soda   { KB_ASCII,  "0",      ")",      ")",      "",       ""}, /* 11 0 */
   1619  1.13      soda   { KB_ASCII,  "-",      "_",      "\037",   "",       ""}, /* 12 - */
   1620  1.13      soda   { KB_ASCII,  "=",      "+",      "+",      "",       ""}, /* 13 = */
   1621  1.13      soda   { KB_ASCII,  "\177",   "\177",   "\010",   "",       ""}, /* 14 backspace */
   1622  1.13      soda   { KB_ASCII,  "\t",     "\t",     "\t",     "",       ""}, /* 15 tab */
   1623  1.13      soda   { KB_ASCII,  "q",      "Q",      "\021",   "",       ""}, /* 16 q */
   1624  1.13      soda   { KB_ASCII,  "w",      "W",      "\027",   "",       ""}, /* 17 w */
   1625  1.13      soda   { KB_ASCII,  "e",      "E",      "\005",   "",       ""}, /* 18 e */
   1626  1.13      soda   { KB_ASCII,  "r",      "R",      "\022",   "",       ""}, /* 19 r */
   1627  1.13      soda   { KB_ASCII,  "t",      "T",      "\024",   "",       ""}, /* 20 t */
   1628  1.13      soda   { KB_ASCII,  "y",      "Y",      "\031",   "",       ""}, /* 21 y */
   1629  1.13      soda   { KB_ASCII,  "u",      "U",      "\025",   "",       ""}, /* 22 u */
   1630  1.13      soda   { KB_ASCII,  "i",      "I",      "\011",   "",       ""}, /* 23 i */
   1631  1.13      soda   { KB_ASCII,  "o",      "O",      "\017",   "",       ""}, /* 24 o */
   1632  1.13      soda   { KB_ASCII,  "p",      "P",      "\020",   "",       ""}, /* 25 p */
   1633  1.13      soda   { KB_ASCII,  "[",      "{",      "\033",   "",       ""}, /* 26 [ */
   1634  1.13      soda   { KB_ASCII,  "]",      "}",      "\035",   "",       ""}, /* 27 ] */
   1635  1.13      soda   { KB_ASCII,  "\r",     "\r",     "\n",     "",       ""}, /* 28 return */
   1636  1.13      soda   { KB_CTL,    "",       "",       "",       "",       ""}, /* 29 control */
   1637  1.13      soda   { KB_ASCII,  "a",      "A",      "\001",   "",       ""}, /* 30 a */
   1638  1.13      soda   { KB_ASCII,  "s",      "S",      "\023",   "",       ""}, /* 31 s */
   1639  1.13      soda   { KB_ASCII,  "d",      "D",      "\004",   "",       ""}, /* 32 d */
   1640  1.13      soda   { KB_ASCII,  "f",      "F",      "\006",   "",       ""}, /* 33 f */
   1641  1.13      soda   { KB_ASCII,  "g",      "G",      "\007",   "",       ""}, /* 34 g */
   1642  1.13      soda   { KB_ASCII,  "h",      "H",      "\010",   "",       ""}, /* 35 h */
   1643  1.13      soda   { KB_ASCII,  "j",      "J",      "\n",     "",       ""}, /* 36 j */
   1644  1.13      soda   { KB_ASCII,  "k",      "K",      "\013",   "",       ""}, /* 37 k */
   1645  1.13      soda   { KB_ASCII,  "l",      "L",      "\014",   "",       ""}, /* 38 l */
   1646  1.13      soda   { KB_ASCII,  ";",      ":",      ";",      "",       ""}, /* 39 ; */
   1647  1.13      soda   { KB_ASCII,  "'",      "\"",     "'",      "",       ""}, /* 40 ' */
   1648  1.13      soda   { KB_ASCII,  "`",      "~",      "`",      "",       ""}, /* 41 ` */
   1649  1.13      soda   { KB_SHIFT,  "\001",   "",       "",       "",       ""}, /* 42 shift */
   1650  1.13      soda   { KB_ASCII,  "\\",     "|",      "\034",   "",       ""}, /* 43 \ */
   1651  1.13      soda   { KB_ASCII,  "z",      "Z",      "\032",   "",       ""}, /* 44 z */
   1652  1.13      soda   { KB_ASCII,  "x",      "X",      "\030",   "",       ""}, /* 45 x */
   1653  1.13      soda   { KB_ASCII,  "c",      "C",      "\003",   "",       ""}, /* 46 c */
   1654  1.13      soda   { KB_ASCII,  "v",      "V",      "\026",   "",       ""}, /* 47 v */
   1655  1.13      soda   { KB_ASCII,  "b",      "B",      "\002",   "",       ""}, /* 48 b */
   1656  1.13      soda   { KB_ASCII,  "n",      "N",      "\016",   "",       ""}, /* 49 n */
   1657  1.13      soda   { KB_ASCII,  "m",      "M",      "\r",     "",       ""}, /* 50 m */
   1658  1.13      soda   { KB_ASCII,  ",",      "<",      "<",      "",       ""}, /* 51 , */
   1659  1.13      soda   { KB_ASCII,  ".",      ">",      ">",      "",       ""}, /* 52 . */
   1660  1.13      soda   { KB_ASCII,  "/",      "?",      "\037",   "",       ""}, /* 53 / */
   1661  1.13      soda   { KB_SHIFT,  "\002",   "",       "",       "",       ""}, /* 54 shift */
   1662  1.13      soda   { KB_KP,     "*",      "*",      "*",      "",       ""}, /* 55 kp * */
   1663  1.13      soda   { KB_ALT,    "",       "",       "",       "",       ""}, /* 56 alt */
   1664  1.13      soda   { KB_ASCII,  " ",      " ",      "\000",   "",       ""}, /* 57 space */
   1665  1.13      soda   { KB_CAPS,   "",       "",       "",       "",       ""}, /* 58 caps */
   1666  1.13      soda   { KB_FUNC,   "\033[M", "\033[Y", "\033[k", "",       ""}, /* 59 f1 */
   1667  1.13      soda   { KB_FUNC,   "\033[N", "\033[Z", "\033[l", "",       ""}, /* 60 f2 */
   1668  1.13      soda   { KB_FUNC,   "\033[O", "\033[a", "\033[m", "",       ""}, /* 61 f3 */
   1669  1.13      soda   { KB_FUNC,   "\033[P", "\033[b", "\033[n", "",       ""}, /* 62 f4 */
   1670  1.13      soda   { KB_FUNC,   "\033[Q", "\033[c", "\033[o", "",       ""}, /* 63 f5 */
   1671  1.13      soda   { KB_FUNC,   "\033[R", "\033[d", "\033[p", "",       ""}, /* 64 f6 */
   1672  1.13      soda   { KB_FUNC,   "\033[S", "\033[e", "\033[q", "",       ""}, /* 65 f7 */
   1673  1.13      soda   { KB_FUNC,   "\033[T", "\033[f", "\033[r", "",       ""}, /* 66 f8 */
   1674  1.13      soda   { KB_FUNC,   "\033[U", "\033[g", "\033[s", "",       ""}, /* 67 f9 */
   1675  1.13      soda   { KB_FUNC,   "\033[V", "\033[h", "\033[t", "",       ""}, /* 68 f10 */
   1676  1.13      soda   { KB_NUM,    "",       "",       "",       "",       ""}, /* 69 num lock */
   1677  1.13      soda   { KB_SCROLL, "",       "",       "",       "",       ""}, /* 70 scroll lock */
   1678  1.13      soda   { KB_KP,     "7",      "\033[H", "7",      "",       ""}, /* 71 kp 7 */
   1679  1.13      soda   { KB_KP,     "8",      "\033[A", "8",      "",       ""}, /* 72 kp 8 */
   1680  1.13      soda   { KB_KP,     "9",      "\033[I", "9",      "",       ""}, /* 73 kp 9 */
   1681  1.13      soda   { KB_KP,     "-",      "-",      "-",      "",       ""}, /* 74 kp - */
   1682  1.13      soda   { KB_KP,     "4",      "\033[D", "4",      "",       ""}, /* 75 kp 4 */
   1683  1.13      soda   { KB_KP,     "5",      "\033[E", "5",      "",       ""}, /* 76 kp 5 */
   1684  1.13      soda   { KB_KP,     "6",      "\033[C", "6",      "",       ""}, /* 77 kp 6 */
   1685  1.13      soda   { KB_KP,     "+",      "+",      "+",      "",       ""}, /* 78 kp + */
   1686  1.13      soda   { KB_KP,     "1",      "\033[F", "1",      "",       ""}, /* 79 kp 1 */
   1687  1.13      soda   { KB_KP,     "2",      "\033[B", "2",      "",       ""}, /* 80 kp 2 */
   1688  1.13      soda   { KB_KP,     "3",      "\033[G", "3",      "",       ""}, /* 81 kp 3 */
   1689  1.13      soda   { KB_KP,     "0",      "\033[L", "0",      "",       ""}, /* 82 kp 0 */
   1690  1.13      soda   { KB_KP,     ",",      "\177",   ",",      "",       ""}, /* 83 kp , */
   1691  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 84 0 */
   1692  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 85 0 */
   1693  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 86 0 */
   1694  1.13      soda   { KB_FUNC,   "\033[W", "\033[i", "\033[u", "",       ""}, /* 87 f11 */
   1695  1.13      soda   { KB_FUNC,   "\033[X", "\033[j", "\033[v", "",       ""}, /* 88 f12 */
   1696  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 89 0 */
   1697  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 90 0 */
   1698  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 91 0 */
   1699  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 92 0 */
   1700  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 93 0 */
   1701  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 94 0 */
   1702  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 95 0 */
   1703  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 96 0 */
   1704  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 97 0 */
   1705  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 98 0 */
   1706  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 99 0 */
   1707  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 100 */
   1708  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 101 */
   1709  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 102 */
   1710  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 103 */
   1711  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 104 */
   1712  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 105 */
   1713  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 106 */
   1714  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 107 */
   1715  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 108 */
   1716  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 109 */
   1717  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 110 */
   1718  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 111 */
   1719  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 112 */
   1720  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 113 */
   1721  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 114 */
   1722  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 115 */
   1723  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 116 */
   1724  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 117 */
   1725  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 118 */
   1726  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 119 */
   1727  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 120 */
   1728  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 121 */
   1729  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 122 */
   1730  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 123 */
   1731  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 124 */
   1732  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 125 */
   1733  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}, /* 126 */
   1734  1.13      soda   { KB_NONE,   "",       "",       "",       "",       ""}  /* 127 */
   1735   1.1  jonathan };
   1736   1.1  jonathan 
   1737   1.1  jonathan /*
   1738   1.1  jonathan  * Get characters from the keyboard.  If none are present, return NULL.
   1739   1.1  jonathan  */
   1740   1.1  jonathan char *
   1741   1.1  jonathan sget()
   1742   1.1  jonathan {
   1743   1.1  jonathan 	u_char dt;
   1744   1.1  jonathan 	static u_char extended = 0, shift_state = 0;
   1745   1.1  jonathan 	static u_char capchar[2];
   1746   1.1  jonathan 
   1747   1.1  jonathan top:
   1748   1.1  jonathan 	KBD_DELAY;
   1749  1.13      soda 	dt = inb(kbd_datap);
   1750   1.1  jonathan 
   1751   1.1  jonathan 	switch (dt) {
   1752   1.1  jonathan 	case KBR_ACK: case KBR_ECHO:
   1753   1.1  jonathan 		kb_oq_get = (kb_oq_get + 1) & 7;
   1754   1.1  jonathan 		if(kb_oq_get != kb_oq_put) {
   1755  1.13      soda 			outb(kbd_datap, kb_oq[kb_oq_get]);
   1756   1.1  jonathan 		}
   1757   1.1  jonathan 		goto loop;
   1758   1.1  jonathan 	case KBR_RESEND:
   1759  1.13      soda 		outb(kbd_datap, kb_oq[kb_oq_get]);
   1760   1.1  jonathan 		goto loop;
   1761   1.1  jonathan 	}
   1762   1.1  jonathan 
   1763   1.1  jonathan 	if (pc_xmode > 0) {
   1764   1.1  jonathan #if defined(DDB) && defined(XSERVER_DDB)
   1765   1.1  jonathan 		/* F12 enters the debugger while in X mode */
   1766   1.1  jonathan 		if (dt == 88)
   1767   1.1  jonathan 			Debugger();
   1768   1.1  jonathan #endif
   1769   1.1  jonathan 		capchar[0] = dt;
   1770   1.1  jonathan 		capchar[1] = 0;
   1771   1.1  jonathan 		/*
   1772   1.1  jonathan 		 * Check for locking keys.
   1773   1.1  jonathan 		 *
   1774   1.1  jonathan 		 * XXX Setting the LEDs this way is a bit bogus.  What if the
   1775   1.1  jonathan 		 * keyboard has been remapped in X?
   1776   1.1  jonathan 		 */
   1777  1.13      soda 		switch (scan_codes[dt & 0x7f].type) {
   1778  1.13      soda 		case KB_NUM:
   1779   1.1  jonathan 			if (dt & 0x80) {
   1780  1.13      soda 				shift_state &= ~KB_NUM;
   1781   1.1  jonathan 				break;
   1782   1.1  jonathan 			}
   1783  1.13      soda 			if (shift_state & KB_NUM)
   1784   1.1  jonathan 				break;
   1785  1.13      soda 			shift_state |= KB_NUM;
   1786  1.13      soda 			lock_state ^= KB_NUM;
   1787   1.1  jonathan 			async_update();
   1788   1.1  jonathan 			break;
   1789  1.13      soda 		case KB_CAPS:
   1790   1.1  jonathan 			if (dt & 0x80) {
   1791  1.13      soda 				shift_state &= ~KB_CAPS;
   1792   1.1  jonathan 				break;
   1793   1.1  jonathan 			}
   1794  1.13      soda 			if (shift_state & KB_CAPS)
   1795   1.1  jonathan 				break;
   1796  1.13      soda 			shift_state |= KB_CAPS;
   1797  1.13      soda 			lock_state ^= KB_CAPS;
   1798   1.1  jonathan 			async_update();
   1799   1.1  jonathan 			break;
   1800  1.13      soda 		case KB_SCROLL:
   1801   1.1  jonathan 			if (dt & 0x80) {
   1802  1.13      soda 				shift_state &= ~KB_SCROLL;
   1803   1.1  jonathan 				break;
   1804   1.1  jonathan 			}
   1805  1.13      soda 			if (shift_state & KB_SCROLL)
   1806   1.1  jonathan 				break;
   1807  1.13      soda 			shift_state |= KB_SCROLL;
   1808  1.13      soda 			lock_state ^= KB_SCROLL;
   1809  1.13      soda 			if ((lock_state & KB_SCROLL) == 0)
   1810   1.1  jonathan 				wakeup((caddr_t)&lock_state);
   1811   1.1  jonathan 			async_update();
   1812   1.1  jonathan 			break;
   1813   1.1  jonathan 		}
   1814   1.1  jonathan 		return capchar;
   1815   1.1  jonathan 	}
   1816   1.1  jonathan 
   1817   1.1  jonathan 	switch (dt) {
   1818   1.1  jonathan 	case KBR_EXTENDED:
   1819   1.1  jonathan 		extended = 1;
   1820   1.1  jonathan 		goto loop;
   1821   1.1  jonathan 	}
   1822   1.1  jonathan 
   1823  1.13      soda #ifdef DDB
   1824   1.1  jonathan 	/*
   1825   1.1  jonathan 	 * Check for cntl-alt-esc.
   1826   1.1  jonathan 	 */
   1827  1.13      soda 	if ((dt == 1) && (shift_state & (KB_CTL | KB_ALT)) == (KB_CTL | KB_ALT)) {
   1828  1.13      soda 		/* XXX - check pccons_is_console */
   1829  1.13      soda 		Debugger();
   1830   1.1  jonathan 		dt |= 0x80;	/* discard esc (ddb discarded ctl-alt) */
   1831   1.1  jonathan 	}
   1832   1.1  jonathan #endif
   1833   1.1  jonathan 
   1834   1.1  jonathan 	/*
   1835   1.1  jonathan 	 * Check for make/break.
   1836   1.1  jonathan 	 */
   1837   1.1  jonathan 	if (dt & 0x80) {
   1838   1.1  jonathan 		/*
   1839   1.1  jonathan 		 * break
   1840   1.1  jonathan 		 */
   1841   1.1  jonathan 		dt &= 0x7f;
   1842  1.13      soda 		switch (scan_codes[dt].type) {
   1843  1.13      soda 		case KB_NUM:
   1844  1.13      soda 			shift_state &= ~KB_NUM;
   1845   1.1  jonathan 			break;
   1846  1.13      soda 		case KB_CAPS:
   1847  1.13      soda 			shift_state &= ~KB_CAPS;
   1848   1.1  jonathan 			break;
   1849  1.13      soda 		case KB_SCROLL:
   1850  1.13      soda 			shift_state &= ~KB_SCROLL;
   1851   1.1  jonathan 			break;
   1852  1.13      soda 		case KB_SHIFT:
   1853  1.13      soda 			shift_state &= ~KB_SHIFT;
   1854   1.1  jonathan 			break;
   1855  1.13      soda 		case KB_ALT:
   1856   1.1  jonathan 			if (extended)
   1857  1.13      soda 				shift_state &= ~KB_ALTGR;
   1858   1.1  jonathan 			else
   1859  1.13      soda 				shift_state &= ~KB_ALT;
   1860   1.1  jonathan 			break;
   1861  1.13      soda 		case KB_CTL:
   1862  1.13      soda 			shift_state &= ~KB_CTL;
   1863   1.1  jonathan 			break;
   1864   1.1  jonathan 		}
   1865   1.1  jonathan 	} else {
   1866   1.1  jonathan 		/*
   1867   1.1  jonathan 		 * make
   1868   1.1  jonathan 		 */
   1869  1.13      soda 		switch (scan_codes[dt].type) {
   1870   1.1  jonathan 		/*
   1871   1.1  jonathan 		 * locking keys
   1872   1.1  jonathan 		 */
   1873  1.13      soda 		case KB_NUM:
   1874  1.13      soda 			if (shift_state & KB_NUM)
   1875   1.1  jonathan 				break;
   1876  1.13      soda 			shift_state |= KB_NUM;
   1877  1.13      soda 			lock_state ^= KB_NUM;
   1878   1.1  jonathan 			async_update();
   1879   1.1  jonathan 			break;
   1880  1.13      soda 		case KB_CAPS:
   1881  1.13      soda 			if (shift_state & KB_CAPS)
   1882   1.1  jonathan 				break;
   1883  1.13      soda 			shift_state |= KB_CAPS;
   1884  1.13      soda 			lock_state ^= KB_CAPS;
   1885   1.1  jonathan 			async_update();
   1886   1.1  jonathan 			break;
   1887  1.13      soda 		case KB_SCROLL:
   1888  1.13      soda 			if (shift_state & KB_SCROLL)
   1889   1.1  jonathan 				break;
   1890  1.13      soda 			shift_state |= KB_SCROLL;
   1891  1.13      soda 			lock_state ^= KB_SCROLL;
   1892  1.13      soda 			if ((lock_state & KB_SCROLL) == 0)
   1893   1.1  jonathan 				wakeup((caddr_t)&lock_state);
   1894   1.1  jonathan 			async_update();
   1895   1.1  jonathan 			break;
   1896   1.1  jonathan 		/*
   1897   1.1  jonathan 		 * non-locking keys
   1898   1.1  jonathan 		 */
   1899  1.13      soda 		case KB_SHIFT:
   1900  1.13      soda 			shift_state |= KB_SHIFT;
   1901   1.1  jonathan 			break;
   1902  1.13      soda 		case KB_ALT:
   1903   1.1  jonathan 			if (extended)
   1904  1.13      soda 				shift_state |= KB_ALTGR;
   1905   1.1  jonathan 			else
   1906  1.13      soda 				shift_state |= KB_ALT;
   1907   1.1  jonathan 			break;
   1908  1.13      soda 		case KB_CTL:
   1909  1.13      soda 			shift_state |= KB_CTL;
   1910   1.1  jonathan 			break;
   1911  1.13      soda 		case KB_ASCII:
   1912  1.13      soda 			/* control has highest priority */
   1913  1.13      soda 			if (shift_state & KB_CTL)
   1914  1.13      soda 				capchar[0] = scan_codes[dt].ctl[0];
   1915  1.13      soda 			else if (shift_state & KB_ALTGR) {
   1916  1.13      soda 				if (shift_state & KB_SHIFT)
   1917  1.13      soda 					capchar[0] = scan_codes[dt].shift_altgr[0];
   1918  1.13      soda 				else
   1919  1.13      soda 					capchar[0] = scan_codes[dt].altgr[0];
   1920   1.1  jonathan 			}
   1921  1.13      soda 			else {
   1922  1.13      soda 				if (shift_state & KB_SHIFT)
   1923  1.13      soda 					capchar[0] = scan_codes[dt].shift[0];
   1924  1.13      soda 				else
   1925  1.13      soda 					capchar[0] = scan_codes[dt].unshift[0];
   1926  1.13      soda 			}
   1927  1.13      soda 			if ((lock_state & KB_CAPS) && capchar[0] >= 'a' &&
   1928   1.1  jonathan 			    capchar[0] <= 'z') {
   1929   1.1  jonathan 				capchar[0] -= ('a' - 'A');
   1930   1.1  jonathan 			}
   1931  1.13      soda 			capchar[0] |= (shift_state & KB_ALT);
   1932   1.1  jonathan 			extended = 0;
   1933   1.1  jonathan 			return capchar;
   1934  1.13      soda 		case KB_NONE:
   1935   1.6  christos printf("keycode %d\n",dt);
   1936   1.1  jonathan 			break;
   1937  1.13      soda 		case KB_FUNC: {
   1938   1.1  jonathan 			char *more_chars;
   1939  1.13      soda 			if (shift_state & KB_SHIFT)
   1940  1.13      soda 				more_chars = scan_codes[dt].shift;
   1941  1.13      soda 			else if (shift_state & KB_CTL)
   1942  1.13      soda 				more_chars = scan_codes[dt].ctl;
   1943   1.1  jonathan 			else
   1944  1.13      soda 				more_chars = scan_codes[dt].unshift;
   1945   1.1  jonathan 			extended = 0;
   1946   1.1  jonathan 			return more_chars;
   1947   1.1  jonathan 		}
   1948  1.13      soda 		case KB_KP: {
   1949   1.1  jonathan 			char *more_chars;
   1950  1.13      soda 			if (shift_state & (KB_SHIFT | KB_CTL) ||
   1951  1.13      soda 			    (lock_state & KB_NUM) == 0 || extended)
   1952  1.13      soda 				more_chars = scan_codes[dt].shift;
   1953   1.1  jonathan 			else
   1954  1.13      soda 				more_chars = scan_codes[dt].unshift;
   1955   1.1  jonathan 			extended = 0;
   1956   1.1  jonathan 			return more_chars;
   1957   1.1  jonathan 		}
   1958   1.1  jonathan 		}
   1959   1.1  jonathan 	}
   1960   1.1  jonathan 
   1961   1.1  jonathan 	extended = 0;
   1962   1.1  jonathan loop:
   1963  1.13      soda 	if ((inb(kbd_cmdp) & KBS_DIB) == 0)
   1964   1.1  jonathan 		return 0;
   1965   1.1  jonathan 	goto top;
   1966   1.1  jonathan }
   1967   1.1  jonathan 
   1968  1.21    simonb paddr_t
   1969   1.1  jonathan pcmmap(dev, offset, nprot)
   1970   1.1  jonathan 	dev_t dev;
   1971  1.21    simonb 	off_t offset;
   1972   1.1  jonathan 	int nprot;
   1973   1.1  jonathan {
   1974   1.1  jonathan 
   1975  1.13      soda 	switch(cputype) {
   1976  1.13      soda 
   1977  1.13      soda 	case ACER_PICA_61:
   1978  1.18      soda 	case NEC_R96:
   1979  1.13      soda 		if (offset >= 0xa0000 && offset < 0xc0000)
   1980  1.13      soda 			return mips_btop(PICA_P_LOCAL_VIDEO + offset);
   1981  1.13      soda 		if (offset >= 0x0000 && offset < 0x10000)
   1982  1.13      soda 			return mips_btop(PICA_P_LOCAL_VIDEO_CTRL + offset);
   1983  1.13      soda 		if (offset >= 0x40000000 && offset < 0x40800000)
   1984  1.13      soda 			return mips_btop(PICA_P_LOCAL_VIDEO + offset - 0x40000000);
   1985  1.14      soda 		return -1;
   1986  1.14      soda 
   1987  1.14      soda 	case DESKSTATION_RPC44:
   1988  1.14      soda 		if (offset >= 0xa0000 && offset < 0xc0000)
   1989  1.14      soda 			return mips_btop(RPC44_P_ISA_MEM + offset);
   1990  1.14      soda 		if (offset >= 0x0000 && offset < 0x10000)
   1991  1.14      soda 			return mips_btop(RPC44_P_ISA_IO + offset);
   1992  1.14      soda 		if (offset >= 0x40000000 && offset < 0x40800000)
   1993  1.14      soda 			return mips_btop(RPC44_P_ISA_MEM + offset - 0x40000000);
   1994  1.13      soda 		return -1;
   1995  1.13      soda 
   1996  1.13      soda 	case DESKSTATION_TYNE:
   1997  1.13      soda 		if (offset >= 0xa0000 && offset < 0xc0000)
   1998  1.18      soda 			return mips_btop(TYNE_P_ISA_MEM + offset);
   1999  1.13      soda 		if (offset >= 0x0000 && offset < 0x10000)
   2000  1.18      soda 			return mips_btop(TYNE_P_ISA_IO + offset);
   2001  1.13      soda 		if (offset >= 0x40000000 && offset < 0x40800000)
   2002  1.18      soda 			return mips_btop(TYNE_P_ISA_MEM + offset - 0x40000000);
   2003  1.13      soda 		return -1;
   2004  1.13      soda 	}
   2005   1.1  jonathan 	return -1;
   2006   1.1  jonathan }
   2007   1.1  jonathan 
   2008  1.13      soda void
   2009   1.1  jonathan pc_xmode_on()
   2010   1.1  jonathan {
   2011   1.1  jonathan 	if (pc_xmode)
   2012   1.1  jonathan 		return;
   2013   1.1  jonathan 	pc_xmode = 1;
   2014   1.1  jonathan 
   2015   1.1  jonathan #ifdef XFREE86_BUG_COMPAT
   2016   1.1  jonathan 	/* If still unchanged, get current shape. */
   2017   1.1  jonathan 	if (cursor_shape == 0xffff)
   2018   1.1  jonathan 		get_cursor_shape();
   2019   1.1  jonathan #endif
   2020   1.1  jonathan }
   2021   1.1  jonathan 
   2022  1.13      soda void
   2023   1.1  jonathan pc_xmode_off()
   2024   1.1  jonathan {
   2025   1.1  jonathan 	if (pc_xmode == 0)
   2026   1.1  jonathan 		return;
   2027   1.1  jonathan 	pc_xmode = 0;
   2028   1.1  jonathan 
   2029   1.1  jonathan #ifdef XFREE86_BUG_COMPAT
   2030   1.1  jonathan 	/* XXX It would be hard to justify why the X server doesn't do this. */
   2031   1.1  jonathan 	set_cursor_shape();
   2032   1.1  jonathan #endif
   2033   1.1  jonathan 	async_update();
   2034   1.1  jonathan }
   2035   1.1  jonathan 
   2036   1.1  jonathan #include <machine/mouse.h>
   2037   1.1  jonathan 
   2038   1.1  jonathan /* status bits */
   2039   1.1  jonathan #define	PMS_OBUF_FULL	0x01
   2040   1.1  jonathan #define	PMS_IBUF_FULL	0x02
   2041   1.1  jonathan 
   2042   1.1  jonathan /* controller commands */
   2043   1.1  jonathan #define	PMS_INT_ENABLE	0x47	/* enable controller interrupts */
   2044   1.1  jonathan #define	PMS_INT_DISABLE	0x65	/* disable controller interrupts */
   2045   1.1  jonathan #define	PMS_AUX_ENABLE	0xa7	/* enable auxiliary port */
   2046   1.1  jonathan #define	PMS_AUX_DISABLE	0xa8	/* disable auxiliary port */
   2047   1.1  jonathan #define	PMS_MAGIC_1	0xa9	/* XXX */
   2048   1.1  jonathan 
   2049   1.1  jonathan #define	PMS_8042_CMD	0x65
   2050   1.1  jonathan 
   2051   1.1  jonathan /* mouse commands */
   2052   1.1  jonathan #define	PMS_SET_SCALE11	0xe6	/* set scaling 1:1 */
   2053   1.1  jonathan #define	PMS_SET_SCALE21 0xe7	/* set scaling 2:1 */
   2054   1.1  jonathan #define	PMS_SET_RES	0xe8	/* set resolution */
   2055   1.1  jonathan #define	PMS_GET_SCALE	0xe9	/* get scaling factor */
   2056   1.1  jonathan #define	PMS_SET_STREAM	0xea	/* set streaming mode */
   2057   1.1  jonathan #define	PMS_SET_SAMPLE	0xf3	/* set sampling rate */
   2058   1.1  jonathan #define	PMS_DEV_ENABLE	0xf4	/* mouse on */
   2059   1.1  jonathan #define	PMS_DEV_DISABLE	0xf5	/* mouse off */
   2060   1.1  jonathan #define	PMS_RESET	0xff	/* reset */
   2061   1.1  jonathan 
   2062   1.1  jonathan #define	PMS_CHUNK	128	/* chunk size for read */
   2063   1.1  jonathan #define	PMS_BSIZE	1020	/* buffer size */
   2064   1.1  jonathan 
   2065  1.13      soda #define	FLUSHQ(q) { if((q)->c_cc) ndflush(q, (q)->c_cc); }
   2066  1.13      soda 
   2067  1.20      soda #if NOPMS > 0
   2068  1.20      soda 
   2069  1.13      soda int opmsopen __P((dev_t, int));
   2070  1.13      soda int opmsclose __P((dev_t, int));
   2071  1.13      soda int opmsread __P((dev_t, struct uio *, int));
   2072  1.13      soda int opmsioctl __P((dev_t, u_long, caddr_t, int));
   2073  1.13      soda int opmsselect __P((dev_t, int, struct proc *));
   2074  1.15      soda int opmspoll __P((dev_t, int, struct proc *));
   2075  1.13      soda static __inline void pms_dev_cmd __P((u_char));
   2076  1.13      soda static __inline void pms_aux_cmd __P((u_char));
   2077  1.13      soda static __inline void pms_pit_cmd __P((u_char));
   2078   1.1  jonathan 
   2079  1.13      soda static __inline void
   2080   1.1  jonathan pms_dev_cmd(value)
   2081   1.1  jonathan 	u_char value;
   2082   1.1  jonathan {
   2083   1.1  jonathan 	kbd_flush_input();
   2084  1.13      soda 	outb(kbd_cmdp, 0xd4);
   2085   1.1  jonathan 	kbd_flush_input();
   2086  1.13      soda 	outb(kbd_datap, value);
   2087   1.1  jonathan }
   2088   1.1  jonathan 
   2089  1.13      soda static __inline void
   2090   1.1  jonathan pms_aux_cmd(value)
   2091   1.1  jonathan 	u_char value;
   2092   1.1  jonathan {
   2093   1.1  jonathan 	kbd_flush_input();
   2094  1.13      soda 	outb(kbd_cmdp, value);
   2095   1.1  jonathan }
   2096   1.1  jonathan 
   2097  1.13      soda static __inline void
   2098   1.1  jonathan pms_pit_cmd(value)
   2099   1.1  jonathan 	u_char value;
   2100   1.1  jonathan {
   2101   1.1  jonathan 	kbd_flush_input();
   2102  1.13      soda 	outb(kbd_cmdp, 0x60);
   2103   1.1  jonathan 	kbd_flush_input();
   2104  1.13      soda 	outb(kbd_datap, value);
   2105   1.1  jonathan }
   2106   1.1  jonathan 
   2107   1.1  jonathan int
   2108  1.13      soda opmsprobe(parent, match, aux)
   2109   1.1  jonathan 	struct device *parent;
   2110  1.13      soda 	struct cfdata *match;
   2111  1.13      soda 	void *aux;
   2112   1.1  jonathan {
   2113   1.1  jonathan 	struct confargs *ca = aux;
   2114   1.1  jonathan 	u_char x;
   2115   1.1  jonathan 
   2116   1.1  jonathan 	/* Make shure we're looking for this type of device */
   2117   1.1  jonathan 	if(!BUS_MATCHNAME(ca, "pms"))
   2118   1.1  jonathan 		return(0);
   2119   1.1  jonathan 
   2120  1.20      soda 	pcinithandle();
   2121   1.1  jonathan 	pms_dev_cmd(KBC_RESET);
   2122   1.1  jonathan 	pms_aux_cmd(PMS_MAGIC_1);
   2123   1.1  jonathan 	delay(10000);
   2124  1.13      soda 	x = inb(kbd_datap);
   2125   1.1  jonathan 	pms_pit_cmd(PMS_INT_DISABLE);
   2126   1.1  jonathan 	if (x & 0x04)
   2127   1.1  jonathan 		return 0;
   2128   1.1  jonathan 
   2129   1.1  jonathan 	return 1;
   2130   1.1  jonathan }
   2131   1.1  jonathan 
   2132   1.1  jonathan void
   2133  1.13      soda opmsattach(parent, self, aux)
   2134   1.1  jonathan 	struct device *parent, *self;
   2135   1.1  jonathan 	void *aux;
   2136   1.1  jonathan {
   2137  1.13      soda 	struct opms_softc *sc = (void *)self;
   2138   1.1  jonathan 	struct confargs *ca = aux;
   2139   1.1  jonathan 
   2140   1.6  christos 	printf("\n");
   2141   1.1  jonathan 
   2142  1.13      soda 	/* Other initialization was done by opmsprobe. */
   2143   1.1  jonathan 	sc->sc_state = 0;
   2144   1.1  jonathan 
   2145  1.13      soda 	BUS_INTR_ESTABLISH(ca, opmsintr, (void *)(long)sc);
   2146   1.1  jonathan }
   2147   1.1  jonathan 
   2148   1.1  jonathan int
   2149  1.13      soda opmsopen(dev, flag)
   2150   1.1  jonathan 	dev_t dev;
   2151   1.1  jonathan 	int flag;
   2152   1.1  jonathan {
   2153   1.1  jonathan 	int unit = PMSUNIT(dev);
   2154  1.13      soda 	struct opms_softc *sc;
   2155   1.1  jonathan 
   2156  1.13      soda 	if (unit >= opms_cd.cd_ndevs)
   2157   1.1  jonathan 		return ENXIO;
   2158  1.13      soda 	sc = opms_cd.cd_devs[unit];
   2159   1.1  jonathan 	if (!sc)
   2160   1.1  jonathan 		return ENXIO;
   2161   1.1  jonathan 
   2162   1.1  jonathan 	if (sc->sc_state & PMS_OPEN)
   2163   1.1  jonathan 		return EBUSY;
   2164   1.1  jonathan 
   2165   1.1  jonathan 	if (clalloc(&sc->sc_q, PMS_BSIZE, 0) == -1)
   2166   1.1  jonathan 		return ENOMEM;
   2167   1.1  jonathan 
   2168   1.1  jonathan 	sc->sc_state |= PMS_OPEN;
   2169   1.1  jonathan 	sc->sc_status = 0;
   2170   1.1  jonathan 	sc->sc_x = sc->sc_y = 0;
   2171   1.1  jonathan 
   2172   1.1  jonathan 	/* Enable interrupts. */
   2173   1.1  jonathan 	pms_dev_cmd(PMS_DEV_ENABLE);
   2174   1.1  jonathan 	pms_aux_cmd(PMS_AUX_ENABLE);
   2175   1.1  jonathan 	pms_dev_cmd(PMS_SET_RES);
   2176   1.1  jonathan 	pms_dev_cmd(3);		/* 8 counts/mm */
   2177   1.1  jonathan 	pms_dev_cmd(PMS_SET_SCALE21);
   2178   1.1  jonathan #if 0
   2179   1.1  jonathan 	pms_dev_cmd(PMS_SET_SAMPLE);
   2180   1.1  jonathan 	pms_dev_cmd(100);	/* 100 samples/sec */
   2181   1.1  jonathan 	pms_dev_cmd(PMS_SET_STREAM);
   2182   1.1  jonathan #endif
   2183   1.1  jonathan 	pms_pit_cmd(PMS_INT_ENABLE);
   2184   1.1  jonathan 
   2185   1.1  jonathan 	return 0;
   2186   1.1  jonathan }
   2187   1.1  jonathan 
   2188   1.1  jonathan int
   2189  1.13      soda opmsclose(dev, flag)
   2190   1.1  jonathan 	dev_t dev;
   2191   1.1  jonathan 	int flag;
   2192   1.1  jonathan {
   2193  1.13      soda 	struct opms_softc *sc = opms_cd.cd_devs[PMSUNIT(dev)];
   2194   1.1  jonathan 
   2195   1.1  jonathan 	/* Disable interrupts. */
   2196   1.1  jonathan 	pms_dev_cmd(PMS_DEV_DISABLE);
   2197   1.1  jonathan 	pms_pit_cmd(PMS_INT_DISABLE);
   2198   1.1  jonathan 	pms_aux_cmd(PMS_AUX_DISABLE);
   2199   1.1  jonathan 
   2200   1.1  jonathan 	sc->sc_state &= ~PMS_OPEN;
   2201   1.1  jonathan 
   2202   1.1  jonathan 	clfree(&sc->sc_q);
   2203   1.1  jonathan 
   2204   1.1  jonathan 	return 0;
   2205   1.1  jonathan }
   2206   1.1  jonathan 
   2207   1.1  jonathan int
   2208  1.13      soda opmsread(dev, uio, flag)
   2209   1.1  jonathan 	dev_t dev;
   2210   1.1  jonathan 	struct uio *uio;
   2211   1.1  jonathan 	int flag;
   2212   1.1  jonathan {
   2213  1.13      soda 	struct opms_softc *sc = opms_cd.cd_devs[PMSUNIT(dev)];
   2214   1.1  jonathan 	int s;
   2215  1.13      soda 	int error = 0;
   2216   1.1  jonathan 	size_t length;
   2217   1.1  jonathan 	u_char buffer[PMS_CHUNK];
   2218   1.1  jonathan 
   2219   1.1  jonathan 	/* Block until mouse activity occured. */
   2220   1.1  jonathan 
   2221   1.1  jonathan 	s = spltty();
   2222   1.1  jonathan 	while (sc->sc_q.c_cc == 0) {
   2223   1.1  jonathan 		if (flag & IO_NDELAY) {
   2224   1.1  jonathan 			splx(s);
   2225   1.1  jonathan 			return EWOULDBLOCK;
   2226   1.1  jonathan 		}
   2227   1.1  jonathan 		sc->sc_state |= PMS_ASLP;
   2228  1.13      soda 		error = tsleep((caddr_t)sc, PZERO | PCATCH, "pmsrea", 0);
   2229  1.13      soda 		if (error) {
   2230   1.1  jonathan 			sc->sc_state &= ~PMS_ASLP;
   2231   1.1  jonathan 			splx(s);
   2232   1.1  jonathan 			return error;
   2233   1.1  jonathan 		}
   2234   1.1  jonathan 	}
   2235   1.1  jonathan 	splx(s);
   2236   1.1  jonathan 
   2237   1.1  jonathan 	/* Transfer as many chunks as possible. */
   2238   1.1  jonathan 
   2239   1.1  jonathan 	while (sc->sc_q.c_cc > 0 && uio->uio_resid > 0) {
   2240   1.1  jonathan 		length = min(sc->sc_q.c_cc, uio->uio_resid);
   2241   1.1  jonathan 		if (length > sizeof(buffer))
   2242   1.1  jonathan 			length = sizeof(buffer);
   2243   1.1  jonathan 
   2244   1.1  jonathan 		/* Remove a small chunk from the input queue. */
   2245   1.1  jonathan 		(void) q_to_b(&sc->sc_q, buffer, length);
   2246   1.1  jonathan 
   2247   1.1  jonathan 		/* Copy the data to the user process. */
   2248  1.13      soda 		error = uiomove(buffer, length, uio);
   2249  1.13      soda 		if (error)
   2250   1.1  jonathan 			break;
   2251   1.1  jonathan 	}
   2252   1.1  jonathan 
   2253   1.1  jonathan 	return error;
   2254   1.1  jonathan }
   2255   1.1  jonathan 
   2256   1.1  jonathan int
   2257  1.13      soda opmsioctl(dev, cmd, addr, flag)
   2258   1.1  jonathan 	dev_t dev;
   2259   1.1  jonathan 	u_long cmd;
   2260   1.1  jonathan 	caddr_t addr;
   2261   1.1  jonathan 	int flag;
   2262   1.1  jonathan {
   2263  1.13      soda 	struct opms_softc *sc = opms_cd.cd_devs[PMSUNIT(dev)];
   2264   1.1  jonathan 	struct mouseinfo info;
   2265   1.1  jonathan 	int s;
   2266   1.1  jonathan 	int error;
   2267   1.1  jonathan 
   2268   1.1  jonathan 	switch (cmd) {
   2269   1.1  jonathan 	case MOUSEIOCREAD:
   2270   1.1  jonathan 		s = spltty();
   2271   1.1  jonathan 
   2272   1.1  jonathan 		info.status = sc->sc_status;
   2273   1.1  jonathan 		if (sc->sc_x || sc->sc_y)
   2274   1.1  jonathan 			info.status |= MOVEMENT;
   2275   1.1  jonathan 
   2276   1.1  jonathan 		if (sc->sc_x > 127)
   2277   1.1  jonathan 			info.xmotion = 127;
   2278   1.1  jonathan 		else if (sc->sc_x < -127)
   2279   1.1  jonathan 			/* Bounding at -127 avoids a bug in XFree86. */
   2280   1.1  jonathan 			info.xmotion = -127;
   2281   1.1  jonathan 		else
   2282   1.1  jonathan 			info.xmotion = sc->sc_x;
   2283   1.1  jonathan 
   2284   1.1  jonathan 		if (sc->sc_y > 127)
   2285   1.1  jonathan 			info.ymotion = 127;
   2286   1.1  jonathan 		else if (sc->sc_y < -127)
   2287   1.1  jonathan 			info.ymotion = -127;
   2288   1.1  jonathan 		else
   2289   1.1  jonathan 			info.ymotion = sc->sc_y;
   2290   1.1  jonathan 
   2291   1.1  jonathan 		/* Reset historical information. */
   2292   1.1  jonathan 		sc->sc_x = sc->sc_y = 0;
   2293   1.1  jonathan 		sc->sc_status &= ~BUTCHNGMASK;
   2294   1.1  jonathan 		ndflush(&sc->sc_q, sc->sc_q.c_cc);
   2295   1.1  jonathan 
   2296   1.1  jonathan 		splx(s);
   2297   1.1  jonathan 		error = copyout(&info, addr, sizeof(struct mouseinfo));
   2298   1.1  jonathan 		break;
   2299   1.1  jonathan 	default:
   2300   1.1  jonathan 		error = EINVAL;
   2301   1.1  jonathan 		break;
   2302   1.1  jonathan 	}
   2303   1.1  jonathan 
   2304   1.1  jonathan 	return error;
   2305   1.1  jonathan }
   2306   1.1  jonathan 
   2307   1.1  jonathan /* Masks for the first byte of a packet */
   2308   1.1  jonathan #define PS2LBUTMASK 0x01
   2309   1.1  jonathan #define PS2RBUTMASK 0x02
   2310   1.1  jonathan #define PS2MBUTMASK 0x04
   2311   1.1  jonathan 
   2312   1.1  jonathan int
   2313  1.13      soda opmsintr(arg)
   2314   1.1  jonathan 	void *arg;
   2315   1.1  jonathan {
   2316  1.13      soda 	struct opms_softc *sc = arg;
   2317   1.1  jonathan 	static int state = 0;
   2318   1.1  jonathan 	static u_char buttons;
   2319   1.1  jonathan 	u_char changed;
   2320   1.1  jonathan 	static char dx, dy;
   2321   1.1  jonathan 	u_char buffer[5];
   2322   1.1  jonathan 
   2323   1.1  jonathan 	if ((sc->sc_state & PMS_OPEN) == 0) {
   2324   1.1  jonathan 		/* Interrupts are not expected.  Discard the byte. */
   2325   1.1  jonathan 		kbd_flush_input();
   2326   1.1  jonathan 		return 0;
   2327   1.1  jonathan 	}
   2328   1.1  jonathan 
   2329   1.1  jonathan 	switch (state) {
   2330   1.1  jonathan 
   2331   1.1  jonathan 	case 0:
   2332  1.13      soda 		buttons = inb(kbd_datap);
   2333   1.1  jonathan 		if ((buttons & 0xc0) == 0)
   2334   1.1  jonathan 			++state;
   2335   1.1  jonathan 		break;
   2336   1.1  jonathan 
   2337   1.1  jonathan 	case 1:
   2338  1.13      soda 		dx = inb(kbd_datap);
   2339   1.1  jonathan 		/* Bounding at -127 avoids a bug in XFree86. */
   2340   1.1  jonathan 		dx = (dx == -128) ? -127 : dx;
   2341   1.1  jonathan 		++state;
   2342   1.1  jonathan 		break;
   2343   1.1  jonathan 
   2344   1.1  jonathan 	case 2:
   2345  1.13      soda 		dy = inb(kbd_datap);
   2346   1.1  jonathan 		dy = (dy == -128) ? -127 : dy;
   2347   1.1  jonathan 		state = 0;
   2348   1.1  jonathan 
   2349   1.1  jonathan 		buttons = ((buttons & PS2LBUTMASK) << 2) |
   2350   1.1  jonathan 			  ((buttons & (PS2RBUTMASK | PS2MBUTMASK)) >> 1);
   2351   1.1  jonathan 		changed = ((buttons ^ sc->sc_status) & BUTSTATMASK) << 3;
   2352   1.1  jonathan 		sc->sc_status = buttons | (sc->sc_status & ~BUTSTATMASK) | changed;
   2353   1.1  jonathan 
   2354   1.1  jonathan 		if (dx || dy || changed) {
   2355   1.1  jonathan 			/* Update accumulated movements. */
   2356   1.1  jonathan 			sc->sc_x += dx;
   2357   1.1  jonathan 			sc->sc_y += dy;
   2358   1.1  jonathan 
   2359   1.1  jonathan 			/* Add this event to the queue. */
   2360  1.13      soda 			buffer[0] = 0x80 | (buttons & BUTSTATMASK);
   2361   1.1  jonathan 			if(dx < 0)
   2362   1.1  jonathan 				buffer[0] |= 0x10;
   2363   1.1  jonathan 			buffer[1] = dx & 0x7f;
   2364   1.1  jonathan 			if(dy < 0)
   2365   1.1  jonathan 				buffer[0] |= 0x20;
   2366   1.1  jonathan 			buffer[2] = dy & 0x7f;
   2367   1.1  jonathan 			buffer[3] = buffer[4] = 0;
   2368   1.1  jonathan 			(void) b_to_q(buffer, sizeof buffer, &sc->sc_q);
   2369   1.1  jonathan 
   2370   1.1  jonathan 			if (sc->sc_state & PMS_ASLP) {
   2371   1.1  jonathan 				sc->sc_state &= ~PMS_ASLP;
   2372   1.1  jonathan 				wakeup((caddr_t)sc);
   2373   1.1  jonathan 			}
   2374   1.1  jonathan 			selwakeup(&sc->sc_rsel);
   2375   1.1  jonathan 		}
   2376   1.1  jonathan 
   2377   1.1  jonathan 		break;
   2378   1.1  jonathan 	}
   2379   1.1  jonathan 	return -1;
   2380   1.1  jonathan }
   2381   1.1  jonathan 
   2382   1.1  jonathan int
   2383  1.13      soda opmspoll(dev, events, p)
   2384   1.1  jonathan 	dev_t dev;
   2385   1.8  jonathan 	int events;
   2386   1.1  jonathan 	struct proc *p;
   2387   1.1  jonathan {
   2388  1.13      soda 	struct opms_softc *sc = opms_cd.cd_devs[PMSUNIT(dev)];
   2389   1.8  jonathan 	int revents = 0;
   2390   1.8  jonathan 	int s = spltty();
   2391   1.1  jonathan 
   2392  1.19      soda 	if (events & (POLLIN | POLLRDNORM)) {
   2393   1.8  jonathan 		if (sc->sc_q.c_cc > 0)
   2394   1.8  jonathan 			revents |= events & (POLLIN | POLLRDNORM);
   2395   1.8  jonathan 		else
   2396   1.8  jonathan 			selrecord(p, &sc->sc_rsel);
   2397  1.19      soda 	}
   2398   1.1  jonathan 
   2399   1.1  jonathan 	splx(s);
   2400   1.8  jonathan 	return (revents);
   2401   1.1  jonathan }
   2402  1.20      soda 
   2403  1.20      soda #endif /* NOPMS > 0 */
   2404