Commit c877cabb authored by Neil Turton's avatar Neil Turton
Browse files

Import from SrcFiler

parent 1aa6d45b
......@@ -61,6 +61,8 @@
"file_format\0 " \
"monitor_title\0" \
"dpms_state\0 " \
"lcd_support\0 " \
"interlaced\0 " \
"startmode\0 " \
"endmode"
#define MAXKEYWORDLEN 13
......@@ -93,6 +95,8 @@ enum keycode
k_file_format,
k_monitor_title,
k_dpms_state,
k_lcd_support,
k_interlaced,
k_startmode,
k_endmode,
......@@ -102,7 +106,7 @@ enum keycode
};
#if DODEBUG
static int dodebug = 0;
static int dodebug = 1;
#define debug if (!dodebug) {} else
#else
#define debug if (1) {} else
......@@ -563,13 +567,13 @@ static _kernel_oserror *check_keyword (enum keycode code, int colon)
static _kernel_oserror *parse_mode (ModeDefinition *mode)
{
uns32 keyseen;
uns32 xres, yres;
assert (last_mode_key <= 32);
keyseen = 0;
mode->interlaced = 0; /* Assume mode is not interlaced, unless we see the keyword */
for (;;)
{
enum keycode kc = read_keyword ();
uns32 param, missed;
uns32 param, missed, ok_to_miss;
_kernel_oserror *res;
if (kc <= last_mode_key)
{
......@@ -589,11 +593,13 @@ static _kernel_oserror *parse_mode (ModeDefinition *mode)
/* Work out which, if any, of the entries have not been supplied */
missed = ~(~(uns32)0 << (last_mode_key+1)) - keyseen;
/*
* In format 1, we insist that x_res = hdisp and y_res =
* vdisp so x_res and y_res are in fact optional. We
* insist that all other keywords do occur.
* In format 1, we normally insist that x_res = hdisp and
* y_res = vdisp so x_res and y_res are in fact optional.
* However if the mode is interlaced, then x_res and y_res are compulsory.
* We insist that all other keywords do occur.
*/
if (missed & ~(1 << k_x_res | 1 << k_y_res))
ok_to_miss = mode->interlaced ? 0 : (1 << k_x_res) | (1 << k_y_res);
if (missed & ~ok_to_miss)
{
/*
* If some other keyword(s) not seen, complain. If
......@@ -607,9 +613,12 @@ static _kernel_oserror *parse_mode (ModeDefinition *mode)
else
return semerrS (ERR_INCOMPLETE, mode->name);
}
/* All keywords seen - check consistency */
if (keyseen & (1 << k_x_res) && xres != mode->hpar[FR_DISP] ||
keyseen & (1 << k_y_res) && yres != mode->vpar[FR_DISP])
/* If xres and/or yres missing, use the xdisp and/or ydisp values */
if (!(keyseen & (1 << k_x_res))) mode->xres = mode->hpar[FR_DISP];
if (!(keyseen & (1 << k_y_res))) mode->yres = mode->vpar[FR_DISP];
/* xres must equal xdisp, and yres must equal ydisp (or ydisp*2 for interlaced modes) */
if (mode->xres != mode->hpar[FR_DISP] || mode->yres != mode->vpar[FR_DISP] * (mode->interlaced+1))
return semerrS (ERR_INCONSISTENT, mode->name);
return check_eol (1);
......@@ -621,13 +630,13 @@ static _kernel_oserror *parse_mode (ModeDefinition *mode)
return synerrK (ERR_WRONGCONTEXT, kc);
case k_x_res:
res = read_one_u32 (&xres, 1);
res = read_one_u32 (&mode->xres, 1);
if (res)
return res;
break;
case k_y_res:
res = read_one_u32 (&yres, 1);
res = read_one_u32 (&mode->yres, 1);
if (res)
return res;
break;
......@@ -647,6 +656,13 @@ static _kernel_oserror *parse_mode (ModeDefinition *mode)
mode->syncpol = param;
break;
case k_interlaced:
mode->interlaced = 1; /* It is an interlaced mode */
res = check_eol (0);
if (res)
return res;
break;
case k_mode_name:
/* TMD 13-Dec-93: We must allow blank mode names now -
* they mean a mode is not shown in DisplayManager menu.
......@@ -714,6 +730,7 @@ static void compute_modedescription (ModeDescriptionRef md)
}
md->line_hz = mp->pixel_khz * 1000 / htot; /* compute line frequency in Hz */
md->frame_mhz = md->line_hz * 1000 / vtot; /* frame frequency in milliHz, high-prec */
if (mp->interlaced) md->frame_mhz /= 2; /* if interlaced, one frame is 2 fields */
md->frame_hz = (md->frame_mhz + 500) / 1000; /* & low-prec for user integer Hz matching */
}
......@@ -819,8 +836,29 @@ static _kernel_oserror *parse_modefile (MonitorDescriptionRef *description)
}
}
/*
* Now check for optional LCD_support keyword
*/
if (res == NULL)
{
md->lcd_support = 0; /* Indicates CRT as default */
if (kc == k_lcd_support)
{
debug printf("Got the lcdsupport keyword\n");
res = skip_char (':');
if (res == NULL) {
res = read_one_u32 (&md->lcd_support, 0); /* read LCD_support value */
if(md->lcd_support != 0) md->dpms_state = -1; /* LCD and DPMS are mutually exclusive */
debug printf("Read the value as %d\n",md->lcd_support);
}
if (res == NULL) kc = read_keyword (); /* then read next keyword */
}
}
if (res == NULL) {
debug printf("Going to read the modes now...\n");
res = parse_modelist (md, kc); /* pass in read keyword token */
}
if (res)
{
......@@ -842,13 +880,13 @@ static _kernel_oserror *parse_modefile (MonitorDescriptionRef *description)
*/
static int modes_inorder (ModeDescriptionRef m1, ModeDescriptionRef m2)
{
if (m1->definition.hpar[FR_DISP] < m2->definition.hpar[FR_DISP])
if (m1->definition.xres < m2->definition.xres)
return 1;
if (m1->definition.hpar[FR_DISP] > m2->definition.hpar[FR_DISP])
if (m1->definition.xres > m2->definition.xres)
return 0;
if (m1->definition.vpar[FR_DISP] < m2->definition.vpar[FR_DISP])
if (m1->definition.yres < m2->definition.yres)
return 1;
if (m1->definition.vpar[FR_DISP] > m2->definition.vpar[FR_DISP])
if (m1->definition.yres > m2->definition.yres)
return 0;
if (m1->frame_mhz > m2->frame_mhz)
return 1;
......@@ -944,10 +982,10 @@ static void show_monitor (MonitorDescriptionRef monitor)
{
ModeDefinition *dp = &mode->definition;
uns32 pixrate = dp->pixel_khz;
uns32 pixels = dp->vpar[FR_DISP] * dp->hpar[FR_DISP];
uns32 pixels = dp->xres * dp->yres;
int log2bpp;
printf ("%p: Mode name \"%s\"\n", mode, mode->definition.name);
printf (" Resolution %u x %u\n", dp->hpar[FR_DISP], dp->vpar[FR_DISP]);
printf (" Resolution %u x %u\n", dp->xres, dp->yres);
printf (" Line rate %u.%03u kHz, Frame rate %d.%03d Hz\n",
mode->line_hz / 1000, mode->line_hz % 1000,
mode->frame_mhz / 1000, mode->frame_mhz % 1000);
......@@ -960,6 +998,7 @@ static void show_monitor (MonitorDescriptionRef monitor)
" sync %u b-porch %u t-border %u display %u b-border %u f-porch %u\n",
dp->vpar[FR_SYNC], dp->vpar[FR_BPCH], dp->vpar[FR_BDR1],
dp->vpar[FR_DISP], dp->vpar[FR_BDR2], dp->vpar[FR_FPCH]);
if (dp->interlaced) printf(" Interlaced\n");
for (log2bpp = 0; log2bpp <= 5; ++log2bpp)
{
uns bits = 1 << log2bpp;
......@@ -1078,11 +1117,20 @@ static int mode_valid (ModeDescriptionRef mp, int depth,
uns32 maxdatarate, uns32 maxdatasize)
{
uns32 pixrate = mp->definition.pixel_khz;
uns32 mx = mp->definition.hpar[FR_DISP];
uns32 my = mp->definition.vpar[FR_DISP];
uns32 mx = mp->definition.xres;
uns32 my = mp->definition.yres;
uns32 pixels = mx * my;
uns32 datarate, datasize;
/*
* TMD 03-Apr-96: For interlaced modes, the line length must be a
* multiple of 32 bytes, ie 256 bits
*/
uns32 bit_multiple = mp->definition.interlaced ? 256 : 32;
/* Convert from pixels to bytes: method varies according to depth */
if((depth > 2) && (current_monitor->lcd_support == 1)) return 0; /** Eek! 4bpp is max for b/w panels! **/
if (depth < 3)
{
uns shift = 3 - depth;
......@@ -1108,16 +1156,17 @@ static int mode_valid (ModeDescriptionRef mp, int depth,
* actually says 128 bits, but it does work for e.g. mode 29 which
* is 32 MOD 128). This check can cut out lower depths for
* certain unusually-dimensioned modes.
*
*/
switch (vidc_type)
{
case V_VIDC1:
if ((mx << depth) % 32 != 0)
if ((mx << depth) % bit_multiple != 0)
return 0;
break;
case V_VIDC20:
if ((mx << depth) % 32 != 0)
if ((mx << depth) % bit_multiple != 0)
return 0;
break;
......@@ -1131,11 +1180,11 @@ static int mode_valid (ModeDescriptionRef mp, int depth,
static ModeDescriptionRef find_by_xy (ModeDescriptionRef mp,
uns32 xres, uns32 yres, int *count)
{
while (mp && mp->definition.hpar[FR_DISP] < xres)
while (mp && mp->definition.xres < xres)
mp = mp->next;
while (mp && mp->definition.hpar[FR_DISP] == xres && mp->definition.vpar[FR_DISP] < yres)
while (mp && mp->definition.xres == xres && mp->definition.yres < yres)
mp = mp->next;
if (mp && mp->definition.hpar[FR_DISP] == xres && mp->definition.vpar[FR_DISP] == yres)
if (mp && mp->definition.xres == xres && mp->definition.yres == yres)
{
int entries;
ModeDescriptionRef head = mp;
......@@ -1144,8 +1193,8 @@ static ModeDescriptionRef find_by_xy (ModeDescriptionRef mp,
{
++entries;
mp = mp->next;
} while (mp && mp->definition.hpar[FR_DISP] == xres &&
mp->definition.vpar[FR_DISP] == yres);
} while (mp && mp->definition.xres == xres &&
mp->definition.yres == yres);
*count = entries;
return head;
}
......@@ -1160,10 +1209,15 @@ static int restrict_bandwidth (int os_limit)
* (but zero means no limit)
*/
if (bandwidth_limit == 0 || os_limit < bandwidth_limit)
/* if (bandwidth_limit == 0 || os_limit < bandwidth_limit)
return os_limit;
else
return bandwidth_limit;
--Commented out by WT 1-8-95 so that 'Turbo' Krytens can be tried (they have
a higher bandwidth & it is inconvenient to reblow ROMs every time. Whether this
becomes a permanent change or not remains to be seen.
*/
if (bandwidth_limit == 0) return os_limit;
else return bandwidth_limit;
}
static void service_modeextension (_kernel_swi_regs *regs)
......@@ -1190,6 +1244,11 @@ static void service_modeextension (_kernel_swi_regs *regs)
* If no list is necessary, the 1st word holds -1.
* If a list is necessary, the 1st word holds DPMS_INDEX, the 2nd
* holds the dpms value, and the 3rd word holds -1.
*
* WT 19-Jan-95 - The parameters list is extended to cater for LCD
* panels, both single and dual panel, as defined in the LCD_support
* field of the mode definition file. So, now 6 words are statically
* allocated.
*/
static VIDCList thevidclist;
......@@ -1197,6 +1256,7 @@ static void service_modeextension (_kernel_swi_regs *regs)
ModeDescriptionRef mp;
uns32 dataratelimit, datasizelimit;
int nmodes;
int ctrllistpos = 0;
/*
* Check for being passed a mode selector as opposed to a mode
......@@ -1265,16 +1325,42 @@ static void service_modeextension (_kernel_swi_regs *regs)
}
vp->pixelrate = mp->definition.pixel_khz;
vp->syncpol = mp->definition.syncpol;
if (current_monitor->dpms_state == -1)
{
vp->vcparam[0].index = -1; /* terminator - no extra video control parameters */
if (current_monitor->dpms_state != -1) {
vp->vcparam[ctrllistpos].index = DPMS_INDEX;
vp->vcparam[ctrllistpos].value = current_monitor->dpms_state;
ctrllistpos++;
}
else
{
vp->vcparam[0].index = DPMS_INDEX;
vp->vcparam[0].value = current_monitor->dpms_state;
vp->vcparam[1].index = -1; /* terminator */
if (current_monitor->lcd_support != 0) {
debug printf("I'm an LCD panel & I'm going to tell the Kernel!\n");
vp->vcparam[ctrllistpos].index = LCDMODE_INDEX;
vp->vcparam[ctrllistpos].value = LCDMODE_VALUE;
ctrllistpos++;
if (current_monitor->lcd_support != 3) {
vp->vcparam[ctrllistpos].index = LCDDUAL_INDEX;
vp->vcparam[ctrllistpos].value = LCDDUAL_VALUE;
ctrllistpos++;
}
vp->vcparam[ctrllistpos].index = LCDOFF0_INDEX;
vp->vcparam[ctrllistpos].value = LCDOFF0_VALUE;
ctrllistpos++;
vp->vcparam[ctrllistpos].index = LCDOFF1_INDEX;
vp->vcparam[ctrllistpos].value = LCDOFF1_VALUE;
ctrllistpos++;
vp->vcparam[ctrllistpos].index = DACCTRL_INDEX;
vp->vcparam[ctrllistpos].value = DACCTRL_VALUE;
ctrllistpos++;
}
if (mp->definition.interlaced) {
vp->vcparam[ctrllistpos].index = INTERLACED_INDEX;
vp->vcparam[ctrllistpos].value = 1;
ctrllistpos++;
}
vp->vcparam[ctrllistpos].index = -1; /* List terminator */
/* Now modify the register set to reflect servicing the call */
regs->r[1] = 0; /* Service_Serviced */
regs->r[3] = (int)vp; /* return pointer to vidc list */
......@@ -1310,7 +1396,7 @@ static void service_enumeratescreenmodes (_kernel_swi_regs *regs)
* Code used to set depth to 5 here, assuming that if the mode
* was invalid at a low depth, it would be invalid at all higher
* depths. This is a wrong assumption when a mode can fail because
* the length of the line is not a multiple of 1 word.
* the length of the line is not a suitable multiple.
*/
}
else
......@@ -1335,8 +1421,8 @@ static void service_enumeratescreenmodes (_kernel_swi_regs *regs)
/* Copy the mode information into the supplied data buffer */
ip->blocksize = entrysize;
ip->format = 0; ip->flags = 0; ip->bit0 = 1;
ip->xresol = mp->definition.hpar[FR_DISP];
ip->yresol = mp->definition.vpar[FR_DISP];
ip->xresol = mp->definition.xres;
ip->yresol = mp->definition.yres;
ip->depth = depth; /* log2 (bits/pixel) */
ip->framerate = mp->frame_hz; /* integer Hz value used here */
......
......@@ -16,7 +16,7 @@
; Screen Modes module
;
help-string: Screen_Modes 0.13
help-string: Screen_Modes 0.19
title-string: ScreenModes
......
......@@ -18,6 +18,7 @@
* Internal definitions used by ScreenModes module.
*/
/*
* The 6 field framing parameters for each direction, horizontal and
* vertical. In horizontal case, the parameters are measured in VIDC
......@@ -35,7 +36,21 @@
* The video control list parameter index for indicating DPMS state
*/
#define DPMS_INDEX 11
/**Added by WT 13-1-95 for Stork **/
#define LCDMODE_INDEX 01
#define LCDMODE_VALUE 1 /*Enable*/
#define LCDDUAL_INDEX 02
#define LCDDUAL_VALUE 1 /*Enable*/
#define LCDOFF0_INDEX 03
#define LCDOFF0_VALUE 6 /*Defining a 640x480 dual-panel LCD as used in Stork*/
#define LCDOFF1_INDEX 04
#define LCDOFF1_VALUE 129 /*Defining a 640x480 dual-panel LCD as used in Stork*/
#define DACCTRL_INDEX 06
#define DACCTRL_VALUE 1 /*Enable - testing only*/
/**End of additions**/
#define DPMS_INDEX 11
#define INTERLACED_INDEX 12
/* Two-word structure in a mode selector or VIDC list */
......@@ -64,7 +79,9 @@ typedef struct
uns32 vpar[FR__COUNT]; /* vertical parameters */
uns32 pixelrate; /* pixel rate measured in kHz */
uns32 syncpol:2, :0; /* sync polarity code, 0..3 */
ModeParam vcparam[2]; /* holds either just -1 terminator, or (DPMS_index, DPMS_value), -1 */
ModeParam vcparam[8]; /* Holds VCparameters: LCD mode, LCD dual-panel, LCD offsets(2), DAC control, -1
* with optional DPMS and/or Interlaced fields
*/
} VIDCList, *VIDCListRef;
/* Mode information block as filled in when handling Service_EnumerateScreenModes */
......@@ -94,11 +111,14 @@ typedef struct
typedef struct
{
char name[MAXMODENAME+1];
uns32 xres; /* User quoted xres (may differ from hpar[FR_DISP], especially in interlaced modes) */
uns32 yres; /* User quoted yres (may differ from vpar[FR_DISP], ... */
uns16 hpar[FR__COUNT]; /* H. framing in vidc pixel times */
uns16 vpar[FR__COUNT]; /* V. framing in vidc raster times */
uns32 pixel_khz; /* vidc pixel rate in kHz */
uns8 syncpol; /* sync polarity code (0..3 for now) */
uns8 spare1, spare2, spare3; /* explicit padding so struct is N*4 bytes long */
uns8 interlaced; /* whether mode is interlaced (0 or 1) */
uns8 spare1, spare2; /* explicit padding so struct is N*4 bytes long */
} ModeDefinition;
/* As stored internally by ScreenModes module */
......@@ -119,6 +139,7 @@ typedef struct
char name[MAXMONITORNAME];
ModeDescriptionRef modelist;
uns32 dpms_state; /* value specified by DPMS_state keyword, or 0 if none */
uns32 lcd_support; /* 0=>modefile is CRT, 1=>LCD single-panel, 2=>LCD dual panel [WT13-01-95] */
} MonitorDescription, *MonitorDescriptionRef;
/* EOF modex.h */
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