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

📄 pcvt_ext.c

📁 freebsd v4.4内核源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (c) 1992, 1995 Hellmuth Michaelis and Joerg Wunsch. * * Copyright (C) 1992, 1993 Soeren Schmidt. * * All rights reserved. * * For the sake of compatibility, portions of this code regarding the * X server interface are taken from Soeren Schmidt's syscons driver. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by *	Hellmuth Michaelis, Joerg Wunsch and Soeren Schmidt. * 4. The name authors may not be used to endorse or promote products *    derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * @(#)pcvt_ext.c, 3.20, Last Edit-Date: [Thu Apr  6 10:07:45 1995] * *//*---------------------------------------------------------------------------* * *	pcvt_ext.c	VT220 Driver Extended Support Routines *	------------------------------------------------------ * *	-hm	------------ Release 3.00 -------------- *	-hm	integrating NetBSD-current patches *	-hm	applied Onno van der Linden's patch for Cirrus BIOS upgrade *	-hm	pcvt_x_hook has to care about fkey labels now *	-hm	changed some bcopyb's to bcopy's *	-hm	TS_INDEX -> TS_DATA for cirrus (mail from Onno/Charles) *	-jw	removed kbc_8042(), and replaced by kbd_emulate_pc() *	-hm	X server patch from John Kohl <jtk@kolvir.blrc.ma.us> *	-hm	applying Joerg's patch for FreeBSD 2.0 *	-hm	enable 132 col support for Trident TVGA8900CL *	-hm	applying patch from Joerg fixing Crtat bug *	-hm	removed PCVT_FAKE_SYSCONS10 *	-hm	fastscroll/Crtat bugfix from Lon Willett *	-hm	bell patch from Thomas Eberhardt for NetBSD *	-hm	multiple X server bugfixes from Lon Willett *	-hm	patch from John Kohl fixing tsleep bug in usl_vt_ioctl() *	-hm	bugfix: clear 25th line when switching to a force 24 lines vt *	-jw	add some forward declarations *	-hm	fixing MDA re-init when leaving X *	-hm	patch from John Kohl fixing potential divide by 0 problem * *---------------------------------------------------------------------------*/#include "vt.h"#if NVT > 0#include <i386/isa/pcvt/pcvt_hdr.h>	/* global include */#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)static int  s3testwritable( void );static int  et4000_col( int );static int  wd90c11_col( int );static int  tri9000_col( int );static int  v7_1024i_col( int );static int  s3_928_col( int );static int  cl_gd542x_col( int );/* storage to save video timing values of 80 columns text mode */static union {	u_char generic[11];	u_char et4000[11];	u_char wd90c11[12];	u_char tri9000[13];	u_char v7_1024i[17];	u_char s3_928[32];	u_char cirrus[13];}savearea;static int regsaved = 0;	/* registers are saved to savearea *//*---------------------------------------------------------------------------* * *	Find out which video board we are running on, taken from: *	Richard Ferraro: Programmers Guide to the EGA and VGA Cards *	and from David E. Wexelblat's SuperProbe Version 1.0. *	When a board is found, for which 132 column switching is *	provided, the global variable "can_do_132col" is set to 1, *	also the global variable vga_family is set to what we found. * *	############################################################### *	## THIS IS GETTING MORE AND MORE A LARGE SPAGHETTI HACK !!!! ## *	############################################################### * *---------------------------------------------------------------------------*/u_charvga_chipset(void){	u_char *ptr;	u_char byte, oldbyte, old1byte, newbyte;#if PCVT_132GENERIC	can_do_132col = 1;	/* assumes everyone can do 132 col */#else	can_do_132col = 0;	/* assumes noone can do 132 col */#endif /* PCVT_132GENERIC */	vga_family = VGA_F_NONE;/*---------------------------------------------------------------------------* * 	check for Western Digital / Paradise chipsets *---------------------------------------------------------------------------*/	ptr = (u_char *)Crtat;	if(color)		ptr += (0xc007d - 0xb8000);	else		ptr += (0xc007d - 0xb0000);	if((*ptr++ == 'V') && (*ptr++ == 'G') &&	   (*ptr++ == 'A') && (*ptr++ == '='))	{		int wd90c10;		vga_family = VGA_F_WD;		outb(addr_6845, 0x2b);		oldbyte = inb(addr_6845+1);		outb(addr_6845+1, 0xaa);		newbyte = inb(addr_6845+1);		outb(addr_6845+1, oldbyte);		if(newbyte != 0xaa)			return(VGA_PVGA);	/* PVGA1A chip */		outb(TS_INDEX, 0x12);		oldbyte = inb(TS_DATA);		outb(TS_DATA, oldbyte & 0xbf);		newbyte = inb(TS_DATA) & 0x40;		if(newbyte != 0)			return(VGA_WD90C00);	/* WD90C00 chip */		outb(TS_DATA, oldbyte | 0x40);		newbyte = inb(TS_DATA) & 0x40;		if(newbyte == 0)			return(VGA_WD90C00);	/* WD90C00 chip */		outb(TS_DATA, oldbyte);		wd90c10 = 0;		outb(TS_INDEX, 0x10);		oldbyte = inb(TS_DATA);		outb(TS_DATA, oldbyte & 0xfb);		newbyte = inb(TS_DATA) & 0x04;		if(newbyte != 0)			wd90c10 = 1;		outb(TS_DATA, oldbyte | 0x04);		newbyte = inb(TS_DATA) & 0x04;		if(newbyte == 0)			wd90c10 = 1;		outb(TS_DATA, oldbyte);		if(wd90c10)			return(VGA_WD90C10);		else		{			can_do_132col = 1;			return(VGA_WD90C11);		}	}/*---------------------------------------------------------------------------* *	check for Trident chipsets *---------------------------------------------------------------------------*/	outb(TS_INDEX, 0x0b);	oldbyte = inb(TS_DATA);	outb(TS_INDEX, 0x0b);	outb(TS_DATA, 0x00);	byte = inb(TS_DATA);	/* chipset type */	outb(TS_INDEX, 0x0e);	old1byte = inb(TS_DATA);	outb(TS_DATA, 0);	newbyte = inb(TS_DATA);	outb(TS_DATA, (old1byte ^ 0x02));	outb(TS_INDEX, 0x0b);	outb(TS_DATA, oldbyte);	if((newbyte & 0x0f) == 0x02)	{		/* is a trident chip */		vga_family = VGA_F_TRI;		switch(byte)		{			case 0x01:				return(VGA_TR8800BR);			case 0x02:				return(VGA_TR8800CS);			case 0x03:				can_do_132col = 1;				return(VGA_TR8900B);			case 0x04:			case 0x13:	/* Haven't tried, but should work */				can_do_132col = 1;				return(VGA_TR8900C);			case 0x23:				can_do_132col = 1;				return(VGA_TR9000);			case 0x33:				can_do_132col = 1;				return(VGA_TR8900CL);			case 0x83:				return(VGA_TR9200);			case 0x93:				return(VGA_TR9100);			default:				return(VGA_TRUNKNOWN);		}	}/*---------------------------------------------------------------------------* *	check for Tseng Labs ET3000/4000 chipsets *---------------------------------------------------------------------------*/	outb(GN_HERCOMPAT, 0x06);	if(color)		outb(GN_DMCNTLC, 0xa0);	else		outb(GN_DMCNTLM, 0xa0);	/* read old value */	if(color)		inb(GN_INPSTAT1C);	else		inb(GN_INPSTAT1M);	outb(ATC_INDEX, ATC_MISC);	oldbyte = inb(ATC_DATAR);	/* write new value */	if(color)		inb(GN_INPSTAT1C);	else		inb(GN_INPSTAT1M);	outb(ATC_INDEX, ATC_MISC);	newbyte = oldbyte ^ 0x10;	outb(ATC_DATAW, newbyte);	/* read back new value */	if(color)		inb(GN_INPSTAT1C);	else		inb(GN_INPSTAT1M);	outb(ATC_INDEX, ATC_MISC);	byte = inb(ATC_DATAR);	/* write back old value */	if(color)		inb(GN_INPSTAT1C);	else		inb(GN_INPSTAT1M);	outb(ATC_INDEX, ATC_MISC);	outb(ATC_DATAW, oldbyte);	if(byte == newbyte)	/* ET3000 or ET4000 */	{		vga_family = VGA_F_TSENG;		outb(addr_6845, CRTC_EXTSTART);		oldbyte = inb(addr_6845+1);		newbyte = oldbyte ^ 0x0f;		outb(addr_6845+1, newbyte);		byte = inb(addr_6845+1);		outb(addr_6845+1, oldbyte);		if(byte == newbyte)		{			can_do_132col = 1;			return(VGA_ET4000);		}		else		{			return(VGA_ET3000);		}	}/*---------------------------------------------------------------------------* *	check for Video7 VGA chipsets *---------------------------------------------------------------------------*/	outb(TS_INDEX, TS_EXTCNTL);	/* enable extensions */	outb(TS_DATA, 0xea);	outb(addr_6845, CRTC_STARTADRH);	oldbyte = inb(addr_6845+1);	outb(addr_6845+1, 0x55);	newbyte = inb(addr_6845+1);	outb(addr_6845, CRTC_V7ID);	/* id register */	byte = inb(addr_6845+1);	/* read id */	outb(addr_6845, CRTC_STARTADRH);	outb(addr_6845+1, oldbyte);	outb(TS_INDEX, TS_EXTCNTL);	/* disable extensions */	outb(TS_DATA, 0xae);	if(byte == (0x55 ^ 0xea))	{					/* is Video 7 */		vga_family = VGA_F_V7;		outb(TS_INDEX, TS_EXTCNTL);	/* enable extensions */		outb(TS_DATA, 0xea);		outb(TS_INDEX, TS_V7CHIPREV);		byte = inb(TS_DATA);		outb(TS_INDEX, TS_EXTCNTL);	/* disable extensions */		outb(TS_DATA, 0xae);		if(byte < 0xff && byte >= 0x80)			return(VGA_V7VEGA);		if(byte < 0x7f && byte >= 0x70)			return(VGA_V7FWVR);		if(byte < 0x5a && byte >= 0x50)			return(VGA_V7V5);		if(byte < 0x4a && byte > 0x40)		{			can_do_132col = 1;			return(VGA_V71024I);		}		return(VGA_V7UNKNOWN);	}/*---------------------------------------------------------------------------* *	check for S3 chipsets *---------------------------------------------------------------------------*/	outb(addr_6845, 0x38);		/* reg 1 lock register */	old1byte = inb(addr_6845+1);	/* get old value */	outb(addr_6845, 0x38);	outb(addr_6845+1, 0x00);	/* lock registers */	if(s3testwritable() == 0)	/* check if locked */	{		outb(addr_6845, 0x38);		outb(addr_6845+1, 0x48);	/* unlock registers */		if(s3testwritable() == 1 )	/* check if unlocked */		{			vga_family = VGA_F_S3;	/* FAMILY S3  */			outb(addr_6845, 0x30);	/* chip id/rev reg */			byte = inb(addr_6845+1);			switch(byte & 0xf0)			{				case 0x80:					switch(byte & 0x0f)					{						case 0x01:							outb(addr_6845, 0x38);							outb(addr_6845+1, old1byte);							return VGA_S3_911;						case 0x02:							outb(addr_6845, 0x38);							outb(addr_6845+1, old1byte);							return VGA_S3_924;						default:							outb(addr_6845, 0x38);							outb(addr_6845+1, old1byte);							return VGA_S3_UNKNOWN;					}					break;				case 0xA0:					outb(addr_6845, 0x38);					outb(addr_6845+1, old1byte);					return VGA_S3_80x;				case 0x90:				case 0xb0:					outb(addr_6845, 0x38);					outb(addr_6845+1, old1byte);					can_do_132col = 1;					return VGA_S3_928;				default:					outb(addr_6845, 0x38);					outb(addr_6845+1, old1byte);					return VGA_S3_UNKNOWN;			}		}	}/*---------------------------------------------------------------------------* *	check for Cirrus chipsets *---------------------------------------------------------------------------*/	outb(TS_INDEX, 6);	oldbyte = inb(TS_DATA);	outb(TS_INDEX, 6);	outb(TS_DATA, 0x12);	outb(TS_INDEX, 6);	newbyte = inb(TS_DATA);	outb(addr_6845, 0x27);	byte = inb(addr_6845 + 1);	outb(TS_INDEX, 6);	outb(TS_DATA, oldbyte);	if (newbyte == 0x12) {		vga_family = VGA_F_CIR;		can_do_132col = 1;		switch ((byte & 0xfc) >> 2) {		case 0x22:			switch (byte & 3) {			case 0:				return VGA_CL_GD5402;			case 1:				return VGA_CL_GD5402r1;			case 2:				return VGA_CL_GD5420;			case 3:				return VGA_CL_GD5420r1;			}			break;		case 0x23:			return VGA_CL_GD5422;		case 0x25:			return VGA_CL_GD5424;		case 0x24:			return VGA_CL_GD5426;		case 0x26:			return VGA_CL_GD5428;		}	}	return(VGA_UNKNOWN);}/*--------------------------------------------------------------------------- * test if index 35 lower nibble is writable (taken from SuperProbe 1.0) *---------------------------------------------------------------------------*/static ints3testwritable(void){	u_char old, new1, new2;	outb(addr_6845, 0x35);	old = inb(addr_6845+1);			/* save */	outb(addr_6845, 0x35);	outb(addr_6845+1, (old & 0xf0));	/* write 0 */	outb(addr_6845, 0x35);	new1 = (inb(addr_6845+1)) & 0x0f;	/* must read 0 */	outb(addr_6845, 0x35);	outb(addr_6845+1, (old | 0x0f));	/* write 1 */	outb(addr_6845, 0x35);	new2 = (inb(addr_6845+1)) & 0x0f;	/* must read 1 */	outb(addr_6845, 0x35);	outb(addr_6845+1, old);			/* restore */	return((new1==0) && (new2==0x0f));}/*---------------------------------------------------------------------------* *	return ptr to string describing vga type *---------------------------------------------------------------------------*/char *vga_string(int number)

⌨️ 快捷键说明

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