/*	
 *	clippky.h
 *
 *	P/ECE POKEY(CO12294) Emulator
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2004 Naoyuki Sawa
 *
 *	* Mon Jan 26 20:20:00 JST 2004 Naoyuki Sawa
 *	- 作成開始。
 *	* Wed Nov 18 21:37:53 JST 2015 Naoyuki Sawa
 *	- 'extern "C" {'〜'}'で囲みました。.cppを含むWin32プロジェクトからもインクルード出来るようにするためです。
 */
#ifndef __CLIP_PKY_H__
#define __CLIP_PKY_H__

#ifdef  __cplusplus
extern "C" {
#endif//__cplusplus

/****************************************************************************
 *
 ****************************************************************************/

typedef struct _POKEY POKEY;

/***** Channel *****/
typedef struct _POKEYCHANNEL {
	int period;			/* 出力反転周期サイクル数 */
	int volume;			/* Volume (0〜15) */
	int volume_only;		/* VolumeOnly (0:No/1:Yes) */
	int distotion;			/* Distotion (0〜7) */
	//
	int progress;			/* サイクル進行カウンタ (ダウンカウンタ) */
	int signal;			/* 現在の出力値 (0:Lo/1:Hi) */
	int output;			/* 現在の出力レベル (-15〜15) */
} POKEYCHANNEL;

/***** POKEY Chip *****/
/*typedef*/ struct _POKEY {
	unsigned char reg[16];		/* レジスタ値保存 */
	//
	POKEYCHANNEL channel[4];	/* チャネル1〜4 */
	unsigned lfsr_progress;		/* LinearFeedbackShiftRegister進行カウンタ (アップカウンタ) */
	//
	DDA progress;			/* サイクル進行DDA */
} /*POKEY*/;

short pokey_process(POKEY* pokey, int cycle);
void pokey_channel_process(POKEY* pokey, POKEYCHANNEL* channel, int cycle);
int pokey_lfsr_signal4(POKEY* pokey);
int pokey_lfsr_signal5(POKEY* pokey);
int pokey_lfsr_signal17_9(POKEY* pokey);
void pokey_channel_setup(POKEY* pokey, int i_channel);

/****************************************************************************
 *	LFSR出力テーブル
 ****************************************************************************/

extern const unsigned char pokey_lfsr_table4[0x2/*output=0xf[bits],padding=1[bits]*/];
extern const unsigned char pokey_lfsr_table5[0x4/*output=0x1f[bits],padding=1[bits]*/];
extern const unsigned char pokey_lfsr_table9[0x40/*output=0x1ff[bits],padding=1[bits]*/];
extern const unsigned char pokey_lfsr_table17[0x4000/*output=0x1ffff[bits],padding=1[bits]*/];

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

/* POKEYコアをリセットします。
 * [in]
 *	pokey		POKEY構造体。
 *	clock		入力クロック。
 * [note]
 *	* アプリケーションプログラムは、少なくとも最初に一度、この関数を呼び出してください。
 *	  その後は、POKEYリセットを行う場合に、必要に応じて呼び出してください。
 */
void pokey_reset(POKEY* pokey, int clock);

/* レジスタ値を読み込みます。
 * [in]
 *	pokey		POKEY構造体。
 *	regno		レジスタ番号。
 */
unsigned char pokey_read(POKEY* pokey, int regno);

/* レジスタ値を書き込みます。
 * [in]
 *	pokey		POKEY構造体。
 *	regno		レジスタ番号。
 *	data		レジスタ値。
 */
void pokey_write(POKEY* pokey, int regno, unsigned char data);

/* 出力サンプリングレート=SPEAKER_OUTPUT[Hz]で、指定されたサンプル数のミキシングを行います。
 * [in]
 *	pokey		POKEY構造体。
 *	wbuff		出力サンプルバッファ。
 *	count		出力サンプル数。
 */
void pokey_mix(POKEY* pokey, short wbuff[/*count*/], int count);

#ifdef  __cplusplus
}//extern "C"
#endif//__cplusplus

#endif /*__CLIP_PKY_H__*/
