Root/
Source at commit 131 created 14 years 29 days ago. By diebuche, typos... | |
---|---|
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 "915resolution.h"␊ |
19 | #include "../boot2/graphics.h"␊ |
20 | ␊ |
21 | char * chipset_type_names[] = {␊ |
22 | ␉"UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", "945GM", "945GME",␊ |
23 | ␉"946GZ", "955X", "G965", "Q965", "965GM", "975X",␊ |
24 | ␉"P35", "X48", "B43", "Q45", "P45", "GM45", "G41", "G31", "G45", "500"␊ |
25 | };␊ |
26 | ␊ |
27 | char * bios_type_names[] = {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"};␊ |
28 | ␊ |
29 | int freqs[] = { 60, 75, 85 };␊ |
30 | ␉␊ |
31 | ␊ |
32 | UInt32 get_chipset_id(void) {␊ |
33 | ␉outl(0xcf8, 0x80000000);␊ |
34 | ␉return inl(0xcfc);␊ |
35 | }␊ |
36 | ␊ |
37 | chipset_type get_chipset(UInt32 id) {␊ |
38 | ␉chipset_type type;␊ |
39 | ␉␊ |
40 | ␉switch (id) {␊ |
41 | ␉␉case 0x35758086:␊ |
42 | ␉␉␉type = CT_830;␊ |
43 | ␉␉␉break;␊ |
44 | ␉␉␊ |
45 | ␉␉case 0x25608086:␊ |
46 | ␉␉␉type = CT_845G;␊ |
47 | ␉␉␉break;␊ |
48 | ␉␉␉␉␊ |
49 | ␉␉case 0x35808086:␊ |
50 | ␉␉␉type = CT_855GM;␊ |
51 | ␉␉␉break;␊ |
52 | ␉␉␉␉␊ |
53 | ␉␉case 0x25708086:␊ |
54 | ␉␉␉type = CT_865G;␊ |
55 | ␉␉␉break;␊ |
56 | ␉␉␊ |
57 | ␉␉case 0x25808086:␊ |
58 | ␉␉␉type = CT_915G;␊ |
59 | ␉␉␉break;␊ |
60 | ␉␉␉␊ |
61 | ␉␉case 0x25908086:␊ |
62 | ␉␉␉type = CT_915GM;␊ |
63 | ␉␉␉break;␊ |
64 | ␉␉␉␊ |
65 | ␉␉case 0x27708086:␊ |
66 | ␉␉␉type = CT_945G;␊ |
67 | ␉␉␉break;␊ |
68 | ␉␉␉␊ |
69 | ␉␉case 0x27748086:␊ |
70 | ␉␉␉type = CT_955X;␊ |
71 | ␉␉␉break;␊ |
72 | ␉␉␉␊ |
73 | ␉␉case 0x277c8086:␊ |
74 | ␉␉␉type = CT_975X;␊ |
75 | ␉␉␉break;␊ |
76 | ␉␉␊ |
77 | ␉␉case 0x27a08086:␊ |
78 | ␉␉␉type = CT_945GM;␊ |
79 | ␉␉␉break;␊ |
80 | ␉␉␉␊ |
81 | ␉␉case 0x27ac8086:␊ |
82 | ␉␉␉type = CT_945GME;␊ |
83 | ␉␉␉break;␊ |
84 | ␉␉␉␊ |
85 | ␉␉case 0x29708086:␊ |
86 | ␉␉␉type = CT_946GZ;␊ |
87 | ␉␉␉break;␊ |
88 | ␉␉␉␊ |
89 | ␉␉case 0x29a08086:␊ |
90 | ␉␉␉type = CT_G965;␊ |
91 | ␉␉␉break;␊ |
92 | ␉␉␉␊ |
93 | ␉␉case 0x29908086:␊ |
94 | ␉␉␉type = CT_Q965;␊ |
95 | ␉␉␉break;␊ |
96 | ␉␉␉␊ |
97 | ␉␉case 0x2a008086:␊ |
98 | ␉␉␉type = CT_965GM;␊ |
99 | ␉␉␉break;␊ |
100 | ␉␉␉␊ |
101 | ␉␉case 0x29e08086:␊ |
102 | ␉␉␉type = CT_X48;␊ |
103 | ␉␉␉break;␉␉␉␊ |
104 | ␉␉␉␊ |
105 | ␉␉case 0x2a408086:␊ |
106 | ␉␉␉type = CT_GM45;␊ |
107 | ␉␉␉break;␊ |
108 | ␉␉␉␊ |
109 | ␉␉case 0x2e108086:␊ |
110 | ␉␉case 0X2e908086:␊ |
111 | ␉␉␉type = CT_B43;␊ |
112 | ␉␉␉break;␊ |
113 | ␉␉␉␊ |
114 | ␉␉case 0x2e208086:␊ |
115 | ␉␉␉type = CT_P45;␊ |
116 | ␉␉␉break;␊ |
117 | ␉␉␉␊ |
118 | ␉␉case 0x2e308086:␊ |
119 | ␉␉␉type = CT_G41;␊ |
120 | ␉␉␉break;␊ |
121 | ␉␉␉␊ |
122 | ␉␉case 0x29c08086:␊ |
123 | ␉␉␉type = CT_G31;␊ |
124 | ␉␉␉break;␊ |
125 | ␉␉␉␊ |
126 | ␉␉case 0x29208086:␊ |
127 | ␉␉␉type = CT_G45;␊ |
128 | ␉␉␉break;␊ |
129 | ␉␉␉␊ |
130 | ␉␉case 0x81008086:␊ |
131 | ␉␉␉type = CT_500;␊ |
132 | ␉␉␉break;␊ |
133 | ␉␉␉␊ |
134 | ␉␉default:␊ |
135 | ␉␉␉type = CT_UNKWN;␊ |
136 | ␉␉␉break;␊ |
137 | ␉}␊ |
138 | ␉return type;␊ |
139 | }␊ |
140 | ␊ |
141 | vbios_resolution_type1 * map_type1_resolution(vbios_map * map, UInt16 res) {␊ |
142 | ␉vbios_resolution_type1 * ptr = ((vbios_resolution_type1*)(map->bios_ptr + res)); ␊ |
143 | ␉return ptr;␊ |
144 | }␊ |
145 | ␊ |
146 | vbios_resolution_type2 * map_type2_resolution(vbios_map * map, UInt16 res) {␊ |
147 | ␉vbios_resolution_type2 * ptr = ((vbios_resolution_type2*)(map->bios_ptr + res)); ␊ |
148 | ␉return ptr;␊ |
149 | }␊ |
150 | ␊ |
151 | vbios_resolution_type3 * map_type3_resolution(vbios_map * map, UInt16 res) {␊ |
152 | ␉vbios_resolution_type3 * ptr = ((vbios_resolution_type3*)(map->bios_ptr + res)); ␊ |
153 | ␉return ptr;␊ |
154 | }␊ |
155 | ␊ |
156 | char detect_bios_type(vbios_map * map, char modeline, int entry_size) {␊ |
157 | ␉UInt32 i;␊ |
158 | ␉UInt16 r1, r2;␊ |
159 | ␉ ␊ |
160 | ␉r1 = r2 = 32000;␊ |
161 | ␉␊ |
162 | ␉for (i=0; i < map->mode_table_size; i++) {␊ |
163 | ␉␉if (map->mode_table[i].resolution <= r1) {␊ |
164 | ␉␉␉r1 = map->mode_table[i].resolution;␊ |
165 | ␉␉}␊ |
166 | ␉␉else {␊ |
167 | ␉␉␉if (map->mode_table[i].resolution <= r2) {␊ |
168 | ␉␉␉␉r2 = map->mode_table[i].resolution;␊ |
169 | ␉␉␉}␊ |
170 | ␉␉}␊ |
171 | ␉␉␊ |
172 | ␉␉/* printf("r1 = %d r2 = %d\n", r1, r2); */␊ |
173 | ␉}␊ |
174 | ␊ |
175 | ␉return (r2-r1-6) % entry_size == 0;␊ |
176 | }␊ |
177 | ␊ |
178 | char detect_ati_bios_type(vbios_map * map) {␉␊ |
179 | ␉return map->mode_table_size % sizeof(ATOM_MODE_TIMING) == 0;␊ |
180 | }␊ |
181 | ␊ |
182 | void close_vbios(vbios_map * map);␊ |
183 | ␊ |
184 | vbios_map * open_vbios(chipset_type forced_chipset) {␊ |
185 | ␉UInt32 z;␊ |
186 | ␉vbios_map * map = NEW(vbios_map);␊ |
187 | ␉for(z=0; z<sizeof(vbios_map); z++) ((char*)map)[z]=0;␊ |
188 | ␉/*␊ |
189 | ␉ * Determine chipset␊ |
190 | ␉*/␊ |
191 | ␉␊ |
192 | ␉if (forced_chipset == CT_UNKWN) {␊ |
193 | ␉␉map->chipset_id = get_chipset_id();␊ |
194 | ␉␉map->chipset = get_chipset(map->chipset_id);␊ |
195 | ␉}␊ |
196 | ␉else if (forced_chipset != CT_UNKWN) {␊ |
197 | ␉␉map->chipset = forced_chipset;␊ |
198 | ␉}␊ |
199 | ␉else {␊ |
200 | ␉␉map->chipset = CT_915GM;␊ |
201 | ␉}␊ |
202 | ␉ ␊ |
203 | ␉/*␊ |
204 | ␉ * Map the video bios to memory␊ |
205 | ␉ */␊ |
206 | ␉␊ |
207 | ␉map->bios_ptr = (unsigned char *)VBIOS_START;␊ |
208 | ␉␊ |
209 | ␉/*␊ |
210 | ␉ * check if we have ATI Radeon␊ |
211 | ␉ */␊ |
212 | ␉␊ |
213 | ␉map->ati_tables.base = map->bios_ptr;␊ |
214 | ␉map->ati_tables.AtomRomHeader = (ATOM_ROM_HEADER *) (map->bios_ptr + *(unsigned short *) (map->bios_ptr + OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER)); ␊ |
215 | ␉if (strcmp ((char *) map->ati_tables.AtomRomHeader->uaFirmWareSignature, "ATOM") != 0) {␊ |
216 | ␉␉␉printf("Not an AtomBios Card\n");␊ |
217 | ␉} else {␊ |
218 | ␉␉map->bios = BT_ATI_1;␊ |
219 | ␉}␊ |
220 | ␊ |
221 | ␊ |
222 | ␉/*␊ |
223 | ␉ * check if we have NVidia␊ |
224 | ␉ */␊ |
225 | ␉if (map->bios != BT_ATI_1) {␊ |
226 | ␉␉int i = 0;␊ |
227 | ␉␉while (i < 512) { // we don't need to look through the whole bios, just the first 512 bytes␊ |
228 | ␉␉␉if ((map->bios_ptr[i] == 'N') ␊ |
229 | ␉␉␉␉&& (map->bios_ptr[i+1] == 'V') ␊ |
230 | ␉␉␉␉&& (map->bios_ptr[i+2] == 'I') ␊ |
231 | ␉␉␉␉&& (map->bios_ptr[i+3] == 'D')) ␊ |
232 | ␉␉␉{␊ |
233 | ␉␉␉␉map->bios = BT_NVDA;␊ |
234 | ␉␉␉␉break;␊ |
235 | ␉␉␉}␊ |
236 | ␉␉␉i++;␊ |
237 | ␉␉}␊ |
238 | ␉}␊ |
239 | ␉␊ |
240 | ␉/*␊ |
241 | ␉ * check if we have Intel␊ |
242 | ␉ */␊ |
243 | ␉ ␊ |
244 | ␉/*if (map->chipset == CT_UNKWN && memmem(map->bios_ptr, VBIOS_SIZE, INTEL_SIGNATURE, strlen(INTEL_SIGNATURE))) {␊ |
245 | ␉␉printf( "Intel chipset detected. However, 915resolution was unable to determine the chipset type.\n");␊ |
246 | ␉␊ |
247 | ␉␉printf("Chipset Id: %x\n", map->chipset_id);␊ |
248 | ␉␉␊ |
249 | ␉␉printf("Please report this problem to stomljen@yahoo.com\n");␊ |
250 | ␉␉␊ |
251 | ␉␉␉close_vbios(map);␊ |
252 | ␉␉␉return 0;␊ |
253 | ␉␉}*/␊ |
254 | ␉␊ |
255 | ␉␉/*␊ |
256 | ␉␉ * check for others␊ |
257 | ␉␉ */␊ |
258 | ␉␊ |
259 | ␉if (map->chipset == CT_UNKWN) {␊ |
260 | ␉␉printf("Unknown chipset type and unrecognized bios.\n");␊ |
261 | ␉␉ ␊ |
262 | ␉␉printf("915resolution only works with Intel 800/900 series graphic chipsets.\n");␊ |
263 | ␉␊ |
264 | ␉␉printf("Chipset Id: %x\n", map->chipset_id);␊ |
265 | ␉␉close_vbios(map);␊ |
266 | ␉␉return 0;␊ |
267 | ␉}␊ |
268 | ␊ |
269 | ␉/*␊ |
270 | ␉ * Figure out where the mode table is ␊ |
271 | ␉ */␊ |
272 | ␉␊ |
273 | ␉if ((map->bios != BT_ATI_1) && (map->bios != BT_NVDA)) ␊ |
274 | ␉{␊ |
275 | ␉␉unsigned char* p = map->bios_ptr + 16;␊ |
276 | ␉␉unsigned char* limit = map->bios_ptr + VBIOS_SIZE - (3 * sizeof(vbios_mode));␊ |
277 | ␉␉␉␊ |
278 | ␉␉while (p < limit && map->mode_table == 0) {␊ |
279 | ␉␉␉vbios_mode * mode_ptr = (vbios_mode *) p;␊ |
280 | ␉␉␉ ␊ |
281 | ␉␉␉if (((mode_ptr[0].mode & 0xf0) == 0x30) && ((mode_ptr[1].mode & 0xf0) == 0x30) &&␊ |
282 | ␉␉␉␉((mode_ptr[2].mode & 0xf0) == 0x30) && ((mode_ptr[3].mode & 0xf0) == 0x30)) {␊ |
283 | ␉␉␉␊ |
284 | ␉␉␉␉map->mode_table = mode_ptr;␊ |
285 | ␉␉␉}␊ |
286 | ␉␉␉ ␊ |
287 | ␉␉␉p++;␊ |
288 | ␉␉}␊ |
289 | ␉␉␊ |
290 | ␉␉if (map->mode_table == 0) {␊ |
291 | ␉␉␉printf("Unable to locate the mode table.\n");␊ |
292 | ␉␉␉printf("Please run the program 'dump_bios' as root and\n");␊ |
293 | ␉␉␉printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");␊ |
294 | ␉␉␉printf("Chipset: %s\n", chipset_type_names[map->chipset]);␊ |
295 | ␉␉␉close_vbios(map);␊ |
296 | ␉␉␉return 0;␊ |
297 | ␉␉}␊ |
298 | ␉} ␊ |
299 | ␉else if (map->bios == BT_ATI_1)␊ |
300 | ␉{␊ |
301 | ␉␉map->ati_tables.MasterDataTables = (unsigned short *) &((ATOM_MASTER_DATA_TABLE *) (map->bios_ptr + map->ati_tables.AtomRomHeader->usMasterDataTableOffset))->ListOfDataTables;␊ |
302 | ␉␉unsigned short std_vesa_offset = (unsigned short) ((ATOM_MASTER_LIST_OF_DATA_TABLES *)map->ati_tables.MasterDataTables)->StandardVESA_Timing;␊ |
303 | ␉␉ATOM_STANDARD_VESA_TIMING * std_vesa = (ATOM_STANDARD_VESA_TIMING *) (map->bios_ptr + std_vesa_offset);␊ |
304 | ␉␉␉␊ |
305 | ␉␉map->ati_mode_table = (char *) &std_vesa->aModeTimings;␊ |
306 | ␉␉if (map->ati_mode_table == 0) {␊ |
307 | ␉␉␉printf("Unable to locate the mode table.\n");␊ |
308 | ␉␉␉printf("Please run the program 'dump_bios' as root and\n");␊ |
309 | ␉␉␉printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");␊ |
310 | ␉␉␉printf("Chipset: %s\n", chipset_type_names[map->chipset]);␊ |
311 | ␉␉␉close_vbios(map);␊ |
312 | ␉␉␉return 0;␊ |
313 | ␉␉}␊ |
314 | ␉␉map->mode_table_size = std_vesa->sHeader.usStructureSize - sizeof(ATOM_COMMON_TABLE_HEADER);␊ |
315 | ␉␉␊ |
316 | ␉␉if (!detect_ati_bios_type(map)) map->bios = BT_ATI_2;␊ |
317 | ␉}␊ |
318 | ␉else if (map->bios == BT_NVDA)␊ |
319 | ␉{␊ |
320 | ␉␉unsigned short nv_data_table_offset = 0;␊ |
321 | ␉␉unsigned short nv_modeline_2_offset = 0;␊ |
322 | ␉␉unsigned short * nv_data_table;␊ |
323 | ␉␉NV_VESA_TABLE * std_vesa;␊ |
324 | ␉␉␊ |
325 | ␉␉int i = 0;␊ |
326 | ␉␉␊ |
327 | ␉␉while (i < 0x300) { //We don't need to look for the table in the whole bios, the 768 first bytes only␊ |
328 | ␉␉␉if ((map->bios_ptr[i] == 0x44) ␊ |
329 | ␉␉␉␉&& (map->bios_ptr[i+1] == 0x01) ␊ |
330 | ␉␉␉␉&& (map->bios_ptr[i+2] == 0x04) ␊ |
331 | ␉␉␉␉&& (map->bios_ptr[i+3] == 0x00)) {␊ |
332 | ␉␉␉␉nv_data_table_offset = (unsigned short) (map->bios_ptr[i+4] | (map->bios_ptr[i+5] << 8));␊ |
333 | ␉␉␉␉break;␊ |
334 | ␉␉␉}␊ |
335 | ␉␉␉i++;␊ |
336 | ␉␉}␊ |
337 | ␉␉␊ |
338 | ␉␉while (i < VBIOS_SIZE) { //We don't know how to locate it other way␊ |
339 | ␉␉␉if ((map->bios_ptr[i] == 0x00) && (map->bios_ptr[i+1] == 0x04) //this is the first 1024 modeline.␊ |
340 | ␉␉␉␉&& (map->bios_ptr[i+2] == 0x00) && (map->bios_ptr[i+3] == 0x03)␊ |
341 | ␉␉␉␉&& (map->bios_ptr[i+4] == 0x80)␊ |
342 | ␉␉␉␉&& (map->bios_ptr[i+5] == 0x2F)␊ |
343 | ␉␉␉␉&& (map->bios_ptr[i+6] == 0x10)␊ |
344 | ␉␉␉␉&& (map->bios_ptr[i+7] == 0x10)␊ |
345 | ␉␉␉␉&& (map->bios_ptr[i+8] == 0x05)) {␊ |
346 | ␉␉␉␉nv_modeline_2_offset = (unsigned short) i;␊ |
347 | ␉␉␉␉break;␊ |
348 | ␉␉␉}␊ |
349 | ␉␉␉i++;␊ |
350 | ␉␉}␊ |
351 | ␉␉␊ |
352 | ␉␉nv_data_table = (unsigned short *) (map->bios_ptr + (nv_data_table_offset + OFFSET_TO_VESA_TABLE_INDEX));␊ |
353 | ␉␉std_vesa = (NV_VESA_TABLE *) (map->bios_ptr + *nv_data_table);␊ |
354 | ␉␉␊ |
355 | ␉␉map->nv_mode_table = (char *) std_vesa->sModelines;␊ |
356 | ␉␉if (nv_modeline_2_offset == (VBIOS_SIZE-1) || nv_modeline_2_offset == 0) {␊ |
357 | ␉␉␉map->nv_mode_table_2 = NULL;␊ |
358 | ␉␉} else {␊ |
359 | ␉␉␉map->nv_mode_table_2 = (char*) map->bios_ptr + nv_modeline_2_offset;␊ |
360 | ␉␉}␊ |
361 | ␉␉if (map->nv_mode_table == 0) {␊ |
362 | ␉␉␉printf("Unable to locate the mode table.\n");␊ |
363 | ␉␉␉printf("Please run the program 'dump_bios' as root and\n");␊ |
364 | ␉␉␉printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");␊ |
365 | ␉␉␉printf("Chipset: %s\n", chipset_type_names[map->chipset]);␊ |
366 | ␉␉␉close_vbios(map);␊ |
367 | ␉␉␉return 0;␊ |
368 | ␉␉}␊ |
369 | ␉␉map->mode_table_size = std_vesa->sHeader.usTable_Size;␊ |
370 | ␉}␊ |
371 | ␉␉␊ |
372 | ␉␊ |
373 | ␉/*␊ |
374 | ␉ * Determine size of mode table␊ |
375 | ␉ */␊ |
376 | ␉ ␊ |
377 | ␉if ((map->bios != BT_ATI_1) && (map->bios != BT_ATI_2) && (map->bios != BT_NVDA)) {␊ |
378 | ␉␉vbios_mode * mode_ptr = map->mode_table;␊ |
379 | ␉␉␉␊ |
380 | ␉␉while (mode_ptr->mode != 0xff) {␊ |
381 | ␉␉␉map->mode_table_size++;␊ |
382 | ␉␉␉mode_ptr++;␊ |
383 | ␉␉}␊ |
384 | ␉}␊ |
385 | ␉␊ |
386 | ␉/*␊ |
387 | ␉ * Figure out what type of bios we have␊ |
388 | ␉ * order of detection is important␊ |
389 | ␉ */␊ |
390 | ␉if ((map->bios != BT_ATI_1) && (map->bios != BT_ATI_2) && (map->bios != BT_NVDA)) {␊ |
391 | ␉␉if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type3))) {␊ |
392 | ␉␉␉map->bios = BT_3;␊ |
393 | ␉␉}␊ |
394 | ␉␉else if (detect_bios_type(map, TRUE, sizeof(vbios_modeline_type2))) {␊ |
395 | ␉␉␉map->bios = BT_2;␊ |
396 | ␉␉}␊ |
397 | ␉␉else if (detect_bios_type(map, FALSE, sizeof(vbios_resolution_type1))) {␊ |
398 | ␉␉␉map->bios = BT_1;␊ |
399 | ␉␉}␊ |
400 | ␉␉else {␊ |
401 | ␉␉␉printf("Unable to determine bios type.\n");␊ |
402 | ␉␉␉printf("Please run the program 'dump_bios' as root and\n");␊ |
403 | ␉␉␉printf("email the file 'vbios.dmp' to stomljen@yahoo.com.\n");␊ |
404 | ␉␉␉␊ |
405 | ␉␉␉printf("Chipset: %s\n", chipset_type_names[map->chipset]);␊ |
406 | ␉␉␉printf("Mode Table Offset: $C0000 + $%x\n", ((UInt32)map->mode_table) - ((UInt32)map->bios_ptr));␊ |
407 | ␉␉␊ |
408 | ␉␉␉printf("Mode Table Entries: %u\n", map->mode_table_size);␊ |
409 | ␉␉␉return 0;␊ |
410 | ␉␉}␊ |
411 | ␉}␊ |
412 | ␉␊ |
413 | ␉return map;␊ |
414 | }␊ |
415 | ␊ |
416 | void close_vbios(vbios_map * map) {␊ |
417 | ␉FREE(map);␊ |
418 | }␊ |
419 | ␊ |
420 | void unlock_vbios(vbios_map * map) {␊ |
421 | ␊ |
422 | ␉map->unlocked = TRUE;␊ |
423 | ␉ ␊ |
424 | ␉switch (map->chipset) {␊ |
425 | ␉␉case CT_UNKWN:␊ |
426 | ␉␉␉break;␊ |
427 | ␉␉case CT_830:␊ |
428 | ␉␉case CT_855GM:␊ |
429 | ␉␉␉outl(0xcf8, 0x8000005a);␊ |
430 | ␉␉␉map->b1 = inb(0xcfe);␊ |
431 | ␉␉␉␉␊ |
432 | ␉␉␉outl(0xcf8, 0x8000005a);␊ |
433 | ␉␉␉outb(0xcfe, 0x33);␊ |
434 | ␉␉␉break;␊ |
435 | ␉␉case CT_845G:␊ |
436 | ␉␉case CT_865G:␊ |
437 | ␉␉case CT_915G:␊ |
438 | ␉␉case CT_915GM:␊ |
439 | ␉␉case CT_945G:␊ |
440 | ␉␉case CT_945GM:␊ |
441 | ␉␉case CT_945GME:␊ |
442 | ␉␉case CT_946GZ:␊ |
443 | ␉␉case CT_955X:␊ |
444 | ␉␉case CT_G965:␊ |
445 | ␉␉case CT_Q965:␊ |
446 | ␉␉case CT_965GM:␊ |
447 | ␉␉case CT_975X:␊ |
448 | ␉␉case CT_P35:␊ |
449 | ␉␉case CT_X48:␊ |
450 | ␉␉case CT_B43:␊ |
451 | ␉␉case CT_Q45:␊ |
452 | ␉␉case CT_P45:␊ |
453 | ␉␉case CT_GM45:␊ |
454 | ␉␉case CT_G41:␊ |
455 | ␉␉case CT_G31:␊ |
456 | ␉␉case CT_G45:␊ |
457 | ␉␉case CT_500:␊ |
458 | ␊ |
459 | ␉␉␉outl(0xcf8, 0x80000090);␊ |
460 | ␉␉␉map->b1 = inb(0xcfd);␊ |
461 | ␉␉␉map->b2 = inb(0xcfe);␊ |
462 | ␉␉␉outl(0xcf8, 0x80000090);␊ |
463 | ␉␉␉outb(0xcfd, 0x33);␊ |
464 | ␉␉␉outb(0xcfe, 0x33);␊ |
465 | ␉␉break;␊ |
466 | ␉}␊ |
467 | ␉␊ |
468 | ␉#if DEBUG␊ |
469 | ␉{␊ |
470 | ␉␉UInt32 t = inl(0xcfc);␊ |
471 | ␉␉printf("unlock PAM: (0x%08x)\n", t);␊ |
472 | ␉}␊ |
473 | #endif␊ |
474 | }␊ |
475 | ␊ |
476 | void relock_vbios(vbios_map * map) {␊ |
477 | ␊ |
478 | ␉map->unlocked = FALSE;␊ |
479 | ␉␊ |
480 | ␉switch (map->chipset) {␊ |
481 | ␉␉case CT_UNKWN:␊ |
482 | ␉␉␉break;␊ |
483 | ␉␉case CT_830:␊ |
484 | ␉␉case CT_855GM:␊ |
485 | ␉␉␉outl(0xcf8, 0x8000005a);␊ |
486 | ␉␉␉outb(0xcfe, map->b1);␊ |
487 | ␉␉␉break;␊ |
488 | ␉␉case CT_845G:␊ |
489 | ␉␉case CT_865G:␊ |
490 | ␉␉case CT_915G:␊ |
491 | ␉␉case CT_915GM:␊ |
492 | ␉␉case CT_945G:␊ |
493 | ␉␉case CT_945GM:␊ |
494 | ␉␉case CT_945GME:␊ |
495 | ␉␉case CT_946GZ:␊ |
496 | ␉␉case CT_955X:␊ |
497 | ␉␉case CT_G965:␊ |
498 | ␉␉case CT_Q965:␊ |
499 | ␉␉case CT_965GM:␊ |
500 | ␉␉case CT_975X:␊ |
501 | ␉␉case CT_P35:␊ |
502 | ␉␉case CT_X48:␊ |
503 | ␉␉case CT_B43:␊ |
504 | ␉␉case CT_Q45:␊ |
505 | ␉␉case CT_P45:␊ |
506 | ␉␉case CT_GM45:␊ |
507 | ␉␉case CT_G41:␊ |
508 | ␉␉case CT_G31:␊ |
509 | ␉␉case CT_G45:␊ |
510 | ␉␉case CT_500:␊ |
511 | ␉␉␉␊ |
512 | ␉␉␉outl(0xcf8, 0x80000090);␊ |
513 | ␉␉␉outb(0xcfd, map->b1);␊ |
514 | ␉␉␉outb(0xcfe, map->b2);␊ |
515 | ␉␉␉break;␊ |
516 | ␉}␊ |
517 | ␉␊ |
518 | ␉#if DEBUG␊ |
519 | ␉{␊ |
520 | UInt32 t = inl(0xcfc);␊ |
521 | ␉␉printf("relock PAM: (0x%08x)\n", t);␊ |
522 | ␉}␊ |
523 | ␉#endif␊ |
524 | }␊ |
525 | ␊ |
526 | void save_vbios(vbios_map * map)␊ |
527 | {␊ |
528 | ␉map->bios_backup_ptr = malloc(VBIOS_SIZE);␊ |
529 | ␉bcopy((const unsigned char *)0xC0000, map->bios_backup_ptr, VBIOS_SIZE);␊ |
530 | }␊ |
531 | ␊ |
532 | void restore_vbios(vbios_map * map)␊ |
533 | {␊ |
534 | ␉bcopy(map->bios_backup_ptr,(unsigned char *)0xC0000, VBIOS_SIZE);␊ |
535 | }␊ |
536 | ␊ |
537 | ␊ |
538 | ␊ |
539 | static void gtf_timings(UInt32 x, UInt32 y, UInt32 freq,␊ |
540 | ␉␉␉␉␉␉unsigned long *clock,␊ |
541 | ␉␉␉␉␉␉UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,␊ |
542 | ␉␉␉␉␉␉UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank)␊ |
543 | {␊ |
544 | ␉UInt32 hbl, vbl, vfreq;␊ |
545 | ␉␊ |
546 | ␉vbl = y + (y+1)/(20000/(11*freq) - 1) + 1;␊ |
547 | ␉␊ |
548 | ␉vfreq = vbl * freq;␊ |
549 | ␉hbl = 16 * (int)(x * (30 - 300000 / vfreq) /␊ |
550 | ␉␉␉␉␉ + (70 + 300000 / vfreq) / 16 + 0);␊ |
551 | ␉␊ |
552 | ␉*vsyncstart = y;␊ |
553 | ␉*vsyncend = y + 3;␊ |
554 | ␉*vblank = vbl - 1;␉␊ |
555 | ␉*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;␉␊ |
556 | ␉*hsyncend = x + hbl / 2 - 1;␉␊ |
557 | ␉*hblank = x + hbl - 1;␉␊ |
558 | ␉*clock = (x + hbl) * vfreq / 1000;␊ |
559 | }␊ |
560 | ␊ |
561 | void cvt_timings(UInt32 x, UInt32 y, UInt32 freq,␊ |
562 | ␉␉␉␉ unsigned long *clock,␊ |
563 | ␉␉␉␉ UInt16 *hsyncstart, UInt16 *hsyncend, UInt16 *hblank,␊ |
564 | ␉␉␉␉ UInt16 *vsyncstart, UInt16 *vsyncend, UInt16 *vblank, bool reduced)␊ |
565 | {␊ |
566 | ␉UInt32 hbl, hbp, vbl, vsync, hperiod;␊ |
567 | ␉␊ |
568 | ␉if (!(y % 3) && ((y * 4 / 3) == x))␊ |
569 | vsync = 4;␊ |
570 | else if (!(y % 9) && ((y * 16 / 9) == x))␊ |
571 | vsync = 5;␊ |
572 | else if (!(y % 10) && ((y * 16 / 10) == x))␊ |
573 | vsync = 6;␊ |
574 | else if (!(y % 4) && ((y * 5 / 4) == x))␊ |
575 | vsync = 7;␊ |
576 | else if (!(y % 9) && ((y * 15 / 9) == x))␊ |
577 | vsync = 7;␊ |
578 | else /* Custom */␊ |
579 | vsync = 10;␊ |
580 | ␉␊ |
581 | ␉if (!reduced) {␊ |
582 | ␉␉hperiod = (1000000/freq - 550) / (y + 3);␊ |
583 | ␉␉vbl = y + (550/hperiod) + 3;␊ |
584 | ␉␉hbp = 30 - ((300*hperiod)/1000);␊ |
585 | ␉␉hbl = (x * hbp) / (100 - hbp);␊ |
586 | ␉␉␊ |
587 | ␉␉*vsyncstart = y + 6;␊ |
588 | ␉␉*vsyncend = *vsyncstart + vsync;␊ |
589 | ␉␉*vblank = vbl - 1;␉␊ |
590 | ␉␉*hsyncstart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 - 1;␉␊ |
591 | ␉␉*hsyncend = x + hbl / 2 - 1;␉␊ |
592 | ␉␉*hblank = x + hbl - 1;␊ |
593 | ␉␉␊ |
594 | ␉} else {␊ |
595 | ␉␉hperiod = (1000000/freq - 460) / y;␊ |
596 | ␉␉vbl = y + 460/hperiod + 1;␊ |
597 | ␉␉hbl = 160;␊ |
598 | ␉␉␊ |
599 | ␉␉*vsyncstart = y + 3;␊ |
600 | ␉␉*vsyncend = *vsyncstart + vsync;␊ |
601 | ␉␉*vblank = vbl - 1;␉␊ |
602 | ␉␉*hsyncstart = x + hbl / 2 - 32;␉␊ |
603 | ␉␉*hsyncend = x + hbl / 2 - 1;␉␊ |
604 | ␉␉*hblank = x + hbl - 1;␊ |
605 | ␉␉␊ |
606 | ␉}␊ |
607 | ␉*clock = (x + hbl) * 1000 / hperiod;␊ |
608 | }␊ |
609 | ␊ |
610 | void set_mode(vbios_map * map, UInt32 x, UInt32 y, UInt32 bp, UInt32 htotal, UInt32 vtotal) {␊ |
611 | ␉UInt32 xprev, yprev;␊ |
612 | ␉UInt32 i = 0, j;␉// patch first available mode␊ |
613 | ␊ |
614 | //␉for (i=0; i < map->mode_table_size; i++) {␊ |
615 | //␉␉if (map->mode_table[0].mode == mode) {␊ |
616 | ␉␉␉switch(map->bios) {␊ |
617 | ␉␉␉␉case BT_1:␊ |
618 | ␉␉␉␉␉{␊ |
619 | ␉␉␉␉␉␉vbios_resolution_type1 * res = map_type1_resolution(map, map->mode_table[i].resolution);␊ |
620 | ␉␉␉␉␉␉␊ |
621 | ␉␉␉␉␉␉if (bp) {␊ |
622 | ␉␉␉␉␉␉␉map->mode_table[i].bits_per_pixel = bp;␊ |
623 | ␉␉␉␉␉␉}␊ |
624 | ␉␉␉␉␉␉␊ |
625 | ␉␉␉␉␉␉res->x2 = (htotal?(((htotal-x) >> 8) & 0x0f) : (res->x2 & 0x0f)) | ((x >> 4) & 0xf0);␊ |
626 | ␉␉␉␉␉␉res->x1 = (x & 0xff);␊ |
627 | ␉␉␉␉␉␉␊ |
628 | ␉␉␉␉␉␉res->y2 = (vtotal?(((vtotal-y) >> 8) & 0x0f) : (res->y2 & 0x0f)) | ((y >> 4) & 0xf0);␊ |
629 | ␉␉␉␉␉␉res->y1 = (y & 0xff);␊ |
630 | ␉␉␉␉␉␉if (htotal)␊ |
631 | ␉␉␉␉␉␉␉res->x_total = ((htotal-x) & 0xff);␊ |
632 | ␉␉␉␉␉␉␊ |
633 | ␉␉␉␉␉␉if (vtotal)␊ |
634 | ␉␉␉␉␉␉␉res->y_total = ((vtotal-y) & 0xff);␊ |
635 | ␉␉␉␉␉}␊ |
636 | ␉␉␉␉␉break;␊ |
637 | ␉␉␉␉case BT_2:␊ |
638 | ␉␉␉␉␉{␊ |
639 | ␉␉␉␉␉␉vbios_resolution_type2 * res = map_type2_resolution(map, map->mode_table[i].resolution);␊ |
640 | ␉␉␉␉␉␉␊ |
641 | ␉␉␉␉␉␉res->xchars = x / 8;␊ |
642 | ␉␉␉␉␉␉res->ychars = y / 16 - 1;␊ |
643 | ␉␉␉␉␉␉xprev = res->modelines[0].x1;␊ |
644 | ␉␉␉␉␉␉yprev = res->modelines[0].y1;␊ |
645 | ␉␉␉␉␉␉␊ |
646 | ␉␉␉␉␉␉for(j=0; j < 3; j++) {␊ |
647 | ␉␉␉␉␉␉␉vbios_modeline_type2 * modeline = &res->modelines[j];␊ |
648 | ␉␉␉␉␉␉␉␊ |
649 | ␉␉␉␉␉␉␉if (modeline->x1 == xprev && modeline->y1 == yprev) {␊ |
650 | ␉␉␉␉␉␉␉␉modeline->x1 = modeline->x2 = x-1;␊ |
651 | ␉␉␉␉␉␉␉␉modeline->y1 = modeline->y2 = y-1;␊ |
652 | ␉␉␉␉␊ |
653 | ␉␉␉␉␉␉␉␉gtf_timings(x, y, freqs[j], &modeline->clock,␊ |
654 | ␉␉␉␉␉␉␉␉␉␉␉&modeline->hsyncstart, &modeline->hsyncend,␊ |
655 | ␉␉␉␉␉␉␉␉␉␉␉&modeline->hblank, &modeline->vsyncstart,␊ |
656 | ␉␉␉␉␉␉␉␉␉␉␉&modeline->vsyncend, &modeline->vblank);␊ |
657 | ␉␉␉␉␉␉␉␉␊ |
658 | ␉␉␉␉␉␉␉␉if (htotal)␊ |
659 | ␉␉␉␉␉␉␉␉␉modeline->htotal = htotal;␊ |
660 | ␉␉␉␉␉␉␉␉else␊ |
661 | ␉␉␉␉␉␉␉␉␉modeline->htotal = modeline->hblank;␊ |
662 | ␉␉␉␉␉␉␉␉␊ |
663 | ␉␉␉␉␉␉␉␉if (vtotal)␊ |
664 | ␉␉␉␉␉␉␉␉␉modeline->vtotal = vtotal;␊ |
665 | ␉␉␉␉␉␉␉␉else␊ |
666 | ␉␉␉␉␉␉␉␉␉modeline->vtotal = modeline->vblank;␊ |
667 | ␉␉␉␉␉␉␉}␊ |
668 | ␉␉␉␉␉␉}␊ |
669 | ␉␉␉␉␉}␊ |
670 | ␉␉␉␉␉break;␊ |
671 | ␉␉␉␉case BT_3:␊ |
672 | ␉␉␉␉␉{␊ |
673 | ␉␉␉␉␉␉vbios_resolution_type3 * res = map_type3_resolution(map, map->mode_table[i].resolution);␊ |
674 | ␉␉␉␉␉␉␊ |
675 | ␉␉␉␉␉␉xprev = res->modelines[0].x1;␊ |
676 | ␉␉␉␉␉␉yprev = res->modelines[0].y1;␊ |
677 | ␉␉␉␉␊ |
678 | ␉␉␉␉␉␉for (j=0; j < 3; j++) {␊ |
679 | ␉␉␉␉␉␉␉vbios_modeline_type3 * modeline = &res->modelines[j];␊ |
680 | ␉␉␉␉␉␉␉ ␊ |
681 | ␉␉␉␉␉␉␉if (modeline->x1 == xprev && modeline->y1 == yprev) {␊ |
682 | ␉␉␉␉␉␉␉␉modeline->x1 = modeline->x2 = x-1;␊ |
683 | ␉␉␉␉␉␉␉␉modeline->y1 = modeline->y2 = y-1;␊ |
684 | ␉␉␉␉␉␉␉␉ ␊ |
685 | ␉␉␉␉␉␉␉␉gtf_timings(x, y, freqs[j], &modeline->clock,␊ |
686 | ␉␉␉␉␉␉␉␉␉␉␉&modeline->hsyncstart, &modeline->hsyncend,␊ |
687 | ␉␉␉␉␉␉␉␉␉␉␉&modeline->hblank, &modeline->vsyncstart,␊ |
688 | ␉␉␉␉␉␉␉␉␉␉␉&modeline->vsyncend, &modeline->vblank);␊ |
689 | ␉␉␉␉␉␉␉␉if (htotal)␊ |
690 | ␉␉␉␉␉␉␉␉␉modeline->htotal = htotal;␊ |
691 | ␉␉␉␉␉␉␉␉else␊ |
692 | ␉␉␉␉␉␉␉␉␉modeline->htotal = modeline->hblank;␊ |
693 | ␉␉␉␉␉␉␉␉if (vtotal)␊ |
694 | ␉␉␉␉␉␉␉␉␉modeline->vtotal = vtotal;␊ |
695 | ␉␉␉␉␉␉␉␉else␊ |
696 | ␉␉␉␉␉␉␉␉␉modeline->vtotal = modeline->vblank;␊ |
697 | ␉␉␉␉␉␉␊ |
698 | ␉␉␉␉␉␉␉␉modeline->timing_h = y-1;␊ |
699 | ␉␉␉␉␉␉␉␉modeline->timing_v = x-1;␊ |
700 | ␉␉␉␉␉␉␉}␊ |
701 | ␉␉␉␉␉␉}␊ |
702 | ␉␉␉␉␉}␊ |
703 | ␉␉␉␉␉break;␊ |
704 | ␉␉␉␉case BT_ATI_1:␊ |
705 | ␉␉␉␉{␊ |
706 | ␉␉␉␉␉edid_mode mode;␊ |
707 | ␉␉␉␉␉VBEModeInfoBlock minfo;␊ |
708 | ␉␉␉␉␉unsigned short mode_n;␊ |
709 | ␉␉␉␉␉unsigned short vesaVersion;␊ |
710 | ␉␉␉␉␉␊ |
711 | ␉␉␉␉␉ATOM_MODE_TIMING *mode_timing = (ATOM_MODE_TIMING *) map->ati_mode_table;␊ |
712 | ␉␉␉␉␉␊ |
713 | ␉␉␉␉␉mode_n = getVESAModeWithProperties( x, y, 32, maColorModeBit |␊ |
714 | ␉␉␉␉␉␉␉␉␉␉␉␉␉ maModeIsSupportedBit |␊ |
715 | ␉␉␉␉␉␉␉␉␉␉␉␉␉ maGraphicsModeBit |␊ |
716 | ␉␉␉␉␉␉␉␉␉␉␉␉␉ maLinearFrameBufferAvailBit,␊ |
717 | ␉␉␉␉␉␉␉␉␉␉␉␉␉ 0,␊ |
718 | ␉␉␉␉␉␉␉␉␉␉␉␉␉ &minfo, &vesaVersion );␊ |
719 | ␉␉␉␉␉␊ |
720 | ␉␉␉␉␉if ( mode_n == modeEndOfList )␊ |
721 | ␉␉␉␉␉{␊ |
722 | ␉␉␉␉␉␉minfo.XResolution = 1024;␊ |
723 | ␉␉␉␉␉␉minfo.YResolution = 768;␊ |
724 | ␉␉␉␉␉}␊ |
725 | ␉␉␉␉␉␊ |
726 | ␉␉␉␉␉␊ |
727 | ␉␉␉␉␉int m_status = getMode(&mode);␊ |
728 | ␉␉␉␉␉␊ |
729 | ␉␉␉␉␉if (m_status || (mode.h_active != x)) {␊ |
730 | ␉␉␉␉␉␉vbios_modeline_type2 * modeline = malloc(sizeof(vbios_modeline_type2));␊ |
731 | ␉␉␉␉␉␉bzero(modeline, sizeof(vbios_modeline_type2));␊ |
732 | ␉␉␉␉␉␉␊ |
733 | ␉␉␉␉␉␉cvt_timings(x, y, 60, &modeline->clock,␊ |
734 | ␉␉␉␉␉␉␉␉␉&modeline->hsyncstart, &modeline->hsyncend,␊ |
735 | ␉␉␉␉␉␉␉␉␉&modeline->hblank, &modeline->vsyncstart,␊ |
736 | ␉␉␉␉␉␉␉␉␉&modeline->vsyncend, &modeline->vblank, FALSE);␊ |
737 | ␉␉␉␉␉␉␊ |
738 | ␉␉␉␉␉␉mode.pixel_clock = modeline->clock /10;␊ |
739 | ␉␉␉␉␉␉mode.h_active = x;␊ |
740 | ␉␉␉␉␉␉mode.h_sync_offset = modeline->hsyncstart - x;␊ |
741 | ␉␉␉␉␉␉mode.h_sync_width = modeline->hsyncend - modeline->hsyncstart;␊ |
742 | ␉␉␉␉␉␉mode.h_blanking = modeline->hblank - x;␊ |
743 | ␉␉␉␉␉␉mode.v_active = y;␊ |
744 | ␉␉␉␉␉␉mode.v_sync_offset = modeline->vsyncstart - y;␊ |
745 | ␉␉␉␉␉␉mode.v_sync_width = modeline->vsyncend - modeline->vsyncstart;␊ |
746 | ␉␉␉␉␉␉mode.v_blanking = modeline->vblank - y;␊ |
747 | ␉␉␉␉␉␉␊ |
748 | ␉␉␉␉␉␉free(modeline);␊ |
749 | ␉␉␉␉␉␉m_status = 0;␊ |
750 | ␉␉␉␉␉}␊ |
751 | ␉␉␉␉␉␊ |
752 | ␉␉␉␉␉if (!m_status) {␉␉␉␉␉␉␊ |
753 | ␉␉␉␉␉␉while (i < (map->mode_table_size / sizeof(ATOM_MODE_TIMING)))␊ |
754 | ␉␉␉␉␉␉{␊ |
755 | ␉␉␉␉␉␉␉if (mode_timing[i].usCRTC_H_Disp == minfo.XResolution) {␉␉␉␉␉␉␉␉␊ |
756 | ␉␉␉␉␉␉␉␉mode_timing[i].usCRTC_H_Total = mode.h_active + mode.h_blanking;␊ |
757 | ␉␉␉␉␉␉␉␉mode_timing[i].usCRTC_H_Disp = mode.h_active;␊ |
758 | ␉␉␉␉␉␉␉␉mode_timing[i].usCRTC_H_SyncStart = mode.h_active + mode.h_sync_offset;␊ |
759 | ␉␉␉␉␉␉␉␉mode_timing[i].usCRTC_H_SyncWidth = mode.h_sync_width;␊ |
760 | ␉␉␉␉␉␉␉␉␊ |
761 | ␉␉␉␉␉␉␉␉mode_timing[i].usCRTC_V_Total = mode.v_active + mode.v_blanking;␊ |
762 | ␉␉␉␉␉␉␉␉mode_timing[i].usCRTC_V_Disp = mode.v_active;␊ |
763 | ␉␉␉␉␉␉␉␉mode_timing[i].usCRTC_V_SyncStart = mode.v_active + mode.v_sync_offset;␊ |
764 | ␉␉␉␉␉␉␉␉mode_timing[i].usCRTC_V_SyncWidth = mode.v_sync_width;␊ |
765 | ␉␉␉␉␉␉␉␉␊ |
766 | ␉␉␉␉␉␉␉␉mode_timing[i].usPixelClock = mode.pixel_clock;␊ |
767 | ␉␉␉␉␉␉␉}␊ |
768 | ␉␉␉␉␉␉␉i++;␊ |
769 | ␉␉␉␉␉␉}␊ |
770 | ␉␉␉␉␉}␉␉␉␉␉␊ |
771 | ␉␉␉␉}␊ |
772 | ␉␉␉␉␉break;␊ |
773 | ␉␉␉␉case BT_ATI_2:␊ |
774 | ␉␉␉␉{␊ |
775 | ␉␉␉␉␉edid_mode mode;␊ |
776 | ␉␉␉␉␉VBEModeInfoBlock minfo;␊ |
777 | ␉␉␉␉␉unsigned short mode_n;␊ |
778 | ␉␉␉␉␉unsigned short vesaVersion;␊ |
779 | ␉␉␉␉␉␊ |
780 | ␉␉␉␉␉ATOM_DTD_FORMAT *mode_timing = (ATOM_DTD_FORMAT *) map->ati_mode_table;␊ |
781 | ␉␉␉␉␉␊ |
782 | ␉␉␉␉␉mode_n = getVESAModeWithProperties( x, y, 32, maColorModeBit |␊ |
783 | ␉␉␉␉␉␉␉␉␉␉␉␉␉ maModeIsSupportedBit |␊ |
784 | ␉␉␉␉␉␉␉␉␉␉␉␉␉ maGraphicsModeBit |␊ |
785 | ␉␉␉␉␉␉␉␉␉␉␉␉␉ maLinearFrameBufferAvailBit,␊ |
786 | ␉␉␉␉␉␉␉␉␉␉␉␉␉ 0,␊ |
787 | ␉␉␉␉␉␉␉␉␉␉␉␉␉ &minfo, &vesaVersion );␊ |
788 | ␉␉␉␉␉␊ |
789 | ␉␉␉␉␉if ( mode_n == modeEndOfList )␊ |
790 | ␉␉␉␉␉{␊ |
791 | ␉␉␉␉␉␉minfo.XResolution = 1024;␊ |
792 | ␉␉␉␉␉␉minfo.YResolution = 768;␊ |
793 | ␉␉␉␉␉}␊ |
794 | ␉␉␉␉␉␊ |
795 | ␉␉␉␉␉␊ |
796 | ␉␉␉␉␉int m_status = getMode(&mode);␊ |
797 | ␉␉␉␉␉␊ |
798 | ␉␉␉␉␉if (m_status || (mode.h_active != x)) {␊ |
799 | ␉␉␉␉␉␉vbios_modeline_type2 * modeline = malloc(sizeof(vbios_modeline_type2));␊ |
800 | ␉␉␉␉␉␉bzero(modeline, sizeof(vbios_modeline_type2));␊ |
801 | ␉␉␉␉␉␉␊ |
802 | ␉␉␉␉␉␉cvt_timings(x, y, 60, &modeline->clock,␊ |
803 | ␉␉␉␉␉␉␉␉␉&modeline->hsyncstart, &modeline->hsyncend,␊ |
804 | ␉␉␉␉␉␉␉␉␉&modeline->hblank, &modeline->vsyncstart,␊ |
805 | ␉␉␉␉␉␉␉␉␉&modeline->vsyncend, &modeline->vblank, FALSE);␊ |
806 | ␉␉␉␉␉␉␊ |
807 | ␉␉␉␉␉␉mode.pixel_clock = modeline->clock /10;␊ |
808 | ␉␉␉␉␉␉mode.h_active = x;␊ |
809 | ␉␉␉␉␉␉mode.h_sync_offset = modeline->hsyncstart - x;␊ |
810 | ␉␉␉␉␉␉mode.h_sync_width = modeline->hsyncend - modeline->hsyncstart;␊ |
811 | ␉␉␉␉␉␉mode.h_blanking = modeline->hblank - x;␊ |
812 | ␉␉␉␉␉␉mode.v_active = y;␊ |
813 | ␉␉␉␉␉␉mode.v_sync_offset = modeline->vsyncstart - y;␊ |
814 | ␉␉␉␉␉␉mode.v_sync_width = modeline->vsyncend - modeline->vsyncstart;␊ |
815 | ␉␉␉␉␉␉mode.v_blanking = modeline->vblank - y;␊ |
816 | ␉␉␉␉␉␉␊ |
817 | ␉␉␉␉␉␉free(modeline);␊ |
818 | ␉␉␉␉␉␉m_status = 0;␊ |
819 | ␉␉␉␉␉}␊ |
820 | ␉␉␉␉␉␊ |
821 | ␉␉␉␉␉if (!m_status) {␉␉␉␉␉␉␊ |
822 | ␉␉␉␉␉␉while (i < (map->mode_table_size / sizeof(ATOM_DTD_FORMAT)))␊ |
823 | ␉␉␉␉␉␉{␊ |
824 | ␉␉␉␉␉␉␉if (mode_timing[i].usHActive == minfo.XResolution) {␊ |
825 | ␉␉␉␉␉␉␉␉␊ |
826 | ␉␉␉␉␉␉␉␉mode_timing[i].usHBlanking_Time = mode.h_blanking;␊ |
827 | ␉␉␉␉␉␉␉␉mode_timing[i].usHActive = mode.h_active;␊ |
828 | ␉␉␉␉␉␉␉␉mode_timing[i].usHSyncOffset = mode.h_sync_offset;␊ |
829 | ␉␉␉␉␉␉␉␉mode_timing[i].usHSyncWidth = mode.h_sync_width;␊ |
830 | ␉␉␉␉␉␉␉␉␊ |
831 | ␉␉␉␉␉␉␉␉mode_timing[i].usVBlanking_Time = mode.v_blanking;␊ |
832 | ␉␉␉␉␉␉␉␉mode_timing[i].usVActive = mode.v_active;␊ |
833 | ␉␉␉␉␉␉␉␉mode_timing[i].usVSyncOffset = mode.v_sync_offset;␊ |
834 | ␉␉␉␉␉␉␉␉mode_timing[i].usVSyncWidth = mode.v_sync_width;␊ |
835 | ␉␉␉␉␉␉␉␉␊ |
836 | ␉␉␉␉␉␉␉␉mode_timing[i].usPixClk = mode.pixel_clock;␊ |
837 | ␉␉␉␉␉␉␉}␊ |
838 | ␉␉␉␉␉␉␉i++;␊ |
839 | ␉␉␉␉␉␉}␊ |
840 | ␉␉␉␉␉}␊ |
841 | ␉␉␉␉␉␊ |
842 | ␉␉␉␉}␊ |
843 | ␉␉␉␉␉break;␊ |
844 | ␉␉␉␉case BT_NVDA:␊ |
845 | ␉␉␉␉{␊ |
846 | ␉␉␉␉␉s_aspect aspect_ratio;␊ |
847 | ␉␉␉␉␉/*␊ |
848 | ␉␉␉␉␉ * Get the aspect ratio for the requested mode␊ |
849 | ␉␉␉␉␉ */␊ |
850 | ␉␉␉␉␉if ((y * 16 / 9) == x) {␊ |
851 | ␉␉␉␉␉␉aspect_ratio.width = 16;␊ |
852 | ␉␉␉␉␉␉aspect_ratio.height = 9;␊ |
853 | ␉␉␉␉␉} else if ((y * 16 / 10) == x) {␊ |
854 | ␉␉␉␉␉␉aspect_ratio.width = 16;␊ |
855 | ␉␉␉␉␉␉aspect_ratio.height = 10;␊ |
856 | ␉␉␉␉␉} else if ((y * 5 / 4) == x) {␊ |
857 | ␉␉␉␉␉␉aspect_ratio.width = 5;␊ |
858 | ␉␉␉␉␉␉aspect_ratio.height = 4;␊ |
859 | ␉␉␉␉␉} else if ((y * 15 / 9) == x) {␊ |
860 | ␉␉␉␉␉␉aspect_ratio.width = 15;␊ |
861 | ␉␉␉␉␉␉aspect_ratio.height = 9;␊ |
862 | ␉␉␉␉␉} else {␊ |
863 | ␉␉␉␉␉␉aspect_ratio.width = 4;␊ |
864 | ␉␉␉␉␉␉aspect_ratio.height = 3;␊ |
865 | ␉␉␉␉␉}␊ |
866 | ␉␉␉␉␉␊ |
867 | ␉␉␉␉␉NV_MODELINE *mode_timing = (NV_MODELINE *) map->nv_mode_table;␊ |
868 | ␉␉␉␉␉NV_MODELINE_2 *mode_timing_2 = (NV_MODELINE_2 *) map->nv_mode_table_2;␊ |
869 | ␉␉␉␉␉␊ |
870 | ␉␉␉␉␉i = 0;␊ |
871 | ␉␉␉␉␉if (mode_timing_2[i].h_disp == 0x140) { //From 320x200 mode.␊ |
872 | ␉␉␉␉␉␉while (mode_timing_2[i].h_disp <= 0x800) {␊ |
873 | ␉␉␉␉␉␉␉␊ |
874 | ␉␉␉␉␉␉␉vbios_modeline_type2 * modeliner = malloc(sizeof(vbios_modeline_type2));␊ |
875 | ␉␉␉␉␉␉␉bzero(modeliner, sizeof(vbios_modeline_type2));␊ |
876 | ␉␉␉␉␉␉␉␊ |
877 | ␉␉␉␉␉␉␉x = mode_timing_2[i].h_disp;␊ |
878 | ␉␉␉␉␉␉␉y = x * aspect_ratio.height / aspect_ratio.width;␊ |
879 | ␉␉␉␉␉␉␉␊ |
880 | ␉␉␉␉␉␉␉cvt_timings(x, y, 60, &modeliner->clock,␊ |
881 | ␉␉␉␉␉␉␉␉␉␉&modeliner->hsyncstart, &modeliner->hsyncend,␊ |
882 | ␉␉␉␉␉␉␉␉␉␉&modeliner->hblank, &modeliner->vsyncstart,␊ |
883 | ␉␉␉␉␉␉␉␉␉␉&modeliner->vsyncend, &modeliner->vblank, TRUE);␊ |
884 | ␉␉␉␉␉␉␉␊ |
885 | ␉␉␉␉␉␉␉mode_timing_2[i].h_disp = x;␊ |
886 | ␉␉␉␉␉␉␉mode_timing_2[i].v_disp = y;␊ |
887 | ␉␉␉␉␉␉␉mode_timing_2[i].h_blank = modeliner->hblank - x;␊ |
888 | ␉␉␉␉␉␉␉mode_timing_2[i].h_syncoffset = modeliner->hsyncstart - x;␊ |
889 | ␉␉␉␉␉␉␉mode_timing_2[i].h_syncwidth = modeliner->hsyncend - modeliner->hsyncstart;␊ |
890 | ␉␉␉␉␉␉␉mode_timing_2[i].v_blank = modeliner->vblank - y;␊ |
891 | ␉␉␉␉␉␉␉i++;␊ |
892 | ␉␉␉␉␉␉␉free(modeliner);␉␊ |
893 | ␉␉␉␉␉␉}␊ |
894 | ␉␉␉␉␉} ␊ |
895 | ␉␉␉␉␉i = 0;␊ |
896 | ␉␉␉␉␉␊ |
897 | ␉␉␉␉␉while ((mode_timing[i].reserved3 & 0xff) == 0xff) {␊ |
898 | ␉␉␉␉␉␉x = mode_timing[i].usH_Active;␊ |
899 | ␉␉␉␉␉␉y = x * aspect_ratio.height / aspect_ratio.width;␊ |
900 | ␉␉␉␉␉␉␊ |
901 | ␉␉␉␉␉␉vbios_modeline_type2 * modeliner = malloc(sizeof(vbios_modeline_type2));␊ |
902 | ␉␉␉␉␉␉bzero(modeliner, sizeof(vbios_modeline_type2));␊ |
903 | ␉␉␉␉␉␉␊ |
904 | ␉␉␉␉␉␉cvt_timings(x, y, 60, &modeliner->clock,␊ |
905 | ␉␉␉␉␉␉␉␉␉&modeliner->hsyncstart, &modeliner->hsyncend,␊ |
906 | ␉␉␉␉␉␉␉␉␉&modeliner->hblank, &modeliner->vsyncstart,␊ |
907 | ␉␉␉␉␉␉␉␉␉&modeliner->vsyncend, &modeliner->vblank, FALSE);␊ |
908 | ␉␉␉␉␉␉␊ |
909 | ␉␉␉␉␉␉mode_timing[i].usH_Total = x + modeliner->hblank;␊ |
910 | ␉␉␉␉␉␉mode_timing[i].usH_Active = x;␊ |
911 | ␉␉␉␉␉␉mode_timing[i].usH_Active_minus_One = x - 1;␊ |
912 | ␉␉␉␉␉␉mode_timing[i].usH_Active_minus_One_ = x - 1;␊ |
913 | ␉␉␉␉␉␉mode_timing[i].usH_SyncStart = modeliner->hsyncstart;␊ |
914 | ␉␉␉␉␉␉mode_timing[i].usH_SyncEnd = modeliner->hsyncend;␊ |
915 | ␉␉␉␉␉␉␊ |
916 | ␉␉␉␉␉␉mode_timing[i].usV_Total = y + modeliner->vblank;␊ |
917 | ␉␉␉␉␉␉mode_timing[i].usV_Active = y;␊ |
918 | ␉␉␉␉␉␉mode_timing[i].usV_Active_minus_One = y - 1;␊ |
919 | ␉␉␉␉␉␉mode_timing[i].usV_Active_minus_One_ = y - 1;␊ |
920 | ␉␉␉␉␉␉mode_timing[i].usV_SyncStart = modeliner->vsyncend;␊ |
921 | ␉␉␉␉␉␉mode_timing[i].usV_SyncEnd = modeliner->vsyncend;␊ |
922 | ␉␉␉␉␉␉␊ |
923 | ␉␉␉␉␉␉mode_timing[i].usPixel_Clock = modeliner->clock;␊ |
924 | ␉␉␉␉␉␉␊ |
925 | ␉␉␉␉␉␉i++;␊ |
926 | ␉␉␉␉␉}␊ |
927 | ␉␉␉␉}␊ |
928 | ␉␉␉␉␉␊ |
929 | ␉␉␉␉␉break;␊ |
930 | ␉␉␉␉case BT_UNKWN:␊ |
931 | ␉␉␉␉␉break;␊ |
932 | ␉␉␉}␊ |
933 | //␉␉}␊ |
934 | //␉}␊ |
935 | }␊ |
936 |