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

📄 console.c

📁 Minix3.11的源码。[MINIX 3是一个为高可靠性应用而设计的自由且简洁的类UNIX系统。]
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Code and data for the IBM console driver. * * The 6845 video controller used by the IBM PC shares its video memory with * the CPU somewhere in the 0xB0000 memory bank.  To the 6845 this memory * consists of 16-bit words.  Each word has a character code in the low byte * and a so-called attribute byte in the high byte.  The CPU directly modifies * video memory to display characters, and sets two registers on the 6845 that * specify the video origin and the cursor position.  The video origin is the * place in video memory where the first character (upper left corner) can * be found.  Moving the origin is a fast way to scroll the screen.  Some * video adapters wrap around the top of video memory, so the origin can * move without bounds.  For other adapters screen memory must sometimes be * moved to reset the origin.  All computations on video memory use character * (word) addresses for simplicity and assume there is no wrapping.  The * assembly support functions translate the word addresses to byte addresses * and the scrolling function worries about wrapping. */#include "../drivers.h"#include <termios.h>#include <minix/callnr.h>#include <minix/com.h>#include "tty.h"#include "../../kernel/const.h"#include "../../kernel/config.h"#include "../../kernel/type.h"/* Definitions used by the console driver. */#define MONO_BASE    0xB0000L	/* base of mono video memory */#define COLOR_BASE   0xB8000L	/* base of color video memory */#define MONO_SIZE     0x1000	/* 4K mono video memory */#define COLOR_SIZE    0x4000	/* 16K color video memory */#define EGA_SIZE      0x8000	/* EGA & VGA have at least 32K */#define BLANK_COLOR   0x0700	/* determines cursor color on blank screen */#define SCROLL_UP          0	/* scroll forward */#define SCROLL_DOWN        1	/* scroll backward */#define BLANK_MEM ((u16_t *) 0)	/* tells mem_vid_copy() to blank the screen */#define CONS_RAM_WORDS    80	/* video ram buffer size */#define MAX_ESC_PARMS      4	/* number of escape sequence params allowed *//* Constants relating to the controller chips. */#define M_6845         0x3B4	/* port for 6845 mono */#define C_6845         0x3D4	/* port for 6845 color */#define INDEX              0	/* 6845's index register */#define DATA               1	/* 6845's data register */#define STATUS             6	/* 6845's status register */#define VID_ORG           12	/* 6845's origin register */#define CURSOR            14	/* 6845's cursor register *//* Beeper. */#define BEEP_FREQ     0x0533	/* value to put into timer to set beep freq */#define B_TIME		   3	/* length of CTRL-G beep is ticks *//* definitions used for font management */#define GA_SEQUENCER_INDEX	0x3C4#define GA_SEQUENCER_DATA	0x3C5#define GA_GRAPHICS_INDEX	0x3CE#define GA_GRAPHICS_DATA	0x3CF#define GA_VIDEO_ADDRESS	0xA0000L#define GA_FONT_SIZE		8192/* Global variables used by the console driver and assembly support. */PUBLIC int vid_index;		/* index of video segment in remote mem map */PUBLIC u16_t vid_seg;PUBLIC vir_bytes vid_off;	/* video ram is found at vid_seg:vid_off */PUBLIC unsigned vid_size;	/* 0x2000 for color or 0x0800 for mono */PUBLIC unsigned vid_mask;	/* 0x1FFF for color or 0x07FF for mono */PUBLIC unsigned blank_color = BLANK_COLOR; /* display code for blank *//* Private variables used by the console driver. */PRIVATE int vid_port;		/* I/O port for accessing 6845 */PRIVATE int wrap;		/* hardware can wrap? */PRIVATE int softscroll;		/* 1 = software scrolling, 0 = hardware */PRIVATE int beeping;		/* speaker is beeping? */PRIVATE unsigned font_lines;	/* font lines per character */PRIVATE unsigned scr_width;	/* # characters on a line */PRIVATE unsigned scr_lines;	/* # lines on the screen */PRIVATE unsigned scr_size;	/* # characters on the screen *//* Per console data. */typedef struct console {  tty_t *c_tty;			/* associated TTY struct */  int c_column;			/* current column number (0-origin) */  int c_row;			/* current row (0 at top of screen) */  int c_rwords;			/* number of WORDS (not bytes) in outqueue */  unsigned c_start;		/* start of video memory of this console */  unsigned c_limit;		/* limit of this console's video memory */  unsigned c_org;		/* location in RAM where 6845 base points */  unsigned c_cur;		/* current position of cursor in video RAM */  unsigned c_attr;		/* character attribute */  unsigned c_blank;		/* blank attribute */  char c_reverse;		/* reverse video */  char c_esc_state;		/* 0=normal, 1=ESC, 2=ESC[ */  char c_esc_intro;		/* Distinguishing character following ESC */  int *c_esc_parmp;		/* pointer to current escape parameter */  int c_esc_parmv[MAX_ESC_PARMS];	/* list of escape parameters */  u16_t c_ramqueue[CONS_RAM_WORDS];	/* buffer for video RAM */} console_t;PRIVATE int nr_cons= 1;		/* actual number of consoles */PRIVATE console_t cons_table[NR_CONS];PRIVATE console_t *curcons;	/* currently visible *//* Color if using a color controller. */#define color	(vid_port == C_6845)/* Map from ANSI colors to the attributes used by the PC */PRIVATE int ansi_colors[8] = {0, 4, 2, 6, 1, 5, 3, 7};/* Structure used for font management */struct sequence {	unsigned short index;	unsigned char port;	unsigned char value;};FORWARD _PROTOTYPE( int cons_write, (struct tty *tp, int try)		);FORWARD _PROTOTYPE( void cons_echo, (tty_t *tp, int c)			);FORWARD _PROTOTYPE( void out_char, (console_t *cons, int c)		);FORWARD _PROTOTYPE( void cons_putk, (int c)				);FORWARD _PROTOTYPE( void beep, (void)					);FORWARD _PROTOTYPE( void do_escape, (console_t *cons, int c)		);FORWARD _PROTOTYPE( void flush, (console_t *cons)			);FORWARD _PROTOTYPE( void parse_escape, (console_t *cons, int c)		);FORWARD _PROTOTYPE( void scroll_screen, (console_t *cons, int dir)	);FORWARD _PROTOTYPE( void set_6845, (int reg, unsigned val)		);FORWARD _PROTOTYPE( void get_6845, (int reg, unsigned *val)		);FORWARD _PROTOTYPE( void stop_beep, (timer_t *tmrp)			);FORWARD _PROTOTYPE( void cons_org0, (void)				);FORWARD _PROTOTYPE( int ga_program, (struct sequence *seq)		);FORWARD _PROTOTYPE( int cons_ioctl, (tty_t *tp, int)			);/*===========================================================================* *				cons_write				     * *===========================================================================*/PRIVATE int cons_write(tp, try)register struct tty *tp;	/* tells which terminal is to be used */int try;{/* Copy as much data as possible to the output queue, then start I/O.  On * memory-mapped terminals, such as the IBM console, the I/O will also be * finished, and the counts updated.  Keep repeating until all I/O done. */  int count;  int result;  register char *tbuf;  char buf[64];  console_t *cons = tp->tty_priv;  if (try) return 1;	/* we can always write to console */  /* Check quickly for nothing to do, so this can be called often without   * unmodular tests elsewhere.   */  if ((count = tp->tty_outleft) == 0 || tp->tty_inhibited) return;  /* Copy the user bytes to buf[] for decent addressing. Loop over the   * copies, since the user buffer may be much larger than buf[].   */  do {	if (count > sizeof(buf)) count = sizeof(buf);	if ((result = sys_vircopy(tp->tty_outproc, D, tp->tty_out_vir, 			SELF, D, (vir_bytes) buf, (vir_bytes) count)) != OK)		break;	tbuf = buf;	/* Update terminal data structure. */	tp->tty_out_vir += count;	tp->tty_outcum += count;	tp->tty_outleft -= count;	/* Output each byte of the copy to the screen.  Avoid calling	 * out_char() for the "easy" characters, put them into the buffer	 * directly.	 */	do {		if ((unsigned) *tbuf < ' ' || cons->c_esc_state > 0			|| cons->c_column >= scr_width			|| cons->c_rwords >= buflen(cons->c_ramqueue))		{			out_char(cons, *tbuf++);		} else {			cons->c_ramqueue[cons->c_rwords++] =					cons->c_attr | (*tbuf++ & BYTE);			cons->c_column++;		}	} while (--count != 0);  } while ((count = tp->tty_outleft) != 0 && !tp->tty_inhibited);  flush(cons);			/* transfer anything buffered to the screen */  /* Reply to the writer if all output is finished or if an error occured. */  if (tp->tty_outleft == 0 || result != OK) {	/* REVIVE is not possible. I/O on memory mapped consoles finishes. */	tty_reply(tp->tty_outrepcode, tp->tty_outcaller, tp->tty_outproc,							tp->tty_outcum);	tp->tty_outcum = 0;  }}/*===========================================================================* *				cons_echo				     * *===========================================================================*/PRIVATE void cons_echo(tp, c)register tty_t *tp;		/* pointer to tty struct */int c;				/* character to be echoed */{/* Echo keyboard input (print & flush). */  console_t *cons = tp->tty_priv;  out_char(cons, c);  flush(cons);}/*===========================================================================* *				out_char				     * *===========================================================================*/PRIVATE void out_char(cons, c)register console_t *cons;	/* pointer to console struct */int c;				/* character to be output */{/* Output a character on the console.  Check for escape sequences first. */  if (cons->c_esc_state > 0) {	parse_escape(cons, c);	return;  }  switch(c) {	case 000:		/* null is typically used for padding */		return;		/* better not do anything */	case 007:		/* ring the bell */		flush(cons);	/* print any chars queued for output */		beep();		return;	case '\b':		/* backspace */		if (--cons->c_column < 0) {			if (--cons->c_row >= 0) cons->c_column += scr_width;		}		flush(cons);		return;	case '\n':		/* line feed */		if ((cons->c_tty->tty_termios.c_oflag & (OPOST|ONLCR))						== (OPOST|ONLCR)) {			cons->c_column = 0;		}		/*FALL THROUGH*/	case 013:		/* CTRL-K */	case 014:		/* CTRL-L */		if (cons->c_row == scr_lines-1) {			scroll_screen(cons, SCROLL_UP);		} else {			cons->c_row++;		}		flush(cons);		return;	case '\r':		/* carriage return */		cons->c_column = 0;		flush(cons);		return;	case '\t':		/* tab */		cons->c_column = (cons->c_column + TAB_SIZE) & ~TAB_MASK;		if (cons->c_column > scr_width) {			cons->c_column -= scr_width;			if (cons->c_row == scr_lines-1) {				scroll_screen(cons, SCROLL_UP);			} else {				cons->c_row++;			}		}		flush(cons);		return;	case 033:		/* ESC - start of an escape sequence */		flush(cons);	/* print any chars queued for output */		cons->c_esc_state = 1;	/* mark ESC as seen */		return;	default:		/* printable chars are stored in ramqueue */		if (cons->c_column >= scr_width) {			if (!LINEWRAP) return;			if (cons->c_row == scr_lines-1) {				scroll_screen(cons, SCROLL_UP);			} else {				cons->c_row++;			}			cons->c_column = 0;			flush(cons);		}		if (cons->c_rwords == buflen(cons->c_ramqueue)) flush(cons);		cons->c_ramqueue[cons->c_rwords++] = cons->c_attr | (c & BYTE);		cons->c_column++;			/* next column */		return;  }}/*===========================================================================* *				scroll_screen				     * *===========================================================================*/PRIVATE void scroll_screen(cons, dir)register console_t *cons;	/* pointer to console struct */int dir;			/* SCROLL_UP or SCROLL_DOWN */{  unsigned new_line, new_org, chars;  flush(cons);  chars = scr_size - scr_width;		/* one screen minus one line */  /* Scrolling the screen is a real nuisance due to the various incompatible   * video cards.  This driver supports software scrolling (Hercules?),   * hardware scrolling (mono and CGA cards) and hardware scrolling without   * wrapping (EGA cards).  In the latter case we must make sure that   *		c_start <= c_org && c_org + scr_size <= c_limit   * holds, because EGA doesn't wrap around the end of video memory.   */  if (dir == SCROLL_UP) {	/* Scroll one line up in 3 ways: soft, avoid wrap, use origin. */	if (softscroll) {		vid_vid_copy(cons->c_start + scr_width, cons->c_start, chars);	} else	if (!wrap && cons->c_org + scr_size + scr_width >= cons->c_limit) {		vid_vid_copy(cons->c_org + scr_width, cons->c_start, chars);		cons->c_org = cons->c_start;	} else {		cons->c_org = (cons->c_org + scr_width) & vid_mask;	}	new_line = (cons->c_org + chars) & vid_mask;  } else {	/* Scroll one line down in 3 ways: soft, avoid wrap, use origin. */	if (softscroll) {		vid_vid_copy(cons->c_start, cons->c_start + scr_width, chars);	} else	if (!wrap && cons->c_org < cons->c_start + scr_width) {		new_org = cons->c_limit - scr_size;		vid_vid_copy(cons->c_org, new_org + scr_width, chars);		cons->c_org = new_org;	} else {		cons->c_org = (cons->c_org - scr_width) & vid_mask;	}	new_line = cons->c_org;  }  /* Blank the new line at top or bottom. */  blank_color = cons->c_blank;  mem_vid_copy(BLANK_MEM, new_line, scr_width);  /* Set the new video origin. */  if (cons == curcons) set_6845(VID_ORG, cons->c_org);  flush(cons);}/*===========================================================================* *				flush					     * *===========================================================================*/PRIVATE void flush(cons)register console_t *cons;	/* pointer to console struct */{/* Send characters buffered in 'ramqueue' to screen memory, check the new * cursor position, compute the new hardware cursor position and set it. */  unsigned cur;  tty_t *tp = cons->c_tty;  /* Have the characters in 'ramqueue' transferred to the screen. */  if (cons->c_rwords > 0) {	mem_vid_copy(cons->c_ramqueue, cons->c_cur, cons->c_rwords);	cons->c_rwords = 0;	/* TTY likes to know the current column and if echoing messed up. */	tp->tty_position = cons->c_column;	tp->tty_reprint = TRUE;  }  /* Check and update the cursor position. */  if (cons->c_column < 0) cons->c_column = 0;

⌨️ 快捷键说明

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