Chameleon

Chameleon Svn Source Tree

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

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

Archive Download this file

Revision: 709