📄 cim_df.c
字号:
src = (fbactive & 0xFFFF) + 1;
if (scale != 0x4000)
{
height_copy = height_copy * (((0x4000 * src) / scale) + 1);
height_copy /= src;
y_copy = y_copy * (((0x4000 * src) / scale) + 1);
y_copy /= src;
}
}
/* SET PRIORITY */
/* Priority is the only alpha parameter that is not in a register that */
/* can be indexed based on the alpha window number. */
pos = 16 + (window << 1);
alpha_ctl = READ_VID32 (DF_VID_ALPHA_CONTROL) & ~(3L << pos);
alpha_ctl |= (alpha_data->priority & 3) << pos;
WRITE_VID32 (DF_VID_ALPHA_CONTROL, alpha_ctl);
/* HANDLE INTERLACED MODES */
if (READ_REG32 (DC3_IRQ_FILT_CTL) & DC3_IRQFILT_INTL_EN)
{
vsyncend_even = ((READ_REG32 (DC3_V_SYNC_EVEN) >> 16) & 0xFFF) + 1;
vtotal_even = ((READ_REG32 (DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1;
vactive_even = (READ_REG32 (DC3_V_ACTIVE_EVEN) & 0xFFF) + 1;
y = y_copy >> 1;
/* SET Y POSITION FOR ODD FIELD */
height = (height_copy + 1) >> 1;
vadjust = vtotal_even - vsyncend_even + 1;
ystart = y + vadjust;
yend = y + vadjust + height;
if (yend > (vactive + vadjust))
yend = vactive + vadjust;
WRITE_VID32 ((DF_ALPHA_YPOS_1 + (window << 5)), (ystart | (yend << 16)));
/* SET Y POSITION FOR EVEN FIELD */
height = height_copy >> 1;
vadjust = vtotal - vsyncend + 1;
ystart = y + vadjust;
yend = y + vadjust + height;
if (yend > (vactive_even + vadjust))
yend = vactive_even + vadjust;
WRITE_VID32 ((DF_VID_ALPHA_Y_EVEN_1 + (window << 3)), (ystart | (yend << 16)));
}
else
{
y = y_copy;
height = height_copy;
vadjust = vtotal - vsyncend + 1;
ystart = y + vadjust;
yend = y + vadjust + height;
if (yend > (vactive + vadjust))
yend = vactive + vadjust;
WRITE_VID32 ((DF_ALPHA_YPOS_1 + (window << 5)), (ystart | (yend << 16)));
}
/* SET ALPHA X POSITION */
/* The x position is the same for both the odd and even fields. */
hadjust = htotal - hsyncend - 2;
xstart = x_copy + hadjust;
xend = x_copy + hadjust + width_copy;
if (xend > (hactive + hadjust))
xend = hactive + hadjust;
WRITE_VID32 ((DF_ALPHA_XPOS_1 + (window << 5)), (xstart | (xend << 16)));
/* SET COLOR REGISTER */
color = alpha_data->color & 0xFFFFFF;
if (alpha_data->flags & DF_ALPHAFLAG_COLORENABLED)
color |= DF_ALPHA_COLOR_ENABLE;
WRITE_VID32 ((DF_ALPHA_COLOR_1 + (window << 5)), color);
/* SET ALPHA VALUE, DELTA AND PER PIXEL */
alpha_ctl = READ_VID32 (DF_ALPHA_CONTROL_1 + (window << 5)) & DF_ACTRL_WIN_ENABLE;
alpha_ctl |= (alpha_data->alpha_value & 0xFF) | DF_ACTRL_LOAD_ALPHA |
(((unsigned long)alpha_data->delta & 0xFF) << 8);
if (alpha_data->flags & DF_ALPHAFLAG_PERPIXELENABLED)
alpha_ctl |= DF_ACTRL_PERPIXEL_EN;
WRITE_VID32 ((DF_ALPHA_CONTROL_1 + (window << 5)), alpha_ctl);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* df_set_alpha_window_enable
*
* This routine enables or disables one of the three hardware alpha regions.
*--------------------------------------------------------------------------*/
int df_set_alpha_window_enable (int window, int enable)
{
unsigned long alpha_ctl;
if (window > 2)
return CIM_STATUS_INVALIDPARAMS;
alpha_ctl = READ_VID32 (DF_ALPHA_CONTROL_1 + (window << 5));
if (enable) alpha_ctl |= DF_ACTRL_WIN_ENABLE;
else alpha_ctl &= ~DF_ACTRL_WIN_ENABLE;
WRITE_VID32 ((DF_ALPHA_CONTROL_1 + (window << 5)), alpha_ctl);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* df_set_no_ck_outside_alpha
*
* This function affects how color/chroma keying is performed inside the video
* window.
*
* If enable is 1, color/chroma key comparison is performed only inside
* the enabled alpha windows. Outside the enabled alpha windows, video
* is displayed if color keying is enabled, or graphics is displayed if
* chroma keying is enabled.
* If enable is 0, color/chroma key comparison is performed inside the
* entire video window.
*--------------------------------------------------------------------------*/
int df_set_no_ck_outside_alpha (int enable)
{
unsigned long value;
value = READ_VID32 (DF_VID_ALPHA_CONTROL);
if (enable) value |= DF_NO_CK_OUTSIDE_ALPHA;
else value &= ~DF_NO_CK_OUTSIDE_ALPHA;
WRITE_VID32 (DF_VID_ALPHA_CONTROL, value);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* df_set_video_request
*
* This routine sets the horizontal (pixel) and vertical (line) video request
* values.
*--------------------------------------------------------------------------*/
int df_set_video_request (unsigned long x, unsigned long y)
{
unsigned long htotal, hsyncend;
unsigned long vtotal, vsyncend;
hsyncend = ((READ_REG32 (DC3_H_SYNC_TIMING) >> 16) & 0xFFF) + 1;
vsyncend = ((READ_REG32 (DC3_V_SYNC_TIMING) >> 16) & 0xFFF) + 1;
htotal = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
vtotal = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
/* SET DISPLAY FILTER VIDEO REQUEST */
x += htotal - hsyncend - 2;
y += vtotal - vsyncend + 1;
if (x >= 0x1000 || y >= 0x800)
return CIM_STATUS_INVALIDPARAMS;
WRITE_VID32(DF_VIDEO_REQUEST, (y | (x << 16)));
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* df_set_output_color_space
*
* This routine sets the color space used when combining graphics and video.
*--------------------------------------------------------------------------*/
int df_set_output_color_space (int color_space)
{
unsigned long alpha_ctl;
alpha_ctl = READ_VID32 (DF_VID_ALPHA_CONTROL);
alpha_ctl &= ~(DF_CSC_GRAPHICS_RGB_TO_YUV | DF_CSC_VIDEO_YUV_TO_RGB |
DF_HD_GRAPHICS | DF_YUV_CSC_EN | DF_ALPHA_DRGB);
/* OUTPUT IS RGB */
/* Enable YUV->RGB CSC if necessary and enable alpha output if */
/* requested. */
if (color_space == DF_OUTPUT_RGB || color_space == DF_OUTPUT_ARGB)
{
if (!(alpha_ctl & DF_VIDEO_INPUT_IS_RGB))
alpha_ctl |= DF_CSC_VIDEO_YUV_TO_RGB;
if (color_space == DF_OUTPUT_ARGB)
alpha_ctl |= DF_ALPHA_DRGB;
}
/* OUTPUT IS YUV */
/* Enable YUV->YUV CSC if necessary and enable RGB->YUV CSC. */
else if (color_space == DF_OUTPUT_SDTV || color_space == DF_OUTPUT_HDTV)
{
alpha_ctl |= DF_CSC_GRAPHICS_RGB_TO_YUV;
if ( ((alpha_ctl & DF_HD_VIDEO) && color_space == DF_OUTPUT_SDTV) ||
(!(alpha_ctl & DF_HD_VIDEO) && color_space == DF_OUTPUT_HDTV))
{
alpha_ctl |= DF_YUV_CSC_EN;
}
if (color_space == DF_OUTPUT_HDTV)
alpha_ctl |= DF_HD_GRAPHICS;
}
else
return CIM_STATUS_INVALIDPARAMS;
WRITE_VID32 (DF_VID_ALPHA_CONTROL, alpha_ctl);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* df_set_output_path
*
* This routine changes the current output path in the display filter.
*--------------------------------------------------------------------------*/
int df_set_output_path (int format)
{
unsigned long panel_tim2, panel_pm;
unsigned long output = 0;
Q_WORD msr_value;
msr_read64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
msr_value.low &= ~(DF_SIMULTANEOUS_CRT_FP | DF_CONFIG_OUTPUT_MASK);
panel_tim2 = READ_VID32 (DF_VIDEO_PANEL_TIM2);
panel_pm = READ_VID32 (DF_POWER_MANAGEMENT);
if (format == DF_DISPLAY_CRT)
{
/* SiBZ #4188 */
/* When CRT output is selected, the DF drives the DISP_EN signal */
/* with the CRT display enable. As a consequence, systems that */
/* wire the DISP_EN signal to the TFT backlight control will not */
/* be able to set CRT-only output without leaving the backlight */
/* enabled. To workaround this issue, we are setting simultaneous */
/* TFT/CRT and disabling the TFT logic. The only caveat to this */
/* is that some TFT pins are shared with VIP 601 pins. VIP 601 */
/* will thus not work when in this pseudo-CRT mode. To address */
/* THAT issue, normal CRT mode sets (in cim_vg.c) will set CRT */
/* as the DF output format. This will allow VIP 601 on CRT-only */
/* systems without a TFT attached. */
panel_pm &= ~DF_PM_PANEL_ON;
panel_tim2 |= DF_PMTIM2_TFT_PASSHTHROUGH;
output = DF_OUTPUT_PANEL | DF_SIMULTANEOUS_CRT_FP;
}
else if (format == DF_DISPLAY_FP || format == DF_DISPLAY_CRT_FP)
{
panel_pm |= DF_PM_PANEL_ON;
panel_tim2 &= ~DF_PMTIM2_TFT_PASSHTHROUGH;
if (format == DF_DISPLAY_FP)
output = DF_OUTPUT_PANEL;
else if (format == DF_DISPLAY_CRT_FP)
output = DF_OUTPUT_PANEL | DF_SIMULTANEOUS_CRT_FP;
}
else
{
switch (format)
{
case DF_DISPLAY_VOP: output = DF_OUTPUT_VOP; break;
case DF_DISPLAY_DRGB: output = DF_OUTPUT_DRGB; break;
case DF_DISPLAY_CRT_DRGB: output = DF_OUTPUT_DRGB | DF_SIMULTANEOUS_CRT_FP; break;
default:
return CIM_STATUS_INVALIDPARAMS;
}
}
msr_value.low |= output;
msr_write64 (MSR_DEVICE_GEODELX_DF, MSR_GEODELINK_CONFIG, &msr_value);
WRITE_VID32 (DF_VIDEO_PANEL_TIM2, panel_tim2);
WRITE_VID32 (DF_POWER_MANAGEMENT, panel_pm);
return CIM_STATUS_OK;
}
/*---------------------------------------------------------------------------
* df_test_video_flip_status
*
* This routine tests if a new video offset has been latched.
*--------------------------------------------------------------------------*/
unsigned long df_test_video_flip_status (void)
{
return (READ_REG32 (DC3_LINE_CNT_STATUS) & DC3_LNCNT_VFLIP);
}
/*---------------------------------------------------------------------------
* df_save_state
*
* This routine saves all persistent DF state information.
*---------------------------------------------------------------------------*/
int df_save_state (DF_SAVE_RESTORE *df_state)
{
unsigned long i;
/* READ ALL DF REGISTERS */
df_state->vcfg = READ_VID32 (DF_VIDEO_CONFIG);
df_state->dcfg = READ_VID32 (DF_DISPLAY_CONFIG);
df_state->video_x = READ_VID32 (DF_VIDEO_X_POS);
df_state->video_y = READ_VID32 (DF_VIDEO_Y_POS);
df_state->video_scaler = READ_VID32 (DF_VIDEO_SCALER);
df_state->video_color_key = READ_VID32 (DF_VIDEO_COLOR_KEY);
df_state->video_color_mask = READ_VID32 (DF_VIDEO_COLOR_MASK);
df_state->sat_limit = READ_VID32 (DF_SATURATION_LIMIT);
df_state->vid_misc = READ_VID32 (DF_VID_MISC);
df_state->video_yscale = READ_VID32 (DF_VIDEO_YSCALE);
df_state->video_xscale = READ_VID32 (DF_VIDEO_XSCALE);
df_state->vid_alpha_control = READ_VID32 (DF_VID_ALPHA_CONTROL);
df_state->cursor_key = READ_VID32 (DF_CURSOR_COLOR_KEY);
df_state->cursor_mask = READ_VID32 (DF_CURSOR_COLOR_MASK);
df_state->cursor_color1 = READ_VID32 (DF_CURSOR_COLOR_1);
df_state->cursor_color2 = READ_VID32 (DF_CURSOR_COLOR_2);
df_state->alpha_xpos1 = READ_VID32 (DF_ALPHA_XPOS_1);
df_state->alpha_ypos1 = READ_VID32 (DF_ALPHA_YPOS_1);
df_state->alpha_color1 = READ_VID32 (DF_ALPHA_COLOR_1);
df_state->alpha_control1 = READ_VID32 (DF_ALPHA_CONTROL_1);
df_state->alpha_xpos2 = READ_VID32 (DF_ALPHA_XPOS_2);
df_state->alpha_ypos2 = READ_VID32 (DF_ALPHA_YPOS_2);
df_state->alpha_color2 = READ_VID32 (DF_ALPHA_COLOR_2);
df_state->alpha_control2 = READ_VID32 (DF_ALPHA_CONTROL_2);
df_state->alpha_xpos3 = READ_VID32 (DF_ALPHA_XPOS_3);
df_state->alpha_ypos3 = READ_VID32 (DF_ALPHA_YPOS_3);
df_state->alpha_color3 = READ_VID32 (DF_ALPHA_COLOR_3);
df_state->alpha_control3 = READ_VID32 (DF_ALPHA_CONTROL_3);
df_state->vid_request = READ_VID32 (DF_VIDEO_REQUEST);
df_state->vid_ypos_even = READ_VID32 (DF_VID_YPOS_EVEN);
df_state->alpha_ypos_even1 = READ_VID32 (DF_VID_ALPHA_Y_EVEN_1);
df_state->alpha_ypos_even2 = READ_VID32 (DF_VID_ALPHA_Y_EVEN_2);
df_state->alpha_ypos_even3 = READ_VID32 (DF_VID_ALPHA_Y_EVEN_3);
df_state->panel_tim1 = READ_VID32 (DF_VIDEO_PANEL_TIM1);
df_state->panel_tim2 = READ_VID32 (DF_VIDEO_PANEL_TIM2);
df_state->panel_pm = READ_VID32 (DF_POWER_MANAGEMENT);
df_state->panel_dither = READ_VID32 (DF_DITHER_CONTROL);
/* READ DF PALETTE */
WRITE_VID32 (DF_PALETTE_ADDRESS, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -