;	[]===========================================================[]
;
;	NOTICE: THIS PROGRAM BELONGS TO AWARD SOFTWARE INTERNATIONAL(R)
;	        INC. IT IS CONSIDERED A TRADE SECRET AND IS NOT TO BE 	
;	        DIVULGED OR USED BY PARTIES WHO HAVE NOT RECEIVED	
;	        WRITTEN AUTHORIZATION FROM THE OWNER.
;
; 	[]===========================================================[]
;

;----------------------------------------------------------------------------
;Rev	Date	 Name	Description
;----------------------------------------------------------------------------
;R08	06/25/97 KVN	Fixed HDD of secondary channel can't to do low level
;			format on some MB (e.g. VX)
;R07	10/29/96 STV	Fixed error HDD low level format sometimes system hang
;			while calculate interleave transfer rate  
;			HDD loformat stop only in function error write-protected
;R06	09/25/96 KVN	Fixed secondary channel drive low level format error
;R05	11/16/95 KVN	Remove all POST message to E000h
;R04	10/07/95 KVN	Disable HDD 32 bits access while execute preformat.
;R03	08/22/95 DNL	Kill duplicate codes
;R02	06/22/95 KVN	Fixed no warning when low level format error
;R01	06/14/95 KVN	Open Support_4_IDE feature become standard feature
;R00	06/13/95 KVN	Reduce Post_func_call and F000_call code size

		PAGE	56,132
		TITLE	LOFORMAT
;R03.386
.386P						;R03

ifndef	No_Support_4_IDE					;R01
Support_4_IDE		EQU	1				;R01
endif	;No_Support_4_IDE					;R01

		INCLUDE BIOS.CFG

		INCLUDE	COMMON.MAC
		INCLUDE	POST.MAC					

		INCLUDE	POST.EQU  

		INCLUDE	SETUP.EXT
		INCLUDE	USERINT.EXT

;R00		extrn	F000_func_end:Near	;128k
;R00		extrn	F000_VECT:Near		;128k
		extrn	F000_call_proc:near	;R00
ifndef	NO_HDD_LOW_LEVEL_FORMAT
		EXTRN	hd_install:NEAR
		extrn	No_Hdd_Str:Near
		extrn	Init_Hdd_Str:Near
		extrn	PREFORMAT_STR:Near
		extrn	main_key:Near
		extrn	CY_HD:Near
		extrn	func_command:Near
		extrn	format_key:Near
		extrn	format_warn:Near
		extrn	search_intl:Near
		extrn	cyl_head_same:Near
		extrn	func0_window:Near
		extrn	func1_window:Near
		extrn	func2_window:Near
		extrn	drive_err_msg:Near
		extrn   drive_write_protected_msg:Near	    ;R07
		extrn	test_intl_msg:Near
		extrn	CY_HD_LEN:ABS
		extrn	func_len:ABS
		extrn	FUNC_MAX:ABS
		extrn	for_key_len:ABS
		extrn	for_warn_len:ABS
		extrn	ch_same_len:ABS
		extrn	func0_len:ABS
		extrn	func1_len:ABS
		extrn	func2_len:ABS
		extrn	tmout_msg_len:ABS
		extrn	wprotect_msg_len:ABS     ;R07
		EXTRN	hrdskio:FAR
		EXTRN	gethparm:NEAR
		extrn	func_win_str:near
		extrn	clear_track_str:near
		extrn	F000_VECT:near		;R03
		extrn	RET_E_SEG:near		;R03
;R05		extrn	F000_Display_String:near	;R03
		extrn	Display_CS_String:near	;R05
		extrn	F000_Vreverse:near		;R03
		extrn	F000_Display_Char:near		;R03
		extrn	F000_VNormal:near		;R03
		extrn	F000_Cursor_On:near		;R03
endif	;NO_HDD_LOW_LEVEL_FORMAT

;R04 start
G_RAM		SEGMENT	USE16 AT 40H
		INCLUDE	G_RAM.INC
G_RAM		ENDS
;R04 end

EGROUP		GROUP	ECODE
ECODE		SEGMENT	USE16 PARA PUBLIC 'ECODE'
		ASSUME	CS:EGROUP,ES:EGROUP

ifndef	NO_HDD_LOW_LEVEL_FORMAT
;-------------- Low level format ------------------

		public	BASE_HIGH
		public	BASE_WIDE
		public	SECOND_ROW

c_reverse	=	67h
SECOND_ROW	=	8
BASE_WIDE	=	60
BASE_HIGH	=	16
BAD_WIDE	=	20
BAD_HIGH	EQU	BASE_HIGH
BAD_COL		EQU	BASE_WIDE
func_len_half		=	11
CY_HD_LEN_half		=	22
for_key_len_half	=	18
for_warn_len_half	=	26
ch_same_len_half	=	20
func1_len_half		=	12
tmout_msg_len_half	=	23
wprotect_msg_len_half	=	23	 ;R07

;----- color value ------
black		EQU	0
blue		EQU	1
green		EQU	2
cyan		EQU	3
red		EQU	4
magenta 	EQU	5
brown		EQU	6
lightgray	EQU	7
darkgray	EQU	8
lightblue	EQU	9
lightgreen	EQU	10
lightcyan	EQU	11
lightred	EQU	12
lightmagenta	EQU	13
yellow		EQU	14
white		EQU	15
;----- function key value -----
UP		EQU	4800h
DOWN		EQU	5000h
ESC_KEY 	EQU	11bh
CR_KEY		EQU	1c0dh
BACK_KEY	EQU	0e08h
BAD_BUFF_SIZE	EQU	500
BUFFER_SEG	EQU	3000h
SECTOR_MARK	EQU	0
READ_BUFFER	EQU	200h

BAD_TRACK_BUFF	EQU	200h+80*512		
;
;********************** variable area ********************
old_cursor	EQU	word ptr ss:[di]
func_posi	EQU	byte ptr ss:[di+2]
func_number	EQU	byte ptr ss:[di+3]
func_posi1	EQU	byte ptr ss:[di+4]
drive_num	EQU	byte ptr ss:[di+5]
interleave	EQU	byte ptr ss:[di+6]
auto_mark	EQU	byte ptr ss:[di+7]
start		EQU	byte ptr ss:[di+8]
DRIVE_CYL	EQU	word ptr ss:[di+9]
DRIVE_HEAD	EQU	byte ptr ss:[di+11]
DRIVE_PREC	EQU	word ptr ss:[di+12]
DRIVE_SEC	EQU	byte ptr ss:[di+14]
HD_COMMAND	EQU	byte ptr ss:[di+15]
PRINT_POSI	EQU	word ptr ss:[di+16]
BUFFER_ADDR	EQU	word ptr ss:[di+18]
BAD_BUFF_POINT	EQU	word ptr ss:[di+20]
TEMP_BYTE	EQU	byte ptr ss:[di+22]
;R06 VARIABLE_NUM	EQU	23
TEMP_BYTE0	EQU	byte ptr ss:[di+23]		;R06
Real_drive_num	EQU     byte ptr [bp+24]		;R06
VARIABLE_NUM    EQU     25				;R06
TEST_SECTOR_NUM	EQU	16
TEST_TIMES	EQU	20
bios_call	MACRO	function
		F000_call	function
		ENDM

;*** main function offset ***
main_func	DW	offset EGROUP:select_drive,offset func0_window
		DW	offset EGROUP:bad_track_list,offset func1_window
		DW	offset EGROUP:preformat,offset func2_window
DM_TABLE_MARK	DB	'MF  DISK TABLES'
dm_mark_len	EQU	$-offset DM_TABLE_MARK
bad_func	DW	offset EGROUP:auto_scan
		DW	offset EGROUP:add_track
		DW	offset EGROUP:mod_del_track
		DW	offset EGROUP:mod_del_track
		DW	offset EGROUP:clear_track
;
;------------------- main program ------------------
		Public	Low_format
Low_format	PROC	NEAR
		pusha
		push	es
		push	ds
;
		push	0f000h
		pop	ds
		xor	ax,ax
		mov	es,ax
		mov	ax,es:[4ch]			;interrupt 13h offset
		cmp	ax,offset hrdskio		;check HDD install?
		je	short Hdd_already_Install	; Yes,jump  	
;R08		mov	dx,TF_STATUS
;R08		in	al,dx
;R08		cmp	al,0ffh
;R08		je	short HDD_has_trouble
		mov	si,offset Init_Hdd_Str		; draw initiative box
;R03		F000_Call	Display_String
;R05		Call	F000_Display_String		;R03
		Call	Display_CS_String		;R05
		or	byte ptr FIXED_ERROR[bp],1	;skip REDIR_INT4146 procedure
		call	hd_install
Hdd_already_Install:						    	
		test	byte ptr FIXED_ERROR[bp],0feh	;HDD install fail?
		jz	short Hdd_Install_OK
HDD_has_trouble:
		mov	si,offset No_Hdd_Str		; draw confirm box...
;R03		F000_Call	Display_String
;R05		Call	F000_Display_String		;R03
		Call	Display_CS_String		;R05
		call	get_key				; get next key for pause
		jmp	Low_Fmt_Exit
Hdd_Install_OK:
		mov	ax,BUFFER_SEG
		mov	es,ax
		sub	sp,VARIABLE_NUM
		mov	di,sp
;
		mov	old_cursor,0
		mov	func_posi,0
		mov	func_number,0
		mov	func_posi1,0
		mov	interleave,0			;interleave initialize to auto
		mov	auto_mark,1			;auto scan initialize to 'No'
		mov	start,1 			;format start initialize to 'No'
		mov	bx,BAD_TRACK_BUFF
		mov	word ptr es:[bx],0ffffh 	;clear bad track table
		mov	BAD_BUFF_POINT,bx
		mov	print_posi,0
		mov	drive_num,0
		mov	real_drive_num,0		;R06
;R06		test	byte ptr FIXED_TYPE[BP],0f0h
		cmp	byte ptr HDD_EXIST_Flag[BP],0	;R06
		jnz	short drive_good
		jmp	exit
drive_good:
		call	main_window
		call	get_drive_parm
		mov	func_posi,0
		call	func_window
		mov	dh,4
		add	dh,func_posi
		mov	dl,31-func_len_half
		mov	cx,func_len-4
		call	reverse_bar
main_loop:
		call	get_key
		cmp	ax,UP
		jne	short next_key0
		mov	temp_byte,-1			;dec func_posi
		jmp	move_func
next_key0:
		cmp	ax,DOWN
		jne	short next_key1
		mov	temp_byte,1			;inc func_posi
move_func:
		mov	dh,4
		add	dh,func_posi
		mov	dl,31-func_len_half
		mov	cx,func_len-4
		call	reverse_bar
		mov	al,temp_byte
		add	func_posi,al
		cmp	func_posi,-1
		jne	short Not_top
		mov	func_posi,FUNC_MAX
Not_top:
		cmp	func_posi,FUNC_MAX+1
		jne	short Not_bottom
		mov	func_posi,0
Not_bottom:
		mov	dh,4
		add	dh,func_posi
		mov	dl,31-func_len_half
		mov	cx,func_len-4
		call	reverse_bar
		call	func_window
		jmp	main_loop
next_key1:
		cmp	ax,CR_KEY
		je	short 	low_cr
		jmp	next_key2
low_cr:
		mov	dh,4
		add	dh,func_posi
		mov	dl,31-func_len_half
		mov	cx,func_len-4
		call	reverse_bar
;
;R03		F000_Call	VREVERSE
		Call	F000_VREVERSE			;R03
		mov	al,func_len
		mov	cl,func_posi
		mul	cl
		lea	si,func_command
		add	si,ax
		add	si,3
		mov	dh,SECOND_ROW
		mov	dl,31-func_len_half
		mov	word ptr CURSOR_X[bp],dx
;R03		F000_Call	Display_String
;R05		Call	F000_Display_String		;R03
		Call	Display_CS_String		;R05
;
		mov	bl,func_posi
		xor	bh,bh
		shl	bx,1
		shl	bx,1
		call	word ptr cs:main_func[bx]
;
		mov	dh,SECOND_ROW
		mov	dl,31-func_len_half
		mov	word ptr CURSOR_X[bp],dx
		mov	cl,func_len-4
		mov	al,'Ä'
		mov	ah,1
		call	dup_char_disp
;
		mov	dh,4
		add	dh,func_posi
		mov	dl,31-func_len_half
		mov	cx,func_len-4
		call	reverse_bar
		jmp	main_loop
next_key2:
		cmp	ax,ESC_KEY
		je	short 	exit
		jmp	main_loop
exit:
		add	sp,VARIABLE_NUM
		mov	ax,BUFFER_SEG	;clear temper buffer to zero
		mov	es,ax
		mov	di,SECTOR_MARK
		xor	al,al
		mov	cx,BAD_TRACK_BUFF+(BAD_BUFF_SIZE+1)*3
		rep	stosb
;---- restore int 40h vector address to int 13h vector [bios]
		xor	ax,ax
		mov	es,ax
		mov	bx,100h 	;int 40h vector table offset
		mov	si,4ch		;int 13h vector table offset
		mov	ax,es:[bx]
		mov	es:[si],ax
		mov	ax,es:[bx+2]
		mov	es:[si+2],ax
;---- restore int 40h vector address to int 13h vector END
Low_Fmt_Exit:
;		lea	si,full_screen
;		F000_Call	Display_String
		pop	ds
		pop	es
		popa
		ret
Low_format	ENDP
;------------------- main program END
Display_Drive_num:
		mov	al,DRIVE_NUM
		cmp	al,1
		jne	short @F
		test	byte ptr FIXED_TYPE[BP],0fh	;Drive D present?
		jnz	short @F			;Yes,jump
		inc	al
@@:
		add	al,'C'
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
		ret
;
Select_drive	PROC	NEAR
		mov	al,DRIVE_NUM
		mov	temp_byte,al
		mov	al,REAL_DRIVE_NUM		;R06
		mov	temp_byte0,al			;R06
sel_drive:
		mov	dh,SECOND_ROW+3
		mov	dl,func0_len+12
		mov	cx,1
		call	reverse_bar
sel_loop:
		call	get_key
		cmp	al,'c'
		je	short 	is_ckey
		cmp	al,'C'
		jne	short comp_dkey
is_ckey:
		cmp	DRIVE_NUM,0
		je	short 	sel_loop
		mov	DRIVE_NUM,0
		test	byte ptr FIXED_TYPE[BP],0f0h
		jnz	short drive_exist
		mov	DRIVE_NUM,1
		jmp	sel_loop
drive_exist:
		push	offset EGROUP:sel_drive
sel_drive_disp:
		mov	dh,SECOND_ROW+3
		mov	dl,func0_len+12
		mov	word ptr CURSOR_X[bp],dx
;R03		F000_Call	VNORMAL
		Call	F000_VNORMAL			;R03
		call	Display_Drive_num			
		pop	bx
		jmp	bx
comp_dkey:
		cmp	al,'d'
		je	short 	is_dkey
		cmp	al,'D'
		je	short 	is_dkey
ifdef	Support_4_IDE
		cmp	al,'e'
		je	short 	is_ekey
		cmp	al,'E'
		je	short 	is_ekey
		cmp	al,'f'
		je	short 	is_fkey
		cmp	al,'F'
		je	short 	is_fkey
endif	;Support_4_IDE
		cmp	ax,CR_KEY
		je	sel_ret
		cmp	ax,ESC_KEY
		jne	short sel_loop
		mov	al,temp_byte
		mov	DRIVE_NUM,al
		mov	al,temp_byte0			;R06
		mov	REAL_DRIVE_NUM,al		;R06
		jmp	sel_ret
is_dkey:
		cmp	DRIVE_NUM,1
		je	short 	sel_loop
;R06		test	byte ptr FIXED_TYPE[BP],0fh
;R06		jz	short @F			
		mov	dl,1				;R06
		call	Search_Drive_Num		;R06
		jnc	short drive_exist		;R06
;R06		mov	DRIVE_NUM,1			
;R06		jmp	short drive_exist		
;R06@@:					
		jmp	sel_loop
ifdef	Support_4_IDE
is_ekey:
		cmp	DRIVE_NUM,2
		je	@B
		cmp	byte ptr CMOS_HDDE[bp],0
		je	@B
		mov	dl,2				;R06
		call	Search_Drive_Num		;R06
		jnc	short drive_exist		;R06
;R06		mov	DRIVE_NUM,2
;R06		test	byte ptr FIXED_TYPE[BP],0fh	;Drive D present?
;R06		jnz	short D_present			;Yes,jump
;R06		dec	DRIVE_NUM
;R06D_present:
;R06		jmp	drive_exist
is_fkey:
		cmp	DRIVE_NUM,3
		je	@B
		cmp	byte ptr CMOS_HDDF[bp],0
		je	@B
;R06		mov	DRIVE_NUM,3
;R06		jmp	drive_exist
		mov	dl,3				;R06
		call	Search_Drive_Num		;R06
		jnc	drive_exist			;R06
endif	;Support_4_IDE
sel_ret:
		push	offset EGROUP:sel_ret0
		jmp	sel_drive_disp
sel_ret0:
		mov	dh,BASE_HIGH-2
		mov	dl,39-CY_HD_LEN_half
		mov	word ptr CURSOR_X[bp],dx
;R03		F000_Call	VREVERSE
		Call	F000_VREVERSE			;R03
		call	Display_Drive_num			
		call	get_drive_parm
		ret
Select_drive	ENDP

;R06 start
; Input	 : dl = drive number
; Output : CF = 0 found match drive number
;		1 not found match drive number
Search_Drive_Num:
		push	ds
		push	G_RAM
		pop	ds
		mov	al,ds:[HDD_Drive_Port]
		pop	ds
		xor	cl,cl
@@:
		mov	ah,al
		and	ah,3
		cmp	dl,ah
		je	short Found_match_drive_num
		shr	al,2
		inc	cl
		cmp	cl,4
		jb	short @B
		stc
		jmp	short @F
Found_match_drive_num:
		mov	REAL_DRIVE_NUM,cl
		mov	DRIVE_NUM,dl
		clc
@@:
		ret
;R06 end

;
bad_track_list	PROC	NEAR
		mov	dh,SECOND_ROW+1
		mov	dl,1+30-func1_len_half
		mov	cx,21
		call	reverse_bar
		mov	func_posi1,0
bad_loop:
		call	get_key
		cmp	ax,UP
		jne	short bad_key0
		mov	temp_byte,-1
		jmp	bad_move_func
bad_key0:
		cmp	ax,DOWN
		jne	short bad_key1
		mov	temp_byte,1
bad_move_func:
		mov	dh,SECOND_ROW+1
		add	dh,func_posi1
		mov	dl,1+30-func1_len_half
		mov	cx,21
		call	reverse_bar
		mov	al,temp_byte
		add	func_posi1,al
		cmp	func_posi1,-1
		jne	short bad_up0
		mov	func_posi1,4
bad_up0:
		cmp	func_posi1,4
		jbe	short bad_down0
		mov	func_posi1,0
bad_down0:
		mov	dh,SECOND_ROW+1
		add	dh,func_posi1
		mov	dl,1+30-func1_len_half
		mov	cx,21
		call	reverse_bar
		jmp	bad_loop
bad_key1:
		cmp	ax,CR_KEY
		je	short 	bad_is_CR
		jmp	bad_key2
bad_is_CR:
		cmp	func_posi1,4
		jne	short not_clear_func
		jmp	print_bad_end
not_clear_func:
		mov	ax,0ffffh
		mov	dh,1
		call	comp_bad_table
		mov	si,BAD_BUFF_POINT
		mov	cx,12
		sub	si,36
		cmp	si,BAD_TRACK_BUFF
		jae	short not_head
		mov	ax,si
		mov	si,BAD_TRACK_BUFF
		add	ax,36
		sub	ax,BAD_TRACK_BUFF
		xor	dx,dx
		mov	cx,3
		div	cx
		mov	cx,ax
		or	cx,cx
		jnz	short not_head
		mov	print_posi,0
		jmp	print_bad_end
not_head:
		mov	print_posi,0
		call	print_bad_table
		mov	ax,BAD_BUFF_POINT
		sub	ax,BAD_TRACK_BUFF
		xor	dx,dx
		mov	cx,3
		div	cx
		cmp	al,12
		jbe	short posi_not_over
		mov	al,12
posi_not_over:
		xor	ah,ah
		mov	print_posi,ax
		cmp	func_posi1,0
		je	short 	print_bad_end
		cmp	func_posi1,1
		je	short 	print_bad_end
		dec	print_posi
		sub	BAD_BUFF_POINT,3
print_bad_end:
		mov	bl,func_posi1
		xor	bh,bh
		shl	bx,1
		call	word ptr cs:bad_func[bx]
		jmp	bad_loop
bad_key2:
		cmp	ax,ESC_KEY
		je	short 	bad_exit
		jmp	bad_loop
bad_exit:
		mov	dh,SECOND_ROW+1
		add	dh,func_posi1
		mov	dl,1+30-func1_len_half
		mov	cx,21
		call	reverse_bar
		ret
bad_track_list	ENDP
;
preformat	PROC	NEAR
		mov	dh,SECOND_ROW+2
		mov	dl,1+func2_len-18
		mov	cx,1
		call	reverse_bar
		mov	func_posi1,0
pre_loop:
		call	get_key
		cmp	ax,UP
		jne	short pre_key0
		cmp	func_posi1,0
		je	short 	pre_loop
		mov	temp_byte,-1
pre_move_func:
		mov	dh,SECOND_ROW+2
		add	dh,func_posi1
		mov	dl,1+func2_len-18
		mov	cx,1
		call	reverse_bar
		mov	al,temp_byte
		add	func_posi1,al
		mov	dh,SECOND_ROW+2
		add	dh,func_posi1
		mov	dl,1+func2_len-18
		mov	cx,1
		call	reverse_bar
		jmp	pre_loop
pre_key0:
		cmp	ax,CR_KEY
		jne	short pre_key1
		cmp	func_posi1,2
		jne	short down_func
exec_enter:
		cmp	start,1 	; is 'no'?
		je	short 	not_start	; Yes,return
;R03		F000_Call	VNORMAL
		Call	F000_VNORMAL			;R03
		or	byte ptr attribute[bp],BLINK	;Set blink
		lea	si,format_warn
;R03		F000_Call	Display_String
;R05		Call	F000_Display_String		;R03
		Call	Display_CS_String		;R05
		call	get_key
		push	ax
		mov	dh,BASE_HIGH-3
		mov	dl,30-for_warn_len_half
		mov	word ptr CURSOR_X[bp],dx
		mov	cl,for_warn_len
		mov	al,' '
		mov	ah,1
		call	dup_char_disp
		pop	ax
		cmp	al,'y'
		je	short 	f_start
		cmp	al,'Y'
		jne	short format_abort
f_start:
		call	format_proc
format_abort:
		mov	dh,SECOND_ROW+2
		add	dh,func_posi1
		mov	dl,1+func2_len-18
		mov	word ptr CURSOR_X[bp],dx
		mov	start,1
		mov	al,'N'
		jmp	disp00
not_start:
		jmp	pre_exit
pre_key1:
		cmp	ax,DOWN
		jne	short pre_key2
down_func:
		cmp	func_posi1,2
		jne	short next_func
		jmp	pre_loop
;		jmp	exec_enter
next_func:
		mov	temp_byte,1
		jmp	pre_move_func
pre_key2:
		cmp	ax,ESC_KEY
		jne	short pre_comp0
		jmp	pre_exit
pre_comp0:
		cmp	func_posi1,0
		jne	short pre_comp2
		cmp	al,'0'
		jb	short pre_ret00
		cmp	al,'8'
		ja	short pre_ret00
		sub	al,'0'
		cmp	interleave,al
		je	short 	down_func
		mov	dh,SECOND_ROW+2
		mov	dl,1+func2_len-18
		mov	word ptr CURSOR_X[bp],dx
		mov	interleave,al
		add	al,'0'
disp00:
		push	ax
;R03		F000_Call	VNORMAL
		Call	F000_VNORMAL			;R03
		pop	ax
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
		mov	dh,SECOND_ROW+2
		add	dh,func_posi1
		mov	dl,1+func2_len-18
		mov	cx,1
		call	reverse_bar
		jmp	down_func
pre_ret00:
		jmp	pre_loop
pre_comp2:
		cmp	func_posi1,1
		jne	short pre_comp3
		mov	dh,SECOND_ROW+3
		mov	dl,1+func2_len-18
		mov	word ptr CURSOR_X[bp],dx
		cmp	al,'y'
		je	short 	pre20
		cmp	al,'Y'
		je	short 	pre20
		cmp	al,'n'
		je	short 	pre21
		cmp	al,'N'
		je	short 	pre21
		jmp	pre_loop
pre20:
		cmp	auto_mark,0
		je	short 	jmp_downfunc
		mov	auto_mark,0
		mov	al,'Y'
		jmp	disp00
pre21:
		cmp	auto_mark,1
		je	short 	jmp_downfunc
		mov	auto_mark,1
		mov	al,'N'
		jmp	disp00
jmp_downfunc:
		jmp	down_func
pre_comp3:
		cmp	func_posi1,2
		jne	short pre_comp4
		mov	dh,SECOND_ROW+4
		mov	dl,1+func2_len-18
		mov	word ptr CURSOR_X[bp],dx
		cmp	al,'y'
		je	short 	pre30
		cmp	al,'Y'
		je	short 	pre30
		cmp	al,'n'
		je	short 	pre31
		cmp	al,'N'
		je	short 	pre31
		jmp	pre_loop
pre30:
		cmp	start,0
		je	short 	jmp_downfunc
		mov	start,0
		mov	al,'Y'
		jmp	disp00
pre31:
		cmp	start,1
		je	short 	jmp_downfunc
		mov	start,1
		mov	al,'N'
		jmp	disp00
pre_comp4:
		jmp	pre_loop
;
pre_exit:
		call	main_window
		call	func_window
		mov	si,BAD_TRACK_BUFF
		mov	print_posi,0
		mov	cx,12
		call	print_bad_table
		ret
preformat	ENDP
;
format_proc	PROC	NEAR
		cld
;R04 start
		push	ds
		push	G_RAM
		pop	ds
		assume	DS:G_RAM
		and	byte ptr G_RAM:[POST_FLAG],not (IDE_CH0_32BIT_MODE or IDE_CH1_32BIT_MODE)
		pop	ds
;R04 end
		cmp	interleave,0
		je	short 	auto_test_intl
		jmp	inter_end
auto_test_intl:
;------ auto test optimize interleave value
		lea	si,search_intl
;R03		F000_Call	Display_String
;R05		Call	F000_Display_String		;R03
		Call	Display_CS_String		;R05
		lea	si,test_intl_msg
;R03		F000_Call	Display_String
;R05		Call	F000_Display_String		;R03
		Call	Display_CS_String		;R05
		mov	ax,DRIVE_CYL
		push	ax
		mov	al,DRIVE_HEAD
		push	ax
		mov	DRIVE_CYL,1
		mov	DRIVE_HEAD,1
		mov	interleave,1
		mov	ax,0ffffh
		mov	dx,0ffffh
auto_intl_loop:
		push	ax
		push	dx
		call	mapping_intl
		mov	bx,SECTOR_MARK
		xor	dh,dh
;R06		mov	dl,DRIVE_NUM
		mov	dl,REAL_DRIVE_NUM		;R06
		add	dl,80h
		mov	cx,1
		mov	ah,5		;format command
		int	13h
		jnc	Drive_OK	;no error
		pop	ax
		pop	ax
		pop	ax
		mov	DRIVE_HEAD,al
		pop	ax
		mov	DRIVE_CYL,ax
		jmp	drive_err_proc
Drive_OK:
		call	test_intl_speed
		pop	dx
		pop	ax
		cmp	dx,bx
		jb	short next_intl
		cmp	dx,bx
		ja	short save_intl
		cmp	ax,cx
		jbe	short next_intl
save_intl:
		mov	ax,cx
		mov	dx,bx
		mov	al,interleave
		mov	temp_byte,al
next_intl:
		inc	interleave
		cmp	interleave,4
		ja	short auto_intl_over
		jmp	auto_intl_loop
auto_intl_over:
		mov	al,temp_byte
		mov	interleave,al
;R03		F000_Call	VNORMAL
		Call	F000_VNORMAL			;R03
		mov	dh,SECOND_ROW+2
		mov	dl,1+func2_len-18
		mov	word ptr CURSOR_X[bp],dx
		mov	al,interleave
		add	al,'0'
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
		pop	ax
		mov	DRIVE_HEAD,al
		pop	ax
		mov	DRIVE_CYL,ax
;------ auto test optimize interleave value END
inter_end:
		call	mapping_intl
		mov	HD_COMMAND,5	;format command
		mov	ax,SECTOR_MARK
		mov	BUFFER_ADDR,ax
		call	exec_int13
format_loop:
		jnc	format_OK	;drive good jump
		pop	bx
		jmp	drive_err_proc
format_OK:
		or	si,si
		jz	short 	cyln_end
		jmp	format_ret
cyln_end:
		or	dh,dh
		jz	short 	head_end
		jmp	format_ret
head_end:
;*** write bad track to cylinder 0, head 0, sector 2
		mov	si,BAD_TRACK_BUFF
		mov	bx,READ_BUFFER
		xor	dx,dx
		xor	cx,cx
save_loop:
		cmp	word ptr es:[si],0ffffh
		je	short 	save_over
		mov	ax,word ptr es:[si]
		mov	word ptr es:[bx],ax
		add	dx,ax
		mov	al,byte ptr es:[si+2]
		mov	byte ptr es:[bx+2],al
		xor	ah,ah
		add	dx,ax
		add	si,3
		add	bx,6
		inc	cx
		jmp	save_loop
save_over:
		mov	bx,READ_BUFFER
		add	bx,0bfah
		mov	es:[bx],cx
		or	cx,cx
		jz	short save_bad_track
		add	dx,cx
		add	bx,2
		lea	si,cs:dm_table_mark
		mov	cx,dm_mark_len
mark_loop:
		mov	al,cs:[si]
		mov	es:[bx],al
		inc	si
		inc	bx
		loop	mark_loop
		mov	bx,READ_BUFFER
		add	bx,0bfeh
		mov	cx,5f0eh
		sub	cx,dx
		mov	es:[bx],cx
save_bad_track:
		mov	ah,3			;write bad track to cylinder 0 head 0 sector 1-17
		mov	al,DRIVE_SEC
		dec	al
		mov	bx,READ_BUFFER
		mov	cx,2
		xor	dh,dh
;R06		mov	dl,DRIVE_NUM
		mov	dl,REAL_DRIVE_NUM		;R06
		add	dl,80h
		int	13h
;*** write bad track to cylinder 0, head 0, sector 2 END
format_ret:
		ret
format_proc	ENDP
;
;********************* drive error procedure *********************
;	When drive occur any error. You can call this procedure
;     then display warning message on screen.
;
;  input : NONE
;  output: NONE
;*****************************************************************
drive_err_proc	PROC	NEAR
;R03		F000_Call	VNORMAL
		push    ax	     ;R07
		Call	F000_VNORMAL			;R03
		or	byte ptr attribute[bp],BLINK	;Set blink
;R07 start
		pop     ax   
	     	push    ax
		cmp     ah,3 	     
		jne	@f
		lea	si,drive_write_protected_msg
		jmp     not_write_protect
@@:		
;R07 end
		lea	si,drive_err_msg
;R03		F000_Call	Display_String
;R05		Call	F000_Display_String		;R03

not_write_protect:		   			 ;R07
		Call	Display_CS_String		;R05
		call	get_key				;pause
		mov	dh,BASE_HIGH-1
;R07 start
		pop     ax
		cmp     ah,3
 		jne	@f
		mov	dl,30-wprotect_msg_len_half
		mov	cl,wprotect_msg_len
		jmp	show_msg
@@:		mov	dl,30-tmout_msg_len_half
		mov	cl,tmout_msg_len
;R07 end
;R07		mov	dl,30-tmout_msg_len_half
show_msg:					       ;R07
		mov	word ptr CURSOR_X[bp],dx
;R07		mov	cl,tmout_msg_len
		mov	al,'Í'
		mov	ah,1
		call	dup_char_disp
		ret
drive_err_proc	ENDP
;
;******************** mapping interleave ************************
;	This procedure can map any interleave number. You can
;     input any interleave number to 'interleave' then map
;     interleave table to SECTOR_MARK buffer.
;
;  input : interleave
;  output: NONE
;****************************************************************
mapping_intl	PROC	NEAR
		mov	ax,100h 	;from first sector start
		xor	dx,dx
		xor	cx,cx
sector_loop:
		shl	dx,1
		mov	si,SECTOR_MARK
		add	si,dx
		mov	es:[si],ax
		shr	dx,1
		add	dl,interleave
		cmp	dl,DRIVE_SEC
		jb	short not_addr_over
		inc	cx
		mov	dx,cx
not_addr_over:
		inc	ah
		cmp	ah,DRIVE_SEC
		jbe	short sector_loop
		mov	dl,DRIVE_SEC
		shl	dx,1
		mov	si,SECTOR_MARK
		add	si,dx
;
		mov	cx,200h 	;mark area total is 512 bytes
		add	cx,SECTOR_MARK
		sub	cx,si
		jc	mark_OK
		mov	al,0ddh 	;don't care mark
store_mark_loop:
		mov	es:[si],al
		inc	si
		loop	store_mark_loop
mark_OK:
		ret
mapping_intl	ENDP
;
;******************* execute int 13h function ********************
;	Execute int 13h all function. Only input HD_COMMAND that
;     you want to call function	number.
;
;  input : HD_COMMAND
;  output: NONE
;*****************************************************************
exec_int13	PROC	NEAR
;*** clear keyboard buffer
clear_key_loop:
		mov	ah,1
		int	16h
		jz	short 	esc_key_msg
		xor	ah,ah
		int	16h
		jmp	clear_key_loop
;*** clear keyboard buffer END
esc_key_msg:
;R03		F000_Call	VNORMAL
		Call	F000_VNORMAL			;R03
		or	byte ptr attribute[bp],BLINK	;Set blink
		lea	si,format_key
;R03		F000_Call	Display_String
;R05		Call	F000_Display_String		;R03
		Call	Display_CS_String		;R05
;R03		F000_Call	VREVERSE
		Call	F000_VREVERSE			;R03
		mov	si,DRIVE_CYL
cyl_loop:
		dec	si
		mov	dh,BASE_HIGH-2
		mov	dl,54-CY_HD_LEN_half
		mov	word ptr CURSOR_X[bp],dx
		mov	ax,si
		mov	bx,4
		call	disp_number
		mov	ax,si
		mov	cl,6
		shl	ah,cl
		xchg	ah,al
		mov	cx,ax
		or	cx,1			;sector number = 1
		mov	dh,DRIVE_HEAD
;R06		mov	dl,DRIVE_NUM
		mov	dl,REAL_DRIVE_NUM		;R06
		add	dl,80h
head_loop:
		dec	dh
		mov	ah,BASE_HIGH-2
		mov	al,68-CY_HD_LEN_half
		mov	word ptr CURSOR_X[bp],ax
		push	dx
		mov	al,dh
		xor	ah,ah
		mov	bx,2
		call	disp_number
		cmp	HD_COMMAND,5		;is format command
		jne	short head_start		;No, jump head_start
		mov	ax,si
		mov	dl,dh
		xor	dh,dh
		call	comp_bad_table
		jnc	bad_sector
		cmp	auto_mark,0		;compare is auto mark bad tracks?
		jne	short not_auto_mark		;No, jump not_auto_mark
		mov	ah,4			;read verify command
		mov	al,DRIVE_SEC
		pop	dx
		push	dx
		int	13h
		jnc	not_auto_mark		;not bad track jump
		mov	ax,si
		mov	dl,dh
		call	store_cyl_head
		inc	print_posi
		add	BAD_BUFF_POINT,3
		mov	bx,BAD_BUFF_POINT
		mov	word ptr es:[bx],0ffffh
		jmp	bad_sector
not_auto_mark:
		xor	al,al
		jmp	sec_mark_over
bad_sector:
		mov	al,80h
sec_mark_over:
		mov	dl,DRIVE_SEC
		mov	bx,SECTOR_MARK
set_sec_loop:
		mov	es:[bx],al
		add	bx,2
		dec	dl
		jnz	short set_sec_loop
head_start:
		pop	dx
		mov	bx,BUFFER_ADDR
		mov	ah,HD_COMMAND
		mov	al,DRIVE_SEC
		cmp	ah,4			;compare is verify cylinder 0?
		jne	short not_vrfy_cyl0
		test	cx,0ffc0h		;is cylinder = 0?
		jnz	short not_vrfy_cyl0
		or	dh,dh	  		;is head = 0?
		jnz	short not_vrfy_cyl0
		mov	al,1			;only verify sector 1
not_vrfy_cyl0:
		int	13h
		jnc	function_OK
		cmp	ah,3		;write protect?
		je	short 	drive_error
;R07	start
;		cmp	ah,20h		;controller failure?
;		je	short 	drive_error
;		cmp	ah,80h		;drive time out?
;		je	short 	drive_error
;		cmp	ah,0aah		;drive not ready?
;		je	short 	drive_error
;R07	end
		cmp	HD_COMMAND,4
;R02		jne	short function_OK
;R07		jne	short drive_error			;R02
		jne	short function_OK				;R07
		mov	ah,10h
drive_error:
		stc
		pop	bx
		push	offset EGROUP:function_OK
		jmp	bx
function_OK:
		mov	ah,1
		int	16h
		jz	short 	next_head		;Not press any key jump
		xor	ah,ah
		int	16h
		cmp	ax,ESC_KEY		;compare is 'ESC'?
		je	short 	format_over		;Yes,break
next_head:
		or	dh,dh
		jz	short 	next_cyl
		jmp	head_loop
next_cyl:
		or	si,si
		jz	short 	format_over
		jmp	cyl_loop
format_over:
		push	si
		push	dx
		mov	dh,BASE_HIGH-1
		mov	dl,30-for_key_len_half
		mov	word ptr CURSOR_X[bp],dx
		mov	cl,for_key_len
		mov	al,'Í'
		mov	ah,1
		call	dup_char_disp
		pop	dx
		pop	si
		clc
		ret
exec_int13	ENDP
;
;**************** auto scan bad track *************************
;	Auto scan bad track with int 13h read verify function
;     on current drive all cylinder and head. If sector error
;     store bad track to bad track buffer. If drive error then
;     call drive error procedure.
;
;  input : NONE
;  output: NONE
;**************************************************************
auto_scan	PROC	NEAR
		call	clear_track
		mov	HD_COMMAND,4	;verify command
		call	exec_int13
scan_loop:
		jnc	verify_OK
		cmp	ah,10h
		je	short 	sector_error
		pop	bx
		jmp	drive_err_proc
sector_error:
		push	dx
		mov	ax,si
		mov	dl,dh
		call	store_cyl_head
		jc	bad_overflow0
		inc	print_posi
		add	BAD_BUFF_POINT,3
		mov	bx,BAD_BUFF_POINT
		mov	word ptr es:[bx],0ffffh
bad_overflow0:
		pop	dx
		pop	bx
		push	offset EGROUP:scan_loop
		jmp	bx
verify_OK:
		ret
auto_scan	ENDP
;
;*********** addition a track to bad track buffer ************
;	Get a track number then stroe in bad track buffer.
;     If buffer is overflow then set carry flag.
;
;  input : NONE
;  output: C flag
;*************************************************************
add_track	PROC	NEAR
;
add_track_loop:
		call	get_cyl_head
		jc	add_ret
		mov	dh,1
		call	comp_bad_table
		jnc	add_track_loop		;track already exist jump
		call	store_cyl_head
		jc	add_ret
		inc	print_posi
		add	BAD_BUFF_POINT,3
		mov	si,BAD_BUFF_POINT
		mov	word ptr es:[si],0ffffh
		jmp	add_track_loop
add_ret:
		ret
add_track	ENDP
;
;**************** input a cylinder & head number *******************
;	Get a track number and display on fix cursor position then
;     output ax and dl.
;  input : NONE
;  output: ax = cylinder
;	   dl = head
;*******************************************************************
get_cyl_head:
		mov	dh,BASE_HIGH-2
		mov	dl,54-CY_HD_LEN_half
		mov	word ptr CURSOR_X[bp],dx
		mov	ax,DRIVE_CYL
		mov	dl,4
		call	input_number
		jnc	get_head
		mov	dh,BASE_HIGH-2
		mov	dl,54-CY_HD_LEN_half
		mov	word ptr CURSOR_X[bp],dx
		xor	ax,ax
		mov	bx,4
		call	disp_number
		jmp	get_ret
get_head:
		push	ax
		mov	dh,BASE_HIGH-2
		mov	dl,68-CY_HD_LEN_half
		mov	word ptr CURSOR_X[bp],dx
		mov	al,DRIVE_HEAD
		xor	ah,ah
		mov	dl,2
		call	input_number
		jc	get_ret0
		mov	dl,al
		pop	ax
		ret
get_ret0:
		pop	ax
		mov	dh,BASE_HIGH-2
		mov	dl,68-CY_HD_LEN_half
		mov	word ptr CURSOR_X[bp],dx
		xor	ax,ax
		mov	bx,2
		call	disp_number
get_ret:
		stc
		ret
;
;*********************** store bad track ************************
;    Store a bad track in bad track buffer. When buffer is full
;  set carry flag.
;  input : ax = cylinder
;	   dl = head
;  output: C flag
;****************************************************************
store_cyl_head	PROC	NEAR
		push	si
		push	cx
		cmp	print_posi,BAD_BUFF_SIZE
		jb	short bad_not_over
		stc
		jmp	store_ret
bad_not_over:
		mov	si,BAD_BUFF_POINT
		mov	es:[si+2],dl
		mov	es:[si],ax
		cmp	print_posi,BAD_HIGH-4
		jb	short print_not_over
		mov	print_posi,0
		mov	cx,11
		sub	si,33
		call	print_bad_table
		add	si,33
		add	print_posi,BAD_HIGH-5
print_not_over:
		mov	cx,1
		call	print_bad_table
;R03		F000_Call	VREVERSE
		Call	F000_VREVERSE			;R03
		clc
store_ret:
		pop	cx
		pop	si
		ret
store_cyl_head	ENDP
;
;************************ modify & delete procedure ***********************
;    Move cursor on bad track table and scroll the bad track table on
;  screen,modify or delete a bad track on current cursor bad track.
;
;  input : NONE
;  output: NONE
;**************************************************************************
mod_del_track	PROC	NEAR
		mov	si,BAD_BUFF_POINT
		cmp	word ptr es:[si],0ffffh
		jne	short table_exist
		ret
table_exist:
		call	reverse_bad_bar
mod_del_loop:
		call	get_key
		cmp	ax,UP
		jne	short mod_key0
		cmp	print_posi,0
		je	short 	mod_is_top
		call	reverse_bad_bar
		dec	print_posi
		call	reverse_bad_bar
		sub	BAD_BUFF_POINT,3
		jmp	mod_del_loop
mod_is_top:
		mov	si,BAD_BUFF_POINT
		cmp	si,BAD_TRACK_BUFF
		je	short 	mod_del_loop
		call	reverse_bad_bar
		mov	cx,12
		sub	BAD_BUFF_POINT,3
		mov	si,BAD_BUFF_POINT
		call	print_bad_table
		call	reverse_bad_bar
		jmp	mod_del_loop
mod_key0:
		cmp	ax,DOWN
		jne	short mod_key1
		mov	si,BAD_BUFF_POINT
		cmp	word ptr es:[si+3],0ffffh
		je	short 	mod_del_loop
		cmp	print_posi,11
		je	short 	mod_is_botm
		call	reverse_bad_bar
		inc	print_posi
		call	reverse_bad_bar
		add	BAD_BUFF_POINT,3
		jmp	mod_del_loop
mod_is_botm:
		add	BAD_BUFF_POINT,3
		mov	si,BAD_BUFF_POINT
		cmp	word ptr es:[si],0ffffh
		je	short 	not_scroll
		call	reverse_bad_bar
		mov	print_posi,0
		sub	si,33
		mov	cx,12
		call	print_bad_table
		mov	print_posi,11
		call	reverse_bad_bar
not_scroll:
		jmp	mod_del_loop
mod_key1:
		cmp	ax,CR_KEY
		je	short 	mod_del_exec
		jmp	mod_key2
mod_del_exec:
		cmp	func_posi1,2
		jne	short is_del_func
		call	reverse_bad_bar
		call	get_cyl_head
		jc	not_modify
		mov	dh,1
		mov	si,BAD_BUFF_POINT
		call	comp_bad_table
		mov	BAD_BUFF_POINT,si
		jnc	not_modify
		call	store_cyl_head
not_modify:
		call	reverse_bad_bar
		jmp	mod_del_loop
is_del_func:
		mov	si,BAD_BUFF_POINT
del_loop:
		cmp	word ptr es:[si],0ffffh
		je	short 	del_func_over
		mov	ax,es:[si+3]
		mov	es:[si],ax
		add	si,2
		mov	al,es:[si+3]
		mov	es:[si],al
		inc	si
		jmp	del_loop
del_func_over:
		push	si
		lea	si,clear_track_str
;R03		F000_Call	Display_String
;R05		Call	F000_Display_String		;R03
		Call	Display_CS_String		;R05
		pop	si
		sub	si,3
		cmp	si,BAD_BUFF_POINT
		jne	short not_table_botm
		cmp	si,BAD_TRACK_BUFF
		jne	short table_not_empty
		mov	print_posi,0
		ret
table_not_empty:
		sub	BAD_BUFF_POINT,3
		cmp	print_posi,0
		je	short 	not_table_botm
		dec	print_posi
not_table_botm:
		mov	si,BAD_BUFF_POINT
		mov	ax,print_posi
		xor	dx,dx
		mov	cx,3
		mul	cx
		sub	si,ax
		push	print_posi
		mov	print_posi,0
		mov	cx,12
		call	print_bad_table
		pop	print_posi
next_del:
		call	reverse_bad_bar
		jmp	mod_del_loop
mod_key2:
		cmp	ax,ESC_KEY
		je	short 	mod_ret
		jmp	mod_del_loop
mod_ret:
		call	reverse_bad_bar
		ret
mod_del_track	ENDP
;
reverse_bad_bar:
		mov	dx,3
		add	dx,print_posi
		xchg	dh,dl
		mov	dl,BAD_COL+2
		mov	cx,BAD_WIDE-4
		call	reverse_bar
		ret
;
clear_track	PROC	NEAR
		mov	si,BAD_TRACK_BUFF
		mov	BAD_BUFF_POINT,si
		cmp	word ptr es:[si],0ffffh
		je	short 	not_clear_scrn
		lea	si,clear_track_str
;R03		F000_Call	Display_String
;R05		Call	F000_Display_String		;R03
		Call	Display_CS_String		;R05
not_clear_scrn:
		mov	print_posi,0
		mov	si,BAD_TRACK_BUFF
		mov	word ptr es:[si],0ffffh 	;clear bad track table
		ret
clear_track	ENDP
;
;***************** print bad table *********************
; input : cx = print counter
;	  si = start offset
;*******************************************************
print_bad_table PROC	NEAR
		push	si
;R03		F000_Call	VNORMAL
		Call	F000_VNORMAL			;R03
		mov	dx,3
		add	dx,print_posi
		xchg	dh,dl
print_loop:
		cmp	word ptr es:[si],0ffffh
		je	short 	print_bad_ret
		push	cx
		push	dx
		mov	dl,BAD_COL+2
		mov	word ptr CURSOR_X[bp],dx
		xor	dx,dx
		mov	ax,si
		sub	ax,BAD_TRACK_BUFF
		mov	cx,3
		div	cx
		mov	bx,4
		call	disp_number
		pop	dx
		push	dx
		mov	dl,BAD_COL+8
		mov	word ptr CURSOR_X[bp],dx
		mov	ax,es:[si]
		mov	bx,4
		call	disp_number
		pop	dx
		push	dx
		mov	dl,BAD_COL+14
		mov	word ptr CURSOR_X[bp],dx
		add	si,2
		mov	al,es:[si]
		xor	ah,ah
		mov	bx,2
		call	disp_number
		inc	si
		pop	dx
		inc	dh
		pop	cx
		loop	print_loop
print_bad_ret:
		pop	si
		ret
print_bad_table ENDP
;
;***************** compare bad table *********************
; input : ax = cylinder
;	  dl = head
;	  dh = 0 not display message
;	       1 display message
; output: if not same set carry flag
;	  if found same clear carry flag
;*******************************************************
comp_bad_table	PROC	NEAR
		push	si
		push	cx
		mov	si,BAD_TRACK_BUFF
bad_comp_loop:
		cmp	word ptr es:[si],0ffffh
		jne	short not_table_end
		stc
		jmp	comp_bad_ret
not_table_end:
		cmp	ax,es:[si]
		jne	short bad_comp_next
		cmp	dl,es:[si+2]
		jne	short bad_comp_next
		or	dh,dh
		jz	short 	not_show_msg
		push	si
;R03		F000_Call	VNORMAL
		Call	F000_VNORMAL			;R03
		or	byte ptr attribute[bp],BLINK	;Set blink
		lea	si,cyl_head_same
;R03		F000_Call	Display_String
;R05		Call	F000_Display_String		;R03
		Call	Display_CS_String		;R05
		mov	word ptr CURSOR_STAT[bp],0
;R03		F000_Call	CURSOR_OFF
		Call	F000_CURSOR_OFF			;R03
		call	get_key 		;pause
		mov	dh,BASE_HIGH-1
		mov	dl,30-ch_same_len_half
		mov	word ptr CURSOR_X[bp],dx
		mov	cl,ch_same_len
		mov	al,'Í'
		mov	ah,1
		call	dup_char_disp
		pop	si
not_show_msg:
		clc
comp_bad_ret:
		mov	BAD_BUFF_POINT,si
		pop	cx
		pop	si
		ret
bad_comp_next:
		add	si,3
		jmp	bad_comp_loop
comp_bad_table	ENDP
;
main_window	PROC	NEAR
		cli						
		lea	si,preformat_str
;R03		F000_Call	Display_String
;R05		Call	F000_Display_String		;R03
		Call	Display_CS_String		;R05
		mov	cx,FUNC_MAX+3
sp_line_loop1:
		push	cx
		add	cl,2
		mov	dh,cl
		mov	dl,19-func_len_half
		mov	word ptr CURSOR_X[bp],dx
		mov	cl,func_len+21
		mov	al,'°'
		mov	ah,1
		call	dup_char_disp
		pop	cx
		loop	sp_line_loop1
		mov	dh,SECOND_ROW
		mov	dl,1
		mov	word ptr CURSOR_X[bp],dx
		mov	cl,BASE_WIDE-2
		mov	al,'Ä'
		mov	ah,1
		call	dup_char_disp
;R03		F000_Call	VNORMAL
		Call	F000_VNORMAL			;R03
		lea	si,func_command
		mov	cx,FUNC_MAX
		inc	cx
disp_func_loop:
		push	cx
		push	si
;R03		F000_Call	Display_String
;R05		Call	F000_Display_String		;R03
		Call	Display_CS_String		;R05
		pop	si
		add	si,func_len
		pop	cx
		loop	disp_func_loop
		sti						
		ret
main_window	ENDP
;
func_window	PROC	NEAR
		cli						
		lea	si,func_win_str
;R03		F000_Call	Display_String
;R05		Call	F000_Display_String		;R03
		Call	Display_CS_String		;R05
		lea	si,cs:main_func
		add	si,2
		mov	al,func_posi
		xor	ah,ah
		shl	ax,1
		shl	ax,1
		add	si,ax
		mov	si,cs:[si]
;R03		F000_Call	Display_String
;R05		Call	F000_Display_String		;R03
		Call	Display_CS_String		;R05
;
		cmp	func_posi,0
		jne	short next_func0
		mov	dh,SECOND_ROW+3
		mov	dl,func0_len+12
		mov	word ptr CURSOR_X[bp],dx
;R03		F000_Call	VNORMAL
		Call	F000_VNORMAL			;R03
		call	Display_Drive_num			
		jmp	func_ret
next_func0:
		cmp	func_posi,2
		je	short 	next_func2
		jmp	func_ret
next_func2:
		mov	dh,SECOND_ROW+2
		mov	dl,1+func2_len-18
		mov	word ptr CURSOR_X[bp],dx
;R03		F000_Call	VNORMAL
		Call	F000_VNORMAL			;R03
		mov	al,interleave
		add	al,'0'
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
		mov	dh,SECOND_ROW+3
		mov	dl,1+func2_len-18
		mov	word ptr CURSOR_X[bp],dx
;R03		F000_Call	VNORMAL
		Call	F000_VNORMAL			;R03
		mov	al,'Y'
		cmp	auto_mark,0
		je	short 	is_yes0
		mov	al,'N'
is_yes0:
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
		mov	dh,SECOND_ROW+4
		mov	dl,1+func2_len-18
		mov	word ptr CURSOR_X[bp],dx
;R03		F000_Call	VNORMAL
		Call	F000_VNORMAL			;R03
		mov	al,'Y'
		cmp	start,0
		je	short 	is_yes1
		mov	al,'N'
is_yes1:
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
func_ret:
		sti						
		ret
func_window	ENDP
;
;********** reverse main function bar *********
;input :  dh - row
;	  dl - column
;	  cx - wide
;output:  reverse function bar
;**********************************************
reverse_bar	PROC	NEAR
		cli						
		push	cx
		mov	ah,2
		xor	bh,bh
		int	10h
		mov	ah,8
		xor	bh,bh
		int	10h
		cmp	byte ptr MONOCHROME[bp],0	;is mono
		jne	short is_color		;No,jump
		test	ah,7
		jz	short 	is_color
		or	ah,17h
		and	ah,9fh
is_color:
		mov	bl,ah
		xor	bl,c_reverse
		mov	ah,9
		mov	cx,1
		int	10h
		inc	dl
		pop	cx
		loop	reverse_bar
		mov	word ptr CURSOR_STAT[bp],0
;R03		F000_Call	CURSOR_OFF
		Call	F000_CURSOR_OFF		;R03
		sti						
		ret
reverse_bar	ENDP
;
;********** Display number to screen *********
;input :  ax = number
;	  bx = digital (1 - 4)
;output:  display ax to Decimal number at now position
;**********************************************
disp_number	PROC	NEAR
		push	si
		push	di
		push	cx
		push	dx
		push	ax
		mov	si,10
		xor	dx,dx
		mov	ax,1
dig_loop:
		dec	bl
		jz	short 	dig_end
		mul	si
		jmp	dig_loop
dig_end:
		mov	cx,ax
		pop	ax
		xor	di,di
disp_loop:
		xor	dx,dx
		div	cx
		or	ax,ax
		jnz	short disp_num0
		cmp	cx,1
		je	short 	disp_num0
		or	di,di
		jnz	short disp_num0
		mov	al,' '
		jmp	disp_num1
disp_num0:
		mov	di,1
		add	al,'0'
disp_num1:
		push	cx
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
		pop	cx
		cmp	cx,1
		je	short 	disp_ret
		mov	ax,cx
		mov	cl,10
		div	cl
		mov	cx,ax
		mov	ax,dx
		jmp	disp_loop
disp_ret:
		pop	dx
		pop	cx
		pop	di
		pop	si
		ret
disp_number	ENDP
;
;*************** Input number *****************
;input :  ax = maximum number
;	  dl = digital (1 - 4)
;output:  get a number to ax
;**********************************************
input_number	PROC	NEAR
		push	di
;R03		F000_Call	VREVERSE
		Call	F000_VREVERSE			;R03
		mov	si,ax
		mov	bl,dl
input_start:
		mov	dx,word ptr CURSOR_X[bp]	;save now cursor position
		xor	di,di
		mov	al,'0'
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
		mov	cl,bl
		dec	cl
		mov	al,' '
		xor	ah,ah
		call	dup_char_disp
		mov	word ptr CURSOR_X[bp],dx
;R03		F000_Call	CURSOR_ON
		Call	F000_CURSOR_ON			;R03
		mov	dl,bl
input_loop:
		call	get_key
		cmp	ax,ESC_KEY
		jne	short inext_key
		mov	word ptr CURSOR_STAT[bp],0
;R03		F000_Call	CURSOR_OFF
		Call	F000_CURSOR_OFF		;R03
		stc
		jmp	input_ret
inext_key:
		cmp	ax,CR_KEY
		jne	short inext_key0
		cmp	si,di
		ja	short input_OK
		mov	ax,word ptr CURSOR_X[bp]
		add	al,dl
		sub	al,bl
		mov	word ptr CURSOR_X[bp],ax
		jmp	input_start
input_OK:
		clc
		jmp	input_ret
inext_key0:
		cmp	ax,BACK_KEY
		jne	short check_num
		cmp	dl,bl
		jae	short input_loop
		inc	dl
		push	dx
		mov	ax,di
		xor	dx,dx
		mov	cx,10
		div	cx
		mov	di,ax
		mov	dx,word ptr CURSOR_X[bp]
		dec	dl
		push	dx
		mov	word ptr CURSOR_X[bp],dx
		mov	al,' '
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
		pop	dx
		mov	word ptr CURSOR_X[bp],dx
;R03		F000_Call	CURSOR_ON
		Call	F000_CURSOR_ON			;R03
		pop	dx
go_inputloop:
		jmp	input_loop
check_num:
		or	dl,dl
		jz	short 	go_inputloop
		cmp	al,'0'
		jb	short go_inputloop
		cmp	al,'9'
		ja	short go_inputloop
		push	ax
		push	dx
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
;R03		F000_Call	CURSOR_ON
		Call	F000_CURSOR_ON			;R03
		mov	ax,di
		xor	dx,dx
		mov	cx,10
		mul	cx
		pop	dx
		mov	di,ax
		pop	ax
		xor	ah,ah
		sub	al,'0'
		add	di,ax
		dec	dl
		jmp	input_loop
input_ret:
		mov	ax,di
		pop	di
		ret
input_number	ENDP
;
;**************** get a key **************
;input : none
;output: al = key code
;*****************************************
get_key 	PROC	NEAR
		mov	ah,1
		int	16h
		jz	short 	get_key
		xor	ah,ah
		int	16h
		ret
get_key		ENDP
;
;******************** get drive parameter ****************************
;    Get current drive parameter. The parameter include cylinder,head,
;  precomp and sector number.
;
; input : DRIVE_NUM = drive number
; output: DRIVE_CYL = drive cylinder
;*********************************************************************
get_drive_parm	PROC	NEAR
		push	es
		mov	dl,DRIVE_NUM
		xor	al,al
;R03		F000_Call	GETHPARM
		Call	F000_GETHPARM			;R03
		mov	DRIVE_CYL,ax
		mov	al,2
;R03		F000_Call	GETHPARM
		Call	F000_GETHPARM			;R03
		mov	DRIVE_HEAD,al
		mov	al,5
;R03		F000_Call	GETHPARM
		Call	F000_GETHPARM			;R03
		mov	DRIVE_PREC,ax
		mov	al,0eh
;R03		F000_Call	GETHPARM
		Call	F000_GETHPARM			;R03
		mov	DRIVE_SEC,al
		pop	es
;*** load bad track table from CYL 2, HEAD 0, SECTOR 0
		call	clear_track
		mov	ah,2
		mov	al,DRIVE_SEC
		dec	al
		mov	bx,READ_BUFFER
		mov	cx,2
		xor	dh,dh
;R06		mov	dl,DRIVE_NUM
		mov	dl,REAL_DRIVE_NUM		;R06
		add	dl,80h
		int	13h
		jc	load_ret
		push	di
		mov	di,READ_BUFFER
		add	di,0c00h
		mov	si,offset DM_TABLE_MARK
		add	si,4
		mov	cx,dm_mark_len
		sub	cx,4
		rep	cmpsb
		pop	di
		jnz	short load_ret
		mov	si,READ_BUFFER
		add	si,0bfah
		mov	cx,es:[si]
		mov	si,READ_BUFFER
		mov	bx,BAD_BUFF_POINT
store_loop:
		mov	word ptr es:[bx],0ffffh
		or	cx,cx
		jz	short 	load_ret
		mov	ax,es:[si]
		cmp	ax,DRIVE_CYL
		jae	short load_ret
		mov	dl,es:[si+2]
		cmp	dl,DRIVE_HEAD
		jae	short load_ret
		push	bx
		call	store_cyl_head
		pop	bx
		jc	load_ret
		inc	print_posi
		add	si,6
		add	bx,3
		mov	BAD_BUFF_POINT,bx
		dec	cx
		jmp	store_loop
load_ret:
		ret
get_drive_parm	ENDP
;
;***************** test interleave speed ****************
; input : NONE
; output: cx = low word time dword
; 	  bx = high word time dword
;********************************************************
test_intl_speed:
		push	ds
		mov	ax,40h
		mov	ds,ax
;
;R03		F000_Call	VNORMAL
		Call	F000_VNORMAL			;R03
		or	byte ptr attribute[bp],BLINK	;Set blink
		mov	ch,SECOND_ROW-1
		add	ch,interleave
		mov	cl,52
		mov	word ptr CURSOR_X[bp],cx
		mov	al,interleave
		add	al,'0'
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
		mov	ah,2
		mov	al,TEST_SECTOR_NUM
		mov	bx,READ_BUFFER
		mov	cx,1
;R06		mov	dl,DRIVE_NUM
		mov	dl,REAL_DRIVE_NUM		;R06
		add	dl,80h
		xor	dh,dh
		int	13h
		EVEN
		xor	al,al
		out	43h,al
		jmp	$+2
		jmp	$+2
		in	al,40h
		mov	cl,al
		jmp	$+2
		in	al,40h
		mov	ch,al
		push	cx
		mov	si,6ch
		mov	bx,[si]
		push	bx
;
		mov	bx,READ_BUFFER
;R06		mov	dl,DRIVE_NUM
		mov	dl,REAL_DRIVE_NUM		;R06
		add	dl,80h
		xor	dh,dh
		mov	cx,1
		xor	ax,ax
count_loop:
		push	ax
		mov	ah,2
		mov	al,TEST_SECTOR_NUM
		int	13h
		pop	ax
		inc	ax
;		test	ax,1
;		jnz	short not_show_rate
		push	ax
;R03		F000_Call	VNORMAL
		Call	F000_VNORMAL			;R03
		mov	byte ptr CURSOR_X[bp],63
		shl	ax,3
		mov	bx,4
		call	disp_number
		mov	bx,READ_BUFFER
	      	mov	cx,1
		pop	ax
not_show_rate:
		cmp	ax,TEST_TIMES
		jb	short count_loop
;
		EVEN
		xor	al,al
		out	43h,al
		jmp	$+2
		jmp	$+2
		in	al,40h
		mov	cl,al
		jmp	$+2
		in	al,40h
		mov	ch,al
		mov	si,6ch
		mov	dx,[si]
;
		pop	bx
		pop	ax
		sub	ax,cx
		sbb	dx,bx
		cmp	dx,-1
		jne	short Not_minus
		xor	dx,dx
Not_minus:
		push	ax
		push	dx
;R07 start
		cmp    	dx,0
		ja      short count_ok
		cmp     ax,18637
		ja      short count_ok
		mov     ax,37274
count_ok:
;R07 end	     
		mov	cx,18637	; 1/64 second counter number
		div	cx
		shl	ax,4
		mov	cx,ax
		mov	dx,TEST_TIMES*TEST_SECTOR_NUM/2
		xor	ax,ax
		mov	bx,cx
		mov	si,1
div_loop:
		cmp	cx,dx
		ja	short Not_mini
		add	cx,bx
		add	cx,bx
		add	si,2
		jmp	short div_loop
Not_mini:
		div	cx
		mov	cl,ah		; dx.ax / 64
		shr	dx,6
		shr	ax,6
		shl	cl,2
		or	dh,cl		;-----
		push	dx
		mul	si
		pop	dx
		mov	byte ptr CURSOR_X[bp],60
		mov	bx,4
		call	disp_number
		mov	al,'.'
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
		mov	al,dh
		mov	cl,100
		mul	cl
		xchg	ah,al
		xor	ah,ah
		cmp	al,10
		jae	short below_ten
		mov	al,10
below_ten:
		mov	bx,2
		call	disp_number
;
		mov	byte ptr CURSOR_X[bp],70
		mov	al,'/'
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
		mov	al,'s'
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
		mov	al,'e'
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
		mov	al,'c'
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
;
		mov	byte ptr CURSOR_X[bp],52
		mov	al,interleave
		add	al,'0'
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
		pop	bx
		pop	cx
		pop	ds
		ret
;
;*******************************************************************
;  Duplicate display input charactory in current cursor position
; input : al = output charactory
;	  ah = attribe option (0 = not change, 1 = normal)
;	  cl = duplicate number
; output: none
;*******************************************************************
dup_char_disp	PROC	NEAR
		or	ah,ah
		jz	short 	attrib_OK
		cmp	ah,1
		jne	short not_normal
;R03		F000_Call	VNORMAL
		Call	F000_VNORMAL			;R03
		jmp	attrib_OK
not_normal:
attrib_OK:
		mov	ch,al
dup_char_loop:
		push	cx
		mov	al,ch
;R03		F000_Call	Display_Char
		Call	F000_Display_Char		;R03
		pop	cx
		dec	cl
		jnz	short dup_char_loop
		ret
dup_char_disp	ENDP
;
comment %
mov_drive_table	PROC	NEAR
		mov	dx,801h
move_loop:
		mov	ah,2
		xor	bh,bh
		int	10h
		mov	ah,8
		int	10h
		push	ax
		mov	ah,2
		add	dh,10
		int	10h
		pop	ax
		mov	bl,ah
		mov	ah,9
		mov	cx,1
		int	10h
		sub	dh,10
		inc	dl
		cmp	dl,79
		jb	short move_loop
		inc	dh
		cmp	dh,11
		jb	short move_loop
		ret
mov_drive_table	ENDP
%
;
		public	LOW_FORMAT_END
LOW_FORMAT_END	LABEL	NEAR

;R03 - start
F000_CURSOR_OFF:
		F000_Call	CURSOR_OFF
		ret
F000_GETHPARM:
		F000_Call	GETHPARM
		ret
;R03 - end

endif;	NO_HDD_LOW_LEVEL_FORMAT

ECODE		ENDS

		END
