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

📄 pm.c

📁 BIOS emulator and interface to Realmode X86 Emulator Library Can emulate a PCI Graphic Controller V
💻 C
📖 第 1 页 / 共 4 页
字号:
		old_flags = fcntl(_PM_console_fd,F_GETFL);		if (ioctl(_PM_console_fd, KDSKBMODE, K_MEDIUMRAW))			perror("KDSKBMODE");		atexit(_PM_restore_kb_mode);		signal(SIGINT, 	_PM_abort);		signal(SIGTERM, _PM_abort);		signal(SIGHUP, 	_PM_abort);		signal(SIGFPE, 	_PM_abort);		signal(SIGSEGV, _PM_abort);		signal(SIGABRT, _PM_abort);		in_raw_mode = true;		}}int PMAPI PM_kbhit(void){   	fd_set s;    struct timeval tv = { 0, 0 };  	if (console_count == 0)		PM_fatalError("You *must* open a console before using PM_kbhit!");	if (!in_raw_mode)      	_PM_keyboard_rawmode();   	FD_ZERO(&s);	FD_SET(_PM_console_fd, &s);	return select(_PM_console_fd+1, &s, NULL, NULL, &tv) > 0;}int PMAPI PM_getch(void){    static uchar 	c;    int release;    static struct kbentry ke;	if (console_count == 0)		PM_fatalError("You *must* open a console before using PM_getch!");	if (!in_raw_mode)      	_PM_keyboard_rawmode();	while (read(_PM_console_fd, &c, 1) > 0) {      	release = c & 0x80;  		c &= 0x7F;    	if (release) {       		switch(c){  	    	  	case 42: case 54: // Shift					_PM_modifiers &= ~KB_SHIFT;   	    			break;   	    	  	case 29: case 97: // Control					_PM_modifiers &= ~KB_CONTROL;   	    			break;   	    	  	case 56: case 100: // Alt / AltGr					_PM_modifiers &= ~KB_ALT;	       			break;       	  		}       	  	continue;       		}        switch (c) {            case 42: case 54: // Shift				_PM_modifiers |= KB_SHIFT;             	 break;            case 29: case 97: // Control				_PM_modifiers |= KB_CONTROL;              	break;            case 56: case 100: // Alt / AltGr				_PM_modifiers |= KB_ALT;              	break;            case 58: // Caps Lock				_PM_modifiers ^= KB_CAPS;				ioctl(_PM_console_fd, KDSETLED, _PM_modifiers & 7);              	break;        	case 69: // Num Lock				_PM_modifiers ^= KB_NUMLOCK;				ioctl(_PM_console_fd, KDSETLED, _PM_modifiers & 7);        	  	break;        	case 70: // Scroll Lock				_PM_modifiers ^= KB_SCROLL;				ioctl(_PM_console_fd, KDSETLED, _PM_modifiers & 7);        	  	break;        	case 28:        	  	return 0x1C;            default:				ke.kb_index = c;    	  		ke.kb_table = 0;				if ((_PM_modifiers & KB_SHIFT) || (_PM_modifiers & KB_CAPS))    				ke.kb_table |= K_SHIFTTAB;				if (_PM_modifiers & KB_ALT)    				ke.kb_table |= K_ALTTAB;				ioctl(_PM_console_fd, KDGKBENT, (ulong)&ke);    	  		c = ke.kb_value & 0xFF;				return c;			}      	}    return 0;}/* VGA index register ports */#define CRT_I   0x3D4		/* CRT Controller Index 					*/#define ATT_IW  0x3C0		/* Attribute Controller Index & Data 		*/#define GRA_I   0x3CE		/* Graphics Controller Index 				*/#define SEQ_I   0x3C4		/* Sequencer Index 							*//* VGA data register ports */#define CRT_D   0x3D5		/* CRT Controller Data Register				*/#define ATT_R   0x3C1		/* Attribute Controller Data Read Register 	*/#define GRA_D   0x3CF		/* Graphics Controller Data Register 		*/#define SEQ_D   0x3C5		/* Sequencer Data Register 					*/#define MIS_R   0x3CC		/* Misc Output Read Register 				*/#define MIS_W   0x3C2		/* Misc Output Write Register 				*/#define IS1_R   0x3DA		/* Input Status Register 1 					*/#define PEL_IW  0x3C8		/* PEL Write Index 							*/#define PEL_IR  0x3C7		/* PEL Read Index 							*/#define PEL_D   0x3C9		/* PEL Data Register 						*//* standard VGA indexes max counts */#define CRT_C   24			/* 24  CRT Controller Registers 			*/#define ATT_C   21			/* 21  Attribute Controller Registers 		*/#define GRA_C   9			/* 9   Graphics Controller Registers 		*/#define SEQ_C   5			/* 5   Sequencer Registers 					*/#define MIS_C   1			/* 1   Misc Output Register 				*/#define	PAL_C	768			/* 768 Paletet Registers					*/#define FONT_C	0x10000		/* 64KB for font data						*//* VGA registers saving indexes */#define CRT     0			/* CRT Controller Registers start 			*/#define ATT     (CRT+CRT_C)	/* Attribute Controller Registers start 	*/#define GRA     (ATT+ATT_C)	/* Graphics Controller Registers start 		*/#define SEQ     (GRA+GRA_C)	/* Sequencer Registers 						*/#define MIS     (SEQ+SEQ_C)	/* General Registers 						*/#define PAL     (MIS+MIS_C)	/* VGA Palette Registers 					*/#define	FONT	(PAL+PAL_C)	/* Font data								*//****************************************************************************REMARKS:Delay for a short period of time.****************************************************************************/static void vga_delay(void){    int i;    for (i = 0; i < 10; i++)    	;}/****************************************************************************REMARKS:Sleep until the virtual terminal is active****************************************************************************/static void wait_vt_active(	int _PM_console_fd){	while (ioctl(_PM_console_fd, VT_WAITACTIVE, tty_vc) < 0) {        if ((errno != EAGAIN) && (errno != EINTR)) {            perror("ioctl(VT_WAITACTIVE)");            exit(1);        	}        usleep(150000);    	}}/****************************************************************************REMARKS:Checks the owner of the specified virtual console.****************************************************************************/static int check_owner(	int vc){    struct stat sbuf;    char fname[30];    sprintf(fname, "/dev/tty%d", vc);    if ((stat(fname, &sbuf) >= 0) && (getuid() == sbuf.st_uid))		return 1;    printf("You must be the owner of the current console to use this program.\n");    return 0;}/****************************************************************************REMARKS:Opens up the console device for output by finding an appropriate virutalconsole that we can run on.****************************************************************************/PM_HWND	PMAPI PM_openConsole(	PM_HWND hwndUser,	int device,	int xRes,	int yRes,	int bpp,	ibool fullScreen){	struct vt_mode 	vtm;    struct vt_stat 	vts;    struct stat 	sbuf;	char 			fname[30];	/* Check if we have already opened the console */	if (console_count++)		return _PM_console_fd;	/* Now, it would be great if we could use /dev/tty and see what it is	 * connected to. Alas, we cannot find out reliably what VC /dev/tty is	 * bound to. Thus we parse stdin through stderr for a reliable VC.	 */	startup_vc = 0;	for (_PM_console_fd = 0; _PM_console_fd < 3; _PM_console_fd++) {		if (fstat(_PM_console_fd, &sbuf) < 0)			continue;		if (ioctl(_PM_console_fd, VT_GETMODE, &vtm) < 0)            continue;        if ((sbuf.st_rdev & 0xFF00) != 0x400)            continue;        if (!(sbuf.st_rdev & 0xFF))            continue;        tty_vc = sbuf.st_rdev & 0xFF;		return _PM_console_fd;    	}	if ((_PM_console_fd = open("/dev/console", O_RDWR)) < 0) {        printf("open_dev_console: can't open /dev/console \n");        exit(1);    	}	if (ioctl(_PM_console_fd, VT_OPENQRY, &tty_vc) < 0)		goto Error;    if (tty_vc <= 0)		goto Error;    sprintf(fname, "/dev/tty%d", tty_vc);	close(_PM_console_fd);    /* Change our control terminal */    setsid();    /* We must use RDWR to allow for output... */	if (((_PM_console_fd = open(fname, O_RDWR)) >= 0) &&			(ioctl(_PM_console_fd, VT_GETSTATE, &vts) >= 0)) {        if (!check_owner(vts.v_active))			goto Error;        /* Success, redirect all stdios */        fflush(stdin);        fflush(stdout);        fflush(stderr);        close(0);        close(1);        close(2);		dup(_PM_console_fd);		dup(_PM_console_fd);		dup(_PM_console_fd);        /* clear screen and switch to it */        fwrite("\e[H\e[J", 6, 1, stderr);        fflush(stderr);        if (tty_vc != vts.v_active) {        	startup_vc = vts.v_active;			ioctl(_PM_console_fd, VT_ACTIVATE, tty_vc);			wait_vt_active(_PM_console_fd);        	}    	}	return _PM_console_fd;Error:	if (_PM_console_fd > 2)		close(_PM_console_fd);	console_count = 0;	PM_fatalError(		"Not running in a graphics capable console,\n"		"and unable to find one.\n");	return -1;}/****************************************************************************REMARKS:Returns the size of the console state buffer.****************************************************************************/int PMAPI PM_getConsoleStateSize(void){    if (!inited)		PM_init();    return CRT_C + ATT_C + GRA_C + SEQ_C + MIS_C + PAL_C + FONT_C*2;}/****************************************************************************REMARKS:Disables the VGA display for screen output making it blank.****************************************************************************/void PMAPI PM_vgaBlankDisplay(void){    /* turn screen off */	port_out(0x01, SEQ_I);	port_out(port_in(SEQ_D) | 0x20, SEQ_D);    /* disable video output */    port_in(IS1_R);    vga_delay();    port_out(0x00, ATT_IW);}/****************************************************************************REMARKS:Enables the VGA display for screen output.****************************************************************************/void PMAPI PM_vgaUnblankDisplay(void){    /* turn screen back on */	port_out(0x01, SEQ_I);	port_out(port_in(SEQ_D) & 0xDF, SEQ_D);    /* enable video output */    port_in(IS1_R);    vga_delay();    port_out(0x20, ATT_IW);}/****************************************************************************REMARKS:Save the color palette values****************************************************************************/static void vga_savepalette(uchar *pal){    int i;    port_out(0, PEL_IR);    for (i = 0; i < 768; i++) {		vga_delay();		*pal++ = port_in(PEL_D);        }}/****************************************************************************REMARKS:Restore the color palette values****************************************************************************/static void vga_restorepalette(const uchar *pal){    int i;    /* restore saved palette */	port_out(0, PEL_IW);	for (i = 0; i < 768; i++) {		vga_delay();		port_out(*pal++, PEL_D);		}}/****************************************************************************REMARKS:Save the state of all VGA compatible registers****************************************************************************/void PMAPI PM_saveVGAState(void *stateBuf){	uchar 	*regs = stateBuf;    int 	i;	/* Save state of VGA registers */    for (i = 0; i < CRT_C; i++) {		port_out(i, CRT_I);		regs[CRT + i] = port_in(CRT_D);    	}	for (i = 0; i < ATT_C; i++) {		port_in(IS1_R);		vga_delay();		port_out(i, ATT_IW);		vga_delay();		regs[ATT + i] = port_in(ATT_R);		vga_delay();    	}    for (i = 0; i < GRA_C; i++) {		port_out(i, GRA_I);		regs[GRA + i] = port_in(GRA_D);    	}    for (i = 0; i < SEQ_C; i++) {		port_out(i, SEQ_I);		regs[SEQ + i] = port_in(SEQ_D);    	}    regs[MIS] = port_in(MIS_R);    /* Save the VGA palette values */    vga_savepalette(&regs[PAL]);    /* Turn the VGA display back on */	PM_vgaUnblankDisplay();}/****************************************************************************REMARKS:Retore the state of all VGA compatible registers****************************************************************************/void PMAPI PM_restoreVGAState(const void *stateBuf){	const uchar	*regs = stateBuf;    int 		i;    /* Restore the state of the VGA compatible registers */    port_out(regs[MIS], MIS_W);    port_outw(0x0100,SEQ_I);    port_out(1, SEQ_I);    port_out(regs[SEQ + 1] | 0x20, SEQ_D);    for (i = 2; i < SEQ_C; i++) {		port_out(i, SEQ_I);		port_out(regs[SEQ + i], SEQ_D);    	}    port_outw(0x0300,SEQ_I);	/* Deprotect CRT registers 0-7 and write CRTC */	port_out(0x11, CRT_I);	port_out(port_in(CRT_D) & 0x7F, CRT_D);    for (i = 0; i < CRT_C; i++) {		port_out(i, CRT_I);		port_out(regs[CRT + i], CRT_D);    	}    for (i = 0; i < GRA_C; i++) {		port_out(i, GRA_I);		port_out(regs[GRA + i], GRA_D);    	}    for (i = 0; i < ATT_C; i++) {		port_in(IS1_R);		/* reset flip-flop */		vga_delay();		port_out(i, ATT_IW);		vga_delay();		port_out(regs[ATT + i], ATT_IW);		vga_delay();    	}    /* Restore the VGA palette values */    vga_restorepalette(&regs[PAL]);    /* Ensure the VGA screen is turned on */	PM_vgaUnblankDisplay();}/****************************************************************************REMARKS:Save the state of the Linux console.****************************************************************************/void PMAPI PM_saveConsoleState(void *stateBuf,int console_id){	uchar 	*regs = stateBuf;	/* Save the current console font */    if (ioctl(console_id,GIO_FONT,&regs[FONT]) < 0)		perror("ioctl(GIO_FONT)");	/* Inform the Linux console that we are going into graphics mode */	if (ioctl(console_id, KDSETMODE, KD_GRAPHICS) < 0)		perror("ioctl(KDSETMODE)");	/* Save state of VGA registers */	PM_saveVGAState(stateBuf);}void PMAPI PM_changeResolution(PM_HWND hwndConsole,int xRes,int yRes,int bpp){	/* Not used for Linux fullscreen consoles */}void PMAPI PM_setSuspendAppCallback(int (_ASMAPIP saveState)(int flags)){	/* TODO: Implement support for allowing console switching! */}/****************************************************************************REMARKS:Restore the state of the Linux console.****************************************************************************/void PMAPI PM_restoreConsoleState(const void *stateBuf,PM_HWND console_id){	const uchar	*regs = stateBuf;	/* Restore the state of the VGA compatible registers */	PM_restoreVGAState(stateBuf);	/* Inform the Linux console that we are back from graphics modes */	if (ioctl(console_id, KDSETMODE, KD_TEXT) < 0)		perror("ioctl(KDSETMODE)");

⌨️ 快捷键说明

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