;	[]===========================================================[]
;
;	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
;----------------------------------------------------------------------------
;R97	04/22/99  STV	Add "Auto_HDD_Detect_IN_STDCMOS" define for stdcmos
;			freature.This feature support auto detect IDE HDD
;			immediately when press 'ENTER' key on Auto type of HDD
;			item.
;R96	04/19/99  STV	Changed save CMOS data to flash area for "Support_CMOS_Backup_Data"
;R95	03/24/99  RAY	Add switch: NO_Y2K_CHECK for some customer that they
;			have RTC that supports century
;R94A	03/22/99  GAR	When define NEW_SUPERIO_KERNEL, R94 will valid
;R94	03/15/99  GAR	Add refresh function for super I/O
;R93	03/08/99  TNY	Add Clear Cmos Func.
;R92	03/08/99  DRS	Jump out of range
;R91	01/28/98  DRS	This function depends on Not_Change_Setup_Color definition
;			Don't support "Change Color" function in SETUP.
;			Set default SETUP color by CMOS3B[bp] = 03h
;R90 	01/28/99  DRS	Customer takes advantage of jumper to clear CMOS,but
;			they don't want to clear password at same time.
;R89	01/22/98  GAR	Add hook Get_Data_From_KB for Superio
;R82A	12/21/98  RCH	Fixed compliation error if switch 
;			"No_Report_CMOS_Error" is used.
;R88B	12/03/98  MCH	Enhanced the R88 code for displaying available option
;			item(up to 16 characters) in help screen of CMOS Setup
;			when it is over the margin especially for JUMPLESS
;			option in CPU feature setup screen.
;R88A	12/03/98  MCH	Fixed the R88 code mistake of help screen of CMOS Setup
;			when the number of total item(ItemMax) is greater
;			then Avail_X(defined by R88) but the actual ItemMax
;			after changed by JUMPLESS.INC is less then Avail_X.
;R88	11/23/98  PAL	Fix available option item over the margin in setup help
;R87	11/23/98  ADS	Support KEYBOARD PASSWORD function by chipset.
;			note: define " PassWord_PSON_By_Chipset" please don't
;			      define " Double_Password "	
;R77b	10/21/98  BAR	Fix debug . Counter CheckSum  address error.
;R86	09/29/98  RAY	Together with STDCMOS.ASM & KERNAL.ASM
;			Move code to XGROUP
;R85	09/24/98  RAY	Add public routine: If_Code_Running_In_F000
;R84	09/21/98  RAY	Some M/B must check the existance of sensor inside
;			setup.
;R83	09/07/98  RAY	Support MASM 6.11
;R73C	09/04/98  RAY	Depends on R73, also support *.SSR
;M01  	09/02/98  RAY	Adapt Preboot-Agent from code modified by US
;	
;	(01/29/98 TJM)  Added MPC 2.0 (Formerly RPB) modifications
;
;R82	08/14/98  BAR	Added check CMOS 10h~12h = 0ddh,cch,bbh 
;			Load CMOS default only
;R81	06/30/98  KVN	Fixed coding mistake that will casue write item wrong
;			value in POST from other file call in this subroutine
;R78d	06/09/98  MAX	Fixed FlashROM CMOS backupData Save to CMOS subroutine
;			function.
;R78c	06/05/98  MAX	Support CMOS default value save to 2M ROM Flash function
;R78b	06/01/98  MAX	Fixed by 1M ROM 4k Unit Only
;R78a	05/26/98  MAX	Change  FLASH_CMOS_Sign  '*CMOS*' lable 
;R80    05/08/98  TNY	Added CPU internal frequency into setup main menu
;R79	05/07/98  DRS	This function depends on New_Swap_Fdd_Method
;			The new method is Drive A exists or Drive B exists , 
;			the Floppy Swap function is available.
;R78	05/06/98  MAX	Support CMOS default value save to Flash function.This
;			function will save CMOS value to flash every time when
;			you change setup value and save it to CMOS.That let you
;			can load it to CMOS if CMOS value is fail or checksum
;			error.The feature will added a hot key (f2) in post error
;			message (POST 78) let you can choise which load CMOS
;			from BIOS setup default or previous setup change value
;                       If you want to use it just define "CMOS_Default_in_Flash EQU 1"
;			in BIOS.CFG
;R77a	04/29/98  MAX	Fixed CMOS backup to Flash ROM function bug.Added Search 
;			CMOS label not found.
;R77	04/28/98  MAX	Fixed CMOS backup to Flash ROM function bug.Added define
;                       "FLASH_CMOS_Size" function in BOOTROM.ASM
;R76	04/27/98  PAL	Move Setup_Selectable Function form Jumpless
;R75	04/24/98  MAX	Support CMOS backup to Flash ROM function.This function
;			will create 2 hot key (F6-Save CMOS to BIOS and
;			F7-Load CMOS from BIOS) in kernel page of setup screen
;			If you want to to use it just define "Backup_CMOS_to_FLASH EQU 1"
;			in BIOS.CFG
;R74	04/13/98  STV	Added "MENU IN BIOS" func-key F7 to print if switch
;			"MIB_Print".
;R28A	03/20/98  RCH	Store the desired item value into CMOS and program
;			register with CMOS value instead of taking BIOS 
;			default while the item is disabled.
;			default while the item is disabled if switch
;			"LOAD_CMOS_FOR_ITEMDISABLE" is used.
;R73B	03/20/98  RAY	Depends on R73, also support *.AIO
;R73A	03/16/98  RAY	Depends on R73, also support *.GEN
;R73	03/14/98  RAY	Add code to decide whether a item in superio.sio 
;			has a help pointer points to F segment or X Segment
;R72	03/11/98  RAY	Add Display_String control JMPSTRING
;R71	03/10/98  DNL	Reduce ACPI S4/BIOS code size to save more space
;R69B	02/18/98  KVN	Fixed coding mistake
;R69A	02/18/98  KVN	Remove MIB code to XGROUP
;R70A	02/16/98  RAY	Fix mess up of "Available Option" Help when handling
;			new format ?feature.asm but some how not every 
;			MENUITEM's [ITEM].HelpOffset has been changed to point
;			to a string offset in XGROUP
;
;			i.e. Allow you to still point to STD_HELP_STR in
;			     [ITEM].HelpOffset even though that file has
;			     already been claimed to be a new format file.
;
;R70	02/14/98  RAY	Support new ?feature.asm format in which the help
;			offset of each item is pointed to XGROUP.
;
;			This is done to let ?feature.asm works both in BIOS
;			4.51 & 4.60(supports Multi-Languages)
;
;R69	02/13/98  STV	Fixed "MENU IN BIOS" item change to func-key F5 and not
;			Define "MENU_IN_BIOS" by cbrom.exe v1.22 after.
;			The length of each line in txt file can't exceed 78 bytes.
;R68	02/04/98  BAR	Added a Hook to Check SupervisorPassword
;			Add define 'Password_Hook	equ	1' in bios.cfg
;
;			Use method same us AFLASH Hook
;			1. Search '$PassWord' string in F000H
;			2. Copy Start address 
;			3. call Subroutine from start address
;R67	12/28/97  LAW	added check EPALOGO_FLAG is "EPA_LOGO_Use_Graphics" or
;			"FULL_SCREEN_LOGO" usering for show char or not
;R66	12/15/97  AVN	Added keyboard password in chipset support,
;			need function call support.
;R63A	12/09/97  LAW	fixed when define "EPA_LOGO_Use_Graphics" and Set Password
;			want cann't show password msg
;R61A	12/04/97  RAY	Fixed compilation error under certain enviroment
;R58A	12/02/97  RCH	Don't put customer specific string as standard code
;			to prevent space wasting.
;R65	12/02/97  RCH	Fixed compilation error under certain enviroment
;R64	11/28/97  LAW	remove some code of device, than create label for device
;			Use
;R63	11/25/97  LAW	modify display_char for "EPA_LOGO_Use_Graphics" show
;			information at text mode
;R62	10/07/97  RCH	Added 4 more lines for help message display
;R61	09/13/97  RAY	Do declare some externals for non-dosversion
;R60	08/19/97  LAW	added Public Display_Whole_Item for Winbond 83977TF
;			"Password_ON_NOW_SUPPORT" 
;R59	07/24/97  TNY	Move "Setup_Saved_Handler" hook from kernal.asm .
;R58	07/16/97  RAX	Add "FDDboot_when_Password_Fail" define for customer
;			don't use default password and if password lose can
;			use FDD Boot.
;R57	06/24/97  RAY	Solve coding mistake that causes the screen to mess
;			up. The sowing loop in SHOW_AUTO_CFG should end at
;			BX >= PAGE_END[bp] but not BX > PAGE_END[bp].
;R56A	06/19/97  RAY	R56 cause setup to hang if run from MODBIN.EXE
;R56	06/18/97  TNY	Always show sensor values in runtime.
;R55	06/04/97  PTY	Add code for RPB
;R54	05/29/97  KVN	Added a new segment for store more BIOS code
;R53	05/26/97  DNL	Add "Support_1_FDD" definition
;R52	04/30/97  RCH	Fixed F10 key sometimes lose function while exit from 
;			any sub-screen.
;R51	04/07/97  DNL	Added STD resume password check support
;R50	03/12/97  KVN	Add "No_Auto_Switch_to_Text" definition
;R49	03/11/97  RCH	Clear keyboard buffer content before treating
;			keystorke for setup operation
;R48	12/18/96  KVN	Cancle "AWARD_SW" default password in BIOS and set it
;			by MODBIN.EXE v4.50.60 or later
;R47	12/11/96  RAY	Fix screen display wrong when calling Self_Disable
;			if that item is located at the right side
;R46A	11/20/96  RAY	Public Check_CMOS_Sum
;R46	11/15/96  RAY	Move some codes to E000 to save F000 area
;
;			Code moved: 
;
;			  . Read/Write CMOS related
;			  . Password related
;
;R44A	11/07/96  RAY	R44 only applys to Notebook_Power_Management
;R45	10/29/96  RAY	Do need to set CMOS year to default when checksum fails
;R44	09/25/96  DNL	Fixed bug of no status screen under window 95
;R43	09/23/96  DNL	Add CHANGE_COLOR,NO_BORDER function for display_string
;R42	09/05/96  DNL	Only accept <Enter> key to ended keying password 
;R41A	09/04/96  DNL   Fixed coding mistake
;R39A	09/02/96  LRY	Fixed auto_items error programming to setup default
;R41	09/02/96  DNL   Display error message when keyin wrong password
;R40    08/12/96  DNL	Added code for customer special request
;R39	08/08/96  RAY	GetItem_Value:
;
;			Check the item value with it's maximum setting. If
;			exceeds, use setup default value !
;
;R38	08/07/96  RAY	Add 2 more special-show routines:
;
;			If_Less_Than_CX_Dis
;			If_Greater_Than_CX_Dis
;
;			They are basically the same as If_CX_Then_Dis
;			except that the way of comparison is different
;
;R34B	08/05/96  KVN	Don't restore security screen if no set password
;R37	08/02/96  LAW   (R34A) Fixed Store screen wrong when keyin wrong password
;R36	08/02/96  LAW	Add defin "No_Default_Password" For some customer
;R35	07/23/96  KGN	Add defin Always_Password_Need For Special Customer
;R34	07/03/96  KVN	Store screen data before verify password and restore
;			original screen data after enter correct password to
;			avoid POST message be destroy
;R33	07/03/96  TNY	Add "SWAP_FDD_SHOW" option.
;R32	06/19/96  RAY	Display the item before we hidden it. This is to 
;			enhance the capability of dependent show.
;R31	05/25/96  TNY	Add Add_PASSWORD_LOOPS definition.(eq:2a59fe4d.cfg)
;R30	05/03/96  RAY	Clear RTC_STATUS, EQUIP_STATUS for CMOS 0Eh when 
;			saving CMOS from stack. This is to prevent DOS from
;			treating all FDD drives as 360K type !
;R29	03/20/96  KVN	Fixed format wrong when enable swap floppy function
;R28	02/16/96  RCH	Added a switch to load CMOS value even the item is
;			disabled.
;R27	02/14/96  RAY	Add option: Never_Disable_Password
;R18A	02/12/96  RAY	Always enable PNPFEAT
;R26	02/07/96  KVN	Fixed HDD type is AUTO but enter Setup utility show USER
;			when wait for POST auto detect
;R25	01/31/96  RAY	Prevent the setup screen from getting mess up when
;			calling from modbin
;R24A	01/19/96  RAY	Skip R24 if setup is invoked from modbin 
;R24	01/12/96  KVN	Added full screen logo display function
;R23	12/15/95  RAY	Share codes of auto-table with CT_TABLE.ASM
;R22	10/26/95  AVN	Add NEW_IO_FEATURE Definition For Audio Setup.
;R21	10/17/95  RAY	Add new public routines:
;
;				If_CX_Then_Dis
;				Self_Dis
;				Re_Enable
;
;R20	10/16/95  RAY	Do not inplement F6/F7 if the corresponding item(s)
;			in KERNAL.ASM is disabled
;R19	10/06/95  KVN	Clear drive0 CMOS12 type when is AUTO type and none HDD
;R17A	09/27/95  LRY	Removed R17,  that cause screen garbage
;R18	09/21/95  KEN	Add NEW_PNP_SETUP definition.
;R17	09/20/95  RAY	Routine Mask_To_Mask_Trans will have error result
;			if the input SI's bit 15 is high & input DI = 0FFFFh
;R13A	08/23/95  KVN	Fixed drive1 type clear error when drive1 is AUTO type
;R16	08/05/95  RAY	Add BIOS.CFG switch: Perfect_Password
;R12A	08/03/95  RAY	No_Support_4_IDE should placed after "include bios.cfg"
;R15	07/15/95  KVN	Added HDD access mode error
;R13	06/21/95  KVN	Fixed WINNT error when drive1 is AUTO type and drive1
;			is absent
;R12	06/14/95  KVN	Open Support_4_IDE feature become standard feature
;R11	06/13/95  KVN	Reduce Post_func_call and F000_call code size
;R10	06/09/95  DNL	Added Cyrix M1 CPU 4 clock mode support
;R09	04/19/95  RAY	Automatically load RTC century as 2000
;R08	01/26/95  RCH	Change default year to 1995
;R07	01/06/95  DNL	Let Next_Item_Value,Prev_Item_Value public
;R06	11/09/94  KVN	Fixed MSD.EXE utility 'DISK Drives' test error
;R05	09/26/94  RCH	User can change use password when both user and 
;			supervisor password are set if setup are enterred.
;R04	08/26/94  RAY	Do not write date/time back to CMOS when cmos fail
;			because the BIOS no longer load defaults for these
;			items!
;R03	08/17/94  KVN	Modify check password table position for POST auto
;			IDE detect function
;R02	08/15/94  RCH	Don't turn on NMI during POST stage
;R01	06/11/94  RCH	Clear secondary password flag if CMOS failed
;R00	06/02/94  RAY	Initial Revision for HDD LBA/LARGE mode & 4 IDE

;R83 - starts
ifdef	MASM611
		.MODEL  SMALL,BASIC
		OPTION	PROC: PRIVATE
endif	;MASM611
;R83 - ends
		PAGE	56,132
;R83		.286
		.386p					;R83

;R12A ifndef	No_Support_4_IDE					;R12
;R12A Support_4_IDE		EQU	1				;R12
;R12A endif	;No_Support_4_IDE					;R12

		include	bios.cfg

ifndef	No_Support_4_IDE					;R12A
Support_4_IDE		EQU	1				;R12A
endif	;No_Support_4_IDE					;R12A
;r55 start
ifdef RPB_ENABLED
    include rpb.cfg
endif ; RPB_ENABLED
;r55 end
		include	bsetup.inc
		include	common.mac
		include	common.equ
		include	cmos.equ

;R96 start
ifdef Support_CMOS_Backup_Data
		include pnp.equ
		include dmi.equ

		extrn	 Post_Flash_Read:near
		extrn	 Post_Flash_Write:near
endif ;Support_CMOS_Backup_Data
;R96 end

ifndef	DOSVERSION
;R61		extrn	Auto_Table_List:near
		extrn	Get_Cmos:Near
		extrn	Set_Cmos:Near
		extrn	Cursor_Off:Near
;R48		extrn	MASTER_PASS_HASH:word
		extrn	MASTER_PASS_HASH:byte	;R48
		extrn	COLOR_SETTING:byte
endif	;DOSVERSION

		extrn	VLF:near					;R72
		extrn	VCR:near					;R72

		EXTRN	BIOS_FEATURE_END:NEAR
		EXTRN	BIOS_FEATURE_KEY_LIST:NEAR
		EXTRN	BIOS_FEATURE_SPECIAL_DO:NEAR
		EXTRN	BIOS_FEATURE_SPECIAL_SHOW:NEAR
		EXTRN	BIOS_FEATURE_START:NEAR
		EXTRN	BIOS_FEATURE_STARTUP_STR:NEAR
		EXTRN	CENTURY_ITEM:NEAR
;R86		EXTRN	CHECK_VALID_HDD_TYPE:NEAR
		EXTRN	fPROC_CHECK_VALID_HDD_TYPE:FAR		;R86
		EXTRN	CHIP_FEATURE_END:NEAR
;R18A		EXTRN	CHIP_FEATURE_KEY_LIST:NEAR
		EXTRN	CHIP_FEATURE_SPECIAL_DO:NEAR
		EXTRN	CHIP_FEATURE_SPECIAL_SHOW:NEAR
		EXTRN	CHIP_FEATURE_START:NEAR
		EXTRN	CHIP_FEATURE_STARTUP_STR:NEAR
;R46		EXTRN	CLEAR_HELP:NEAR
		EXTRN	CMOS_CHECK_SUM:NEAR
		EXTRN	DATE_ITEM:NEAR
		EXTRN	DO_K_ESC:NEAR

		EXTRN	DO_SAVE_EXIT:NEAR
		EXTRN	GOTO_KERNAL:NEAR

;R69A		EXTRN	Do_k_F5_MIB:NEAR	;R69
;R69A		EXTRN	check_MIB:NEAR		;R69
		EXTRN	MIB_key:NEAR		;R69
;R78 start
;R78cifndef Flash_16K_8K_8K_Unit	  ;R78b
ifdef  Support_CMOS_Backup_Data 
		extrn	Flash_Write:near
		extrn	Flash_Read:near
endif ; Support_CMOS_Backup_Data 
ifdef  Backup_CMOS_to_FLASH
		EXTRN  S_CMOS_TO_BIOS:NEAR		
		EXTRN  L_CMOS_FROM_BIOS:NEAR		
		EXTRN  Save_CMOS_TO_BIOS_Default:NEAR	
		EXTRN  Load_CMOS_From_BIOS_Default:NEAR
endif  ;Backup_CMOS_to_FLASH
;R78cendif  ;Flash_16K_8K_8K_Unit	  ;R78b
;R78 end

		EXTRN	MIB_screen:NEAR		;R69A
		extrn	XCALL_PROC:near		;R69A
		extrn	post_decompress:near	;R69A

;R46		EXTRN	HELP_BORDER:NEAR
		EXTRN	HOUR_ITEM:NEAR
		EXTRN	KERNAL_END:NEAR
		EXTRN	KERNAL_KEY_LIST:NEAR
		EXTRN	KERNAL_SPECIAL_DO:NEAR
		EXTRN	KERNAL_SPECIAL_SHOW:NEAR
		EXTRN	KERNAL_START:NEAR
		EXTRN	KERNAL_STARTUP_STR:NEAR
		EXTRN	MINUTE_ITEM:NEAR
		EXTRN	MONTH_ITEM:NEAR
		EXTRN	PM_FEATURE_END:NEAR
;R18A		EXTRN	PM_FEATURE_KEY_LIST:NEAR
		EXTRN	PM_FEATURE_SPECIAL_DO:NEAR
		EXTRN	PM_FEATURE_SPECIAL_SHOW:NEAR
		EXTRN	PM_FEATURE_START:NEAR
		EXTRN	PM_FEATURE_STARTUP_STR:NEAR
		EXTRN	SECOND_ITEM:NEAR
		EXTRN	SECURITY_ITEM:NEAR
		EXTRN	STDCMOS_END:NEAR
		EXTRN	STDCMOS_KEY_LIST:NEAR
		EXTRN	STDCMOS_SPECIAL_DO:NEAR
		EXTRN	STDCMOS_SPECIAL_SHOW:NEAR
		EXTRN	STDCMOS_START:NEAR
		EXTRN	STDCMOS_STARTUP_STR:NEAR
		EXTRN	STD_CLR_STR1:NEAR
		EXTRN	STD_HELP_STR:NEAR
ifdef	Support_Calender_In_Setup
		EXTRN	TOGGLE_CALENDER:NEAR
endif	;Support_Calender_In_Setup
		EXTRN	WRITE_TIME_TO_CMOS1:NEAR
		EXTRN	YEAR_ITEM:NEAR
		extrn	Temp_Year_Item:near	;R09

		EXTRN	PCI_Feature_Special_Do:Near
		EXTRN	PCI_Feature_Special_Show:Near
;R18A		EXTRN	PCI_Feature_Key_List:Near
		EXTRN	PCI_Feature_StartUp_Str:Near
		EXTRN	PCI_Feature_Start:Near
		EXTRN	PCI_Feature_End:Near

;R18A ifdef	NEW_PNP_SETUP	;R18
		EXTRN	PNP_Feature_Special_Do:Near
		EXTRN	PNP_Feature_Special_Show:Near
;R18A		EXTRN	PNP_Feature_Key_List:Near
		EXTRN	PNP_Feature_StartUp_Str:Near
		EXTRN	PNP_Feature_Start:Near
		EXTRN	PNP_Feature_End:Near
;R18A endif	;NEW_PNP_SETUP

;R80 - start
ifdef	NEW_CPU_FEATURE
		EXTRN	CPU_Feature_Special_Do:Near
		EXTRN	CPU_Feature_Special_Show:Near
		EXTRN	CPU_Feature_StartUp_Str:Near
		EXTRN	CPU_Feature_Start:Near
		EXTRN	CPU_Feature_End:Near
endif;	NEW_CPU_FEATURE
;R80 - end

;R22 - start
ifdef	NEW_IO_FEATURE
		EXTRN	IO_Feature_Special_Do:Near
		EXTRN	IO_Feature_Special_Show:Near
;R18A		EXTRN	IO_Feature_Key_List:Near
		EXTRN	IO_Feature_StartUp_Str:Near
		EXTRN	IO_Feature_Start:Near
		EXTRN	IO_Feature_End:Near
endif	;NEW_IO_FEATURE
;R22 - end

ifdef	Double_Password
		extrn	SuperPassword_Item:near
		extrn	UserPassword_Item:near
		extrn	Ct_User_Password_Location:near
endif	;Double_Password

;R86		extrn	Do_HDD:near
;R86		extrn	Update_User_Type:near
;R86		extrn	Show_HDD:near
		extrn	HDDC_ITEM:near
;R86		extrn	Check_If_HDD_Type_Item:near
		extrn	X_Check_If_HDD_Type_Item:near		;R86
		extrn	Get_HDD_CMOS_Info:near
		extrn	X_Get_HDD_CMOS_Info:near		;R86
		extrn	fPROC_Get_HDD_CMOS_Info:far		;R86

    		extrn	Ct_ReTable_Auto:near
		extrn	Ct_Auto_Check:near
		extrn	Convert_6_Digit:near

;R61Aifdef	DOSVERSION					;R61
;R61A		extrn	Auto_Table_List:near		;R61
;R61A		extrn	Auto_CPU_386DX:near
;R61A		extrn	Auto_CPU_386SX:near
;R61A		extrn	Auto_CPU_386SL:near
;R61A		extrn	Auto_CPU_486DX:near
;R61A		extrn	Auto_CPU_486SX:near
;R61A		extrn	Auto_CPU_486DX2:near
;R61A		extrn	Auto_CPU_486SLC:near
;R61A		extrn	Auto_CPU_486DLC:near
;R61A		extrn	Auto_CPU_IBM386SLC:near
;R61A		extrn	Auto_CPU_IBM486SLC2:near
;R61A		extrn	Auto_CPU_P24T:near
;R61A		extrn	Auto_CPU_486DXS:near
;R61A		extrn	Auto_CPU_486SXS:near
;R61A		extrn	Auto_CPU_486DX2S:near
;R61A		extrn	Auto_CPU_IBM486DLC3:near
;R61Aendif	;DOSVERSION					;R61

ifdef	PM_SUPPORT
		extrn	PM_Init:near
		extrn	PM_Option_Check:near
endif	;PM_SUPPORT
;R11		extrn	POST_func_end:Near		;128k
;R11		extrn	POST_VECT:Near			;128k
		extrn	Post_call_proc:near		;R11

	ifdef	Perfect_Password			;R16
		extrn	Ct_Perfect_Password_Loc:near	;R16
	endif	;Perfect_Password			;R16
		extrn	HDDD_ITEM:near			;R13A

		extrn	Load_BIOS_D4_Item:near		;R20
		extrn	Load_SETUP_D4_Item:near		;R20
		extrn	LoadSetupD4Str:near		;R20
		extrn	LoadBIOSD4Str:near		;R20

		extrn	Get_Auto_Table_Offset:near	;R23
	ifndef	Support_1_FDD				;R53
		extrn	SwapFloppy_Item:near		;R29
	endif	;Support_1_FDD				;R53	;M01
;r55 start
ifdef RPB_FEATUREPAGE_ENABLED       ; RXX
		extrn	rpb_feature_start:near
		extrn	rpb_feature_end:near
		extrn	rpb_feature_key_list:near
		extrn	rpb_feature_special_do:near
		extrn	rpb_feature_special_show:near
		extrn	rpb_feature_startup_str:near
endif ; RPB_FEATUREPAGE_ENABLED

ifdef RPB_POSTMENU_ENABLED          ; RXX
		extrn	rpb_postmenu_start:near
		extrn	rpb_postmenu_end:near
		extrn	rpb_postmenu_special_do:near
		extrn	rpb_postmenu_special_show:near
		extrn	rpb_postmenu_startup_str:near
endif ; RPB_POSTMENU_ENABLED
;r55 end

;M01	endif	;Support_1_FDD				;R53


;M01 - start
ifdef	RPB_ENABLED
ifdef	RPB_REBOOT_DISABLE
		extrn	rpbf_prepare_for_reset:near	; prepare MPC for reset
endif	;RPB_REBOOT_DISABLE
endif	;RPB_ENABLED
;M01 - end

		extrn	F000_call_proc:near		;R46
		extrn	Display_CS_String:near		;R46
;R69A		extrn	F000_Display_String:near	;R46
		extrn	F000_Get_Cmos:near		;R46
		extrn	F000_Set_Cmos:near		;R46

ifdef	HELP_IDIOT					;R46
		extrn	Ct_CK_Password:near		;R46
endif	;HELP_IDIOT					;R46
if	Desktop_Power_Management	EQ	2	;R51
	ifndef	NO_STR_PASSWORD_CHECK			;R51
		extrn	Get_SMM_Key:far			;R51
		extrn	Clear_Screen:far		;R51
	endif	;NO_STR_PASSWORD_CHECK			;R51
endif	;Desktop_Power_Management	EQ	2	;R51

;R73 - starts
ifdef	NEW_SUPERIO_KERNEL
		extrn	First_IO_Item:near
		extrn	Last_IO_Item:near
		extrn	Prg_Super_IO_Chip:near
endif	;NEW_SUPERIO_KERNEL
;R73 - ends

;R73A - starts
IF	CLKCNTL_KERNEL
		extrn	First_Clock_Item:near
		extrn	Last_Clock_Item:near
		extrn	Prepare_ClkGen_Val:near
ENDIF	;CLKCNTL_KERNEL
;R73A - ends

;R73B - starts
IF	AUDIO_KERNEL
		extrn	First_Audio_Item:near
		extrn	Last_Audio_Item:near
		extrn	Prg_Audio_Chip:near
ENDIF	;AUDIO_KERNEL
;R73B - ends

;R84 - starts
ifdef	Check_Sensor_In_Setup
		extrn	fPROC_Hide_Sensor_If_Not_Plugged:far
endif	;Check_Sensor_In_Setup
;R84 - ends


		extrn	X_Check_If_LBA_Item:Near		;R86
		extrn	X_Do_LBA:Near				;R86
		extrn	X_Do_HDD:Near				;R86
		extrn	X_Show_HDD:Near				;R86
		extrn	X_Update_User_Type:Near			;R86
		extrn	X_Display_String:near			;R86
ifdef Auto_HDD_Detect_IN_STDCMOS				;R97
		extrn	X_Check_If_Auto_Type:near		;R97
endif ;Auto_HDD_Detect_IN_STDCMOS				;R97

		Public	Setup
		Public	PageOffset
ifdef	PM_SUPPORT
		Public	PM_Page_Offset
endif	;PM_SUPPORT
		Public	Vnormal
		Public	Vhilite
		Public	Vreverse
		Public	VWarn
		Public	VPos
		Public	VNewLine
		Public	VBlink
		Public	VStrshow
		Public	VBorder
		Public	Check_Display_Mode
		Public	Save_All_Cmos
		Public	Read_Cmos_To_Stack
		Public	Key
		Public	AX_To_HEX5
		Public	AX_To_HEX4
		Public	AX_To_HEX3
		Public	AX_To_HEX2
		Public	AX_To_DEC2
		Public	AX_To_DEC3
		Public	AX_To_DEC4
		Public	AX_To_DEC5
		Public	Show_SIX_DIGIT
		Public	Display_String
		Public	Display_Char
		Public	Seq_Up
		Public	Seq_Down
		Public	Seq_Up_By_Menu_List
		Public	Seq_Down_By_Menu_List
		Public	Go_Right_Item
		Public	Go_Left_Item
		Public	Go_Above_Item
		Public	Go_Below_Item
		Public	Go_Most_Above_Item
		Public	Go_Most_Below_Item
		Public	Go_Most_Right_Item
		Public	Go_Most_Left_Item
		Public	DESTROY_KEY_THEN_RET
		Public	DISPLAY_WHOLE_ITEM
		Public	DISP_ITEMTITLE
		Public	DISP_ITEMVAR
		Public	Read_Item_Value
		Public	Write_Item_Value
		Public	HEX_TO_BCD
		Public	SET_CMOS12H
		Public	MOVE_CURSOR
		Public	UP_LINE
		Public	DOWN_LINE
		Public	GET_ITEMSTAT_AX
		Public	SET_ITEMSTAT_AX
		Public	TEST_ITEMSTAT
		Public	ASK_CONFIRM
		Public	EDIT_STRING
		Public	INIT_PAGE
		Public	LOAD_ALL_DEFAULT
		Public	REFRESH_MENU
		Public	REFRESH_MENU1
		Public	WRITE_OUT_CMOS
		Public	YES_EXIT
		Public	VERIFY_PASSWORD
                PUBLIC  Hash_Password
		Public	Get_Password
		Public	Confirm_Password
		Public	Valid_Value
		Public	Get_VarString_Offset

		Public	Show_auto_Cfg
		Public	Get_Auto_Cfg_Value

		Public	BCD_TO_HEX
		Public	Get_Item_BIOS_D4
		Public	Get_Item_SETUP_D4

ifdef	DOSVERSION
		Public	GET_CMOS
		Public	SET_CMOS
endif	;DOSVERSION

ifdef	Password_ON_NOW_SUPPORT			;R64
		Public	SIO_Input_Pass		;R64
		Public	SIO_EnterPass_Msg	;R64
		Public	SIO_Confirmpass_Msg	;R64
endif;	Password_ON_NOW_SUPPORT			;R64

		Public	Mono_Style
;r55 start
ifdef RPB_ENABLED                   ; RXX
    Public  Do_Key_In_Item
    Public  F1_Show_Help
    Public  Special_Enter
    Public  Check_Active_Item

		Public	UPDATE_ITEMSTAT_BUF
		Public	DISP_KEYIN_ITEM
		Public	SHOW_HELP_ON_THE_FLY
endif ; RPB_ENABLED
;r55 end
G_RAM		SEGMENT	AT 0
		ORG	400H
		INCLUDE	G_RAM.INC
G_RAM		ENDS
		extrn	Update_Sensor_Screen:far	;R56

		COMPILE_FOR_SENSOR_MNU = 5	;R73C
		include	all_ssr.inc		;R73C

ifdef	NEW_SUPERIO_KERNEL			;R94A
;R94 - start
		COMPILE_FOR_SUPERIO_MNU = 7
		include	superio.sio	   
;R94 - end
endif	;NEW_SUPERIO_KERNEL			;R94A

DGROUP		GROUP	FCODE
FCODE		SEGMENT	USE16 PARA PUBLIC 'CODE'		;R83
;R83 FCODE		SEGMENT	WORD PUBLIC 'CODE'
		ASSUME	CS:DGROUP,DS:DGROUP
		jmp	start

;-----------------------------------------------------------------------
PageOffset	Label	word
;
;Page 1 point to Kernal Control
;
		dw	offset Kernal_Start
		dw	offset Kernal_End
		dw	offset Kernal_Startup_Str
Page_Data_Diff	EQU	($-offset PageOffset)

;
;Page 2 point to Standard CMOS Features
;
		dw	offset StdCMOS_Start
		dw	offset StdCMOS_End
		dw	offset StdCMOS_Startup_Str
;
;Page 3 point to Extended BIOS Features
;
		dw	offset BIOS_Feature_Start
		dw	offset BIOS_Feature_End
		dw	offset BIOS_Feature_Startup_Str
;
;Page 4 point to Chipset Features
;
		dw	offset Chip_Feature_Start
		dw	offset Chip_Feature_End
		dw	offset Chip_Feature_Startup_Str
;
;Page 5 point to Power Management Setup
;
ifdef	PM_SUPPORT
PM_Page_Offset:
endif	;PM_SUPPORT
		dw	offset PM_Feature_Start
		dw	offset PM_Feature_End
		dw	offset PM_Feature_Startup_Str

		dw	offset PCI_Feature_Start
		dw	offset PCI_Feature_End
		dw	offset PCI_Feature_Startup_Str

;R18A ifdef	NEW_PNP_SETUP	;R18
		dw	offset PNP_Feature_Start
		dw	offset PNP_Feature_End
		dw	offset PNP_Feature_Startup_Str
;R18A endif	;NEW_PNP_SETUP

;R80 - start
ifdef	NEW_CPU_FEATURE
		dw	offset CPU_Feature_Start
		dw	offset CPU_Feature_End
		dw	offset CPU_Feature_Startup_Str
endif;	NEW_CPU_FEATURE
;R80 - end

;R22 - start
ifdef	NEW_IO_FEATURE
		dw	offset IO_Feature_Start
		dw	offset IO_Feature_End
		dw	offset IO_Feature_Startup_Str
endif	;NEW_IO_FEATURE
;R22 - end
;r55 start
ifdef RPB_FEATUREPAGE_ENABLED               ; RXX
		dw	offset rpb_feature_start            ; setup page
		dw	offset rpb_feature_end
		dw	offset rpb_feature_startup_str
endif ; RPB_FEATUREPAGE_ENABLED

ifdef RPB_POSTMENU_ENABLED                  ; RXX
		dw	offset rpb_postmenu_start           ; post menu page
		dw	offset rpb_postmenu_end
		dw	offset rpb_postmenu_startup_str
endif ; RPB_POSTMENU_ENABLED
;r55 end
MAXPAGE		EQU	($ - offset PageOffset)/Page_Data_Diff

		dw	-1					;End of Table

;--------------------------------------------------------------

Special_Do_Show_Off	Label	Word
		dw	offset Kernal_Special_Do
		dw	offset Kernal_Special_Show
		dw	offset Kernal_Key_List
Special_Do_Show_Diff	EQU	$-offset Special_Do_Show_Off

		dw	offset StdCMOS_Special_Do
		dw	offset StdCMOS_Special_Show
		dw	offset StdCMOS_Key_List

		dw	offset BIOS_Feature_Special_Do
		dw	offset BIOS_Feature_Special_Show
		dw	offset BIOS_Feature_Key_List

		dw	offset Chip_Feature_Special_Do
		dw	offset Chip_Feature_Special_Show
;R18A		dw	offset Chip_Feature_Key_List
		dw	offset BIOS_Feature_Key_List	;R18A

		dw	offset PM_Feature_Special_Do
		dw	offset PM_Feature_Special_Show
;R18A		dw	offset PM_Feature_Key_List
		dw	offset BIOS_Feature_Key_List	;R18A

		dw	offset PCI_Feature_Special_Do
		dw	offset PCI_Feature_Special_Show
;R18A		dw	offset PCI_Feature_Key_List
		dw	offset BIOS_Feature_Key_List	;R18A

;R18A ifdef	NEW_PNP_SETUP	;R18
		dw	offset PNP_Feature_Special_Do
		dw	offset PNP_Feature_Special_Show
;R18A		dw	offset PNP_Feature_Key_List
		dw	offset BIOS_Feature_Key_List	;R18A
;R18A endif	;NEW_PNP_SETUP

;R80 - start
ifdef	NEW_CPU_FEATURE
		dw	offset CPU_Feature_Special_Do
		dw	offset CPU_Feature_Special_Show
		dw	offset BIOS_Feature_Key_List	
endif;	NEW_CPU_FEATURE
;R80 - end

;R22 - start
ifdef	NEW_IO_FEATURE
		dw	offset IO_Feature_Special_Do
		dw	offset IO_Feature_Special_Show
;R18A		dw	offset IO_Feature_Key_List
		dw	offset BIOS_Feature_Key_List	;R18A
endif	;NEW_IO_FEATURE
;R22 - end
;r55 start
ifdef RPB_FEATUREPAGE_ENABLED       ; RXX
		dw	offset rpb_feature_special_do
		dw	offset rpb_feature_special_show
		dw	offset BIOS_Feature_Key_List
endif ; RPB_FEATUREPAGE_ENABLED

ifdef RPB_POSTMENU_ENABLED          ; RXX
		dw	offset rpb_postmenu_special_do
		dw	offset rpb_postmenu_special_show
		dw	offset BIOS_Feature_Key_List
endif ; RPB_POSTMENU_ENABLED
;r55 end
;-----------------------------------------------------------------------

		Public	MONO_Buffer
MONO_Buffer	label	near
		Color_Style	<07h,	0fh,	70h,	07h>
		Color_Style	<70h,	78h,	07h,	70h>
MONO_Buffer_End	label	near
;
		Public	VGA_Buffer
VGA_Buffer	label	near
;				    NORMAL		   HILITE		   REVERSE		   WARN
;---------------------------------------------------------------------------------------------------------------------------

		Color_Style	<BLUE*16+WHITE,\
				 BLUE*16+YELLOW,\
				 RED*16+WHITE,\
				 BLUE*16+WHITE>			;color style 0

		Color_Style	<BLUE*16+LIGHTGREEN,\
				 BLUE*16+LIGHTMAGENTA,\
				 MAGENTA*16+WHITE,\
				 BLUE*16+WHITE>			;color style 1

		Color_Style	<GREEN*16+LIGHTCYAN,\
				 GREEN*16+YELLOW,\
				 CYAN*16+BLACK,\
				 GREEN*16+BLACK>		;color style 2

		Color_Style	<CYAN*16+BLACK,\
				 CYAN*16+YELLOW,\
				 GREEN*16+BLACK,\
				 CYAN*16+LIGHTGREEN>		;color style 3

		Color_Style	<CYAN*16+WHITE,\
				 CYAN*16+BLACK,\
				 LIGHTGRAY*16+BLUE,\
				 CYAN*16+YELLOW>		;color style 4

		Color_Style	<CYAN*16+BLACK,\
				 CYAN*16+BROWN,\
				 BROWN*16+LIGHTGRAY,\
				 CYAN*16+WHITE>			;color style 5

		Color_Style	<RED*16+YELLOW,\
				 RED*16+WHITE,\
				 BLACK*16+GREEN,\
				 RED*16+GREEN>			;color style 6

		Color_Style	<RED*16+LIGHTGRAY,\
				 RED*16+WHITE,\
				 BLUE*16+WHITE,\
				 RED*16+WHITE>			;color style 7

		Color_Style	<MAGENTA*16+LIGHTCYAN,\
				 MAGENTA*16+LIGHTGREEN,\
				 LIGHTGRAY*16+BLACK,\
				 MAGENTA*16+WHITE>		;color style 8

		Color_Style	<MAGENTA*16+WHITE,\
				 MAGENTA*16+YELLOW,\
				 GREEN*16+BLUE,\
				 MAGENTA*16+LIGHTRED>		;color style 19

		Color_Style	<LIGHTGRAY*16+BLACK,\
				 LIGHTGRAY*16+RED,\
				 CYAN*16+WHITE,\
				 LIGHTGRAY*16+WHITE>		;color style 10

		Color_Style	<LIGHTGRAY*16+BLUE,\
				 LIGHTGRAY*16+YELLOW,\
				 MAGENTA*16+WHITE,\
				 LIGHTGRAY*16+WHITE>		;color style 11

		Color_Style	<LIGHTGRAY*16+LIGHTGREEN,\
				 LIGHTGRAY*16+LIGHTCYAN,\
				 GREEN*16+WHITE,\
				 LIGHTGRAY*16+WHITE>		;color style 12

		Color_Style	<BLACK*16+LIGHTGREEN,\
				 BLACK*16+LIGHTCYAN,\
				 CYAN*16+YELLOW,\
				 BLACK*16+YELLOW>		;color style 13
Mono_Style:
		Color_Style	<BLACK*16+LIGHTGRAY,\
				 BLACK*16+WHITE,\
				 LIGHTGRAY*16+BLACK,\
				 BLACK*16+LIGHTGRAY>		;color style 14

		Color_Style	<BLACK*16+LIGHTMAGENTA,\
				 BLACK*16+LIGHTGREEN,\
				 LIGHTGRAY*16+RED,\
				 BLACK*16+LIGHTRED>		;color style 15
VGA_Buffer_End	label	near

;---------------------------------------------------------------------------------------------------------------------------

ifdef	DOSVERSION
		include	hdtable.inc		;HDD parameters
endif;	DOSVERSION

;[]========================================================================[]
;[]========================================================================[]
Setup		Proc	Near
;R83 start:
start	Label	Near		;R83
ifdef	DOSVERSION
		mov	al,1
endif	;DOSVERSION

		push	cs
		pop	ds

		cmp	al,POST_CALL
;R26		jne	short @F
		jne	short Not_From_Post			;R26

;M01 - start
ifdef RPB_ENABLED
		extrn	rpbf_reinit:near
		call	rpbf_reinit
endif ; RPB_ENABLED
;M01 - end

;R49 - start
;Clear keyboard buffer
		push	ds
		push	ax
		mov	ax,G_RAM
		mov	ds,ax
		ASSUME	DS:G_RAM
		mov	ax,word ptr ds:PTR_KBD_BUF_TL	;Kbd buffer tail
		mov	word ptr ds:PTR_KBD_BUF_HD,ax	;set buffer head
		and	byte ptr ds:SHFT_STAT,0f0h	;clear shift,alt,ctrl
		pop	ax				;status
		pop	ds
;R49 - end

;R91 -start
ifdef	Not_Change_Setup_Color
		mov	byte ptr CMOS3B[bp],03h		
endif	;Not_Change_Setup_Color			
;R91 -end

;R26 start
		test	byte ptr Post_Temp_Byte[bp],DriveC_AUTO
		jz	short @F
		mov	byte ptr EXT_FIXED_0[bp],47
@@:
		test	byte ptr Post_Temp_Byte[bp],DriveD_AUTO
		jz	short @F
		mov	byte ptr EXT_FIXED_1[bp],47
@@:
		test	byte ptr Post_Temp_Byte[bp],DriveE_AUTO
		jz	short @F
		mov	byte ptr CMOS_HDDE[bp],47
@@:
		test	byte ptr Post_Temp_Byte[bp],DriveF_AUTO
		jz	short @F
		mov	byte ptr CMOS_HDDF[bp],47
@@:
;R26 end
ifndef	Support_1_FDD					;R53
ifndef	SWAP_FDD_SHOW					;R33
ifNdef	New_Swap_Fdd_Method				;R79
;R29 start
		push	ax
		test	byte ptr FLOPPY_TYPE[bp],00001111b
		jz	short @F
		mov	si,offset SwapFloppy_Item
		call	GetItem_Value
		or	al,al
		jz	short @F
		rol	byte ptr FLOPPY_TYPE[bp],4
@@:
		pop	ax
;R29 end
endif	;New_Swap_Fdd_Method				;R79
endif;	SWAP_FDD_SHOW					;R33
endif	;Support_1_FDD					;R53
		or	byte ptr Post_Temp_Byte[bp],Text_POST	;R24
		mov	byte ptr CALLTYPE[bp],al
;R84 - starts
ifdef	Check_Sensor_In_Setup
		call	fPROC_Hide_Sensor_If_Not_Plugged
endif	;Check_Sensor_In_Setup
;R84 - ends
		jmp	short No_Reserve
;R26 @@:
Not_From_Post:							;R26
		sub	sp,DATAAREASIZE		; and reserve space for vars
		mov	bp,sp

		push	ax			;save input al

		mov	ax,ss			; LOAD ES
		mov	es,ax			; WITH STACK SEGMENT
		xor	al,al
		mov	di,bp			; initialize local variables
		mov	cx,DATAAREASIZE		; to zero.  Important if CMOS
		rep	stosb			; is bad.

		pop	ax			;retore input al
		mov	byte ptr CALLTYPE[bp],al;put input al into stack

;R46		call	Read_Cmos_To_Stack
;R46 - starts
 		and	byte ptr CMOS3B[bp],0Fh		;load default color
;R46 - ends
No_Reserve:
		mov	al,CMOS12[bp]
		mov	cl,4
		shr	al,cl
		cmp	al,0fh
		je	short C_Less_15
		mov	CMOS19[bp],al
C_Less_15:
		mov	al,CMOS12[bp]
		and	al,0fh
		cmp	al,0fh
		je	short D_Less_15
		mov	CMOS1A[bp],al
D_Less_15:
		call	Check_Display_Mode
		mov	ax,87h			;Set mode & don't clear video RAM.
		cmp	byte ptr Monochrome[bp],0
		je	short @F
		mov	ax,1202h
		mov	bl,30h
		int	10h
		mov	ax,83h	; Set mode & don't clear video RAM.
@@:
		int	10h
		mov	al,CMOS3B[bp]
		call	Get_Color_Off		;Get color status from CMOS

		mov	STACK_POINTER[bp],SP
		call	Goto_Kernal

		mov	ax,PAGE_START[bp]		;R05
		mov	KERNAL_ITEM[bp],ax		;R05

;R85		cmp	byte ptr CALLTYPE[bp],POST_CALL	;R46
		call	If_Code_Running_In_F000			;R85
		jne	short @F			;R46

ifdef	Double_Password
		test	byte ptr CMOS11[bp],02h		;super pass needed?
		jnz	short Go_Password		;yes, needed!
;R46		call	Chk_User_Needed			;user pass needed?
		call	far ptr fPROC_Chk_User_Needed	;user pass needed? ;R46
		jc	short @F			;no needed!
Go_Password:
else	;Double_Password

		test	byte ptr CMOS11[bp],02h
		jz	short @F

endif	;Double_Password

;R46		cmp	byte ptr CALLTYPE[bp],POST_CALL
;R46		jne	short @F

		mov	byte ptr USE_ITEMSTAT_BUF[bp],0
		call	Update_ITEMSTAT_BUF
		call	Refresh_Menu1
		mov	al,1
;R46		call	Verify_Password
		call	far ptr fPROC_Verify_Password			;R46
		call	Goto_Kernal

ifdef	Double_Password					;R05
		cmp	byte ptr SIX_DIGIT[bp],0AAh	;R05
		jne	short @F			;R05
;R46		call	Hidden_Except_UserPass		;R05
		call	far ptr fPROC_Hidden_Except_UserPass		;R46
		jmp	short DDFF			;R05
endif	;Double_Password				;R05

	@@:

;R05		mov	ax,PAGE_START[bp]
;R05		mov	KERNAL_ITEM[bp],ax

;---------------------------------------------------------------------------
Check_NextPage:
		mov	byte ptr USE_ITEMSTAT_BUF[bp],0
		call	Update_ITEMSTAT_BUF
	DDFF:							;R05
		call	Refresh_Menu1
		mov	bx,PAGE_START[bp]
		cmp	byte ptr CUR_PAGE[bp],PAGE_STDCMOS
		jbe	short @F
		call	Go_Most_Above_Item
		mov	bx,si
		call	Go_Most_Left_Item
		mov	bx,si
	@@:
		mov	KEYIN_ITEM_OFF[bp],bx
		mov	word ptr LAST_KEY[bp],DOWN_ARROW

		cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL
		jne	short Not_In_Kernal
		mov	bx,KERNAL_ITEM[bp]
		mov	OLDITEM[bp],bx
Not_In_Kernal:

;---------------------------------------------------------------------------
Do_Next_Item:
		mov	OLDITEM[bp],bx			;save old item
		CHK_ITEMSTAT ITEMDISABLE+SHOWONLY+HIDDEN;item disable or show only?
		jz	short Normal_Item		;No, go normal operation
		mov	ax,LAST_KEY[bp]
		jmp	short Check_Cursor
Normal_Item:
		cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL
		jne	short @F
		mov	KERNAL_ITEM[bp],bx
	@@:
		call	Display_Whole_Item		;display the current item in REVERSE
		call	Disp_Keyin_Item

		call	Show_Help_On_The_Fly
Call_Key:	call	Key
		call	F1_Show_Help

		call	Special_Enter
		jc	Check_NextPage

		call	Do_K_ESC
		jc	Check_NextPage

;R69A		call	Do_k_F5_MIB		;R69
;R69A start
		cmp	byte ptr CALLTYPE[bp],MODBIN_CALL
		je	short @F
		Xcall	Do_k_F5_MIB
;R75 start
;R78cifndef Flash_16K_8K_8K_Unit	  ;R78b
ifdef  Backup_CMOS_to_FLASH
		Xcall	Do_F6_S_CMOS
		Xcall	Do_F7_S_CMOS
endif ;Backup_CMOS_to_FLASH
;R78cendif ; Flash_16K_8K_8K_Unit	  ;R78b
;R75 end

@@:
;R69A end

		call	Old_Value
		call	Page_BIOS_D4
		call	Page_SETUP_D4

ifdef	Support_Calender_In_Setup
		call	Toggle_Calender
endif	;Support_Calender_In_Setup

		call	Change_Color

		call	Do_Save_Exit
		call	Do_Key_In_Item		;do Key in
		call	Special_Enter
		call	Do_Plus_Minus_Key	;process if +/-/PU/PD

Check_Cursor:
		call	Check_Active_Item	;are there any active item
		jz	short Call_Key		;no, go wait for key input
		call	Move_Cursor		;move cursor
		jnc	short Go_Next		;cursor change
;R75;		jmp	short Do_Next_Item	;cursor not change
		jmp	Do_Next_Item		;R75 cursor not change
Go_Next:
		mov	KEYIN_ITEM_OFF[bp],bx
		push	bx
		mov	bx,OLDITEM[bp]		;display the last item in hilite
		dec	word ptr OLDITEM[bp]	;prevent it from being REVERSED
		call	Display_Whole_Item
		inc	word ptr OLDITEM[bp]	;prevent it from being REVERSED
Skip_Item:
		pop	bx
		jmp	Do_Next_Item
;---------------------------------------------------------------------------
Reshow_Screen:
		push	bx
		call	Refresh_Menu
		jmp	short Skip_Item
;R83 Write_Out_Cmos:
Write_Out_Cmos	Label	Near			;R83

		call	Set_CMOS12h

		mov	ax,CMOS30[bp]
		mov	CMOS17[bp],ax

		and	byte ptr CMOS14[bp],not 0C2h
		test	byte ptr CMOS10[bp],0Fh
		jz	short @F
		or	byte ptr CMOS14[bp],40h
	@@:
		test	byte ptr CMOS10[bp],0FFh
		jz	short @F
		or	byte ptr CMOS14[bp],01h
	@@:
;R85		cmp	byte ptr CALLTYPE[bp],POST_CALL
		call	If_Code_Running_In_F000			;R85
		je	short Save_Result
		cmp	byte ptr CALLTYPE[bp],DOS_CALL
		jne	short Yes_Exit
Save_Result:
ifndef	Support_1_FDD					;R53
ifndef	SWAP_FDD_SHOW					;R33
ifNdef	New_Swap_Fdd_Method				;R79
;R29 start
		test	byte ptr FLOPPY_TYPE[bp],00001111b
		jz	short @F
		mov	si,offset SwapFloppy_Item
		call	GetItem_Value
		or	al,al
		jz	short @F
		rol	byte ptr FLOPPY_TYPE[bp],4
@@:
;R29 end
endif	;New_Swap_Fdd_Method				;R79
endif	;SWAP_FDD_SHOW					;R33
endif	;Support_1_FDD					;R53
		call	Save_All_Cmos

ifdef	PM_SUPPORT
		cmp	byte ptr CALLTYPE[bp],DOS_CALL
		jne	short No_Init
;compress	call	PM_Init
		POST_func_call	PM_Init	;compress
No_Init:
endif	;PM_SUPPORT

;R59 - start
ifdef	Special_Handler_After_Setup_Saved
		extrn	Setup_Saved_Handler:far
		far_call	EGROUP:Setup_Saved_Handler, 0E000h
endif	;Special_Handler_After_Setup_Saved
;R59 - end

;R93 - start
ifdef	ICH
		extrn	Ct_Setup_Saved_Handler:far
		call	far ptr Ct_Setup_Saved_Handler
endif;	ICH
;R93 - end

;R83 Yes_Exit:
Yes_Exit	Label	Near			;R83
		mov	ax,0600h
		xor	cx,cx
		mov	dx,184fh
		mov	bh,07h
		int	10h			;clear screen

;M01 - start
ifdef	RPB_ENABLED
ifdef	RPB_REBOOT_DISABLE
		call	rpbf_prepare_for_reset       ; prepare MPC for reset
endif	;RPB_REBOOT_DISABLE
endif	;RPB_ENABLED
;M01 - end

ifdef	DOSVERSION
		mov	ax,4c00h		;return to DOS
		int	21h
endif;	DOSVERSION

;R85		cmp	byte ptr CALLTYPE[bp],POST_CALL
		call	If_Code_Running_In_F000			;R85
		je	short No_Restore
		add	sp,DATAAREASIZE		; and reserve space for vars
No_Restore:

		ret
Setup		endp

;R85 - starts
		Public	If_Code_Running_In_F000
If_Code_Running_In_F000	Proc	Near
		push	ax
		mov	ax, cs
		cmp	ax, 0F000h
		pop	ax
		ret
If_Code_Running_In_F000	Endp
;R85 - ends

;[]========================================================================[]
;Function :	Initial all the corresponding informations for the page
;		specified
;
;Input	:	AX = page number
;		     1 : kernal page
;		     2 : standard CMOS page
;		     3 : bios feature page
;		     4 : chipset feature page
;		     5 : power management page
;
;Output	:	CUR_PAGE[bp]		= input AX
;		PAGE_START[bp]		= menuitem table start
;	 	PAGE_END[bp]		= menuitem table end
;	 	STROFFSET[bp]		= start up string to show
;		UP_ARROW_FUNC[bp]	= function for UP_ARROW
;		DOWN_ARROW_FUNC[bp]	= function for DOWN_ARROW
;		LEFT_ARROW_FUNC[bp]	= function for LEFT_ARROW
;		RIGHT_ARROW_FUNC[bp]	= function for RIGHT_ARROW
;
;Registers :	CX, SI, DX, FLAG - Destroyed
;[]========================================================================[]
Init_Page	Proc	Near
		push	ax
		mov	cl,al
		xor	ch,ch
		mov	si,offset PageOffset
@@:
		dec	cx
		jz	short @F
		add	si,Page_Data_Diff
		jmp	short @B
@@:
		mov	ax,cs:[si]
		cmp	ax,cs:[si+2]
		je	short Page_Absent

		mov	PAGE_START[bp],ax
		mov	ax,cs:[si+2]
		mov	PAGE_END[bp],ax
		mov	ax,cs:[si+4]
		mov	STROFFSET[bp],ax

		mov	ax,si
		sub	ax,offset PageOffset
		mov	cx,Special_Do_Show_Diff
		mul	cx
		mov	cx,Page_Data_Diff
		xor	dx,dx
		div	cx
		mov	si,ax
		add	si,offset Special_Do_Show_Off
		mov	si,[si+4]

		mov	ax,cs:[si]
		mov	UP_ARROW_FUNC[bp],ax
		mov	ax,cs:[si+2]
		mov	DOWN_ARROW_FUNC[bp],ax
		mov	ax,cs:[si+4]
		mov	LEFT_ARROW_FUNC[bp],ax
		mov	ax,cs:[si+6]
		mov	RIGHT_ARROW_FUNC[bp],ax

		pop	ax
		mov	CUR_PAGE[bp],al
		stc
		ret
Page_Absent:
		pop	ax
		clc
		ret
Init_Page	Endp

;[]========================================================================[]
;Function :	Display the item pointed to by KEYIN_ITEM_OFF[bp] in
;		attribute BLINK
;
;Input	:	None
;
;Output	:	None
;
;Registers :	BX - Preserved
;		Others - Unknown
;[]========================================================================[]
Disp_Keyin_Item	Proc	Near

		cmp	byte ptr Cur_Page[bp],PAGE_KERNAL;in kernal page?
		je	short Disp_Keyin_Exit		 ;yes, exit

;if KEYIN_ITEM_OFF <> OLDITEM, set KEYIN_ITEM_OFF to BLINK

		push	bx
		mov	bx,KEYIN_ITEM_OFF[bp]
		call	Disp_ItemTitle
		call	Vreverse
		cmp	bx,OLDITEM[bp]
		je	short @F
		call	VBLINK
	@@:
		call	Disp_ItemVar
		pop	bx

Disp_Keyin_Exit:
		ret
Disp_Keyin_Item	Endp

;[]========================================================================[]
;Function :	Display the HELP message if K_F1 is pressed
;
;Input	:	None
;
;Output	:	None
;
;Registers :	----
;[]========================================================================[]
F1_Show_Help	Proc	Near


;R85		cmp	byte ptr CALLTYPE[bp],POST_CALL		;R46
		call	If_Code_Running_In_F000			;R85
		jne	short @F				;R46
		call	far ptr fPROC_F1_Show_Help		;R46
	@@:							;R46
		ret						;R46

;R46		cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL
;R46		je	short F1_Show_Help_Exit
;R46
;R46		cmp	ax,K_F1
;R46		jne	short Show_Help_Exit
;R46
;R46		mov	byte ptr IN_F1_HELP[bp],1	;indicate in F1
;R46		call	Display_Help_Str
;R46		mov	byte ptr IN_F1_HELP[bp],0	;indicate not in F1
;R46		call	Refresh_Menu
;R46
;R46F1_Show_Help_Exit:
;R46
;R46		ret

F1_Show_Help	Endp

;[]========================================================================[]
;Function :	Display the HELP message on the fly for kernal page
;
;Input	:	None
;
;Output	:	None
;
;Registers :	----
;[]========================================================================[]
Show_Help_On_The_Fly	Proc	Near

;R85		cmp	byte ptr CALLTYPE[bp],POST_CALL		;R46
		call	If_Code_Running_In_F000			;R85
		jne	short @F				;R46
		call	far ptr fPROC_Show_Help_On_The_Fly	;R46
	@@:							;R46
		ret						;R46

;R46		cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL
;R46		jne	short Show_Help_Exit
;R46
;R46		mov	byte ptr IN_F1_HELP[bp],0	;indicate not in F1
;R46							; e.g. Show_Calender will refer to this flag
;R46		mov	word ptr CURSOR_X[bp],(22 shl 8) + 1
;R46
;R46		mov	al,' '
;R46		mov	cx,78
;R46	@@:
;R46		call	Display_Char
;R46		loop	short @B
;R46		call	Vhilite
;R46
;R46		mov	si,[bx].HelpOffset
;R46		call	Display_String
;R46Show_Help_Exit:
;R46		ret

Show_Help_On_The_Fly	Endp

;R46 ;[]========================================================================[]
;R46 ;[]========================================================================[]
;R46 Display_Help_Str	proc	near
;R46 
;R46 		mov	si,[bx].HelpOffset	;get help string offset
;R46 		cmp	byte ptr ds:[si],0	;null string?
;R46 		jne	short @F		;no, continue
;R46 		jmp	No_Help			;yes, exit
;R46 	@@:
;R46 ;display help border
;R46 
;R46 		push	si			;save offset
;R46 		call	Vnormal			;normal attribute
;R46 		mov	si,offset Help_Border	;clear help area first
;R46 		call	Display_String
;R46 		pop	si			;restore si
;R46 
;R46 ;set margin
;R46 		call	Vnormal			;normal attribute
;R46 		mov	byte ptr LMARGIN_X[bp],22
;R46 		mov	CURSOR_X[bp],0916h
;R46 
;R46 ;display help strings
;R46 
;R46 		push	si			;save offset
;R46 		call	Display_String		;show help string
;R46 		pop	si			;restore si
;R46 
;R46 ;display standard help string
;R46 ;-----------------------------------------------------------------------
;R46 		cmp	si,offset Std_Help_Str	;does this item use
;R46 						; standard help?
;R46 		jne	short No_Quit		;no, exit
;R46 
;R46 
;R46 		mov	si,offset d4_msg
;R46 		call	Display_String
;R46 
;R46 		mov	dx,[bx].ItemMin		;started form min.
;R46 
;R46 Show_Available_Options:
;R46 
;R46 		push	dx			;save dx
;R46 		call	Check_VarNull
;R46 		jc	short Next_Avail_Option	;not available
;R46 
;R46 		call	Vnormal			;normal attribute
;R46 		call	Get_VarString_Offset
;R46 		call	Display_String		;available, display it
;R46 
;R46 		call	VHilite			;hilite attribute
;R46 
;R46 		call	Read_Item_Value		;get shift value (cl)
;R46 		pop	ax			;pop current option value
;R46 		push	ax			;push current option value
;R46 		mov	si,offset bios_d4_msg	;bios defaults string
;R46 		call	Get_Item_BIOS_D4	;get BIOS default in DX
;R46 		cmp	ax,dx			;current option = BIOS d4?
;R46 		jne	short @F		;no,
;R46 		push	ax
;R46 		call	display_String		;yes, show message
;R46 		pop	ax
;R46 	@@:
;R46 		mov	si,offset setup_d4_msg	;setup defaults string
;R46 		call	Get_Item_Setup_D4	;get setup d4 in DX
;R46 		cmp	ax,dx			;current option = setup d4?
;R46 		jne	short Option_Not_D4	;no,
;R46 		call	display_String		;yes, show message
;R46 Option_Not_D4:
;R46 		call	VNewLine		;next line
;R46 
;R46 Next_Avail_Option:
;R46 
;R46 		pop	dx			;restore dx
;R46 
;R46 		cmp	dx,[bx].ItemMax		;max. reached?
;R46 		jae	short Std_Help_Exit	;yes, leave
;R46 
;R46 		inc	dx			;next option
;R46 		jmp	short Show_Available_Options
;R46 Std_Help_Exit:
;R46 ;-----------------------------------------------------------------------
;R46 No_Quit:
;R46 		call	Key				;wait for key
;R46 		cmp	ax,K_F1				;is if 'F1'
;R46 		je	short @F			;yes
;R46 		cmp	ax,K_ESC1			;is if 'ESC'
;R46 		jne	short No_Quit			;no
;R46 	@@:
;R46 		mov	si,offset Clear_Help		;clear the help area
;R46 		call	Display_String			;
;R46 		mov	word ptr LAST_KEY[bp],0		;destroy key
;R46 No_Help:
;R46 		ret					;return to caller
;R46 
;R46 d4_msg		ADDX	<,23>
;R46 		db	'Default Type',NEWLINE
;R46 		ADDX	<,22>
;R46 		db	'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ'
;R46 		db	NEWLINE,0
;R46 setup_d4_msg	POS	<,54-2,>
;R46 		db	'<Setup>',0
;R46 bios_d4_msg	POS	<,45,>
;R46 		db	'<BIOS>',0
;R46 
;R46 Display_Help_Str	endp

;[]========================================================================[]
;Function :	Ask the user for Yes or no (Y/N)
;
;input:	CF = 0 (NC) ---> if ENTER pressed immediately, default to YES
;       CF = 1 (CY) ---> if ENTER pressed immediately, default to No
;
;output: 1: When ZF = 1	(ZR)
;		CF = 0 ---> YES
;	 	CF = 1 ---> NO
;
;	 2: When ZF = 0	(NZ)
;		ESC is pressed, CF the same as (1)
;
;Registers :	AX, FLAG - Destroyed
;[]========================================================================[]
Ask_Confirm	Proc	Near

		push	cx
		push	si

		pushf							;R56A
		or	byte ptr Post_Temp_Byte[bp],DO_NOT_UPDATE_TIME	;R56
		popf							;R56A

		mov	al,'N'			;if ENTER pressed --> YES
		mov	ah,'Y'
		jc	short @F
		xchg	ah,al
	@@:
		mov	KEYIN_BUF[bp+0],al
		mov	KEYIN_BUF[bp+1],ah
		add	ax,2020h
		mov	KEYIN_BUF[bp+2],al
		mov	KEYIN_BUF[bp+3],ah
		mov	cx,4
		call	ASK_INPUTS

		pushf								;R56
		and	byte ptr Post_Temp_Byte[bp],not DO_NOT_UPDATE_TIME	;R56
		popf								;R56

		pop	si
		pop	cx
		ret

Ask_Confirm	Endp

;[]========================================================================[]
;Function :	Ask the user for CHARs in KEYIN_BUF[bp]
;
;input	  :	CX number of CHARs to check
;		KEYIN_BUF[bp]
;
;output	  :	SI point to the input character in KEYIN_BUF[bp]
;		  e.g. KEYIN_BUF[bp+0] = 'A'
;		       KEYIN_BUF[bp+1] = 'Z'
;		       if input = 'A' --> SI=0
;				  'Z' --> SI=1
;
;		NC = 'Y' or 'y' is pressed
;		NZ = ESC is pressed
;[]========================================================================[]
		Public	ASK_INPUTS
ASK_INPUTS	Proc	Near
		push	dx			;save dx
		push	cx

		mov	si,KEYIN_BUF
Echo_Input:
		or	byte ptr ATTRIBUTE[bp],80h
		mov	al,[bp+si]
		push	si
		call	Display_Char		;display 'Y' or 'N' on screen
		pop	si
		dec	byte ptr CURSOR_X[bp]	;cursor position

Check_Confirm_D4:
		push	si
		call	key			;wait for key
		pop	si
		cmp	ax,K_CR1		;ENTER ?
		mov	dh,1			;for updating ZF
		je	short Got_Answer	;yes
		cmp	ax,K_ESC1		;ESC ?
		mov	dh,2			;for updating ZF
		je	short Got_Answer	;yes

		pop	cx
		push	cx
		mov	dx,si
		mov	si,KEYIN_BUF
	@@:
		cmp	al,[bp+si]
		je	short Echo_Input
		inc	si
		loop	short @B
		mov	si,dx
		jmp	short Check_Confirm_D4	;go and wait for ENTER/ESC

Got_Answer:
		sub	si,KEYIN_BUF
		cmp	byte ptr KEYIN_BUF[bp+si],'Y'
		je	short Ask_Confirm_Exit
		cmp	byte ptr KEYIN_BUF[bp+si],'y'
		je	short Ask_Confirm_Exit

		stc
Ask_Confirm_Exit:
		dec	dh			;set ZF for ESC
						;CF not affected
		pop	cx
		pop	dx			;restore dx
		ret				;return to caller
ASK_INPUTS	Endp

;[]========================================================================[]
;Function:	Change the color of the screen
;
;Input	:	AX - key input
;
;Output	:	i> if input AX = K_F2	---> next color style
;			    AX = K_SHFT_F2 ---> Previous Color
;		ii> Color_Offset[bp] point to current color structure
;
;Registers :	BX, AX - Preserved
;[]========================================================================[]
Change_Color	Proc	Near
;R91 -start
ifdef	Not_Change_Setup_Color			
		mov	byte ptr CMOS3B[bp],03h	
		ret				
else	;Not_Change_Setup_Color		
;R91 -end
		push	ax
		cmp	ax,K_F2
		jne	short Try_SHFT_F2
		add	byte ptr CMOS3B[bp],10h
		jmp	short @F
Try_SHFT_F2:
		cmp	ax,K_SHFT_F2
		jne	short Change_Color_Exit
		sub	byte ptr CMOS3B[bp],10h
	@@:
		mov	al,CMOS3B[bp]
		call	Get_Color_Off
		call	Refresh_Menu1

Change_Color_Exit:
		pop	ax
		ret
endif	;Not_Change_Setup_Color			;R91
Change_Color	Endp

;[]========================================================================[]
;Function :	Get the color set according to bit 7654 of
;		input AL
;
;Input	:	AL
;
;Output	:	word ptr Color_offset[bp] = offset of color set
;
;Registers :	CX, AX - Destroyed
;[]========================================================================[]
		Public	Get_Color_Off
Get_Color_Off	Proc	Near

		test	byte ptr Monochrome[bp],1
		jnz	short Is_Color
;Mono display
		mov	cx,offset MONO_Buffer
		test	al,10h
		mov	ax,0
		jz	short @F
		mov	ax,size Color_style
	@@:
		jmp	short Color_Style_Got
Is_Color:
		shr	al,4
		mov	cl,size Color_style
		mul	cl
		mov	cx,offset VGA_Buffer

Color_Style_Got:
		add	ax,cx
		mov	Color_Offset[bp],ax

		ret
Get_Color_Off	Endp

;[]========================================================================[]
;Function :	check the current display mode
;
;Input	:	None
;
;Output	:	MONOCHROME[bp] :   0  - MONO Display
;				   1  - COLOR Display
;		Color_Offset[bp] : offset MONO_Buffset for MONO
;					  VGA_Buffer	   Color
;[]========================================================================[]
Check_Display_Mode	proc	near
;Check current mode is monochrome or color
		mov	ah,0fh
		int	10h				;get mode
		xor	ah,ah				;assume mono
		mov	word ptr Color_Offset[bp],offset MONO_Buffer
		test	byte ptr EQUIPMENT[bp],DT_MONO
		cmp	al,07h
		je	short Yes_Mono
		mov	ah,1
		mov	word ptr Color_Offset[bp],offset VGA_Buffer
Yes_Mono:
		mov	byte ptr MONOCHROME[bp],ah
		ret
Check_Display_Mode	endp

;R46 ;[]========================================================================[]
;R46 ;Function :	Save standard CMOS and extended CMOS datas
;R46 ;
;R46 ;Input :	DI : 0 - write CMOS checksum bytes
;R46 ;		     1 - write CMOS checksum bytes and load default if checksum fail
;R46 ;
;R46 ;Output:	None
;R46 ;[]========================================================================[]
;R46 		public	Check_CMOS_Sum
;R46 Check_CMOS_Sum	proc	near
;R46 
;R46 		push	cs
;R46 		pop	ds
;R46 
;R46 		mov	al,CUR_PAGE[bp]		;save current page no.
;R46 		push	ax
;R46 
;R46 
;R46 ;get start, end & checksum location
;R46 		mov	si,offset Cmos_Check_Sum
;R46 Next_Sum:
;R46 		lodsb
;R46 		or	al,al
;R46 		jnz	short @F
;R46 		jmp	Finish_Sum
;R46 @@:
;R46 
;R46 		mov	cl,al			;start of checksum
;R46 		lodsb
;R46 		mov	ch,al			;end of checksum
;R46 		lodsb
;R46 		mov	dl,al			;checksum low byte
;R46 		xor	dh,dh
;R46 
;R46 ;start calculation of checksum
;R46 
;R46 		push	si
;R46 
;R46 		xor	bx,bx
;R46 		xor	ah,ah
;R46 		mov	si,cx
;R46 		and	si,0ffh			;low byte only
;R46 Next_Cmos_Byte:
;R46 		mov	al,[bp+si]
;R46 		add	bx,ax
;R46 		inc	si
;R46 		inc	cl
;R46 		cmp	cl,ch
;R46 		jbe	short Next_Cmos_Byte
;R46 		mov	si,dx			;checksum byte location
;R46 						; was stored in dx
;R46 		or	di,di			;does caller request
;R46 						; to write checksum byte ?
;R46 		jz	short Save_Only		;yes, do it!
;R46 
;R46 		cmp	[bp+si],bh		;checksum valid?
;R46 		jne	short Default_It	;no, load default
;R46 		cmp	[bp+si+1],bl		;checksum byte valid?
;R46 		je	short Check_Next_Sum	;yes, check next checksum!
;R46 Default_It:
;R46 		pusha
;R46 		mov	di,SetupDef		;load setup defaults
;R46 		mov	cl,2			;started from stdcmos
;R46 		call	Load_All_Default	;load all defaults
;R46 
;R46 ;R04;---------------------------------------------------------
;R46 ;R04;write default time back to CMOS
;R46 ;R04;---------------------------------------------------------
;R46 ;R04		cmp	byte ptr CALLTYPE[bp],POST_CALL
;R46 ;R04		jne	short Dont_Write_Time
;R46 ;R04
;R46 ;R04		mov	si,offset Update_Time_Tbl
;R46 ;R04Update_Next_Date:
;R46 ;R04		lodsw
;R46 ;R04		mov	bx,ax
;R46 ;R04		call	Write_Time_To_CMOS1
;R46 ;R04		lodsb
;R46 ;R04		cmp	si,offset Update_Item_End
;R46 ;R04		jb	short Update_Next_Date
;R46 ;R04
;R46 ;R04Dont_Write_Time:
;R46 
;R46 		call	Set_HDD_To_Defaults
;R46 
;R46 ;---------------------------------------------------------
;R46 		popa
;R46 
;R46 		or	byte ptr CMOS0E[bp],CKSM_STATUS+EQUIP_STATUS
;R46 		and	byte ptr CMOS14[bp],not 0C2h	;default 1 FDD, no Coprocessor
;R46 		and	byte ptr CMOS11[bp],0FDh	;default to password invalid
;R46 		and	byte ptr CMOS3B[bp],0Fh		;load default color
;R46 
;R46 ;R35 - Start
;R46 ifdef	Always_Password_Need
;R46 		mov	al, 11h
;R46 		call	Get_Cmos
;R46 		xchg	ah, al
;R46 		or	ah, 00000010b
;R46 		mov	al, 11h
;R46 		call	Set_Cmos
;R46 		or	byte ptr CMOS11[bp], 2
;R46 endif	;Always_Password_Need
;R46 ;R35 - End
;R46 
;R46 ;R01 - start
;R46 ifdef	Double_Password
;R46 		push	di
;R46 		call	Ct_User_Password_Location	;get second password CMOS
;R46 		not	dl				;disable password
;R46 		and	[bp+si],dl			;clear password flag
;R46 		pop	di
;R46 endif;	Double_Password
;R46 ;R01 - end
;R46 
;R46 ifndef	DOSVERSION
;R46 		mov	al,cs:COLOR_SETTING
;R46 		shl	al,4
;R46 		or	byte ptr CMOS3B[bp],al
;R46 endif	;DOSVERSION
;R46 
;R46 		test	byte ptr CMOS10[bp],0FFh
;R46 		jz	short @F
;R46 		or	byte ptr CMOS14[bp],01h
;R46 	@@:
;R46 
;R46 ;R45		mov	byte ptr CMOS32[bp],19
;R46 ;R45		mov	byte ptr CMOS09[bp],95	;R08
;R46 
;R46 		pop	si
;R46 		jmp	short finish_Sum
;R46 Save_Only:
;R46 		mov	[bp+si],bh		;checksum low byte
;R46 		mov	[bp+si+1],bl		;checksum high byte
;R46 
;R46 Check_Next_Sum:
;R46 		pop	si
;R46 		jmp	Next_Sum
;R46 Finish_Sum:
;R46 		pop	ax
;R46 		mov	CUR_PAGE[bp],al		;restore current page no.
;R46 		ret
;R46 Check_CMOS_Sum	endp

;[]========================================================================[]
;Function :	if cmos fails, load defaults for page CFEATURE
;
;note :		call from post.asm right after measuring CPU speed
;[]========================================================================[]
		Public	Load_Auto_Cfg_D4
Load_Auto_Cfg_D4:
		test	byte ptr CMOS0E[bp],CKSM_STATUS
		jz	short D4_Exit
		mov	byte ptr USE_ITEMSTAT_BUF[bp],03h
		mov	di,SetupDef		;load setup defaults
		mov	al,PAGE_CFEATURE	;started from cfeature

		push	cs
		pop	ds
		call	Init_Page
		call	Load_Page_Default
D4_Exit:
		ret

;[]========================================================================[]
;Function :	Save standard CMOS and extended CMOS
;
;Input :	None
;
;Output:	None
;[]========================================================================[]
Save_All_Cmos	proc	near

;R46 ifndef	DOSVERSION
;R46 		mov	ah,byte ptr CMOS32[bp]	;convert century to BCD
;R46 		call	Hex_To_Bcd
;R46 		mov	byte ptr CMOS32[bp],ah	;convert century to BCD
;R46 
;R46 ;R19 start
;R46 		cmp	byte ptr EXT_FIXED_0[bp],47
;R46 		jne	short @F
;R46 		mov	bx,offset HDDC_ITEM
;R46 		call	Get_HDD_CMOS_Info
;R46 		cmp	word ptr [bp+di+0],0
;R46 		jne	short @F
;R46  		and	byte ptr FIXED_TYPE[bp],0fh
;R46 @@:
;R46 ;R19 end
;R46 ;R13 start
;R46 		cmp	byte ptr EXT_FIXED_1[bp],47
;R46 		jne	short @F
;R46 ;R13A start
;R46 		mov	bx,offset HDDD_ITEM
;R46 		call	Get_HDD_CMOS_Info
;R46 		cmp	word ptr [bp+di+0],0
;R46 		jne	short @F
;R46 ;R13A end
;R46  		and	byte ptr FIXED_TYPE[bp],0f0h
;R46 @@:
;R46 ;R13 end
;R46 ;R06 start
;R46 		cmp	byte ptr EXT_FIXED_0[bp],49
;R46 		jne	short @F
;R46 		mov	byte ptr EXT_FIXED_0[bp],46
;R46 @@:
;R46 		cmp	byte ptr EXT_FIXED_1[bp],48
;R46 		jne	short @F
;R46 		mov	byte ptr EXT_FIXED_1[bp],46
;R46 @@:
;R46 ifdef	Support_4_IDE
;R46 		cmp	byte ptr CMOS_HDDE[bp],51
;R46 		jne	short @F
;R46 		mov	byte ptr CMOS_HDDE[bp],46
;R46 @@:
;R46 		cmp	byte ptr CMOS_HDDF[bp],50
;R46 		jne	short @F
;R46 		mov	byte ptr CMOS_HDDF[bp],46
;R46 @@:
;R46 endif	;Support_4_IDE
;R46 ;R06 end
;R46 		xor	di,di
;R46 		call	Check_CMOS_Sum
;R46 
;R46 		mov	di,offset Cmos_Check_Sum
;R46 
;R46 		mov	ch,CMOS10	;start & end locations to save
;R46 		mov	cl,CMOS3F
;R46 	@@:
;R46 		call	Save_CMOS_Bytes
;R46 		mov	ch,[di+2]
;R46 		mov	cl,ch
;R46 		inc	cl
;R46 		call	Save_CMOS_Bytes	;save checksum word
;R46 
;R46 		add	di,3
;R46 		mov	ch,[di]		;next start & end locations to save
;R46 		mov	cl,[di+1]
;R46 		or	ch,ch
;R46 		jnz	short @B
;R46 
;R46 ;R30 - starts
;R46 	;-------------------------------------------------------------------
;R46 	;Clear RTC_STATUS, EQUIP_STATUS for CMOS 0Eh when saving CMOS from 
;R46 	;stack. This is to prevent DOS from treating all FDD drives as 360K
;R46 	;type !
;R46 	;-------------------------------------------------------------------
;R46 
;R46 		mov	ax, (CMOS_STATUS shl 8) + CMOS_STATUS
;R46 		call	Get_CMOS
;R46 		and	al, not (RTC_STATUS + EQUIP_STATUS)
;R46 		xchg	ah, al
;R46 		call	Set_CMOS
;R46 ;R30 - ends
;R46 
;R46 endif	;DOSVERSION
;R46 
;R46 		ret
;R46 
;R46 Save_CMOS_Bytes:
;R46 		mov	si,cx
;R46 		and	si,0ffh
;R46 Save_Byte:
;R46 		mov	al,cl
;R46 		mov	ah,[bp+si]
;R46 		call	Set_Cmos
;R46 		dec	si
;R46 		dec	cl
;R46 		cmp	cl,ch
;R46 		jae	short Save_Byte

		call	far ptr fPROC_Save_All_Cmos
		ret

Save_All_Cmos	endp

;[]========================================================================[]
;Function ;	1. write all CMOS locations related to user defined HDD to 0
;		2. Program byte ptr CMOS12[bp]/FIXED_TYPE[bp] to correct
;		   format
;
;Input :	None
;
;Output	:	None
;
;Registers :	----
;
;Note	:	Only be called if CMOS checksum is fail, i.e. call from
;		routine Check_CMOS_Sum
;[]========================================================================[]
Set_HDD_To_Defaults	Proc	Near

		mov	di,DRV_48_CYL
		call	Clear_All_HDD_Params

		mov	di,DRV_49_CYL
		call	Clear_All_HDD_Params

ifdef	Support_4_IDE
		mov	di,DRV_50_CYL
		call	Clear_All_HDD_Params
		mov	di,DRV_51_CYL
		call	Clear_All_HDD_Params
endif	;Support_4_IDE

;[]========================================================================[]
;Function :	Program byte ptr CMOS12[bp]/FIXED_TYPE[bp] to correct format
;
;Input :	CMOS19[bp] & CMOS1A[bp]
;
;Output	:	None
;
;Registers :	----
;[]========================================================================[]
;R83 Set_CMOS12h:
Set_CMOS12h	Label	Near			;R83
		mov	al,0F0h
		cmp	byte ptr CMOS19[bp],16		;drive c
		jae	short @F
		mov	cl,CMOS19[bp]
		shl	cl,4
		and	al,0Fh
		or	al,cl
		mov	byte ptr CMOS19[bp],0
	@@:
		or	al,0fh
		cmp	byte ptr CMOS1A[bp],16		;drive c
		jae	short @F
		mov	cl,CMOS1A[bp]
		and	al,0F0h
		or	al,cl
		mov	byte ptr CMOS1A[bp],0
	@@:
		mov	CMOS12[bp],al

		ret

Set_HDD_To_Defaults	Endp

;----------------------------------------------------------------
;function:	Clear 8 consecutive bytes starting from DI
;input	 :	DI = starting CMOS address to clear
;output	 :	None
;----------------------------------------------------------------
Clear_All_HDD_Params:
		mov	cx,8
	@@:
		mov	byte ptr [bp+di],0
		inc	di
		loop	@B
		ret

;[]========================================================================[]
;Function :	Load setup defaults for pages started from which CL is
;		specified
;
;Input	:	CL - from which page the setup defauts is to to loaded
;
;Output	:	None
;
;Registers :	BX - Preserved
;		Others - Unknown
;[]========================================================================[]
Load_All_Default	Proc	Near
		mov	byte ptr USE_ITEMSTAT_BUF[bp],03h
Next_Page_D4:
		push	cx
		mov	al,cl
		call	Init_Page
		jnc	short Invalid_Page
		call	Load_Page_Default
		align 16
Invalid_Page:
		pop	cx
		inc	cl
		cmp	cl,MAXPAGE
		jbe	short Next_Page_D4
		mov	byte ptr USE_ITEMSTAT_BUF[bp],00h

		ret
Load_All_Default	Endp

;[]========================================================================[]
;Function :	Load current page's default
;
;Input	:	DI = SetupDef    ---> Load setup default
;		DI = RomDefault  ---> Load BIOS default
;		DI = 0FFFFh      ---> Laad old value
;
;Output	:	NONE
;
;Registers:	AX,CX,SI,DX - Destroyed
;		Others	    - Preserved
;[]========================================================================[]
Load_Page_Default	proc	near
		push	bx
		mov	bx,PAGE_START[bp]	;start from first item
Next_Def:
ifdef	LOAD_CMOS_FOR_ITEMDISABLE					   ;R28
		test	word ptr [bx].ItemStat,NODEFAULT+HIDDEN		   ;R28
else;	LOAD_CMOS_FOR_ITEMDISABLE					   ;R28
		test	word ptr [bx].ItemStat,NODEFAULT+HIDDEN+ITEMDISABLE
endif;	LOAD_CMOS_FOR_ITEMDISABLE					   ;R28

		jnz	short Only_Byte

;check if caller want to load old value
;-------------------------------------------------------------------------
		cmp	di,0FFFFh			;load old value?
		jne	short Not_Load_Old_Value	;no

		call	Read_Item_Value		;get shift value in CL

   		xor	dx,dx				;clear DX first
		mov	al,[bx].CmosLoc			;get CMOS location
		mov	ah,al				;save to ah
		call	Get_Cmos			;get CMOS value
		mov	dl,al				;low byte
		test	word ptr [bx].CmosMask,0FF00h	;word value ?
		jz	short @F			;no
		mov	al,ah				;cmos location
		inc	al				;high byte location
		call	Get_Cmos			;cmos value
		mov	dh,al				;write to high byte
@@:
		and	dx,[bx].CmosMask
		shr	dx,cl
		test	byte ptr CMOS0E[bp],CKSM_STATUS	;checksum fail?
		jz	short Copy_D4_To_Stack		;no
		call	Get_Item_Setup_D4		;get setup default
		jmp	short Copy_D4_To_Stack

Not_Load_Old_Value:
;-------------------------------------------------------------------------

		call	Get_Item_Setup_D4	;get setup default
		cmp	di,SetupDef		;Setup default requested ?
		je	short Copy_D4_To_Stack	;Setup default !
		call	Get_Item_BIOS_D4	;get ROM default

Copy_D4_To_Stack:

		call	Write_Item_Value		;put into stack
Only_Byte:
		add	bx,ITEM_SIZE
		cmp	bx,PAGE_END[bp]
		jb	short Next_Def
		pop	bx
		ret

Load_Page_Default	endp

;[]========================================================================[]
;Function :	Read CMOS data into stack
;		if check sum fail, load defaults
;
;Input	:	BP
;
;Output	:	None
;
;note	:	call from POST for BIOS version, start of setup for DOS version
;[]========================================================================[]
Read_Cmos_To_Stack	proc	near

;R46 		mov	cx,80h			;total 128 bytes to read
;R46 		mov	si,CMOS00
;R46 
;R46 Next_Cmos:
;R46 		mov	ax,si
;R46 		call	Get_Cmos
;R46 
;R46 		mov	[bp+si],al
;R46 		inc	si
;R46 		loop	short Next_Cmos
;R46 
;R46 		call	Check_Valid_HDD_Type
;R46 		call	Read_RtcTime
;R46 
;R46 ;R02		mov	al,0fh			;turn on NMI
;R46 ;R02		out	70h,al
;R46 ;R02		NEWIODELAY
;R46 
;R46 		mov	di,1	  		;don't write CMOS checksum bytes
;R46 		call	Check_CMOS_Sum
;R46 
;R46 		call	Tran_HDD_User_Type	;R06

		call	far ptr fPROC_Read_Cmos_To_Stack	;R46
		ret

Read_Cmos_To_Stack	endp

;R06 start
		public	Tran_HDD_User_Type
Tran_HDD_User_Type	Proc	Near
;R19 start
		cmp	byte ptr EXT_FIXED_0[bp],47
		jne	short @F
 		or	byte ptr FIXED_TYPE[bp],0f0h
@@:
;R19 end
;R13 start
		cmp	byte ptr EXT_FIXED_1[bp],47
		jne	short @F
 		or	byte ptr FIXED_TYPE[bp],0fh
@@:
;R13 end
		cmp	byte ptr EXT_FIXED_0[bp],46
		jne	short @F
		mov	byte ptr EXT_FIXED_0[bp],49
@@:
		cmp	byte ptr EXT_FIXED_1[bp],46
		jne	short @F
		mov	byte ptr EXT_FIXED_1[bp],48
@@:
ifdef	Support_4_IDE
		cmp	byte ptr CMOS_HDDE[bp],46
		jne	short @F
		mov	byte ptr CMOS_HDDE[bp],51
@@:
		cmp	byte ptr CMOS_HDDF[bp],46
		jne	short @F
		mov	byte ptr CMOS_HDDF[bp],50
@@:
endif	;Support_4_IDE
		ret
Tran_HDD_User_Type	ENDP
;R06 end

;R46 ;[]========================================================================[]
;R46 ;Function :	Read RTC and transfer to hex number into stack area
;R46 ;
;R46 ;Input	:	NONE
;R46 ;
;R46 ;Output	:	NONE
;R46 ;[]========================================================================[]
;R46 Read_RtcTime	proc	near
;R46 		push	si
;R46 		mov	si,CMOS00
;R46 		mov	cx,10			;total 10 bytes to read
;R46 Rtc1:
;R46 		mov	ax,si
;R46 		call	Get_Cmos		;read RTC time
;R46 		call	Bcd_To_Hex		;convert to hex number
;R46 		cmp	si,CMOS00		;Is second field
;R46 		jne	short Not_Sec
;R46 		cmp	bx,offset SECOND_ITEM	;processing second filed
;R46 		je	short No_Updation
;R46 Not_Sec:
;R46 		mov	[bp+si],al		;store in stack
;R46 No_Updation:
;R46 		inc	si
;R46 		loop	short Rtc1
;R46 
;R46 		mov	si,CMOS32
;R46 		mov	ax,si
;R46 		call	Get_Cmos		;read RTC time
;R46 		call	Bcd_To_Hex		;convert to hex number
;R46 		mov	[bp+si],al		;store in stack
;R46 		pop	si
;R46 		ret
;R46 Read_RtcTime	endp

;[]========================================================================[]
;Function :	Load old values(CMOS value) for current page
;
;Input	:	None
;
;Output	:	None

;Registers :	BX     - Preserved
;		Others - Destroyed or Unknown
;[]========================================================================[]
Old_Value	Proc	Near
		mov	si,offset Old_Value_Msg
		mov	di,0FFFFh
		mov	ax,K_F5
		call	F5_F6_F7
		ret
Old_Value	endp

Old_Value_Msg	Label	Near
		db	V_REVERSE
		BORDER1	<,18,11,61,15,Empty_Border>
		POS	<,20,13>
;R20		db	' Load Old Values for this page(Y/N) ? ',0
		db	' Load Old Values'				;R20
ForThisPageStr	db	' for this page (Y/N)? ',0			;R20

;[]========================================================================[]
;Function :	Load BIOS defaults for current page
;
;Input	:	None
;
;Output	:	None

;Registers :	BX     - Preserved
;		Others - Destroyed or Unknown
;[]========================================================================[]
Page_BIOS_D4	Proc	Near

;R20 - starts
		mov	ax, K_F6
		cmp	ax, LAST_KEY[bp]
		jne	short @F

		call	If_BIOS_D4_Needed
		jnz	short Page_BIOS_D4_Exit
	@@:
;R20 - ends

		mov	si,offset Page_BIOS_D4_Msg
		mov	di,RomDefault
;R20		mov	ax,K_F6
		call	F5_F6_F7

Page_BIOS_D4_Exit:					;R20

		ret
Page_BIOS_D4	Endp

Page_BIOS_D4_Msg	Label	Near
		db	V_REVERSE
		BORDER1	<,18,11,61,15,Empty_Border>
;R20		POS	<,20,13>
;R20		db	'Load BIOS Default for this page (Y/N)? ',0
		STRSHOW	<,19,13,offset LoadBIOSD4Str>			;R20
		STRSHOW	<,,,offset ForThisPageStr>			;R20
		db	0						;R20

;R20 - starts
		Public	If_BIOS_D4_Needed
If_BIOS_D4_Needed	Proc	Near

	test	word ptr cs:[Load_BIOS_D4_Item].ITEMSTAT, ITEMDISABLE
	ret

If_BIOS_D4_Needed	Endp
;R20 - ends

;[]========================================================================[]
;Function :	1. Load setup defaults for current page
;		2. Load value according to Auto-Cfg table for item which
;		   is to be auto-cfg
;
;Input	:	None
;
;Output	:	None
;
;Registers :	BX     - Preserved
;		Others - Destroyed or Unknown
;[]========================================================================[]
Page_SETUP_D4	Proc	Near

;R20 - starts
		mov	ax, K_F7
		cmp	ax, LAST_KEY[bp]
		jne	short @F

		call	If_Setup_D4_Needed
		jnz	short Page_SETUP_D4_Exit
	@@:
;R20 - ends

		mov	si,offset Page_SETUP_D4_Msg
		mov	di,SetupDef
;R20		mov	ax,K_F7
		call	F5_F6_F7

Page_SETUP_D4_Exit:					;R20

		ret

Page_SETUP_D4	Endp

Page_SETUP_D4_Msg	Label	Near
		db	V_REVERSE
		BORDER1	<,18,11,61,15,Empty_Border>
		POS	<,20,13>
;R20		db	'Load SETUP Default for this page(Y/N)? ',0
		STRSHOW	<,19,13,offset LoadSetupD4Str>			;R20
		STRSHOW	<,,,offset ForThisPageStr>			;R20
		db	0						;R20

;R20 - starts
		Public	If_Setup_D4_Needed
If_Setup_D4_Needed	Proc	Near

	test	word ptr cs:[Load_SETUP_D4_Item].ITEMSTAT, ITEMDISABLE
	ret

If_Setup_D4_Needed	Endp
;R20 - ends

;[]========================================================================[]
;Function :	Load values for current page according to input DI
;
;input :	SI - point to message to show
;		DI - RomDefault: Load BIOS ROM default
;     		SetupDef  : Load BIOS Setup default
;     		0FFFFh    : Load old value
;		AX - KEY to compare (F5, F6 or F7)
;
;Output	:	None
;
;Registers :	BX, DI - Preserved
;		Others - Unknown or destroyed
;[]========================================================================[]
F5_F6_F7	Proc	Near
		cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL	;kernal ?
		je	short F5_F6_F7_Exit			;yes, exit
		cmp	byte ptr CUR_PAGE[bp],PAGE_STDCMOS	;standard CMOS?
		je	short F5_F6_F7_Exit			;yes, exit

		cmp	ax,LAST_KEY[bp]		;correct key pressed?
		jne	short F5_F6_F7_Exit	;no, exit

		call	Display_String		;show message to user
		stc				;default NO
		call	Ask_Confirm		;ask user for confirmation
		mov	word ptr LAST_KEY[bp],0	;invalidate key

		jnz	short F5_F6_F7_Exit0	;'ESC' is pressed
		jc	short F5_F6_F7_Exit0	;'N' is pressed

		call	Load_Page_Default

F5_F6_F7_Exit0:
		mov	si,offset Std_Clr_Str1	;clear the message
		call	Display_String		;clear the message
		call	Refresh_Menu		;re-display screen
F5_F6_F7_Exit:

		CHK_ITEMSTAT HIDDEN+SHOWONLY+ITEMDISABLE
		jz	short @F
		mov	word ptr LAST_KEY[bp],DOWN_ARROW
@@:
		mov	ax,LAST_KEY[bp]		;restore LAST_KEY
		ret				;return to caller
F5_F6_F7	Endp

;[]========================================================================[]
;Function :	Increase item value for input key = PGDN/K_PLUS
;		Decrease item value for input key = PGUP/K_MINUS
;
;Input	:	BX - item offset
;		LAST_KEY[bp]
;
;Output	:	[BX].CmosLoc will be updated
;[]========================================================================[]
		Public	Do_Plus_Minus_Key
Do_Plus_Minus_Key	PROC	NEAR

		mov	bx,OLDITEM[bp]
		cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL
		je	short Key_Exit1

		mov	al,Special_Before	;Pre-Do i.e. special Do before
		call	Special_Do		;	     standard Do
		jnc	short @F
		ret
@@:
		mov	bx,OLDITEM[bp]
		mov	ax,LAST_KEY[bp]

		push	ax
		call	Read_Item_Value
		pop	ax

		cmp	ax,K_PLUS
		je	short Inc_Value
		cmp	ax,PGDN
		je	short Inc_Value

		cmp	ax,K_MINUS
		je	short Dec_Value
		cmp	ax,PGUP
		jne	short Key_Exit
Dec_Value:
		call	Prev_Item_Value
		jmp	short Process_Key
Inc_Value:
		call	Next_Item_Value
Process_Key:
		call	Write_Item_Value
Key_Exit:
		mov	al,Special_After	;Post-Do i.e. special Do after
		call	Special_Do		;	      standard Do
		mov	ax,LAST_KEY[bp]
Key_Exit1:
		ret

Do_Plus_Minus_Key	ENDP

;[]========================================================================[]
;Function :	Get next item value.
;		Item range & "available or not" is taken into consideration
;
;Input	:	DX - current item value
;
;Output	:	DX - next item value
;[]========================================================================[]
		Public	Next_Item_Value			;R07
Next_Item_Value	Proc	Near
		push	di
		mov	cx,1
		mov	si,ItemMin

;R83 Next_Item_Value_1:
Next_Item_Value_1	Label	Near		;R83

		add	dx,cx

		call	Check_Item_Range
		jnc	short @F
		mov	dx,[bx+si]
	@@:
		call	Check_VarNull
		jc	short Next_Item_Value_1

		pop	di

		ret
Next_Item_Value	Endp

;[]========================================================================[]
;Function :	Get previous item value.
;		Item range & "available or not" is taken into consideration
;
;Input	:	DX - current item value
;
;Output	:	DX - previous item value
;[]========================================================================[]
		Public	Prev_Item_Value			;R07
Prev_Item_Value	Proc	Near
		push	di
		mov	cx,-1
		mov	si,ItemMax
		jmp	short Next_Item_Value_1
Prev_Item_Value	Endp

;[]========================================================================[]
;Function :	Get input if item is KEYIN type
;
;Input	:	BX - Item offset
;
;Output	:	[BX].CmosLoc will be updated
;[]========================================================================[]
Do_Key_In_Item	Proc	Near

		mov	bx,KEYIN_ITEM_OFF[bp]

;if key is control key, exit

		mov	ax,LAST_KEY[bp]
		call	Chk_Ctrl_Key		;check if key = control key
		jnz	short @F
		ret				;Key got was control key
@@:


;if KEYIN is not defined then exit

		CHK_ITEMSTAT KEYIN
		jnz	short @F
		ret				;this item is not key-in type
@@:
		pusha

;if key != number, exit

		mov	dl,EDIT_DEC
		CHK_ITEMSTAT SHOWHEX
		jz	short @F
		or	dl,EDIT_HEX
@@:
		call	Qualify_Key		;is it a valid key or not ?
		jnc	short @F
		jmp	short Key_In_End
@@:

;check if there is special Pre-Do

		mov	al,Special_Before	;Pre-Do i.e. special Do before
		call	Special_Do		;	     standard Do
		jnc	short @F
		jmp	short Key_In_End
@@:
		mov	bx,KEYIN_ITEM_OFF[bp]

;determine how many characters to get

		call	Get_ItemStat_AX
		and	ax,NO_OF_DIGIT

		mov	cx,2
		cmp	ax,DIGIT2
		je	short @F

		mov	cx,3
		cmp	ax,DIGIT3
		je	short @F

		mov	cx,4
		cmp	ax,DIGIT4
		je	short @F

		mov	cx,5
@@:
;calculate cursor position

;R70		call	Vnormal
;R70		mov	al,[bx].Item_Xaxis	;get column position
;R70		mov	CURSOR_X[bp],al		;set column position
;R70		mov	al,[bx].Item_Yaxis	;get row position
;R70		mov	CURSOR_Y[bp],al		;set row position
;R70		mov	si,[bx].ItemName
;R70		call	Display_String

		pusha				;R70
		call	Disp_ItemTitle		;R70
		popa				;R70

		call	Edit_String		;get string into KEYIN_BUF[bp]

		cmp	byte ptr KEYIN_BUF[bp],0;no keyin ?
		je	short No_Key_In		;yes, skip
		call	Conv_Buf_To_Hex		;convert the buffer ASCII
						;ASCII into hex number
		mov	dx,ax			;
		call	Write_Item_Value		;save it into cmos location
No_Key_In:
		mov	al,Special_After	;Post-Do i.e. special Do after
		call	Special_Do		;	      standard Do

Key_In_End:
		popa
		ret
Do_Key_In_Item	Endp

;[]========================================================================[]
;Function : Get a string inpurt from KB
;
;Input	: 1. CURSOR_X[bp] & CURSOR_Y[bp] point to position where
;	     string is to be echoed
;	  2. CL = no of characters to get
;	  3. LAST_KEY[bp]
;	  4. DL: Editing  mask  (7=Mask output as '*'
;				 6=Reserved
;				 5=Reserved
;				 4=allow punctuations
;				 3=Allow hex alphabet (A-F,a-f)
;				 2=Allow dec numbers (0-9)
;				 1=Allow lower-case alphabet ("a"-"z", "_")
;				 0=Allow upper-case alphabet ("A"-"Z", "_")
;
;Output	: input ASCII will be placed in KEYIN_BUF[bp]
;[]========================================================================[]
Edit_String	Proc	Near

;blank the item variable field on screen

		push	cx			;save input cx
		xor	ch,ch
		call	Vreverse		;reverse attribute
		push	word ptr CURSOR_X[bp]	;save cursor
Put_Blank:
		mov	al,' '
		call	Display_Char		;display ' '
		loop	short Put_Blank		;next blank
		pop	word ptr CURSOR_X[bp]	;restore cursor
		pop	cx			;restore input cx

		mov	ch,cl

;Echo the character onto screen

		mov	di,KEYIN_BUF		;di point to KEYIN_BUF
		mov	ax,LAST_KEY[bp]		;get last key
Echo_Char:
		call	Vreverse		;reverse attribute
		call	Qualify_Key		;is it valid key ?
		jc	short Get_Key		;no
		push	ax			;save key
		test	dl,ECHO_ASTERISK	;echo '*' ?
		jz	short @F		;no
;R87 - starts
ifdef Password_PSON_By_Chipset
INEnter:
		push	ax
		push	bx
		cmp	byte ptr Item_P[bp],08h	       ;KB power on			
		jne  	short Non_save
		mov	bx,di	      		       ;di Key in counter	
		and	bl,0fh			       ;save low 4 bit
		or	bl,80h
		mov	al,bl
     		out	72h,al
		mov	al, ah
		out	73h,al

		mov	al,81h
		out	72h,al
		mov	al,bl			      ;save counter value		
		out	73h,al

Non_save:
		pop	bx
		pop	ax
endif;	Password_PSON_By_Chipset
;R87 - ends
		mov	al,'*'			;yes
	@@:
		call	Display_Char		;echo it on screen
		pop	ax			;restore key

		mov	[bp+di],al		;put character into buffer
		inc	di			;point to next byte
		dec	cl			;decrease counter
	PUBLIC	Get_Key				;R66
Get_Key		Label	Near			;R83 
;R83 Get_Key:
		call	key			;wait for key
		pushf
		cmp	word ptr LAST_KEY[bp],K_ESC1
		je	short Key_In_Exit1
		popf
		jz	short Key_In_Exit	;special control key detected

		cmp	ax,K_BS1		;back space?
		jne	short Not_Backspace	;no
		cmp	cl,ch			;spaces to go left?
		je	short Get_Key		;no more, get input again!
		mov	word ptr [bp+di],0	;clear input buffer for 1 byte
		dec	di			;point to previous address
		dec	byte ptr CURSOR_X[bp]	;decrease X coordinate
		mov	al,' '
		call	Vreverse		;reverse attribute
		call	Display_Char		;display ' '
		dec	byte ptr CURSOR_X[bp]	;decrease X coordinate
		inc	cl			;increase counter
		jmp	short Get_Key		;get input again
Not_Backspace:
		cmp	cl,0			;maximum no of input reached?
		jne	short Echo_Char		;no, echo it out
		jmp	short Get_Key		;wait for next key
Key_In_Exit:
		mov	byte ptr [bp+di],0	;put 0 into buffer
		clc
		ret

Key_In_Exit1:
		popf
		mov	byte ptr KEYIN_BUF[bp],0;no keyin
		clc
		ret

Edit_String	Endp

;[]========================================================================[]
;Function :	Check whether AL is a valid ASCII or not
;
;input	:	al = ASCII input
;		DL: Editing  mask  (b4=Allow punctuation
;				    b3=Allow hex alphabet (A-F,a-f)
;				    b2=Allow dec numbers (0-9)
;				    b1=Allow lower-case alphabet (a-z))
;				    b0=Allow upper-case alphabet (A-Z))
;
;output	:	CF - invalid ASCII
;		NC - valid ASCII
;[]========================================================================[]
Qualify_Key	Proc	Near
		push	cx
		push	si
		mov	si,offset Key_Qualify_Tbl
		mov	cx,No_Of_Key_Grp
Qualify_Next:
		cmp	al,cs:[si]
		jb	short Qualify_Exit

		cmp	al,cs:[si+1]
		ja	short Qualify_Exit

		test	dl,cs:[si+2]
		jnz	short Qualify_Pass
Qualify_Exit:
		add	si,3
		loop	short Qualify_Next

;;Qualify Fail
		pop	si
		pop	cx
		stc
		ret
Qualify_Pass:
		pop	si
		pop	cx
		clc
		ret
Qualify_Key	Endp

Key_Qualify_Tbl	db	'0','9',EDIT_DEC
		db	'_','_',EDIT_UPPER+EDIT_LOWER
		db	'A','Z',EDIT_UPPER
		db	'a','z',EDIT_LOWER
		db	'A','F',EDIT_HEX
		db	'a','f',EDIT_HEX
		db	' ','/',EDIT_PUNCT
		db	':','@',EDIT_PUNCT
		db	'[','`',EDIT_PUNCT
		db	'{','',EDIT_PUNCT
No_Of_Key_Grp	EQU	($-offset Key_Qualify_Tbl)/3

;[]========================================================================[]
;Function :	convert the ASCII code in KEYIN_BUF[bp] to HEX
;		until: - 00h is reached
;		       - input CH reach 0
;
;input	:	CH = maximum no of bytes in KEYIN_BUF to be converted
;
;output	:	AX = HEX number
;[]========================================================================[]
Conv_Buf_To_Hex	Proc	Near
		push	si
		push	di
		push	bx
		push	cx
		push	dx

		mov	di,KEYIN_BUF
		mov	cl,ch
		xor	ch,ch
		xor	si,si
Conv_To_HEX:
		cmp	byte ptr [bp+di],0
		je	short Convert_End

		mov	al,[bp+di]		;save key
		and	al,0Fh			;ASCII --> number
		test	byte ptr [bp+di],10h	;is 0-9 ?
		jnz	short @F		;yes
		add	al,9			;it is A-F
@@:
		xor	ah,ah

		push	ax			;save number

		mov	ax,si	;get
		mov	dx,10
		CHK_ITEMSTAT SHOWHEX
		jz	short @F
		mov	dx,16
@@:
		mul	dx			;shl 1 place
		pop	dx
		add	ax,dx	;add number
		mov	si,ax	;update value

		inc	di
		loop	short Conv_To_HEX

Convert_End:
		mov	ax,si

		pop	dx
		pop	cx
		pop	bx
		pop	di
		pop	si

		ret
Conv_Buf_To_Hex	Endp

ifdef	DOSVERSION
;[]========================================================================[]
;Function :	Turn off cursor on screen
;
;Input	:	None
;
;Output	:	None
;[]========================================================================[]
Cursor_Off	Proc	Near
		mov	ah,1				;disable cursor
		mov	cx,0ff00h
		int	10h
		ret
Cursor_Off	Endp

;[]========================================================================[]
;Function :	Write CMOS
;
;Input :	AH - cmos value , AL - cmos index
;
;Output:	None
;[]========================================================================[]
Set_Cmos	proc	near
		cli
		out	CMOS,al
		NEWIODELAY
		xchg	ah,al
		out	CMOS+1,al
		NEWIODELAY
		xchg	ah,al		;restore AH & AL
		sti
		ret
Set_Cmos	endp

;[]========================================================================[]
;Function :	Read CMOS value
;
;Input :	AL - cmos index
;
;Output:	AL - cmos value
;[]========================================================================[]
Get_Cmos	proc	near
		cli
		out	CMOS,al
		NEWIODELAY
		in	al,CMOS+1
		NEWIODELAY
		sti
		ret
Get_Cmos	endp
endif	;DOSVERSION

;[]========================================================================[]
;Function :	Convert two digit BCD to one byte Hex number
;
;Input	:	AL in BCD format
;
;Output	:	AL in HEX format
;[]========================================================================[]
Bcd_To_Hex	proc	near
		push	bx
		push	cx
		mov	bl,al
		and	bl,0fh
		xor	ah,ah
		mov	cl,4
		shr	al,cl
		mov	cl,10
		mul	cl
		add	al,bl
		pop	cx
		pop	bx
		ret
Bcd_To_Hex	endp

;[]========================================================================[]
;Function :	Convert one byte Hex number to BCD
;
;Input	:	AH in HEX
;
;Output	:	AH in BCD
;
;Destory :	AL
;[]========================================================================[]
Hex_To_Bcd	proc	near
		push	cx
		xchg	ah,al
		xor	ah,ah
		mov	cl,10
		idiv	cl
		mov	cl,4
		shl	al,cl
		or	ah,al
		pop	cx
		ret
Hex_To_Bcd	endp

;[]========================================================================[]
;Function :	Read a key from keyboard
;
;Input	:	None
;
;Output	:	AX - key input
;[]========================================================================[]
Key		proc	near
		push	cx

		call	Cursor_Off

;	Wait for a key, meanwhile calling a background routine. This
;	background routine is usually for updating the time on screen

;R51 - start
if	Desktop_Power_Management	EQ	2		
	ifndef	NO_STR_PASSWORD_CHECK
		cmp	byte ptr CALLTYPE[bp],SMM_CALL	
		jne	short k_0

		call	far ptr Get_SMM_Key
		jmp	short k_1
	endif	;NO_STR_PASSWORD_CHECK
endif	;Desktop_Power_Management	EQ	2
;R51 - end
k_0:
		mov	cx,200		;scan KB 200 times then update time
Scan_Key:
		mov	ah,01h
		int	16h
		jnz	short k_01
		loop	short Scan_Key

		test	byte ptr Post_Temp_Byte[bp],DO_NOT_UPDATE_TIME	;R56
		jnz	short DoNotUpdateTime				;R56
		call	Update_Time

;R85		cmp	byte ptr CALLTYPE[bp],POST_CALL			;R56A
		call	If_Code_Running_In_F000			;R85
		jne	short DoNotUpdateTime				;R56A
		call	far ptr Update_Sensor_Screen			;R56
	DoNotUpdateTime:						;R56

		jmp	short k_0

;	Once we have a key, we get it out of the buffer

k_01:
		mov	ah, 10h			; get the key
		int	16h

		cmp	ah,53h			;DEL key?
		jne	short @F		;no
		xor	al,al			;clear ASCII code
		jmp	short k_1		;yes...
	@@:
		cmp	ax, k_pad5		; keypad 5?
		je	short k_1		; yes...

;	put the key back if it is NOT the keypad 5 key

		push	cx
		mov	cx, ax
		mov	ah, 5			; unget char
		int	16h
		pop	cx

;	and get it with the non-extended read key function so that 101
;	 keyboard arrow keys and special keys work

		xor	ah,ah			; get the key
		int	16h
k_1:
		pop	cx
		mov	LAST_KEY[bp],ax
;R83 Chk_Ctrl_Key:
Chk_Ctrl_Key	Label	Near		;R83
		push	es

		push	cs			; get correct segment
		pop	es

		push	cx
		push	di			; save the registers

		mov	di,offset Ctrl_key_list	; beginning of key table
		mov	cx,No_Of_Ctrl_Key
		repne	scasw

		pop	di
		pop	cx
		pop	es

		ret
Key		endp

Ctrl_Key_List	Label	word

		dw	K_F3		;stdcmos
		dw	K_F5		;         bios, chipset
		dw	K_F6		;         bios, chipset
		dw	K_F7		;         bios, chipset
		dw	K_PLUS		;stdcmos, bios, chipset
		dw	K_MINUS		;stdcmos, bios, chipset
		dw	PGUP		;stdcmos, bios, chipset
		dw	PGDN		;stdcmos, bios, chipset
		dw	K_F1		;stdcmos, bios, chipset
		dw	UP_ARROW	;stdcmos, bios, chipset, kernal
		dw	DOWN_ARROW	;stdcmos, bios, chipset, kernal
		dw	LEFT_ARROW	;stdcmos, bios, chipset, kernal
		dw	RIGHT_ARROW	;stdcmos, bios, chipset, kernal
		dw	K_ESC1		;stdcmos, bios, chipset, kernal
		dw	K_F2		;stdcmos, bios, chipset, kernal
		dw	K_CR1		;stdcmos, bios, chipset, kernal
		dw	K_F10		;                        kernal

No_Of_Ctrl_Key	EQU	($-offset Ctrl_Key_List)/2

;[]========================================================================[]
;Function :	Read the CMOS time and display it on screen
;		if it is not the same value as that of the stack.
;
;Input	:	None
;
;Output	:	None
;
;Note	:	call from subroutine KEY only
;[]========================================================================[]
Update_Time	proc	near

		pusha
		push	word ptr CURSOR_X[bp]

		cmp	byte ptr CUR_PAGE[bp],PAGE_STDCMOS
		jne	short U_TimeExit

		mov	di,offset Update_Time_Tbl

Update_Next_Date_Item:

		push	bx
		push	di

		mov	bx,cs:[di]
		call	Read_Item_Value		;Get Stack value

		mov	al,0Ah			;get RTC status
		call	Get_Cmos		;
		test	al,80h			;is update in progress?
		jnz	short @F		;yes, no re-display

		mov	al,cs:[di+2]
		call	Get_Cmos		;get CMOS value
;		cmp	al,0FFh			;is CMOS updating?
;		je	short @F		;yes, no re-display

		call	BCD_To_Hex		;convert to Hex
		cmp	dl,al			;CMOS diff. from stack?
		je	short @F		;no, no re-display

		mov	dl,al
		call	Write_Item_Value		;put CMOS value into stack
		call	Display_Whole_Item	;temp year
@@:
		pop	di
		pop	bx
		add	di,3
		cmp	di,offset Update_Item_End
		jb	short Update_Next_Date_Item

;R09 - starts
ifndef	NO_Y2K_CHECK					;R95
		cmp	word ptr TEMP_YEAR[bp],1999
		jne	short U_TimeExit
		cmp	byte ptr CMOS09[bp],00h
		jne	short U_TimeExit

		mov	ax,2032h
		call	Set_Cmos
		mov	byte ptr CMOS32[bp],20
		mov	bx,offset Temp_Year_Item
		mov	dx,2000
		call	Write_Item_Value
		call	Display_Whole_Item
endif	;NO_Y2K_CHECK					;R95
;R09 - ends

U_TimeExit:
		pop	word ptr CURSOR_X[bp]
		popa
		ret
Update_Time	endp

Update_Time_Tbl:
		dw	offset Century_Item
		db	CMOS32
		dw	offset Year_Item
		db	CMOS09
		dw	offset Month_Item
		db	CMOS08
		dw	offset DATE_ITEM		;item offset
		db	CMOS07				;CMOS location
		dw	offset HOUR_ITEM
		db	CMOS04
		dw	offset MINUTE_ITEM
		db	CMOS02
		dw	offset SECOND_ITEM
		db	CMOS00
Update_Item_End	Label	byte

;[]========================================================================[]
;input	: bx - point to menuitem
;	  dx - value to set
;output	: 1. NC: [bx].CmosLoc[bp] updated
;	  2. CF: [bx].CmosLoc[bp] not updated
;[]========================================================================[]
Write_Item_Value	Proc	Near

		push	si
		push	cx
		push	dx

		push	dx
		call	Read_Item_Value
		pop	dx

;R81		cmp	dx,[bx].ItemMax
		cmp	dx,cs:[bx].ItemMax		;R81
		ja	short Set_Shift_Error
;R81		cmp	dx,[bx].ItemMin
		cmp	dx,cs:[bx].ItemMin		;R81
		jb	short Set_Shift_Error

		shl	dx,cl
;R81		mov	cx,[bx].CmosMask
		mov	cx,cs:[bx].CmosMask		;R81
		not	cx
;R81		test	word ptr [bx].CmosMask,0FF00h	;word for item value?
		test	word ptr cs:[bx].CmosMask,0FF00h;R81 word for item value?
		jnz	short Word_Value

		and	[bp+si],cl
		or	[bp+si],dl		;set value
		jmp	short ModVal_Exit
Word_Value:
		and	[bp+si],cx
		or	[bp+si],dx
ModVal_Exit:
		clc
		jmp	short Set_Shift_Exit
Set_Shift_Error:
		stc
Set_Shift_Exit:
		pop	dx
		pop	cx
		pop	si
		ret
Write_Item_Value	Endp

;[]========================================================================[]
;Function :	Get the stack value of specified item
;
;Input	:	bx - item offset
;
;Output	:	dx - stack value (shifted)
;		cx - no of bits to shift right
;		si = [bp].CmosLoc
;
;Registers :	FLAG, DX, CX, SI - Destroyed
;		Others - Preserved
;[]========================================================================[]
Read_Item_Value	proc	near
		push	ax
		xor	ah,ah
		mov	al,cs:[bx].CmosLoc	;get CMOS location
		mov	si,ax
		mov	dx,[bp+si]		;read value from stack
		mov	ax,cs:[bx].CmosMask
		and	dx,ax
		mov	cx,-1			;Init shift value
Next_Bit:
		inc	cx
		ror	ax,1
		jnc	short Next_bit
		shr	dx,cl
		pop	ax
		ret
Read_Item_Value	endp

;[]========================================================================[]
;Function :	Read the BIOS/ROM default for a specified item
;
;input	:	bx point to menuitem
;
;output	:	DX - ROM/BIOS default (shifted)
;		CX - no of bits to shift right
;
;Registers :	FLAG, DX, CX - Destroyed
;		Others - Preserved
;[]========================================================================[]
Get_Item_BIOS_D4	Proc	Near
		push	si
		push	di
		push	ax
		push	word ptr TEMP_YEAR[bp]		;use this word
							;for temporary use

		mov	word ptr TEMP_YEAR[bp],K_F6

		cmp	word ptr cs:[bx].CtRegMask,0
		jne	short Mask_Not_0
		call	Get_Item_Setup_D4
		jmp	short Item_BIOS_D4_Exit

Mask_Not_0:
		call	Auto_Value_Or_BIOS_D4

		mov	di,cs:[bx].CmosMask
		call	Mask_To_Mask_Trans
		push	ax
		call	Read_Item_Value
		pop	ax
		shr	ax,cl
		mov	dx,ax

Item_BIOS_D4_Exit:

		pop	word ptr TEMP_YEAR[bp]
		pop	ax
		pop	di
		pop	si

		ret

Get_Item_BIOS_D4	Endp

Auto_Value_Or_BIOS_D4		Proc	Near
		push	word ptr PAGE_END[bp]
		mov	si,offset cs:PageOffset
		sub	si,6
Try_Next_P:
		add	si,6
		cmp	word ptr cs:[si],-1
		je	short Page_End_found
		cmp	bx,cs:[si]
		jb	short Try_Next_P
		cmp	bx,cs:[si+2]
		jae	short Try_Next_P
Page_End_found:
		mov	si,cs:[si+2]
		mov	PAGE_END[bp],si
;----------------------------------------------------------------

		xor	dx,dx
		xor	cx,cx
		mov	di,0FFFFh

		push	bx

	Next_Merge_Item:

	;shift all RomDefault bits to the right

		mov	si,cs:[bx].CtRegMask
		mov	ax,cs:[bx].RomDefault

		cmp	word ptr TEMP_YEAR[bp],K_F6
		je	short Is_F6
		mov	si,OLDITEM[bp]		;if it is F7
						; OLDITEM[bp]=offset auto table
		mov	ax,cs:[bx].CtReg
	@@:
		cmp	ax,cs:[si].RomReg
		je	short @F
		add	si,ROMITEM_SIZE
		jmp	short @B
	@@:
		mov	ax,cs:[si].RomValue
		mov	si,cs:[bx].CtRegMask
	Is_F6:
		and	ax,si
		call	Mask_To_Mask_Trans	;move all mask bit to right
		or	dx,ax

	;shift all mask bits to the right

		mov	ax,si
		call	Mask_To_Mask_Trans	;move all mask bit to right
		or	cx,ax
		not	ax
		and	di,ax

	;check next menuitm if it is HIDDEN

		add	bx,ITEM_SIZE
		cmp	bx,PAGE_END[bp]
		jae	short Not_Merge_Item
		test	word ptr cs:[bx].ItemStat,HIDDEN
		jnz	short Next_Merge_Item

	Not_Merge_Item:

		mov	ax,dx
		mov	si,di
		not	si

		pop	bx
		pop	word ptr PAGE_END[bp]
		ret
Auto_Value_Or_BIOS_D4		Endp

;[]========================================================================[]
;Function :	Read the SETUP default for a specified item
;
;input	:	bx point to menuitem
;
;output	:	DX - Setup default (shifted)
;		CX - no of bits to shift right
;
;Registers :	FLAG, DX, CX - Destroyed
;		Others - Preserved
;[]========================================================================[]
Get_Item_Setup_D4	Proc	Near
		push	si
		push	di
		push	ax

		test	word ptr [bx].ItemStat,AUTOPROG
		jz	short @F

ifdef	PM_SUPPORT
;------------------------- Get PM Auto Value -------------------------
		test	word ptr [bx].ItemStat,PMITEM
		jz	short Not_PM_Item
		pusha
		call	PM_Option_Check
		popa
		jz	short @F		;user defined, use stack(cmos)
		call	Get_PM_Auto_Value 	;values in table
		jmp	short Setup_D4_Got
Not_PM_Item:
endif	;PM_SUPPORT

;----------------------- Get Chipset Auto Value ----------------------
		pusha
		call	Ct_Auto_Check
		popa
		jz	short @F
		call	Get_Auto_Cfg_Value
		jmp	short Setup_D4_Got
@@:
		call	Read_Item_Value
		mov	dx,cs:[bx].SetupDef
		and	dx,cs:[bx].CmosMask
		shr	dx,cl
Setup_D4_Got:
		pop	ax
		pop	di
		pop	si

		ret
Get_Item_Setup_D4	Endp

;[]========================================================================[]
;input	:	si - mask 1
;		di - mask 2
;		ax - value which fit mask 1
;
;output	:	ax : mask 1 format ---> mask 2 format
;
;e.g.1	mask 1: 11100000b
;		ax = 10100000b
;	mask 2: 00000111b
;	=>	ax = 00000101b
;
;e.g.2	mask 1: 11010011b
;		ax = 10010010b
;	mask 2: 00011111b
;	=>	ax = 00010110b
;[]========================================================================[]
		public	Mask_To_Mask_Trans
Mask_To_Mask_Trans	Proc	Near

		push	bx			;save bx
		push	cx
		push	dx
		push	si
		push	di

;R17 - starts
;R17A		test	si, 8000h
;R17A		jz	short _ikjuyhgt
;R17A		ror	si, 1
;R17A		ror	ax, 1
;R17A
;R17A	_ikjuyhgt:
;R17 - ends

		push	word ptr OLDITEM[bp]	;use this word as temp. storage
		mov	OLDITEM[bp],si		;use this word as temp. storage

		xor	bx,bx			;Clear output value at the
						; first place
		and	ax,si			;mask input value
		mov	cx,16			;16 bits operation

	Next_Output_Bit:

		test	di,01h			;is this output bit a mask bit?
		jz	short Not_Mask_Bit	;no, skip it

	Next_Input_Bit:

		test	si,01h			;is this input bit a mask bit?
		jnz	short @F		;yes, update output value
		ror	si,1			;shift input value right

		cmp	si,OLDITEM[bp]
		je	short Shift_Till_End

		ror	ax,1			;shift input value right
		jmp	short Next_Input_Bit	;try next input bit
	@@:
		mov	dx,ax			;temp for input value
		and	dx,01h			;get one bit
		or	bx,dx			;put it into out put value

		ror	si,1			;shift input value right
		ror	ax,1			;shift input value right

	Not_Mask_Bit:

		ror	bx,1			;shift output value right
		ror	di,1			;shift output mask right
		loop	short Next_Output_Bit	;try next output bit
		jmp	short M_To_M_End

	Shift_Till_End:

		ror	bx,1
		ror	di,1
		loop	short Shift_Till_End

	M_To_M_End:

		mov	ax,bx			;output value in ax

		pop	word ptr OLDITEM[bp]	;restore OLDITEM[bp]
		pop	di
		pop	si
		pop	dx
		pop	cx
		pop	bx			;restore bx

		ret				;return to caller

Mask_To_Mask_Trans	Endp

;[]========================================================================[]
;Function :	Clear screen & re-display all items
;
;Input	:	STROFFSET[bp]	- string to show e.g. borders
;		PAGE_START[bp]	- menu start
;		PAGE_END[bp]	- menu end
;
;Output	:	None
;
;Registers :	BX - preserved
;[]========================================================================[]
Refresh_Menu1	Proc	near

;R52 - start
	;clear shift status while exit from sub-screen
		push	ds
		mov	ax,G_RAM
		mov	ds,ax
		ASSUME	DS:G_RAM
		and	byte ptr ds:SHFT_STAT,NOT 03h	;clear shift status
		pop	ds
;R52 - end

		push	bx
		call	Vnormal
		mov	ax,0600h
		xor	cx,cx
		mov	dx,194fh
		mov	bh,ATTRIBUTE[bp]
		int	10h			;clear screen
		pop	bx
		call	Refresh_Menu
;R75 start
;R78cifndef Flash_16K_8K_8K_Unit	  ;R78b
ifdef  Backup_CMOS_to_FLASH
	       	cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL ;R77
	       	jne	short @F			  ;R77
		push	ds
		push	seg XGROUP
		pop	ds
		lea	si,XGROUP:S_CMOS_TO_BIOS	  ;display CMOS function key (F7) in kernel page
		call	Display_String
	      	lea	si,XGROUP:L_CMOS_FROM_BIOS	  ;display CMOS function key (F8) in kernel page
	      	call	Display_String
		pop	ds
@@:							  ;R77
endif ;Backup_CMOS_to_FLASH
;R78cendif ; Flash_16K_8K_8K_Unit	  ;R78b
;R75 end

;R69 - start
		cmp	byte ptr CALLTYPE[bp],MODBIN_CALL	;R69A
		je	short @F				;R69A
;R69A		cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL
;R69A		jne	short @F
;R69A		call	check_MIB
		Xcall	check_MIB				;R69A
		jnc	short @F
		push	ds					;R69A
		push	seg XGROUP				;R69A
		pop	ds					;R69A
		lea	si,XGROUP:MIB_key		;display MIB function key (F5) in kernel page
		call	Display_String
		pop	ds					;R69A
@@:
;R69 - end
		ret
Refresh_Menu1	Endp

;[]========================================================================[]
;Function :	Re-Display all items without clearing screen
;
;Input	:	STROFFSET[bp]	- string to show e.g. borders
;		PAGE_START[bp]	- menu start
;		PAGE_END[bp]	- menu end
;
;Output	:	None
;
;Registers :	BX - preserved
;[]========================================================================[]
Refresh_Menu	proc	near
		push	bx

;Display some fixed strings
		mov	si,STROFFSET[bp]
		call	Display_String
;-------------------------------------------------------------------
		mov	bx,PAGE_START[bp]
Next_Item:
		push	bx
		call	Display_Whole_Item
		pop	bx
		add	bx,ITEM_SIZE
		cmp	bx,PAGE_END[bp]
		jne	short Next_Item
		pop	bx
		ret
Refresh_Menu	endp

;[]========================================================================[]
;Function :	Display an item including item title & variable
;
;Input	:	BX - item offset
;
;Output	:	NONE
;[]========================================================================[]
		Public	Display_Whole_Item	;R60
Display_Whole_Item	proc	near

		mov	al,ATTRIBUTE[bp]
		push	ax

		CHK_ITEMSTAT ITEMDISABLE+HIDDEN
		jnz	short Whole_Item_Exit
		call	Disp_ItemTitle

		CHK_ITEMSTAT SHOWONLY
		jnz	short @F
		call	Vhilite

		cmp	bx,OLDITEM[bp]
		jne	short @F
		call	VReverse
@@:
		call	Disp_ItemVar

Whole_Item_Exit:

		pop	ax
		mov	ATTRIBUTE[bp],al

		ret

Display_Whole_Item	endp

;[]========================================================================[]
;Function :	Show item title
;
;		Example:
;
;		TypeSpeed_Item:
;			menuitem <0,\
;			  offset TypeSpeed_Str,NOCT,01110000b,13H,01110000b,\
;			  offset Rate_Str,0,7,Xaxis,Yaxis,0,0,Offset Std_Help_Str>
;
;		TypeSpeed_Str		db	'Typematic Rate (Chars/Sec) : ',0
;		Rate_Str		db	'6 ',0
;					db	'8 ',1		;not available
;					db	'10',0
;					db	'12',1		;not available
;					db	'15',0
;					db	'20',1		;not available
;					db	'24',0
;					db	'30',0
;
;		===> the string "Typematic Rate (Chars/Sec) : " will be displayed
;		     on screen position <Xaxis,Yaxis>
;
;Input	:	BX - item offset (e.g. offset TypeSpeed_Item)
;
;Output :	None
;
;Registers :	----
;[]========================================================================[]
Disp_ItemTitle	proc	near
		mov	al,[bx].Item_Xaxis	;get column position
		mov	CURSOR_X[bp],al		;get column position
		mov	al,[bx].Item_Yaxis	;get row position
		mov	CURSOR_Y[bp],al		;get row position
;R87 - starts
ifdef Password_PSON_By_Chipset
		mov	Item_P[bp],al       	
endif;Password_PSON_By_Chipset
;R87 - ends
		call	Vnormal
		mov	si,[bx].ItemName	;get string offset
		call	Display_String
		ret
Disp_ItemTitle	endp

;[]========================================================================[]
;Function :	Dispaly the current value of a item
;
;		Example:
;
;		TypeSpeed_Item:
;			menuitem <ITEMSTAT,\
;			  offset TypeSpeed_Str,NOCT,11110000b,13H,11110000b,\
;			  offset Rate_Str,0,15,Xaxis,Yaxis,0,0,Offset Std_Help_Str>
;
;		TypeSpeed_Str		db	'Typematic Rate (Chars/Sec) : ',0
;		Rate_Str		db	'6 ',0
;					db	'8 ',1		;not available
;					db	'10',0
;					db	'12',1		;not available
;					db	'15',0
;					db	'20',1		;not available
;					db	'24',0
;					db	'30',0
;					db	'31',0
;					db	'32',0
;					db	'33',0
;					db	'34',0
;					db	'35',0
;					db	'36',0
;					db	'37',0
;					db	'38',0
;
;		if item value = 12 i.e. bit 7654 of CMOS13[bp] = 1100b
;
;		i. if itemstat is not SHOWNUM
;		   ===> string ('35',0) will be displayed on screen
;		ii. if itemstat is SHOWNUM
;		    ===> "12" will be displayed on screen for not SHOWHEX & DIGIT2
;			 "  12" will be displayed on screen for not SHOWHEX & DIGIT4
;			 "   12" will be displayed on screen for not SHOWHEX & DIGIT5
;		    ===> "0C" will be displayed on screen for SHOWHEX & DIGIT2
;		         "000C" will be displayed on screen for SHOWHEX & DIGIT4
;		         " 000C" will be displayed on screen for SHOWHEX & DIGIT5
;
;Input	:	BX - item offset
;
;Output	:	None
;[]========================================================================[]
Disp_ItemVar	proc	near

		mov	al,Special_Before	;Pre-show i.e. special show before
		call	Special_Show		;	       standard show
		jnc	short @F
		ret
@@:
		CHK_ITEMSTAT SHOWNUM		;show number?
		jz	short Normal_ShowItem	;no, show string

		call	Get_ItemStat_AX
		test	ax,SHOWHEX
		jz	short Show_DEC
Show_HEX:
		and	ax,NO_OF_DIGIT
		mov	di,offset AX_To_HEX2
		cmp	ax,DIGIT2
		je	short Show_Number

		mov	di,offset AX_To_HEX3
		cmp	ax,DIGIT3
		je	short Show_Number

		mov	di,offset AX_To_HEX4
		cmp	ax,DIGIT4
		je	short Show_Number

		mov	di,offset AX_To_HEX5
		jmp	short Show_Number
Show_DEC:
		and	ax,NO_OF_DIGIT

		mov	di,offset AX_To_DEC2
		cmp	ax,DIGIT2
		je	short Show_Number

		mov	di,offset AX_To_DEC3
		cmp	ax,DIGIT3
		je	short Show_Number

		mov	di,offset AX_To_DEC4
		cmp	ax,DIGIT4
		je	short Show_Number

		mov	di,offset AX_To_DEC5
Show_Number:
		call	Valid_Value		;if invalid, find a valid value
		mov	ax,dx			;to be display
		call	di			;translate ax into ASCII
		call	Show_SIX_DIGIT		;display the buffer
		jmp	short Disp_ItemVar_Exit	;exit

Normal_ShowItem:
		call	Valid_Value		;if invalid, find a valid value
		call	Get_VarString_Offset	;get string to show
		call	Display_String		;display it

Disp_ItemVar_Exit:

		mov	al,Special_After	;Post-show i.e. special show after
		call	Special_Show		;	        standard show

		ret

;R83 Valid_Value:
Valid_Value	Label	Near		;R83
		call	Get_ItemStat_AX
		and	ax,AUTOPROG+SHOWONLY
		cmp	ax,AUTOPROG+SHOWONLY
		jne	short @F
		call	Get_Item_Setup_D4
		jmp	short Return_Valid_Value
	@@:

		call	Read_Item_Value		;read item value
		call	Check_Item_Range	;is it within range
		jnc	short @F		;yes

		call	Get_Item_Setup_D4
	@@:
		call	Check_VarNull		;is this value available?
		jnc	short @F		;available
		call	Next_Item_Value		;get next value
		call	Write_Item_Value	;write to stack
	@@:
Return_Valid_Value:

		ret				;return to caller

Disp_ItemVar	endp

;[]========================================================================[]
;Function :	Get the string offset of an item corresponding to item value
;		Example:
;
;		TypeSpeed_Item:
;			menuitem <0,\
;			  offset TypeSpeed_Str,NOCT,01110000b,13H,01110000b,\
;			  offset Rate_Str,0,7,Xaxis,Yaxis,0,0,Offset Std_Help_Str>
;
;		TypeSpeed_Str		db	'Typematic Rate (Chars/Sec) : ',0
;		Rate_Str		db	'6 ',0
;					db	'8 ',1		;not available
;					db	'10',0
;					db	'12',1		;not available
;					db	'15',0
;					db	'20',1		;not available
;					db	'24',0
;					db	'30',0
;
;		if item value = 3 i.e. bit 654 of CMOS13[bp] = 011b
;		===> SI = offset of string '12',0
;
;Input	:	BX - item offset (e.g. offset TypeSpeed_Item)
;		DX - item value
;
;output:	DS:SI
;
;Registers :	----
;[]========================================================================[]
Get_VarString_Offset	Proc	Near

		sub	dx,[bx].ItemMin
		mov	cx,dx
		mov	si,[bx].ItemValName

Get_VarString_Offset_1:

		jcxz	short Disp_This
See_Byte:
		lodsb
		cmp	al,V_DONE
		je	short @F
		cmp	al,V_DONE_1
		je	short @F
		jnz	short See_Byte
	@@:
	 	dec	cx
		jmp	short Get_VarString_Offset_1
Disp_This:
		ret
Get_VarString_Offset	Endp

;[]========================================================================[]
;Function :	Check to see if value is within range
;
;		Example:
;
;		TypeSpeed_Item:
;			menuitem <0,\
;			  offset TypeSpeed_Str,NOCT,01110000b,13H,01110000b,\
;			  offset Rate_Str,0,7,Xaxis,Yaxis,0,0,Offset Std_Help_Str>
;
;Input :  	BX	- item offset	(e.g. BX = offset TypeSpeed_Item)
;		DX	- item value
;
;Output:	CF - value is out of range	( DX > 7 or DX < 0 )
;		NC - value is within range	( 0 < DX < 7 )
;[]========================================================================[]
Check_Item_Range	Proc	Near

		cmp	dx,[bx].ItemMin
		jb	short Out_Of_Range
		cmp	dx,[bx].ItemMax
		jbe	short Within_Range

	Out_Of_Range:

		stc
		ret

	Within_Range:

		clc
		ret

Check_Item_Range	Endp

;[]========================================================================[]
;Function :	to check if this item value is available
;
;		Example:
;
;		TypeSpeed_Item:
;			menuitem <0,\
;			  offset TypeSpeed_Str,NOCT,01110000b,13H,01110000b,\
;			  offset Rate_Str,0,7,Xaxis,Yaxis,0,0,Offset Std_Help_Str>
;
;		Rate_Str		db	'6 ',0
;					db	'8 ',1		;not available
;					db	'10',0
;					db	'12',1		;not available
;					db	'15',0
;					db	'20',1		;not available
;					db	'24',0
;					db	'30',0
;
;Input :  	BX	- item offset	(e.g. BX = offset TypeSpeed_Item)
;		DX	- item value	(e.g. DX = 0 - 7)
;
;Output:	CF - value is not available	(e.g. 1,3,5)
;		NC - value is available		(e.g. 0,2,4,6,7)
;[]========================================================================[]
Check_VarNull	Proc	Near

		pusha

		CHK_ITEMSTAT SHOWNUM
		jnz	short Var_Not_Null

		call	Get_VarString_Offset

Check_VarNull_1:
		cmp	byte ptr ds:[si],V_DONE
		je	short Var_Not_Null
		cmp	byte ptr ds:[si],V_DONE_1
		je	short Var_Null
		inc	si
		jmp	short Check_VarNull_1
Var_Null:
		popa
		stc
		ret
Var_Not_Null:
		popa
		clc
		ret

Check_VarNull	Endp

;[]========================================================================[]
;Function :	Convert one word integer to 5 HEX ASCII
;
;Input :	AX - word to be converted
;
;Output:	ss:[bp+SIX_DIGIT]
;[]========================================================================[]
AX_To_HEX5	label	near
		mov	cx,4
		mov	si,SIX_DIGIT
		mov	byte ptr [bp+si],' '
		inc	si
		jmp	short Conv_HEX1

AX_To_HEX4	label	near
		mov	cx,4
		jmp	short Conv_HEX0

AX_To_HEX3	label	near
		mov	cx,3
		jmp	short Conv_HEX0

AX_To_HEX2	Proc	near
		mov	cx,2
;R83 Conv_HEX0:
Conv_HEX0	Label	Near		;R83
		mov	si,SIX_DIGIT
;R83 Conv_HEX1:
Conv_HEX1	Label	Near		;R83
Not_None:
		push	cx
	@@:
		ror	ax,4
		loop	@B
		pop	cx
		mov	di,ax

Conv_HEX2:
		rol	di,4
		mov	ax,di
		and	ax,0Fh

		mov	ah,30h
		cmp	al,9
		jbe	short Less_Than_0Ah
		mov	ah,40h
		sub	al,9
Less_Than_0Ah:
		add	al,ah
		mov	[bp+si],al
		inc	si
		loop	Conv_HEX2

		mov	byte ptr [bp+si],0
Conv_HEX_End:
		ret
AX_To_HEX2	Endp

;[]========================================================================[]
;Function :	Convert three byte integer to 6 DEC ASCII
;
;Input	:	EAX - word to be converted
;
;Output	:	ss:[bp+SIX_DIGIT]
;[]========================================================================[]
		public	BLAX_To_DEC6
BLAX_To_DEC6	label	near
		mov	si,SIX_DIGIT
		call	Convert_6_Digit
		ret

;[]========================================================================[]
;Function :	Convert one word integer to 5 DEC ASCII
;
;Input	:	AX - word to be converted
;
;Output	:	ss:[bp+SIX_DIGIT]
;[]========================================================================[]
Factor_Ten_Thu	dw	10000
Factor_Thu	dw	1000
Factor_Hun	dw	100
Factor_Ten	dw	10

AX_To_DEC2	label	near
		mov	cx,1		;1 iterations
		mov	di,offset Factor_Ten
		jmp	short Convert_Word

AX_To_DEC3	label	Near
		mov	cx,2		;2 iterations
		mov	di,offset Factor_Hun
		jmp	short Convert_Word

AX_To_DEC4	label	near
		mov	cx,3		;3 iterations
		mov	di,offset Factor_Thu
		jmp	short Convert_Word

AX_To_DEC5	proc	near
		mov	cx,4		;4 iterations
		mov	di,offset Factor_Ten_Thu
		jmp	short Convert_Word

;R83 Convert_Word:
Convert_Word	Label	Near		;R83
		mov	si,SIX_DIGIT
Convert_3Byte:
		xor	dl,dl		;for leading space judge
		mov	byte ptr [bp+si],30h
Not_O:
Sub_Again:
		inc	byte ptr [bp+si]
		sub	ax,cs:[di]
		je	short Next_Digit
		jnc	short Sub_Again
Add_Back:
		add	ax,cs:[di]
		dec	byte ptr [bp+si]
Next_Digit:
		cmp	byte ptr [bp+si],30h
		jne	short Non_Zero
		or	dl,dl
		jnz	short Non_Zero
		mov	byte ptr [bp+si],20h	;leading space
		jmp	short Zero_Space
Non_Zero:
		inc	dl
Zero_Space:
		inc	di
		inc	di
		inc	si
		mov	byte ptr [bp+si],30h
		loop	short Sub_Again

		add	[bp+si],al
		mov	byte ptr [bp+si+1],0	;ending string

		ret
AX_To_DEC5	endp

;[]========================================================================[]
;Function :	Display the buffer SIX_DIGIT[bp]
;
;Input	:	None
;
;Output	:	None
;
;Registers :	----
;[]========================================================================[]
Show_SIX_DIGIT	Proc	Near
		push	ds

		mov	si,bp
		add	si,SIX_DIGIT

		push	ss
		pop	ds				;DS point to SS
		call	Display_String

		pop	ds
		ret
Show_SIX_DIGIT	Endp

;[]========================================================================[]
;Function :	Display a string on screen in which the control bytes defined
;		in Display_Control is allowed
;		e.g. POS, BORDER1, CLEAR...
;
;Input	:	SI - string offset
;
;Output	:	None
;
;Registers :	----
;[]========================================================================[]
Display_String	Proc	Near
		push	es
		push	di
		push	bx
Display_Str1:
		lodsb
		cmp	al,V_DONE
		je	short Display_Str_End
		cmp	al,V_DONE_1
		je	short Display_Str_End

		cmp	al,V_Special
		jbe	short Display_Str2
		call	Display_Char
		jmp	short Display_Str1
Display_Str2:
		xor	bh,bh
		shl	al,1
		mov	bl,al
		call	word ptr cs:Display_Control[bx]
		jmp	short Display_Str1

Display_Str_End:
		pop	bx
		pop	di
		pop	es
		ret

Display_String	Endp

VDone:
		ret

Display_Control:
		dw	offset VDone
		dw	offset VDone
		dw	offset VBorder
		dw	offset VClear
		dw	offset VStrshow
		dw	offset VPos
		dw	offset VHilite
		dw	offset VReverse
		dw	offset VNormal
		dw	offset VBlink
;R72		dw	offset VWarn
		dw	offset VLF			;R72
		dw	offset VNewLine
		dw	offset VADDX
;R72		dw	offset VSUBX
		dw	offset VCR			;R72
		dw	offset VADDY
		dw	offset VSUBY
		dw	offset VCALLROUTINE
		dw	offset VCHG_COLOR		;R43
		dw	offset VWarn			;R72
		dw	offset VSUBX			;R72
		dw	offset VJmpString		;R72

;[]========================================================================[]
;Function:	Write a border on screen
;
;Input	:	DS = CS
;		SI = (offset BORDER STRUCT + 1)
;		e.g. BORDER <,0,0,20,20>
;
;Output	:	None
;
;Destroy:	All except BX
;[]========================================================================[]
VBorder		proc	near
		push	bx
		dec	si
		mov	bx,si

		test	byte ptr [bx].Btype,Empty_Border
		jz	short _Not_Empty_Border
		push	bx
		push	cx
		mov	ax,0600h
		mov	cl,[bx].LeftX
		mov	ch,[bx].LeftY
		mov	dl,[bx].RightX
		mov	dh,[bx].RightY
		mov	bh,ATTRIBUTE[bp]
;R44		int	10h
		Call	Check_Call_Source	;R44
		pop	cx
		pop	bx
_Not_Empty_Border:
		test	byte ptr [bx].Btype,No_Border	;R43
		jz	Draw_Border			;R43
		jmp	No_Angle			;R43
Draw_Border:						;R43

;----------------------------------------------------------------
		mov	al,[bx].LeftX
		mov	CURSOR_X[bp],al
		mov	al,[bx].LeftY
		mov	CURSOR_Y[bp],al

_VBorder_1:
		mov	al,205			;'Í'
		test	[bx].Btype,01h
		jnz	short _VBorder_1_1
		mov	al,196			;'Ä'
_VBorder_1_1:
		call	Display_Char

		mov	ah,CURSOR_X[bp]
		cmp	ah,[bx].RightX
		jbe	short _VBorder_1

;----------------------------------------------------------------

		mov	al,[bx].LeftX
		mov	CURSOR_X[bp],al
		mov	al,[bx].RightY
		mov	CURSOR_Y[bp],al

_VBorder_2:
		mov	al,205			;'Í'
		test	[bx].Btype,01h
		jnz	short _VBorder_2_1
		mov	al,196			;'Ä'
_VBorder_2_1:
		call	Display_Char

		mov	ah,CURSOR_X[bp]
		cmp	ah,[bx].RightX
		jb	short _VBorder_2
;----------------------------------------------------------------

		mov	al,186			;'º'
		test	[bx].Btype,01h
		jnz	short _VBorder_2_3
		mov	al,179			;'³'
_VBorder_2_3:
		mov	dl,[bx].LeftX		;start point X
		mov	dh,[bx].LeftY		;start point Y
		inc	dh
		mov	cl,[bx].RightY		;count of chars
		sub	cl,dh

		mov	ch,[bx].LeftX
		cmp	ch,[bx].RightX
		jne	short @F
		add	cl,2
		dec	dh
	@@:
		call	Show_Vertical

		mov	dl,[bx].RightX		;start point X
		call	Show_Vertical

;----------------------------------------------------------------
		mov	al,[bx].LeftX
		cmp	al,[bx].RightX
		je	No_Angle

		mov	al,[bx].LeftY
		cmp	al,[bx].RightY
		je	No_Angle

;----------------------------------------------------------------
;Top Left
		mov	al,[bx].LeftX
		mov	CURSOR_X[bp],al
		mov	al,[bx].LeftY
		mov	CURSOR_Y[bp],al

		mov	al,201			;'É'
		test	[bx].Btype,01h
		jnz	short VBorder_TL
		mov	al,218			;'Ú'
VBorder_TL:
		call	Display_Char
;----------------------------------------------------------------
;Top Right
		mov	al,[bx].RightX
		mov	CURSOR_X[bp],al
		mov	al,[bx].LeftY
		mov	CURSOR_Y[bp],al

		mov	al,187			;'»'
		test	[bx].Btype,01h
		jnz	short VBorder_TR
		mov	al,191			;'¿'
VBorder_TR:
		call	Display_Char
;----------------------------------------------------------------
;Bottom Left
		mov	al,[bx].LeftX
		mov	CURSOR_X[bp],al
		mov	al,[bx].RightY
		mov	CURSOR_Y[bp],al

		mov	al,200			;'È'
		test	[bx].Btype,01h
		jnz	short VBorder_BL
		mov	al,192			;'À'
VBorder_BL:
		call	Display_Char
;----------------------------------------------------------------
;Bottom Right
		mov	al,[bx].RightX
		mov	CURSOR_X[bp],al
		mov	al,[bx].RightY
		mov	CURSOR_Y[bp],al

		mov	al,188			;'¼'
		test	[bx].Btype,01h
		jnz	short VBorder_BR
		mov	al,217			;'Ù'
VBorder_BR:
		call	Display_Char
;----------------------------------------------------------------
No_Angle:

		add	si,6		;to next pattern
		pop	bx
		ret
VBorder		endp

;[]========================================================================[]
;Function :	Clear a block on screen
;
;Input	:	DS = CS
;		SI = (offset CLEAR1 STRUCT) + 1
;		e.g. CLEAR1 <,0,0,40,40)
;
;Output	:	None
;
;Preserve:	All except FLAG & SI
;[]========================================================================[]
VClear		proc	near
		pusha

		lodsw
		mov	cx,ax
		lodsw
		mov	dx,ax
		mov	ax,0600h
		mov	bh,ATTRIBUTE[bp]
;R44		int	10h
		Call	Check_Call_Source	;R44

		popa
		add	si,4
		ret
VClear		endp

;[]========================================================================[]
;Function :	Display a String on screen according to the addr.
;		specified in STRSHOW STRUCT
;
;Input	:	DS = CS
;		SI = (offset STRSHOW STRUCT) + 1
;		e.g. CLEAR1 <,0,0,offset string)
;
;Output	:	None
;
;Registers:	BX preserved
;		others unknown
;[]========================================================================[]
VStrshow	proc	near
		push	bx
		dec	si
		mov	bx,si

		mov	al,[bx].StartX
		cmp	al,-1
		je	short @F
		mov	CURSOR_X[bp],al
@@:
		mov	al,[bx].StartY
		cmp	al,-1
		je	short @F
		mov	CURSOR_Y[bp],al
@@:

		push	si
		mov	si,[bx].StrAddr
		call	Display_String
		pop	si

		add	si,5
		pop	bx
		ret
VStrshow	endp

;R72 - starts
VJmpString	Proc	Near
		mov	si,[si]
		ret
VJmpString	Endp
;R72 - ends

;[]========================================================================[]
;Function :	Program the cursor position according to the position
;		specified in POS STRUCT
;
;Input	:	DS = CS
;		SI = (offset POS STRUCT) + 1
;		e.g. POS <,0,0>
;
;Output :	CURSOR_X[bp] & CURSOR_Y[bp] updated
;
;Registers:	FLAG,SI - destroyed
;		others  - preserved
;[]========================================================================[]
VPos		Proc	Near
		push	ax
		lodsb
		cmp	al,-1
		je	short @F
		mov	CURSOR_X[bp],al
	@@:
		lodsb
		cmp	al,-1
		je	short @F
		mov	CURSOR_Y[bp],al
	@@:

		pop	ax
		ret
VPos		Endp
;r55 start
ifdef RPB_ENABLED                   ; RXX
;[]========================================================================[]
;Function:	RPB_SET_ATTRIBUTE
;
;Input:	    AL  = VT100 attribute
;Output:	  NONE
;
;Registers:	All preserved
;[]========================================================================[]
rpb_set_attribute proc

  push  ax
  mov   ah,0FFh                   ; set attribute function
  int   10h
  pop   ax

  ret

rpb_set_attribute endp
endif ; RPB_ENABLED
;r55 end
;[]========================================================================[]
;Function :	Set the display attrib to HILITE
;
;Input	:	None
;
;Output :	byte ptr ATTRIBUTE[bp] updated
;
;Registers:	All preserved
;[]========================================================================[]
Vhilite		proc	near
		push	ax
		push	bx
		mov	bx,Color_Offset[bp]
		mov	al,cs:[bx].CHILITE
		mov	ATTRIBUTE[bp],al
;r55 start
ifdef RPB_ENABLED                   ; RXX
    call  rpb_set_attribute
endif ; RPB_ENABLED
;r55 end
		pop	bx
		pop	ax
		ret
Vhilite		endp

;[]========================================================================[]
;Function :	Set the display attrib to REVERSE
;
;Input	:	None
;
;Output :	byte ptr ATTRIBUTE[bp] updated
;
;Registers:	All preserved
;[]========================================================================[]
Vreverse 	proc	near
		push	ax
		push	bx
		mov	bx,Color_Offset[bp]
		mov	al,cs:[bx].CREVERSE
		mov	ATTRIBUTE[bp],al
;r55 start
ifdef RPB_ENABLED                   ; RXX
    call  rpb_set_attribute
endif ; RPB_ENABLED
;r55 end
		pop	bx
		pop	ax
		ret
Vreverse	endp

;[]========================================================================[]
;Function :	Set the display attrib to NORMAL
;
;Input	:	None
;
;Output :	byte ptr ATTRIBUTE[bp] updated
;
;Registers:	All preserved
;[]========================================================================[]
Vnormal		proc	near
		push	ax
		push	bx
		mov	bx,Color_Offset[bp]
		mov	al,cs:[bx].CNORMAL
		mov	ATTRIBUTE[bp],al
;r55 start
ifdef RPB_ENABLED                   ; RXX
    call  rpb_set_attribute
endif ; RPB_ENABLED
;r55 end
		pop	bx
		pop	ax
		ret
Vnormal		endp

;[]========================================================================[]
;Function :	Set the display attrib to BLINK
;
;Input	:	None
;
;Output :	byte ptr ATTRIBUTE[bp] updated
;
;Registers:	FLAG   - detroyed
;		Others - preserved
;[]========================================================================[]
VBlink		Proc	Near
		or	byte ptr ATTRIBUTE[bp],80h
;r55 start
ifdef RPB_ENABLED                   ; RXX
    push  ax
		mov	  al,ATTRIBUTE[bp]
    call  rpb_set_attribute
    pop   ax
endif ; RPB_ENABLED
;r55 end
		ret
VBlink		Endp

;[]========================================================================[]
;Function :	Set the display attrib to WARN
;
;Input	:	None
;
;Output :	byte ptr ATTRIBUTE[bp] updated
;
;Registers:	All preserved
;[]========================================================================[]
VWarn		proc	near
		push	ax
		push	bx
		mov	bx,Color_Offset[bp]
		mov	al,cs:[bx].CWARN
		mov	ATTRIBUTE[bp],al
		pop	bx
		pop	ax
		ret
VWarn		endp

;[]========================================================================[]
;Function :	Move cursor to new line
;
;Input  :	None
;
;Output :	byte ptr Cursor_X[bp] & Cursor_Y[bp] changed
;
;Registers:	All preserved
;[]========================================================================[]
VNewLine	proc	near
		push	ax
		pushf
		inc	byte ptr CURSOR_Y[bp]
		mov	al,LMARGIN_X[bp]
		mov	CURSOR_X[bp],al
		popf
		pop	ax
		ret
VNewLine	endp

;[]========================================================================[]
;Function :	CURSOR X according to STUCT ADDX
;
;Input	:	DS
;		SI = (offset ADDX STRUCT) + 1
;		e.g. ADDX <,3>
;
;Output	:	byte ptr CURSOR_X[bp] changed
;
;Registers:	AL, SI, FLAG - Destroyed
;		Others	     - Preserved
;[]========================================================================[]
VADDX		Proc
		lodsb
		add	CURSOR_X[bp],al
		ret
VADDX		Endp

;[]========================================================================[]
;Function :	CURSOR X according to STUCT SUBX
;
;Input	:	DS
;		SI = (offset SUBX STRUCT) + 1
;		e.g. SUBX <,3>
;
;Output	:	byte ptr CURSOR_X[bp] changed
;
;Registers:	AL, SI, FLAG - Destroyed
;		Others	     - Preserved
;[]========================================================================[]
VSUBX		Proc
		lodsb
		sub	CURSOR_X[bp],al
		ret
VSUBX		Endp

;[]========================================================================[]
;Function :	CURSOR Y according to STUCT ADDY
;
;Input	:	DS
;		SI = (offset ADDY STRUCT) + 1
;		e.g. ADDY <,3>
;
;Output	:	byte ptr CURSOR_Y[bp] changed
;
;Registers:	AL, SI, FLAG - Destroyed
;		Others	     - Preserved
;[]========================================================================[]
VADDY		Proc
		lodsb
		add	CURSOR_Y[bp],al
		ret
VADDY		Endp

;[]========================================================================[]
;Function :	CURSOR Y according to STUCT SUBY
;
;Input	:	DS
;		SI = (offset SUBY STRUCT) + 1
;		e.g. SUBY <,3>
;
;Output	:	byte ptr CURSOR_Y[bp] changed
;
;Registers:	AL, SI, FLAG - Destroyed
;		Others	     - Preserved
;[]========================================================================[]
VSUBY		Proc
		lodsb
		sub	CURSOR_Y[bp],al
		ret
VSUBY		Endp

;[]========================================================================[]
;Function :	call a specified subroutine
;[]========================================================================[]
VCALLROUTINE	Proc	Near
		lodsw
		push	ds
		push	si
		call	ax
		pop	si
		pop	ds
		ret
VCALLROUTINE	Endp

;R43 - start
;[]========================================================================[]
;Function :	call a specified subroutine
;[]========================================================================[]
VCHG_COLOR	Proc	Near

		lodsb
		call	Get_Color_Off		;Get color status from CMOS
		ret

VCHG_COLOR	Endp
;R43 - end

;[]========================================================================[]
;Funtion :	Display 1 character on screen
;
;Input	:	al = ASCII code
;
;Output	:	CURSOR_X[bp] & CURSOR_Y[bp] changed
;
;Registers:	FLAG    - Destroyed
;		Others	- Preserved
;[]========================================================================[]
Display_Char	proc	near
		push	ax
		push	bx
		push	cx
		push	dx

;R24 start
		pushf
;R67ifdef	EPA_LOGO_Use_Graphics			;R63
;R67FULL_SCREEN_LOGO	EQU	1		;R63
;R67endif;	EPA_LOGO_Use_Graphics			;R63
;R67ifdef FULL_SCREEN_LOGO
ifdef	Graphics_Post						;R67

;R44		cmp	byte ptr CALLTYPE[bp],MODBIN_CALL	;R24A
;R44		je	short Is_Text_POST			;R24A
;R85		cmp	byte ptr CALLTYPE[bp],POST_CALL		;R44
		call	If_Code_Running_In_F000			;R85
		jne	short Is_Text_POST			;R44

		cli
		test	byte ptr Post_Temp_Byte[bp],Text_POST
		jnz	short Is_Text_POST
		mov	bl,al				;Store display ASCII
;R67ifndef	EPA_LOGO_Use_Graphics			;R63
;R67		mov	al,80*2				;1 char = 2 bytes
;R67		mul	byte ptr CURSOR_Y[bp]
;R67;R63 - start
;R67else;	EPA_LOGO_Use_Graphics
		push	bx
		mov	bl, byte ptr CURSOR_Y[bp]
		cmp	bl, 19h
		jb	short @f
		pop	bx
		mov	al, bl
		cmp	byte ptr EPALOGO_FLAG[bp], 055h	;R67;check is not EPALOGO
		je	short Exit_Display_Char		;R67
		jmp	short Is_Text_POST
	@@:
		mov	al,80*2				;1 char = 2 bytes
		mul	bl
;R67endif;	EPA_LOGO_Use_Graphics
;R67;R63 - end
		mov	cl,CURSOR_X[bp]
;R67;R63 - start
;R67ifdef	EPA_LOGO_Use_Graphics
		mov	bl, byte ptr CURSOR_Y[bp]
		cmp	bl, 2
		ja	short @f
		sub	cl, 3
	@@:
		pop	bx
;R67endif;	EPA_LOGO_Use_Graphics
;R67;R63 - end
		xor	ch,ch
		add	ax,cx
		add	ax,cx
		mov	di,ax
		add	di,Temp_VGA_Off
		mov	ax,Temp_VGA_Seg
		mov	es,ax
		mov	ah,ATTRIBUTE[bp]		;Get display attribute
		mov	al,bl
		stosw
;R67ifndef	EPA_LOGO_Use_Graphics			;R63
		cmp	byte ptr EPALOGO_FLAG[bp], 055h	;R67;check is not EPALOGO
		jne	short Is_Text_POST		;R67
		jmp	short Exit_Display_Char
;R67endif;	EPA_LOGO_Use_Graphics			;R63
Is_Text_POST:
endif;	Graphics_Post						;R67
;R67endif ;FULL_SCREEN_LOGO
;R24 end
		push	ax
		;Set cursor position to display item name
		mov	dl,CURSOR_X[bp]		;get column position
		mov	dh,CURSOR_Y[bp]		;get row position
		xor	bh,bh			;first page
		mov	ah,2			;set cursor position
;R44		int	10h
		Call	Check_Call_Source	;R44
		pop	ax

		mov	ah,09h			;write TTY
		mov	bl,byte ptr ATTRIBUTE[bp]
		mov	cx,1
;R44		int	10h
		Call	Check_Call_Source	;R44
Exit_Display_Char:					;R24
		inc	byte ptr CURSOR_X[bp]
		popf					;R24
		pop	dx
		pop	cx
		pop	bx
		pop	ax
		ret
Display_Char	endp

;R44 - start
Check_Call_Source	Proc	Near
;R71 ifdef	Notebook_Power_Management		;R44A
if	STD_Function	EQ	1			;R71
		cmp	byte ptr CALLTYPE[bp],SMM_CALL	
		jne	short Not_From_SMM		

		push	si
		extrn	Video_Func:near
		Call	Video_Func
		pop	si
		ret
Not_From_SMM:
endif	;STD_Function	EQ	1			;R71
;R71 endif	;Notebook_Power_Management			;R44A
		int	10h
		ret
Check_Call_Source	Endp
;R44 - end

;[]========================================================================[]
;Function :	Display a vertical line
;
;Input	:	AL - ASCII of line pattern
;		CL - Line length
;		DL - start point X
;		DH - start point Y
;
;Output	:	NONE
;
;Registers :	AX, FLAG - Destroyed
;		Others	- Preserved
;[]========================================================================[]
Show_Vertical	proc	near
		push	cx

		cmp	cl,0
		jl	short SV_End

		xor	ch,ch
		mov	byte ptr CURSOR_X[bp],dl
		mov	byte ptr CURSOR_Y[bp],dh

Show_Ver:
		call	Display_Char
		dec	byte ptr CURSOR_X[bp]
		inc	byte ptr CURSOR_Y[bp]

		loop	short Show_Ver
SV_End:
		pop	cx
		ret
Show_Vertical	endp

;[]========================================================================[]
;Function :	Display a Horizontal line
;
;Input :	AL - ASCII of line pattern
;		CL - Line length
;		DL - start point X
;		DH - start point Y
;
;Output	:	NONE
;
;Registers :	AX, FLAG - Destroyed
;		Others	 - Preserved
;[]========================================================================[]
Show_Horizontal	proc	near
		push	cx

		xor	ch,ch
		mov	byte ptr CURSOR_X[bp],dl
		mov	byte ptr CURSOR_Y[bp],dh

Show_Hon:
		call	Display_Char

		loop	short Show_Hon

		pop	cx
		ret
Show_Horizontal	endp

;[]========================================================================[]
;Function :	copy all ItemStat field of current page
;		into ITEMSTAT_BUF[bp]
;
;Input	:	None
;
;Output	:	ITEMSTAT_BUF[bp] updated
;
;Registers:	FLAG - Destroyed
;		Others - Preserved
;[]========================================================================[]
Update_ITEMSTAT_BUF	Proc	Near
		pusha

		mov	si,PAGE_START[bp]
		mov	di,ITEMSTAT_BUF
@@:
		mov	ax,cs:[si]
		mov	[bp+di],ax
		inc	di
		inc	di
		add	si,ITEM_SIZE
		cmp	si,PAGE_END[bp]
		jb	short @B

		popa
		ret
Update_ITEMSTAT_BUF	Endp

;[]========================================================================[]
;Function :	get the current status of one Menuitem into AX
;
;Input   :	bx point to Menuitem
;
;Output  :	ax = corresponding Itemstat in ITEMSTAT_BUF[bp]
;
;Registers :	FLAG - Destroyed
;		Others	    - Preserved
;[]========================================================================[]
Get_ItemStat_AX	Proc	Near
		push	si
		push	bx
		push	cx
		xor	si,si
	@@:
		sub	bx,ITEM_SIZE
		cmp	bx,PAGE_START[bp]
		jb	short @F
		inc	si
		jmp	short @B
	@@:
		mov	cl,1
		shl	si,cl
		mov	ax,ITEMSTAT_BUF[bp+si]

		pop	cx
		pop	bx

		cmp	byte ptr USE_ITEMSTAT_BUF[bp],0
		je	short @F
		mov	ax,[bx].itemstat
@@:

		pop	si
		ret
Get_ItemStat_AX	Endp

;[]========================================================================[]
;Function :	change the ItemStatus of one menuitem
;
;Input   :	bx = point to Menuitem
;		ax = Pattern to program to ITEMSTAT_BUF[bp]
;		     corresponding to [bx].ItemStat
;
;Output  :	corresponding ItemStat in ITEMSTAT_BUF[bp]
;
;Registers :	FLAG   - Destroyed
;		Others - Preserved
;[]========================================================================[]
Set_ITEMSTAT_AX	Proc	Near
		pusha
		xor	si,si
	@@:
		sub	bx,ITEM_SIZE
		cmp	bx,PAGE_START[bp]
		jb	short @F
		inc	si
		jmp	short @B
	@@:
		mov	cl,1
		shl	si,cl
		mov	ITEMSTAT_BUF[bp+si],ax
		popa
		ret
Set_ITEMSTAT_AX	Endp

;[]========================================================================[]
;Function :	Test the corresponging ItemStat with CX
;
;Input   :	BX point to menuitem
;		CX test pattern
;
;Output  :	FLAG register updated
;
;Registers :	FLAG   - Destroyed
;		Others - Preserved
;[]========================================================================[]
Test_ItemStat	Proc	Near
		push	ax
		call	Get_ItemStat_AX
		test	ax,cx
		pop	ax
		ret
Test_Itemstat	Endp

;[]========================================================================[]
;Function :	Check to see if there is any 'active item' in this page
;
;Input	:	None
;
;Output	:	ZF - No active item in this page i.e. all of them are
;		     SHOWONLY or ITEMDISABLE
;		NZ - at least one item active
;
;registers :	ZF changed
;[]========================================================================[]
Check_Active_Item	Proc	Near

		pusha
		pushf

		mov	bx,PAGE_START[bp]

		mov	dx,1				;assume no active item

Next_Active_Item:

		cmp	bx,PAGE_END[bp]			;page end reached?
		je	short Check_Active_Item_End	;yes, exit

		CHK_ITEMSTAT SHOWONLY+ITEMDISABLE+HIDDEN;this item active?
		jnz	short @F
		inc	dx
	@@:
		add	bx,ITEM_SIZE
		jmp	short Next_Active_Item

Check_Active_Item_End:

		popf
		dec	dx			;update ZF, others no change
						;if dx = 0, dec dx ===> ZF
						;   dx > 0, dec dx ===> NZ
		popa

		ret

Check_Active_Item	Endp

;[]========================================================================[]
;Function :	Move the REVERSE item according to LAST_KEY[bp]
;
;input	:	AX = key input
;		BX - menuitem offset
;
;output	: 	BX point to menuitem found
;		2. CF : item not changed
;		   NC : item changed
;
;Registers :	FLAG,BX - Destroyed
;		Others  - Preserved
;[]========================================================================[]
Move_Cursor	Proc	Near
		push	si
		push	di

		mov	ax,LAST_KEY[bp]		;hdd cur
Try_Up_Arrow:
		cmp	ax,UP_ARROW
		jne	short Try_Down_Arrow
		call	word ptr UP_ARROW_FUNC[bp]
		jmp	short Cursor_Changed
Try_Down_Arrow:
		cmp	ax,DOWN_ARROW
		jne	short Try_Left_Arrow
		call	word ptr DOWN_ARROW_FUNC[bp]
		jmp	short Cursor_Changed
Try_Left_Arrow:
		cmp	ax,LEFT_ARROW
		jne	short Try_Right_Arrow
		call	word ptr LEFT_ARROW_FUNC[bp]
		jmp	short Cursor_Changed
Try_Right_Arrow:
		cmp	ax,RIGHT_ARROW
		jne	short Cursor_Not_Changed
		call	word ptr RIGHT_ARROW_FUNC[bp]
Cursor_Changed:
		cmp	bx,si
		je	short Cursor_Not_Changed
		mov	bx,si
		pop	di
		pop	si
		clc
		ret

Cursor_Not_Changed:

		pop	di
		pop	si
		stc
		ret
Move_Cursor	Endp

;[]========================================================================[]
;Function :	Go up one item in respective to the sequence defined in
;		the menuitem list.
;		ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;Input	:	BX - item offset
;
;Output	:	SI - item found
;
;Registers :	SI, FLAG - Destroyed
;		Others - Preserved
;[]========================================================================[]
Seq_Up_By_Menu_List	Proc	Near
		push	bx
@@:
		sub	bx,ITEM_SIZE
		cmp	bx,word ptr PAGE_START[bp]
		jae	short Seq_Up_Exit
		mov	bx,word ptr PAGE_END[bp]
		sub	bx,ITEM_SIZE
Seq_Up_Exit:
		CHK_ITEMSTAT SHOWONLY+ITEMDISABLE+HIDDEN
		jnz	short @B
		mov	si,bx
		pop	bx
		ret
Seq_Up_By_Menu_List	Endp

;[]========================================================================[]
;Function :	Go down one item in respective to the sequence defined in
;		the menuitem list.
;		ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;Input	:	BX - item offset
;
;Output	:	SI - item found
;
;Registers :	SI, FLAG - Destroyed
;		Others - Preserved
;[]========================================================================[]
Seq_Down_By_Menu_List	Proc	Near
		push	bx
@@:
		add	bx,ITEM_SIZE
		cmp	bx,word ptr PAGE_END[bp]
		jb	short Seq_Down_Exit
		mov	bx,word ptr PAGE_START[bp]
Seq_Down_Exit:
		CHK_ITEMSTAT SHOWONLY+ITEMDISABLE+HIDDEN
		jnz	short @B
		mov	si,bx
		pop	bx
		ret
Seq_Down_By_Menu_List	Endp

;[]========================================================================[]
;Funtion :	1. Go up one item according to the X,Y axis of the items.
;		2. If the input item is at the top of the current column,
;		   item will go to the bottom of next column
;		3. ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;Input	:	BX - menuitem offset
;
;Output	:	SI point to menuitem found
;
;Registers :	SI, FLAG - Destroyed
;		Others   - Preserved
;[]========================================================================[]
Seq_Up		Proc	Near
		mov	di,offset ABOVE_NEXT
		jmp	short Seq_Down_1
Seq_Up		Endp

;[]========================================================================[]
;Funtion :	1. Go soen one item according to the X,Y axis of the items.
;		2. If the input item is at the bottom of the current column,
;		   item will go to the top of next column
;		3. ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;Input	:	BX - menuitem offset
;
;Output	:	SI point to menuitem found
;
;Registers :	SI, FLAG - Destroyed
;		Others   - Preserved
;[]========================================================================[]
Seq_Down	Proc	Near
		mov	di,offset BELOW_NEXT
;R83 Seq_Down_1:
Seq_Down_1	Label	Near		;R83
		push	bx

		call	Find_Extreme

		push	si			;save bottom item
		call	Neighbour_Item
		pop	ax			;ax = bottom item
		cmp	si,ax
		jne	short @F

		push	di
		mov	di,CHANGE_COL
		call	Neighbour_Item
		pop	di
		mov	bx,si
		call	Find_Extreme
	@@:
		pop	bx
		ret

Find_Extreme:
		push	di
		or	di,EXTREME
		xor	di,RIGHT_DOWN
		call	Neighbour_Item
		pop	di
		ret

Seq_Down	Endp

;[]========================================================================[]
;Function :	cursor go Up untill item found
;		ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;Input	:	BX - menuitem offset
;
;output	:	SI point to menuitem found
;
;Registers :	AX, SI, FLAG - Destroyed
;		Others   - Preserved
;[]========================================================================[]
Up_Line		Proc	Near
		mov	ah,-1
		call	Change_Line
		ret
Up_Line		Endp

;[]========================================================================[]
;Function :	cursor go down untill item found
;		ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;Input	:	BX - menuitem offset
;
;output	:	SI point to menuitem found
;
;Registers :	AX, SI, FLAG - Destroyed
;		Others   - Preserved
;[]========================================================================[]
Down_Line	Proc	Near
		mov	ah,1
		call	Change_Line
		ret
Down_Line	Endp

;[]========================================================================[]
;Function :	cursor go up/down untill item found
;		ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;Input	:	ah =  1 cursor go down untill item found
;		   = -1 cursor go up untill item found
;		bx - item offset
;
;Output	:	si point to menuitem found
;
;Registers :	SI, FLAG - Destroyed
;		Others   - Preserved
;[]========================================================================[]
MIN_Y	EQU	1
MAX_Y	EQU	23
Change_Line	Proc	Near
		push	cx
		push	bx
		push	dx
		push	di

		mov	ch,[bx].Item_Xaxis
		mov	cl,[bx].Item_Yaxis

		mov	dx,MAX_Y

Next_Line:
		add	cl,ah
		cmp	cl,MIN_Y
		jae	short @F
		mov	cl,MAX_Y
	@@:
		cmp	cl,MAX_Y
		jbe	short @F
		mov	cl,MIN_Y
	@@:
		mov	di,NEAREST
		push	dx
		call	NeighbourHood
		pop	dx
		cmp	bx,si
		jne	short @F
		dec	dx
		jnz	short Next_Line
@@:
		pop	di
		pop	dx
		pop	bx
		pop	cx
		ret
Change_Line	Endp

;[]========================================================================[]
;Function :	Go to item at right
;		ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;Input	:	BX - menuitem offset
;
;output	:	SI point to menuitem found
;
;Registers :	AX, SI, FLAG - Destroyed
;		Others   - Preserved
;[]========================================================================[]
Go_Right_Item	Proc	Near
		mov	di,RIGHT_NEXT
		jmp	Neighbour_Item
Go_Right_Item	Endp

;[]========================================================================[]
;Function :	Go to item at right extreme
;		ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;Input	:	BX - menuitem offset
;
;output	:	SI point to menuitem found
;
;Registers :	AX, SI, FLAG - Destroyed
;		Others   - Preserved
;[]=======================================================================[]
Go_Most_Right_Item	Proc	Near
		mov	di,RIGHT_MOST
		jmp	Neighbour_Item
Go_Most_Right_Item	Endp

;[]========================================================================[]
;Function :	Go to item at left
;		ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;Input	:	BX - menuitem offset
;
;output	:	SI point to menuitem found
;
;Registers :	AX, SI, FLAG - Destroyed
;		Others   - Preserved
;[]========================================================================[]
Go_Left_Item	Proc	Near
		mov	di,LEFT_NEXT
		jmp	Neighbour_Item
Go_Left_Item	Endp

;[]========================================================================[]
;Function :	Go to item at left extreme
;		ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;Input	:	BX - menuitem offset
;
;output	:	SI point to menuitem found
;
;Registers :	AX, SI, FLAG - Destroyed
;		Others   - Preserved
;[]========================================================================[]
Go_Most_Left_Item	Proc	Near
		mov	di,LEFT_MOST
		jmp	Neighbour_Item
Go_Most_Left_Item	Endp

;[]========================================================================[]
;Function :	Go to item at above
;		ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;Input	:	BX - menuitem offset
;
;output	:	SI point to menuitem found
;
;Registers :	AX, SI, FLAG - Destroyed
;		Others   - Preserved
;[]========================================================================[]
Go_Above_Item	Proc	Near
		mov	di,ABOVE_NEXT
		jmp	Neighbour_Item
Go_Above_Item	Endp

;[]========================================================================[]
;Function :	Go to item on top
;		ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;Input	:	BX - menuitem offset
;
;output	:	SI point to menuitem found
;
;Registers :	AX, SI, FLAG - Destroyed
;		Others   - Preserved
;[]========================================================================[]
Go_Most_Above_Item	Proc	Near
		mov	di,ABOVE_MOST
		jmp	Neighbour_Item
Go_Most_Above_Item	Endp

;[]========================================================================[]
;Function :	Go to item at below
;		ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;Input	:	BX - menuitem offset
;
;output	:	SI point to menuitem found
;
;Registers :	AX, SI, FLAG - Destroyed
;		Others   - Preserved
;[]========================================================================[]
Go_Below_Item	Proc	Near
		mov	di,BELOW_NEXT
		jmp	Neighbour_Item
Go_Below_Item	Endp

;[]========================================================================[]
;Function :	Go to item at bottom
;		ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;Input	:	BX - menuitem offset
;
;output	:	SI point to menuitem found
;
;Registers :	AX, SI, FLAG - Destroyed
;		Others   - Preserved
;[]========================================================================[]
Go_Most_Below_Item	Proc	Near
		mov	di,BELOW_MOST
		jmp	Neighbour_Item
Go_Most_Below_Item	Endp

Neighbour_Item:
		push	bx

		mov	ch,[bx].Item_Xaxis
		mov	cl,[bx].Item_Yaxis
		test	di,LEFT_RIGHT
		jnz	short Goto_Next
		xchg	ch,cl
Goto_Next:
		call	NeighbourHood
		cmp	si,bx
		jne	short Go_Left_Item_Exit

		test	di,EXTREME
		jnz	short Go_Left_Item_Exit
		push	di
		xor	di,RIGHT_DOWN
		or	di,EXTREME
		mov	bx,si
		call	NeighbourHood

		pop	di

Go_Left_Item_Exit:

		pop	bx

		ret

;[]========================================================================[]
;Function :	Go to the neighbourhood item on the same Y axis
;		ITEMDISABLE, SHOWONLY & HIDDEN is taken into consideration
;
;input :	ch - Xaxis if Left/Right operations
;		     Yaxis if Up/Down operations
;		cl - Yaxis if Left/Right operations
;		     Xaxis if Up/Down operations
;		di : NEAREST	 - goto nearest item (left or right)
;		     LEFT_NEXT	 - goto item at left
;		     LEFT_MOST	 - goto item at left most
;		     RIGHT_NEXT  - goto item at right
;		     RIGHT_MOST	 - goto item at right most
;		     ABOVE_NEXT	 - goto item above
;		     ABOVE_MOST	 - goto item at top most
;		     BELOW_NEXT  - goto item below
;		     BELOW_MOST  - goto item at bottom most
;
;output	:	if found : si point to the item found
;		else	 : si = input bx
;
;Registers :	SI, FLAG - Destroyed
;		Others   - Preserved
;[]========================================================================[]
CHANGE_COL	EQU	0000000000001000b

NEAREST		EQU	0000000000000011b

EXTREME		EQU	1000000000000000b	;0 : goto next
						;1 : goto extreme

LEFT_RIGHT	EQU	0000000000000010b	;0 : Up/Down operation
						;1 : Left/Right operation

RIGHT_DOWN	EQU	0000000000000100b	;0 : Left/Up operation
						;1 : Right/Down operation
LEFT_NEXT	EQU	0000000000000010b
LEFT_MOST	EQU	1000000000000010b

RIGHT_NEXT	EQU	0000000000000110b
RIGHT_MOST	EQU	1000000000000110b

ABOVE_NEXT	EQU	0000000000000000b
ABOVE_MOST	EQU	1000000000000000b

BELOW_NEXT	EQU	0000000000000100b
BELOW_MOST	EQU	1000000000000100b

NeighbourHood	Proc	Near
		push	ax
		push	bx
		push	dx

		mov	ah,0FFh			;find smallest
		test	di,EXTREME
		jz	short @F
		mov	ah,0			;find largest
	@@:
		mov	si,bx
		mov	bx,PAGE_START[bp]
Chk_Next_Item:

		mov	dh,[bx].Item_Xaxis
		mov	dl,[bx].Item_Yaxis
		test	di,LEFT_RIGHT		;move left/right
		jnz	short @F		;yes
		xchg	dh,dl			;swap x/y
	@@:
		cmp	bx,PAGE_END[bp]
		je	short NeighbourHood_Exit

		CHK_ITEMSTAT SHOWONLY+ITEMDISABLE+HIDDEN
		jnz	short Next_


	Change_Column:

		cmp	di,CHANGE_COL
		jne	short Goto_Nearest

		cmp	cl,dl
		je	short Next_

		mov	si,bx
		jmp	short NeighbourHood_Exit

	Goto_Nearest:

		cmp	cl,dl
		jne	short Next_

		cmp	di,NEAREST
		jne	short Goto_Right_Below

		mov	al,dh
		sub	al,ch
		jae	short Pick_Smallest
		neg	al
		jmp	short Pick_Smallest

	Goto_Right_Below:

		test	di,RIGHT_DOWN
		jz	short Goto_Left_Above

		mov	al,dh
		sub	al,ch
		jmp	short @F

	Goto_Left_Above:

		mov	al,ch
		sub	al,dh
	@@:
		jbe	short Next_
		test	di,EXTREME
		jnz	short Pick_Largest

	Pick_Smallest:

		cmp	al,ah
		jae	short Next_
		jmp	short @F

	Pick_Largest:

		cmp	al,ah
		jbe	short Next_
	@@:
		mov	ah,al
		mov	si,bx
Next_:
		add	bx,ITEM_SIZE
		jmp	short Chk_Next_Item

NeighbourHood_Exit:

		pop	dx
		pop	bx
		pop	ax

		ret
NeighbourHood	Endp

;[]========================================================================[]
;Funtion :	1. Call respective function for kernal page if ENTER is
;		   pressed
;		2. for standard CMOS page, if ENTER is pressed, change
;		   LAST_KEY[bp] to DOWN_ARROW
;
;Input	:	word ptr LAST_KEY[bp]
;
;Output	:	None
;
;Registers :	FLAG   - Destroyed
;		Others - Preserved
;[]========================================================================[]
Special_Enter	Proc	Near

		push	word ptr KERNAL_ITEM[bp]

		cmp	word ptr LAST_KEY[bp],K_CR1
		jne	short Special_Enter_Exit

;;Check if in kenal page

		cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL
		jne	short @F
		call	Special_Do_1
		jmp	short Special_Enter_Exit1

;;Check if in stand cmos page
@@:
		cmp	byte ptr CUR_PAGE[bp],PAGE_STDCMOS
		jne	short Special_Enter_Exit
;R97 start
ifdef Auto_HDD_Detect_IN_STDCMOS
		Xcall	X_Check_If_Auto_Type
		je	short Special_Enter_Exit	;yes
endif ;Auto_HDD_Detect_IN_STDCMOS
;R97 end
		mov	ax,RIGHT_ARROW
		mov	LAST_KEY[bp],ax

Special_Enter_Exit:

		clc

Special_Enter_Exit1:

		pop	word ptr KERNAL_ITEM[bp]
		ret

Special_Enter	Endp

;[]========================================================================[]
;Funtion :	Call respective SHOW function according to
;		the specail show list
;
;Input	:	None
;
;Output	:	None
;
;Registers :	FLAG   - Destroyed
;		Others - Preserved
;[]========================================================================[]
Special_Show	Proc	Near
		pusha
		mov	dx,2
;R83		call	short Check_Special_Call
		call	Check_Special_Call		;R83
		popa
		ret
Special_Show	Endp

;[]========================================================================[]
;Funtion :	Call respective DO function according to
;		the specail do list (except kernal page)
;
;Input	:	None
;
;Output	:	None
;
;Registers :	FLAG   - Destroyed
;		Others - Preserved
;[]========================================================================[]
		Public	Special_Do
;r55 start
ifdef RPB_ENABLED             ; RXX
		Public	Special_Do_1      
endif ; RPB_ENABLED
;r55 end
Special_Do	Proc	Near
		cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL
		je	short No_Special_Do
;R83 Special_Do_1:
Special_Do_1	Label	Near		;R83
		pusha
		mov	dx,0
;R83		call	short Check_Special_Call
		call	Check_Special_Call		;R83
		popa
No_Special_Do:
		ret
Special_Do	Endp

Check_Special_Call:

;----------------------------------------------------
;if it is not a special SHOW or DO request, skip this
;----------------------------------------------------

		cmp	dx,2			;special SHOW request?
		je	short @F		;yes
		or	dx,dx			;special DO request?
		jnz	short End_Special_HDD	;no, leave HDD special
	@@:

;R86;-----------------------------
;R86;if item is not HDD item, skip
;R86;-----------------------------
;R86
;R86		push	dx
;R86		call	Get_HDD_CMOS_Info	;HDD item(cylinder, head..)?
;R86		pop	dx
;R86		jc	short End_Special_HDD	;no, leave HDD special
;R86
;R86;---------------------------------------
;R86;direct to corresponding special routine
;R86;---------------------------------------
;R86
;R86		cmp	dx,2			;special show?
;R86		mov	dx,offset Show_HDD
;R86		je	short @F		;yes, all HDD special SHOW
;R86						;are directed to SHOW_HDD
;R86		mov	dx,offset Do_HDD
;R86		call	Check_If_HDD_Type_Item	;this item is HDD type item?
;R86		je	short @F		;yes!
;R86		mov	dx,offset Update_User_Type
;R86	@@:
;R86		call	dx
;R86		ret
;R86 - starts
		call	If_Code_Running_In_F000
		jne	End_Special_HDD			;no special in MODBIN

		call	fPROC_HDD_Special_Do_Show
		jz	Special_Call_Exit		;ZF: HDD Items done!
;R86 - ends
End_Special_HDD:

		mov	cl,CUR_PAGE[bp]
		dec	cl

		push	ax			;preserve last key
		mov	ax,Special_Do_Show_Diff
		mul	cl
		mov	si,offset Special_Do_Show_Off
		add	si,ax
		add	si,dx
		pop	ax			;restore last key

		mov	si,cs:[si]		;special call table addr
		mov	cx,cs:[si]		;no of items
		add	si,2			;List start

		or	cx,cx			;more to check?
		clc
		jz	short Special_Call_Exit	;no, exit

Next_Special_Call:
 		cmp	bx,cs:[si]		;item offset on list?
		je	short Special_Call_Found;yes, call the special routine
		add	si,4			;not found, point to next entry
		loop	short Next_Special_Call	;try next entry
		clc
		jmp	short Special_Call_Exit	;all checked, thus exit

Special_Call_Found:
		call	cs:[si+2]		;special routine found
						; call it
Special_Call_Exit:
		ret				;return to caller

;[]========================================================================[]
;Function :	Destroy word ptr LAST_KEY[bp]
;
;Input	:	None
;
;Output :	word ptr LAST_KEY[bp] = 0
;
;Registers :	All preserved
;[]========================================================================[]
Destroy_Key_Then_Ret:

		mov	word ptr LAST_KEY[bp],0
		ret

;R46 ;[]========================================================================[]
;R46 ;Function :	Read password and verify match or not
;R46 ;
;R46 ;Input	:	AL - 01h -> setup entering check
;R46 ;		AL - 02h -> setup and boot check
;R46 ;
;R46 ;Output	:	ZF - pass
;R46 ;		otherwise - infinite loop
;R46 ;[]========================================================================[]
;R46 ifdef	DOSVERSION
;R46 		MASTER_PASS_HASH	dw	01EAAh
;R46 endif;	DOSVERSION
;R46 Verify_Password	Proc	Near
;R46 
;R46 ;R40 - start
;R46 ifdef	HELP_IDIOT
;R46 		pusha
;R46 		extrn	Ct_CK_Password:near
;R46 		Call	Ct_Ck_Password
;R46 		popa
;R46 		jnc	short @F
;R46 		ret
;R46 @@:
;R46 endif	;HELP_IDIOT
;R46 ;R40 - end
;R46 ;R27 - starts
;R46 ifdef	Never_Disable_Password
;R46 		pusha
;R46 		mov	si, offset Security_Item
;R46 		call	GetItem_Value
;R46 		mov	ah, al
;R46 		and	byte ptr CMOS11[bp], not 01h
;R46 		and	ah, 01h
;R46 		or	byte ptr CMOS11[bp], ah
;R46 		cmp	al, 02h
;R46 		popa
;R46 		jb	short @F
;R46 		ret
;R46 	@@:
;R46 endif	;Never_Disable_Password
;R46 ;R27 - ends
;R46 
;R46 ifdef	Double_Password
;R46 		push	word ptr ATTRIBUTE[bp]
;R46 		push	word ptr TEMP_YEAR[bp]
;R46 
;R46 		cmp	al,02h				;booting?
;R46 		jne	short @F			;no, continue!
;R46 		test	byte ptr CMOS11[bp],01h		;booting need pass?
;R46 		jz	short Verify_Pass_Exit		;no, exit
;R46 	@@:
;R46 		mov	TEMP_YEAR[bp],al
;R46 
;R46 ifdef	Add_PASSWORD_LOOPS						;R31
;R46 		mov	byte ptr PASSWORD_LOOPS[bp],PASSWORD_LOOPS_NUM	;R31
;R46 		inc	byte ptr PASSWORD_LOOPS[bp]			;R31
;R46 endif;	Add_PASSWORD_LOOPS						;R31
;R46 
;R46 ;R37Chk_Super_Pass:						
;R46 		call	Backup_pass_screen		;R34
;R46 Chk_Super_Pass:						;R37
;R46 
;R46 ifdef	Add_PASSWORD_LOOPS				;R31
;R46 		dec	byte ptr PASSWORD_LOOPS[bp]	;R31
;R46 		jnz	short @F			;R31
;R46 ;R41 - start
;R46 		mov	ax,3			
;R46 		int	10h			
;R46 
;R46 		mov	si,offset ErrorHold_Msg
;R46 ;R41A		call	Display_String
;R46 		Call	Show_CS_String			;R41A
;R46 		cli
;R46 ;R41 - end
;R46 		jmp	$				;R31
;R46 	    @@:						;R31
;R46 endif;	Add_PASSWORD_LOOPS				;R31
;R46 
;R46 		mov	byte ptr SIX_DIGIT[bp],0	;R05
;R46 		mov	bx,offset SuperPassword_Item
;R46 		test	cs:[bx].ItemStat,ITEMDISABLE
;R46 		jnz	short Chk_User_Pass
;R46 
;R46 		test	byte ptr CMOS11[bp],02h		;Super Password needed?
;R46 		jz	short Chk_User_Pass		;no need!
;R46 
;R46 		call	Check_Pass_1
;R46 ifndef	No_Default_Password				;R36
;R46 		je	short Password_Valid
;R46 endif;	No_Default_Password				;R36
;R46 
;R46 	Comp_Super:
;R46 
;R46 		cmp	ax,CMOS1C[bp]			;super pass equal?
;R46 		je	short Password_Valid		;yes
;R46 
;R46 		cmp	byte ptr TEMP_YEAR[bp],01h	;R05 entering setup?
;R46 		jne	short @F			;R05 no
;R46 		mov	byte ptr SIX_DIGIT[bp],0AAh	;R05
;R46 	@@:						;R05
;R46 
;R46 	;it is a booting password check!
;R46 
;R46 		call	Chk_User_Needed			;user pass needed?
;R46 ;R41		jc	short Chk_Super_Pass		;no need, so only
;R46 ;R41							; super can boot!
;R46 ;R41		jmp	short Comp_User
;R46 ;R41 - Start
;R46 		jnc	short Comp_User
;R46 		Call	Error_PassWord
;R46 		jmp	short Chk_Super_Pass
;R46 ;R41 - end
;R46 
;R46 
;R46 Chk_User_Pass:
;R46 		call	Chk_User_Needed			;user pass needed?
;R46 		jc	short Password_Valid		;no need!
;R46 
;R46 		call	Check_Pass_1
;R46 ifndef	No_Default_Password				;R36
;R46 		je	short Password_Valid
;R46 endif;	No_Default_Password				;R36
;R46 
;R46 	Comp_User:
;R46 
;R46 		call	Ct_User_Password_Location
;R46 		cmp	ax,[bp+di]			;user pass equal?
;R46 ;R41		jne	short Chk_Super_Pass		;yes
;R46 ;R41 - Start
;R46 		je	short Password_Valid
;R46 		Call	Error_PassWord
;R46 		jmp	short Chk_Super_Pass
;R46 ;R41 - end
;R46 
;R46 Password_Valid:
;R46 		call	Restore_pass_screen		;R34
;R46 Verify_Pass_Exit:
;R46 
;R46 		pop	word ptr TEMP_YEAR[bp]		;use this word
;R46 		pop	word ptr ATTRIBUTE[bp]
;R46 
;R46 		ret
;R46 
;R46 ;
;R46 ;output	:	ZF : input password = MASTER_PASS_HASH
;R46 ;		AX : Hashed password
;R46 ;
;R46 Check_Pass_1:
;R46 		mov	byte ptr CUR_PAGE[bp],0	; don't update time
;R46 		mov	word ptr LAST_KEY[bp],0	; dummy word
;R46 		call	Get_Password
;R46 ifndef	No_Default_Password			;R36
;R46 		cmp	ax,cs:MASTER_PASS_HASH	; default password
;R46 endif;	No_Default_Password			;R36
;R46 		ret
;R46 ;
;R46 ;output	:	CY =	user password not needed
;R46 ;		NC =	user password needed
;R46 ;
;R46 Chk_User_Needed:
;R46 		mov	bx,offset UserPassword_Item
;R46 		test	cs:[bx].ItemStat,ITEMDISABLE
;R46 		jnz	short @F
;R46 
;R46 		call	Ct_User_Password_Location
;R46 		test	[bp+si],dl			;user password needed?
;R46 		jz	short @F			;no need!
;R46 
;R46 		clc			;user password needed
;R46 		ret
;R46 	@@:
;R46 		stc			;user password not needed
;R46 		ret
;R46 
;R46 else	;Double_Password
;R46 
;R46 		push	bx			;save bx
;R46 		mov	bl,ATTRIBUTE[bp]
;R46 		push	bx			;save attribute
;R46 
;R46 		mov	bx,offset SECURITY_ITEM
;R46 		test	cs:[bx].ItemStat,ITEMDISABLE
;R46 		jnz	short No_Security
;R46 
;R46 		test	byte ptr CMOS11[bp],02h
;R46 		jz	short No_Security
;R46 
;R46 		test	byte ptr CMOS11[bp],01h	;setup & boot both needed?
;R46 		jnz	short Check_Pass	;yes
;R46 
;R46 		cmp	al,2			;boot password?
;R46 		je	short No_Security	;yes, exit
;R46 
;R46 ifdef	Add_PASSWORD_LOOPS						;R31
;R46 		mov	byte ptr PASSWORD_LOOPS[bp],PASSWORD_LOOPS_NUM	;R31
;R46 		inc	byte ptr PASSWORD_LOOPS[bp]			;R31
;R46 endif;	Add_PASSWORD_LOOPS						;R31
;R46 
;R46 Check_Pass:						
;R46 		call	Backup_pass_screen		;R34
;R46 Check_Pass_1:						;R37
;R46 
;R46 ifdef	Add_PASSWORD_LOOPS				;R31
;R46 		dec	byte ptr PASSWORD_LOOPS[bp]	;R31
;R46 		jnz	short @F			;R31
;R46 ;R41 - start
;R46 		mov	ax,3			
;R46 		int	10h			
;R46 
;R46 		mov	si,offset ErrorHold_Msg
;R46 ;R41A		call	Display_String
;R46 		Call	Show_CS_String			;R41A
;R46 		cli
;R46 ;R41 - end
;R46 		jmp	$				;R31
;R46 	    @@:						;R31
;R46 endif;	Add_PASSWORD_LOOPS				;R31
;R46 
;R46 		mov	byte ptr CUR_PAGE[bp],0	; don't update time
;R46 		mov	word ptr LAST_KEY[bp],0	; dummy word
;R46 		call	Get_Password
;R46 ifdef	Perfect_Password				;R16
;R46 		call	Chk_Perfect_Password		;R16
;R46 else	;Perfect_Password				;R16
;R46 ifndef	No_Default_Password				;R36
;R46 		cmp	ax,cs:MASTER_PASS_HASH	; default password
;R46 ;R34B		je	short No_Security
;R46 		je	short No_Security_1		;R34B
;R46 endif;	No_Default_Password				;R36
;R46 		cmp	ax,CMOS1C[bp]
;R46 endif	;Perfect_Password				;R16
;R46 
;R46 ;R37		jne	short Check_Pass
;R46 ;R41		jne	short Check_Pass_1		;R37
;R46 ;R41 - Start
;R46 		je	short No_Security_1
;R46 		Call	Error_PassWord
;R46 		jmp	short Check_Pass_1	
;R46 ;R41 - end
;R46 No_Security_1:						;R34B
;R46 		call	Restore_pass_screen		;R34B
;R46 No_Security:
;R46 ;R34B		call	Restore_pass_screen		;R34
;R46 		pop	bx			;restore attribute
;R46 		mov	ATTRIBUTE[bp],bl
;R46 		pop	bx			;restore bx
;R46 		ret
;R46 
;R46 endif	;Double_Password
;R46 Verify_Password	endp
;R46 
;R46 ;R41 - start
;R46 Error_PassWord:
;R46 		mov	si,offset ErrorPass_Msg
;R46 ;R41A		call	Display_String
;R46 		Call	Show_CS_String			;R41A
;R46 
;R46 		xor	ax,ax			;wait for key
;R46 		int	16h
;R46 
;R46 		call	Restore_pass_screen
;R46 		ret
;R46 ;R41 - end
;R46 ;R34 start
;R46 temp_mem	equ	8000h
;R46 Backup_pass_screen:
;R46 	push	es
;R46 	pusha
;R46 	mov	ax,temp_mem
;R46 	mov	es,ax
;R46 	xor	di,di
;R46 	cld
;R46 ;R41	mov	dh,PassMsg_Start_Y
;R46 	mov	dh,ErrorPass_Start_Y		;R41
;R46 LoopY0:
;R46 ;R41	mov	dl,PassMsg_Start_X
;R46 	mov	dl,ErrorPass_Start_X		;R41
;R46 LoopX0:
;R46 	mov	ah,2
;R46 	xor	bh,bh
;R46 	int	10h				;set cursor position
;R46 	mov	ah,8
;R46 	int	10h				;get char and attribute
;R46 	stosw
;R46 	inc	dl
;R46 	cmp	dl,PassMsg_End_X
;R46 	jbe	short LoopX0
;R46 	inc	dh
;R46 	cmp	dh,PassMsg_End_Y
;R46 	jbe	short LoopY0
;R46 	popa
;R46 	pop	es
;R46 	ret
;R46 ;
;R46 Restore_pass_screen:
;R46 	push	ds
;R46 	pusha
;R46 	pushf
;R46 	mov	ax,temp_mem
;R46 	mov	ds,ax
;R46 	xor	si,si
;R46 ;R41	mov	dh,PassMsg_Start_Y
;R46 	mov	dh,ErrorPass_Start_Y		;R41
;R46 LoopY1:
;R46 ;R41	mov	dl,PassMsg_Start_X
;R46 	mov	dl,ErrorPass_Start_X		;R41
;R46 LoopX1:
;R46 	mov	ah,2
;R46 	xor	bh,bh
;R46 	int	10h				;set cursor position
;R46 	lodsw
;R46 	mov	bl,ah
;R46 	mov	ah,9
;R46 	mov	cx,1
;R46 	int	10h				;get char and attribute
;R46 	inc	dl
;R46 	cmp	dl,PassMsg_End_X
;R46 	jbe	short LoopX1
;R46 	inc	dh
;R46 	cmp	dh,PassMsg_End_Y
;R46 	jbe	short LoopY1
;R46 	popf
;R46 	popa
;R46 	pop	ds
;R46 	ret
;R46 ;R34 end
;R46 
;R46 ;R05 - starts
;R46 ifdef	Double_Password
;R46 Hidden_Except_UserPass	Proc	Near
;R46 
;R46 		mov	bx,PAGE_START[bp]
;R46 		mov	dx,PAGE_END[bp]
;R46 		sub	dx,ITEM_SIZE*2
;R46 	@@:
;R46 		call	Get_ItemStat_AX
;R46 		or	ax,SHOWONLY
;R46 		call	Set_ItemStat_AX
;R46 		add	bx,ITEM_SIZE
;R46 		cmp	bx,dx
;R46 		jb	short @B
;R46 
;R46 		mov	bx,offset UserPassword_Item
;R46 		call	Get_ItemStat_AX
;R46 		and	ax,not (ITEMDISABLE+SHOWONLY)
;R46 		call	Set_ItemStat_AX
;R46 
;R46 		mov	si,offset jjkkll
;R46 		call	Display_String
;R46 
;R46 		ret
;R46 
;R46 jjkkll:
;R46 		CLEAR	<,1,4,79,20>
;R46 		db	0
;R46 
;R46 Hidden_Except_UserPass	Endp
;R46 endif	;Double_Password
;R46 ;R05 - ends
;R46 
;R46 ;[]========================================================================[]
;R46 ;Function :	Get password for system or setup access
;R46 ;
;R46 ;Input	:	None
;R46 ;
;R46 ;Output	:	AX : hashed password
;R46 ;[]========================================================================[]
;R46 Get_Password	Proc	Near
;R46 		mov	si,offset EnterPass_Msg
;R46 		jmp	short Input_Pass
;R46 
;R46 Confirm_Password:
;R46 
;R46 		mov	si,offset ConfirmPass_Msg
;R46 Input_Pass:
;R46 ;R41A		push	ds
;R46 ;R41A		push	cs
;R46 ;R41A		pop	ds
;R46 ;R41A		call	Display_String
;R46 ;R41A		pop	ds
;R46 		Call	Show_CS_String			;R41A
;R46 
;R46 		mov	dl,ECHO_ASTERISK+EDIT_PUNCT+\
;R46 			   EDIT_LOWER+EDIT_UPPER+\
;R46 			   EDIT_DEC			;keyin type
;R46 		mov	cl,8				;maximum 8 characters
;R46 		call	Edit_String			;get string into buffer
;R46 
;R46 Re_Get_Key:						;R42
;R46 		cmp	word ptr LAST_KEY[bp],K_CR1	;R42
;R46 		je	short Check_Key_Buffer		;R42
;R46 		push	offset Re_get_Key		;R42
;R46 		jmp	Get_Key				;R42
;R46 Check_Key_Buffer:					;R42
;R46 		cmp     byte ptr KEYIN_BUF[bp],0
;R46 		je	short Input_Pass_Bad		;buffer is empty
;R46 ;R42		cmp	word ptr LAST_KEY[bp],K_CR1	;is <Enter> pressed?
;R46 ;R42		jne	short Input_Pass_Bad		;no, then exit
;R46 
;R46 Input_Pass_Good:
;R46 ifndef	Perfect_Password			;R16
;R46 		call	Hash_Password
;R46 endif	;Perfect_Password			;R16
;R46 		clc
;R46 		ret
;R46 
;R46 Input_Pass_Bad:
;R46 		stc
;R46 		ret
;R46 
;R46 ;R41A - start
;R46 		Public	Show_CS_String
;R46 Show_CS_String:
;R46 		push	ds
;R46 		push	cs
;R46 		pop	ds
;R46 		call	Display_String
;R46 		pop	ds
;R46 		ret
;R46 ;R41A - end
;R46 EnterPass_Msg	db	V_REVERSE
;R46 ;R03		BORDER1 <,24,12,54,14,0+Empty_Border>
;R46 ;R34		BORDER1 <,24,13,54,15,0+Empty_Border>	;R03
;R46 ;R34 start
;R46 PassMsg_Start_X	equ	24
;R46 PassMsg_Start_Y	equ	13
;R46 PassMsg_End_X	equ	54
;R46 PassMsg_End_Y	equ	15
;R46 		BORDER1 <,PassMsg_Start_X,PassMsg_Start_Y,PassMsg_End_X,PassMsg_End_Y,0+Empty_Border>
;R46 ;R34 end
;R46 ;R03		POS	<,26,13>
;R46 		POS	<,26,14>			;R03
;R46 		db	'Enter Password:   '
;R46 		db	0
;R46 
;R46 ConfirmPass_Msg	db	V_REVERSE
;R46 ;R03		POS	<,26,13>
;R46 		POS	<,26,14>			;R03
;R46 		db	'Confirm Password: '
;R46 		db	0
;R46 
;R46 ;R41 - start
;R46 ErrorPass_Msg	db	V_REVERSE
;R46 ErrorPass_Start_X	equ	24
;R46 ErrorPass_Start_Y	equ	12
;R46 ErrorPass_End_X		equ	54
;R46 ErrorPass_End_Y		equ	15
;R46 		BORDER1 <,ErrorPass_Start_X,ErrorPass_Start_Y,ErrorPass_End_X,ErrorPass_End_Y,0+Empty_Border>
;R46 		POS	<,31,13>			
;R46 		db	'Invalid Password !'
;R46 		POS	<,26,14>			
;R46 		db	'Press Any Key to Continue. '
;R46 		db	0
;R46 
;R46 ErrorHold_Msg	db	V_REVERSE
;R46 ErrorHold_Start_X	equ	24
;R46 ErrorHold_Start_Y	equ	13
;R46 ErrorHold_End_X		equ	54
;R46 ErrorHold_End_Y		equ	15
;R46 		BORDER1 <,ErrorHold_Start_X,ErrorHold_Start_Y,ErrorHold_End_X,ErrorHold_End_Y,0+Empty_Border>
;R46 		POS	<,32,14>
;R46 		db	'System Disabled'
;R46 		db	0
;R46 ;R41 - end
;R46 Get_Password	Endp
;R46 
;R46 ;[]========================================================================[]
;R46 ;Function :	Encode the password using hash algorithm
;R46 ;
;R46 ;Input	:	KEYIN_BUF[bp]
;R46 ;
;R46 ;Output	:	AX - hashed password
;R46 ;[]========================================================================[]
;R46 Hash_Password	Proc    Near
;R46 
;R46 ifndef	Perfect_Password			;R16
;R46 
;R46 		push    si 			; save regs
;R46 		push    bx
;R46 		push    cx
;R46 		push    dx
;R46 
;R46 		xor     si,si			; clear index
;R46 		xor     bx,bx			; clear current hash value
;R46 		xor	ah,ah
;R46 		mov     cx,8			; set length counter
;R46 hash_pw1:
;R46 		mov     al,KEYIN_BUF[bp+si]
;R46 		or	al,al			; last byte = 0?
;R46 		jz	hash_done		; skip to quit if so
;R46 		rol	bx,1			; adjust
;R46 		rol	bx,1
;R46 ifdef	KEYBOARD_SECURITY
;R46 		call	Ascii_To_Scan
;R46 endif;	KEYBOARD_SECURITY
;R46 		add	bx,ax			; add in current char
;R46 		inc	si			; bump index
;R46 		loop	hash_pw1		; do for all significant password chars
;R46 hash_done:
;R46 		xchg	ax,bx			; return result in ax
;R46 		pop     dx			; restore regs
;R46 		pop     cx
;R46 		pop     bx
;R46 		pop     si
;R46 
;R46 endif	;Perfect_Password			;R16
;R46 
;R46 		ret
;R46 
;R46 Hash_Password	Endp
;R46 
;R46 ;R16 - starts
;R46 ifdef	Perfect_Password
;R46 ;[]==============================================================[]
;R46 ;Procedure :	Save_Perfect_Password
;R46 ;
;R46 ;Input	:	KEYIN_BUF[bp] to KEYIN_BUF[bp+7]
;R46 ;
;R46 ;Output	:	None
;R46 ;
;R46 ;Save	:	All registers
;R46 ;
;R46 ;Note	:	Save the characters stored in 
;R46 ;		KEYIN_BUF[bp] to KEYIN_BUF[bp+7] to CMOS RAM
;R46 ;[]==============================================================[]
;R46 		Public	Save_Perfect_Password
;R46 Save_Perfect_Password	Proc	Near
;R46 
;R46 		pusha
;R46 
;R46 		mov     cx,8			; set length counter
;R46 		xor	si,si			;index to point to KEYIN_BUF[bp]
;R46 		call	Ct_Perfect_Password_Loc	;DI point to CMOS
;R46 
;R46 Save_Next_Pass_Byte:
;R46 
;R46 		mov     al,KEYIN_BUF[bp+si]
;R46 		ror	al,3
;R46 		mov	[bp+di],al
;R46 		inc	si
;R46 		inc	di
;R46 		loop	short Save_Next_Pass_Byte	;
;R46 
;R46 		popa
;R46 		ret
;R46 
;R46 Save_Perfect_Password	Endp
;R46 
;R46 ;[]==============================================================[]
;R46 ;Procedure :	Chk_Perfect_Password
;R46 ;
;R46 ;Input	:	KEYIN_BUF[bp] to KEYIN_BUF[bp+7]
;R46 ;
;R46 ;Output	:	ZF : Input password correct
;R46 ;		NZ : Input password wrong
;R46 ;
;R46 ;Save	:	All registers
;R46 ;
;R46 ;Note	:	compare KEYIN_BUF[bp] to KEYIN_BUF[bp+7]
;R46 ;		with CMOS RAM's data
;R46 ;[]==============================================================[]
;R46 		Public	Chk_Perfect_Password
;R46 Chk_Perfect_Password	Proc	Near
;R46 
;R46 		pusha
;R46 
;R46 		mov     cx,8			;set length counter
;R46 		xor	si,si			;index to point to KEYIN_BUF[bp]
;R46 		call	Ct_Perfect_Password_Loc	;DI point to CMOS
;R46 
;R46 Chk_Next_Pass_Byte:
;R46 
;R46 		mov	al,KEYIN_BUF[bp+si]	;key in byte
;R46 		mov	ah,[bp+di]		;pass word byte in CMOS
;R46 		ror	al,3
;R46 		cmp	al,ah			;pass word byte in CMOS
;R46 		jne	short Chk_Pass_End
;R46 
;R46 		or	ax,ax
;R46 		jz	short @F
;R46 
;R46 		inc	si
;R46 		inc	di
;R46 		loop	short Chk_Next_Pass_Byte
;R46 	@@:
;R46 		xor	al,al
;R46 
;R46 	Chk_Pass_End:
;R46 
;R46 		popa
;R46 		ret
;R46 
;R46 Chk_Perfect_Password	Endp
;R46 endif	;Perfect_Password
;R46 ;R16 - ends

ifdef	PM_SUPPORT
			Public	Get_PM_Auto_Value
Get_PM_Auto_Value	Proc	Near
		push	ax
		push	cx
		push	si
		push	di
		push	word ptr OLDITEM[bp]
		push	word ptr TEMP_YEAR[bp]		;use this word
							;for temporary use
		call	PM_Option_Check			;si=offset auto-table
		mov	OLDITEM[bp],si
		mov	word ptr TEMP_YEAR[bp],K_F7
		call	Auto_Value_Or_BIOS_D4

		pop	word ptr TEMP_YEAR[bp]
		pop	word ptr OLDITEM[bp]
		pop	di
		pop	si
		pop	cx
		pop	ax

		ret
Get_PM_Auto_Value	Endp
endif	;PM_SUPPORT

;[]========================================================================[]
;Function :	Get the item value on the auto-cfg table according to current
;		system clock
;
;Input	:	BX - item which needed to be auto-cfg
;
;Output	:	DX - auto-cfg value
;
;Registers :	BX - Destroyed
;		Others - Preserved
;[]========================================================================[]


Get_Auto_Cfg_Value	Proc	Near
		push	ax
		push	cx
		push	si
		push	di
		push	word ptr OLDITEM[bp]
		push	word ptr TEMP_YEAR[bp]		;use this word
							;for temporary use

		mov	word ptr TEMP_YEAR[bp],K_F7

;Get mask bits from auto-cfg ROM table

;R23		push	ds
;R23		mov	ax,G_RAM
;R23		mov	ds,ax
;R23		assume	ds:G_RAM
;R23		mov	al,ds:[CPU_CLOCK]
;R23
;R23;R10		test	byte ptr OVERRIDE[bp],DOUBLE_CLOCK+THREE_CLOCK
;R23		test	byte ptr OVERRIDE[bp],CLOCK_MODE		;R10
;R23		jz	short OneClk
;R23
;R23	      	cmp	al,CPU25
;R23	      	jae	short @F
;R23
;R23		mov	al,CPU25
;R23@@:
;R23		sub	al,CPU20		;DX2 must start from 25Mhz
;R23OneClk:
;R23
;R23		xor	ah,ah
;R23		mov	cl,3
;R23		shr	ax,cl
;R23		dec	ax
;R23		dec	ax
;R23
;R23		pop	ds
;R23		assume	ds:DGROUP
;R23
;R23		mov	si,offset cs:Auto_Table_List
;R23		mov	dl,FIXED_DISK_STEP[bp]
;R23		and	dl,not CPUCACHE+COPROCESSOR
;R23		xor	dh,dh
;R23		add	si,dx
;R23		mov	si,cs:[si]
;R23
;R23		call	Ct_ReTable_Auto
;R23		add	si,ax
;R23		mov	si,cs:[si]		;si point to auto cfg data

		extrn	Auto_Table:near				;R25
		mov	si, offset Auto_Table			;R25
		cmp	byte ptr CALLTYPE[bp],MODBIN_CALL	;R25
		je	short @F				;R25

		call	Get_Auto_Table_Offset		;R23
	@@:							;R25

		mov	OLDITEM[bp],si

;----------------------------------------------------------------------------

		call	Auto_Value_Or_BIOS_D4

		mov	di,cs:[bx].CmosMask
		call	Mask_To_Mask_Trans
		push	ax
		call	Read_Item_Value
		pop	dx
		shr	dx,cl

		pop	word ptr TEMP_YEAR[bp]
		pop	word ptr OLDITEM[bp]
		pop	di
		pop	si
		pop	cx
		pop	ax

		ret
Get_Auto_Cfg_Value	Endp

;R61Aifdef	DOSVERSION
;R61A		public	Auto_Table_List
;R61AAuto_Table_List:
;R61A		dw	Auto_CPU_386DX
;R61A		dw	Auto_CPU_386SX
;R61A		dw	Auto_CPU_386SL
;R61A		dw	Auto_CPU_486DX
;R61A		dw	Auto_CPU_486SX
;R61A		dw	Auto_CPU_486DX2
;R61A		dw	Auto_CPU_486SLC
;R61A		dw	Auto_CPU_486DLC
;R61A		dw	Auto_CPU_IBM386SLC
;R61A		dw	Auto_CPU_IBM486SLC2
;R61A		dw	Auto_CPU_P24T
;R61A		dw	Auto_CPU_486DXS
;R61A		dw	Auto_CPU_486SXS
;R61A		dw	Auto_CPU_486DX2S
;R61A		dw	Auto_CPU_IBM486DLC3
;R61Aendif	;DOSVERSION

;[]========================================================================[]
;Function :	Program the items in Auto_Item_List to be SHOWONLY or NORMAL
;
;Input	:	None
;
;Output	:	Itemstat of all items in Auto_Item_List will be:
;		- SHOWONLY if auto configuration is enabled
;		- not SHOWONLY if auto configuration is disabled
;
;Note	:	This is a special show routine which will be called by
;		Display_ItemVar
;[]========================================================================[]
Show_auto_Cfg	Proc	Near
		cmp	al,Special_Before
		jne	short S_Auto_9

		call	Read_Item_Value
		xor	di,di
		or	dx,dx
		jz	short S_Auto_1
		or	di,SHOWONLY
S_Auto_1:
		push	word ptr CURSOR_X[bp]
		push	bx

		mov	bx,PAGE_START[bp]
S_Auto_3:
		CHK_ITEMSTAT AUTOPROG
		jz	short S_Auto_4

;program SHOWONLY or NORMAL

		test	word ptr [bx].ItemStat,SHOWONLY
		jnz	short @F
		call	Get_Itemstat_AX
		and	ax,not SHOWONLY
		or	ax,di
		call	Set_Itemstat_AX
	@@:
		pusha
		call	Display_Whole_Item
		popa
S_Auto_4:
		add	bx,ITEM_SIZE
		cmp	bx,PAGE_END[bp]
;R57		jbe	short S_Auto_3
		jb	short S_Auto_3		;R57
S_Auto_8:
		pop	bx
		pop	word ptr CURSOR_X[bp]
S_Auto_9:
		clc
		ret

Show_auto_Cfg	endp

;R38 - starts
		Public	If_Less_Than_CX_Dis
If_Less_Than_CX_Dis	Label	Near

		push	dx
		mov	dl, -1
		jmp	short If_XXX_Then_Dis

		Public	If_Greater_Than_CX_Dis
If_Greater_Than_CX_Dis	Label	Near

		push	dx
		mov	dl, -2
		jmp	short If_XXX_Then_Dis
;R38 - ends

;R21 - starts
;-------------------------------------------------------------------------
;Input	:	BX = Item which value is to be compared with CL
;		CX = value to be compared with item value
;		DI = Table of items that are to be hidden or re-enable
;
;Output	:	If ((item value of BX)=CX)
;		{
;		  Items specified in table pointed by DI will be hidden
;		}
;		else
;		{
;		  Items specified in table pointed by DI will be re-enable
;		};
;-------------------------------------------------------------------------
		Public	If_CX_Then_Dis
If_CX_Then_Dis	Proc	Near

		push	dx					;R38
		xor	dl, dl					;R38
;R83 If_XXX_Then_Dis:						;R38
If_XXX_Then_Dis	Label	Near					;R83
		cmp	al,Special_Before
		je	short If_CX_Then_Dis_Exit

		pusha
;R38		push	word ptr ATTRIBUTE[bp]
;R38		push	word ptr Cursor_X[bp]
;R38 - starts
.386
		push	dword ptr ATTRIBUTE[bp]
;R83 .286
;R38 - ends

		push	dx					;R38
		push	cx
		call	VNormal
		call	Read_Item_Value
		pop	cx
		cmp	dx,cx
		mov	si,offset Self_Dis
		pop	ax					;R38

;R38 - starts
		mov	ah, 0				;equal
		je	short @F			;equal
		inc	ah				;does not affect CF
		jb	short @F			;less than
		inc	ah				;greater than
	@@:
		add	ah, al
;R38 - ends
		je	short @F
		mov	si,offset Re_Enable
	@@:
		mov	bx,cs:[di]
		cmp	bx,-1
		je	short @F
		push	di
		call	si
		pop	di
		inc	di
		inc	di
		jmp	short @B
	@@:
;R38 - starts
.386
		pop	dword ptr ATTRIBUTE[bp]
;R83 .286
;R38 - ends
;R38		pop	word ptr Cursor_X[bp]
;R38		pop	word ptr ATTRIBUTE[bp]
		popa

If_CX_Then_Dis_Exit:

		pop	dx					;R38

		clc
		ret

If_CX_Then_Dis	Endp

;----------------------------------------------------------
;
;	To set the ITEMDISABLE flag of specified item &
;	then clear that line !
;
;Input	:	BX = Item offset
;
;Output	:	None
;
;----------------------------------------------------------
		public	Self_Dis
Self_Dis	Proc	Near
		push	si

		test	cs:[bx].ItemStat,ITEMDISABLE
		jnz	short @F

	;R32 - starts
		pusha
		call	Display_Whole_Item
		popa
	;R32 - ends

		mov	ax,word ptr cs:[bx].Item_Xaxis
		mov	CURSOR_X[bp],ax
		call	Self_Disable
	@@:
		pop	si
		ret
Self_Dis	Endp

;----------------------------------------------------------
;
;	To clear the ITEMDISABLE flag of specified item &
;	then show it again.
;
;Input	:	BX = Item offset
;
;Output	:	None
;
;----------------------------------------------------------
		public	Re_Enable
Re_Enable	Proc	Near
		push	si
		call	Get_ItemStat_AX
		test	cs:[bx].ItemStat,ITEMDISABLE
		jnz	short @F
		and	ax,not ITEMDISABLE
	@@:
		call	Set_ItemStat_AX
		call	Display_Whole_Item
		pop	si
		ret
Re_Enable	Endp
;R21 - ends

;[]====================================================================[]
;[]====================================================================[]
		Public	Self_Disable
Self_Disable	Proc	Near
		push	word ptr CURSOR_X[bp]
		push	ax
		push	cx

		call	Get_ItemStat_AX
		or	ax,ITEMDISABLE
		call	Set_ItemStat_AX

		mov	ah,1
		mov	cx,38
		cmp	byte ptr CURSOR_X[bp],40
		jbe	short @F
;R47		dec	cx
		add	ah,40
	@@:
		mov	CURSOR_X[bp],ah
		mov	al,' '
	@@:
		call	Display_Char
		loop	short @B

		pop	cx
		pop	ax
		pop	word ptr CURSOR_X[bp]
		ret
Self_Disable	Endp

;[]----------------------------------------------------------------[]
;GetItem_Cmos
;	Read CMOS value from CMOS RAM for one item
;Input : si = item's offset
;Outpu : AL = return value
;[]----------------------------------------------------------------[]
		public	GetItem_Cmos
GetItem_Cmos	proc	near
		mov	ax,cs:[si].RomDefault
		test	word ptr cs:[si].ItemStat,ITEMDISABLE
		jnz	short @F
		mov	al,cs:[si+1].CmosLoc
		call	Get_Cmos
		mov	ah,al
		mov	al,cs:[si].CmosLoc
		call	Get_Cmos
@@:
		call	Get_Real_Value

		ret
GetItem_Cmos	endp

;[]----------------------------------------------------------------[]
;GetItem_Value
;	Read CMOS value from STACK for one item
;Input : si = item's offset
;Outpu : AL = return value
;[]----------------------------------------------------------------[]
		public	GetItem_Value
GetItem_Value	proc	near
		push	si
		push	di
		push	bx
		push	cx
		push	dx
		push	ds
		push	cs
		pop	ds
		push	word ptr USE_ITEMSTAT_BUF[bp]
		mov	byte ptr USE_ITEMSTAT_BUF[bp],1

;--------------------------------------------------------------------
		push	si
		mov	di,offset Get_Item_Bios_D4
ifndef	LOAD_CMOS_FOR_ITEMDISABLE			;R28A
		test	word ptr cs:[si].ItemStat,ITEMDISABLE
		jnz	short Get_Value
endif;	LOAD_CMOS_FOR_ITEMDISABLE			;R28A

		test	word ptr cs:[si].ItemStat,AUTOPROG
		jz	short Not_Auto_Item

ifdef	PM_SUPPORT
;R29		mov	si,offset PM_Option_Check
		test	word ptr cs:[si].ItemStat,PMITEM
		mov	si,offset PM_Option_Check		;R29
		jnz	short @F
endif	;PM_SUPPORT
		mov	si,offset Ct_Auto_Check
	@@:
		call	si

		mov	di,offset Get_Item_Setup_D4
		jnz	short Get_Value

	Not_Auto_Item:

		mov	di,offset Read_Item_Value
;R39 - starts
;R39A		mov	bx,si
		pop	bx					;R39A
		push	bx					;R39A
		call	Read_Item_Value
		cmp	dx, cs:[bx].ItemMax
		jbe	short Get_Value
		mov	di, offset Get_Item_Setup_D4
;R39 - ends

	Get_Value:
		pop	si
;--------------------------------------------------------------------

		mov	bx,si
		call	di
		mov	ax,dx

		pop	word ptr USE_ITEMSTAT_BUF[bp]
		pop	ds
		pop	dx
		pop	cx
		pop	bx
		pop	di
		pop	si

		ret
GetItem_Value	endp

;Input : AX    - value to treate
;	 CS:SI - menuitem table offset
;Output: AX    - value return
		public	Get_Real_Value				;R71
Get_Real_Value	proc	near
		push	cx
		mov	cx,cs:[si].CmosMask
		jcxz	short @F
		and	ax,cx
Next_Mask:
		shr	cx,1
		jc	short @F
		shr	ax,1
		jmp	short Next_Mask
@@:
		pop	cx
		ret
Get_Real_Value	endp

;R15 start
CHS_LBA_Str	db	'CHS ',0
CHS_LBA_Str_Len	EQU	$ - offset CHS_LBA_Str
		db	'LBA ',0
		db	'LRG ',0
		public	Disp_Access_mode
Disp_Access_mode:
		push	ds
		push	cs
		pop	ds
		mov	al,ch
		mov	si,offset CHS_LBA_Str
		mov	cl,CHS_LBA_Str_Len
		mul	cl
		add	si,ax
		call	Display_String
		pop	ds
		ret
;R15 end

;R68 - start
ifdef Password_Hook
		DB	'$PassWord'
;[]----------------------------------------------------------------[]
;GetSupervisorStatus
;	Read CMOS value
;Input : AX = function number
;Outpu : AX = return value   = 0 Disable
;			     = 1 Enable
;			     =81 Invalid
;[]----------------------------------------------------------------[]
		DW	GetSupervisorStatus
		DW	CheckSupervisorPassword

		public	GetSupervisorStatus
GetSupervisorStatus	proc	near
		or	ax,ax				;check function number
		jnz	short Function_Invalid		;No,skip
ifdef	Double_Password
		pusha					;Return used 
		mov	al,11h				;SECURITY_FLAGS 
		call	Get_CMOS			;
		test	al,02				;SECURITY_FLAGS bit
		popa
		jnz	short Password_Enable
		xor	ax,ax
		retf
Password_Enable:
		mov	ax,1
		retf
else;	Double_Password
		xor	ax,ax			;Passwrod disable 
		retf
endif;	Double_Password
Function_Invalid:
		mov	ax,81h		;return invalid function parameter
		retf

GetSupervisorStatus 	endp
;[]----------------------------------------------------------------[]
;CheckSupervisorPassword       
;	Read CMOS value
;Input : AX     = function number
;	 ES:DI	= Password String
;Outpu : AX     = return value   = 0 incorrect
;		 		 = 1 Correct
;			     	 =81 Invalid
;[]----------------------------------------------------------------[]
		public	CheckSupervisorPassword 
CheckSupervisorPassword 	proc	near
		cmp	ax,1			;check function number
		jne	short Function_Invalid	;No,skip
ifdef	Double_Password
		push	ss			;
		push	bp
		mov	ax,es
		mov	ss,ax
		mov	bp,di
		add     bp,-( KEYIN_BUF)
	ifndef	Perfect_Password
 		pusha
		call	Hash_Password
		mov	bx,ax
		mov	al,1dh				;CMOS password addr
		call	Get_CMOS			;get low byte
		mov	ah,al				;keep value 
		mov	al,1ch				;CMOS password addr
		call	Get_CMOS			;get high byte value
		cmp	ax,bx
		popa
		je	short Password_correct
		xor	ax,ax
		jmp	short CS_Password_R
	endif;	Perfect_Password
Password_correct:
		mov	ax,1
CS_Password_R:
		pop	bp
		pop	ss
		retf

else;	Double_Password
		mov	ax,1			;No password retrun correct
		retf

endif;	Double_Password
CheckSupervisorPassword 	endp
;[]========================================================================[]
;Function :	Encode the password using hash algorithm
;
;Input	:	KEYIN_BUF[bp]
;
;Output	:	AX - hashed password
;[]========================================================================[]
Hash_Password	Proc    Near
ifndef	Perfect_Password
		push    si 			; save regs
		push    bx
		push    cx
		push    dx

		xor     si, si			; clear index
		xor     bx, bx			; clear current hash value
		xor	ah, ah
		mov     cx, 8			; set length counter
hash_pw1:
		mov     al, KEYIN_BUF[bp+si]
		or	al, al			; last byte = 0?
		jz	hash_done		; skip to quit if so
		rol	bx, 1			; adjust
		rol	bx, 1
ifdef	KEYBOARD_SECURITY
		F000_Call Ascii_To_Scan
endif;	KEYBOARD_SECURITY
		add	bx, ax			; add in current char
		inc	si			; bump index
		loop	hash_pw1		; do for all significant password chars
hash_done:
		xchg	ax, bx			; return result in ax
		pop     dx			; restore regs
		pop     cx
		pop     bx
		pop     si

endif	;Perfect_Password

		ret

Hash_Password	Endp

endif; define Password_Hook
		
;R68 - end
FCODE		ENDS

;R46 - starts
.386p
EGROUP		GROUP	ECODE
ECODE		SEGMENT USE16 PARA PUBLIC 'ECODE'
		ASSUME	CS:EGROUP, DS:NOTHING, ES:NOTHING
;R76 - start
;[]=============================================================[]
; Inputs:	si = item offset
;		bl = change value start
;		bh = change value end
;		dh = 0 selectable, 1 unselectable
; Output:
		public	Setup_Selectable
Setup_Selectable PROC	NEAR

		push	ds
		push	0F000h
		pop	ds
		pusha
		mov	dl,byte ptr ds:[si].ItemMin
		mov	ah,byte ptr ds:[si].ItemMax
		mov	si,ds:[si].ItemValName

scan_0_1:	lodsb
		test	al,11111110b		;al=0 or 1?
		jnz	short scan_0_1
		cmp	dl,bl
		jb	short scan_next_v
		cmp	dl,ah
		ja	short sel_exceed
		mov	byte ptr ds:[si-1],dh
scan_next_v:	inc	dl
		cmp	dl,bh
		jbe	short scan_0_1
sel_exceed:
		popa
		pop	ds
	 	ret
Setup_Selectable ENDP
;R76 - end

;-------------------
;R70 fPROC_F1_Show_Help	Proc	Far
;R70 
;R70 		cmp	byte ptr CUR_PAGE[bp], PAGE_KERNAL
;R70 		je	short F1_Show_Help_Exit
;R70 
;R70 		cmp	ax, K_F1
;R70		jne	short Show_Help_Exit
;R70 
;R70 		or	byte ptr Post_Temp_Byte[bp],DO_NOT_UPDATE_TIME	;R56
;R70 		mov	byte ptr IN_F1_HELP[bp], 1	;indicate in F1
;R70 		call	Display_Help_Str
;R70 		mov	byte ptr IN_F1_HELP[bp], 0	;indicate not in F1
;R70 		F000_Call Refresh_Menu
;R70 		and	byte ptr Post_Temp_Byte[bp],not DO_NOT_UPDATE_TIME	;R56
;R70 
;R70 F1_Show_Help_Exit:
;R70 
;R70 		retf
;R70 
;R70 fPROC_F1_Show_Help	Endp

;-------------------

;R70 fPROC_Show_Help_On_The_Fly	Proc	Far
;R70 
;R70 		cmp	byte ptr CUR_PAGE[bp], PAGE_KERNAL
;R70 		jne	short Show_Help_Exit
;R70 
;R70 		mov	byte ptr IN_F1_HELP[bp], 0	;indicate not in F1
;R70 							; e.g. Show_Calender will refer to this flag
;R70 		mov	word ptr CURSOR_X[bp], (22 shl 8) + 1
;R70 
;R70 		mov	al, ' '
;R70 		mov	cx, 78
;R70 	@@:
;R70 		F000_Call Display_Char
;R70 		loop	short @B
;R70 		F000_Call Vhilite
;R70 
;R70 		mov	si, [bx].HelpOffset
;R70 		F000_Call Display_String
;R70 Show_Help_Exit:
;R70 
;R70 		ret
;R70 
;R70 fPROC_Show_Help_On_The_Fly	Endp

;R70 ;[]========================================================================[]
;R70 ;[]========================================================================[]
;R70 Display_Help_Str	proc	near
;R70 
;R70 		mov	si, [bx].HelpOffset	;get help string offset
;R70 		cmp	byte ptr ds:[si], 0	;null string?
;R70 		je	No_Help			;yes, exit
;R70 
;R70 ;display help border
;R70 
;R70 		push	si			;save offset
;R70 		F000_Call Vnormal			;normal attribute
;R70 		mov	si, offset Help_Border	;clear help area first
;R70 		call	Display_CS_String
;R70 		pop	si			;restore si
;R70 
;R70 ;set margin
;R70 		F000_Call Vnormal			;normal attribute
;R70 		mov	byte ptr LMARGIN_X[bp], 22
;R70 		mov	CURSOR_X[bp], 0516h	;R62
;R70 ;R62		mov	CURSOR_X[bp], 0916h
;R70 
;R70 ;display help strings
;R70 
;R70 		push	si			;save offset
;R70 		call	F000_Display_String	;show help string
;R70 		pop	si			;restore si
;R70 
;R70 ;display standard help string
;R70 ;-----------------------------------------------------------------------
;R70 		cmp	si, offset Std_Help_Str	;does this item use
;R70 						; standard help?
;R70 ;R54		jne	short No_Quit		;no, exit
;R70 		jne	No_Quit			;R54 no, exit
;R70 
;R70 		mov	si, offset d4_msg
;R70 		call	Display_CS_String
;R70 
;R70 		mov	dx, [bx].ItemMin		;started form min.
;R70 
;R70 Show_Available_Options:
;R70 
;R70 		push	dx			;save dx
;R70 		F000_Call Check_VarNull
;R70 		jc	short Next_Avail_Option	;not available
;R70 
;R70 		F000_call Vnormal		;normal attribute
;R70 		F000_call Get_VarString_Offset
;R70 		call	F000_Display_String	;available, display it
;R70 
;R70 		F000_Call VHilite		;hilite attribute
;R70 
;R70 		F000_call Read_Item_Value	;get shift value (cl)
;R70 		pop	ax			;pop current option value
;R70 		push	ax			;push current option value
;R70 		mov	si, offset bios_d4_msg	;bios defaults string
;R70 		F000_call Get_Item_BIOS_D4	;get BIOS default in DX
;R70 		cmp	ax, dx			;current option = BIOS d4?
;R70 		jne	short @F		;no, 
;R70 		push	ax
;R70 		call	Display_CS_String	;yes, show message
;R70 		pop	ax
;R70 	@@:
;R70 		mov	si, offset setup_d4_msg	;setup defaults string
;R70 		F000_Call Get_Item_Setup_D4	;get setup d4 in DX
;R70 		cmp	ax, dx			;current option = setup d4?
;R70 		jne	short Option_Not_D4	;no, 
;R70 		call	Display_CS_String		;yes, show message
;R70 Option_Not_D4:
;R70 		F000_Call VNewLine		;next line
;R70 
;R70 Next_Avail_Option:
;R70 
;R70 		pop	dx			;restore dx
;R70 
;R70 		cmp	dx, [bx].ItemMax		;max. reached?
;R70 		jae	short Std_Help_Exit	;yes, leave
;R70 
;R70 		inc	dx			;next option
;R70 ;R54		jmp	short Show_Available_Options
;R70 		jmp	Show_Available_Options	;R54
;R70 Std_Help_Exit:
;R70 ;-----------------------------------------------------------------------
;R70 No_Quit:
;R70 		F000_Call Key				;wait for key
;R70 		cmp	ax, K_F1				;is if 'F1'
;R70 		je	short @F			;yes
;R70 		cmp	ax, K_ESC1			;is if 'ESC'
;R70 		jne	short No_Quit			;no
;R70 	@@:
;R70 		mov	si, offset Clear_Help		;clear the help area
;R70 		call	Display_CS_String			;
;R70 		mov	word ptr LAST_KEY[bp], 0		;destroy key
;R70 No_Help:
;R70 		ret					;return to caller
;R70 
;R70 Help_Border	Label	Near
;R70 		db	V_WARN
;R70 		BORDER1	<, 21, 4, 60, 22, 1+Empty_Border>	;R62
;R70 		POS	<, 26, 21>				;R62
;R70 ;R62		BORDER1	<, 21, 8, 60, 22, 1+Empty_Border>
;R70 ;R62		POS	<, 22, 21>
;R70 		db	V_HILITE, 'Press F1 or ESC to exit help'
;R70 		db	0
;R70 
;R70 Clear_Help	Label	Near
;R70 		db	V_NORMAL
;R70 		CLEAR	<, 21, 4, 60, 22>			;R62
;R70 ;R62		CLEAR	<, 21, 8, 60, 22>
;R70 		db	0
;R70 
;R70 d4_msg		ADDX	<, 23>
;R70 		db	'Default Type', NEWLINE
;R70 		ADDX	<, 22>
;R70 		db	'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ'
;R70 		db	NEWLINE, 0
;R70 setup_d4_msg	POS	<, 54-2, >
;R70 		db	'<Setup>', 0
;R70 bios_d4_msg	POS	<, 45, >
;R70 		db	'<BIOS>', 0
;R70 
;R70 Display_Help_Str	endp

;[]========================================================================[]
;Function :	Read CMOS data into stack
;		if check sum fail, load defaults
;
;Input	:	BP
;
;Output	:	None
;
;note	:	call from POST for BIOS version, start of setup for DOS version
;[]========================================================================[]
		Public	fPROC_Read_Cmos_To_Stack		;R51
fPROC_Read_Cmos_To_Stack	Proc	Far

		mov	cx, 80h			;total 128 bytes to read
		mov	si, CMOS00

Next_Cmos:
		mov	ax, si
		call	F000_Get_Cmos

		mov	[bp+si], al
		inc	si
		loop	short Next_Cmos

;R86		F000_Call Check_Valid_HDD_Type
		call	fPROC_Check_Valid_HDD_Type	;R86
		call	Read_RtcTime

		mov	di, 1	  		;don't write CMOS checksum bytes
		call	Check_CMOS_Sum

		F000_Call Tran_HDD_User_Type
 		retf

fPROC_Read_Cmos_To_Stack	endp

;[]========================================================================[]
;Function :	Read RTC and transfer to hex number into stack area
;
;Input	:	NONE
;
;Output	:	NONE
;[]========================================================================[]
Read_RtcTime	proc	near
		push	si
		mov	si, CMOS00
		mov	cx, 10			;total 10 bytes to read
Rtc1:
		mov	ax, si
		call	F000_Get_Cmos		;read RTC time
		F000_Call Bcd_To_Hex	;convert to hex number
		cmp	si, CMOS00		;Is second field
		jne	short Not_Sec
		cmp	bx, offset SECOND_ITEM	;processing second filed
		je	short No_Updation
Not_Sec:
		mov	[bp+si], al		;store in stack
No_Updation:
		inc	si
		loop	short Rtc1

		mov	si, CMOS32
		mov	ax, si
		call	F000_Get_Cmos		;read RTC time
		F000_Call Bcd_To_Hex	;convert to hex number
		mov	[bp+si], al		;store in stack
		pop	si
		ret
Read_RtcTime	endp

;[]========================================================================[]
;Function :	Save standard CMOS and extended CMOS
;
;Input :	None
;
;Output:	None
;[]========================================================================[]
fPROC_Save_All_Cmos	Proc	Far

ifndef	DOSVERSION
		mov	ah, byte ptr CMOS32[bp]	;convert century to BCD
		F000_Call Hex_To_Bcd
		mov	byte ptr CMOS32[bp], ah	;convert century to BCD

		cmp	byte ptr EXT_FIXED_0[bp], 47
		jne	short @F
		mov	bx, offset HDDC_ITEM
;R86		F000_Call Get_HDD_CMOS_Info
		call	fPROC_Get_HDD_CMOS_Info			;R86
		cmp	word ptr [bp+di+0], 0
		jne	short @F
 		and	byte ptr FIXED_TYPE[bp], 0fh
@@:
		cmp	byte ptr EXT_FIXED_1[bp], 47
		jne	short @F
		mov	bx, offset HDDD_ITEM
;R86		F000_Call Get_HDD_CMOS_Info
		call	fPROC_Get_HDD_CMOS_Info			;R86
		cmp	word ptr [bp+di+0], 0
		jne	short @F
 		and	byte ptr FIXED_TYPE[bp], 0f0h
@@:
		cmp	byte ptr EXT_FIXED_0[bp], 49
		jne	short @F
		mov	byte ptr EXT_FIXED_0[bp], 46
@@:
		cmp	byte ptr EXT_FIXED_1[bp], 48
		jne	short @F
		mov	byte ptr EXT_FIXED_1[bp], 46
@@:
ifdef	Support_4_IDE
		cmp	byte ptr CMOS_HDDE[bp], 51
		jne	short @F
		mov	byte ptr CMOS_HDDE[bp], 46
@@:
		cmp	byte ptr CMOS_HDDF[bp], 50
		jne	short @F
		mov	byte ptr CMOS_HDDF[bp], 46
@@:
endif	;Support_4_IDE

		xor	di, di
		call	Check_CMOS_Sum

		mov	di, offset Cmos_Check_Sum

		mov	ch, CMOS10	;start & end locations to save
		mov	cl, CMOS3F
	@@:
		call	Save_CMOS_Bytes
		mov	ch, [di+2]
		mov	cl, ch
		inc	cl
		call	Save_CMOS_Bytes	;save checksum word

		add	di, 3
		mov	ch, [di]		;next start & end locations to save
		mov	cl, [di+1]
		or	ch, ch
		jnz	short @B

	;-------------------------------------------------------------------
	;Clear RTC_STATUS, EQUIP_STATUS for CMOS 0Eh when saving CMOS from 
	;stack. This is to prevent DOS from treating all FDD drives as 360K
	;type !
	;-------------------------------------------------------------------

		mov	ax, (CMOS_STATUS shl 8) + CMOS_STATUS
		call	F000_Get_CMOS
		and	al, not (RTC_STATUS + EQUIP_STATUS)
		xchg	ah, al
		call	F000_Set_CMOS

endif	;DOSVERSION

		retf

fPROC_Save_All_Cmos	endp

Save_CMOS_Bytes	Proc	Near
		mov	si, cx
		and	si, 0ffh
Save_Byte:
		mov	al, cl
		mov	ah, [bp+si]
		call	F000_Set_Cmos
		dec	si
		dec	cl
		cmp	cl, ch
		jae	short Save_Byte
		retn
Save_CMOS_Bytes	Endp

;[]========================================================================[]
;Function :	Save standard CMOS and extended CMOS datas
;
;Input :	DI : 0 - write CMOS checksum bytes
;		     1 - write CMOS checksum bytes and load default if checksum fail
;
;Output:	None
;[]========================================================================[]
		Public	Check_CMOS_Sum		;R46A
Check_CMOS_Sum	proc	near
assume	ds:dgroup
		push	SEG DGROUP
		pop	ds

		mov	al, CUR_PAGE[bp]		;save current page no.
		push	ax


;get start, end & checksum location
		mov	si, offset Cmos_Check_Sum
Next_Sum:
		lodsb
		or	al, al
		jnz	short @F
		jmp	Finish_Sum
@@:

		mov	cl, al			;start of checksum
		lodsb
		mov	ch, al			;end of checksum
		lodsb
		mov	dl, al			;checksum low byte
		xor	dh, dh

;start calculation of checksum

		push	si

		xor	bx, bx
		xor	ah, ah
		mov	si, cx
		and	si, 0ffh			;low byte only
Next_Cmos_Byte:
		mov	al, [bp+si]
		add	bx, ax
		inc	si
		inc	cl
		cmp	cl, ch
		jbe	short Next_Cmos_Byte
		mov	si, dx			;checksum byte location
						; was stored in dx
		or	di, di			;does caller request
						; to write checksum byte ?
;R92		jz	short Save_Only		;yes, do it!
		jz	Save_Only		;yes, do it!	;R92

		cmp	[bp+si], bh		;checksum valid?
		jne	short Default_It	;no, load default
		cmp	[bp+si+1], bl		;checksum byte valid?
;R92		je	short Check_Next_Sum	;yes, check next checksum!
		je	Check_Next_Sum		;yes, check next checksum! ;R92
Default_It:
;R82 - start		
		cmp	byte ptr CMOS10[bp], 0DDh
		jne	short Not_Load_Default_only
		cmp	byte ptr CMOS11[bp], 0CCh
		jne	short Not_Load_Default_only
		cmp	byte ptr CMOS12[bp], 0BBh
Not_Load_Default_only:
		pushf
;R82 - end
		pusha
		mov	di, SetupDef		;load setup defaults
		mov	cl, 2			;started from stdcmos
		F000_Call Load_All_Default	;load all defaults

		F000_Call Set_HDD_To_Defaults

;---------------------------------------------------------
		popa
		popf					;R82
		je	short No_Report_CMOS_Error1	;R82	;R82A
		or	byte ptr CMOS0E[bp], CKSM_STATUS+EQUIP_STATUS
No_Report_CMOS_Error1:					;R82	;R82A

		and	byte ptr CMOS14[bp], not 0C2h	;default 1 FDD, no Coprocessor
		and	byte ptr CMOS11[bp], 0FDh	;default to password invalid
		and	byte ptr CMOS3B[bp], 0Fh		;load default color

ifdef	Always_Password_Need
ifNdef	Clear_CMOS_PASSWORD_Option			;R90
		mov	al, 11h
		call	F000_Get_Cmos
		xchg	ah, al
		or	ah, 00000010b
		mov	al, 11h
		call	F000_Set_Cmos
		or	byte ptr CMOS11[bp], 2
;R90 -start
else	;Clear_CMOS_PASSWORD_Option
 		mov	al,2Eh + 80h
		call 	F000_Get_Cmos
		cmp	al,055h			; Clear CMOS by jumper ?
		jne	short @f		; NO

		mov	al, 11h NMI_OFF
		call	F000_Get_Cmos
		test	al,00000010b		; Password exist previous ??	
		jz	short @f

		or	byte ptr CMOS11[bp],02h
	@@:
endif	;Clear_CMOS_PASSWORD_Option
;R90 -end
endif	;Always_Password_Need

ifdef	Double_Password
		push	di
		F000_call Ct_User_Password_Location	;get second password CMOS
		not	dl				;disable password
		and	[bp+si], dl			;clear password flag
		pop	di
endif;	Double_Password

ifndef	DOSVERSION
		mov	si, offset DGROUP:COLOR_SETTING
		mov	al, byte ptr ds:[si]
		shl	al, 4
		or	byte ptr CMOS3B[bp], al
endif	;DOSVERSION

		test	byte ptr CMOS10[bp], 0FFh
		jz	short @F
		or	byte ptr CMOS14[bp], 01h
	@@:

		pop	si
		jmp	short finish_Sum
Save_Only:
		mov	[bp+si], bh		;checksum low byte
		mov	[bp+si+1], bl		;checksum high byte

Check_Next_Sum:
		pop	si
		jmp	Next_Sum
Finish_Sum:
		pop	ax
		mov	CUR_PAGE[bp], al		;restore current page no.

		ret

Check_CMOS_Sum	endp

;[]========================================================================[]
;Function :	Read password and verify match or not
;
;Input	:	AL - 01h -> setup entering check
;		AL - 02h -> setup and boot check
;
;Output	:	ZF - pass
;		otherwise - infinite loop
;[]========================================================================[]
		Public	fPROC_Verify_Password
fPROC_Verify_Password	Proc	far
		call	Verify_Password
		retf
fPROC_Verify_Password	Endp
Verify_Password	Proc	near

	ifdef	HELP_IDIOT
		pusha
		F000_Call Ct_Ck_Password
		popa
		jnc	short @F
		ret
	@@:
	endif	;HELP_IDIOT

	ifdef	Never_Disable_Password
		pusha
		mov	si, offset DGROUP:Security_Item
		call	F000_GetItem_Value
		mov	ah, al
		and	byte ptr CMOS11[bp], not 01h
		and	ah, 01h
		or	byte ptr CMOS11[bp], ah
		cmp	al, 02h
		popa
		jb	short @F
		ret
	@@:
	endif	;Never_Disable_Password

ifdef	Double_Password
		push	word ptr ATTRIBUTE[bp]
		push	word ptr TEMP_YEAR[bp]
		push	ds

		mov	si, DGROUP
		mov	ds, si
		assume	DS: DGROUP

		cmp	al, 02h				;booting?
		jne	short @F			;no, continue!
		test	byte ptr CMOS11[bp], 01h		;booting need pass?
		jz	short Verify_Pass_Exit		;no, exit
	@@:
		mov	TEMP_YEAR[bp], al

;R50 start
ifdef No_Auto_Switch_to_Text
		pusha
		cmp	al,2
		mov	ax,3
		je	short @F
		mov	al,83h
@@:
		int	10h
		popa
endif ;No_Auto_Switch_to_Text
;R50 end
;R67ifdef	EPA_LOGO_Use_Graphics				;R63A
ifdef	Graphics_Post						;R67
		extrn	Switch_LOGO_To_Text:near		;R63A
		call	Switch_LOGO_To_Text			;R63A
endif;	Graphics_Post						;R67
;R67endif;	EPA_LOGO_Use_Graphics				;R63A
	ifdef	Add_PASSWORD_LOOPS
		mov	byte ptr PASSWORD_LOOPS[bp], PASSWORD_LOOPS_NUM
		inc	byte ptr PASSWORD_LOOPS[bp]
	endif;	Add_PASSWORD_LOOPS

		call	Backup_pass_screen
Chk_Super_Pass:

	ifdef	Add_PASSWORD_LOOPS
		dec	byte ptr PASSWORD_LOOPS[bp]
		jnz	short @F

		mov	ax, 3
		int	10h

		mov	si, offset ErrorHold_Msg

		call	Display_CS_String
		cli

		jmp	$
	    @@:
	endif;	Add_PASSWORD_LOOPS

		mov	byte ptr SIX_DIGIT[bp], 0
		mov	bx, offset SuperPassword_Item
		test	ds:[bx].ItemStat, ITEMDISABLE
		jnz	short Chk_User_Pass

		test	byte ptr CMOS11[bp], 02h		;Super Password needed?
		jz	short Chk_User_Pass		;no need!

		call	Check_Pass_1
	ifndef	No_Default_Password
		je	short Password_Valid
	endif;	No_Default_Password

	Comp_Super:

		cmp	ax, CMOS1C[bp]			;super pass equal?
		je	short Password_Valid		;yes

		cmp	byte ptr TEMP_YEAR[bp], 01h
		jne	short @F
		mov	byte ptr SIX_DIGIT[bp], 0AAh
	@@:

	;it is a booting password check!

		call	Chk_User_Needed		;user pass needed?

		jnc	short Comp_User
		Call	Error_PassWord
ifdef	FDDboot_when_Password_Fail			;R58
		jnc	short Comp_User			;R58
endif;	FDDboot_when_Password_Fail			;R58
		jmp	short Chk_Super_Pass

	Chk_User_Pass:

		call	Chk_User_Needed			;user pass needed?
		jc	short Password_Valid		;no need!

		call	Check_Pass_1
	ifndef	No_Default_Password
		je	short Password_Valid
	endif;	No_Default_Password

	Comp_User:

		F000_call Ct_User_Password_Location
		cmp	ax, [bp+di]			;user pass equal?

		je	short Password_Valid
		Call	Error_PassWord
ifdef	FDDboot_when_Password_Fail			;R58
		jnc	short Password_Valid		;R58
endif;	FDDboot_when_Password_Fail			;R58
		jmp	short Chk_Super_Pass

Password_Valid:
		call	Restore_pass_screen
Verify_Pass_Exit:

		pop	ds
		pop	word ptr TEMP_YEAR[bp]		;use this word
		pop	word ptr ATTRIBUTE[bp]

		ret

else	;Double_Password

		push	ds
ifdef	FDDboot_when_Password_Fail			;R58
		push	word ptr TEMP_YEAR[bp]		;R58
		mov	TEMP_YEAR[bp], al		;R58
endif;	FDDboot_when_Password_Fail			;R58

		mov	si, DGROUP
		mov	ds, si
		assume	DS: DGROUP

		push	bx			;save bx
		mov	bl, ATTRIBUTE[bp]
		push	bx			;save attribute

		mov	bx, offset SECURITY_ITEM
		test	ds:[bx].ItemStat, ITEMDISABLE
		jnz	short No_Security

		test	byte ptr CMOS11[bp], 02h
		jz	short No_Security

		test	byte ptr CMOS11[bp], 01h	;setup & boot both needed?
		jnz	short Check_Pass	;yes

		cmp	al, 2			;boot password?
		je	short No_Security	;yes, exit

ifdef	Add_PASSWORD_LOOPS
		mov	byte ptr PASSWORD_LOOPS[bp], PASSWORD_LOOPS_NUM
		inc	byte ptr PASSWORD_LOOPS[bp]
endif;	Add_PASSWORD_LOOPS

Check_Pass:
;R50 start
ifdef No_Auto_Switch_to_Text
		pusha
		cmp	al,2
		mov	ax,3
		je	short @F
		mov	al,83h
@@:
		int	10h
		popa
endif ;No_Auto_Switch_to_Text
;R50 end
;R67ifdef	EPA_LOGO_Use_Graphics				;R63A
ifdef	Graphics_Post						;R67
		extrn	Switch_LOGO_To_Text:near		;R63A
		call	Switch_LOGO_To_Text			;R63A
endif;	Graphics_Post						;R67
;R67endif;	EPA_LOGO_Use_Graphics				;R63A
		call	Backup_pass_screen
Check_Pass_1:

	ifdef	Add_PASSWORD_LOOPS
		dec	byte ptr PASSWORD_LOOPS[bp]
		jnz	short @F

		mov	ax, 3
		int	10h

		mov	si, offset ErrorHold_Msg

		Call	Display_CS_String
		cli

		jmp	$
	    @@:
	endif;	Add_PASSWORD_LOOPS

		mov	byte ptr CUR_PAGE[bp], 0	; don't update time
		mov	word ptr LAST_KEY[bp], 0	; dummy word
		call	Get_Password
  ifdef	Perfect_Password
		call	Chk_Perfect_Password
  else	;Perfect_Password
	ifndef	No_Default_Password
;R48		cmp	ax, ds:MASTER_PASS_HASH	; default password
		call	Compare_Password	;R48
		je	short No_Security_1
	endif;	No_Default_Password
		cmp	ax, CMOS1C[bp]
  endif	;Perfect_Password

		je	short No_Security_1
		Call	Error_PassWord
ifdef	FDDboot_when_Password_Fail			;R58
		jnc	short No_Security_1		;R58
endif;	FDDboot_when_Password_Fail			;R58
		jmp	short Check_Pass_1

No_Security_1:
		call	Restore_pass_screen
No_Security:

		pop	bx			;restore attribute
		mov	ATTRIBUTE[bp], bl
		pop	bx			;restore bx

ifdef	FDDboot_when_Password_Fail			;R58
		pop	word ptr TEMP_YEAR[bp]		;R58
endif;	FDDboot_when_Password_Fail			;R58
		pop	ds

		ret

endif	;Double_Password

Verify_Password	endp

ifdef	Double_Password
;---------------------------------------------------------------------------
;output	:	ZF : input password = MASTER_PASS_HASH
;		AX : Hashed password
;---------------------------------------------------------------------------
Check_Pass_1	Proc	Near
		mov	byte ptr CUR_PAGE[bp], 0	; don't update time
		mov	word ptr LAST_KEY[bp], 0	; dummy word
		call	Get_Password
	ifndef	No_Default_Password
;R48		cmp	ax, ds:MASTER_PASS_HASH	; default password
		call	Compare_Password	;R48
	endif;	No_Default_Password
		retn
Check_Pass_1	Endp

;---------------------------------------------------------------------------
;output	:	CY =	user password not needed
;		NC =	user password needed
;---------------------------------------------------------------------------
fPROC_Chk_User_Needed	Proc	far
		call	Chk_User_Needed
		retf
fPROC_Chk_User_Needed	Endp
Chk_User_Needed	Proc	near

		mov	bx, offset UserPassword_Item
		test	ds:[bx].ItemStat, ITEMDISABLE
		jnz	short @F

		F000_Call Ct_User_Password_Location
		test	[bp+si], dl			;user password needed?
		jz	short @F			;no need!

		clc			;user password needed
		ret
	@@:
		stc			;user password not needed
		ret

Chk_User_Needed	Endp
endif	;Double_Password

;R61A - starts
ifdef	DOSVERSION
MASTER_PASS_HASH	Label	Near
			dw	01EAAh
endif;	DOSVERSION
;R61A - ends

;R48 start
Compare_Password:
;---------------------------------------------------------------------------
;output	:	ZF : input password = MASTER_PASS_HASH
;---------------------------------------------------------------------------
		mov	dl,1				;assume not match
		xor	si,si				;index password char 0
CompPass_Loop:
		movzx	cx,byte ptr KEYIN_BUF[bp+si]	;compare same with keyin?
		cmp	byte ptr ds:MASTER_PASS_HASH[si],0	;Is last char?
		jne	short @F			;Yes,skip
		or	si,si
		jz	short CompPass_Over
		or	cl,cl
		jnz	short CompPass_Over
		jmp	short CompPass_Match
@@:
		shl	cx,3				;hash password
		shl	ch,3				;    :
		ror	cl,3				;    :
		ror	cx,3				;    :
		rol	cl,3				;    :
		or	cl,ch				;-------
		cmp	cl,ds:MASTER_PASS_HASH[si]	;compare same with keyin?
		jne	short CompPass_Over		;No,skip
		inc	si				;next char
		cmp	si,8				;over 8 char?
		jb	short CompPass_Loop		;No,continue
CompPass_Match:
		xor	dl,dl				;Set match flag
CompPass_Over:
		or	dl,dl
		ret
;R48 end

Error_PassWord	Proc	Near
		mov	si, offset ErrorPass_Msg
ifdef	FDDboot_when_Password_Fail			;R58
		cmp	byte ptr TEMP_YEAR[bp],1	;R58
		je	short notBootcall		;R58
		mov	si, offset ErrorPass_Msg1	;R58
notBootcall:						;R58
endif;	FDDboot_when_Password_Fail			;R58
		Call	Display_CS_String

;R51 - start
if	Desktop_Power_Management	EQ	2		
	ifndef	NO_STR_PASSWORD_CHECK
		cmp	byte ptr CALLTYPE[bp],SMM_CALL	
		jne	short S_0

		call	far ptr Get_SMM_Key
		call	far ptr Clear_Screen
		ret
	S_0:
	endif	;NO_STR_PASSWORD_CHECK
endif	;Desktop_Power_Management	EQ	2
;R51 - end
		xor	ax, ax			;wait for key
		int	16h
;R58 start
ifdef	FDDboot_when_Password_Fail			;R58
		cmp	byte ptr TEMP_YEAR[bp],1	;call from setup
		stc					;set check again flag
		je	short not_Y			;Yes! dont check
		or	al,20h
		cmp	al,79h
		stc					;set check again flag
		jne	short not_Y
		push	ds
		push	G_RAM
		pop	ds
		assume	ds:G_RAM
		mov	ds:[NUMHDSKS],0			;Protect HDD be access
		pop	ds
		clc					;Set boot flag
not_Y:
endif;	FDDboot_when_Password_Fail			;R58
;R58 end
		call	Restore_pass_screen
		ret
Error_PassWord	Endp

temp_mem	equ	8000h
Backup_pass_screen	Proc	Near

;R51 - start
if	Desktop_Power_Management	EQ	2		
	ifndef	NO_STR_PASSWORD_CHECK
		cmp	byte ptr CALLTYPE[bp],SMM_CALL	
		jne	short Normal_Backup_Pass	
		Call	far ptr Clear_Screen		
		ret					
	endif	;NO_STR_PASSWORD_CHECK
Normal_Backup_Pass:					
endif	;Desktop_Power_Management	EQ	2		
;R51 - end

		push	es
		pusha
		mov	ax, temp_mem
		mov	es, ax
		xor	di, di
		cld

		mov	dh, ErrorPass_Start_Y
	LoopY0:

ifndef	FDDboot_when_Password_Fail			;R58
		mov	dl, ErrorPass_Start_X
else;	FDDboot_when_Password_Fail			;R58
		mov	dl, _ErrorPass_Start_X		;R58
endif;	FDDboot_when_Password_Fail			;R58
	LoopX0:
		mov	ah, 2
		xor	bh, bh
		int	10h				;set cursor position
		mov	ah, 8
		int	10h				;get char and attribute
		stosw
		inc	dl
ifndef	FDDboot_when_Password_Fail			;R58
		cmp	dl, PassMsg_End_X
else;	FDDboot_when_Password_Fail			;R58
		cmp	dl, _ErrorPass_End_X		;R58
endif;	FDDboot_when_Password_Fail			;R58
		jbe	short LoopX0
		inc	dh
ifndef	FDDboot_when_Password_Fail			;R58
		cmp	dh, PassMsg_End_Y
else;	FDDboot_when_Password_Fail			;R58
		cmp	dh, _ErrorPass_End_Y		;R58
endif;	FDDboot_when_Password_Fail			;R58
		jbe	short LoopY0
		popa
		pop	es
		ret

Backup_pass_screen	Endp

Restore_pass_screen	Proc	Near

;R51 - start
if	Desktop_Power_Management	EQ	2		
	ifndef	NO_STR_PASSWORD_CHECK
		cmp	byte ptr CALLTYPE[bp],SMM_CALL	
		jne	short Normal_Restore_Pass	
		ret
	endif	;NO_STR_PASSWORD_CHECK
Normal_Restore_Pass:
endif	;Desktop_Power_Management	EQ	2		
;R51 - end

		push	ds
		pusha
		pushf
		mov	ax, temp_mem
		mov	ds, ax
		xor	si, si

		mov	dh, ErrorPass_Start_Y
	LoopY1:

ifndef	FDDboot_when_Password_Fail			;R58
		mov	dl, ErrorPass_Start_X
else;	FDDboot_when_Password_Fail			;R58
		mov	dl, _ErrorPass_Start_X		;R58
endif;	FDDboot_when_Password_Fail			;R58
	LoopX1:
		mov	ah, 2
		xor	bh, bh
		int	10h				;set cursor position
		lodsw
		mov	bl, ah
		mov	ah, 9
		mov	cx, 1
		int	10h				;get char and attribute
		inc	dl
ifndef	FDDboot_when_Password_Fail			;R58
		cmp	dl, PassMsg_End_X
else;	FDDboot_when_Password_Fail			;R58
		cmp	dl, _ErrorPass_End_X		;R58
endif;	FDDboot_when_Password_Fail			;R58
		jbe	short LoopX1
		inc	dh
ifndef	FDDboot_when_Password_Fail			;R58
		cmp	dh, PassMsg_End_Y
else;	FDDboot_when_Password_Fail			;R58
		cmp	dh, _ErrorPass_End_Y		;R58
endif;	FDDboot_when_Password_Fail			;R58
		jbe	short LoopY1
		popf
		popa
		pop	ds
		ret

Restore_pass_screen	Endp

ifdef	Double_Password
fPROC_Hidden_Except_UserPass	Proc	Far

		mov	bx, PAGE_START[bp]
		mov	dx, PAGE_END[bp]
		sub	dx, ITEM_SIZE*2
	@@:
		F000_Call Get_ItemStat_AX
		or	ax, SHOWONLY
		F000_Call Set_ItemStat_AX
		add	bx, ITEM_SIZE
		cmp	bx, dx
		jb	short @B

		mov	bx, offset UserPassword_Item
		F000_Call Get_ItemStat_AX
		and	ax, not (ITEMDISABLE+SHOWONLY)
		F000_Call Set_ItemStat_AX

		mov	si, offset jjkkll
		call	Display_CS_String

		ret

fPROC_Hidden_Except_UserPass	Endp

jjkkll:
		CLEAR	<, 1, 4, 79, 20>
		db	0

endif	;Double_Password

;[]========================================================================[]
;Function :	Get password for system or setup access
;
;Input	:	None
;
;Output	:	AX : hashed password
;[]========================================================================[]
;R64;R60 - start
;R64ifdef	Password_ON_NOW_SUPPORT
;R64
;R64		public	Get_KB_Password
;R64Get_KB_Password	Proc	Near
;R64		mov	si, offset EnterPass_Msg
;R64		jmp	short Input_Pass2
;R64Get_KB_Password	Endp
;R64
;R64		public	Confirm_KB_Password
;R64Confirm_KB_Password	Proc	Near
;R64		mov	si, offset ConfirmPass_Msg
;R64
;R64Input_Pass2:
;R64		Call	Display_CS_String
;R64		mov	dl, ECHO_ASTERISK+\
;R64			   EDIT_LOWER+EDIT_UPPER+\
;R64			   EDIT_DEC			;keyin type
;R64		mov	cl, 5
;R64		jmp	short Input_Pass1
;R64Confirm_KB_Password	Endp
;R64endif;	Password_ON_NOW_SUPPORT
;R64;R60 - end
Get_Password	Proc	Near
		mov	si, offset EnterPass_Msg
		jmp	short Input_Pass

;R83 Confirm_Password:
Confirm_Password	Label	Near		;R83

		mov	si, offset ConfirmPass_Msg
Input_Pass:

		Call	Display_CS_String
	mov	dl, ECHO_ASTERISK+EDIT_PUNCT+EDIT_LOWER+EDIT_UPPER+EDIT_DEC	;R65 Keyin type
		mov	cl, 8				;maximum 8 characters
SIO_Input_Pass	label	near			;R64
;R89 - start
		public	Get_Data_From_KB
Get_Data_From_KB	label	near
;R89 - end
Input_Pass1:					;R60
		F000_Call Edit_String		;get string into buffer

Re_Get_Key:
		cmp	word ptr LAST_KEY[bp], K_CR1
		je	short Check_Key_Buffer
		F000_Call Get_Key
		jmp	short Re_get_Key
Check_Key_Buffer:
		cmp     byte ptr KEYIN_BUF[bp], 0
		je	short Input_Pass_Bad		;buffer is empty

Input_Pass_Good:
ifndef	Perfect_Password
ifndef Password_Hook					;R68
		call	Hash_Password
else; Password_Hook					;R68
		F000_call	Hash_Password		;R68
endif; Password_Hook					;R68
endif	;Perfect_Password
		clc
		ret

Input_Pass_Bad:
		stc
		ret

Get_Password	Endp

	PUBLIC	EnterPass_Msg			;R66
SIO_EnterPass_Msg	label	near
EnterPass_Msg	db	V_REVERSE

PassMsg_Start_X	equ	24
PassMsg_Start_Y	equ	13
PassMsg_End_X	equ	54
PassMsg_End_Y	equ	15
		BORDER1 <, PassMsg_Start_X, PassMsg_Start_Y, PassMsg_End_X, PassMsg_End_Y, 0+Empty_Border>
		POS	<, 26, 14>
		db	'Enter Password:   '
		db	0

	PUBLIC	ConfirmPass_Msg			;R66
SIO_Confirmpass_Msg	label	near
ConfirmPass_Msg	db	V_REVERSE

		POS	<, 26, 14>
		db	'Confirm Password: '
		db	0

ErrorPass_Msg	db	V_REVERSE
ErrorPass_Start_X	equ	24
ErrorPass_Start_Y	equ	12
ErrorPass_End_X		equ	54
ErrorPass_End_Y		equ	15
		BORDER1 <, ErrorPass_Start_X, ErrorPass_Start_Y, ErrorPass_End_X, ErrorPass_End_Y, 0+Empty_Border>
		POS	<, 31, 13>
		db	'Invalid Password !'
		POS	<, 26, 14>
		db	'Press Any Key to Continue. '
		db	0

;R58 start
ifdef	FDDboot_when_Password_Fail			;R58A
ErrorPass_Msg1	db	V_REVERSE
_ErrorPass_Start_X	equ	17
_ErrorPass_Start_Y	equ	12
_ErrorPass_End_X	equ	61
_ErrorPass_End_Y	equ	17
		BORDER1 <, _ErrorPass_Start_X, _ErrorPass_Start_Y, _ErrorPass_End_X, _ErrorPass_End_Y, 0+Empty_Border>
		POS	<, 19, 13>
		db	'Password Invalid, HDD cannot be accessed!'
		POS	<, 24, 14>
		db	'Insert Boot diskette in Drive A'
		POS	<, 26, 15>
		db	'Press N to Re-enter Password'
		POS	<, 33, 16>
		db	'Press Y to Boot'
		db	0
endif;	FDDboot_when_Password_Fail			;R58A
;R58 end

ifdef	Add_PASSWORD_LOOPS				;R58A
ErrorHold_Msg	db	V_REVERSE
ErrorHold_Start_X	equ	24
ErrorHold_Start_Y	equ	13
ErrorHold_End_X		equ	54
ErrorHold_End_Y		equ	15
		BORDER1 <, ErrorHold_Start_X, ErrorHold_Start_Y, ErrorHold_End_X, ErrorHold_End_Y, 0+Empty_Border>
		POS	<, 32, 14>
		db	'System Disabled'
		db	0
endif;	Add_PASSWORD_LOOPS				;R58A

;R68  Move code 0f000h segment,becasue need run time call Hash_password.
ifndef Password_Hook					;R68

;[]========================================================================[]
;Function :	Encode the password using hash algorithm
;
;Input	:	KEYIN_BUF[bp]
;
;Output	:	AX - hashed password
;[]========================================================================[]
Hash_Password	Proc    Near

ifndef	Perfect_Password

		push    si 			; save regs
		push    bx
		push    cx
		push    dx

		xor     si, si			; clear index
		xor     bx, bx			; clear current hash value
		xor	ah, ah
		mov     cx, 8			; set length counter
hash_pw1:
		mov     al, KEYIN_BUF[bp+si]
		or	al, al			; last byte = 0?
		jz	hash_done		; skip to quit if so
		rol	bx, 1			; adjust
		rol	bx, 1
ifdef	KEYBOARD_SECURITY
		F000_Call Ascii_To_Scan
endif;	KEYBOARD_SECURITY
		add	bx, ax			; add in current char
		inc	si			; bump index
		loop	hash_pw1		; do for all significant password chars
hash_done:
		xchg	ax, bx			; return result in ax
		pop     dx			; restore regs
		pop     cx
		pop     bx
		pop     si

endif	;Perfect_Password

		ret

Hash_Password	Endp
endif; Password_Hook					;R68

ifdef	Perfect_Password
;[]==============================================================[]
;Procedure :	Save_Perfect_Password
;
;Input	:	KEYIN_BUF[bp] to KEYIN_BUF[bp+7]
;
;Output	:	None
;
;Save	:	All registers
;
;Note	:	Save the characters stored in
;		KEYIN_BUF[bp] to KEYIN_BUF[bp+7] to CMOS RAM
;[]==============================================================[]
		Public	Save_Perfect_Password
Save_Perfect_Password	Proc	Near

		pusha

		mov     cx, 8			; set length counter
		xor	si, si			;index to point to KEYIN_BUF[bp]
		F000_Call Ct_Perfect_Password_Loc	;DI point to CMOS

Save_Next_Pass_Byte:

		mov     al, KEYIN_BUF[bp+si]
		ror	al, 3
		mov	[bp+di], al
		inc	si
		inc	di
		loop	short Save_Next_Pass_Byte	;

		popa
		ret

Save_Perfect_Password	Endp

;[]==============================================================[]
;Procedure :	Chk_Perfect_Password
;
;Input	:	KEYIN_BUF[bp] to KEYIN_BUF[bp+7]
;
;Output	:	ZF : Input password correct
;		NZ : Input password wrong
;
;Save	:	All registers
;
;Note	:	compare KEYIN_BUF[bp] to KEYIN_BUF[bp+7]
;		with CMOS RAM's data
;[]==============================================================[]
		Public	Chk_Perfect_Password
Chk_Perfect_Password	Proc	Near

		pusha

		mov     cx, 8			;set length counter
		xor	si, si			;index to point to KEYIN_BUF[bp]
		F000_Call Ct_Perfect_Password_Loc	;DI point to CMOS

Chk_Next_Pass_Byte:

		mov	al, KEYIN_BUF[bp+si]	;key in byte
		mov	ah, [bp+di]		;pass word byte in CMOS
		ror	al, 3
		cmp	al, ah			;pass word byte in CMOS
		jne	short Chk_Pass_End

		or	ax, ax
		jz	short @F

		inc	si
		inc	di
		loop	short Chk_Next_Pass_Byte
	@@:
		xor	al, al

	Chk_Pass_End:

		popa
		ret

Chk_Perfect_Password	Endp
endif	;Perfect_Password

ECODE		ENDS
;R46 - ends


;R70 - starts
.386P

XGROUP		GROUP	XCODE
XCODE		SEGMENT USE16 PARA PUBLIC 'XCODE'
		ASSUME	CS:XGROUP,ES:XGROUP

fPROC_F1_Show_Help	Proc	Far

		cmp	byte ptr CUR_PAGE[bp], PAGE_KERNAL
		je	short F1_Show_Help_Exit

		cmp	ax, K_F1
		jne	short F1_Show_Help_Exit

		or	byte ptr Post_Temp_Byte[bp],DO_NOT_UPDATE_TIME	;R56
		mov	byte ptr IN_F1_HELP[bp], 1	;indicate in F1
		call	Display_Help_Str
		mov	byte ptr IN_F1_HELP[bp], 0	;indicate not in F1
		F000_Call Refresh_Menu
		and	byte ptr Post_Temp_Byte[bp],not DO_NOT_UPDATE_TIME	;R56

F1_Show_Help_Exit:

		retf

fPROC_F1_Show_Help	Endp

;[]========================================================================[]
;[]========================================================================[]
Display_Help_Str	proc	near
Avail_X		EQU	13			;R88set help window available X
		push	ds
		call	GetAvail_ItemNumber	;Get item number;R88
		mov	si, [bx].HelpOffset	;get help string offset
;R73		cmp	byte ptr ds:[si], 0	;null string?
;R73		je	No_Help			;yes, exit


;R73 ;display help border
;R73 
;R73 		push	si			;save offset
;R73 		call	X_VNormal		;normal attribute
;R73 		mov	si, offset Help_Border	;clear help area first
;R73 		call	X_Display_CS_String
;R73 		pop	si			;restore si
;R73 
;R73 ;set margin
;R73 		call	X_VNormal		;normal attribute
;R73 		mov	byte ptr LMARGIN_X[bp], 22
;R73 		mov	CURSOR_X[bp], 0516h

;display help strings

		call	Check_If_Std_Help		;R70A
		je	short Show_Standard_Help	;R70A

		push	si			;save offset
		call	Try_Show_Help_String
		pop	si			;restore si
		jc	No_Help					;R73
		jne	No_Quit			;ZF=Show , exit

		jmp	short Show_Standard_Help1		;R73

Show_Standard_Help:

		call	Show_Help_Border			;R73

Show_Standard_Help1:						;R73

		mov	si, offset d4_msg
		call	X_Display_CS_String

		mov	dx, [bx].ItemMin		;started form min.
		mov	byte ptr Current_Item_Number[bp],dl  	;R88A
		
;R88 - start
		cmp	byte ptr Item_Number[bp],Avail_X;Is above availabel X
		ja	short Normal_POS
;R88B		mov	byte ptr LMARGIN_X[bp], 32	;change margin X to 32
;R88B		mov	byte ptr CURSOR_X[bp], 20h	;start of d4_msg1 address
;R88B - start
		mov	byte ptr LMARGIN_X[bp], 29	;change margin X to 32
		mov	byte ptr CURSOR_X[bp], 1Dh	;start of d4_msg1 address
;R88B - end
Normal_POS:
Help_Loop:
		mov	si, offset d4_msg1		
		call	X_Display_CS_String	;display d4_msg1
;R88 - end

Show_Available_Options:

		push	dx			;save dx

		F000_Call Check_VarNull
;R88		jc	short Next_Avail_Option	;not available
		jc	Next_Avail_Option	;R88not available

		call	X_Vnormal		;normal attribute
		F000_call Get_VarString_Offset
;R88 - start
		cmp	byte ptr Item_Number[bp],Avail_X
		ja	short Normal_POS1
		mov	byte ptr CURSOR_X[bp], 16h
Normal_POS1:
;R88 - end

		call	X_Display_String	;available, display it

		F000_Call VHilite		;hilite attribute

		F000_call Read_Item_Value	;get shift value (cl)
		pop	ax			;pop current option value
		push	ax			;push current option value
		mov	si, offset bios_d4_msg	;bios defaults string
		F000_call Get_Item_BIOS_D4	;get BIOS default in DX
		cmp	ax, dx			;current option = BIOS d4?
		jne	short @F		;no, 

;R88 - start
		push	CURSOR_X[bp]		
		mov	byte ptr CURSOR_X[bp],45
		cmp	byte ptr Item_Number[bp], Avail_X
		jbe	short Normal_POS2
;R88B		mov	byte ptr CURSOR_X[bp],26
		mov	byte ptr CURSOR_X[bp],24	;R88B
		push	ax			;save current option
		sub	ax, [bx].ItemMin	;count actual item number
		cmp	al, Avail_X		;option is over available X
		pop	ax			;restore current option
		jbe	short Normal_POS2	
;R88B		mov	byte ptr CURSOR_X[bp],53
		mov	byte ptr CURSOR_X[bp],57	;R88B
	Normal_POS2:
;R88 - end

		push	ax
		call	X_Display_CS_String	;yes, show message
		pop	ax
		pop	CURSOR_X[bp]		;R88
	@@:
		mov	si, offset setup_d4_msg	;setup defaults string
		F000_Call Get_Item_Setup_D4	;get setup d4 in DX
		cmp	ax, dx			;current option = setup d4?
		jne	short Option_Not_D4	;no, 
;R88 - start
		push	CURSOR_X[bp]		
		mov	byte ptr CURSOR_X[bp],52
		cmp	byte ptr Item_Number[bp],Avail_X	
		jbe	short Normal_POS3
;R88B		mov	byte ptr CURSOR_X[bp],33
		mov	byte ptr CURSOR_X[bp],31	;R88B
		push	ax			;save current option
		sub	ax, [bx].ItemMin	;count actual item number
		cmp	al, Avail_X		;option is over available X
		pop	ax			;restore current option
		jbe	short Normal_POS3	
;R88B		mov	byte ptr CURSOR_X[bp],60
		mov	byte ptr CURSOR_X[bp],64	;R88B
	Normal_POS3:
;R88 - end
		call	X_Display_CS_String	;yes, show message
		pop	CURSOR_X[bp]		;R88
Option_Not_D4:
		F000_Call VNewLine		;next line

		inc	byte ptr Current_Item_Number[bp] 	;R88A

Next_Avail_Option:

		pop	dx			;restore dx

		cmp	dx, [bx].ItemMax	;max. reached?
		jae	short Std_Help_Exit	;yes, leave

;R88B - start
		cmp	byte ptr Current_Item_Number[bp],(Avail_X*2)
		jae	short Std_Help_Exit	;if the displayed item is
						;over (Avail_X*2), then leave
;R88B - end
		inc	dx			;next option
;R88 start
		push	ax			;save current option
;R88A		mov	ax, dx			
		movzx	ax,byte ptr Current_Item_Number[bp] ;R88A
		sub	ax, [bx].ItemMin	;count actual item number
		cmp	al, Avail_X		;option is over available X
		pop	ax			;restore current option
		jne	short Help_Not_Over
;R88B		mov	byte ptr LMARGIN_X[bp], 40
;R88B		mov	CURSOR_X[bp],628h
		mov	byte ptr LMARGIN_X[bp], 41	;R88B
		mov	CURSOR_X[bp],629h		;R88B
		call	X_Vnormal		;normal attribute
		jmp	Help_Loop
Help_Not_Over:
;R88 end
		jmp	Show_Available_Options
Std_Help_Exit:
;-----------------------------------------------------------------------
No_Quit:
		F000_Call Key				;wait for key
		cmp	ax, K_F1			;is if 'F1'
		je	short @F			;yes
		cmp	ax, K_ESC1			;is if 'ESC'
		jne	short No_Quit			;no
	@@:
		mov	si, offset Clear_Help		;clear the help area
		call	X_Display_CS_String		;
		mov	word ptr LAST_KEY[bp], 0	;destroy key
No_Help:
		pop	ds
		ret					;return to caller

Help_Border	Label	Near
		db	V_WARN
		BORDER1	<, 21, 4, 60, 22, 1+Empty_Border>
;R88 start
		db	0
Help_Border1	Label	Near
		db	V_WARN
;R88B		BORDER1	<, 12, 4, 67, 22, 1+Empty_Border>
		BORDER1	<, 7, 4, 72, 22, 1+Empty_Border>	;R88B
		db	0
Help_string	label	near
;R88 end
		POS	<, 26, 21>
		db	V_HILITE, 'Press F1 or ESC to exit help'
		db	0

Clear_Help	Label	Near
		db	V_NORMAL
;R88		CLEAR	<, 21, 4, 60, 22>
;R88B		CLEAR	<, 12, 4, 67, 22>		;R88
		CLEAR	<, 7, 4, 72, 22>		;R88B;R88
		db	0

;R88d4_msg		db	'Available Options:',NEWLINE
;R88		ADDX	<, 23>
;R88		Public	X_Display_CS_String		;R86
;R88		db	'Default Type', NEWLINE
;R88		ADDX	<, 22>
;R88		db	'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ'
;R88		db	NEWLINE, 0
;R88 - start
d4_msg		db	'Available Options:',NEWLINE
		db	0
		Public	X_Display_CS_String		;R86
d4_msg1		ADDX	<, 17>				;R88B
;R88B		ADDX	<, 13>
		db	'Default Type', NEWLINE
;R88B		ADDX	<, 12>
;R88B		db	'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ'
		ADDX	<, 16>				;R88B
		db	'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ'		;R88B
		db	NEWLINE, 0
;R88 - end

;R88setup_d4_msg	POS	<, 54-2, >
;R88		db	'<Setup>', 0
;R88bios_d4_msg	POS	<, 45, >
;R88		db	'<BIOS>', 0

setup_d4_msg	db	'<Setup>', 0	;R88
bios_d4_msg	db	'<BIOS>', 0	;R88


Display_Help_Str	endp
;R88 - start
GetAvail_ItemNumber	Proc	Near
		pushad
;R88A		mov	ax, [bx].ItemMin
;R88A		mov	bx, [bx].ItemMax
;R88A		sub	bx, ax
;R88A		add	bx, 1
;R88A		mov	byte ptr Item_Number[bp],bl
;R88A - start
		mov	dx,[bx].ItemMin
		mov	cx,[bx].ItemMax
		xor	ax,ax
		inc	cx

loop_Check_ValNull:
		F000_Call Check_VarNull
		jc	short not_ValNull_found
		inc	ax
not_ValNull_found:
		inc	dx
		loop	short loop_Check_ValNull

		mov	byte ptr Item_Number[bp],al
;R88A - end
		popad
		ret
GetAvail_ItemNumber	endp
;R88 - end

;R73 - starts
Show_Help_Border	Proc	Near

;display help border

		push	si			;save offset
		call	X_VNormal		;normal attribute
		mov	si, offset Help_Border	;clear help area first
;R88 start
		cmp	byte ptr Item_Number[bp],Avail_X
		jbe	short Normal_Border
		mov	si, offset Help_Border1	;clear help area first
Normal_Border:
;R88 end
		call	X_Display_CS_String
;R88 start
		mov	si, offset Help_String	;clear help area first
		call	X_Display_CS_String
;R88 end

;set margin
		call	X_VNormal		;normal attribute
		mov	byte ptr LMARGIN_X[bp], 22
		mov	CURSOR_X[bp], 0516h
;R88 start
		cmp	byte ptr Item_Number[bp],Avail_X
		jbe	short Normal_CURSOR
;R88B		mov	byte ptr LMARGIN_X[bp], 13
;R88B		mov	CURSOR_X[bp], 050Dh
		mov	byte ptr LMARGIN_X[bp], 8		;R88B
		mov	CURSOR_X[bp], 0508h			;R88B
Normal_CURSOR:
;R88 end
		pop	si			;restore si
		ret

Show_Help_Border	Endp
;R73 - ends


;[]========================================================================[]
;[]========================================================================[]
fPROC_Show_Help_On_The_Fly	Proc	Far

		cmp	byte ptr CUR_PAGE[bp], PAGE_KERNAL
		jne	short Show_Help_Exit

		mov	byte ptr IN_F1_HELP[bp], 0	;indicate not in F1
							; e.g. Show_Calender will refer to this flag
		mov	word ptr CURSOR_X[bp], (22 shl 8) + 1

		mov	al, ' '
		mov	cx, 78
	@@:
		extrn	X_Display_Char:near
		call	X_Display_Char
		loop	short @B
		F000_Call Vhilite

		call	Try_Show_Help_String

Show_Help_Exit:

		ret

fPROC_Show_Help_On_The_Fly	Endp

;[]========================================================================[]
;[]========================================================================[]
Try_Show_Help_String	Proc	Near

		mov	si, [bx].HelpOffset
		push	ds
		call	Check_New_Help_Format
		jne	short @F
		mov	ax, SEG XGROUP
		mov	ds, ax
	@@:
		cmp	byte ptr ds:[si], 0				;R73
		jne	@F						;R73
		stc							;R73
		jmp	short Try_Show_Help_String_End			;R73
	@@:								;R73
		cmp	byte ptr CUR_PAGE[bp], PAGE_KERNAL		;R73
		je	short @F					;R73
		call	Show_Help_Border				;R73
	@@:								;R73
		call	X_Display_String
		cmp	byte ptr ds:[si-1], 1
		clc							;R73

	Try_Show_Help_String_End:					;R73

		pop	ds
		ret

Try_Show_Help_String	Endp
;R70A - starts
Check_If_Std_Help	Proc	Near

		push	ds

		push	SEG XGROUP
		pop	ds

		cmp	dword ptr ds:[si], '_DTS'
		jne	short Not_Std_Help
		cmp	dword ptr ds:[si+4], 'PLEH'
;R73		jne	short Not_Std_Help
;R73
;R73		pop	ds
;R73		ret

	Not_Std_Help:

		pop	ds
		ret

Check_If_Std_Help	Endp
;R70A - ends

X_Display_CS_String	Proc	Near
		push	ds
		push	cs
		pop	ds
		call	X_Display_String
		pop	ds
		ret
X_Display_CS_String	Endp

;R86 X_Display_String	Proc	Near
;R86 		F000_Call Display_String
;R86 		ret
;R86 X_Display_String	Endp
;R86 
;R86 X_VNormal	Proc	Near
;R86 		F000_Call Vnormal			;normal attribute
;R86 		ret
;R86 X_VNormal	Endp

;R73A - starts
New_Format_Labels_Tbl	Label	Near
ifdef	NEW_SUPERIO_KERNEL
	dw	offset First_IO_Item, offset Last_IO_Item
	dw	SEG Prg_Super_IO_Chip, offset Prg_Super_IO_Chip
endif	;NEW_SUPERIO_KERNEL

IF	CLKCNTL_KERNEL
	dw	offset First_Clock_Item, offset Last_Clock_Item
	dw	SEG Prepare_ClkGen_Val, offset Prepare_ClkGen_Val
ENDIF	;CLKCNTL_KERNEL

;R73B - starts
IF	AUDIO_KERNEL
	dw	offset First_Audio_Item, offset Last_Audio_Item
	dw	SEG Prg_Audio_Chip, offset Prg_Audio_Chip
ENDIF	;AUDIO_KERNEL
;R73B - ends

	COMPILE_FOR_SENSOR_MNU = 4	;R73C
	include	all_ssr.inc		;R73C

ifdef	NEW_SUPERIO_KERNEL		;R94A
;R94 - start
	COMPILE_FOR_SUPERIO_MNU = 6
	include	superio.sio	   
;R94 - end
endif	;NEW_SUPERIO_KERNEL		;R94A

	dw	-1
;R73A - ends

;[]========================================================================[]
;[]========================================================================[]
Check_New_Help_Format	Proc	Near

		pusha
		push	ds

;R73A - starts
		mov	di, (offset New_Format_Labels_Tbl) - 8
	@@:
		add	di, 8
		cmp	word ptr cs:[di], -1
		je	short @F

		cmp	bx, cs:[di]
		jb	short @B
		cmp	bx, cs:[di+2]
		jae	short @B

		mov	ax, cs:[di+4]
		mov	ds, ax
		mov	si, cs:[di+6]
		cmp	dword ptr ds:[si-4], '$LM$'
		je	short Its_New_Format
		jmp	short Its_Old_Format
	@@:
;R73A - ends

;R73A ;R73 - starts
;R73A ifdef	NEW_SUPERIO_KERNEL
;R73A 		cmp	bx, offset First_IO_Item
;R73A 		jb	short @F
;R73A 		cmp	bx, offset Last_IO_Item
;R73A 		jae	short @F
;R73A 
;R73A 		mov	ax, SEG Prg_Super_IO_Chip
;R73A 		mov	ds, ax
;R73A 		mov	si, offset Prg_Super_IO_Chip
;R73A 		cmp	dword ptr ds:[si-4], '$LM$'
;R73A 		je	short Its_New_Format
;R73A 		jmp	short Its_Old_Format
;R73A 	@@:
;R73A endif	;NEW_SUPERIO_KERNEL
;R73A ;R73 - ends

		mov	ax, Special_Do_Show_Diff
		mov	cl, CUR_PAGE[bp]
		dec	cl
		mul	cl
		mov	si, offset Special_Do_Show_Off
		add	si, ax

		push	SEG Special_Do_Show_Off
		pop	ds
		mov	si, ds:[si]
		cmp	dword ptr ds:[si-4], '$LM$'
;R73 - starts
		je	short Its_New_Format

	Its_Old_Format:

		or	sp, sp			;Clear Zero Flag

	Its_New_Format:
;R73 - ends

		pop	ds
		popa

		ret

Check_New_Help_Format	Endp

;R69A - start

F000_Display_String:
		F000_call	Display_String
		ret

;[]===========================================================[]
;[]===========================================================[]
Do_k_F5_MIB	Proc	Near
		call	check_MIB
		jnc	short DKFM_Exit
;R69B		cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL	;kernal ?
;R69B		jne	short DKFM_Exit
		cmp	LAST_KEY[bp],K_F5
		jne	short DKFM_Exit
		mov	si,offset Goto_Kernal
		cmp	word ptr PAGE_START[bp],offset Kernal_Start	;kernal ?
		jne	short @F
		mov	si,offset Goto_MIB_Feature
@@:
		call	si
DKFM_Exit:
		ret
Do_k_F5_MIB	Endp

;[]===========================================================[]
; Input : None
;
;Output : NC means MIB not present
;	  CY means MIB present
;[]===========================================================[]
check_MIB	Proc	Near
		push	es
		pusha

		cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL	;R69B;kernal ?
		jne	short no_mib_file			;R69B
		mov	ax,Temp_EXP_Seg		     	;cbrom table segment
		mov	es,ax
		mov	di,(0fh+1)*4			;cbrom /mib table offset
		mov	ebx,es:[di+Temp_EXP_Off]	;compress file address
		or	ebx,ebx				;have ?
		jz	short no_mib_file		;no exit
		cmp	bx,0ffffh			;have ?
		je	short no_mib_file		;no exit

		stc					;present
		jmp	short @F
no_mib_file:
		clc					;not found
@@:
		popa
		pop	es
		ret
check_MIB	Endp

;[]===========================================================[]
;Goto_MIB_Feature : di = (0fh+1)*4
;MIB File Structure as follow :
;  offset 0 (start)
;  	:	5 -MIB-
;  	:	4 {11,12,1,0}	(NewLine)
;  	:	9 {3,1,4,78,23,5,1,4,0}	  (Clear String)
;  	:	2 row offset table start offset
;  	:	2 row offset table end offset
;  offset 12h 
;  	:	
;  	:	
;  	:	File Data
;  	:	
;  	:
;  offset (data end)
;  string offset table for all row
;  	:	
;  	:	every row store size is word.
;  	:	bit 0 : 0 -> segment 4000h
;  	:		1 -> segment 5000h
;  	:	
;  	:	bit 1-15 : each row offset
;  	:	
;  string offset table end (maximum=1ffffh, that mean total max size is 128k from offset 0)
;[]===========================================================[]
Goto_MIB_Feature	Proc	Near
		push	es
		push	ds

		mov	di,(MIB_Expand_Address+1)*4;;;;; (0fh+1)*4		;MIB index for decompress
		post_func_call	post_decompress
		jnc	short MIB_avail
		jmp	exit_MIB
MIB_avail:
		push	4000h			;MIB data segment after decompress
		pop	ds
		cmp	dword ptr ds:[0],'BIM-'	;check MIB signature
		je	short @F
		jmp	exit_MIB
@@:
		mov	bx,ds:[18]			;row offset table start
		pop	ds
		mov	ax,4000h			;segment 4000h
		test	bl,1				;bit-0 = 1?
		jz	short @F
		and	bl,0feh				;clear bit-0
		mov	ax,5000h			;segment 5000h
@@:
		mov	es,ax
Rest_show_MIB:
		push	ds
		push	bx
		push	cs				;set MIB_Screen segment
		pop	ds				;to DS
		lea	si,MIB_Screen			;MIB screen
		call	F000_Display_String
		push	4000h
		pop	ds
		pop	bx
rest_show_str:
		push	bx

		mov	si,9				;clear string
		call	F000_Display_String

		mov	cx,20				;20 row for each page
MIB_Str_loop:
		push	cx
		push	ds

		mov	ax,es:[bx]
		mov	si,ax
		test	al,1				;check in first segment?
		jz	short @F			;Yes,jump
		and	al,0feh
		mov	si,ax
		mov	ax,5000h			;set to second segment
		mov	ds,ax
@@:
		call	F000_Display_String			;show string
		cmp	si,0				; > 64k?
		jne	short @F
		mov	ax,ds				;point to next segment
		add	ah,10h
		mov	ds,ax
		jmp	short @B
@@:
		pop	ds
		mov	si,5				;newline
		call	F000_Display_String
		mov	ax,ds:[20]			;row end offset
		add	bx,2
		pop	cx
		and	al,0feh				;isolate for exact offset
		cmp	ax,bx
		je	short @F
		loop	short MIB_Str_loop
@@:
		pop	bx
key_wait:
		push	bx
		F000_call	key				;wait for key
		pop	bx
;====UP_ARROW KEY====
		cmp	ax,UP_ARROW
		jne	short not_UP_ARROW
		mov	ax,ds:[18]			;row offset start
		and	al,0feh				;isolate for exact offset
		cmp	bx,ax				;= row offset start?
		je	short key_wait
		sub	bx,2
		jmp	short rest_show_str
;====DOWN_ARROW KEY====
not_UP_ARROW:		      
		cmp	ax,DOWN_ARROW
		jne	short not_DOWN_ARROW
		mov	ax,ds:[20]
		and	al,0feh				;isolate for exact offset
		sub	ax,bx
		cmp	ax,20*2
		jbe	short key_wait
		add	bx,2
		jmp	rest_show_str
;====PAGE UP KEY====
not_DOWN_ARROW:
		cmp	ax,PGUP
		jne	short not_PGUP
		mov	ax,ds:[18]
		and	al,0feh				;isolate for exact offset
		cmp	bx,ax
		je	short key_wait
		mov	ax,bx
		mov	cx,ds:[18]
		and	cl,0feh				;isolate for exact offset
		sub	ax,cx
		cmp	ax,20*2
		ja	short @F
		mov	bx,ds:[18]
		and	bl,0feh
		jmp	rest_show_str
@@:
		sub	bx,20*2
		jmp	rest_show_str
;====PAGE DOWN KEY====
not_PGUP:
		cmp	ax,PGDN
		jne	short not_PGDN
		mov	ax,ds:[20]
		and	al,0feh				;isolate for exact offset
		sub	ax,bx
		cmp	ax,20*2
		jbe	short key_wait

		cmp	ax,20*2*2
		jae	short @F
		sub	ax,20*2
		add	bx,ax
		jmp	rest_show_str
@@:
		add	bx,20*2
		jmp	rest_show_str
;====F2 KEY (Change Color)====
not_PGDN:
		cmp	ax,K_F2
		jne	short SHFT_F2_try
		add	byte ptr CMOS3B[bp],10h
		jmp	short @F
;====Shift+F2 KEY (Change Color)====
SHFT_F2_try:
		cmp	ax,K_SHFT_F2
		jne	short not_Change_Color
		sub	byte ptr CMOS3B[bp],10h
@@:
		mov	al,CMOS3B[bp]
		F000_call	Get_Color_Off
		pop	ds
		jmp	Rest_show_MIB
not_Change_Color:

;R74 start
ifdef MIB_Print
;==== MIB_Print_KEY ====
		cmp	ax,K_F7
		jne	short not_Print
		call	MIB_Print_Fun
		pop	ds
		jmp	Rest_show_MIB
not_Print:
endif	;MIB_Print
;R74 end

;====ESC KEY (Exit)====
		cmp	ax,K_ESC1
		je	short exit_MIB
		jmp	key_wait
exit_MIB:
		pop	ds
		pop	es
		F000_call	Refresh_Menu1			;re-display screen
		mov	word ptr LAST_KEY[bp],0
		ret
Goto_MIB_Feature	endp
;R69A - end

;R74 start
ifdef MIB_Print
;[]===========================================================[]
;MIB_Print_Fun:
;Input : None
;Output : None
;[]===========================================================[]
MIB_Print_Fun	Proc	Near
		push	ds
		pusha
chk_prn:
		call	check_printer			;check printer
		jnc	short printer_ready		;ready?

;====printer not ready=====
		call	show_prt_msg			;show printer error
K_WAIT1:
		F000_call	key			;wait for key

		cmp	ax,K_ESC1			;exit?
		je	exit_MIB_Print_Fun
		cmp	ax,K_CR1			;retry?
		je	short chk_prn
		jmp	short K_WAIT1
		jmp	exit_MIB_Print_Fun
;=====printer ready=====
printer_ready:
		call	show_prt_wait			;show Wait

		push	4000h				;decompress in 4000h:0
		pop	ds
		mov	bx,ds:[18]			;row offset table start
		mov	ax,4000h			;segment 4000h
		test	bl,1				;bit-0 = 1?
							; 1->seg=5000h
		jz	short @F
		and	bl,0feh				;clear bit-0
		mov	ax,5000h			;segment 5000h
@@:
		mov	es,ax
;=====start printing=====
print_char1:
		push	ds

		mov	ax,es:[bx]			;row table
		mov	cx,4000h
		test	al,1				;check in first segment?
		jz	short @F			;Yes,jump
		and	al,0feh
		mov	cx,5000h			;set to second segment
@@:
		mov	si,ax
		mov	ds,cx
;=====row print=====
print_char2:
		mov	al,ds:[si]
		or	al,al
		jz	short exit_print2

		xor	ah,ah
		call	prn_char

		test	ah,69h				;check printer error?
		jz	short prn_nothing
		call	show_prt_msg
K_WAIT2:
		F000_call	key 			;wait for key

		cmp	ax,K_ESC1			;exit?
		je	short exit_prn
		cmp	ax,K_CR1			;retry?
		je	short print_char2
		jmp	short K_WAIT2
exit_prn:
		pop	ds
		jmp	short exit_MIB_Print_Fun	;exit MIB_print
prn_nothing:
		inc	si
		cmp	si,0				; > 64k?
		jne	short @F
		mov	ax,ds				;point to next segment
		add	ah,10h
		mov	ds,ax
@@:
		jmp	short print_char2

exit_print2:
		mov	ax,0dh		;
		call	prn_char	;
		mov	ax,0ah		;new line
		call	prn_char	

		pop	ds
		mov	ax,ds:[20]
		and	al,0feh		;isolate for exact offset

		add	bx,2
		cmp	bx,ax
		jb	short print_char1

		mov	ax,0ch		;end print
		call	prn_char
exit_MIB_Print_Fun:
		popa
		pop	ds
		ret
MIB_Print_Fun	endp

;[]===========================================================[]
;prn_char:
;Input : Ah -> 00 write character
;	       01 initialize printer port
;	       02 status request
;Output : AH -> printer status byte
;		bit0 : Time-out 
;		bit1 : RESERVED	
;		bit2 : RESERVED	
;		bit3 : I/O Error
;		bit4 : Selected
;		bit5 : Out of Pager
;		bit6 : Acknowledge
;		bit7 : Not Busy
;[]===========================================================[]
prn_char	Proc	Near
		push	dx
		xor	dx,dx		;printer number
		int	17h		;printer function
		pop	dx
		ret
prn_char	endp

;[]===========================================================[]
;check_printer:
;Input : None
;Output : CF = 0 -> printer ready.  1 -> printer not ready
;[]===========================================================[]
check_printer	Proc	Near
		mov	ax,0200h		;status request
		call	prn_char		;call printer function
		stc				;set carry means have some error
		test	ah,01101001b		;test printer status
		jnz	short not_print_ready	;have some error then return carry
		clc				;clear carry means no error
not_print_ready:
		ret
check_printer	endp

;[]===========================================================[]
;show_prt_msg:
;Input : None
;Output : None
;[]===========================================================[]
show_prt_msg	Proc	Near
		push	ds
		pusha

		mov	al,byte ptr CMOS3B[bp]		;save color
		push	ax
		
		mov	ax,cs
		mov	ds,ax
		mov	si,offset Prn_not_ready
		call	F000_Display_String

		pop	ax
		F000_call	Get_Color_Off		;restore color

		popa
		pop	ds
		ret

Prn_not_ready	label	near
		db	V_REVERSE
		BORDER1	<,22,12,57,15,Empty_Border>
		POS	<,31,13>
		db	'Printer Not Ready'
		POS	<,26,14>
		db	'<ESC> Exit     <ENTER> Retry'
		db	0

show_prt_msg	Endp

;[]===========================================================[]
;show_prt_wait:
;Input : None
;Output : None
;[]===========================================================[]
show_prt_wait	Proc	Near
		push	ds
		pusha

		mov	al,byte ptr CMOS3B[bp]
		push	ax
		
		mov	ax,cs
		mov	ds,ax
		mov	si,offset Prn_Pl_wait
		call	F000_Display_String

		pop	ax
		F000_call	Get_Color_Off

		popa
		pop	ds
		ret

Prn_Pl_wait	label	near
		db	V_REVERSE
		BORDER1	<,22,12,57,15,Empty_Border>
		POS	<,35,13>
		db	'Printing'
		POS	<,33,14>
		db	V_BLINK
		db	'Please  Wait'
		db	0

show_prt_wait	Endp

endif	;MIB_Print
;R74 end

;R96 start
ifdef Support_CMOS_Backup_Data
;[]===========================================================[]
;                 Check_Flash_CMOS
;Input : dh ==> 0aah - save cmos to flash
;		05h  - load cmos for flash
;Output : None
;[]===========================================================[]
	       PUBLIC   Check_Flash_CMOS
Check_Flash_CMOS	proc	near
		pusha
		push	ds
		push	es

	     	cmp     dh,0aah				; 0aah -> save cmos to flash
							; 05h  -> load cmos for flash
	     	je      short save_cmos
		cmp     dh,05h
		jne	short cmos_exit

                call	check_CMOS_label		;check CMOS label
		jz	short cmos_exit			;No CMOS data

                mov    	dl,byte ptr ds:[si]		;get cmos length

	      	call	load_flash_to_cmos		;flash to cmos
		jmp	short cmos_exit
	save_cmos:
		call	save_cmos_to_flash		;save cmos
	cmos_exit:
		pop	es
		pop	ds
		popa
		ret
Check_Flash_CMOS	endp
;[]=====================================================[]
Read_CMOS_for_Flash:
ifndef		Flash_IN_SMBASE
		mov	ax, DMI_STORAGE_BASE
		mov	ds, ax
		mov	esi, DMI_OFFSET
else ;Flash_IN_SMBASE
		mov	eax,DMI_STORAGE_BASE shl 4  
		mov	ax, DMI_ADDR
		mov	esi,eax
endif ;Flash_IN_SMBASE
		push	TEMP_MEM
		pop	es
		xor	edi,edi
		mov	cx,DMI_STORAGE_SIZE
		f000_call	Post_Flash_Read
		ret
;[]=====================================================[]
Write_CMOS_for_Flash:
ifndef		Flash_IN_SMBASE
		mov	ax, DMI_STORAGE_BASE
		mov	es, ax
		mov	edi, DMI_OFFSET
else ;Flash_IN_SMBASE
		mov	eax,DMI_STORAGE_BASE shl 4  
		mov	ax, DMI_ADDR
		mov	edi,eax
endif ;Flash_IN_SMBASE
		push	TEMP_MEM
		pop	ds
		xor	esi,esi
		mov	cx,DMI_STORAGE_SIZE
		f000_call	Post_Flash_Write
		ret
;[]=====================================================[]
check_CMOS_label:
		call	Read_CMOS_for_Flash
		push	es
		pop	ds
ifdef dmi_gpnv_support
		mov	si, DMI_TBL_OFFSET + DMI_MAX_POOL_SIZE + GPNV_MIN_BUF_SIZE
else ;dmi_gpnv_support
		mov	si, DMI_TBL_OFFSET + DMI_MAX_POOL_SIZE
endif ;dmi_gpnv_support

		push	cs
		pop	es
	       	lea	di,CMOS_Label
		mov	cx,CMOS_Label_Size
		cld
	     	rep	cmpsb
ifdef dmi_gpnv_support
		cmp	si, DMI_TBL_OFFSET + DMI_MAX_POOL_SIZE + GPNV_MIN_BUF_SIZE
else ;dmi_gpnv_support
		cmp	si, DMI_TBL_OFFSET + DMI_MAX_POOL_SIZE
endif ;dmi_gpnv_support
		jz	short no_found_cmos_label

	      	mov     bx,si				;save si
		add	bx,2				;CMOS data start
	no_found_cmos_label:
		ret
;[]===========================================================[]
save_cmos_to_flash:
		call	Read_CMOS_for_Flash
ifdef dmi_gpnv_support
		mov	di, DMI_TBL_OFFSET + DMI_MAX_POOL_SIZE + GPNV_MIN_BUF_SIZE
else ;dmi_gpnv_support
		mov	di, DMI_TBL_OFFSET + DMI_MAX_POOL_SIZE
endif ;dmi_gpnv_support

		push	cs
		pop	ds
	       	lea	si,CMOS_Label
		mov	cx,CMOS_Label_Size
		rep	movsb
		mov	byte ptr es:[di], CMOS_BACKUP_SIZE	;CMOS data length
		add	di,2					;length & checksum

		push	ss
		pop	ds
		mov	bx,bp
		add	bx,10h
		mov	si,bx
		push	si
		mov	cx,CMOS_BACKUP_SIZE
		rep	movsb					;save cmos(stack)
		pop	si

		mov	cx,CMOS_BACKUP_SIZE
		xor     ah,ah
	cmos_checksum_loop:
		lodsb
		add	ah,al
		loop	short cmos_checksum_loop

		sub	di,CMOS_BACKUP_SIZE+1
		mov	byte ptr es:[di], ah			;CMOS data checksum

		call	Write_CMOS_for_Flash
		ret
;[]===========================================================[]
load_flash_to_cmos:
		movzx	cx,dl				;cmos length
		push	cx
		mov	si,bx
		xor	ah,ah
	check_checksum:
		lodsb
		add	ah,al
		loop	short check_checksum
		cmp	ah,byte ptr ds:[bx-1]		;chech cmos checksum
		pop	cx
		jne	short csum_error

		push	ss
		pop	es
		mov	si,bx
		mov	bx,bp				;mov buffer data
		add	bx,10h				;to cmos(stack)
		mov	di,bx				;
		rep	movsb				;
csum_error:
		ret

CMOS_Label:
		db	FLASH_CMOS_Sign			;signature  
CMOS_Label_Size	EQU	$-offset CMOS_Label
endif  ;Support_CMOS_Backup_Data 

ifdef  Backup_CMOS_to_FLASH
;[]===========================================================[]
Do_F6_S_CMOS	Proc	Near
	       	cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL
	 	jne	short NOT_F6_Exit
		cmp	LAST_KEY[bp],K_F6
		jne	short NOT_F6_Exit
		F000_call   Save_CMOS_TO_BIOS_Default
NOT_F6_Exit:
		ret
Do_F6_S_CMOS	Endp
;[]===========================================================[]
Do_F7_S_CMOS	Proc	Near
	       	cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL
	 	jne	short NOT_F7_Exit
		cmp	LAST_KEY[bp],K_F7
		jne	short NOT_F7_Exit
		F000_call   Load_CMOS_From_BIOS_Default	
NOT_F7_Exit:
		ret
Do_F7_S_CMOS	Endp
endif	;Backup_CMOS_to_FLASH
;R96 end

;R96 ;R75 start
;R96 ;R78cifndef Flash_16K_8K_8K_Unit	  ;R78b
;R96 ifdef  Support_CMOS_Backup_Data    ;R78
;R96 ;R78 ifdef  Backup_CMOS_to_FLASH
;R96 CMOS_DATA_AREA		EQU	8000H
;R96 bPnpModeFlag		EQU	byte ptr [ebp-20]  ;R78c
;R96 CMOS_FLASH_R_W		EQU	01000000b  	   ;R78c
;R96 ;************************************************
;R96 ;Name:   	SET_CMOS_RAM_SEGMEMT
;R96 ;set_cmos_segment  will:
;R96 ;************************************************
;R96 SET_CMOS_RAM_SEGMEMT	PROC	NEAR
;R96 		push	bx
;R96 		push	ds
;R96 		push	CMOS_Data_Area
;R96 		pop	ds
;R96 		mov	bl, al
;R96 		xor	bh, bh
;R96 ;R77-start
;R96        		push   ax
;R96 		mov	al,byte ptr DS:[si]
;R96        		cmp     al,ah
;R96        		jne	short  CMOS_EQU_ROM 
;R96 
;R96 	        inc	dl		       ;CMP CMOS_DATA EQU ROM_DATA    
;R96 					       ; EQUAL 	DL +  1
;R96 CMOS_EQU_ROM: 
;R96 	      	pop     ax
;R96 ;R77-end
;R96 		mov	byte ptr DS:[si], ah
;R96 		pop	ds
;R96 		pop	bx
;R96 
;R96 		RET
;R96 SET_CMOS_RAM_SEGMEMT	ENDP
;R96 ;[]===========================================================[]
;R96 ;	       CMOS_DRAM_TX
;R96 ;Input :  None
;R96 ;Output : None
;R96 ;[]===========================================================[]
;R96 ;Read data from CMOS(80h-10H) Write data to DRAM
;R96 CMOS_DRAM_TX	proc	near
;R96 ;R77		pusha
;R96 	        xor    dl,dl	     ;R77
;R96 		mov	cl, 10h
;R96 CMOS_DRAM_TX_LP:
;R96 ;R77		push	dx
;R96 		mov	al, cl	
;R96 		ALIGN	4
;R96 		OUT	CMOS,AL			; address to interface
;R96 		jcxz	short $+2
;R96 		jcxz	short $+2
;R96 		ALIGN	4
;R96 		IN	AL,CMOS+1
;R96 		jcxz	short $+2
;R96 		jcxz	short $+2
;R96 		mov	ah, al
;R96 		mov	al, cl
;R96 		call   	SET_CMOS_RAM_SEGMEMT
;R96 ;R77		pop	dx
;R96 		inc     si
;R96 		inc	cl
;R96 ;R77		cmp	cl,7fh
;R96 		xor     bl,bl		  ;R77
;R96 		mov	bl,dh             ;R77;FLASH_CMOS_len==dh
;R96 		add	bl,0fh		  ;R77
;R96 		cmp	cl,bl		  ;R77
;R96 
;R96 		jbe	short CMOS_DRAM_TX_LP
;R96 ;R77		popa
;R96 		ret
;R96 CMOS_DRAM_TX	endp
;R96 ;[]===========================================================[]
;R96 ;	       WRITE_TO_CMOS_RAM	
;R96 ;Input  : None
;R96 ;Output : None
;R96 ;[]===========================================================[]
;R96 ;Read data from DRAM Write data to CMOSRAM(80h-10H)
;R96 WRITE_TO_CMOS_RAM	proc	near
;R96 		pusha
;R96 ;R78		mov	cl, 10h
;R96 		mov	cx, 10h	   ;R78
;R96 	   	mov	bx,bp	   ;R78
;R96 		add     bx,cx	   ;R78
;R96 WRITE_TO_CMOS_DRAM_LP:
;R96 		mov	al,cl              ;ah=index,al=value	    
;R96 		mov	ah,byte ptr DS:[si]
;R96 		mov	byte ptr ss:[bx],ah;R78
;R96 		cmp     dh,03h		             ;R78d;	     
;R96 		je      short Setup_Write_To_CMOSRAM ;R78d;		     
;R96 		ALIGN	4
;R96 		OUT	CMOS,AL	           ;address to interface
;R96 		jcxz	short $+2
;R96 		jcxz	short $+2
;R96 	    	xchg	al,ah	           ;ah=index,al=value
;R96 		ALIGN	4
;R96 		OUT	CMOS+1,Al          ;and output it
;R96 		jcxz	short $+2
;R96 		jcxz	short $+2
;R96 Setup_Write_To_CMOSRAM:				     ;R78d;
;R96 		inc     si
;R96 		inc	cl
;R96 		inc     bx	           ;R78
;R96 ;R77		cmp	cl,7fh
;R96 ;R78		mov	bl,dl              ;R77 FLASH CMOS len ==  dl
;R96 ;R78		add	bl,0fh		   ;R77
;R96 ;R78		cmp	cl,bl		   ;R77
;R96 		mov	ch,dl              ;R78 FLASH CMOS len ==  dl
;R96 		add	ch,0fh		   ;R78
;R96 		cmp	cl,ch		   ;R78
;R96 
;R96 		jbe	short WRITE_TO_CMOS_DRAM_LP
;R96 		popa
;R96 		ret
;R96 WRITE_TO_CMOS_RAM		endp
;R96 ;[]===========================================================[]
;R96 ;               DRAM2FLASH
;R96 ;Input  : None
;R96 ;Output : None
;R96 ;[]===========================================================[]
;R96 ; Read data from DRAM(80000:8ffff) Write data to FlashROM
;R96 	    PUBLIC 	DRAM2FLASH  ;R78
;R96 DRAM2FLASH	proc	near
;R96 		push	es
;R96 		push	ds
;R96 		pusha
;R96 		push	CMOS_Data_Area
;R96 		pop	ds		 
;R96 	     	and	bx,0f000h	     ;AND Data_Area get by 4k
;R96 	       	push	0F000h
;R96 	       	pop	es
;R96 	        mov	si,bx
;R96 		push    bx 
;R96 		push    si 
;R96 		xor     ax,ax                ;****get checksum**** 
;R96 		add	bx,0fffh	     ;*by  DS:SI 4k Area**  
;R96 checksum_loop:				     ;********************
;R96 		add	al, byte ptr DS:[si] ;
;R96 		inc     si		     ;search next address
;R96 		cmp	si,bx		     ;
;R96 		jne     short   checksum_loop;
;R96 		mov	byte ptr DS:[si],al  ;save  checksum
;R96 
;R96 		pop     si 
;R96 		pop     bx 
;R96 ;R78cifdef	ESCD_M2
;R96 ;R78c		sub	bx,0A000h             ;-A000h for ESCD M2
;R96 ;R78cendif	;ESCD_M2
;R96 ;R78c-start
;R96 ifdef	ESCD_M2
;R96 		sub	bx,0A000h             ;-A000h for ESCD M2
;R96 ifdef		Flash_4K_Unit
;R96 		sub	bx,0A000h             ;-A000h for ESCD M2
;R96 elseifdef	Flash_16K_Unit
;R96 		sub	bx,08000h             ;-A000h for ESCD M2
;R96 elseifdef	Flash_16K_8K_8K_Unit
;R96 		sub	bx,06000h             ;-A000h for ESCD M2
;R96 elseifdef	Flash1M_16K_8K_8K_Unit			;R18
;R96 		sub	bx,08000h             ;-A000h for ESCD M2
;R96 endif
;R96 
;R96 endif	;ESCD_M2
;R96 ;R78c-end
;R96 		mov	di, bx
;R96 		mov	cx,1000h		    ;R78d;
;R96 ;R78d;;R78cstart
;R96 ;R78d;ifdef	Flash_16K_8K_8K_Unit
;R96 ;R78d;		push	ebp
;R96 ;R78d;	       	movzx	ebp, sp
;R96 ;R78d;	       	sub	sp,20 ;DEFAULT_STACK+PARA_SIZE
;R96 ;R78d;               	mov	bPnpModeFlag,CMOS_FLASH_R_W  ;CMOS_FLASH_R_W is High
;R96 ;R78d;endif  ;Flash_16K_8K_8K_Unit
;R96 ;R78d;;R78cend
;R96 ;R78d;
;R96 ;R78d;		mov	cx,1000h	
;R96 ;R78d;		F000_CALL	Flash_Write
;R96 ;R78d;;R78cstart
;R96 ;R78d;ifdef	Flash_16K_8K_8K_Unit
;R96 ;R78d;	       	add	sp,20 ; DEFAULT_STACK+PARA_SIZE
;R96 ;R78d;               	and	bPnpModeFlag,Not CMOS_FLASH_R_W  ;CMOS_FLASH_R_W is High
;R96 ;R78d;		pop	ebp;R78c
;R96 ;R78d;endif  ;Flash_16K_8K_8K_Unit
;R96 ;R78d;;R78cend
;R96 		push    ax			   ;R78d;
;R96 		mov     al,0a0h			   ;R78d;
;R96 		call    CMOS_FLASHROM_READ_WRITE   ;R78d;
;R96     		pop     ax			   ;R78d;
;R96 
;R96 		popa
;R96 		pop	ds
;R96 		pop	es
;R96 		ret
;R96 DRAM2Flash	endp
;R96 ;[]===========================================================[]
;R96 ;                 Check_Flash_CMOS
;R96 ;Input  : None
;R96 ;Output : None
;R96 ;[]===========================================================[]
;R96 ;add dh=005h  READ_FlashROM_TO_CMOS	 dh=0aah READ_CMOS_TO_FLASHROM
;R96 	       PUBLIC   Check_Flash_CMOS
;R96 Check_Flash_CMOS	proc	near
;R96 		
;R96 		pusha
;R96 		push	ds
;R96 		push	es
;R96 ;R77-START
;R96 		xor     dl,dl
;R96                 call	Search_CMOS_label      ;Search CMOS label
;R96 		cmp	si,0		   ;R77;SI == 0 not found
;R96 		je	short cmos_exit	   ;R77;
;R96 		push    dx               
;R96 	        push    bx
;R96            	push    si
;R96               	and	si,0fff0h		;GET  CMOS LENGTH Value
;R96 ;R78a                mov    	dh,byte ptr ds:[si]
;R96                 mov    	dh,byte ptr ds:[si+6]   ;R78a
;R96 		pop     si
;R96         	pop    	bx
;R96         	push    bx
;R96                ; Read data from CMOS(80h-10H) Write data to DRAM
;R96              	call	CMOS_DRAM_TX   
;R96         	pop    	bx
;R96 ;R78		cmp     dl,6eh			;CMP CMOS_DATA EQU ROM_DATA    
;R96 		cmp     dl,70h	                ;R78;CMP CMOS_DATA EQU ROM_DATA    
;R96 		xchg	al,dh		        ;    EQUAL   DL==06eH	       
;R96 		pop     dx			;
;R96  		mov     dl,al		        ;
;R96 		ja	short cmos_exit		;Above     Check_Flash_CMOS  EXIT
;R96 
;R96         	push    bx
;R96                 call  CMOS_DRAM_CHECKSUM
;R96 	   	pop     si 
;R96 ;R77_END
;R96 ;R77            call	Search_CMOS_label 
;R96 	     	cmp     dh,0aah		             ;COMPARE  DH== aah	 READ_CMOS_TO_FlashROM
;R96 	     	je      short  READ_CMOS_TO_FlashROM ;	       DH== 05h	 RAMDATA_WRITE_TO_CMOS_RAM
;R96 		cmp     dh,05h			     ;
;R96 		ja	short cmos_exit		     ;
;R96 ;R78d;		jne	short cmos_exit		     ;
;R96                ; Read data from DRAM(80000:8ffff) Write data to CMOSRAM
;R96 	      	call	WRITE_TO_CMOS_RAM
;R96 	      	jmp     short cmos_exit
;R96 READ_CMOS_TO_FlashROM:	       
;R96 ;R77      	call	CMOS_DRAM_TX   
;R96                ; Read data from DRAM(80000:8ffff) Write data to FlashROM
;R96 	      	call	DRAM2FLASH	
;R96 cmos_exit:
;R96 		pop	es
;R96 		pop	ds
;R96 		popa
;R96 		ret
;R96 Check_Flash_CMOS	endp
;R96 ;[]===========================================================[]
;R96 ;                 CMOS_DRAM_CHECKSUM 
;R96 ;Input  : None
;R96 ;Output : None
;R96 ;[]===========================================================[]
;R96 		PUBLIC  CMOS_DRAM_CHECKSUM  ;R78
;R96 ;R77-START
;R96 CMOS_DRAM_CHECKSUM    proc	near
;R96 		push	dx		;R77B
;R96 		push    bx
;R96 ;R77B		push    si
;R96 ;R77B		push    bx
;R96 ;R77B		mov     si,bx
;R96 		push	CMOS_Data_Area
;R96 		pop	ds		 
;R96 		xor     ax,ax                         ;get checksum 
;R96 ;R77B	  	add	bl,dl                         ;FLASH CMOS len value==dl         
;R96 ram_checksum_loop:				      ;
;R96 ;R77b - start
;R96 		add	al, byte ptr DS:[bx] 	      ;
;R96 		inc     bx		     	      ;search next address
;R96 		dec 	dl
;R96 		jnz	short   ram_checksum_loop;
;R96 
;R96 		pop     bx
;R96 		push    bx
;R96 		and     bl,0f0h		      	      ;GET CMOS CHECKSUM ADDRESS
;R96 	  	mov	byte ptr DS:[bx+6+1],al       ;SAVE CMOS CHECKSUM Value
;R96 ;R77b - end
;R96 ;R77B		add	al, byte ptr DS:[si] 	      ;
;R96 ;R77B		inc     si		     	      ;search next address
;R96 ;R77B		cmp	si,bx		     	      ;
;R96 ;R77B		jne     short   ram_checksum_loop;
;R96 ;R77B		pop     si
;R96 ;R77B		and     si,0fff0h		      ;GET CMOS CHECKSUM ADDRESS
;R96 ;R77B;R78a	  	mov	byte ptr DS:[si+1],al         ;SAVE CMOS CHECKSUM Value
;R96 ;R77B	  	mov	byte ptr DS:[si+6+1],al  ;R78a;SAVE CMOS CHECKSUM Value
;R96 ;R77B		pop     si
;R96 		pop     bx
;R96 		pop     dx				;R77B
;R96 		     ret
;R96 CMOS_DRAM_CHECKSUM	endp
;R96 ;R77-END
;R96 
;R96 ;[]=====================================================[]
;R96 ;Input  : NONE
;R96 ;Output : SI = 0 not found otherwise is founded
;R96 ;[]=====================================================[]
;R96 	    	PUBLIC	Search_CMOS_label  ;R78
;R96 Search_CMOS_label  proc	near
;R96 		push   0f000h 
;R96 	        pop     ds      
;R96 ;R78c		mov	si,0h 
;R96 		mov     bx,CMOS_DATA_AREA
;R96 	        mov     es,bx	     
;R96 ;R78cifdef	ESCD_M2
;R96 ;R78c		mov	di,0A000h               ;A000h for ESCD M2
;R96 ;R78cendif	;ESCD_M2
;R96 ;R78cstart
;R96  ifdef	ESCD_M2
;R96  	     	mov    edi,0ffffA000h               ;A000h for ESCD M2
;R96  ifdef		Flash_4K_Unit
;R96  	     	mov    edi,0ffffA000h               ;A000h for ESCD M2
;R96  elseifdef	Flash_16K_Unit
;R96  	     	mov    edi,0ffff8000h               ;A000h for ESCD M2
;R96  elseifdef	Flash_16K_8K_8K_Unit
;R96  	     	mov    edi,000h               ;A000h for ESCD M2
;R96  elseifdef	Flash1M_16K_8K_8K_Unit			;R18
;R96  	     	mov    di,08000h               ;A000h for ESCD M2
;R96  endif
;R96  endif	;ESCD_M2
;R96 ;R78cend
;R96 		mov	esi,0h 		  ;R78c
;R96 		mov     cx,0ffffh		;read ROM F0000:FFFFF
;R96 ;R78d;;R78cstart
;R96 ;R78d;ifdef	Flash_16K_8K_8K_Unit
;R96 ;R78d;		push	ebp
;R96 ;R78d;	      	movzx	ebp, sp
;R96 ;R78d;	      	sub	sp,20 ;DEFAULT_STACK+PARA_SIZE
;R96 ;R78d;              	mov	bPnpModeFlag,CMOS_FLASH_R_W  ;CMOS_FLASH_R_W is High
;R96 ;R78d;endif  ;Flash_16K_8K_8K_Unit
;R96 ;R78d;;R78cend
;R96 ;R78d;		F000_CALL	Flash_Read	;TO  DRAM 80000:8FFFF 
;R96 ;R78d;ifdef	Flash_16K_8K_8K_Unit
;R96 ;R78d;	      	add	sp,20 ; DEFAULT_STACK+PARA_SIZE
;R96 ;R78d;              	and	bPnpModeFlag,Not CMOS_FLASH_R_W  ;CMOS_FLASH_R_W is High
;R96 ;R78d;		pop	ebp   ;R78c
;R96 ;R78d;endif  ;Flash_16K_8K_8K_Unit
;R96 ;R78d;;R78cend
;R96 		push    ax			     ;R78d;
;R96 		mov     al,0ah			     ;R78d;
;R96 		call    CMOS_FLASHROM_READ_WRITE     ;R78d;
;R96     		pop     ax			     ;R78d;
;R96 
;R96 		mov     bx,CMOS_DATA_AREA
;R96 	        mov     ds,bx
;R96 	       	mov     bx,6000h	        ;XGROUP ES:DI
;R96 	        mov     es,bx	     		;save segment
;R96 		mov	si,0h  			;address
;R96 		mov	ax,0h  			;address
;R96 		cld
;R96 Search_CMOS_label_loop:				;Search_CMOS_label
;R96 	       	lea	di,CMOS_Label		;From DRAM 80000:8FFFF
;R96 ;R77	      	mov	cx,04h
;R96 		mov	cx,CMOS_Label_Size	;R77
;R96 	     	rep	cmpsb
;R96 		jz	short Found_CMOS_label	;If found then going
;R96 	       	inc     ax 			;search next address
;R96 	       	jnz	short Search_CMOS_label_loop
;R96 		xor	si,si			;Not found,clear ESI high word
;R96 Found_CMOS_label:
;R96 	    	add     si,2	  		;R78a
;R96 	      	mov     bx,si
;R96 		ret
;R96 
;R96 CMOS_Label	label	near
;R96 		db	FLASH_CMOS_Sign   	;R77 signature  
;R96 CMOS_Label_Size	EQU	$-offset CMOS_Label	;R77  
;R96 ;R77		db	'*MM*'  
;R96 Search_CMOS_label	endp
;R96 ;R77-start
;R96 ;[]===========================================================[]
;R96 ;              Search_ROM_CMOS_CHECK 
;R96 ;Input  : None
;R96 ;Output : None
;R96 ;[]===========================================================[]
;R96 
;R96 Search_ROM_CMOS_CHECK  proc	near
;R96 		push   0f000h 
;R96 	        pop     ax      
;R96 	 	mov	ds,ax 
;R96               	and	si,0fff0h
;R96 		inc     si 
;R96 		mov     bx,CMOS_DATA_AREA
;R96 	        mov     es,bx	     
;R96 ;ifdef	ESCD_M2
;R96 ;		mov	di,0A000h               ;A000h for ESCD M2
;R96 ;endif	;ESCD_M2
;R96 ;R78cstart
;R96 ifdef	ESCD_M2
;R96 	     	mov    di,0A000h               ;A000h for ESCD M2
;R96 ifdef		Flash_4K_Unit
;R96 	     	mov    di,0A000h               ;A000h for ESCD M2
;R96 elseifdef	Flash_16K_Unit
;R96 	     	mov    di,08000h               ;A000h for ESCD M2
;R96 elseifdef	Flash_16K_8K_8K_Unit
;R96 	     	mov    di,0000h               ;A000h for ESCD M2
;R96 elseifdef	Flash1M_16K_8K_8K_Unit			;R18
;R96 	     	mov    di,08000h               ;A000h for ESCD M2
;R96 endif
;R96 endif	;ESCD_M2
;R96 ;R78cend
;R96 		mov     cx,01h	         	;read ROM F0000:FFFFF
;R96 ;R78d;;R78cstart
;R96 ;R78d;ifdef	Flash_16K_8K_8K_Unit
;R96 ;R78d;		push	ebp
;R96 ;R78d;	      	movzx	ebp, sp
;R96 ;R78d;	     	sub	sp,20 ;DEFAULT_STACK+PARA_SIZE
;R96 ;R78d;              	mov	bPnpModeFlag,CMOS_FLASH_R_W  ;CMOS_FLASH_R_W is High
;R96 ;R78d;endif  ;Flash_16K_8K_8K_Unit
;R96 ;R78d;;R78cend
;R96 ;R78d;		F000_CALL	Flash_Read	;TO  DRAM 80000:8FFFF 
;R96 ;R78d;
;R96 ;R78d;;R78cstart
;R96 ;R78d;ifdef	Flash_16K_8K_8K_Unit
;R96 ;R78d;	      	add	sp,20 ; DEFAULT_STACK+PARA_SIZE
;R96 ;R78d;              	and	bPnpModeFlag,Not CMOS_FLASH_R_W  ;CMOS_FLASH_R_W is High
;R96 ;R78d;		pop	ebp ;R78c
;R96 ;R78d;endif  ;Flash_16K_8K_8K_Unit
;R96 ;R78d;;R78cend
;R96 
;R96 		push    ax			 ;R78d;
;R96 		mov     al,0ah			 ;R78d;
;R96 		call    CMOS_FLASHROM_READ_WRITE ;R78d;
;R96     		pop     ax			 ;R78d;
;R96 
;R96 Search_ROM_CMOS_CHECK	ENDP
;R96 ;[]===========================================================[]
;R96 ;                 CMOS_FLASHROM_READ_WRITE 
;R96 ;Input  : AL=0AH READ FLASHROM   / AL=0A0H WRITE FLASHROM
;R96 ;Output : None
;R96 ;[]===========================================================[]
;R96 		PUBLIC  CMOS_FLASHROM_READ_WRITE
;R96 CMOS_FLASHROM_READ_WRITE   proc	near
;R96 
;R96 ifdef	Flash_16K_8K_8K_Unit
;R96 		push	ebp
;R96 	       	movzx	ebp, sp
;R96 	       	sub	sp,20 ;DEFAULT_STACK+PARA_SIZE
;R96                	mov	bPnpModeFlag,CMOS_FLASH_R_W  ;CMOS_FLASH_R_W is High
;R96 endif  ;Flash_16K_8K_8K_Unit
;R96                 cmp     al,0ah
;R96 		jne	short   write_flash
;R96 		F000_CALL	Flash_Read	;TO  DRAM 80000:8FFFF 
;R96 		jmp	short Flash_Read_Write_exit
;R96 write_flash:
;R96                 cmp     al,0a0h
;R96 		jne	short Flash_Read_Write_exit
;R96 		F000_CALL	Flash_Write
;R96 Flash_Read_Write_exit:
;R96 
;R96 ifdef	Flash_16K_8K_8K_Unit
;R96 	       	add	sp,20 ; DEFAULT_STACK+PARA_SIZE
;R96                	and	bPnpModeFlag,Not CMOS_FLASH_R_W  ;CMOS_FLASH_R_W is High
;R96 		pop	ebp;R78c
;R96 endif  ;Flash_16K_8K_8K_Unit
;R96 
;R96 CMOS_FLASHROM_READ_WRITE   endp
;R96 ;[]===========================================================[]
;R96 ;R77-end
;R96 endif  ;Support_CMOS_Backup_Data 
;R96 ;R78cendif  ; Flash_16K_8K_8K_Unit	  ;R78b
;R96 ;R78cifndef Flash_16K_8K_8K_Unit	  ;R78b
;R96 ifdef  Backup_CMOS_to_FLASH 	  ;R78
;R96 
;R96 ;[]===========================================================[]
;R96 Do_F6_S_CMOS	Proc	Near
;R96 	       	cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL ;R78c
;R96 	 	jne	short NOT_F6_Exit		  ;R78c
;R96 		cmp	LAST_KEY[bp],K_F6
;R96 		jne	short NOT_F6_Exit
;R96 		F000_call   Save_CMOS_TO_BIOS_Default
;R96 NOT_F6_Exit:
;R96 		ret
;R96 Do_F6_S_CMOS	Endp
;R96 
;R96 Do_F7_S_CMOS	Proc	Near
;R96 	       	cmp	byte ptr CUR_PAGE[bp],PAGE_KERNAL ;R78c
;R96 	 	jne	short NOT_F7_Exit		  ;R78c
;R96 		cmp	LAST_KEY[bp],K_F7
;R96 		jne	short NOT_F7_Exit
;R96 		F000_call   Load_CMOS_From_BIOS_Default	
;R96 NOT_F7_Exit:
;R96 		ret
;R96 Do_F7_S_CMOS	Endp
;R96 endif	;Backup_CMOS_to_FLASH
;R96 ;R78cendif   ; Flash_16K_8K_8K_Unit	  ;R78b
;R96 ;R75 end

;R86 - starts
;--------------------------------------------------------------------
;input	:	DX = 2 : Special Show request
;		DX = 0 : Special Do request
;		BX     : Item Offset
;
;Output :	NZ = Not HDD special 
;		ZF = HDD special already done
;--------------------------------------------------------------------
fPROC_HDD_Special_Do_Show	Proc	Far

		call	X_Check_If_LBA_Item		;LBA item?
		je	HDD_Special_Do_Show		;yes !

		push	dx
		call	X_Get_HDD_CMOS_Info		;HDD item(cylinder, head..)?
		pop	dx
		jnc	HDD_Special_Do_Show		;NC = HDD items!
		or	sp, sp				;Set ZF=0 or NZ
		ret

	HDD_Special_Do_Show:

		cmp	dx, 2				;special show?
		mov	dx, offset X_Show_HDD
		je	Invoke_HDD_Special_Do_Show	;yes, all HDD special SHOW
							;are directed to SHOW_HDD
		mov	dx, offset X_Do_LBA
		call	X_Check_If_LBA_Item		;LBA item?
		je	Invoke_HDD_Special_Do_Show	;yes!

		mov	dx, offset X_Do_HDD
		call	X_Check_If_HDD_Type_Item	;HDD type item?
		je	Invoke_HDD_Special_Do_Show	;yes!

		mov	dx, offset X_Update_User_Type

	Invoke_HDD_Special_Do_Show:

		call	dx

		mov	al, 0				;Clear ZF
		or	al, al				;preserve CF
		ret

fPROC_HDD_Special_Do_Show	Endp

		Public	X_Read_Item_Value
X_Read_Item_Value	Proc	Near
		F000_Call Read_Item_Value
		ret
X_Read_Item_Value	Endp

		Public	X_Write_Item_Value
X_Write_Item_Value	Proc	Near
		F000_Call Write_Item_Value
		ret
X_Write_Item_Value	Endp

		Public	X_Refresh_Menu1
X_Refresh_Menu1	Proc	Near
		F000_call Refresh_Menu1
		ret
X_Refresh_Menu1	Endp

		Public	X_Display_Whole_Item
X_Display_Whole_Item	Proc	Near
		F000_call Display_Whole_Item
		ret
X_Display_Whole_Item	Endp

		Public	X_Move_Cursor
X_Move_Cursor	Proc	Near
		F000_Call Move_Cursor
		ret
X_Move_Cursor	Endp

		Public	X_Vnormal
X_Vnormal	Proc	Near
		F000_Call VNormal
		ret
X_Vnormal	Endp

		Public	X_VReverse
X_VReverse	Proc	Near
		F000_Call VReverse
		ret
X_VReverse	Endp

		Public	X_Disp_ItemTitle
X_Disp_ItemTitle	Proc	Near
		F000_call Disp_ItemTitle
		ret
X_Disp_ItemTitle	Endp

		Public	X_Disp_ItemVar
X_Disp_ItemVar	Proc	Near
		F000_Call Disp_ItemVar
		ret
X_Disp_ItemVar	Endp

		Public	X_Get_Itemstat_AX
X_Get_Itemstat_AX	Proc	Near
		F000_Call Get_Itemstat_AX
		ret
X_Get_Itemstat_AX	Endp

		Public	X_Set_Itemstat_AX
X_Set_Itemstat_AX	Proc	Near
		F000_Call Set_Itemstat_AX
		ret
X_Set_Itemstat_AX	Endp
;R86 - ends

XCODE		ENDS
;R70 - ends


		END
