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 detect_ati_bios_type(vbios_map * map) {␉␊ |
13 | ␉return map->mode_table_size % sizeof(ATOM_MODE_TIMING) == 0;␊ |
14 | }␊ |
15 | ␊ |
16 | vbios_map * open_ati_vbios(vbios_map * map, bios_tables_t ati_tables)␊ |
17 | {␊ |
18 | ␉/*␊ |
19 | ␉ * Locate the Standard VESA Table␊ |
20 | ␉ */␊ |
21 | ␉␊ |
22 | ␉ati_tables.MasterDataTables = (unsigned short *) &((ATOM_MASTER_DATA_TABLE *) (map->bios_ptr + ati_tables.AtomRomHeader->usMasterDataTableOffset))->ListOfDataTables;␊ |
23 | ␉unsigned short std_vesa_offset = (unsigned short) ((ATOM_MASTER_LIST_OF_DATA_TABLES *)ati_tables.MasterDataTables)->StandardVESA_Timing;␊ |
24 | ␉ATOM_STANDARD_VESA_TIMING * std_vesa = (ATOM_STANDARD_VESA_TIMING *) (map->bios_ptr + std_vesa_offset);␊ |
25 | ␉␊ |
26 | ␉map->mode_table = (char *) &std_vesa->aModeTimings;␊ |
27 | ␉verbose("Standard VESA Table at offset * 0x%x\n", std_vesa_offset);␊ |
28 | ␉if (map->mode_table == 0) {␊ |
29 | ␉␉verbose("Unable to locate the mode table.\n");␊ |
30 | ␉␉verbose("Please run the program 'dump_bios' as root and\n");␊ |
31 | ␉␉verbose("email the file 'vbios.dmp' to gaeloulacuisse@yahoo.fr.\n");␊ |
32 | ␉␉␊ |
33 | ␉␉close_vbios(map);␊ |
34 | ␉␉return 0;␊ |
35 | ␉}␊ |
36 | ␉␊ |
37 | ␉//Determine Size of the Table␊ |
38 | ␉map->mode_table_size = std_vesa->sHeader.usStructureSize - sizeof(ATOM_COMMON_TABLE_HEADER);␊ |
39 | ␉␊ |
40 | ␉/*␊ |
41 | ␉ * Find out type of table and how many entries it has␊ |
42 | ␉ */␊ |
43 | ␉␊ |
44 | ␉if (!detect_ati_bios_type(map)) map->bios = BT_ATI_2;␊ |
45 | ␉if (map->bios == BT_ATI_2) {␊ |
46 | ␉␉map->modeline_num = map->mode_table_size / sizeof(ATOM_DTD_FORMAT);␊ |
47 | ␉␉verbose("Using DTD Format modelines\n");␊ |
48 | ␉} else {␊ |
49 | ␉␉map->modeline_num = map->mode_table_size / sizeof(ATOM_MODE_TIMING);␊ |
50 | ␉␉verbose("Using Atom Mode Timing modelines\n");␊ |
51 | ␉}␊ |
52 | ␉return map;␊ |
53 | }␊ |
54 | ␊ |
55 | bool ati_set_mode_1(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y)␊ |
56 | {␊ |
57 | ␉ATOM_MODE_TIMING *mode_timing = (ATOM_MODE_TIMING *) map->mode_table;␊ |
58 | ␉␊ |
59 | ␉if ((*x != 0) && (*y != 0) && ( mode_timing[idx].usCRTC_H_Disp >= 640 )) {␊ |
60 | ␉␉␊ |
61 | ␉␉verbose("Mode %dx%d -> %dx%d\n",mode_timing[idx].usCRTC_H_Disp,mode_timing[idx].usCRTC_V_Disp,␊ |
62 | ␉␉␉ *x, *y);␊ |
63 | ␉␉␊ |
64 | ␉␉mode_timing[idx].usCRTC_H_Disp = *x;␊ |
65 | ␉␉mode_timing[idx].usCRTC_V_Disp = *y;␊ |
66 | ␉}␊ |
67 | ␉␊ |
68 | ␉*x = mode_timing[idx + 1].usCRTC_H_Disp;␊ |
69 | ␉*y = mode_timing[idx + 1].usCRTC_V_Disp;␊ |
70 | ␉␊ |
71 | ␉return TRUE;␊ |
72 | }␊ |
73 | ␊ |
74 | bool ati_set_mode_2(vbios_map* map, UInt8 idx, UInt32* x, UInt32* y)␊ |
75 | {␊ |
76 | ␉ATOM_DTD_FORMAT *mode_timing = (ATOM_DTD_FORMAT *) map->mode_table;␊ |
77 | ␉␊ |
78 | ␉if ((*x != 0) && (*y != 0) && ( mode_timing[idx].usHActive >= 640 )) {␊ |
79 | ␉␉␊ |
80 | ␉␉verbose("Mode %dx%d -> %dx%d\n", mode_timing[idx].usHActive, mode_timing[idx].usHActive,␊ |
81 | ␉␉␉ *x, *y);␊ |
82 | ␉␉␊ |
83 | ␉␉mode_timing[idx].usHActive = *x;␊ |
84 | ␉␉mode_timing[idx].usVActive = *y;␊ |
85 | ␉}␊ |
86 | ␉␊ |
87 | ␉*x = mode_timing[idx + 1].usHActive;␊ |
88 | ␉*y = mode_timing[idx + 1].usVActive;␊ |
89 | ␉␊ |
90 | ␉return TRUE;␊ |
91 | }␊ |
92 | |