/****************************************************************************
 * DECFUNC.C                                                                *
 *                                                                          *
 * Purpose: Rage Theatre video in decoder functions                         *
 *                                                                          *
 * Copyright (C) 1999 ATI Technologies Inc.  All rights reserved.           *
 ****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
#include "main.h"
#include "defines.h"
#include "regdef.h"

WORD TickCount (void);

/****************************************************************************
 * RT_Init (void)                                                           *
 *  Function: Initializes the Rage Theatre, and sets default video settings *
 *    Inputs: NONE                                                          *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_Init (void)
{
    RT_InitInfoStruct ();
    RT_EnableDecoder ();
    RT_SetConnector (DEC_TUNER, 0);
    RT_SetStandard (RT_NTSC | extNTSC);
    RT_SetInterlace (1);
    RT_SetTint (RT_INFO->iHue);
    RT_SetSaturation (RT_INFO->iSaturation);
    RT_SetBrightness (RT_INFO->iBrightness);
    RT_SetSharpness (DEC_SMOOTH);
    RT_SetContrast (RT_INFO->iContrast);
    RT_SetOutputVideoSize (640, 480, 1, 1);
    return;

} // RT_Init ()...

/****************************************************************************
 * RT_SetTint (int hue)                                                     *
 *  Function: sets the tint (hue) for the Rage Theatre video in             *
 *    Inputs: int hue - the hue value to be set.                            *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_SetTint (int hue)
{
    DWORD nhue;

    // Scale hue value from 0<->200 to -180<->180
    hue = (double)hue * 1.8 - 180;

    // Validate Hue level
    if (hue < -180)
    {
        hue = -180;
    }
    else if (hue > 180)
    {
        hue = 180;
    }

    // save the "validated" hue, but scale it back up to 0<->200
    RT_INFO->iHue = 100 + (double)hue/1.8;

    switch (RT_INFO->wStandard & 0x00FF)
    {
        case (DEC_NTSC):
                            if (hue >= 0)
                            {
                                nhue = (DWORD) (256 * hue)/360;
                            }
                            else
                            {
                                nhue = (DWORD) (256 * (hue + 360))/360;
                            }
                            break;
        case (DEC_PAL):
        case (DEC_SECAM):
                            break;

        default:            break;
    }

    WriteRT_fld (fld_CP_HUE_CNTL, nhue);

    return;

} // RT_SetTint ()...


/****************************************************************************
 * RT_SetSaturation (int Saturation)                                        *
 *  Function: sets the saturation level for the Rage Theatre video in       *
 *    Inputs: int Saturation - the saturation value to be set.              *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_SetSaturation (int Saturation)
{
    WORD   wSaturation_V, wSaturation_U;
    double dbSaturation = 0, dbCrGain = 0, dbCbGain = 0;

    // VALIDATE SATURATION LEVEL
    if (Saturation < 0L)
    {
        Saturation = 0;
    }
    else if (Saturation > 200L)
    {
        Saturation = 200;
    }

    RT_INFO->iSaturation = Saturation;

    if (Saturation > 100)
    {
        // Scale saturation up, to use full allowable register width
        Saturation = (double)(Saturation - 100) * 4.9 + 100;
    }

    dbSaturation = (double) Saturation / 100.0;

    CalculateCrCbGain (&dbCrGain, &dbCbGain, RT_INFO->wStandard);

    wSaturation_U = (WORD) ((dbCrGain * dbSaturation * 128.0) + 0.5);
    wSaturation_V = (WORD) ((dbCbGain * dbSaturation * 128.0) + 0.5);

    // SET SATURATION LEVEL
    WriteRT_fld (fld_CRDR_ACTIVE_GAIN, wSaturation_U);
    WriteRT_fld (fld_CBDB_ACTIVE_GAIN, wSaturation_V);

    RT_INFO->wSaturation_U = wSaturation_U;
    RT_INFO->wSaturation_V = wSaturation_V;

    return;

} // RT_SetSaturation ()...

/****************************************************************************
 * RT_SetBrightness (int Brightness)                                        *
 *  Function: sets the brightness level for the Rage Theatre video in       *
 *    Inputs: int Brightness - the brightness value to be set.              *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_SetBrightness (int Brightness)
{
    double dbSynctipRef0=0, dbContrast=1;

    double dbYgain=0;
    double dbBrightness=0;
    double dbSetup=0;
    WORD   wBrightness=0;

    // VALIDATE BRIGHTNESS LEVEL
    if (Brightness < 0)
    {
        Brightness = 0;
    }
    else if (Brightness > 200)
    {
        Brightness = 200;
    }

    // Save value
    RT_INFO->iBrightness = Brightness;

    RT_INFO->dbBrightnessRatio =  (double) Brightness / 100.0;

    dbBrightness = (double) (Brightness - 100);

    dbSynctipRef0 = ReadRT_fld (fld_SYNCTIP_REF0);

    if(RT_INFO->dbContrast == 0)
    {
        RT_INFO->dbContrast = 1.0; //NTSC default;
    }

    dbContrast = (double) RT_INFO->dbContrast;

    // Use the following formula to determine the brightness level
    switch (RT_INFO->wStandard & 0x00FF)
    {
        case (DEC_NTSC):
            if ((RT_INFO->wStandard & 0xFF00) == extNTSC_J)
            {
                dbYgain = 219.0 / ( 100.0 * (double)(dbSynctipRef0) /40.0);
            }
            else
            {
                dbSetup = 7.5 * (double)(dbSynctipRef0) / 40.0;
                dbYgain = 219.0 / (92.5 * (double)(dbSynctipRef0) / 40.0);
            }
            break;
        case (DEC_PAL):
        case (DEC_SECAM):
            dbYgain = 219.0 / ( 100.0 * (double)(dbSynctipRef0) /43.0);
            break;
        default:
            break;
    }

    wBrightness = (WORD) (16.0 * ((dbBrightness-dbSetup) + (16.0 / (dbContrast * dbYgain))));

    WriteRT_fld (fld_LP_BRIGHTNESS, wBrightness);

    //RT_SetSaturation (RT_INFO->iSaturation);

    return;

} // RT_SetBrightness ()...


/****************************************************************************
 * RT_SetSharpness (WORD wSharpness)                                        *
 *  Function: sets the sharpness level for the Rage Theatre video in        *
 *    Inputs: WORD wSharpness - the sharpness value to be set.              *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_SetSharpness (WORD wSharpness)
{
    switch (wSharpness)
    {
        case DEC_SMOOTH :
            WriteRT_fld (fld_H_SHARPNESS, RT_NORM_SHARPNESS);
            RT_INFO->wSharpness = RT_NORM_SHARPNESS;
            break;
        case DEC_SHARP  :
            WriteRT_fld (fld_H_SHARPNESS, RT_HIGH_SHARPNESS);
            RT_INFO->wSharpness = RT_HIGH_SHARPNESS;
            break;
        default:
            break;
    }
    return;

} // RT_SetSharpness ()...


/****************************************************************************
 * RT_SetContrast (int Contrast)                                            *
 *  Function: sets the contrast level for the Rage Theatre video in         *
 *    Inputs: int Contrast - the contrast value to be set.                  *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_SetContrast (int Contrast)
{
    double dbSynctipRef0=0, dbContrast=0;
    double dbYgain=0;
    BYTE   bTempContrast=0;

    // VALIDATE CONTRAST LEVEL
    if (Contrast < 0)
    {
        Contrast = 0;
    }
    else if (Contrast > 200)
    {
        Contrast = 200;
    }

    // Save contrast value
    RT_INFO->iContrast = Contrast;

    dbSynctipRef0 = ReadRT_fld (fld_SYNCTIP_REF0);
    dbContrast = (double) Contrast / 100.0;

    switch (RT_INFO->wStandard & 0x00FF)
    {
        case (DEC_NTSC):
            if ((RT_INFO->wStandard & 0xFF00) == (extNTSC_J))
            {
                dbYgain = 219.0 / ( 100.0 * (double)(dbSynctipRef0) /40.0);
            }
            else
            {
                dbYgain = 219.0 / ( 92.5 * (double)(dbSynctipRef0) /40.0);
            }
            break;
        case (DEC_PAL):
        case (DEC_SECAM):
            dbYgain = 219.0 / ( 100.0 * (double)(dbSynctipRef0) /43.0);
            break;
        default:
            break;
    }

    bTempContrast = (BYTE) ((dbContrast * dbYgain * 64) + 0.5);

    WriteRT_fld (fld_LP_CONTRAST, (DWORD)bTempContrast);

    // Save value for future modification
    RT_INFO->dbContrast = dbContrast;

    return;

} // RT_SetContrast ()...

/****************************************************************************
 * RT_SetInterlace (BYTE bInterlace)                                        *
 *  Function: to set the interlacing pattern for the Rage Theatre video in  *
 *    Inputs: BYTE bInterlace                                               *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_SetInterlace (BYTE bInterlace)
{

    switch(bInterlace)
     {
        case (TRUE):    //DEC_INTERLACE
                        WriteRT_fld (fld_V_DEINTERLACE_ON, 0x1);
                        RT_INFO->wInterlaced = (WORD) RT_DECINTERLACED;
                        break;
       case (FALSE):    //DEC_NONINTERLACE
                        WriteRT_fld (fld_V_DEINTERLACE_ON, RT_DECNONINTERLACED);
                        RT_INFO->wInterlaced = (WORD) RT_DECNONINTERLACED;
                        break;
       default:
                        break;
     }

    return;

} // RT_SetInterlace ()...


/****************************************************************************
 * RT_SetStandard (WORD wStandard)                                          *
 *  Function: to set the input standard for the Rage Theatre video in       *
 *    Inputs: WORD wStandard - input standard (NTSC, PAL, SECAM)            *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_SetStandard (WORD wStandard)
{
    double dbFsamp=0, dbLPeriod=0, dbFPeriod=0;
    WORD   wFrameTotal = 0;
    double dbSPPeriod = 4.70;

    // Get the constants for the given standard.
    GetStandardConstants (&dbLPeriod, &dbFPeriod, &dbFsamp, wStandard);

    wFrameTotal = (WORD) (((2.0 * dbFPeriod) * 1000 / dbLPeriod) + 0.5);

    // Procedures before setting the standards:
    WriteRT_fld (fld_VIN_CLK_SEL, RT_REF_CLK);
    WriteRT_fld (fld_VINRST, RT_VINRST_RESET);

    RT_SetVINClock (wStandard);

    WriteRT_fld (fld_VINRST, RT_VINRST_ACTIVE);
    WriteRT_fld (fld_VIN_CLK_SEL, RT_PLL_VIN_CLK);

    // Program the new standards:
    switch (wStandard & 0x00FF)
    {
        case (DEC_NTSC): //NTSC GROUP - 480 lines
            WriteRT_fld (fld_STANDARD_SEL,     RT_NTSC);
            WriteRT_fld (fld_SYNCTIP_REF0,     RT_NTSCM_SYNCTIP_REF0);
            WriteRT_fld (fld_SYNCTIP_REF1,     RT_NTSCM_SYNCTIP_REF1);
            WriteRT_fld (fld_CLAMP_REF,         RT_NTSCM_CLAMP_REF);
            WriteRT_fld (fld_AGC_PEAKWHITE,    RT_NTSCM_PEAKWHITE);
            WriteRT_fld (fld_VBI_PEAKWHITE,    RT_NTSCM_VBI_PEAKWHITE);
            WriteRT_fld (fld_WPA_THRESHOLD,    RT_NTSCM_WPA_THRESHOLD);
            WriteRT_fld (fld_WPA_TRIGGER_LO,   RT_NTSCM_WPA_TRIGGER_LO);
            WriteRT_fld (fld_WPA_TRIGGER_HIGH, RT_NTSCM_WPA_TRIGGER_HIGH);
            WriteRT_fld (fld_LOCKOUT_START,    RT_NTSCM_LP_LOCKOUT_START);
            WriteRT_fld (fld_LOCKOUT_END,      RT_NTSCM_LP_LOCKOUT_END);
            WriteRT_fld (fld_CH_DTO_INC,       RT_NTSCM_CH_DTO_INC);
            WriteRT_fld (fld_PLL_SGAIN,        RT_NTSCM_CH_PLL_SGAIN);
            WriteRT_fld (fld_PLL_FGAIN,        RT_NTSCM_CH_PLL_FGAIN);

            WriteRT_fld (fld_CH_HEIGHT,        RT_NTSCM_CH_HEIGHT);
            WriteRT_fld (fld_CH_KILL_LEVEL,    RT_NTSCM_CH_KILL_LEVEL);

            WriteRT_fld (fld_CH_AGC_ERROR_LIM, RT_NTSCM_CH_AGC_ERROR_LIM);
            WriteRT_fld (fld_CH_AGC_FILTER_EN, RT_NTSCM_CH_AGC_FILTER_EN);
            WriteRT_fld (fld_CH_AGC_LOOP_SPEED,RT_NTSCM_CH_AGC_LOOP_SPEED);

            WriteRT_fld (fld_VS_FIELD_BLANK_START,  RT_NTSCM_VS_FIELD_BLANK_START);
            WriteRT_fld (fld_VS_FIELD_BLANK_END,   RT_NTSCM_VS_FIELD_BLANK_END);

            WriteRT_fld (fld_H_ACTIVE_START,   RT_NTSCM_H_ACTIVE_START);
            WriteRT_fld (fld_H_ACTIVE_END,   RT_NTSCM_H_ACTIVE_END);

            WriteRT_fld (fld_V_ACTIVE_START,   RT_NTSCM_V_ACTIVE_START);
            WriteRT_fld (fld_V_ACTIVE_END,   RT_NTSCM_V_ACTIVE_END);

            WriteRT_fld (fld_H_VBI_WIND_START,   RT_NTSCM_H_VBI_WIND_START);
            WriteRT_fld (fld_H_VBI_WIND_END,   RT_NTSCM_H_VBI_WIND_END);

            WriteRT_fld (fld_V_VBI_WIND_START,   RT_NTSCM_V_VBI_WIND_START);
            WriteRT_fld (fld_V_VBI_WIND_END,   RT_NTSCM_V_VBI_WIND_END);

            WriteRT_fld (fld_UV_INT_START,   (BYTE)((0.10 * dbLPeriod * dbFsamp / 2.0) + 0.5 - 32));

            WriteRT_fld (fld_VSYNC_INT_TRIGGER , (WORD) RT_NTSCM_VSYNC_INT_TRIGGER);
            WriteRT_fld (fld_VSYNC_INT_HOLD, (WORD) RT_NTSCM_VSYNC_INT_HOLD);

            switch (wStandard & 0xFF00)
            {
                case (extPAL_M):
                case (extNONE):
                case (extNTSC):
                    WriteRT_fld (fld_CR_BURST_GAIN,        RT_NTSCM_CR_BURST_GAIN);
                    WriteRT_fld (fld_CB_BURST_GAIN,        RT_NTSCM_CB_BURST_GAIN);

                    WriteRT_fld (fld_CRDR_ACTIVE_GAIN,     RT_NTSCM_CRDR_ACTIVE_GAIN);
                    WriteRT_fld (fld_CBDB_ACTIVE_GAIN,     RT_NTSCM_CBDB_ACTIVE_GAIN);

                    WriteRT_fld (fld_VERT_LOCKOUT_START,   RT_NTSCM_VERT_LOCKOUT_START);
                    WriteRT_fld (fld_VERT_LOCKOUT_END,     RT_NTSCM_VERT_LOCKOUT_END);

                    break;
                case (extNTSC_J):
                    WriteRT_fld (fld_CR_BURST_GAIN,        RT_NTSCJ_CR_BURST_GAIN);
                    WriteRT_fld (fld_CB_BURST_GAIN,        RT_NTSCJ_CB_BURST_GAIN);

                    WriteRT_fld (fld_CRDR_ACTIVE_GAIN,     RT_NTSCJ_CRDR_ACTIVE_GAIN);
                    WriteRT_fld (fld_CBDB_ACTIVE_GAIN,     RT_NTSCJ_CBDB_ACTIVE_GAIN);

                    WriteRT_fld (fld_CH_HEIGHT,            RT_NTSCJ_CH_HEIGHT);
                    WriteRT_fld (fld_CH_KILL_LEVEL,        RT_NTSCJ_CH_KILL_LEVEL);

                    WriteRT_fld (fld_CH_AGC_ERROR_LIM,     RT_NTSCJ_CH_AGC_ERROR_LIM);
                    WriteRT_fld (fld_CH_AGC_FILTER_EN,     RT_NTSCJ_CH_AGC_FILTER_EN);
                    WriteRT_fld (fld_CH_AGC_LOOP_SPEED,    RT_NTSCJ_CH_AGC_LOOP_SPEED);

                    WriteRT_fld (fld_VERT_LOCKOUT_START,   RT_NTSCJ_VERT_LOCKOUT_START);
                    WriteRT_fld (fld_VERT_LOCKOUT_END,     RT_NTSCJ_VERT_LOCKOUT_END);

                    break;
                default:
                    break;
            }
            break;
        case (DEC_PAL):  //PAL GROUP  - 525 lines
            WriteRT_fld (fld_STANDARD_SEL,     RT_PAL);
            WriteRT_fld (fld_SYNCTIP_REF0,     RT_PAL_SYNCTIP_REF0);
            WriteRT_fld (fld_SYNCTIP_REF1,     RT_PAL_SYNCTIP_REF1);
            WriteRT_fld (fld_CLAMP_REF,         RT_PAL_CLAMP_REF);
            WriteRT_fld (fld_AGC_PEAKWHITE,    RT_PAL_PEAKWHITE);
            WriteRT_fld (fld_VBI_PEAKWHITE,    RT_PAL_VBI_PEAKWHITE);

            WriteRT_fld (fld_WPA_THRESHOLD,    RT_PAL_WPA_THRESHOLD);
            WriteRT_fld (fld_WPA_TRIGGER_LO,   RT_PAL_WPA_TRIGGER_LO);
            WriteRT_fld (fld_WPA_TRIGGER_HIGH, RT_PAL_WPA_TRIGGER_HIGH);

            WriteRT_fld (fld_LOCKOUT_START,RT_PAL_LP_LOCKOUT_START);
            WriteRT_fld (fld_LOCKOUT_END,  RT_PAL_LP_LOCKOUT_END);
            WriteRT_fld (fld_CH_DTO_INC,       RT_PAL_CH_DTO_INC);
            WriteRT_fld (fld_PLL_SGAIN,        RT_PAL_CH_PLL_SGAIN);
            WriteRT_fld (fld_PLL_FGAIN,        RT_PAL_CH_PLL_FGAIN);

            WriteRT_fld (fld_CR_BURST_GAIN,    RT_PAL_CR_BURST_GAIN);
            WriteRT_fld (fld_CB_BURST_GAIN,    RT_PAL_CB_BURST_GAIN);

            WriteRT_fld (fld_CRDR_ACTIVE_GAIN, RT_PAL_CRDR_ACTIVE_GAIN);
            WriteRT_fld (fld_CBDB_ACTIVE_GAIN, RT_PAL_CBDB_ACTIVE_GAIN);

            WriteRT_fld (fld_CH_HEIGHT,        RT_PAL_CH_HEIGHT);
            WriteRT_fld (fld_CH_KILL_LEVEL,    RT_PAL_CH_KILL_LEVEL);

            WriteRT_fld (fld_CH_AGC_ERROR_LIM, RT_PAL_CH_AGC_ERROR_LIM);
            WriteRT_fld (fld_CH_AGC_FILTER_EN, RT_PAL_CH_AGC_FILTER_EN);
            WriteRT_fld (fld_CH_AGC_LOOP_SPEED,RT_PAL_CH_AGC_LOOP_SPEED);

            WriteRT_fld (fld_VERT_LOCKOUT_START,   RT_PAL_VERT_LOCKOUT_START);
            WriteRT_fld (fld_VERT_LOCKOUT_END, RT_PAL_VERT_LOCKOUT_END);
            WriteRT_fld (fld_VS_FIELD_BLANK_START,  (WORD)RT_PALSEM_VS_FIELD_BLANK_START);

            WriteRT_fld (fld_VS_FIELD_BLANK_END,   RT_PAL_VS_FIELD_BLANK_END);

            WriteRT_fld (fld_H_ACTIVE_START,   RT_PAL_H_ACTIVE_START);
            WriteRT_fld (fld_H_ACTIVE_END,   RT_PAL_H_ACTIVE_END);

            WriteRT_fld (fld_V_ACTIVE_START,   RT_PAL_V_ACTIVE_START);
            WriteRT_fld (fld_V_ACTIVE_END,   RT_PAL_V_ACTIVE_END);

            WriteRT_fld (fld_H_VBI_WIND_START,   RT_PAL_H_VBI_WIND_START);
            WriteRT_fld (fld_H_VBI_WIND_END,   RT_PAL_H_VBI_WIND_END);

            WriteRT_fld (fld_V_VBI_WIND_START,   RT_PAL_V_VBI_WIND_START);
            WriteRT_fld (fld_V_VBI_WIND_END,   RT_PAL_V_VBI_WIND_END);

            WriteRT_fld (fld_UV_INT_START,   (BYTE)( (0.12 * dbLPeriod * dbFsamp / 2.0) + 0.5 - 32 ));

            WriteRT_fld (fld_VSYNC_INT_TRIGGER , (WORD) RT_PALSEM_VSYNC_INT_TRIGGER);
            WriteRT_fld (fld_VSYNC_INT_HOLD, (WORD) RT_PALSEM_VSYNC_INT_HOLD);

            break;
        case (DEC_SECAM):  //PAL GROUP
            WriteRT_fld (fld_STANDARD_SEL,     RT_SECAM);
            WriteRT_fld (fld_SYNCTIP_REF0,     RT_SECAM_SYNCTIP_REF0);
            WriteRT_fld (fld_SYNCTIP_REF1,     RT_SECAM_SYNCTIP_REF1);
            WriteRT_fld (fld_CLAMP_REF,         RT_SECAM_CLAMP_REF);
            WriteRT_fld (fld_AGC_PEAKWHITE,    RT_SECAM_PEAKWHITE);
            WriteRT_fld (fld_VBI_PEAKWHITE,    RT_SECAM_VBI_PEAKWHITE);

            WriteRT_fld (fld_WPA_THRESHOLD,    RT_SECAM_WPA_THRESHOLD);

            WriteRT_fld (fld_WPA_TRIGGER_LO,   RT_SECAM_WPA_TRIGGER_LO);
            WriteRT_fld (fld_WPA_TRIGGER_HIGH, RT_SECAM_WPA_TRIGGER_HIGH);

            WriteRT_fld (fld_LOCKOUT_START,RT_SECAM_LP_LOCKOUT_START);
            WriteRT_fld (fld_LOCKOUT_END,  RT_SECAM_LP_LOCKOUT_END);

            WriteRT_fld (fld_CH_DTO_INC,       RT_SECAM_CH_DTO_INC);
            WriteRT_fld (fld_PLL_SGAIN,        RT_SECAM_CH_PLL_SGAIN);
            WriteRT_fld (fld_PLL_FGAIN,        RT_SECAM_CH_PLL_FGAIN);

            WriteRT_fld (fld_CR_BURST_GAIN,    RT_SECAM_CR_BURST_GAIN);
            WriteRT_fld (fld_CB_BURST_GAIN,    RT_SECAM_CB_BURST_GAIN);

            WriteRT_fld (fld_CRDR_ACTIVE_GAIN, RT_SECAM_CRDR_ACTIVE_GAIN);
            WriteRT_fld (fld_CBDB_ACTIVE_GAIN, RT_SECAM_CBDB_ACTIVE_GAIN);

            WriteRT_fld (fld_CH_HEIGHT,        RT_SECAM_CH_HEIGHT);
            WriteRT_fld (fld_CH_KILL_LEVEL,    RT_SECAM_CH_KILL_LEVEL);

            WriteRT_fld (fld_CH_AGC_ERROR_LIM, RT_SECAM_CH_AGC_ERROR_LIM);
            WriteRT_fld (fld_CH_AGC_FILTER_EN, RT_SECAM_CH_AGC_FILTER_EN);
            WriteRT_fld (fld_CH_AGC_LOOP_SPEED,RT_SECAM_CH_AGC_LOOP_SPEED);

            WriteRT_fld (fld_VERT_LOCKOUT_START,   RT_SECAM_VERT_LOCKOUT_START);  //Might not need
            WriteRT_fld (fld_VERT_LOCKOUT_END, RT_SECAM_VERT_LOCKOUT_END);  //Might not need

            WriteRT_fld (fld_VS_FIELD_BLANK_START,  (WORD)RT_PALSEM_VS_FIELD_BLANK_START);
            WriteRT_fld (fld_VS_FIELD_BLANK_END,   RT_PAL_VS_FIELD_BLANK_END);

            WriteRT_fld (fld_H_ACTIVE_START,   RT_PAL_H_ACTIVE_START);
            WriteRT_fld (fld_H_ACTIVE_END,   RT_PAL_H_ACTIVE_END);

            WriteRT_fld (fld_V_ACTIVE_START,   RT_PAL_V_ACTIVE_START);
            WriteRT_fld (fld_V_ACTIVE_END,   RT_PAL_V_ACTIVE_END);

            WriteRT_fld (fld_H_VBI_WIND_START,   RT_PAL_H_VBI_WIND_START);
            WriteRT_fld (fld_H_VBI_WIND_END,   RT_PAL_H_VBI_WIND_END);

            WriteRT_fld (fld_V_VBI_WIND_START,   RT_PAL_V_VBI_WIND_START);
            WriteRT_fld (fld_V_VBI_WIND_END,   RT_PAL_V_VBI_WIND_END);

            WriteRT_fld (fld_VSYNC_INT_TRIGGER , (WORD) RT_PALSEM_VSYNC_INT_TRIGGER);
            WriteRT_fld (fld_VSYNC_INT_HOLD, (WORD) RT_PALSEM_VSYNC_INT_HOLD);

            WriteRT_fld (fld_UV_INT_START,   (BYTE)( (0.12 * dbLPeriod * dbFsamp / 2.0) + 0.5 - 32 ));

            break;
        default:
            break;
    }

    if (RT_INFO->wConnector == DEC_SVIDEO)
    {

        RT_SetCombFilter (wStandard, RT_SVIDEO);
    }
    else
    {
        // Set up extra (connector and std) registers.
        RT_SetCombFilter (wStandard, RT_COMPOSITE);
    }

    // Set the following values according to the formulas
    WriteRT_fld (fld_HS_LINE_TOTAL, (WORD)((dbLPeriod * dbFsamp / 2.0) +0.5));
    WriteRT_fld (fld_MIN_PULSE_WIDTH, (BYTE)(0.75 * dbSPPeriod * dbFsamp/2.0));
    WriteRT_fld (fld_MAX_PULSE_WIDTH, (BYTE)(1.25 * dbSPPeriod * dbFsamp/2.0));
    WriteRT_fld (fld_WIN_OPEN_LIMIT, (WORD)(((dbLPeriod * dbFsamp / 4.0) + 0.5) - 16));
    WriteRT_fld (fld_WIN_CLOSE_LIMIT, (WORD)(1.15 * dbSPPeriod * dbFsamp / 2.0));
    WriteRT_fld (fld_VS_FIELD_IDLOCATION,   (WORD)fld_VS_FIELD_IDLOCATION_def);
    WriteRT_fld (fld_VS_FRAME_TOTAL,   (WORD)(wFrameTotal) + 10);
    WriteRT_fld (fld_BLACK_INT_START,   (BYTE)((0.09 * dbLPeriod * dbFsamp / 2.0) - 32 ));
    WriteRT_fld (fld_SYNC_TIP_START,   (WORD)((dbLPeriod * dbFsamp / 2.0 + 0.5) - 28 ));

    RT_INFO->wStandard = wStandard;
    return;

} // RT_SetStandard ()...


/****************************************************************************
 * RT_SetVINClock (WORD wStandard)                                          *
 *  Function: to set the VIN clock for the selected standard                *
 *    Inputs: WORD wStandard - input standard (NTSC, PAL, SECAM)            *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_SetVINClock (WORD wStandard)
{
    DWORD dwM0=0, dwN0=0, dwP=0;
    BYTE ref_freq;

    // Determine the reference frequency first.  This can be obtained
    // from the MMTABLE.video_decoder_type field (bits 4:7)
    // The Rage Theatre currently only supports reference frequencies of
    // 27 or 29.49 MHz.
    ref_freq = (MMTABLE.video_decoder_type & 0xF0) >> 4;

    switch (wStandard & 0x00FF)
    {
        case (DEC_NTSC): //NTSC GROUP - 480 lines
            switch (wStandard & 0xFF00)
            {
                case  (extNONE):
                case  (extNTSC):
                case  (extNTSC_J):
                    if (ref_freq == RT_FREF_2950)
                    {
                        dwM0 =  0x39;
                        dwN0 =  0x14C;
                        dwP  =  0x6;
                    }
                    else
                    {
                        dwM0 =  0x0B;
                        dwN0 =  0x46;
                        dwP  =  0x6;
                    }
                    break;

                case  (extNTSC_443):
                    if (ref_freq == RT_FREF_2950)
                    {
                        dwM0 =  0x23;
                        dwN0 =  0x88;
                        dwP  =  0x7;
                    }
                    else
                    {
                        dwM0 =  0x2C;
                        dwN0 =  0x121;
                        dwP  =  0x5;
                    }
                    break;

                case (extPAL_M):
                    if (ref_freq == RT_FREF_2950)
                    {
                        dwM0 =  0x2C;
                        dwN0 =  0x12B;
                        dwP  =  0x7;
                    }
                    else
                    {
                        dwM0 =  0x0B;
                        dwN0 =  0x46;
                        dwP  =  0x6;
                    }
                    break;

                default:
                    return;
            }
            break;
        case (DEC_PAL):
            switch (wStandard & 0xFF00)
            {
                case (extPAL_N):
                case (extPAL_BGHI):
                case (extPAL_60):
                    if (ref_freq == RT_FREF_2950)
                    {
                        dwM0 = 0x0E;
                        dwN0 = 0x65;
                        dwP  = 0x6;
                    }
                    else
                    {
                        dwM0 = 0x2C;
                        dwN0 = 0x0121;
                        dwP  = 0x5;
                    }
                    break;

                case (extPAL_NCOMB):
                    if (ref_freq == RT_FREF_2950)
                    {
                        dwM0 = 0x23;
                        dwN0 = 0x88;
                        dwP  = 0x7;
                    }
                    else
                    {
                        dwM0 = 0x37;
                        dwN0 = 0x1D3;
                        dwP  = 0x8;
                    }
                    break;

                default:
                    return;
            }
            break;

        case (DEC_SECAM):
            if (ref_freq == RT_FREF_2950)
            {
                dwM0 =  0xE;
                dwN0 =  0x65;
                dwP  =  0x6;
            }
            else
            {
                dwM0 =  0x2C;
                dwN0 =  0x121;
                dwP  =  0x5;
            }
            break;
    }

    // VIN_PLL_CNTL
    WriteRT_fld (fld_VIN_M0, dwM0);
    WriteRT_fld (fld_VIN_N0, dwN0);
    WriteRT_fld (fld_VIN_P, dwP);

    return;
} // RT_SetVINClock ()...


/****************************************************************************
 * RT_SetCombFilter (WORD wStandard, WORD wConnector)                       *
 *  Function: sets the input comb filter based on the standard and          *
 *            connector being used (composite vs. svideo)                   *
 *    Inputs: WORD wStandard - input standard (NTSC, PAL, SECAM)            *
 *            WORD wConnector - COMPOSITE, SVIDEO                           *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_SetCombFilter (WORD wStandard, WORD wConnector)
{
    DWORD dwComb_Cntl0=0;
    DWORD dwComb_Cntl1=0;
    DWORD dwComb_Cntl2=0;
    DWORD dwComb_Line_Length=0;

    switch (wConnector)
    {
        case RT_COMPOSITE:
                switch (wStandard & 0x00FF)
                {
                    case (DEC_NTSC):
                        switch (wStandard & 0xFF00)
                        {
                            case  (extNONE):
                            case  (extNTSC):
                            case  (extNTSC_J):
                                dwComb_Cntl0= RT_NTSCM_COMB_CNTL0_COMPOSITE;
                                dwComb_Cntl1= RT_NTSCM_COMB_CNTL1_COMPOSITE;
                                dwComb_Cntl2= RT_NTSCM_COMB_CNTL2_COMPOSITE;
                                dwComb_Line_Length= RT_NTSCM_COMB_LENGTH_COMPOSITE;
                                break;
                            case  (extPAL_M):
                                dwComb_Cntl0= RT_PALM_COMB_CNTL0_COMPOSITE;
                                dwComb_Cntl1= RT_PALM_COMB_CNTL1_COMPOSITE;
                                dwComb_Cntl2= RT_PALM_COMB_CNTL2_COMPOSITE;
                                dwComb_Line_Length= RT_PALM_COMB_LENGTH_COMPOSITE;
                                break;
                            default:
                                return;
                        }
                        break;
                    case (DEC_PAL):
                        switch (wStandard & 0xFF00)
                        {
                            case  (extNONE):
                            case  (extPAL):
                                dwComb_Cntl0=   RT_PAL_COMB_CNTL0_COMPOSITE;
                                dwComb_Cntl1=   RT_PAL_COMB_CNTL1_COMPOSITE;
                                dwComb_Cntl2=   RT_PAL_COMB_CNTL2_COMPOSITE;
                                dwComb_Line_Length=  RT_PAL_COMB_LENGTH_COMPOSITE;
                                break;
                            case  (extPAL_N):
                                dwComb_Cntl0=   RT_PALN_COMB_CNTL0_COMPOSITE;
                                dwComb_Cntl1=   RT_PALN_COMB_CNTL1_COMPOSITE;
                                dwComb_Cntl2=   RT_PALN_COMB_CNTL2_COMPOSITE;
                                dwComb_Line_Length=  RT_PALN_COMB_LENGTH_COMPOSITE;
                                break;
                            default:
                                return;
                        }
                        break;
                    case (DEC_SECAM):
                        dwComb_Cntl0=   RT_SECAM_COMB_CNTL0_COMPOSITE;
                        dwComb_Cntl1=   RT_SECAM_COMB_CNTL1_COMPOSITE;
                        dwComb_Cntl2=   RT_SECAM_COMB_CNTL2_COMPOSITE;
                        dwComb_Line_Length=  RT_SECAM_COMB_LENGTH_COMPOSITE;
                        break;
                    default:
                        return;
                }
            break;
        case RT_SVIDEO:
                switch (wStandard & 0x00FF)
                {
                    case (DEC_NTSC):
                        switch (wStandard & 0xFF00)
                        {
                            case  (extNONE):
                            case  (extNTSC):
                                dwComb_Cntl0= RT_NTSCM_COMB_CNTL0_SVIDEO;
                                dwComb_Cntl1= RT_NTSCM_COMB_CNTL1_SVIDEO;
                                dwComb_Cntl2= RT_NTSCM_COMB_CNTL2_SVIDEO;
                                dwComb_Line_Length= RT_NTSCM_COMB_LENGTH_SVIDEO;
                                break;
                            case  (extPAL_M):
                                dwComb_Cntl0= RT_PALM_COMB_CNTL0_SVIDEO;
                                dwComb_Cntl1= RT_PALM_COMB_CNTL1_SVIDEO;
                                dwComb_Cntl2= RT_PALM_COMB_CNTL2_SVIDEO;
                                dwComb_Line_Length= RT_PALM_COMB_LENGTH_SVIDEO;
                                break;
                            default:
                                return;
                        }
                        break;
                    case (DEC_PAL):
                        switch (wStandard & 0xFF00)
                        {
                            case  (extNONE):
                            case  (extPAL):
                                dwComb_Cntl0=   RT_PAL_COMB_CNTL0_SVIDEO;
                                dwComb_Cntl1=   RT_PAL_COMB_CNTL1_SVIDEO;
                                dwComb_Cntl2=   RT_PAL_COMB_CNTL2_SVIDEO;
                                dwComb_Line_Length=  RT_PAL_COMB_LENGTH_SVIDEO;
                                break;
                            case  (extPAL_N):
                                dwComb_Cntl0=   RT_PALN_COMB_CNTL0_SVIDEO;
                                dwComb_Cntl1=   RT_PALN_COMB_CNTL1_SVIDEO;
                                dwComb_Cntl2=   RT_PALN_COMB_CNTL2_SVIDEO;
                                dwComb_Line_Length=  RT_PALN_COMB_LENGTH_SVIDEO;
                                break;
                            default:
                                return;
                        }
                        break;
                    case (DEC_SECAM):
                        dwComb_Cntl0=   RT_SECAM_COMB_CNTL0_SVIDEO;
                        dwComb_Cntl1=   RT_SECAM_COMB_CNTL1_SVIDEO;
                        dwComb_Cntl2=   RT_SECAM_COMB_CNTL2_SVIDEO;
                        dwComb_Line_Length=  RT_SECAM_COMB_LENGTH_SVIDEO;
                        break;
                    default:
                        return;
                }
            break;
        default:
            return;
    }

    WriteRT_fld (fld_COMB_CNTL0, dwComb_Cntl0);
    WriteRT_fld (fld_COMB_CNTL1, dwComb_Cntl1);
    WriteRT_fld (fld_COMB_CNTL2, dwComb_Cntl2);
    WriteRT_fld (fld_COMB_LENGTH, dwComb_Line_Length);

    return;

} // RT_SetCombFilter ()...


/****************************************************************************
 * RT_SetOutputVideoSize (WORD wHorzSize, WORD wVertSize,                   *
 *                          BYTE fCC_On, BYTE fVBICap_On)                   *
 *  Function: sets the output video size for the Rage Theatre video in      *
 *    Inputs: WORD wHorzSize - width of output in pixels                    *
 *            WORD wVertSize - height of output in pixels (lines)           *
 *            BYTE fCC_On - enable CC output                                *
 *            BYTE fVBI_Cap_On - enable VBI capture                         *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_SetOutputVideoSize (WORD wHorzSize, WORD wVertSize, BYTE fCC_On, BYTE fVBICap_On)
{
    DWORD  dwHwinStart=0;
    DWORD  dwHScaleRatio=0;
    DWORD  dwHActiveLength=0;
    DWORD  dwVwinStart=0;
    DWORD  dwVScaleRatio=0;
    DWORD  dwVActiveLength=0;
    DWORD  dwTempRatio=0;
    DWORD  dwEvenFieldOffset=0;
    DWORD  dwOddFieldOffset=0;
    DWORD  dwXin=0;
    DWORD  dwYin=0;

    if (fVBICap_On)
    {
        WriteRT_fld (fld_VBI_CAPTURE_ENABLE, 1);
        switch (RT_INFO->wStandard & 0x00FF)
        {
            case (DEC_NTSC):
                WriteRT_fld (fld_H_VBI_WIND_START,  RT_NTSCM_H_VBI_WIND_START);
                WriteRT_fld (fld_H_VBI_WIND_END, RT_NTSCM_H_VBI_WIND_END);
                WriteRT_fld (fld_V_VBI_WIND_START, RT_NTSCM_V_VBI_WIND_START);
                WriteRT_fld (fld_V_VBI_WIND_END, RT_NTSCM_V_VBI_WIND_END);
                break;
            case (DEC_PAL):
                WriteRT_fld (fld_H_VBI_WIND_START, RT_PAL_H_VBI_WIND_START);
                WriteRT_fld (fld_H_VBI_WIND_END, RT_PAL_H_VBI_WIND_END);
                WriteRT_fld (fld_V_VBI_WIND_START, RT_PAL_V_VBI_WIND_START);
                WriteRT_fld (fld_V_VBI_WIND_END, RT_PAL_V_VBI_WIND_END);
                break;
            case (DEC_SECAM):
                WriteRT_fld (fld_H_VBI_WIND_START, RT_PAL_H_VBI_WIND_START);
                WriteRT_fld (fld_H_VBI_WIND_END, RT_PAL_H_VBI_WIND_END);
                WriteRT_fld (fld_V_VBI_WIND_START, RT_PAL_V_VBI_WIND_START);
                WriteRT_fld (fld_V_VBI_WIND_END, RT_PAL_V_VBI_WIND_END);
                break;
            default:
                break;
        }
    }
    else
    {
        WriteRT_fld (fld_VBI_CAPTURE_ENABLE, 0);
    }

    if (RT_INFO->wInterlaced != RT_DECINTERLACED)
    {
        wVertSize *= 2;
    }

    //1. Calculate Horizontal Scaling ratio:
    switch (RT_INFO->wStandard & 0x00FF)
    {
        case (DEC_NTSC):
            dwHwinStart = RT_NTSCM_H_IN_START;
            dwXin = (ReadRT_fld (fld_H_ACTIVE_END) - ReadRT_fld (fld_H_ACTIVE_START)); //tempscaler
            dwHScaleRatio = (DWORD) ((long) dwXin * 65536L / wHorzSize);
            dwHScaleRatio = dwHScaleRatio & 0x001FFFFF; //21 bit number;
            dwHActiveLength = wHorzSize;
            break;
        case (DEC_PAL):
            dwHwinStart = RT_PAL_H_IN_START;
            dwXin = RT_PAL_H_ACTIVE_SIZE;
            dwHScaleRatio = (DWORD) ((long) dwXin * 65536L / wHorzSize);
            dwHScaleRatio = dwHScaleRatio & 0x001FFFFF; //21 bit number;
            dwHActiveLength = wHorzSize;
            break;
        case (DEC_SECAM):
            dwHwinStart = RT_SECAM_H_IN_START;
            dwXin = RT_SECAM_H_ACTIVE_SIZE;
            dwHScaleRatio = (DWORD) ((long) dwXin * 65536L / wHorzSize);
            dwHScaleRatio = dwHScaleRatio & 0x001FFFFF; //21 bit number;
            dwHActiveLength = wHorzSize;
            break;
        default:
            break;
    }

    //2. Calculate Vertical Scaling ratio:
    switch (RT_INFO->wStandard & 0x00FF)
    {
        case (DEC_NTSC):
            dwVwinStart = RT_NTSCM_V_IN_START;
            dwYin = (ReadRT_fld (fld_V_ACTIVE_END) - ReadRT_fld (fld_V_ACTIVE_START)); //tempscaler
            dwTempRatio = (DWORD)((long) wVertSize / dwYin);
            dwVScaleRatio = (DWORD)((long)wVertSize * 2048L / dwYin);
            dwVScaleRatio = dwVScaleRatio & 0x00000FFF;
            dwVActiveLength = wVertSize;
            break;
        case (DEC_PAL):
            dwVwinStart = RT_PAL_V_IN_START;
            dwYin = RT_PAL_V_ACTIVE_SIZE;
            dwTempRatio = (DWORD)(wVertSize/dwYin);
            dwVScaleRatio = (DWORD)((long)wVertSize * 2048L / dwYin);
            dwVScaleRatio = dwVScaleRatio & 0x00000FFF;
            dwVActiveLength = wVertSize;
            break;
        case (DEC_SECAM):
            dwVwinStart = RT_SECAM_V_IN_START;
            dwYin = RT_SECAM_V_ACTIVE_SIZE;
            dwTempRatio = (DWORD) (wVertSize / dwYin);
            dwVScaleRatio = (DWORD) ((long) wVertSize  * 2048L / dwYin);
            dwVScaleRatio = dwVScaleRatio & 0x00000FFF;
            dwVActiveLength = wVertSize;
            break;
        default:
            break;
    }

    //4. Set up offset based on if interlaced or not:
    if (RT_INFO->wInterlaced == RT_DECINTERLACED)
    {
        dwEvenFieldOffset = (DWORD) ((1.0 - ((double) wVertSize / (double) dwYin)) * 512.0);
        dwOddFieldOffset  =  dwEvenFieldOffset;
        WriteRT_fld (fld_V_DEINTERLACE_ON, 0x1);
    }
    else
    {
        dwEvenFieldOffset = (DWORD)(dwTempRatio * 512.0);
        dwOddFieldOffset  = (DWORD)(2048 - dwEvenFieldOffset);
        WriteRT_fld (fld_V_DEINTERLACE_ON, 0x0);
    }

    // Set the registers:
    WriteRT_fld (fld_H_IN_WIND_START,  dwHwinStart);
    WriteRT_fld (fld_H_SCALE_RATIO,    dwHScaleRatio);
    WriteRT_fld (fld_H_OUT_WIND_WIDTH, dwHActiveLength);

    WriteRT_fld (fld_V_IN_WIND_START,  dwVwinStart);
    WriteRT_fld (fld_V_SCALE_RATIO,    dwVScaleRatio);
    WriteRT_fld (fld_V_OUT_WIND_WIDTH, dwVActiveLength);

    WriteRT_fld (fld_EVENF_OFFSET,     dwEvenFieldOffset);
    WriteRT_fld (fld_ODDF_OFFSET,      dwOddFieldOffset);

    RT_INFO->dwHorzScalingRatio = dwHScaleRatio;
    RT_INFO->dwVertScalingRatio = dwVScaleRatio;

    return;

} // RT_SetOutputVideoSize ()...


/****************************************************************************
 * GetStandardConstants (double *LPeriod, double *FPeriod,                  *
 *                          double *Fsamp, WORD wStandard)                  *
 *  Function: return timing values for a given standard                     *
 *    Inputs: double *LPeriod -
 *            double *FPeriod -
 *            double *Fsamp - sampling frequency used for a given standard  *
 *            WORD wStandard - input standard (NTSC, PAL, SECAM)            *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void GetStandardConstants (double *LPeriod, double *FPeriod,
                           double *Fsamp, WORD wStandard)
{
    *LPeriod = 0.0;
    *FPeriod = 0.0;
    *Fsamp   = 0.0;

    switch (wStandard & 0x00FF)
    {
        case (DEC_NTSC): //NTSC GROUP - 480 lines
            switch (wStandard & 0xFF00)
            {
                case  (extNONE):
                case  (extNTSC):
                case  (extNTSC_J):
                    *LPeriod = (double) 63.5555;
                    *FPeriod = (double) 16.6833;
                    *Fsamp = (double) 28.63636;
                    break;
                case  (extPAL_M):
                    *LPeriod = (double) 63.492;
                    *FPeriod = (double) 16.667;
                    *Fsamp = (double) 28.63689192;
                    break;
                default:
                    return;
            }
            break;
        case (DEC_PAL):
            if(  (wStandard & 0xFF00) == extPAL_N )
            {
                *LPeriod = (double) 64.0;
                *FPeriod = (double) 20.0;
                *Fsamp = (double) 28.65645;
            }
            else
            {
                *LPeriod = (double) 64.0;
                *FPeriod = (double) 20.0;
                *Fsamp = (double) 35.46895;
            }
            break;
        case (DEC_SECAM):
            *LPeriod = (double) 64.0;
            *FPeriod = (double) 20.0;
            *Fsamp = (double) 35.46895;
            break;
    }
    return;

} // GetStandardConstants ()...

/****************************************************************************
 * CalculateCrCbGain (double *CrGain, double *CbGain, WORD wStandard)       *
 *  Function:                                                               *
 *    Inputs: double *CrGain -
 *            double *CbGain -
 *            WORD wStandard - input standard (NTSC, PAL, SECAM)            *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void CalculateCrCbGain (double *CrGain, double *CbGain, WORD wStandard)
{
    #define UVFLTGAIN   1.5
    #define FRMAX       280000.0
    #define FBMAX       230000.0

    double dbSynctipRef0=0, dbFsamp=0, dbLPeriod=0, dbFPeriod=0;

    dbSynctipRef0 = ReadRT_fld (fld_SYNCTIP_REF0);

    GetStandardConstants (&dbLPeriod, &dbFPeriod, &dbFsamp, wStandard);

    *CrGain=0.0;
    *CbGain=0.0;

    switch (wStandard & 0x00FF)
    {
        case (DEC_NTSC): //NTSC GROUP - 480 lines
            switch (wStandard & 0xFF00)
            {
                case  (extNONE):
                case  (extNTSC):
                case  (extPAL_M):
                    *CrGain = (double)(40.0 / (dbSynctipRef0)) * (100.0/92.5) * (1.0/0.877) * ((112.0/70.1)/UVFLTGAIN);
                    *CbGain = (double)(40.0 / (dbSynctipRef0)) * (100.0/92.5) * (1.0/0.492) * ((112.0/88.6)/UVFLTGAIN);
                    break;
                case  (extNTSC_J):
                    *CrGain = (double)(40.0 / (dbSynctipRef0)) * (100.0/100.0) * (1.0/0.877) * ((112.0/70.1)/UVFLTGAIN);
                    *CbGain = (double)(40.0 / (dbSynctipRef0)) * (100.0/100.0) * (1.0/0.492) * ((112.0/88.6)/UVFLTGAIN);
                    break;
                default:
                    return;
            }
            break;
        case (DEC_PAL):
            *CrGain = (double)(43.0 / (dbSynctipRef0)) * (100.0/92.5) * (1.0/0.877) * ((112.0/70.1)/UVFLTGAIN);
            *CbGain = (double)(43.0 / (dbSynctipRef0)) * (100.0/92.5) * (1.0/0.492) * ((112.0/88.6)/UVFLTGAIN);
            break;
        case (DEC_SECAM):
            *CrGain = (double) 32.0 * 32768.0 / FRMAX / (33554432.0 / dbFsamp) * (1.597 / 1.902) / UVFLTGAIN;
            *CbGain = (double) 32.0 * 32768.0 / FBMAX / (33554432.0 / dbFsamp) * (1.267 / 1.505) / UVFLTGAIN;
            break;
    }

    return;

} // CalculateCrCbGain ()...

/****************************************************************************
 * RT_SetConnector (WORD wStandard, int tunerFlag)                          *
 *  Function:
 *    Inputs: WORD wStandard - input standard (NTSC, PAL, SECAM)            *
 *            int tunerFlag
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_SetConnector (WORD wConnector, int tunerFlag)
{
    DWORD dwTempContrast=0;
    DWORD i;
    static int lastState = -1;

    // Get the contrast value - make sure we are viewing a visible line
    while (!(ReadRT_fld (fld_VS_LINE_COUNT)> 1 && ReadRT_fld (fld_VS_LINE_COUNT)<20));

    dwTempContrast = ReadRT_fld (fld_LP_CONTRAST);

    WriteRT_fld (fld_LP_CONTRAST, 0x0);

    switch (wConnector)
    {
        case (DEC_TUNER):   // Tuner
            WriteRT_fld (fld_INPUT_SELECT, RT_INFO->wTunerConnector );
            WriteRT_fld (fld_STANDARD_YC, RT_COMPOSITE);
            RT_SetCombFilter (RT_INFO->wStandard, RT_COMPOSITE);
            break;
        case (DEC_COMPOSITE):   // Comp
            WriteRT_fld (fld_INPUT_SELECT, RT_INFO->wComp0Connector);
            WriteRT_fld (fld_STANDARD_YC, RT_COMPOSITE);
            RT_SetCombFilter (RT_INFO->wStandard, RT_COMPOSITE);
            break;
        case (DEC_SVIDEO):  // Svideo
            WriteRT_fld (fld_INPUT_SELECT, RT_INFO->wSVideo0Connector);
            WriteRT_fld (fld_STANDARD_YC, RT_SVIDEO);
            RT_SetCombFilter (RT_INFO->wStandard, RT_SVIDEO);
            break;
        default:
            WriteRT_fld (fld_INPUT_SELECT, RT_INFO->wComp0Connector);
            WriteRT_fld (fld_STANDARD_YC, RT_COMPOSITE);
            RT_SetCombFilter (RT_INFO->wStandard, RT_COMPOSITE);
            break;
    }

    RT_INFO->wConnector = wConnector;

    WriteRT_fld (fld_COMB_CNTL1, ReadRT_fld (fld_COMB_CNTL1) ^ 0x100);
    WriteRT_fld (fld_COMB_CNTL1, ReadRT_fld (fld_COMB_CNTL1) ^ 0x100);

    i = TickCount();

    while (((TickCount() - i) < 10) && (! ReadRT_fld (fld_HS_GENLOCKED)));
    while (!(ReadRT_fld (fld_VS_LINE_COUNT)> 1 && ReadRT_fld (fld_VS_LINE_COUNT)<20));

    WriteRT_fld (fld_LP_CONTRAST, dwTempContrast);

    lastState = wConnector;

    return;

} // RT_SetConnector ()...

/****************************************************************************
 * RT_ResetVideoLevels (void)                                               *
 *  Function: Resets the various video settings to default values           *
 *    Inputs: NONE                                                          *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_ResetVideoLevels (void)
{
    // Set structure members to default values.
    RT_INFO->iHue = 100;
    RT_INFO->iBrightness = 100;
    RT_INFO->iSaturation = 100;
    RT_INFO->iContrast = 100;
    RT_INFO->dbContrast = 1.0;

    // Call appropriate functions to reset the video levels to default.
    RT_SetTint (RT_INFO->iHue);
    RT_SetSaturation (RT_INFO->iSaturation);
    RT_SetBrightness (RT_INFO->iBrightness);
    RT_SetSharpness (DEC_SMOOTH);
    RT_SetContrast (RT_INFO->iContrast);

} // RT_ResetVideoLevels ()...

/****************************************************************************
 * RT_ShutDown (void)                                                       *
 *  Function: Shuts down the video decoder of the Rage Theatre              *
 *    Inputs: NONE                                                          *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_ShutDown (void)
{
    WriteRT_fld (fld_VIN_ASYNC_RST, RT_ASYNC_DISABLE);
    WriteRT_fld (fld_VINRST       , RT_VINRST_RESET);
    WriteRT_fld (fld_ADC_PDWN     , RT_ADC_DISABLE);
    WriteRT_fld (fld_DVS_DIRECTION, RT_DVSDIR_IN);

    return;
} // RT_ShutDown ()...

/****************************************************************************
 * RT_InitInfoStruct (void)                                                 *
 *  Function: Creates a structure with the default register values          *
 *    Inputs: NONE                                                          *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_InitInfoStruct (void)
{
    BYTE bTemp;
    BYTE loop;

    memcpy (RT_INFO->RegsMap, &RT_RegMap,  regRT_MAX_REGS * sizeof(RTREGMAP));

    // Set default values for NTSC
    RT_INFO->wStandard = DEC_NTSC | extNTSC;
    RT_INFO->wConnector = DEC_SRC_TUNER;
    RT_INFO->wSharpness = 0;
    RT_INFO->wSaturation_V = 0;
    RT_INFO->wSaturation_U = 0;
    RT_INFO->dbContrast = 1.0;
    RT_INFO->dbBrightnessRatio = 1.0;
    RT_INFO->wInterlaced = 1;
    RT_INFO->iHue = 100;
    RT_INFO->iBrightness = 100;
    RT_INFO->iContrast = 100;
    RT_INFO->iSaturation = 100;

    // Determine what physical connectors are attached to what input.
    // This information was previously retrieved by reading the MM table
    // in the Rage 128 BIOS. See GetMMTable () for more info.

    for (loop = 0; loop < 5; loop ++)
    {
        bTemp = MMTABLE.input[loop] & 0x3;

        if (bTemp != 0)
        {
            switch (bTemp)
            {
                case 1:     RT_INFO->wTunerConnector = loop;
                            break;
                case 2:     if (MMTABLE.input[loop] && 0x4)
                            {
                                RT_INFO->wComp0Connector = RT_COMP2;
                            }
                            else
                            {
                                RT_INFO->wComp0Connector = RT_COMP1;
                            }
                            break;
                case 3:     if (MMTABLE.input[loop] && 0x4)
                            {
                                RT_INFO->wSVideo0Connector = RT_YCR_COMP4;
                            }
                            else
                            {
                                RT_INFO->wSVideo0Connector = RT_YCF_COMP4;
                            }
                default:    break;
            }
        }
    }

} // RT_InitInfoStruct ()...

/****************************************************************************
 * RT_EnableDecoder (void)                                                  *
 *  Function: enables the video in decoder of the Rage Theatre              *
 *    Inputs: NONE                                                          *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void RT_EnableDecoder (void)
{
    DWORD     data;

    // 1.
    // Set the VIN_PLL to NTSC value
    RT_SetVINClock (RT_NTSC);

    // Take VINRST and L54RST out of reset
    RT_regr (VIP_PLL_CNTL1, &data);
    RT_regw (VIP_PLL_CNTL1, data & ~((RT_VINRST_RESET << 1) | (RT_L54RST_RESET << 3)));
    RT_regr (VIP_PLL_CNTL1, &data);

    // Set VIN_CLK_SEL to PLL_VIN_CLK
    RT_regr (VIP_CLOCK_SEL_CNTL, &data);
    RT_regw (VIP_CLOCK_SEL_CNTL, data | (RT_PLL_VIN_CLK << 7));
    RT_regr (VIP_CLOCK_SEL_CNTL, &data);

    // 2.
    // Set HW_DEBUG to 0xF000 before setting the standards registers
    RT_regw (VIP_HW_DEBUG, 0x0000F000);
    RT_SetStandard (RT_INFO->wStandard);

    // 3.
    // Set DVS port to OUTPUT
    RT_regr (VIP_DVS_PORT_CTRL, &data);
    RT_regw (VIP_DVS_PORT_CTRL, data | RT_DVSDIR_OUT);
    RT_regr (VIP_DVS_PORT_CTRL, &data);

    // 4.
    // Set default values for ADC_CNTL
    RT_regw (VIP_ADC_CNTL, RT_ADC_CNTL_DEFAULT);

    // 5.
    // Clear the VIN_ASYNC_RST bit
    RT_regr (VIP_MASTER_CNTL, &data);
    RT_regw (VIP_MASTER_CNTL, data & ~0x20);
    RT_regr (VIP_MASTER_CNTL, &data);

    // Clear the DVS_ASYNC_RST bit
    RT_regr (VIP_MASTER_CNTL, &data);
    RT_regw (VIP_MASTER_CNTL, data & ~(RT_DVS_ASYNC_RST));
    RT_regr (VIP_MASTER_CNTL, &data);

    // Set the GENLOCK delay
    RT_regw (VIP_HS_GENLOCKDELAY, 0x10);

    RT_regr (fld_DVS_DIRECTION, &data);
	RT_regw (fld_DVS_DIRECTION, data & RT_DVSDIR_OUT);
//	WriteRT_fld (fld_DVS_DIRECTION, RT_DVSDIR_IN);

} // RT_EnableDecoder ()...

