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