Chameleon

Chameleon Svn Source Tree

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

Source at commit 132 created 14 years 1 month ago.
By diebuche, Adding lebidous latest changes
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 "autoresolution.h"
19#include "nvidia_resolution.h"
20#include "ati_resolution.h"
21#include "gma_resolution.h"
22#include "../boot2/graphics.h"
23
24char * chipset_type_names[] = {
25"UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", "945GM", "945GME",
26"946GZ", "955X", "G965", "Q965", "965GM", "975X",
27"P35", "X48", "B43", "Q45", "P45", "GM45", "G41", "G31", "G45", "500"
28};
29
30UInt32 get_chipset_id(void) {
31outl(0xcf8, 0x80000000);
32return inl(0xcfc);
33}
34
35chipset_type get_chipset(UInt32 id) {
36chipset_type type;
37
38switch (id) {
39case 0x35758086:
40type = CT_830;
41break;
42
43case 0x25608086:
44type = CT_845G;
45break;
46
47case 0x35808086:
48type = CT_855GM;
49break;
50
51case 0x25708086:
52type = CT_865G;
53break;
54
55case 0x25808086:
56type = CT_915G;
57break;
58
59case 0x25908086:
60type = CT_915GM;
61break;
62
63case 0x27708086:
64type = CT_945G;
65break;
66
67case 0x27748086:
68type = CT_955X;
69break;
70
71case 0x277c8086:
72type = CT_975X;
73break;
74
75case 0x27a08086:
76type = CT_945GM;
77break;
78
79case 0x27ac8086:
80type = CT_945GME;
81break;
82
83case 0x29708086:
84type = CT_946GZ;
85break;
86
87case 0x29a08086:
88type = CT_G965;
89break;
90
91case 0x29908086:
92type = CT_Q965;
93break;
94
95case 0x2a008086:
96type = CT_965GM;
97break;
98
99case 0x29e08086:
100type = CT_X48;
101break;
102
103case 0x2a408086:
104type = CT_GM45;
105break;
106
107case 0x2e108086:
108case 0X2e908086:
109type = CT_B43;
110break;
111
112case 0x2e208086:
113type = CT_P45;
114break;
115
116case 0x2e308086:
117type = CT_G41;
118break;
119
120case 0x29c08086:
121type = CT_G31;
122break;
123
124case 0x29208086:
125type = CT_G45;
126break;
127
128case 0x81008086:
129type = CT_500;
130break;
131
132default:
133type = CT_UNKWN;
134break;
135}
136return type;
137}
138
139
140void gtf_timings(UInt32 x, UInt32 y, UInt32 freq,
141 unsigned long *clock,
142 UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,
143 UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank)
144{
145UInt32 hbl, vbl, vfreq;
146
147vbl = y + (y+1)/(20000/(11*freq) - 1) + 1;
148
149vfreq = vbl * freq;
150hbl = 16 * (int)(x * (30 - 300000 / vfreq) /
151 + (70 + 300000 / vfreq) / 16 + 0);
152
153*vsyncstart = y;
154*vsyncend = y + 3;
155*vblank = vbl;
156*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 ;
157*hsyncend = x + hbl / 2;
158*hblank = x + hbl;
159*clock = (x + hbl) * vfreq / 1000;
160}
161
162
163void get_aspect_ratio(s_aspect* aspect, UInt32 x, UInt32 y)
164{
165if ((y * 16 / 9) == x) {
166aspect->width = 16;
167aspect->height = 9;
168} else if ((y * 16 / 10) == x) {
169aspect->width = 16;
170aspect->height = 10;
171} else if ((y * 5 / 4) == x) {
172aspect->width = 5;
173aspect->height = 4;
174} else if ((y * 15 / 9) == x) {
175aspect->width = 15;
176aspect->height = 9;
177} else {
178aspect->width = 4;
179aspect->height = 3;
180}
181verbose("Aspect Ratio is %d/%d\n", aspect->width, aspect->height);
182}
183
184void cvt_timings(UInt32 x, UInt32 y, UInt32 freq,
185 unsigned long *clock,
186 UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,
187 UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank, bool reduced)
188{
189UInt32 hbl, hbp, vbl, vsync, hperiod;
190
191if (!(y % 3) && ((y * 4 / 3) == x))
192 vsync = 4;
193 else if (!(y % 9) && ((y * 16 / 9) == x))
194 vsync = 5;
195 else if (!(y % 10) && ((y * 16 / 10) == x))
196 vsync = 6;
197 else if (!(y % 4) && ((y * 5 / 4) == x))
198 vsync = 7;
199 else if (!(y % 9) && ((y * 15 / 9) == x))
200 vsync = 7;
201 else /* Custom */
202 vsync = 10;
203
204if (!reduced) {
205hperiod = (1000000/freq - 550) / (y + 3);
206vbl = y + (550/hperiod) + 3;
207hbp = 30 - ((300*hperiod)/1000);
208hbl = (x * hbp) / (100 - hbp);
209
210*vsyncstart = y + 6;
211*vsyncend = *vsyncstart + vsync;
212*vblank = vbl - 1;
213*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;
214*hsyncend = x + hbl / 2 - 1;
215*hblank = x + hbl - 1;
216
217} else {
218hperiod = (1000000/freq - 460) / y;
219vbl = y + 460/hperiod + 1;
220hbl = 160;
221
222*vsyncstart = y + 3;
223*vsyncend = *vsyncstart + vsync;
224*vblank = vbl - 1;
225*hsyncstart = x + hbl / 2 - 32;
226*hsyncend = x + hbl / 2 - 1;
227*hblank = x + hbl - 1;
228
229}
230*clock = (x + hbl) * 1000 / hperiod;
231}
232
233
234
235void close_vbios(vbios_map * map);
236
237vbios_map * open_vbios(chipset_type forced_chipset) {
238UInt32 z;
239vbios_map * map = NEW(vbios_map);
240for(z=0; z<sizeof(vbios_map); z++) ((char*)map)[z]=0;
241
242/*
243 * Determine chipset
244 */
245
246if (forced_chipset == CT_UNKWN) {
247map->chipset_id = get_chipset_id();
248map->chipset = get_chipset(map->chipset_id);
249verbose("Chipset is %s (pci id 0x%x)\n",chipset_type_names[map->chipset], map->chipset_id);
250}
251else if (forced_chipset != CT_UNKWN) {
252map->chipset = forced_chipset;
253}
254else {
255map->chipset = CT_915GM;
256}
257
258/*
259 * Map the video bios to memory
260 */
261
262map->bios_ptr=(unsigned char*)VBIOS_START;
263
264/*
265 * check if we have ATI Radeon and open atombios
266 */
267bios_tables_t ati_tables;
268
269ati_tables.base = map->bios_ptr;
270ati_tables.AtomRomHeader = (ATOM_ROM_HEADER *) (map->bios_ptr + *(unsigned short *) (map->bios_ptr + OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER));
271if (strcmp ((char *) ati_tables.AtomRomHeader->uaFirmWareSignature, "ATOM") == 0) {
272map->bios = BT_ATI_1;
273verbose("We have an AtomBios Card\n");
274return open_ati_vbios(map, ati_tables);
275}
276
277
278/*
279 * check if we have NVidia
280 */
281if (map->bios != BT_ATI_1) {
282int i = 0;
283while (i < 512) { // we don't need to look through the whole bios, just the firs 512 bytes
284if ((map->bios_ptr[i] == 'N')
285&& (map->bios_ptr[i+1] == 'V')
286&& (map->bios_ptr[i+2] == 'I')
287&& (map->bios_ptr[i+3] == 'D'))
288{
289map->bios = BT_NVDA;
290verbose("We have an NVIDIA Card\n");
291return open_nvidia_vbios(map);
292break;
293}
294i++;
295}
296}
297
298/*
299 * check if we have Intel
300 */
301
302if ((map->bios != BT_ATI_1) && (map->bios != BT_NVDA)) {
303int i = 0;
304while (i < VBIOS_SIZE) { // we don't need to look through the whole bios, just the firs 512 bytes
305if ((map->bios_ptr[i] == 'I')
306&& (map->bios_ptr[i+1] == 'n')
307&& (map->bios_ptr[i+2] == 't')
308&& (map->bios_ptr[i+3] == 'e')
309&& (map->bios_ptr[i+4] == 'l'))
310{
311map->bios = BT_1;
312verbose("We have an Intel Card\n");
313return open_intel_vbios(map);
314break;
315}
316i++;
317}
318}
319
320/*
321 * Unidentified Chipset
322 */
323
324if (map->chipset == CT_UNKWN) {
325verbose("Unknown chipset type and unrecognized bios.\n");
326
327verbose("autoresolution only works with Intel 800/900 series graphic chipsets.\n");
328
329verbose("Chipset Id: %x\n", map->chipset_id);
330close_vbios(map);
331return 0;
332}
333
334/*
335 * Should never get there
336 */
337return 0;
338}
339
340void close_vbios(vbios_map * map) {
341if (autoResolution == TRUE) autoResolution = FALSE;
342FREE(map);
343}
344
345void unlock_vbios(vbios_map * map) {
346
347map->unlocked = TRUE;
348
349switch (map->chipset) {
350case CT_UNKWN:
351break;
352case CT_830:
353case CT_855GM:
354outl(0xcf8, 0x8000005a);
355map->b1 = inb(0xcfe);
356
357outl(0xcf8, 0x8000005a);
358outb(0xcfe, 0x33);
359break;
360case CT_845G:
361case CT_865G:
362case CT_915G:
363case CT_915GM:
364case CT_945G:
365case CT_945GM:
366case CT_945GME:
367case CT_946GZ:
368case CT_955X:
369case CT_G965:
370case CT_Q965:
371case CT_965GM:
372case CT_975X:
373case CT_P35:
374case CT_X48:
375case CT_B43:
376case CT_Q45:
377case CT_P45:
378case CT_GM45:
379case CT_G41:
380case CT_G31:
381case CT_G45:
382case CT_500:
383
384outl(0xcf8, 0x80000090);
385map->b1 = inb(0xcfd);
386map->b2 = inb(0xcfe);
387outl(0xcf8, 0x80000090);
388outb(0xcfd, 0x33);
389outb(0xcfe, 0x33);
390break;
391}
392
393#if DEBUG
394{
395UInt32 t = inl(0xcfc);
396printf("unlock PAM: (0x%08x)\n", t);
397}
398#endif
399}
400
401void relock_vbios(vbios_map * map) {
402
403map->unlocked = FALSE;
404
405switch (map->chipset) {
406case CT_UNKWN:
407break;
408case CT_830:
409case CT_855GM:
410outl(0xcf8, 0x8000005a);
411outb(0xcfe, map->b1);
412break;
413case CT_845G:
414case CT_865G:
415case CT_915G:
416case CT_915GM:
417case CT_945G:
418case CT_945GM:
419case CT_945GME:
420case CT_946GZ:
421case CT_955X:
422case CT_G965:
423case CT_Q965:
424case CT_965GM:
425case CT_975X:
426case CT_P35:
427case CT_X48:
428case CT_B43:
429case CT_Q45:
430case CT_P45:
431case CT_GM45:
432case CT_G41:
433case CT_G31:
434case CT_G45:
435case CT_500:
436
437outl(0xcf8, 0x80000090);
438outb(0xcfd, map->b1);
439outb(0xcfe, map->b2);
440break;
441}
442
443#if DEBUG
444{
445 UInt32 t = inl(0xcfc);
446printf("relock PAM: (0x%08x)\n", t);
447}
448#endif
449}
450
451
452void save_vbios(vbios_map * map)
453{
454map->bios_backup_ptr = malloc(VBIOS_SIZE);
455bcopy((const unsigned char *)0xC0000, map->bios_backup_ptr, VBIOS_SIZE);
456}
457
458void restore_vbios(vbios_map * map)
459{
460bcopy(map->bios_backup_ptr,(unsigned char *)0xC0000, VBIOS_SIZE);
461}
462
463
464void patch_vbios(vbios_map * map, UInt32 x, UInt32 y, UInt32 bp, UInt32 htotal, UInt32 vtotal) {
465UInt32 i = 0;
466bool err = TRUE;
467/*
468 * Get the aspect ratio for the requested mode
469 */
470get_aspect_ratio(&map->aspect_ratio, x, y);
471
472i = x = y = 0;
473
474if (map->bios != BT_NVDA) {
475while (i < map->modeline_num) {
476if (x == 1400) x = 1440;
477if (x == 1600) x = 1680;
478
479y = x * map->aspect_ratio.height / map->aspect_ratio.width;
480switch (map->bios) {
481case BT_1:
482intel_set_mode_1(map, i, &x, &y);
483break;
484case BT_2:
485intel_set_mode_2(map, i, &x, &y);
486break;
487case BT_3:
488intel_set_mode_3(map, i, &x, &y);
489break;
490case BT_ATI_1:
491ati_set_mode_1(map, i, &x, &y);
492break;
493case BT_ATI_2:
494ati_set_mode_2(map, i, &x, &y);
495break;
496default:
497break;
498}
499i++;
500}
501}
502
503if (map->bios == BT_NVDA) {
504err = TRUE;
505
506x = y = 0;
507while (err == TRUE) {
508if (x == 1400) x = 1440;
509if (x == 1600) x = 1680;
510
511y = x * map->aspect_ratio.height / map->aspect_ratio.width;
512err = nvidia_set_mode(map, i, &x, &y, MAIN_VESA_TABLE);
513
514}
515err = TRUE;
516x = y = 0;
517while (err == TRUE) {
518if (x == 1400) x = 1440;
519if (x == 1600) x = 1680;
520
521y = x * map->aspect_ratio.height / map->aspect_ratio.width;
522err = nvidia_set_mode(map, i, &x, &y, SECOND_VESA_TABLE);
523}
524}
525}

Archive Download this file

Revision: 132