Chameleon

Chameleon Svn Source Tree

Root/branches/azimutz/Chazi/i386/libsaio/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 "bootstruct.h"
13#include "boot.h"
14#include "graphics.h"
15
16
17//static biosBuf_t bb; // reminder
18
19UInt32 xResolution = 0;
20UInt32 yResolution = 0;
21UInt32 bpResolution = 0;
22
23
24void getResolution(UInt32* params)
25{
26unsigned char* edidInfo = readEDID();
27
28if(!edidInfo) {
29xResolution = 1024;
30yResolution = 768;
31bpResolution = 32;
32
33free( edidInfo );
34} else {
35// TODO: check *all* resolutions reported and either use the highest,
36// or the native resolution (if there is a flag for that).
37xResolution = edidInfo[56] | ((edidInfo[58] & 0xF0) << 4);
38yResolution = edidInfo[59] | ((edidInfo[61] & 0xF0) << 4);
39
40bpResolution = 32;// assume 32bits
41
42free( edidInfo );
43
44// Mode Sanity check
45if ((xResolution < 1024) || !yResolution || !xResolution)
46{
47xResolution = 1024;
48yResolution = 768;
49}
50
51params[0] = xResolution;
52params[1] = yResolution;
53params[2] = bpResolution;
54}
55}
56
57unsigned char* readEDID()
58{
59SInt16 last_reported = -1;
60UInt8 edidInfo[EDID_BLOCK_SIZE];
61
62//UInt8 pointer;
63
64UInt8 header1[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
65UInt8 header2[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
66
67int status;
68unsigned int blocks_left = 1;
69
70do
71{
72// TODO: This currently only retrieves the *last* block, make the block buffer expand
73// as needed / calculated from the 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: 618