Chameleon

Chameleon Svn Source Tree

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

Source at commit 106 created 10 years 10 months ago.
By diebuche, Adding 915patch and edid
1/* Copied from 915 resolution created by steve tomljenovic
2 * This source code is into the public domain.
3 *
4 * Included to Chameleon RC3 by meklort
5 *
6 * Included to RC4 and edited by deviato to match more intel chipsets
7 *
8 */
9
10#include "libsaio.h"
11#include "915resolution.h"
12
13char * chipset_type_names[] = {
14"UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", "945GM", "945GME",
15"946GZ", "G965", "Q965", "965GM", "G41", "G31", "G45", "GM45", "500"
16};
17
18char * bios_type_names[] = {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"};
19
20int freqs[] = { 60, 75, 85 };
21
22UInt32 get_chipset_id(void) {
23outl(0xcf8, 0x80000000);
24return inl(0xcfc);
25}
26
27chipset_type get_chipset(UInt32 id) {
28chipset_type type;
29
30switch (id) {
31case 0x35758086:
32type = CT_830;
33break;
34
35case 0x25608086:
36type = CT_845G;
37break;
38
39case 0x35808086:
40type = CT_855GM;
41break;
42
43case 0x25708086:
44type = CT_865G;
45break;
46
47case 0x25808086:
48type = CT_915G;
49break;
50
51case 0x25908086:
52type = CT_915GM;
53break;
54
55case 0x27708086:
56type = CT_945G;
57break;
58
59case 0x27a08086:
60type = CT_945GM;
61break;
62
63case 0x27ac8086:
64type = CT_945GME;
65break;
66
67case 0x29708086:
68type = CT_946GZ;
69break;
70
71case 0x29a08086:
72type = CT_G965;
73break;
74
75case 0x29908086:
76type = CT_Q965;
77break;
78
79case 0x2a008086:
80type = CT_965GM;
81break;
82
83case 0x2a408086:
84type = CT_GM45;
85break;
86
87case 0x2e308086:
88type = CT_G41;
89break;
90
91case 0x29c08086:
92type = CT_G31;
93break;
94
95case 0x2e208086:
96type = CT_G45;
97break;
98
99case 0x81008086:
100type = CT_500;
101break;
102
103
104default:
105type = CT_UNKWN;
106break;
107}
108return type;
109}
110
111vbios_resolution_type1 * map_type1_resolution(vbios_map * map, UInt16 res) {
112vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res));
113return ptr;
114}
115
116vbios_resolution_type2 * map_type2_resolution(vbios_map * map, UInt16 res) {
117vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res));
118return ptr;
119}
120
121vbios_resolution_type3 * map_type3_resolution(vbios_map * map, UInt16 res) {
122vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res));
123return ptr;
124}
125
126char detect_bios_type(vbios_map * map, char modeline, int entry_size) {
127UInt32 i;
128UInt16 r1, r2;
129
130r1 = r2 = 32000;
131
132for (i=0; i < map->mode_table_size; i++) {
133if (map->mode_table[i].resolution <= r1) {
134r1 = map->mode_table[i].resolution;
135}
136else {
137if (map->mode_table[i].resolution <= r2) {
138r2 = map->mode_table[i].resolution;
139}
140}
141
142/*printf("r1 = %d r2 = %d\n", r1, r2);*/
143}
144
145return (r2-r1-6) % entry_size == 0;
146}
147
148void close_vbios(vbios_map * map);
149
150vbios_map * open_vbios(chipset_type forced_chipset) {
151UInt32 z;
152vbios_map * map = NEW(vbios_map);
153for(z=0; z<sizeof(vbios_map); z++) ((char*)map)[z]=0;
154
155/*
156 * Determine chipset
157 */
158
159if (forced_chipset == CT_UNKWN) {
160map->chipset_id = get_chipset_id();
161map->chipset = get_chipset(map->chipset_id);
162}
163else if (forced_chipset != CT_UNKWN) {
164map->chipset = forced_chipset;
165}
166else {
167map->chipset = CT_915GM;
168}
169
170/*
171 * Map the video bios to memory
172 */
173
174map->bios_ptr=(char*)VBIOS_START;
175
176/*
177 * check if we have ATI Radeon
178 */
179
180/*
181 * check if we have NVIDIA
182 */
183
184/*
185 * check if we have Intel
186 */
187
188/*
189 * check for others
190 */
191
192if (map->chipset == CT_UNKWN) {
193printf("Unknown chipset type and unrecognized bios.\n");
194printf("915resolution only works with Intel 800/900 series graphic chipsets.\n");
195
196printf("Chipset Id: %x\n", map->chipset_id);
197close_vbios(map);
198return 0;
199}
200
201/*
202 * Figure out where the mode table is
203 */
204
205{
206char* p = map->bios_ptr + 16;
207char* limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode));
208
209while (p < limit && map->mode_table == 0) {
210vbios_mode * mode_ptr = (vbios_mode *) p;
211
212if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) &&
213((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) {
214
215map->mode_table = mode_ptr;
216}
217
218p++;
219}
220
221if (map->mode_table == 0) {
222printf("Unable to locate the mode table.\n");
223printf("Please run the program 'dump_bios' as root and\n");
224printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
225printf("Chipset: %s\n", chipset_type_names[map->chipset]);
226close_vbios(map);
227return 0;
228}
229}
230
231/*
232 * Determine size of mode table
233 */
234
235{
236vbios_mode * mode_ptr = map->mode_table;
237
238while (mode_ptr->mode != 0xff) {
239map->mode_table_size++;
240mode_ptr++;
241}
242}
243
244/*
245 * Figure out what type of bios we have
246 * order of detection is important
247 */
248
249if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type3))) {
250map->bios = BT_3;
251}
252else if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type2))) {
253map->bios = BT_2;
254}
255else if (detect_bios_type(map, FALSE, sizeof(vbios_resolution_type1))) {
256map->bios = BT_1;
257}
258else {
259printf("Unable to determine bios type.\n");
260printf("Please run the program 'dump_bios' as root and\n");
261printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");
262
263printf("Chipset: %s\n", chipset_type_names[map->chipset]);
264printf("Mode Table Offset: $C0000 + $%x\n", ((UInt32)map->mode_table) - ((UInt32)map->bios_ptr));
265printf("Mode Table Entries: %u\n", map->mode_table_size);
266return 0;
267}
268
269return map;
270}
271
272void close_vbios(vbios_map * map) {
273FREE(map);
274}
275
276void unlock_vbios(vbios_map * map) {
277
278map->unlocked = TRUE;
279
280switch (map->chipset) {
281case CT_UNKWN:
282break;
283case CT_830:
284case CT_855GM:
285outl(0xcf8, 0x8000005a);
286map->b1 = inb(0xcfe);
287
288outl(0xcf8, 0x8000005a);
289outb(0xcfe, 0x33);
290break;
291case CT_845G:
292case CT_865G:
293case CT_915G:
294case CT_915GM:
295case CT_945G:
296case CT_945GM:
297case CT_945GME:
298case CT_946GZ:
299case CT_G965:
300case CT_Q965:
301case CT_965GM:
302case CT_GM45:
303case CT_G41:
304case CT_G31:
305case CT_G45:
306case CT_500:
307outl(0xcf8, 0x80000090);
308map->b1 = inb(0xcfd);
309map->b2 = inb(0xcfe);
310
311outl(0xcf8, 0x80000090);
312outb(0xcfd, 0x33);
313outb(0xcfe, 0x33);
314break;
315}
316
317#if DEBUG
318{
319UInt32 t = inl(0xcfc);
320printf("unlock PAM: (0x%08x)\n", t);
321}
322#endif
323}
324
325void relock_vbios(vbios_map * map) {
326
327map->unlocked = FALSE;
328
329switch (map->chipset) {
330case CT_UNKWN:
331break;
332case CT_830:
333case CT_855GM:
334outl(0xcf8, 0x8000005a);
335outb(0xcfe, map->b1);
336break;
337case CT_845G:
338case CT_865G:
339case CT_915G:
340case CT_915GM:
341case CT_945G:
342case CT_945GM:
343case CT_945GME:
344case CT_946GZ:
345case CT_G965:
346case CT_Q965:
347case CT_965GM:
348case CT_GM45:
349case CT_G41:
350case CT_G31:
351case CT_G45:
352case CT_500:
353outl(0xcf8, 0x8000005a);
354outb(0xcfd, map->b1);
355outb(0xcfe, map->b2);
356break;
357}
358
359#if DEBUG
360{
361 UInt32 t = inl(0xcfc);
362printf("relock PAM: (0x%08x)\n", t);
363}
364#endif
365}
366
367
368void list_modes(vbios_map *map, UInt32 raw) {
369 UInt32 i, x, y;
370
371 for (i=0; i < map->mode_table_size; i++) {
372 switch(map->bios) {
373case BT_1:
374 {
375 vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
376
377 x = ((((UInt32) res->x2) & 0xf0) << 4) | res->x1;
378 y = ((((UInt32) res->y2) & 0xf0) << 4) | res->y1;
379
380 if (x != 0 && y != 0) {
381 printf("Mode %02x : %dx%d, %d bits/pixel\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
382 }
383
384if (raw)
385{
386 printf("Mode %02x (raw) :\n\t%02x %02x\n\t%02x\n\t%02x\n\t%02x\n\t%02x\n\t%02x\n\t%02x\n", map->mode_table[i].mode, res->unknow1[0],res->unknow1[1], res->x1,res->x_total,res->x2,res->y1,res->y_total,res->y2);
387}
388
389 }
390break;
391case BT_2:
392 {
393 vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
394
395 x = res->modelines[0].x1+1;
396 y = res->modelines[0].y1+1;
397
398 if (x != 0 && y != 0) {
399 printf("Mode %02x : %dx%d, %d bits/pixel\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
400 }
401 }
402break;
403case BT_3:
404 {
405 vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
406
407 x = res->modelines[0].x1+1;
408 y = res->modelines[0].y1+1;
409
410 if (x != 0 && y != 0) {
411 printf("Mode %02x : %dx%d, %d bits/pixel\n", map->mode_table[i].mode, x, y, map->mode_table[i].bits_per_pixel);
412 }
413 }
414break;
415case BT_UNKWN:
416break;
417 }
418 }
419}
420
421static void gtf_timings(UInt32 x, UInt32 y, UInt32 freq,
422unsigned long *clock,
423UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,
424UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank)
425{
426UInt32 hbl, vbl, vfreq;
427
428vbl = y + (y+1)/(20000.0/(11*freq) - 1) + 1.5;
429vfreq = vbl * freq;
430hbl = 16 * (int)(x * (30.0 - 300000.0 / vfreq) /
431 + (70.0 + 300000.0 / vfreq) / 16.0 + 0.5);
432
433*vsyncstart = y;
434*vsyncend = y + 3;
435*vblank = vbl - 1;
436*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
437*hsyncend = x + hbl / 2 - 1;
438*hblank = x + hbl - 1;
439*clock = (x + hbl) * vfreq / 1000;
440}
441
442void set_mode(vbios_map * map, /*UInt32 mode,*/ UInt32 x, UInt32 y, UInt32 bp, UInt32 htotal, UInt32 vtotal) {
443UInt32 xprev, yprev;
444UInt32 i = 0, j;// patch first available mode
445
446//for (i=0; i < map->mode_table_size; i++) {
447//if (map->mode_table[0].mode == mode) {
448switch(map->bios) {
449case BT_1:
450{
451vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);
452
453if (bp) {
454map->mode_table[i].bits_per_pixel = bp;
455}
456
457res->x2 = (htotal?(((htotal-x) >> 8) & 0x0f) : (res->x2 & 0x0f)) | ((x >> 4) & 0xf0);
458res->x1 = (x & 0xff);
459
460res->y2 = (vtotal?(((vtotal-y) >> 8) & 0x0f) : (res->y2 & 0x0f)) | ((y >> 4) & 0xf0);
461res->y1 = (y & 0xff);
462if (htotal)
463res->x_total = ((htotal-x) & 0xff);
464
465if (vtotal)
466res->y_total = ((vtotal-y) & 0xff);
467}
468break;
469case BT_2:
470{
471vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);
472
473res->xchars = x / 8;
474res->ychars = y / 16 - 1;
475xprev = res->modelines[0].x1;
476yprev = res->modelines[0].y1;
477
478for(j=0; j < 3; j++) {
479vbios_modeline_type2 * modeline = &res->modelines[j];
480
481if (modeline->x1 == xprev && modeline->y1 == yprev) {
482modeline->x1 = modeline->x2 = x-1;
483modeline->y1 = modeline->y2 = y-1;
484
485gtf_timings(x, y, freqs[j], &modeline->clock,
486&modeline->hsyncstart, &modeline->hsyncend,
487&modeline->hblank, &modeline->vsyncstart,
488&modeline->vsyncend, &modeline->vblank);
489
490if (htotal)
491modeline->htotal = htotal;
492else
493modeline->htotal = modeline->hblank;
494
495if (vtotal)
496modeline->vtotal = vtotal;
497else
498modeline->vtotal = modeline->vblank;
499}
500}
501}
502break;
503case BT_3:
504{
505vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);
506
507xprev = res->modelines[0].x1;
508yprev = res->modelines[0].y1;
509
510for (j=0; j < 3; j++) {
511vbios_modeline_type3 * modeline = &res->modelines[j];
512
513if (modeline->x1 == xprev && modeline->y1 == yprev) {
514modeline->x1 = modeline->x2 = x-1;
515modeline->y1 = modeline->y2 = y-1;
516
517gtf_timings(x, y, freqs[j], &modeline->clock,
518&modeline->hsyncstart, &modeline->hsyncend,
519&modeline->hblank, &modeline->vsyncstart,
520&modeline->vsyncend, &modeline->vblank);
521if (htotal)
522modeline->htotal = htotal;
523else
524modeline->htotal = modeline->hblank;
525if (vtotal)
526modeline->vtotal = vtotal;
527else
528modeline->vtotal = modeline->vblank;
529
530modeline->timing_h = y-1;
531modeline->timing_v = x-1;
532}
533}
534}
535break;
536case BT_UNKWN:
537break;
538}
539//}
540//}
541}
542
543void display_map_info(vbios_map * map) {
544printf("Chipset: %s\n", chipset_type_names[map->chipset]);
545printf("BIOS: %s\n", bios_type_names[map->bios]);
546
547printf("Mode Table Offset: $C0000 + $%x\n", ((UInt32)map->mode_table) - ((UInt32)map->bios_ptr));
548printf("Mode Table Entries: %u\n", map->mode_table_size);
549}
550

Archive Download this file

Revision: 106