示例#1
0
static int init_kbd(unsigned ss, unsigned typematic, unsigned xlat)
{
	while(read_kbd() != -1)
		/* nothing */;
/* disable keyboard before programming it */
	write_kbd_await_ack(0xF5);
/* disable PS/2 mouse, set SYS bit, and Enable Keyboard Interrupt... */
	write_kbd(0x64, 0x60);
/*jach: enable mouse */
	//write_kbd(0x64, 0xA8);
/* ...and either disable or enable AT-to-XT keystroke conversion */
	write_kbd(0x60, xlat ? 0x65 : 0x25);
/* program desired scancode set */
	write_kbd_await_ack(0xF0);
	write_kbd_await_ack(ss);
/* we want all keys to return both a make code (when pressed)
and a break code (when released -- scancode set 3 only) */
	if(ss == 3)
	{
		write_kbd_await_ack(0xFA);
	}
/* set typematic delay and rate */
	write_kbd_await_ack(0xF3);
	write_kbd_await_ack(typematic);
/* enable keyboard */
	write_kbd_await_ack(0xF4);
	return 0;
}
示例#2
0
/********************************************************
 This identifies the current keyboard as being MF II, then checks the
 current scancode set and changes it to set 2 if it is not currently set 2.

 NOTE: work on keyboard driver so that it doesn't require cli/sti, but
 just mutexes.
********************************************************/
void setup_keyboard()
{
	volatile u_short *keyboard_isr_fired;

	// first, find out what kinda keyboard we have here
	k_printf("Detecting type of keyboard...\n");

	switch(kbd_get_id())
	{
		case 0:
			k_printf("Unknown keyboard... Ripple has halted.\n");
			asm("cli");
			asm("hlt");
		case 1:
			k_printf("AT keyboard found, Ripple requires a newer keyboard... Ripple has halted.\n");
			asm("cli");
			asm("hlt");
		case 2:
			k_printf("MF II keyboard detected.\n");
			break;
		default:
			k_printf("No keyboard found, Ripple requires a keyboard... Ripple has halted.\n");
			asm("cli");
			asm("hlt");
	};

	asm("cli");

	// setup scancode set 2
	kbd_set_scancode_set(2);
	k_printf("Scancode set is: %d\n", kbd_curr_scancode_set());

	// disable "IBM PC compatibility mode"(no converting scancode sets to set 1)
	write_kbd(0x64, 0x60);
	write_kbd(0x60, 0x07);

	k_printf("\nWatching IRQ 1... \n");
	keyboard_isr_fired = watch_irq(1, 0x12984C00);
	if(keyboard_isr_fired != 0)
	{
		*keyboard_isr_fired = 0;
		k_printf("success, IRQ has been allocated.\n");
		asm("sti");
		for(;;)
		{
			//putc('x');
			if(*keyboard_isr_fired >= 1)
			{
				k_printf("%x\n", inportb(0x60));
				*keyboard_isr_fired -= 1;
			};
		};
	} else
	{
		asm("sti");
		k_printf("failure\n");
		return;
	};
};
示例#3
0
static int write_kbd_await_ack(unsigned val)
{
	int got;

	write_kbd(0x60, val);
	got = read_kbd();
	if(got != 0xFA)
	{
		
		return -1;
	}
	return 0;
};
示例#4
0
// 1 = succes
u_char write_kbd_await_ack(u_char val)
{
	u_char got;

	write_kbd(0x60, val);
	got = read_kbd();
	if(got != 0xFA)
	{
		k_printf("write_kbd_await_ack: expected acknowledge (0xFA), got 0x%x\n", got);
		return 0;
	};
	return 1;
};
示例#5
0
static int
set_typematic(keyboard_t *kbd)
{
	int val, error;
	atkbd_state_t *state = kbd->kb_data;

	val = typematic(DEFAULT_DELAY, DEFAULT_RATE);
	error = write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, val);
	if (error == 0) {
		kbd->kb_delay1 = typematic_delay(val);
		kbd->kb_delay2 = typematic_rate(val);
	}

	return (error);
}
示例#6
0
/* some useful control functions */
static int
atkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
{
    /* translate LED_XXX bits into the device specific bits */
    static u_char ledmap[8] = {
        0, 4, 2, 6, 1, 5, 3, 7,
    };
    atkbd_state_t *state = kbd->kb_data;
    int error;
    int s;
    int i;
#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
    int ival;
#endif

    s = spltty();
    switch (cmd) {

    case KDGKBMODE:		/* get keyboard mode */
        *(int *)arg = state->ks_mode;
        break;
#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
    case _IO('K', 7):
        ival = IOCPARM_IVAL(arg);
        arg = (caddr_t)&ival;
        /* FALLTHROUGH */
#endif
    case KDSKBMODE:		/* set keyboard mode */
        switch (*(int *)arg) {
        case K_XLATE:
            if (state->ks_mode != K_XLATE) {
                /* make lock key state and LED state match */
                state->ks_state &= ~LOCK_MASK;
                state->ks_state |= KBD_LED_VAL(kbd);
            }
        /* FALLTHROUGH */
        case K_RAW:
        case K_CODE:
            if (state->ks_mode != *(int *)arg) {
                atkbd_clear_state(kbd);
                state->ks_mode = *(int *)arg;
            }
            break;
        default:
            splx(s);
            return EINVAL;
        }
        break;

    case KDGETLED:		/* get keyboard LED */
        *(int *)arg = KBD_LED_VAL(kbd);
        break;
#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
    case _IO('K', 66):
        ival = IOCPARM_IVAL(arg);
        arg = (caddr_t)&ival;
        /* FALLTHROUGH */
#endif
    case KDSETLED:		/* set keyboard LED */
        /* NOTE: lock key state in ks_state won't be changed */
        if (*(int *)arg & ~LOCK_MASK) {
            splx(s);
            return EINVAL;
        }
        i = *(int *)arg;
        /* replace CAPS LED with ALTGR LED for ALTGR keyboards */
        if (state->ks_mode == K_XLATE &&
                kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
            if (i & ALKED)
                i |= CLKED;
            else
                i &= ~CLKED;
        }
        if (KBD_HAS_DEVICE(kbd)) {
            error = write_kbd(state->kbdc, KBDC_SET_LEDS,
                              ledmap[i & LED_MASK]);
            if (error) {
                splx(s);
                return error;
            }
        }
        KBD_LED_VAL(kbd) = *(int *)arg;
        break;

    case KDGKBSTATE:	/* get lock key state */
        *(int *)arg = state->ks_state & LOCK_MASK;
        break;
#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
    case _IO('K', 20):
        ival = IOCPARM_IVAL(arg);
        arg = (caddr_t)&ival;
        /* FALLTHROUGH */
#endif
    case KDSKBSTATE:	/* set lock key state */
        if (*(int *)arg & ~LOCK_MASK) {
            splx(s);
            return EINVAL;
        }
        state->ks_state &= ~LOCK_MASK;
        state->ks_state |= *(int *)arg;
        splx(s);
        /* set LEDs and quit */
        return atkbd_ioctl(kbd, KDSETLED, arg);

    case KDSETREPEAT:	/* set keyboard repeat rate (new interface) */
        splx(s);
        if (!KBD_HAS_DEVICE(kbd))
            return 0;
        i = typematic(((int *)arg)[0], ((int *)arg)[1]);
        error = write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, i);
        if (error == 0) {
            kbd->kb_delay1 = typematic_delay(i);
            kbd->kb_delay2 = typematic_rate(i);
        }
        return error;

#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
    defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
    case _IO('K', 67):
        ival = IOCPARM_IVAL(arg);
        arg = (caddr_t)&ival;
        /* FALLTHROUGH */
#endif
    case KDSETRAD:		/* set keyboard repeat rate (old interface) */
        splx(s);
        if (!KBD_HAS_DEVICE(kbd))
            return 0;
        error = write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, *(int *)arg);
        if (error == 0) {
            kbd->kb_delay1 = typematic_delay(*(int *)arg);
            kbd->kb_delay2 = typematic_rate(*(int *)arg);
        }
        return error;

    case PIO_KEYMAP:	/* set keyboard translation table */
    case PIO_KEYMAPENT:	/* set keyboard translation table entry */
    case PIO_DEADKEYMAP:	/* set accent key translation table */
        state->ks_accents = 0;
    /* FALLTHROUGH */
    default:
        splx(s);
        return genkbd_commonioctl(kbd, cmd, arg);
    }

    splx(s);
    return 0;
}
示例#7
0
void settogglebits(unsigned char b)
{
    write_kbd(0x60,0xED);
    write_kbd(0x60,b);
;};
示例#8
0
static int set1_scancode_to_ascii(unsigned code)
{
	static const unsigned char map[] =
	{
/* 00 */0,	0x1B,	'1',	'2',	'3',	'4',	'5',	'6',
/* 08 */'7',	'8',	'9',	'0',	'-',	'=',	'\b',	'\t',
/* 10 */'q',	'w',	'e',	'r',	't',	'y',	'u',	'i',
/* 1Dh is left Ctrl */
/* 18 */'o',	'p',	'[',	']',	'\n',	0,	'a',	's',
/* 20 */'d',	'f',	'g',	'h',	'j',	'k',	'l',	';',
/* 2Ah is left Shift */
/* 28 */'\'',	'`',	0,	'\\',	'z',	'x',	'c',	'v',
/* 36h is right Shift */
/* 30 */'b',	'n',	'm',	',',	'.',	'/',	0,	0,
/* 38h is left Alt, 3Ah is Caps Lock */
/* 38 */0,	' ',	0,	KEY_F1,	KEY_F2,	KEY_F3,	KEY_F4,	KEY_F5,
/* 45h is Num Lock, 46h is Scroll Lock */
/* 40 */KEY_F6,	KEY_F7,	KEY_F8,	KEY_F9,	KEY_F10,0,	0,	KEY_HOME,
/* 48 */KEY_UP,	KEY_PGUP,'-',	KEY_LFT,'5',	KEY_RT,	'+',	KEY_END,
/* 50 */KEY_DN,	KEY_PGDN,KEY_INS,KEY_DEL,0,	0,	0,	KEY_F11,
/* 58 */KEY_F12
	};
	static const unsigned char shift_map[] =
	{
/* 00 */0,	0x1B,	'!',	'@',	'#',	'$',	'%',	'^',
/* 08 */'&',	'*',	'(',	')',	'_',	'+',	'\b',	'\t',
/* 10 */'Q',	'W',	'E',	'R',	'T',	'Y',	'U',	'I',
/* 1Dh is left Ctrl */
/* 18 */'O',	'P',	'{',	'}',	'\n',	0,	'A',	'S',
/* 20 */'D',	'F',	'G',	'H',	'J',	'K',	'L',	':',
/* 2Ah is left Shift */
/* 28 */'"',	'~',	0,	'|',	'Z',	'X',	'C',	'V',
/* 36h is right Shift */
/* 30 */'B',	'N',	'M',	'<',	'>',	'?',	0,	0,
/* 38h is left Alt, 3Ah is Caps Lock */
/* 38 */0,	' ',	0,	KEY_F1,	KEY_F2,	KEY_F3,	KEY_F4,	KEY_F5,
/* 45h is Num Lock, 46h is Scroll Lock */
/* 40 */KEY_F6,	KEY_F7,	KEY_F8,	KEY_F9,	KEY_F10,0,	0,	KEY_HOME,
/* 48 */KEY_UP,	KEY_PGUP,'-',	KEY_LFT,'5',	KEY_RT,	'+',	KEY_END,
/* 50 */KEY_DN,	KEY_PGDN,KEY_INS,KEY_DEL,0,	0,	0,	KEY_F11,
/* 58 */KEY_F12
	};
	static unsigned saw_break_code;
/**/
	unsigned temp;

/* check for break code (i.e. a key is released) */
	if(code >= 0x80)
	{
		saw_break_code = 1;
		code &= 0x7F;
	}
/* the only break codes we're interested in are Shift, Ctrl, Alt */
	if(saw_break_code)
	{
		if(code == RAW1_LEFT_ALT || code == RAW1_RIGHT_ALT)
			kbd_status &= ~KBD_META_ALT;
		else if(code == RAW1_LEFT_CTRL || code == RAW1_RIGHT_CTRL)
			kbd_status &= ~KBD_META_CTRL;
		else if(code == RAW1_LEFT_SHIFT || code == RAW1_RIGHT_SHIFT)
			kbd_status &= ~KBD_META_SHIFT;
		saw_break_code = 0;
		return -1;
	}

/* it's a make code: check the "meta" keys, as above */
	if(code == RAW1_LEFT_ALT || code == RAW1_RIGHT_ALT)
	{
		kbd_status |= KBD_META_ALT;
		return -1;
	}
	if(code == RAW1_LEFT_CTRL || code == RAW1_RIGHT_CTRL)
	{
		kbd_status |= KBD_META_CTRL;
		return -1;
	}
	if(code == RAW1_LEFT_SHIFT || code == RAW1_RIGHT_SHIFT)
	{
		kbd_status |= KBD_META_SHIFT;
		return -1;
	}


/* Scroll Lock, Num Lock, and Caps Lock set the LEDs. These keys
have on-off (toggle or XOR) action, instead of momentary action */
	if(code == RAW1_SCROLL_LOCK)
	{
		kbd_status ^= KBD_META_SCRL;
		goto LEDS;
	}
	if(code == RAW1_NUM_LOCK)
	{
		kbd_status ^= KBD_META_NUM;
		goto LEDS;
	}
	if(code == RAW1_CAPS_LOCK)
	{
		kbd_status ^= KBD_META_CAPS;
LEDS:		write_kbd(0x60, 0xED);	/* "set LEDs" command */
		temp = 0;
		if(kbd_status & KBD_META_SCRL)
			temp |= 1;
		if(kbd_status & KBD_META_NUM)
			temp |= 2;
		if(kbd_status & KBD_META_CAPS)
			temp |= 4;
		write_kbd(0x60, temp);	/* bottom 3 bits set LEDs */
		return -1;
	};
	    
	
    if ( (kbd_status & KBD_META_ALT) && (kbd_status & KBD_META_CTRL))
        {
      		if(code >= sizeof(shift_map) / sizeof(shift_map[0]))
			return -1;
   		    temp = shift_map[code];
   		    if (temp == KEY_DEL) return SOFT_RESET;
   		    return temp+400;
        };	
	
	
	/*if(kbd_status & KBD_META_ALT)
		return code+300;*/

/* convert A-Z[\]^_ to control chars */
	if(kbd_status & KBD_META_CTRL)
	{
		if(code >= sizeof(map) / sizeof(map[0]))
			return -1;
		temp = map[code];
		if(temp >= 'a' && temp <= 'z')
			return temp - 'a';
		if(temp >= '[' && temp <= '_')
			return temp - '[' + 0x1B;
		return -1;
	}
/* convert raw scancode to ASCII */
	if(kbd_status & KBD_META_SHIFT)
	{
/* ignore invalid scan codes */
		if(code >= sizeof(shift_map) / sizeof(shift_map[0]))
			return -1;
		temp = shift_map[code];
/* defective keyboard? non-US keyboard? more than 104 keys? */
		if(temp == 0)
			return -1;
/* caps lock? */
		if(kbd_status & KBD_META_CAPS)
		{
			if(temp >= 'A' && temp <= 'Z')
				temp = map[code];
		}
	}
	else
	{
		if(code >= sizeof(map) / sizeof(map[0]))
			return -1;
		temp = map[code];
		if(temp == 0)
			return -1;
		if(kbd_status & KBD_META_CAPS)
		{
			if(temp >= 'a' && temp <= 'z')
				temp = shift_map[code];
		}
	}
	return temp;
};
示例#9
0
// returns current scancode set, or 0 upon failer
u_char kbd_curr_scancode_set()
{
	write_kbd_await_ack(0xF0);
	write_kbd(0x60, 0);
	return(read_kbd());	// return scancode set
};