add: ;
context: void Radeon_CalcImpacTVRegisters( 	accelerator_info *ai, display_mode *mode, 	impactv_params *params, impactv_regs *values, int crtc_idx, 	bool internal_encoder, tv_standard_e tv_format, display_device_e display_device ){	const tv_timing *timing = &params->timing;		SHOW_FLOW0( 2, "" );		if( tv_format < ts_ntsc || tv_format > ts_max )		tv_format = ts_ntsc;		values->tv_ftotal = timing->f_total;		// RE: UV_THINNER should affect sharpness only, but the only effect is that	// the colour fades out, so I leave it zero	values->tv_vscaler_cntl1 = RADEON_TV_VSCALER_CNTL1_Y_W_EN;		values->tv_vscaler_cntl1 = 		(values->tv_vscaler_cntl1 & 0xe3ff0000) |		params->uv_inc;			if( internal_encoder ) {		// RE: was on - update: disabling it breaks restart		values->tv_vscaler_cntl1 |= RADEON_TV_VSCALER_CNTL1_RESTART_FIELD;		if( mode->timing.h_display == 1024 )			values->tv_vscaler_cntl1 |= 4 << RADEON_TV_VSCALER_CNTL1_Y_DEL_W_SIG_SHIFT;		else			values->tv_vscaler_cntl1 |= 2 << RADEON_TV_VSCALER_CNTL1_Y_DEL_W_SIG_SHIFT;	} else {		values->tv_vscaler_cntl1 |= 2 << RADEON_TV_VSCALER_CNTL1_Y_DEL_W_SIG_SHIFT;	}		values->tv_y_saw_tooth_cntl =		params->y_saw_tooth_amp |		(params->y_saw_tooth_slope << RADEON_TV_Y_SAW_TOOTH_CNTL_SLOPE_SHIFT);		values->tv_y_fall_cntl =		params->y_fall_accum_init |		RADEON_TV_Y_FALL_CNTL_Y_FALL_PING_PONG |		(params->y_coeff_enable ? RADEON_TV_Y_FALL_CNTL_Y_COEFF_EN : 0) |		(params->y_coeff_value << RADEON_TV_Y_FALL_CNTL_Y_COEFF_VALUE_SHIFT);			values->tv_y_rise_cntl = 		params->y_rise_accum_init |		RADEON_TV_Y_RISE_CNTL_Y_RISE_PING_PONG;	// RE: all dither flags/values were zero	values->tv_vscaler_cntl2 =		(values->tv_vscaler_cntl2 & 0x00fffff0) | 		(params->uv_accum_init << RADEON_TV_VSCALER_CNTL2_UV_ACCUM_INIT_SHIFT);			if( internal_encoder ) {		values->tv_vscaler_cntl2 |= 			RADEON_TV_VSCALER_CNTL2_DITHER_MODE |			RADEON_TV_VSCALER_CNTL2_Y_OUTPUT_DITHER_EN |			RADEON_TV_VSCALER_CNTL2_UV_OUTPUT_DITHER_EN |			RADEON_TV_VSCALER_CNTL2_UV_TO_BUF_DITHER_EN;	}	values->tv_hrestart = params->h_restart;	values->tv_vrestart = params->v_restart;	values->tv_frestart = params->f_restart;		values->tv_tv_pll_cntl = 		(params->tv_dividers.ref & RADEON_TV_PLL_CNTL_TV_M0_LO_MASK) |		((params->tv_dividers.feedback & RADEON_TV_PLL_CNTL_TV_N0_LO_MASK) 			<< RADEON_TV_PLL_CNTL_TV_N0_LO_SHIFT) |		((params->tv_dividers.ref >> RADEON_TV_PLL_CNTL_TV_M0_LO_BITS) 			<< RADEON_TV_PLL_CNTL_TV_M0_HI_SHIFT) |		((params->tv_dividers.feedback >> RADEON_TV_PLL_CNTL_TV_N0_LO_BITS) 			<< RADEON_TV_PLL_CNTL_TV_N0_HI_SHIFT) |		// RE: was on		//RADEON_TV_PLL_CNTL_TV_SLIP_EN |		(params->tv_dividers.post << RADEON_TV_PLL_CNTL_TV_P_SHIFT); //|		// RE: was on		//RADEON_TV_PLL_CNTL_TV_DTO_EN;	values->tv_crt_pll_cntl = 		(params->crt_dividers.ref & RADEON_TV_CRT_PLL_CNTL_M0_LO_MASK) |		((params->crt_dividers.feedback & RADEON_TV_CRT_PLL_CNTL_N0_LO_MASK) 			<< RADEON_TV_CRT_PLL_CNTL_N0_LO_SHIFT) |		((params->crt_dividers.ref >> RADEON_TV_CRT_PLL_CNTL_M0_LO_BITS) 			<< RADEON_TV_CRT_PLL_CNTL_M0_HI_SHIFT) |		((params->crt_dividers.feedback >> RADEON_TV_CRT_PLL_CNTL_N0_LO_BITS) 			<< RADEON_TV_CRT_PLL_CNTL_N0_HI_SHIFT) |		(params->crt_dividers.extra_post == 2 ? RADEON_TV_CRT_PLL_CNTL_CLKBY2 : 0);	// TK: from Gatos	// in terms of byte clock devider, I have no clue how that works, 	// but leaving it 1 seems to be save	values->tv_clock_sel_cntl = 		0x33 |		((/*params->crt_dividers.post_code - 1*/0) << RADEON_TV_CLOCK_SEL_CNTL_BYTCLK_SHIFT) |		(1 << RADEON_TV_CLOCK_SEL_CNTL_BYTCLKD_SHIFT);        values->tv_clkout_cntl = 0x09;    if( !internal_encoder )    	values->tv_clkout_cntl |= 1 << 5;	values->tv_htotal = mode->timing.h_total - 1;	values->tv_hsize = mode->timing.h_display;	values->tv_hdisp = mode->timing.h_display - 1;	values->tv_hstart =		// TK: was -12, but this cuts off the left border of the image		internal_encoder ? 		values->tv_hdisp + 1 - params->mode888 + 12 :		values->tv_hdisp + 1 - params->mode888 + 12;			values->tv_vtotal = mode->timing.v_total - 1;	values->tv_vdisp = mode->timing.v_display - 1;	values->tv_sync_size = mode->timing.h_display + 8;	values->tv_timing_cntl = 		(values->tv_timing_cntl & 0xfffff000) |		params->h_inc;		if( ai->si->asic >= rt_r300 ) {		// this is a hack to fix improper UV scaling		// (at least this is what the sample code says)		values->tv_timing_cntl =			(values->tv_timing_cntl & 0x00ffffff) |			((0x72 * 640 / mode->timing.h_display) 				<< RADEON_TV_TIMING_CNTL_UV_OUTPUT_POST_SCALE_SHIFT);	}		if( internal_encoder ) {		// tell TV-DAC to generate proper NTSC/PAL signal		values->tv_dac_cntl =			RADEON_TV_DAC_CNTL_NBLANK |			RADEON_TV_DAC_CNTL_NHOLD |			(8 << RADEON_TV_DAC_CNTL_BGADJ_SHIFT) |			(6 << RADEON_TV_DAC_CNTL_DACADJ_SHIFT);					switch( tv_format ) {		case ts_ntsc:			values->tv_dac_cntl |= RADEON_TV_DAC_CNTL_STD_NTSC;			break;					case ts_pal_bdghi:		case ts_pal_m:		case ts_pal_nc:		case ts_scart_pal:		case ts_pal_60:			values->tv_dac_cntl |= RADEON_TV_DAC_CNTL_STD_PAL;			break;		default:		}				// enable composite or S-Video DAC		values->tv_dac_cntl |=			RADEON_TV_DAC_CNTL_RDACPD |			RADEON_TV_DAC_CNTL_GDACPD |			RADEON_TV_DAC_CNTL_BDACPD;					if( (display_device & dd_ctv) != 0 ) {			values->tv_dac_cntl &=				~RADEON_TV_DAC_CNTL_BDACPD;		}				if( (display_device & dd_stv) != 0 ) {			values->tv_dac_cntl &= 				~(RADEON_TV_DAC_CNTL_RDACPD |				  RADEON_TV_DAC_CNTL_GDACPD);		}	} else {		values->tv_dac_cntl =			(values->tv_dac_cntl & ~(RADEON_TV_DAC_CNTL_STD_NTSC | 0x88 | 				RADEON_TV_DAC_CNTL_BGSLEEP | RADEON_TV_DAC_CNTL_PEDESTAL)) |			RADEON_TV_DAC_CNTL_DETECT | 			RADEON_TV_DAC_CNTL_NBLANK |			RADEON_TV_DAC_CNTL_NHOLD;	}	values->tv_modulator_cntl1 &= ~(		RADEON_TV_MODULATOR_CNTL1_ALT_PHASE_EN | 		RADEON_TV_MODULATOR_CNTL1_SYNC_TIP_LEVEL | 		RADEON_TV_MODULATOR_CNTL1_SET_UP_LEVEL_MASK | 		RADEON_TV_MODULATOR_CNTL1_BLANK_LEVEL_MASK);				switch( tv_format ) {	case ts_ntsc:		// RE: typo?		//values->tv_dac_cntl |=		values->tv_modulator_cntl1 |= 			RADEON_TV_MODULATOR_CNTL1_SYNC_TIP_LEVEL |			(0x46 << RADEON_TV_MODULATOR_CNTL1_SET_UP_LEVEL_SHIFT) |			(0x3b << RADEON_TV_MODULATOR_CNTL1_BLANK_LEVEL_SHIFT);		values->tv_modulator_cntl2 = 			(-111 & TV_MODULATOR_CNTL2_U_BURST_LEVEL_MASK) |			((0 & TV_MODULATOR_CNTL2_V_BURST_LEVEL_MASK) << TV_MODULATOR_CNTL2_V_BURST_LEVEL_SHIFT);		break;			case ts_pal_bdghi:		values->tv_modulator_cntl1 |= 			RADEON_TV_MODULATOR_CNTL1_ALT_PHASE_EN |			RADEON_TV_MODULATOR_CNTL1_SYNC_TIP_LEVEL |			(0x3b << RADEON_TV_MODULATOR_CNTL1_SET_UP_LEVEL_SHIFT) |			(0x3b << RADEON_TV_MODULATOR_CNTL1_BLANK_LEVEL_SHIFT);		values->tv_modulator_cntl2 = 			(-78 & TV_MODULATOR_CNTL2_U_BURST_LEVEL_MASK) |			((62 & TV_MODULATOR_CNTL2_V_BURST_LEVEL_MASK) << TV_MODULATOR_CNTL2_V_BURST_LEVEL_SHIFT);		break;			case ts_scart_pal:		// from register spec		values->tv_modulator_cntl1 |= 			RADEON_TV_MODULATOR_CNTL1_ALT_PHASE_EN |			RADEON_TV_MODULATOR_CNTL1_SYNC_TIP_LEVEL;		values->tv_modulator_cntl2 = 			(0 & TV_MODULATOR_CNTL2_U_BURST_LEVEL_MASK) |			((0 & TV_MODULATOR_CNTL2_V_BURST_LEVEL_MASK) << TV_MODULATOR_CNTL2_V_BURST_LEVEL_SHIFT);		break;		    default:		// there are many formats missing, sigh...    }        // RE:    values->tv_modulator_cntl1 |=    	RADEON_TV_MODULATOR_CNTL1_YFLT_EN |    	RADEON_TV_MODULATOR_CNTL1_UVFLT_EN |    	RADEON_TV_MODULATOR_CNTL1_SLEW_RATE_LIMIT |    	(2 << RADEON_TV_MODULATOR_CNTL1_CY_FILT_BLEND_SHIFT);	if( internal_encoder ) {		values->tv_data_delay_a = 0x0b0c0a06;		values->tv_data_delay_b = 0x070a0a0c;	} else {		values->tv_data_delay_a = 0x07080604;		values->tv_data_delay_b = 0x03070607;	}		values->tv_frame_lock_cntl = internal_encoder ? 0 : 0xf0f;	if( internal_encoder ) {		values->tv_pll_cntl1 = 			(4 << RADEON_TV_PLL_CNTL1_TVPCP_SHIFT) |			(4 << RADEON_TV_PLL_CNTL1_TVPVG_SHIFT) |			// RE: was 2			(1 << RADEON_TV_PLL_CNTL1_TVPDC_SHIFT) |			RADEON_TV_PLL_CNTL1_TVCLK_SRC_SEL_TVPLLCLK |			RADEON_TV_PLL_CNTL1_TVPLL_TEST;					values->tv_rgb_cntl = 			((crtc_idx == 1 ? 2 : 0) << RADEON_TV_RGB_CNTL_RGB_SRC_SEL_SHIFT) |			RADEON_TV_RGB_CNTL_RGB_DITHER_EN |			(0xb << RADEON_TV_RGB_CNTL_UVRAM_READ_MARGIN_SHIFT) |			(7 << RADEON_TV_RGB_CNTL_FIFORAM_FIFOMACRO_READ_MARGIN_SHIFT);					// RE:		values->tv_rgb_cntl |= 0x4000000;					values->tv_pre_dac_mux_cntl = 			RADEON_TV_PRE_DAC_MUX_CNTL_Y_RED_EN |			RADEON_TV_PRE_DAC_MUX_CNTL_C_GRN_EN |			RADEON_TV_PRE_DAC_MUX_CNTL_CMP_BLU_EN |			RADEON_TV_PRE_DAC_MUX_CNTL_DAC_DITHER_EN;				// RE:			/* |			(0x2c << RADEON_TV_PRE_DAC_MUX_CNTL_FORCE_DAC_DATA_SHIFT);*/	} else {		// this register seems to have completely different meaning on Theatre chip		values->tv_pll_cntl1 =			(1 << 3) | (1 << 4) | (4 << 8) | (1 << 11)		    | (5 << 13) | (4 << 16) | (1 << 19) | (5 << 21);		    		// this one too		values->tv_rgb_cntl = params->mode888;				values->tv_pre_dac_mux_cntl = 			RADEON_TV_PRE_DAC_MUX_CNTL_Y_RED_EN |			RADEON_TV_PRE_DAC_MUX_CNTL_C_GRN_EN |			RADEON_TV_PRE_DAC_MUX_CNTL_CMP_BLU_EN |			RADEON_TV_PRE_DAC_MUX_CNTL_DAC_DITHER_EN;			// RE:			/*(0xaf << RADEON_TV_PRE_DAC_MUX_CNTL_FORCE_DAC_DATA_SHIFT);*/	}		values->tv_pll_fine_cntl = 0;		// TBD: this is certainly broken 	// (they do an ((orig & 0xe0) & 0x600) which is constant zero)	values->tv_master_cntl = 		RADEON_TV_MASTER_CNTL_CRT_FIFO_CE_EN |		RADEON_TV_MASTER_CNTL_TV_FIFO_CE_EN;	if( tv_format == ts_ntsc )		values->tv_master_cntl |= RADEON_TV_MASTER_CNTL_RESTART_PHASE_FIX;	else		values->tv_master_cntl &= ~RADEON_TV_MASTER_CNTL_RESTART_PHASE_FIX;			// this is missing in the sample code	if( internal_encoder )		values->tv_master_cntl |= RADEON_TV_MASTER_CNTL_TV_ON;	else		values->tv_master_cntl |= 			RADEON_TV_MASTER_CNTL_RESTART_PHASE_FIX | // RE: guessed						RADEON_TV_MASTER_CNTL_VIN_ASYNC_RST |			RADEON_TV_MASTER_CNTL_AUD_ASYNC_RST |			RADEON_TV_MASTER_CNTL_DVS_ASYNC_RST;		values->tv_gain_limit_settings = 0x017f05ff;	values->tv_linear_gain_settings = 0x01000100;	values->tv_upsamp_and_gain_cntl = 0x00000005;	values->tv_crc_cntl = 0;		SHOW_FLOW( 2, "tv_master_cntl=%x", values->tv_master_cntl );	memcpy( values->tv_upsample_filter_coeff, std_upsample_filter_coeff, 		RADEON_TV_UPSAMP_COEFF_NUM * sizeof( uint32 ));	// setup output timing		memcpy( values->tv_hor_timing, hor_timings[tv_format-1], 		RADEON_TV_TIMING_SIZE * sizeof( uint16 ));	memcpy( values->tv_vert_timing, vert_timings[tv_format-1], 		RADEON_TV_TIMING_SIZE * sizeof( uint16 ) );		// arbitrary position of vertical timing table in FIFO	values->tv_uv_adr = TV_UV_ADR_INI;}