//Sourcecode for BlackBox stv5730a development board
//G. Bjoerneseth, LA5EKA - NORWAY, email is gisle at break dot org
//Processor is PIC16F84, compiler HiTech Picc.exe
//Release is preliminary, and has a few bugs. Please replace
//my callsign with yours :)

#include <pic.h>

#define	TRUE			1
#define	FALSE			0	

#define	CLK  RA0
#define	DATA RA1
#define	CSN  RA2

#define BLACK		0
#define BLUE		1
#define GREEN		2
#define CYAN		3
#define RED		4
#define MAGENTA		5
#define YELLOW		6
#define WHITE		7

#define ON		1
#define OFF		0

#define BACKGROUND_ON	1
#define BACKGROUND_OFF	0

#define	BUF_SIZE	10
#define	SCRBKGCOL 0x0E00
#define	CHRBKGCOL 0x0007
#define	CHRBORCOL 0x0038

void printascii(unsigned char color, unsigned char background,char c);
void printch(unsigned char color, unsigned char background,char c);
void puts(unsigned char color, unsigned char background, unsigned char x, unsigned char y, const unsigned char *s);
void setPos(unsigned char x, unsigned char y);
void Reset(void);
void setDisplayedLine(unsigned char line, unsigned char Displayed);
void ClsScr(void);
void txch(unsigned int c);
void setControl(unsigned int control);
void setScrOffset(void);
//void setZoom(unsigned int z);

unsigned char scr_x=0, scr_y=0;
unsigned char scr_h=28, scr_v=24; //High text, video generator


#define LA5EKA
//#define LA1ATV
//#define LA7MHA

#ifdef LA1ATV
const unsigned char CONST_Line0[]=     "| LA1ATV ";
const unsigned char CONST_Line1[]=     "                            ";
const unsigned char CONST_Line2[]=     " Dette er Tonsberg gruppens ";
const unsigned char CONST_Line3[]=     " ATV repeater med midlerti  ";
const unsigned char CONST_Line4[]=     " dig sendetillatelse fra Po ";
const unsigned char CONST_Line5[]=     " st og Teletilsynet  231001 ";
const unsigned char CONST_Line6[]=     "                            ";
const unsigned char CONST_Line7[]=     " LA1T Repeater ansv. LA7MHA ";
const unsigned char CONST_Line8[]=     "____________________________";
const unsigned char CONST_Line9[]=     "LA1ATV      23cm      JO59FE";
const unsigned char CONST_Line10[]=    "1280TX  1246RX 6.0 MHz Audio";
#endif
#ifdef LA5EKA
const unsigned char CONST_Line0[]=     "| LA5EKA ";			//Line zoomed to 3x
const unsigned char CONST_Line1[]=     "      Amateur TV Station    ";
const unsigned char CONST_Line2[]=     "                            ";
const unsigned char CONST_Line3[]=     "   WWL Locator:   JO59FJ    ";
const unsigned char CONST_Line4[]=     "   QTH is Horten  36masl    ";
const unsigned char CONST_Line5[]=     "                            ";
const unsigned char CONST_Line6[]=     "    QRV - Talkback 70cm     ";
const unsigned char CONST_Line7[]=     "         433.500MHz         ";
const unsigned char CONST_Line8[]=     "____________________________"; 
const unsigned char CONST_Line9[]=     "LA5EKA      23cm      JO59FJ";
const unsigned char CONST_Line10[]=    "TX 15W Ant. Vertical HBL6111";
#endif

#ifdef LA7MHA
const unsigned char CONST_Line0[]=     "  LA7MHA ";
const unsigned char CONST_Line1[]=     "                            ";
const unsigned char CONST_Line2[]=     "                            ";
const unsigned char CONST_Line3[]=     "          23cm ATV          ";
const unsigned char CONST_Line4[]=     "          23cm ATV          ";
const unsigned char CONST_Line5[]=     "          23cm ATV          ";
const unsigned char CONST_Line6[]=     "                            ";
const unsigned char CONST_Line7[]=     "                            ";	
const unsigned char CONST_Line8[]=     "                            ";
const unsigned char CONST_Line9[]=     "                            ";
const unsigned char CONST_Line10[]=    "                            ";
#endif     

unsigned int stv_control=0b1101111010100;

#ifdef LA7MHA
unsigned int stv_zoom=   0b1000000000000;
#endif
#ifndef LA7MHA
unsigned int stv_zoom=   0b1000000001010;
#endif


unsigned int stv_color=  0b1000000000001;

unsigned char SyncDetected;

//Sourcecode for BlackBox stv5730a development board
//G. Bjoerneseth, LA5EKA - NORWAY, email is gisle at break dot org
//Processor is PIC16F84, compiler HiTech Picc.exe
//Release is preliminary, and has a few bugs. Please replace
//my callsign with yours :)

/*------------------------------------------------------------------------------------*/
void main()
{
//unsigned int yy, zz;
	unsigned char tt;
	
	SyncDetected=0;
	TRISA= 0b00000000;
	TRISB= 0b11111101;
	RBPU=0;		//Clear bit turns on pullup
	RA0=1;
	RA1=1;
	RA2=1;

	Reset();
	ClsScr();

	stv_control&=0xFFFE;	//Bit 0 indicates mixed mode
	setControl(stv_control);
	#ifdef LA7MHA
	for(tt=1;tt<8;tt++)
		setDisplayedLine(tt, OFF);
	#endif
	#ifndef LA7MHA
	for(tt=0;tt<8;tt++)
		setDisplayedLine(tt, OFF);
	#endif
	puts(WHITE,BACKGROUND_OFF,0,0,  CONST_Line0);
	puts(BLACK,BACKGROUND_ON,0,1,   CONST_Line1);
	puts(BLUE,BACKGROUND_ON,0,2,    CONST_Line2);
	puts(GREEN,BACKGROUND_ON,0,3,   CONST_Line3);
	puts(CYAN,BACKGROUND_ON,0,4,    CONST_Line4);
	puts(RED,BACKGROUND_ON,0,5,     CONST_Line5);
	puts(MAGENTA,BACKGROUND_ON,0,6, CONST_Line6);
	puts(YELLOW,BACKGROUND_ON,0,7,  CONST_Line7);

        puts(WHITE,BACKGROUND_OFF,0,8,  CONST_Line8);
	puts(YELLOW,BACKGROUND_OFF,0,9, CONST_Line9);
	puts(YELLOW,BACKGROUND_OFF,0,10,CONST_Line10);

	while(1)
	{

		if(SyncDetected!=RB0){			//the board is strapped so that the PIC can detect videosync
							//see the datasheet.
			if(!SyncDetected)		//No video input signal detected
			{
				/*
				for(zz=0;zz<1000;zz++)
				{
				for(yy=0;yy<1000;yy++)
					asm("NOP");
				}
				*/
				stv_control|=0x0001;	//Bit 0 indicates fullpage mode
				setControl(stv_control);
				for(tt=0;tt<8;tt++)
					setDisplayedLine(tt, ON);
				puts(YELLOW,BACKGROUND_ON,0,9, CONST_Line9);
				puts(YELLOW,BACKGROUND_ON,0,10,CONST_Line10);
				RB1=0;		//signal out no detected sync

			}
			else
			{
		
				stv_control&=0xFFFE;	//Bit 0 indicates mixed mode
				setControl(stv_control);
				#ifdef LA7MHA
				for(tt=1;tt<8;tt++)
					setDisplayedLine(tt, OFF);
				#endif
				#ifndef LA7MHA
				for(tt=0;tt<8;tt++)
					setDisplayedLine(tt, OFF);
				#endif
				puts(YELLOW,BACKGROUND_OFF,0,9, CONST_Line9);
				puts(YELLOW,BACKGROUND_OFF,0,10,CONST_Line10);
				RB1=1;		//signal out detected sync
			}
			SyncDetected=!SyncDetected;
			}

	}//end while

}	
/*------------------------------------------------------------------------------------*/
void setDisplayedLine(unsigned char line, unsigned char Displayed)
{
	//line is 0:10	
	txch(0b0000011000000+line); 			//SELECT ROW ATTRIBUTES registers (stru=11)
	if(Displayed){
	txch(0b1000011000000);  			//Set Row data, row enabled
	}
	else{
	txch(0b1000001000000);  			//Set Row data, row disabled
	}
}

/*------------------------------------------------------------------------------------*/
void Reset(void)
{
	txch(0x00DB);					    //SEND RESET
	txch(0x1000);  
	txch(0x3000);							
	txch(0x3000);	
	txch(0x00DB);
	txch(0x1000);  
	txch(0b0000011001100);  //SELECT ZOOM REGISTER (1ST CONTROL REG)		address 12
	txch(stv_zoom); 	//SEND ZOOM DATA					address 12
	txch(stv_color); 	//SEND COLOR DATA					address 13
	txch(stv_control);	//Send control data					address 14
	txch(0x1000 + (scr_v << 6) + scr_h); //SEND POSITION DATA			address 15
	txch(0b1000100100100); 	//SEND MODE DATA					address 16
				//(M2 indicates mute high on missing sync, M3 is 32lines)
}
/*------------------------------------------------------------------------------------*/
void ClsScr(void)
{
unsigned int j;
	txch(0b0000000000000);			//Select PAGE ROW 0
	for(j=0;j<=307;j++)
 		txch(0b0001011100001011);	//Write incremental data, character d11 (' ')

	txch(0b0000000000000);			//Select PAGE ROW 0

	txch(0b0000011000000); 			//SELECT ROW ATTRIBUTES, Start at ROW 0
	for(j=0;j<=10;j++)			//SEND ROW ATTRIB DATA, Chars at current row displayed, and have border 
		txch(0b1000011000000);  	//ROW number increments, 0-10.
						//Erase screen with space to prevent initial garbage
}
/*------------------------------------------------------------------------------------*/

void setControl(unsigned int control)
{
	txch(0b0000011001110); 
	txch(control);
}


/*------------------------------------------------------------------------------------*/
void setPos(unsigned char x, unsigned char y)
{
	if(	(x<28) && (y<11))
	{
		scr_x=x; scr_y=y;
	}
}

/*------------------------------------------------------------------------------------*/
void puts(unsigned char color, unsigned char background, unsigned char x, unsigned char y, const unsigned char *s)
{
	setPos(x, y);
	while(*s)
		printascii(color,background,*s++);
}

/*------------------------------------------------------------------------------------*/
void printascii(unsigned char color, unsigned char background,char c)
{
  if(c==' ') {printch(color,background,0x0B);}
  else if(c=='/') {printch(color,background,0x28);}
  else if(c=='|') {printch(color,background,110);}	//sat dish
  else if(c==':') {printch(color,background,0x26);}
  else if(c=='-') {printch(color,background,0x0A);}//den andre er nr 0d100
  else if(c=='_') {printch(color,background,114);}
  else if(c=='.') {printch(color,background,0x27);} 
	else if((c>=65) && (c<95)) {printch(color,background,c-53);}   
	else if((c>=97) && (c<123)) {printch(color,background,c-55);}
	else if((c>=48) && (c<60)) {printch(color,background,c-48);}
}

/*------------------------------------------------------------------------------------*/
void printch(unsigned char color, unsigned char background,char c)
{
unsigned int OutData;
	//Write pointer is Buf[11:8], Stru[7:6],DontCare[5] Depl[4:0]
	txch((scr_y << 8) + scr_x);	//Set write pointer - row(y) + character number(x). Stru is 00 for page address
	scr_x++;
	if (scr_x >= 28)
	{
		scr_x=0;
  	scr_y++;
		if(scr_y >= 11)
		{ scr_x=27; scr_y=10;}
	}
	//[BE,11][R,10][G,9][B,8][BK,7][Charcode, 6:0]
	//txch(0b1 0 100 0 0000000+c);
	OutData=0b1000000000000;
	if(background){
	OutData|=0b0100000000000;	
	}
	OutData=OutData|(color<<8);
	txch(OutData+c); 
}

/*------------------------------------------------------------------------------------*/
void setScrOffset(void)
{
	txch(0b0000011001111); 
	txch(0x1000 + (scr_v << 6) + scr_h);
}

/*------------------------------------------------------------------------------------*/
/*
void setZoom(unsigned int zoom)
{
	txch(0b0000011001100); //SELECT ZOOM REGISTER (1ST CONTROL REG)	address 12
	txch(zoom); 
}
*/

/*------------------------------------------------------------------------------------*/
//This is the function that writes to the stv device
void txch(unsigned int c)
{

	unsigned char	bitno;
	
	CLK = 1;
	DATA= 1;
	CSN = 1;

	CSN = 0;

	bitno = 16;
	do
	{
		CLK = 0;
		if(c & 0x8000)
		{	DATA = 1;}
		else
		{	DATA = 0;}
		CLK = 1;
		c = (c << 1);
	} while(--bitno);  

	CSN = 1;
}



