~mcf/plan9front

9c02337fc30994d69e979748743d61b2e97d45ce — cinap_lenrek 2 years ago 5c96a51 + 954f9f1
merge
1 files changed, 73 insertions(+), 60 deletions(-)

M sys/src/cmd/aux/vga/edid.c
M sys/src/cmd/aux/vga/edid.c => sys/src/cmd/aux/vga/edid.c +73 -60
@@ 6,8 6,8 @@
#include "pci.h"
#include "vga.h"

static Modelist*
addmode(Modelist *l, Mode m)
static void
addmode(Modelist **l, Mode m)
{
	Modelist *ll;
	int rr;


@@ 15,17 15,15 @@ addmode(Modelist *l, Mode m)
	rr = (m.frequency+m.ht*m.vt/2)/(m.ht*m.vt);
	snprint(m.name, sizeof m.name, "%dx%d@%dHz", m.x, m.y, rr);

	for(ll = l; ll != nil; ll = ll->next){
		if(strcmp(ll->name, m.name) == 0){
			ll->Mode = m;
			return l;
		}
	for(ll = *l; ll != nil; ll = *l){
		if(strcmp(ll->name, m.name) == 0)
			return;
		l = &ll->next;
	}

	ll = alloc(sizeof(Modelist));
	ll->Mode = m;
	ll->next = l;
	return ll;
	*l = ll;
}

/*


@@ 282,70 280,85 @@ parseedid128(void *v)

	assert(p == (uchar*)v+8+10+2+5+10);
	/*
	 * Established timings: a bitmask of 19 preset timings.
	 * Timing information priority order (EDID 1.3 section 5)
	 *   1. Preferred Timing Mode (first detailed timing block)
	 *   2. Other Detailed Timing Mode, in order listed
	 *   3. Standard Timings, in order listed
	 *   4. Established Timings
	 */
	estab = (p[0]<<16) | (p[1]<<8) | p[2];
	p += 3;

	for(i=0, m=1<<23; i<nelem(estabtime); i++, m>>=1)
		if(estab & m)
			if(vesalookup(&mode, estabtime[i]) == 0)
				e->modelist = addmode(e->modelist,  mode);
	/*
	 * Detailed Timings
	 */
	p = (uchar*)v+8+10+2+5+10+3+16;
	for(i=0; i<4; i++, p+=18)
		if(p[0] || p[1])	/* detailed timing block: p[0] or p[1] != 0 */
			if(decodedtb(&mode, p) == 0)
				addmode(&e->modelist, mode);
	assert(p == (uchar*)v+8+10+2+5+10+3+16+72);

	assert(p == (uchar*)v+8+10+2+5+10+3);
	/*
	 * Standard Timing Identifications: eight 2-byte selectors
	 * of more standard timings.
	 */

	p = (uchar*)v+8+10+2+5+10+3;
	for(i=0; i<8; i++, p+=2)
		if(decodesti(&mode, p+2*i) == 0)
			e->modelist = addmode(e->modelist, mode);

			addmode(&e->modelist, mode);
	assert(p == (uchar*)v+8+10+2+5+10+3+16);
	/*
	 * Detailed Timings
	 */
	for(i=0; i<4; i++, p+=18) {
		if(p[0] || p[1]) {	/* detailed timing block: p[0] or p[1] != 0 */
			if(decodedtb(&mode, p) == 0)
				e->modelist = addmode(e->modelist, mode);
		} else if(p[2]==0) {	/* monitor descriptor block */
			switch(p[3]) {
			case 0xFF:	/* monitor serial number (13-byte ascii, 0A terminated) */
				if(q = memchr(p+5, 0x0A, 13))
					*q = '\0';
				memset(e->serialstr, 0, sizeof(e->serialstr));
				strncpy(e->serialstr, (char*)p+5, 13);
				break;
			case 0xFE:	/* ascii string (13-byte ascii, 0A terminated) */
				break;
			case 0xFD:	/* monitor range limits */
				e->rrmin = p[5];
				e->rrmax = p[6];
				e->hrmin = p[7]*1000;
				e->hrmax = p[8]*1000;
				if(p[9] != 0xFF)
					e->pclkmax = p[9]*10*1000000;
				break;
			case 0xFC:	/* monitor name (13-byte ascii, 0A terminated) */
				if(q = memchr(p+5, 0x0A, 13))
					*q = '\0';
				memset(e->name, 0, sizeof(e->name));
				strncpy(e->name, (char*)p+5, 13);
				break;
			case 0xFB:	/* extra color point data */
				break;
			case 0xFA:	/* extra standard timing identifications */
				for(i=0; i<6; i++)
					if(decodesti(&mode, p+5+2*i) == 0)
						e->modelist = addmode(e->modelist, mode);
				break;
			}

	p = (uchar*)v+8+10+2+5+10+3+16;
	for(i=0; i<4; i++, p+=18){
		if(p[0] || p[1])
			continue;
		/* monitor descriptor block */
		switch(p[3]) {
		case 0xFF:	/* monitor serial number (13-byte ascii, 0A terminated) */
			if(q = memchr(p+5, 0x0A, 13))
				*q = '\0';
			memset(e->serialstr, 0, sizeof(e->serialstr));
			strncpy(e->serialstr, (char*)p+5, 13);
			break;
		case 0xFE:	/* ascii string (13-byte ascii, 0A terminated) */
			break;
		case 0xFD:	/* monitor range limits */
			e->rrmin = p[5];
			e->rrmax = p[6];
			e->hrmin = p[7]*1000;
			e->hrmax = p[8]*1000;
			if(p[9] != 0xFF)
				e->pclkmax = p[9]*10*1000000;
			break;
		case 0xFC:	/* monitor name (13-byte ascii, 0A terminated) */
			if(q = memchr(p+5, 0x0A, 13))
				*q = '\0';
			memset(e->name, 0, sizeof(e->name));
			strncpy(e->name, (char*)p+5, 13);
			break;
		case 0xFB:	/* extra color point data */
			break;
		case 0xFA:	/* extra standard timing identifications */
			for(i=0; i<6; i++)
				if(decodesti(&mode, p+5+2*i) == 0)
					addmode(&e->modelist, mode);
			break;
		}
	}

	assert(p == (uchar*)v+8+10+2+5+10+3+16+72);

	/*
	 * Established timings: a bitmask of 19 preset timings.
	 */
	p = (uchar*)v+8+10+2+5+10;
	estab = (p[0]<<16) | (p[1]<<8) | p[2];
	p += 3;

	for(i=0, m=1<<23; i<nelem(estabtime); i++, m>>=1)
		if(estab & m)
			if(vesalookup(&mode, estabtime[i]) == 0)
				addmode(&e->modelist, mode);
	assert(p == (uchar*)v+8+10+2+5+10+3);

	return e;
}