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
60if (nvModeline_2_Offset == (VBIOS_SIZE-1) || nvModeline_2_Offset == 0)
61{
62//If no second vesa table is available, free the corresponding table in chain
63free(table->next);
64table->next = NULL;
65PRINT("There is no Second Standard VESA Table to patch\n");
66}
67else
68{
69table = table->next;
70table->pointer = map->biosPtr + nvModeline_2_Offset;
71PRINT("Second Standard VESA Table at offset 0x%x\n", (unsigned int)(table->pointer - map->biosPtr));
72}
73
74if (table->prev->pointer == NULL)
75{
76PRINT("Unable to locate the mode table.\n");
77PRINT("Please run the program 'dumpBios' as root and\n");
78PRINT("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n");
79
80closeVbios(map);
81return 0;
82}
83
84// reset the table pointer to the first in chain
85table = map->modeTables;
86
87/*
88 * for each table in chain, figure out how many modes are available
89 * and what is the size of the table
90 */
91while (table != NULL)
92{
93table->modeCount = 0;
94PRINT("Table #%d has ", table->id);
95
96if (table->id == MAIN_VESA_TABLE)
97{
98table->modeCount = stdVesa->header.tableSize & 0xff;
99if (table->modeCount == 0) table->modeCount = 16;
100table->size = table->modeCount * sizeof(nvModeline);
101}
102
103if (table->id == SECOND_VESA_TABLE)
104{
105nvModeline_2 * modePtr = (nvModeline_2 *)table->pointer;
106while (1)
107{
108if (modePtr[table->modeCount].hActive > 2048) break;
109table->modeCount++;
110}
111if (table->modeCount == 0) table->modeCount = 31;
112table->size = table->modeCount * sizeof(nvModeline_2);
113}
114
115PRINT("%d modes\n", table->modeCount);
116table = table->next;
117}
118
119map->setMode = nvidiaSetMode;
120
121saveTables(map->modeTables);
122
123#ifdef AUTORES_DEBUG
124getc();
125#endif
126
127return map;
128}
129
130bool nvidiaSetMode(sModeTable * table, uint8_t idx, uint32_t* x, uint32_t* y)
131{
132//In First VESA table, only first mode in table is patched
133if (table->id == MAIN_VESA_TABLE)
134{
135nvModeline * modeTiming = (nvModeline *)table->pointer;
136
137// patch only if mode differs and if the mode to patch isn't a console mode
138if (((*x != modeTiming[idx].hActive) || (*y != modeTiming[idx].vActive))
139&& (modeTiming[idx].hActive > 100))
140{
141
142PRINT("Mode %dx%d -> ", modeTiming[idx].hActive, modeTiming[idx].vActive);
143
144if (modeTiming[idx].hActive != *x)
145{
146modeTiming[idx].hActive = *x;
147modeTiming[idx].hActiveMinusOne = *x - 1;
148modeTiming[idx].hActiveMinusOne_ = *x - 1;
149}
150
151modeTiming[idx].vActive = *y;
152modeTiming[idx].vActiveMinusOne = *y - 1;
153modeTiming[idx].vActiveMinusOne_ = *y - 1;
154
155PRINT("%dx%d (%d %d %d %d %d %d)\n",
156 modeTiming[idx].hActive,
157 modeTiming[idx].vActive,
158 modeTiming[idx].hSyncStart,
159 modeTiming[idx].hSyncEnd,
160 modeTiming[idx].hTotal,
161 modeTiming[idx].vSyncStart,
162 modeTiming[idx].vSyncEnd,
163 modeTiming[idx].vTotal);
164}
165
166//Since we are only patching the first mode, this deprecated
167*x = modeTiming[idx + 1].hActive;
168*y = modeTiming[idx + 1].vActive;
169}
170
171if (table->id == SECOND_VESA_TABLE)
172{
173nvModeline_2 * modeTiming = (nvModeline_2 *) table->pointer;
174int h = *y;
175int w = *x;
176
177while (idx < table->modeCount)
178{
179*y = *x * h / w;
180//patch only different mode in table except console modes and 320 wide modes
181if (((*x != modeTiming[idx].hActive) || (*y != modeTiming[idx].vActive))
182&& (modeTiming[idx].hActive > 400))
183{
184
185PRINT("Mode %dx%d -> ", modeTiming[idx].hActive, modeTiming[idx].vActive);
186
187if (modeTiming[idx].hActive != *x)
188modeTiming[idx].hActive = *x;
189
190modeTiming[idx].vActive = *y;
191
192PRINT("%dx%d (%d %d %d %d ",
193 modeTiming[idx].hActive,
194 modeTiming[idx].vActive,
195 modeTiming[idx].hActive + modeTiming[idx].hSyncOffset,
196 modeTiming[idx].hActive + modeTiming[idx].hSyncOffset + modeTiming[idx].hSyncWidth,
197 modeTiming[idx].hActive + modeTiming[idx].hBlank,
198 modeTiming[idx].vActive + modeTiming[idx].vBlank);
199
200if ((modeTiming[idx].flags & HSyncPolarityMask) == HSyncPolarityMask)
201{PRINT("H- ");}
202else
203{PRINT("H+ ");}
204
205if ((modeTiming[idx].flags & VSyncPolarityMask) == VSyncPolarityMask)
206{PRINT("V-)\n");}
207else
208{PRINT("V+)\n");}
209}
210//returns the next mode in table
211*x = modeTiming[idx + 1].hActive;
212*y = modeTiming[idx + 1].vActive;
213
214idx++;
215}
216}
217return TRUE;
218}
219

Archive Download this file

Revision: 701