1 | /* Copied from 915 resolution created by steve tomljenovic␊ |
2 | *␊ |
3 | * This code is based on the techniques used in :␊ |
4 | *␊ |
5 | * - 855patch. Many thanks to Christian Zietz (czietz gmx net)␊ |
6 | * for demonstrating how to shadow the VBIOS into system RAM␊ |
7 | * and then modify it.␊ |
8 | *␊ |
9 | * - 1280patch by Andrew Tipton (andrewtipton null li).␊ |
10 | *␊ |
11 | * - 855resolution by Alain Poirier␊ |
12 | *␊ |
13 | * This source code is into the public domain.␊ |
14 | */␊ |
15 | ␊ |
16 | //#include "libsaio.h"␊ |
17 | //#include "autoresolution.h" - included on *_resolution.h␊ |
18 | //------------␊ |
19 | #include "boot.h"␊ |
20 | #include "gui.h"␊ |
21 | #include "options.h"␊ |
22 | #include "nvidia_resolution.h"␊ |
23 | #include "ati_resolution.h"␊ |
24 | #include "gma_resolution.h"␊ |
25 | #include "../boot2/graphics.h" //Azi:reminder␊ |
26 | ␊ |
27 | char * chipsetTypeNames[] = {␊ |
28 | ␉"UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", "945GM", "945GME",␊ |
29 | ␉"946GZ", "955X", "G965", "Q965", "965GM", "975X",␊ |
30 | ␉"P35", "X48", "B43", "Q45", "P45", "GM45", "G41", "G31", "G45", "500"␊ |
31 | };␊ |
32 | ␊ |
33 | uint32_t getChipsetId(void)␊ |
34 | {␊ |
35 | ␉outl(0xcf8, 0x80000000);␊ |
36 | ␉return inl(0xcfc);␊ |
37 | }␊ |
38 | ␊ |
39 | chipsetType getChipset(uint32_t id)␊ |
40 | {␊ |
41 | ␉chipsetType type;␊ |
42 | ␉␊ |
43 | ␉switch (id)␊ |
44 | ␉{␊ |
45 | ␉␉case 0x35758086:␊ |
46 | ␉␉␉type = CT_830;␊ |
47 | ␉␉␉break;␊ |
48 | ␉␉␊ |
49 | ␉␉case 0x25608086:␊ |
50 | ␉␉␉type = CT_845G;␊ |
51 | ␉␉␉break;␊ |
52 | ␉␉␉␉␊ |
53 | ␉␉case 0x35808086:␊ |
54 | ␉␉␉type = CT_855GM;␊ |
55 | ␉␉␉break;␊ |
56 | ␉␉␉␉␊ |
57 | ␉␉case 0x25708086:␊ |
58 | ␉␉␉type = CT_865G;␊ |
59 | ␉␉␉break;␊ |
60 | ␉␉␊ |
61 | ␉␉case 0x25808086:␊ |
62 | ␉␉␉type = CT_915G;␊ |
63 | ␉␉␉break;␊ |
64 | ␉␉␉␊ |
65 | ␉␉case 0x25908086:␊ |
66 | ␉␉␉type = CT_915GM;␊ |
67 | ␉␉␉break;␊ |
68 | ␉␉␉␊ |
69 | ␉␉case 0x27708086:␊ |
70 | ␉␉␉type = CT_945G;␊ |
71 | ␉␉␉break;␊ |
72 | ␉␉␉␊ |
73 | ␉␉case 0x27748086:␊ |
74 | ␉␉␉type = CT_955X;␊ |
75 | ␉␉␉break;␊ |
76 | ␉␉␉␊ |
77 | ␉␉case 0x277c8086:␊ |
78 | ␉␉␉type = CT_975X;␊ |
79 | ␉␉␉break;␊ |
80 | ␉␉␊ |
81 | ␉␉case 0x27a08086:␊ |
82 | ␉␉␉type = CT_945GM;␊ |
83 | ␉␉␉break;␊ |
84 | ␉␉␉␊ |
85 | ␉␉case 0x27ac8086:␊ |
86 | ␉␉␉type = CT_945GME;␊ |
87 | ␉␉␉break;␊ |
88 | ␉␉␉␊ |
89 | ␉␉case 0x29708086:␊ |
90 | ␉␉␉type = CT_946GZ;␊ |
91 | ␉␉␉break;␊ |
92 | ␉␉␉␊ |
93 | ␉␉case 0x29a08086:␊ |
94 | ␉␉␉type = CT_G965;␊ |
95 | ␉␉␉break;␊ |
96 | ␉␉␉␊ |
97 | ␉␉case 0x29908086:␊ |
98 | ␉␉␉type = CT_Q965;␊ |
99 | ␉␉␉break;␊ |
100 | ␉␉␉␊ |
101 | ␉␉case 0x2a008086:␊ |
102 | ␉␉␉type = CT_965GM;␊ |
103 | ␉␉␉break;␊ |
104 | ␉␉␉␊ |
105 | ␉␉case 0x29e08086:␊ |
106 | ␉␉␉type = CT_X48;␊ |
107 | ␉␉␉break;␉␉␉␊ |
108 | ␉␉␉␊ |
109 | ␉␉case 0x2a408086:␊ |
110 | ␉␉␉type = CT_GM45;␊ |
111 | ␉␉␉break;␊ |
112 | ␉␉␉␊ |
113 | ␉␉case 0x2e108086:␊ |
114 | ␉␉case 0X2e908086:␊ |
115 | ␉␉␉type = CT_B43;␊ |
116 | ␉␉␉break;␊ |
117 | ␉␉␉␊ |
118 | ␉␉case 0x2e208086:␊ |
119 | ␉␉␉type = CT_P45;␊ |
120 | ␉␉␉break;␊ |
121 | ␉␉␉␊ |
122 | ␉␉case 0x2e308086:␊ |
123 | ␉␉␉type = CT_G41;␊ |
124 | ␉␉␉break;␊ |
125 | ␉␉␉␊ |
126 | ␉␉case 0x29c08086:␊ |
127 | ␉␉␉type = CT_G31;␊ |
128 | ␉␉␉break;␊ |
129 | ␉␉␉␊ |
130 | ␉␉case 0x29208086:␊ |
131 | ␉␉␉type = CT_G45;␊ |
132 | ␉␉␉break;␊ |
133 | ␉␉␉␊ |
134 | ␉␉case 0x81008086:␊ |
135 | ␉␉␉type = CT_500;␊ |
136 | ␉␉␉break;␊ |
137 | ␉␉␉␊ |
138 | ␉␉default:␊ |
139 | ␉␉␉type = CT_UNKNOWN;␊ |
140 | ␉␉␉break;␊ |
141 | ␉}␊ |
142 | ␉return type;␊ |
143 | }␊ |
144 | ␊ |
145 | ␊ |
146 | void gtfTimings(uint32_t x, uint32_t y, uint32_t freq,␊ |
147 | ␉␉␉␉ uint32_t *clock,␊ |
148 | ␉␉␉␉ uint16_t *hSyncStart, uint16_t *hSyncEnd, uint16_t *hBlank,␊ |
149 | ␉␉␉␉ uint16_t *vSyncStart, uint16_t *vSyncEnd, uint16_t *vBlank)␊ |
150 | {␊ |
151 | ␉uint32_t hbl, vbl, vfreq;␊ |
152 | ␉␊ |
153 | ␉vbl = y + (y+1)/(20000/(11*freq) - 1) + 1;␊ |
154 | ␉␊ |
155 | ␉vfreq = vbl * freq;␊ |
156 | ␉hbl = 16 * (int)(x * (30 - 300000 / vfreq) /␊ |
157 | ␉␉␉␉␉ + (70 + 300000 / vfreq) / 16 + 0);␊ |
158 | ␉␊ |
159 | ␉*vSyncStart = y;␊ |
160 | ␉*vSyncEnd = y + 3;␊ |
161 | ␉*vBlank = vbl;␉␊ |
162 | ␉*hSyncStart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 ;␉␊ |
163 | ␉*hSyncEnd = x + hbl / 2;␉␊ |
164 | ␉*hBlank = x + hbl;␉␊ |
165 | ␉*clock = (x + hbl) * vfreq / 1000;␊ |
166 | }␊ |
167 | ␊ |
168 | ␊ |
169 | void getAspectRatio(sAspect* aspect, uint32_t x, uint32_t y)␊ |
170 | {␊ |
171 | ␉if ((y * 16 / 9) == x)␊ |
172 | ␉{␊ |
173 | ␉␉aspect->width = 16;␊ |
174 | ␉␉aspect->height = 9;␊ |
175 | ␉}␊ |
176 | ␉else if ((y * 16 / 10) == x)␊ |
177 | ␉{␊ |
178 | ␉␉aspect->width = 16;␊ |
179 | ␉␉aspect->height = 10;␊ |
180 | ␉}␊ |
181 | ␉else if ((y * 5 / 4) == x)␊ |
182 | ␉{␊ |
183 | ␉␉aspect->width = 5;␊ |
184 | ␉␉aspect->height = 4;␊ |
185 | ␉}␊ |
186 | ␉else if ((y * 15 / 9) == x)␊ |
187 | ␉{␊ |
188 | ␉␉aspect->width = 15;␊ |
189 | ␉␉aspect->height = 9;␊ |
190 | ␉}␊ |
191 | ␉else␊ |
192 | ␉{␊ |
193 | ␉␉aspect->width = 4;␊ |
194 | ␉␉aspect->height = 3;␊ |
195 | ␉}␊ |
196 | ␉PRINT("Aspect Ratio is %d/%d\n", aspect->width, aspect->height);␊ |
197 | }␊ |
198 | ␊ |
199 | ␊ |
200 | /*␊ |
201 | * initialize the mode tables chain␊ |
202 | * tablesCount represents the number of VESA tables in the vBios␊ |
203 | * return value is a pointer to the first table␊ |
204 | */␊ |
205 | sModeTable * intializeTables(vBiosMap * map, int tablesCount) {␊ |
206 | ␉map->modeTables = (sModeTable *)malloc(sizeof(sModeTable));␊ |
207 | ␉sModeTable * table = map->modeTables;␊ |
208 | ␉␊ |
209 | ␉PRINT("Creating %d Mode Tables\n", tablesCount);␊ |
210 | ␉␊ |
211 | ␉int i = tablesCount;␊ |
212 | ␉while ( i != 0 )␊ |
213 | ␉{␉␉␊ |
214 | ␉␉table->id = tablesCount - i;␊ |
215 | ␉␉PRINT("New table with id: %d\n", table->id);␊ |
216 | ␉␉␊ |
217 | ␉␉// opening the chain if it's the first table␊ |
218 | ␉␉if (i == tablesCount)␊ |
219 | ␉␉␉table->prev = NULL;␊ |
220 | ␉␉else // attache the table to the chain␊ |
221 | ␉␉␉table->prev = table; ␊ |
222 | ␉␉␊ |
223 | ␉␉//if there is more than one table, alloc the next one␊ |
224 | ␉␉if (i > 1)␊ |
225 | ␉␉{␊ |
226 | ␉␉␉table->next = (sModeTable *)malloc(sizeof(sModeTable));␊ |
227 | ␉␉␉table = table->next;␊ |
228 | ␉␉}␊ |
229 | ␉␉else // no more table, close the chain␊ |
230 | ␉␉␉table->next = NULL;␊ |
231 | ␉␉␊ |
232 | ␉␉i--;␊ |
233 | ␉}␊ |
234 | ␉␊ |
235 | ␉return map->modeTables;␊ |
236 | }␊ |
237 | ␊ |
238 | ␊ |
239 | //void closeVbios(vBiosMap * map); azi: dup - declared on header␊ |
240 | ␊ |
241 | vBiosMap * openVbios(chipsetType forcedChipset)␊ |
242 | {␊ |
243 | ␉uint32_t z;␊ |
244 | ␉vBiosMap * map = NEW(vBiosMap);␊ |
245 | ␉␊ |
246 | ␉for(z = 0; z < sizeof(vBiosMap); z++)␊ |
247 | ␉␉((char*)map)[z] = 0;␊ |
248 | ␉␊ |
249 | ␉/*␊ |
250 | ␉ * Determine chipset␊ |
251 | ␉ */␊ |
252 | ␉␊ |
253 | ␉if (forcedChipset == CT_UNKNOWN)␊ |
254 | ␉{␊ |
255 | ␉␉map->chipsetId = getChipsetId();␊ |
256 | ␉␉map->chipset = getChipset(map->chipsetId);␊ |
257 | ␉␉PRINT("Chipset is %s (pci id 0x%x)\n",chipsetTypeNames[map->chipset], map->chipsetId);␊ |
258 | ␉}␊ |
259 | ␉else if (forcedChipset != CT_UNKNOWN)␊ |
260 | ␉{␊ |
261 | ␉␉map->chipset = forcedChipset;␊ |
262 | ␉}␊ |
263 | ␉else␊ |
264 | ␉{␊ |
265 | ␉␉map->chipset = CT_915GM;␊ |
266 | ␉}␊ |
267 | ␉ ␊ |
268 | ␉/*␊ |
269 | ␉ * Map the video bios to memory␊ |
270 | ␉ */␊ |
271 | ␉␊ |
272 | ␉map->biosPtr=(uint8_t*)VBIOS_START;␊ |
273 | ␉␊ |
274 | ␉/*␊ |
275 | ␉ * Common initialisation␊ |
276 | ␉ */␊ |
277 | ␉␊ |
278 | //␉map->hasSwitched = false;␊ |
279 | ␉␊ |
280 | ␉/*␊ |
281 | ␉ * check if we have ATI Radeon and open atombios␊ |
282 | ␉ */␊ |
283 | ␉atiBiosTables atiTables;␊ |
284 | ␉␊ |
285 | ␉atiTables.base = map->biosPtr;␊ |
286 | ␉atiTables.atomRomHeader = (atomRomHeader *) (map->biosPtr + *(uint16_t *) (map->biosPtr + OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER)); ␊ |
287 | ␉␊ |
288 | ␉if (strcmp ((char *) atiTables.atomRomHeader->firmWareSignature, "ATOM") == 0)␊ |
289 | ␉{␊ |
290 | ␉␉map->bios = BT_ATI_1;␊ |
291 | ␉␉PRINT("We have an AtomBios Card\n");␊ |
292 | ␉␉return openAtiVbios(map, atiTables);␊ |
293 | ␉}␊ |
294 | ␊ |
295 | ␊ |
296 | ␉/*␊ |
297 | ␉ * check if we have NVidia␊ |
298 | ␉ */␊ |
299 | ␉if (map->bios != BT_ATI_1)␊ |
300 | ␉{␊ |
301 | ␉␉int i = 0;␊ |
302 | ␉␉while (i < 512) // we don't need to look through the whole bios, just the first 512 bytes␊ |
303 | ␉␉{␊ |
304 | ␉␉␉if ((map->biosPtr[i] == 'N') ␊ |
305 | ␉␉␉␉&& (map->biosPtr[i+1] == 'V') ␊ |
306 | ␉␉␉␉&& (map->biosPtr[i+2] == 'I') ␊ |
307 | ␉␉␉␉&& (map->biosPtr[i+3] == 'D')) ␊ |
308 | ␉␉␉{␊ |
309 | ␉␉␉␉map->bios = BT_NVDA;␊ |
310 | ␉␉␉␉PRINT("We have an NVIDIA Card\n");␊ |
311 | ␉␉␉␉return openNvidiaVbios(map);␊ |
312 | ␉␉␉␉break;␊ |
313 | ␉␉␉}␊ |
314 | ␉␉␉i++;␊ |
315 | ␉␉}␊ |
316 | ␉}␊ |
317 | ␉␊ |
318 | ␉/*␊ |
319 | ␉ * check if we have Intel␊ |
320 | ␉ */␊ |
321 | ␉ ␊ |
322 | ␉if ((map->bios != BT_ATI_1) && (map->bios != BT_NVDA))␊ |
323 | ␉{␊ |
324 | ␉␉int i = 0;␊ |
325 | ␉␉while (i < VBIOS_SIZE)␊ |
326 | ␉␉{␊ |
327 | ␉␉␉if ((map->biosPtr[i] == 'I') ␊ |
328 | ␉␉␉␉&& (map->biosPtr[i+1] == 'n') ␊ |
329 | ␉␉␉␉&& (map->biosPtr[i+2] == 't') ␊ |
330 | ␉␉␉␉&& (map->biosPtr[i+3] == 'e') ␊ |
331 | ␉␉␉␉&& (map->biosPtr[i+4] == 'l')) ␊ |
332 | ␉␉␉{␊ |
333 | ␉␉␉␉map->bios = BT_1;␊ |
334 | ␉␉␉␉PRINT("We have an Intel Card\n");␊ |
335 | ␉␉␉␉saveVbios(map);␊ |
336 | ␉␉␉␉return openIntelVbios(map);␊ |
337 | ␉␉␉␉break;␊ |
338 | ␉␉␉}␊ |
339 | ␉␉␉i++;␊ |
340 | ␉␉}␊ |
341 | ␉}␊ |
342 | ␉␊ |
343 | ␉/*␊ |
344 | ␉ * Unidentified Chipset␊ |
345 | ␉ */␊ |
346 | ␉␊ |
347 | ␉if ( (map->chipset == CT_UNKNOWN) || ((map->bios != BT_ATI_1) && (map->bios != BT_NVDA) && (map->bios != BT_1)) )␊ |
348 | ␉{␊ |
349 | ␉␉PRINT("Unknown chipset type and unrecognized bios.\n");␊ |
350 | ␉␉␊ |
351 | ␉␉PRINT("autoresolution only works with Intel 800/900 series graphic chipsets.\n"); //Azi:reminder␊ |
352 | ␉␉␊ |
353 | ␉␉PRINT("Chipset Id: %x\n", map->chipsetId);␊ |
354 | ␉␉closeVbios(map);␊ |
355 | ␉␉return 0;␊ |
356 | ␉}␊ |
357 | ␊ |
358 | ␉/*␊ |
359 | ␉ * Should never get there ␊ |
360 | ␉ */␊ |
361 | ␉return 0;␊ |
362 | }␊ |
363 | ␊ |
364 | void closeVbios(vBiosMap * map)␊ |
365 | {␊ |
366 | ␉PRINT("Closing VBios\n");␊ |
367 | ␉//make sure to turn autoResolution off␊ |
368 | ␉if (gAutoResolution == true)␊ |
369 | ␉␉gAutoResolution = false;␊ |
370 | ␉␊ |
371 | ␉// if we saved the vBios, free the copy␊ |
372 | ␉if (map->biosBackupPtr != NULL)␊ |
373 | ␉{␊ |
374 | ␉␉PRINT("Freeing biosBackupPtr\t");␊ |
375 | ␉␉FREE(map->biosBackupPtr);␊ |
376 | ␉␉PRINT("[OK]\n");␊ |
377 | ␉}␊ |
378 | ␉␊ |
379 | ␉// free table backups if any␊ |
380 | ␉sModeTable * table = map->modeTables;␊ |
381 | ␉while (table != NULL)␊ |
382 | ␉{␉␉␊ |
383 | ␉␉if (table->backup != NULL)␊ |
384 | ␉␉{␊ |
385 | ␉␉␉PRINT("Table #%d: Freeing backup\t", table->id);␊ |
386 | ␉␉␉FREE(table->backup);␊ |
387 | ␉␉␉PRINT("[OK]\n");␊ |
388 | ␉␉}␊ |
389 | ␉␉␊ |
390 | ␉␉if (table != NULL)␊ |
391 | ␉␉{ ␊ |
392 | ␉␉␉PRINT("Table #%d: Freeing\t\t", table->id);␊ |
393 | ␉␉␉FREE(table);␊ |
394 | ␉␉␉PRINT("[OK]\n");␊ |
395 | ␉␉}␊ |
396 | ␉␉␊ |
397 | ␉␉if (table->next == NULL)␊ |
398 | ␉␉␉break;␊ |
399 | ␉␉␊ |
400 | ␉␉table = table->next;␊ |
401 | ␉}␊ |
402 | ␉␊ |
403 | ␉PRINT("Freeing map\t\t\t");␊ |
404 | ␉FREE(map);␊ |
405 | ␉PRINT("[OK]\n");␊ |
406 | }␊ |
407 | ␊ |
408 | void unlockVbios(vBiosMap * map)␊ |
409 | {␊ |
410 | ␊ |
411 | ␉map->unlocked = true;␊ |
412 | ␉ ␊ |
413 | ␉switch (map->chipset)␊ |
414 | ␉{␊ |
415 | ␉␉case CT_UNKNOWN:␊ |
416 | ␉␉␉break;␊ |
417 | ␉␉case CT_830:␊ |
418 | ␉␉case CT_855GM:␊ |
419 | ␉␉␉outl(0xcf8, 0x8000005a);␊ |
420 | ␉␉␉map->b1 = inb(0xcfe);␊ |
421 | ␉␉␉␉␊ |
422 | ␉␉␉outl(0xcf8, 0x8000005a);␊ |
423 | ␉␉␉outb(0xcfe, 0x33);␊ |
424 | ␉␉␉break;␊ |
425 | ␉␉case CT_845G:␊ |
426 | ␉␉case CT_865G:␊ |
427 | ␉␉case CT_915G:␊ |
428 | ␉␉case CT_915GM:␊ |
429 | ␉␉case CT_945G:␊ |
430 | ␉␉case CT_945GM:␊ |
431 | ␉␉case CT_945GME:␊ |
432 | ␉␉case CT_946GZ:␊ |
433 | ␉␉case CT_955X:␊ |
434 | ␉␉case CT_G965:␊ |
435 | ␉␉case CT_Q965:␊ |
436 | ␉␉case CT_965GM:␊ |
437 | ␉␉case CT_975X:␊ |
438 | ␉␉case CT_P35:␊ |
439 | ␉␉case CT_X48:␊ |
440 | ␉␉case CT_B43:␊ |
441 | ␉␉case CT_Q45:␊ |
442 | ␉␉case CT_P45:␊ |
443 | ␉␉case CT_GM45:␊ |
444 | ␉␉case CT_G41:␊ |
445 | ␉␉case CT_G31:␊ |
446 | ␉␉case CT_G45:␊ |
447 | ␉␉case CT_500:␊ |
448 | ␊ |
449 | ␉␉␉outl(0xcf8, 0x80000090);␊ |
450 | ␉␉␉map->b1 = inb(0xcfd);␊ |
451 | ␉␉␉map->b2 = inb(0xcfe);␊ |
452 | ␉␉␉outl(0xcf8, 0x80000090);␊ |
453 | ␉␉␉outb(0xcfd, 0x33);␊ |
454 | ␉␉␉outb(0xcfe, 0x33);␊ |
455 | ␉␉break;␊ |
456 | ␉}␊ |
457 | ␉␊ |
458 | ␉#if DEBUG␊ |
459 | ␉{␊ |
460 | ␉␉uint32_t t = inl(0xcfc);␊ |
461 | ␉␉PRINT("unlock PAM: (0x%08x)\n", t);␊ |
462 | ␉}␊ |
463 | #endif␊ |
464 | }␊ |
465 | ␊ |
466 | void relockVbios(vBiosMap * map)␊ |
467 | {␊ |
468 | ␊ |
469 | ␉map->unlocked = false;␊ |
470 | ␉␊ |
471 | ␉switch (map->chipset)␊ |
472 | ␉{␊ |
473 | ␉␉case CT_UNKNOWN:␊ |
474 | ␉␉␉break;␊ |
475 | ␉␉case CT_830:␊ |
476 | ␉␉case CT_855GM:␊ |
477 | ␉␉␉outl(0xcf8, 0x8000005a);␊ |
478 | ␉␉␉outb(0xcfe, map->b1);␊ |
479 | ␉␉␉break;␊ |
480 | ␉␉case CT_845G:␊ |
481 | ␉␉case CT_865G:␊ |
482 | ␉␉case CT_915G:␊ |
483 | ␉␉case CT_915GM:␊ |
484 | ␉␉case CT_945G:␊ |
485 | ␉␉case CT_945GM:␊ |
486 | ␉␉case CT_945GME:␊ |
487 | ␉␉case CT_946GZ:␊ |
488 | ␉␉case CT_955X:␊ |
489 | ␉␉case CT_G965:␊ |
490 | ␉␉case CT_Q965:␊ |
491 | ␉␉case CT_965GM:␊ |
492 | ␉␉case CT_975X:␊ |
493 | ␉␉case CT_P35:␊ |
494 | ␉␉case CT_X48:␊ |
495 | ␉␉case CT_B43:␊ |
496 | ␉␉case CT_Q45:␊ |
497 | ␉␉case CT_P45:␊ |
498 | ␉␉case CT_GM45:␊ |
499 | ␉␉case CT_G41:␊ |
500 | ␉␉case CT_G31:␊ |
501 | ␉␉case CT_G45:␊ |
502 | ␉␉case CT_500:␊ |
503 | ␉␉␉␊ |
504 | ␉␉␉outl(0xcf8, 0x80000090);␊ |
505 | ␉␉␉outb(0xcfd, map->b1);␊ |
506 | ␉␉␉outb(0xcfe, map->b2);␊ |
507 | ␉␉␉break;␊ |
508 | ␉}␊ |
509 | ␉␊ |
510 | ␉#if DEBUG␊ |
511 | ␉{␊ |
512 | uint32_t t = inl(0xcfc);␊ |
513 | ␉␉PRINT("relock PAM: (0x%08x)\n", t);␊ |
514 | ␉}␊ |
515 | ␉#endif␊ |
516 | }␊ |
517 | ␊ |
518 | /*␊ |
519 | * saveVbios - save the entire vBios in case the patch has to be removed␊ |
520 | * Azi: only on Intel??␊ |
521 | */␊ |
522 | void saveVbios(vBiosMap * map)␊ |
523 | {␊ |
524 | ␉map->biosBackupPtr = malloc(VBIOS_SIZE);␊ |
525 | ␉bcopy((const uint8_t *)0xC0000, map->biosBackupPtr, VBIOS_SIZE);␊ |
526 | }␊ |
527 | ␊ |
528 | /*␊ |
529 | * restoreVbios - restore the vBios backup or table backups if any␊ |
530 | */␊ |
531 | void restoreVbios(vBiosMap * map)␊ |
532 | {␊ |
533 | ␉if ((map->bios == BT_ATI_1) || (map->bios == BT_ATI_2) || (map->bios == BT_NVDA))␊ |
534 | ␉{␊ |
535 | ␉␉restoreTables(map, map->modeTables);␊ |
536 | ␉}␊ |
537 | ␉else␊ |
538 | ␉{␊ |
539 | ␉␉unlockVbios(map);␊ |
540 | ␉␉bcopy(map->biosBackupPtr,(uint8_t *)0xC0000, VBIOS_SIZE);␊ |
541 | ␉␉relockVbios(map);␊ |
542 | ␉}␊ |
543 | }␊ |
544 | ␊ |
545 | /*␊ |
546 | * saveTables - save the tables in case the patch has to be removed␊ |
547 | */␊ |
548 | void saveTables(sModeTable * table)␊ |
549 | {␊ |
550 | ␉while (table != NULL)␊ |
551 | ␉{␊ |
552 | ␉␉table->backup = (uint8_t *)malloc(table->size);␊ |
553 | ␉␉bcopy((const uint8_t *)table->pointer, table->backup, table->size);␊ |
554 | ␉␉table = table->next;␊ |
555 | ␉}␊ |
556 | }␊ |
557 | ␊ |
558 | /*␊ |
559 | * restoreTables - restore tables backup ␊ |
560 | */␊ |
561 | void restoreTables(vBiosMap * map, sModeTable * table)␊ |
562 | {␊ |
563 | ␉unlockVbios(map);␊ |
564 | ␉while (table != NULL)␊ |
565 | ␉{␊ |
566 | ␉␉bcopy(table->backup, (uint8_t *)table->pointer, table->size);␊ |
567 | ␉␉table = table->next;␊ |
568 | ␉␉verbose("Restoring table/s for patch cancelation\n");␊ |
569 | ␉}␊ |
570 | ␉relockVbios(map);␊ |
571 | }␊ |
572 | ␊ |
573 | /*␊ |
574 | * patchVbios - call the vendor specific function to patch the VESA tables␊ |
575 | * x & y are horizontal and vertical dimensions respectively, in pixels␊ |
576 | * for GMA and ATI, only first mode in Table is patched␊ |
577 | *␊ |
578 | * each vendor specific function have the same form :␊ |
579 | * bool vendorSetMode_type(sModeTable * table, uint8_t index, uint32_t * x, uint32_t * y);␊ |
580 | * where 'table' is the VESA table to patch, 'index' is the index of the mode in table,␊ |
581 | * 'x' & 'y' are pointer to the target resolution and return the next resolution in table.␊ |
582 | */␊ |
583 | void patchVbios(vBiosMap * map, uint32_t x, uint32_t y, uint32_t bp, uint32_t hTotal, uint32_t vTotal)␊ |
584 | {␊ |
585 | ␉uint32_t i = 0;␊ |
586 | ␉␊ |
587 | ␉sModeTable * table = map->modeTables;␊ |
588 | ␉␊ |
589 | ␉// save the target resolution for future use␊ |
590 | ␉map->currentX = x;␊ |
591 | ␉map->currentY = y;␊ |
592 | ␉␊ |
593 | ␉unlockVbios(map);␊ |
594 | ␉␊ |
595 | ␉// Get the aspect ratio for the requested mode␊ |
596 | ␉getAspectRatio(&map->aspectRatio, x, y);␊ |
597 | ␉␊ |
598 | ␉i = 0;␊ |
599 | ␉␊ |
600 | ␉// Call the vendor specific function for each available VESA Table␊ |
601 | ␉table = map->modeTables;␊ |
602 | ␉while (table != NULL)␊ |
603 | ␉{␊ |
604 | ␉␉//reset resolution value before treating a new table␊ |
605 | ␉␉x = map->currentX;␊ |
606 | ␉␉y = map->currentY;␊ |
607 | ␉␉␊ |
608 | ␉␉PRINT("Patching Table #%d: \n", table->id);␊ |
609 | ␉␉␊ |
610 | ␉␉map->setMode(table, i, &x, &y);␊ |
611 | #ifdef AUTORES_DEBUG␊ |
612 | ␉␉pause();␊ |
613 | #endif␊ |
614 | ␊ |
615 | ␉␉table = table->next;␊ |
616 | ␉}␊ |
617 | ␉␊ |
618 | ␉relockVbios(map);␊ |
619 | ␉return;␊ |
620 | }␊ |
621 | ␊ |
622 | void initAutoRes()␊ |
623 | {␊ |
624 | //␉UInt32 paramsAR[4];␊ |
625 | ␉paramsAR[3] = 0;␊ |
626 | ␊ |
627 | ␉// Open the Vbios and store Vbios or Tables␊ |
628 | ␉map = openVbios(CT_UNKNOWN);␊ |
629 | ␊ |
630 | ␉//Get resolution from Graphics Mode key...␊ |
631 | ␉int count = getNumberArrayFromProperty(kGraphicsModeKey, paramsAR, 4);␊ |
632 | ␉␊ |
633 | ␉// ... or EDID.␊ |
634 | ␉if (count < 3)␊ |
635 | ␉{␊ |
636 | ␉␉getResolution(paramsAR);␊ |
637 | ␉␉// check the DEBUG stuff... also on TEXT MODE (this is not printing).␊ |
638 | ␉␉PRINT("Resolution: %dx%d (EDID)\n",paramsAR[0], paramsAR[1]);␊ |
639 | ␉}␊ |
640 | ␉else␊ |
641 | ␉{␊ |
642 | ␉␉PRINT("Resolution: %dx%d (Graphics Mode key)\n",paramsAR[0], paramsAR[1]);␊ |
643 | ␊ |
644 | ␉␉if ( paramsAR[2] == 256 ) paramsAR[2] = 8;␊ |
645 | ␉␉if ( paramsAR[2] == 555 ) paramsAR[2] = 16;␊ |
646 | ␉␉if ( paramsAR[2] == 888 ) paramsAR[2] = 32;␊ |
647 | ␉}␊ |
648 | ␉␊ |
649 | ␉// perfom the actual Vbios patching␊ |
650 | ␉if (paramsAR[0] != 0 && paramsAR[1] != 0)␊ |
651 | ␉{␊ |
652 | ␉␉patchVbios(map, paramsAR[0], paramsAR[1], paramsAR[2], 0, 0);␊ |
653 | ␉}␊ |
654 | ␉␊ |
655 | ␉//Azi: passing resolution for TEXT MODE "verbose" boot. (check again later!)␊ |
656 | ␉if (bootArgs->Video.v_display == VGA_TEXT_MODE)␊ |
657 | ␉{␊ |
658 | ␉␉gui.screen.width = paramsAR[0];␊ |
659 | ␉␉gui.screen.height = paramsAR[1];␊ |
660 | ␉}␊ |
661 | ␉␊ |
662 | ␉// If the patch is working properly, we're done. If not and it's just a matter␊ |
663 | ␉// of wrong resolution, we can try reapply the patch; see "case kF2Key:", options.c.␊ |
664 | }␊ |
665 | ␊ |
666 | void reloadAutoRes()␊ |
667 | {␊ |
668 | ␉extern int␉ key;␊ |
669 | ␉extern int␉ nextRow;␊ |
670 | ␉extern BVRef menuBVR;␊ |
671 | ␉extern bool␉ showPrompt;␊ |
672 | ␉␊ |
673 | ␉extern bool␉ showBootBanner;␊ |
674 | ␉extern␉␉ MenuItem * menuItems;␊ |
675 | ␉extern int␉ selectIndex;␊ |
676 | ␉␊ |
677 | ␉extern void showMenu( const MenuItem * items, int count, int selection, int row, int height );␊ |
678 | ␉extern void showBootPrompt(int row, bool visible);␊ |
679 | //␉extern void clearBootArgs(void); Azi: declared on options.h␊ |
680 | ␉extern void changeCursor( int col, int row, int type, CursorState * cs );␊ |
681 | ␉␊ |
682 | ␉if (!map)␊ |
683 | ␉{␊ |
684 | ␉␉// Open the Vbios and store Vbios or Tables␊ |
685 | ␉␉map = openVbios(CT_UNKNOWN);␊ |
686 | ␉␉gAutoResolution = true;␊ |
687 | ␉}␊ |
688 | ␉␊ |
689 | ␉if ((gAutoResolution == true) && useGUI && map ) //Azi: should this work on TEXTMODE ???␊ |
690 | ␉{␊ |
691 | ␉␉// get the new Graphics Mode key␊ |
692 | ␉␉processBootOptions(); //Azi: use processBootArgument instead?␊ |
693 | //␉␉processBootArgument(kGraphicsModeKey, cp, configKernelFlags,␊ |
694 | //␉␉␉␉␉␉␉bootInfo->config, &argP, &cntRemaining, gRootDevice)␊ |
695 | ␊ |
696 | //␉␉UInt32 paramsAR[4];␊ |
697 | ␉␉paramsAR[3] = 0;␊ |
698 | ␉␉␊ |
699 | ␉␉getNumberArrayFromProperty(kGraphicsModeKey, paramsAR, 4);␊ |
700 | ␉␉␊ |
701 | ␉␉// user changed resolution...␊ |
702 | ␉␉if ((paramsAR[0] != 0) && (paramsAR[1] != 0) &&␊ |
703 | ␉␉␉(paramsAR[0] != map->currentX) && (paramsAR[1] != map->currentY))␊ |
704 | ␉␉{␊ |
705 | ␉␉␉//Azi: identical to "case kTabKey:"␉␉␉(check later)␊ |
706 | ␉␉␉if (bootArgs->Video.v_display == GRAPHICS_MODE)␊ |
707 | ␉␉␉{␊ |
708 | ␉␉␉␉CursorState cursorState;␊ |
709 | ␉␉␉␉␊ |
710 | ␉␉␉␉// Go back to TEXT MODE while we change the mode␊ |
711 | ␉␉␉␉setVideoMode(VGA_TEXT_MODE, 0);␊ |
712 | ␊ |
713 | ␉␉␉␉setCursorPosition(0, 0, 0);␊ |
714 | ␉␉␉␉clearScreenRows(0, kScreenLastRow);␊ |
715 | ␉␉␉␉changeCursor( 0, 0, kCursorTypeHidden, &cursorState );␊ |
716 | ␉␉␉␉␊ |
717 | ␉␉␉␉// Reapply patch␊ |
718 | ␉␉␉␉patchVbios(map, paramsAR[0], paramsAR[1], paramsAR[2], 0, 0);␊ |
719 | ␊ |
720 | ␉␉␉␉if (useGUI && (gui.initialised == true))␊ |
721 | ␉␉␉␉␉initGUI();␊ |
722 | ␉␉␉␉// Make sure all values are set␊ |
723 | ␉␉␉␉if (bootArgs->Video.v_display != GRAPHICS_MODE)␊ |
724 | ␉␉␉␉␉bootArgs->Video.v_display = GRAPHICS_MODE;␊ |
725 | ␊ |
726 | ␉␉␉␉if (!useGUI)␊ |
727 | ␉␉␉␉␉useGUI = true;␊ |
728 | ␊ |
729 | ␉␉␉␉// redraw the background buffer␊ |
730 | ␉␉␉␉drawBackground();␊ |
731 | ␉␉␉␉gui.devicelist.draw = true;␊ |
732 | ␉␉␉␉gui.redraw = true;␊ |
733 | ␉␉␉␉␊ |
734 | ␉␉␉␉if (showBootBanner)␊ |
735 | ␉␉␉␉{␊ |
736 | ␉␉␉␉␉// Display banner and show hardware info.␊ |
737 | ␉␉␉␉␉gprintf(&gui.screen, bootBanner + 1, (bootInfo->convmem + bootInfo->extmem) / 1024);␊ |
738 | ␉␉␉␉}␊ |
739 | ␊ |
740 | ␉␉␉␉// redraw background␊ |
741 | ␉␉␉␉memcpy(gui.backbuffer->pixels, gui.screen.pixmap->pixels,␊ |
742 | ␉␉␉␉␉ gui.backbuffer->width * gui.backbuffer->height * 4);␊ |
743 | ␊ |
744 | ␉␉␉␉nextRow = kMenuTopRow;␊ |
745 | ␉␉␉␉showPrompt = true;␊ |
746 | ␊ |
747 | ␉␉␉␉if (gDeviceCount)␊ |
748 | ␉␉␉␉{␊ |
749 | ␉␉␉␉␉showMenu( menuItems, gDeviceCount, selectIndex, kMenuTopRow + 2, kMenuMaxItems );␊ |
750 | ␉␉␉␉␉nextRow += MIN( gDeviceCount, kMenuMaxItems ) + 3;␊ |
751 | ␉␉␉␉}␊ |
752 | ␊ |
753 | ␉␉␉␉// Show the boot prompt.␊ |
754 | ␉␉␉␉showPrompt = (gDeviceCount == 0) || (menuBVR->flags & kBVFlagNativeBoot);␊ |
755 | ␉␉␉␉showBootPrompt( nextRow, showPrompt );␊ |
756 | ␊ |
757 | ␉␉␉␉// this is used to avoid resetting the incorrect mode while quiting the boot menu␊ |
758 | //␉␉␉␉␉␉map->hasSwitched = true; (check again later!)␊ |
759 | ␉␉␉}␊ |
760 | ␉␉}␊ |
761 | ␉␉␊ |
762 | ␉␉clearBootArgs();␊ |
763 | ␉␉key = 0;␊ |
764 | ␉}␉␊ |
765 | ␉else // if gAutoResolution == false...␊ |
766 | ␉{␊ |
767 | ␉␉// ... do "nothing".␉␉␉(Reviewing...)␊ |
768 | ␉␉clearBootArgs();␊ |
769 | ␉␉key = 0;␊ |
770 | ␉}␊ |
771 | }␊ |
772 | ␊ |
773 | void finishAutoRes()␊ |
774 | {␊ |
775 | ␉// User disabled AutoResolution at boot prompt...␊ |
776 | ␉if ((gAutoResolution == false) && map)␊ |
777 | ␉{␊ |
778 | ␉␉// restore and close Vbios for patch cancelation.␊ |
779 | ␉␉restoreVbios(map);␊ |
780 | ␉␉closeVbios(map);␊ |
781 | ␉}␊ |
782 | ␉else if (map) // assume (gAutoResolution == true)␊ |
783 | ␉{␊ |
784 | ␉␉//Azi: while testing, i didn't got any problems when booting without␊ |
785 | ␉␉// closing Vbios... closing it just in case. (check again later!)␊ |
786 | ␉␉closeVbios(map);␊ |
787 | ␊ |
788 | ␉␉// gAutoResolution was just set to false on closeVbios();␊ |
789 | ␉␉// we need it to be "true" for drawBootGraphics().␊ |
790 | ␉␉gAutoResolution = true;␊ |
791 | ␉}␊ |
792 | }␊ |
793 | ␊ |
794 | ␊ |
795 | |