;==============================================================================
;	<< MASM V5.1 >>  for  FM TOWNS
;==============================================================================
	page		60,132
	name		invpad
	title		PAD to KYB(invaders用) Program
;==============================================================================
;	invpad Program
;
;	ｷｰﾏﾄﾘｸｽ取得時､ﾊﾟｯﾄﾞ操作により､次のｷｰをONの状態にして値を返す｡
;	← : 'Z'
;	→ : 'C'
;	A/B : SPACE
;
;	ﾊﾟｯﾄﾞのRUNﾎﾞﾀﾝを押すと、改行ｺｰﾄﾞを入力文字列に追加する。
;
;	CREATE : 1990.05.11
;	FINISH : 1990.05.12  Version 0.50
;
;	< HISTORY >
;	1990.05.11 : CREATE
;	1990.05.15 : Version 0.51
;				 ｼﾞｮｲｽﾃｨｯｸ対応(ﾊﾞｸﾞ修正) COM入力を見ないようにした。
;	1991.08.31 : V0.52 ﾒｯｾｰｼﾞ出力をDOSﾌｧﾝｸｼｮﾝ使用に変更.
;
;	All Rights Reserved, Copyright (C) Y.Hirata 1990-1991.
;
;	Programmed by Y.Hirata ( NIFTY-ID : NAB03321 )
;==============================================================================
;
code		segment
			assume	cs:code,ds:code,es:code,ss:code
;
;--------------------------------------------
			org 000h
SEGTOP		label	WORD
;--------------------------------------------
;
;--------------------------------------------
			org 02ch
ENVADRS		label	WORD
;--------------------------------------------
;
;--------------------------------------------
			org	080h
ARGUMENT	label	WORD
;--------------------------------------------
;
;--------------------------------------------
			org	100h
entry:		jmp	main
;--------------------------------------------
;
COPYRIGHT	db			0Dh
			db			01Bh,'[2K',0Dh,0Ah,07h
			db			0Dh,0Ah,09h
			db			'INVADERS-PAD  V0.52   1991-08-31',0Dh,0Ah
			db			0Dh,0Ah,09h
			db			'Copyright (C) Y.Hirata 1990-1991.'
			db			0Dh,0Ah,0Dh,0Ah,1Ah
;
TITLE_name	db			'INVADERS-PAD'
TITLE_len	EQU			$-TITLE_name
;
TRUE		EQU			1
FALSE		EQU			0
;
KEY_REP_ST	EQU			20000				; x 10us : 200ms ｷｰﾘﾋﾟｰﾄ開始
;
;********************************************
;			キーアドレス
;********************************************
;
Z_KEY		EQU			2Ah
Z_ADR		EQU			5
Z_POS		EQU			04h
;
C_KEY		EQU			2Ch
C_ADR		EQU			5
C_POS		EQU			10h
;
SPACE_KEY	EQU			35h
SPACE_ADR	EQU			6
SPACE_POS	EQU			20h
;
RET_KEY		EQU			1Dh
RET_ADR		EQU			3
RET_POS		EQU			20h
;
;********************************************
;			パッド
;********************************************
;
PAD_OUT_REG	EQU			04D6h				; ﾊﾟｯﾄﾞ制御
PAD_STATUS	EQU			0Fh					; COM出力なし
;
PAD_REG_IN1	EQU			04D0h				; ﾊﾟｯﾄﾞ1
PAD_REG_IN2	EQU			04D2h				; ﾊﾟｯﾄﾞ2
;
PAD_RIGHT	EQU			04h					;
PAD_LEFT	EQU			08h					;
PAD_RUN_BOT	EQU			03h					;
PAD_A_BOT	EQU			20h					; ｼﾞｮｲｽﾃｨｯｸ対応用に
PAD_B_BOT	EQU			10h					; COMは無視する。
;
;********************************************
;			データ領域
;********************************************
;
vct_90h		dd		far						; ｷｰﾎﾞｰﾄﾞBIOS
;
int90flg	db		FALSE					; 多重割り込み防止用
keyinflg	db		FALSE					;
;
key_tbl		db		16 dup(?)				; ｷｰﾏﾄﾘｸｽ用
key_add_str	dw		0Dh						; 入力文字列追加用(改行)
;
;
;********************************************
;			MACRO
;********************************************
;
INT90H		macro							; ｷｰﾎﾞｰﾄﾞBIOS
			pushf							;
			call	cs:[vct_90h]			;
			endm							;
;
KYB_bufcls	macro							; ｷｰﾎﾞｰﾄﾞ･ﾊﾞｯﾌｧｸﾘｱ
			mov		ah,06h					;
			INT90H							;
			endm							;
;
KYB_matrix	macro							; ｷｰﾎﾞｰﾄﾞ･ﾏﾄﾘｸｽ取得
			push	di						;
			mov		di,offset key_tbl		;
			mov		ah,0Ah					;
			INT90H							;
			pop		di						;
			endm							;
;
KYB_addstr	macro							; 入力文字列の追加
			push	di						;
			push	cx						;
			mov		cx,1					;
			mov		di,offset key_add_str	;
			mov		ax,0B01h				;
			INT90H							;
			pop		cx						;
			pop		di						;
			endm							;
;
SOFTIME		macro	timecnt					; ｿﾌﾄﾀｲﾏ･10us単位で待つ
			push	cx						;
			mov		cx,timecnt				;
			int		0FDH					;
			pop		cx						;
			endm							;
;
pgend		macro							; ﾌﾟﾛｸﾞﾗﾑ終了(4CH)
			mov		ax,4C00h				;
			int		21h						; Program End !
			endm							;
;
outb		macro	port,val				; ﾎﾟｰﾄ出力(BYTE)
			push	dx						;
			mov		dx,port					;
			mov		al,val					;
			out		dx,al					;
			pop		dx						;
			endm							;
;
inb			macro	port					; ﾎﾟｰﾄ入力(BYTE)
			push	dx						;
			mov		dx,port					;
			in		al,dx					;
			pop		dx						;
			endm							;
;
;
;********************************************
;			常駐処理部
;********************************************
;
;--------------------------------------------
;	ｷｰﾎﾞｰﾄﾞBIOSの横取り処理
;--------------------------------------------
INT90hook	proc	far						;
			cmp		ah,0Ah					; ﾏﾄﾘｸｽ入力
			je		i90_st					;
			mov		cs:keyinflg,TRUE		;
i90_st:
			push	ax						; +18
			push	cx						; +16
			push	dx						; +14
			push	bx						; +12
			push	sp						; +10
			push	bp						; +8
			push	si						; +6
			push	di						; +4
			push	ds						; +2
			push	es						; +0
			mov		bp,sp					;
			mov		ax,cs					;
			mov		es,ax					;
			cli								;
			cld								;
;
			cmp		cs:int90flg,TRUE		; 多重割り込み防止
			jne		i90						;
			jmp		i90end					;
i90:		mov		cs:int90flg,TRUE		;
;
			cmp		cs:keyinflg,TRUE		;
			jne		i90_mx					;
			jmp		i90_inkey				;
i90_mx:
			push	di						;
			push	ds						;
;
			KYB_bufcls						;
			push	ds						;
			push	cs						;
			pop		ds						; ds=cs
			KYB_matrix						; ｷｰﾏﾄﾘｸｽ取得
			pop		es						; es=ds
			mov		cx,16					;
			mov		si,offset key_tbl		;
		rep	movsb							; ds:si -> es:di
;
			pop		ds						;
			pop		di						;
;
			inb		PAD_REG_IN1				;
			push	ax						; PAD STATUS
;
			and		al,0Ch					;
			cmp		al,PAD_LEFT				; LEFT
			jne		pad_r					;
			jmp		left_on					;
pad_r:		cmp		al,PAD_RIGHT			; RIGHT
			je		right_on				;
			jmp		pad_bot					;
right_on:
			mov		dh,BYTE ptr ds:[di+C_ADR]
											;
			or		dh,C_POS				;
			mov		BYTE ptr ds:[di+C_ADR],dh
											;
			jmp		pad_bot					;
left_on:
			mov		dh,BYTE ptr	ds:[di+Z_ADR]
											;
			or		dh,Z_POS				;
			mov		BYTE ptr ds:[di+Z_ADR],dh
											;
pad_bot:
			pop		ax						; PAD STATUS
			and		al,30h					;
;
			cmp		al,PAD_A_BOT			;
			jne		pad_b					;
			jmp		b_on					;
pad_b:		cmp		al,PAD_B_BOT			;
			je		b_on					;
			jmp		i90end					;
b_on:
			mov		dh,BYTE ptr ds:[di+SPACE_ADR]
											;
			or		dh,SPACE_POS			;
			mov		BYTE ptr ds:[di+SPACE_ADR],dh
											;
			jmp		i90end					;
;
i90_inkey:
			push	cs						;
			pop		ds						; ds=cs
;
			outb	PAD_OUT_REG,PAD_STATUS	; COM出力なし
			nop								;
			inb		PAD_REG_IN1				;
			and		al,0Fh					;
			cmp		al,PAD_RUN_BOT			; RUN
			je		run_on					;
			jmp		i90end					;
run_on:
			mov		dh,BYTE ptr ds:[di+RET_ADR]
											;
			or		dh,RET_POS				;
			mov		BYTE ptr ds:[di+RET_ADR],dh
											;
			KYB_addstr						; 入力文字(改行)の追加
			SOFTIME	KEY_REP_ST				;
;
i90end:
			mov		sp,bp					; 割り込み時の状態に戻す。
			pop		es						;
			pop		ds						;
			pop		di						;
			pop		si						;
			pop		bp						;
			pop		bx						;
			pop		bx						;
			pop		dx						;
			pop		cx						;
			pop		ax						;
;
			mov		cs:int90flg,FALSE		;
			cmp		cs:keyinflg,TRUE		;
			je		keyin_on				;
			iret							;
keyin_on:
			mov		cs:keyinflg,FALSE		;
;
i90_ret:	jmp		cs:[vct_90h]			; 本来のﾍﾞｸﾀに処理を移す｡
;			iret							;
INT90hook	endp							;
;
;--------------------------------------------
SEGEND		label	WORD
;--------------------------------------------
;
;-------------------------------------------;
;	文字列表示
;
;	< INPUT >
;	si : 文字列格納位置	
;	cx : 文字数
;-------------------------------------------;
outchar		PROC							;
			mov		ah,02					;
			mov		dl,[si]					;
			int		21h						; 文字表示
			inc		si						;
			loop	outchar					;
			ret								;
outchar		ENDP							;
;
;********************************************
;			起動処理( メイン )
;********************************************
main		proc	near					;
;
			mov		cx,msg0_len				; ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ(文字数)
			lea		si,msg0					;
			call	outchar					;
;
			mov		si,offset ARGUMENT		;
optsw:										; ｵﾌﾟｼｮﾝｽｲｯﾁ は '/','-'で始まる｡
			inc		si						;
			cmp		BYTE ptr cs:[si],' '	;
			jz		optsw					;
			cmp		BYTE ptr cs:[si],'/'	;
			jz		optsw_1					;
			cmp		BYTE ptr cs:[si],'-'	;
			jz		optsw_1					;
			cmp		BYTE ptr cs:[si],0Dh	;
			jnz		optsw					;
			jmp		tsr_init				;
optsw_1:
			cmp		BYTE ptr cs:[si+1],0Dh	;
			jz		tsr_init				;
			or		BYTE ptr cs:[si+1],20h	; 大文字 -> 小文字
			cmp		BYTE ptr cs:[si+1],'r'	;
			jnz		tsr_init				; 常駐処理へ
;
			mov		ax,3590h				;
			int		21h						; ｷｰﾎﾞｰﾄﾞBIOS割込みﾍﾞｸﾀ取得
			mov		cx,TITLE_len			;
			mov		si,offset TITLE_name	;
			mov		di,offset TITLE_name	;
			repz	cmpsb					; 常駐ﾁｪｯｸ
			je		mem_clear				; 常駐解除へ
			jmp		mem_noclr				; 終了
;
;
;	常駐解除処理
;
mem_clear:
			mov		cx,msg2_len				; 開放ﾒｯｾｰｼﾞ
			lea		si,msg2					;
			call	outchar					;
;
			lds		dx,DWORD ptr es:vct_90h	;
			mov		ax,2590h				; ｷｰﾎﾞｰﾄﾞBIOSを元のﾍﾞｸﾀに!
			int		21h						;
;
			push	es						;
			mov		si,offset ENVADRS		; 環境変数領域を開放
			mov		ax,es:[si]				;
			mov		es,ax					;
			mov		ah,49h					;
			int		21h						;
			pop		es						;
;
			mov		ah,49h					; プログラムを開放
			int		21h						;
;
			pgend							;
;
mem_noclr:
			mov		cx,msg4_len				; 非常駐ﾒｯｾｰｼﾞ
			lea		si,msg4					;
			call	outchar					;
			pgend							;
;
;
;	常駐処理
;
tsr_init:
			mov		ax,3590h				; * ｷｰﾎﾞｰﾄﾞBIOS *
			int		21h						;
			mov		WORD ptr cs:vct_90h,bx	;
			mov		WORD ptr cs:vct_90h+2,es
											; 本来のINT90ﾍﾞｸﾀの取得･保存
;
			mov		cx,TITLE_len			;
			mov		si,offset TITLE_name	;
			mov		di,offset TITLE_name	;
			repz	cmpsb					; 常駐ﾁｪｯｸ
			jne		mem_setup				; 常駐処理へ
;
			mov		cx,msg3_len				; 常駐済ﾒｯｾｰｼﾞ
			lea		si,msg3					;
			call	outchar					;
			mov		cx,msghp_len			; ﾍﾙﾌﾟﾒｯｾｰｼﾞ
			lea		si,msghp				;
			call	outchar					;
			pgend							;
;
mem_setup:
			mov		cx,msg1_len				; 常駐ﾒｯｾｰｼﾞ
			lea		si,msg1					;
			call	outchar					;
			mov		cx,msghp_len			; ﾍﾙﾌﾟﾒｯｾｰｼﾞ
			lea		si,msghp				;
			call	outchar					;
;
			mov		dx,offset INT90hook		; 常駐処理ﾌﾟﾛｼｼﾞｬを
			mov		ax,2590h				; ﾍﾞｸﾀｾｯﾄ
			int		21h						; (ｷｰﾎﾞｰﾄﾞ割り込み)
;
			mov		dx,offset SEGEND		;
			add		dx,15					;
			mov		cl,4					;
			shr		dx,cl					; ﾊﾟﾗｸﾞﾗﾌ単位
			mov		ax,3100h				;
			int		21h						; 常駐終了
;
main		endp
;
msg0		db		'INVADERS-PAD  (C)パオパオ 1990-1991.'
			db		0Dh,0Ah
			db		'INVADERS-PAD Version 0.52   '
msg0_len	equ		$-msg0
msg1		db		'★ 常駐します ★',0Dh,0Ah
msg1_len	equ		$-msg1
msg2		db		'☆ 解除しました ☆',0Dh,0Ah
msg2_len	equ		$-msg2
msg3		db		'常駐しています.',0Dh,0Ah,07h
msg3_len	equ		$-msg3
msg4		db		'常駐していません.',0Dh,0Ah,07h
msg4_len	equ		$-msg4
msghp		db		0Dh,0Ah
			db		'使用方法 ★ ｵﾌﾟｼｮﾝｽｲｯﾁ /r で、常駐解除します。'
			db		0Dh,0Ah
msghp_len	equ		$-msghp
;
code		ends
			end		entry

