⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ps2_kbd.c

📁 umon bootloader source code, support mips cpu.
💻 C
📖 第 1 页 / 共 2 页
字号:
	return 0;
}
	
//--------------------------------------------------------------------------
// wait_ps2_kbd_obf_set()
//
// This routine waits until the Output Buffer Flag is Set,
// or time's out
vulong wait_ps2_kbd_obf_set()
{
	int timeout;

	// check the results
    timeout = PS2_TIMEOUT;
	while(timeout){
		// delay before each check
		monDelay(1);
		if (PS2_REG(PS2_STAT) & PS2_STAT_OBF) break;
   		timeout--;
    }
	if (timeout == 0){
		ps2_kbd_ok = 0;
        printf("PS2 Wait for Output Buffer Flag Set Timed Out - Controller Failure?\n");
		return -1;	
	}
	return 0;
}
	
//--------------------------------------------------------------------------
// ps2_gotachar()
//
// This routine will retreive a character from the PS/2 keyboard.  We
// have to do a scan code conversion to see if we have a returnable
// character, thus removing it from the ps/2 controller.  This routine
// will save the converted value, if valid, in ps2_char for retrieval
// by ps2_getchar.
//
vulong ps2_gotachar()
{
	vuchar sc, c;

	// make sure we even have a keyboard
	if(ps2_kbd_ok == 0) return 0;

	// return true immediately if we still have a
	// character that has not been read
	if(ps2_char_ok == 1) return 1;

	// get a scan code
	sc = ps2_scan();
	if(sc){
		// make sure we have a valid code
		// if not we just ignore it
		if (sc <= LAST_SCAN_CODE) {

			// check the state of caps, ctl and shift to get the
			// right array
			if (ps2_ctl_flag) {
				c = ps2_scan_code[sc][3];
			}
			else if(ps2_shift_flag) {
				c = ps2_scan_code[sc][1];
			}
			else if(ps2_led_flag & PS2_KBD_CMD_LED_CAPS){
				c = ps2_scan_code[sc][2];
			}
			else {
				c = ps2_scan_code[sc][0];
			}
			// see if we have a valid ascii lookup	
			if(c != 0xff) {	
				ps2_char = c; 
				ps2_char_ok = 1;
				return 1;
			}
		} // if sc <= LAST_SCAN_CODE
	} // if sc
	return 0;
}	

//--------------------------------------------------------------------------
// ps2_getchar()
//
// This routine returns ps2_char
//
vuchar ps2_getchar()
{
	if((ps2_kbd_ok) && (ps2_char_ok)) {
		ps2_char_ok = 0;
		return ps2_char;
	}
	return 0;
}

//--------------------------------------------------------------------------
// ps2_scan()
//
// This routine will return a scan code from the keyboard if there is
// one.  If not, or if it is a control key, it will return 0.  For control
// keys it will update the global flags so the calling routine can
// interpret the next non-control key appropriately. 
//
vuchar ps2_scan()
{
	vuchar c;

	if(PS2_REG(PS2_STAT) & PS2_STAT_OBF){
		c = PS2_REG(PS2_DATA);
		// if it is a break, we still process it to handle de-assertion of shift, alt, etc,
		if(c & 0x80) ps2_break_c = 1;
		// strip the break bit
		c = c & 0x7f;
		switch (c){
			case KEY_EXT0 :
			case KEY_EXT1 :
				break;
			// set the flags for shift, ctl and alt when the key
			// is pressed, clear when the key is released
			case KEY_R_SHIFT :
			case KEY_L_SHIFT : 
				if(ps2_break_c == 0) ps2_shift_flag = 1;
				else{ ps2_shift_flag = 0; ps2_break_c = 0; }
				break;
			case KEY_ALT : 
				if(ps2_break_c == 0) ps2_alt_flag = 1;
				else { ps2_alt_flag = 0; ps2_break_c = 0; }
				break;
			case KEY_CTL : 
				if(ps2_break_c == 0) ps2_ctl_flag = 1;
				else { ps2_ctl_flag = 0; ps2_break_c = 0; }
				break;
			// update led_flag when CAPS, NUM or Scroll lock are pressed,
			// maintain state when they are released.
			case KEY_CAPS :
				if(ps2_break_c == 0) ps2_led_flag = ps2_led_flag ^ PS2_KBD_CMD_LED_CAPS;
				else ps2_break_c = 0;
				// update the LED's
				if (wait_ps2_kbd_ibf_clr()) return 0;
			    PS2_REG(PS2_DATA) = PS2_KBD_CMD_LED;
				if (wait_ps2_kbd_ibf_clr()) return 0;
			    PS2_REG(PS2_DATA) = ps2_led_flag & 0x07;
				ps2_kbd_obf_flush();
				break;
			case KEY_NUM_LK : 
				if(ps2_break_c == 0) ps2_led_flag = ps2_led_flag ^ PS2_KBD_CMD_LED_NUM;
				else ps2_break_c = 0;
				// update the LED's
				if (wait_ps2_kbd_ibf_clr()) return 0;
			    PS2_REG(PS2_DATA) = PS2_KBD_CMD_LED;
				if (wait_ps2_kbd_ibf_clr()) return 0;
			    PS2_REG(PS2_DATA) = ps2_led_flag & 0x07;
				ps2_kbd_obf_flush();
				break;
			case KEY_SCROLL_LK : 
				if(ps2_break_c == 0) ps2_led_flag = ps2_led_flag ^ PS2_KBD_CMD_LED_SCROLL;
				else ps2_break_c = 0;
				// update the LED's
				if (wait_ps2_kbd_ibf_clr()) return 0;
			    PS2_REG(PS2_DATA) = PS2_KBD_CMD_LED;
				if (wait_ps2_kbd_ibf_clr()) return 0;
			    PS2_REG(PS2_DATA) = ps2_led_flag & 0x07;
				ps2_kbd_obf_flush();
				break;
			default : 
//				printf("c = 0x%02x\n", c);
				if(ps2_break_c == 0) return c;
				else { ps2_break_c = 0; break; }
		} // switch
	} // if	PS2_STAT
	return 0;
}

//--------------------------------------------------------------------------
// ps2_tst()
//
// This routine will display an ascii string corresponding to the 
// received scan code.  The END key will end the test.
//
char *ps2Help[] = {
	"PS/2 compatible port test",
	"",
	"Notes:",
	" * For each keypress (except control keys), this test will display",
	"   an ascii string describing the scan code.  If the scan code is",
	"   not recognized the hex value of the scan code will be displayed",
	"   instead.",
	" * Pressing the END Key terminates the test.  It also updates the",
	"   LEDs when CAPS, Num Lock or Scroll Lock are pressed.",
	(char *)0,
};

int ps2_tst()
{
	vuchar c, sc;

	ps2_kbd_init();

	if (ps2_kbd_ok == 0){
		printf("PS/2 Keyboard Init Failed.\n");
		return 0;
	}
	printf("Keyboard Detected - Turning LEDs off.\n");

	// Flush the Output buffer
	ps2_kbd_obf_flush();	

	// Blink the LED's
	if (wait_ps2_kbd_ibf_clr()) return 0;
    PS2_REG(PS2_DATA) = PS2_KBD_CMD_LED;
	if (wait_ps2_kbd_ibf_clr()) return 0;
    PS2_REG(PS2_DATA) = 0x00;

	monDelay(100);

	printf("Turning LEDs on.\n");
	ps2_kbd_obf_flush();	
	if (wait_ps2_kbd_ibf_clr()) return 0;
    PS2_REG(PS2_DATA) = PS2_KBD_CMD_LED;
	if (wait_ps2_kbd_ibf_clr()) return 0;
    PS2_REG(PS2_DATA) = PS2_KBD_CMD_LED_SCROLL |
    					PS2_KBD_CMD_LED_NUM |
    					PS2_KBD_CMD_LED_CAPS;

	monDelay(100);

	printf("Turning LEDs off.\n");
	ps2_kbd_obf_flush();	
	if (wait_ps2_kbd_ibf_clr()) return 0;
    PS2_REG(PS2_DATA) = PS2_KBD_CMD_LED;
	if (wait_ps2_kbd_ibf_clr()) return 0;
    PS2_REG(PS2_DATA) = 0x00;

	if (wait_ps2_kbd_ibf_clr()) return 0;
	ps2_kbd_obf_flush();
		
	ps2_shift_flag = 0;
	ps2_alt_flag = 0;
	ps2_ctl_flag = 0;
	ps2_led_flag = 0;

	printf("Entering Scan Code Display Loop.  Press END key to terminate.\n");
	// loop until the END key or an error (which will clear ps2_kbd_ok)      
	while(ps2_kbd_ok == 1){
		sc = ps2_scan();
		if(sc){
			// make sure we have a valid code
			// if not we just ignore it
			if (sc <= LAST_SCAN_CODE) {

				printf("Raw Keypress = 0x%02x, ", sc);
				printf("Converted Keypress = ");

				// print a leading CTL- or ALT- based on the flags
				if(ps2_ctl_flag) printf("CTL-");
				if(ps2_alt_flag) printf("ALT-");

				// check the state of caps and shift to get the
				// right array
				if(ps2_shift_flag) {
					c = ps2_scan_code[sc][1];
				}
				else if(ps2_led_flag & PS2_KBD_CMD_LED_CAPS){
					c = ps2_scan_code[sc][2];
				}
				else {
					c = ps2_scan_code[sc][0];
				}
				// only print it if it is printable
				if ((c < 0x7f) && (c > 0x1f)) printf("%c\n", c); 
				else printf("\n");
			} // if c <= LAST_SCAN_CODE
		} // if ps2_scan
	 	if(c == KEY_END) break;
	} // while
	return 0; 
}

//--------------------------------------------------------------------------
// End of ps2_kbd.c

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -