Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
		
			
				
	
	
		
			248 lines
		
	
	
	
		
			5 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			248 lines
		
	
	
	
		
			5 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
#include <linux/keyboard.h>
 | 
						|
 | 
						|
#include "defkeymap.c"	/* yeah I know it's bad -- Cort */
 | 
						|
 | 
						|
 | 
						|
unsigned char shfts, ctls, alts, caps;
 | 
						|
 | 
						|
#define	KBDATAP		0x60	/* kbd data port */
 | 
						|
#define	KBSTATUSPORT	0x61	/* kbd status */
 | 
						|
#define	KBSTATP		0x64	/* kbd status port */
 | 
						|
#define	KBINRDY		0x01
 | 
						|
#define	KBOUTRDY	0x02
 | 
						|
 | 
						|
extern unsigned char inb(int port);
 | 
						|
extern void outb(int port, char val);
 | 
						|
extern void puts(const char *);
 | 
						|
extern void puthex(unsigned long val);
 | 
						|
extern void udelay(long x);
 | 
						|
 | 
						|
static int kbd(int noblock)
 | 
						|
{
 | 
						|
	unsigned char dt, brk, val;
 | 
						|
	unsigned code;
 | 
						|
loop:
 | 
						|
	if (noblock) {
 | 
						|
	    if ((inb(KBSTATP) & KBINRDY) == 0)
 | 
						|
		return (-1);
 | 
						|
	} else while((inb(KBSTATP) & KBINRDY) == 0) ;
 | 
						|
 | 
						|
	dt = inb(KBDATAP);
 | 
						|
 | 
						|
	brk = dt & 0x80;	/* brk == 1 on key release */
 | 
						|
	dt = dt & 0x7f;		/* keycode */
 | 
						|
 | 
						|
	if (shfts)
 | 
						|
	    code = shift_map[dt];
 | 
						|
	else if (ctls)
 | 
						|
	    code = ctrl_map[dt];
 | 
						|
	else
 | 
						|
	    code = plain_map[dt];
 | 
						|
 | 
						|
	val = KVAL(code);
 | 
						|
	switch (KTYP(code) & 0x0f) {
 | 
						|
	    case KT_LATIN:
 | 
						|
		if (brk)
 | 
						|
		    break;
 | 
						|
		if (alts)
 | 
						|
		    val |= 0x80;
 | 
						|
		if (val == 0x7f)	/* map delete to backspace */
 | 
						|
		    val = '\b';
 | 
						|
		return val;
 | 
						|
 | 
						|
	    case KT_LETTER:
 | 
						|
		if (brk)
 | 
						|
		    break;
 | 
						|
		if (caps)
 | 
						|
		    val -= 'a'-'A';
 | 
						|
		return val;
 | 
						|
 | 
						|
	    case KT_SPEC:
 | 
						|
		if (brk)
 | 
						|
		    break;
 | 
						|
		if (val == KVAL(K_CAPS))
 | 
						|
		    caps = !caps;
 | 
						|
		else if (val == KVAL(K_ENTER)) {
 | 
						|
enter:		    /* Wait for key up */
 | 
						|
		    while (1) {
 | 
						|
			while((inb(KBSTATP) & KBINRDY) == 0) ;
 | 
						|
			dt = inb(KBDATAP);
 | 
						|
			if (dt & 0x80) /* key up */ break;
 | 
						|
		    }
 | 
						|
		    return 10;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	    case KT_PAD:
 | 
						|
		if (brk)
 | 
						|
		    break;
 | 
						|
		if (val < 10)
 | 
						|
		    return val;
 | 
						|
		if (val == KVAL(K_PENTER))
 | 
						|
		    goto enter;
 | 
						|
		break;
 | 
						|
 | 
						|
	    case KT_SHIFT:
 | 
						|
		switch (val) {
 | 
						|
		    case KG_SHIFT:
 | 
						|
		    case KG_SHIFTL:
 | 
						|
		    case KG_SHIFTR:
 | 
						|
			shfts = brk ? 0 : 1;
 | 
						|
			break;
 | 
						|
		    case KG_ALT:
 | 
						|
		    case KG_ALTGR:
 | 
						|
			alts = brk ? 0 : 1;
 | 
						|
			break;
 | 
						|
		    case KG_CTRL:
 | 
						|
		    case KG_CTRLL:
 | 
						|
		    case KG_CTRLR:
 | 
						|
			ctls = brk ? 0 : 1;
 | 
						|
			break;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
 | 
						|
	    case KT_LOCK:
 | 
						|
		switch (val) {
 | 
						|
		    case KG_SHIFT:
 | 
						|
		    case KG_SHIFTL:
 | 
						|
		    case KG_SHIFTR:
 | 
						|
			if (brk)
 | 
						|
			    shfts = !shfts;
 | 
						|
			break;
 | 
						|
		    case KG_ALT:
 | 
						|
		    case KG_ALTGR:
 | 
						|
			if (brk)
 | 
						|
			    alts = !alts;
 | 
						|
			break;
 | 
						|
		    case KG_CTRL:
 | 
						|
		    case KG_CTRLL:
 | 
						|
		    case KG_CTRLR:
 | 
						|
			if (brk)
 | 
						|
			    ctls = !ctls;
 | 
						|
			break;
 | 
						|
		}
 | 
						|
		break;
 | 
						|
	}
 | 
						|
	if (brk) return (-1);  /* Ignore initial 'key up' codes */
 | 
						|
	goto loop;
 | 
						|
}
 | 
						|
 | 
						|
static int __kbdreset(void)
 | 
						|
{
 | 
						|
	unsigned char c;
 | 
						|
	int i, t;
 | 
						|
 | 
						|
	/* flush input queue */
 | 
						|
	t = 2000;
 | 
						|
	while ((inb(KBSTATP) & KBINRDY))
 | 
						|
	{
 | 
						|
		(void)inb(KBDATAP);
 | 
						|
		if (--t == 0)
 | 
						|
			return 1;
 | 
						|
	}
 | 
						|
	/* Send self-test */
 | 
						|
	t = 20000;
 | 
						|
	while (inb(KBSTATP) & KBOUTRDY)
 | 
						|
		if (--t == 0)
 | 
						|
			return 2;
 | 
						|
	outb(KBSTATP,0xAA);
 | 
						|
	t = 200000;
 | 
						|
	while ((inb(KBSTATP) & KBINRDY) == 0)	/* wait input ready */
 | 
						|
		if (--t == 0)
 | 
						|
			return 3;
 | 
						|
	if ((c = inb(KBDATAP)) != 0x55)
 | 
						|
	{
 | 
						|
		puts("Keyboard self test failed - result:");
 | 
						|
		puthex(c);
 | 
						|
		puts("\n");
 | 
						|
	}
 | 
						|
	/* Enable interrupts and keyboard controller */
 | 
						|
	t = 20000;
 | 
						|
	while (inb(KBSTATP) & KBOUTRDY)
 | 
						|
		if (--t == 0) return 4;
 | 
						|
	outb(KBSTATP,0x60);
 | 
						|
	t = 20000;
 | 
						|
	while (inb(KBSTATP) & KBOUTRDY)
 | 
						|
		if (--t == 0) return 5;
 | 
						|
	outb(KBDATAP,0x45);
 | 
						|
	for (i = 0;  i < 10000;  i++) udelay(1);
 | 
						|
 | 
						|
	t = 20000;
 | 
						|
	while (inb(KBSTATP) & KBOUTRDY)
 | 
						|
		if (--t == 0) return 6;
 | 
						|
	outb(KBSTATP,0x20);
 | 
						|
	t = 200000;
 | 
						|
	while ((inb(KBSTATP) & KBINRDY) == 0)	/* wait input ready */
 | 
						|
		if (--t == 0) return 7;
 | 
						|
	if (! (inb(KBDATAP) & 0x40)) {
 | 
						|
		/*
 | 
						|
		 * Quote from PS/2 System Reference Manual:
 | 
						|
		 *
 | 
						|
		 * "Address hex 0060 and address hex 0064 should be
 | 
						|
		 * written only when the input-buffer-full bit and
 | 
						|
		 * output-buffer-full bit in the Controller Status
 | 
						|
		 * register are set 0." (KBINRDY and KBOUTRDY)
 | 
						|
		 */
 | 
						|
		t = 200000;
 | 
						|
		while (inb(KBSTATP) & (KBINRDY | KBOUTRDY))
 | 
						|
			if (--t == 0) return 8;
 | 
						|
		outb(KBDATAP,0xF0);
 | 
						|
		t = 200000;
 | 
						|
		while (inb(KBSTATP) & (KBINRDY | KBOUTRDY))
 | 
						|
			if (--t == 0) return 9;
 | 
						|
		outb(KBDATAP,0x01);
 | 
						|
	}
 | 
						|
	t = 20000;
 | 
						|
	while (inb(KBSTATP) & KBOUTRDY)
 | 
						|
		if (--t == 0) return 10;
 | 
						|
	outb(KBSTATP,0xAE);
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
static void kbdreset(void)
 | 
						|
{
 | 
						|
	int ret = __kbdreset();
 | 
						|
 | 
						|
	if (ret) {
 | 
						|
		puts("__kbdreset failed: ");
 | 
						|
		puthex(ret);
 | 
						|
		puts("\n");
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/* We have to actually read the keyboard when CRT_tstc is called,
 | 
						|
 * since the pending data might be a key release code, and therefore
 | 
						|
 * not valid data.  In this case, kbd() will return -1, even though there's
 | 
						|
 * data to be read.  Of course, we might actually read a valid key press,
 | 
						|
 * in which case it gets queued into key_pending for use by CRT_getc.
 | 
						|
 */
 | 
						|
 | 
						|
static int kbd_reset = 0;
 | 
						|
 | 
						|
static int key_pending = -1;
 | 
						|
 | 
						|
int CRT_getc(void)
 | 
						|
{
 | 
						|
	int c;
 | 
						|
	if (!kbd_reset) {kbdreset(); kbd_reset++; }
 | 
						|
 | 
						|
        if (key_pending != -1) {
 | 
						|
                c = key_pending;
 | 
						|
                key_pending = -1;
 | 
						|
                return c;
 | 
						|
        } else {
 | 
						|
	while ((c = kbd(0)) == 0) ;
 | 
						|
                return c;
 | 
						|
        }
 | 
						|
}
 | 
						|
 | 
						|
int CRT_tstc(void)
 | 
						|
{
 | 
						|
	if (!kbd_reset) {kbdreset(); kbd_reset++; }
 | 
						|
 | 
						|
        while (key_pending == -1 && ((inb(KBSTATP) & KBINRDY) != 0)) {
 | 
						|
                key_pending = kbd(1);
 | 
						|
        }
 | 
						|
 | 
						|
        return (key_pending != -1);
 | 
						|
}
 |