📄 vga.c
字号:
if(B8000_MEM_POINTER==NULL){ if(__svgalib_banked_mem_base==0)__svgalib_banked_mem_base=0xa0000; if(__svgalib_banked_mem_size==0)__svgalib_banked_mem_size=0x10000; BANKED_MEM_POINTER=mmap((caddr_t) 0, __svgalib_banked_mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, __svgalib_mem_fd, __svgalib_banked_mem_base ); if(__svgalib_linear_mem_size) { LINEAR_MEM_POINTER=mmap((caddr_t) 0, __svgalib_linear_mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, __svgalib_mem_fd, (off_t) __svgalib_linear_mem_base ); };/* else LINEAR_MEM_POINTER=NULL;*/ if(__svgalib_mmio_size) MMIO_POINTER=mmap((caddr_t) 0, __svgalib_mmio_size, PROT_READ | PROT_WRITE, MAP_SHARED, __svgalib_mem_fd, (off_t) __svgalib_mmio_base ); else MMIO_POINTER=NULL; B8000_MEM_POINTER=mmap((caddr_t) 0, 32768, PROT_READ | PROT_WRITE, MAP_SHARED, __svgalib_mem_fd, (off_t) 0xb8000); }; __vga_mmap(); if ((long) GM < 0) { printf("svgalib: mmap error rrr\n"); exit(1); } /* disable video */ vga_screenoff(); /* Sanity check: (from painful experience) */ i = __svgalib_saveregs(text_regs); if (i > MAX_REGS) { puts("svgalib: FATAL internal error:"); printf("Set MAX_REGS at least to %d in src/driver.h and recompile everything.\n", i); exit(1); } /* This appears to fix the Trident 8900 rebooting problem. */ if (__svgalib_chipset == TVGA8900) { port_out(0x0c, SEQ_I); /* reg 12 */ text_regs[EXT + 11] = port_in(SEQ_D); port_out(0x1f, __svgalib_CRT_I); text_regs[EXT + 12] = port_in(__svgalib_CRT_D); } /* save text mode palette - first select palette index 0 */ if(!__svgalib_novga) port_out(0, PEL_IR); /* read RGB components - index is autoincremented */ savepalette(text_red, text_green, text_blue); /* shift to color emulation */ setcoloremulation(); /* save font data - first select a 16 color graphics mode */ if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->savefont) { __svgalib_driverspecs->emul->savefont(); } else if(!__svgalib_novga) { __svgalib_driverspecs->setmode(GPLANE16, prv_mode); save_text(); /* Allocate space for textmode font. */#ifndef BACKGROUND font_buf1 = malloc(FONT_SIZE * 2);#endif#ifdef BACKGROUND font_buf1 = valloc(FONT_SIZE * 2); #endif font_buf2 = font_buf1 + FONT_SIZE; /* save font data in plane 2 */ port_out(0x04, GRA_I); port_out(0x02, GRA_D);#ifdef __alpha__ port_out(0x06, GRA_I); port_out(0x00, GRA_D);#endif#if defined(CONFIG_ALPHA_JENSEN) slowcpy_from_sm(font_buf1, SM, FONT_SIZE);#else slowcpy(font_buf1, GM, FONT_SIZE);#endif /* save font data in plane 3 */ port_out(0x04, GRA_I); port_out(0x03, GRA_D);#if defined(CONFIG_ALPHA_JENSEN) slowcpy_from_sm(font_buf2, SM, FONT_SIZE);#else slowcpy(font_buf2, GM, FONT_SIZE);#endif#ifdef BACKGROUND /* Let's protect font. */ /* Read only */ if (-1 == mprotect(font_buf1,FONT_SIZE*2,PROT_READ)) { printf("svgalib: Memory protect error\n"); exit(-1); }#endif } initialized = 1; /* do our own interrupt handling */ for (i = 0; i < sizeof(sig2catch); i++) { siga.sa_handler = signal_handler; siga.sa_flags = 0; zero_sa_mask(&(siga.sa_mask)); sigaction((int) sig2catch[i], &siga, old_signal_handler + i); } /* vga_unlockvc(); */}#ifndef BACKGROUNDinline void vga_setpage(int p){ p += vga_page_offset; if (p == __svgalib_currentpage && !__svgalib_simple) return; (*__svgalib_setpage) (p); __svgalib_currentpage = p;}void vga_setreadpage(int p){ p += vga_page_offset; if (p == __svgalib_currentpage) return; (*__svgalib_setrdpage) (p); __svgalib_currentpage = -1;}void vga_setwritepage(int p){ p += vga_page_offset; if (p == __svgalib_currentpage) return; (*__svgalib_setwrpage) (p); __svgalib_currentpage = -1;}#endifvoid vga_safety_fork(void (*shutdown_routine) (void)){ pid_t childpid; int child_status, oldkbmode; if (initialized) { printf("svgalib: warning: vga_safety_fork() called when already initialized\n"); goto no_fork; } initialize(); /* * get current keyboard mode: * If this didn't suffice we claim we are on an old system and just don't * need to restore it. */ ioctl(__svgalib_tty_fd, KDGKBMODE, &oldkbmode); childpid = fork(); if (childpid < 0) { no_fork: printf("svgalib: warning: can't fork to enhance reliability; proceeding anyway"); return; } if (childpid) { ioctl(__svgalib_tty_fd, (int) TIOCNOTTY, (char *)0); for (;;) { while (waitpid(childpid, &child_status, WUNTRACED) != childpid); if (shutdown_routine) shutdown_routine(); vga_setmode(TEXT); /* resets termios as well */ ioctl(__svgalib_tty_fd, KDSKBMODE, oldkbmode); if (WIFEXITED(child_status)) exit(WEXITSTATUS(child_status)); if (WCOREDUMP(child_status)) puts("svgalib:vga_safety_fork: Core dumped!"); if (WIFSIGNALED(child_status)) { printf("svgalib:vga_safety_fork: Killed by signal %d, %s.\n", WTERMSIG(child_status), strsignal(WTERMSIG(child_status))); exit(1); } if (WIFSTOPPED(child_status)) { printf("svgalib:vga_safety_fork: Stopped by signal %d, %s.\n", WSTOPSIG(child_status), strsignal(WSTOPSIG(child_status))); puts("\aWARNING! Continue stopped svgalib application at own risk. You are better\n" "off killing it NOW!"); continue; } } } /* These need to be done again because the child doesn't inherit them. */ __svgalib_get_perm();#ifdef BACKGROUND if (__svgalib_virtual_mem_fd>0)close(__svgalib_virtual_mem_fd); { char tmp[50]; __svgalib_processnumber=getpid(); sprintf(tmp,"/proc/%d/mem",__svgalib_processnumber); if ((__svgalib_virtual_mem_fd = open(tmp,O_RDWR)) < 0) { printf("svgalib: Cannot open /proc/%d/mem.\n", __svgalib_processnumber); exit(-1); } };#endif /* * But alas. That doesn't suffice. We raise the iopl here what merely makes * the previous call pointless. * * If IOPERM is set, assume permissions have already been set by Olaf Titz' * ioperm(1). */ if (CHIPSET != FBDEV && getenv("IOPERM") == NULL) { if (iopl(3) < 0) { printf("svgalib(vga_safety_fork): Cannot get I/O permissions.\n"); exit(1); } } /* * Actually the mmap's are inherited anyway (and not all are remade here), * but it does not really harm. */#ifdef BACKGROUND /* * __vga_mmap() call is now really dangerous. You can only call * mmap once. Once virtual screen has been allocated its better * stay in one place. At least for now. Anyway this works now. */#else __vga_mmap();#endif /* * We might still want to do vc switches. */ __svgalib_takevtcontrol();}static void prepareforfontloading(void){ if (__svgalib_chipset == CIRRUS) { outb(SEQ_I, 0x0f); /* Disable CRT FIFO Fast-Page mode. */ outb(SEQ_D, inb(SEQ_D) | 0x40); }}static void fontloadingcomplete(void){ if (__svgalib_chipset == CIRRUS) { outb(SEQ_I, 0x0f); /* Re-enable CRT FIFO Fast-Page mode. */ outb(SEQ_D, inb(SEQ_D) & 0xbf); }}int vga_setmode(int mode){ int modeflags=mode&0xfffff000; if(mode==-1)return vga_version; mode&=0xfff;#ifdef BACKGROUND __svgalib_dont_switch_vt_yet(); /* Can't initialize if screen is flipped. */ if (__svgalib_oktowrite)#endif if (!initialized) initialize(); if (mode != TEXT && !chipset_modeavailable(mode)) {#ifdef BACKGROUND __svgalib_is_vt_switching_needed();#endif return -1; } #ifdef BACKGROUND if (!__svgalib_oktowrite) { prv_mode=CM; CM=mode; vga_setpage(0); __svgalib_is_vt_switching_needed(); return(0); /* propably this was enough. */ /* hmm.. there... virtual screen... */ }#endif/* if (!flip) vga_lockvc(); */ disable_interrupt(); prv_mode = CM; CM = mode; /* disable video */ vga_screenoff(); if(!__svgalib_novga) { /* Should be more robust (eg. grabbed X modes) */ if (__svgalib_getchipset() == ET4000 && prv_mode != G640x480x256 && SVGAMODE(prv_mode)) chipset_setmode(G640x480x256, prv_mode); /* This is a hack to get around the fact that some C&T chips * are programmed to ignore syncronous resets. So if we are * a C&T wait for retrace start */ if (__svgalib_getchipset() == CHIPS) { while (((port_in(__svgalib_IS1_R)) & 0x08) == 0x08 );/* wait VSync off */ while (((port_in(__svgalib_IS1_R)) & 0x08) == 0 ); /* wait VSync on */ port_outw(0x07,SEQ_I); /* reset hsync - just in case... */ } } if (mode == TEXT) { /* Returning to textmode. */ if (SVGAMODE(prv_mode)) vga_setpage(0); /* The extended registers are restored either by the */ /* chipset setregs function, or the chipset setmode function. */ /* restore font data - first select a 16 color graphics mode */ /* Note: this should restore the old extended registers if */ /* setregs is not defined for the chipset. */ if(__svgalib_novga) __svgalib_driverspecs->setmode(TEXT, prv_mode); if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->restorefont) { __svgalib_driverspecs->emul->restorefont(); chipset_setregs(text_regs, mode); } else if(!__svgalib_novga) { __svgalib_driverspecs->setmode(GPLANE16, prv_mode); if (CHIPSET != EGA) /* restore old extended regs */ chipset_setregs(text_regs, mode); /* disable Set/Reset Register */ port_out(0x01, GRA_I); port_out(0x00, GRA_D); prepareforfontloading(); restore_text(); /* restore font data in plane 2 - necessary for all VGA's */ port_out(0x02, SEQ_I); port_out(0x04, SEQ_D);#ifdef __alpha__ port_out(0x06, GRA_I); port_out(0x00, GRA_D);#endif#ifdef BACKGROUND if (-1 == mprotect(font_buf1,FONT_SIZE*2,PROT_READ|PROT_WRITE)) { printf("svgalib: Memory protect error\n"); exit(-1); }#endif#if defined(CONFIG_ALPHA_JENSEN) slowcpy_to_sm(SM, font_buf1, FONT_SIZE);#else slowcpy(GM, font_buf1, FONT_SIZE);#endif /* restore font data in plane 3 - necessary for Trident VGA's */ port_out(0x02, SEQ_I); port_out(0x08, SEQ_D);#if defined(CONFIG_ALPHA_JENSEN) slowcpy_to_sm(SM, font_buf2, FONT_SIZE);#else slowcpy(GM, font_buf2, FONT_SIZE);#endif#ifdef BACKGROUND if (-1 == mprotect(font_buf1,FONT_SIZE*2,PROT_READ)) { printf("svgalib: Memory protect error\n"); exit(1); }#endif fontloadingcomplete(); /* change register adresses if monochrome text mode */ /* EGA is assumed to use color emulation. */ if (!color_text) { __svgalib_CRT_I = CRT_IM; __svgalib_CRT_D = CRT_DM; __svgalib_IS1_R = IS1_RM; port_out(port_in(MIS_R) & 0xFE, MIS_W); } } else chipset_setregs(text_regs, mode); /* restore saved palette */ restorepalette(text_red, text_green, text_blue); /* restore text mode VGA registers */ __svgalib_setregs(text_regs); /* Set VMEM to some minimum value .. probably pointless.. */ { vga_claimvideomemory(12); }/* if (!flip) */ /* enable text output - restores the screen contents */ if (!__svgalib_secondary) ioctl(__svgalib_tty_fd, KDSETMODE, KD_TEXT); /* now wait for signal to stabilize, but don't do it on C&T chips. */ /* This is needed to restore correct text mode stretching. */ if (__svgalib_chipset != CHIPS) usleep(MODESWITCHDELAY); /* enable video */ vga_screenon(); if (!flip) /* restore text mode termio */ set_texttermio(); } else { /* Setting a graphics mode. */ /* disable text output */ if (!__svgalib_secondary) ioctl(__svgalib_tty_fd, KDSETMODE, KD_GRAPHICS); if (SVGAMODE(prv_mode)) { /* The current mode is an SVGA mode, and we now want to */ /* set a
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -