Chameleon

Chameleon Svn Source Tree

Root/trunk/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
17//static biosBuf_t bb;
18
19UInt32 xResolution = 0;
20UInt32 yResolution = 0;
21UInt32 bpResolution = 0;
22
23
24void getResolution(UInt32* x, UInt32* y, UInt32* bp)
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 eithe ruse the highest, or the native resolution (if there is a flag for that)
36xResolution = edidInfo[56] | ((edidInfo[58] & 0xF0) << 4);
37yResolution = edidInfo[59] | ((edidInfo[61] & 0xF0) << 4);
38
39bpResolution = 32;// assume 32bits
40
41free( edidInfo );
42}
43
44if (!xResolution) xResolution = 1024;
45if (!yResolution) yResolution = 768;
46
47*x = xResolution;
48*y = yResolution;
49*bp = bpResolution;
50
51}
52
53int getMode(edid_mode *mode)
54{
55unsigned char* edidInfo = readEDID();
56
57if(!edidInfo) return 1;
58
59mode->pixel_clock = (edidInfo[55] << 8) | edidInfo[54];
60mode->h_active = edidInfo[56] | ((edidInfo[58] & 0xF0) << 4);
61mode->h_blanking = ((edidInfo[58] & 0x0F) << 8) | edidInfo[57];
62mode->v_active = edidInfo[59] | ((edidInfo[61] & 0xF0) << 4);
63mode->v_blanking = ((edidInfo[61] & 0x0F) << 8) | edidInfo[60];
64mode->h_sync_offset = ((edidInfo[65] & 0xC0) >> 2) | edidInfo[62];
65mode->h_sync_width = (edidInfo[65] & 0x30) | edidInfo[63];
66mode->v_sync_offset = (edidInfo[65] & 0x0C) | ((edidInfo[64] & 0x0C) >> 2);
67mode->v_sync_width = ((edidInfo[65] & 0x3) << 2) | (edidInfo[64] & 0x03);
68
69
70free( edidInfo );
71
72if(!mode->h_active) return 1;
73
74return 0;
75
76}
77
78unsigned char* readEDID()
79{
80SInt16 last_reported = -1;
81UInt8 edidInfo[EDID_BLOCK_SIZE];
82
83//UInt8 pointer;
84
85UInt8 header1[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
86UInt8 header2[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
87
88int status;
89unsigned int blocks_left = 1;
90
91do
92{
93// TODO: This currently only retrieves the *last* block, make the block buffer expand as needed / calculated from the first block
94
95bzero( edidInfo, EDID_BLOCK_SIZE);
96
97status = getEDID(edidInfo, blocks_left);
98
99//printf("Buffer location: 0x%X\n", SEG(buffer) << 16 | OFF(buffer));
100
101/*
102int j, i;
103for (j = 0; j < 8; j++) {
104for(i = 0; i < 16; i++) printf("0x%X ", ebiosInfo[((i+1) * (j + 1)) - 1]);
105
106}
107printf("\n");
108*/
109
110if(status == 0)
111{
112//if( edidInfo[0] == 0x00 || edidInfo[0] == 0xFF)
113if((memcmp(edidInfo, header1, sizeof(header1)) != 0) ||
114 (memcmp(edidInfo, header2, sizeof(header2)) != 0) )
115{
116blocks_left--;
117int reported = edidInfo[ EDID_V1_BLOCKS_TO_GO_OFFSET ];
118
119if ( reported > blocks_left )
120{
121
122printf("EDID claims %d more blocks left\n", reported);
123}
124
125if ( (last_reported <= reported && last_reported != -1)
126|| reported == 0xff
127/* 0xff frequently comes up in corrupt edids */
128//|| reported == MAGIC
129)
130{
131printf("Last reported %d\n", last_reported);
132printf( "EDID blocks left is wrong.\n"
133 "Your EDID is probably invalid.\n");
134return 0;
135}
136else
137{
138//printf("Reading EDID block\n");
139//printf("H Active = %d", ebiosInfo[56] | ((ebiosInfo[58] & 0xF0) << 4) );
140//printf("V Active = %d", ebiosInfo[59] | ((ebiosInfo[61] & 0xF0) << 4) );
141
142last_reported = reported;
143blocks_left = reported;
144}
145}
146else
147{
148printf("Invalid block %d\n", blocks_left);
149printf("Header1 = %d", memcmp(edidInfo, header1, sizeof(header1)) );
150printf("Header2 = %d", memcmp(edidInfo, header2, sizeof(header2)) );
151return 0;
152}
153} else return 0;
154
155blocks_left = 0;
156} while(blocks_left);
157
158UInt8* ret = malloc(sizeof(edidInfo));
159memcpy(ret, edidInfo, sizeof(edidInfo));
160return (ret);
161}
162

Archive Download this file

Revision: 127