| 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" --> bootstruct.h␊ |
| 12 | //#include "bootstruct.h" - included on graphics.h␊ |
| 13 | #include "graphics.h"␊ |
| 14 | #include "boot.h"␊ |
| 15 | ␊ |
| 16 | ␊ |
| 17 | //static biosBuf_t bb;␊ |
| 18 | ␊ |
| 19 | UInt32 xResolution = 0;␊ |
| 20 | UInt32 yResolution = 0;␊ |
| 21 | UInt32 bpResolution = 0;␊ |
| 22 | ␊ |
| 23 | ␊ |
| 24 | void getResolution(UInt32* params)␊ |
| 25 | {␊ |
| 26 | ␉unsigned char* edidInfo = readEDID();␊ |
| 27 | ␉␊ |
| 28 | ␉if(!edidInfo) {␊ |
| 29 | ␉␉xResolution = 1024;␊ |
| 30 | ␉␉yResolution = 768;␊ |
| 31 | ␉␉bpResolution = 32;␊ |
| 32 | ␉␉␊ |
| 33 | ␉␉free( 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).␊ |
| 37 | ␉␉xResolution = edidInfo[56] | ((edidInfo[58] & 0xF0) << 4);␊ |
| 38 | ␉␉yResolution = edidInfo[59] | ((edidInfo[61] & 0xF0) << 4);␊ |
| 39 | ␉␉␊ |
| 40 | ␉␉bpResolution = 32;␉// assume 32bits␊ |
| 41 | ␉␉␊ |
| 42 | ␉␉free( edidInfo );␊ |
| 43 | ␉␉␊ |
| 44 | ␉␉// Mode Sanity check␊ |
| 45 | ␉␉if ((xResolution < 1024) || !yResolution || !xResolution) ␊ |
| 46 | ␉␉{␊ |
| 47 | ␉␉␉xResolution = 1024;␊ |
| 48 | ␉␉␉yResolution = 768;␊ |
| 49 | ␉␉}␊ |
| 50 | ␉␉␊ |
| 51 | ␉␉params[0] = xResolution;␊ |
| 52 | ␉␉params[1] = yResolution;␊ |
| 53 | ␉␉params[2] = bpResolution;␊ |
| 54 | ␉}␊ |
| 55 | }␊ |
| 56 | ␊ |
| 57 | ␊ |
| 58 | unsigned char* readEDID()␊ |
| 59 | {␊ |
| 60 | ␉SInt16 last_reported = -1;␊ |
| 61 | ␉UInt8 edidInfo[EDID_BLOCK_SIZE];␊ |
| 62 | ␊ |
| 63 | ␉//UInt8 pointer;␊ |
| 64 | ␊ |
| 65 | ␉UInt8 header1[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};␊ |
| 66 | ␉UInt8 header2[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};␊ |
| 67 | ␉␊ |
| 68 | ␉int status;␊ |
| 69 | ␉unsigned int blocks_left = 1;␊ |
| 70 | ␉␊ |
| 71 | ␉do␊ |
| 72 | ␉{␊ |
| 73 | ␉␉// TODO: This currently only retrieves the *last* block, make the block buffer expand␊ |
| 74 | ␉␉// as needed / calculated from the first block.␊ |
| 75 | ␊ |
| 76 | ␉␉bzero( edidInfo, EDID_BLOCK_SIZE);␊ |
| 77 | ␊ |
| 78 | ␉␉status = getEDID(edidInfo, blocks_left);␊ |
| 79 | ␉␉␊ |
| 80 | ␉␉//printf("Buffer location: 0x%X\n", SEG(buffer) << 16 | OFF(buffer));␊ |
| 81 | ␊ |
| 82 | ␉␉/*␊ |
| 83 | ␉␉int j, i;␊ |
| 84 | ␉␉for (j = 0; j < 8; j++) {␊ |
| 85 | ␉␉␉for(i = 0; i < 16; i++) printf("0x%X ", ebiosInfo[((i+1) * (j + 1)) - 1]);␊ |
| 86 | ␊ |
| 87 | ␉␉}␊ |
| 88 | ␉␉printf("\n");␊ |
| 89 | ␉␉*/␊ |
| 90 | ␉␉␊ |
| 91 | ␉␉if(status == 0)␊ |
| 92 | ␉␉{␊ |
| 93 | ␉␉␉//if( edidInfo[0] == 0x00 || edidInfo[0] == 0xFF)␊ |
| 94 | ␉␉␉if((memcmp(edidInfo, header1, sizeof(header1)) != 0) ||␊ |
| 95 | ␉␉␉ (memcmp(edidInfo, header2, sizeof(header2)) != 0) )␊ |
| 96 | ␉␉␉{␊ |
| 97 | ␉␉␉␉blocks_left--;␊ |
| 98 | ␉␉␉␉int reported = edidInfo[ EDID_V1_BLOCKS_TO_GO_OFFSET ];␊ |
| 99 | ␉␉␉␉␊ |
| 100 | ␉␉␉␉if ( reported > blocks_left )␊ |
| 101 | ␉␉␉␉{␊ |
| 102 | ␉␉␉␉␉␊ |
| 103 | ␉␉␉␉␉printf("EDID claims %d more blocks left\n", reported);␊ |
| 104 | ␉␉␉␉}␊ |
| 105 | ␉␉␉␉␊ |
| 106 | ␉␉␉␉if ( (last_reported <= reported && last_reported != -1)␊ |
| 107 | ␉␉␉␉␉|| reported == 0xff␊ |
| 108 | ␉␉␉␉␉/* 0xff frequently comes up in corrupt edids */␊ |
| 109 | ␉␉␉␉␉//|| reported == MAGIC␊ |
| 110 | ␉␉␉␉␉)␊ |
| 111 | ␉␉␉␉{␊ |
| 112 | ␉␉␉␉␉printf("Last reported %d\n", last_reported);␊ |
| 113 | ␉␉␉␉␉printf( "EDID blocks left is wrong.\n"␊ |
| 114 | ␉␉␉␉␉␉ "Your EDID is probably invalid.\n");␊ |
| 115 | ␉␉␉␉␉return 0;␊ |
| 116 | ␉␉␉␉}␊ |
| 117 | ␉␉␉␉else␊ |
| 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 | ␊ |
| 123 | ␉␉␉␉␉last_reported = reported;␊ |
| 124 | ␉␉␉␉␉blocks_left = reported;␊ |
| 125 | ␉␉␉␉}␊ |
| 126 | ␉␉␉} ␊ |
| 127 | ␉␉␉else␊ |
| 128 | ␉␉␉{␊ |
| 129 | ␉␉␉␉printf("Invalid block %d\n", blocks_left);␊ |
| 130 | ␉␉␉␉printf("Header1 = %d", memcmp(edidInfo, header1, sizeof(header1)) );␊ |
| 131 | ␉␉␉␉printf("Header2 = %d", memcmp(edidInfo, header2, sizeof(header2)) );␊ |
| 132 | ␉␉␉␉return 0;␊ |
| 133 | ␉␉␉}␊ |
| 134 | ␉␉} else {␊ |
| 135 | ␉␉␉return 0;␊ |
| 136 | ␉␉}␊ |
| 137 | ␊ |
| 138 | ␉␉␊ |
| 139 | ␉␉blocks_left = 0;␉␊ |
| 140 | ␉} while(blocks_left);␊ |
| 141 | ␊ |
| 142 | ␉UInt8* ret = malloc(sizeof(edidInfo));␊ |
| 143 | ␉memcpy(ret, edidInfo, sizeof(edidInfo));␊ |
| 144 | ␉return (ret);␊ |
| 145 | }␊ |
| 146 | |