/*************************************************************************
Copyright(c) 2004-2006 Analog Devices, Inc. All Rights Reserved.

This software is proprietary and confidential.  By using this software you agree
to the terms of the associated Analog Devices License Agreement.

File Name: srgp.c 

Description - Main source file for SRGP application.  See readmefile  for details.

*********************************************************************************/
#include <sysreg.h>
#include <ccblkfn.h>

#if defined(__ADSPBF533__)
#include <cdefbf533.h>

#endif
#if defined(__ADSPBF537__) 
#include <cdefbf537.h>
#endif

#if defined(__ADSPBF561__) 
#include <cdefbf561.h>
#endif


#include <sys/exception.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <services/services.h>
#include <services/int/adi_int.h>
#include <drivers/adi_dev.h>
#include <drivers/ppi/adi_ppi.h>

#include <srgp.h>
#include <adi_graph_font.h>
#include <adi_graph.h>
#include <adi_graph_driver.h>
#include <SDK-ezkitutilities.h>
#include <adi_itu656.h>
#include <adi_ssl_init.h>           // initialization sizings

#define NTSC_WIDTH ITU_ACTIVE_DATA_PER_LINE / EAV_SIZE


// Handles for the DMA and DEVICE manager services
static ADI_DEV_DEVICE_HANDLE  DeviceHandle;

// two dimensional buffer
static ADI_DEV_2D_BUFFER Buffer;

#if defined(__ADSP_EDINBURGH__)
#define FLAG_PERIPHERAL_ID	(ADI_INT_PFA)
#endif

#if defined(__ADSP_BRAEMAR__)
#define FLAG_PERIPHERAL_ID	(ADI_INT_PORTFG_A)
#endif

#if defined(__ADSP_TETON__)
#define FLAG_PERIPHERAL_ID	(ADI_INT_PF0_15_A)
#endif


#define LOW_X   (50)
#define LOW_Y   (50)
#define HIGH_X  ((NTSC_WIDTH)-50)
#define HIGH_Y	((NTSC_HEIGHT/2)-50)
#define MID_X   ((LOW_X+HIGH_X)/2)
#define MID_Y   ((LOW_Y+HIGH_Y)/2)

#define NUM_VERTS 5


const int vx[NUM_VERTS] = { -10, 20, -20, 10,  0  };
const int vy[NUM_VERTS] = { -20, 10, 10,  -20, 20 };


// index that allows user to seqquence through the screens
static int TEST_INDEX = 0;


void welcome ()
{
	SRGP_setFont ( 0 );

	SRGP_text ( SRGP_defPoint ( LOW_X+5, HIGH_Y-40 ), "This program will show the various drawing" );
	SRGP_text ( SRGP_defPoint ( LOW_X+5, HIGH_Y-55 ), "features available in SRGP." );

	
	SRGP_text ( SRGP_defPoint ( LOW_X+5, HIGH_Y-100 ), "1st EZ-Kit button displays previous screen." );
	SRGP_text ( SRGP_defPoint ( LOW_X+5, HIGH_Y-115 ), "2nd EZ-Kit button displays next screen." );
}

void point001 ()
{
	int x, y;
	
	SRGP_setColor ( SRGPWHITE );
	
	for ( x = 0; x <= (NTSC_WIDTH); x += 20 )
		for ( y = 0; y <= (NTSC_HEIGHT/2); y += 20 )
			SRGP_point ( SRGP_defPoint ( x, y ) );

	SRGP_loadCommonColor ( 2, "red" );
	SRGP_setColor ( 2 );
		
	for ( x = 10; x <= (NTSC_WIDTH); x += 20 )
		for ( y = 10; y <= (NTSC_HEIGHT/2); y += 20 )
			SRGP_pointCoord ( x, y );
}

void line001 ()
{
	SRGP_loadCommonColor ( 2, "red" );
	SRGP_loadCommonColor ( 3, "green" );
	SRGP_loadCommonColor ( 4, "blue" );
	SRGP_loadCommonColor ( 5, "yellow" );
	{
		int x, y;
		for ( x = LOW_X+10; x <= HIGH_X-10; x += 10 )
		{
			SRGP_setColor ( 2 );
			SRGP_line ( SRGP_defPoint ( MID_X, MID_Y ), SRGP_defPoint ( x, LOW_Y+10 ) );
			SRGP_setColor ( 3 );
			SRGP_line ( SRGP_defPoint ( MID_X, MID_Y ), SRGP_defPoint ( x, HIGH_Y-10 ) );
		}
		for ( y = LOW_Y+10; y <= HIGH_Y-10; y += 10 )
		{
			SRGP_setColor ( 4 );
			SRGP_line ( SRGP_defPoint ( MID_X, MID_Y ), SRGP_defPoint ( LOW_X+10, y ) );
			SRGP_setColor ( 5 );
			SRGP_line ( SRGP_defPoint ( MID_X, MID_Y ), SRGP_defPoint ( HIGH_X-10, y ) );
		}
	}
}

void line002 ()
{
	SRGP_loadCommonColor ( 2, "red" );
	SRGP_loadCommonColor ( 3, "green" );

	SRGP_setColor ( 2 );
	SRGP_line ( SRGP_defPoint ( 0, HIGH_Y-25 ), SRGP_defPoint ( NTSC_WIDTH, HIGH_Y-26 ) );
	SRGP_line ( SRGP_defPoint ( 0, HIGH_Y-30 ), SRGP_defPoint ( NTSC_WIDTH, HIGH_Y-30 ) );
	SRGP_line ( SRGP_defPoint ( 0, HIGH_Y-35 ), SRGP_defPoint ( NTSC_WIDTH, HIGH_Y-34 ) );

	SRGP_setColor ( 3 );
	SRGP_line ( SRGP_defPoint ( HIGH_X-25, 0 ), SRGP_defPoint ( HIGH_X-26, (NTSC_HEIGHT/2) ) );
	SRGP_line ( SRGP_defPoint ( HIGH_X-30, 0 ), SRGP_defPoint ( HIGH_X-30, (NTSC_HEIGHT/2) ) );
	SRGP_line ( SRGP_defPoint ( HIGH_X-35, 0 ), SRGP_defPoint ( HIGH_X-34, (NTSC_HEIGHT/2) ) );
}

void rect001 ()
{
	SRGP_loadCommonColor ( 2, "red" );
	SRGP_loadCommonColor ( 3, "green" );
	SRGP_loadCommonColor ( 4, "blue" );
	SRGP_loadCommonColor ( 5, "yellow" );

	SRGP_setColor ( 2 );
	SRGP_rectangle ( SRGP_defRectangle ( LOW_X+10, LOW_Y+10, LOW_X+60, LOW_Y+60  ) );
	SRGP_rectangle ( SRGP_defRectangle ( LOW_X-10, LOW_Y+70, LOW_X+60, HIGH_Y+10 ) );
	
	SRGP_setColor ( 3 );
	SRGP_rectanglePt ( SRGP_defPoint ( LOW_X+70, LOW_Y+10) , SRGP_defPoint ( LOW_X+120, LOW_Y+60  ) );
	SRGP_rectanglePt ( SRGP_defPoint ( LOW_X+70, LOW_Y+70) , SRGP_defPoint ( LOW_X+120, HIGH_Y+10 ) );

	SRGP_setColor ( 4 );
	SRGP_rectangleCoord ( LOW_X+130, LOW_Y+10, LOW_X+180, LOW_Y+60  );
	SRGP_rectangleCoord ( LOW_X+130, LOW_Y+70, LOW_X+180, HIGH_Y+10 );
}

void rect002 ()
{
	SRGP_loadCommonColor ( 2, "red" );
	SRGP_loadCommonColor ( 3, "green" );
	SRGP_loadCommonColor ( 4, "blue" );
	SRGP_loadCommonColor ( 5, "yellow" );

	SRGP_setColor ( 2 );
	SRGP_fillRectangle ( SRGP_defRectangle ( LOW_X+10, LOW_Y+10, LOW_X+60, LOW_Y+60  ) );
	SRGP_fillRectangle ( SRGP_defRectangle ( LOW_X-10, LOW_Y+70, LOW_X+60, HIGH_Y+10 ) );
	
	SRGP_setColor ( 3 );
	SRGP_fillRectanglePt ( SRGP_defPoint ( LOW_X+70, LOW_Y+10) , SRGP_defPoint ( LOW_X+120, LOW_Y+60  ) );
	SRGP_fillRectanglePt ( SRGP_defPoint ( LOW_X+70, LOW_Y+70) , SRGP_defPoint ( LOW_X+120, HIGH_Y+10 ) );

	SRGP_setColor ( 4 );
	SRGP_fillRectangleCoord ( LOW_X+130, LOW_Y+10, LOW_X+180, LOW_Y+60  );
	SRGP_fillRectangleCoord ( LOW_X+130, LOW_Y+70, LOW_X+180, HIGH_Y+10 );
}

void elli001 ()
{
	SRGP_loadCommonColor ( 2, "red" );
	SRGP_loadCommonColor ( 3, "green" );
	SRGP_loadCommonColor ( 4, "blue" );
	SRGP_loadCommonColor ( 5, "yellow" );

	SRGP_setColor ( 2 );
	SRGP_ellipse ( SRGP_defRectangle ( LOW_X-100, LOW_Y+50, LOW_X+100, LOW_Y+100 ) );

	SRGP_setColor ( 3 );
	SRGP_ellipse ( SRGP_defRectangle ( LOW_X+120, LOW_Y+10, LOW_X+160, HIGH_Y-50 ) );

	SRGP_setColor ( 4 );
	SRGP_ellipse ( SRGP_defRectangle ( LOW_X+20, LOW_Y+20, LOW_X+30, LOW_Y+30 ) );
	SRGP_ellipse ( SRGP_defRectangle ( LOW_X+170, LOW_Y+50, LOW_X+230, LOW_Y+110 ) );

	SRGP_setColor ( 5 );
	SRGP_ellipse ( SRGP_defRectangle ( HIGH_X-50, LOW_Y-50, HIGH_X+50, LOW_Y+50 ) );
	SRGP_ellipse ( SRGP_defRectangle ( LOW_X, HIGH_Y-30, HIGH_X+200, HIGH_Y+50 ) );
}

void elli002 ()
{
	SRGP_loadCommonColor ( 2, "red" );
	SRGP_loadCommonColor ( 3, "green" );
	SRGP_loadCommonColor ( 4, "blue" );
	SRGP_loadCommonColor ( 5, "yellow" );

	SRGP_setColor ( 2 );
	SRGP_fillEllipse ( SRGP_defRectangle ( LOW_X-100, LOW_Y+50, LOW_X+100, LOW_Y+100 ) );

	SRGP_setColor ( 3 );
	SRGP_fillEllipse ( SRGP_defRectangle ( LOW_X+120, LOW_Y+10, LOW_X+160, HIGH_Y-50 ) );

	SRGP_setColor ( 4 );
	SRGP_fillEllipse ( SRGP_defRectangle ( LOW_X+20, LOW_Y+20, LOW_X+30, LOW_Y+30 ) );
	SRGP_fillEllipse ( SRGP_defRectangle ( LOW_X+170, LOW_Y+50, LOW_X+230, LOW_Y+110 ) );

	SRGP_setColor ( 5 );
	SRGP_fillEllipse ( SRGP_defRectangle ( HIGH_X-50, LOW_Y-50, HIGH_X+50, LOW_Y+50 ) );
	SRGP_fillEllipse ( SRGP_defRectangle ( LOW_X, HIGH_Y-30, HIGH_X+200, HIGH_Y+50 ) );
}


void translate_verts (
					const int vert_count,
					const int *in_x_coords, const int *in_y_coords,
					int *out_x_coords, int *out_y_coords,
					const int x, const int y )
{
	int i;
	for ( i = 0; i < vert_count; ++i )
	{
		*out_x_coords = *in_x_coords + x;
		*out_y_coords = *in_y_coords + y;
		
		++in_x_coords; ++out_x_coords;
		++in_y_coords; ++out_y_coords;
	}
}

void scale_verts (
					const int vert_count,
					const int *in_x_coords, const int *in_y_coords,
					int *out_x_coords, int *out_y_coords,
					const float sx, const float sy )
{
	int i;
	for ( i = 0; i < vert_count; ++i )
	{
		*out_x_coords = *in_x_coords * sx;
		*out_y_coords = *in_y_coords * sy;
		
		++in_x_coords; ++out_x_coords;
		++in_y_coords; ++out_y_coords;
	}
}

void rotate_verts (
					const int vert_count,
					const int *in_x_coords, const int *in_y_coords,
					int *out_x_coords, int *out_y_coords,
					const float angle )
{
	int i;
	for ( i = 0; i < vert_count; ++i )
	{
		*out_x_coords = *in_x_coords*cosf(angle) - *in_y_coords*sinf(angle);
		*out_y_coords = *in_x_coords*sinf(angle) + *in_y_coords*cosf(angle);
		
		++in_x_coords; ++out_x_coords;
		++in_y_coords; ++out_y_coords;
	}
}


void show_stars ( void (*fp)(int, int*,int*) )
{
	int x[NUM_VERTS], y[NUM_VERTS];
	
	SRGP_loadCommonColor ( 4, "blue" );
	SRGP_setColor ( 4 );
	
	translate_verts ( NUM_VERTS, vx, vy, x, y, 100, 180 );
	fp ( NUM_VERTS, x, y );
	
	rotate_verts    ( NUM_VERTS, vx, vy, x, y, (1.0*-3.1415/2.0)/5.0 );
	scale_verts     ( NUM_VERTS,  x,  y, x, y, 0.9, 0.9 );
	translate_verts ( NUM_VERTS,  x,  y, x, y, 150, 160 );
	fp ( NUM_VERTS, x, y );
	
	rotate_verts    ( NUM_VERTS, vx, vy, x, y, (2.0*-3.1415/2.0)/5.0 );
	scale_verts     ( NUM_VERTS,  x,  y, x, y, 0.9, 0.9 );
	translate_verts ( NUM_VERTS,  x,  y, x, y, 190, 140 );
	fp ( NUM_VERTS, x, y );

	rotate_verts    ( NUM_VERTS, vx, vy, x, y, (3.0*-3.1415/2.0)/5.0 );
	scale_verts     ( NUM_VERTS,  x,  y, x, y, 0.8, 0.8 );
	translate_verts ( NUM_VERTS,  x,  y, x, y, 220, 120 );
	fp ( NUM_VERTS, x, y );

	rotate_verts    ( NUM_VERTS, vx, vy, x, y, (4.0*-3.1415/2.0)/5.0 );
	scale_verts     ( NUM_VERTS,  x,  y, x, y, 0.7, 0.7 );
	translate_verts ( NUM_VERTS,  x,  y, x, y, 240, 100 );
	fp ( NUM_VERTS, x, y );
	
	rotate_verts    ( NUM_VERTS, vx, vy, x, y, (5.0*-3.1415/2.0)/5.0 );
	scale_verts     ( NUM_VERTS,  x,  y, x, y, 0.6, 0.6 );
	translate_verts ( NUM_VERTS,  x,  y, x, y, 250,  80 );
	fp ( NUM_VERTS, x, y );
}

void poly001 ()
{
	show_stars ( &SRGP_polyPointCoord );
}

void poly002 ()
{
	SRGP_setMarkerStyle ( MARKER_CIRCLE );
	SRGP_setMarkerSize ( 10 );
	show_stars ( &SRGP_polyMarkerCoord );
}

void poly003 ()
{
	SRGP_setMarkerStyle ( MARKER_SQUARE );
	SRGP_setMarkerSize ( 3 );
	show_stars ( &SRGP_polyMarkerCoord );
}

void poly004 ()
{
	SRGP_setMarkerStyle ( MARKER_X );
	SRGP_setMarkerSize ( 6 );
	show_stars ( &SRGP_polyMarkerCoord );
}

void poly005 ()
{
	show_stars ( &SRGP_polyLineCoord );
}

void poly006 ()
{
	show_stars ( &SRGP_polygonCoord );
}

void color001 ()
{
	unsigned short r[] = {  56, 255, 255,  40, 139 };
	unsigned short g[] = {  87, 140, 204, 174,  17 };
	unsigned short b[] = { 155,   0,   0,  78, 116 };
	
	SRGP_loadColorTable ( 2, sizeof ( r ) / sizeof ( unsigned short ),
		( unsigned short * ) &r, ( unsigned short * ) &g, ( unsigned short * ) &b );
	
	SRGP_setColor ( 2 );
	SRGP_fillRectangleCoord ( LOW_X+10,  LOW_Y+10, LOW_X+50,  HIGH_Y-10 );

	SRGP_setColor ( 3 );
	SRGP_fillRectangleCoord ( LOW_X+60,  LOW_Y+10, LOW_X+100, HIGH_Y-10 );

	SRGP_setColor ( 4 );
	SRGP_fillRectangleCoord ( LOW_X+110, LOW_Y+10, LOW_X+150, HIGH_Y-10 );

	SRGP_setColor ( 5 );
	SRGP_fillRectangleCoord ( LOW_X+160, LOW_Y+10, LOW_X+200, HIGH_Y-10 );
	
	SRGP_setColor ( 6 );
	SRGP_fillRectangleCoord ( LOW_X+210, LOW_Y+10, LOW_X+250, HIGH_Y-10 );
}

void color002 ()
{
	typedef struct 
	{
		int r, g, b;
		char *name;
	} ADI_sCommonColor;
	
	extern const ADI_sCommonColor* ADI_CommonColors[];
	const ADI_sCommonColor* pColor = ( ADI_sCommonColor* )&ADI_CommonColors;
	
	const int swatch_size = 12;
	
	int x = LOW_X+5;
	int y = LOW_Y+5;
	
	do
	{
		if ( x + swatch_size > HIGH_X )
		{
			x = LOW_X+5;
			y += swatch_size + 5;
		}
		
		SRGP_setColor ( 0 );
		SRGP_loadCommonColor ( 2, pColor->name );
		SRGP_setColor ( 2 );
		
		SRGP_fillRectangleCoord ( x, y, x+swatch_size, y+swatch_size );
		
		++pColor;
		x += swatch_size + 5;
		
	} while ( strcmp ( pColor->name, "thistle" ) );
}


void show_font (void)
{
	SRGP_loadCommonColor ( 2, "red" );
	SRGP_loadCommonColor ( 3, "green" );
	SRGP_loadCommonColor ( 4, "blue" );
	SRGP_loadCommonColor ( 5, "yellow" );

	SRGP_setFont ( 2 ); SRGP_setColor ( 2 );
	SRGP_text (SRGP_defPoint ( LOW_X+10, HIGH_Y-20 ), "Regular text, next line clipped." );
	SRGP_text (SRGP_defPoint ( LOW_X-20, HIGH_Y-40 ), "Clipped." );
	
	SRGP_setFont ( 3 ); SRGP_setColor ( 3 );
	SRGP_text (SRGP_defPoint ( LOW_X+10, HIGH_Y-60 ), "Bold text." );

	SRGP_setFont ( 4 ); SRGP_setColor ( 4 );
	SRGP_text (SRGP_defPoint ( LOW_X+10, HIGH_Y-80 ), "Italic text." );

	SRGP_setFont ( 5 ); SRGP_setColor ( 5 );
	SRGP_text (SRGP_defPoint ( LOW_X+10, HIGH_Y-100 ), "Bold-Italic text." );
}

void font001 ()
{
	SRGP_ADI_loadFont ( 2, ( void * ) &ADI_font_timR14 );
	SRGP_ADI_loadFont ( 3, ( void * ) &ADI_font_timB14 );
	SRGP_ADI_loadFont ( 4, ( void * ) &ADI_font_timI14 );
	SRGP_ADI_loadFont ( 5, ( void * ) &ADI_font_timBI14 );
	show_font ();
}

void font002 ()
{
	SRGP_ADI_loadFont ( 2, ( void * ) &ADI_font_courR14 );
	SRGP_ADI_loadFont ( 3, ( void * ) &ADI_font_courB14 );
	SRGP_ADI_loadFont ( 4, ( void * ) &ADI_font_courO14 );
	SRGP_ADI_loadFont ( 5, ( void * ) &ADI_font_courBO14 );
	show_font ();
}

void font003 ()
{
	SRGP_ADI_loadFont ( 2, ( void * ) &ADI_font_helvR14 );
	SRGP_ADI_loadFont ( 3, ( void * ) &ADI_font_helvB14 );
	SRGP_ADI_loadFont ( 4, ( void * ) &ADI_font_helvO14 );
	SRGP_ADI_loadFont ( 5, ( void * ) &ADI_font_helvBO14 );
	show_font ();
}

void font004 ()
{
	SRGP_ADI_loadFont ( 2, ( void * ) &ADI_font_lubR14 );
	SRGP_ADI_loadFont ( 3, ( void * ) &ADI_font_lubB14 );
	SRGP_ADI_loadFont ( 4, ( void * ) &ADI_font_lubI14 );
	SRGP_ADI_loadFont ( 5, ( void * ) &ADI_font_lubBI14 );
	show_font ();
}

void canv001 ()
{
	canvasID logo;
	rectangle rect;
	int y1;
	unsigned short r = 96, g = 103, b = 172;
	int height, width;
	int x, y;
	
	logo = SRGP_createCanvas ( 21, 21 );
	rect = SRGP_defRectangle ( 0, 0, 20, 20 );
	
	SRGP_setColor ( 0 );
	SRGP_loadColorTable ( 2, 1, &r, &g, &b );
	SRGP_setColor ( 2 );
	
	SRGP_fillRectangle ( rect );
	SRGP_setColor ( 0 );
		
	for ( y1 = 3; y1 <= 10 ; ++y1 )
	{
		int x1 = 2;
		int x2 = 2 + 2 * ( y1 - 3 );
		int y2 = 20 - y1;
		
		SRGP_line ( SRGP_defPoint ( x1, y1 ), SRGP_defPoint ( x2, y1 ) );
		SRGP_line ( SRGP_defPoint ( x1, y2 ), SRGP_defPoint ( x2, y2 ) );
	}
	
	/* Tile this bitmap on the main screen canvas */
	
	SRGP_useCanvas ( 0 );
	
	SRGP_inquireCanvasSize ( logo, &width, &height );
	width += 5;
	height += 5;
	
	for ( x = 13; x <= (NTSC_WIDTH); x += width )
		for ( y = 13; y <= (NTSC_HEIGHT); y += height )
		{
			SRGP_copyPixel ( logo, rect, SRGP_defPoint ( x, y ) );
		}
	
	SRGP_deleteCanvas ( logo );
}

void style001 ()
{
	int i;
	
	SRGP_setColor ( SRGPWHITE );

	SRGP_setLineStyle ( CONTINUOUS );
	SRGP_line ( SRGP_defPoint ( LOW_X+10, LOW_Y+10 ), SRGP_defPoint ( LOW_X+10, HIGH_Y-10 ) );
	
	SRGP_setLineStyle ( DASHED );
	SRGP_line ( SRGP_defPoint ( LOW_X+20, LOW_Y+10 ), SRGP_defPoint ( LOW_X+20, HIGH_Y-10 ) );

	SRGP_setLineStyle ( DOTTED );
	SRGP_line ( SRGP_defPoint ( LOW_X+30, LOW_Y+10 ), SRGP_defPoint ( LOW_X+30, HIGH_Y-10 ) );
	
	SRGP_setLineStyle ( DOT_DASHED );
	SRGP_line ( SRGP_defPoint ( LOW_X+40, LOW_Y+10 ), SRGP_defPoint ( LOW_X+40, HIGH_Y-10 ) );
	
	for ( i = 1; i < 20; ++i )
		SRGP_line ( SRGP_defPoint ( LOW_X+40+i, LOW_Y+10-i ), SRGP_defPoint ( LOW_X+40+i, HIGH_Y-10+i ) );
		
	SRGP_rectangleCoord ( LOW_X+70, LOW_Y+10, LOW_X+80, HIGH_Y-10 );
	SRGP_fillRectangleCoord ( LOW_X+90, LOW_Y+10, LOW_X+100, HIGH_Y-10 );

	SRGP_setMarkerStyle ( MARKER_SQUARE );
	SRGP_setMarkerSize ( 16 );
	SRGP_markerCoord ( LOW_X+110, LOW_Y+50 );
	
	SRGP_setMarkerStyle ( MARKER_X );
	SRGP_setMarkerSize ( 16 );
	SRGP_markerCoord ( LOW_X+110, LOW_Y+100 );
	
	SRGP_ellipse ( SRGP_defRectangle ( LOW_X+130, LOW_Y+10, LOW_X+140, HIGH_Y-10 ) );

	SRGP_setLineStyle ( CONTINUOUS );
}

void draw_tile ( int x1, int y1, int x2, int y2, char *text, int face_color, int top_edge_color, int bottom_edge_color, int text_color, int text_font )
{
	int width, height, descent;
	
	// Fill the face of the button
	SRGP_setColor ( face_color );
	SRGP_fillRectangleCoord ( x1+2, y1+2, x2-2, y2-2 );

	// Draw the bottom and right edges	
	SRGP_setColor ( bottom_edge_color );
	SRGP_lineCoord ( x1, y1, x2, y1 );
	SRGP_lineCoord ( x1+1, y1+1, x2-1, y1+1 );
	SRGP_lineCoord ( x2, y1, x2, y2 );
	SRGP_lineCoord ( x2-1, y1+1, x2-1, y2-1 );
	
	// Draw the top and left edges
	SRGP_setColor ( top_edge_color );
	SRGP_lineCoord ( x2-1, y2, x1, y2 );
	SRGP_lineCoord ( x2-2, y2-1, x1+1, y2-1 );
	SRGP_lineCoord ( x1, y2, x1, y1 );
	SRGP_lineCoord ( x1+1, y2-1, x1+1, y1+1 );

	// Put the text left-aligned, vertically centered.
	SRGP_setColor ( text_color );
	SRGP_setFont ( text_font );
	SRGP_inquireTextExtent ( text, &width, &height, &descent );
	SRGP_text ( SRGP_defPoint ( x1+5, y1+((y2-y1)/2-height/2)), text );
}

void style002 ()
{
	static char pat[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
	SRGP_setFillStyle ( SOLID );
	SRGP_setColor ( SRGPWHITE );
	SRGP_fillEllipse ( SRGP_defRectangle ( LOW_X+10, LOW_Y+50, HIGH_X-10, HIGH_Y-50 ) );

	SRGP_loadCommonColor ( 2, "red" );
	SRGP_loadCommonColor ( 3, "blue" );
	SRGP_setColor ( 2 );
	SRGP_setBackgroundColor ( 3 );
	
	SRGP_setFillStyle ( BITMAP_PATTERN_TRANSPARENT );
	SRGP_loadBitmapPattern ( 3, (char * ) pat );
	SRGP_setFillBitmapPattern ( 3 );
	SRGP_fillEllipse ( SRGP_defRectangle ( LOW_X+30, LOW_Y+80, LOW_X+60, HIGH_Y-40 ) );
	SRGP_fillRectangleCoord ( LOW_X+150, HIGH_Y-70, HIGH_X-10, HIGH_Y-10 );
	
	SRGP_setFillStyle ( BITMAP_PATTERN_OPAQUE );
	SRGP_fillRectangleCoord ( LOW_X+150, LOW_Y+10, HIGH_X-10, LOW_Y+70 );
	SRGP_fillEllipse ( SRGP_defRectangle ( LOW_X+70, LOW_Y+80, LOW_X+100, HIGH_Y-40 ) );
	
	SRGP_setFillStyle ( SOLID );
}

void demo001 ()
{
	// Set-top box DirecTV/DISH 

	const int marine_face  = 2;
	const int marine_light = 3;
	const int marine_dark  = 4;
	
	const int marine_grey  = 5;
	const int marine_grey_light = 6;
	const int marine_grey_dark = 7;
	
	const int marine_cursor = 8;
	
	unsigned short r[] = {136,200,72, 160,210, 90,255};
	unsigned short g[] = {192,224,144,160,210, 90,255};
	unsigned short b[] = {184,216,136,164,214, 94,128};
	
	SRGP_loadColorTable ( 2, sizeof ( r ) / sizeof ( unsigned short ), r, g, b );
	SRGP_ADI_loadFont ( 2, ( void * ) &ADI_font_timR10 );

	// Column Headings
	draw_tile ( LOW_X+1,   LOW_Y+140, LOW_X+99,  LOW_Y+159, "Channel", marine_grey, marine_grey_light, marine_grey_dark, SRGPWHITE, 2 );
	draw_tile ( LOW_X+100, LOW_Y+140, LOW_X+149, LOW_Y+159, "8:00",    marine_grey, marine_grey_light, marine_grey_dark, SRGPWHITE, 2 );
	draw_tile ( LOW_X+150, LOW_Y+140, LOW_X+199, LOW_Y+159, "8:30",    marine_grey, marine_grey_light, marine_grey_dark, SRGPWHITE, 2 );
	draw_tile ( LOW_X+200, LOW_Y+140, LOW_X+249, LOW_Y+159, "9:00",    marine_grey, marine_grey_light, marine_grey_dark, SRGPWHITE, 2 );
	draw_tile ( LOW_X+250, LOW_Y+140, LOW_X+299, LOW_Y+159, "9:30",    marine_grey, marine_grey_light, marine_grey_dark, SRGPWHITE, 2 );

	draw_tile ( LOW_X+1,   LOW_Y+120, LOW_X+99,   LOW_Y+139, "2 PBS",    marine_grey, marine_grey_light, marine_grey_dark, SRGPWHITE, 2 );
	draw_tile ( LOW_X+100, LOW_Y+120, LOW_X+199,  LOW_Y+139, "NOW With Bill M...",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	draw_tile ( LOW_X+200, LOW_Y+120, LOW_X+249,  LOW_Y+139, "Washin...",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	draw_tile ( LOW_X+250, LOW_Y+120, LOW_X+299,  LOW_Y+139, "Tucke...",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	
	draw_tile ( LOW_X+1,   LOW_Y+100, LOW_X+99,  LOW_Y+119, "4 CBS (HD)",    marine_grey, marine_grey_light, marine_grey_dark, SRGPWHITE, 2 );
	draw_tile ( LOW_X+100, LOW_Y+100, LOW_X+199,  LOW_Y+119, "Joan of Arcadia",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	draw_tile ( LOW_X+200, LOW_Y+100, LOW_X+299,  LOW_Y+119, "JAG",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	
	draw_tile ( LOW_X+1,   LOW_Y+ 80, LOW_X+99,  LOW_Y+ 99, "5 ABC (HD)",    marine_grey, marine_grey_light, marine_grey_dark, SRGPWHITE, 2 );
	draw_tile ( LOW_X+100, LOW_Y+ 80, LOW_X+149, LOW_Y+ 99, "George...",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	draw_tile ( LOW_X+150, LOW_Y+ 80, LOW_X+199, LOW_Y+ 99, "Married...",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	draw_tile ( LOW_X+200, LOW_Y+ 80, LOW_X+249, LOW_Y+ 99, "Hope &...",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	draw_tile ( LOW_X+250, LOW_Y+ 80, LOW_X+299, LOW_Y+ 99, "Life W...",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	
	draw_tile ( LOW_X+1,   LOW_Y+ 60, LOW_X+99,  LOW_Y+ 79, "7 NBC (HD)",    marine_grey, marine_grey_light, marine_grey_dark, SRGPWHITE, 2 );
	draw_tile ( LOW_X+100, LOW_Y+ 60, LOW_X+199, LOW_Y+ 79, "Dateline NBC",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	draw_tile ( LOW_X+200, LOW_Y+ 60, LOW_X+299, LOW_Y+ 79, "Dateline NBC",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	
	draw_tile ( LOW_X+1,   LOW_Y+ 40, LOW_X+99,  LOW_Y+ 59, "13 FOX",   marine_grey, marine_grey_light, marine_grey_dark, SRGPWHITE, 2 );
	draw_tile ( LOW_X+100, LOW_Y+ 40, LOW_X+149, LOW_Y+ 59, "Bernie...",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	draw_tile ( LOW_X+150, LOW_Y+ 40, LOW_X+199, LOW_Y+ 59, "Method...",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	draw_tile ( LOW_X+200, LOW_Y+ 40, LOW_X+299, LOW_Y+ 59, "The Jury",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	
	draw_tile ( LOW_X+1,   LOW_Y+ 20, LOW_X+99,  LOW_Y+ 39, "22 MSNBC", marine_grey, marine_grey_light, marine_grey_dark, SRGPWHITE, 2 );
	draw_tile ( LOW_X+100, LOW_Y+ 20, LOW_X+199, LOW_Y+ 39, "Countdown With K...",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	draw_tile ( LOW_X+200, LOW_Y+ 20, LOW_X+299, LOW_Y+ 39, "Deborah Norville",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	
	draw_tile ( LOW_X+1,   LOW_Y+  0, LOW_X+99,  LOW_Y+ 19, "24 DISN",  marine_grey, marine_grey_light, marine_grey_dark, SRGPWHITE, 2 );
	draw_tile ( LOW_X+100, LOW_Y+  0, LOW_X+249, LOW_Y+ 19, "Toy Story *** (1995) G",    marine_face, marine_cursor, marine_cursor, SRGPBLACK, 2 );
	draw_tile ( LOW_X+250, LOW_Y+  0, LOW_X+399, LOW_Y+ 19, "Toy Story *** (1995) G",    marine_face, marine_light, marine_dark, SRGPBLACK, 2 );
	
	return;
}

void demo002 ()
{
	int width, height, descent;
	char *running_time = "4:14";

	const int button_face  = 2;
	const int button_light = 3;
	const int button_dark  = 4;
	const int vol_bar      = 5;
	const int novol_bar    = 6;
	
	unsigned short r[] = {224,255,157,  0,255};
	unsigned short g[] = {223,251,157,255,255};
	unsigned short b[] = {227,240,161,  0,  0};

	SRGP_loadColorTable ( 2, sizeof ( r ) / sizeof ( unsigned short ), r, g, b );
	SRGP_ADI_loadFont ( 2, ( void * ) &ADI_font_timR10 );
	
	// Buttons at the bottom
	draw_tile ( LOW_X+10,  LOW_Y+4, LOW_X+69,  LOW_Y+19, "Browse...", button_face, button_light, button_dark, SRGPBLACK, 2 );
	draw_tile ( LOW_X+90,  LOW_Y+4, LOW_X+149, LOW_Y+19, "ID3 Info...", button_face, button_light, button_dark, SRGPBLACK, 2 );
	draw_tile ( LOW_X+170, LOW_Y+4, LOW_X+229, LOW_Y+19, "Settings...", button_face, button_light, button_dark, SRGPBLACK, 2 );
	
	// Title Info
	SRGP_setFont ( 0 );
	SRGP_setColor ( button_face );
	SRGP_text ( SRGP_defPoint ( LOW_X+10, LOW_Y+130 ), "Led Zeppelin" );
	SRGP_text ( SRGP_defPoint ( LOW_X+10, LOW_Y+115 ),  "Heartbreaker" );
	SRGP_text ( SRGP_defPoint ( LOW_X+10, LOW_Y+100  ),  "Led Zeppelin II (\xa9 1969)" );
	
	// Channel volume and time remaining
	SRGP_rectangleCoord ( LOW_X+10, LOW_Y+25, HIGH_X-10, LOW_Y+39 );
	SRGP_fillRectangleCoord ( LOW_X+10, LOW_Y+25, LOW_X+65, LOW_Y+39 );
	SRGP_inquireTextExtent ( running_time, &width, &height, &descent );
	SRGP_text ( SRGP_defPoint ( (LOW_X+10+HIGH_X-10)/2-width/2, LOW_Y+26+((15)/2-height/2)), running_time );
	
	unsigned short cr=0;
	unsigned short cg=255;
	unsigned short cb=0;
	const int num_ticks = 12;
	
	int i;
	
	for ( i = 0; i < num_ticks; ++i )
	{
		SRGP_loadColorTable ( 2 + sizeof ( r ) / sizeof ( unsigned short ), 1, &cr, &cg, &cb );
		SRGP_setColor ( SRGPBLACK );
		SRGP_setColor ( 2 + sizeof ( r ) / sizeof ( unsigned short ) );
		
		if ( i < num_ticks - 3 )
			SRGP_fillRectangleCoord ( LOW_X+10+i*20, LOW_Y+50, LOW_X+10+(i+1)*20-2, LOW_Y+65 );
		else
			SRGP_lineCoord ( LOW_X+10+i*20, LOW_Y+50, LOW_X+10+i*20, LOW_Y+65 );
		
		if ( i < num_ticks - 1 )
			SRGP_fillRectangleCoord ( LOW_X+10+i*20, LOW_Y+75, LOW_X+10+(i+1)*20-2, LOW_Y+90 );
		else
			SRGP_lineCoord ( LOW_X+10+i*20, LOW_Y+75, LOW_X+10+i*20, LOW_Y+90 );
		
		cr += 255/num_ticks;
		cg -= 255/num_ticks;
	}
	
	// Battery Indicator
	
	int batt_x[] = {LOW_X+10,  LOW_X+10, LOW_X+50, LOW_X+50, LOW_X+55, LOW_X+55,  LOW_X+50,  LOW_X+50  };
	int batt_y[] = {HIGH_Y-20, HIGH_Y-5, HIGH_Y-5, HIGH_Y-8, HIGH_Y-8, HIGH_Y-17, HIGH_Y-17, HIGH_Y-20 };
	SRGP_polygonCoord ( sizeof ( batt_x ) / sizeof ( int ), batt_x, batt_y );
	SRGP_fillRectangleCoord ( LOW_X+10, HIGH_Y-20, LOW_X+15, HIGH_Y-5 );
	
	// Headphones
	
	const int x_ref = LOW_X+120;
	
	SRGP_setColor ( 2 );
	SRGP_ellipse ( SRGP_defRectangle ( x_ref, HIGH_Y-20, x_ref+15, HIGH_Y-4 ));
	SRGP_fillEllipse ( SRGP_defRectangle ( x_ref+5, HIGH_Y-15, x_ref+10, HIGH_Y-9 ));
	SRGP_lineCoord ( x_ref+8, HIGH_Y-12, x_ref-10, HIGH_Y-12 );
	SRGP_lineCoord ( x_ref-10, HIGH_Y-12, x_ref-7, HIGH_Y-9 );
	SRGP_lineCoord ( x_ref-10, HIGH_Y-12, x_ref-7, HIGH_Y-15 );
	
	SRGP_setColor ( vol_bar );
	SRGP_fillRectangleCoord ( x_ref+20, HIGH_Y-20, x_ref+22, HIGH_Y-17 );
	SRGP_fillRectangleCoord ( x_ref+24, HIGH_Y-20, x_ref+26, HIGH_Y-14 );
	SRGP_fillRectangleCoord ( x_ref+28, HIGH_Y-20, x_ref+30, HIGH_Y-11 );
	SRGP_fillRectangleCoord ( x_ref+32, HIGH_Y-20, x_ref+32, HIGH_Y-8 );
	SRGP_fillRectangleCoord ( x_ref+36, HIGH_Y-20, x_ref+36, HIGH_Y-5 );
	
	
	SRGP_setColor ( SRGPWHITE );
	
	return;
}

typedef struct
{
	void (*f)();
	char *name;
	char *description;
} sTest;

sTest TESTS[] =
{
	{ welcome,  "WELCOME",                 "Welcome to SRGP" },
	{ point001, "SRGP_point...()",         "Grid of points, including clipped points" },
	{ line001,  "SRGP_line()",             "Lines of various slopes and colors" },
	{ line002,  "SRGP_line()",             "Clipped with slopes at (or close to) zero/infinity" },
	{ rect001,  "SRGP_rectangle...()",     "Unfilled rectangles, upper rectangles clipped" },
	{ rect002,  "SRGP_fillRectangle...()", "Filled rectangles, upper rectangles clipped" },
	{ elli001,  "SRGP_ellipse...()",       "Unfilled ellipses, some clipped" },
	{ elli002,  "SRGP_fillEllipse()",      "Filled ellipses, some clipped" },
	{ poly001,  "SRGP_polyPoint()",        "Pixels at a vector of points" },
	{ poly002,  "SRGP_polyMarker()",       "MARKER_CIRCLE at a vector of points" },
	{ poly003,  "SRGP_polyMarker()",       "MARKER_SQUARE at a vector of points" },
	{ poly004,  "SRGP_polyMarker()",       "MARKER_X at a vector of points" },
    { poly005,  "SRGP_polyLine()",         "Lines between a vector of points" },
	{ poly006,  "SRGP_polygon()",          "Closed polygon from a vector of points" },
	{ color001, "SRGP_loadColorTable()",   "Analog Devices' color palette using custom RGB values" },
	{ color002, "SRGP_loadCommonColor()",  "Out-of-the-box color definitions" },
	{ font001,  "SRGP_text()",             "Times Roman 14-point font with various styles and colors" },
	{ font002,  "SRGP_text()",             "Courier 14-point font with various styles and colors" },
	{ font003,  "SRGP_text()",             "Helvetia 14-point font with various styles and colors" },
	{ font004,  "SRGP_text()",             "Lucida 14-point font with various styles and colors" },
	{ canv001,  "SRGP_...Canvas()",        "Image created once \"off screen\" and pasted onto main screen" },
	{ style001, "SRGP_setLineStyle()",     "Various line styles, with clipping" },
	{ style002, "SRGP_setFillStyle()",     "Solid, transapent, and opaque fill styles" },
	{ demo001,  "STB Programming Guide",   "Example set-top box GUI rendered in SRGP" },
	{ demo002,  "Multimedia Jukebox",      "Example portable multimedia player GUI rendered in SRGP" },
};

// This handler just cycle the LED's and loop
      
static ADI_INT_HANDLER(Default_Handler)
{
    ezErrorCheck(1);
    return(ADI_INT_RESULT_PROCESSED); 
}



/*********************************************************************

	Function:		Callback

	Description:	Each type of callback event has it's own unique ID 
					so we can use a single callback function for all 
					callback events.  The switch statement tells us 
					which event has occurred.
					
					In the example, we'll get a callback when the PPI 
					has completed processing of the input buffer.  We 
					don't really need the callback function as the main 
					code uses the ProcessedFlag field of the buffer to 
					determine when the inbound buffer has completed 
					processing, but it's included here for illustrative 
					purposes.  
					
					Note that in the device driver model, in order to 
					generate a callback for buffer completion, the 
					CallbackParameter of the buffer must be set to a non-NULL 
					value.  That non-NULL value is then passed to the 
					callback function as the pArg parameter.  In the example,
					the CallbackParameter is set to be the address of the 
					buffer itself.  That allows	the callback function to 
					determine which buffer was processed.  Often the 
					CallbackParameter value is set to NULL for every buffer 
					except the last buffer in a chain. That technique causes 
					the callback function to get called only when the last 
					buffer in the chain has been processed.  

*********************************************************************/


static void Callback(
	void *AppHandle,
	u32  Event,
	void *pArg)
{
	
	static unsigned int Counter = 0;	// count the number of input buffers processed
	ADI_DEV_BUFFER *pBuffer;			// pointer to the buffer that was processed
	
	// CASEOF (event type)
	switch (Event) {
		
		// CASE (buffer processed)
		case ADI_DEV_EVENT_BUFFER_PROCESSED:
		
			// point to the buffer
			pBuffer = (ADI_DEV_BUFFER *)pArg;
	
			// increment our counter
			Counter++;
			break;
			
		// CASE (an error)
		case ADI_DEV_EVENT_DMA_ERROR_INTERRUPT:
		case ADI_PPI_EVENT_ERROR_INTERRUPT:
		
			// turn on all LEDs and wait for help
			ezTurnOnAllLEDs();
			while (1) ;
			
	// ENDCASE
	}
	
	// return
}

/***********************************************************************

	Function:		ShowTest	 

***********************************************************************/

void ShowTest(int num)
{
	sTest test;
	char buf[16];
	int x,y;

	// Define three rectangles, screen, win, clip
	rectangle screen = SRGP_defRectangle ( 0, 0, (NTSC_WIDTH)-1, (NTSC_HEIGHT/2)-1 );
	rectangle win = SRGP_defRectangle ( LOW_X, LOW_Y, HIGH_X, HIGH_Y );
	rectangle clip = SRGP_defRectangle ( LOW_X+1, LOW_Y+1, HIGH_X-1, HIGH_Y-1 );
	
	// Use the test indicated by the index, 'num'
	test = TESTS[num];
		
	// Set background color to black
	SRGP_setColor ( SRGPBLACK );
	
	// clip the screen rectangle
	SRGP_setClipRectangle ( screen );
	
	SRGP_fillRectangle ( screen );
	SRGP_setColor ( SRGPWHITE );
	SRGP_rectangle ( win );
	SRGP_setFont ( 1 );
	sprintf ( buf, "%d of %d", num+1, ( sizeof ( TESTS ) / sizeof ( sTest ) ) );
	{
		int width, height, descent;
		SRGP_inquireTextExtent ( buf, &width, &height, &descent);
		x = HIGH_X-width;
	}
	SRGP_text ( SRGP_defPoint ( x, LOW_Y-9 ), buf );
	y = HIGH_Y+3;
	SRGP_text ( SRGP_defPoint ( LOW_X, y ), test.description );
		
	SRGP_setFont ( 0 );
	y+= 10;
	SRGP_text ( SRGP_defPoint ( LOW_X, y ), test.name );
		
	SRGP_setClipRectangle ( clip );
		
	test.f ( );		
}


/***********************************************************************

	Function:		main	 

***********************************************************************/

int main ()
{
	
	int i, NumTests;
	char *frame_start;
	unsigned short X_pels, Y_pels;
	
	// Changing this address allows the canvas to be located someplace other than 0
	// Remember to allocate memory in the LDF
	frame_start = (char*)0x00;

	X_pels = 1716;
	Y_pels = 525;
	
	/* initialize the ezKit power,EBIU,DMA....*/
	adi_ssl_Init();	

	/* enable and configure async memory */
	ezInit(1);
	
	/* speed up clock frequency */
#if defined(__ADSP_EDINBURGH__)			
	/* only configure 533 as 561 cannot operate a max speed */
	adi_pwr_SetFreq( 0, 0, ADI_PWR_DF_NONE );
#endif     
	// initialize all LEDS
	for (i = EZ_FIRST_LED; i < EZ_NUM_LEDS; i++){
        	ezInitLED(i);
	}
    
	// turn off all the LEDs
	ezTurnOffAllLEDs();
        
	// initialize Buttons used for this application
	ezInitButton(EZ_FIRST_BUTTON);
	ezInitButton(EZ_FIRST_BUTTON+1);
	
	// catch spurious interrupts
	ezErrorCheck(adi_int_CECHook(3, Default_Handler, &Default_Handler, FALSE)); 
	ezErrorCheck(adi_int_CECHook(5, Default_Handler, &Default_Handler, FALSE)); 
 	ezErrorCheck(adi_int_CECHook(2, Default_Handler, &Default_Handler, FALSE));  // ANMI
 	ezErrorCheck(adi_int_CECHook(4, Default_Handler, &Default_Handler, FALSE));  // RESERVED

		
	// Resets the Video Encoder chip 
	ezEnableVideoEncoder();

	// Initialize the video frame
	adi_video_FrameFormat ( frame_start, NTSC_IL);	

		// create a 2D buffer for the video frame
	Buffer.Data = frame_start;
	Buffer.ElementWidth = 1; 
	Buffer.XCount = X_pels;
	Buffer.XModify = 1;		
	Buffer.YCount = Y_pels;
	Buffer.YModify = 1;		
	Buffer.CallbackParameter = NULL;
	Buffer.pNext = NULL;

// open the PPI driver for output	

#if defined(__ADSPBF561__) 	
// The BF561 has two PPI ports, #1 is output.
	ezErrorCheck(adi_dev_Open(adi_dev_ManagerHandle, &ADIPPIEntryPoint, 1, NULL, &DeviceHandle, ADI_DEV_DIRECTION_OUTBOUND, adi_dma_ManagerHandle, NULL, Callback));
#else			
	// open the PPI device for output,  
	ezErrorCheck(adi_dev_Open(adi_dev_ManagerHandle, &ADIPPIEntryPoint, 0, NULL, &DeviceHandle, ADI_DEV_DIRECTION_OUTBOUND, adi_dma_ManagerHandle, NULL, Callback));
#endif

	// configure the PPI device, using the adi_dev_control function
	ezErrorCheck(adi_dev_Control(DeviceHandle, ADI_DEV_CMD_SET_DATAFLOW_METHOD,     (void *)ADI_DEV_MODE_CHAINED_LOOPBACK));
	ezErrorCheck(adi_dev_Control(DeviceHandle, ADI_PPI_CMD_SET_CONTROL_REG,         (void *)0x02));
	ezErrorCheck(adi_dev_Control(DeviceHandle, ADI_PPI_CMD_SET_LINES_PER_FRAME_REG, (void *)525	));

	// Give the buffer to the PPI device
	ezErrorCheck(adi_dev_Write(DeviceHandle, ADI_DEV_2D, (ADI_DEV_BUFFER *)&Buffer));

	SetVideoBufferBaseAddress ( frame_start );
	
	/* NTSC is effectively 360x262 progressive */
	SRGP_begin ( frame_start /*NULL*/, NTSC_WIDTH, (NTSC_HEIGHT/2), /*2^*/ 7, TRUE );

		
	SRGP_ADI_loadFont ( 0, ( void * ) &ADI_font_timR14 );
	SRGP_ADI_loadFont ( 1, ( void * ) &ADI_font_timR10 );
	
	// enable data flow
	ezErrorCheck(adi_dev_Control(DeviceHandle, ADI_DEV_CMD_SET_DATAFLOW, (void *)TRUE));
	
	NumTests = (sizeof(TESTS) / sizeof(sTest)) - 1;
	
	// Start by displaying the first screen
	TEST_INDEX = 0;
	ShowTest(TEST_INDEX);
	
	// Loop forever...
	// Each time one of the first two buttons are depressed, display either 
	// the next (second button) or the previous (first button) screen. 
	while ( TRUE )
	{
		// If first button is depressed
		if( ezIsButtonPushed(EZ_FIRST_BUTTON))
		{
			// Wait for first button to be released
			while( ezIsButtonPushed(EZ_FIRST_BUTTON) );
			
	
			if ( --TEST_INDEX < 0 ) 
				TEST_INDEX = NumTests;				

			ShowTest(TEST_INDEX);

		}
		
	
		// If second button is depressed
		if( ezIsButtonPushed(EZ_FIRST_BUTTON+1))
		{
			// Wait for second button to be released
			while( ezIsButtonPushed(EZ_FIRST_BUTTON+1) );
			
			if ( ++TEST_INDEX >= ( sizeof ( TESTS ) / sizeof ( sTest ) ) )
				TEST_INDEX = 0;

			ShowTest(TEST_INDEX);

		}
	}
}


