/*	
 *	clipgbs.h
 *
 *	P/ECE GBS Driver
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2004 Naoyuki Sawa
 *
 *	* Thu Jan 15 20:09:00 JST 2004 Naoyuki Sawa
 *	- 作成開始。
 */
#ifndef __CLIP_GBS_H__
#define __CLIP_GBS_H__

/****************************************************************************
 *	GBSファイル仕様
 ****************************************************************************/

/* * GBSHEADER構造体はリトルエンディアンで、フィールドアライメントされています。
 *   従って、特に気をつかうことなく、そのままフィールド値を読み込んで大丈夫です。
 */

/* GBSファイルヘッダ */
typedef struct _GBSHEADER {
	         char  signature[3];		/* +0x00, 3: Identifier string ("GBS") */
	unsigned char  version;			/* +0x03, 1: Version (1) */
	unsigned char  num_songs;		/* +0x04, 1: Number of songs (1-255) */
	unsigned char  first_song;		/* +0x05, 1: First song (usually 1) */
	unsigned short load_addr;		/* +0x06, 2: Load address ($400-$7fff) */
	unsigned short init_addr;		/* +0x08, 2: Init address ($400-$7fff) */
	unsigned short play_addr;		/* +0x0a, 2: Play address ($400-$7fff) */
	unsigned short stack_ptr;		/* +0x0c, 2: Stack pointer */
	unsigned char  timer_mod;		/* +0x0e, 1: Timer modulo */
	unsigned char  timer_ctl;		/* +0x0f, 1: Timer control */
	         char  title[32];		/* +0x10,32: Title string */
	         char  author[32];		/* +0x30,32: Author string */
	         char  copyright[32];		/* +0x50,32: Copyright string */
} GBSHEADER;					/* =0x70,??: Code and Data */

/****************************************************************************
 *	GBSドライバ
 ****************************************************************************/

#define GBSBUFLEN	320	/* = 16000/50 … 1[tick](=1/50[sec])当たりのサンプル数 */

#define GBS_CLOCK	4194304	/* DMG-CPU/Sound 入力クロック (=2^22)*/

/*
 *	GBSドライバ
 */
typedef struct _GBSDRIVER {
	/*{{DMGコアのREAD外部関数を使うため、レイアウト固定*/
	DMG dmg;			/* DMG-CPU */
	unsigned char mem[0x10000];	/* メインメモリ */
	/*}}DMGコアのREAD外部関数を使うため、レイアウト固定*/
	DMGSOUND ds;			/* DMG-Sound */
	//
	GBSHEADER* header;		/* gbs_init()に渡されたGBSHEADERアドレス */
	const unsigned char* bank1;	/* ROM Bank1 先頭アドレス */
	int length;			/* bank1以降の有効データバイト数 */
	int rom1_bank;			/* ROM Area1(0x4000-0x7fff)のバンク選択状態 */
	//
	int interrupt_interval;		/* 割り込み周期[サイクル] */
	int interrupt_progress;		/* 割り込み進行カウンタ */
} GBSDRIVER;

/*
 *	DMGエミュレーション用外部関数
 */
//unsigned char gbs_dmg_read(DMG* dmg, unsigned short addr);
void gbs_dmg_write(DMG* dmg, unsigned short addr, unsigned char data);
//unsigned char gbs_dmg_in(DMG* dmg, unsigned char addr);
void gbs_dmg_out(DMG* dmg, unsigned char addr, unsigned char data);

/*
 *	GBSドライバ内部関数
 */
void gbs_dmg_setup(GBSDRIVER* gbs, int a, int pc);
int gbs_init(GBSDRIVER* gbs, const void* data, int len, int i_song);
void gbs_rom1_bank(GBSDRIVER* gbs, int i_bank);
int gbs_mix(GBSDRIVER* gbs, short wbuff[/*GBSBUFLEN*/]);
int gbs_stream_callback(short* wbuff, int param);

/****************************************************************************
 *	アプリケーション用関数
 ****************************************************************************/

/* GBSファイルの再生を開始します。
 * [in]
 *	data		GBSデータの先頭アドレス。
 *	len		GBSデータのバイト数。
 *	i_song		トラック番号。(0〜)
 *			-1を指定すると、GBSファイル既定の開始曲番号となります。
 * [out]
 *	戻り値		再生開始に成功したら、 0を返します。
 *			再生開始できなければ、-1を返します。
 * [note]
 *	* この関数は内部でstream_play()を呼び出しています。
 *	* stream_play()を呼ぶと、サウンド割り込みベクタがフックされます。
 *	  プログラム終了前に必ずgbs_stop()を呼んで、ベクタを復元してください。
 */
int gbs_play(const void* data, int len, int i_song);

/* GBSファイルの再生を停止します。
 * [note]
 *	* 再生中でなければ、この関数は何もしません。
 */
void gbs_stop();

#endif /*__CLIP_GBS_H__*/
