/*	
 *	clipsap.h
 *
 *	P/ECE SAP Driver
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2004 Naoyuki Sawa
 *
 *	* Mon Jan 26 06:00:00 JST 2004 Naoyuki Sawa
 *	- 作成開始。
 */
#ifndef __CLIP_SAP_H__
#define __CLIP_SAP_H__

typedef struct _SAPDRIVER SAPDRIVER;

/****************************************************************************
 *	SAPファイル形式
 ****************************************************************************/

/*
 *	SAPファイルヘッダ
 *
 *	SAPファイルヘッダは行単位のテキスト形式です。
 *	SAPHEADER構造体とバイナリ一致ではありません。
 */
typedef struct _SAPHEADER {
	char author[32];	/* Name of composer */
	char name[32];		/* Song title */
	char date[32];		/* Copyright year or yrar of creation */
	char type;		/* Player type */
	unsigned short player;	/* Address of player part which will be executed in 1/50 sec intervals */
	unsigned short music;	/* Address with music data (for C type) */
	unsigned short init;	/* Address of player part which will init player (for all types except C) */
	int songs;		/* Number of songs */
	int defsong;		/* First song which will be played when .sap will be loaded */
	int fastplay;		/* Number of lines between each call of playing routine */
	int stereo;		/* Tune uses dual POKEY configuration */
} SAPHEADER;

/****************************************************************************
 *	SAPドライバ
 ****************************************************************************/

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

#define SAP_CLOCK	1773447		/* PAL 版 CPU＆POKEYクロック[Hz] (共通です) */
//#define SAP_CLOCK	1789772		/* NTSC版 CPU＆POKEYクロック[Hz] (共通です) */
/* POKEY Chip 内での64KHzクロック生成は、この基本クロックを28分周。 */
/* 15KHzクロック生成は、基本クロックを28×4=112分周して生成します。 */

/*
 *	SAPドライバ
 */
/*typedef*/ struct _SAPDRIVER {
	/*{{M6502コアのREAD外部関数を使うため、レイアウト固定*/
	M6502 m6502;			/* 6502 Core */
	unsigned char mem[0x10000];	/* Main Memory */
	/*}}M6502コアのREAD外部関数を使うため、レイアウト固定*/
	POKEY pokey;			/* POKEY Chip */
	//
	SAPHEADER header;		/* SAPファイルヘッダ情報 */
	//
	DDA samples_dda;		/* 割り込み間隔の出力サンプル数計算用DDA */
	int samples;			/* 次回割り込み発生までの残り出力サンプル数 */
} /*SAPDRIVER*/;

/*
 *	M6502エミュレーション用外部関数
 *
 *	SAP_IO_READシンボルを定義すると、I/O READに対応します。
 *	大抵のSAPファイルは、I/O READに対応しなくても演奏できるようです。
 *	I/O READに対応すると6502エミュレーションがかなり遅くなるので、
 *	通常はSAP_IO_READシンボルを定義しないで下さい。
 */
//#define SAP_IO_READ
#ifdef SAP_IO_READ /* I/O READ対応時のみ */
unsigned char sap_m6502_read(M6502* m6502, unsigned short addr);
unsigned char sap_m6502_in(M6502* m6502, unsigned short addr);
#endif /*SAP_IO_READ*/
void sap_m6502_write(M6502* m6502, unsigned short addr, unsigned char data);
void sap_m6502_out(M6502* m6502, unsigned short addr, unsigned char data);

/*
 *	SAPドライバ内部関数
 */
void sap_m6502_setup(SAPDRIVER* sap, int a, int x, int y, int pc);
int sap_init(SAPDRIVER* sap, const void* _data, int len, int i_song);
const void* sap_init_header(SAPHEADER* header, const void* _data);
int sap_mix(SAPDRIVER* sap, short* wbuff);
int sap_stream_callback(short* wbuff, int param);

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

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

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

#endif /*__CLIP_SAP_H__*/
