Chameleon

Chameleon Svn Source Tree

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

Source at commit 133 created 10 years 10 months ago.
By diebuche, Futher fixes..
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
12vbios_map * open_nvidia_vbios(vbios_map *map)
13{
14unsigned short nv_data_table_offset = 0;
15unsigned short nv_modeline_2_offset = 0;
16unsigned short * nv_data_table = NULL;
17NV_VESA_TABLE * std_vesa;
18
19/*
20 * Locate the VESA Tables
21 */
22
23int i = 0;
24
25while (i < 0x300) { //We don't need to look for the table in the whole bios, the 768 first bytes only
26if ((map->bios_ptr[i] == 0x44)
27&& (map->bios_ptr[i+1] == 0x01)
28&& (map->bios_ptr[i+2] == 0x04)
29&& (map->bios_ptr[i+3] == 0x00)) {
30nv_data_table_offset = (unsigned short) (map->bios_ptr[i+4] | (map->bios_ptr[i+5] << 8));
31break;
32}
33i++;
34}
35//Second VESA Table on some nVidia 8xxx 9xxx and GT
36while (i < VBIOS_SIZE) { //We don't know how to locate it other way
37if ((map->bios_ptr[i] == 0x40) && (map->bios_ptr[i+1] == 0x01) //this is the first 320x200 modeline.
38&& (map->bios_ptr[i+2] == 0xC8) && (map->bios_ptr[i+3] == 0x00)
39&& (map->bios_ptr[i+4] == 0x28)
40&& (map->bios_ptr[i+5] == 0x18)
41&& (map->bios_ptr[i+6] == 0x08)
42&& (map->bios_ptr[i+7] == 0x08)) {
43nv_modeline_2_offset = (unsigned short) i;
44break;
45}
46i++;
47}
48
49nv_data_table = (unsigned short *) (map->bios_ptr + (nv_data_table_offset + OFFSET_TO_VESA_TABLE_INDEX));
50std_vesa = (NV_VESA_TABLE *) (map->bios_ptr + *nv_data_table);
51map->mode_table = (char *) std_vesa->sModelines;
52verbose("First Standard VESA Table at offset 0x%x\n", *nv_data_table);
53
54if (nv_modeline_2_offset == (VBIOS_SIZE-1) || nv_modeline_2_offset == 0) {
55map->nv_mode_table_2 = NULL;
56verbose("There is no Second Standard VESA Table to patch\n");
57} else {
58map->nv_mode_table_2 = (char*) map->bios_ptr + nv_modeline_2_offset;
59verbose("Second Standard VESA Table at offset 0x%x\n", nv_modeline_2_offset);
60}
61
62if (map->mode_table == NULL) {
63verbose("Unable to locate the mode table.\n");
64verbose("Please run the program 'dump_bios' as root and\n");
65verbose("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n");
66
67close_vbios(map);
68return 0;
69}
70
71//This won't be used as there is no garanty this is right
72map->mode_table_size = std_vesa->sHeader.usTable_Size;
73/*
74 * Determine how many modes and tables sizes
75 */
76
77NV_MODELINE *mode_ptr =(NV_MODELINE *)map->mode_table;
78NV_MODELINE_2 *mode_2_ptr =(NV_MODELINE_2 *)map->nv_mode_table_2;
79map->modeline_num = map->nv_modeline_num_2 = 0;
80
81//First Table
82while ((mode_ptr[map->modeline_num].reserved3 & 0xff) == 0xff)
83map->modeline_num++;
84
85verbose("First VESA Table has %d modes\n",map->modeline_num);
86if (map->modeline_num == 0) {
87verbose("%d is incorrect, make it a 16\n",map->modeline_num);
88map->modeline_num = 16;
89}
90map->mode_table_size = map->modeline_num * sizeof(NV_MODELINE);
91
92//Second Table
93while (mode_2_ptr[map->nv_modeline_num_2].h_disp <= 0x800)
94map->nv_modeline_num_2++;
95
96printf("Second VESA Table has %d modes\n",map->nv_modeline_num_2);
97if (map->nv_modeline_num_2 == 0) {
98verbose("%d is incorrect, make it a 32\n",map->nv_modeline_num_2);
99map->nv_modeline_num_2 = 32;
100}
101map->nv_mode_table_2_size = map->nv_modeline_num_2 * sizeof(NV_MODELINE_2);
102
103return map;
104}
105
106bool nvidia_set_mode(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y, char Type)
107{
108if (Type == MAIN_VESA_TABLE) {
109NV_MODELINE * mode_timing = (NV_MODELINE *) map->mode_table;
110
111if ((mode_timing[idx].reserved3 & 0xff) != 0xff) return FALSE;
112
113if ((*x != 0) && (*y != 0) && ( mode_timing[idx].usH_Active >= 640 )) {
114
115verbose("Mode %dx%d -> %dx%d ", mode_timing[idx].usH_Active, mode_timing[idx].usV_Active,
116*x, *y);
117
118generic_modeline modeline;
119
120cvt_timings(*x, *y, 60, &modeline.clock,
121&modeline.hsyncstart, &modeline.hsyncend,
122&modeline.htotal, &modeline.vsyncstart,
123&modeline.vsyncend, &modeline.vtotal, FALSE);
124
125mode_timing[idx].usH_Active = *x;
126mode_timing[idx].usH_Active_minus_One = *x - 1;
127mode_timing[idx].usH_Active_minus_One_ = *x - 1;
128
129mode_timing[idx].usV_Active = *y;
130mode_timing[idx].usV_Active_minus_One = *y - 1;
131mode_timing[idx].usV_Active_minus_One_ = *y - 1;
132
133mode_timing[idx].usH_Total = modeline.htotal;
134mode_timing[idx].usH_SyncStart = modeline.hsyncstart;
135mode_timing[idx].usH_SyncEnd = modeline.hsyncend;
136
137mode_timing[idx].usV_Total = modeline.vtotal;
138mode_timing[idx].usV_SyncStart = modeline.vsyncstart;
139mode_timing[idx].usV_SyncEnd = modeline.vsyncend;
140
141mode_timing[idx].usPixel_Clock = modeline.clock;
142}
143
144*x = mode_timing[idx + 1].usH_Active;
145*y = mode_timing[idx + 1].usV_Active;
146}
147
148if (Type == SECOND_VESA_TABLE) {
149NV_MODELINE_2 * mode_timing = (NV_MODELINE_2 *) map->nv_mode_table_2;
150
151if (mode_timing[idx].h_disp > 0x800) return FALSE;
152
153if ((*x != 0) && (*y != 0) && ( mode_timing[idx].h_disp >= 640 )) {
154
155verbose("Mode %dx%d -> %dx%d ", mode_timing[idx].h_disp, mode_timing[idx].v_disp,
156*x, *y);
157
158generic_modeline modeline;
159
160cvt_timings(*x, *y, 60, &modeline.clock,
161&modeline.hsyncstart, &modeline.hsyncend,
162&modeline.htotal, &modeline.vsyncstart,
163&modeline.vsyncend, &modeline.vtotal, TRUE);
164
165mode_timing[idx].h_disp = *x;
166mode_timing[idx].v_disp = *y;
167mode_timing[idx].h_blank = modeline.htotal - *x;
168mode_timing[idx].h_syncoffset = modeline.hsyncstart - *x;
169mode_timing[idx].h_syncwidth = modeline.hsyncend - modeline.hsyncstart;
170mode_timing[idx].v_blank = modeline.vtotal - *y;
171}
172
173*x = mode_timing[idx + 1].h_disp;
174*y = mode_timing[idx + 1].v_disp;
175}
176return TRUE;
177}
178

Archive Download this file

Revision: 133