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