Commit f2073d25 authored by John Ballance's avatar John Ballance
Browse files

Extended to optionally generate a saved mdf instead of updating the current loaded mdf.

Detail:
  For field support it is extremely helpful to determine what a customer's monitor
  reports. Whilst (hopefully) this module will correctly produce modes the monitor
  can handle and the computer generate, when that doesn't happen support types need
  to be able to find out why, ideally using the same exact information that is generated.
  So:
  The ReadEDID command, if called with a full file name, will now save the discovered
  mdf information to that file instead of loading it.
  The resultant mdf can be used directly, or used as the basis for further
  modifications. It exports additional information in the header section
  which may prove helpful to 'mdf tweakers'.
Admin:
  Tested in imx rom. In 'advertised' use it is the same code as before. It is
  only when the  filename is given to the readedid command that different paths
  are invoked. Further enhancements may be desirable.

Version 0.40. Tagged as 'ScrModes-0_40'
parent d893357d
No preview for this file type
No preview for this file type
/* (0.39)
/* (0.40)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 0.39
#define Module_MajorVersion_CMHG 0.40
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 08 Feb 2015
#define Module_Date_CMHG 10 Feb 2015
#define Module_MajorVersion "0.39"
#define Module_Version 39
#define Module_MajorVersion "0.40"
#define Module_Version 40
#define Module_MinorVersion ""
#define Module_Date "08 Feb 2015"
#define Module_Date "10 Feb 2015"
#define Module_ApplicationDate "08-Feb-15"
#define Module_ApplicationDate "10-Feb-15"
#define Module_ComponentName "ScrModes"
#define Module_ComponentPath "castle/RiscOS/Sources/Video/UserI/ScrModes"
#define Module_FullVersion "0.39"
#define Module_HelpVersion "0.39 (08 Feb 2015)"
#define Module_LibraryVersionInfo "0:39"
#define Module_FullVersion "0.40"
#define Module_HelpVersion "0.40 (10 Feb 2015)"
#define Module_LibraryVersionInfo "0:40"
......@@ -2279,12 +2279,13 @@ static int get_extd_type(EDIDBlockRef edidblockref, int block_no)
}
static _kernel_oserror *parseedid(char *ediddata)
static _kernel_oserror *parseedid(char *ediddata, FILE *f)
{
_kernel_oserror *res;
MonitorDescriptionRef new_monitor;
ModeDescriptionRef new_preferred_mode = NULL; /* No preferred mode */
EDIDBlockRef edidblockref = (EDIDBlockRef) ediddata;
int RangeBlock = 0; /* edid block containing timimg limits */
/* OK, commit to reading a monitor description - go allocate space */
new_monitor = (MonitorDescriptionRef) malloc (sizeof(MonitorDescription));
......@@ -2414,6 +2415,9 @@ static _kernel_oserror *parseedid(char *ediddata)
#if DODEBUG
printf ("Display range limits\n");
#endif
RangeBlock = blockno; /* remember*/
/* Not 100% sure about this but think this is how we pick up CVT-RB support */
if (timing_support == EDID_USE_CVT)
{
......@@ -2522,56 +2526,112 @@ static _kernel_oserror *parseedid(char *ediddata)
#if DODEBUG
printf("Modes sorted\n");
#endif
if(f)
{
fprintf(f,"# Monitor description file for %s\n",new_monitor->name);
fprintf(f,"# Created by ScrModes %s\n",Module_VersionString);
fprintf(f,"# (EDID specified modes only, no calculated modes)\n\n");
fprintf(f,"# Max Viewable H %d cm \n",edidblockref->horizontal_screen_size);
fprintf(f,"# Max Viewable V %d cm\n",edidblockref->vertical_screen_size);
uint8_t flags = edidblockref->data_block[RangeBlock][4];
int vmin=0,vmax=0,hmin=0,hmax=0, pixmax=0;
if((flags&0x3)==0x2) {vmax=255;}
if((flags&0x3)==0x2) {vmax=255; vmin=255;}
if((flags&0xc)==0x8) {hmax=255;}
if((flags&0xc)==0xc) {hmax=255; hmin=255;}
vmin+=edidblockref->data_block[RangeBlock][5];
vmax+=edidblockref->data_block[RangeBlock][6];
hmin+=edidblockref->data_block[RangeBlock][7];
hmax+=edidblockref->data_block[RangeBlock][8];
pixmax=edidblockref->data_block[RangeBlock][9];
fprintf(f,"# Line rate: %2d - %2dkHz\n",hmin,hmax);
fprintf(f,"# Frame rate: %2d - %2dHz\n",vmin,vmax);
fprintf(f,"# Max Dot rate: %3dMHz (rounded down)\n",pixmax*10);
fprintf(f,"# Uses %s frequency pixel clocks\n", ((edidblockref->feature_support & 1) == 1)?"Continuous":"Specific");
char *rules="unknown";
switch(timing_support)
{
case EDID_USE_CVT:rules="CVT";break;
case EDID_USE_DMT:rules="DMT";break;
case EDID_USE_CVTRB:rules="CVTRB";break;
case EDID_USE_GTF:rules="GTF";break;
case EDID_USE_GTF2:rules="GTF2";break;
}
fprintf(f,"# Use %s timing rules\n",rules);
/* Below taken from the loadmodefile code
* If we haven't got a file loaded at present, then
* read current monitortype, to restore on module shutdown
*/
if (old_monitortype == -1) {
old_monitortype = read_monitortype ();
}
res = set_monitortype (MONITOR_FILE);
if (res != NULL)
{
_kernel_oserror *res2;
debug printf ("setting of monitor type to type `FILE' failed\n");
res2 = restore_monitortype (); /* restore old value */
if (res2 != NULL)
{
debug printf ("couldn't reset monitor type to CMOS default!\n");
}
fprintf(f,"file_format:1\nmonitor_title:%s\nDPMS_state:%d\n",new_monitor->name,(new_monitor->dpms_state==-1)?0:new_monitor->dpms_state);
ModeDescriptionRef this = new_monitor->modelist;
do
{
fprintf(f,"\n# Mode: %d x %d @ %dHz",this->definition.hpar[FR_DISP],this->definition.vpar[FR_DISP],this->frame_hz);
float tmp =(float)(this->definition.hpar[0]+this->definition.hpar[1]+this->definition.hpar[2]+this->definition.hpar[3]+this->definition.hpar[4]+this->definition.hpar[5]);
fprintf(f,"\n# Bounds: H %3.2fkHz, V %3.2f, DClock %3.2fMHz",((float)(this->definition.pixel_khz))/tmp,(float)(this->frame_hz),(float)(this->definition.pixel_khz)/1000);
fprintf(f,"\nstartmode");
fprintf(f,"\n mode_name:%d x %d",this->definition.hpar[FR_DISP],this->definition.vpar[FR_DISP]);
fprintf(f,"\n x_res:%d",this->definition.hpar[FR_DISP]);
fprintf(f,"\n y_res:%d",this->definition.vpar[FR_DISP]);
fprintf(f,"\n pixel_rate:%d",this->definition.pixel_khz);
fprintf(f,"\n h_timings:%d,%d,%d,%d,%d,%d",this->definition.hpar[0],this->definition.hpar[1],this->definition.hpar[2],this->definition.hpar[3],this->definition.hpar[4],this->definition.hpar[5]);
fprintf(f,"\n v_timings:%d,%d,%d,%d,%d,%d",this->definition.vpar[0],this->definition.vpar[1],this->definition.vpar[2],this->definition.vpar[3],this->definition.vpar[4],this->definition.vpar[5]);
fprintf(f,"\n sync_pol:%d",this->definition.syncpol);
fprintf(f,"\nEndMode\n");
this = this->next; /* will be NULL at list end*/
} while (this);
fprintf(f,"#End\n");
}
else
{
_kernel_swi_regs regs;
release_currentmonitor ();
current_monitor = new_monitor;
/* Set up the mode specifier */
preferred_mode->bit0 = 1;
preferred_mode->format = 0;
preferred_mode->xresol = new_preferred_mode->definition.hpar[FR_DISP];
preferred_mode->yresol = new_preferred_mode->definition.vpar[FR_DISP];
preferred_mode->depth = 5;
preferred_mode->framerate = new_preferred_mode->frame_hz;
preferred_mode->param[0].index = -1;
/* Set the preferred sync type from video input definition bit 3. */
/* (ref EDID spec table 3.11) */
if ((edidblockref->video_input_definition & 0x8) == 0x8) {
preferred_sync_type = 0;
}
else {
preferred_sync_type = 1;
}
debug printf("Monitor type changed\n");
/* Newly defined monitor, announce it */
regs.r[1] = Service_ModeFileChanged;
_kernel_swi (OS_ServiceCall, &regs, &regs);
debug printf("Service_ModeFileChanged issued\n");
/* Below taken from the loadmodefile code
* If we haven't got a file loaded at present, then
* read current monitortype, to restore on module shutdown
*/
if (old_monitortype == -1) {
old_monitortype = read_monitortype ();
}
res = set_monitortype (MONITOR_FILE);
if (res != NULL)
{
_kernel_oserror *res2;
debug printf ("setting of monitor type to type `FILE' failed\n");
res2 = restore_monitortype (); /* restore old value */
if (res2 != NULL)
{
debug printf ("couldn't reset monitor type to CMOS default!\n");
}
}
else
{
_kernel_swi_regs regs;
release_currentmonitor ();
current_monitor = new_monitor;
/* Set up the mode specifier */
preferred_mode->bit0 = 1;
preferred_mode->format = 0;
preferred_mode->xresol = new_preferred_mode->definition.hpar[FR_DISP];
preferred_mode->yresol = new_preferred_mode->definition.vpar[FR_DISP];
preferred_mode->depth = 5;
preferred_mode->framerate = new_preferred_mode->frame_hz;
preferred_mode->param[0].index = -1;
/* Set the preferred sync type from video input definition bit 3. */
/* (ref EDID spec table 3.11) */
if ((edidblockref->video_input_definition & 0x8) == 0x8) {
preferred_sync_type = 0;
}
else {
preferred_sync_type = 1;
}
debug printf("Monitor type changed\n");
/* Newly defined monitor, announce it */
regs.r[1] = Service_ModeFileChanged;
_kernel_swi (OS_ServiceCall, &regs, &regs);
debug printf("Service_ModeFileChanged issued\n");
}
}
return res;
......@@ -2600,7 +2660,7 @@ static _kernel_oserror *loadedid (const char *file)
res = Check_EDID_Checksum((char *)edidblock, EDID_Check_AllBlocks);
}
if (!res) {
parseedid(edidblock);
parseedid(edidblock,NULL);
}
free(edidblock);
}
......@@ -2650,26 +2710,30 @@ static _kernel_oserror *loadmodefile (const char *file)
return res;
}
static _kernel_oserror *readedid (void)
static _kernel_oserror *readedid (const char *file)
{
_kernel_oserror *res;
FILE *f = NULL;
EDIDBlockRef edidblock = (EDIDBlockRef) malloc(128);
if (edidblock == NULL) {
return error (ERR_NOSPACE, 0, 0, 0);
}
if (file)
{
f = fopen (file, "w");
}
debug printf ("ReadEDID called\n");
int iic_code = (0xa1 << 16) | (0 << 0);
int op_code = (0 << 24) | (0 << 16) | (14 << 0);
res = _swix(OS_CallAVector, _INR(0,2) | _IN(4) | _IN(9) | _OUT(0) | _OUT(4), iic_code, edidblock, 0x7f,op_code, 42, &iic_code, &op_code);
res = _swix(OS_CallAVector, _INR(0,2) | _IN(4) | _IN(9) | _OUT(0) | _OUT(4), iic_code, edidblock, 0x80, op_code, 42, &iic_code, &op_code);
/* If GraphicsV 14 was not claimed, R4 (op_code) should return
unchanged in which case we need to alert the user that the
hardware doesn't like EDID :-( */
if (iic_code != 0) {
res = error (iic_code, 0, 0, 0);
}
......@@ -2682,7 +2746,7 @@ static _kernel_oserror *readedid (void)
/* Check the block is valid */
if (!res) {
res = Check_EDID_Checksum((char *)edidblock, EDID_Check_BaseOnly);
}
}
/* Now use a separate pointer to the block for extending it and */
/* setting up extensions */
......@@ -2710,7 +2774,11 @@ static _kernel_oserror *readedid (void)
if (!res) {
debug printf ("Parsing EDID block\n");
res = parseedid(ediddata);
res = parseedid(ediddata,f);
}
if(f) {
fclose(f);
}
free(edidblock);
......@@ -3397,7 +3465,7 @@ static void service_displaychanged (_kernel_swi_regs *regs)
driver-specific things which we store.
At the moment all the driver-specific stuff happens during the
enumerate/translate calls, so there's nothing to do. */
res = readedid();
res = readedid(NULL);
break;
case DisplayChanged_Changed:
......@@ -3441,7 +3509,7 @@ _kernel_oserror *ScreenModes_initialise(const char *cmd_tail, int podule_base, v
UNUSED(podule_base);
UNUSED(pw);
readedid();
readedid(NULL);
return NULL;
}
......@@ -3506,7 +3574,7 @@ _kernel_oserror *ScreenModes_cmdhandler (const char *arg_string, int argc, int c
result = loadmodefile (arg_string);
break;
case CMD_ReadEDID:
result = readedid ();
result = readedid (arg_string);
break;
default:
return NULL;
......
......@@ -43,7 +43,7 @@ command-keyword-table: ScreenModes_cmdhandler
LoadModeFile(min-args:1, max-args: 1, international:,
invalid-syntax: "SSMDLMF",
help-text: "HSMDLMF"),
ReadEDID(min-args:0,max-args:0, international:,
ReadEDID(min-args:0,max-args:1, international:,
invalid-syntax: "SSMDRED",
help-text: "HSMDRED")
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment