; -------------
BLOOD segment
assume cs:BLOOD , ds:BLOOD ,SS:BLOOD , ES:BLOOD
org 100H
P486

start:	jmp install

install:
	;
	lea dx, [copyright]
	call pis
	;
	mov si, 80h
	xor cx, cx
	;
	mov cl, byte ptr [si]
	;
	or cx, cx
	jz go_on
	;
	inc si
	;
looping_:
	;
	call get_char
	;
	cmp al, '/'
	jnz go_on
	;
	lodsb
	;
	and al, 0dfh
	;
	cmp al, 'I'
	jnz check_f
	;
	xor ax, ax
	;
	call hex_2_dec
	;
	mov byte ptr [interrupt_], al
	;
	jmp looping_
	;
check_f:
	;
	cmp al, 'F'
	jnz go_on
	;
	xor ax, ax
	;
	call hex_2_dec
	;
	mov byte ptr [function_], al
	;
go_on:
	;
	call trace_trough
	call mcbz_umbz_
	call vdisk_check
	call write_it
	;
konec:
	;
	int 20h
	;
	
	;
get_char:
	;
	lodsb
	;
	dec cx
	jcxz go_on
	;
	cmp al, 20h
	jz get_char
	;
	cmp al, 09h
	jz get_char
	;
	cmp al, 0ah
	jz get_char
	;
	cmp al, 0dh
	jz get_char
	;
	retn
	;

	;
trace_trough:
	;
	mov word ptr [buffer], cs
	;
	push ds
	;
	xor ax, ax
	mov ds, ax
	;
	mov eax, dword ptr ds:[01h * 4]
	;
	mov dword ptr cs:[push_im32], eax
	;
	mov word ptr ds:[01h * 4], offset new_int_01h
	mov word ptr ds:[01h * 4 + 2], cs
	;
	pushf
	;
	pop ax
	or ah, 1
	push ax
	;
	popf
	;
	db	0b4h
function_	db	0ffh
	;
	db	0cdh
interrupt_	db	21h
	;
	pushf
	;
	pop ax
	and ah, 0feh
	push ax
	;
	popf
	;
	db	66h, 68h
push_im32	dd	?
	;
	pop dword ptr ds:[01h * 4]
	;
	pop ds
	;
	retn
	;

	;
new_int_01h:
	;
	push ax
	push ax
	push ax
	push bp
	;
	mov bp, sp
	;
	push ax
	push bx
	push cx
	push ds
	;
	push cs
	pop ds
	;
	mov ax, word ptr [bp+0ah]
	mov cx, word ptr [bp+08h]
	;
	mov bx, cs
	;
	cmp ax, bx
	jz new_int_01h_check_int
	;
	mov bx, word ptr [table_pointer]
	;
	cmp bx, offset buffer_ - 10
	ja new_int_01h_end
	;
	cmp ax, word ptr [bx]
	jz new_int_01h_check_int
	;
	inc word ptr [counter_]
	;
	inc bx
	inc bx
	;
	mov word ptr [bx], cx
	;
	inc bx
	inc bx
	;
	mov word ptr [bx], ax
	;
	mov word ptr [table_pointer], bx
	;
new_int_01h_check_int:
	;
	mov ds, ax
	mov bx, cx
	;
	mov ax, word ptr [bx]
	;
	cmp al, 0cdh
	jnz new_int_01h_end
	;
	mov al, ah
	xor ah, ah
	;
	shl ax, 2
	;
	mov bx, ax
	;
	xor ax, ax
	mov ds, ax
	;
	mov ax, word ptr [bx]
	;
	inc bx
	inc bx
	;
	mov bx, word ptr [bx]
	;
	add word ptr [bp+8], 2
	;
	mov word ptr [bp+6], bx
	mov word ptr [bp+4], ax
	;
	mov ax, word ptr [bp+12]
	mov word ptr [bp+2], ax
	;
	pop ds
	pop cx
	pop bx
	pop ax
	pop bp
	popf
	;
	retf
	;
new_int_01h_end:
	;
	pop ds
	pop cx
	pop bx
	pop ax
	pop bp
	pop ax
	pop ax
	pop ax
	;
	iret
	;

	;
mcbz_umbz_:
	;
	mov ah, 52h
	int 21h
	;
	mov bx, word ptr es:[bx - 2]
	;
	mov word ptr [first_mcb], bx
	;
	call find_end
	;
main_loop_:
	;
	mov es, bx
	;
	call end_?
	jc main_loop_end
	;
	call get_owner_name
	call store_it_2_buffer_
	;
	mov bx, es
	add bx, word ptr es:[3]
	inc bx
	;
	jmp short main_loop_
	;
main_loop_end:
	;
	retn
	;
	
	;
store_it_2_buffer_:
	;
	cmp ax, 04h
	jz store_it_2_buffer_end
	;
	mov word ptr [mov_ax_?], ax
	;
	mov di, word ptr [buffer_pointer]
	;
	mov word ptr [di], es
	;
	inc di
	inc di
	;
	mov ax, es
	add ax, word ptr es:[3]
	inc ax
	;
	mov word ptr [di], ax
	;
	inc di
	inc di
	;
	push ds
	push es
	;
	db	0b8h
mov_ax_?	dw	?
	;
	mov cx, ds
	;
	or ax, ax
	jz jump_over_
	;
	push es
	pop ds
	;
jump_over_:
	;
	push di
	;
	mov es, cx
	;
	mov cx, 08h
	;
	push cx
	;
	rep movsb
	;
	pop cx
	pop di
	;
	xor ax, ax
	;
	repnz scasb
	;
	mov al, '$'
	stosb
	;
	pop es
	pop ds
	;
	add word ptr [buffer_pointer], 13
	;
	inc word ptr [counter__]
	;
store_it_2_buffer_end:
	;
	retn
	;

	;
get_owner_name:
	;
	call get_mcb_type
	;
	or ax, ax
	lea si, [msdos_]
	jnz go_on_owner_name
	;
	push es
	;
	call msdos_type
	;
	pop es
	;
	jmp short ok_name_found
	;
go_on_owner_name:
	;
	cmp ax, 01h
	lea si, es:[8]
	jz ok_name_found
	;
	call find_prog_
	;
ok_name_found:
	;
	retn
	;
	
	;
msdos_type:
	;
	cmp word ptr es:[8], 'CS'
	jnz go_on_msdos_type
	;
	push bx
	;
	mov bx, es
	;
	cmp word ptr [mcb_end], bx
	pop bx
	ja msdos_type_end_
	;
	jmp short msdos_type_end
	;
go_on_msdos_type:
	;
	cmp word ptr es:[8], 'DS'
	jnz msdos_type_end_
	;
	mov ax, es
	inc ax
	;
msdos_type_loop:
	;
	mov es, ax
	;
	cmp byte ptr es:[0], 'M'
	jz msdos_type_end
	;
	cmp byte ptr es:[0], 'Z'
	jz msdos_type_end
	;
	cmp byte ptr es:[0], 'D'
	jnz msdos_type_go_on
	;
	push ax
	;
	mov ax, 01h
	lea si, es:[8]
	;
	call store_it_2_buffer_
	;
	pop ax
	;
msdos_type_go_on:
	;
	add ax, word ptr es:[03]
	inc ax
	;
	jmp short msdos_type_loop
	;
msdos_type_end:
	;
	mov ax, 04h
	;
msdos_type_end_:
	;
	retn
	;
	
	;
find_prog_:
	;
	push es
	push ds
	;
	mov dx, word ptr es:[1]
	;
	mov es, word ptr [first_mcb]
	;
find_prog_loop_:
	;
	call end_?
	jc prog_end
	;
	cmp word ptr es:[1], dx
	jz check_prog_
	;
go_2_next_mcb:
	;
	mov ax, es
	;
	add ax, word ptr es:[3]
	inc ax
	;
	mov es, ax
	;
	jmp short find_prog_loop_
	;
check_prog_:
	;
	call get_mcb_type
	;
	cmp ax, 01h
	jnz go_2_next_mcb
	;
	mov cx, ds
	;
	push es
	pop ds
	;
	mov es, cx
	lea di, [name_]
	;
	mov cx, 08h
	;
	rep movsb
	;
prog_end:
	;
	pop ds
	pop es
	;
	xor ax, ax
	lea si, [name_]
	;
	retn
	;

	;
find_end:
	;
	mov ax, word ptr [first_mcb]
	;
find_end_loop:
	;
	mov fs, ax
	;
	cmp byte ptr fs:[0], 'Z'
	jz ok_found_end
	;
	add ax, word ptr fs:[3]
	inc ax
	;
	jmp short find_end_loop
	;
ok_found_end:
	;
	mov word ptr [mcb_end], fs
	;
	retn
	;

	;
end_?:
	;
	cmp byte ptr es:[0], 'Z'
	jnz end_?_end
	;
	mov ax, es
	;
	cmp ax, word ptr [mcb_end]
	ja end_?_end_
	;
	add ax, word ptr es:[3]
	inc ax
	;
	mov es, ax
	;
	jmp short end_?
	;
end_?_end:
	;
	cmp byte ptr es:[0], 'M'
	jnz end_?_end_
	;
	clc
	;
	retn
	;
end_?_end_:
	;
	stc
	;
	retn
	;
	
	;
get_mcb_type:
; getz : ax = mcb_type
;	 ax = 00h 4 MSDOS
;	      01h 4 program
;	      02h 4 system_var
;	      03h 4 data
;	      04h 4 free_mcb
	;
	mov cx, word ptr es:[1]
	;
	mov ax, 04h
	;
	or cx, cx
	jz get_type_end
	;
	xor ax, ax
	;
	cmp cx, 08h
	jz get_type_end
	;
	mov ax, es
	sub cx, ax
	;
	neg cx
	;
	cmp cx, 0ffffh
	jnz check_system_varz
	;
	mov ax, 01h
	;
	jmp get_type_end
	;
check_system_varz:
	;
	mov ax, es
	;
	mov fs, word ptr es:[1]
	;
	sub ax, word ptr fs:[2ch]
	;
	cmp ax, 0ffffh
	mov ax, 03h
	jnz get_type_end
	;
	mov ax, 02h
	;
get_type_end:
	;
	retn
	;
	
	;
print_it:
	;
	push cx
	;
	mov cx, 4
	;
repeat_:
	;
	push cx
	;
	rol ax, 04h
	;
	push ax
	;
	and al, 0fh
	add al, 30h
	;
	cmp al, 39h
	jbe print_it_
	;
	add al, 7
	;
print_it_:
	;
	mov ah, 2
	mov dl, al
	int 21h
	;
	pop ax
	pop cx
	;
	loop repeat_
	;
	pop cx
	;
	retn
	;
	
	;
pis:
	;
	mov ah, 09h
	int 21h
	;
	retn
	;
	
	;
vdisk_addr	dw	13h, 0ffffh
vdisk_string	db	'VDISK$'
	;
vdisk_check:
	;
	push ds
	push es
	;
	push cs
	pop es
	;
	lds si, dword ptr [vdisk_addr]
	;
	lea di, [vdisk_string]
	;
	mov cx, 5
	;
	cld
	;
	repz cmpsb
	;
	pop es
	pop ds
	;
	jnz vdisk_not_found
	;
	mov word ptr [mov_dx_?], offset vdisk_string
	;
vdisk_not_found:
	;
	retn
	;

	;
write_it:
	;
	mov bx, offset buffer + 2
	mov word ptr [table_pointer], bx
	;
write_it_loop_:
	;
	call write_cs_ip
	call write_owner
	;
	lea dx, [radka]
	call pis
	;
	dec word ptr [counter_]
	jnz write_it_loop_
	;
	retn
	;
write_cs_ip:
	;
	mov bx, word ptr [table_pointer]
	;
	mov ax, word ptr [bx + 2]
	call print_it
	;
	mov ah, 02h
	mov dl, ':'
	int 21h
	;
	mov ax, word ptr [bx]
	call print_it
	;
	add word ptr [table_pointer], 04h
	;
	retn
	;
write_owner:
	;
	mov cx, 10
	;
write_20h:
	;
	mov ah, 02h
	mov dl, ' '
	int 21h
	;
	loop write_20h
	;
	mov bx, word ptr [table_pointer]
	sub bx, 04h
	;
	movzx eax, word ptr [bx]
	shr eax, 4
	movzx ecx, word ptr [bx + 2]
	add eax, ecx
	;
	db	0bah
mov_dx_?	dw	offset donno_
	;
	cmp eax, 0ffffh
	ja write_it_now
	;
	mov cx, word ptr [counter__]
	jcxz write_owner_loop_end_
	;
	mov si, offset buffer_
	;
write_owner_loop_:
	;
	lea dx, [msdos_]
	cmp ax, word ptr [first_mcb]
	jc write_it_now
	;
	cmp ax, word ptr [si]
	jc write_owner_go_on
	;
	cmp ax, word ptr [si + 2]
	ja write_owner_go_on
	;
	lea dx, [si + 4]
	;
	jmp short write_owner_loop_end
	;
write_owner_go_on:
	;
	add si, 13
	;
	loop write_owner_loop_
	;
write_owner_loop_end:
	;
	cmp dx, offset msdos_
	jnz write_it_now
	;
	lea dx, [bios_]
	;
	cmp ax, 09fffh
	ja write_it_now
	;
	lea dx, [donno_]
	;
write_it_now:
	;
	mov ah, 09h
	int 21h
	;
write_owner_loop_end_:
	;
	retn
	;
	
	;
include	hex2dec.inc
	;
_comp_	db	'Compiled on '
	db	??date, ' at '
	db	??time, '.'
	;
copyright	db	'Interrupt_tracer v.1.5		(C)Copyright 1999 BLOOD PMsoft (Petr Matousek)', 0ah, 0dh
		db	'syntaxe : int_trac.com /i<interrupt>/f<function>', 0ah, 0dh
		db	'default : int_21h; fc_0ffh', 0ah, 0dh
		db	'------------------------------------------------------------------------------', 0ah, 0dh, '$'
radka	db	0ah, 0dh, '$'
	;
msdos_	db	'MSDOS', 0, '$'
bios_	db	'BIOS', 0, '$'
donno_	db	'????$'
name_	db	'????'
	db	4 dup(20h)
	;
table_pointer	dw	offset buffer
counter_	dw	0
buffer_pointer	dw	offset buffer_
counter__	dw	0
first_mcb	dw	?
mcb_end		dw	?
	;
buffer	db	20000 dup(?)
buffer_	db	20000 dup(?)
	;
BLOOD	ends
	end start