Chameleon

Chameleon Svn Source Tree

Root/branches/meklort/i386/libsaio/edid.c

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

Archive Download this file

Revision: 150