Chameleon

Chameleon Svn Source Tree

Root/branches/valv/i386/libsaio/nvidia_resolution.c

  • Property svn:executable set to
1/*
2 * nvidia_resolution.c
3 *
4 *
5 * Created by Le Bidou on 19/03/10.
6 * Copyright 2010 ---. All rights reserved.
7 *
8 */
9
10#include "nvidia_resolution.h"
11
12vBiosMap * openNvidiaVbios(vBiosMap *map)
13{
14unsigned short nvDataTableOffset = 0;
15unsigned short nvModeline_2_Offset = 0;
16unsigned short * nvDataTable = NULL;
17nvVesaTable * stdVesa;
18
19// initialize the table chain with two elements
20sModeTable * table = intializeTables(map, 2);
21/*
22 * Locate the VESA Tables
23 */
24
25int i = 0;
26//First VESA Table
27while (i < 0x300) //We don't need to look for the table in the whole bios, the 768 first bytes only
28{
29if ((map->biosPtr[i] == 0x44)
30&& (map->biosPtr[i+1] == 0x01)
31&& (map->biosPtr[i+2] == 0x04)
32&& (map->biosPtr[i+3] == 0x00)) {
33nvDataTableOffset = (unsigned short) (map->biosPtr[i+4] | (map->biosPtr[i+5] << 8));
34break;
35}
36i++;
37}
38
39nvDataTable = (unsigned short *) (map->biosPtr + (nvDataTableOffset + OFFSET_TO_VESA_TABLE_INDEX));
40stdVesa = (nvVesaTable *) (map->biosPtr + *nvDataTable);
41table->pointer = (uint8_t *) stdVesa + sizeof(nvCommonTableHeader);
42verbose("First Standard VESA Table at offset 0x%x\n",(unsigned int) (table->pointer - map->biosPtr));
43
44//Second VESA Table
45while (i < VBIOS_SIZE) //We don't know how to locate it other way
46{
47if ((map->biosPtr[i] == 0x40) && (map->biosPtr[i+1] == 0x01) //this is the first 320x200 modeline.
48&& (map->biosPtr[i+2] == 0xC8) && (map->biosPtr[i+3] == 0x00)
49&& (map->biosPtr[i+4] == 0x28)
50&& (map->biosPtr[i+5] == 0x18)
51&& (map->biosPtr[i+6] == 0x08)
52&& (map->biosPtr[i+7] == 0x08))
53{
54nvModeline_2_Offset = (unsigned short) i;
55break;
56}
57i++;
58}
59
60
61
62if (nvModeline_2_Offset == (VBIOS_SIZE-1) || nvModeline_2_Offset == 0)
63{
64//If no second vesa table is available, free the corresponding table in chain
65free(table->next);
66table->next = NULL;
67PRINT("There is no Second Standard VESA Table to patch\n");
68}
69else
70{
71table = table->next;
72table->pointer = map->biosPtr + nvModeline_2_Offset;
73PRINT("Second Standard VESA Table at offset 0x%x\n", (unsigned int)(table->pointer - map->biosPtr));
74}
75
76if (table->prev->pointer == NULL)
77{
78PRINT("Unable to locate the mode table.\n");
79PRINT("Please run the program 'dumpBios' as root and\n");
80PRINT("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n");
81
82closeVbios(map);
83return 0;
84}
85
86// reset the table pointer to the first in chain
87table = map->modeTables;
88
89/*
90 * for each table in chain, figure out how many modes are available
91 * and what is the size of the table
92 */
93while (table != NULL)
94{
95table->modeCount = 0;
96PRINT("Table #%d has ", table->id);
97
98if (table->id == MAIN_VESA_TABLE)
99{
100table->modeCount = stdVesa->header.tableSize & 0xff;
101if (table->modeCount == 0) table->modeCount = 16;
102table->size = table->modeCount * sizeof(nvModeline);
103}
104
105if (table->id == SECOND_VESA_TABLE)
106{
107nvModeline_2 * modePtr = (nvModeline_2 *)table->pointer;
108while (1)
109{
110if (modePtr[table->modeCount].hActive > 2048) break;
111table->modeCount++;
112}
113if (table->modeCount == 0) table->modeCount = 31;
114table->size = table->modeCount * sizeof(nvModeline_2);
115}
116
117PRINT("%d modes\n", table->modeCount);
118table = table->next;
119}
120
121map->setMode = nvidiaSetMode;
122
123saveTables(map->modeTables);
124
125#if AUTORES_DEBUG
126PRINT("Press Any Key...\n");
127getc();
128#endif
129
130return map;
131}
132
133bool nvidiaSetMode(sModeTable * table, uint8_t idx, uint32_t* x, uint32_t* y)
134{
135//In First VESA table, only first mode in table is patched
136if (table->id == MAIN_VESA_TABLE)
137{
138nvModeline * modeTiming = (nvModeline *)table->pointer;
139
140// patch only if mode differs and if the mode to patch isn't a console mode
141if (((*x != modeTiming[idx].hActive) || (*y != modeTiming[idx].vActive))
142&& (modeTiming[idx].hActive > 100))
143{
144
145PRINT("Mode %dx%d -> ", modeTiming[idx].hActive, modeTiming[idx].vActive);
146
147if (modeTiming[idx].hActive != *x)
148{
149modeTiming[idx].hActive = *x;
150modeTiming[idx].hActiveMinusOne = *x - 1;
151modeTiming[idx].hActiveMinusOne_ = *x - 1;
152}
153
154modeTiming[idx].vActive = *y;
155modeTiming[idx].vActiveMinusOne = *y - 1;
156modeTiming[idx].vActiveMinusOne_ = *y - 1;
157
158PRINT("%dx%d (%d %d %d %d %d %d)\n",
159 modeTiming[idx].hActive,
160 modeTiming[idx].vActive,
161 modeTiming[idx].hSyncStart,
162 modeTiming[idx].hSyncEnd,
163 modeTiming[idx].hTotal,
164 modeTiming[idx].vSyncStart,
165 modeTiming[idx].vSyncEnd,
166 modeTiming[idx].vTotal);
167}
168
169//Since we are only patching the first mode, this deprecated
170*x = modeTiming[idx + 1].hActive;
171*y = modeTiming[idx + 1].vActive;
172}
173
174if (table->id == SECOND_VESA_TABLE)
175{
176nvModeline_2 * modeTiming = (nvModeline_2 *) table->pointer;
177int h = *y;
178int w = *x;
179
180while (idx < table->modeCount)
181{
182*y = *x * h / w;
183//patch only different mode in table except console modes and 320 wide modes
184if (((*x != modeTiming[idx].hActive) || (*y != modeTiming[idx].vActive))
185&& (modeTiming[idx].hActive > 400))
186{
187
188PRINT("Mode %dx%d -> ", modeTiming[idx].hActive, modeTiming[idx].vActive);
189
190if (modeTiming[idx].hActive != *x)
191modeTiming[idx].hActive = *x;
192
193modeTiming[idx].vActive = *y;
194
195PRINT("%dx%d (%d %d %d %d ",
196 modeTiming[idx].hActive,
197 modeTiming[idx].vActive,
198 modeTiming[idx].hActive + modeTiming[idx].hSyncOffset,
199 modeTiming[idx].hActive + modeTiming[idx].hSyncOffset + modeTiming[idx].hSyncWidth,
200 modeTiming[idx].hActive + modeTiming[idx].hBlank,
201 modeTiming[idx].vActive + modeTiming[idx].vBlank);
202
203if ((modeTiming[idx].flags & HSyncPolarityMask) == HSyncPolarityMask)
204{PRINT("H- ");}
205else
206{PRINT("H+ ");}
207
208if ((modeTiming[idx].flags & VSyncPolarityMask) == VSyncPolarityMask)
209{PRINT("V-)\n");}
210else
211{PRINT("V+)\n");}
212}
213//returns the next mode in table
214*x = modeTiming[idx + 1].hActive;
215*y = modeTiming[idx + 1].vActive;
216
217idx++;
218}
219
220
221
222}
223return TRUE;
224}

Archive Download this file

Revision: 665