Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/modules/Resolution/edid.c

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 "libsaio.h"
12#include "edid.h"
13#include "vbe.h"
14#include "graphics.h"
15
16void getResolutionHook(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, void* arg6)
17{
18getResolution(arg1, arg2, arg3);
19}
20
21void getResolution(UInt32* x, UInt32* y, UInt32* bp)
22{
23int val;
24static UInt32 xResolution, yResolution, bpResolution;
25
26if(getIntForKey(kScreenWidth, &val, DEFAULT_BOOT_CONFIG))
27{
28xResolution = val;
29}
30
31if(getIntForKey(kScreenHeight, &val, DEFAULT_BOOT_CONFIG))
32{
33yResolution = val;
34}
35
36bpResolution = 32;// assume 32bits
37
38
39if(!xResolution || !yResolution || !bpResolution)
40{
41
42char* edidInfo = readEDID();
43
44if(!edidInfo) return;
45
46// TODO: check *all* resolutions reported and either use the highest, or the native resolution (if there is a flag for that)
47xResolution = edidInfo[56] | ((edidInfo[58] & 0xF0) << 4);
48yResolution = edidInfo[59] | ((edidInfo[61] & 0xF0) << 4);
49
50//printf("H Active = %d", edidInfo[56] | ((edidInfo[58] & 0xF0) << 4) );
51//printf("V Active = %d", edidInfo[59] | ((edidInfo[61] & 0xF0) << 4) );
52
53free( edidInfo );
54
55if(!xResolution) xResolution = DEFAULT_SCREEN_WIDTH;
56if(!yResolution) yResolution = DEFAULT_SCREEN_HEIGHT;
57
58}
59
60*x = xResolution;
61*y = yResolution;
62*bp = bpResolution;
63
64}
65
66char* readEDID(void)
67{
68SInt16 last_reported = -1;
69UInt8 edidInfo[EDID_BLOCK_SIZE];
70
71UInt8 header1[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
72UInt8 header2[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
73
74SInt16 status;
75UInt16 blocks_left = 1;
76
77do
78{
79// TODO: This currently only retrieves the *last* block, make the block buffer expand as needed / calculated from the first block
80
81bzero( edidInfo, EDID_BLOCK_SIZE);
82
83status = getEDID(edidInfo, blocks_left);
84
85
86//printf("Buffer location: 0x%X\n", SEG(buffer) << 16 | OFF(buffer));
87/*
88int j, i;
89for (j = 0; j < 8; j++) {
90for(i = 0; i < 16; i++) printf("0x%X ", ebiosInfo[((i+1) * (j + 1)) - 1]);
91
92}
93printf("\n");
94*/
95
96if(status == 0)
97{
98//if( edidInfo[0] == 0x00 || edidInfo[0] == 0xFF)
99if((memcmp(edidInfo, header1, sizeof(header1)) != 0) ||
100 (memcmp(edidInfo, header2, sizeof(header2)) != 0) )
101{
102blocks_left--;
103int reported = edidInfo[ EDID_V1_BLOCKS_TO_GO_OFFSET ];
104
105if ( reported > blocks_left )
106{
107
108printf("EDID claims %d more blocks left\n", reported);
109}
110
111if ( (last_reported <= reported && last_reported != -1)
112|| reported == 0xff
113/* 0xff frequently comes up in corrupt edids */
114//|| reported == MAGIC
115)
116{
117printf("Last reported %d\n", last_reported);
118printf( "EDID blocks left is wrong.\n"
119 "Your EDID is probably invalid.\n");
120return 0;
121}
122else
123{
124//printf("Reading EDID block\n");
125//printf("H Active = %d", ebiosInfo[56] | ((ebiosInfo[58] & 0xF0) << 4) );
126//printf("V Active = %d", ebiosInfo[59] | ((ebiosInfo[61] & 0xF0) << 4) );
127
128last_reported = reported;
129blocks_left = reported;
130}
131}
132else
133{
134printf("Invalid block %d\n", blocks_left);
135printf("Header1 = %d", memcmp(edidInfo, header1, sizeof(header1)) );
136printf("Header2 = %d", memcmp(edidInfo, header2, sizeof(header2)) );
137return 0;
138}
139}
140blocks_left = 0;
141} while(blocks_left);
142
143char* ret = malloc(sizeof(edidInfo));
144 if (!ret) {
145 return 0;
146 }
147memcpy(ret, edidInfo, sizeof(edidInfo));
148return ret;
149}
150

Archive Download this file

Revision: 1984