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

📄 console.c

📁 操作系统控制台程序
💻 C
📖 第 1 页 / 共 2 页
字号:
		cons->c_row -= n;
		flush(cons);
		break;

	    case 'B':		/* ESC [nB moves down n lines */
		n = (value == 0 ? 1 : value);
		cons->c_row += n;
		flush(cons);
		break;

	    case 'C':		/* ESC [nC moves right n spaces */
		n = (value == 0 ? 1 : value);
		cons->c_column += n;
		flush(cons);
		break;

	    case 'D':		/* ESC [nD moves left n spaces */
		n = (value == 0 ? 1 : value);
		cons->c_column -= n;
		flush(cons);
		break;

	    case 'H':		/* ESC [m;nH" moves cursor to (m,n) */
		cons->c_row = cons->c_esc_parmv[0] - 1;
		cons->c_column = cons->c_esc_parmv[1] - 1;
		flush(cons);
		break;

	    case 'J':		/* ESC [sJ clears in display */
		switch (value) {
		    case 0:	/* Clear from cursor to end of screen */
			count = scr_size - (cons->c_cur - cons->c_org);
			dst = cons->c_cur;
			break;
		    case 1:	/* Clear from start of screen to cursor */
			count = cons->c_cur - cons->c_org;
			dst = cons->c_org;
			break;
		    case 2:	/* Clear entire screen */
			count = scr_size;
			dst = cons->c_org;
			break;
		    default:	/* Do nothing */
			count = 0;
			dst = cons->c_org;
		}
		blank_color = cons->c_blank;
		mem_vid_copy(BLANK_MEM, dst, count);
		break;

	    case 'K':		/* ESC [sK clears line from cursor */
		switch (value) {
		    case 0:	/* Clear from cursor to end of line */
			count = scr_width - cons->c_column;
			dst = cons->c_cur;
			break;
		    case 1:	/* Clear from beginning of line to cursor */
			count = cons->c_column;
			dst = cons->c_cur - cons->c_column;
			break;
		    case 2:	/* Clear entire line */
			count = scr_width;
			dst = cons->c_cur - cons->c_column;
			break;
		    default:	/* Do nothing */
			count = 0;
			dst = cons->c_cur;
		}
		blank_color = cons->c_blank;
		mem_vid_copy(BLANK_MEM, dst, count);
		break;

	    case 'L':		/* ESC [nL inserts n lines at cursor */
		n = value;
		if (n < 1) n = 1;
		if (n > (scr_lines - cons->c_row))
			n = scr_lines - cons->c_row;

		src = cons->c_org + cons->c_row * scr_width;
		dst = src + n * scr_width;
		count = (scr_lines - cons->c_row - n) * scr_width;
		vid_vid_copy(src, dst, count);
		blank_color = cons->c_blank;
		mem_vid_copy(BLANK_MEM, src, n * scr_width);
		break;

	    case 'M':		/* ESC [nM deletes n lines at cursor */
		n = value;
		if (n < 1) n = 1;
		if (n > (scr_lines - cons->c_row))
			n = scr_lines - cons->c_row;

		dst = cons->c_org + cons->c_row * scr_width;
		src = dst + n * scr_width;
		count = (scr_lines - cons->c_row - n) * scr_width;
		vid_vid_copy(src, dst, count);
		blank_color = cons->c_blank;
		mem_vid_copy(BLANK_MEM, dst + count, n * scr_width);
		break;

	    case '@':		/* ESC [n@ inserts n chars at cursor */
		n = value;
		if (n < 1) n = 1;
		if (n > (scr_width - cons->c_column))
			n = scr_width - cons->c_column;

		src = cons->c_cur;
		dst = src + n;
		count = scr_width - cons->c_column - n;
		vid_vid_copy(src, dst, count);
		blank_color = cons->c_blank;
		mem_vid_copy(BLANK_MEM, src, n);
		break;

	    case 'P':		/* ESC [nP deletes n chars at cursor */
		n = value;
		if (n < 1) n = 1;
		if (n > (scr_width - cons->c_column))
			n = scr_width - cons->c_column;

		dst = cons->c_cur;
		src = dst + n;
		count = scr_width - cons->c_column - n;
		vid_vid_copy(src, dst, count);
		blank_color = cons->c_blank;
		mem_vid_copy(BLANK_MEM, dst + count, n);
		break;

	    case 'm':		/* ESC [nm enables rendition n */
		switch (value) {
		    case 1:	/* BOLD  */
			if (color) {
				/* Can't do bold, so use yellow */
				cons->c_attr = (cons->c_attr & 0xf0ff) | 0x0E00;
			} else {
				/* Set intensity bit */
				cons->c_attr |= 0x0800;
			}
			break;

		    case 4:	/* UNDERLINE */
			if (color) {
				/* Use light green */
				cons->c_attr = (cons->c_attr & 0xf0ff) | 0x0A00;
			} else {
				cons->c_attr = (cons->c_attr & 0x8900);
			}
			break;

		    case 5:	/* BLINKING */
			if (color) {
				/* Use magenta */
				cons->c_attr = (cons->c_attr & 0xf0ff) | 0x0500;
			} else {
				/* Set the blink bit */
				cons->c_attr |= 0x8000;
			}
			break;

		    case 7:	/* REVERSE */
			if (color) {
				/* Swap fg and bg colors */
				cons->c_attr =
					((cons->c_attr & 0xf000) >> 4) |
					((cons->c_attr & 0x0f00) << 4);
			} else
			if ((cons->c_attr & 0x7000) == 0) {
				cons->c_attr = (cons->c_attr & 0x8800) | 0x7000;
			} else {
				cons->c_attr = (cons->c_attr & 0x8800) | 0x0700;
			}
			break;

		    default:	/* COLOR */
		        if (30 <= value && value <= 37) {
				cons->c_attr =
					(cons->c_attr & 0xf0ff) |
					(ansi_colors[(value - 30)] << 8);
				cons->c_blank =
					(cons->c_blank & 0xf0ff) |
					(ansi_colors[(value - 30)] << 8);
			} else
			if (40 <= value && value <= 47) {
				cons->c_attr =
					(cons->c_attr & 0x0fff) |
					(ansi_colors[(value - 40)] << 12);
				cons->c_blank =
					(cons->c_blank & 0x0fff) |
					(ansi_colors[(value - 40)] << 12);
			} else {
				cons->c_attr = cons->c_blank;
			}
			break;
		}
		break;
	}
  }
  cons->c_esc_state = 0;
}


/*===========================================================================*
 *				set_6845				     *
 *===========================================================================*/
PRIVATE void set_6845(reg, val)
int reg;			/* which register pair to set */
unsigned val;			/* 16-bit value to set it to */
{
/* Set a register pair inside the 6845.
 * Registers 12-13 tell the 6845 where in video ram to start
 * Registers 14-15 tell the 6845 where to put the cursor
 */
  lock();			/* try to stop h/w loading in-between value */
  out_byte(vid_port + INDEX, reg);		/* set the index register */
  out_byte(vid_port + DATA, (val>>8) & BYTE);	/* output high byte */
  out_byte(vid_port + INDEX, reg + 1);		/* again */
  out_byte(vid_port + DATA, val&BYTE);		/* output low byte */
  unlock();
}


/*===========================================================================*
 *				beep					     *
 *===========================================================================*/
PRIVATE void beep()
{
/* Making a beeping sound on the speaker (output for CRTL-G).
 * This routine works by turning on the bits 0 and 1 in port B of the 8255
 * chip that drive the speaker.
 */

  message mess;

  if (beeping) return;
  out_byte(TIMER_MODE, 0xB6);	/* set up timer channel 2 (square wave) */
  out_byte(TIMER2, BEEP_FREQ & BYTE);	/* load low-order bits of frequency */
  out_byte(TIMER2, (BEEP_FREQ >> 8) & BYTE);	/* now high-order bits */
  lock();			/* guard PORT_B from keyboard intr handler */
  out_byte(PORT_B, in_byte(PORT_B) | 3);	/* turn on beep bits */
  unlock();
  beeping = TRUE;

  mess.m_type = SET_ALARM;
  mess.CLOCK_PROC_NR = TTY;
  mess.DELTA_TICKS = B_TIME;
  mess.FUNC_TO_CALL = (sighandler_t) stop_beep;
  sendrec(CLOCK, &mess);
}


/*===========================================================================*
 *				stop_beep				     *
 *===========================================================================*/
PRIVATE void stop_beep()
{
/* Turn off the beeper by turning off bits 0 and 1 in PORT_B. */

  lock();			/* guard PORT_B from keyboard intr handler */
  out_byte(PORT_B, in_byte(PORT_B) & ~3);
  beeping = FALSE;
  unlock();
}


/*===========================================================================*
 *				scr_init				     *
 *===========================================================================*/
PUBLIC void scr_init(tp)
tty_t *tp;
{
/* Initialize the screen driver. */
  console_t *cons;
  phys_bytes vid_base;
  u16_t bios_crtbase;
  int line;
  unsigned page_size;

  /* Associate console and TTY. */
  line = tp - &tty_table[0];
  if (line >= nr_cons) return;
  cons = &cons_table[line];
  cons->c_tty = tp;
  tp->tty_priv = cons;

  /* Initialize the keyboard driver. */
  kb_init(tp);

  /* Output functions. */
  tp->tty_devwrite = cons_write;
  tp->tty_echo = cons_echo;

  /* Get the BIOS parameters that tells the VDU I/O base register. */
  phys_copy(0x463L, vir2phys(&bios_crtbase), 2L);

  vid_port = bios_crtbase;

  if (color) {
	vid_base = COLOR_BASE;
	vid_size = COLOR_SIZE;
  } else {
	vid_base = MONO_BASE;
	vid_size = MONO_SIZE;
  }
  if (ega) vid_size = EGA_SIZE;
  wrap = !ega;

  vid_seg = protected_mode ? VIDEO_SELECTOR : physb_to_hclick(vid_base);
  init_dataseg(&gdt[VIDEO_INDEX], vid_base, (phys_bytes) vid_size,
							TASK_PRIVILEGE);
  vid_size >>= 1;		/* word count */
  vid_mask = vid_size - 1;

  /* There can be as many consoles as video memory allows. */
  nr_cons = vid_size / scr_size;
  if (nr_cons > NR_CONS) nr_cons = NR_CONS;
  if (nr_cons > 1) wrap = 0;
  page_size = vid_size / nr_cons;
  cons->c_start = line * page_size;
  cons->c_limit = cons->c_start + page_size;
  cons->c_org = cons->c_start;
  cons->c_attr = cons->c_blank = BLANK_COLOR;

  /* Clear the screen. */
  blank_color = BLANK_COLOR;
  mem_vid_copy(BLANK_MEM, cons->c_start, scr_size);
  select_console(0);
}


/*===========================================================================*
 *				putk					     *
 *===========================================================================*/
PUBLIC void putk(c)
int c;				/* character to print */
{
/* This procedure is used by the version of printf() that is linked with
 * the kernel itself.  The one in the library sends a message to FS, which is
 * not what is needed for printing within the kernel.  This version just queues
 * the character and starts the output.
 */

  if (c != 0) {
	if (c == '\n') putk('\r');
	out_char(&cons_table[0], (int) c);
  } else {
	flush(&cons_table[0]);
  }
}


/*===========================================================================*
 *				toggle_scroll				     *
 *===========================================================================*/
PUBLIC void toggle_scroll()
{
/* Toggle between hardware and software scroll. */

  cons_org0();
  softscroll = !softscroll;
  printf("%sware scrolling enabled.\n", softscroll ? "Soft" : "Hard");
}


/*===========================================================================*
 *				cons_stop				     *
 *===========================================================================*/
PUBLIC void cons_stop()
{
/* Prepare for halt or reboot. */
  cons_org0();
  softscroll = 1;
  select_console(0);
  cons_table[0].c_attr = cons_table[0].c_blank = BLANK_COLOR;
}


/*===========================================================================*
 *				cons_org0				     *
 *===========================================================================*/
PRIVATE void cons_org0()
{
/* Scroll video memory back to put the origin at 0. */
  int cons_line;
  console_t *cons;
  unsigned n;

  for (cons_line = 0; cons_line < nr_cons; cons_line++) {
	cons = &cons_table[cons_line];
	while (cons->c_org > cons->c_start) {
		n = vid_size - scr_size;	/* amount of unused memory */
		if (n > cons->c_org - cons->c_start)
			n = cons->c_org - cons->c_start;
		vid_vid_copy(cons->c_org, cons->c_org - n, scr_size);
		cons->c_org -= n;
	}
	flush(cons);
  }
  select_console(current);
}


/*===========================================================================*
 *				select_console				     *
 *===========================================================================*/
PUBLIC void select_console(int cons_line)
{
/* Set the current console to console number 'cons_line'. */

  if (cons_line < 0 || cons_line >= nr_cons) return;
  current = cons_line;
  curcons = &cons_table[cons_line];
  set_6845(VID_ORG, curcons->c_org);
  set_6845(CURSOR, curcons->c_cur);
}


/*===========================================================================*
 *				con_loadfont				     *
 *===========================================================================*/

PUBLIC int con_loadfont(user_phys)
phys_bytes user_phys;
{
/* Load a font into the EGA or VGA adapter. */
  static struct sequence seq1[7] = {
	{ GA_SEQUENCER_INDEX, 0x00, 0x01 },
	{ GA_SEQUENCER_INDEX, 0x02, 0x04 },
	{ GA_SEQUENCER_INDEX, 0x04, 0x07 },
	{ GA_SEQUENCER_INDEX, 0x00, 0x03 },
	{ GA_GRAPHICS_INDEX, 0x04, 0x02 },
	{ GA_GRAPHICS_INDEX, 0x05, 0x00 },
	{ GA_GRAPHICS_INDEX, 0x06, 0x00 },
  };
  static struct sequence seq2[7] = {
	{ GA_SEQUENCER_INDEX, 0x00, 0x01 },
	{ GA_SEQUENCER_INDEX, 0x02, 0x03 },
	{ GA_SEQUENCER_INDEX, 0x04, 0x03 },
	{ GA_SEQUENCER_INDEX, 0x00, 0x03 },
	{ GA_GRAPHICS_INDEX, 0x04, 0x00 },
	{ GA_GRAPHICS_INDEX, 0x05, 0x10 },
	{ GA_GRAPHICS_INDEX, 0x06,    0 },
  };

  seq2[6].value= color ? 0x0E : 0x0A;

  if (!ega) return(ENOTTY);

  lock();
  ga_program(seq1);	/* bring font memory into view */

  phys_copy(user_phys, (phys_bytes)GA_VIDEO_ADDRESS, (phys_bytes)GA_FONT_SIZE);

  ga_program(seq2);	/* restore */
  unlock();

  return(OK);
}


/*===========================================================================*
 *				ga_program				     *
 *===========================================================================*/

PRIVATE void ga_program(seq)
struct sequence *seq;
{
  int len= 7;
  do {
	out_byte(seq->index, seq->port);
	out_byte(seq->index+1, seq->value);
	seq++;
  } while (--len > 0);
}

⌨️ 快捷键说明

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