/****************************************************************************
 * DECODER.C                                                                *
 *                                                                          *
 * Purpose: Basic decoder functions, for use with Rage 128 and the ATI TV   *
 *          Tuner card (Brooktree 8x9 decoder)                              *
 *                                                                          *
 * Copyright (C) 1999 ATI Technologies Inc.  All rights reserved.           *
 ****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "main.h"
#include "defines.h"
#include "regdef.h"

/****************************************************************************
 * R128_SetDecoderDefaults (BYTE format, BYTE input)                        *
 *  Function: Sets up the Bt8x9 for default operation, as per the format    *
 *            and input requested.                                          *
 *    Inputs: BYTE format - the capture format of the decoder               *
 *                          (NTSC 640x480, NTSC 720x480, NTSC320x240)       *
 *            BYTE input - which physical input the decoder will use        *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void R128_SetDecoderDefaults (BYTE format, BYTE input)
{
    BYTE data[16];
    BYTE retval;
    BYTE counter;
    _I2C_PACKET Packet;

    data[0] = 0x16;
    data[1] = 0x80;
    Packet.data = data;
    Packet.start = 1;
    Packet.stop = 1;
    Packet.address = AddressInfo.Decoder;
    Packet.number_of_bytes = 1;
    counter = 0;
    do
    {
        //retval = I2C_Set (AddressInfo.Decoder, 1, &data);
        retval = I2C_Set (&Packet);
        counter++;
    }
    while ((retval != I2C_DONE) && (counter < 5));

    // reset the decoder by writing to register 0x1F
    data[0] = 0x1F;
    data[1] = 0x0;
    Packet.number_of_bytes = 2;
    counter = 0;
    do
    {
        //retval = I2C_Set (AddressInfo.Decoder, 2, &data);
        retval = I2C_Set (&Packet);
        counter++;
    }
    while ((retval != I2C_DONE) && (counter < 5));

    R128_SetDecoderFormat (format);
    R128_SetDecoderSource (input);

} // R128_SetDecoderDefaults ()...

/****************************************************************************
 * R128_SetDecoderSource (BYTE src)                                         *
 *  Function: Sets the Bt8x9 input source selection.                        *
 *    Inputs: BYTE src - the input source requested:                        *
 *            0 - tuner, 1 - composite, 2 - svideo                          *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void R128_SetDecoderSource (BYTE src)
{
    BYTE data[16];
    BYTE retval;
    BYTE counter;
    _I2C_PACKET Packet;

    R128_Delay (2);

    switch (src)
    {
        case DEC_SRC_COMPOSITE:
            // set register 0x1 (INPUT FORMAT) to 0x38
            data[0] = 0x01;
            data[1] = 0x38;
            Packet.data = data;
            Packet.start = 1;
            Packet.stop = 1;
            Packet.address = AddressInfo.Decoder;
            Packet.number_of_bytes = 2;
            counter = 0;
            do
            {
                //retval = I2C_Set (AddressInfo.Decoder, 2, &data);
                retval = I2C_Set (&Packet);
                counter++;
            }
            while ((retval != I2C_DONE) && (counter < 5));

            data[0] = 0x0B;
            data[1] = 0x20;
            Packet.data = data;
            Packet.start = 1;
            Packet.stop = 1;
            Packet.address = AddressInfo.Decoder;
            Packet.number_of_bytes = 2;
            counter = 0;
            do
            {
                //retval = I2C_Set (AddressInfo.Decoder, 2, &data);
                retval = I2C_Set (&Packet);
                counter++;
            }
            while ((retval != I2C_DONE) && (counter < 5));
            break;

        case DEC_SRC_SVIDEO:
            // set register 0x1 (INPUT FORMAT) to 0x78
            data[0] = 0x01;
            data[1] = 0x78;
            Packet.data = data;
            Packet.start = 1;
            Packet.stop = 1;
            Packet.address = AddressInfo.Decoder;
            Packet.number_of_bytes = 2;
            counter = 0;
            do
            {
                //retval = I2C_Set (AddressInfo.Decoder, 2, &data);
                retval = I2C_Set (&Packet);
                counter++;
            }
            while ((retval != I2C_DONE) && (counter < 5));

            data[0] = 0x0B;
            data[1] = 0x60;
            Packet.data = data;
            Packet.start = 1;
            Packet.stop = 1;
            Packet.address = AddressInfo.Decoder;
            Packet.number_of_bytes = 2;
            counter = 0;
            do
            {
                //retval = I2C_Set (AddressInfo.Decoder, 2, &data);
                retval = I2C_Set (&Packet);
                counter++;
            }
            while ((retval != I2C_DONE) && (counter < 5));
            break;

        case DEC_SRC_TUNER:
            // set register 0x1 (INPUT FORMAT) to 0x58
            data[0] = 0x01;
            data[1] = 0x58;
            Packet.data = data;
            Packet.start = 1;
            Packet.stop = 1;
            Packet.address = AddressInfo.Decoder;
            Packet.number_of_bytes = 2;
            counter = 0;
            do
            {
                //retval = I2C_Set (AddressInfo.Decoder, 2, &data);
                retval = I2C_Set (&Packet);
                counter++;
            }
            while ((retval != I2C_DONE) && (counter < 5));

            data[0] = 0x0B;
            data[1] = 0x20;
            Packet.data = data;
            Packet.start = 1;
            Packet.stop = 1;
            Packet.address = AddressInfo.Decoder;
            Packet.number_of_bytes = 2;
            counter = 0;
            do
            {
                //retval = I2C_Set (AddressInfo.Decoder, 2, &data);
                retval = I2C_Set (&Packet);
                counter++;
            }
            while ((retval != I2C_DONE) && (counter < 5));

            // Now, set the tuner to channel 24 for test purposes.
            R128_SetTunerChannel (24);
            break;
        default:
            break;
    }

    R128_Delay (2);

} // R128_SetDecoderSource ()...


/****************************************************************************
 * R128_SetDecoderFormat (BYTE fmt)                                         *
 *  Function: Sets up the Bt8x9 for the specified output operation.         *
 *    Inputs: BYTE fmt - 0 (640x480 NTSC)                                   *
 *                       1 (720x480 CCIR NTSC)                              *
 *                       2 (320x240 2:1 NSTC)                               *
 *   Outputs: NONE                                                          *
 ****************************************************************************/
void R128_SetDecoderFormat (BYTE fmt)
{
    BYTE data[16];
    BYTE retval, loop;
    BYTE counter;
    _I2C_PACKET Packet;

    BYTE format_data[3][27] =   {
                        {   // 640x480 NTSC
                        0x00, 0x58, 0x00, 0x12, 0x16, 0xE0, 0x78, 0x80,
                        0x02, 0xAC, 0x00, 0x20, 0xD8, 0xFE, 0xB4, 0x00,
                        0x00, 0xCF, 0x0A, 0x60, 0x00, 0x01, 0x00, 0x70,
                        0x68, 0x5D, 0x80
                        },

                        {   // 720x480 CCIR NTSC
                        0x00, 0x58, 0x00, 0x12, 0x16, 0xE0, 0x80, 0xD0,
                        0x00, 0xF8, 0x00, 0x20, 0xD8, 0xFE, 0xB4, 0x00,
                        0x00, 0xCF, 0x0A, 0x60, 0x00, 0x01, 0x00, 0x70,
                        0x68, 0x5D, 0x80
                        },

                        {   // 320x240 NTSC - CIF
                        0x00, 0x58, 0x00, 0x11, 0x16, 0xE0, 0x40, 0x40,
                        0x11, 0xF0, 0x00, 0x20, 0xD8, 0xFE, 0xB4, 0x00,
                        0x00, 0xCF, 0x0A, 0x40, 0x00, 0x01, 0x00, 0x70,
                        0x68, 0x5D, 0x80
                        }       };

    data[0] = 0;

    for (loop = 0; loop < 14; loop++)
    {
        data [loop+1] = format_data[fmt][loop];
    }

    // Write first 14 bytes to Bt8x9

    Packet.data = data;
    Packet.start = 1;
    Packet.stop = 1;
    Packet.address = AddressInfo.Decoder;
    Packet.number_of_bytes = 15;
    counter = 0;
    do
    {
        //retval = I2C_Set (AddressInfo.Decoder, 15, &data);
        retval = I2C_Set (&Packet);
        counter++;
    }
    while ((retval != I2C_DONE) && (counter < 5));

    data[0] = 14;

    for (loop = 0; loop < 13; loop++)
    {
        data [loop+1] = format_data[fmt][loop+14];
    }

    // Write last 13 bytes to Bt8x9

    Packet.data = data;
    Packet.start = 1;
    Packet.stop = 1;
    Packet.address = AddressInfo.Decoder;
    Packet.number_of_bytes = 14;
    do
    {
        //retval = I2C_Set (AddressInfo.Decoder, 14, &data);
        retval = I2C_Set (&Packet);
        counter++;
    }
    while ((retval != I2C_DONE) && (counter < 5));

} // R128_SetDecoderFormat ()...

