📄 thresher.cpp
字号:
if(video_mode == VIDEO_MODE_NTSC)
{
initializeRegisters_NTSC();
}
else if(video_mode == VIDEO_MODE_SECAM)
{
initializeRegisters_SECAM();
}
else if(video_mode == VIDEO_MODE_PAL_N)
{
initializeRegisters_PAL_N();
}
else if(video_mode == VIDEO_MODE_PAL_NC)
{
initializeRegisters_PAL_NC();
}
else
{
initializeRegisters_PAL();
}
// Handle any MODE_CTRL overrides
do_MODE_CTRL_overrides();
}
/////////////////////////////////////////////////////////////////////////////////////////
VOID Thresher::setResolution(ULONG width, ULONG height)
{
_width = width;
_height = height;
// Note: This function appears to set only the width. The
// height is set when it is put into PAL or NTSC mode.
// This is calculated as: (720/width - 1)*2^20
// or ((720 - width)*2^20)/width (doesn't require floating point)
const DWORD MAX_WIDTH = 720;
// validate the width - cannot be negative
if (width > MAX_WIDTH)
{
DbgLogWarn(("Thresher::setResolution : width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH \n", width, MAX_WIDTH));
_width = width = MAX_WIDTH;
}
DWORD hscale = ((MAX_WIDTH-width)*(0x00100000))/width;
hscale &= 0x00FFFFFF;
_p_registers->writeDword(HSCALE_CTRL, hscale);
// Vertical scaling = 2^16 - (scaling ratio - 1)*2^9
// This is calculated as 2^16 - (max_height/height - 1)*2^9
// or 2^16 - ((max_height - height)*2^9)/height (doesn't require floating point)
DWORD MAX_HEIGHT = 480;
if (_video_mode == VIDEO_MODE_NTSC)
MAX_HEIGHT = 480;
else
MAX_HEIGHT = 576;
// validate the height - cannot be negative
if (height > MAX_HEIGHT)
{
DbgLogWarn(("Thresher::setResolution : height %d > MAX_HEIGHT %d ! resetting to MAX_HEIGHT \n", height, MAX_HEIGHT));
_height = height = MAX_HEIGHT;
}
DWORD vscale = 0x00010000 - ((MAX_HEIGHT-height)*0x00000200)/height;
vscale &= 0x00001FFF;
_p_registers->writeDword(VSCALE_CTRL, vscale);
DbgLogInfo(("Thresher::setResolution : hscale = 0x%x, vscale = 0x%x\n", hscale, vscale));
}
/////////////////////////////////////////////////////////////////////////////////////////
VOID Thresher::waitForLock()
{
//not used, same as corona
}
/////////////////////////////////////////////////////////////////////////////////////////
BOOLEAN Thresher::setBrightness(INT brightness)
{
if((brightness > VIDEO_PROCAMP_MAX) || (brightness < VIDEO_PROCAMP_MIN))
{
return FALSE;
}
_brightness = brightness;
INT new_brightness = 0;
map(
VIDEO_PROCAMP_MIN,
VIDEO_PROCAMP_MAX,
brightness,
SIGNED_BYTE_MIN,
SIGNED_BYTE_MAX,
&new_brightness);
_preserved_brightness = static_cast<BYTE>(new_brightness);
if(!_video_muted)
{
_p_registers->writeByte(BRIGHTNESS_CTRL_BYTE, _preserved_brightness);
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
BOOLEAN Thresher::setContrast(INT contrast)
{
if((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN))
{
return FALSE;
}
_contrast = contrast;
INT new_contrast = 0;
map(
VIDEO_PROCAMP_MIN,
VIDEO_PROCAMP_MAX,
contrast,
UNSIGNED_BYTE_MIN,
UNSIGNED_BYTE_MAX,
&new_contrast);
_preserved_contrast = static_cast<BYTE>(new_contrast);
if(!_video_muted)
{
_p_registers->writeByte(CONTRAST_CTRL_BYTE, _preserved_contrast);
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
BOOLEAN Thresher::setHue(INT hue)
{
if((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN))
{
return FALSE;
}
_hue = hue;
INT new_hue = 0;
map(
VIDEO_PROCAMP_MIN,
VIDEO_PROCAMP_MAX,
hue,
SIGNED_BYTE_MIN,
SIGNED_BYTE_MAX,
&new_hue);
_p_registers->writeByte(HUE_CTRL_BYTE, (BYTE) new_hue);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
BOOLEAN Thresher::setSaturation(INT saturation)
{
if((saturation > VIDEO_PROCAMP_MAX) || (saturation < VIDEO_PROCAMP_MIN))
{
return FALSE;
}
_saturation = saturation;
INT new_saturation = 0;
map(
VIDEO_PROCAMP_MIN,
VIDEO_PROCAMP_MAX,
saturation,
UNSIGNED_BYTE_MIN,
UNSIGNED_BYTE_MAX,
&new_saturation);
_preserved_saturation = static_cast<BYTE>(new_saturation);
if(!_video_muted)
{
_p_registers->writeByte(USAT_CTRL_BYTE, _preserved_saturation);
_p_registers->writeByte(VSAT_CTRL_BYTE, _preserved_saturation);
}
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
BOOLEAN Thresher::setSharpness(INT sharpness)
{
if((sharpness > VIDEO_PROCAMP_MAX) || (sharpness < VIDEO_PROCAMP_MIN))
{
return FALSE;
}
_sharpness = sharpness;
INT new_sharpness = 0;
map(
0,
100,
sharpness,
0,
4,
&new_sharpness);
//These are in order from least sharp to most sharp
BYTE sharpness_mappings[5] =
{
0x00, // sharpness enhancement (aka luma peaking) disabled
0x04, // +2.0dB response @ center freq
0x05, // +3.5dB response @ center freq
0x06, // +5.0dB response @ center freq
0x07 // +6.0dB response @ center freq
};
_p_registers->lock();
BYTE sharp_value;
_p_registers->readByte(LUMA_CTRL_BYTE_3, &sharp_value);
sharp_value &= ~0x07;
sharp_value |= sharpness_mappings[new_sharpness];
_p_registers->writeByte(LUMA_CTRL_BYTE_3, sharp_value);
_p_registers->unlock();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////////////////
VOID Thresher::enableVideoOutput()
{
// not used, same as corona
_p_registers->lock();
_p_registers->writeByte(TS1_PIN_CTL0,0xff);
_p_registers->writeByte(TS1_PIN_CTL1,0x0f);
_p_registers->unlock();
}
/////////////////////////////////////////////////////////////////////////////////////////
VOID Thresher::disableVideoOutput()
{
// not used, same as corona
_p_registers->lock();
DWORD value;
_p_registers->readDword(PIN_CTRL, &value);
//Polaris remove these FLD
//value &= ~(FLD_AGC_OUT_EN | FLD_VID_DATA_OUT_EN | FLD_VID_CTRL_OUT_EN);
_p_registers->writeDword(PIN_CTRL, value);
_p_registers->unlock();
}
/////////////////////////////////////////////////////////////////////////////////////////
// Handle any video-mode specific overrides that are different on a per video standards
// basis after touching the MODE_CTRL register which resets many values for autodetect
//
VOID Thresher::do_MODE_CTRL_overrides()
{
DWORD value = 0;
// Let the standard autodetect do its job before doing any overrides
pauseThread(100);
_p_registers->lock();
// Change the DFE_CTRL3 bp_percent to fix flagging
//_p_registers->readModifyWriteDword(DFE_CTRL3, FLD_DCC_LOOP_GAIN, 0x00 );
// as per Kaelan to improve secam perfermance
_p_registers->writeDword(DFE_CTRL3,0xCD3F0280);
// Rev A CX23888 and all CX23885
switch (_video_mode)
{
case VIDEO_MODE_NTSC:
DbgLog(("do_MODE_CTRL_overrides NTSC\n"));
// Move the close caption lines out of active video, adjust the active video start point
_p_registers->readModifyWriteDword(VERT_TIM_CTRL, FLD_VBLANK_CNT, 0x1A );
_p_registers->readModifyWriteDword(VERT_TIM_CTRL, FLD_VACTIVE_CNT, 0x1E6000 );
_p_registers->readModifyWriteDword(VERT_TIM_CTRL, FLD_V656BLANK_CNT, 0x1E000000 );
_p_registers->readModifyWriteDword(HORIZ_TIM_CTRL, FLD_HBLANK_CNT,_p_registers->Set_Field(FLD_HBLANK_CNT, 0x7F));
break;
case VIDEO_MODE_PAL:
case VIDEO_MODE_PAL_N:
case VIDEO_MODE_PAL_NC:
DbgLog(("do_MODE_CTRL_overrides PAL\n"));
_p_registers->readModifyWriteDword(VERT_TIM_CTRL, FLD_VBLANK_CNT, 0x24 );
// Adjust the active video horizontal start point
_p_registers->readModifyWriteDword(HORIZ_TIM_CTRL, FLD_HBLANK_CNT,_p_registers->Set_Field(FLD_HBLANK_CNT, 0x89));
break;
case VIDEO_MODE_SECAM:
DbgLog(("do_MODE_CTRL_overrides SECAM\n"));
_p_registers->readModifyWriteDword(VERT_TIM_CTRL, FLD_VBLANK_CNT, 0x24 );
// Adjust the active video horizontal start point
_p_registers->readModifyWriteDword(HORIZ_TIM_CTRL, FLD_HBLANK_CNT,_p_registers->Set_Field(FLD_HBLANK_CNT, 0x89));
break;
}
_p_registers->unlock();
}
BOOLEAN Thresher::IsVideoPresent()
{
DWORD gen_stat;
BOOLEAN video_locked;
_p_registers->readDword(GEN_STAT, &gen_stat);
return video_locked = ((gen_stat & FLD_VLOCK) == 0) ? FALSE : TRUE; // VLock
}
BOOLEAN Thresher::GetVideoLock()
{
DWORD gen_stat;
BOOLEAN video_locked;
_p_registers->readDword(GEN_STAT, &gen_stat);
DbgLog(("Thresher::GetVideoLock GEN_STAT = 0x%x\n",gen_stat));
return video_locked =
((gen_stat & FLD_VPRES) && // video present
(gen_stat & FLD_AGC_LOCK)); // AGC Lock
}
DWORD Thresher::caliberateDroopComp()
{
// Poalris do not use Droop comp
return(0);
}
/////////////////////////////////////////////////////////////////////////////////////////
//Thresher::setupHTL_CTRL
//
// Description : If we have to change the default KdKi values 0x0802 (such as for 888/887 tuner
// Input we have to) to something else then we have to make sure that the
// new values are applied after Thresher has got a lock
//
/////////////////////////////////////////////////////////////////////////////////////////
void Thresher::setupHTL_CTRL()
{
if (_video_input == VIDEO_INPUT_TUNER )
{
DWORD oldValue = 0;
DWORD value = 0;
_p_registers->readDword(HTL_CTRL, &oldValue);
// If the value read is not the default
if ((oldValue & 0x0000FFFF) != 0x0802)
{
DWORD counter = 0;
// first set the default
value = oldValue;
value &= 0xFFFF0000; // clear Kd Ki default values
value |= 0x00000802; // change Kd Ki values
_p_registers->writeDword(HTL_CTRL, value);
//Give a delay of about 25ms
pauseThread(25);
// Now if we have VideoLock, then we will set it to the modified value
while (counter < 3)
{
if(!GetVideoLock())
{
// Try again
pauseThread(5);
counter++;
}
else
{
// Got Video lock
_p_registers->writeDword(HTL_CTRL, oldValue);
//bail out
break;
}
} // end of while loop
} // end of If ((oldValue & 0x0000FFFF) != 0x0802) clause
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -