Chameleon

Chameleon Commit Details

Date:2010-09-01 06:26:42 (13 years 8 months ago)
Author:Azimutz
Commit:465
Parents: 464
Message:Adding extra files for AutoResolution patch. Edit libsaio/makefile accordingly; leaving "debug build" stuff out, it get's messy!
Changes:
A/branches/azimutz/Chazi/i386/libsaio/ati_resolution.c
A/branches/azimutz/Chazi/i386/libsaio/autoresolution.h
A/branches/azimutz/Chazi/i386/libsaio/nvidia_resolution.h
A/branches/azimutz/Chazi/i386/libsaio/gma.c
A/branches/azimutz/Chazi/i386/libsaio/ati_resolution.h
A/branches/azimutz/Chazi/i386/libsaio/edid.c
A/branches/azimutz/Chazi/i386/libsaio/gma_resolution.c
A/branches/azimutz/Chazi/i386/libsaio/gma.h
A/branches/azimutz/Chazi/i386/libsaio/edid.h
A/branches/azimutz/Chazi/i386/libsaio/autoresolution.c
A/branches/azimutz/Chazi/i386/libsaio/gma_resolution.h
A/branches/azimutz/Chazi/i386/libsaio/nvidia_resolution.c
M/branches/azimutz/Chazi/i386/libsaio/Makefile

File differences

branches/azimutz/Chazi/i386/libsaio/ati_resolution.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
* ati_resolution.c
*
*
* Created by Le Bidou on 19/03/10.
* Copyright 2010 ---. All rights reserved.
*
*/
#include "ati_resolution.h"
char detectAtiBiosType(sModeTable * table) {
return table->size % sizeof(atomModeTiming) == 0;
}
vBiosMap * openAtiVbios(vBiosMap * map, atiBiosTables atiTables)
{
/*
* Locate the Standard VESA Table
*/
atiTables.masterDataTables = (uint16_t *) &((atomMasterDataTable *) (map->biosPtr + atiTables.atomRomHeader->masterDataTableOffset))->listOfDataTables;
uint16_t stdVesaOffset = (uint16_t) ((atomMasterListOfDataTables *)atiTables.masterDataTables)->StandardVESA_Timing;
atomStandardVesaTiming * stdVesa = (atomStandardVesaTiming *) (map->biosPtr + stdVesaOffset);
// intialize the table chain with one element
sModeTable * table = intializeTables(map, 1);
table->pointer = (uint8_t *)stdVesa + sizeof(atomCommonTableHeader);
PRINT("Standard VESA Table at offset * 0x%x\n", (uint8_t)(table->pointer - map->biosPtr));
if (table->pointer == 0) {
PRINT("Unable to locate the mode table.\n");
PRINT("Please run the program 'dump_bios' as root and\n");
PRINT("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n");
closeVbios(map);
return 0;
}
//Determine Size of the Table
table->size = stdVesa->header.structureSize - sizeof(atomCommonTableHeader);
/*
* Find out type of table and how many entries it has
*/
if (!detectAtiBiosType(table)) map->bios = BT_ATI_2;
if (map->bios == BT_ATI_2) {
table->modeCount = table->size / sizeof(atomDtdFormat);
map->setMode = atiSetMode_2;
PRINT("Using DTD Format modelines\n");
} else {
table->modeCount = table->size / sizeof(atomModeTiming);
map->setMode = atiSetMode_1;
PRINT("Using Atom Mode Timing modelines\n");
}
saveTables(table);
return map;
}
bool atiSetMode_1(sModeTable * table, uint8_t idx, uint32_t * x, uint32_t * y)
{
atomModeTiming *modeTiming = (atomModeTiming *) table->pointer;
// patch only if mode differs
if ((*x != modeTiming[idx].hActive) || (*y != modeTiming[idx].vActive)) {
PRINT("Mode %dx%d -> ",modeTiming[idx].hActive, modeTiming[idx].vActive);
modeTiming[idx].hActive = *x;
modeTiming[idx].vActive = *y;
PRINT("%dx%d\n",modeTiming[idx].hActive, modeTiming[idx].vActive);
}
// since only the first mode in table is patched, this is deprecated
*x = modeTiming[idx + 1].hActive;
*y = modeTiming[idx + 1].vActive;
return TRUE;
}
bool atiSetMode_2(sModeTable * table, uint8_t idx, uint32_t* x, uint32_t* y)
{
atomDtdFormat *modeTiming = (atomDtdFormat *) table->pointer;
// patch only if mode differs
if ((*x != modeTiming[idx].hActive) || (*y != modeTiming[idx].vActive)) {
PRINT("Mode %dx%d -> ", modeTiming[idx].hActive, modeTiming[idx].vActive);
modeTiming[idx].hActive = *x;
modeTiming[idx].vActive = *y;
PRINT("%dx%d\n", modeTiming[idx].hActive, modeTiming[idx].vActive);
}
// since only the first mode in table is patched, this is deprecated
*x = modeTiming[idx + 1].hActive;
*y = modeTiming[idx + 1].hActive;
return TRUE;
}
branches/azimutz/Chazi/i386/libsaio/ati_resolution.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*
* ati_resolution.h
*
*
* Created by Le Bidou on 19/03/10.
* Copyright 2010 ---. All rights reserved.
*
*/
#ifndef _ATI_RESOLUTION_H_
#define _ATI_RESOLUTION_H_
#include "libsaio.h"
#include "autoresolution.h"
#define ATI_SIGNATURE1 "ATI MOBILITY RADEON"
#define ATI_SIGNATURE2 "ATI Technologies Inc"
/****************************************************************************/
/*Shortatombios.h parts: */
/*Portion I: Definitions shared between VBIOS and Driver */
/****************************************************************************/
#define ATOM_VERSION_MAJOR 0x00020000
#define ATOM_VERSION_MINOR 0x00000002
#define ATOM_HEADER_VERSION (ATOM_VERSION_MAJOR | ATOM_VERSION_MINOR)
#pragma pack(1) /* BIOS data must use byte aligment */
/* Define offset to location of ROM header. */
#define OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER0x00000048L
#define OFFSET_TO_ATOM_ROM_IMAGE_SIZE 0x00000002L
typedef struct
{
uint16_t structureSize;
uint8_t TableFormatRevision; /*Change it when the Parser is not backward compatible */
uint8_t TableContentRevision; /*Change it only when the table needs to change but the firmware */
/*Image can't be updated, while Driver needs to carry the new table! */
}atomCommonTableHeader;
typedef struct
{
atomCommonTableHeadersHeader;
uint8_t firmWareSignature[4]; /*Signature to distinguish between Atombios and non-atombios,
atombios should init it as "ATOM", don't change the position */
uint16_t biosRuntimeSegmentAddress;
uint16_t protectedModeInfoOffset;
uint16_t configFilenameOffset;
uint16_t cRcBlockOffset;
uint16_t BiosBootupMessageOffset;
uint16_t int10Offset;
uint16_t pciBusDevInitCode;
uint16_t ioBaseAddress;
uint16_t subsystemVendorID;
uint16_t subsystemID;
uint16_t pciInfoOffset;
uint16_t masterCommandTableOffset; /*Offset for SW to get all command table offsets, Don't change the position */
uint16_t masterDataTableOffset; /*Offset for SW to get all data table offsets, Don't change the position */
uint8_t extendedFunctionCode;
uint8_t reserved;
}atomRomHeader;
/****************************************************************************/
// Structure used in Data.mtb
/****************************************************************************/
typedef struct
{
uint16_t UtilityPipeLine; // Offest for the utility to get parser info,Don't change this position!
uint16_t MultimediaCapabilityInfo; // Only used by MM Lib,latest version 1.1, not configuable from Bios, need to include the table to build Bios
uint16_t MultimediaConfigInfo; // Only used by MM Lib,latest version 2.1, not configuable from Bios, need to include the table to build Bios
uint16_t StandardVESA_Timing; // Only used by Bios
uint16_t FirmwareInfo; // Shared by various SW components,latest version 1.4
uint16_t DAC_Info; // Will be obsolete from R600
uint16_t LVDS_Info; // Shared by various SW components,latest version 1.1
uint16_t TMDS_Info; // Will be obsolete from R600
uint16_t AnalogTV_Info; // Shared by various SW components,latest version 1.1
uint16_t SupportedDevicesInfo; // Will be obsolete from R600
uint16_t GPIO_I2C_Info; // Shared by various SW components,latest version 1.2 will be used from R600
uint16_t VRAM_UsageByFirmware; // Shared by various SW components,latest version 1.3 will be used from R600
uint16_t GPIO_Pin_LUT; // Shared by various SW components,latest version 1.1
uint16_t VESA_ToInternalModeLUT; // Only used by Bios
uint16_t ComponentVideoInfo; // Shared by various SW components,latest version 2.1 will be used from R600
uint16_t PowerPlayInfo; // Shared by various SW components,latest version 2.1,new design from R600
uint16_t CompassionateData; // Will be obsolete from R600
uint16_t SaveRestoreInfo; // Only used by Bios
uint16_t PPLL_SS_Info; // Shared by various SW components,latest version 1.2, used to call SS_Info, change to new name because of int ASIC SS info
uint16_t OemInfo; // Defined and used by external SW, should be obsolete soon
uint16_t XTMDS_Info; // Will be obsolete from R600
uint16_t MclkSS_Info; // Shared by various SW components,latest version 1.1, only enabled when ext SS chip is used
uint16_t Object_Header; // Shared by various SW components,latest version 1.1
uint16_t IndirectIOAccess; // Only used by Bios,this table position can't change at all!!
uint16_t MC_InitParameter; // Only used by command table
uint16_t ASIC_VDDC_Info;// Will be obsolete from R600
uint16_t ASIC_InternalSS_Info;// New tabel name from R600, used to be called "ASIC_MVDDC_Info"
uint16_t TV_VideoMode;// Only used by command table
uint16_t VRAM_Info;// Only used by command table, latest version 1.3
uint16_t MemoryTrainingInfo;// Used for VBIOS and Diag utility for memory training purpose since R600. the new table rev start from 2.1
uint16_t IntegratedSystemInfo;// Shared by various SW components
uint16_t ASIC_ProfilingInfo;// New table name from R600, used to be called "ASIC_VDDCI_Info" for pre-R600
uint16_t VoltageObjectInfo;// Shared by various SW components, latest version 1.1
uint16_tPowerSourceInfo;// Shared by various SW components, latest versoin 1.1
}atomMasterListOfDataTables;
typedef struct
{
atomCommonTableHeaderheader;
atomMasterListOfDataTableslistOfDataTables;
}atomMasterDataTable;
typedef union
{
uint16_t usAccess;
}atomModeMiscInfoAccess;
/****************************************************************************/
// Structure used in StandardVESA_TimingTable
// AnalogTV_InfoTable
// ComponentVideoInfoTable
/****************************************************************************/
typedef struct
{
uint16_t hTotal;
uint16_t hActive;
uint16_t hSyncStart;
uint16_t hSyncWidth;
uint16_t vTotal;
uint16_t vActive;
uint16_t vSyncStart;
uint16_t vSyncWidth;
uint16_t pixelClock; //in 10Khz unit
atomModeMiscInfoAccess modeMiscInfo;
uint16_t overscanRight;
uint16_t overscanLeft;
uint16_t overscanBottom;
uint16_t overscanTop;
uint16_t teserve;
uint8_t internalModeNumber;
uint8_t refreshRate;
}atomModeTiming;
typedef struct
{
uint16_t pixelClock;
uint16_t hActive;
uint16_t hBlank;
uint16_t vActive;
uint16_t vBlank;
uint16_t hSyncOffset;
uint16_t hSyncWidth;
uint16_t vSyncOffset;
uint16_t vSyncWidth;
uint16_t imageHSize;
uint16_t imageVSize;
uint8_t hBorder;
uint8_t vBorder;
atomModeMiscInfoAccess modeMiscInfo;
uint8_t internalModeNumber;
uint8_t refreshRate;
}atomDtdFormat;
/****************************************************************************/
/*Original ati_resolution.h parts: */
/****************************************************************************/
typedef struct
{
atomCommonTableHeader header;
uint8_t * modeTimings;
}atomStandardVesaTiming;
typedef struct
{
uint8_t *base;
atomRomHeader *atomRomHeader;
uint16_t *masterCommandTables;
uint16_t *masterDataTables;
} atiBiosTables;
char detectAtiBiosType(sModeTable * table);
vBiosMap * openAtiVbios(vBiosMap * map, atiBiosTables atiTables);
bool atiSetMode_1(sModeTable* map, uint8_t idx, uint32_t* x, uint32_t* y);
bool atiSetMode_2(sModeTable* map, uint8_t idx, uint32_t* x, uint32_t* y);
#endif
branches/azimutz/Chazi/i386/libsaio/Makefile
4242
4343
4444
45
46
45
46
47
48
4749
4850
4951
cpu.o platform.o acpi_patcher.o \
smbios_patcher.o fake_efi.o ext2fs.o \
hpet.o dram_controllers.o spd.o usb.o pci_setup.o \
device_inject.o nvidia.o ati.o pci_root.o \
convert.o mem.o aml_generator.o
device_inject.o nvidia.o ati.o gma.o \
gma_resolution.o ati_resolution.o nvidia_resolution.o \
pci_root.o convert.o mem.o aml_generator.o \
autoresolution.o edid.o
SAIO_EXTERN_OBJS = console.o
branches/azimutz/Chazi/i386/libsaio/gma.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
Original patch by nawcom -> http://forum.voodooprojects.org/index.php/topic,1029.msg4427.html#msg4427
*/
#include "libsaio.h"
#include "bootstruct.h"
#include "pci.h"
#include "platform.h"
#include "device_inject.h"
#include "gma.h"
#ifndef DEBUG_GMA
#define DEBUG_GMA 0
#endif
#if DEBUG_GMA
#define DBG(x...)printf(x)
#else
#define DBG(x...)
#endif
uint8_t GMAX3100_vals[22][4] = {
{ 0x01,0x00,0x00,0x00 },
{ 0x01,0x00,0x00,0x00 },
{ 0x01,0x00,0x00,0x00 },
{ 0x00,0x00,0x00,0x08 },
{ 0x64,0x00,0x00,0x00 },
{ 0x00,0x00,0x00,0x08 },
{ 0x01,0x00,0x00,0x00 },
{ 0x20,0x00,0x00,0x00 },
{ 0x00,0x00,0x00,0x00 },
{ 0x01,0x00,0x00,0x00 },
{ 0x20,0x03,0x00,0x00 },
{ 0x00,0x00,0x00,0x00 },
{ 0x00,0x00,0x00,0x00 },
{ 0x00,0x00,0x00,0x00 },
{ 0x08,0x52,0x00,0x00 },
{ 0x00,0x00,0x00,0x00 },
{ 0x00,0x00,0x00,0x00 },
{ 0x01,0x00,0x00,0x00 },
{ 0x01,0x00,0x00,0x00 },
{ 0x3B,0x00,0x00,0x00 },
{ 0x00,0x00,0x00,0x00 }
};
uint8_t reg_TRUE[] = { 0x01 ,0x00 ,0x00 ,0x00 };
uint8_t reg_FALSE[] = { 0x00,0x00,0x00,0x00 };
static struct gma_gpu_t KnownGPUS[] = {
{ 0x00000000, "Unknown" },
{ 0x808627A2, "Mobile GMA950" },
{ 0x808627AE, "Mobile GMA950" },
{ 0x808627A6, "Mobile GMA950" },
{ 0x80862772, "Desktop GMA950" },
{ 0x80862776, "Desktop GMA950" },
{ 0x80862A02, "GMAX3100" },
{ 0x80862A03, "GMAX3100" },
{ 0x80862A12, "GMAX3100" },
{ 0x80862A13, "GMAX3100" },
};
char *get_gma_model(uint32_t id) {
int i=0;
for(i = 0; i < (sizeof(KnownGPUS) / sizeof(KnownGPUS[0])); i++) {
if(KnownGPUS[i].device == id)
return KnownGPUS[i].name;
}
return KnownGPUS[0].name;
}
bool setup_gma_devprop(pci_dt_t *gma_dev)
{
//intlen;
char *devicepath;
volatile uint8_t *regs;
uint32_t bar[7];
char *model;
uint8_t BuiltIn = 0x00;
uint8_t ClassFix[4] = { 0x00, 0x00, 0x03, 0x00 };
devicepath = get_pci_dev_path(gma_dev);
bar[0] = pci_config_read32(gma_dev->dev.addr, 0x10);
regs = (uint8_t *) (bar[0] & ~0x0f);
model = get_gma_model((gma_dev->vendor_id << 16) | gma_dev->device_id);
verbose("Intel %s [%04x:%04x] :: %s\n",
model, gma_dev->vendor_id, gma_dev->device_id, devicepath);
if (!string)
string = devprop_create_string();
struct DevPropDevice *device = malloc(sizeof(struct DevPropDevice));
device = devprop_add_device(string, devicepath);
if(!device)
{
printf("Failed initializing dev-prop string dev-entry, press any key...\n");
getc();
return false;
}
devprop_add_value(device, "model", (uint8_t*)model, (strlen(model) + 1));
devprop_add_value(device, "device_type", (uint8_t*)"display", 8);
if (model == (char *)"Mobile GMA950") {
devprop_add_value(device, "AAPL,HasPanel", reg_TRUE, 4);
devprop_add_value(device, "built-in", &BuiltIn, 1);
devprop_add_value(device, "class-code", ClassFix, 4);
} else if (model == (char *)"Desktop GMA950") {
BuiltIn = 0x01;
devprop_add_value(device, "built-in", &BuiltIn, 1);
} else if (model == (char *)"GMAX3100") {
devprop_add_value(device, "AAPL,HasPanel",GMAX3100_vals[0], 4);
devprop_add_value(device, "AAPL,SelfRefreshSupported",GMAX3100_vals[1], 4);
devprop_add_value(device, "AAPL,aux-power-connected",GMAX3100_vals[2], 4);
devprop_add_value(device, "AAPL,backlight-control",GMAX3100_vals[3], 4);
devprop_add_value(device, "AAPL00,blackscreen-preferences",GMAX3100_vals[4], 4);
devprop_add_value(device, "AAPL01,BacklightIntensity",GMAX3100_vals[5], 4);
devprop_add_value(device, "AAPL01,blackscreen-preferences",GMAX3100_vals[6], 4);
devprop_add_value(device, "AAPL01,DataJustify",GMAX3100_vals[7], 4);
devprop_add_value(device, "AAPL01,Depth",GMAX3100_vals[8], 4);
devprop_add_value(device, "AAPL01,Dither",GMAX3100_vals[9], 4);
devprop_add_value(device, "AAPL01,DualLink",GMAX3100_vals[10], 4);
devprop_add_value(device, "AAPL01,Height",GMAX3100_vals[11], 4);
devprop_add_value(device, "AAPL01,Interlace",GMAX3100_vals[12], 4);
devprop_add_value(device, "AAPL01,Inverter",GMAX3100_vals[13], 4);
devprop_add_value(device, "AAPL01,InverterCurrent",GMAX3100_vals[14], 4);
devprop_add_value(device, "AAPL01,InverterCurrency",GMAX3100_vals[15], 4);
devprop_add_value(device, "AAPL01,LinkFormat",GMAX3100_vals[16], 4);
devprop_add_value(device, "AAPL01,LinkType",GMAX3100_vals[17], 4);
devprop_add_value(device, "AAPL01,Pipe",GMAX3100_vals[18], 4);
devprop_add_value(device, "AAPL01,PixelFormat",GMAX3100_vals[19], 4);
devprop_add_value(device, "AAPL01,Refresh",GMAX3100_vals[20], 4);
devprop_add_value(device, "AAPL01,Stretch",GMAX3100_vals[21], 4);
}
stringdata = malloc(sizeof(uint8_t) * string->length);
if(!stringdata)
{
printf("no stringdata press a key...\n");
getc();
return false;
}
memcpy(stringdata, (uint8_t*)devprop_generate_string(string), string->length);
stringlength = string->length;
return true;
}
branches/azimutz/Chazi/i386/libsaio/gma.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef __LIBSAIO_GMA_H
#define __LIBSAIO_GMA_H
bool setup_gma_devprop(pci_dt_t *gma_dev);
struct gma_gpu_t {
unsigned device;
char *name;
};
#define REG8(reg) ((volatile uint8_t *)regs)[(reg)]
#define REG16(reg) ((volatile uint16_t *)regs)[(reg) >> 1]
#define REG32(reg) ((volatile uint32_t *)regs)[(reg) >> 2]
#endif /* !__LIBSAIO_GMA_H */
branches/azimutz/Chazi/i386/libsaio/autoresolution.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
/* Copied from 915 resolution created by steve tomljenovic
*
* This code is based on the techniques used in :
*
* - 855patch. Many thanks to Christian Zietz (czietz gmx net)
* for demonstrating how to shadow the VBIOS into system RAM
* and then modify it.
*
* - 1280patch by Andrew Tipton (andrewtipton null li).
*
* - 855resolution by Alain Poirier
*
* This source code is into the public domain.
*/
#include "libsaio.h"
#include "autoresolution.h"
#include "nvidia_resolution.h"
#include "ati_resolution.h"
#include "gma_resolution.h"
#include "../boot2/graphics.h"
char * chipsetTypeNames[] = {
"UNKNOWN", "830", "845G", "855GM", "865G", "915G", "915GM", "945G", "945GM", "945GME",
"946GZ", "955X", "G965", "Q965", "965GM", "975X",
"P35", "X48", "B43", "Q45", "P45", "GM45", "G41", "G31", "G45", "500"
};
uint32_t getChipsetId(void)
{
outl(0xcf8, 0x80000000);
return inl(0xcfc);
}
chipsetType getChipset(uint32_t id)
{
chipsetType type;
switch (id)
{
case 0x35758086:
type = CT_830;
break;
case 0x25608086:
type = CT_845G;
break;
case 0x35808086:
type = CT_855GM;
break;
case 0x25708086:
type = CT_865G;
break;
case 0x25808086:
type = CT_915G;
break;
case 0x25908086:
type = CT_915GM;
break;
case 0x27708086:
type = CT_945G;
break;
case 0x27748086:
type = CT_955X;
break;
case 0x277c8086:
type = CT_975X;
break;
case 0x27a08086:
type = CT_945GM;
break;
case 0x27ac8086:
type = CT_945GME;
break;
case 0x29708086:
type = CT_946GZ;
break;
case 0x29a08086:
type = CT_G965;
break;
case 0x29908086:
type = CT_Q965;
break;
case 0x2a008086:
type = CT_965GM;
break;
case 0x29e08086:
type = CT_X48;
break;
case 0x2a408086:
type = CT_GM45;
break;
case 0x2e108086:
case 0X2e908086:
type = CT_B43;
break;
case 0x2e208086:
type = CT_P45;
break;
case 0x2e308086:
type = CT_G41;
break;
case 0x29c08086:
type = CT_G31;
break;
case 0x29208086:
type = CT_G45;
break;
case 0x81008086:
type = CT_500;
break;
default:
type = CT_UNKWN;
break;
}
return type;
}
void gtfTimings(uint32_t x, uint32_t y, uint32_t freq,
uint32_t *clock,
uint16_t *hSyncStart, uint16_t *hSyncEnd, uint16_t *hBlank,
uint16_t *vSyncStart, uint16_t *vSyncEnd, uint16_t *vBlank)
{
uint32_t hbl, vbl, vfreq;
vbl = y + (y+1)/(20000/(11*freq) - 1) + 1;
vfreq = vbl * freq;
hbl = 16 * (int)(x * (30 - 300000 / vfreq) /
+ (70 + 300000 / vfreq) / 16 + 0);
*vSyncStart = y;
*vSyncEnd = y + 3;
*vBlank = vbl;
*hSyncStart = x + hbl / 2 - (x + hbl + 50) / 100 * 8 ;
*hSyncEnd = x + hbl / 2;
*hBlank = x + hbl;
*clock = (x + hbl) * vfreq / 1000;
}
void getAspectRatio(sAspect* aspect, uint32_t x, uint32_t y)
{
if ((y * 16 / 9) == x)
{
aspect->width = 16;
aspect->height = 9;
}
else if ((y * 16 / 10) == x)
{
aspect->width = 16;
aspect->height = 10;
}
else if ((y * 5 / 4) == x)
{
aspect->width = 5;
aspect->height = 4;
}
else if ((y * 15 / 9) == x)
{
aspect->width = 15;
aspect->height = 9;
}
else
{
aspect->width = 4;
aspect->height = 3;
}
PRINT("Aspect Ratio is %d/%d\n", aspect->width, aspect->height);
}
/*
* initialize the mode tables chain
* tablesCount represents the number of VESA tables in the vBios
* return value is a pointer to the first table
*/
sModeTable * intializeTables(vBiosMap * map, int tablesCount) {
map->modeTables = (sModeTable *)malloc(sizeof(sModeTable));
sModeTable * table = map->modeTables;
PRINT("Creating %d Mode Tables\n", tablesCount);
int i = tablesCount;
while ( i != 0 )
{
table->id = tablesCount - i;
PRINT("New table with id : %d\n", table->id);
// opening the chain if it's the first table
if (i == tablesCount)
table->prev = NULL;
else // attache the table to the chain
table->prev = table;
//if there is more than one table, alloc the next one
if (i > 1)
{
table->next = (sModeTable *)malloc(sizeof(sModeTable));
table = table->next;
}
else // no more table, close the chain
table->next = NULL;
i--;
}
return map->modeTables;
}
void closeVbios(vBiosMap * map);
vBiosMap * openVbios(chipsetType forcedChipset)
{
uint32_t z;
vBiosMap * map = NEW(vBiosMap);
for(z = 0; z < sizeof(vBiosMap); z++)
((char*)map)[z] = 0;
/*
* Determine chipset
*/
if (forcedChipset == CT_UNKWN)
{
map->chipsetId = getChipsetId();
map->chipset = getChipset(map->chipsetId);
PRINT("Chipset is %s (pci id 0x%x)\n",chipsetTypeNames[map->chipset], map->chipsetId);
}
else if (forcedChipset != CT_UNKWN)
{
map->chipset = forcedChipset;
}
else
{
map->chipset = CT_915GM;
}
/*
* Map the video bios to memory
*/
map->biosPtr=(uint8_t*)VBIOS_START;
/*
* Common initialisation
*/
map->hasSwitched = false;
/*
* check if we have ATI Radeon and open atombios
*/
atiBiosTables atiTables;
atiTables.base = map->biosPtr;
atiTables.atomRomHeader = (atomRomHeader *) (map->biosPtr + *(uint16_t *) (map->biosPtr + OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER));
if (strcmp ((char *) atiTables.atomRomHeader->firmWareSignature, "ATOM") == 0)
{
map->bios = BT_ATI_1;
PRINT("We have an AtomBios Card\n");
return openAtiVbios(map, atiTables);
}
/*
* check if we have NVidia
*/
if (map->bios != BT_ATI_1)
{
int i = 0;
while (i < 512) // we don't need to look through the whole bios, just the first 512 bytes
{
if ((map->biosPtr[i] == 'N')
&& (map->biosPtr[i+1] == 'V')
&& (map->biosPtr[i+2] == 'I')
&& (map->biosPtr[i+3] == 'D'))
{
map->bios = BT_NVDA;
PRINT("We have an NVIDIA Card\n");
return openNvidiaVbios(map);
break;
}
i++;
}
}
/*
* check if we have Intel
*/
if ((map->bios != BT_ATI_1) && (map->bios != BT_NVDA))
{
int i = 0;
while (i < VBIOS_SIZE)
{
if ((map->biosPtr[i] == 'I')
&& (map->biosPtr[i+1] == 'n')
&& (map->biosPtr[i+2] == 't')
&& (map->biosPtr[i+3] == 'e')
&& (map->biosPtr[i+4] == 'l'))
{
map->bios = BT_1;
PRINT("We have an Intel Card\n");
saveVbios(map);
return openIntelVbios(map);
break;
}
i++;
}
}
/*
* Unidentified Chipset
*/
if ( (map->chipset == CT_UNKWN) || ((map->bios != BT_ATI_1) && (map->bios != BT_NVDA) && (map->bios != BT_1)) )
{
PRINT("Unknown chipset type and unrecognized bios.\n");
PRINT("autoresolution only works with Intel 800/900 series graphic chipsets.\n");
PRINT("Chipset Id: %x\n", map->chipsetId);
closeVbios(map);
return 0;
}
/*
* Should never get there
*/
return 0;
}
void closeVbios(vBiosMap * map)
{
PRINT("Closing VBios\n");
//make sure to turn autoResolution off
if (gAutoResolution == TRUE)
gAutoResolution = FALSE;
// if we saved the vBios, free the copy
if (map->biosBackupPtr != NULL)
{
PRINT("Freeing biosBackupPtr\t");
FREE(map->biosBackupPtr);
PRINT("[OK]\n");
}
// free table backups if any
sModeTable * table = map->modeTables;
while (table != NULL)
{
if (table->backup != NULL)
{
PRINT("Table #%d : Freeing backup\t", table->id);
FREE(table->backup);
PRINT("[OK]\n");
}
if (table != NULL)
{
PRINT("Table #%d : Freeing\t\t", table->id);
FREE(table);
PRINT("[OK]\n");
}
if (table->next == NULL)
break;
table = table->next;
}
PRINT("Freeing map\t\t\t");
FREE(map);
PRINT("[OK]\n");
}
void unlockVbios(vBiosMap * map)
{
map->unlocked = TRUE;
switch (map->chipset)
{
case CT_UNKWN:
break;
case CT_830:
case CT_855GM:
outl(0xcf8, 0x8000005a);
map->b1 = inb(0xcfe);
outl(0xcf8, 0x8000005a);
outb(0xcfe, 0x33);
break;
case CT_845G:
case CT_865G:
case CT_915G:
case CT_915GM:
case CT_945G:
case CT_945GM:
case CT_945GME:
case CT_946GZ:
case CT_955X:
case CT_G965:
case CT_Q965:
case CT_965GM:
case CT_975X:
case CT_P35:
case CT_X48:
case CT_B43:
case CT_Q45:
case CT_P45:
case CT_GM45:
case CT_G41:
case CT_G31:
case CT_G45:
case CT_500:
outl(0xcf8, 0x80000090);
map->b1 = inb(0xcfd);
map->b2 = inb(0xcfe);
outl(0xcf8, 0x80000090);
outb(0xcfd, 0x33);
outb(0xcfe, 0x33);
break;
}
#if DEBUG
{
uint32_t t = inl(0xcfc);
PRINT("unlock PAM: (0x%08x)\n", t);
}
#endif
}
void relockVbios(vBiosMap * map)
{
map->unlocked = FALSE;
switch (map->chipset)
{
case CT_UNKWN:
break;
case CT_830:
case CT_855GM:
outl(0xcf8, 0x8000005a);
outb(0xcfe, map->b1);
break;
case CT_845G:
case CT_865G:
case CT_915G:
case CT_915GM:
case CT_945G:
case CT_945GM:
case CT_945GME:
case CT_946GZ:
case CT_955X:
case CT_G965:
case CT_Q965:
case CT_965GM:
case CT_975X:
case CT_P35:
case CT_X48:
case CT_B43:
case CT_Q45:
case CT_P45:
case CT_GM45:
case CT_G41:
case CT_G31:
case CT_G45:
case CT_500:
outl(0xcf8, 0x80000090);
outb(0xcfd, map->b1);
outb(0xcfe, map->b2);
break;
}
#if DEBUG
{
uint32_t t = inl(0xcfc);
PRINT("relock PAM: (0x%08x)\n", t);
}
#endif
}
/*
* saveVbios - save the entire vBios in case the patch has to be removed
*/
void saveVbios(vBiosMap * map)
{
map->biosBackupPtr = malloc(VBIOS_SIZE);
bcopy((const uint8_t *)0xC0000, map->biosBackupPtr, VBIOS_SIZE);
}
/*
* restoreVbios - restore the vBios backup or table backups if any
*/
void restoreVbios(vBiosMap * map)
{
if ((map->bios == BT_ATI_1) || (map->bios == BT_ATI_2) || (map->bios == BT_NVDA))
{
restoreTables(map, map->modeTables);
}
else
{
unlockVbios(map);
bcopy(map->biosBackupPtr,(uint8_t *)0xC0000, VBIOS_SIZE);
relockVbios(map);
}
}
/*
* saveTables - save the tables in case the patch has to be removed
*/
void saveTables(sModeTable * table)
{
while (table != NULL)
{
table->backup = (uint8_t *)malloc(table->size);
bcopy((const uint8_t *)table->pointer, table->backup, table->size);
table = table->next;
}
}
/*
* restoreTables - restore tables backup
*/
void restoreTables(vBiosMap * map, sModeTable * table)
{
unlockVbios(map);
while (table != NULL)
{
bcopy(table->backup, (uint8_t *)table->pointer, table->size);
table = table->next;
}
relockVbios(map);
}
/*
* patchVbios - call the vendor specific function to patch the VESA tables
* x & y are horizontal and vertical dimensions respectively, in pixels
* for GMA and ATI, only first mode in Table is patched
*
* each vendor specific function have the same form :
* bool vendorSetMode_type(sModeTable * table, uint8_t index, uint32_t * x, uint32_t * y);
* where 'table' is the VESA table to patch, 'index' is the index of the mode in table,
* 'x' & 'y' are pointer to the target resolution and return the next resolution in table.
*/
void patchVbios(vBiosMap * map, uint32_t x, uint32_t y, uint32_t bp, uint32_t hTotal, uint32_t vTotal)
{
uint32_t i = 0;
sModeTable * table = map->modeTables;
// save the target resolution for future use
map->currentX = x;
map->currentY = y;
unlockVbios(map);
// Get the aspect ratio for the requested mode
getAspectRatio(&map->aspectRatio, x, y);
i = 0;
// Call the vendor specific function for each available VESA Table
table = map->modeTables;
while (table != NULL)
{
//reset resolution value before treating a new table
x = map->currentX;
y = map->currentY;
PRINT("Patching Table #%d : \n", table->id);
map->setMode(table, i, &x, &y);
#ifdef AUTORES_DEBUG
getc();
#endif
table = table->next;
}
relockVbios(map);
return;
}
branches/azimutz/Chazi/i386/libsaio/autoresolution.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* Copied from 915 resolution created by steve tomljenovic
*
* This code is based on the techniques used in :
*
* - 855patch. Many thanks to Christian Zietz (czietz gmx net)
* for demonstrating how to shadow the VBIOS into system RAM
* and then modify it.
*
* - 1280patch by Andrew Tipton (andrewtipton null li).
*
* - 855resolution by Alain Poirier
*
* This source code is into the public domain.
*/
#ifndef __915_RESOLUTION_H
#define __915_RESOLUTION_H
#include "edid.h"
#if DEBUG
#ifndef AUTORES_DEBUG
#define AUTORES_DEBUG
#endif
#endif
#ifdef AUTORES_DEBUG
#define PRINT(a, b...) printf(a, ##b);
#else
#define PRINT(a, b...) verbose(a, ##b);
#endif
#define __packed __attribute__((packed))
#define NEW(a) ((a *)(malloc(sizeof(a))))
#define FREE(a) (free(a))
#define VBIOS_START 0xc0000
#define VBIOS_SIZE 0x10000
#define FALSE 0
#define TRUE 1
bool gAutoResolution;
typedef struct
{
uint8_t width;
uint8_t height;
} sAspect;
typedef enum
{
CT_UNKWN, CT_830, CT_845G, CT_855GM, CT_865G,
CT_915G, CT_915GM, CT_945G, CT_945GM, CT_945GME, CT_946GZ,
CT_955X, CT_G965, CT_Q965, CT_965GM, CT_975X,
CT_P35, CT_X48, CT_B43, CT_Q45, CT_P45,
CT_GM45, CT_G41, CT_G31, CT_G45, CT_500
} chipsetType;
typedef enum
{
BT_UNKWN, BT_1, BT_2, BT_3, BT_ATI_1, BT_ATI_2, BT_NVDA
} biosType;
typedef struct
{
uint32_tclock;
uint16_tx;
uint16_thSyncStart;
uint16_thSyncEnd;
uint16_thTotal;
uint16_ty;
uint16_tvSyncStart;
uint16_tvSyncEnd;
uint16_tvTotal;
} generic_modeline;
typedef struct sModeTable_
{
uint8_t*pointer;
uint8_tid;
uint32_tsize;
uint32_tmodeCount;
uint8_t *backup;
struct sModeTable_ *prev;
struct sModeTable_ *next;
} sModeTable;
typedef struct
{
uint32_t chipsetId;
chipsetType chipset;
biosType bios;
uint8_t* biosBackupPtr;
uint8_t* biosPtr;
sModeTable *modeTables;
uint32_t currentX, currentY;
uint8_t b1, b2;
bool hasSwitched;
bool (*setMode)(sModeTable *,uint8_t,uint32_t*,uint32_t*);
sAspect aspectRatio;
uint8_t unlocked;
} vBiosMap;
vBiosMap *map;
vBiosMap * openVbios(chipsetType type);
void closeVbios (vBiosMap* map);
void unlockVbios(vBiosMap* map);
void relockVbios(vBiosMap* map);
void saveVbios(vBiosMap* map);
void restoreVbios(vBiosMap* map);
void saveTables(sModeTable * table);
void restoreTables(vBiosMap * map, sModeTable * table);
void gtfTimings(uint32_t x, uint32_t y, uint32_t freq,
uint32_t *clock,
uint16_t *hSyncStart, uint16_t *hSyncEnd, uint16_t *hBlank,
uint16_t *vSyncStart, uint16_t *vSyncEnd, uint16_t *vBlank);
sModeTable * intializeTables(vBiosMap * map, int tablesCount);
void patchVbios(vBiosMap* map, uint32_t x, uint32_t y, uint32_t bp, uint32_t hTotal, uint32_t vTotal);
#endif
branches/azimutz/Chazi/i386/libsaio/nvidia_resolution.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/*
* nvidia_resolution.c
*
*
* Created by Le Bidou on 19/03/10.
* Copyright 2010 ---. All rights reserved.
*
*/
#include "nvidia_resolution.h"
vBiosMap * openNvidiaVbios(vBiosMap *map)
{
unsigned short nvDataTableOffset = 0;
unsigned short nvModeline_2_Offset = 0;
unsigned short * nvDataTable = NULL;
nvVesaTable * stdVesa;
// initialize the table chain with two elements
sModeTable * table = intializeTables(map, 2);
/*
* Locate the VESA Tables
*/
int i = 0;
//First VESA Table
while (i < 0x300) //We don't need to look for the table in the whole bios, the 768 first bytes only
{
if ((map->biosPtr[i] == 0x44)
&& (map->biosPtr[i+1] == 0x01)
&& (map->biosPtr[i+2] == 0x04)
&& (map->biosPtr[i+3] == 0x00)) {
nvDataTableOffset = (unsigned short) (map->biosPtr[i+4] | (map->biosPtr[i+5] << 8));
break;
}
i++;
}
nvDataTable = (unsigned short *) (map->biosPtr + (nvDataTableOffset + OFFSET_TO_VESA_TABLE_INDEX));
stdVesa = (nvVesaTable *) (map->biosPtr + *nvDataTable);
table->pointer = (uint8_t *) stdVesa + sizeof(nvCommonTableHeader);
printf("First Standard VESA Table at offset 0x%x\n",(unsigned int) (table->pointer - map->biosPtr));
//Second VESA Table
while (i < VBIOS_SIZE) //We don't know how to locate it other way
{
if ((map->biosPtr[i] == 0x40) && (map->biosPtr[i+1] == 0x01) //this is the first 320x200 modeline.
&& (map->biosPtr[i+2] == 0xC8) && (map->biosPtr[i+3] == 0x00)
&& (map->biosPtr[i+4] == 0x28)
&& (map->biosPtr[i+5] == 0x18)
&& (map->biosPtr[i+6] == 0x08)
&& (map->biosPtr[i+7] == 0x08))
{
nvModeline_2_Offset = (unsigned short) i;
break;
}
i++;
}
if (nvModeline_2_Offset == (VBIOS_SIZE-1) || nvModeline_2_Offset == 0)
{
//If no second vesa table is available, free the corresponding table in chain
free(table->next);
table->next = NULL;
PRINT("There is no Second Standard VESA Table to patch\n");
}
else
{
table = table->next;
table->pointer = map->biosPtr + nvModeline_2_Offset;
PRINT("Second Standard VESA Table at offset 0x%x\n", (unsigned int)(table->pointer - map->biosPtr));
}
if (table->prev->pointer == NULL)
{
PRINT("Unable to locate the mode table.\n");
PRINT("Please run the program 'dumpBios' as root and\n");
PRINT("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n");
closeVbios(map);
return 0;
}
// reset the table pointer to the first in chain
table = map->modeTables;
/*
* for each table in chain, figure out how many modes are available
* and what is the size of the table
*/
while (table != NULL)
{
table->modeCount = 0;
PRINT("Table #%d has ", table->id);
if (table->id == MAIN_VESA_TABLE)
{
table->modeCount = stdVesa->header.tableSize & 0xff;
if (table->modeCount == 0) table->modeCount = 16;
table->size = table->modeCount * sizeof(nvModeline);
}
if (table->id == SECOND_VESA_TABLE)
{
nvModeline_2 * modePtr = (nvModeline_2 *)table->pointer;
while (1)
{
if (modePtr[table->modeCount].hActive > 2048) break;
table->modeCount++;
}
if (table->modeCount == 0) table->modeCount = 31;
table->size = table->modeCount * sizeof(nvModeline_2);
}
PRINT("%d modes\n", table->modeCount);
table = table->next;
}
map->setMode = nvidiaSetMode;
saveTables(map->modeTables);
#ifdef AUTORES_DEBUG
PRINT("Press Any Key...\n");
getc();
#endif
return map;
}
bool nvidiaSetMode(sModeTable * table, uint8_t idx, uint32_t* x, uint32_t* y)
{
//In First VESA table, only first mode in table is patched
if (table->id == MAIN_VESA_TABLE)
{
nvModeline * modeTiming = (nvModeline *)table->pointer;
// patch only if mode differs and if the mode to patch isn't a console mode
if (((*x != modeTiming[idx].hActive) || (*y != modeTiming[idx].vActive))
&& (modeTiming[idx].hActive > 100))
{
PRINT("Mode %dx%d -> ", modeTiming[idx].hActive, modeTiming[idx].vActive);
if (modeTiming[idx].hActive != *x)
{
modeTiming[idx].hActive = *x;
modeTiming[idx].hActiveMinusOne = *x - 1;
modeTiming[idx].hActiveMinusOne_ = *x - 1;
}
modeTiming[idx].vActive = *y;
modeTiming[idx].vActiveMinusOne = *y - 1;
modeTiming[idx].vActiveMinusOne_ = *y - 1;
PRINT("%dx%d (%d %d %d %d %d %d)\n",
modeTiming[idx].hActive,
modeTiming[idx].vActive,
modeTiming[idx].hSyncStart,
modeTiming[idx].hSyncEnd,
modeTiming[idx].hTotal,
modeTiming[idx].vSyncStart,
modeTiming[idx].vSyncEnd,
modeTiming[idx].vTotal);
}
//Since we are only patching the first mode, this deprecated
*x = modeTiming[idx + 1].hActive;
*y = modeTiming[idx + 1].vActive;
}
if (table->id == SECOND_VESA_TABLE)
{
nvModeline_2 * modeTiming = (nvModeline_2 *) table->pointer;
int h = *y;
int w = *x;
while (idx < table->modeCount)
{
*y = *x * h / w;
//patch only different mode in table except console modes and 320 wide modes
if (((*x != modeTiming[idx].hActive) || (*y != modeTiming[idx].vActive))
&& (modeTiming[idx].hActive > 400))
{
PRINT("Mode %dx%d -> ", modeTiming[idx].hActive, modeTiming[idx].vActive);
if (modeTiming[idx].hActive != *x)
modeTiming[idx].hActive = *x;
modeTiming[idx].vActive = *y;
PRINT("%dx%d (%d %d %d %d ",
modeTiming[idx].hActive,
modeTiming[idx].vActive,
modeTiming[idx].hActive + modeTiming[idx].hSyncOffset,
modeTiming[idx].hActive + modeTiming[idx].hSyncOffset + modeTiming[idx].hSyncWidth,
modeTiming[idx].hActive + modeTiming[idx].hBlank,
modeTiming[idx].vActive + modeTiming[idx].vBlank);
if ((modeTiming[idx].flags & HSyncPolarityMask) == HSyncPolarityMask)
{PRINT("H- ");}
else
{PRINT("H+ ");}
if ((modeTiming[idx].flags & VSyncPolarityMask) == VSyncPolarityMask)
{PRINT("V-)\n");}
else
{PRINT("V+)\n");}
}
//returns the next mode in table
*x = modeTiming[idx + 1].hActive;
*y = modeTiming[idx + 1].vActive;
idx++;
}
}
return TRUE;
}
branches/azimutz/Chazi/i386/libsaio/nvidia_resolution.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/*
* nviviaresolution.h
*
*
* Created by Le Bidou on 19/03/10.
* Copyright 2010 ---. All rights reserved.
*
*/
#ifndef _NVDA_RESOLUTION_HEADER_
#define _NVDA_RESOLUTION_HEADER_
#include "libsaio.h"
#include "autoresolution.h"
#define NVIDIA_SIGNATURE "NVIDIA Corp"
#define OFFSET_TO_VESA_TABLE_INDEX 2
#define MAIN_VESA_TABLE 0
#define SECOND_VESA_TABLE 1
#define HSyncPolarityMask0x4
#define VSyncPolarityMask0x2
#define isGraphicsModeMask0x1
typedef struct {
unsigned chartableMajor; //These names are probably wrong
unsigned chartableMinor;
unsigned chartableRev;
unsigned shorttableSize;
}__packed nvCommonTableHeader;
typedef struct {
unsigned shortclock;
unsigned shorthActive;
unsigned short hActiveMinusOne;
unsigned shortreserved1;
unsigned short hActiveMinusOne_;
unsigned shorthSyncStart;
unsigned shorthSyncEnd;
unsigned shorthTotal;
unsigned shortvActive;
unsigned short vActiveMinusOne;
unsigned shortreserved2;
unsigned short vActiveMinusOne_;
unsigned shortvSyncStart;
unsigned shortvSyncEnd;
unsigned shortvTotal;
unsigned shortreserved3;
}__packed nvModeline;
typedef struct {
unsigned short hActive;
unsigned short vActive;
unsigned char hBlank;
unsigned char hSyncOffset;
unsigned char hSyncWidth;
unsigned char vBlank;
//unsigned char vSyncwidth;
unsigned char flags; //looks like flags & 1 means "Graphics Mode", to oppose to "Console Mode"
//on 7xxx the high four bits look like a mode id number.
//on 8xxx only the low four bits are used, standard graphics mode are always 5.
//it can be 1 (1400x1050 and 2048x1536) (HSync High, VSync High ?)
// 3 (1440x900, 1680x1050 and 1920x1200) (HSync High, VSync Low ?)
// 5 (Standard Timings) (HSync Low, VSync High ?)
// or 7 (1280x800 and 768x340) (HSync Low, VSync Low ?)
}__packed nvModeline_2;
typedef struct {
nvCommonTableHeaderheader;
nvModeline*modelines;
}__packed nvVesaTable;
vBiosMap * openNvidiaVbios(vBiosMap *map);
bool nvidiaSetMode(sModeTable* table, uint8_t idx, uint32_t* x, uint32_t* y);
#endif
branches/azimutz/Chazi/i386/libsaio/edid.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
* edid.c
*
*
* Created by Evan Lojewski on 12/1/09.
* Copyright 2009. All rights reserved.
*
*/
#include "libsaio.h"
#include "edid.h"
#include "vbe.h"
#include "bootstruct.h"
#include "graphics.h"
#include "boot.h"
//static biosBuf_t bb;
UInt32 xResolution = 0;
UInt32 yResolution = 0;
UInt32 bpResolution = 0;
void getResolution(UInt32* params)
{
unsigned char* edidInfo = readEDID();
if(!edidInfo) {
xResolution = 1024;
yResolution = 768;
bpResolution = 32;
free( edidInfo );
} else {
// TODO: check *all* resolutions reported and eithe ruse the highest, or the native resolution (if there is a flag for that)
xResolution = edidInfo[56] | ((edidInfo[58] & 0xF0) << 4);
yResolution = edidInfo[59] | ((edidInfo[61] & 0xF0) << 4);
bpResolution = 32;// assume 32bits
free( edidInfo );
// Mode Sanity check
if ((xResolution < 1024) || !yResolution || !xResolution)
{
xResolution = 1024;
yResolution = 768;
}
params[0] = xResolution;
params[1] = yResolution;
params[2] = bpResolution;
}
}
unsigned char* readEDID()
{
SInt16 last_reported = -1;
UInt8 edidInfo[EDID_BLOCK_SIZE];
//UInt8 pointer;
UInt8 header1[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
UInt8 header2[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
int status;
unsigned int blocks_left = 1;
do
{
// TODO: This currently only retrieves the *last* block, make the block buffer expand as needed / calculated from the first block
bzero( edidInfo, EDID_BLOCK_SIZE);
status = getEDID(edidInfo, blocks_left);
//printf("Buffer location: 0x%X\n", SEG(buffer) << 16 | OFF(buffer));
/*
int j, i;
for (j = 0; j < 8; j++) {
for(i = 0; i < 16; i++) printf("0x%X ", ebiosInfo[((i+1) * (j + 1)) - 1]);
}
printf("\n");
*/
if(status == 0)
{
//if( edidInfo[0] == 0x00 || edidInfo[0] == 0xFF)
if((memcmp(edidInfo, header1, sizeof(header1)) != 0) ||
(memcmp(edidInfo, header2, sizeof(header2)) != 0) )
{
blocks_left--;
int reported = edidInfo[ EDID_V1_BLOCKS_TO_GO_OFFSET ];
if ( reported > blocks_left )
{
printf("EDID claims %d more blocks left\n", reported);
}
if ( (last_reported <= reported && last_reported != -1)
|| reported == 0xff
/* 0xff frequently comes up in corrupt edids */
//|| reported == MAGIC
)
{
printf("Last reported %d\n", last_reported);
printf( "EDID blocks left is wrong.\n"
"Your EDID is probably invalid.\n");
return 0;
}
else
{
//printf("Reading EDID block\n");
//printf("H Active = %d", ebiosInfo[56] | ((ebiosInfo[58] & 0xF0) << 4) );
//printf("V Active = %d", ebiosInfo[59] | ((ebiosInfo[61] & 0xF0) << 4) );
last_reported = reported;
blocks_left = reported;
}
}
else
{
printf("Invalid block %d\n", blocks_left);
printf("Header1 = %d", memcmp(edidInfo, header1, sizeof(header1)) );
printf("Header2 = %d", memcmp(edidInfo, header2, sizeof(header2)) );
return 0;
}
} else {
return 0;
}
blocks_left = 0;
} while(blocks_left);
UInt8* ret = malloc(sizeof(edidInfo));
memcpy(ret, edidInfo, sizeof(edidInfo));
return (ret);
}
branches/azimutz/Chazi/i386/libsaio/edid.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*
* edid.h
*
*
* Created by Evan Lojewski on 12/1/09.
* Copyright 2009. All rights reserved.
*
*/
#ifndef _EDID_H
#define _EDID_H
#define EDID_BLOCK_SIZE128
#define EDID_V1_BLOCKS_TO_GO_OFFSET 126
#define SERVICE_REPORT_DDC0
#define SERVICE_READ_EDID1
#define SERVICE_LAST1 // Read VDIF has been removed from the spec.
#define FUNC_GET_EDID0x4F15
typedef struct _edid_mode {
unsigned short pixel_clock;
unsigned short h_active;
unsigned short h_blanking;
unsigned short v_active;
unsigned short v_blanking;
unsigned short h_sync_offset;
unsigned short h_sync_width;
unsigned short v_sync_offset;
unsigned short v_sync_width;
}edid_mode;
unsigned char* readEDID();
void getResolution(UInt32* params);
#endif
branches/azimutz/Chazi/i386/libsaio/gma_resolution.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
/*
* gmaResolution.c
*
*
* Created by Le Bidou on 19/03/10.
* Copyright 2010 ---. All rights reserved.
*
*/
#include "gma_resolution.h"
char * biosTypeNames[] = {"UNKNOWN", "TYPE 1", "TYPE 2", "TYPE 3"};
int freqs[] = { 60, 75, 85 };
vbiosResolutionType1 * mapType1Resolution(vBiosMap * map, uint16_t res)
{
vbiosResolutionType1 * ptr = ((vbiosResolutionType1*)(map->biosPtr + res));
return ptr;
}
vbiosResolutionType2 * mapType2Resolution(vBiosMap * map, uint16_t res)
{
vbiosResolutionType2 * ptr = ((vbiosResolutionType2*)(map->biosPtr + res));
return ptr;
}
vbiosResolutionType3 * mapType3Resolution(vBiosMap * map, uint16_t res)
{
vbiosResolutionType3 * ptr = ((vbiosResolutionType3*)(map->biosPtr + res));
return ptr;
}
char detectBiosType(vBiosMap * map, char modeline, int entrySize)
{
uint32_t i;
uint16_t r1, r2;
vbiosMode * modeTable = (vbiosMode *)map->modeTables->pointer;
r1 = r2 = 32000;
for (i=0; i < map->modeTables->size; i++)
{
if (modeTable[i].resolution <= r1)
r1 = modeTable[i].resolution;
else if (modeTable[i].resolution <= r2)
r2 = modeTable[i].resolution;
}
return (r2-r1-6) % entrySize == 0;
}
vBiosMap * openIntelVbios(vBiosMap *map)
{
/*
* Find the location of the Mode Table
*/
unsigned char* p = map->biosPtr + 16;
unsigned char* limit = map->biosPtr + VBIOS_SIZE - (3 * sizeof(vbiosMode));
// initialize the table chain with one element
sModeTable * table = intializeTables(map, 1);
while (p < limit && table->pointer == 0)
{
vbiosMode* modePtr = (vbiosMode*) p;
if (((modePtr[0].mode & 0xf0) == 0x30) && ((modePtr[1].mode & 0xf0) == 0x30) &&
((modePtr[2].mode & 0xf0) == 0x30) && ((modePtr[3].mode & 0xf0) == 0x30))
{
table->pointer = (uint8_t *)modePtr;
}
p++;
}
if (table->pointer == 0)
{
PRINT("Unable to locate the mode table.\n");
PRINT("Please run the program 'dump_bios' as root and\n");
PRINT("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n");
closeVbios(map);
return 0;
}
PRINT("Mode Table at offset : 0x%x\n", (table->pointer) - map->biosPtr);
/*
* Determine size of mode table
*/
vbiosMode * modePtr = (vbiosMode *)table->pointer;
while (modePtr->mode != 0xff)
{
table->size++;
modePtr++;
}
table->modeCount = table->size;
PRINT("Mode Table size : %d\n", table->modeCount);
/*
* Figure out what type of bios we have
* order of detection is important
*/
if (detectBiosType(map, TRUE, sizeof(vbiosModelineType3)))
{
map->bios = BT_3;
map->setMode = intelSetMode_3;
PRINT("Bios Type : BT_3\n");
}
else if (detectBiosType(map, TRUE, sizeof(vbiosModelineType2)))
{
map->bios = BT_2;
map->setMode = intelSetMode_2;
PRINT("Bios Type : BT_2\n");
}
else if (detectBiosType(map, FALSE, sizeof(vbiosResolutionType1)))
{
map->bios = BT_1;
map->setMode = intelSetMode_1;
PRINT("Bios Type : BT_1\n");
}
else
{
PRINT("Unable to determine bios type.\n");
PRINT("Please run the program 'dump_bios' as root and\n");
PRINT("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n");
return 0;
}
return map;
}
bool intelSetMode_1(sModeTable * table, uint8_t idx, uint32_t* x, uint32_t* y)
{
vbiosMode *modeTiming = (vbiosMode *) table->pointer;
vbiosResolutionType1 * res = mapType1Resolution(map, modeTiming[idx].resolution);
//retreive the original mode's dimensions
uint32_t actualX = ((res->hActive2 & 0xf0) << 4) | (res->hActive1 & 0xff);
uint32_t actualY = ((res->vActive2 & 0xf0) << 4) | (res->vActive1 & 0xff);
// patch only if mode differs
if ((*x != actualX) || (*y != actualY))
{
PRINT("Mode %dx%d -> ", actualX, actualY);
res->hActive2 = (res->hActive2 & 0x0f) | ((*x >> 4) & 0xf0);
res->hActive1 = (*x & 0xff);
res->vActive2 = (res->hActive2 & 0x0f) | ((*y >> 4) & 0xf0);
res->vActive1 = (*y & 0xff);
uint32_t actualX = ((res->hActive2 & 0xf0) << 4) | (res->hActive1 & 0xff);
uint32_t actualY = ((res->vActive2 & 0xf0) << 4) | (res->vActive1 & 0xff);
PRINT("%dx%d \n", actualX, actualY);
}
//since only the first mode is patched, this is deprecated
res = mapType1Resolution(map, modeTiming[idx + 1].resolution);
actualX = ((res->hActive2 & 0xf0) << 4) | (res->hActive1 & 0xff);
actualY = ((res->vActive2 & 0xf0) << 4) | (res->vActive1 & 0xff);
*x = actualX;
*y = actualY;
return true;
}
bool intelSetMode_2(sModeTable * table, uint8_t idx, uint32_t* x, uint32_t* y)
{
uint32_t xprev, yprev, j = 0;
vbiosMode *modeTiming = (vbiosMode *) table->pointer;
vbiosResolutionType2 * res = mapType2Resolution(map, modeTiming[idx].resolution);
//patch only if mode differs
if ((*x != (res->modelines[0].hActive1 + 1))
||(*y != (res->modelines[0].vActive1 + 1)) )
{
PRINT("Mode %dx%d -> ", res->modelines[0].hActive1 + 1, res->modelines[0].vActive1 + 1);
res->xChars = *x / 8;
res->yChars = *y / 16 - 1;
xprev = res->modelines[0].hActive1;
yprev = res->modelines[0].vActive1;
// recalculate timigs for all frequencies and patch
for(j = 0; j < 3; j++)
{
vbiosModelineType2 * mode = &res->modelines[j];
if (mode->hActive1 == xprev && mode->vActive1 == yprev)
{
mode->hActive1 = mode->hActive2 = *x - 1;
mode->vActive1 = mode->vActive2 = *y - 1;
gtfTimings(*x, *y, freqs[j], &mode->clock,
&mode->hSyncStart, &mode->hSyncEnd,
&mode->hBlank, &mode->vSyncStart,
&mode->vSyncEnd, &mode->vBlank);
mode->hTotal = mode->hBlank;
mode->vTotal = mode->vBlank;
}
}
PRINT("%dx%d\n", res->modelines[0].hActive1 + 1, res->modelines[0].vActive1 + 1);
}
//since only the first mode is patched, this is deprecated
res = mapType2Resolution(map, modeTiming[idx + 1].resolution);
*x = res->modelines[0].hActive1 + 1;
*y = res->modelines[0].vActive1 + 1;
return true;
}
bool intelSetMode_3(sModeTable * table, uint8_t idx, uint32_t* x, uint32_t* y)
{
uint32_t xprev, yprev, j = 0;
vbiosMode *modeTiming = (vbiosMode *) table->pointer;
vbiosResolutionType3 * res = mapType3Resolution(map, modeTiming[idx].resolution);
// patch only if mode differs
if ((*x != (res->modelines[0].hActive1 + 1))
||(*y != (res->modelines[0].vActive1 + 1)) )
{
PRINT("Mode %dx%d -> ", res->modelines[0].hActive1 + 1, res->modelines[0].vActive1 + 1);
xprev = res->modelines[0].hActive1;
yprev = res->modelines[0].vActive1;
// recalculate timings for all frequencies and patch
for(j = 0; j < 3; j++) {
vbiosModelineType3 * mode = &res->modelines[j];
if (mode->hActive1 == xprev && mode->vActive1 == yprev)
{
mode->hActive1 = mode->hActive2 = *x - 1;
mode->vActive1 = mode->vActive2 = *y - 1;
gtfTimings(*x, *y, freqs[j], &mode->clock,
&mode->hSyncStart, &mode->hSyncEnd,
&mode->hBlank, &mode->vSyncStart,
&mode->vSyncEnd, &mode->vBlank);
mode->hTotal = mode->hBlank;
mode->vTotal = mode->vBlank;
mode->timingH = *y-1;
mode->timingV = *x-1;
}
}
PRINT("%dx%d\n", res->modelines[0].hActive1 + 1, res->modelines[0].vActive1 + 1);
}
//since only the first mode is patched, this is deprecated
res = mapType3Resolution(map, modeTiming[idx + 1].resolution);
*x = res->modelines[0].hActive1 + 1;
*y = res->modelines[0].vActive1 + 1;
return true;
}
branches/azimutz/Chazi/i386/libsaio/gma_resolution.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
* gma_resolution.h
*
*
* Created by Le Bidou on 19/03/10.
* Copyright 2010 ---. All rights reserved.
*
*/
#ifndef _GMA_RESOLUTION_H_
#define _GMA_RESOLTUION_H_
#include "libsaio.h"
#include "autoresolution.h"
#define MODE_TABLE_OFFSET_845G 617
#define INTEL_SIGNATURE "Intel Corp"
typedef struct {
uint8_t mode;
uint8_t bitsPerPixel;
uint16_t resolution;
uint8_t unknown;
} __packed vbiosMode;
typedef struct {
uint8_t unknow1[2];
uint8_t hActive1;
uint8_t xTotal;
uint8_t hActive2;
uint8_t vActive1;
uint8_t yTotal;
uint8_t vActive2;
} __packed vbiosResolutionType1;
typedef struct {
uint32_t clock;
uint16_t hActive1;
uint16_t hTotal;
uint16_t hActive2;
uint16_t hBlank;
uint16_t hSyncStart;
uint16_t hSyncEnd;
uint16_t vActive1;
uint16_t vTotal;
uint16_t vActive2;
uint16_t vBlank;
uint16_t vSyncStart;
uint16_t vSyncEnd;
} __packed vbiosModelineType2;
typedef struct {
uint8_t xChars;
uint8_t yChars;
uint8_t unknown[4];
vbiosModelineType2 modelines[];
} __packed vbiosResolutionType2;
typedef struct {
uint32_t clock;
uint16_t hActive1;
uint16_t hTotal;
uint16_t hActive2;
uint16_t hBlank;
uint16_t hSyncStart;
uint16_t hSyncEnd;
uint16_t vActive1;
uint16_t vTotal;
uint16_t vActive2;
uint16_t vBlank;
uint16_t vSyncStart;
uint16_t vSyncEnd;
uint16_t timingH;
uint16_t timingV;
uint8_t unknown[6];
} __packed vbiosModelineType3;
typedef struct {
unsigned char unknown[6];
vbiosModelineType3 modelines[];
} __packed vbiosResolutionType3;
vbiosResolutionType1 * mapType1Resolution(vBiosMap * map, uint16_t res);
vbiosResolutionType2 * mapType2Resolution(vBiosMap * map, uint16_t res);
vbiosResolutionType3 * mapType3Resolution(vBiosMap * map, uint16_t res);
char detectBiosType(vBiosMap * map, char modeline, int entrySize);
vBiosMap * openIntelVbios(vBiosMap *);
bool intelSetMode_1(sModeTable* table, uint8_t idx, uint32_t* x, uint32_t* y);
bool intelSetMode_2(sModeTable* table, uint8_t idx, uint32_t* x, uint32_t* y);
bool intelSetMode_3(sModeTable* table, uint8_t idx, uint32_t* x, uint32_t* y);
#endif

Archive Download the corresponding diff file

Revision: 465