;============================================================================
;	<< MASM V5.1 >>  for  FM TOWNS
;============================================================================
.186
	PAGE		60,132
	NAME		RETRY
	TITLE		INT 24h retry
;============================================================================
;	致命的ｴﾗｰﾄﾗｯﾌﾟﾌﾟﾛｸﾞﾗﾑ
;
;	All Rights Reserved, Copyright (C) Y.Hirata 1993.
;	Programmed by Y.Hirata ( NIFTY-ID : NAB03321 )
;
;	< NOTE > TAB=4
;============================================================================
code		SEGMENT
			ASSUME	cs:code,ds:code,es:code,ss:code
;----------------------------------------------------------------------------
			ORG		000h
SEGTOP		LABEL	BYTE
;----------------------------------------------------------------------------
			ORG		012h
critadrs	DD		FAR
;----------------------------------------------------------------------------
			ORG		016h
owner		DW		?
;----------------------------------------------------------------------------
			ORG		02Ch
envadrs		DW		?
;----------------------------------------------------------------------------
			ORG		080h
ARGUMENT	LABEL	BYTE
argc		DB		?						; 引数の文字数
;----------------------------------------------------------------------------
			ORG		100h
entry:		jmp		main
;----------------------------------------------------------------------------
CR			EQU		0Dh						;
LF			EQU		0Ah						;
BEL			EQU		07h						;
TAB			EQU		09h						;
EOF			EQU		1Ah						;
;
TITLE_name	DB			'RETRY v1.00'		; 常駐ﾁｪｯｸ用文字列
TITLE_len	EQU			$-TITLE_name		;
;
;****************************************************************************
;			データ領域
;****************************************************************************
v_24		DD		FAR						; ﾍﾞｸﾀｱﾄﾞﾚｽ
rcnt		DW		0						; ﾘﾄﾗｲｶｳﾝﾀ
rax			DW		?						;
rcx			DW		?						;
paraoff		LABEL	BYTE					;
nretry		DW		?						; ﾘﾄﾗｲ回数
wtime		DW		?						; ﾘﾄﾗｲ時待ち時間
trapflg		DB		?						; ﾄﾗｯﾌﾟ処理ﾌﾗｸﾞ
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		ax,cs:envadrs			;
			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							;
;
;****************************************************************************
;			常駐処理部
;****************************************************************************
;----------------------------------------------------------------------------
;			割り込みﾌｯｸ処理
;----------------------------------------------------------------------------
i21h		PROC	FAR						;
			mov		WORD PTR cs:rcnt,0		;
			mov		cs:rax,ax				; AX退避
			cmp		ax,2524h				;
			jnz		short i21chain			;
			mov		al,cs:trapflg			;
			or		al,al					;
			jnz		i24setvect				;
			mov		ax,ds					;
			cmp		ax,WORD PTR cs:owner	;
			jz		short i24setvect		;
i21chain:									;
			mov		ax,cs:rax				; AX復元
			DB		0EAh					; far jump
v_21		DD		FAR						; ﾍﾞｸﾀｱﾄﾞﾚｽ
;;			jmp		cs:[v_21]				; 本来のﾍﾞｸﾀに処理を移す｡
i24setvect:									;
			push	si						;
			push	es						;
			xor		ax,ax					;
			mov		es,ax					; es=0
			mov		ax,24h					;
			shl		ax,2					; *4
			mov		si,ax					;
			mov		ax,OFFSET cs:i24h		;
			mov		WORD PTR es:[si],ax		; offset
			mov		ax,cs					;
			mov		WORD PTR es:[si+2],ax	; segment
			pop		es						;
			pop		si						;
			mov		ax,cs:rax				; AX復元
			iret							;
i21h		ENDP							;
;----------------------------------------------------------------------------
;			割り込みﾌｯｸ処理
;----------------------------------------------------------------------------
i24h		PROC	FAR						;
			mov		cs:rcx,cx				; ﾚｼﾞｽﾀ退避
			mov		cx,cs:wtime				;
			int		0FDh					; wait
			mov		cx,cs:rcx				; ﾚｼﾞｽﾀ復元
			mov		ax,cs:rcnt				;
			cmp		ax,WORD PTR cs:nretry	;
			jb		short i24h_retry		;
			mov		ax,0003h				; ｼｽﾃﾑｺｰﾙ失敗でﾘﾀｰﾝ
			mov		WORD PTR cs:rcnt,0		;
			iret							;
i24h_retry:									;
			inc		ax						;
			mov		cs:rcnt,ax				;
			mov		ax,0001h				; ﾘﾄﾗｲ
			iret							;
i24h		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		; 本来の割り込みﾍﾞｸﾀの取得･保存
			nop								;
			mov		ax,3524h				;
			int		21h						; 割込みﾍﾞｸﾀ取得
			mov		WORD PTR v_24,bx		;
			mov		WORD PTR v_24+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:										;
			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					; 常駐しているか ?
			jnz		short mem_clear			; YES->常駐処理へ
			jmp		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						;
			nop								;
			lds		dx,DWORD PTR es:v_24	;
			mov		ax,2524h				; 割り込みﾍﾞｸﾀを元に戻す!
			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:										; ﾘﾄﾗｲ回数
			cmp		al,'c'					; 'c'か ?
			jne		short optsw3			; NO->次のﾁｪｯｸへ
			call	atou					;
			cmp		BYTE PTR valflg,0		; 数値指定あり ?
			jne		short optsw2chk			; YES->数値ﾁｪｯｸへ
			mov		WORD PTR nretry,3		; 標準値設定
			jmp		short optswon			;
optsw2chk:									;
			mov		nretry,ax				; 値格納
			jmp		short optswon			;
optsw3:										; ﾘﾄﾗｲ時待ち時間
			cmp		al,'w'					; 'w'か ?
			jne		short optsw4			; NO->次のﾁｪｯｸへ
			call	atou					;
			cmp		BYTE PTR valflg,0		; 数値指定あり ?
			jne		short optsw3chk			; YES->数値ﾁｪｯｸへ
			mov		WORD PTR wtime,100		; 標準値設定
			jmp		short optswon			;
optsw3chk:									;
			cmp		ax,0					;
			jz		short opterr			; 0ならばｴﾗｰ
			mov		wtime,ax				; 値格納
			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			;
optsw4:										; ﾄﾗｯﾌﾟ処理識別
			cmp		al,'a'					; 'a'か ?
			jne		short opterr			; NO->次のﾁｪｯｸへ
			call	atou					;
			cmp		BYTE PTR valflg,0		; 数値指定あり ?
			jne		short optsw4chk			; YES->数値ﾁｪｯｸへ
			mov		BYTE PTR trapflg,0		; 標準値設定
			jmp		short optswon			;
optsw4chk:									;
			or		ax,ax					;
			jnz		short optsw4chk2		; 0以外は次のﾁｪｯｸへ
			mov		trapflg,al				;
			jmp		short optswon			;
optsw4chk2:									;
			cmp		ax,1					;
			jne		short opterr			; 1でなければｴﾗｰ
			mov		trapflg,al				;
			jmp		short optswon			;
opterr:										; ｵﾌﾟｼｮﾝｽｲｯﾁｴﾗｰ
			mov		BYTE PTR argflg,1		;
			ret								;
;----------------------------------------------------------------------------
;	文字列を整数に変換
;	< IN  >	: ds:bx	文字列の先頭位置-1
;	< RET >	: ax	整数値(符号なし)
;
;	< USE >	: bx, cx, dx
;----------------------------------------------------------------------------
atou:										;
			inc		bx						;
			xor		ax,ax					; ax=0
			xor		dx,dx					; dx=0
			xor		ch,ch					; ch=0
			mov		BYTE PTR valflg,0		;
atou_next:									;
			mov		cl,[bx]					; 文字ｺｰﾄﾞ取得
			sub		cl,'0'					; 文字->数字
			jb		short atou_end			; '0'よりも小さければ終わり
			cmp		cl,9					; '9'よりも大きいか ?
			ja		short atou_end			; YESならば終わり
			push	cx						;
			mov		cx,0AH					;
			mul		cx						; AXを10倍する
			pop		cx						;
			add		ax,cx					; AXに新値を格納
			inc		bx						; 次の文字位置
			mov		BYTE PTR valflg,1		;
			jmp		short atou_next			;
atou_end:									;
			dec		bx						; 先読み分を戻す
			ret								;
;
main		ENDP							;
;
tsrflg		DB		0						; 常駐ﾌﾗｸﾞ
argflg		DB		0						; 引数ﾁｪｯｸﾌﾗｸﾞ
optflg		DB		0						; ｵﾌﾟｼｮﾝﾌﾗｸﾞ
valflg		DB		0						; ｵﾌﾟｼｮﾝ数値ﾌﾗｸﾞ
relflg		DB		0						; 常駐解除ﾌﾗｸﾞ
hookflg		DB		0						; ﾍﾞｸﾀﾌｯｸﾌﾗｸﾞ
;
pspseg		DW		?						; PSPｾｸﾞﾒﾝﾄ
prgname		DB		11,'RETRY v1.00',CR		;
prgnamelen	EQU		$-prgname				;
;
msg0		DB		CR,LF,'Critical error Trap  Version 1.00'
			DB		'  (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: 'RETRY "
			DB		"[-r] [-a[n]] [-c[n]] [-w[n]]'"
			DB		CR,LF
			DB		'        -r     常駐解除            ',CR,LF
			DB		'        -a[n]  トラップ処理        '
			DB		'n: 0=親プロセスのみ, 1=全プロセス,  標準: 0',CR,LF
			DB		'        -c[n]  リトライ回数        '
			DB		'n: 0〜65535,   標準: 3',CR,LF
			DB		'        -w[n]  リトライ時待ち時間  '
			DB		'n: 1〜65535,   標準: 100(*10us)',CR,LF
			DB		0
;
code		ENDS							;
			END		entry					;
;
;	< HISTORY >
;============================================================================
;	1993.04.12 : CREATE
;============================================================================

