Chameleon Applications

Chameleon Applications Svn Source Tree

Root/branches/iFabio/Chameleon/i386/modules/Resolution/edid.c

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
17void getResolution(UInt32* x, UInt32* y, UInt32* bp)
18{
19static UInt32 xResolution, yResolution, bpResolution;
20
21bpResolution = 32;// assume 32bits
22
23if(!xResolution || !yResolution || !bpResolution)
24{
25
26char* edidInfo = readEDID();
27
28if(!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)
31xResolution = edidInfo[56] | ((edidInfo[58] & 0xF0) << 4);
32yResolution = 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
37free( edidInfo );
38
39if(!xResolution) xResolution = DEFAULT_SCREEN_WIDTH;
40if(!yResolution) yResolution = DEFAULT_SCREEN_HEIGHT;
41
42}
43
44*x = xResolution;
45*y = yResolution;
46*bp = bpResolution;
47
48}
49
50char* readEDID()
51{
52SInt16 last_reported = -1;
53UInt8 edidInfo[EDID_BLOCK_SIZE];
54
55UInt8 header1[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
56UInt8 header2[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
57
58SInt16 status;
59UInt16 blocks_left = 1;
60
61do
62{
63// TODO: This currently only retrieves the *last* block, make the block buffer expand as needed / calculated from the first block
64
65bzero( edidInfo, EDID_BLOCK_SIZE);
66
67status = getEDID(edidInfo, blocks_left);
68
69
70//printf("Buffer location: 0x%X\n", SEG(buffer) << 16 | OFF(buffer));
71/*
72int j, i;
73for (j = 0; j < 8; j++) {
74for(i = 0; i < 16; i++) printf("0x%X ", ebiosInfo[((i+1) * (j + 1)) - 1]);
75
76}
77printf("\n");
78*/
79
80if(status == 0)
81{
82//if( edidInfo[0] == 0x00 || edidInfo[0] == 0xFF)
83if((memcmp(edidInfo, header1, sizeof(header1)) != 0) ||
84 (memcmp(edidInfo, header2, sizeof(header2)) != 0) )
85{
86blocks_left--;
87int reported = edidInfo[ EDID_V1_BLOCKS_TO_GO_OFFSET ];
88
89if ( reported > blocks_left )
90{
91
92printf("EDID claims %d more blocks left\n", reported);
93}
94
95if ( (last_reported <= reported && last_reported != -1)
96|| reported == 0xff
97/* 0xff frequently comes up in corrupt edids */
98//|| reported == MAGIC
99)
100{
101printf("Last reported %d\n", last_reported);
102printf( "EDID blocks left is wrong.\n"
103 "Your EDID is probably invalid.\n");
104return 0;
105}
106else
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
112last_reported = reported;
113blocks_left = reported;
114}
115}
116else
117{
118printf("Invalid block %d\n", blocks_left);
119printf("Header1 = %d", memcmp(edidInfo, header1, sizeof(header1)) );
120printf("Header2 = %d", memcmp(edidInfo, header2, sizeof(header2)) );
121return 0;
122}
123}
124blocks_left = 0;
125} while(blocks_left);
126
127char* ret = malloc(sizeof(edidInfo));
128memcpy(ret, edidInfo, sizeof(edidInfo));
129return ret;
130}
131
132
133int getEDID( void * edidBlock, UInt8 block)
134{
135biosBuf_t bb;
136
137bzero(&bb, sizeof(bb));
138 bb.intno = 0x10;
139 bb.eax.rr = 0x4F15;
140bb.ebx.r.l= 0x01;
141bb.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

Archive Download this file

Revision: 307