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

📄 console.h

📁 一个简单的操作系统minix的核心代码
💻 H
📖 第 1 页 / 共 3 页
字号:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
				src/kernel/console.c	 	 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

13600	/* Code and data for the IBM console driver.
13601	 *
13602	 * The 6845 video controller used by the IBM PC shares its video memory with
13603	 * the CPU somewhere in the 0xB0000 memory bank.  To the 6845 this memory
13604	 * consists of 16-bit words.  Each word has a character code in the low byte
13605	 * and a so-called attribute byte in the high byte.  The CPU directly modifies
13606	 * video memory to display characters, and sets two registers on the 6845 that
13607	 * specify the video origin and the cursor position.  The video origin is the
13608	 * place in video memory where the first character (upper left corner) can
13609	 * be found.  Moving the origin is a fast way to scroll the screen.  Some
13610	 * video adapters wrap around the top of video memory, so the origin can
13611	 * move without bounds.  For other adapters screen memory must sometimes be
13612	 * moved to reset the origin.  All computations on video memory use character
13613	 * (word) addresses for simplicity and assume there is no wrapping.  The
13614	 * assembly support functions translate the word addresses to byte addresses
13615	 * and the scrolling function worries about wrapping.
13616	 */
13617	
13618	#include "kernel.h"
13619	#include <termios.h>
13620	#include <minix/callnr.h>
13621	#include <minix/com.h>
13622	#include "protect.h"
13623	#include "tty.h"
13624	#include "proc.h"
13625	
13626	/* Definitions used by the console driver. */
13627	#define MONO_BASE    0xB0000L   /* base of mono video memory */
13628	#define COLOR_BASE   0xB8000L   /* base of color video memory */
13629	#define MONO_SIZE     0x1000    /* 4K mono video memory */
13630	#define COLOR_SIZE    0x4000    /* 16K color video memory */
13631	#define EGA_SIZE      0x8000    /* EGA & VGA have at least 32K */
13632	#define BLANK_COLOR   0x0700    /* determines cursor color on blank screen */
13633	#define SCROLL_UP          0    /* scroll forward */
13634	#define SCROLL_DOWN        1    /* scroll backward */
13635	#define BLANK_MEM ((u16_t *) 0) /* tells mem_vid_copy() to blank the screen */
13636	#define CONS_RAM_WORDS    80    /* video ram buffer size */
13637	#define MAX_ESC_PARMS      2    /* number of escape sequence params allowed */
13638	
13639	/* Constants relating to the controller chips. */
13640	#define M_6845         0x3B4    /* port for 6845 mono */
13641	#define C_6845         0x3D4    /* port for 6845 color */
13642	#define EGA            0x3C4    /* port for EGA or VGA card */
13643	#define INDEX              0    /* 6845's index register */
13644	#define DATA               1    /* 6845's data register */
13645	#define VID_ORG           12    /* 6845's origin register */
13646	#define CURSOR            14    /* 6845's cursor register */
13647	
13648	/* Beeper. */
13649	#define BEEP_FREQ     0x0533    /* value to put into timer to set beep freq */
13650	#define B_TIME             3    /* length of CTRL-G beep is ticks */
13651	
13652	/* definitions used for font management */
13653	#define GA_SEQUENCER_INDEX      0x3C4
13654	#define GA_SEQUENCER_DATA       0x3C5
13655	#define GA_GRAPHICS_INDEX       0x3CE
13656	#define GA_GRAPHICS_DATA        0x3CF
13657	#define GA_VIDEO_ADDRESS        0xA0000L
13658	#define GA_FONT_SIZE            8192
13659	
13660	/* Global variables used by the console driver. */
13661	PUBLIC unsigned vid_seg;        /* video ram selector (0xB0000 or 0xB8000) */
13662	PUBLIC unsigned vid_size;       /* 0x2000 for color or 0x0800 for mono */
13663	PUBLIC unsigned vid_mask;       /* 0x1FFF for color or 0x07FF for mono */
13664	PUBLIC unsigned blank_color = BLANK_COLOR; /* display code for blank */
13665	
13666	/* Private variables used by the console driver. */
13667	PRIVATE int vid_port;           /* I/O port for accessing 6845 */
13668	PRIVATE int wrap;               /* hardware can wrap? */
13669	PRIVATE int softscroll;         /* 1 = software scrolling, 0 = hardware */
13670	PRIVATE unsigned vid_base;      /* base of video ram (0xB000 or 0xB800) */
13671	PRIVATE int beeping;            /* speaker is beeping? */
13672	#define scr_width       80      /* # characters on a line */
13673	#define scr_lines       25      /* # lines on the screen */
13674	#define scr_size        (80*25) /* # characters on the screen */
13675	
13676	/* Per console data. */
13677	typedef struct console {
13678	  tty_t *c_tty;                 /* associated TTY struct */
13679	  int c_column;                 /* current column number (0-origin) */
13680	  int c_row;                    /* current row (0 at top of screen) */
13681	  int c_rwords;                 /* number of WORDS (not bytes) in outqueue */
13682	  unsigned c_start;             /* start of video memory of this console */
13683	  unsigned c_limit;             /* limit of this console's video memory */
13684	  unsigned c_org;               /* location in RAM where 6845 base points */
13685	  unsigned c_cur;               /* current position of cursor in video RAM */
13686	  unsigned c_attr;              /* character attribute */
13687	  unsigned c_blank;             /* blank attribute */
13688	  char c_esc_state;             /* 0=normal, 1=ESC, 2=ESC[ */
13689	  char c_esc_intro;             /* Distinguishing character following ESC */
13690	  int *c_esc_parmp;             /* pointer to current escape parameter */
13691	  int c_esc_parmv[MAX_ESC_PARMS];       /* list of escape parameters */
13692	  u16_t c_ramqueue[CONS_RAM_WORDS];     /* buffer for video RAM */
13693	} console_t;
13694	
13695	PRIVATE int nr_cons= 1;         /* actual number of consoles */
13696	PRIVATE console_t cons_table[NR_CONS];
13697	PRIVATE console_t *curcons;     /* currently visible */
13698	
13699	/* Color if using a color controller. */
13700	#define color   (vid_port == C_6845)
13701	
13702	/* Map from ANSI colors to the attributes used by the PC */
13703	PRIVATE int ansi_colors[8] = {0, 4, 2, 6, 1, 5, 3, 7};
13704	
13705	/* Structure used for font management */
13706	struct sequence {
13707	        unsigned short index;
13708	        unsigned char port;
13709	        unsigned char value;
13710	};
13711	
13712	FORWARD _PROTOTYPE( void cons_write, (struct tty *tp)                   );
13713	FORWARD _PROTOTYPE( void cons_echo, (tty_t *tp, int c)                  );
13714	FORWARD _PROTOTYPE( void out_char, (console_t *cons, int c)             );
13715	FORWARD _PROTOTYPE( void beep, (void)                                   );
13716	FORWARD _PROTOTYPE( void do_escape, (console_t *cons, int c)            );
13717	FORWARD _PROTOTYPE( void flush, (console_t *cons)                       );
13718	FORWARD _PROTOTYPE( void parse_escape, (console_t *cons, int c)         );
13719	FORWARD _PROTOTYPE( void scroll_screen, (console_t *cons, int dir)      );
13720	FORWARD _PROTOTYPE( void set_6845, (int reg, unsigned val)              );
13721	FORWARD _PROTOTYPE( void stop_beep, (void)                              );
13722	FORWARD _PROTOTYPE( void cons_org0, (void)                              );
13723	FORWARD _PROTOTYPE( void ga_program, (struct sequence *seq) );
13724	
13725	
13726	/*===========================================================================*
13727	 *                              cons_write                                   *
13728	 *===========================================================================*/
13729	PRIVATE void cons_write(tp)
13730	register struct tty *tp;        /* tells which terminal is to be used */
13731	{
13732	/* Copy as much data as possible to the output queue, then start I/O.  On
13733	 * memory-mapped terminals, such as the IBM console, the I/O will also be
13734	 * finished, and the counts updated.  Keep repeating until all I/O done.
13735	 */
13736	
13737	  int count;
13738	  register char *tbuf;
13739	  char buf[64];
13740	  phys_bytes user_phys;
13741	  console_t *cons = tp->tty_priv;
13742	
13743	  /* Check quickly for nothing to do, so this can be called often without
13744	   * unmodular tests elsewhere.
13745	   */
13746	  if ((count = tp->tty_outleft) == 0 || tp->tty_inhibited) return;
13747	
13748	  /* Copy the user bytes to buf[] for decent addressing. Loop over the
13749	   * copies, since the user buffer may be much larger than buf[].
13750	   */
13751	  do {
13752	        if (count > sizeof(buf)) count = sizeof(buf);
13753	        user_phys = proc_vir2phys(proc_addr(tp->tty_outproc), tp->tty_out_vir);
13754	        phys_copy(user_phys, vir2phys(buf), (phys_bytes) count);
13755	        tbuf = buf;
13756	
13757	        /* Update terminal data structure. */
13758	        tp->tty_out_vir += count;
13759	        tp->tty_outcum += count;
13760	        tp->tty_outleft -= count;
13761	
13762	        /* Output each byte of the copy to the screen.  Avoid calling
13763	         * out_char() for the "easy" characters, put them into the buffer
13764	         * directly.
13765	         */
13766	        do {
13767	                if ((unsigned) *tbuf < ' ' || cons->c_esc_state > 0
13768	                        || cons->c_column >= scr_width
13769	                        || cons->c_rwords >= buflen(cons->c_ramqueue))
13770	                {
13771	                        out_char(cons, *tbuf++);
13772	                } else {
13773	                        cons->c_ramqueue[cons->c_rwords++] =
13774	                                        cons->c_attr | (*tbuf++ & BYTE);
13775	                        cons->c_column++;
13776	                }
13777	        } while (--count != 0);
13778	  } while ((count = tp->tty_outleft) != 0 && !tp->tty_inhibited);
13779	
13780	  flush(cons);                  /* transfer anything buffered to the screen */
13781	
13782	  /* Reply to the writer if all output is finished. */
13783	  if (tp->tty_outleft == 0) {
13784	        tty_reply(tp->tty_outrepcode, tp->tty_outcaller, tp->tty_outproc,
13785	                                                        tp->tty_outcum);
13786	        tp->tty_outcum = 0;
13787	  }
13788	}
	
	
13791	/*===========================================================================*
13792	 *                              cons_echo                                    *
13793	 *===========================================================================*/
13794	PRIVATE void cons_echo(tp, c)
13795	register tty_t *tp;             /* pointer to tty struct */
13796	int c;                          /* character to be echoed */
13797	{
13798	/* Echo keyboard input (print & flush). */
13799	  console_t *cons = tp->tty_priv;
13800	
13801	  out_char(cons, c);
13802	  flush(cons);
13803	}
	
	
13806	/*===========================================================================*
13807	 *                              out_char                                     *
13808	 *===========================================================================*/
13809	PRIVATE void out_char(cons, c)
13810	register console_t *cons;       /* pointer to console struct */
13811	int c;                          /* character to be output */
13812	{
13813	/* Output a character on the console.  Check for escape sequences first. */
13814	  if (cons->c_esc_state > 0) {
13815	        parse_escape(cons, c);
13816	        return;
13817	  }
13818	
13819	  switch(c) {
13820	        case 000:               /* null is typically used for padding */
13821	                return;         /* better not do anything */
13822	
13823	        case 007:               /* ring the bell */
13824	                flush(cons);    /* print any chars queued for output */
13825	                beep();
13826	                return;
13827	
13828	        case '\b':              /* backspace */
13829	                if (--cons->c_column < 0) {
13830	                        if (--cons->c_row >= 0) cons->c_column += scr_width;
13831	                }
13832	                flush(cons);
13833	                return;
13834	
13835	        case '\n':              /* line feed */
13836	                if ((cons->c_tty->tty_termios.c_oflag & (OPOST|ONLCR))
13837	                                                == (OPOST|ONLCR)) {
13838	                        cons->c_column = 0;
13839	                }
13840	                /*FALL THROUGH*/
13841	        case 013:               /* CTRL-K */
13842	        case 014:               /* CTRL-L */
13843	                if (cons->c_row == scr_lines-1) {
13844	                        scroll_screen(cons, SCROLL_UP);
13845	                } else {
13846	                        cons->c_row++;
13847	                }
13848	                flush(cons);
13849	                return;
13850	
13851	        case '\r':              /* carriage return */
13852	                cons->c_column = 0;
13853	                flush(cons);
13854	                return;
13855	
13856	        case '\t':              /* tab */
13857	                cons->c_column = (cons->c_column + TAB_SIZE) & ~TAB_MASK;
13858	                if (cons->c_column > scr_width) {
13859	                        cons->c_column -= scr_width;
13860	                        if (cons->c_row == scr_lines-1) {
13861	                                scroll_screen(cons, SCROLL_UP);
13862	                        } else {
13863	                                cons->c_row++;
13864	                        }
13865	                }
13866	                flush(cons);
13867	                return;
13868	
13869	        case 033:               /* ESC - start of an escape sequence */
13870	                flush(cons);    /* print any chars queued for output */
13871	                cons->c_esc_state = 1;  /* mark ESC as seen */
13872	                return;
13873	
13874	        default:                /* printable chars are stored in ramqueue */
13875	                if (cons->c_column >= scr_width) {
13876	                        if (!LINEWRAP) return;
13877	                        if (cons->c_row == scr_lines-1) {
13878	                                scroll_screen(cons, SCROLL_UP);
13879	                        } else {
13880	                                cons->c_row++;
13881	                        }
13882	                        cons->c_column = 0;
13883	                        flush(cons);
13884	                }
13885	                if (cons->c_rwords == buflen(cons->c_ramqueue)) flush(cons);
13886	                cons->c_ramqueue[cons->c_rwords++] = cons->c_attr | (c & BYTE);
13887	                cons->c_column++;                       /* next column */
13888	                return;
13889	  }
13890	}
	
	
13893	/*===========================================================================*
13894	 *                              scroll_screen                                *
13895	 *===========================================================================*/
13896	PRIVATE void scroll_screen(cons, dir)
13897	register console_t *cons;       /* pointer to console struct */
13898	int dir;                        /* SCROLL_UP or SCROLL_DOWN */
13899	{
13900	  unsigned new_line, new_org, chars;
13901	
13902	  flush(cons);
13903	  chars = scr_size - scr_width;         /* one screen minus one line */
13904	
13905	  /* Scrolling the screen is a real nuisance due to the various incompatible
13906	   * video cards.  This driver supports software scrolling (Hercules?),
13907	   * hardware scrolling (mono and CGA cards) and hardware scrolling without
13908	   * wrapping (EGA and VGA cards).  In the latter case we must make sure that
13909	   *            c_start <= c_org && c_org + scr_size <= c_limit
13910	   * holds, because EGA and VGA don't wrap around the end of video memory.
13911	   */
13912	  if (dir == SCROLL_UP) {
13913	        /* Scroll one line up in 3 ways: soft, avoid wrap, use origin. */
13914	        if (softscroll) {

⌨️ 快捷键说明

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