📄 pcvt_sup.c
字号:
oldsize = svsp->screen_rowsize; oldrows = svsp->screen_rows; newsize = sizetab[(vgacs[curvgacs].screen_size)]; newrows = newsize; if (svsp->vt_pure_mode == M_HPVT) newrows -= 3; if (newrows == 25 && svsp->force24) newrows = 24; if (newrows < oldrows) { int nscroll = svsp->row + 1 - newrows; if (svsp->row >= oldrows) /* Sanity check */ nscroll = oldrows - newrows; if (nscroll > 0) { /* Scroll up */ bcopy (svsp->Crtat + nscroll * svsp->maxcol, svsp->Crtat, newrows * svsp->maxcol * CHR); svsp->row -= nscroll; svsp->cur_offset -= nscroll * svsp->maxcol; } if (newrows < newsize) fillw(user_attr | ' ', svsp->Crtat + newrows * svsp->maxcol, (newsize - newrows) * svsp->maxcol); } else if (oldrows < newsize) fillw(user_attr | ' ', svsp->Crtat + oldrows * svsp->maxcol, (newsize - oldrows) * svsp->maxcol); svsp->screen_rowsize = newsize; svsp->screen_rows = newrows; /* Clip scrolling region */ if(svsp->scrr_end > svsp->screen_rows - 1) svsp->scrr_end = svsp->screen_rows - 1; svsp->scrr_len = svsp->scrr_end - svsp->scrr_beg + 1; /* Clip cursor pos */ if(svsp->cur_offset > (svsp->scrr_len * svsp->maxcol)) svsp->cur_offset = (svsp->scrr_len * svsp->maxcol) + svsp->col;}/*---------------------------------------------------------------------------* * select a vga character set *---------------------------------------------------------------------------*/voidselect_vga_charset(int vga_charset){ int first, second; int fflag = 0; int sflag = 0; u_char cmap = 0; static u_char cmaptaba[] = {0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13}; static u_char cmaptabb[] = {0x00, 0x04, 0x08, 0x0c, 0x20, 0x24, 0x28, 0x2c}; if((adaptor_type != EGA_ADAPTOR) && (adaptor_type != VGA_ADAPTOR)) return; if((vga_charset < 0) || (vga_charset >= totalfonts)) return; if(!vgacs[vga_charset].loaded) return; /*-------------------------------------------------------------- find the the first and second charset of a given resolution. the first is used for lower 256 and the second (if any) is used for the upper 256 entries of a complete 512 entry ega/ vga charset. --------------------------------------------------------------*/ for(first = 0; first < totalfonts; first++) { if(!vgacs[first].loaded) continue; if(vgacs[first].screen_size != vgacs[vga_charset].screen_size) continue; if(vgacs[first].char_scanlines != vgacs[vga_charset].char_scanlines) continue; if(vgacs[first].scr_scanlines != vgacs[vga_charset].scr_scanlines) continue; fflag = 1; break; } if(fflag != 1) return; for(second = first+1; second < totalfonts; second++) { if(!vgacs[second].loaded) continue; if(vgacs[second].screen_size != vgacs[vga_charset].screen_size) continue; if(vgacs[second].char_scanlines != vgacs[vga_charset].char_scanlines) continue; if(vgacs[second].scr_scanlines != vgacs[vga_charset].scr_scanlines) continue; sflag = 1; break; } cmap = cmaptaba[first]; if(sflag) { cmap |= cmaptabb[second]; vgacs[first].secondloaded = second; } else { vgacs[first].secondloaded = 0; /*cs 0 can never become a 2nd!*/ } if(vsp->wd132col) { cmap = (vga_charset & 0x07); cmap |= 0x10; } outb(TS_INDEX, TS_FONTSEL); /* character map select register */ outb(TS_DATA, cmap); /* new char map */ outb(addr_6845, CRTC_MAXROW); /* max scan line reg */ outb(addr_6845+1, vgacs[first].char_scanlines); /* scanlines/char */ outb(addr_6845, CRTC_VDE); /* vert display enable end */ outb(addr_6845+1, vgacs[first].scr_scanlines); /* low byte of scr scanlines */ if((color == 0) && (adaptor_type == VGA_ADAPTOR)) { outb(addr_6845, CRTC_ULOC); /* underline location reg */ outb(addr_6845+1, (vgacs[first].char_scanlines & 0x1F)); }}/*---------------------------------------------------------------------------* * switch vga-card to load a character set *---------------------------------------------------------------------------*/static voidsetchargen(void){ chargen_access = 1; /* flag we are accessing the chargen ram */ /* program sequencer to access character generator */ outb(TS_INDEX, TS_SYNCRESET); outb(TS_DATA, 0x01); /* synchronous reset */ outb(TS_INDEX, TS_WRPLMASK); outb(TS_DATA, 0x04); /* write to map 2 */ outb(TS_INDEX, TS_MEMMODE); outb(TS_DATA, 0x07); /* sequential addressing */ outb(TS_INDEX, TS_SYNCRESET); outb(TS_DATA, 0x03); /* clear synchronous reset */ /* program graphics controller to access character generator */ outb(GDC_INDEX, GDC_RDPLANESEL); outb(GDC_DATA, 0x02); /* select map 2 for cpu reads */ outb(GDC_INDEX, GDC_MODE); outb(GDC_DATA, 0x00); /* disable odd-even addressing */ outb(GDC_INDEX, GDC_MISC); outb(GDC_DATA, 0x00); /* map starts at 0xA000 */}/*---------------------------------------------------------------------------* * switch vga-card to load a character set to plane 3 *---------------------------------------------------------------------------*/static voidsetchargen3(void){ chargen_access = 1; /* flag we are accessing the chargen ram */ /* program sequencer to access character generator */ outb(TS_INDEX, TS_SYNCRESET); outb(TS_DATA, 0x01); /* synchronous reset */ outb(TS_INDEX, TS_WRPLMASK); outb(TS_DATA, 0x08); /* write to map 3 */ outb(TS_INDEX, TS_MEMMODE); outb(TS_DATA, 0x07); /* sequential addressing */ outb(TS_INDEX, TS_SYNCRESET); outb(TS_DATA, 0x03); /* clear synchronous reset */ /* program graphics controller to access character generator */ outb(GDC_INDEX, GDC_RDPLANESEL); outb(GDC_DATA, 0x03); /* select map 3 for cpu reads */ outb(GDC_INDEX, GDC_MODE); outb(GDC_DATA, 0x00); /* disable odd-even addressing */ outb(GDC_INDEX, GDC_MISC); outb(GDC_DATA, 0x00); /* map starts at 0xA000 */}/*---------------------------------------------------------------------------* * switch back vga-card to normal operation *---------------------------------------------------------------------------*/static voidresetchargen(void){ /* program sequencer to access video ram */ outb(TS_INDEX, TS_SYNCRESET); outb(TS_DATA, 0x01); /* synchronous reset */ outb(TS_INDEX, TS_WRPLMASK); outb(TS_DATA, 0x03); /* write to map 0 & 1 */ outb(TS_INDEX, TS_MEMMODE); outb(TS_DATA, 0x03); /* odd-even addressing */ outb(TS_INDEX, TS_SYNCRESET); outb(TS_DATA, 0x03); /* clear synchronous reset */ /* program graphics controller to access character generator */ outb(GDC_INDEX, GDC_RDPLANESEL); outb(GDC_DATA, 0x00); /* select map 0 for cpu reads */ outb(GDC_INDEX, GDC_MODE); outb(GDC_DATA, 0x10); /* enable odd-even addressing */ outb(GDC_INDEX, GDC_MISC); if(color) outb(GDC_DATA, 0x0e); /* map starts at 0xb800 */ else outb(GDC_DATA, 0x0a); /* map starts at 0xb000 */ chargen_access = 0; /* flag we are NOT accessing the chargen ram */}#if PCVT_WAITRETRACE/*---------------------------------------------------------------------------* * wait for being in a retrace time window * NOTE: this is __VERY__ bad programming practice in this environment !! *---------------------------------------------------------------------------*/static voidwait_retrace(void){ if(color) { while(!(inb(GN_INPSTAT1C) & 0x01)) ; } else { while(!(inb(GN_INPSTAT1M) & 0x01)) ; }}#endif /* PCVT_WAITRETRACE *//*---------------------------------------------------------------------------* * switch screen off (VGA only) *---------------------------------------------------------------------------*/voidvga_screen_off(void){ unsigned char old; outb(TS_INDEX, TS_SYNCRESET); outb(TS_DATA, 0x01); /* synchronous reset */ outb(TS_INDEX, TS_MODE); /* clocking mode reg */ old = inb(TS_DATA); /* get current value */ outb(TS_INDEX, TS_MODE); /* clocking mode reg */ outb(TS_DATA, (old | 0x20)); /* screen off bit on */ outb(TS_INDEX, TS_SYNCRESET); outb(TS_DATA, 0x03); /* clear synchronous reset */}/*---------------------------------------------------------------------------* * switch screen back on (VGA only) *---------------------------------------------------------------------------*/voidvga_screen_on(void){ unsigned char old; outb(TS_INDEX, TS_SYNCRESET); outb(TS_DATA, 0x01); /* synchronous reset */ outb(TS_INDEX, TS_MODE); /* clocking mode reg */ old = inb(TS_DATA); /* get current value */ outb(TS_INDEX, TS_MODE); /* clocking mode reg */ outb(TS_DATA, (old & ~0x20)); /* screen off bit off */ outb(TS_INDEX, TS_SYNCRESET); outb(TS_DATA, 0x03); /* clear synchronous reset */}/*---------------------------------------------------------------------------* * compute character set base address (in kernel map) *---------------------------------------------------------------------------*/static unsigned char *compute_charset_base(unsigned fontset){ unsigned char *d = (unsigned char *)Crtat; static int charset_offset[8] = { 0x0000, 0x4000, 0x8000, 0xC000, 0x2000, 0x6000, 0xA000, 0xE000 }; static int charsetw_offset[8] = { 0x0000, 0x2000, 0x4000, 0x6000, 0x8000, 0xA000, 0xC000, 0xE000 }; switch(adaptor_type) { case EGA_ADAPTOR: fontset = (fontset > 3) ? 3 : fontset; break; case VGA_ADAPTOR: fontset = (fontset > 7) ? 7 : fontset; break; default: return 0; } if(color) d -= (0xB8000 - 0xA0000); /* Point to 0xA0000 */ else d -= (0xB0000 - 0xA0000); /* Point to 0xA0000 */ if(vsp->wd132col) d += charsetw_offset[fontset]; /* Load into Character set n */ else d += charset_offset[fontset]; /* Load into Character set n */ return d;}/*---------------------------------------------------------------------------* * load a char into ega/vga character generator ram *---------------------------------------------------------------------------*/voidloadchar(int fontset, int character, int char_scanlines, u_char *char_table){ unsigned char *d;#if PCVT_BACKUP_FONTS unsigned char *bak;#endif /* PCVT_BACKUP_FONTS */ int j, k; if((d = compute_charset_base(fontset)) == 0) return; d += (character * 32); /* 32 bytes per character */ if(vsp->wd132col && (fontset == 1||fontset == 3||fontset == 5||fontset == 7)) setchargen3(); /* access chargen ram */ else setchargen(); /* access chargen ram */ for(j = k = 0; j < char_scanlines; j++) /* x bit high characters */ { *d = char_table[k]; d++; k++; } for(; j < 32; j++) /* Up to 32 bytes per character image*/ { *d = 0x00; d++; } resetchargen(); /* access video ram */#if PCVT_BACKUP_FONTS if(saved_charsets[fontset] == 0) saved_charsets[fontset] = (u_char *)malloc(32 * 256, M_DEVBUF, M_WAITOK); if((bak = saved_charsets[fontset])) { /* make a backup copy of this char */ bak += (character * 32); bzero(bak, 32); bcopy(char_table, bak, char_scanlines); }#ifdef DIAGNOSTIC else panic("pcvt loadchar: no backup buffer");#endif /* DIAGNOSTIC */#endif /* PCVT_BACKUP_FONTS */}/*---------------------------------------------------------------------------* * save/restore character set n to addr b *---------------------------------------------------------------------------*/#if !PCVT_BACKUP_FONTSvoidvga_move_charset(unsigned n, unsigned char *b, int save_it){ unsigned char *d = compute_charset_base(n);#ifdef DIAGNOSTIC if(d == 0) panic("vga_move_charset: wrong adaptor");#endif if(vsp->wd132col && (n == 1||n == 3||n == 5||n == 7)) { setchargen3(); d -= 0x2000; } else { setchargen(); } /* PLEASE, leave the following alone using bcopyb, as several */ /* chipsets have problems if their memory is accessed with 32 */ /* or 16 bits wide, don't change this to using bcopy for speed! */ if(save_it) bcopyb(d, b, 256 /* chars */ * 32 /* bytes per char */); else bcopyb(b, d, 256 /* chars */ * 32 /* bytes per char */); resetchargen();}#else /* PCVT_BACKUP_FONTS *//* since there are always backed up copies, we do not save anything here *//* parameter "b" is totally ignored */voidvga_move_charset(unsigned n, unsigned char *b, int save_it){ unsigned char *d = compute_charset_base(n); if(save_it) return; if(saved_charsets[n] == 0)#ifdef DIAGNOSTIC panic("pcvt: restoring unbuffered charset");#else return;#endif#ifdef DIAGNOSTIC if(d == 0) panic("vga_move_charset: wrong adaptor");#endif if(vsp->wd132col && (n == 1||n == 3||n == 5||n == 7)) { setchargen3(); d -= 0x2000; } else { setchargen(); } /* PLEASE, leave the following alone using bcopyb, as several */ /* chipsets have problems if their memory is accessed with 32 */ /* or 16 bits wide, don't change this to using bcopy for speed! */ bcopyb(saved_charsets[n], d, 256 /* chars */ * 32 /* bytes per char */); resetchargen();}#endif /* PCVT_BACKUP_FONTS */#if !PCVT_USL_VT_COMPAT/*---------------------------------------------------------------------------* * switch to virtual screen n (0 ... PCVT_NSCREENS-1) *---------------------------------------------------------------------------*/voidvgapage(int n){#if !PCVT_KBD_FIFO int x;#endif /* !PCVT_KBD_FIFO */ int cols = vsp->maxcol; /* get current col val */ if(n < 0 || n >= totalscreens) return;#if !PCVT_KBD_FIFO x = spltty(); /* protect us */#endif /* !PCVT_KBD_FIFO */ /* video board memory -> kernel memory */ bcopy(vsp->Crtat, vsp->Memory, vsp->screen_rows * vsp->maxcol * CHR); vsp->Crtat = vsp->Memory; /* operate in memory now */ /* update global screen pointers/variables */ current_video_screen = n; /* current screen no */#if !PCVT_NETBSD && !(PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200) pcconsp = &pccons[n]; /* current tty */#elif PCVT_FREEBSD > 110 && PCVT_FREEBSD < 200 pcconsp = pccons[n]; /* current tty */#else pcconsp = pc_tty[n]; /* current tty */#endif vsp = &vs[n]; /* current video state ptr */ /* kernel memory -> video board memory */ bcopy(vsp->Crtat, Crtat, vsp->screen_rows * vsp->maxcol * CHR); vsp->Crtat = Crtat; /* operate on screen now */ outb(addr_6845, CRTC_STARTADRH); outb(addr_6845+1, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -