Chameleon

Chameleon Svn Source Tree

Root/branches/azimutz/Chazileon/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 "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* resolutions reported and eithe ruse the highest, or the native resolution (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
58
59unsigned char* readEDID()
60{
61SInt16 last_reported = -1;
62UInt8 edidInfo[EDID_BLOCK_SIZE];
63
64//UInt8 pointer;
65
66UInt8 header1[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
67UInt8 header2[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
68
69int status;
70unsigned int blocks_left = 1;
71
72do
73{
74// TODO: This currently only retrieves the *last* block, make the block buffer expand as needed / calculated from the first block
75
76bzero( edidInfo, EDID_BLOCK_SIZE);
77
78status = getEDID(edidInfo, blocks_left);
79
80//printf("Buffer location: 0x%X\n", SEG(buffer) << 16 | OFF(buffer));
81
82/*
83int j, i;
84for (j = 0; j < 8; j++) {
85for(i = 0; i < 16; i++) printf("0x%X ", ebiosInfo[((i+1) * (j + 1)) - 1]);
86
87}
88printf("\n");
89*/
90
91if(status == 0)
92{
93//if( edidInfo[0] == 0x00 || edidInfo[0] == 0xFF)
94if((memcmp(edidInfo, header1, sizeof(header1)) != 0) ||
95 (memcmp(edidInfo, header2, sizeof(header2)) != 0) )
96{
97blocks_left--;
98int reported = edidInfo[ EDID_V1_BLOCKS_TO_GO_OFFSET ];
99
100if ( reported > blocks_left )
101{
102
103printf("EDID claims %d more blocks left\n", reported);
104}
105
106if ( (last_reported <= reported && last_reported != -1)
107|| reported == 0xff
108/* 0xff frequently comes up in corrupt edids */
109//|| reported == MAGIC
110)
111{
112printf("Last reported %d\n", last_reported);
113printf( "EDID blocks left is wrong.\n"
114 "Your EDID is probably invalid.\n");
115return 0;
116}
117else
118{
119//printf("Reading EDID block\n");
120//printf("H Active = %d", ebiosInfo[56] | ((ebiosInfo[58] & 0xF0) << 4) );
121//printf("V Active = %d", ebiosInfo[59] | ((ebiosInfo[61] & 0xF0) << 4) );
122
123last_reported = reported;
124blocks_left = reported;
125}
126}
127else
128{
129printf("Invalid block %d\n", blocks_left);
130printf("Header1 = %d", memcmp(edidInfo, header1, sizeof(header1)) );
131printf("Header2 = %d", memcmp(edidInfo, header2, sizeof(header2)) );
132return 0;
133}
134} else {
135return 0;
136}
137
138
139blocks_left = 0;
140} while(blocks_left);
141
142UInt8* ret = malloc(sizeof(edidInfo));
143memcpy(ret, edidInfo, sizeof(edidInfo));
144return (ret);
145}
146

Archive Download this file

Revision: 399