;==============================================================================
;	<< 386ASM V2.0 >>  for  FM TOWNS
;==============================================================================
.386p
		PAGE		60,132
		NAME		RETRY
		TITLE		CRITICAL ERROR auto Retry
;==============================================================================
;	致命的ｴﾗｰ回避処理(CTRL+Cﾏｽｸ処理)
;
;	CREATE : 1990.06.01
;	FINISH : 1990.06.02
;
;	< High C からの呼出形式 >
;------------------------------------------------------------------------------
;	extern void _harderr_clear( void ) ;
;	extern void _harderr_retry( void ) ;
;	_harderr_clear() ;
;	_harderr_retry() ;
;------------------------------------------------------------------------------
;
;	< NOTE > : TABS = 4
;
;	< HISTORY >
;	1990.06.01 : CREATE
;	1993.08.24 : 致命的ｴﾗｰ処理を自動回避処理とする
;
;	< ｺﾒﾝﾄ >
;	ﾍﾞｸﾀを書き換えた場合には,元に戻しておくべきなのだが,INT23h/INT24hについて
;	は,DOSがPSPによって元に戻してくれるのでここでは処理していない.
;
;	Programmed by Y.Hirata ( Nifty-ID : NAB03321 )
;==============================================================================
INCLUDE	TOWNS.INC							;
;
CGROUP	GROUP pmcode, CODE					;
DGROUP	GROUP pmdata, DATA					;
;
;--------------------------------------------
		public	_harderr_clear				; 致命的ｴﾗｰ回数ｸﾘｱ
		public	_harderr_retry				; 致命的ｴﾗｰ割り込み登録
;--------------------------------------------
;
;////////////////////////////////////////////
;			ネイティブ部
;////////////////////////////////////////////
;********************************************
;	致命的ｴﾗｰﾈｲﾃｨﾌﾞﾊﾝﾄﾞﾗ内での使用データ領域
;********************************************
DATA	SEGMENT								;
rcnt		DW		0						; ﾘﾄﾗｲｶｳﾝﾀ
rax			DW		?						;
rcx			DW		?						;
nretry		DW		3						; ﾘﾄﾗｲ回数
wtime		DW		100						; ﾘﾄﾗｲ時待ち時間
DATA	ENDS								;
;
;********************************************
;	致命的ｴﾗｰﾊﾝﾄﾞﾗ/ﾈｲﾃｨﾌﾞ処理
;********************************************
pmcode	SEGMENT 							;
		ASSUME	cs:CGROUP, ds:DGROUP		;
;--------------------------------------------
;	CTRL+C ﾈｲﾃｨﾌﾞﾊﾝﾄﾞﾗ
;--------------------------------------------
		ALIGN	4							; dword boundary
INT23_hook	PROC	FAR						;
			iretd							;
INT23_hook	ENDP							;
;
;--------------------------------------------
;	致命的ｴﾗｰﾈｲﾃｨﾌﾞﾊﾝﾄﾞﾗ
;--------------------------------------------
		ALIGN	4							; dword boundary
INT24_retry	PROC	FAR						;
			cli								;
			push	ds						;
			push	eax						; eax退避
			mov		ax,DATASEG				; ﾃﾞｰﾀｾｸﾞﾒﾝﾄ設定
			mov		ds,ax					;
			pop		eax						; eax復元
			mov		rcx,cx					; ﾚｼﾞｽﾀ退避
			mov		cx,wtime				;
			int		0FDh					; wait
			mov		cx,rcx					; ﾚｼﾞｽﾀ復元
			mov		ax,rcnt					;
			cmp		ax,nretry				;
			jb		short i24h_retry		;
			mov		ax,0003h				; ｼｽﾃﾑｺｰﾙ失敗でﾘﾀｰﾝ
			mov		rcnt,0					;
			pop		ds						;
			iretd							; 割り込み復帰
i24h_retry:									;
			inc		ax						;
			mov		rcnt,ax					;
			mov		ax,0001h				; ﾘﾄﾗｲ
			pop		ds						;
			iretd							; 割り込み復帰
INT24_retry	ENDP							;
;
;--------------------------------------------
;	CTRL+C割り込み登録
;--------------------------------------------
		ALIGN	4							; dword boundary
_signal_mask:								;
			cli								;
			lea		edx,INT23_hook			;
			mov		cl,23h					; CTRL+Cの割り込み番号
			mov		ax,2506h				; ﾈｲﾃｨﾌﾞﾊﾝﾄﾞﾗの登録
			sti								;
			int		INT_DOS					;
			ret								;
;
;--------------------------------------------
;	致命的ｴﾗｰ回数ｸﾘｱ
;--------------------------------------------
		ALIGN	4							; dword boundary
_harderr_clear	PROC						;
			mov		rcnt,0					;
			ret								;
_harderr_clear	ENDP						;
;
;--------------------------------------------
;	致命的ｴﾗｰ割り込み登録
;--------------------------------------------
		ALIGN	4							; dword boundary
_harderr_retry	PROC						;
			push	ebp						;
			mov		ebp,esp					; ｽﾀｯｸﾌﾚｰﾑ形成
;
			push	ds						;
			push	es						;
			push	edx						;
			push	ecx						;
;
			push	cs						;
			pop		ds						; ds = cs
;
			call	_signal_mask			; CTRL+Cをﾏｽｸ
;
			cli								;
			lea		edx,INT24_retry			;
			mov		cl,24h					; 致命的ｴﾗｰの割り込み番号
			mov		ax,2506h				; ﾈｲﾃｨﾌﾞﾊﾝﾄﾞﾗの登録
			sti								;
			int		INT_DOS					;
;
			pop		ecx						;
			pop		edx						;
			pop		es						;
			pop		ds						;
			xor		eax,eax					; return code = 0
;
			pop		ebp						; ｽﾀｯｸﾌﾚｰﾑ開放
			ret								;
_harderr_retry	ENDP						;
;
pmcode		ENDS							;
;
		END

