Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 113