/************************************
 *        PAD access library        *
 *     Program made by  K,Ajima     *
 *   Copyright ajiyan soft l.t.d.   *
 ************************************/



/*** pad *****************************************************************

  ＦＭ−Ｔｏｗｎｓ  のＰＡＤをアクセスする関数を提供するライブラリです、
ハードウェアを直接扱うため  ＦＭ−Ｔｏｗｎｓ  専用です。
  ｐａｄ．ｈを必要なソースにインクルードし、ｘｐａｄ．ｌｉｂとリンクしま
す。


ｐａｄ＿ｘｘｘｘｘ（）			：  メイン関数
ｅｐａｄ＿ｘｘｘｘｘ（）		：  高レベル関数

****************************************************************************/



#include <conio.h>
#include <time.h>
#include <dos.h>



/********************************************************************
 *
 *		pad_xxxxx() 関数群
 *
 *
 *
 *
 */



													/* PAD ポート番号 */
#define PAD_PORT_1	0x04d0U								/* 左ポート */
#define PAD_PORT_2	0x04d2U								/* 右ポート */



													/* PAD 入出力レジスタ */
#define COM1	16
#define COM2	32
#define ABOTAN1	1
#define BBOTAN1	2
#define ABOTAN2	4
#define BBOTAN2	8



/********************************************************************
 *	PAD のトリガレジスタ取得
 *		1. PAD のポート番号
 *		ret: レジスタの内容
 ********************************************************************/
int _fastcall pad_get_stat(unsigned int pad_port)
{
	return(inp(pad_port));
}



/********************************************************************
 *	PAD の入出力レジスタ設定
 *		1. レジスタの内容
 ********************************************************************/
void _fastcall pad_set_stat(int pad_stat)
{
	outp(0x04d6U,pad_stat);
}



/********************************************************************
 *
 *		epad_xxxxx() 関数群
 *
 *
 *
 */



													/* PAD トリガ番号 */
#define PAD_A		0
#define PAD_B		1
#define PAD_LEFT	2
#define PAD_RIGHT	3
#define PAD_UP		4
#define PAD_DOWN	5
#define PAD_RUN		6
#define PAD_SELECT	7
#define PAD_COM		8



													/* PAD トリガの状態 */
#define PAD_BRK	0
#define PAD_MKE	1



typedef struct _pad_rep_status PAD_REP_STAT;		/* PAD 連射制御情報 */

struct _pad_rep_status {
	char rep[8];
};



													/* リピート機能 */
#define PAD_REP_OFF	0									/* リピート無し */
#define PAD_REP_ON	-1									/* リピート有り */



/********************************************************************
 *	PAD のトリガの状態の取得
 *		1. PAD のトリガレジスタの内容
 *		2. 確認したいトリガ
 *		ret: PAD_BRK 押されていない
 *			 PAD_MKE 押されている
 ********************************************************************/
int _fastcall epad_check_trig(int pad_stat,int pad_trig)
{
	static int mask[9]={16,32,12,12, 3, 3,12, 3,64}; /* マスク   */
	static int pat[9] ={ 0, 0, 8, 4, 2, 1, 0, 0,64}; /* パターン */

	return((mask[pad_trig]&pad_stat)==pat[pad_trig]);
}



/********************************************************************
 *	現在の PAD のトリガの状態の取得
 *		1. PAD のポート番号
 *		2. 確認したいトリガ
 *		ret; PAD_BRK 押されていない
 *			 PAD_MKE 押されている
 ********************************************************************/
int _fastcall epad_check_intrig(unsigned int pad_port,int pad_trig)
{
	return(epad_check_trig(pad_get_stat(pad_port),pad_trig));
}



/********************************************************************
 *	PAD 連射制御情報作成（本関数を使わずに直接代入しても構わない）
 *		1. 連射制御情報を格納するポインタ
 *		2. A
 *		3. B
 *		4. LEFT
 *		5. RIGHT
 *		6. UP
 *		7. DOWN
 *		8. RUN
 *		9. SELECT
 *		10. COM
 ********************************************************************/
void _fastcall epad_make_rep_stat(
			PAD_REP_STAT *pad_rep_stat,
			char pad_a,
			char pad_b,
			char pad_left,
			char pad_right,
			char pad_up,
			char pad_down,
			char pad_run,
			char pad_select,
			char pad_com)
{
	pad_rep_stat->rep[0]=pad_a;
	pad_rep_stat->rep[1]=pad_b;
	pad_rep_stat->rep[2]=pad_left;
	pad_rep_stat->rep[3]=pad_right;
	pad_rep_stat->rep[4]=pad_up;
	pad_rep_stat->rep[5]=pad_down;
	pad_rep_stat->rep[6]=pad_run;
	pad_rep_stat->rep[7]=pad_select;
	pad_rep_stat->rep[8]=pad_com;
}




/********************************************************************
 *	連射制御機能付き PAD のトリガの状態取得
 *		1. PAD のトリガレジスタの内容
 *		2. 確認したいトリガ
 *		3. 連射制御情報が格納されているポインタ
 *		ret; PAD_BRK 押されていない
 *			 PAD_MKE 押されている
 ********************************************************************/
int _fastcall epad_rep_check_pad(
			int pad_stat,
			unsigned int pad_trig,
			PAD_REP_STAT *pad_rep_stat)
{
	int ret;

	ret=epad_check_trig(pad_stat,pad_trig);			/* 状態取得 */

	switch(pad_rep_stat->rep[pad_trig]) {
		case PAD_REP_ON:								/* リピート有り */
			return(ret);

		case PAD_BRK:									/* さっきは押されていなかった */
			pad_rep_stat->rep[pad_trig]=(char)ret;
			return(ret);

		case PAD_MKE:									/* さっきは押されていた */
			pad_rep_stat->rep[pad_trig]=(char)ret;
			return(PAD_BRK);
	}
}



/********************************************************************
 *	連射制御機能付き 現在の PAD のトリガの状態取得
 *		1. PAD のポート番号
 *		2. 確認したいトリガ
 *		3. 連射制御情報が格納されているポインタ
 *		ret; PAD_BRK 押されていない
 *			 PAD_MKE 押されている
 ********************************************************************/
int _fastcall epad_rep_check_inpad(
			int pad_port,
			unsigned int pad_trig,
			PAD_REP_STAT *pad_rep_stat)
{
	return(epad_rep_check_pad(pad_get_stat(pad_port),pad_trig,pad_rep_stat));
}



