void parse_cea_block(EdidInfo e, BYTE *d,DEPLINT block_number) { struct MySADescriptorList sad; DEPLINT i; i = block_number; /* * Checksum calculation for CEA extension */ { DEPLINT j; BYTE sum = 0; for(j = i; j < (i + 128); j++) sum += d[j]; if(sum) { ERROR_MESSAGE("Check sum does not match, EDID information corrupted\n"); e->cea->checksum = FALSE; } else { DEBUG_MESSAGE("checksum ok\n"); e->cea->checksum = TRUE; } } e->cea->cea_rev = d[i+1]; e->cea->underscan = get_bits(d[i+3],7,7); e->cea->audio = get_bits(d[i+3],6,6); e->cea->YCC444 = get_bits(d[i+3],5,5); e->cea->YCC422 = get_bits(d[i+3],4,4); e->cea->native_formats = get_bits(d[i+3],3,0); //iterrate through data block { DEPLINT j = i + 4; while(j < i+d[i+2]) { DEPLINT tag = get_bits(d[j],7,5); if(tag==1) { DEBUG_MESSAGE("Short Audio Descriptor\n"); sad.aud_format = get_bits(d[j+1],6,3); sad.max_num_chan = get_bits(d[j+1],2,0)+1; sad.khz_192 = get_bits(d[j+2],6,6); sad.khz_176 = get_bits(d[j+2],5,5); sad.khz_96 = get_bits(d[j+2],4,4); sad.khz_88 = get_bits(d[j+2],3,3); sad.khz_48 = get_bits(d[j+2],2,2); sad.khz_44 = get_bits(d[j+2],1,1); sad.khz_32 = get_bits(d[j+2],0,0); sad.sample_rates = get_bits(d[j+2],6,0); if(sad.aud_format == 1) { sad.unc_24bit = get_bits(d[j+3],2,2); sad.unc_20bit = get_bits(d[j+3],1,1); sad.unc_16bit = get_bits(d[j+3],0,0); sad.sample_sizes = get_bits(d[j+3],2,0); } else { sad.comp_maxbitrate = d[j+3]*8; } add_sad(sad,e); } else if(tag==2) { struct MySVDescriptorList svd; DEPLINT k;// = j+1; DEBUG_MESSAGE("Short Video Descriptor\n"); for(k = j +1;k<=(j+get_bits(d[j],4,0));k++) { svd.vid_id = get_bits(d[k],6,0); svd.native = get_bits(d[k],7,7); add_svd(svd,e); } } else if(tag==3) { DEBUG_MESSAGE("Vendor Specific Data Block\n"); //lsb e->cea->cea->ieee_reg[1] = (WORD)((d[j+1])|(d[j+2]<<8)); //msb e->cea->cea->ieee_reg[0] = (WORD)(d[j+3]); e->cea->cea->hdmi_addr_a = get_bits(d[j+4],7,4); e->cea->cea->hdmi_addr_b = get_bits(d[j+4],3,0); e->cea->cea->hdmi_addr_c = get_bits(d[j+5],7,4); e->cea->cea->hdmi_addr_d = get_bits(d[j+5],3,0); if(get_bits(d[j],4,0)>=6) { DEPLINT k = 1; e->cea->cea->supports_ai = get_bits(d[j+6],1,1); e->cea->cea->vsdb_ext[0] = get_bits(d[j+6],6,0); while((k<(get_bits(d[j],4,0)-5))&&(k<24)) e->cea->cea->vsdb_ext[k] = d[j+6+k]; } if((e->cea->cea->ieee_reg[1] == 0x0C03) || (e->cea->cea->ieee_reg[0] == 0x00)) e->cea->cea->vsdb_hdmi=TRUE; } else if(tag==4) { DEBUG_MESSAGE("Speaker Allocation Block\n"); e->cea->cea->spad->rlc_rrc = get_bits(d[j+1],6,6); e->cea->cea->spad->flc_frc =get_bits(d[j+1],5,5); e->cea->cea->spad->rc =get_bits(d[j+1],4,4); e->cea->cea->spad->rl_rr =get_bits(d[j+1],3,3); e->cea->cea->spad->fc =get_bits(d[j+1],2,2); e->cea->cea->spad->lfe =get_bits(d[j+1],1,1); e->cea->cea->spad->fl_fr =get_bits(d[j+1],0,0); //e->cea->cea->spad-> } else if((tag==0)||(tag==5)||(tag==6)||(tag==7)) DEBUG_MESSAGE("Reserved\n"); else ERROR_MESSAGE("invalid tag in cea data block\n"); j+= (get_bits(d[j],4,0)+1); } } //iterrate through Detailed Timing Descriptors { DEPLINT j = d[i+2] + i; //look for 18 bit detailed timing descriptors until 0xFF - 18 while((d[j]!=0x0) && (j<=0xED)) { add_dtb(parse_dtb(j,d),e); j+=18; } } }
void parse_0_block(EdidInfo e,BYTE *d) { DEPLINT first_dtb = 0x36; DEPLINT last_dtb = 0x6C; DEPLINT i; DEPLINT j; BYTE header[8] = {0x00, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00}; if (memcmp(header,d,8)) e->edid_header=FALSE; else e->edid_header=TRUE; e->edid_extensions = d[0x7E]; /* *Checksum calculation for block 0 */ { DEPLINT i; BYTE sum = 0; for(i = 0; i < 128; i++) sum += d[i]; if(sum) { ERROR_MESSAGE("Check sum does not match, EDID information corrupted\n"); e->edid_checksum = FALSE; } else { DEBUG_MESSAGE("checksum ok\n"); e->edid_checksum = TRUE; } } /* *Manufacturer name is 3 5-bit ascii characters packed into 16-bit, big endian format */ e->vpi->manuf[0] = (char)(get_bits(d[0x8],6,2)+'A'-1); e->vpi->manuf[1] = (char)(((get_bits(d[0x8],1,0)<<3)|get_bits(d[9],7,5))+('A'-1)); e->vpi->manuf[2] = (char)(get_bits(d[0x9],4,0)+'A'-1); e->vpi->manuf[3] = '\0'; /* *product code is little endian 16-bit */ e->vpi->prodcode[0] = d[0xA]; e->vpi->prodcode[1] = d[0xB]; /* *optional product serial is little endian 32-bit 0x010101 = UNUSED */ //lsb e->vpi->serial[1] = (WORD)d[0xC]|(WORD)(d[0xD]<<8); //msb e->vpi->serial[0] = (WORD)d[0xE]|(WORD)(d[0xF]<<8); e->vpi->week = (int)d[0x10]; e->vpi->year = 1990 + (int)d[0x11]; e->evr->ver = d[0x12]; e->evr->rev = d[0x13]; /* *Basic display parameter byte bits[6:0] are *defined differently for analog and digital */ e->bdp->anadig = get_bits(d[0x14],7,7); if(e->bdp->anadig) { e->bdp->dfp1x = get_bits(d[0x14],0,0); } else { e->bdp->siglev = get_bits(d[0x14],6,5); e->bdp->setup = get_bits(d[0x14],4,4); e->bdp->sepsyn = get_bits(d[0x14],3,3); e->bdp->compsync = get_bits(d[0x14],2,2); e->bdp->sog = get_bits(d[0x14],1,1); e->bdp->vsync_ser = get_bits(d[0x14],0,0); } e->bdp->maxh = d[0x15]; e->bdp->maxv = d[0x16]; e->bdp->dtc_gam = d[0x17]; e->bdp->standby = get_bits(d[0x18],7,7); e->bdp->suspend = get_bits(d[0x18],6,6); e->bdp->aovlp = get_bits(d[0x18],5,5); e->bdp->disptype = get_bits(d[0x18],4,3); e->bdp->def_col_sp = get_bits(d[0x18],2,2); e->bdp->pt_mode = get_bits(d[0x18],1,1); e->bdp->def_gtf = get_bits(d[0x18],0,0); /* *colorimetry bits are converted into binary fractions */ e->cc->rx = get_bits(d[0x19],7,6)|(d[0x1B]<<2); e->cc->ry = get_bits(d[0x19],5,4)|(d[0x1C]<<2); e->cc->gx = get_bits(d[0x19],3,2)|(d[0x1D]<<2); e->cc->gy = get_bits(d[0x19],1,0)|(d[0x1E]<<2); e->cc->bx = get_bits(d[0x19],7,6)|(d[0x1F]<<2); e->cc->by = get_bits(d[0x19],5,4)|(d[0x20]<<2); e->cc->wx = get_bits(d[0x19],3,2)|(d[0x21]<<2); e->cc->wy = get_bits(d[0x19],1,0)|(d[0x22]<<2); e->et->m720_400_70 = get_bits(d[0x23],7,7); e->et->m720_400_88 = get_bits(d[0x23],6,6); e->et->m640_480_60 = get_bits(d[0x23],5,5); e->et->m640_480_67 = get_bits(d[0x23],4,4); e->et->m640_480_72 = get_bits(d[0x23],3,3); e->et->m640_480_75 = get_bits(d[0x23],2,2); e->et->m800_600_56 = get_bits(d[0x23],1,1); e->et->m800_600_60 = get_bits(d[0x23],0,0); // Established Timing II e->et->m800_600_72 = get_bits(d[0x24],7,7); e->et->m800_600_75 = get_bits(d[0x24],6,6); e->et->m832_624_75 = get_bits(d[0x24],5,5); e->et->m1024_768_87 = get_bits(d[0x24],4,4); e->et->m1024_768_60 = get_bits(d[0x24],3,3); e->et->m1024_768_70 = get_bits(d[0x24],2,2); e->et->m1024_768_75 = get_bits(d[0x24],1,1); e->et->m1280_1024_75= get_bits(d[0x24],0,0); // Manufacturer's Timings e->et->m1152_870_75 = get_bits(d[0x25],7,7); // Reserved e->et->res_7 = get_bits(d[0x25],6,6); e->et->res_6 = get_bits(d[0x25],5,5); e->et->res_5 = get_bits(d[0x25],4,4); e->et->res_4 = get_bits(d[0x25],3,3); e->et->res_3 = get_bits(d[0x25],2,2); e->et->res_2 = get_bits(d[0x25],1,1); e->et->res_1 = get_bits(d[0x25],0,0); for(j=0x26;j<=0x34;j+=2) { struct MyStandardTimingList st; st.hap = d[j] * 8 + 248; st.imasp = get_bits(d[j+1],7,6); st.ref = get_bits(d[j+1],5,0) + 60; add_st(st,e); } for(i=first_dtb;i<=last_dtb;i+=0x12) { /* *Monitor Descriptor */ if((d[i]==0x0)&&(d[i+1]==0x0)) { /* *Monitor S/N */ if(d[i+3]==0xFF) { DEPLINT j; DEBUG_MESSAGE("Monitor S/N\n"); for(j=0;j<13;j++) { e->mdb->mon_snum[j] = d[i + 5 + j]; if(d[i + 5 + j] == 0xA) e->mdb->mon_name[j] = '\0'; } } /* *ASCII Data String */ if(d[i+3]==0xFE) { DEPLINT j; DEBUG_MESSAGE("ASCII String\n"); for(j=0;j<13;j++) { e->mdb->ascii_data[j] = d[i + 5 + j]; if(d[i + 5 + j] == 0xA) e->mdb->mon_name[j] = '\0'; } } /* *Monitor Range Limits */ if(d[i+3]==0xFD) { DEBUG_MESSAGE("Range Limits\n"); e->mdb->mrl_min_vrate = d[i+5]; e->mdb->mrl_max_vrate = d[i+6]; e->mdb->mrl_min_hrate=d[i+7]; e->mdb->mrl_max_hrate=d[i+8]; e->mdb->mrl_max_pix_clk = d[i+9]*10; if(d[i+10]==0x2) { e->mdb->mrl_gtf_support = TRUE; e->mdb->mrl_gtf_start_freq = d[i+12]*2000; e->mdb->mrl_gtf_c = d[i+13]/2; e->mdb->mrl_gtf_m = d[i+14]|(d[1+15]<<8); e->mdb->mrl_gtf_k =d[i+16]; e->mdb->mrl_gtf_j = d[i+17]/2; } else e->mdb->mrl_gtf_support=FALSE; } /* *Monitor Name */ if(d[i+3]==0xFC) { DEPLINT j; DEBUG_MESSAGE("Monitor Name\n"); for(j=0;j<13;j++) { e->mdb->mon_name[j] = d[i + 5 + j]; if(d[i + 5 + j] == 0xA) e->mdb->mon_name[j] = '\0'; } } /* *Additional Color PoDEPLINT Data */ if(d[i+3]==0xFB) { DEBUG_MESSAGE("Additional Color PoDEPLINT Data\n"); e->mdb->cp_wpoint_index1 = d[i+5]; e->mdb->cp_w_lb1 = d[i+6]; e->mdb->cp_w_x1 = d[i+7]; e->mdb->cp_w_y1 = d[i+8]; e->mdb->cp_w_gam1 = d[i+9]; if(d[i+10]!=0x00) { e->mdb->cp_wpoint_index2 = d[i+10]; e->mdb->cp_w_lb2 = d[i+11]; e->mdb->cp_w_x2 = d[i+12]; e->mdb->cp_w_y2 = d[i+13]; e->mdb->cp_w_gam2 = d[i+14]; } } /* *Additional Standard Timing Definitions */ if(d[i+3]==0xFA) { DEPLINT j; DEBUG_MESSAGE("Additional Standard Timing Definitions\n"); for(j=5;j<18;j+=2) { struct MyStandardTimingList st; st.hap = (d[i + j]/28)-31; st.imasp = get_bits(d[i + j+1],7,6); st.ref = get_bits(d[i + j+1],5,0) + 60; add_st(st,e); } } /* *Dummy Descriptor */ if(d[i+3]==0x10) { DEBUG_MESSAGE("Dummy Descriptor\n"); } /* *Manufacturer Defined descriptor *Only supports one for now. To more e->mbd->ms_byte can be converted into a linked list of ms[] */ if(d[i+3]<=0x0F) { DEPLINT j; DEBUG_MESSAGE("Manufacturer Defined Descriptor\n"); for(j=0;j<13;j++) { e->mdb->ms_byte[j] = d[i + 5 + j]; } } } else { DEBUG_MESSAGE("DTB\n"); /* *Flag 1st DTB as preferred timing */ add_dtb(parse_dtb(i,d),e); } } }
int main(int argc, char *argv[]) { void *ram; int opt, ret, fd; int malloc_size = CONFIG_MALLOC_SIZE; int fdno = 0, envno = 0, option_index = 0; while (1) { option_index = 0; opt = getopt_long(argc, argv, optstring, long_options, &option_index); if (opt == -1) break; switch (opt) { case 'h': print_usage(basename(argv[0])); exit(0); case 'm': malloc_size = strtoul(optarg, NULL, 0); break; case 'i': break; case 'e': break; case 'd': ret = add_dtb(optarg); if (ret) { printf("Failed to load dtb: '%s'\n", optarg); exit(1); } break; case 'O': fd = open(optarg, O_WRONLY); if (fd < 0) { perror("open"); exit(1); } barebox_register_console("cout", -1, fd); break; case 'I': fd = open(optarg, O_RDWR); if (fd < 0) { perror("open"); exit(1); } barebox_register_console("cin", fd, -1); break; case 'x': sdl_xres = strtoul(optarg, NULL, 0); break; case 'y': sdl_yres = strtoul(optarg, NULL, 0); break; default: exit(1); } } ram = malloc(malloc_size); if (!ram) { printf("unable to get malloc space\n"); exit(1); } mem_malloc_init(ram, ram + malloc_size - 1); /* * Reset getopt. * We need to run a second getopt to count -i parameters. * This is for /dev/fd# devices. */ optind = 1; while (1) { option_index = 0; opt = getopt_long(argc, argv, optstring, long_options, &option_index); if (opt == -1) break; switch (opt) { case 'i': ret = add_image(optarg, "fd%d", &fdno); if (ret) exit(1); break; case 'e': ret = add_image(optarg, "env%d", &envno); if (ret) exit(1); break; default: break; } } barebox_register_console("console", fileno(stdin), fileno(stdout)); rawmode(); start_barebox(); /* never reached */ return 0; }