;==============================================================================
;	<< MASM V5.1 >>  for  FM TOWNS
;==============================================================================
	PAGE		60,132
	NAME		INT21MON
	TITLE		INT21h Monitor
;==============================================================================
;	DOS Function monitor program
;
;	MS-DOSのﾌｧﾝｸｼｮﾝをﾓﾆﾀｰする.
;
;	CREATE : 1991.06.22
;	FINISH : 1991.06.22  Version 0.50
;
;	< HISTORY >
;	1991.06.22 : CREATE
;
;	All Rights Reserved, Copyright (C) Y.Hirata 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			'INT21h Monitor V0.50   1991-06-22',0Dh,0Ah
			db			0Dh,0Ah,'        '
			db			'Copyright (C) Y.Hirata 1991.'
			db			0Dh,0Ah,0Dh,0Ah,1Ah
;
TITLE_name	db			'INT21h Monitor by パオパオ'
TITLE_len	EQU			$-TITLE_name
;
TRUE		EQU			1
FALSE		EQU			0
;
AttrBlock	struc							; 文字表示用(ｱﾄﾘﾋﾞｭｰﾄ含む)
	Amoji	db			0					; 文字属性(ﾃﾞﾌｫﾙﾄ)
	Adisp	db			0					; 表示属性(ﾃﾞﾌｫﾙﾄ)
	Acolor	dw			5					; 色番号(水色)(ﾃﾞﾌｫﾙﾄ)
AttrBlock	ends							;
;
DispBlock	struc							; 表示情報格納領域
	Moff	dw			?					; 文字    : ｵﾌｾｯﾄ  ;+0
	Mseg	dw			?					;         : ｾｸﾞﾒﾝﾄ ;+2
	Aoff	dw			?					; ｱﾄﾘﾋﾞｭｰﾄ: ｵﾌｾｯﾄ  ;+4
	Aseg	dw			?					;         : ｾｸﾞﾒﾝﾄ ;+6
DispBlock	ends							;
;
;********************************************
;			データ領域
;********************************************
;
vct_21h		DD		far						; MS-DOS
int21flg	DB		FALSE					; 多重割り込み防止用
;
;					 0         1         2         3         4
;					 01234567890123456789012345678901234567890123456
stat		DB		"AX=0000 BX=0000 CX=0000 DX=0000 DS=0000 DI=0000"
stat_len	EQU		$-stat					;
sixteen		DB		16						;
;
disp_tbl	DispBlock <>					; 表示情報格納領域
atr_def		AttrBlock stat_len dup (<>)		; ﾃﾞﾌｫﾙﾄ
;
;********************************************
;			MACRO
;********************************************
;
pgend		macro							; ﾌﾟﾛｸﾞﾗﾑ終了(4CH)
			mov		ax,4C00h				;
			int		21h						; Program End !
			endm							;
;
disp		macro	nchar					; 文字/ｱﾄﾘﾋﾞｭｰﾄ表示(ｼｽﾃﾑ行)
			mov		al,1					;
			mov		cx,nchar				;
			mov		dl,2					; 開始位置(桁)
			mov		di,offset disp_tbl		;
			mov		ah,1Fh					;
			int		91h						;
			endm							;
;
convert		macro	val,base,dest			; 数字(0〜15)->文字
			local	table,start				;
			jmp		short start				;
table		DB		"0123456789ABCDEF"		;
start:										;
			push	ax						;
			push	bx						;
			push	dx						;
			mov		al,val					;
			xor		ah,ah					; AH=0
			xor		bx,bx					; BX=0
			div		base					; AX/base -> AL(商) AH(剰余)
			mov		bl,al					;
			mov		al,cs:table[bx]			;
			mov		dest,al					;
			mov		bl,ah					;
			mov		al,cs:table[bx]			;
			mov		dest[1],al				;
			pop		dx						;
			pop		bx						;
			pop		ax						;			
			endm							;
;
;********************************************
;			常駐処理部
;********************************************
;
;--------------------------------------------
;	DOSﾌｧﾝｸｼｮﾝの横取り処理
;--------------------------------------------
INT21hook	proc	far						;
			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					;
			push	ax						;
			mov		ax,cs					;
			mov		ds,ax					;
			mov		es,ax					; es = ds = cs
			pop		ax						;
			cli								;
			cld								;
;
			cmp		cs:int21flg,TRUE		; 多重割り込み防止
			jne		i21						;
			jmp		i21end					;
;
i21:		mov		cs:int21flg,TRUE		;
			convert	ah,sixteen,stat[3]		;
			convert	al,sixteen,stat[5]		; AX
			convert	bh,sixteen,stat[11]		;
			convert	bl,sixteen,stat[13]		; BX
			convert	ch,sixteen,stat[19]		;
			convert	cl,sixteen,stat[21]		; CX
			convert	dh,sixteen,stat[27]		;
			convert	dl,sixteen,stat[29]		; DX
			mov		bx,sp					;
			mov		ax,[bx+2]				;
			convert	ah,sixteen,stat[35]		;
			convert	al,sixteen,stat[37]		; DS
			mov		ax,di					;
			convert	ah,sixteen,stat[43]		;
			convert	al,sixteen,stat[45]		; DI
;
			mov		bx,offset disp_tbl		; 表示情報格納領域 : [BX]
			mov		ax,offset stat			;
			mov		[bx].Moff,ax			; 文字    : ｵﾌｾｯﾄ
			mov		ax,offset atr_def		;
			mov		[bx].Aoff,ax			; ｱﾄﾘﾋﾞｭｰﾄ: ｵﾌｾｯﾄ
			mov		ax,cs					;
			mov		[bx].Mseg,ax			; 文字    : ｾｸﾞﾒﾝﾄ
			mov		[bx].Aseg,ax			; ｱﾄﾘﾋﾞｭｰﾄ: ｾｸﾞﾒﾝﾄ
			sti								;
			disp	stat_len				; ﾌｧﾝｸｼｮﾝ状態表示
;
i21end:
			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:int21flg,FALSE		;
;
i21_ret:	jmp		cs:[vct_21h]			; 本来のﾍﾞｸﾀに処理を移す｡
;			iret							;
INT21hook	endp							;
;
;--------------------------------------------
SEGEND		label	WORD
;--------------------------------------------
;
;********************************************
;			起動処理( メイン )
;********************************************
main		proc	near					;
;
			mov		cx,msg0_len				; ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ(文字数)
			mov		di,offset msg0			; ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ(文字列)
			mov		ah,1Eh					;
			int		91h						; 文字列出力(ｵｰﾌﾟﾆﾝｸﾞﾒｯｾｰｼﾞ)
;
			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,3521h				;
			int		21h						; DOSﾌｧﾝｸｼｮﾝ割込みﾍﾞｸﾀ取得
			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				; 開放ﾒｯｾｰｼﾞ
			mov		di,offset msg2			;
			mov		ah,1Eh					;
			int		91h						;
;
			lds		dx,DWORD ptr es:vct_21h	;
			mov		ax,2521h				; DOSﾌｧﾝｸｼｮﾝを元のﾍﾞｸﾀに!
			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				; 非常駐ﾒｯｾｰｼﾞ
			mov		di,offset msg4			;
			mov		ah,1Eh					;
			int		91h						;
			pgend							;
;
;
;	常駐処理
;
tsr_init:
			mov		ax,3521h				; * DOSﾌｧﾝｸｼｮﾝ *
			int		21h						;
			mov		WORD ptr cs:vct_21h,bx	;
			mov		WORD ptr cs:vct_21h+2,es
											; 本来のINT21ﾍﾞｸﾀの取得･保存
;
			mov		cx,TITLE_len			;
			mov		si,offset TITLE_name	;
			mov		di,offset TITLE_name	;
			repz	cmpsb					; 常駐ﾁｪｯｸ
			jne		mem_setup				; 常駐処理へ
;
			mov		cx,msg3_len				; 常駐済ﾒｯｾｰｼﾞ
			mov		di,offset msg3			;
			mov		ah,1Eh					;
			int		91h						;
			mov		cx,msghp_len			; ﾍﾙﾌﾟﾒｯｾｰｼﾞ
			mov		di,offset msghp			;
			mov		ah,1Eh					;
			int		91h						;
			pgend							;
;
mem_setup:
			mov		cx,msg1_len				; 常駐ﾒｯｾｰｼﾞ
			mov		di,offset msg1			;
			mov		ah,1Eh					;
			int		91h						;
			mov		cx,msghp_len			; ﾍﾙﾌﾟﾒｯｾｰｼﾞ
			mov		di,offset msghp			;
			mov		ah,1Eh					;
			int		91h						;
;
			mov		dx,offset INT21hook		; 常駐処理ﾌﾟﾛｼｼﾞｬを
			mov		ax,2521h				; ﾍﾞｸﾀｾｯﾄ
			int		21h						; (DOSﾌｧﾝｸｼｮﾝ)
;
			mov		dx,offset SEGEND		;
			add		dx,15					;
			mov		cl,4					;
			shr		dx,cl					; ﾊﾟﾗｸﾞﾗﾌ単位
			mov		ax,3100h				;
			int		21h						; 常駐終了
;
main		endp
;
msg0		db		'DOS Function monitor  (C)パオパオ 1991.      '
			db		'<< Copyright (C) Y.Hirata 1991. >>',0Dh,0Ah,0Dh,0Ah
			db		'DOS Function monitor Version 0.50   '
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

