;============================================================================
;	<< MASM V5.1 >>  for  FM TOWNS
;============================================================================
.186
	PAGE		60,132
	NAME		TRAPVER
	TITLE		TRAP VERSION
;============================================================================
;	MS-DOSのﾊﾞｰｼﾞｮﾝ番号をﾄﾗｯﾌﾟする.
;
;	All Rights Reserved, Copyright (C) Y.Hirata 1993.
;	Programmed by Y.Hirata ( NIFTY-ID : NAB03321 )
;
;	< NOTE >
;============================================================================
code		SEGMENT
			ASSUME	cs:code,ds:code,es:code,ss:code
;----------------------------------------------------------------------------
			ORG		000h
SEGTOP		LABEL	BYTE
;----------------------------------------------------------------------------
			ORG		02Ch
ENVADRS		LABEL	WORD
;----------------------------------------------------------------------------
			ORG		080h
ARGUMENT	LABEL	BYTE
;----------------------------------------------------------------------------
			ORG		100h
entry:		jmp		main
;----------------------------------------------------------------------------
CR			EQU		0Dh						;
LF			EQU		0Ah						;
BEL			EQU		07h						;
TAB			EQU		09h						;
EOF			EQU		1Ah						;
;
COPYRIGHT	DB		CR
			DB		01Bh,'[2K',CR,LF,BEL
			DB		CR,LF,TAB
			DB		'MS-DOS trap-ver  Version 1.00   1993.03.16'
			DB		CR,LF,TAB
			DB		CR,LF,TAB
			DB		'Copyright (C) Y.Hirata 1993.',CR,LF
			DB		CR,LF,EOF
;
TITLE_name	DB			'TRAP-VER v1.00'	; 常駐ﾁｪｯｸ文字列
TITLE_len	EQU			$-TITLE_name		;
;
;****************************************************************************
;			データ領域
;****************************************************************************
paraoff		LABEL	BYTE					;
v_21		DD		FAR						; ﾍﾞｸﾀｱﾄﾞﾚｽ
ver			DB		3						; ﾊﾞｰｼﾞｮﾝ
lev			DB		10						; ﾚﾍﾞﾙ
parasize	EQU		$-paraoff				; ﾊﾟﾗﾒﾀ領域ｻｲｽﾞ
;
;****************************************************************************
;			MACRO
;****************************************************************************
TSREND		MACRO							; ﾌﾟﾛｸﾞﾗﾑ常駐終了(31H)
			local	close					;
			mov		cx,5					; ﾃﾞﾌｫﾙﾄｵｰﾌﾟﾝﾌｧｲﾙのｸﾛｰｽﾞ
close:										;
			mov		bx,cx					;
			dec		bx						; ( 0 〜 4 )
			mov		ah,3Eh					; ﾌｧｲﾙｸﾛｰｽﾞ
			int		21h						;
			loop	close					;
;
			mov		si,OFFSET ENVADRS		; 環境変数領域を開放
			mov		ax,cs:[si]				;
			mov		es,ax					;
			mov		ah,49h					;
			int		21h						;
;
			mov		dx,OFFSET SEGEND		;
			add		dx,15					;
			shr		dx,4					; ﾊﾟﾗｸﾞﾗﾌ単位
			mov		ax,3100h				;
			int		21h						; 常駐終了
			ENDM							;
;----------------------------------------------------------------------------
PRGEND		MACRO							; ﾌﾟﾛｸﾞﾗﾑ終了(4CH)
			mov		ax,4C00h				;
			int		21h						; Program End !
			ENDM							;
;----------------------------------------------------------------------------
INT21H		MACRO							; DOS call
			pushf							;
			call	cs:[v_21]				;
			ENDM							;
;
;****************************************************************************
;			常駐処理部
;****************************************************************************
;----------------------------------------------------------------------------
;	割り込みﾌｯｸ処理							;
;----------------------------------------------------------------------------
i21h		PROC	FAR						;
			cmp		ah,30h					;
			jnz		short i21h_org			;
			INT21H							; DOS call
			mov		al,cs:ver				;
			mov		ah,cs:lev				;
			sti								; 割り込み許可
			ret		2						; ﾌﾗｸﾞをpopせずに,iretをｼﾐｭﾚｰﾄ
i21h_org:									;
			jmp		cs:[v_21]				; 本来のﾍﾞｸﾀに処理を移す｡
i21h		ENDP							;
;----------------------------------------------------------------------------
SEGEND		LABEL	BYTE					; ↑ここまでを常駐
;----------------------------------------------------------------------------
;
;****************************************************************************
;			非常駐処理部
;****************************************************************************
;----------------------------------------------------------------------------
;	文字列表示(^C無効)
;	< IN  >	: ds:si	文字列格納位置	
;
;	< USE >	: si
;----------------------------------------------------------------------------
puts		PROC	NEAR					;
			push	dx						;
putslp:										;
			mov		dl,[si]					;
			or		dl,dl					; 文字列終端 ?
			jz		short putsend			; YES->終了
			mov		ah,02					;
			int		21h						; 文字表示
			inc		si						;
			jmp		short putslp			;
putsend:									;
			pop		dx						;
			ret								;
puts		ENDP							;
;----------------------------------------------------------------------------
;	ﾍﾞｸﾀ取得(ds=csでcall)
;	< RET >	: es:bx	ﾍﾞｸﾀｱﾄﾞﾚｽ
;----------------------------------------------------------------------------
getvct:										;
			mov		ax,3521h				;
			int		21h						; 割込みﾍﾞｸﾀ取得
			mov		WORD PTR v_21,bx		;
			mov		WORD PTR v_21+2,es		; 本来の割り込みﾍﾞｸﾀの取得･保存
			ret								;
;----------------------------------------------------------------------------
;	常駐文字列ﾁｪｯｸ(ds=csでcall)
;	< IN  >	: es	常駐ｾｸﾞﾒﾝﾄ
;	< RET >	: ｾﾞﾛﾌﾗｸﾞ (等しければ, ｾﾞﾛﾌﾗｸﾞon)
;
;	< USE >	: si, di
;----------------------------------------------------------------------------
tsrcmp:										;
			mov		cx,TITLE_len			;
			mov		si,OFFSET TITLE_name	; ds:si
			mov		di,OFFSET TITLE_name	; es:di
	repz	cmpsb							; 常駐ﾁｪｯｸ
			ret								;
;----------------------------------------------------------------------------
;	常駐ﾁｪｯｸ(ds=csでcall)
;	< RET >	: es:bx	常駐ｱﾄﾞﾚｽ
;
;	< USE >	: ax, si, di
;----------------------------------------------------------------------------
tsr_chk:									;
			mov		BYTE PTR tsrflg,0		; 常駐ﾌﾗｸﾞｸﾘｱ
			mov		BYTE PTR hookflg,0		; ﾍﾞｸﾀﾌｯｸﾌﾗｸﾞｸﾘｱ
mcb_chk:									;
			mov		ah,52h					; 内部変数領域ｱﾄﾞﾚｽ取得
			int		21h						;
			mov		es,es:[bx-2]			; 先頭MCBｾｸﾞﾒﾝﾄｱﾄﾞﾚｽ
mcb_lp:										;
			cmp		BYTE PTR es:[0],'Z'		; 最終MCB ?
			je		short mcb_end			; YES->終了
			cmp		BYTE PTR es:[0],'M'		; MCB ?
			jne		short mcb_err			; NO ->MCB MARK ERROR
mcb_idchk:									;
			push	es						; MCBｾｸﾞﾒﾝﾄ退避
			mov		es,WORD PTR es:[1]		; PSPｾｸﾞﾒﾝﾄ(Owner ID)
			mov		ax,es					;
			cmp		ax,pspseg				; 起動ﾌﾟﾛｸﾞﾗﾑのPSPか ?
			je		short mcb_next			; YES->次のMCBをﾁｪｯｸ
			call	tsrcmp					; 常駐文字列照合
			jz		short mcb_on			; 等しければ, 常駐済
mcb_next:									;
			pop		es						; MCBｾｸﾞﾒﾝﾄ復元
			mov		ax,es					;
			add		ax,es:[3]				; 使用ﾒﾓﾘのﾊﾟﾗｸﾞﾗﾌ数加算
			inc		ax						; 次のMCBｾｸﾞﾒﾝﾄ
			mov		es,ax					;
			jmp		short mcb_lp			;
mcb_on:										; 常駐済
			pop		ax						; ｽﾀｯｸ調整
			mov		BYTE PTR tsrflg,1		;
mcb_end:									; 非常駐
			push	bx						;
			push	es						;
			call	getvct					; 割込みﾍﾞｸﾀ取得
			pop		es						;
			pop		bx						;
vctchk_21:									;
			mov		ax,es					;
			cmp		WORD PTR v_21+2,ax		; 常駐ｾｸﾞﾒﾝﾄ比較
			je		short vctchk_99			;
			mov		BYTE PTR hookflg,1		; ﾍﾞｸﾀﾌｯｸされている
vctchk_99:									;
			ret								;
mcb_err:									;
			mov		si,OFFSET msg6			; MCBｴﾗｰ
			call	puts					;
			ret								;
;----------------------------------------------------------------------------
;	ﾌﾟﾛｸﾞﾗﾑ名の設定(es=ds=csでcall)
;	常駐時の識別用として, ｺﾏﾝﾄﾞﾗｲﾝ領域にﾌﾟﾛｸﾞﾗﾑ名を複写しておく.
;----------------------------------------------------------------------------
setpname:									;
			mov		si,OFFSET prgname		;
			mov		di,OFFSET ARGUMENT		;
			mov		cx,prgnamelen			;
	rep		movsb							; ds:si->es:di
			ret								;
;----------------------------------------------------------------------------
;	初期処理(es=ds=csでcall)
;----------------------------------------------------------------------------
init:										;
			mov		ah,30h					; get dos version
			cmp		BYTE PTR tsrflg,0		; 常駐していない ?
			jnz		short init_fcall		; NO->far call
			int		21h						;
			jmp		short init_set			;
init_fcall:									;
			INT21H							;
init_set:									;
			mov		defver,al				;
			mov		deflev,ah				;
			ret								;
;----------------------------------------------------------------------------
;	起動処理( メイン )
;----------------------------------------------------------------------------
main		PROC	NEAR					;
			mov		WORD PTR pspseg,es		; PSPｾｸﾞﾒﾝﾄ保存
			cli								; 割り込み禁止
			cld								;
;
			mov		si,OFFSET msg0			; ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ(文字列)
			call	puts					;
			call	tsr_chk					; 常駐ﾁｪｯｸ
			cmp		BYTE PTR tsrflg,0		; 常駐していない ?
			jz		short arg_chk			; YES->arg_chk
;
			push	ds						; 常駐領域内ﾊﾟﾗﾒﾀを複写
			push	es						;
			mov		ax,es					;
			push	ds						;
			pop		es						;
			mov		ds,ax					; ds<->es
			mov		si,OFFSET paraoff		;
			mov		di,OFFSET paraoff		;
			mov		cx,parasize				; ﾊﾟﾗﾒﾀ領域ｻｲｽﾞ
	rep		movsb							; ds:si->es:di
			pop		es						;
			pop		ds						;
arg_chk:									;
			call	init					; 初期処理
			sti								;
			call	argchk					; 引数のﾁｪｯｸ
			mov		al,argflg				;
			or		al,al					; al=0 ?
			jz		short tsr_init			; YES->通常処理開始へ
			mov		si,OFFSET usage			; ﾍﾙﾌﾟﾒｯｾｰｼﾞ
			call	puts					;
			PRGEND							;
tsr_init:									;
			mov		al,tsrflg				; 常駐ﾌﾗｸﾞ
			or		al,al					; 常駐しているか ?
			jz		short mem_noclr			; NO->非常駐処理へ
;-------------------------------------------;
;	常駐解除処理
;-------------------------------------------;
mem_clear:									;
			mov		al,relflg				; 常駐解除ﾌﾗｸﾞ
			or		al,al					; 常駐解除しない ?
			jz		short mem_update		; YES->終了
mem_clrchk:									;
			cmp		BYTE PTR hookflg,0		; ﾍﾞｸﾀﾌｯｸされていないか ?
			je		short mem_clear_ok		; YES->常駐解除
			mov		si,OFFSET msg7			; 常駐解除不可ﾒｯｾｰｼﾞ
			call	puts					;
			PRGEND							;
mem_clear_ok:								;
			push	ds						;
			lds		dx,DWORD PTR es:v_21	;
			mov		ax,2521h				; 割り込みﾍﾞｸﾀを元に戻す!
			int		21h						;
			mov		ah,49h					; プログラムを開放
			int		21h						;
			pop		ds						;
			jc		short mem_clrerr		; ﾒﾓﾘ開放失敗
			mov		si,OFFSET msg2			; 開放ﾒｯｾｰｼﾞ
			jmp		short mem_clrend		;
mem_clrerr:									;
			mov		si,OFFSET msg8			; ﾒﾓﾘ開放失敗ﾒｯｾｰｼﾞ
mem_clrend:									;
			call	puts					;
			PRGEND							;
;
mem_update:									; 常駐領域内のﾊﾟﾗﾒﾀ値変更
			mov		si,OFFSET msg3			; 常駐済ﾒｯｾｰｼﾞ
			call	puts					;
			mov		al,optflg				;
			or		al,al					; ｵﾌﾟｼｮﾝ指定なし ?
			jz		short mem_upend			; YES->終了
			cli								;
			mov		si,OFFSET paraoff		;
			mov		di,OFFSET paraoff		;
			mov		cx,parasize				; ﾊﾟﾗﾒﾀ領域ｻｲｽﾞ
	rep		movsb							; ds:si->es:di
			sti								;
			mov		si,OFFSET msg5			; ｱｯﾌﾟﾃﾞｰﾄﾒｯｾｰｼﾞ(文字数)
			call	puts					;
mem_upend:									;
			PRGEND							;
;
mem_noclr:									;
			mov		al,relflg				; 常駐解除ﾌﾗｸﾞ
			or		al,al					; 常駐解除 ?
			jz		short mem_setup			; NO->常駐処理へ
			mov		si,OFFSET msg4			; 非常駐ﾒｯｾｰｼﾞ
			call	puts					;
			PRGEND							;
;-------------------------------------------;
;	常駐処理
;-------------------------------------------;
mem_setup:									;
			push	cs						;
			pop		es						; es=cs
			call	setpname				;
			mov		si,OFFSET msg1			; 常駐ﾒｯｾｰｼﾞ
			call	puts					;
;
			mov		dx,OFFSET i21h			; 常駐処理ﾌﾟﾛｼｼﾞｬを
			mov		ax,2521h				; ﾍﾞｸﾀｾｯﾄ
			int		21h						;
;
			TSREND							; 常駐終了
;----------------------------------------------------------------------------
;	引数のﾁｪｯｸ
;----------------------------------------------------------------------------
argchk:										; 引数のﾁｪｯｸ
			mov		bx,OFFSET ARGUMENT		;
			mov		BYTE PTR optflg,0		;
arglp:										;
			inc		bx						;
			mov		al,[bx]					;
			cmp		al,CR					;
			jne		short optchk			;
			ret								; 引数ﾁｪｯｸ終了
optchk:										; 引数ﾁｪｯｸ開始
			cmp		al,'-'					; ｵﾌﾟｼｮﾝｽｲｯﾁは'-','/'で始まる.
			je		short optsw1			;
			cmp		al,'/'					;
			je		short optsw1			;
			cmp		al,' '					; SPACE
			je		short arglp				;
			cmp		al,TAB					; TAB
			je		short arglp				;
			jmp		opterr					;
optsw1:										;
			inc		bx						;
			mov		al,[bx]					;
			or		al,20H					; 大文字->小文字
			cmp		al,'r'					; 'r','R'か ?
			jne		short optsw2			; NO->次のﾁｪｯｸへ
			mov		BYTE PTR relflg,1		; 常駐解除ﾌﾗｸﾞ ON
			jmp		short arglp				;
optsw2:										; R/W以外のﾌｧﾝｸｼｮﾝ表示
			cmp		al,'v'					; 'v'か ?
			jne		short opterr			; NO->次のﾁｪｯｸへ
			call	atoi					;
			cmp		BYTE PTR valflg,0		; 数値指定あり ?
			jne		short optsw2chk			; YES->数値ﾁｪｯｸへ
			mov		al,[bx+1]				;
			cmp		al,'.'					; 小数点 ?
			jz		short optsw2th			; YES->小数点ﾁｪｯｸへ
			mov		al,defver				;
			mov		ver,al					; 標準値設定
			jmp		short optsw2def			;
optsw2chk:									;
			mov		ver,al					; 値格納
			mov		al,[bx+1]				;
			cmp		al,'.'					; 小数点 ?
			jnz		short optswon			; NO->次のﾁｪｯｸへ
optsw2th:									;
			inc		bx						;
			call	atoi					;
			cmp		BYTE PTR valflg,0		; 数値指定あり ?
			jne		short optsw2lev			; YES->数値ﾁｪｯｸへ
optsw2def:									;
			mov		al,deflev				;
			mov		lev,al					; 標準値設定
			jmp		short optswon			;
optsw2lev:									;
			mov		lev,al					; 値格納
			jmp		short optswon			;
optpause:									;
			mov		al,[bx+1]				;
			cmp		al,' '					; SPACE
			je		short arglp				;
			cmp		al,TAB					; TAB
			je		short arglp				;
			cmp		al,CR					; 終了
			je		short arglp				;
			jmp		optsw1					;
optswon:									;
			mov		BYTE PTR optflg,1		; ｵﾌﾟｼｮﾝｽｲｯﾁ ON
			jmp		short optpause			;
opterr:										; ｵﾌﾟｼｮﾝｽｲｯﾁｴﾗｰ
			mov		BYTE PTR argflg,1		;
			ret								;
;----------------------------------------------------------------------------
;	文字列を整数に変換
;	< IN  >	: ds:bx	文字列の先頭位置-1
;	< RET >	: ax	整数値
;
;	< USE >	: bx, cx, dx
;----------------------------------------------------------------------------
atoi:										;
			inc		bx						;
			xor		ax,ax					; ax=0
			xor		dx,dx					; dx=0
			xor		ch,ch					; ch=0
			mov		BYTE PTR valflg,0		;
atoi_next:									;
			mov		cl,[bx]					; 文字ｺｰﾄﾞ取得
			sub		cl,'0'					; 文字->数字
			jb		short atoi_end			; '0'よりも小さければ終わり
			cmp		cl,9					; '9'よりも大きいか ?
			ja		short atoi_end			; YESならば終わり
			push	cx						;
			mov		cx,0AH					;
			imul	cx						; AXを10倍する
			pop		cx						;
			add		ax,cx					; AXに新値を格納
			inc		bx						; 次の文字位置
			mov		BYTE PTR valflg,1		;
			jmp		short atoi_next			;
atoi_end:									;
			dec		bx						; 先読み分を戻す
			ret								;
;
main		ENDP							;
;
tsrflg		DB		0						; 常駐ﾌﾗｸﾞ
argflg		DB		0						; 引数ﾁｪｯｸﾌﾗｸﾞ
optflg		DB		0						; ｵﾌﾟｼｮﾝﾌﾗｸﾞ
valflg		DB		0						; ｵﾌﾟｼｮﾝ数値ﾌﾗｸﾞ
relflg		DB		0						; 常駐解除ﾌﾗｸﾞ
hookflg		DB		0						; ﾍﾞｸﾀﾌｯｸﾌﾗｸﾞ
;
defver		DB		?						;
deflev		DB		?						;
;
pspseg		DW		?						; PSPｾｸﾞﾒﾝﾄ
prgname		DB		14,'TRAP-VER v1.00',CR	;
prgnamelen	EQU		$-prgname				;
;
msg0		DB		CR,LF,'MS-DOS trap-ver  Version 1.00  (C)パオパオ 1993. '
			DB		CR,LF,0
msg1		DB		'★ 常駐します ★',CR,LF,0
msg2		DB		'☆ 常駐解除しました ☆',CR,LF,0
msg3		DB		'常駐しています.',CR,LF,0
msg4		DB		'常駐していません.',CR,LF,BEL,0
msg5		DB		'オプションパラメタ値を更新しました.',CR,LF,BEL,0
msg6		DB		'メモリの状態が正しくありません.',CR,LF,BEL,0
msg7		DB		'ベクタをフックされているため, 常駐解除できません.'
			DB		CR,LF,BEL,0
msg8		DB		'メモリの開放に失敗しました.',CR,LF,BEL,0
;
usage		DB		"Usage: 'TRAPVER "
			DB		"[-r] [-v[d.f]]'"
			DB		CR,LF
			DB		'        -r       常駐解除        ',CR,LF
			DB		'        -v[d.f]  バージョン      '
			DB		'                 標準例: 3.10',CR,LF
			DB		0
;
code		ENDS							;
			END		entry					;
;
;	< HISTORY >
;============================================================================
;	1993.03.16 : CREATE
;============================================================================

