/*
	oprate2.c
	入力でストップしない ( = inkey() )
	getch -> getop
	使用前に padinit() で初期化すること
	ストップしないので kbhit,getch の置き換えにならない
	参考文献
	ＦＭ　ＴＯＷＮＳテクニカルデータブック　アスキー出版
	趣味のパソコン 10倍楽しむ教養講座  平林 雅英  技術評論社
	1994/03/02 1994/11/21
*/

#include <dos.h>
#include <time.h>
#include "oprate2.h"

/* パッド1入力レジスタ 04d0 */
/* パッド2入力レジスタ 04d2 */
/* -.COM.TRG2.TRG1.RIGHT_B.LEFT_B.BACK.FWD */

/* パッド出力レジスタ 04d6 */
/* 0.0.JOY2COM.JOY1COM.JOY2TRIG2.JOY2TRIG1.JOY1TRIG2.JOY1TRIG1 */

#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 NULL (0)


/* 1/10sec wait */

#define TIME time((long *)0) /* 現在時刻取得マクロ */

void wait( long t ){

	/* 初めての呼び出しまたは、t<0 で初期化 */
	static int base = 0;
	long wtime;

	if( t < 0 ) base = 0;
	if( base == 0 ){
		/* 初期化 */
		wtime = TIME;
		while(wtime == TIME);
		wtime++;
		while(wtime == TIME) base++;
	}else{
		/* 時間待ち */
		wtime =  t * base / 100 ;
		while( wtime-- > 0 ) TIME;
	}

}


unsigned char kbios( void ){
	union REGS in,out;
	/* バッファクリア */
	in.h.ah = 0x06;
	in.h.al = 0;
	int86(0x90,&in,&out);
	/* 1/10 sec wait */
	wait( 10 );
	/* 入力チェック */
	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 ){
	char ps;
	ps = (~inp( PADINP1 )) & 0x3f ;
	switch ( 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;
}


unsigned char inkey( void ){
	char r;
	if(( r = kbios() ) != NULL ) return r;
	return ( padst() );
}

void padinit( void ){
	outp( PADCTRL, 0x0f );
}
