
/////////////////////////////////////////////////////////////////////////////
//
//             /
//      -  P  /  E  C  E  -
//           /                 mobile equipment
//
//              System Programs
//
//
// PIECE LIBRARY : pceapi : Ver 1.00
//
// Copyright (C)2001 AUQAPLUS Co., Ltd. / OeRSTED, Inc. all rights reserved.
//
// Coded by MIO.H (OeRSTED)
//
// Comments:
//
//	○アプリケーション・ヘッダー
//	○スタート・アップ
//
//  v1.00 2001.11.09 MIO.H
//  v1.06 2001.11.23 MIO.H スタックサイズ指定に対応
//  v1.09 2001.11.30 MIO.H バージョン・チェック
//
//	* Tue Jan 08 12:18:40 JST 2008 Naoyuki Sawa
//	- \usr\PIECE\lib\cstart.oの代わりに使う、カスタムスタートアップルーチンです。
//	  カスタムスタートアップルーチンを使うために、リンカオプション-nodefsupが必要です。
//	  (2008/01/08対応済みです。clip.mkの中で、LDFLAGSにて指定するようにしました。)
//	- カスタムスタートアップルーチンが必要となった理由は、以下のとおりです。
//	  これまでは、ベクタ領域のFRAMコードには除算だけを転送していたのですが、
//	  今後、memset()とmemcpy()もベクタ領域のFRAMコードに転送することにしました。
//	  アプリケーションのコードとして最初に呼ばれるpceAppInit00()がmemset()を呼び出しているので、
//	  これまでのように、pceAppInit()で転送したのでは、間に合わなくなりました。
//	  pceAppInit00()がmemset()を呼び出す前に、ベクタ領域のFRAMコードを転送する必要が生じました。
//	  そのため、カスタムスタートアップルーチンを使用し、pceAppInit00()の先頭で転送することにしました。
//	- ここで、FRAM4領域のFRAMコードも転送することも可能ですが、サイズ超過時のDIE()ができないこと、
//	  FRAM4領域のFRAMコードは緊急性が少ないことから、これまでどおりapp_init()で転送することにします。
//
//	* Tue Dec 23 15:42:08 JST 2014 Naoyuki Sawa
//	- 高速RAMにコードを転送する処理を、clippce.cのapp_init()⇒cstart.cのpceAppInit00()へ移動しました。
//	  app_init()で行っても問題無いですが、より早くpceAppInit00()で行う方がより確実だと思ったからです。
//
//	* Wed Dec 31 17:37:43 JST 2014 Naoyuki Sawa
//	- cstart.cのpceAppInit00()でpceLCDDispStart()を呼び出し、液晶画面の表示を開始するようにしました。
//	- アプリケーション開始直後に液晶画面の表示を開始し、アプリケーション終了するまで液晶画面を表示したままにします。
//	  今後は、アプリケーションプログラムは、液晶画面の表示状態を考慮する必要は有りません。
//	- 常に液晶画面を表示するために、アプリケーションプログラムは、原則としてpceLCDDispStop()を使用しないでください。
//	  もしpceLCDDispStop()を使用した場合は、出来るだけ早くpceLCDDispStart()を呼んで液晶画面の表示を再開してください。
//

#if 0 //{{N.SAWA
//#include <piece.h>
//#include <string.h>
#else //↓N.SAWA
#include "clip.h"
#endif//}}N.SAWA

extern unsigned char __START_DEFAULT_BSS[];
extern unsigned char __END_DEFAULT_BSS[];
extern unsigned char __SIZEOF_DEFAULT_BSS[];

#if 1 //{{N.SAWA
/* 高速RAMの空きエリアアドレスを表すシンボル（リンカが自動生成）  */								//┐
extern unsigned long __START_FRAM_ADDR[];	/* 転送先アドレス */								//│
extern unsigned long __SIZEOF_FRAM_ADDR[];	/* 転送先サイズ[byte]（転送元シンボルでは全体サイズの取得不可！) */		//├2014/12/23追加:clippce.cからコピーして来ました。
extern unsigned long __START_framtop_code[];	/* 転送元アドレス */								//│
//extern unsigned long __END_DEFAULT_BSS[];	/* システムスタック先頭アドレス（==BSS領域終端アドレス） */			//┘
#endif//}}N.SAWA

extern unsigned char _stacklen[];

extern void pceAppInit( void );
extern void pceAppProc( int cnt );
extern void pceAppExit( void );
extern int pceAppNotify( int type, int param );

extern int __version_check( int opef );

#if 1 //{{N.SAWA
//{{2015/01/03変更:clipidiv.s⇒ksvec128.s,ksvec200.sの変更に伴い、転送処理を変更しました。
//extern void idiv_init(); /* clipidiv.s */
//↓2015/01/03変更:clipidiv.s⇒ksvec128.s,ksvec200.sの変更に伴い、転送処理を変更しました。
extern unsigned long __START_KSVEC128_ADDR[],__SIZEOF_KSVEC128_ADDR[],__START_ksvec128_code[];
extern unsigned long __START_KSVEC200_ADDR[],__SIZEOF_KSVEC200_ADDR[],__START_ksvec200_code[];
//}}2015/01/03変更:clipidiv.s⇒ksvec128.s,ksvec200.sの変更に伴い、転送処理を変更しました。
#endif//}}N.SAWA

static void pceAppInit00( void );
static void pceAppProc00( int cnt );
static void pceAppExit00( void );
static int pceAppNotify00( int type, int param );

static const pceAPPHEAD pceAppHead = {
	APPSIG,
	APPSYSVER,
	0,
	pceAppInit00,
	pceAppProc00,
	pceAppExit00,
	pceAppNotify00,
	(unsigned long)_stacklen,
	__END_DEFAULT_BSS,
};

static void pceAppInit00( void )
{
#if 1 //{{N.SAWA
	// 液晶画面の表示を開始します。
	pceLCDDispStart();
#endif//}}N.SAWA
#if 1 //{{N.SAWA
    //{{2015/01/03変更:clipidiv.s⇒ksvec128.s,ksvec200.sの変更に伴い、転送処理を変更しました。
    //	// ベクタ領域のFRAMコードを転送します。
    //	idiv_init();
    //↓2015/01/03変更:clipidiv.s⇒ksvec128.s,ksvec200.sの変更に伴い、転送処理を変更しました。
	// カーネルサービステーブルの空き領域に転送するルーチンを転送します。
	#define memcpy(x,y,z) ((void* (*)(void*,const void*,size_t))__START_ksvec200_code)((x),(y),(z))		//memcpy()はksvec200.sの先頭に有り、転送前なので、転送前のアドレスで実行します。
    //	if((int)__SIZEOF_KSVEC128_ADDR > 256) DIE();	/* 転送サイズがカーネルサービステーブルの空き領域(128〜191)を超えないこと */	//ここではまだDIE()が動作できないので検査を省略することにしました。シンボルファイルの__SIZEOF_KSVEC128_ADDRを目視で確認してください。
    //	if((int)__SIZEOF_KSVEC200_ADDR > 192) DIE();	/* 転送サイズがカーネルサービステーブルの空き領域(200〜247)を超えないこと */	//ここではまだDIE()が動作できないので検査を省略することにしました。シンボルファイルの__SIZEOF_KSVEC200_ADDRを目視で確認してください。
	memcpy(__START_KSVEC128_ADDR, __START_ksvec128_code, (int)__SIZEOF_KSVEC128_ADDR);
	memcpy(__START_KSVEC200_ADDR, __START_ksvec200_code, (int)__SIZEOF_KSVEC200_ADDR);
	#undef  memcpy												//memcpy()はこれ以降、転送後のアドレス(シンボルどおりのアドレス)で実行できます。
	// カーネルサービステーブルの空き領域(200〜247)に転送するルーチンを転送します。
    //}}2015/01/03変更:clipidiv.s⇒ksvec128.s,ksvec200.sの変更に伴い、転送処理を変更しました。
	//↑↓この順序は必須です。memcpy()はベクタ領域のFRAMコードに含まれているからです。
	// 高速RAMにコードを転送します。											//┐
    //	if((int)__START_FRAM_ADDR != 0x1000) DIE();	/* 転送先アドレスが高速RAMの空きエリア先頭(0x1000)に一致すること */	//├2014/12/23追加:clippce.cからコピーして来ました。
    //	if((int)__SIZEOF_FRAM_ADDR > 0x1000) DIE();	/* 転送サイズが高速RAMの空きエリア(0x1000〜0x2000)を超えないこと */	//│ここではまだDIE()が動作できないので検査を省略することにしました。予めリンクマップファイルを確認して高速RAMに配置するコードの合計サイズが4KB以下であることを確認してください。
	memcpy(__START_FRAM_ADDR, __START_framtop_code, (int)__SIZEOF_FRAM_ADDR);						//┘
#endif//}}N.SAWA
	// bss領域をゼロクリアします
#if 0 //{{N.SAWA
//	memset( __START_DEFAULT_BSS, 0, __SIZEOF_DEFAULT_BSS );
#else //↓N.SAWA
	memset( __START_DEFAULT_BSS, 0, (int)__SIZEOF_DEFAULT_BSS );
#endif//}}N.SAWA
	if ( __version_check(0) ) return;
	pceAppInit();
}

static void pceAppProc00( int cnt )
{
	if ( __version_check(cnt) ) return;
	pceAppProc( cnt );
}

static void pceAppExit00( void )
{
	if ( __version_check(0) ) return;
	pceAppExit();
}

static int pceAppNotify00( int type, int param )
{
	if ( __version_check(0) ) return APPNR_IGNORE;
	return pceAppNotify( type, param );
}


