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 + -
显示快捷键?