/*
	oprate.c
	getch -> getop
	参考文献
	ＦＭ　ＴＯＷＮＳテクニカルデータブック　アスキー出版
	1994/03/02
*/

#include <dos.h>

#ifdef TOWNS
#error not towns err.
#endif

/* パッド1入力レジスタ 04d0 */
/* パッド2入力レジスタ 04d2 */
/* -.COM.TRG2.TRG1.RIGHT_B.LEFT_B.BACK.FWD */

/* パッド出力レジスタ 04d6 */
/* 0.0.JOY2COM.JOY1COM.JOY2TRIG2.JOY2TRIG1.JOY1TRIG2.JOY1TRIG1 */

#define ON (1)
#define OFF (0)

#define TRG2 (32)
#define TRG1 (16)
#define RIGHT_B (8)
#define LEFT_B  (4)
#define BACK  (2)
#define FWD   (1)
#define PADINP1 (0x04d0)
#define PADINP2 (0x04d2)
#define PADCTRL (0x04d6)

#define LEFT (29)
#define RIGHT (28)
#define UP (30)
#define DOWN (31)
#define EXEC (18)
#define QUIT (17)
#define ESCKEY (0x1b)

#define NULL (0)

unsigned char padst( void );
unsigned char kbios( void );

unsigned char getop( void ){
	char r;
	while(( (r=padst()) ==NULL)&&( (r=kbios()) ==NULL));
	return r;
}

unsigned char kbios( void ){
	signed int i;
	union REGS in,out;
	/* バッファクリア */
	in.h.ah = 0x06;
	in.h.al = 0;
	int86(0x90,&in,&out);
	/* 時間待ち */
	for(i=1;i>0;i++);
	/* 入力チェック */
	in.h.ah = 0x07;
	int86(0x90,&in,&out);
	if(out.h.ah!=0) return NULL;
	if(out.h.dh==0xff) return NULL;
	return out.h.dl;
}

unsigned char padst( void ){
	static char rs = NULL;
	char ps;
	do{
		ps = (~inp( PADINP1 )) & 0x3f ;
	}while(	ps != NULL && rs == ps );
	switch ( rs = ps ) {
	case TRG2:
		return QUIT ;
	case TRG1:
		return EXEC ;
	case FWD + BACK:		/* sellect ESCキー */
		return ESCKEY ;
	case LEFT_B + RIGHT_B:		/* run 実行キー */
		return EXEC ;
	/* ４方向の処理 */
	case FWD:
		return UP  ;
	case RIGHT_B:
		return RIGHT  ;
	case BACK:
		return DOWN  ;
	case LEFT_B:
		return LEFT  ;
	default:
	/* 斜めは無視 */
		break;
	}
	return NULL;
}
