Chameleon

Chameleon Svn Source Tree

Root/branches/diebuche/i386/libsaio/ATIresolution.c

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

Archive Download this file

Revision: 113