/*----------------------------------------------------------------------------
		sbinit2.c Ver.2.06  2000/08/30
		Copyright (C) 1997-2000 SEGA Enterprises Co.,Ltd
		All Rights Reserved
----------------------------------------------------------------------------*/
/* ここの記述は、ライブラリ使用者のシステムに合わせて                 */
/* 変更することができます。                                           */
/* 変更の際は関連ドキュメントを参照し、各項目を適切に修正してください */

/* You can change a description of this place according to a system   */
/* of library user.                                                   */
/* When change it, please refer to a document concerned and revise    */
/* each item adequately.                                              */


#include <shinobi.h>     	 /* 忍ヘッダファイル                      */
                         	 /* Shinobi library header file           */


extern Uint8* _BSS_END;   /* BSG/BSG32セクションの終了アドレス        */
                          /* End address of BSG/BSG32 section         */

#define WORK_START (0x8C000000)		/* ワークRAMの先頭アドレス        */
#define WORK_END   (0x8D000000)		/* ワークRAMの終了アドレス        */

/* ワークとして領域を固定確保するサイズ                               */
/* _BSS_END から WORK_END-WORK_FIXED_SIZE までがヒープ領域になります  */
/* WORK_END-WORK_FIXED_SIZE から WORK_END までが固定領域になります    */
#define WORK_FIXED_SIZE (0x00000000)

/* syMalloc()の管理下に置くヒープの先頭アドレスとヒープのサイズ       */
/* The top address of the heap area and heap size                     */
#define HEAP_AREA ((((Uint32)_BSS_END | 0x80000000) + 0x1F) & 0xFFFFFFE0)
#define HEAP_SIZE (WORK_END - WORK_FIXED_SIZE - HEAP_AREA)



/* GD:同時に開くことのできる最大ファイル数                            */
/* GD:Maximum file number opening at the same time.                   */
#define FILES (8)

/* GD:カレントディレクトリバッファ                                    */
/* GD:Current directory buffer                                        */
#define BUFFERS (1024)

/* FIBER:同時に使用する最大ファイバ数(メイン+ミドルウエア+ユーザー)   */
/* FIBER:Max fibers(Main+MiddleWare+User)                             */
#define FIBERS (1+4+11)

/* INTERRUPT:割り込み用スタックサイズ(byte)                           */
/* INTERRUPT:Stack size for the interrupt handler                     */
#define INTSTACK_SIZE (20 * 1024)



/* グローバルワークの宣言                                             */
/* Global work area                                                   */

#define SYD_ALIGN32(x) ((void*)(((Uint32)(x) + 0x1F) & 0xFFFFFFE0))

Uint8 gMapleRecvBuf[1024 * 24 * 2 + 32];
Uint8 gMapleSendBuf[1024 * 24 * 2 + 32];

Uint8 gdfswork[GDFS_WORK_SIZE(FILES) + 32];
Uint8 gdfscurdir[GDFS_DIRREC_SIZE(BUFFERS) + 32];

Uint32 gIntStackBuf[INTSTACK_SIZE / sizeof(Uint32)];
SYS_FBR_INFO gFiberInfo[FIBERS];


/* グローバルコンストラクタの呼び出し方法が使用するコンパイラに       */
/* よって違うため、各コンパイラに合わせてマクロを定義してください     */
/* Global constructor/destructor (C++ using) setting                  */
/*  Please define your compile system                                 */
/*    Nothing   : Hitachi SHC V5.x                                    */
/*  __HITACHI__ : Hitachi SHC V6.x~                                   */
/*  __MWERKS__  : Metrowerks CodeWarrior                              */
/*  __GNUC__    : GNU                                                 */

/* グローバルコンストラクタ／デストラクタ呼び出し関数の宣言           */
/* Prototype of global constructor/destructor functions */
void syStartGlobalConstructorAlt( void );
void syStartGlobalDestructorAlt( void );

/*----------------------------------------------------------------------------
		アプリケーションの初期化関数
		Initialization function of the application.
----------------------------------------------------------------------------*/
void sbInitSystem(void)
{
	/* 標準的な初期化処理を行います。                             */
	/* この設定で、多くのアプリケーションが最大のパフォーマンスを */
	/* 得ることができます。                                       */
	/* 特に理由のない限り、ここの記述を修正しないでください。     */
	/* 修正する場合は、各ライブラリの仕様を十分理解した上、       */
	/* ライブラリ使用者の責任において修正してください。           */
	
	/* Do standard initialization.                                */
	/* By this setting, many applications can get the greatest    */
	/* performance.                                               */
	/* Without the special reason, please do not change a         */
	/* desctiption of this place.                                 */
	/* When change it, please understand specification of each    */
	/* library enough, and revise it in responsibility of library */
	/* user.                                                      */
	
	/* 割り込み禁止       */
	/* Disable interrupt. */
	set_imask(15);
	
	/* ボーダーカラーの設定 */
	/* Set border color.    */
	syVideoWaitVBlankSetBorderColor(0x00000000);
	
	/* ハードウェアの初期化 */
	/* Initialize hardware.  */
	syHwInit( &gIntStackBuf[INTSTACK_SIZE/sizeof(Uint32)] );
	
	/* メモリ管理の初期化            */
	/* Initialize memory management. */
	syMallocInit( (void*)HEAP_AREA, HEAP_SIZE );
	
	/* グローバルコンストラクタの呼び出し */
	/* Call global constructor            */
	syStartGlobalConstructorAlt();
	
	/* ファイバーライブラリの初期化  */
	/* Initialize fiber library.     */
	syFbrInitEx( gFiberInfo, FIBERS,
						&gIntStackBuf[INTSTACK_SIZE/sizeof(Uint32)], NULL );
	
	/* コントローラライブラリの初期化 */
	/* Initialize controller library. */
	pdInitPeripheral( PDD_PLOGIC_ACTIVE,
					SYD_ALIGN32(gMapleRecvBuf), SYD_ALIGN32(gMapleSendBuf) );
	
	/* コールバックライブラリの初期化 */
	/* Initialize callback library.   */
	syCallbackInit();
	
	/* 割り込み許可      */
	/* Enable interrupt. */
	set_imask(0);
	
	/* GDファイルシステムの初期化                               */
	/* Initialize GD filesystem.                                */
	gdFsInit2(	FILES  , SYD_ALIGN32(gdfswork),
				BUFFERS, SYD_ALIGN32(gdfscurdir) );
	
	/* ミドルウェア等で使用するファイルシステムの初期化         */
	/* Initialize filesystem for middleware                     */
	syFsInit();
}


/*----------------------------------------------------------------------------
		アプリケーションの終了関数
		Finalize application.
----------------------------------------------------------------------------*/
void sbExitSystem(void)
{
	/* ミドルウェア等で使用するファイルシステムの終了処理       */
	/* Finalize fiber manager for middleware                    */
	syFsFinish();
	
	/* GDファイルシステムの終了処理 */
	/* Finalize GD filesystem.      */
	gdFsFinish();
	
	/* コールバックライブラリの終了処理 */
	/* Finalize callback library.       */
	syCallbackFinish();
	
	/* コントローラライブラリの終了処理 */
	/* Finalize controller library.     */
	pdExitPeripheral();
	
	/* ファイバーライブラリの終了処理   */
	/* Finalize fiber library.          */
	syFbrExit();
	
	/* グローバルデストラクタの呼び出し */
	/* Call global destructor           */
	syStartGlobalDestructorAlt();
	
	/* メモリ管理の終了処理        */
	/* Finalize memory management. */
	syMallocFinish();
	
	/* ハードウェアの終了処理 */
	/* Finalize hardware.     */
	syHwFinish();
	
	/* 割り込み禁止       */
	/* Disable interrupt. */
	set_imask(15);
}


/*----------------------------------------------------------------------------
 C++ global constructor support for All environment
----------------------------------------------------------------------------*/
#ifdef __HITACHI__
#include <_h_c_lib.h>
#endif
void syStartGlobalConstructorAlt ( void )
{
#ifdef __HITACHI__
	syStartGlobalConstructorSegaLib();
	_CALL_INIT();
#else
	#if defined(__MWERKS__) || defined(__GNUC__)
		void (*pf)();
		Uint32 *adr;
		
		for( adr = (Uint32 *) (&_START_DSG_INIT_);
			 adr < (Uint32 *) (&_END_DSG_INIT_);
			 adr++ ){
			if( !( ( *adr == 0x00000000) || ( *adr == 0xFFFFFFFF) )){
				pf = (void(*)())( *adr );
				(*pf)();
			}
		}
		#ifdef __MWERKS__
			__call_static_initializers(); /* For CodeWarrior */
		#endif /* __MWERKS__ */
		#ifdef __GNUC__
			__do_global_ctors(); /* For GCC */
		#endif /* __GNUC__ */
	#else
		syStartGlobalConstructor(); /* For SHC V5.1 (Default) */
	#endif /* __MWERKS__ or __GNUC__ */
#endif /* __HITACHI__ */
}
/*----------------------------------------------------------------------------
 C++ global destructor support for All environment 
----------------------------------------------------------------------------*/
void syStartGlobalDestructorAlt ( void )
{
#ifdef __HITACHI__
	syStartGlobalDestructorSegaLib();
	_CALL_END();
#else
	#if defined(__MWERKS__) || defined(__GNUC__)
		void (*pf)();
	    Uint32 *adr;
		
		for( adr = (Uint32 *) (&_START_DSG_END_) ;
			 adr < (Uint32 *) (&_END_DSG_END_) ;
			 adr++ ){
			if( !( ( *adr == 0x00000000) || ( *adr == 0xFFFFFFFF) )){
				pf = (void(*)())( *adr );
				(*pf)();
			}
		}
		#ifdef __MWERKS__
			__destroy_global_chain();
		#endif /* __MWERKS__ */
		#ifdef __GNUC__
			__do_global_dtors();
		#endif /* __GNUC__ */
	#else
		syStartGlobalDestructor(); /* For SHC V5.1 (Default) */
	#endif /* __MWERKS__ or __GNUC__ */
#endif /* __HITACHI__ */
}


#ifdef __HITACHI__
#ifdef __cplusplus
extern "C" 
#endif
void abort( void ){
	for(;;);
}
#endif


/*--------------------------------------------------------------------------*/
