File: /usr/src/linux/drivers/video/sis/sis_300.c

1     /* Recently Update by v1.09.50 */
2     #include <linux/config.h>
3     #include "sis_300.h"
4     
5     #if defined(ALLOC_PRAGMA)
6     #pragma alloc_text(PAGE,SiSSetMode)
7     #pragma alloc_text(PAGE,SiSInit300)
8     #endif
9     
10     
11     #ifdef NOBIOS
12     BOOLEAN SiSInit300(PHW_DEVICE_EXTENSION HwDeviceExtension)
13     {
14     	ULONG	ROMAddr  = (ULONG)HwDeviceExtension->VirtualRomBase;
15     	ULONG	FBAddr	= (ULONG)HwDeviceExtension->VirtualVideoMemoryAddress;
16     	USHORT  BaseAddr = (USHORT)HwDeviceExtension->IOAddress;
17     	UCHAR	i,temp,AGP;
18     	ULONG	j,k,ulTemp;
19     	UCHAR	SR07,SR11,SR19,SR1A,SR1F,SR21,SR22,SR23,SR24,SR25,SR32;
20     	UCHAR	SR14;
21     	ULONG	Temp;
22     
23     	if(ROMAddr==0)	return (FALSE);
24     	if(FBAddr==0)	 return (FALSE);
25     	if(BaseAddr==0)  return (FALSE);
26     	if(HwDeviceExtension->jChipID >= SIS_Trojan)
27     		if(!HwDeviceExtension->bIntegratedMMEnabled)  return (FALSE);
28     
29     	P3c4=BaseAddr+0x14;
30     	P3d4=BaseAddr+0x24;
31     	P3c0=BaseAddr+0x10;
32     	P3ce=BaseAddr+0x1e;
33     	P3c2=BaseAddr+0x12;
34     	P3ca=BaseAddr+0x1a;
35     	P3c6=BaseAddr+0x16;
36     	P3c7=BaseAddr+0x17;
37     	P3c8=BaseAddr+0x18;
38     	P3c9=BaseAddr+0x19;
39     	P3da=BaseAddr+0x2A;
40     	Set_LVDS_TRUMPION();
41     
42     	SetReg1(P3c4,0x05,0x86);	// 1.Openkey
43     	SR14 = (UCHAR)GetReg1(P3c4,0x14);
44     	SR19 = (UCHAR)GetReg1(P3c4,0x19);
45     	SR1A = (UCHAR)GetReg1(P3c4,0x1A);
46     	for(i=0x06;i< 0x20;i++) SetReg1(P3c4,i,0);	// 2.Reset Extended register
47     	for(i=0x21;i<=0x27;i++) SetReg1(P3c4,i,0);	//	Reset Extended register
48     	for(i=0x31;i<=0x3D;i++) SetReg1(P3c4,i,0);
49     	for(i=0x30;i<=0x37;i++) SetReg1(P3d4,i,0);
50     
51     	if(HwDeviceExtension->jChipID >= SIS_Trojan)
52     		temp=(UCHAR)SR1A;		// 3.Set Define Extended register
53     	else
54     	{
55     		temp=*((UCHAR *)(ROMAddr+SoftSettingAddr));
56     		if((temp&SoftDRAMType)==0){					
57     			temp=(UCHAR)GetReg1(P3c4,0x3A);	// 3.Set Define Extended register
58     		}
59     	} 
60     	RAMType=temp&0x07;
61     	SetMemoryClock(ROMAddr);
62     	for(k=0; k<5; k++)
63     	{
64     		for(j=0; j<0xffff; j++)
65     		{
66     			ulTemp = (ULONG)GetReg1(P3c4, 0x05);
67     		}
68     	}
69     	Temp = (ULONG)GetReg1(P3c4, 0x3C);
70     	Temp = Temp | 0x01;
71     	SetReg1(P3c4, 0x3C, (USHORT)Temp);
72     	for(k=0; k<5; k++)
73     	{
74     		for(j=0; j<0xffff; j++)
75     		{
76     			Temp = (ULONG)GetReg1(P3c4, 0x05);
77     		}
78     	}
79     	Temp = (ULONG)GetReg1(P3c4, 0x3C);
80     	Temp = Temp & 0xFE;
81     	SetReg1(P3c4, 0x3C, (USHORT)Temp);
82     	for(k=0; k<5; k++)
83     	{
84     		for(j=0; j<0xffff; j++)
85     		{
86     			Temp = (ULONG)GetReg1(P3c4, 0x05);
87     		}
88     	}
89     
90     	SR07=*((UCHAR *)(ROMAddr+0xA4));
91     	SetReg1(P3c4,0x07,SR07);
92     	if (HwDeviceExtension->jChipID == SIS_Glamour )
93     	{
94     		for(i=0x15;i<=0x1C;i++) 
95     		{
96     			temp=*((UCHAR *)(ROMAddr+0xA5+((i-0x15)*8)+RAMType));
97     			SetReg1(P3c4,i,temp);
98     		}
99     	}
100     
101     	SR1F=*((UCHAR *)(ROMAddr+0xE5));
102     	SetReg1(P3c4,0x1F,SR1F);
103     
104     	AGP=1;							// Get AGP
105     	temp=(UCHAR)GetReg1(P3c4,0x3A);
106     	temp=temp&0x30;
107     	if(temp==0x30) AGP=0;			// PCI
108     
109     	SR21=*((UCHAR *)(ROMAddr+0xE6));
110     	if(AGP==0) SR21=SR21&0xEF;		// PCI
111     	SetReg1(P3c4,0x21,SR21);
112     
113     	SR22=*((UCHAR *)(ROMAddr+0xE7));
114     	if(AGP==1) SR22=SR22&0x20;		// AGP
115     	SetReg1(P3c4,0x22,SR22);
116     
117     	SR23=*((UCHAR *)(ROMAddr+0xE8));
118     	SetReg1(P3c4,0x23,SR23);
119     
120     	SR24=*((UCHAR *)(ROMAddr+0xE9));
121     	SetReg1(P3c4,0x24,SR24);
122     
123     	SR25=*((UCHAR *)(ROMAddr+0xEA));
124     	SetReg1(P3c4,0x25,SR25);
125     
126     	SR32=*((UCHAR *)(ROMAddr+0xEB));
127     	SetReg1(P3c4,0x32,SR32);
128     
129     	SR11=0x0F;
130     	SetReg1(P3c4,0x11,SR11);
131     
132     	if(IF_DEF_LVDS==1){				//LVDS
133     		temp=ExtChipLVDS;
134     	}else if(IF_DEF_TRUMPION==1){ 	//Trumpion
135     		temp=ExtChipTrumpion;
136     	}else{ 			//301
137     		temp=ExtChip301;
138     	}
139     	SetReg1(P3d4,0x37,temp);
140     
141     	//For SiS 630/540 Chip
142     	//Restore SR14, SR19 and SR1A
143     	SetReg1(P3c4,0x14,SR14);
144     	SetReg1(P3c4,0x19,SR19);
145     	SetReg1(P3c4,0x1A,SR1A);
146     
147     	SetReg3(P3c6,0xff);		// Reset register
148     	ClearDAC(P3c8);			// Reset register
149     	DetectMonitor(HwDeviceExtension);	 //sense CRT1
150     	GetSenseStatus(HwDeviceExtension,BaseAddr,ROMAddr);//sense CRT2		
151     	
152     	return(TRUE);
153     }
154     
155     VOID Set_LVDS_TRUMPION(VOID)
156     {
157     	IF_DEF_LVDS=0;
158     	IF_DEF_TRUMPION=0;	 
159     }
160     
161     VOID SetMemoryClock(ULONG ROMAddr)
162     {
163     	UCHAR data,i;
164     
165     	MCLKData=*((USHORT *)(ROMAddr+0x20C));		// MCLKData Table
166     	MCLKData=MCLKData+RAMType*5;
167     	ECLKData=MCLKData+0x28;
168     
169     	for(i=0x28;i<=0x2A;i++) {					// Set MCLK
170     		data=*((UCHAR *)(ROMAddr+MCLKData));
171     		SetReg1(P3c4,i,data);
172     		MCLKData++;
173     	}
174     
175     	for(i=0x2E;i<=0x30;i++) {					// Set ECLK
176     		data=*((UCHAR *)(ROMAddr+ECLKData));
177     		SetReg1(P3c4,i,data);
178     		ECLKData++;
179     	}
180     }
181     #endif   /* NOBIOS */
182     
183     #ifdef CONFIG_FB_SIS_LINUXBIOS
184     BOOLEAN SiSInit300(PHW_DEVICE_EXTENSION HwDeviceExtension)
185     {
186     	ULONG	ROMAddr  = 0;
187     	USHORT  BaseAddr = (USHORT)HwDeviceExtension->IOAddress;
188     	UCHAR	i,temp,AGP;
189     	ULONG	j,k,ulTemp;
190     	UCHAR	SR07,SR11,SR19,SR1A,SR1F,SR21,SR22,SR23,SR24,SR25,SR32;
191     	UCHAR	SR14;
192     	ULONG	Temp;
193     
194     	if(BaseAddr==0)  return (FALSE);
195     	if(HwDeviceExtension->jChipID >= SIS_Trojan)
196     		if(!HwDeviceExtension->bIntegratedMMEnabled)  return (FALSE);
197     
198     	P3c4=BaseAddr+0x14;
199     	P3d4=BaseAddr+0x24;
200     	P3c0=BaseAddr+0x10;
201     	P3ce=BaseAddr+0x1e;
202     	P3c2=BaseAddr+0x12;
203     	P3ca=BaseAddr+0x1a;
204     	P3c6=BaseAddr+0x16;
205     	P3c7=BaseAddr+0x17;
206     	P3c8=BaseAddr+0x18;
207     	P3c9=BaseAddr+0x19;
208     	P3da=BaseAddr+0x2A;
209     
210     	SetReg1(P3c4,0x05,0x86);	// 1.Openkey
211     
212     	SR14 = (UCHAR)GetReg1(P3c4,0x14);
213     	SR19 = (UCHAR)GetReg1(P3c4,0x19);
214     	SR1A = (UCHAR)GetReg1(P3c4,0x1A);
215     
216     	for(i=0x06;i< 0x20;i++) SetReg1(P3c4,i,0);	// 2.Reset Extended register
217     	for(i=0x21;i<=0x27;i++) SetReg1(P3c4,i,0);	//	Reset Extended register
218     	for(i=0x31;i<=0x3D;i++) SetReg1(P3c4,i,0);
219     	for(i=0x30;i<=0x37;i++) SetReg1(P3d4,i,0);
220     
221     	temp=(UCHAR)SR1A;		// 3.Set Define Extended register
222     
223     	RAMType=temp&0x07;
224     	SetMemoryClock(ROMAddr);
225     	for(k=0; k<5; k++)
226     		for(j=0; j<0xffff; j++)
227     			ulTemp = (ULONG)GetReg1(P3c4, 0x05);
228     
229     	Temp = (ULONG)GetReg1(P3c4, 0x3C);
230     	Temp = Temp | 0x01;
231     	SetReg1(P3c4, 0x3C, (USHORT)Temp);
232     
233     	for(k=0; k<5; k++)
234     		for(j=0; j<0xffff; j++)
235     			Temp = (ULONG)GetReg1(P3c4, 0x05);
236     
237     	Temp = (ULONG)GetReg1(P3c4, 0x3C);
238     	Temp = Temp & 0xFE;
239     	SetReg1(P3c4, 0x3C, (USHORT)Temp);
240     
241     	for(k=0; k<5; k++)
242     		for(j=0; j<0xffff; j++)
243     			Temp = (ULONG)GetReg1(P3c4, 0x05);
244     
245     	SR07=SRegsInit[0x07];
246     	SetReg1(P3c4,0x07,SR07);
247     
248     	SR1F=SRegsInit[0x1F];
249     	SetReg1(P3c4,0x1F,SR1F);
250     
251     	AGP=1;							// Get AGP
252     	temp=(UCHAR)GetReg1(P3c4,0x3A);
253     	temp=temp&0x30;
254     	if(temp==0x30) AGP=0;			// PCI
255     
256     	SR21=SRegsInit[0x21];
257     	if(AGP==0) SR21=SR21&0xEF;		// PCI
258     	SetReg1(P3c4,0x21,SR21);
259     
260     	SR22=SRegsInit[0x22];
261     	if(AGP==1) SR22=SR22&0x20;		// AGP
262     	SetReg1(P3c4,0x22,SR22);
263     
264     	SR23=SRegsInit[0x23];
265     	SetReg1(P3c4,0x23,SR23);
266     
267     	SR24=SRegsInit[0x24];
268     	SetReg1(P3c4,0x24,SR24);
269     
270     	SR25=SRegsInit[0x25];
271     	SetReg1(P3c4,0x25,SR25);
272     
273     	SR32=SRegsInit[0x32];
274     	SetReg1(P3c4,0x32,SR32);
275     
276     	SR11=0x0F;
277     	SetReg1(P3c4,0x11,SR11);
278     
279     	temp=ExtChip301;
280     	SetReg1(P3d4,0x37,temp);
281     
282     	SetReg1(P3c4,0x14,SR14);
283     	SetReg1(P3c4,0x19,SR19);
284     	SetReg1(P3c4,0x1A,SR1A);
285     
286     	SetReg3(P3c6,0xff);		// Reset register
287     	ClearDAC(P3c8);			// Reset register
288     	DetectMonitor(HwDeviceExtension);	 //sense CRT1
289     	
290     	return(TRUE);
291     }
292     
293     VOID SetMemoryClock(ULONG ROMAddr)
294     {
295     	UCHAR  i;
296     	USHORT idx;
297     
298     	u8 MCLK[] = {
299     		0x5A, 0x64, 0x80, 0x66, 0x00,	// SDRAM
300     		0xB3, 0x45, 0x80, 0x83, 0x00,	// SGRAM
301     		0x37, 0x61, 0x80, 0x00, 0x01,	// ESDRAM
302     		0x37, 0x22, 0x80, 0x33, 0x01,
303     		0x37, 0x61, 0x80, 0x00, 0x01,
304     		0x37, 0x61, 0x80, 0x00, 0x01,
305     		0x37, 0x61, 0x80, 0x00, 0x01,
306     		0x37, 0x61, 0x80, 0x00, 0x01
307     	};
308     
309     	u8 ECLK[] = {
310     		0x54, 0x43, 0x80, 0x00, 0x01,
311     		0x53, 0x43, 0x80, 0x00, 0x01,
312     		0x55, 0x43, 0x80, 0x00, 0x01,
313     		0x52, 0x43, 0x80, 0x00, 0x01,
314     		0x3f, 0x42, 0x80, 0x00, 0x01,
315     		0x54, 0x43, 0x80, 0x00, 0x01,
316     		0x54, 0x43, 0x80, 0x00, 0x01,
317     		0x54, 0x43, 0x80, 0x00, 0x01
318     	};
319     
320     	idx = RAMType * 5;
321     
322     	for (i = 0x28; i <= 0x2A; i++) {	// Set MCLK
323     		SetReg1(P3c4, i, MCLK[idx]);
324     		idx++;
325     	}
326     
327     	idx = RAMType * 5;
328     	for (i = 0x2E; i <= 0x30; i++) {	// Set ECLK
329     		SetReg1(P3c4, i, ECLK[idx]);
330     		idx++;
331     	}
332     
333     }
334     
335     #endif   /* CONFIG_FB_SIS_LINUXBIOS */
336     
337     // =========================================
338     // ======== SiS SetMode Function  ==========
339     // =========================================
340     
341     #ifdef CONFIG_FB_SIS_LINUXBIOS
342     BOOLEAN SiSSetMode(PHW_DEVICE_EXTENSION HwDeviceExtension,
343     						 USHORT ModeNo)
344     {
345     	ULONG	i;
346     	USHORT  cr30flag,cr31flag;
347     	ULONG	ROMAddr  = (ULONG)HwDeviceExtension->VirtualRomBase;
348     	USHORT  BaseAddr = (USHORT)HwDeviceExtension->IOAddress;
349     
350     	P3c4=BaseAddr+0x14;
351     	P3d4=BaseAddr+0x24;
352     	P3c0=BaseAddr+0x10;
353     	P3ce=BaseAddr+0x1e;
354     	P3c2=BaseAddr+0x12;
355     	P3ca=BaseAddr+0x1a;
356     	P3c6=BaseAddr+0x16;
357     	P3c7=BaseAddr+0x17;
358     	P3c8=BaseAddr+0x18;
359     	P3c9=BaseAddr+0x19;
360     	P3da=BaseAddr+0x2A;
361     
362     	cr30flag=(UCHAR)GetReg1(P3d4,0x30);
363     
364     	if(((cr30flag&0x01)==1)||((cr30flag&0x02)==0)){
365     		SetReg1(P3d4,0x34,ModeNo); 
366     		//SetSeqRegs(ROMAddr);
367     		{
368     			UCHAR SRdata;
369     			SRdata = SRegs[0x01] | 0x20;
370     			SetReg1(P3c4, 0x01, SRdata);
371     
372     			for (i = 02; i <= 04; i++)
373     				SetReg1(P3c4, i, SRegs[i]);
374     		}
375     
376     		//SetMiscRegs(ROMAddr);
377     		{
378     			SetReg3(P3c2, 0x23);
379     		}
380     
381     		//SetCRTCRegs(ROMAddr);
382     		{
383     			UCHAR CRTCdata;
384     
385     			CRTCdata = (UCHAR) GetReg1(P3d4, 0x11);
386     			SetReg1(P3d4, 0x11, CRTCdata);
387     
388     			for (i = 0; i <= 0x18; i++)
389     				SetReg1(P3d4, i, CRegs[i]);
390     		}
391     
392     		//SetATTRegs(ROMAddr);
393     		{
394     			for (i = 0; i <= 0x13; i++) {
395     				GetReg2(P3da);
396     				SetReg3(P3c0, i);
397     				SetReg3(P3c0, ARegs[i]);
398     			}
399     			GetReg2(P3da);
400     			SetReg3(P3c0, 0x14);
401     			SetReg3(P3c0, 0x00);
402     			GetReg2(P3da);
403     			SetReg3(P3c0, 0x20);
404     		}
405     
406     		//SetGRCRegs(ROMAddr);
407     		{
408     			for (i = 0; i <= 0x08; i++)
409     				SetReg1(P3ce, i, GRegs[i]);
410     		}
411     
412     		//ClearExt1Regs();
413     		{
414     			for (i = 0x0A; i <= 0x0E; i++)
415     				SetReg1(P3c4, i, 0x00);
416     		}
417     
418     
419     		//SetSync(ROMAddr);
420     		{
421     			SetReg3(P3c2, MReg);
422     		}
423     
424     		//SetCRT1CRTC(ROMAddr);
425     		{
426     			UCHAR data;
427     
428     			data = (UCHAR) GetReg1(P3d4, 0x11);
429     			data = data & 0x7F;
430     			SetReg1(P3d4, 0x11, data);
431     
432     			for (i = 0; i <= 0x07; i++)
433     				SetReg1(P3d4, i, CRegs[i]);
434     			for (i = 0x10; i <= 0x12; i++)
435     				SetReg1(P3d4, i, CRegs[i]);
436     			for (i = 0x15; i <= 0x16; i++)
437     				SetReg1(P3d4, i, CRegs[i]);
438     			for (i = 0x0A; i <= 0x0C; i++)
439     				SetReg1(P3c4, i, SRegs[i]);
440     
441     			data = SRegs[0x0E] & 0xE0;
442     			SetReg1(P3c4, 0x0E, data);
443     
444     			SetReg1(P3d4, 0x09, CRegs[0x09]);
445     		}
446     
447     		//SetCRT1Offset(ROMAddr);
448     		{
449     			SetReg1(P3c4, 0x0E, SRegs[0x0E]);
450     			SetReg1(P3c4, 0x10, SRegs[0x10]);
451     		}
452     
453     		//SetCRT1VCLK(HwDeviceExtension, ROMAddr);
454     		{
455     			SetReg1(P3c4, 0x31, 0);
456     
457     			for (i = 0x2B; i <= 0x2C; i++)
458     				SetReg1(P3c4, i, SRegs[i]);
459     			SetReg1(P3c4, 0x2D, 0x80);
460     		}
461     
462     		//SetVCLKState(HwDeviceExtension, ROMAddr, ModeNo);
463     		{
464     			SetReg1(P3c4, 0x32, SRegs[0x32]);
465     			SetReg1(P3c4, 0x07, SRegs[0x07]);
466     		}
467     
468     		//SetCRT1FIFO2(ROMAddr);
469     		{
470     			SetReg1(P3c4, 0x15, SRegs[0x15]);
471     
472     			SetReg4(0xcf8, 0x80000050);
473     			SetReg4(0xcfc, 0xc5041e04);
474     
475     			SetReg1(P3c4, 0x08, SRegs[0x08]);
476     			SetReg1(P3c4, 0x0F, SRegs[0x0F]);
477     			SetReg1(P3c4, 0x3b, 0x00);
478     			SetReg1(P3c4, 0x09, SRegs[0x09]);
479     		}
480     
481     		//SetCRT1ModeRegs(ROMAddr, ModeNo);
482     		{
483     			SetReg1(P3c4, 0x06, SRegs[0x06]);
484     			SetReg1(P3c4, 0x01, SRegs[0x01]);
485     			SetReg1(P3c4, 0x0F, SRegs[0x0F]);
486     			SetReg1(P3c4, 0x21, SRegs[0x21]);
487     		}
488     
489     		if(HwDeviceExtension->jChipID >= SIS_Trojan)
490     		{
491     			//SetInterlace(ROMAddr,ModeNo);
492     			SetReg1(P3d4, 0x19, CRegs[0x19]);
493     			SetReg1(P3d4, 0x1A, CRegs[0x1A]);
494     		}
495     
496     		LoadDAC(ROMAddr);
497     
498     		ClearBuffer(HwDeviceExtension);
499     	}
500     
501     	cr31flag=(UCHAR)GetReg1(P3d4,0x31);
502     	DisplayOn();	// 16.DisplayOn
503     	return(NO_ERROR);
504     }
505     
506     VOID LoadDAC(ULONG ROMAddr)
507     {
508     	USHORT data,data2;
509     	USHORT time,i,j,k;
510     	USHORT m,n,o;
511     	USHORT si,di,bx,dl;
512     	USHORT al,ah,dh;
513     	USHORT *table=VGA_DAC;
514     
515     	time=256;
516     	table=VGA_DAC;
517     	j=16;
518     
519     	SetReg3(P3c6,0xFF);
520     	SetReg3(P3c8,0x00);
521     
522     	for(i=0;i<j;i++) {
523     		data=table[i];
524     		for(k=0;k<3;k++) {
525     			data2=0;
526     			if(data&0x01) data2=0x2A;
527     			if(data&0x02) data2=data2+0x15;
528     			SetReg3(P3c9,data2);
529     			data=data>>2;
530     		}
531     	}
532     
533     	if(time==256) {
534     		for(i=16;i<32;i++) {
535     			data=table[i];
536     			for(k=0;k<3;k++) SetReg3(P3c9,data);
537     		}
538     		si=32;
539     		for(m=0;m<9;m++) {
540     			di=si;
541     			bx=si+0x04;
542     			dl=0;
543     			for(n=0;n<3;n++) {
544     				for(o=0;o<5;o++) {
545     					dh=table[si];
546     					ah=table[di];
547     					al=table[bx];
548     					si++;
549     					WriteDAC(dl,ah,al,dh);
550     				}	
551     				si=si-2;
552     				for(o=0;o<3;o++) {
553     					dh=table[bx];
554     					ah=table[di];
555     					al=table[si];
556     					si--;
557     					WriteDAC(dl,ah,al,dh);
558     				}	
559     				dl++;
560     			}
561     			si=si+5;
562     		}
563     	}
564     }
565     
566     VOID WriteDAC(USHORT dl, USHORT ah, USHORT al, USHORT dh)
567     {
568     	USHORT temp;
569     	USHORT bh,bl;
570     
571     	bh=ah;
572     	bl=al;
573     	if(dl!=0) {
574     		temp=bh;
575     		bh=dh;
576     		dh=temp;
577     		if(dl==1) {
578     			temp=bl;
579     			bl=dh;
580     			dh=temp;
581     		}
582     		else {
583     			temp=bl;
584     			bl=bh;
585     			bh=temp;
586     		}
587     	}
588     	SetReg3(P3c9,(USHORT)dh);
589     	SetReg3(P3c9,(USHORT)bh);
590     	SetReg3(P3c9,(USHORT)bl);
591     }
592     
593     
594     VOID DisplayOn()
595     {
596     	USHORT data;
597     
598     	data=GetReg1(P3c4,0x01);
599     	data=data&0xDF;
600     	SetReg1(P3c4,0x01,data);
601     }
602     
603     
604     #else
605     BOOLEAN SiSSetMode(PHW_DEVICE_EXTENSION HwDeviceExtension,
606     						 USHORT ModeNo)
607     {
608     	ULONG	temp;
609     	USHORT  cr30flag,cr31flag;
610     	ULONG	ROMAddr  = (ULONG)HwDeviceExtension->VirtualRomBase;
611     	USHORT  BaseAddr = (USHORT)HwDeviceExtension->IOAddress;
612     
613     	P3c4=BaseAddr+0x14;
614     	P3d4=BaseAddr+0x24;
615     	P3c0=BaseAddr+0x10;
616     	P3ce=BaseAddr+0x1e;
617     	P3c2=BaseAddr+0x12;
618     	P3ca=BaseAddr+0x1a;
619     	P3c6=BaseAddr+0x16;
620     	P3c7=BaseAddr+0x17;
621     	P3c8=BaseAddr+0x18;
622     	P3c9=BaseAddr+0x19;
623     	P3da=BaseAddr+0x2A;
624     	if(ModeNo&0x80){
625     	  ModeNo=ModeNo&0x7F;
626     	  flag_clearbuffer=0;		  
627     	}else{
628     	  flag_clearbuffer=1;
629     	}
630     
631     	PresetScratchregister(P3d4,HwDeviceExtension); //add for CRT2
632     
633     	SetReg1(P3c4,0x05,0x86);				// 1.Openkey
634     	temp=SearchModeID(ROMAddr,ModeNo);		// 2.Get ModeID Table
635     	if(temp==0)  return(0);
636     	
637     	SetTVSystem(HwDeviceExtension,ROMAddr);	//add for CRT2
638     	GetLCDDDCInfo(HwDeviceExtension);		//add for CRT2
639     	GetVBInfo(BaseAddr,ROMAddr);			//add for CRT2
640     	GetLCDResInfo(ROMAddr,P3d4);			//add for CRT2
641     
642     	temp=CheckMemorySize(ROMAddr);			// 3.Check memory size
643     	if(temp==0) return(0);
644     	cr30flag=(UCHAR)GetReg1(P3d4,0x30);
645     	if(((cr30flag&0x01)==1)||((cr30flag&0x02)==0)){
646     		// if cr30 d[0]=1 or d[1]=0 set crt1  
647     		SetReg1(P3d4,0x34,ModeNo); 
648     		// set CR34->CRT1 ModeNofor CRT2 FIFO
649     		GetModePtr(ROMAddr,ModeNo);			// 4.GetModePtr
650     		SetSeqRegs(ROMAddr);				// 5.SetSeqRegs
651     		SetMiscRegs(ROMAddr);				// 6.SetMiscRegs
652     		SetCRTCRegs(ROMAddr);				// 7.SetCRTCRegs
653     		SetATTRegs(ROMAddr);				// 8.SetATTRegs
654     		SetGRCRegs(ROMAddr);				// 9.SetGRCRegs
655     		ClearExt1Regs();					// 10.Clear Ext1Regs
656     		temp=GetRatePtr(ROMAddr,ModeNo);	// 11.GetRatePtr
657     		if(temp) {
658     			SetSync(ROMAddr);				// 12.SetSync
659     			SetCRT1CRTC(ROMAddr);			// 13.SetCRT1CRTC
660     			SetCRT1Offset(ROMAddr);			// 14.SetCRT1Offset
661     			SetCRT1VCLK(HwDeviceExtension, ROMAddr);	// 15.SetCRT1VCLK
662     			SetVCLKState(HwDeviceExtension, ROMAddr, ModeNo);
663     			if(HwDeviceExtension->jChipID >= SIS_Trojan)
664     				SetCRT1FIFO2(ROMAddr);
665     			else
666     				SetCRT1FIFO(ROMAddr);
667     		}
668     		SetCRT1ModeRegs(ROMAddr, ModeNo);
669     		if(HwDeviceExtension->jChipID >= SIS_Trojan)
670     			SetInterlace(ROMAddr,ModeNo);
671     		LoadDAC(ROMAddr);
672     		if(flag_clearbuffer) ClearBuffer(HwDeviceExtension);
673     	}
674     
675     	cr31flag=(UCHAR)GetReg1(P3d4,0x31);
676     	if(((cr30flag&0x01)==1)||((cr30flag&0x03)==0x02)
677     	  ||(((cr30flag&0x03)==0x00)&&((cr31flag&0x20)==0x20))){
678     		//if CR30 d[0]=1 or d[1:0]=10, set CRT2 or cr30 cr31== 0x00 0x20	
679     		SetCRT2Group(BaseAddr,ROMAddr,ModeNo, HwDeviceExtension); //CRT2
680     	}
681     	DisplayOn();	// 16.DisplayOn
682     	return(NO_ERROR);
683     }
684     
685     BOOLEAN SearchModeID(ULONG ROMAddr, USHORT ModeNo)
686     {
687     	UCHAR ModeID;
688     	USHORT  usIDLength;
689     
690     	ModeIDOffset=*((USHORT *)(ROMAddr+0x20A));		// Get EModeIDTable
691     	ModeID=*((UCHAR *)(ROMAddr+ModeIDOffset));		// Offset 0x20A
692     	usIDLength = GetModeIDLength(ROMAddr, ModeNo);
693     	while(ModeID!=0xff && ModeID!=ModeNo) {
694     		ModeIDOffset=ModeIDOffset+usIDLength;
695     		ModeID=*((UCHAR *)(ROMAddr+ModeIDOffset));
696     	}
697     	if(ModeID==0xff) return(FALSE);
698     	else return(TRUE);
699     }
700     
701     BOOLEAN CheckMemorySize(ULONG ROMAddr)
702     {
703     	USHORT memorysize;
704     	USHORT modeflag;
705     	USHORT temp;
706     
707     	modeflag=*((USHORT *)(ROMAddr+ModeIDOffset+0x01));	// si+St_ModeFlag
708     	ModeType=modeflag&ModeInfoFlag;				// Get mode type
709     
710     	memorysize=modeflag&MemoryInfoFlag;
711     	memorysize=memorysize>MemorySizeShift;
712     	memorysize++;								// Get memory size
713     
714     	temp=GetReg1(P3c4,0x14);					// Get DRAM Size
715     	temp=temp&0x3F;
716     	temp++;
717     
718     	if(temp<memorysize) return(FALSE);
719     	else return(TRUE);
720     }
721     
722     VOID GetModePtr(ULONG ROMAddr, USHORT ModeNo)
723     {
724     	UCHAR index;
725     
726     	StandTable=*((USHORT *)(ROMAddr+0x202));	// Get First  0x202
727     												// StandTable Offset
728     	if(ModeNo<=13) {
729     		index=*((UCHAR *)(ROMAddr+ModeIDOffset+0x03));	// si+St_ModeFlag
730     	}
731     	else {
732     		if(ModeType <= 0x02) index=0x1B;		// 02 -> ModeEGA
733     		else index=0x0F;
734     	}
735     
736     	StandTable=StandTable+64*index;				// Get ModeNo StandTable
737     
738     }
739     
740     VOID SetSeqRegs(ULONG ROMAddr)
741     {
742     	UCHAR SRdata;
743     	USHORT i;
744     
745     	SetReg1(P3c4,0x00,0x03);					// Set SR0
746     	StandTable=StandTable+0x05;
747     	SRdata=*((UCHAR *)(ROMAddr+StandTable));	// Get SR01 from file
748     	if(IF_DEF_LVDS==1){
749     		if(VBInfo&SetCRT2ToLCD){
750     			if(VBInfo&SetInSlaveMode){
751     				if(LCDInfo&LCDNonExpanding){
752     					SRdata=SRdata|0x01;
753     				}
754     			}
755     		}
756     	}
757     
758     	SRdata=SRdata|0x20;
759     	SetReg1(P3c4,0x01,SRdata);					// Set SR1
760     	for(i=02;i<=04;i++) {
761     		StandTable++;
762     		SRdata=*((UCHAR *)(ROMAddr+StandTable));	// Get SR2,3,4 from file
763     		SetReg1(P3c4,i,SRdata);					// Set SR2 3 4
764     	}
765     }
766     
767     VOID SetMiscRegs(ULONG ROMAddr)
768     {
769     	UCHAR Miscdata;
770     
771     	StandTable++;
772     	Miscdata=*((UCHAR *)(ROMAddr+StandTable));	// Get Misc from file
773     	SetReg3(P3c2,Miscdata);						// Set Misc(3c2)
774     }
775     
776     VOID SetCRTCRegs(ULONG ROMAddr)
777     {
778     	UCHAR CRTCdata;
779     	USHORT i;
780     
781     	CRTCdata=(UCHAR)GetReg1(P3d4,0x11);
782     	CRTCdata=CRTCdata&0x7f;
783     	SetReg1(P3d4,0x11,CRTCdata);				// Unlock CRTC
784     
785     	for(i=0;i<=0x18;i++) {
786     		StandTable++;
787     		CRTCdata=*((UCHAR *)(ROMAddr+StandTable));		// Get CRTC from file
788     		SetReg1(P3d4,i,CRTCdata);				// Set CRTC(3d4)
789     	}
790     }
791     
792     VOID SetATTRegs(ULONG ROMAddr)
793     {
794     	UCHAR ARdata;
795     	USHORT i;
796     
797     	for(i=0;i<=0x13;i++) {
798     		StandTable++;
799     		ARdata=*((UCHAR *)(ROMAddr+StandTable));	  // Get AR for file
800     		if(IF_DEF_LVDS==1){  //for LVDS
801     			if(VBInfo&SetCRT2ToLCD){
802     				if(VBInfo&SetInSlaveMode){
803     					if(LCDInfo&LCDNonExpanding){
804     				 		if(i==0x13){
805     							ARdata=0;
806     				 		}
807     					}
808     				}
809     			}
810     		}
811     		GetReg2(P3da);			// reset 3da
812     		SetReg3(P3c0,i);		// set index
813     		SetReg3(P3c0,ARdata);	// set data
814     	}
815     	if(IF_DEF_LVDS==1){  //for LVDS
816     		if(VBInfo&SetCRT2ToLCD){
817     			if(VBInfo&SetInSlaveMode){
818     				if(LCDInfo&LCDNonExpanding){
819     				
820     				}
821     		 	}
822     		}
823     	}
824     	GetReg2(P3da);			// reset 3da
825     	SetReg3(P3c0,0x14);		// set index
826     	SetReg3(P3c0,0x00);		// set data
827     
828     	GetReg2(P3da);			// Enable Attribute
829     	SetReg3(P3c0,0x20);
830     }
831     
832     VOID SetGRCRegs(ULONG ROMAddr)
833     {
834     	UCHAR GRdata;
835     	USHORT i;
836     
837     	for(i=0;i<=0x08;i++) {
838     		StandTable++;
839     		GRdata=*((UCHAR *)(ROMAddr+StandTable));	// Get GR from file
840     		SetReg1(P3ce,i,GRdata);						// Set GR(3ce)
841     	}
842     	if(ModeType>ModeVGA){
843     		GRdata=(UCHAR)GetReg1(P3ce,0x05);
844     		GRdata=GRdata&0xBF;
845     		SetReg1(P3ce,0x05,GRdata); 
846     	}
847     }
848     
849     VOID ClearExt1Regs()
850     {
851     	USHORT i;
852     
853     	for(i=0x0A;i<=0x0E;i++) SetReg1(P3c4,i,0x00);	// Clear SR0A-SR0E
854     }
855     
856     
857     BOOLEAN GetRatePtr(ULONG ROMAddr, USHORT ModeNo)
858     {
859     	SHORT	index;
860       	USHORT temp;
861       	USHORT ulRefIndexLength;
862     
863     	if(ModeNo<0x14) return(FALSE);				// Mode No <= 13h then return
864     
865     	index=GetReg1(P3d4,0x33);					// Get 3d4 CRTC33
866     	index=index&0x0F;							// Frame rate index
867     	if(index!=0) index--;
868     	REFIndex=*((USHORT *)(ROMAddr+ModeIDOffset+0x04));	// si+Ext_point
869     
870     	ulRefIndexLength = GetRefindexLength(ROMAddr, ModeNo);
871     	do {
872     		temp=*((USHORT *)(ROMAddr+REFIndex));	// di => REFIndex
873     		if(temp==0xFFFF) break;
874     		temp=temp&ModeInfoFlag;
875     		if(temp<ModeType) break;
876     
877     		REFIndex=REFIndex+ulRefIndexLength;		// rate size
878     		index--;
879     	} while(index>=0);
880     
881     	REFIndex=REFIndex-ulRefIndexLength;			// rate size
882     	return(TRUE);
883     }
884     
885     VOID SetSync(ULONG ROMAddr)
886     {
887     	USHORT sync;
888     	USHORT temp;
889     
890     	sync=*((USHORT *)(ROMAddr+REFIndex));		// di+0x00
891     	sync=sync&0xC0;
892     	temp=0x2F;
893     	temp=temp|sync;
894     	SetReg3(P3c2,temp);							// Set Misc(3c2)
895     }
896     
897     VOID SetCRT1CRTC(ULONG ROMAddr)
898     {
899     	UCHAR  index;
900     	UCHAR  data;
901     	USHORT i;
902     
903     	index=*((UCHAR *)(ROMAddr+REFIndex+0x02));	// Get index
904     	index=index&0x03F;
905     	CRT1Table=*((USHORT *)(ROMAddr+0x204));		// Get CRT1Table
906     	CRT1Table=CRT1Table+index*CRT1Len;
907     
908     	data=(UCHAR)GetReg1(P3d4,0x11);
909     	data=data&0x7F;
910     	SetReg1(P3d4,0x11,data);					// Unlock CRTC
911     
912     	CRT1Table--;
913     	for(i=0;i<=0x05;i++) {
914     		CRT1Table++;
915     		data=*((UCHAR *)(ROMAddr+CRT1Table));
916     		SetReg1(P3d4,i,data);
917     	}
918     	for(i=0x06;i<=0x07;i++) {
919     		CRT1Table++;
920     		data=*((UCHAR *)(ROMAddr+CRT1Table));
921     		SetReg1(P3d4,i,data);
922     	}
923     	for(i=0x10;i<=0x12;i++) {
924     		CRT1Table++;
925     		data=*((UCHAR *)(ROMAddr+CRT1Table));
926     		SetReg1(P3d4,i,data);
927     	}
928     	for(i=0x15;i<=0x16;i++) {
929     		CRT1Table++;
930     		data=*((UCHAR *)(ROMAddr+CRT1Table));
931     		SetReg1(P3d4,i,data);
932     	}
933     	for(i=0x0A;i<=0x0C;i++) {
934     		CRT1Table++;
935     		data=*((UCHAR *)(ROMAddr+CRT1Table));
936     		SetReg1(P3c4,i,data);
937     	}
938     
939     	CRT1Table++;
940     	data=*((UCHAR *)(ROMAddr+CRT1Table));
941     	data=data&0xE0;
942     	SetReg1(P3c4,0x0E,data);
943     
944     	data=(UCHAR)GetReg1(P3d4,0x09);
945     	data=data&0xDF;
946     	i=*((UCHAR *)(ROMAddr+CRT1Table));
947     	i=i&0x01;
948     	i=i<<5;
949     	data=data|i;
950     	i=*((USHORT *)(ROMAddr+ModeIDOffset+0x01));
951     	i=i&DoubleScanMode;
952     	if(i) data=data|0x80;
953     	SetReg1(P3d4,0x09,data);
954     
955     	if(ModeType>0x03) SetReg1(P3d4,0x14,0x4F);
956     }
957     
958     VOID SetCRT1Offset(ULONG ROMAddr)
959     {
960     	USHORT temp,ah,al;
961     	USHORT temp2,i;
962     	USHORT DisplayUnit;
963     
964     	temp=*((UCHAR *)(ROMAddr+ModeIDOffset+0x03));		// si+Ext_ModeInfo
965     	temp=temp>>4;										// index
966     	ScreenOffset=*((USHORT *)(ROMAddr+0x206));			// ScreenOffset
967     	temp=*((UCHAR *)(ROMAddr+ScreenOffset+temp));		// data
968     
969     	temp2=*((USHORT *)(ROMAddr+REFIndex+0x00));
970     	temp2=temp2&InterlaceMode;
971     	if(temp2) temp=temp<<1;
972     	temp2=ModeType-ModeEGA;
973     	switch (temp2) {
974     		case 0 : temp2=1; break;
975     		case 1 : temp2=2; break;
976     		case 2 : temp2=4; break;
977     		case 3 : temp2=4; break;
978     		case 4 : temp2=6; break;
979     		case 5 : temp2=8; break;
980     	}
981     	temp=temp*temp2;
982     	DisplayUnit=temp;
983     
984     	temp2=temp;
985     	temp=temp>>8;		
986     	temp=temp&0x0F;
987     	i=GetReg1(P3c4,0x0E);
988     	i=i&0xF0;
989     	i=i|temp;
990     	SetReg1(P3c4,0x0E,i);
991     
992     	temp=(UCHAR)temp2;
993     	temp=temp&0xFF;		
994     	SetReg1(P3d4,0x13,temp);
995     
996     	temp2=*((USHORT *)(ROMAddr+REFIndex+0x00));
997     	temp2=temp2&InterlaceMode;
998     	if(temp2) DisplayUnit>>=1;
999     
1000     	DisplayUnit=DisplayUnit<<5;
1001     	ah=(DisplayUnit&0xff00)>>8;
1002     	al=DisplayUnit&0x00ff;
1003     	if(al==0) ah=ah+1;
1004     	else ah=ah+2;
1005     	SetReg1(P3c4,0x10,ah);
1006     }
1007     
1008     
1009     VOID SetCRT1VCLK(PHW_DEVICE_EXTENSION HwDeviceExtension, ULONG ROMAddr)
1010     {
1011     	USHORT i;
1012     	UCHAR  index,data;
1013     
1014     	index=*((UCHAR *)(ROMAddr+REFIndex+0x03));
1015     	index=index&0x03F;
1016     	CRT1VCLKLen=GetVCLKLen(ROMAddr);
1017     	data=index*CRT1VCLKLen;
1018     	VCLKData=*((USHORT *)(ROMAddr+0x208));
1019     	VCLKData=VCLKData+data;
1020     
1021     	SetReg1(P3c4,0x31,0);
1022     	for(i=0x2B;i<=0x2C;i++) {
1023     		data=*((UCHAR *)(ROMAddr+VCLKData));
1024     		SetReg1(P3c4,i,data);
1025     		VCLKData++;
1026     	}
1027     	SetReg1(P3c4,0x2D,0x80);
1028     }
1029     
1030     
1031     VOID SetCRT1ModeRegs(ULONG ROMAddr, USHORT ModeNo)
1032     {
1033     
1034     	USHORT data,data2,data3;
1035     
1036     	if(ModeNo>0x13)	data=*((USHORT *)(ROMAddr+REFIndex+0x00));
1037     	else data=0;
1038     
1039     	data2=0;
1040     	if(ModeNo>0x13)
1041     		if(ModeType>0x02) {
1042     			data2=data2|0x02;
1043     			data3=ModeType-ModeVGA;
1044     			data3=data3<<2;
1045     			data2=data2|data3;
1046     	 	}
1047     
1048     	data=data&InterlaceMode;
1049     	if(data) data2=data2|0x20;
1050     	SetReg1(P3c4,0x06,data2);
1051     
1052     	data=GetReg1(P3c4,0x01);
1053     	data=data&0xF7;
1054     	data2=*((USHORT *)(ROMAddr+ModeIDOffset+0x01));
1055     	data2=data2&HalfDCLK;
1056     	if(data2) data=data|0x08;
1057     	SetReg1(P3c4,0x01,data);
1058     
1059     	data=GetReg1(P3c4,0x0F);
1060     	data=data&0xF7;
1061     	data2=*((USHORT *)(ROMAddr+ModeIDOffset+0x01));
1062     	data2=data2&LineCompareOff;
1063     	if(data2) data=data|0x08;
1064     	SetReg1(P3c4,0x0F,data);
1065     
1066     	data=GetReg1(P3c4,0x21);
1067     	data=data&0x1F;
1068     	if(ModeType==0x00) data=data|0x60;			// Text Mode
1069     	else if(ModeType<=0x02) data=data|0x00;		// EGA Mode
1070     	else data=data|0xA0;						// VGA Mode
1071     	SetReg1(P3c4,0x21,data);
1072     }
1073     
1074     VOID SetVCLKState(PHW_DEVICE_EXTENSION HwDeviceExtension, ULONG ROMAddr, USHORT ModeNo)
1075     {
1076     	USHORT data,data2;
1077     	USHORT VCLK;
1078     	UCHAR  index;
1079     
1080     	index=*((UCHAR *)(ROMAddr+REFIndex+0x03));
1081     	index=index&0x03F;
1082     	CRT1VCLKLen=GetVCLKLen(ROMAddr);
1083     	data=index*CRT1VCLKLen;
1084     	VCLKData=*((USHORT *)(ROMAddr+0x208));
1085     	VCLKData=VCLKData+data+(CRT1VCLKLen-2);
1086     	VCLK=*((USHORT *)(ROMAddr+VCLKData));
1087     	if(ModeNo<=0x13) VCLK=0;
1088     
1089     	data=GetReg1(P3c4,0x07);
1090     	data=data&0x7B;
1091     	if(VCLK>=150) data=data|0x80;	// VCLK > 150
1092     	SetReg1(P3c4,0x07,data);
1093     
1094     	data=GetReg1(P3c4,0x32);
1095     	data=data&0xD7;
1096     	if(VCLK>=150) data=data|0x08;	// VCLK > 150
1097     	SetReg1(P3c4,0x32,data);
1098     
1099     	data2=0x03;
1100     	if(VCLK>135) data2=0x02;
1101     	if(VCLK>160) data2=0x01;
1102     	if(VCLK>260) data2=0x00;
1103     	data=GetReg1(P3c4,0x07);
1104     	data=data&0xFC;
1105     	data=data|data2;
1106     	SetReg1(P3c4,0x07,data);
1107     }
1108     
1109     VOID LoadDAC(ULONG ROMAddr)
1110     {
1111     	USHORT data,data2;
1112     	USHORT time,i,j,k;
1113     	USHORT m,n,o;
1114     	USHORT si,di,bx,dl;
1115     	USHORT al,ah,dh;
1116     	USHORT *table=VGA_DAC;
1117     
1118     	data=*((USHORT *)(ROMAddr+ModeIDOffset+0x01));
1119     	data=data&DACInfoFlag;
1120     	time=64;
1121     	if(data==0x00) table=MDA_DAC;
1122     	if(data==0x08) table=CGA_DAC;
1123     	if(data==0x10) table=EGA_DAC;
1124     	if(data==0x18) {
1125     		time=256;
1126     		table=VGA_DAC;
1127     	}
1128     	if(time==256) j=16;
1129     	else j=time;
1130     
1131     	SetReg3(P3c6,0xFF);
1132     	SetReg3(P3c8,0x00);
1133     
1134     	for(i=0;i<j;i++) {
1135     		data=table[i];
1136     		for(k=0;k<3;k++) {
1137     			data2=0;
1138     			if(data&0x01) data2=0x2A;
1139     			if(data&0x02) data2=data2+0x15;
1140     			SetReg3(P3c9,data2);
1141     			data=data>>2;
1142     		}
1143     	}
1144     
1145     	if(time==256) {
1146     		for(i=16;i<32;i++) {
1147     			data=table[i];
1148     			for(k=0;k<3;k++) SetReg3(P3c9,data);
1149     		}
1150     		si=32;
1151     		for(m=0;m<9;m++) {
1152     			di=si;
1153     			bx=si+0x04;
1154     			dl=0;
1155     			for(n=0;n<3;n++) {
1156     				for(o=0;o<5;o++) {
1157     					dh=table[si];
1158     					ah=table[di];
1159     					al=table[bx];
1160     					si++;
1161     					WriteDAC(dl,ah,al,dh);
1162     				}	
1163     				si=si-2;
1164     				for(o=0;o<3;o++) {
1165     					dh=table[bx];
1166     					ah=table[di];
1167     					al=table[si];
1168     					si--;
1169     					WriteDAC(dl,ah,al,dh);
1170     				}	
1171     				dl++;
1172     			}
1173     			si=si+5;
1174     		}
1175     	}
1176     }
1177     
1178     VOID WriteDAC(USHORT dl, USHORT ah, USHORT al, USHORT dh)
1179     {
1180     	USHORT temp;
1181     	USHORT bh,bl;
1182     
1183     	bh=ah;
1184     	bl=al;
1185     	if(dl!=0) {
1186     		temp=bh;
1187     		bh=dh;
1188     		dh=temp;
1189     		if(dl==1) {
1190     			temp=bl;
1191     			bl=dh;
1192     			dh=temp;
1193     		}
1194     		else {
1195     			temp=bl;
1196     			bl=bh;
1197     			bh=temp;
1198     		}
1199     	}
1200     	SetReg3(P3c9,(USHORT)dh);
1201     	SetReg3(P3c9,(USHORT)bh);
1202     	SetReg3(P3c9,(USHORT)bl);
1203     }
1204     
1205     
1206     VOID DisplayOn()
1207     {
1208     	USHORT data;
1209     
1210     	data=GetReg1(P3c4,0x01);
1211     	data=data&0xDF;
1212     	SetReg1(P3c4,0x01,data);
1213     }
1214     
1215     USHORT GetModeIDLength(ULONG ROMAddr, USHORT ModeNo)
1216     {
1217     	USHORT modeidlength;
1218     	USHORT usModeIDOffset;
1219     	USHORT PreviousWord,CurrentWord;
1220     
1221     	modeidlength=0;
1222     	usModeIDOffset=*((USHORT *)(ROMAddr+0x20A));		// Get EModeIDTable
1223     	//	maybe = 2Exx or xx2E		
1224     	CurrentWord=*((USHORT *)(ROMAddr+usModeIDOffset));	// Offset 0x20A
1225     	PreviousWord=*((USHORT *)(ROMAddr+usModeIDOffset-2));	// Offset 0x20A
1226     	while((CurrentWord!=0x2E07)||(PreviousWord!=0x0801)) {
1227     		modeidlength++;
1228     		usModeIDOffset=usModeIDOffset+1;				// 10 <= ExtStructSize
1229     		CurrentWord=*((USHORT *)(ROMAddr+usModeIDOffset));
1230     		PreviousWord=*((USHORT *)(ROMAddr+usModeIDOffset-2)); 
1231     	}
1232     	modeidlength++;
1233     	return(modeidlength);
1234     }
1235     
1236     USHORT GetRefindexLength(ULONG ROMAddr, USHORT ModeNo)
1237     {
1238     	UCHAR ModeID;
1239     	UCHAR temp;
1240     	USHORT refindexlength;
1241     	USHORT usModeIDOffset;
1242     	USHORT usREFIndex;
1243     	USHORT usIDLength;
1244     
1245     	usModeIDOffset=*((USHORT *)(ROMAddr+0x20A));	// Get EModeIDTable
1246     	ModeID=*((UCHAR *)(ROMAddr+usModeIDOffset));	// Offset 0x20A
1247     	usIDLength = GetModeIDLength(ROMAddr, ModeNo);
1248     	while(ModeID!=0x40) {
1249     		usModeIDOffset=usModeIDOffset+usIDLength; 	// 10 <= ExtStructSize
1250     		ModeID=*((UCHAR *)(ROMAddr+usModeIDOffset));
1251     	}
1252     
1253     	refindexlength=1;
1254     	usREFIndex=*((USHORT *)(ROMAddr+usModeIDOffset+0x04));	// si+Ext_point
1255     	usREFIndex++;
1256     	temp=*((UCHAR *)(ROMAddr+usREFIndex));			// di => REFIndex
1257     	while(temp!=0xFF) {
1258     		refindexlength++;
1259     		usREFIndex++;
1260     		temp=*((UCHAR *)(ROMAddr+usREFIndex));		// di => REFIndex
1261     	}
1262     	return(refindexlength);
1263     }
1264     
1265     VOID SetInterlace(ULONG ROMAddr, USHORT ModeNo)
1266     {
1267     	ULONG Temp;
1268     	USHORT data,Temp2;
1269     
1270     	Temp = (ULONG)GetReg1(P3d4, 0x01);
1271     	Temp++;
1272     	Temp=Temp*8;
1273     
1274     	if(Temp==1024) data=0x0035;
1275     	else if(Temp==1280) data=0x0048;
1276     	else data=0x0000;
1277     
1278     	Temp2=*((USHORT *)(ROMAddr+REFIndex+0x00));
1279     	Temp2 &= InterlaceMode;
1280     	if(Temp2 == 0) data=0x0000;
1281     
1282     	SetReg1(P3d4,0x19,data);
1283     
1284     	Temp = (ULONG)GetReg1(P3d4, 0x1A);
1285     	Temp2= (USHORT)(Temp & 0xFC);
1286     	SetReg1(P3d4,0x1A,(USHORT)Temp);
1287     
1288     	Temp = (ULONG)GetReg1(P3c4, 0x0f);
1289     	Temp2= (USHORT)Temp & 0xBF;
1290     	if(ModeNo==0x37) Temp2=Temp2|0x40;
1291     	SetReg1(P3d4,0x1A,(USHORT)Temp2);
1292     }
1293     
1294     VOID SetCRT1FIFO(ULONG ROMAddr)
1295     {
1296     	USHORT	colorth=0,index,data,VCLK,data2,MCLKOffset,MCLK;
1297     	USHORT  ah,bl,A,B;
1298     
1299     	index=*((UCHAR *)(ROMAddr+REFIndex+0x03));
1300     	index=index&0x03F;
1301     	CRT1VCLKLen=GetVCLKLen(ROMAddr);
1302     	data=index*CRT1VCLKLen;
1303     	VCLKData=*((USHORT *)(ROMAddr+0x208));
1304     	VCLKData=VCLKData+data+(CRT1VCLKLen-2);
1305     	VCLK=*((USHORT *)(ROMAddr+VCLKData));		// Get VCLK
1306     
1307     	MCLKOffset=*((USHORT *)(ROMAddr+0x20C));
1308     	index=GetReg1(P3c4,0x3A);
1309     	index=index&07;
1310     	MCLKOffset=MCLKOffset+index*5;
1311     	MCLK=*((UCHAR *)(ROMAddr+MCLKOffset+0x03));	// Get MCLK
1312     
1313     	data2=ModeType-0x02;
1314     	switch (data2) {
1315     		case 0 : colorth=1; break;
1316     		case 1 : colorth=2; break;
1317     		case 2 : colorth=4; break;
1318     		case 3 : colorth=4; break;
1319     		case 4 : colorth=6; break;
1320     		case 5 : colorth=8; break;
1321     	 }
1322     
1323     	do{
1324     		B=(CalcDelay(ROMAddr,0)*VCLK*colorth);
1325     		B=B/(16*MCLK);
1326     		B++;
1327     
1328     		A=(CalcDelay(ROMAddr,1)*VCLK*colorth);
1329     		A=A/(16*MCLK);
1330     		A++;
1331     
1332     		if(A<4) A=0;
1333     		else A=A-4;
1334     
1335     		if(A>B)	bl=A;
1336     		else bl=B;
1337     
1338     		bl++;
1339     		if(bl>0x13) {
1340     			data=GetReg1(P3c4,0x16);
1341     			data=data>>6;
1342     			if(data!=0) {
1343     				data--;
1344     				data=data<<6;
1345     				data2=GetReg1(P3c4,0x16);
1346     				data2=(data2&0x3f)|data;
1347     				SetReg1(P3c4,0x16,data2);
1348     			}
1349     			else bl=0x13;
1350     		}
1351     	} while(bl>0x13);
1352     
1353     	ah=bl;
1354     	ah=ah<<4;
1355     	ah=ah|0x0f;
1356     	SetReg1(P3c4,0x08,ah);
1357     
1358     	data=bl;
1359     	data=data&0x10;
1360     	data=data<<1;
1361     	data2=GetReg1(P3c4,0x0F);
1362     	data2=data2&0x9f;
1363     	data2=data2|data;
1364     	SetReg1(P3c4,0x0F,data2);
1365     
1366     	data=bl+3;
1367     	if(data>0x0f) data=0x0f;
1368     	SetReg1(P3c4,0x3b,0x00);
1369     	data2=GetReg1(P3c4,0x09);
1370     	data2=data2&0xF0;
1371     	data2=data2|data;
1372     	SetReg1(P3c4,0x09,data2);
1373     }
1374     
1375     static USHORT CalcDelay(ULONG ROMAddr,USHORT key)
1376     {
1377     	USHORT data,data2,temp0,temp1;
1378     	UCHAR  ThLowA[]={61,3,52,5,68,7,100,11,
1379     					 43,3,42,5,54,7, 78,11,
1380     					 34,3,37,5,47,7, 67,11};
1381     	UCHAR  ThLowB[]={81,4,72,6,88,8,120,12,
1382     					 55,4,54,6,66,8, 90,12,
1383     					 42,4,45,6,55,8, 75,12};
1384     	UCHAR  ThTiming[]= {1,2,2,3,0,1,1,2};
1385     
1386     	data=GetReg1(P3c4,0x16);
1387     	data=data>>6;
1388     	data2=GetReg1(P3c4,0x14);
1389     	data2=(data2>>4)&0x0C;
1390     	data=data|data2;
1391     	data=data<1;
1392     	if(key==0) {
1393     		temp0=(USHORT)ThLowA[data];
1394     		temp1=(USHORT)ThLowA[data+1];
1395     	}
1396     	else {
1397     		temp0=(USHORT)ThLowB[data];
1398     		temp1=(USHORT)ThLowB[data+1];
1399     	}
1400     
1401     	data2=0;
1402     	data=GetReg1(P3c4,0x18);
1403     	if(data&0x02) data2=data2|0x01;
1404     	if(data&0x20) data2=data2|0x02;
1405     	if(data&0x40) data2=data2|0x04;
1406     
1407     	data=temp1*ThTiming[data2]+temp0;
1408     	return(data);
1409     }
1410     
1411     VOID SetCRT1FIFO2(ULONG ROMAddr)
1412     {
1413     	USHORT  colorth=0,index,data,VCLK,data2,MCLKOffset,MCLK;
1414     	USHORT  ah,bl,B;
1415     	ULONG	eax;
1416     
1417     	index=*((UCHAR *)(ROMAddr+REFIndex+0x03));
1418     	index=index&0x03F;
1419     	CRT1VCLKLen=GetVCLKLen(ROMAddr);
1420     	data=index*CRT1VCLKLen;
1421     	VCLKData=*((USHORT *)(ROMAddr+0x208));
1422     	VCLKData=VCLKData+data+(CRT1VCLKLen-2);
1423     	VCLK=*((USHORT *)(ROMAddr+VCLKData));			// Get VCLK
1424     
1425     	MCLKOffset=*((USHORT *)(ROMAddr+0x20C));
1426     	index=GetReg1(P3c4,0x1A);
1427     	index=index&07;
1428     	MCLKOffset=MCLKOffset+index*5;
1429     	MCLK=*((USHORT *)(ROMAddr+MCLKOffset+0x03));	// Get MCLK  
1430     
1431     	data2=ModeType-0x02;
1432     	switch (data2) {
1433     		case 0 : colorth=1; break;
1434     		case 1 : colorth=1; break;
1435     		case 2 : colorth=2; break;
1436     		case 3 : colorth=2; break;
1437     		case 4 : colorth=3; break;
1438     		case 5 : colorth=4; break;
1439     	}
1440     
1441     	do{
1442     		B=(CalcDelay2(ROMAddr,0)*VCLK*colorth);
1443     		if (B%(16*MCLK) == 0)
1444     		{
1445     			B=B/(16*MCLK);
1446     			bl=B+1;
1447     		}
1448     		else
1449     		{
1450     			B=B/(16*MCLK);
1451     			bl=B+2;
1452     		}
1453     
1454     		if(bl>0x13) {
1455     			data=GetReg1(P3c4,0x15);
1456     			data=data&0xf0;
1457     			if(data!=0xb0) {
1458     				data=data+0x20;
1459     				if(data==0xa0) data=0x30;
1460     
1461     				data2=GetReg1(P3c4,0x15);
1462     				data2=(data2&0x0f)|data;
1463     				SetReg1(P3c4,0x15,data2);
1464     			}
1465     			else bl=0x13;
1466     		}
1467     	} while(bl>0x13);
1468     
1469     	data2=GetReg1(P3c4,0x15);
1470     	data2=(data2&0xf0)>>4;
1471     	data2=data2<<24;
1472     
1473     	SetReg4(0xcf8,0x80000050);
1474     	eax=GetReg3(0xcfc);
1475     	eax=eax&0x0f0ffffff;
1476     	eax=eax|data2;
1477     	SetReg4(0xcfc,eax);
1478     
1479     	ah=bl;
1480     	ah=ah<<4;
1481     	ah=ah|0x0f;
1482     	SetReg1(P3c4,0x08,ah);
1483     
1484     	data=bl;
1485     	data=data&0x10;
1486     	data=data<<1;
1487     	data2=GetReg1(P3c4,0x0F);
1488     	data2=data2&0x9f;
1489     	data2=data2|data;
1490     	SetReg1(P3c4,0x0F,data2);
1491     
1492     	data=bl+3;
1493     	if(data>0x0f) data=0x0f;
1494     	SetReg1(P3c4,0x3b,0x00);
1495     	data2=GetReg1(P3c4,0x09);
1496     	data2=data2&0xF0;
1497     	data2=data2|data;
1498     	SetReg1(P3c4,0x09,data2);
1499     }
1500     
1501     USHORT CalcDelay2(ULONG ROMAddr,USHORT key)
1502     {
1503     	USHORT data,index;
1504     	UCHAR  LatencyFactor[]={88,80,78,72,70,00,
1505     							00,79,77,71,69,49,
1506     							88,80,78,72,70,00,
1507     							00,72,70,64,62,44};
1508     
1509     	index=0;
1510     	data=GetReg1(P3c4,0x14);
1511     	if(data&0x80) index=index+12;
1512     
1513     	data=GetReg1(P3c4,0x15);
1514     	data=(data&0xf0)>>4;
1515     	if(data&0x01) index=index+6;
1516     
1517     	data=data>>1;
1518     	index=index+data;
1519     	data=LatencyFactor[index];
1520     
1521     	return(data);
1522     }
1523     
1524     #endif /* CONFIG_FB_SIS_LINUXBIOS */
1525