Chameleon

Chameleon Svn Source Tree

Root/branches/azimutz/Chazileon/i386/libsaio/gma_resolution.c

1/*
2 * gmaResolution.c
3 *
4 *
5 * Created by Le Bidou on 19/03/10.
6 * Copyright 2010 ---. All rights reserved.
7 *
8 */
9
10#include "gma_resolution.h"
11
12char * biosTypeNames[] = {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"};
13int freqs[] = { 60, 75, 85 };
14
15
16vbiosResolutionType1 * mapType1Resolution(vBiosMap * map, uint16_t res)
17{
18vbiosResolutionType1 * ptr = ((vbiosResolutionType1*)(map->biosPtr + res));
19return ptr;
20}
21
22vbiosResolutionType2 * mapType2Resolution(vBiosMap * map, uint16_t res)
23{
24vbiosResolutionType2 * ptr = ((vbiosResolutionType2*)(map->biosPtr + res));
25return ptr;
26}
27
28vbiosResolutionType3 * mapType3Resolution(vBiosMap * map, uint16_t res)
29{
30vbiosResolutionType3 * ptr = ((vbiosResolutionType3*)(map->biosPtr + res));
31return ptr;
32}
33
34char detectBiosType(vBiosMap * map, char modeline, int entrySize)
35{
36uint32_t i;
37uint16_t r1, r2;
38
39vbiosMode * modeTable = (vbiosMode *)map->modeTables->pointer;
40
41r1 = r2 = 32000;
42
43for (i=0; i < map->modeTables->size; i++)
44{
45if (modeTable[i].resolution <= r1)
46r1 = modeTable[i].resolution;
47else if (modeTable[i].resolution <= r2)
48r2 = modeTable[i].resolution;
49}
50
51return (r2-r1-6) % entrySize == 0;
52}
53
54vBiosMap * openIntelVbios(vBiosMap *map)
55{
56/*
57 * Find the location of the Mode Table
58 */
59unsigned char* p = map->biosPtr + 16;
60unsigned char* limit = map->biosPtr + VBIOS_SIZE - (3 * sizeof(vbiosMode));
61
62// initialize the table chain with one element
63sModeTable * table = intializeTables(map, 1);
64
65while (p < limit && table->pointer == 0)
66{
67vbiosMode* modePtr = (vbiosMode*) p;
68
69if (((modePtr[0].mode & 0xf0) == 0x30) && ((modePtr[1].mode & 0xf0) == 0x30) &&
70((modePtr[2].mode & 0xf0) == 0x30) && ((modePtr[3].mode & 0xf0) == 0x30))
71{
72
73table->pointer = (uint8_t *)modePtr;
74}
75
76p++;
77}
78
79if (table->pointer == 0)
80{
81PRINT("Unable to locate the mode table.\n");
82PRINT("Please run the program 'dump_bios' as root and\n");
83PRINT("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n");
84
85closeVbios(map);
86return 0;
87}
88
89PRINT("Mode Table at offset : 0x%x\n", (table->pointer) - map->biosPtr);
90
91/*
92 * Determine size of mode table
93 */
94
95vbiosMode * modePtr = (vbiosMode *)table->pointer;
96
97while (modePtr->mode != 0xff)
98{
99table->size++;
100modePtr++;
101}
102
103table->modeCount = table->size;
104PRINT("Mode Table size : %d\n", table->modeCount);
105
106/*
107 * Figure out what type of bios we have
108 * order of detection is important
109 */
110
111if (detectBiosType(map, TRUE, sizeof(vbiosModelineType3)))
112{
113map->bios = BT_3;
114map->setMode = intelSetMode_3;
115PRINT("Bios Type : BT_3\n");
116}
117else if (detectBiosType(map, TRUE, sizeof(vbiosModelineType2)))
118{
119map->bios = BT_2;
120map->setMode = intelSetMode_2;
121PRINT("Bios Type : BT_2\n");
122}
123else if (detectBiosType(map, FALSE, sizeof(vbiosResolutionType1)))
124{
125map->bios = BT_1;
126map->setMode = intelSetMode_1;
127PRINT("Bios Type : BT_1\n");
128}
129else
130{
131PRINT("Unable to determine bios type.\n");
132PRINT("Please run the program 'dump_bios' as root and\n");
133PRINT("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n");
134
135return 0;
136}
137
138return map;
139}
140
141
142
143bool intelSetMode_1(sModeTable * table, uint8_t idx, uint32_t* x, uint32_t* y)
144{
145vbiosMode *modeTiming = (vbiosMode *) table->pointer;
146vbiosResolutionType1 * res = mapType1Resolution(map, modeTiming[idx].resolution);
147
148//retreive the original mode's dimensions
149uint32_t actualX = ((res->hActive2 & 0xf0) << 4) | (res->hActive1 & 0xff);
150uint32_t actualY = ((res->vActive2 & 0xf0) << 4) | (res->vActive1 & 0xff);
151
152// patch only if mode differs
153if ((*x != actualX) || (*y != actualY))
154{
155PRINT("Mode %dx%d -> ", actualX, actualY);
156
157res->hActive2 = (res->hActive2 & 0x0f) | ((*x >> 4) & 0xf0);
158res->hActive1 = (*x & 0xff);
159
160res->vActive2 = (res->hActive2 & 0x0f) | ((*y >> 4) & 0xf0);
161res->vActive1 = (*y & 0xff);
162
163uint32_t actualX = ((res->hActive2 & 0xf0) << 4) | (res->hActive1 & 0xff);
164uint32_t actualY = ((res->vActive2 & 0xf0) << 4) | (res->vActive1 & 0xff);
165
166PRINT("%dx%d \n", actualX, actualY);
167}
168
169//since only the first mode is patched, this is deprecated
170res = mapType1Resolution(map, modeTiming[idx + 1].resolution);
171
172actualX = ((res->hActive2 & 0xf0) << 4) | (res->hActive1 & 0xff);
173actualY = ((res->vActive2 & 0xf0) << 4) | (res->vActive1 & 0xff);
174
175*x = actualX;
176*y = actualY;
177
178return true;
179}
180
181bool intelSetMode_2(sModeTable * table, uint8_t idx, uint32_t* x, uint32_t* y)
182{
183uint32_t xprev, yprev, j = 0;
184
185vbiosMode *modeTiming = (vbiosMode *) table->pointer;
186vbiosResolutionType2 * res = mapType2Resolution(map, modeTiming[idx].resolution);
187
188//patch only if mode differs
189if ((*x != (res->modelines[0].hActive1 + 1))
190||(*y != (res->modelines[0].vActive1 + 1)) )
191{
192
193PRINT("Mode %dx%d -> ", res->modelines[0].hActive1 + 1, res->modelines[0].vActive1 + 1);
194
195res->xChars = *x / 8;
196res->yChars = *y / 16 - 1;
197xprev = res->modelines[0].hActive1;
198yprev = res->modelines[0].vActive1;
199
200// recalculate timigs for all frequencies and patch
201for(j = 0; j < 3; j++)
202{
203vbiosModelineType2 * mode = &res->modelines[j];
204
205if (mode->hActive1 == xprev && mode->vActive1 == yprev)
206{
207mode->hActive1 = mode->hActive2 = *x - 1;
208mode->vActive1 = mode->vActive2 = *y - 1;
209
210gtfTimings(*x, *y, freqs[j], &mode->clock,
211&mode->hSyncStart, &mode->hSyncEnd,
212&mode->hBlank, &mode->vSyncStart,
213&mode->vSyncEnd, &mode->vBlank);
214
215mode->hTotal = mode->hBlank;
216mode->vTotal = mode->vBlank;
217}
218}
219PRINT("%dx%d\n", res->modelines[0].hActive1 + 1, res->modelines[0].vActive1 + 1);
220
221}
222//since only the first mode is patched, this is deprecated
223res = mapType2Resolution(map, modeTiming[idx + 1].resolution);
224
225*x = res->modelines[0].hActive1 + 1;
226*y = res->modelines[0].vActive1 + 1;
227
228return true;
229}
230
231bool intelSetMode_3(sModeTable * table, uint8_t idx, uint32_t* x, uint32_t* y)
232{
233uint32_t xprev, yprev, j = 0;
234
235vbiosMode *modeTiming = (vbiosMode *) table->pointer;
236vbiosResolutionType3 * res = mapType3Resolution(map, modeTiming[idx].resolution);
237
238// patch only if mode differs
239if ((*x != (res->modelines[0].hActive1 + 1))
240||(*y != (res->modelines[0].vActive1 + 1)) )
241{
242
243PRINT("Mode %dx%d -> ", res->modelines[0].hActive1 + 1, res->modelines[0].vActive1 + 1);
244
245xprev = res->modelines[0].hActive1;
246yprev = res->modelines[0].vActive1;
247
248// recalculate timings for all frequencies and patch
249for(j = 0; j < 3; j++) {
250vbiosModelineType3 * mode = &res->modelines[j];
251
252if (mode->hActive1 == xprev && mode->vActive1 == yprev)
253{
254mode->hActive1 = mode->hActive2 = *x - 1;
255mode->vActive1 = mode->vActive2 = *y - 1;
256
257gtfTimings(*x, *y, freqs[j], &mode->clock,
258&mode->hSyncStart, &mode->hSyncEnd,
259&mode->hBlank, &mode->vSyncStart,
260&mode->vSyncEnd, &mode->vBlank);
261
262mode->hTotal = mode->hBlank;
263mode->vTotal = mode->vBlank;
264
265mode->timingH = *y-1;
266mode->timingV = *x-1;
267}
268}
269
270PRINT("%dx%d\n", res->modelines[0].hActive1 + 1, res->modelines[0].vActive1 + 1);
271
272}
273//since only the first mode is patched, this is deprecated
274res = mapType3Resolution(map, modeTiming[idx + 1].resolution);
275
276*x = res->modelines[0].hActive1 + 1;
277*y = res->modelines[0].vActive1 + 1;
278
279return true;
280}

Archive Download this file

Revision: 399