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

📄 keyboard.c

📁 MINIX2.0操作系统源码 MINIX2.0操作系统源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		break;
  	case NLOCK:
		if (make && num_off) {
			numlock = 1 - numlock;
			set_leds();
		}
		num_off = 1 - make;
		ch = -1;
		break;
  	case SLOCK:
		if (make & slock_off) {
			slock = 1 - slock;
			set_leds();
		}
		slock_off = 1 - make;
		ch = -1;
		break;
  	case EXTKEY:
		esc = 1;
		return(-1);
  	default:
		if (!make) ch = -1;
  }
  esc = 0;
  return(ch);
}


/*===========================================================================*
 *				set_leds				     *
 *===========================================================================*/
PRIVATE void set_leds()
{
/* Set the LEDs on the caps lock and num lock keys */

  unsigned leds;

  if (!pc_at) return;	/* PC/XT doesn't have LEDs */

  /* encode LED bits */
  leds = (slock << 0) | (numlock << 1) | (capslock << 2);

  kb_wait();			/* wait for buffer empty  */
  out_byte(KEYBD, LED_CODE);	/* prepare keyboard to accept LED values */
  kb_ack();			/* wait for ack response  */

  kb_wait();			/* wait for buffer empty  */
  out_byte(KEYBD, leds);	/* give keyboard LED values */
  kb_ack();			/* wait for ack response  */
}


/*==========================================================================*
 *				kb_wait					    *
 *==========================================================================*/
PRIVATE int kb_wait()
{
/* Wait until the controller is ready; return zero if this times out. */

  int retries;

  retries = MAX_KB_BUSY_RETRIES + 1;
  while (--retries != 0 && in_byte(KB_STATUS) & KB_BUSY)
	;			/* wait until not busy */
  return(retries);		/* nonzero if ready */
}


/*==========================================================================*
 *				kb_ack					    *
 *==========================================================================*/
PRIVATE int kb_ack()
{
/* Wait until kbd acknowledges last command; return zero if this times out. */

  int retries;

  retries = MAX_KB_ACK_RETRIES + 1;
  while (--retries != 0 && in_byte(KEYBD) != KB_ACK)
	;			/* wait for ack */
  return(retries);		/* nonzero if ack received */
}

/*===========================================================================*
 *				kb_init					     *
 *===========================================================================*/
PUBLIC void kb_init(tp)
tty_t *tp;
{
/* Initialize the keyboard driver. */

  register struct kb_s *kb;

  /* Input function. */
  tp->tty_devread = kb_read;

  kb = kb_addr();

  /* Set up input queue. */
  kb->ihead = kb->itail = kb->ibuf;

  /* Set initial values. */
  caps_off = 1;
  num_off = 1;
  slock_off = 1;
  esc = 0;

  set_leds();			/* turn off numlock led */

  scan_keyboard();		/* stop lockup from leftover keystroke */

  put_irq_handler(KEYBOARD_IRQ, kbd_hw_int);	/* set the interrupt handler */
  enable_irq(KEYBOARD_IRQ);	/* safe now everything initialised! */
}


/*===========================================================================*
 *				kbd_loadmap				     *
 *===========================================================================*/
PUBLIC int kbd_loadmap(user_phys)
phys_bytes user_phys;
{
/* Load a new keymap. */

  phys_copy(user_phys, vir2phys(keymap), (phys_bytes) sizeof(keymap));
  return(OK);
}


/*===========================================================================*
 *				func_key				     *
 *===========================================================================*/
PRIVATE int func_key(scode)
int scode;			/* scan code for a function key */
{
/* This procedure traps function keys for debugging and control purposes. */

  unsigned code;

  code = map_key0(scode);			/* first ignore modifiers */
  if (code < F1 || code > F12) return(FALSE);	/* not our job */

  switch (map_key(scode)) {			/* include modifiers */

  case F1:	p_dmp(); break;		/* print process table */
  case F2:	map_dmp(); break;	/* print memory map */
  case F3:	toggle_scroll(); break;	/* hardware vs. software scrolling */

#if ENABLE_NETWORKING
  case F5:	dp_dump(); break;		/* network statistics */
#endif
  case CF7:	sigchar(&tty_table[CONSOLE], SIGQUIT); break;
  case CF8:	sigchar(&tty_table[CONSOLE], SIGINT); break;
  case CF9:	sigchar(&tty_table[CONSOLE], SIGKILL); break;
  default:	return(FALSE);
  }
  return(TRUE);
}


/*==========================================================================*
 *				scan_keyboard				    *
 *==========================================================================*/
PRIVATE int scan_keyboard()
{
/* Fetch the character from the keyboard hardware and acknowledge it. */

  int code;
  int val;

  code = in_byte(KEYBD);	/* get the scan code for the key struck */
  val = in_byte(PORT_B);	/* strobe the keyboard to ack the char */
  out_byte(PORT_B, val | KBIT);	/* strobe the bit high */
  out_byte(PORT_B, val);	/* now strobe it low */
  return code;
}


/*==========================================================================*
 *				wreboot					    *
 *==========================================================================*/
PUBLIC void wreboot(how)
int how;		/* 0 = halt, 1 = reboot, 2 = panic!, ... */
{
/* Wait for keystrokes for printing debugging info and reboot. */

  int quiet, code;
  static u16_t magic = MEMCHECK_MAG;
  struct tasktab *ttp;

  /* Mask all interrupts. */
  out_byte(INT_CTLMASK, ~0);

  /* Tell several tasks to stop. */
  cons_stop();
#if ENABLE_NETWORKING
  dp8390_stop();
#endif
  floppy_stop();
  clock_stop();

  if (how == RBT_HALT) {
	printf("System Halted\n");
	if (!mon_return) how = RBT_PANIC;
  }

  if (how == RBT_PANIC) {
	/* A panic! */
	printf("Hit ESC to reboot, F-keys for debug dumps\n");

	(void) scan_keyboard();	/* ack any old input */
	quiet = scan_keyboard();/* quiescent value (0 on PC, last code on AT)*/
	for (;;) {
		milli_delay(100);	/* pause for a decisecond */
		code = scan_keyboard();
		if (code != quiet) {
			/* A key has been pressed. */
			if (code == ESC_SCAN) break; /* reboot if ESC typed */
			(void) func_key(code);	     /* process function key */
			quiet = scan_keyboard();
		}
	}
	how = RBT_REBOOT;
  }

  if (how == RBT_REBOOT) printf("Rebooting\n");

  if (mon_return && how != RBT_RESET) {
	/* Reinitialize the interrupt controllers to the BIOS defaults. */
	intr_init(0);
	out_byte(INT_CTLMASK, 0);
	out_byte(INT2_CTLMASK, 0);

	/* Return to the boot monitor. */
	if (how == RBT_HALT) {
		reboot_code = vir2phys("");
	} else
	if (how == RBT_REBOOT) {
		reboot_code = vir2phys("delay;boot");
	}
	level0(monitor);
  }

  /* Stop BIOS memory test. */
  phys_copy(vir2phys(&magic), (phys_bytes) MEMCHECK_ADR,
						(phys_bytes) sizeof(magic));

  if (protected_mode) {
	/* Use the AT keyboard controller to reset the processor.
	 * The A20 line is kept enabled in case this code is ever
	 * run from extended memory, and because some machines
	 * appear to drive the fake A20 high instead of low just
	 * after reset, leading to an illegal opode trap.  This bug
	 * is more of a problem if the fake A20 is in use, as it
	 * would be if the keyboard reset were used for real mode.
	 */
	kb_wait();
	out_byte(KB_COMMAND,
		 KB_PULSE_OUTPUT | (0x0F & ~(KB_GATE_A20 | KB_RESET)));
	milli_delay(10);

	/* If the nice method fails then do a reset.  In protected
	 * mode this means a processor shutdown.
	 */
	printf("Hard reset...\n");
	milli_delay(250);
  }
  /* In real mode, jumping to the reset address is good enough. */
  level0(reset);
}

⌨️ 快捷键说明

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