Root/
Source at commit 307 created 12 years 11 months ago. By ifabio, merge changes from trunk (929). Also merge the module changes from Azimutz branche (fix compile error) Also edited the info.plist into AHCIPortInjector.kext: http://forum.voodooprojects.org/index.php/topic,1170.0.html | |
---|---|
1 | /*␊ |
2 | * edid.c␊ |
3 | * ␊ |
4 | *␊ |
5 | * Created by Evan Lojewski on 12/1/09.␊ |
6 | * Copyright 2009. All rights reserved.␊ |
7 | *␊ |
8 | */␊ |
9 | ␊ |
10 | ␊ |
11 | #include "edid.h"␊ |
12 | #include "vbe.h"␊ |
13 | #include "graphics.h"␊ |
14 | ␊ |
15 | ␊ |
16 | ␊ |
17 | void getResolution(UInt32* x, UInt32* y, UInt32* bp)␊ |
18 | {␊ |
19 | ␉static UInt32 xResolution, yResolution, bpResolution;␊ |
20 | ␊ |
21 | ␉bpResolution = 32;␉// assume 32bits␊ |
22 | ␉␊ |
23 | ␉if(!xResolution || !yResolution || !bpResolution)␊ |
24 | ␉{␊ |
25 | ␉␉␊ |
26 | ␉␉char* edidInfo = readEDID();␊ |
27 | ␉␉␊ |
28 | ␉␉if(!edidInfo) return;␊ |
29 | ␉␉␊ |
30 | ␉␉// TODO: check *all* resolutions reported and either use the highest, or the native resolution (if there is a flag for that)␊ |
31 | ␉␉xResolution = edidInfo[56] | ((edidInfo[58] & 0xF0) << 4);␊ |
32 | ␉␉yResolution = edidInfo[59] | ((edidInfo[61] & 0xF0) << 4);␊ |
33 | ␉␉␊ |
34 | ␉␉//printf("H Active = %d", edidInfo[56] | ((edidInfo[58] & 0xF0) << 4) );␊ |
35 | ␉␉//printf("V Active = %d", edidInfo[59] | ((edidInfo[61] & 0xF0) << 4) );␊ |
36 | ␉␉␊ |
37 | ␉␉free( edidInfo );␊ |
38 | ␉␉␊ |
39 | ␉␉if(!xResolution) xResolution = DEFAULT_SCREEN_WIDTH;␊ |
40 | ␉␉if(!yResolution) yResolution = DEFAULT_SCREEN_HEIGHT;␊ |
41 | ␊ |
42 | ␉}␊ |
43 | ␊ |
44 | ␉*x = xResolution;␊ |
45 | ␉*y = yResolution;␊ |
46 | ␉*bp = bpResolution;␊ |
47 | ␊ |
48 | }␊ |
49 | ␊ |
50 | char* readEDID()␊ |
51 | {␊ |
52 | ␉SInt16 last_reported = -1;␊ |
53 | ␉UInt8 edidInfo[EDID_BLOCK_SIZE];␊ |
54 | ␊ |
55 | ␉UInt8 header1[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};␊ |
56 | ␉UInt8 header2[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};␊ |
57 | ␉␊ |
58 | ␉SInt16 status;␊ |
59 | ␉UInt16 blocks_left = 1;␊ |
60 | ␉␊ |
61 | ␉do␊ |
62 | ␉{␊ |
63 | ␉␉// TODO: This currently only retrieves the *last* block, make the block buffer expand as needed / calculated from the first block␊ |
64 | ␊ |
65 | ␉␉bzero( edidInfo, EDID_BLOCK_SIZE);␊ |
66 | ␊ |
67 | ␉␉status = getEDID(edidInfo, blocks_left);␊ |
68 | ␉␉␊ |
69 | ␉␉␊ |
70 | ␉␉//printf("Buffer location: 0x%X\n", SEG(buffer) << 16 | OFF(buffer));␊ |
71 | ␉␉/*␊ |
72 | ␉␉int j, i;␊ |
73 | ␉␉for (j = 0; j < 8; j++) {␊ |
74 | ␉␉␉for(i = 0; i < 16; i++) printf("0x%X ", ebiosInfo[((i+1) * (j + 1)) - 1]);␊ |
75 | ␊ |
76 | ␉␉}␊ |
77 | ␉␉printf("\n");␊ |
78 | ␉␉*/␊ |
79 | ␉␉␊ |
80 | ␉␉if(status == 0)␊ |
81 | ␉␉{␊ |
82 | ␉␉␉//if( edidInfo[0] == 0x00 || edidInfo[0] == 0xFF)␊ |
83 | ␉␉␉if((memcmp(edidInfo, header1, sizeof(header1)) != 0) ||␊ |
84 | ␉␉␉ (memcmp(edidInfo, header2, sizeof(header2)) != 0) )␊ |
85 | ␉␉␉{␊ |
86 | ␉␉␉␉blocks_left--;␊ |
87 | ␉␉␉␉int reported = edidInfo[ EDID_V1_BLOCKS_TO_GO_OFFSET ];␊ |
88 | ␉␉␉␉␊ |
89 | ␉␉␉␉if ( reported > blocks_left )␊ |
90 | ␉␉␉␉{␊ |
91 | ␉␉␉␉␉␊ |
92 | ␉␉␉␉␉printf("EDID claims %d more blocks left\n", reported);␊ |
93 | ␉␉␉␉}␊ |
94 | ␉␉␉␉␊ |
95 | ␉␉␉␉if ( (last_reported <= reported && last_reported != -1)␊ |
96 | ␉␉␉␉␉|| reported == 0xff␊ |
97 | ␉␉␉␉␉/* 0xff frequently comes up in corrupt edids */␊ |
98 | ␉␉␉␉␉//|| reported == MAGIC␊ |
99 | ␉␉␉␉␉)␊ |
100 | ␉␉␉␉{␊ |
101 | ␉␉␉␉␉printf("Last reported %d\n", last_reported);␊ |
102 | ␉␉␉␉␉printf( "EDID blocks left is wrong.\n"␊ |
103 | ␉␉␉␉␉␉ "Your EDID is probably invalid.\n");␊ |
104 | ␉␉␉␉␉return 0;␊ |
105 | ␉␉␉␉}␊ |
106 | ␉␉␉␉else␊ |
107 | ␉␉␉␉{␊ |
108 | ␉␉␉␉␉//printf("Reading EDID block\n");␊ |
109 | ␉␉␉␉␉//printf("H Active = %d", ebiosInfo[56] | ((ebiosInfo[58] & 0xF0) << 4) );␊ |
110 | ␉␉␉␉␉//printf("V Active = %d", ebiosInfo[59] | ((ebiosInfo[61] & 0xF0) << 4) );␊ |
111 | ␊ |
112 | ␉␉␉␉␉last_reported = reported;␊ |
113 | ␉␉␉␉␉blocks_left = reported;␊ |
114 | ␉␉␉␉}␊ |
115 | ␉␉␉} ␊ |
116 | ␉␉␉else␊ |
117 | ␉␉␉{␊ |
118 | ␉␉␉␉printf("Invalid block %d\n", blocks_left);␊ |
119 | ␉␉␉␉printf("Header1 = %d", memcmp(edidInfo, header1, sizeof(header1)) );␊ |
120 | ␉␉␉␉printf("Header2 = %d", memcmp(edidInfo, header2, sizeof(header2)) );␊ |
121 | ␉␉␉␉return 0;␊ |
122 | ␉␉␉}␊ |
123 | ␉␉}␊ |
124 | ␉␉blocks_left = 0;␉␊ |
125 | ␉} while(blocks_left);␊ |
126 | ␊ |
127 | ␉char* ret = malloc(sizeof(edidInfo));␊ |
128 | ␉memcpy(ret, edidInfo, sizeof(edidInfo));␊ |
129 | ␉return ret;␊ |
130 | }␊ |
131 | ␊ |
132 | ␊ |
133 | int getEDID( void * edidBlock, UInt8 block)␊ |
134 | {␊ |
135 | ␉biosBuf_t bb;␊ |
136 | ␉␊ |
137 | ␉bzero(&bb, sizeof(bb));␊ |
138 | bb.intno = 0x10;␊ |
139 | bb.eax.rr = 0x4F15;␊ |
140 | ␉bb.ebx.r.l= 0x01;␊ |
141 | ␉bb.edx.rr = block;␊ |
142 | ␉␊ |
143 | bb.es = SEG( edidBlock );␊ |
144 | bb.edi.rr = OFF( edidBlock );␊ |
145 | ␉␊ |
146 | bios( &bb );␊ |
147 | return(bb.eax.r.h);␊ |
148 | }␊ |
149 | ␊ |
150 |