Chameleon

Chameleon Svn Source Tree

Root/branches/diebuche/i386/libsaio/915resolution.c

Source at commit 131 created 14 years 29 days ago.
By diebuche, typos...
1
2/* Copied from 915 resolution created by steve tomljenovic
3 *
4 * This code is based on the techniques used in :
5 *
6 * - 855patch. Many thanks to Christian Zietz (czietz gmx net)
7 * for demonstrating how to shadow the VBIOS into system RAM
8 * and then modify it.
9 *
10 * - 1280patch by Andrew Tipton (andrewtipton null li).
11 *
12 * - 855resolution by Alain Poirier
13 *
14 * This source code is into the public domain.
15 */
16
17#include "libsaio.h"
18#include "915resolution.h"
19#include "../boot2/graphics.h"
20
21char * chipset_type_names[] = {
22"UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", "945GM", "945GME",
23"946GZ", "955X", "G965", "Q965", "965GM", "975X",
24"P35", "X48", "B43", "Q45", "P45", "GM45", "G41", "G31", "G45", "500"
25};
26
27char * bios_type_names[] = {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"};
28
29int freqs[] = { 60, 75, 85 };
30
31
32UInt32 get_chipset_id(void) {
33outl(0xcf8, 0x80000000);
34return inl(0xcfc);
35}
36
37chipset_type get_chipset(UInt32 id) {
38chipset_type type;
39
40switch (id) {
41case 0x35758086:
42type = CT_830;
43break;
44
45case 0x25608086:
46type = CT_845G;
47break;
48
49case 0x35808086:
50type = CT_855GM;
51break;
52
53case 0x25708086:
54type = CT_865G;
55break;
56
57case 0x25808086:
58type = CT_915G;
59break;
60
61case 0x25908086:
62type = CT_915GM;
63break;
64
65case 0x27708086:
66type = CT_945G;
67break;
68
69case 0x27748086:
70type = CT_955X;
71break;
72
73case 0x277c8086:
74type = CT_975X;
75break;
76
77case 0x27a08086:
78type = CT_945GM;
79break;
80
81case 0x27ac8086:
82type = CT_945GME;
83break;
84
85case 0x29708086:
86type = CT_946GZ;
87break;
88
89case 0x29a08086:
90type = CT_G965;
91break;
92
93case 0x29908086:
94type = CT_Q965;
95break;
96
97case 0x2a008086:
98type = CT_965GM;
99break;
100
101case 0x29e08086:
102type = CT_X48;
103break;
104
105case 0x2a408086:
106type = CT_GM45;
107break;
108
109case 0x2e108086:
110case 0X2e908086:
111type = CT_B43;
112break;
113
114case 0x2e208086:
115type = CT_P45;
116break;
117
118case 0x2e308086:
119type = CT_G41;
120break;
121
122case 0x29c08086:
123type = CT_G31;
124break;
125
126case 0x29208086:
127type = CT_G45;
128break;
129
130case 0x81008086:
131type = CT_500;
132break;
133
134default:
135type = CT_UNKWN;
136break;
137}
138return type;
139}
140
141vbios_resolution_type1 * map_type1_resolution(vbios_map * map, UInt16 res) {
142vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res));
143return ptr;
144}
145
146vbios_resolution_type2 * map_type2_resolution(vbios_map * map, UInt16 res) {
147vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res));
148return ptr;
149}
150
151vbios_resolution_type3 * map_type3_resolution(vbios_map * map, UInt16 res) {
152vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res));
153return ptr;
154}
155
156char detect_bios_type(vbios_map * map, char modeline, int entry_size) {
157UInt32 i;
158UInt16 r1, r2;
159
160r1 = r2 = 32000;
161
162for (i=0; i < map->mode_table_size; i++) {
163if (map->mode_table[i].resolution <= r1) {
164r1 = map->mode_table[i].resolution;
165}
166else {
167if (map->mode_table[i].resolution <= r2) {
168r2 = map->mode_table[i].resolution;
169}
170}
171
172/* printf("r1 = %d r2 = %d\n", r1, r2); */
173}
174
175return (r2-r1-6) % entry_size == 0;
176}
177
178char detect_ati_bios_type(vbios_map * map) {
179return map->mode_table_size % sizeof(ATOM_MODE_TIMING) == 0;
180}
181
182void close_vbios(vbios_map * map);
183
184vbios_map * open_vbios(chipset_type forced_chipset) {
185UInt32 z;
186vbios_map * map = NEW(vbios_map);
187for(z=0; z<sizeof(vbios_map); z++) ((char*)map)[z]=0;
188/*
189 * Determine chipset
190*/
191
192if (forced_chipset == CT_UNKWN) {
193map->chipset_id = get_chipset_id();
194map->chipset = get_chipset(map->chipset_id);
195}
196else if (forced_chipset != CT_UNKWN) {
197map->chipset = forced_chipset;
198}
199else {
200map->chipset = CT_915GM;
201}
202
203/*
204 * Map the video bios to memory
205 */
206
207map->bios_ptr = (unsigned char *)VBIOS_START;
208
209/*
210 * check if we have ATI Radeon
211 */
212
213map->ati_tables.base = map->bios_ptr;
214map->ati_tables.AtomRomHeader = (ATOM_ROM_HEADER *) (map->bios_ptr + *(unsigned short *) (map->bios_ptr + OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER));
215if (strcmp ((char *) map->ati_tables.AtomRomHeader->uaFirmWareSignature, "ATOM") != 0) {
216printf("Not an AtomBios Card\n");
217} else {
218map->bios = BT_ATI_1;
219}
220
221
222/*
223 * check if we have NVidia
224 */
225if (map->bios != BT_ATI_1) {
226int i = 0;
227while (i < 512) { // we don't need to look through the whole bios, just the first 512 bytes
228if ((map->bios_ptr[i] == 'N')
229&& (map->bios_ptr[i+1] == 'V')
230&& (map->bios_ptr[i+2] == 'I')
231&& (map->bios_ptr[i+3] == 'D'))
232{
233map->bios = BT_NVDA;
234break;
235}
236i++;
237}
238}
239
240/*
241 * check if we have Intel
242 */
243
244/*if (map->chipset == CT_UNKWN && memmem(map->bios_ptr, VBIOS_SIZE, INTEL_SIGNATURE, strlen(INTEL_SIGNATURE))) {
245printf( "Intel chipset detected. However, 915resolution was unable to determine the chipset type.\n");
246
247printf("Chipset Id: %x\n", map->chipset_id);
248
249printf("Please report this problem to stomljen@yahoo.com\n");
250
251close_vbios(map);
252return 0;
253}*/
254
255/*
256 * check for others
257 */
258
259if (map->chipset == CT_UNKWN) {
260printf("Unknown chipset type and unrecognized bios.\n");
261
262printf("915resolution only works with Intel 800/900 series graphic chipsets.\n");
263
264printf("Chipset Id: %x\n", map->chipset_id);
265close_vbios(map);
266return 0;
267}
268
269/*
270 * Figure out where the mode table is
271 */
272
273if ((map->bios != BT_ATI_1) && (map->bios != BT_NVDA))
274{
275unsigned char* p = map->bios_ptr + 16;
276unsigned char* limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode));
277
278while (p < limit && map->mode_table == 0) {
279vbios_mode * mode_ptr = (vbios_mode *) p;
280
281if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) &&
282((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) {
283
284map->mode_table = mode_ptr;
285}
286
287p++;
288}
289
290if (map->mode_table == 0) {
291printf("Unable to locate the mode table.\n");
292printf("Please run the program 'dump_bios' as root and\n");
293printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
294printf("Chipset: %s\n", chipset_type_names[map->chipset]);
295close_vbios(map);
296return 0;
297}
298}
299else if (map->bios == BT_ATI_1)
300{
301map->ati_tables.MasterDataTables = (unsigned short *) &((ATOM_MASTER_DATA_TABLE *) (map->bios_ptr + map->ati_tables.AtomRomHeader->usMasterDataTableOffset))->ListOfDataTables;
302unsigned short std_vesa_offset = (unsigned short) ((ATOM_MASTER_LIST_OF_DATA_TABLES *)map->ati_tables.MasterDataTables)->StandardVESA_Timing;
303ATOM_STANDARD_VESA_TIMING * std_vesa = (ATOM_STANDARD_VESA_TIMING *) (map->bios_ptr + std_vesa_offset);
304
305map->ati_mode_table = (char *) &std_vesa->aModeTimings;
306if (map->ati_mode_table == 0) {
307printf("Unable to locate the mode table.\n");
308printf("Please run the program 'dump_bios' as root and\n");
309printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
310printf("Chipset: %s\n", chipset_type_names[map->chipset]);
311close_vbios(map);
312return 0;
313}
314map->mode_table_size = std_vesa->sHeader.usStructureSize - sizeof(ATOM_COMMON_TABLE_HEADER);
315
316if (!detect_ati_bios_type(map)) map->bios = BT_ATI_2;
317}
318else if (map->bios == BT_NVDA)
319{
320unsigned short nv_data_table_offset = 0;
321unsigned short nv_modeline_2_offset = 0;
322unsigned short * nv_data_table;
323NV_VESA_TABLE * std_vesa;
324
325int i = 0;
326
327while (i < 0x300) { //We don't need to look for the table in the whole bios, the 768 first bytes only
328if ((map->bios_ptr[i] == 0x44)
329&& (map->bios_ptr[i+1] == 0x01)
330&& (map->bios_ptr[i+2] == 0x04)
331&& (map->bios_ptr[i+3] == 0x00)) {
332nv_data_table_offset = (unsigned short) (map->bios_ptr[i+4] | (map->bios_ptr[i+5] << 8));
333break;
334}
335i++;
336}
337
338while (i < VBIOS_SIZE) { //We don't know how to locate it other way
339if ((map->bios_ptr[i] == 0x00) && (map->bios_ptr[i+1] == 0x04) //this is the first 1024 modeline.
340&& (map->bios_ptr[i+2] == 0x00) && (map->bios_ptr[i+3] == 0x03)
341&& (map->bios_ptr[i+4] == 0x80)
342&& (map->bios_ptr[i+5] == 0x2F)
343&& (map->bios_ptr[i+6] == 0x10)
344&& (map->bios_ptr[i+7] == 0x10)
345&& (map->bios_ptr[i+8] == 0x05)) {
346nv_modeline_2_offset = (unsigned short) i;
347break;
348}
349i++;
350}
351
352nv_data_table = (unsigned short *) (map->bios_ptr + (nv_data_table_offset + OFFSET_TO_VESA_TABLE_INDEX));
353std_vesa = (NV_VESA_TABLE *) (map->bios_ptr + *nv_data_table);
354
355map->nv_mode_table = (char *) std_vesa->sModelines;
356if (nv_modeline_2_offset == (VBIOS_SIZE-1) || nv_modeline_2_offset == 0) {
357map->nv_mode_table_2 = NULL;
358} else {
359map->nv_mode_table_2 = (char*) map->bios_ptr + nv_modeline_2_offset;
360}
361if (map->nv_mode_table == 0) {
362printf("Unable to locate the mode table.\n");
363printf("Please run the program 'dump_bios' as root and\n");
364printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
365printf("Chipset: %s\n", chipset_type_names[map->chipset]);
366close_vbios(map);
367return 0;
368}
369map->mode_table_size = std_vesa->sHeader.usTable_Size;
370}
371
372
373/*
374 * Determine size of mode table
375 */
376
377if ((map->bios != BT_ATI_1) && (map->bios != BT_ATI_2) && (map->bios != BT_NVDA)) {
378vbios_mode * mode_ptr = map->mode_table;
379
380while (mode_ptr->mode != 0xff) {
381map->mode_table_size++;
382mode_ptr++;
383}
384}
385
386/*
387 * Figure out what type of bios we have
388 * order of detection is important
389 */
390if ((map->bios != BT_ATI_1) && (map->bios != BT_ATI_2) && (map->bios != BT_NVDA)) {
391if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type3))) {
392map->bios = BT_3;
393}
394else if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type2))) {
395map->bios = BT_2;
396}
397else if (detect_bios_type(map, FALSE, sizeof(vbios_resolution_type1))) {
398map->bios = BT_1;
399}
400else {
401printf("Unable to determine bios type.\n");
402printf("Please run the program 'dump_bios' as root and\n");
403printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
404
405printf("Chipset: %s\n", chipset_type_names[map->chipset]);
406printf("Mode Table Offset: $C0000 + $%x\n", ((UInt32)map->mode_table) - ((UInt32)map->bios_ptr));
407
408printf("Mode Table Entries: %u\n", map->mode_table_size);
409return 0;
410}
411}
412
413return map;
414}
415
416void close_vbios(vbios_map * map) {
417FREE(map);
418}
419
420void unlock_vbios(vbios_map * map) {
421
422map->unlocked = TRUE;
423
424switch (map->chipset) {
425case CT_UNKWN:
426break;
427case CT_830:
428case CT_855GM:
429outl(0xcf8, 0x8000005a);
430map->b1 = inb(0xcfe);
431
432outl(0xcf8, 0x8000005a);
433outb(0xcfe, 0x33);
434break;
435case CT_845G:
436case CT_865G:
437case CT_915G:
438case CT_915GM:
439case CT_945G:
440case CT_945GM:
441case CT_945GME:
442case CT_946GZ:
443case CT_955X:
444case CT_G965:
445case CT_Q965:
446case CT_965GM:
447case CT_975X:
448case CT_P35:
449case CT_X48:
450case CT_B43:
451case CT_Q45:
452case CT_P45:
453case CT_GM45:
454case CT_G41:
455case CT_G31:
456case CT_G45:
457case CT_500:
458
459outl(0xcf8, 0x80000090);
460map->b1 = inb(0xcfd);
461map->b2 = inb(0xcfe);
462outl(0xcf8, 0x80000090);
463outb(0xcfd, 0x33);
464outb(0xcfe, 0x33);
465break;
466}
467
468#if DEBUG
469{
470UInt32 t = inl(0xcfc);
471printf("unlock PAM: (0x%08x)\n", t);
472}
473#endif
474}
475
476void relock_vbios(vbios_map * map) {
477
478map->unlocked = FALSE;
479
480switch (map->chipset) {
481case CT_UNKWN:
482break;
483case CT_830:
484case CT_855GM:
485outl(0xcf8, 0x8000005a);
486outb(0xcfe, map->b1);
487break;
488case CT_845G:
489case CT_865G:
490case CT_915G:
491case CT_915GM:
492case CT_945G:
493case CT_945GM:
494case CT_945GME:
495case CT_946GZ:
496case CT_955X:
497case CT_G965:
498case CT_Q965:
499case CT_965GM:
500case CT_975X:
501case CT_P35:
502case CT_X48:
503case CT_B43:
504case CT_Q45:
505case CT_P45:
506case CT_GM45:
507case CT_G41:
508case CT_G31:
509case CT_G45:
510case CT_500:
511
512outl(0xcf8, 0x80000090);
513outb(0xcfd, map->b1);
514outb(0xcfe, map->b2);
515break;
516}
517
518#if DEBUG
519{
520 UInt32 t = inl(0xcfc);
521printf("relock PAM: (0x%08x)\n", t);
522}
523#endif
524}
525
526void save_vbios(vbios_map * map)
527{
528map->bios_backup_ptr = malloc(VBIOS_SIZE);
529bcopy((const unsigned char *)0xC0000, map->bios_backup_ptr, VBIOS_SIZE);
530}
531
532void restore_vbios(vbios_map * map)
533{
534bcopy(map->bios_backup_ptr,(unsigned char *)0xC0000, VBIOS_SIZE);
535}
536
537
538
539static void gtf_timings(UInt32 x, UInt32 y, UInt32 freq,
540unsigned long *clock,
541UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,
542UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank)
543{
544UInt32 hbl, vbl, vfreq;
545
546vbl = y + (y+1)/(20000/(11*freq) - 1) + 1;
547
548vfreq = vbl * freq;
549hbl = 16 * (int)(x * (30 - 300000 / vfreq) /
550 + (70 + 300000 / vfreq) / 16 + 0);
551
552*vsyncstart = y;
553*vsyncend = y + 3;
554*vblank = vbl - 1;
555*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
556*hsyncend = x + hbl / 2 - 1;
557*hblank = x + hbl - 1;
558*clock = (x + hbl) * vfreq / 1000;
559}
560
561void cvt_timings(UInt32 x, UInt32 y, UInt32 freq,
562 unsigned long *clock,
563 UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,
564 UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank, bool reduced)
565{
566UInt32 hbl, hbp, vbl, vsync, hperiod;
567
568if (!(y % 3) && ((y * 4 / 3) == x))
569 vsync = 4;
570 else if (!(y % 9) && ((y * 16 / 9) == x))
571 vsync = 5;
572 else if (!(y % 10) && ((y * 16 / 10) == x))
573 vsync = 6;
574 else if (!(y % 4) && ((y * 5 / 4) == x))
575 vsync = 7;
576 else if (!(y % 9) && ((y * 15 / 9) == x))
577 vsync = 7;
578 else /* Custom */
579 vsync = 10;
580
581if (!reduced) {
582hperiod = (1000000/freq - 550) / (y + 3);
583vbl = y + (550/hperiod) + 3;
584hbp = 30 - ((300*hperiod)/1000);
585hbl = (x * hbp) / (100 - hbp);
586
587*vsyncstart = y + 6;
588*vsyncend = *vsyncstart + vsync;
589*vblank = vbl - 1;
590*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
591*hsyncend = x + hbl / 2 - 1;
592*hblank = x + hbl - 1;
593
594} else {
595hperiod = (1000000/freq - 460) / y;
596vbl = y + 460/hperiod + 1;
597hbl = 160;
598
599*vsyncstart = y + 3;
600*vsyncend = *vsyncstart + vsync;
601*vblank = vbl - 1;
602*hsyncstart = x + hbl / 2 - 32;
603*hsyncend = x + hbl / 2 - 1;
604*hblank = x + hbl - 1;
605
606}
607*clock = (x + hbl) * 1000 / hperiod;
608}
609
610void set_mode(vbios_map * map, UInt32 x, UInt32 y, UInt32 bp, UInt32 htotal, UInt32 vtotal) {
611UInt32 xprev, yprev;
612UInt32 i = 0, j;// patch first available mode
613
614//for (i=0; i < map->mode_table_size; i++) {
615//if (map->mode_table[0].mode == mode) {
616switch(map->bios) {
617case BT_1:
618{
619vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
620
621if (bp) {
622map->mode_table[i].bits_per_pixel = bp;
623}
624
625res->x2 = (htotal?(((htotal-x) >> 8) & 0x0f) : (res->x2 & 0x0f)) | ((x >> 4) & 0xf0);
626res->x1 = (x & 0xff);
627
628res->y2 = (vtotal?(((vtotal-y) >> 8) & 0x0f) : (res->y2 & 0x0f)) | ((y >> 4) & 0xf0);
629res->y1 = (y & 0xff);
630if (htotal)
631res->x_total = ((htotal-x) & 0xff);
632
633if (vtotal)
634res->y_total = ((vtotal-y) & 0xff);
635}
636break;
637case BT_2:
638{
639vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
640
641res->xchars = x / 8;
642res->ychars = y / 16 - 1;
643xprev = res->modelines[0].x1;
644yprev = res->modelines[0].y1;
645
646for(j=0; j < 3; j++) {
647vbios_modeline_type2 * modeline = &res->modelines[j];
648
649if (modeline->x1 == xprev && modeline->y1 == yprev) {
650modeline->x1 = modeline->x2 = x-1;
651modeline->y1 = modeline->y2 = y-1;
652
653gtf_timings(x, y, freqs[j], &modeline->clock,
654&modeline->hsyncstart, &modeline->hsyncend,
655&modeline->hblank, &modeline->vsyncstart,
656&modeline->vsyncend, &modeline->vblank);
657
658if (htotal)
659modeline->htotal = htotal;
660else
661modeline->htotal = modeline->hblank;
662
663if (vtotal)
664modeline->vtotal = vtotal;
665else
666modeline->vtotal = modeline->vblank;
667}
668}
669}
670break;
671case BT_3:
672{
673vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
674
675xprev = res->modelines[0].x1;
676yprev = res->modelines[0].y1;
677
678for (j=0; j < 3; j++) {
679vbios_modeline_type3 * modeline = &res->modelines[j];
680
681if (modeline->x1 == xprev && modeline->y1 == yprev) {
682modeline->x1 = modeline->x2 = x-1;
683modeline->y1 = modeline->y2 = y-1;
684
685gtf_timings(x, y, freqs[j], &modeline->clock,
686&modeline->hsyncstart, &modeline->hsyncend,
687&modeline->hblank, &modeline->vsyncstart,
688&modeline->vsyncend, &modeline->vblank);
689if (htotal)
690modeline->htotal = htotal;
691else
692modeline->htotal = modeline->hblank;
693if (vtotal)
694modeline->vtotal = vtotal;
695else
696modeline->vtotal = modeline->vblank;
697
698modeline->timing_h = y-1;
699modeline->timing_v = x-1;
700}
701}
702}
703break;
704case BT_ATI_1:
705{
706edid_mode mode;
707VBEModeInfoBlock minfo;
708unsigned short mode_n;
709unsigned short vesaVersion;
710
711ATOM_MODE_TIMING *mode_timing = (ATOM_MODE_TIMING *) map->ati_mode_table;
712
713mode_n = getVESAModeWithProperties( x, y, 32, maColorModeBit |
714 maModeIsSupportedBit |
715 maGraphicsModeBit |
716 maLinearFrameBufferAvailBit,
717 0,
718 &minfo, &vesaVersion );
719
720if ( mode_n == modeEndOfList )
721{
722minfo.XResolution = 1024;
723minfo.YResolution = 768;
724}
725
726
727int m_status = getMode(&mode);
728
729if (m_status || (mode.h_active != x)) {
730vbios_modeline_type2 * modeline = malloc(sizeof(vbios_modeline_type2));
731bzero(modeline, sizeof(vbios_modeline_type2));
732
733cvt_timings(x, y, 60, &modeline->clock,
734&modeline->hsyncstart, &modeline->hsyncend,
735&modeline->hblank, &modeline->vsyncstart,
736&modeline->vsyncend, &modeline->vblank, FALSE);
737
738mode.pixel_clock = modeline->clock /10;
739mode.h_active = x;
740mode.h_sync_offset = modeline->hsyncstart - x;
741mode.h_sync_width = modeline->hsyncend - modeline->hsyncstart;
742mode.h_blanking = modeline->hblank - x;
743mode.v_active = y;
744mode.v_sync_offset = modeline->vsyncstart - y;
745mode.v_sync_width = modeline->vsyncend - modeline->vsyncstart;
746mode.v_blanking = modeline->vblank - y;
747
748free(modeline);
749m_status = 0;
750}
751
752if (!m_status) {
753while (i < (map->mode_table_size / sizeof(ATOM_MODE_TIMING)))
754{
755if (mode_timing[i].usCRTC_H_Disp == minfo.XResolution) {
756mode_timing[i].usCRTC_H_Total = mode.h_active + mode.h_blanking;
757mode_timing[i].usCRTC_H_Disp = mode.h_active;
758mode_timing[i].usCRTC_H_SyncStart = mode.h_active + mode.h_sync_offset;
759mode_timing[i].usCRTC_H_SyncWidth = mode.h_sync_width;
760
761mode_timing[i].usCRTC_V_Total = mode.v_active + mode.v_blanking;
762mode_timing[i].usCRTC_V_Disp = mode.v_active;
763mode_timing[i].usCRTC_V_SyncStart = mode.v_active + mode.v_sync_offset;
764mode_timing[i].usCRTC_V_SyncWidth = mode.v_sync_width;
765
766mode_timing[i].usPixelClock = mode.pixel_clock;
767}
768i++;
769}
770}
771}
772break;
773case BT_ATI_2:
774{
775edid_mode mode;
776VBEModeInfoBlock minfo;
777unsigned short mode_n;
778unsigned short vesaVersion;
779
780ATOM_DTD_FORMAT *mode_timing = (ATOM_DTD_FORMAT *) map->ati_mode_table;
781
782mode_n = getVESAModeWithProperties( x, y, 32, maColorModeBit |
783 maModeIsSupportedBit |
784 maGraphicsModeBit |
785 maLinearFrameBufferAvailBit,
786 0,
787 &minfo, &vesaVersion );
788
789if ( mode_n == modeEndOfList )
790{
791minfo.XResolution = 1024;
792minfo.YResolution = 768;
793}
794
795
796int m_status = getMode(&mode);
797
798if (m_status || (mode.h_active != x)) {
799vbios_modeline_type2 * modeline = malloc(sizeof(vbios_modeline_type2));
800bzero(modeline, sizeof(vbios_modeline_type2));
801
802cvt_timings(x, y, 60, &modeline->clock,
803&modeline->hsyncstart, &modeline->hsyncend,
804&modeline->hblank, &modeline->vsyncstart,
805&modeline->vsyncend, &modeline->vblank, FALSE);
806
807mode.pixel_clock = modeline->clock /10;
808mode.h_active = x;
809mode.h_sync_offset = modeline->hsyncstart - x;
810mode.h_sync_width = modeline->hsyncend - modeline->hsyncstart;
811mode.h_blanking = modeline->hblank - x;
812mode.v_active = y;
813mode.v_sync_offset = modeline->vsyncstart - y;
814mode.v_sync_width = modeline->vsyncend - modeline->vsyncstart;
815mode.v_blanking = modeline->vblank - y;
816
817free(modeline);
818m_status = 0;
819}
820
821if (!m_status) {
822while (i < (map->mode_table_size / sizeof(ATOM_DTD_FORMAT)))
823{
824if (mode_timing[i].usHActive == minfo.XResolution) {
825
826mode_timing[i].usHBlanking_Time = mode.h_blanking;
827mode_timing[i].usHActive = mode.h_active;
828mode_timing[i].usHSyncOffset = mode.h_sync_offset;
829mode_timing[i].usHSyncWidth = mode.h_sync_width;
830
831mode_timing[i].usVBlanking_Time = mode.v_blanking;
832mode_timing[i].usVActive = mode.v_active;
833mode_timing[i].usVSyncOffset = mode.v_sync_offset;
834mode_timing[i].usVSyncWidth = mode.v_sync_width;
835
836mode_timing[i].usPixClk = mode.pixel_clock;
837}
838i++;
839}
840}
841
842}
843break;
844case BT_NVDA:
845{
846s_aspect aspect_ratio;
847/*
848 * Get the aspect ratio for the requested mode
849 */
850if ((y * 16 / 9) == x) {
851aspect_ratio.width = 16;
852aspect_ratio.height = 9;
853} else if ((y * 16 / 10) == x) {
854aspect_ratio.width = 16;
855aspect_ratio.height = 10;
856} else if ((y * 5 / 4) == x) {
857aspect_ratio.width = 5;
858aspect_ratio.height = 4;
859} else if ((y * 15 / 9) == x) {
860aspect_ratio.width = 15;
861aspect_ratio.height = 9;
862} else {
863aspect_ratio.width = 4;
864aspect_ratio.height = 3;
865}
866
867NV_MODELINE *mode_timing = (NV_MODELINE *) map->nv_mode_table;
868NV_MODELINE_2 *mode_timing_2 = (NV_MODELINE_2 *) map->nv_mode_table_2;
869
870i = 0;
871if (mode_timing_2[i].h_disp == 0x140) { //From 320x200 mode.
872while (mode_timing_2[i].h_disp <= 0x800) {
873
874vbios_modeline_type2 * modeliner = malloc(sizeof(vbios_modeline_type2));
875bzero(modeliner, sizeof(vbios_modeline_type2));
876
877x = mode_timing_2[i].h_disp;
878y = x * aspect_ratio.height / aspect_ratio.width;
879
880cvt_timings(x, y, 60, &modeliner->clock,
881&modeliner->hsyncstart, &modeliner->hsyncend,
882&modeliner->hblank, &modeliner->vsyncstart,
883&modeliner->vsyncend, &modeliner->vblank, TRUE);
884
885mode_timing_2[i].h_disp = x;
886mode_timing_2[i].v_disp = y;
887mode_timing_2[i].h_blank = modeliner->hblank - x;
888mode_timing_2[i].h_syncoffset = modeliner->hsyncstart - x;
889mode_timing_2[i].h_syncwidth = modeliner->hsyncend - modeliner->hsyncstart;
890mode_timing_2[i].v_blank = modeliner->vblank - y;
891i++;
892free(modeliner);
893}
894}
895i = 0;
896
897while ((mode_timing[i].reserved3 & 0xff) == 0xff) {
898x = mode_timing[i].usH_Active;
899y = x * aspect_ratio.height / aspect_ratio.width;
900
901vbios_modeline_type2 * modeliner = malloc(sizeof(vbios_modeline_type2));
902bzero(modeliner, sizeof(vbios_modeline_type2));
903
904cvt_timings(x, y, 60, &modeliner->clock,
905&modeliner->hsyncstart, &modeliner->hsyncend,
906&modeliner->hblank, &modeliner->vsyncstart,
907&modeliner->vsyncend, &modeliner->vblank, FALSE);
908
909mode_timing[i].usH_Total = x + modeliner->hblank;
910mode_timing[i].usH_Active = x;
911mode_timing[i].usH_Active_minus_One = x - 1;
912mode_timing[i].usH_Active_minus_One_ = x - 1;
913mode_timing[i].usH_SyncStart = modeliner->hsyncstart;
914mode_timing[i].usH_SyncEnd = modeliner->hsyncend;
915
916mode_timing[i].usV_Total = y + modeliner->vblank;
917mode_timing[i].usV_Active = y;
918mode_timing[i].usV_Active_minus_One = y - 1;
919mode_timing[i].usV_Active_minus_One_ = y - 1;
920mode_timing[i].usV_SyncStart = modeliner->vsyncend;
921mode_timing[i].usV_SyncEnd = modeliner->vsyncend;
922
923mode_timing[i].usPixel_Clock = modeliner->clock;
924
925i++;
926}
927}
928
929break;
930case BT_UNKWN:
931break;
932}
933//}
934//}
935}
936

Archive Download this file

Revision: 131