📄 init.c
字号:
SiS_Pr->SiS_UseROM = TRUE; } else if(SiS_Pr->ChipType < SIS_315H) { /* Sony's VAIO BIOS 1.09 follows the standard, so perhaps * the others do as well */ SiS_Pr->SiS_UseROM = TRUE; } else { /* 315/330 series stick to the standard(s) */ SiS_Pr->SiS_UseROM = TRUE; if((SiS_Pr->SiS_ROMNew = SiSDetermineROMLayout661(SiS_Pr))) { SiS_Pr->SiS_EMIOffset = 14; SiS_Pr->SiS_PWDOffset = 17; SiS_Pr->SiS661LCD2TableSize = 36; /* Find out about LCD data table entry size */ if((romptr = SISGETROMW(0x0102))) { if(ROMAddr[romptr + (32 * 16)] == 0xff) SiS_Pr->SiS661LCD2TableSize = 32; else if(ROMAddr[romptr + (34 * 16)] == 0xff) SiS_Pr->SiS661LCD2TableSize = 34; else if(ROMAddr[romptr + (36 * 16)] == 0xff) /* 0.94, 2.05.00+ */ SiS_Pr->SiS661LCD2TableSize = 36; else if( (ROMAddr[romptr + (38 * 16)] == 0xff) || /* 2.00.00 - 2.02.00 */ (ROMAddr[0x6F] & 0x01) ) { /* 2.03.00 - <2.05.00 */ SiS_Pr->SiS661LCD2TableSize = 38; /* UMC data layout abandoned at 2.05.00 */ SiS_Pr->SiS_EMIOffset = 16; SiS_Pr->SiS_PWDOffset = 19; } } } } }}/*********************************************//* HELPER: SET SEGMENT REGISTERS *//*********************************************/static voidSiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value){ unsigned short temp; value &= 0x00ff; temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0xf0; temp |= (value >> 4); SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp); temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0xf0; temp |= (value & 0x0f); SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);}static voidSiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value){ unsigned short temp; value &= 0x00ff; temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0x0f; temp |= (value & 0xf0); SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp); temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0x0f; temp |= (value << 4); SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);}static voidSiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value){ SiS_SetSegRegLower(SiS_Pr, value); SiS_SetSegRegUpper(SiS_Pr, value);}static voidSiS_ResetSegmentReg(struct SiS_Private *SiS_Pr){ SiS_SetSegmentReg(SiS_Pr, 0);}static voidSiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value){ unsigned short temp = value >> 8; temp &= 0x07; temp |= (temp << 4); SiS_SetReg(SiS_Pr->SiS_P3c4,0x1d,temp); SiS_SetSegmentReg(SiS_Pr, value);}static voidSiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr){ SiS_SetSegmentRegOver(SiS_Pr, 0);}static voidSiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr){ if((IS_SIS65x) || (SiS_Pr->ChipType >= SIS_661)) { SiS_ResetSegmentReg(SiS_Pr); SiS_ResetSegmentRegOver(SiS_Pr); }}/*********************************************//* HELPER: GetVBType *//*********************************************/#ifdef SIS_LINUX_KERNELstatic#endifvoidSiS_GetVBType(struct SiS_Private *SiS_Pr){ unsigned short flag = 0, rev = 0, nolcd = 0; unsigned short p4_0f, p4_25, p4_27; SiS_Pr->SiS_VBType = 0; if((SiS_Pr->SiS_IF_DEF_LVDS) || (SiS_Pr->SiS_IF_DEF_CONEX)) return; if(SiS_Pr->ChipType == XGI_20) return; flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00); if(flag > 3) return; rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01); if(flag >= 2) { SiS_Pr->SiS_VBType = VB_SIS302B; } else if(flag == 1) { if(rev >= 0xC0) { SiS_Pr->SiS_VBType = VB_SIS301C; } else if(rev >= 0xB0) { SiS_Pr->SiS_VBType = VB_SIS301B; /* Check if 30xB DH version (no LCD support, use Panel Link instead) */ nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23); if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD; } else { SiS_Pr->SiS_VBType = VB_SIS301; } } if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) { if(rev >= 0xE0) { flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x39); if(flag == 0xff) SiS_Pr->SiS_VBType = VB_SIS302LV; else SiS_Pr->SiS_VBType = VB_SIS301C; /* VB_SIS302ELV; */ } else if(rev >= 0xD0) { SiS_Pr->SiS_VBType = VB_SIS301LV; } } if(SiS_Pr->SiS_VBType & (VB_SIS301C | VB_SIS301LV | VB_SIS302LV | VB_SIS302ELV)) { p4_0f = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x0f); p4_25 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x25); p4_27 = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x27); SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x0f,0x7f); SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x25,0x08); SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x27,0xfd); if(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x08) { SiS_Pr->SiS_VBType |= VB_UMC; } SiS_SetReg(SiS_Pr->SiS_Part4Port,0x27,p4_27); SiS_SetReg(SiS_Pr->SiS_Part4Port,0x25,p4_25); SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0f,p4_0f); }}/*********************************************//* HELPER: Check RAM size *//*********************************************/#ifdef SIS_LINUX_KERNELstatic BOOLEANSiS_CheckMemorySize(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex){ unsigned short AdapterMemSize = SiS_Pr->VideoMemorySize / (1024*1024); unsigned short modeflag = SiS_GetModeFlag(SiS_Pr, ModeNo, ModeIdIndex); unsigned short memorysize = ((modeflag & MemoryInfoFlag) >> MemorySizeShift) + 1; if(!AdapterMemSize) return TRUE; if(AdapterMemSize < memorysize) return FALSE; return TRUE;}#endif/*********************************************//* HELPER: Get DRAM type *//*********************************************/#ifdef SIS315Hstatic unsigned charSiS_Get310DRAMType(struct SiS_Private *SiS_Pr){ unsigned char data; if((*SiS_Pr->pSiS_SoftSetting) & SoftDRAMType) { data = (*SiS_Pr->pSiS_SoftSetting) & 0x03; } else { if(SiS_Pr->ChipType >= XGI_20) { /* Do I need this? SR17 seems to be zero anyway... */ data = 0; } else if(SiS_Pr->ChipType >= SIS_340) { /* TODO */ data = 0; } if(SiS_Pr->ChipType >= SIS_661) { if(SiS_Pr->SiS_ROMNew) { data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6); } else { data = SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0x07; } } else if(IS_SIS550650740) { data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07; } else { /* 315, 330 */ data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03; if(SiS_Pr->ChipType == SIS_330) { if(data > 1) { switch(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30) { case 0x00: data = 1; break; case 0x10: data = 3; break; case 0x20: data = 3; break; case 0x30: data = 2; break; } } else { data = 0; } } } } return data;}static unsigned shortSiS_GetMCLK(struct SiS_Private *SiS_Pr){ unsigned char *ROMAddr = SiS_Pr->VirtualRomBase; unsigned short index; index = SiS_Get310DRAMType(SiS_Pr); if(SiS_Pr->ChipType >= SIS_661) { if(SiS_Pr->SiS_ROMNew) { return((unsigned short)(SISGETROMW((0x90 + (index * 5) + 3)))); } return(SiS_Pr->SiS_MCLKData_0[index].CLOCK); } else if(index >= 4) { return(SiS_Pr->SiS_MCLKData_1[index - 4].CLOCK); } else { return(SiS_Pr->SiS_MCLKData_0[index].CLOCK); }}#endif/*********************************************//* HELPER: ClearBuffer *//*********************************************/#ifdef SIS_LINUX_KERNELstatic voidSiS_ClearBuffer(struct SiS_Private *SiS_Pr, unsigned short ModeNo){ unsigned char SISIOMEMTYPE *memaddr = SiS_Pr->VideoMemoryAddress; unsigned int memsize = SiS_Pr->VideoMemorySize; unsigned short SISIOMEMTYPE *pBuffer; int i; if(!memaddr || !memsize) return; if(SiS_Pr->SiS_ModeType >= ModeEGA) { if(ModeNo > 0x13) { SiS_SetMemory(memaddr, memsize, 0); } else { pBuffer = (unsigned short SISIOMEMTYPE *)memaddr; for(i = 0; i < 0x4000; i++) writew(0x0000, &pBuffer[i]); } } else if(SiS_Pr->SiS_ModeType < ModeCGA) { pBuffer = (unsigned short SISIOMEMTYPE *)memaddr; for(i = 0; i < 0x4000; i++) writew(0x0720, &pBuffer[i]); } else { SiS_SetMemory(memaddr, 0x8000, 0); }}#endif/*********************************************//* HELPER: SearchModeID *//*********************************************/BOOLEANSiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, unsigned short *ModeIdIndex){ unsigned char VGAINFO = SiS_Pr->SiS_VGAINFO; if((*ModeNo) <= 0x13) { if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01; for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) { if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == (*ModeNo)) break; if(SiS_Pr->SiS_SModeIDTable[(*ModeIdIndex)].St_ModeID == 0xFF) return FALSE; } if((*ModeNo) == 0x07) { if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */ /* else 350 lines */ } if((*ModeNo) <= 0x03) { if(!(VGAINFO & 0x80)) (*ModeIdIndex)++; if(VGAINFO & 0x10) (*ModeIdIndex)++; /* 400 lines */ /* else 350 lines */ } /* else 200 lines */ } else { for((*ModeIdIndex) = 0; ;(*ModeIdIndex)++) { if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == (*ModeNo)) break; if(SiS_Pr->SiS_EModeIDTable[(*ModeIdIndex)].Ext_ModeID == 0xFF) return FALSE; } } return TRUE;}/*********************************************//* HELPER: GetModePtr *//*********************************************/unsigned shortSiS_GetModePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex){ unsigned short index; if(ModeNo <= 0x13) { index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex; } else { if(SiS_Pr->SiS_ModeType <= ModeEGA) index = 0x1B; else index = 0x0F; } return index;}/*********************************************//* HELPERS: Get some indices *//*********************************************/unsigned shortSiS_GetRefCRTVCLK(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide){ if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) { if(UseWide == 1) { return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_WIDE; } else { return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK_NORM; } } else { return SiS_Pr->SiS_RefIndex[Index].Ext_CRTVCLK; }}unsigned shortSiS_GetRefCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short Index, int UseWide){ if(SiS_Pr->SiS_RefIndex[Index].Ext_InfoFlag & HaveWideTiming) { if(UseWide == 1) { return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_WIDE; } else { return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC_NORM; } } else { return SiS_Pr->SiS_RefIndex[Index].Ext_CRT1CRTC; }}/*********************************************//* HELPER: LowModeTests *//*********************************************/static BOOLEANSiS_DoLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo){ unsigned short temp, temp1, temp2; if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12)) return TRUE; temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11); SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80); temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00); SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,0x55); temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00); SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,temp1); SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp); if((SiS_Pr->ChipType >= SIS_315H) || (SiS_Pr->ChipType == SIS_300)) { if(temp2 == 0x55) return FALSE; else return TRUE; } else { if(temp2 != 0x55) return TRUE; else { SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01); return FALSE; } }}static voidSiS_SetLowModeTest(struct SiS_Private *SiS_Pr, unsigned short ModeNo){ if(SiS_DoLowModeTest(SiS_Pr, ModeNo)) { SiS_Pr->SiS_SetFlag |= LowModeTests; }}/*********************************************//* HELPER: OPEN/CLOSE CRT1 CRTC *//*********************************************/static voidSiS_OpenCRTC(struct SiS_Private *SiS_Pr){ if(IS_SIS650) { SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f); if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20); SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7); } else if(IS_SIS661741660760) { SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x61,0xf7); SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f); SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7); if(!SiS_Pr->SiS_ROMNew) { SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x3a,0xef); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -