Index: branches/meklort/i386/libsaio/vbe.c =================================================================== --- branches/meklort/i386/libsaio/vbe.c (revision 146) +++ branches/meklort/i386/libsaio/vbe.c (revision 147) @@ -105,6 +105,23 @@ return(bb.eax.r.h); } +int getEDID( void * edidBlock, UInt8 block) +{ + bzero(&bb, sizeof(bb)); + bb.intno = 0x10; + bb.eax.rr = funcGetEDID; + bb.ebx.r.l= 0x01; + bb.edx.rr = block; + + bb.es = SEG( edidBlock ); + bb.edi.rr = OFF( edidBlock ); + + bios( &bb ); + return(bb.eax.r.h); +} + + + /* * Default GTF parameter values. */ Index: branches/meklort/i386/libsaio/vbe.h =================================================================== --- branches/meklort/i386/libsaio/vbe.h (revision 146) +++ branches/meklort/i386/libsaio/vbe.h (revision 147) @@ -68,7 +68,9 @@ funcGetSetPaletteFormat = 0x4F08, funcGetSetPaletteData = 0x4F09, funcGetProtModeInterdace = 0x4F0A, - funcGetSetPixelClock = 0x4F0B + funcGetSetPixelClock = 0x4F0B, + funcGetEDID = 0x4F15 + }; enum { @@ -269,6 +271,7 @@ typedef unsigned long VBEPalette[256]; extern int getVBEInfo(void *vinfo_p); +extern int getEDID( void * edidBlock, UInt8 block); extern int getVBEModeInfo(int mode, void *minfo_p); extern int getVBEDACFormat(unsigned char *format); extern int setVBEDACFormat(unsigned char format); Index: branches/meklort/i386/libsaio/edid.c =================================================================== --- branches/meklort/i386/libsaio/edid.c (revision 0) +++ branches/meklort/i386/libsaio/edid.c (revision 147) @@ -0,0 +1,145 @@ +/* + * edid.c + * + * + * Created by Evan Lojewski on 12/1/09. + * Copyright 2009. All rights reserved. + * + */ + + +#include "libsaio.h" +#include "edid.h" +#include "vbe.h" +#include "graphics.h" +#include "boot.h" + +void getResolution(UInt32* x, UInt32* y, UInt32* bp) +{ + int val; + static UInt32 xResolution, yResolution, bpResolution; + + if(getIntForKey(kScreenWidth, &val, &bootInfo->bootConfig)) + { + xResolution = val; + } + + if(getIntForKey(kScreenHeight, &val, &bootInfo->bootConfig)) + { + yResolution = val; + } + + bpResolution = 32; // assume 32bits + + + if(!xResolution || !yResolution || !bpResolution) + { + + char* edidInfo = readEDID(); + + if(!edidInfo) return; + + // TODO: check *all* resolutions reported and either use the highest, or the native resolution (if there is a flag for that) + xResolution = edidInfo[56] | ((edidInfo[58] & 0xF0) << 4); + yResolution = edidInfo[59] | ((edidInfo[61] & 0xF0) << 4); + + //printf("H Active = %d", edidInfo[56] | ((edidInfo[58] & 0xF0) << 4) ); + //printf("V Active = %d", edidInfo[59] | ((edidInfo[61] & 0xF0) << 4) ); + + + + + free( edidInfo ); + + if(!xResolution) xResolution = DEFAULT_SCREEN_WIDTH; + if(!yResolution) yResolution = DEFAULT_SCREEN_HEIGHT; + + } + + *x = xResolution; + *y = yResolution; + *bp = bpResolution; + +} + +char* readEDID() +{ + SInt16 last_reported = -1; + UInt8 edidInfo[EDID_BLOCK_SIZE]; + + UInt8 header1[] = {0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}; + UInt8 header2[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + SInt16 status; + UInt16 blocks_left = 1; + + do + { + // TODO: This currently only retrieves the *last* block, make the block buffer expand as needed / calculated from the first block + + bzero( edidInfo, EDID_BLOCK_SIZE); + + status = getEDID(edidInfo, blocks_left); + + + //printf("Buffer location: 0x%X\n", SEG(buffer) << 16 | OFF(buffer)); + /* + int j, i; + for (j = 0; j < 8; j++) { + for(i = 0; i < 16; i++) printf("0x%X ", ebiosInfo[((i+1) * (j + 1)) - 1]); + + } + printf("\n"); + */ + + if(status == 0) + { + //if( edidInfo[0] == 0x00 || edidInfo[0] == 0xFF) + if((memcmp(edidInfo, header1, sizeof(header1)) != 0) || + (memcmp(edidInfo, header2, sizeof(header2)) != 0) ) + { + blocks_left--; + int reported = edidInfo[ EDID_V1_BLOCKS_TO_GO_OFFSET ]; + + if ( reported > blocks_left ) + { + + printf("EDID claims %d more blocks left\n", reported); + } + + if ( (last_reported <= reported && last_reported != -1) + || reported == 0xff + /* 0xff frequently comes up in corrupt edids */ + //|| reported == MAGIC + ) + { + printf("Last reported %d\n", last_reported); + printf( "EDID blocks left is wrong.\n" + "Your EDID is probably invalid.\n"); + return 0; + } + else + { + //printf("Reading EDID block\n"); + //printf("H Active = %d", ebiosInfo[56] | ((ebiosInfo[58] & 0xF0) << 4) ); + //printf("V Active = %d", ebiosInfo[59] | ((ebiosInfo[61] & 0xF0) << 4) ); + + last_reported = reported; + blocks_left = reported; + } + } + else + { + printf("Invalid block %d\n", blocks_left); + printf("Header1 = %d", memcmp(edidInfo, header1, sizeof(header1)) ); + printf("Header2 = %d", memcmp(edidInfo, header2, sizeof(header2)) ); + return 0; + } + } + blocks_left = 0; + } while(blocks_left); + + char* ret = malloc(sizeof(edidInfo)); + memcpy(ret, edidInfo, sizeof(edidInfo)); + return ret; +} Index: branches/meklort/i386/libsaio/edid.h =================================================================== --- branches/meklort/i386/libsaio/edid.h (revision 0) +++ branches/meklort/i386/libsaio/edid.h (revision 147) @@ -0,0 +1,15 @@ +/* + * edid.h + * + * + * Created by Evan Lojewski on 12/1/09. + * Copyright 2009. All rights reserved. + * + */ + + +#define EDID_BLOCK_SIZE 128 +#define EDID_V1_BLOCKS_TO_GO_OFFSET 126 + +char* readEDID(); +void getResolution(UInt32* x, UInt32* y, UInt32* bp); \ No newline at end of file Index: branches/meklort/i386/boot2/gui.c =================================================================== --- branches/meklort/i386/boot2/gui.c (revision 146) +++ branches/meklort/i386/boot2/gui.c (revision 147) @@ -11,6 +11,7 @@ #include "gui.h" #include "appleboot.h" #include "vers.h" +#include "edid.h" #define THEME_NAME_DEFAULT "Default" static const char *theme_name = THEME_NAME_DEFAULT; @@ -556,7 +557,7 @@ int initGUI(void) { - int val; + //int val; #ifdef EMBED_THEME config_file_t *config; @@ -577,6 +578,7 @@ return 1; } #endif + /* // parse display size parameters if (getIntForKey("screen_width", &val, &bootInfo->themeConfig)) { screen_params[0] = val; @@ -585,7 +587,10 @@ screen_params[1] = val; } screen_params[2] = 32; + */ + getResolution(&screen_params[0], &screen_params[1], &screen_params[2]); + // Initalizing GUI strucutre. bzero(&gui, sizeof(gui_t)); @@ -1685,7 +1690,7 @@ // drawBootGraphics void drawBootGraphics(void) { - int pos; + //int pos; int length; const char *dummyVal; bool legacy_logo; @@ -1697,6 +1702,7 @@ loadBootGraphics(); } + /* // parse screen size parameters if (getIntForKey("boot_width", &pos, &bootInfo->themeConfig)) { screen_params[0] = pos; @@ -1709,7 +1715,11 @@ screen_params[1] = DEFAULT_SCREEN_HEIGHT; } screen_params[2] = 32; + */ + + getResolution(&screen_params[0], &screen_params[1], &screen_params[2]); + gui.screen.width = screen_params[0]; gui.screen.height = screen_params[1];