sis_300.c

来自「讲述linux的初始化过程」· C语言 代码 · 共 1,525 行 · 第 1/3 页

C
1,525
字号
	VCLKData=VCLKData+data;	SetReg1(P3c4,0x31,0);	for(i=0x2B;i<=0x2C;i++) {		data=*((UCHAR *)(ROMAddr+VCLKData));		SetReg1(P3c4,i,data);		VCLKData++;	}	SetReg1(P3c4,0x2D,0x80);}VOID SetCRT1ModeRegs(ULONG ROMAddr, USHORT ModeNo){	USHORT data,data2,data3;	if(ModeNo>0x13)	data=*((USHORT *)(ROMAddr+REFIndex+0x00));	else data=0;	data2=0;	if(ModeNo>0x13)		if(ModeType>0x02) {			data2=data2|0x02;			data3=ModeType-ModeVGA;			data3=data3<<2;			data2=data2|data3;	 	}	data=data&InterlaceMode;	if(data) data2=data2|0x20;	SetReg1(P3c4,0x06,data2);	data=GetReg1(P3c4,0x01);	data=data&0xF7;	data2=*((USHORT *)(ROMAddr+ModeIDOffset+0x01));	data2=data2&HalfDCLK;	if(data2) data=data|0x08;	SetReg1(P3c4,0x01,data);	data=GetReg1(P3c4,0x0F);	data=data&0xF7;	data2=*((USHORT *)(ROMAddr+ModeIDOffset+0x01));	data2=data2&LineCompareOff;	if(data2) data=data|0x08;	SetReg1(P3c4,0x0F,data);	data=GetReg1(P3c4,0x21);	data=data&0x1F;	if(ModeType==0x00) data=data|0x60;			// Text Mode	else if(ModeType<=0x02) data=data|0x00;		// EGA Mode	else data=data|0xA0;						// VGA Mode	SetReg1(P3c4,0x21,data);}VOID SetVCLKState(PHW_DEVICE_EXTENSION HwDeviceExtension, ULONG ROMAddr, USHORT ModeNo){	USHORT data,data2;	USHORT VCLK;	UCHAR  index;	index=*((UCHAR *)(ROMAddr+REFIndex+0x03));	index=index&0x03F;	CRT1VCLKLen=GetVCLKLen(ROMAddr);	data=index*CRT1VCLKLen;	VCLKData=*((USHORT *)(ROMAddr+0x208));	VCLKData=VCLKData+data+(CRT1VCLKLen-2);	VCLK=*((USHORT *)(ROMAddr+VCLKData));	if(ModeNo<=0x13) VCLK=0;	data=GetReg1(P3c4,0x07);	data=data&0x7B;	if(VCLK>=150) data=data|0x80;	// VCLK > 150	SetReg1(P3c4,0x07,data);	data=GetReg1(P3c4,0x32);	data=data&0xD7;	if(VCLK>=150) data=data|0x08;	// VCLK > 150	SetReg1(P3c4,0x32,data);	data2=0x03;	if(VCLK>135) data2=0x02;	if(VCLK>160) data2=0x01;	if(VCLK>260) data2=0x00;	data=GetReg1(P3c4,0x07);	data=data&0xFC;	data=data|data2;	SetReg1(P3c4,0x07,data);}VOID LoadDAC(ULONG ROMAddr){	USHORT data,data2;	USHORT time,i,j,k;	USHORT m,n,o;	USHORT si,di,bx,dl;	USHORT al,ah,dh;	USHORT *table=VGA_DAC;	data=*((USHORT *)(ROMAddr+ModeIDOffset+0x01));	data=data&DACInfoFlag;	time=64;	if(data==0x00) table=MDA_DAC;	if(data==0x08) table=CGA_DAC;	if(data==0x10) table=EGA_DAC;	if(data==0x18) {		time=256;		table=VGA_DAC;	}	if(time==256) j=16;	else j=time;	SetReg3(P3c6,0xFF);	SetReg3(P3c8,0x00);	for(i=0;i<j;i++) {		data=table[i];		for(k=0;k<3;k++) {			data2=0;			if(data&0x01) data2=0x2A;			if(data&0x02) data2=data2+0x15;			SetReg3(P3c9,data2);			data=data>>2;		}	}	if(time==256) {		for(i=16;i<32;i++) {			data=table[i];			for(k=0;k<3;k++) SetReg3(P3c9,data);		}		si=32;		for(m=0;m<9;m++) {			di=si;			bx=si+0x04;			dl=0;			for(n=0;n<3;n++) {				for(o=0;o<5;o++) {					dh=table[si];					ah=table[di];					al=table[bx];					si++;					WriteDAC(dl,ah,al,dh);				}					si=si-2;				for(o=0;o<3;o++) {					dh=table[bx];					ah=table[di];					al=table[si];					si--;					WriteDAC(dl,ah,al,dh);				}					dl++;			}			si=si+5;		}	}}VOID WriteDAC(USHORT dl, USHORT ah, USHORT al, USHORT dh){	USHORT temp;	USHORT bh,bl;	bh=ah;	bl=al;	if(dl!=0) {		temp=bh;		bh=dh;		dh=temp;		if(dl==1) {			temp=bl;			bl=dh;			dh=temp;		}		else {			temp=bl;			bl=bh;			bh=temp;		}	}	SetReg3(P3c9,(USHORT)dh);	SetReg3(P3c9,(USHORT)bh);	SetReg3(P3c9,(USHORT)bl);}VOID DisplayOn(){	USHORT data;	data=GetReg1(P3c4,0x01);	data=data&0xDF;	SetReg1(P3c4,0x01,data);}USHORT GetModeIDLength(ULONG ROMAddr, USHORT ModeNo){	USHORT modeidlength;	USHORT usModeIDOffset;	USHORT PreviousWord,CurrentWord;	modeidlength=0;	usModeIDOffset=*((USHORT *)(ROMAddr+0x20A));		// Get EModeIDTable	//	maybe = 2Exx or xx2E			CurrentWord=*((USHORT *)(ROMAddr+usModeIDOffset));	// Offset 0x20A	PreviousWord=*((USHORT *)(ROMAddr+usModeIDOffset-2));	// Offset 0x20A	while((CurrentWord!=0x2E07)||(PreviousWord!=0x0801)) {		modeidlength++;		usModeIDOffset=usModeIDOffset+1;				// 10 <= ExtStructSize		CurrentWord=*((USHORT *)(ROMAddr+usModeIDOffset));		PreviousWord=*((USHORT *)(ROMAddr+usModeIDOffset-2)); 	}	modeidlength++;	return(modeidlength);}USHORT GetRefindexLength(ULONG ROMAddr, USHORT ModeNo){	UCHAR ModeID;	UCHAR temp;	USHORT refindexlength;	USHORT usModeIDOffset;	USHORT usREFIndex;	USHORT usIDLength;	usModeIDOffset=*((USHORT *)(ROMAddr+0x20A));	// Get EModeIDTable	ModeID=*((UCHAR *)(ROMAddr+usModeIDOffset));	// Offset 0x20A	usIDLength = GetModeIDLength(ROMAddr, ModeNo);	while(ModeID!=0x40) {		usModeIDOffset=usModeIDOffset+usIDLength; 	// 10 <= ExtStructSize		ModeID=*((UCHAR *)(ROMAddr+usModeIDOffset));	}	refindexlength=1;	usREFIndex=*((USHORT *)(ROMAddr+usModeIDOffset+0x04));	// si+Ext_point	usREFIndex++;	temp=*((UCHAR *)(ROMAddr+usREFIndex));			// di => REFIndex	while(temp!=0xFF) {		refindexlength++;		usREFIndex++;		temp=*((UCHAR *)(ROMAddr+usREFIndex));		// di => REFIndex	}	return(refindexlength);}VOID SetInterlace(ULONG ROMAddr, USHORT ModeNo){	ULONG Temp;	USHORT data,Temp2;	Temp = (ULONG)GetReg1(P3d4, 0x01);	Temp++;	Temp=Temp*8;	if(Temp==1024) data=0x0035;	else if(Temp==1280) data=0x0048;	else data=0x0000;	Temp2=*((USHORT *)(ROMAddr+REFIndex+0x00));	Temp2 &= InterlaceMode;	if(Temp2 == 0) data=0x0000;	SetReg1(P3d4,0x19,data);	Temp = (ULONG)GetReg1(P3d4, 0x1A);	Temp2= (USHORT)(Temp & 0xFC);	SetReg1(P3d4,0x1A,(USHORT)Temp);	Temp = (ULONG)GetReg1(P3c4, 0x0f);	Temp2= (USHORT)Temp & 0xBF;	if(ModeNo==0x37) Temp2=Temp2|0x40;	SetReg1(P3d4,0x1A,(USHORT)Temp2);}VOID SetCRT1FIFO(ULONG ROMAddr){	USHORT	colorth=0,index,data,VCLK,data2,MCLKOffset,MCLK;	USHORT  ah,bl,A,B;	index=*((UCHAR *)(ROMAddr+REFIndex+0x03));	index=index&0x03F;	CRT1VCLKLen=GetVCLKLen(ROMAddr);	data=index*CRT1VCLKLen;	VCLKData=*((USHORT *)(ROMAddr+0x208));	VCLKData=VCLKData+data+(CRT1VCLKLen-2);	VCLK=*((USHORT *)(ROMAddr+VCLKData));		// Get VCLK	MCLKOffset=*((USHORT *)(ROMAddr+0x20C));	index=GetReg1(P3c4,0x3A);	index=index&07;	MCLKOffset=MCLKOffset+index*5;	MCLK=*((UCHAR *)(ROMAddr+MCLKOffset+0x03));	// Get MCLK	data2=ModeType-0x02;	switch (data2) {		case 0 : colorth=1; break;		case 1 : colorth=2; break;		case 2 : colorth=4; break;		case 3 : colorth=4; break;		case 4 : colorth=6; break;		case 5 : colorth=8; break;	 }	do{		B=(CalcDelay(ROMAddr,0)*VCLK*colorth);		B=B/(16*MCLK);		B++;		A=(CalcDelay(ROMAddr,1)*VCLK*colorth);		A=A/(16*MCLK);		A++;		if(A<4) A=0;		else A=A-4;		if(A>B)	bl=A;		else bl=B;		bl++;		if(bl>0x13) {			data=GetReg1(P3c4,0x16);			data=data>>6;			if(data!=0) {				data--;				data=data<<6;				data2=GetReg1(P3c4,0x16);				data2=(data2&0x3f)|data;				SetReg1(P3c4,0x16,data2);			}			else bl=0x13;		}	} while(bl>0x13);	ah=bl;	ah=ah<<4;	ah=ah|0x0f;	SetReg1(P3c4,0x08,ah);	data=bl;	data=data&0x10;	data=data<<1;	data2=GetReg1(P3c4,0x0F);	data2=data2&0x9f;	data2=data2|data;	SetReg1(P3c4,0x0F,data2);	data=bl+3;	if(data>0x0f) data=0x0f;	SetReg1(P3c4,0x3b,0x00);	data2=GetReg1(P3c4,0x09);	data2=data2&0xF0;	data2=data2|data;	SetReg1(P3c4,0x09,data2);}static USHORT CalcDelay(ULONG ROMAddr,USHORT key){	USHORT data,data2,temp0,temp1;	UCHAR  ThLowA[]={61,3,52,5,68,7,100,11,					 43,3,42,5,54,7, 78,11,					 34,3,37,5,47,7, 67,11};	UCHAR  ThLowB[]={81,4,72,6,88,8,120,12,					 55,4,54,6,66,8, 90,12,					 42,4,45,6,55,8, 75,12};	UCHAR  ThTiming[]= {1,2,2,3,0,1,1,2};	data=GetReg1(P3c4,0x16);	data=data>>6;	data2=GetReg1(P3c4,0x14);	data2=(data2>>4)&0x0C;	data=data|data2;	data=data<1;	if(key==0) {		temp0=(USHORT)ThLowA[data];		temp1=(USHORT)ThLowA[data+1];	}	else {		temp0=(USHORT)ThLowB[data];		temp1=(USHORT)ThLowB[data+1];	}	data2=0;	data=GetReg1(P3c4,0x18);	if(data&0x02) data2=data2|0x01;	if(data&0x20) data2=data2|0x02;	if(data&0x40) data2=data2|0x04;	data=temp1*ThTiming[data2]+temp0;	return(data);}VOID SetCRT1FIFO2(ULONG ROMAddr){	USHORT  colorth=0,index,data,VCLK,data2,MCLKOffset,MCLK;	USHORT  ah,bl,B;	ULONG	eax;	index=*((UCHAR *)(ROMAddr+REFIndex+0x03));	index=index&0x03F;	CRT1VCLKLen=GetVCLKLen(ROMAddr);	data=index*CRT1VCLKLen;	VCLKData=*((USHORT *)(ROMAddr+0x208));	VCLKData=VCLKData+data+(CRT1VCLKLen-2);	VCLK=*((USHORT *)(ROMAddr+VCLKData));			// Get VCLK	MCLKOffset=*((USHORT *)(ROMAddr+0x20C));	index=GetReg1(P3c4,0x1A);	index=index&07;	MCLKOffset=MCLKOffset+index*5;	MCLK=*((USHORT *)(ROMAddr+MCLKOffset+0x03));	// Get MCLK  	data2=ModeType-0x02;	switch (data2) {		case 0 : colorth=1; break;		case 1 : colorth=1; break;		case 2 : colorth=2; break;		case 3 : colorth=2; break;		case 4 : colorth=3; break;		case 5 : colorth=4; break;	}	do{		B=(CalcDelay2(ROMAddr,0)*VCLK*colorth);		if (B%(16*MCLK) == 0)		{			B=B/(16*MCLK);			bl=B+1;		}		else		{			B=B/(16*MCLK);			bl=B+2;		}		if(bl>0x13) {			data=GetReg1(P3c4,0x15);			data=data&0xf0;			if(data!=0xb0) {				data=data+0x20;				if(data==0xa0) data=0x30;				data2=GetReg1(P3c4,0x15);				data2=(data2&0x0f)|data;				SetReg1(P3c4,0x15,data2);			}			else bl=0x13;		}	} while(bl>0x13);	data2=GetReg1(P3c4,0x15);	data2=(data2&0xf0)>>4;	data2=data2<<24;	SetReg4(0xcf8,0x80000050);	eax=GetReg3(0xcfc);	eax=eax&0x0f0ffffff;	eax=eax|data2;	SetReg4(0xcfc,eax);	ah=bl;	ah=ah<<4;	ah=ah|0x0f;	SetReg1(P3c4,0x08,ah);	data=bl;	data=data&0x10;	data=data<<1;	data2=GetReg1(P3c4,0x0F);	data2=data2&0x9f;	data2=data2|data;	SetReg1(P3c4,0x0F,data2);	data=bl+3;	if(data>0x0f) data=0x0f;	SetReg1(P3c4,0x3b,0x00);	data2=GetReg1(P3c4,0x09);	data2=data2&0xF0;	data2=data2|data;	SetReg1(P3c4,0x09,data2);}USHORT CalcDelay2(ULONG ROMAddr,USHORT key){	USHORT data,index;	UCHAR  LatencyFactor[]={88,80,78,72,70,00,							00,79,77,71,69,49,							88,80,78,72,70,00,							00,72,70,64,62,44};	index=0;	data=GetReg1(P3c4,0x14);	if(data&0x80) index=index+12;	data=GetReg1(P3c4,0x15);	data=(data&0xf0)>>4;	if(data&0x01) index=index+6;	data=data>>1;	index=index+data;	data=LatencyFactor[index];	return(data);}#endif /* CONFIG_FB_SIS_LINUXBIOS */

⌨️ 快捷键说明

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