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