/******************************************************************************
 * Rage 128 Chapter 3 sample code                                             *
 *                                                                            *
 * nobios.c - This program sets a display mode without using the video        *
 * BIOS.  The screen is cleared.                                              *
 *                                                                            *
 * Copyright (c) 1999 ATI Technologies Inc. All rights reserved.              *
 ******************************************************************************/
#include <stdio.h>
#include <io.h>
#include <conio.h>
#include <stdlib.h>
#include "..\util\regdef.h"
#include "..\util\main.h"
#include "..\util\defines.h"

void main (int argc, char *argv[])
{
    WORD result, x, y;
    DWORD temp;
    char *framebuffer;
    CRTCInfoBlock *mtable;
    FILE *op;

    op = fopen ("output.txt", "w");

    get_old_mode ();

    if (!R128_Detect ())
    {
        // shut down, and restore the old text mode.
        R128_ShutDown ();
        printf ("\nCannot detect a RAGE128 based graphics adapter.");
        printf ("\nProgram terminated.");
        exit (1);
    }
    process_command_line (argc, argv);
    R128_AdapterInfo.xres = R128_AdapterInfo.xres;
    R128_AdapterInfo.yres = R128_AdapterInfo.yres;
    R128_AdapterInfo.bpp = R128_AdapterInfo.bpp;
    if (R128_AdapterInfo.bpp == 24)
    {
        R128_AdapterInfo.pitch = R128_AdapterInfo.xres/8;
    }
    else
    {
        R128_AdapterInfo.pitch = R128_AdapterInfo.xres;
    }

    // detection tests!
    if (!R128_FindRom ())
    {
        // shut down, and restore the old text mode.
        R128_ShutDown ();
        printf ("\nRage 128 BIOS ROM not found.");
        printf ("\nProgram terminated.");
        exit (1);
    }

    if (!R128_RegTest ())
    {
        // shut down, and restore the old text mode.
        R128_ShutDown ();
        printf ("\nRage 128 scratch register test FAILED.");
        printf ("\nProgram terminated.");
        exit (1);
    }

    switch (R128_AdapterInfo.xres)
    {
        case 320:   mtable = &mode320_60;
                    break;
        case 400:   mtable = &mode400_75;
                    break;
        case 512:   mtable = &mode512;
                    break;
        case 640:   mtable = &mode640_60;
                    break;
        case 720:   mtable = &mode720_60;
                    break;
        case 800:   mtable = &mode800_60;
                    break;
        case 848:   mtable = &mode848_88;
                    break;
        case 864:   mtable = &mode864_60;
                    break;
        case 1024:  mtable = &mode1024_60;
                    break;
        case 1152:  mtable = &mode1152_60;
                    break;
        case 1280:  mtable = &mode1280_60;
                    break;
        case 1600:  mtable = &mode1600_60;
                    break;
        case 1920:  mtable = &mode1920_60;
                    break;
        default:    mtable = &mode640_60;
                    break;
    }

    result = R128_GetBPPValue (R128_AdapterInfo.bpp);
    R128_SetModeNB (R128_AdapterInfo.xres, R128_AdapterInfo.yres, result, mtable);

    // fill the screen with blue pixels
    framebuffer = (char *)R128_AdapterInfo.virtual_MEM_BASE;

    for (x=0; x<R128_AdapterInfo.xres; x++)
    {
        for (y=0; y<R128_AdapterInfo.yres; y++)
        {
            switch (R128_AdapterInfo.bpp)
            {
                case 8:     *framebuffer = 0x09;
                            framebuffer+=1;
                            break;

                case 15:
                case 16:    *framebuffer = 0x1F;
                            framebuffer+=1;
                            *framebuffer = 0x00;
                            framebuffer+=1;
                            break;

                case 24:    *framebuffer = 0xFF;
                            framebuffer+=1;
                            *framebuffer = 0x00;
                            framebuffer+=1;
                            *framebuffer = 0x00;
                            framebuffer+=1;
                            break;

                case 32:    *framebuffer = 0xFF;
                            framebuffer+=1;
                            *framebuffer = 0x00;
                            framebuffer+=1;
                            *framebuffer = 0x00;
                            framebuffer+=1;
                            *framebuffer = 0x00;
                            framebuffer+=1;
                            break;
            } // switch
        } // for (y...
    } // for (x...

    for (x = 0x1; x < 0x14; x++)
    {
        //R128_WaitForFifo (1);
        temp = PLL_regr (x);
        fprintf (op, "\nPLL %2.2X: %8.8X", x, temp);
    }

    fclose (op);

    // eat up the keyboard hit
    getch();

    // shut down, and restore the old text mode.
    R128_ShutDown ();

    R128_PrintInfoStruct ();
    printf ("\nDisplay mode successfully set, without using the BIOS.");
    printf ("\nX resolution: %d, Y resolution: %d, bits per pixel: %d\n",
            R128_AdapterInfo.xres, R128_AdapterInfo.yres,
            R128_AdapterInfo.bpp);

    exit (0);
}

