1 | /*␊ |
2 | * ati_resolution.c␊ |
3 | * ␊ |
4 | *␊ |
5 | * Created by Le Bidou on 19/03/10.␊ |
6 | * Copyright 2010 ---. All rights reserved.␊ |
7 | *␊ |
8 | */␊ |
9 | ␊ |
10 | #include "ati_resolution.h"␊ |
11 | ␊ |
12 | char detectAtiBiosType(sModeTable * table) {␉␊ |
13 | ␉return table->size % sizeof(atomModeTiming) == 0;␊ |
14 | }␊ |
15 | ␊ |
16 | ␊ |
17 | ␊ |
18 | vBiosMap * openAtiVbios(vBiosMap * map, atiBiosTables atiTables)␊ |
19 | {␊ |
20 | ␉/*␊ |
21 | ␉ * Locate the Standard VESA Table␊ |
22 | ␉ */␊ |
23 | ␉␊ |
24 | ␉atiTables.masterDataTables = (uint16_t *) &((atomMasterDataTable *) (map->biosPtr + atiTables.atomRomHeader->masterDataTableOffset))->listOfDataTables;␊ |
25 | ␉uint16_t stdVesaOffset = (uint16_t) ((atomMasterListOfDataTables *)atiTables.masterDataTables)->StandardVESA_Timing;␊ |
26 | ␉atomStandardVesaTiming * stdVesa = (atomStandardVesaTiming *) (map->biosPtr + stdVesaOffset);␊ |
27 | ␉␊ |
28 | ␉// intialize the table chain with one element␊ |
29 | ␉sModeTable * table = intializeTables(map, 1);␊ |
30 | ␉␉␊ |
31 | ␉table->pointer = (uint8_t *)stdVesa + sizeof(atomCommonTableHeader);␊ |
32 | ␉PRINT("Standard VESA Table at offset * 0x%x\n", (uint8_t)(table->pointer - map->biosPtr));␊ |
33 | ␉if (table->pointer == 0) {␊ |
34 | ␉␉PRINT("Unable to locate the mode table.\n");␊ |
35 | ␉␉PRINT("Please run the program 'dump_bios' as root and\n");␊ |
36 | ␉␉PRINT("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n");␊ |
37 | ␉␉␊ |
38 | ␉␉closeVbios(map);␊ |
39 | ␉␉return 0;␊ |
40 | ␉}␊ |
41 | ␉␊ |
42 | ␉//Determine Size of the Table␊ |
43 | ␉table->size = stdVesa->header.structureSize - sizeof(atomCommonTableHeader);␊ |
44 | ␉␊ |
45 | ␉/*␊ |
46 | ␉ * Find out type of table and how many entries it has␊ |
47 | ␉ */␊ |
48 | ␉␊ |
49 | ␉if (!detectAtiBiosType(table)) map->bios = BT_ATI_2;␊ |
50 | ␉if (map->bios == BT_ATI_2) {␊ |
51 | ␉␉table->modeCount = table->size / sizeof(atomDtdFormat);␊ |
52 | ␉␉map->setMode = atiSetMode_2;␊ |
53 | ␉␉PRINT("Using DTD Format modelines\n");␊ |
54 | ␉} else {␊ |
55 | ␉␉table->modeCount = table->size / sizeof(atomModeTiming);␊ |
56 | ␉␉map->setMode = atiSetMode_1;␊ |
57 | ␉␉PRINT("Using Atom Mode Timing modelines\n");␊ |
58 | ␉}␊ |
59 | ␉saveTables(table);␊ |
60 | ␉return map;␊ |
61 | }␊ |
62 | ␊ |
63 | bool atiSetMode_1(sModeTable * table, uint8_t idx, uint32_t * x, uint32_t * y)␊ |
64 | {␊ |
65 | ␉atomModeTiming *modeTiming = (atomModeTiming *) table->pointer;␊ |
66 | ␉␊ |
67 | ␉// patch only if mode differs␊ |
68 | ␉if ((*x != modeTiming[idx].hActive) || (*y != modeTiming[idx].vActive)) {␊ |
69 | ␉␉PRINT("Mode %dx%d -> ",modeTiming[idx].hActive, modeTiming[idx].vActive);␊ |
70 | ␉␉␊ |
71 | ␉␉modeTiming[idx].hActive = *x;␊ |
72 | ␉␉modeTiming[idx].vActive = *y;␊ |
73 | ␉␉␊ |
74 | ␉␉PRINT("%dx%d\n",modeTiming[idx].hActive, modeTiming[idx].vActive);␊ |
75 | ␉}␊ |
76 | ␉␊ |
77 | ␉// since only the first mode in table is patched, this is deprecated␊ |
78 | ␉*x = modeTiming[idx + 1].hActive;␊ |
79 | ␉*y = modeTiming[idx + 1].vActive;␊ |
80 | ␉␊ |
81 | ␉return true;␊ |
82 | }␊ |
83 | ␊ |
84 | bool atiSetMode_2(sModeTable * table, uint8_t idx, uint32_t* x, uint32_t* y)␊ |
85 | {␊ |
86 | ␉atomDtdFormat *modeTiming = (atomDtdFormat *) table->pointer;␊ |
87 | ␉␊ |
88 | ␉// patch only if mode differs␊ |
89 | ␉if ((*x != modeTiming[idx].hActive) || (*y != modeTiming[idx].vActive)) {␊ |
90 | ␉␉␊ |
91 | ␉␉PRINT("Mode %dx%d -> ", modeTiming[idx].hActive, modeTiming[idx].vActive);␊ |
92 | ␉␉␊ |
93 | ␉␉modeTiming[idx].hActive = *x;␊ |
94 | ␉␉modeTiming[idx].vActive = *y;␊ |
95 | ␉␉␊ |
96 | ␉␉PRINT("%dx%d\n", modeTiming[idx].hActive, modeTiming[idx].vActive);␊ |
97 | ␉}␊ |
98 | ␉␊ |
99 | ␉// since only the first mode in table is patched, this is deprecated␊ |
100 | ␉*x = modeTiming[idx + 1].hActive;␊ |
101 | ␉*y = modeTiming[idx + 1].hActive;␊ |
102 | ␉␊ |
103 | ␉return true;␊ |
104 | }␊ |
105 | |