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

📄 cons.c.virtual

📁 一款类linux的操作系统源码
💻 VIRTUAL
字号:
#include <ctype.h>#include <errno.h>#include <event.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys.h>#include <sys/i8255.h>#include <sys/i8259.h>#include <sys/intr.h>#include <sys/ioctl.h>#include <sys/proc.h>#define CONSOLES		4#define LINES			25#define COLS			80#define SCREEN_BASE		((char *) 0xb8000)#define SCREEN_END		((char *) SCREEN_BASE + LINES * 2 * COLS)#define CONS			(cons[console])#define CONS_BASE		(CONS.buf)#define CONS_END		(CONS.buf + LINES * 2 * COLS)#define CONS_CURSOR_X		(((CONS.curs - CONS_BASE) / 2) / COLS)#define CONS_CURSOR_Y		(((CONS.curs - CONS_BASE) / 2) % COLS)#define TAB_SPACES		8#define NORMAL			0x07#define BRIGHT			0x0f#define REVERSE			0x70#define BLINK			0x87#define CURSOR			'_'#define SCAN_CODES		0x60#define SCAN_CODE_LSHFT		0x2a#define SCAN_CODE_RSHFT		0x36#define SCAN_CODE_LSREL		0xaa#define SCAN_CODE_RSREL		0xb6#define SCAN_CODE_LCTRL		0x1d#define SCAN_CODE_RCTRL		0x5a#define SCAN_CODE_LCREL		0x9d#define SCAN_CODE_RCREL		0xda#define SCAN_CODE_F1		0x3b#define SCAN_CODE_F2		0x3c#define SCAN_CODE_F3		0x3d#define SCAN_CODE_F4		0x3e#define NULL_CODE		255#define MAX_CODES		16struct console {    proc_t proc;		       /* Process waiting for input */#define CONS_RAW	0x0001#define CONS_CURSOR_OFF	0x0002#define CONS_BRIGHT	0x0004#define CONS_REVERSE	0x0008#define CONS_BLINK	0x0010#define CONS_SHIFT	0x0020#define CONS_CTRL	0x0040    int flags;#if 0    char *buf;			       /* Screen buffer */#endif    char buf[LINES * COLS * 2];	       /* Screen buffer */    char *curs;			       /* Cursor location */    u_char codes[MAX_CODES];	       /* Keyboard scan code queue */    int ch, ct;			       /* Scan code queue ptrs */};static struct console cons[CONSOLES];static int currcons = 0;	       /* Current console */static char *screencurs;static char asciishift[SCAN_CODES] = {    '\0', ESC, '!', '@', '#', '$', '%', '^',    '&', '*', '(', ')', '_', '+', '\b', '\t',    'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I',    'O', 'P', '{', '}', '\n', '\0', 'A', 'S',    'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',    '"', '~', '\0', '|', 'Z', 'X', 'C', 'V',    'B', 'N', 'M', '<', '>', '?', '\0', '*',    '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0',    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '7',    '8', '9', '-', '4', '5', '6', '+', '1',    '2', '3', '0', '.', '\0', '\0', '\0', '\0',    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'};static char asciinormal[SCAN_CODES] = {    '\0', ESC, '1', '2', '3', '4', '5', '6',    '7', '8', '9', '0', '-', '=', '\b', '\t',    'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',    'o', 'p', '[', ']', '\n', '\0', 'a', 's',    'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',    '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v',    'b', 'n', 'm', ',', '.', '/', '\0', '*',    '\0', ' ', '\0', '\0', '\0', '\0', '\0', '\0',    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '7',    '8', '9', '-', '4', '5', '6', '+', '1',    '2', '3', '0', '.', '\0', '\0', '\0', '\0',    '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'};voidclear_screen(int cursor){    for (screencurs = SCREEN_BASE; screencurs < SCREEN_END; screencurs += 2) {	*screencurs = ' ';	*(screencurs + 1) = NORMAL;    }    screencurs = SCREEN_BASE;    if (cursor) {	*screencurs = CURSOR;	*(screencurs + 1) = BLINK;    }}static voidclear_console(int console){    /* Clear console buffer */    for (CONS.curs = CONS_BASE; CONS.curs < CONS_END; CONS.curs += 2) {	*(CONS.curs) = ' ';	*(CONS.curs + 1) = NORMAL;    }    CONS.curs = CONS_BASE;}static voidscroll_screen(int cursor){    char *i, *j;    for (i = SCREEN_BASE, j = SCREEN_BASE + 2 * COLS;	 j < SCREEN_END; i += 2 * COLS, j += 2 * COLS)	bcopy(j, i, 2 * COLS);    while (i < SCREEN_END) {	*(i + 1) = NORMAL;	*i = ' ';	i += 2;    }    screencurs = SCREEN_END - 2 * COLS;    if (cursor) {	*screencurs = CURSOR;	*(screencurs + 1) = BLINK;    }}static voidscroll_console(int console){    char *i, *j;    /* Scroll console buffer */    for (i = CONS_BASE, j = CONS_BASE + 2 * COLS;	 j < CONS_END; i += 2 * COLS, j += 2 * COLS)	bcopy(j, i, 2 * COLS);    while (i < CONS_END) {	*(i + 1) = NORMAL;	*i = ' ';	i += 2;    }    CONS.curs = CONS_END - 2 * COLS;}charconsole_attr(console){    char attr = NORMAL;    if (CONS.flags & CONS_BRIGHT)	attr = BRIGHT;    if (CONS.flags & CONS_REVERSE)	attr = REVERSE;    if (CONS.flags & CONS_BLINK)	attr = BLINK;    return attr;}voidput_screen(char c, int cursor){    if (isprint(c)) {	if (cursor) {	    *(screencurs + 1) = NORMAL;	    *screencurs = ' ';	}	*(screencurs + 1) = console_attr(currcons);	*screencurs = c;	screencurs += 2;	if (screencurs >= SCREEN_END)	    scroll_screen(cursor);	if (cursor) {	    *screencurs = CURSOR;	    *(screencurs + 1) = BLINK;	}    } else if (c == '\t') {	int i;	if (cursor) {	    *(screencurs + 1) = NORMAL;	    *screencurs = ' ';	}	for (i = 0; i < TAB_SPACES; i++) {	    *(screencurs + 1) = console_attr(currcons);	    *screencurs = ' ';	    screencurs += 2;	    if (screencurs >= SCREEN_END)		scroll_screen(cursor);	}	if (cursor) {	    *screencurs = CURSOR;	    *(screencurs + 1) = BLINK;	}    } else if (c == '\n') {	if (cursor) {	    *(screencurs + 1) = NORMAL;	    *screencurs = ' ';	}	if (screencurs < SCREEN_END - 2 * COLS) {	    char *i = SCREEN_BASE;	    while (i <= screencurs)		i += 2 * COLS;	    screencurs = i;	} else	    scroll_screen(cursor);	if (cursor) {	    *screencurs = CURSOR;	    *(screencurs + 1) = BLINK;	}    } else if (c == '\b' && screencurs > SCREEN_BASE) {	if (cursor) {	    *(screencurs + 1) = NORMAL;	    *screencurs = ' ';	}	screencurs -= 2;	if (cursor) {	    *screencurs = CURSOR;	    *(screencurs + 1) = BLINK;	}    }}voidput(char c){    put_screen(c, 1);}static voidput_console(int console, char c){    disable;    if (isprint(c)) {	*(CONS.curs + 1) = console_attr(console);	*(CONS.curs) = c;	CONS.curs += 2;	if (CONS.curs >= CONS_END)	    scroll_console(console);    } else if (c == '\t') {	int i;	for (i = 0; i < TAB_SPACES; i++) {	    *(CONS.curs + 1) = console_attr(console);	    *(CONS.curs) = ' ';	    CONS.curs += 2;	    if (CONS.curs >= CONS_END)		scroll_console(console);	}    } else if (c == '\n') {	if (CONS.curs < CONS_END - 2 * COLS) {	    char *i = CONS_BASE;	    while (i <= CONS.curs)		i += 2 * COLS;	    CONS.curs = i;	} else	    scroll_console(console);    } else if (c == '\b' && CONS.curs > CONS_BASE)	CONS.curs -= 2;    if (console == currcons)	put_screen(c, (CONS.flags & CONS_CURSOR_OFF ? 0 : 1));    enable;}#define CONSOLE_SWITCH(CONSOLE)						\    if (currcons != (CONSOLE)) {					\	currcons = (CONSOLE);						\	bcopy(cons[(CONSOLE)].buf, SCREEN_BASE, 2 * LINES * COLS);	\	screencurs =							\	    cons[(CONSOLE)].curs - cons[(CONSOLE)].buf + SCREEN_BASE;	\	if (!(cons[(CONSOLE)].flags & CONS_CURSOR_OFF)) {		\	    *screencurs = CURSOR;					\	    *(screencurs + 1) = BLINK;					\	}								\    }static voidkbd_isr(){    u_char code;    disable;    if ((code = inb(I8255_PORT_A)) == SCAN_CODE_F1) {	CONSOLE_SWITCH(0);    } else if (code == SCAN_CODE_F2) {	CONSOLE_SWITCH(1);    } else if (code == SCAN_CODE_F3) {	CONSOLE_SWITCH(2);    } else if (code == SCAN_CODE_F4) {	CONSOLE_SWITCH(3);    } else if ((cons[currcons].ct + 1) % MAX_CODES != cons[currcons].ch) {	cons[currcons].codes[cons[currcons].ct] = code;	cons[currcons].ct = (cons[currcons].ct + 1) % MAX_CODES;    }    enable;    /* Issue keyboard eoi */    outb(I8259_MSTR_CTRL, I8259_EOI_KBD);}static charget_console(int console){    u_char code = NULL_CODE;    char c = '\0';    if (console < 0)	console = currcons;    disable;    if (CONS.proc != NULL) {	enable;	proc_exit(EFAIL);	kprintf("get_console: system restart\n");	reboot();		       /* System restart */    }    CONS.proc = current;    enable;    while (c == '\0') {	disable;	if (CONS.ch == CONS.ct) {	    enable;	    event_wait(EVENT_KBD);	    continue;	}	code = CONS.codes[CONS.ch];	CONS.ch = (CONS.ch + 1) % MAX_CODES;	enable;	if (code == SCAN_CODE_LCTRL || code == SCAN_CODE_RCTRL)	    CONS.flags |= CONS_CTRL;	else if (code == SCAN_CODE_LCREL || code == SCAN_CODE_RCREL)	    CONS.flags &= ~CONS_CTRL;	else if (code == SCAN_CODE_LSHFT || code == SCAN_CODE_RSHFT)	    CONS.flags |= CONS_SHIFT;	else if (code == SCAN_CODE_LSREL || code == SCAN_CODE_RSREL)	    CONS.flags &= ~CONS_SHIFT;	else if (code > 0 && code < SCAN_CODES) {	    if (CONS.flags & CONS_CTRL) {#if 0		/* Ctrl-c generates a SIGKILL */		if (code == 0x2e)		    signal(CONS.t, SIGKILL);#endif	    } else if (CONS.flags & CONS_SHIFT)		c = asciishift[code];	    else		c = asciinormal[code];	}    }    if (!(CONS.flags & CONS_RAW) && !(CONS.flags & CONS_CTRL))	put_console(console, c);    disable;    CONS.proc = NULL;    enable;    return c;}static int initialized = 0;intcons_init(){    u_char code;    int i;#if 0    cons[0].buf = (char *) kmalloc(LINES * COLS * 2);    cons[1].buf = (char *) kmalloc(LINES * COLS * 2);    cons[2].buf = (char *) kmalloc(LINES * COLS * 2);    cons[3].buf = (char *) kmalloc(LINES * COLS * 2);#endif    for (i = 0; i < CONSOLES; i++) {	cons[i].proc = NULL;	/* Clear console buffer and set cursor */	clear_console(i);	/* Clear keyboard buffer */	cons[i].ch = cons[i].ct = 0;	cons[i].flags = CONS_RAW;    }    /* Setup keyboard interrupt */    isr_inst(INTR_KBD, kbd_isr, NULL);    intr_unmask(INTR_KBD);    /* Flush keyboard buffer */    code = inb(I8255_PORT_A);    code = inb(I8255_PORT_A);    /* Issue keyboard eoi */    outb(I8259_MSTR_CTRL, I8259_EOI_KBD);    initialized = 1;    return 0;}static intcons_ioctl(int console, u_int cmd, void *args){    int result = 0;    switch (cmd) {#if 0    case GET_BLOCK_TYPE:	*((int *) args) = BLK_FIXED;	break;#endif    case GET_BUFFER_SIZE:	if (args == NULL)	    return EINVAL;	*((u_long *) args) = 1;	break;    case GET_WINDOW_HEIGHT:	*((int *) args) = LINES;	break;    case GET_WINDOW_WIDTH:	*((int *) args) = COLS;	break;#if 0    case SET_RAW:	disable;	CONS.flags |= CONS_RAW;	enable;	break;    case SET_CANON:	disable;	CONS.flags &= ~CONS_RAW;	enable;	break;#endif    case GET_CURSOR_POS:	{	    cursor_t c = (cursor_t) args;	    disable;	    c->x = CONS_CURSOR_X;	    c->y = CONS_CURSOR_Y;	    enable;	}	break;    case GET_CURSOR_CHAR:	{	    char *ch = (char *) args;	    disable;	    *ch = *(CONS.curs);	    enable;	}	break;    case SET_CURSOR_ON:	disable;	CONS.flags &= ~CONS_CURSOR_OFF;	if (console == currcons) {	    screencurs = (CONS.curs - CONS_BASE) + SCREEN_BASE;	    *screencurs = CURSOR;	    *(screencurs + 1) = BLINK;	}	enable;	break;    case SET_CURSOR_OFF:	disable;	CONS.flags |= CONS_CURSOR_OFF;	enable;	break;    case SET_CURSOR_POS:	{	    cursor_t c = (cursor_t) args;	    if (c->x < 0 || c->x >= LINES || c->y < 0 || c->y >= COLS) {		result = EFAIL;		break;	    }	    disable;	    CONS.curs = CONS_BASE + 2 * (c->x * COLS + c->y);	    if (console == currcons) {		screencurs = (CONS.curs - CONS_BASE) + SCREEN_BASE;		if (!(CONS.flags & CONS_CURSOR_OFF)) {		    *screencurs = CURSOR;		    *(screencurs + 1) = BLINK;		}	    }	    enable;	}	break;    case SET_NORMAL_VIDEO:	disable;	CONS.flags &= ~(CONS_BRIGHT | CONS_REVERSE | CONS_BLINK);	enable;	break;    case SET_BRIGHT_VIDEO:	disable;	CONS.flags &= ~(CONS_BRIGHT | CONS_REVERSE | CONS_BLINK);	CONS.flags |= CONS_BRIGHT;	enable;	break;    case SET_REVERSE_VIDEO:	disable;	CONS.flags &= ~(CONS_BRIGHT | CONS_REVERSE | CONS_BLINK);	CONS.flags |= CONS_REVERSE;	enable;	break;    case SET_BLINK_VIDEO:	disable;	CONS.flags &= ~(CONS_BRIGHT | CONS_REVERSE | CONS_BLINK);	CONS.flags |= CONS_BLINK;	enable;	break;    case CLEAR_TO_EOL:	{	    int i;	    disable;	    for (i = 0;		 i < (2 * COLS) - ((CONS.curs - CONS_BASE) % (2 * COLS));		 i += 2) {		*(CONS.curs + i) = ' ';		*(CONS.curs + i + 1) = NORMAL;		if (console == currcons) {		    *(screencurs + i) = ' ';		    *(screencurs + i + 1) = NORMAL;		}	    }	    enable;	}	break;    case CLEAR:	disable;	clear_console(console);	if (console == currcons)	    clear_screen(CONS.flags & CONS_CURSOR_OFF ? 0 : 1);	enable;	break;    default:	result = ENOTTY;    }    return result;}/******************************************************************************* Console 0                                                                   *******************************************************************************/intcons0_init(){    return cons_init();}intcons0_ioctl(u_int cmd, void *args){    return cons_ioctl(0, cmd, args);}intcons0_get(int *c){    *c = get_console(0);    return 0;}intcons0_put(int c){    put_console(0, (char) c);    return 0;}intcons0_shut(){    return ENOSYS;}/******************************************************************************* Console 1                                                                   *******************************************************************************/intcons1_init(){    if (initialized)	return 0;    else	return EFAIL;}intcons1_ioctl(u_int cmd, void *args){    return cons_ioctl(1, cmd, args);}intcons1_get(int *c){    *c = get_console(1);    return 0;}intcons1_put(int c){    put_console(1, (char) c);    return 0;}intcons1_shut(){    return ENOSYS;}/******************************************************************************* Console 2                                                                   *******************************************************************************/intcons2_init(){    if (initialized)	return 0;    else	return EFAIL;}intcons2_ioctl(u_int cmd, void *args){    return cons_ioctl(2, cmd, args);}intcons2_get(int *c){    *c = get_console(2);    return 0;}intcons2_put(int c){    put_console(2, (char) c);    return 0;}intcons2_shut(){    return ENOSYS;}/******************************************************************************* Console 3                                                                   *******************************************************************************/intcons3_init(){    if (initialized)	return 0;    else	return EFAIL;}intcons3_ioctl(u_int cmd, void *args){    return cons_ioctl(3, cmd, args);}intcons3_get(int *c){    *c = get_console(3);    return 0;}intcons3_put(int c){    put_console(3, (char) c);    return 0;}intcons3_shut(){    return ENOSYS;}

⌨️ 快捷键说明

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