Chameleon Applications

Chameleon Applications Svn Source Tree

Root/branches/iFabio/Chameleon/i386/modules/Resolution/edid.c

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

Archive Download this file

Revision: 296