////////////////////////////////////////////////////////////////////////////////
//  CQ出版社 インターフェース 2008年7月号
//
//  初音ミク・グラフィック表示
//  FRマイコン用プログラム	Copyright(c)2008 Sumio Morioka
//  morioka@fb3.so-net.ne.jp,  http://www002.upp.so-net.ne.jp/morioka/
//
//  本プログラムコードの商業利用，および改変ファイルの二次配布を禁じます．それ以外の
//  利用はとくに制限しませんが，利用によって生じた被害・不利益などに対しては，一切
//  責任を負いませんのでご了承ください．
//
//  また，本プログラムのサンプルとして同梱される初音ミク，はちゅねミク，鏡音リン・レンの
//  画像（フォント・データも含む）は，クリプトン・フューチャー・メディア株式会社
// （http://www.crypton.co.jp）の著作物です．商業利用等については同社へ問い合わせてください．
//
//
// History:
// 1. Original coding by Sumio Morioka, 2008/04/15
//
////////////////////////////////////////////////////////////////////////////////

#include "_fr.h"
#define col_max 41
#define row_max 15

/************************************************************************/
/*   関数のプロトタイプ宣言                                             */
/************************************************************************/
void osdc_init(void); /* OSD初期化関数 */
void set_cursor(int x,int y); /* VRAMアドレス指定関数 */
void clearscreen(void); /* VRAM一括クリア関数 */
void disp_str(unsigned char *str_code); /* 英数字表示関数 */
__interrupt void osdc_int(void); /* OSD割込み関数 */
void v_wait(unsigned int vcnt); /*VSYNCウエイト関数*/

/************************************************************************/
/*   グローバル変数の定義                                               */
/************************************************************************/
static int cursor_x,cursor_y;
unsigned int fill_flag;
unsigned int v_count;

/************************************************************************/
/*   OSD初期化関数                                                      */
/************************************************************************/
void osdc_init(void)
{
	int i;
	/*1. ドットクロック設定コマンド*/
	/* 理想値：XGA HSYNC=48.363KHz,PLL=65MHz(x1344) */
	/* PPG0=48.076KHz , PLL=48.076 x 1344 = 64.6MHz */
	IO_OSDC.IO_OSD_DCLKC1.hword=0x0000; /* DotCLK出力OFF*/
	IO_OSDC.IO_OSD_DCLKC2.hword=0x0540; /* 0x540=1344分周 */
	IO_OSDC.IO_OSD_DCLKC3.hword=0x00ab; /* VCO動作許可,VCO3選択*/
	/*2. OSDC動作制御コマンド */
	IO_OSDC.IO_OSD_ACT1.hword=0x0011; /* 内部PLL使用,DAC動作許可 */
	IO_OSDC.IO_OSD_ACT2.hword=0x0017; /* OSD動作許可,Analog-RGB出力許可 */
	/*3. 入出力端子制御コマンド */
	IO_OSDC.IO_OSD_IOC2.hword = 0x0000; /* 水平・垂直同期信号：負論理 */
	/*4. 同期制御コマンド */
	IO_OSDC.IO_OSD_SYNCC.hword = 0x0040; /* ノンインターレス */
	/*5. 割込み制御コマンド */
	IO_OSDC.IO_OSD_JRC.bit.VIE = 1; /* VSYNC Interrupt Enable */
	IO_OSDC.IO_OSD_JRC.bit.FIE = 1; /* VRAM-Fill Interrupt Enable */
	/*6. 表示期間制御コマンド */
	IO_OSDC.IO_OSD_DPC1.hword=0x0022; /* 垂直方向表示開始制御 */
	IO_OSDC.IO_OSD_DPC2.hword=0x0300; /* 垂直方向表示終了制御 */
	IO_OSDC.IO_OSD_DPC3.hword=0x00AF; /* 水平方向表示開始制御 */
	IO_OSDC.IO_OSD_DPC4.hword=0x0499; /* 水平方向表示終了制御 */
	/*7. 表示位置制御コマンド */
	IO_OSDC.IO_OSD_VDPC.hword = 0x0008; /* 垂直表示位置制御 */
	IO_OSDC.IO_OSD_HDPC.hword = 0x0008; /* 水平表示位置制御 */

	/*8. カラーパレット設定コマンド */
///////////////////////////////////////////////////////////////////////////////
#include "hatsune.h"
///////////////////////////////////////////////////////////////////////////////

	/*9. 文字垂直サイズ制御コマンド */
	IO_OSDC.IO_OSD_CVSC.hword = 0x0077; /* A:32ドット,B:32ドット*/
	/*10. 画面背景文字制御コマンド */
//	IO_OSDC.IO_OSD_SBCC1.hword=0x0010;
	IO_OSDC.IO_OSD_SBCC1.hword=0x0000;
	/*11. 影付背景枠色制御コマンド */
//	IO_OSDC.IO_OSD_SBFCC.hword = 0x0007; /*A:パレット7,B:パレット0*/
	IO_OSDC.IO_OSD_SBFCC.hword = 0x0000; /*A:パレット7,B:パレット0*/
	/*12. 画面出力制御コマンド */
	IO_OSDC.IO_OSD_SOC2.hword = 0x00D0; /* ブリンク制御 */
	/*13. 透明色制御コマンド */
//	IO_OSDC.IO_OSD_THCC.hword = 0x0307; /* 透明色：パレット0,半透明色：パレット7 */
	IO_OSDC.IO_OSD_THCC.hword = 0x0000; /* 透明色：OFF */
	/*14. 行制御データ設定コマンド */
	for(i=0;i<=row_max;i++) {
		set_cursor(0,i); /* 行指定 */
		IO_OSDC.IO_OSD_RCD1.hword = 0x0000; /* 属性の初期化 */
		IO_OSDC.IO_OSD_RCD2.hword = 0x1000; /* 行文字出力許可 */
	}
	/*15. VRAM一括クリア*/
	clearscreen(); 
	/*16. 画面出力制御コマンド*/
//	IO_OSDC.IO_OSD_SOC1.bit.SDS = 1; /* スプライト文字出力許可 */
	IO_OSDC.IO_OSD_SOC1.bit.SDS = 0; /* スプライト文字出力許可 */
	IO_OSDC.IO_OSD_SOC1.bit.UDS = 0; /* 画面背景出力禁止 */
	IO_OSDC.IO_OSD_SOC1.bit.PDS = 0; /* 画面背景文字出力禁止 */
	IO_OSDC.IO_OSD_SOC1.bit.DSP = 1; /* 表示出力許可*/

    IO_OSDC.IO_OSD_GFCC.hword = 0;

}

/************************************************************************/
/*   VRAMアドレス指定関数                                               */
/************************************************************************/
void set_cursor(int x,int y)
{
	cursor_x=x; /* VRAMの水平アドレス */
	cursor_y=y; /* VRAMの垂直アドレス */
	IO_OSDC.IO_OSD_VADR.hword = (unsigned short)((cursor_y << 8) | cursor_x); /*VRAMアドレス設定*/
}

/************************************************************************/
/*   VRAM一括クリア関数                                               */
/************************************************************************/
void clearscreen(void)
{
	fill_flag = 1;
	IO_OSDC.IO_OSD_VADR.hword = 0x8000; /* VRAM-Fill  */
//	IO_OSDC.IO_OSD_CD1.hword  = 0x0A7F; /* 文字色：パレット7、文字背景色：パレット15 */
//	IO_OSDC.IO_OSD_CD1.hword  = 0x0A00; /* 文字色：パレット0、文字背景色：パレット0 */
	IO_OSDC.IO_OSD_CD1.hword  = 0x0000; /* 文字色：パレット0、文字背景色：パレット0 */
	IO_OSDC.IO_OSD_CD2.hword  = 0x0020; /* Fill Character */
	while(fill_flag){} /* wait VRAM-Fill Interrupt */
	set_cursor(0,0); /* VRAM指定アドレス初期化 */
}

/************************************************************************/
/*   英数字表示関数                                                     */
/************************************************************************/
void disp_str(unsigned char *str_code)
{
	int i,j;
	j = strlen(str_code); /* 表示文字の数 */
	for(i=0;i<j;i++) {
		switch(*str_code) {
			case 0x0d: /* 改行 VRAM指定アドレスを0列へ移動*/
				cursor_x=0; set_cursor(cursor_x,cursor_y); break;
			case 0x0a: /* 改行 VRAM指定アドレスを1行下へ移動*/
				cursor_y++; set_cursor(cursor_x,cursor_y); break;
			default:/*VRAMへ文字コード設定*/
				IO_OSDC.IO_OSD_CD2.hword=(unsigned short)*str_code; break;
		}
		str_code=str_code+1;/*ポインタアドレスをインクリメント*/
	}
}

/************************************************************************/
/*   OSD割込み関数                                                      */
/************************************************************************/
__interrupt void osdc_int(void)
{
	IO_EIRR.bit.ER6 = 0; /* OSD割込みフラグクリア */
	if(IO_OSDC.IO_OSD_JRC.bit.FIF) {
		IO_OSDC.IO_OSD_JRC.bit.FIF = 0; /* VRAM-Fill割込みフラグクリア */
		fill_flag = 0; /* fillフラグクリア */
	}
	else if(IO_OSDC.IO_OSD_JRC.bit.VIF) {
		IO_OSDC.IO_OSD_JRC.bit.VIF = 0;/* VSYNC割込みフラグクリア */
		if(v_count>0){v_count--;} /* VSYNCカウンタデクリメント */
	}
}

/************************************************************************/
/*   VSYNCウエイト関数                                                  */
/************************************************************************/
void v_wait(unsigned int vcnt)
{
	v_count=vcnt;
	while(v_count!=0){};/* 指定したVSYNC数をウエイト */
}

