;	[]===========================================================[]
;
;	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
;----------------------------------------------------------------------------
;R118	02/24/99 VIN	Added codes for acpi s3 support	for desktop power off
;			Saving HDD_PIO_MODE & ULTRA_DMA_MODE			
;R115B	11/10/98 AVN	Fixed set HDD standby timer fail.
;R117	11/03/98 KVN	Patch Hdd set large mode can't do S2D
;R116	10/22/98 TNY	Add PMRAM:SuspendMaskIRQ to mask some PCI IRQ to fix 
;			some driver's bug cause suspend failed.
;R115A	09/29/98 RAY	1. R115 cannot be applied to MediaGX
;			2. VSA will take care of the HDD timer, thus we can
;			   skip all those HDD timer related codes for MediaGX
;R115	09/29/98 RAY	Moved the "Set_HDD_Standby_Timer" from PMKERNAL.ASM
;			to APM.ASM. Inside function 08h & function 0Dh ,
;			invode this routine to disable/enable HDD timer.
;
;			Reason:
;			-------
;			New HCT Test required the BIOS to disable HDD
;			time-out if the following functions are being 
;			called:
;
;			 - "PM Disabled"(Function 08)
;			 - "Secondary storage PM Disabled (Function 0Dh)
;
;R114	08/19/98 RAY	If the VGA used is C&T 6900, do not touch V/H SYNC for
;			DISABLE_CRT
;
;R113	06/17/98 RAY	Support device power management for Function 0Dh & 0Fh
;
;			1. Invalidate variable OPTION_ROM_ID in PM_RAM.INC
;			2. Define DEVICE_PM_STATUS in the same location to
;			   store the device PM status
;
;R112	05/22/98 RAX	Move VSA save to disk function HDD space check code
;			to here and alwayse check.
;R111A	04/07/98 KVN	Show PM_RAM size in compiler stage if over to 0FE000h
;R111	03/30/98 KVN	Added PM_RAM size override to 0FE000h error message
;			in compiler stage. That fixed some utility (PCDR.EXE)
;			check 'AWARD' signature from 0FE000h to correctly.
;R105C	03/17/98 TNY	R105 causes Win98 APM fail ,so we add a option
;			"NEW_APM_REPORT_METHOD" to support R105. The default
;			option is old.
;R110A	03/11/98 DNL	Fixed coding mistake
;R110	03/10/98 DNL	Reduce ACPI S4/BIOS code size to save more space
;R105B	02/27/98 RCH	Fixed system hang up while execute PM_INIT for ALD
;			486 chipset. It need special switch 
;			OLD_APM_REPORT_METHOD
;R109	02/27/98 RAX	Added "ZV_CHECK_BEEPS" define for some customer reqire
;			Beeps can be re-define.
;R108	02/26/98 JDN	Fixed OS/2 mouse driver will disable G_RAM COM port
;			status.	  				
;R107	02/25/98 DNL	Added ACPI S4/BIOS support
;R105A	02/18/98 RAY	Some people do not want the feature of R105, so add
;			BIOS.CFG switch to skip R105 which is:
;			"ALWAYS_ENABLE_POWER_MANAGEMENT"
;R106	02/04/98 DNL	Added STD partition ID 84h support for APM 1.2 spec
;R105	02/03/98 RAY	To let Win95 Shutdown-->PowerOff functionality
;			still exist if PM is disabled in CMOS Setup.
;R104	12/03/97 JKY	Add "No_0V_SPACE_NO_BEEP" definition for customer 
;			special	request.
;R99A	11/25/97 JKY	Added FAT32 volume partition-type acknowledge code.
;R103	11/07/97 RAY	The routines in CT_TABLE.ASM has been moved to 
;			XGROUP
;R102	10/27/97 KGN	move defin LCD_CRT_OPTION to common.equ
;R101	09/18/97 DNL	Fixed bug of system reset while resume from 0v suspend
;R100	09/03/97 DNL	Fix Onboard vga conflict with add vga card problem
;R99	08/25/97 DNL	Added FAT32 file support
;R76	08/01/97 JKY	Fixed mistake
;R75	07/17/97 DNL	Fixed system halt while HDD's partition is not FAT format
;R74	07/04/97 KVN	Fixed 0V suspend HDD connect to any channel not only
;			for primary master but still only support first HDD
;R73A	06/10/97 DNL	Fixed coding mistake
;R73	06/06/97 DNL	Added code to support onboard DRAM above 64M for STD
;R14	03/20/97 DNL	Fix when DRAM size above 64M , get Extend DRAM size 
;	05/30/97 RCH	Clean up revision comment for readability, The old
;			file backuped as pmkernal.530
;R72	05/30/97 RCH	Report PM enabled for APM OS in order to turn power
;			off for ATX form factor even the power management
;			is disable by user in CMOS setup. Note : It is 
;			optional.
;R70A	05/15/97 RAX	Chang lable for 16-32 bit code merge
;R71	05/07/97 RAX	Add code for NEW_VGA_KERNEL support & patch system
;			hang in SMI call int 10h
;R69A	05/01/97 LAW	Remove USB Keyboard Patch code
;R70	04/29/97 RAX	Add code to move SMBus DEV-ID table for support customer
;			OEM SMBUS INT15 interface
;R69	04/24/97 LAW	Patch usb keyboard enable but pm disable run WIN95 reboot
;			or hang
;R68	04/11/97 RAX	Add routine for new Notebook BIOS function support :
;			runtime switch PM setting -> Disable, Min save, 
;			Max save,or USER define
;			Usage:
;			current PM saving method store in PM_RAM:[PM_Save_Method]
;			call "Get_PMITEM_Value" to get item value in which method
;R67	03/07/97 DNL	Modify for future ues
;R66	01/27/97 DNL	Added switch Special_Save_VGA_status to support special 
;			customer
;R65	11/11/96 DNL	Added Zero-volt suspend function for desktop system
;R64	11/01/96 DNL	Added "NEW_SUPERVGA_KERNEL" definition to support
;			notebook VGA chips
;R63	10/17/96 DNL	Added "E000_SMI_SUPPORT" definition to save F-segment 
;R62	10/14/96 DNL	Added no CRT auto detection support
;R61	10/11/96 DNL	Added LCD only model support
;R60	10/01/96 DNL	Support zero-volt suspend function new structure
;R59	09/30/96 DNL	Added 4M Video RAM support
;R58	09/23/96 DNL	Added realtime status display for 0V suspend/resume
;R57	09/12/96 RAX	Added codes to warn user no 0V-	file or partition
;R56	09/06/96 DNL	Added codes for Notebook Power Management.
;R55A	08/15/96 RCH	Fixed error coding of R55
;R55	08/13/96 DNL	Modify codes for Notebook Power Management
;R49C	08/13/96 DNL	Fixed coding mistake
;R54	07/26/96 DNL	Added codes for customer special request
;R53	07/24/96 KVN	Remove "Set_HDD_Standby_Timer" subrotine code from AHDSK.ASM
;			for reduce 0F0000h runtime code size
;R52A	06/04/96 DNL	Added C&T 655XX LCD controller support
;R52	05/10/96 DNL	Save INT10 vector table for more application
;R49B	05/03/96 DNL	Fixed coding mistake
;R51	04/24/96 DNL	Modify codes for Notebook Power Management
;R49A	04/11/96 DNL	Added auto-detect display type support
;R50	04/09/96 DNL	Fix bug	of system halt when only SCSI HDD installed
;R49	04/02/96 DNL	Added C&T,Cirrus LCD controller support
;R48	03/27/96 DNL	Fixed bug of system hlt while HDD was not partitioned
;			or not formated.
;R47A	03/20/96 DNL	Fixed coding mistake
;R47	03/09/96 RAY	When global PM is disable, still enable APM to let
;			WIN95 & OS/2 successfully install APM
;R46	02/12/96 DNL	Fixed bug of system hang while no HDD installed
;R45	02/01/96 DNL	Fixed coding mistake
;R44	01/25/96 DNL	Added codes for Notebook Power Management.
;R43	01/22/96 DNL	Fixed coding mistake
;R42A	01/09/96 DNL	Added suspend to file for Notebook Power Management.
;R42	01/03/96 DNL	Added suspend to file for Notebook Power Management.
;R41	12/20/95 DNL	Added codes for Notebook Power Management.
;R40	11/22/95 HTR	Point DS to F000 Segment in PM_Init
;R39A	09/21/95 KVN	Fixed R39 code bug
;R39	09/19/95 KVN	Fixed Quantum 540AT HDD failure
;R38	09/18/95 DNL	Added codes for Notebook Power Management.
;R37	09/15/95 DNL	Added codes for Notebook Power Management.
;R36	09/09/95 DNL	Fixed coding mistake
;R35	08/24/94 KVN	Remove EPA and award logo to fpinstal.asm for reduse
;			E8000h code size
;R34	08/22/95 DNL	Kill duplicate codes
;R33	06/13/95 KVN	Reduce Post_func_call and F000_call code size
;R32	03/16/95 BEN	Added codes for Notebook Power Management.
;R28	02/24/95 RCH	Tseng VGA scan failed due to error data segment assign
;R27	01/20/95 KVN	Fixed Drive 2 not to be set timer when drive 1 absent
;R25	12/08/94 BEN	Fixed for when CRT control using DPMS but the VGA card
;			did not support DPMS then we do Blank CRT only, don't
;			use turn off H/V sync.
;R24	11/14/94 KVN	Reset HDD when set HDD timer failure
;R23	10/28/94 DNL	Add "ALLOW_SETUP_FROM_DOS" definition to save some
;			APM flags when calling setup under DOS
;R22	10/14/94 RCH	Added IRQ 10 for Non-S CPU power management
;R21	10/05/94 BEN	Change 'ifdef DPMS_STANDARD' to 'ifndef	None_DPMS_STANDARD'.
;R20	09/29/94 BEN	Added DPMS string checking instead of checking DPMS
;			vector. This avoid checking error in protected mode
;			or V86 mode.
;R19	09/27/94 RAY	Somebody always want to set the second IDE channel
;			power down timer
;R18	09/02/94 KVN	Support 4 IDE sleep mode
;R17	08/10/94 BEN	Support DPMS.
;R12A	07/12/94 KVN	Fixed up ZSI HDD boot failure.
;R16	06/23/94 KVN	Added 'NO_EPA_LOGO' support don't want show EPA logo
;R15	03/11/93 DNL	Don't set HDD standby timer if no IDE HDD present
;R14	03/10/94 RAY	Add IFDEF for APM_INIT
;R13	02/23/94 RAY	Add Hook:Ct_Check_Green_VGA to ask setup if VGA card's
;			V/H SYNC signals could be turned off or not!
;R12	01/24/94 KVN	Fixed up wait some time when is reading after set HDD
;			timer.
;R11	01/13/94 KVN	Skip TSENG-LABS card disable H-SYNC because it can't
;			screen on when change VGA mode.
;R10	12/10/93 KVN	Skip set HDD drive 1 standby timer if HDD only one drive.
;R09	12/10/93 KVN	Disabled HDD standby mode when PM is disabled.
;R08	11/22/93 RAY	Do not check POST flag during PM_INIT
;R07	11/17/93 RCH	Save APM_STATUS byte when calling setup under DOS
;R03A	11/09/93 RAY	Do not check VGA logo for 'Tseng' when not in POST
;			because we do not know the VGA segment
;R01A	11/05/93 RAY	PM_Option_Check spec. was changed to return a CARRY
;			FLAG which indicates whether global PM should be
;			enabled or not! If CY, call Ct_Global_PM_Disable
;			in PMU.ASM
;R06	11/05/93 RAY	Move PM_Option_Check to PMU.ASM as a OEM dependent
;			subroutine.
;R04	10/29/93 KVN	modify HDD power down for 2 HDDs
;R03	10/29/93 KVN	Scan Tseng's VGA for En/Dis CRT
;R02	10/28/93 RAY	Clear_PM_RAM becomes a external procedures in PMU.ASM
;R01	10/23/93 RCH	Don't initiate power management if the setup value is
;			disable

.386p
		PAGE	56,132
		TITLE	CHIPSET  -- 386/486 EISA/ISA ROM/BIOS

		INCLUDE	BIOS.CFG
		INCLUDE	COMMON.EQU
		INCLUDE	COMMON.MAC
		INCLUDE	POST.MAC
		INCLUDE	BSETUP.INC
		include	CMOS.EQU
A8259		=	20H			; first 8259
B8259		=	0A0H			; second (slave) 8259

END_OF_INT	=	20H			; end of interrupt code

IFDEF	PM_SUPPORT
;R103		extrn	PRG_CHIPSET:near		;CT_TABLE.ASM
;R103		extrn	AUTO_PRG_PM:near		;CT_TABLE.ASM
		extrn	fProc_Auto_Prg_PM:Far		;R103
		extrn	fProc_Prg_Chipset:Far		;R103

		extrn	A20_ON:near			;R101
		extrn	F000_GetItem_Value:near		
		extrn	F000_Get_Cmos:near		
		extrn	F000_Set_Cmos:near		
		extrn	PM_CONFIG_BYTE:BYTE		;ATORGS.ASM
		extrn	Check_In_Post:near		;ATORGS.ASM 

		extrn	Get_PMU:near			;PMU.ASM
		extrn	Set_PMU:near			;PMU.ASM
		extrn	Ct_Early_PM_Init:near		;PMU.ASM
		extrn	Ct_PM_Init:near			;PMU.ASM
		extrn	Ct_LCD_Init:near		;PMU.ASM		;Program LCD power down
		extrn	HDD_Standby_Offset:near		;PMU.ASM
		extrn	Get_PM_RAM_Seg:near		;PMU.ASM
		extrn	Clear_PM_RAM:near		;PMU.ASM 
		extrn	Open_PM_RAM:near		;PMU.ASM
		extrn	Close_PM_RAM:near		;PMU.ASM
		extrn	Get_IRQ15_Offset:Near		;PMU.ASM
	ifdef	ADVANCE_POWER_MANAGEMENT	
		extrn	APM_Init:near			;APM.ASM
	endif	;ADVANCE_POWER_MANAGEMENT	
		extrn	PM_Option_Check:near		;PMU.ASM 
		extrn	Ct_Global_PM_Disable:near	;PMU.ASM 
		extrn	Ct_Check_Green_VGA:near		;PMU.ASM 
		extrn	Get_DPMS_Option:near
		extrn	Get_PM_IRQ:near

;R110 - start
if	STD_Function		EQ	1
;R110A 		extrn	check_S4_Resume:near
		EXTRN	Get_EXT_Memory:Near
		EXTRN	HDD_Transfer:Near
		EXTRN	Check_0V_Resume:Near
		EXTRN	BIOS_INFORM_STR:NEAR
		EXTRN	F000_Display_String:NEAR
		EXTRN	Software_SMI:NEAR
endif	;STD_Function		EQ	1
;R110 - end
;R110A - start
ifdef	ACPI_SUPPORT
ifdef	S4_SUPPORT
	extrn	check_S4_Resume:near
endif	;S4_SUPPORT
endif	;ACPI_SUPPORT
;R110A - end
;Equation for compling BIOS
	DESKTOP_POWER_MANAGEMENT		= 1	;for desktop
ifdef	Notebook_Power_Management
	ifndef	DESKTOP_SYSTEM					
		DESKTOP_POWER_MANAGEMENT	= 2	;for notebook
	endif	;DESKTOP_SYSTEM					
;R110 ;R107 - start
;R110 	ifdef	ACPI_SUPPORT
;R110 	ifdef	S4_SUPPORT
;R110 		extrn	check_S4_Resume:near
;R110 	endif	;S4_SUPPORT
;R110 	endif	;ACPI_SUPPORT
;R110 ;R107 - end
;R110		EXTRN	Get_EXT_Memory:Near
;R110		EXTRN	HDD_Transfer:Near
;R110		EXTRN	Check_0V_Resume:Near
;R110		EXTRN	BIOS_INFORM_STR:NEAR
;R110		EXTRN	F000_Display_String:NEAR
;R110		EXTRN	Software_SMI:NEAR
		EXTRN	Ct_Get_Suspend_Mode:near	
ifdef	NO_ZV_REALTIME_MESSAGE				
		EXTRN	ZV_Display_MSG:near
		EXTRN	Resume_ZV_MSG:near
endif	;NO_ZV_REALTIME_MESSAGE				
;R102	ifndef	NO_LCD_DISPLAY				
;R102		LCD_CRT_OPTION		EQU	1	
;R102	endif	;NO_LCD_DISPLAY				
	ifndef	NO_BATTERY_SYSTEM			
		BATTERY_SYSTEM		EQU	1	
	endif	;NO_BATTERY_SYSTEM			
	ifdef	Special_Save_VGA_status			
		extrn	Ct_Special_Save_VGA:near	
	endif	;Special_Save_VGA_status		
endif	;Notebook_Power_Management
	ifdef	LCD_CRT_OPTION				
		extrn	Disable_CRT:near		
		extrn	Enable_CRT:near			
		extrn	LCD_Backlight_ON:near		
		extrn	LCD_Backlight_Off:near		
		extrn	Disp_Mode_Item:near		
	ifdef	CHIP_65545				
		CHIP_655XX		EQU	1	
	endif	;CHIP_65545				
	endif	;LCD_CRT_OPTION				
	ifdef	BATTERY_SYSTEM				
		Extrn	Get_BATTERY_UNIT:NEAR		
	endif	;BATTERY_SYSTEM				

ifdef	No_0V_SPACE_WARNING
		extrn	SND_SPKR:near			;ATORGS.ASM
		extrn	Suspend_Option_Item:near	;PFEATURE.ASM
endif	;No_0V_SPACE_WARNING

ifdef	NEW_SUPERVGA_KERNEL
;R114	ifdef	ONBOARD_PCI_VGA					;R100
;R114		extrn	PCI_VGA_INFO:near			;R100
;R114	endif	;ONBOARD_PCI_VGA				;R100
		extrn	Alternate_INT10_for_SMI:near
endif	;NEW_SUPERVGA_KERNEL

		extrn	PCI_VGA_INFO:ABS			;R114

;R112 start
ifdef	VSA_VGA
ifdef	S2D_SUPPORT
 		extrn	ExtMem128Mb:near
endif	;S2D_SUPPORT
endif	;VSA_VGA
;R112 end
ENDIF	;PM_SUPPORT


G_RAM		SEGMENT	USE16 AT 0

		ORG	04H*4
		INCLUDE	SEG_0.INC

		ORG	400H
		INCLUDE	G_RAM.INC

G_RAM		ENDS


IFDEF	PM_SUPPORT

;R110 ifdef	Notebook_Power_Management
if	STD_Function		EQ	1		;R110
SM_RAM		SEGMENT	USE16 AT 0
		INCLUDE	SM_RAM.INC
SM_RAM		ENDS
;R110 endif	;Notebook_Power_Management
Endif	;STD_Function		EQ	1		;R110

;R111A start
Print_PM_RAM_Size	Macro	PM_RAM_SIZE
	%OUT ERROR, The PM_RAM_LEN(size is PM_RAM_SIZE) is too big and override to 0FE000h
	ENDM
;R111A end

PM_RAM		SEGMENT	USE16 AT 0 	; define PM RAM segment

		ORG	0
PM_RAM_START	LABEL	BYTE				;R111
		INCLUDE	PM_RAM.INC
;R111 start
		include 		CT_PMRAM.INC
;R111A if (($-Offset PM_RAM:PM_RAM_START) GT (0fe00h-PM_RAM_SEGMENT) shl 4)
PM_RAM_SIZE	=	$ - Offset PM_RAM:PM_RAM_START	;R111A
if (PM_RAM_SIZE GT (0fe00h-PM_RAM_SEGMENT) shl 4)	;R111A
	if2
;R111A 	%OUT ERROR, The PM_RAM_LEN is too big and override to 0FE000h
	Print_PM_RAM_Size	%PM_RAM_SIZE		;R111A
	endif

	.ERR
endif
;R111 end

PM_RAM		ENDS
ENDIF	;PM_SUPPORT

		extrn	F000_call_proc:near	
		extrn	F000_VECT:near		
		extrn	RET_E_SEG:near		

		extrn	PM_Option_Item:near		;R105

if	DESKTOP_Power_Management	EQ	2	;for notebook
ifndef	No_HotKey_Set_PM
	extrn	PM_Option_Item:near		;PFEATURE.ASM
	extrn	PM_Auto_Table:near		;PFEATURE.ASM
	extrn	PM_FEATURE_START:near		;PFEATURE.ASM
	extrn	PM_Feature_END:near		;PFEATURE.ASM
	extrn	Read_Item_Value:near		;Setup.ASM
endif	;No_HotKey_Set_PM
endif	;DESKTOP_Power_Management	EQ	2

ifdef	SMBIOS_INTERFACE
		extrn	SMB_DEVICE_TABLE:near		;SMB.ASM
		extrn	SMB_DEVID_TABLE:near		;PMUPOST.ASM
		extrn	F000_Shadow_W:near		;CHIPPOST.ASM
		extrn	F000_Shadow_R:near		;CHIPPOST.ASM
endif	;SMBIOS_INTERFACE

ifndef	VSA_VGA						;R115A
		extrn	APM_HDD_Drive_Port:Byte		;R115
		extrn	APM_HDD_EXIST_Flag:Byte		;R115
		extrn	APM_HDD_TIMER_VALUE:Byte	;R115
		extrn	fPROC_Set_HDD_Standby_Timer:far	;R115
endif	;VSA_VGA					;R115A

EGROUP		GROUP	ECODE
ECODE		SEGMENT	USE16 PARA PUBLIC 'ECODE'
		ASSUME	CS:EGROUP,DS:EGROUP,ES:EGROUP

ifndef	PM_SUPPORT
		Public	PM_Init
PM_Init:
		ret
endif	;PM_SUPPORT

IFDEF	PM_SUPPORT

;[]==================================================================[]
;Procedure:	Early_PM_Init
;
;Function :	PM chip initialization early during POST (POST 9)
;
;Input    :	None
;
;Output   :	None
;
;[Note]	  :	Called from POST 9
;[]==================================================================[]
		Public	Early_PM_Init
Early_PM_Init	Proc	Near

ifdef	SMBIOS_INTERFACE
	call	Move_SMB_ID_TBL
endif	;SMBIOS_INTERFACE

ifdef	E000_SMI_SUPPORT				
		call	Ct_Early_PM_Init		
else	;E000_SMI_SUPPORT				
		F000_call	Ct_Early_PM_Init
endif	;E000_SMI_SUPPORT				
		clc
		ret
Early_PM_Init	Endp

;[]==================================================================[]
;Procedure:	PM_INIT
;
;Function :	To initialize all power management features including
;		the chipset's(if any) & APM
;
;Input    :	None
;
;Output   :	None
;
;[Note]	  :	Called from POST 79
;[]==================================================================[]
		Public	PM_Init
PM_Init		Proc	Near
		push	ds
		push	es
		push	fs
		pushad


		push	0F000h
		pop	ds
		call	F000_Get_PM_RAM_Seg
		mov	es,ax
		ASSUME	ES:PM_RAM
		call	F000_Open_PM_RAM

;R113 		xor	al,al
;R113 		cmp	word ptr es:[0],0AA55h
;R113 		jne	short No_Option_ROM
;R113 		or	al,1
;R113 No_Option_ROM:
;R113 		push	ax

ifdef	ALLOW_SETUP_FROM_DOS
		mov	bl,PM_RAM:[PM_CTRL_FLAG]
		push	bx
endif	;ALLOW_SETUP_FROM_DOS

		call	F000_Open_PM_RAM

ifdef	ALLOW_SETUP_FROM_DOS
		mov	cl,PM_RAM:[APM_STATUS]	;save APM status
		push	cx
endif	;ALLOW_SETUP_FROM_DOS

ifdef	E000_SMI_SUPPORT				
		call	Clear_PM_RAM			
else	;E000_SMI_SUPPORT				
		F000_call	Clear_PM_RAM
endif	;E000_SMI_SUPPORT				

ifdef	ALLOW_SETUP_FROM_DOS
		pop	cx
		test	cl,80h			;APM already connect?
		jz	short @F
		mov	PM_RAM:[APM_STATUS],cl	;restore APM status
@@:
		pop	bx

		test	bl,IS_TSENG
		jz	short @F
		mov	PM_RAM:[PM_CTRL_FLAG],bl
	@@:
endif	;ALLOW_SETUP_FROM_DOS

;R116 - start
		call	BuildSuspendMaskIRQ
;R116 - end

;R113 		pop	ax
;R113 
;R113 		mov	PM_RAM:[OPTION_ROM_ID],0AA55h
;R113 		mov	PM_RAM:[OPTION_ROM_ID+2],40h
;R113 		mov	PM_RAM:[OPTION_ROM_EXIST],al

;R105if	DESKTOP_POWER_MANAGEMENT	EQ	1	;for desktop
;R105		F000_call	PM_Option_Check
;R105		jnc	short Enable_PM
;R105
;R105		xor	al,al		;disable hdd standby mode	
;R105		call	Set_HDD_Standby_Timer		
;R105		push	es						
;R105		mov	ax,G_RAM					
;R105		mov	es,ax						
;R105		and	byte ptr es:FDD_VERIFY_CMD_FLAG,not 0ch		
;R105		pop	es						
;R105	ifdef	E000_SMI_SUPPORT			
;R105		call	Ct_Global_PM_Disable		
;R105	else	;E000_SMI_SUPPORT			
;R105		F000_call	Ct_Global_PM_Disable
;R105	endif	;E000_SMI_SUPPORT			
;R105	ifdef	ADVANCE_POWER_MANAGEMENT		
;R105	 ifdef	PM_DISABLE_POWER_OFF_FOR_ATX		
;R105		mov	al,1	;report PM enabled	
;R105	 else;	PM_DISABLE_POWER_OFF_FOR_ATX		
;R105		xor	al, al	;report PM disabled	
;R105	 endif;	PM_DISABLE_POWER_OFF_FOR_ATX		
;R105		F000_call	APM_Init		
;R105	endif	;ADVANCE_POWER_MANAGEMENT		
;R105		jmp	PM_Disable
;R105	Enable_PM:
;R105endif	;DESKTOP_POWER_MANAGEMENT	EQ	1	

;R105B -start
;R105Cifdef	OLD_APM_REPORT_METHOD		
ifndef	NEW_APM_REPORT_METHOD
if	DESKTOP_POWER_MANAGEMENT	EQ	1	;for desktop
ifndef	VSA_VGA							;R115b
		call	Prepare_Variable_For_HDD_Timer		;R115b
endif	;VSA_VGA						;R115b
		F000_call	PM_Option_Check
		jnc	short Enable_PM

;R115		xor	al,al		;disable hdd standby mode	
;R115		call	Set_HDD_Standby_Timer		
ifndef	VSA_VGA							;R115A
;R115b		call	Prepare_Variable_For_HDD_Timer		;R115
		xor	al, al					;R115
		call	far ptr fPROC_Set_HDD_Standby_Timer	;R115
endif	;VSA_VGA						;R115A
		push	es						
		mov	ax,G_RAM					
		mov	es,ax						
		and	byte ptr es:FDD_VERIFY_CMD_FLAG,not 0ch		
		pop	es						
	ifdef	E000_SMI_SUPPORT			
		call	Ct_Global_PM_Disable		
	else	;E000_SMI_SUPPORT			
		F000_call	Ct_Global_PM_Disable
	endif	;E000_SMI_SUPPORT			
	ifdef	ADVANCE_POWER_MANAGEMENT		
	 ifdef	PM_DISABLE_POWER_OFF_FOR_ATX		
		mov	al,1	;report PM enabled	
	 else;	PM_DISABLE_POWER_OFF_FOR_ATX		
		xor	al, al	;report PM disabled	
	 endif;	PM_DISABLE_POWER_OFF_FOR_ATX		
		F000_call	APM_Init		
	endif	;ADVANCE_POWER_MANAGEMENT		
		jmp	PM_Disable
	Enable_PM:
endif	;DESKTOP_POWER_MANAGEMENT	EQ	1	
;R105Cendif;	OLD_APM_REPORT_METHOD		
endif;	NEW_APM_REPORT_METHOD				;R105C
;R105B -end

		call	Scan_VGA_chipset

		test	PM_RAM:[PM_CTRL_FLAG],V_H_SYNC_ENABLE
		jz	short @F
		F000_call	Ct_Check_Green_VGA
		jnz	short @F
		and	PM_RAM:[PM_CTRL_FLAG],not V_H_SYNC_ENABLE
	@@:

;to let APPS think this area is a option ROM

		mov	di,2				;2=later PM_Init
;R103		F000_call	PRG_CHIPSET
		call	far ptr fProc_Prg_Chipset		;R103

;R103		F000_call	AUTO_PRG_PM
		call	far ptr fProc_Auto_Prg_PM		;R103

if	DESKTOP_Power_Management	EQ	2	;for notebook
ifndef	No_HotKey_Set_PM

		pushf
		F000_call	PM_Option_Check
		mov	byte ptr PM_RAM:[PM_Method],al
		popf
		call	PM_Save_USER_Define

endif	;No_HotKey_Set_PM
endif	;DESKTOP_Power_Management	EQ	2

		call	Set_HDD_Timer			;program HDD standby timer	
	ifdef	E000_SMI_SUPPORT			
		call	Ct_LCD_Init			
		call	Ct_PM_Init			
	else	;E000_SMI_SUPPORT			
		F000_call	Ct_LCD_Init
		F000_call	Ct_PM_Init
	endif	;E000_SMI_SUPPORT			

	IFDEF	NoteBook_Power_Management				
		call	Notebook_Init					
	ENDIF	;NoteBook_Power_Management				

	ifndef	None_DPMS_STANDARD		
		call	DPMS_Init		
	endif	;None_DPMS_STANDARD		

	ifdef	ADVANCE_POWER_MANAGEMENT	
		mov	al, 1			
		F000_call	APM_Init
	ifdef	BATTERY_SYSTEM			
	ifdef	E000_SMI_SUPPORT		
		Call   Get_BATTERY_UNIT		
	else	;E000_SMI_SUPPORT		
		F000_Call   Get_BATTERY_UNIT	
	endif	;E000_SMI_SUPPORT		
		mov	PM_RAM:BATTERY_UNIT,al	
	endif	;BATTERY_SYSTEM			
	endif	;ADVANCE_POWER_MANAGEMENT	

		F000_call	Get_PM_IRQ
		jc	short PM_Init_Exit		;do not serve IRQ
		cmp	al,1				;PM using IRQ 15
		jne	short PM_Not_IRQ15		;no...

		F000_call	Get_IRQ15_Offset
		jc	short PM_Not_IRQ15		;do not serve IRQ

ifdef	NON_S_USE_IRQ10
PM_IRQ_VECT	EQU	INT72			;use IRQ 10 for PM
PM_IRQ_MASK	EQU	11111011b		;use IRQ 10 for PM
else;	NON_S_USE_IRQ10
PM_IRQ_VECT	EQU	INT77			;use IRQ 15 for PM
PM_IRQ_MASK	EQU	01111111b		;use IRQ 15 for PM
endif;	NON_S_USE_IRQ10

;R76		mov	ax,G_RAM				
;R76		mov	ds,ax					

		mov	dx,G_RAM	;R76
		mov	ds,dx		;R76
		ASSUME	DS:G_RAM				

		mov	word ptr G_RAM:[PM_IRQ_VECT],si
		mov	word ptr G_RAM:[PM_IRQ_VECT+2],ax

		in	al,B8259+1		;Unmask IRQ
		IODELAY
		and	al,PM_IRQ_MASK		;enable IRQ for PM
		out	B8259+1,al

PM_Not_IRQ15:
PM_Init_Exit:

;--------------------------------------------------------------------
PM_Disable:						
;R105Cifndef	OLD_APM_REPORT_METHOD		;R105B
ifdef	NEW_APM_REPORT_METHOD			;R105C
;R105 - starts
if	DESKTOP_POWER_MANAGEMENT	EQ	1	;for desktop
;R105Cifndef	ALWAYS_ENABLE_POWER_MANAGEMENT				;R105A
ifndef	VSA_VGA							;R115b
		call	Prepare_Variable_For_HDD_Timer		;R115b
endif	;VSA_VGA						;R115b
		mov	si,offset PM_Option_Item		
		call	F000_GetItem_Value			
		cmp	al,1
		jne	short Enable_PM


;R115		xor	al,al		;disable hdd standby mode	
;R115		call	Set_HDD_Standby_Timer		
ifndef	VSA_VGA							;R115A
;R115b		call	Prepare_Variable_For_HDD_Timer		;R115
		xor	al, al					;R115
		call	far ptr fPROC_Set_HDD_Standby_Timer	;R115
endif	;VSA_VGA						;R115A
		push	ds						
		mov	ax,G_RAM					
		mov	ds,ax	    
		mov	si, offset FDD_VERIFY_CMD_FLAG
		and	byte ptr ds:[si], not 0ch
		pop	ds						

		or	PM_RAM:[APM_STATUS], SETUP_PM_DISABLED

	Enable_PM:
;R105Cendif	;ALWAYS_ENABLE_POWER_MANAGEMENT				;R105A
endif	;DESKTOP_POWER_MANAGEMENT	EQ	1	
;R105 - ends
;R105Cendif;	OLD_APM_REPORT_METHOD		;R105B
endif;	NEW_APM_REPORT_METHOD			;R105C

 		push	ds				
		mov	ax,G_RAM			
		mov	ds,ax				
		assume	ds:G_RAM			
		mov	eax,G_RAM:INT10			

ifdef	NEW_SUPERVGA_KERNEL
	ifdef	ONBOARD_PCI_VGA					;R100
		cmp	byte ptr PCI_VGA_INFO[bp],(ONBOARD_PCI_VGA) SHL 3 ;R100
		jne	short @f				;R100
	endif	;ONBOARD_PCI_VGA				;R100
		call	Alternate_INT10_for_SMI
@@:								;R100
 else	;NEW_SUPERVGA_KERNEL

 ifdef	CHIP_655XX 					
		ror	eax,16				
		mov	ds,ax				
		shl	eax,16				
		mov	ax,ds:[8bh]  	;Get Alternate INT 10h entry point
 endif	;CHIP_655XX					

 ifdef	NeoMagic_2093AB
		ror	eax,16
		mov	ds,ax
		shl	eax,16
		mov	ax,ds:[0Eh]  	;Get Alternate INT 10h entry point
 endif	;NeoMagic_2093AB
endif	;NEW_SUPERVGA_KERNEL

		mov	PM_RAM:INT10_Save,eax		
		pop	ds				

		mov	al,PM_RAM:[OPTION_ROM_EXIST]	;tell if option ROM in this area or not
		call	F000_Close_PM_RAM	

;R112 start
ifdef	VSA_VGA
ifdef	S2D_SUPPORT
		call	Reserve_ZV_HDD
endif	;S2D_SUPPORT
endif	;VSA_VGA
;R112 end

;R110 IFDEF	NoteBook_Power_Management				
if	STD_Function		EQ	1		;R110
		call	Reserve_ZV_HDD				
	ifdef	Special_Save_VGA_status				
		Call	Ct_Special_Save_VGA			
	endif	;Special_Save_VGA_status			
;R110 ENDIF	;NoteBook_Power_Management				
endif	;STD_Function		EQ	1		;R110

		popad
		pop	fs
		pop	es
		pop	ds
		ret
PM_Init		Endp

;R116 - start
BuildSuspendMaskIRQ	proc	near
ifdef	AGP_SLOTID
		call	MaskAGPIRQ
endif;	AGP_SLOTID
	   	ret
BuildSuspendMaskIRQ	endp

ifdef	AGP_SLOTID
MaskAGPIRQ	proc	near

		xor	bh,bh			
		mov	bl,AGP_SLOTID
		mov	di, 19H			
		mov	ax, 0b108H		
		int	1AH			

		mov	bh,cl			;get AGP device bus no.
		xor	bl,bl			;AGP must be dev=0 func=0
		mov	di, 3cH			;IRQ register
		mov	ax, 0b108H		;PCI byte read in CL
		int	1AH			;PCI BIOS interface

		cmp	cl,0ffh
		je	short BadAGPDev
		cmp	cl,0
		je	short BadAGPDev
		mov	ax,1
		shl	ax,cl
		or	word ptr es:[SuspendMaskIRQ],ax
BadAGPDev:
	   	ret
MaskAGPIRQ	endp
endif;	AGP_SLOTID
;R116 - end

;[]==================================================================[]
;Procedure Name: Scan_VGA_chipset
;
;Saves    :	All but flags
;
;Input    :	ES = PM_RAM
;		DS = DGROUP
;
;Output   :	None
;[]==================================================================[]
CT_CTRL_Str	DB	'Tseng'
		ASSUME	ES:PM_RAM
		public	Scan_VGA_chipset
Scan_VGA_chipset	PROC	NEAR

		pusha
		push	ds
		push	es

		push	cs			
		pop	ds			

		xor	ax,ax			;segment 0
		mov	es,ax
		mov	ax,es:[42h]		;VGA source code (int 10h) segment.

		cmp	ax,0f000h		;is MONO?
		je	short Not_found		;Yes,jump
		mov	es,ax
		cld
		xor	di,di			;search target name start offset.
Found_loop:
		mov	cx,5			;get string length
		lea	si,CT_CTRL_Str
		rep	cmpsb
		jz	short Found_Str
		cmp	di,100h
		jb	short Found_loop
Not_found:
		mov	ah,V_H_SYNC_ENABLE	;not Tseng's VGA
		jmp	short Search_ret
Found_Str:
		mov	ah,IS_TSENG
Search_ret:
		pop	es
		and	PM_RAM:[PM_CTRL_FLAG],not (V_H_SYNC_ENABLE+IS_TSENG)
;R114 - starts
		pushad
		mov	bx, PCI_VGA_INFO[bp]	;bh = bus no. bl=dev+fun no
		xor	di, di			;di = register location
		mov	ax, 0B10Ah		;read dword
		int	1ah
		cmp	ecx, 00C0102Ch
		popad
		je	short No_VH_SYNC
;R114 - ends
		or	PM_RAM:[PM_CTRL_FLAG],ah

	No_VH_SYNC:					;R114

		pop	ds
		popa
		ret
Scan_VGA_chipset	ENDP

;[]========================================================================[]
;Procdure:	Set_HDD_Timer
;
;Function:	Set the HDD power down timer
;
;Input   :	None
;
;Output	 :	None
;[]========================================================================[]
		public	Set_HDD_Timer
Set_HDD_Timer	Proc	Near

;R115		F000_call	HDD_Standby_Offset
;R115		jc	short @F
;R115		call	F000_GetItem_Value
;R115		call	Set_HDD_Standby_Timer		
;R115@@:
ifndef	VSA_VGA							;R115A
		mov	al, 1					;R115
		call	far ptr fPROC_Set_HDD_Standby_Timer	;R115
endif	;VSA_VGA						;R115A
		ret

Set_HDD_Timer	Endp

ifndef	None_DPMS_STANDARD		
;[]========================================================================[]
;Procdure:	DPMS_Init
;
;Function:	Initial Display Power Management Signaling (DPMS).
;
;Input   :	None
;
;Output	 :	None
;[]========================================================================[]
		ASSUME	ES:PM_RAM
DPMS_Init	proc	near

	; Init DPMS setup option

		F000_call	Get_DPMS_Option
;----------------------------------------------------------------------------
;Output   :	AL = 0  DPMS not support
;		(CRT sleep disable or Controll by H/V sync & Blanking)
;		   = 1  CRT sleep use DPMS STANDBY
;		   = 2	CRT sleep use DPMS SUSPEND
;		   = 3	CRT sleep use DPMS OFF
;		   = 4	CRT sleep use DPMS REDUCE ON (not support in v1.0)
;----------------------------------------------------------------------------
		or	al,al
		jz	short End_DPMS_Init
		dec	al
		mov	cl,al
		mov	al,1
		shl	al,cl
		mov	PM_RAM:DPMS_Request_State,al

		and	PM_RAM:[PM_CTRL_FLAG],not V_H_SYNC_ENABLE

	; Get VBE/PM Capability

		push	es
		mov	ax,4f10h	; VESA Extentsion & VBE/PM Service
		xor	bl,bl		; Report VBE/PM Capability (bl=0)
		xor	cx,cx		; Controller unit number (cx=00 primary)
		mov	es,cx		; ES:DI = 0000:0000
		xor	di,di		; Null pointer
		int	10h
		pop	es

		cmp	ax,004fh	; Is function call success ?
		jne	short End_DPMS_Init

	; Set DPMS label for checking right in protect mode & V86 mode.

		mov	dword ptr PM_RAM:DPMS_Label,'DPMS'	

	; Save VBE/PM capability

		mov	byte ptr PM_RAM:DPMS_Capability,bh

	; Save DPMS function call entry pointer (INT 10H)

End_DPMS_Init:
		ret

DPMS_Init	endp
endif	;None_DPMS_STANDARD			

;R110 - start
if	STD_Function		EQ	1
;[]========================================================================[]
;Procedure:	Notebook_Resume
;
;Function :	To check 0V suspend had been happend or not.
;		If it is 0V resume to display the message & to do resume.
;
;Input	  :	None
;
;Output   :	None
;
;Note	  :
;
;[]========================================================================[]
		Public	Notebook_Resume
Notebook_Resume	proc	near

		F000_call	Check_0V_Resume
		jz	short @F

		call	F000_Open_PM_RAM		
		call	F000_Get_PM_RAM_Seg		
		mov	es,ax
		ASSUME	ES:PM_RAM

		cmp	dword ptr PM_RAM:ZV_HDD_Sector,0
		je	short @F

ifdef	NO_ZV_REALTIME_MESSAGE			
	; To Show the message before resume

		mov	si,offset Resume_ZV_MSG
		F000_call	ZV_Display_MSG
endif	;NO_ZV_REALTIME_MESSAGE			

	; Generate a software SMI to resume

if	BIOS_SUPPORT_686				
		mov	al,P6_A20_CMOS NMI_OFF			
		Call	F000_Get_Cmos
		test	al,P6_A20_Status
		jz	short Not_A20_High
		F000_Call	A20_ON			
Not_A20_High:
endif	;BIOS_SUPPORT_686

		mov	PM_RAM:Software_SMI_Type,SMI_0V_Resume	
ifdef	ACPI_SUPPORT
ifdef	S4_SUPPORT
		F000_call	Check_S4_Resume
		jz	short Not_S4_Resume
		mov	PM_RAM:Software_SMI_Type,SMI_S4_Resume	
Not_S4_resume:
endif	;S4_SUPPORT
endif	;ACPI_SUPPORT

		F000_call	Software_SMI
		mov	PM_RAM:Software_SMI_Type,0		
		jmp	$
	@@:
		mov	al,0Fh NMI_OFF			
		mov	ah,0			; Clear 0V suspend flag
		call	F000_Set_CMOS			

		ret
Notebook_Resume	Endp

;[]========================================================================[]
;Procedure:	Reserve_ZV_HDD
;
;Function :	Routine to check 0V partition and reserve cylinders for
;		0V partition
;
;Input	  :	None
;
;Output   :	None
;
;Note	  :
;
;	The following is 0V suspend partition save location brief..
;
;	Sector 0	  : For ID sector.
;
;				Byte 0 - 23  : Chipset Name & Part No.(24 Bytes)
;					AA55AA55 = Skip reserve 0V partition.
;
;				Byte 24 - 25 : Suspend checksum.(2 Bytes)
;
;				Byte 26 - 29 : ID for ZVHDD.EXE.(4 Bytes)
;					AA55AA55 = 0V partition exist.
;
;				Byte 30 - 31 : Current HDD total cylinder.
;
;	Sector 1 - 64	  : For Save SMBASE. (32 KB)
;
;	Sector 65 - 2112  : For Save BASE Mmemory. (1024 KB)
;		            (640 KB DRAM & C0000 - FFFFF Shadow RAM )
;			    (Usually, we do not care A0000 - BFFFF shadow)
;
;	Sector 2113 - 6208: For Save VIDEO Mmemory. (2048KB)
;
;	Sector 6209 - Max : For Save EXT Mmemory.
;
;[]========================================================================[]
		PUBLIC	Reserve_ZV_HDD
Reserve_ZV_HDD	PROC	NEAR
		pushad
		push	ds
		push	es

		cli

		call	Get_EXT_Memory		
		shl	ecx,6				;1K block
		mov	ebx,ecx				;
		add	ebx,1024+4096			;Add base memory and video memory

		call	F000_Get_PM_RAM_Seg		
		mov	ds,ax
		call	F000_Open_PM_RAM	

		mov	ax,G_RAM
		mov	es,ax

		cmp	byte ptr HDD_EXIST_Flag[bp],0	
		je	short End_Reserve_HDD1		

		mov	cl,es:HDD_Drive_Port
		and	cl,3
		mov	ah,es:HDD_MODE_FLAG
		shr	ah,cl
		shr	ah,cl
		and	ah,3
		shl	ah,2
		or	ah,cl
		or	ds:[ZV_HDD_Scheme],ah

		mov	si,word ptr es:[DR0VECTOR]	; Get HDD table pointer.
		mov	ax,word ptr es:[DR0VECTOR+2]
		mov	es,ax

		mov	cl,es:[si+2]		; Max. Head   / cylinder.
		mov	ds:[Logical_Heads], cl	;R117 Get Hdd Logical heads
		mov	al,es:[si+0eh]		; Max. Sector / head.

		mov	ds:[Head_Sector],al	; Init Sectors per head

		mul	cl

		mov	ds:[Cylinder_Sector],ax	; Init Sectors per Cylinder
;R117 - start
		mov	al,es:[si+11]
		mov	ds:[Hdd_Head], al	;save Hdd phicial head number
;R117 - end
		Call	Ck_SUS_Partition
		jnc	short End_Reserve_HDD1		
		Call	Ck_SUS_FAT_File			
End_Reserve_HDD1:

	;;;Record G_RAM COMM port status
		push	ds
		push	G_RAM
		pop	ds
		mov	eax, dword ptr G_RAM:[COMM_PORT_ADDRS]
		pop	ds
		mov	dword ptr ds:[COMA_ADDRS], eax
		
;R118 - start
if	STR_Function	EQ	1
		mov	al,HDD_0_MODE[bp]	
		mov	bl,HDD_0_MODE[bp+1]	
		shl	bl,4
		or	al,bl
		mov	ah,HDD_0_MODE[bp+2] 
		mov	bl,HDD_0_MODE[bp+3]	
		shl	bl,4
		or	ah,bl
		mov	ds:[HDD_PIO_MODE],ax
ifdef	Ultra_DMA33_support 
		push	si
		xor	bx,bx
		xor	si,si
   next_drive: 	mov	al,HDD_0_UltraDMA[bp+si]  
		and	al,00000011b	
		mov	cx,si
		shl	cl,1
		shl	al,cl
		or	bl,al
		inc	si			
		cmp	si,4
		jb	Next_drive			
		mov	ds:[Ultra_Dma_Mode],bl
		pop	si
endif	;Ultra_DMA33_support
endif	;STR_Function	EQ	1
;R118 - end	 	

		call	F000_Close_PM_RAM	

	; Clear temp memory

		mov	ax,04000h
		mov	es,ax
		xor	eax,eax
		xor	di,di
		mov	cx,2000h			;clear 32K
		cld
		rep	stosd

		pop	es
		pop	ds
		popad

		RET
Reserve_ZV_HDD	ENDP

;[]========================================================================[]
;Procedure:	Ck_SUS_FAT_File
;
;Function :	Routine to check 0v-suspend is use FAT file or not
;
;Input	  :	None
;
;Output   :	CF = 1  not use FAT file
;		CF = 0  use FAT file
;Note	  :
;
;[]========================================================================[]
PART_BUFFER	EQU	000h
EXT_PART_BUFFER	EQU	200h
BOOT_BUFFER	EQU	400h
EXT_PARTITION	EQU	05h

		ALIGN	4
Ck_SUS_FAT_File	Proc	Near

		push	es
		push	si
		push	ax
		push	ebx

	; Read partition table

		Call	Read_Partition
		cmp	word ptr es:[di+1feh],0AA55h	
		jne	short Bad_File			

		add	di,01BFh		; Starting sector/head/Cylinder
		mov	cx,4
Find_FAT_part:
		Call	Ck_FAT_Partition_Exist
		jc	short End_Check		;Not FAT system

		push	di

		cmp	al,EXT_PARTITION
		jne	short _P11

		Call	Read_Ext_Partition
		cmp	word ptr es:[di+1feh],0AA55h	
		je	short check_file		
		pop	di				
		jmp	short End_Check			
Check_File:						
		add	di,1bfh			; Starting sector/head/Cylinder
_P11:
		Call	Ck_FAT_File_Exist
		pop	di
		jnc	short FAT_File_Exist	;Get FAT File
End_Check:
		add	di,16
		loop	short Find_FAT_part

		jmp	short Bad_File
FAT_File_Exist:

		pop	eax
		push	eax
		

		shl	eax,1			;1K = 2 sectors
		add	eax,1
		shl	eax,9			;1 sector = 512 Bytes

		cmp	edx,eax			; Is reserved space enough ?
		jb	short bad_File		; No

		clc
_C22:
		pop	ebx
		pop	ax
		pop	si
		pop	es
		ret
Bad_File:
	; Clear start sector number of Zero-Volt partition

		mov	dword ptr ds:[ZV_HDD_Sector],0
		stc
		jmp	short _C22


Ck_SUS_FAT_File	Endp

;[]========================================================================[]
;Procedure:	Ck_FAT_Partition_Exist
;
;Function :	Routine to check FAT system exist or not
;
;Input	  :	ES:[DI+3] = Partition Type (byte)
;			= 00h	unknown
;			= 01h	DOS with 12-bit FAT
;			= 04h	DOS with 16-bit FAT
;			= 05h	extended DOS partition
;			= 06h	32-bit FAT (OS/2 FAT)
;			= 07h	OS/2 HPFS
;			= DBh	concurrent DOS
;			= 0Ah   MultiBoot Maganer
;			= 0Bh   Windows95 FAT32
;			= 0Ch   Windows95 FAT32
;			= 17h   Windows NT NTFS
;			= 16h   Windows95 (Windows4.0) FAT
;
;Output   :	CF = 1  Not FAT system
;		CF = 0  FAT system
;		AL =    Parttion Type
;Note	  :
;
;[]========================================================================[]
		ALIGN	4
Ck_FAT_Partition_Exist	Proc	Near

		mov	si,offset Part_Tbl
	@@:
		lods	byte ptr cs:[si]
		cmp	al,0FFh
		je	short @F

		cmp	es:[di+3],al
		jne	short @B

		clc
		ret
	@@:
		stc
		ret
Ck_FAT_Partition_Exist	Endp

Part_Tbl:
		db	001h	;DOS with 12-bit FAT
		db	004h	;DOS with 16-bit FAT
		db	005h	;extended DOS partition
		db	006h	;32-bit FAT (OS/2 FAT)
		db	00Bh	;32-bit FAT (Windows95 FAT32)
		db	00Ch	;32-bit FAT (Windows95 FAT32)
		db	016h    ;Windows95 (Windows4.0) FAT
		db	0FFh

;[]========================================================================[]
;Procedure:	Read_Ext_Partition
;
;Function :	Routine to read extended partition sector
;
;Input	  :	ES:[DI]  Extended Partition sector
;
;Output   :	CF = 1  Partition not exist
;		CF = 0  Partition exist
;		DI = first parttion point
;Note	  :
;
;[]========================================================================[]
Read_Ext_Partition	Proc	Near

		push	cx

		Call	Get_Start_Sector

	;Read Extended Partition Sector

		mov	ebx,edx
		mov	ah,20h			; Read command
		mov	al,1			; Sector Count
		mov	edi,EXT_PART_BUFFER
		call	HDD_Transfer	

		pop	cx

		ret

Read_Ext_Partition	Endp

Get_Start_Sector	Proc	Near

	;Startint setcor :
	;  =  ( Sectors pre head * head pre cylinder * starting Cylinder )
	;  + ( Sectors pre head * Starting head )
	;  + ( Starting sector ) - 1 			;Zero base

		mov	ah,es:[di+1]		; Starting cylinder
		and	ah,0c0h
		shr	ah,6
		mov	al,es:[di+2]
		mul	word ptr ds:[Cylinder_Sector]
		shl	edx,16
		mov	dx,ax

		xor	eax,eax
		mov	al,es:[di]		; Starting head
		mul	byte ptr ds:[Head_Sector]
		add	edx,eax

		xor	eax,eax
		mov	al,es:[di+1]		; Starting sector
		and	al,3Fh
		dec	al
		add	edx,eax			; Logical starting sector

		ret

Get_Start_Sector	Endp

;[]========================================================================[]
;Procedure:	Ck_FAT_File_Exist
;
;Function :	Routine to check file (sus2disk.awa) exist or not
;
;Input	  :	ES:[DI]  DISK BOOT SECTOR
;
;Output   :	CF = 1  file not exist
;		CF = 0  file exist
;		EDX = file size
;Note	  :
;
;[]========================================================================[]

FAT_TYPE_STR	db	'FAT12   ',FAT_12bit
FAT_TYPE_LEN	EQU	$ - FAT_TYPE_STR
		db	'FAT16   ',FAT_16bit
		db	'FAT     ',FAT_16bit
FAT_TYPE_END:
FAT32_TYPE_STR:						
		db	'FAT32   ',FAT_32bit		

FAT_FILE_NAME	db	'SAVE2DSKBIN'	
FAT_FILE_LEN	EQU	$ - FAT_FILE_NAME

		ALIGN	4
Ck_FAT_File_Exist	Proc	Near

		push	cx

		Call	Get_Start_Sector

	;Read Disk Boot Sector

		push	di

		mov	ebx,edx
		mov	ah,20h			; Read command
		mov	al,1			; Sector Count
		mov	edi,BOOT_BUFFER
		call	HDD_Transfer		

		cmp	word ptr es:[di+1feh],0AA55h	
		je	short @F			
		stc					
		jmp	end_Fine			
@@:							
	;Strating Data area :
	;	=  ( Boot Disk sector + FAT sectors + Root dir ectors )

	; Calculator sector pre cluster

		mov	al,byte ptr es:[di+0Dh]		; Sectors Pre Cluster
		mov	ds:[Cluster_Sector],al

	; Check FAT type

		push	ds
		push	di

	;; check FAT32 string first

		add	di,52h			;Point to File-system ID
		
		push	cs
		pop	ds
		mov	si,offset FAT32_TYPE_STR
		push	si
		mov	cx,FAT_TYPE_LEN - 1
		repz	cmpsb
		pop	si
		jz	short @F

	;; If not FAT32 system , check FAT16 or FAT12
		pop	di
		push	di

		add	di,36h			;Point to File-system ID

		push	cs
		pop	ds
		mov	si,offset FAT_TYPE_STR
_Next:
		push	si
		push	di
		mov	cx,FAT_TYPE_LEN - 1
		repz	cmpsb
		pop	di
		pop	si
		jz	short @F

		cmp	si,((offset FAT_TYPE_END) - FAT_TYPE_LEN)
		jb	short Next_FAT_TYPE

		pop	di
		pop	ds
		stc
		jmp	end_Fine			
Next_FAT_TYPE:

		add	si,FAT_TYPE_LEN
		jmp	short _Next
@@:
		add	si,FAT_TYPE_LEN - 1
		lodsb				;Get FAT size
		pop	di
		pop	ds
		mov	ds:[FAT_TYPE],al
		cmp	al,FAT_32BIT		
		je	Check_FAT32_File	

		inc	ebx
	; Calculator FAT area sectors

		mov	ax,word ptr es:[di+16h]	; Sector per FAT
		mov	cl,byte ptr es:[di+10h]	; FAT copies
		xor	ch,ch
		mul	cx
		shl	edx,16
		mov	dx,ax			; Total secotrs of FAT
		add	ebx,edx

	; Calculator Root dir area sectors

		xor	eax,eax
		mov	ax,word ptr es:[di+11h]	; Root directory entries
		mov	cx,20h			; Directory entries size
		mul	cx
		mov	cx,512
		div	cx			; Total secotrs of Root
		or	dx,dx
		jz	short @F

		inc	al
@@:
		push	eax
		push	edi
		mov	cx,word ptr es:[di+11h]	; Root directory entries

		mov	ah,20h			; Read command
		mov	edi,400h		; Write to 400h
		call	HDD_Transfer	

		push	ds
		push	cs
		pop	ds
@@:
		push	cx
		push	di
		mov	cx,FAT_FILE_LEN		;file name lenght
		mov	si,offset FAT_FILE_NAME
		repz	cmpsb
		pop	di
		pop	cx
		jnz	short No_Find

		mov	ax,es:[di+1Ah]		;starting cluster number
		mov	edx,es:[di+1Ch]		;File size
		clc
		jmp	short Find_It
No_Find:
		add	di,20h
		loop	short @B
		stc
find_it:
		pop	ds
		pop	edi
		pop	ecx
		jc	end_Fine

		push	edx			
		add	ebx,ecx				; data area
		mov	ds:[ZV_HDD_Sector],ebx

		sub	ax,2
		xor	bh,bh
		mov	bl,byte ptr ds:[Cluster_Sector]
		mul	bx
		xchg	dx,ax
		shl	eax,16
		mov	ax,dx
		add	ds:[ZV_HDD_Sector],eax
		pop	edx


		clc
end_Fine:
		pop	di
		pop	cx

		ret

Ck_FAT_File_Exist	Endp

Check_FAT32_File	Proc	Near

		mov	FAT32_SECTOR_FLAG[bp],ebx
	; Calculator FAT area sectors

		xor	eax,eax	
		mov	ax,es:[di+0Eh]		; Reserved sector at begin
		add	ebx,eax

		mov	eax,es:[di+24h]		; Sector per FAT
		xor	ecx,ecx
		mov	cl,byte ptr es:[di+10h]	; FAT copies
		mul	ecx
		add	ebx,eax			; Add Total secotrs of FAT
		mov	FAT32_ROOT_FLAG[bp],ebx

Check_Next_Root_Cluster:
		mov	ah,20h			; Read command
		mov	al,ds:[Cluster_Sector]	; Read 1 cluster
		mov	edi,400h		; Write to 400h
		call	HDD_Transfer	

		mov	cl,(512/20h)
		mul	cl
		mov	cx,ax
@@:
		push	ds
		push	cs
		pop	ds
		push	cx
		push	di
		mov	cx,FAT_FILE_LEN		;file name lenght
		mov	si,offset FAT_FILE_NAME
		repz	cmpsb
		pop	di
		pop	cx
		pop	ds
		jnz	short No_Find_FAT32

		mov	ax,es:[di+14h]		;starting cluster number
		shl	eax,16
		mov	ax,es:[di+1Ah]		;starting cluster number
		mov	edx,es:[di+1Ch]		;File size
		clc
		jmp	short Find_FAT32_File
No_Find_FAT32:
		add	di,20h
		loop	short @B

		Call	Skip_To_Next_Cluster
		jnc	short Check_Next_Root_Cluster

Find_FAT32_File:
		jc	short End_FAT32_Fine

		push	edx
		sub	eax,2
		xor	ecx,ecx
		mov	cl,byte ptr ds:[Cluster_Sector]
		mul	ecx
		add	eax,FAT32_ROOT_FLAG[bp]
		mov	ds:[ZV_HDD_Sector],eax
		pop	edx

		clc
End_FAT32_Fine:
		pop	di
		pop	cx

		ret

Check_FAT32_File	Endp

;input : EDX = cluster Number
;Ouput : CF  = 1    No next cluster
;	 CF  = 0    Find next cluster
;	     EDX = next cluster Number
;	     EBX = next cluster sector number
Skip_To_Next_Cluster	Proc	Near

		xor	eax,eax
		mov	ax,dx
		shr	edx,16

		mov	bx,(512 / 4)
		div	bx
		mov	ebx,FAT32_SECTOR_FLAG[bp]
		add	ebx,eax

		mov	ah,20h			; Read command
		mov	al,ds:[Cluster_Sector]	; Read 1 cluster
		mov	edi,400h		; Write to 400h
		call	HDD_Transfer

		shr	edx,2
		add	edi,edx
	
		mov	edx,es:[edi]		; Get next cluster number
		cmp	edx,0FFFFFF8h		; Linker end ?
		jae	short @f		; Yes

		sub	edx,2			;Frist Cluster
		mov	eax,edx
		push	edx
		xor	ecx,ecx
		mov	cl,ds:[Cluster_Sector]
		mul	ecx
		pop	edx
		
		mov	ebx,FAT32_ROOT_FLAG[bp]
		add	ebx,eax
		
		clc
		ret
@@:
		stc
		ret
Skip_To_Next_Cluster	Endp

;[]========================================================================[]
;Procedure:	Read_Partition
;
;Function :	Routine to read partition sector
;
;Input	  :	none
;
;Output   :	ES:[DI]  Partition sector
;
;Note	  :
;
;[]========================================================================[]
Read_Partition	Proc	Near

		xor	ebx,ebx
		mov	ax,04000h
		mov	es,ax
		mov	ah,20h			; Read command
		mov	al,1			; Sector Count
		mov	edi,PART_BUFFER
		call	HDD_Transfer	

		ret
Read_Partition	Endp

;[]========================================================================[]
;Procedure:	Ck_SUS_Partition
;
;Function :	Routine to check 0V-suspend is use partition or not
;
;Input	  :	None
;
;Output   :	CF = 1 partition not exist
;		CF = 0 partition exist
;Note	  :
;
;[]========================================================================[]
RESERVED_TYPE	EQU	0A0h			
RESERVED_TYPE1	EQU	084h
Ck_SUS_Partition	Proc	Near

	; Get the Min. 0V partition size.

		mov	cx,512			; 512 byte / sector.
		mul	cx
		mov	cx,1024
		div	cx
		or	dx,dx
		jz	short @F
		xor	dx,dx
		inc	ax
	@@:
		mov	cx,ax			; ??KB / cylinder.
		push	ebx			
		pop	ax			
		pop	dx			
		div	cx			; Get cylinders for reserved.
		or	dx,dx
		jz	short @F
		inc	ax
	@@:

		push	es
		push	si
		push	ax
		push	ebx

	; Read partition table

		Call	Read_Partition

		cmp	word ptr es:[di+1feh],0AA55h
		je	short @F
		pop	ebx
		pop	ax
		pop	si
		jmp	No_Reserve_HDD
@@:
		xor	edx,edx

		add	di,01efh		; 4st partition type
		cmp	byte ptr es:[di+3h],RESERVED_TYPE
		je	short @f				
		cmp	byte ptr es:[di+3h],RESERVED_TYPE1	
		jne	short No_Find_Partition			
@@:								
		mov	edx,dword ptr es:[di+0bh]
No_Find_Partition:
		pop	ebx			
		pop	cx
		pop	si

		mov	eax,ebx
		shl	eax,1			; system request space
		add	eax,1			; 1 ID sector

		cmp	edx,eax			; Is reserved space enough ?
		jb	short No_Reserve_HDD	; No

		mov	ah,es:[di+1]		; Starting cylinder
		and	ah,0c0h
		shr	ah,6
		mov	al,es:[di+2]
		mul	word ptr ds:[Cylinder_Sector]
		shl	edx,16
		mov	dx,ax

	; Initial start sector number of Zero-Volt partition

		mov	dword ptr ds:[ZV_HDD_Sector],edx

End_Reserve_HDD:
		pop	es
		clc
		ret

No_Reserve_HDD:
		pop	es
		stc
		ret

Ck_SUS_Partition	Endp

;[]========================================================================[]
;Procedure:	Show_PM_Config
;
;Function :	To show the message that 0V-Partition is reserved or not
;		before booting.
;
;Input	  :	None
;
;Output   :	None
;
;[]========================================================================[]
		PUBLIC	Show_PM_Config
Show_PM_Config	PROC	NEAR

		push	ds
		call	F000_Get_PM_RAM_Seg	
		mov	ds,ax
		cmp	dword ptr ds:[ZV_HDD_Sector],0
		je	short @F

		mov	si,offset Reserve_ZV_File_Str
		cmp	byte ptr ds:[FAT_TYPE],FAT_16BIT
		je	short Use_FAT_File

		mov	si,offset Reserve_ZV_FAT32_Str
		cmp	byte ptr ds:[FAT_TYPE],FAT_32BIT
		je	short Use_FAT_File
		mov	si,offset Reserve_ZV_HDD_Str
Use_FAT_File:

		push	cs
		pop	ds
		mov	byte ptr CURSOR_X[bp],0
		call	F000_Display_String	
		inc	byte ptr CURSOR_Y[bp]

ifdef	No_0V_SPACE_WARNING
		pop	ds
		ret
	@@:
		mov	si,offset Suspend_Option_Item
		call	F000_Getitem_Value
		cmp	al,1
		jne	short @F

		push	cs
		pop	ds
		mov	si,offset NO_RESERVE_Str
		mov	byte ptr CURSOR_X[bp],0
		CALL	F000_Display_String
		inc	byte ptr CURSOR_Y[bp]

ifndef	No_0V_SPACE_NO_BEEP			
ifndef	ZV_CHECK_BEEPS				
		mov	cx,05h
else	;ZV_CHECK_BEEPS				
		mov	cx,ZV_CHECK_BEEPS	
endif	;ZV_CHECK_BEEPS				
	WARNING_B:
		PUSH	cx
		mov	bl,5
		F000_call	SND_SPKR
		iodelay
		iodelay
		POP	cx
		loop	short WARNING_B
		xor	ecx,ecx
		loop	short $
endif	;No_0V_SPACE_NO_BEEP
endif	;No_0V_SPACE_WARNING

	@@:
		pop	ds
		ret
Show_PM_Config	ENDP

Reserve_ZV_File_Str:						
		db	'0V-Suspend FAT16 file reserved.',0	
Reserve_ZV_FAT32_Str:						
		db	'0V-Suspend FAT32 file reserved.',0	
Reserve_ZV_HDD_Str:
		db	'0V-Suspend partition reserved.',0


ifdef	No_0V_SPACE_WARNING
NO_RESERVE_Str:
		db	'Warning !! Can not find 0V-Suspend space or not enough, funtion will fail !!',0
endif	;No_0V_SPACE_WARNING
endif	;STD_Function		EQ	1
;R110 - end

ifdef	Notebook_Power_Management
;лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл
;л
;л	Zero-Volt-Suspend Kernal for NoteBook Power Management
;л
;л	Codes during POST.
;л
;лллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

;[]========================================================================[]
;Procedure:	Notebook_Init
;
;Function :
;
;Input	  :	None
;
;Output   :	None
;
;Note	  :
;
;[]========================================================================[]
		Public	Notebook_Init
Notebook_Init	Proc	Near

	; Initial Suspend Option for NoteBook.

		Call	Ct_Get_Suspend_Mode	
		mov	PM_RAM:Suspend_Option,al

	; Save current INT 10H Vector
	; We need show message during run-time in SMM, so the original INT 10H
	; vector need to be saved.

ifndef	SMM_Show_String				
	; Force a software SMI for save current SMBASE.
	; That is for 0V suspend show message, we need exit form SMM mode
	; to real mode.

		mov	PM_RAM:Software_SMI_Type,SMI_BIOS_RSM	
		F000_call	Software_SMI
		mov	PM_RAM:Software_SMI_Type,0		
endif	;SMM_Show_String					

		ret
Notebook_Init	Endp

;R110 ;[]========================================================================[]
;R110 ;Procedure:	Notebook_Resume
;R110 ;
;R110 ;Function :	To check 0V suspend had been happend or not.
;R110 ;		If it is 0V resume to display the message & to do resume.
;R110 ;
;R110 ;Input	  :	None
;R110 ;
;R110 ;Output   :	None
;R110 ;
;R110 ;Note	  :
;R110 ;
;R110 ;[]========================================================================[]
;R110 		Public	Notebook_Resume
;R110 Notebook_Resume	proc	near
;R110 
;R110 		F000_call	Check_0V_Resume
;R110 		jz	short @F
;R110 
;R110 		call	F000_Open_PM_RAM		
;R110 		call	F000_Get_PM_RAM_Seg		
;R110 		mov	es,ax
;R110 		ASSUME	ES:PM_RAM
;R110 
;R110 		cmp	dword ptr PM_RAM:ZV_HDD_Sector,0
;R110 		je	short @F
;R110 
;R110 ifdef	NO_ZV_REALTIME_MESSAGE			
;R110 	; To Show the message before resume
;R110 
;R110 		mov	si,offset Resume_ZV_MSG
;R110 		F000_call	ZV_Display_MSG
;R110 endif	;NO_ZV_REALTIME_MESSAGE			
;R110 
;R110 	; Generate a software SMI to resume
;R110 
;R110 ;R101 - start
;R110 if	BIOS_SUPPORT_686				
;R110 		mov	al,P6_A20_CMOS NMI_OFF			
;R110 		Call	F000_Get_Cmos
;R110 		test	al,P6_A20_Status
;R110 		jz	short Not_A20_High
;R110 		F000_Call	A20_ON			
;R110 Not_A20_High:
;R110 endif	;BIOS_SUPPORT_686
;R110 ;R101 - end
;R110 
;R110 		mov	PM_RAM:Software_SMI_Type,SMI_0V_Resume	
;R110 ;R107 - start
;R110 ifdef	ACPI_SUPPORT
;R110 ifdef	S4_SUPPORT
;R110 		F000_call	Check_S4_Resume
;R110 		jz	short Not_S4_Resume
;R110 		mov	PM_RAM:Software_SMI_Type,SMI_S4_Resume	
;R110 Not_S4_resume:
;R110 endif	;S4_SUPPORT
;R110 endif	;ACPI_SUPPORT
;R110 ;R107 - end
;R110 		F000_call	Software_SMI
;R110 		mov	PM_RAM:Software_SMI_Type,0		
;R110 		jmp	$
;R110 	@@:
;R110 		mov	al,0Fh NMI_OFF			
;R110 		mov	ah,0			; Clear 0V suspend flag
;R110 		call	F000_Set_CMOS			
;R110 
;R110 		ret
;R110 Notebook_Resume	Endp
;R110 
;R110 ;[]========================================================================[]
;R110 ;Procedure:	Reserve_ZV_HDD
;R110 ;
;R110 ;Function :	Routine to check 0V partition and reserve cylinders for
;R110 ;		0V partition
;R110 ;
;R110 ;Input	  :	None
;R110 ;
;R110 ;Output   :	None
;R110 ;
;R110 ;Note	  :
;R110 ;
;R110 ;	The following is 0V suspend partition save location brief..
;R110 ;
;R110 ;	Sector 0	  : For ID sector.
;R110 ;
;R110 ;				Byte 0 - 23  : Chipset Name & Part No.(24 Bytes)
;R110 ;					AA55AA55 = Skip reserve 0V partition.
;R110 ;
;R110 ;				Byte 24 - 25 : Suspend checksum.(2 Bytes)
;R110 ;
;R110 ;				Byte 26 - 29 : ID for ZVHDD.EXE.(4 Bytes)
;R110 ;					AA55AA55 = 0V partition exist.
;R110 ;
;R110 ;				Byte 30 - 31 : Current HDD total cylinder.
;R110 ;
;R110 ;	Sector 1 - 64	  : For Save SMBASE. (32 KB)
;R110 ;
;R110 ;	Sector 65 - 2112  : For Save BASE Mmemory. (1024 KB)
;R110 ;		            (640 KB DRAM & C0000 - FFFFF Shadow RAM )
;R110 ;			    (Usually, we do not care A0000 - BFFFF shadow)
;R110 ;
;R110 ;	Sector 2113 - 6208: For Save VIDEO Mmemory. (2048KB)
;R110 ;
;R110 ;	Sector 6209 - Max : For Save EXT Mmemory.
;R110 ;
;R110 ;[]========================================================================[]
;R110 		PUBLIC	Reserve_ZV_HDD
;R110 Reserve_ZV_HDD	PROC	NEAR
;R110 		pushad
;R110 		push	ds
;R110 		push	es
;R110 
;R110 		cli
;R110 
;R110 		call	Get_EXT_Memory		
;R110 ;R73		mov	bx,cx
;R110 ;R73		add	bx,1024+4096			;Reserve extended memory + 5120K
;R110 ;R73A		shl	ecx,10				;R73
;R110 		shl	ecx,6				;R73A 1K block
;R110 		mov	ebx,ecx				;R73
;R110 		add	ebx,1024+4096			;R73 Add base memory and video memory
;R110 
;R110 		call	F000_Get_PM_RAM_Seg		
;R110 		mov	ds,ax
;R110 		call	F000_Open_PM_RAM	
;R110 
;R110 		mov	ax,G_RAM
;R110 		mov	es,ax
;R110 
;R110 		cmp	byte ptr HDD_EXIST_Flag[bp],0	
;R110 		je	short End_Reserve_HDD1		
;R110 ;R74 start
;R110 		mov	cl,es:HDD_Drive_Port
;R110 		and	cl,3
;R110 		mov	ah,es:HDD_MODE_FLAG
;R110 		shr	ah,cl
;R110 		shr	ah,cl
;R110 		and	ah,3
;R110 		shl	ah,2
;R110 		or	ah,cl
;R110 		or	ds:[ZV_HDD_Scheme],ah
;R110 ;R74 end
;R110 		mov	si,word ptr es:[DR0VECTOR]	; Get HDD table pointer.
;R110 		mov	ax,word ptr es:[DR0VECTOR+2]
;R110 		mov	es,ax
;R110 
;R110 		mov	cl,es:[si+2]		; Max. Head   / cylinder.
;R110 		mov	al,es:[si+0eh]		; Max. Sector / head.
;R110 
;R110 		mov	ds:[Head_Sector],al	; Init Sectors per head
;R110 
;R110 		mul	cl
;R110 
;R110 		mov	ds:[Cylinder_Sector],ax	; Init Sectors per Cylinder
;R110 
;R110 		Call	Ck_SUS_Partition
;R110 		jnc	short End_Reserve_HDD1		
;R110 		Call	Ck_SUS_FAT_File			
;R110 End_Reserve_HDD1:
;R110 
;R110 ;R108 - start
;R110 	;;;Record G_RAM COMM port status
;R110 		push	ds
;R110 		push	G_RAM
;R110 		pop	ds
;R110 		mov	eax, dword ptr G_RAM:[COMM_PORT_ADDRS]
;R110 		pop	ds
;R110 		mov	dword ptr ds:[COMA_ADDRS], eax
;R110 ;R108 - end
;R110 		
;R110 		call	F000_Close_PM_RAM	
;R110 
;R110 	; Clear temp memory
;R110 
;R110 		mov	ax,04000h
;R110 		mov	es,ax
;R110 		xor	eax,eax
;R110 		xor	di,di
;R110 		mov	cx,2000h			;clear 32K
;R110 		cld
;R110 		rep	stosd
;R110 
;R110 		pop	es
;R110 		pop	ds
;R110 		popad
;R110 
;R110 		RET
;R110 Reserve_ZV_HDD	ENDP
;R110 
;R110 ;[]========================================================================[]
;R110 ;Procedure:	Ck_SUS_FAT_File
;R110 ;
;R110 ;Function :	Routine to check 0v-suspend is use FAT file or not
;R110 ;
;R110 ;Input	  :	None
;R110 ;
;R110 ;Output   :	CF = 1  not use FAT file
;R110 ;		CF = 0  use FAT file
;R110 ;Note	  :
;R110 ;
;R110 ;[]========================================================================[]
;R110 PART_BUFFER	EQU	000h
;R110 EXT_PART_BUFFER	EQU	200h
;R110 BOOT_BUFFER	EQU	400h
;R110 EXT_PARTITION	EQU	05h
;R110 
;R110 		ALIGN	4
;R110 Ck_SUS_FAT_File	Proc	Near
;R110 
;R110 		push	es
;R110 		push	si
;R110 		push	ax
;R110 ;R73		push	bx
;R110 		push	ebx			;R73
;R110 
;R110 	; Read partition table
;R110 
;R110 		Call	Read_Partition
;R110 		cmp	word ptr es:[di+1feh],0AA55h	
;R110 		jne	short Bad_File			
;R110 
;R110 		add	di,01BFh		; Starting sector/head/Cylinder
;R110 		mov	cx,4
;R110 Find_FAT_part:
;R110 		Call	Ck_FAT_Partition_Exist
;R110 		jc	short End_Check		;Not FAT system
;R110 
;R110 		push	di
;R110 
;R110 		cmp	al,EXT_PARTITION
;R110 		jne	short _P11
;R110 
;R110 		Call	Read_Ext_Partition
;R110 		cmp	word ptr es:[di+1feh],0AA55h	
;R110 		je	short check_file		
;R110 		pop	di				
;R110 		jmp	short End_Check			
;R110 Check_File:						
;R110 		add	di,1bfh			; Starting sector/head/Cylinder
;R110 _P11:
;R110 		Call	Ck_FAT_File_Exist
;R110 		pop	di
;R110 		jnc	short FAT_File_Exist	;Get FAT File
;R110 End_Check:
;R110 		add	di,16
;R110 		loop	short Find_FAT_part
;R110 
;R110 		jmp	short Bad_File
;R110 FAT_File_Exist:
;R110 
;R110 ;R73		xor	eax,eax
;R110 
;R110 ;R73		pop	ax
;R110 ;R73		push	ax
;R110 		pop	eax			;R73
;R110 		push	eax			;R73
;R110 		
;R110 
;R110 ;R73		shl	eax,10			; system request space
;R110 		shl	eax,1			;R73 1K = 2 sectors
;R110 		add	eax,1
;R110 		shl	eax,9			;R73A 1 sector = 512 Bytes
;R110 
;R110 		cmp	edx,eax			; Is reserved space enough ?
;R110 		jb	short bad_File		; No
;R110 
;R110 		clc
;R110 _C22:
;R110 ;R73		pop	bx
;R110 		pop	ebx			;R73
;R110 		pop	ax
;R110 		pop	si
;R110 		pop	es
;R110 		ret
;R110 Bad_File:
;R110 	; Clear start sector number of Zero-Volt partition
;R110 
;R110 		mov	dword ptr ds:[ZV_HDD_Sector],0
;R110 		stc
;R110 		jmp	short _C22
;R110 
;R110 
;R110 Ck_SUS_FAT_File	Endp
;R110 
;R110 ;[]========================================================================[]
;R110 ;Procedure:	Ck_FAT_Partition_Exist
;R110 ;
;R110 ;Function :	Routine to check FAT system exist or not
;R110 ;
;R110 ;Input	  :	ES:[DI+3] = Partition Type (byte)
;R110 ;			= 00h	unknown
;R110 ;			= 01h	DOS with 12-bit FAT
;R110 ;			= 04h	DOS with 16-bit FAT
;R110 ;			= 05h	extended DOS partition
;R110 ;			= 06h	32-bit FAT (OS/2 FAT)
;R110 ;			= 07h	OS/2 HPFS
;R110 ;			= DBh	concurrent DOS
;R110 ;			= 0Ah   MultiBoot Maganer
;R110 ;			= 0Bh   Windows95 FAT32			;R99
;R110 ;			= 17h   Windows NT NTFS
;R110 ;			= 16h   Windows95 (Windows4.0) FAT
;R110 ;
;R110 ;Output   :	CF = 1  Not FAT system
;R110 ;		CF = 0  FAT system
;R110 ;		AL =    Parttion Type
;R110 ;Note	  :
;R110 ;
;R110 ;[]========================================================================[]
;R110 		ALIGN	4
;R110 Ck_FAT_Partition_Exist	Proc	Near
;R110 
;R110 		mov	si,offset Part_Tbl
;R110 	@@:
;R110 		lods	byte ptr cs:[si]
;R110 		cmp	al,0FFh
;R110 		je	short @F
;R110 
;R110 		cmp	es:[di+3],al
;R110 		jne	short @B
;R110 
;R110 		clc
;R110 		ret
;R110 	@@:
;R110 		stc
;R110 		ret
;R110 Ck_FAT_Partition_Exist	Endp
;R110 
;R110 Part_Tbl:
;R110 		db	001h	;DOS with 12-bit FAT
;R110 		db	004h	;DOS with 16-bit FAT
;R110 		db	005h	;extended DOS partition
;R110 		db	006h	;32-bit FAT (OS/2 FAT)
;R110 		db	00Bh	;32-bit FAT (Windows95 FAT32)	;R99
;R110 		db	00Ch	;32-bit FAT (Windows95 FAT32)   ;R99A
;R110 		db	016h    ;Windows95 (Windows4.0) FAT
;R110 		db	0FFh
;R110 
;R110 ;[]========================================================================[]
;R110 ;Procedure:	Read_Ext_Partition
;R110 ;
;R110 ;Function :	Routine to read extended partition sector
;R110 ;
;R110 ;Input	  :	ES:[DI]  Extended Partition sector
;R110 ;
;R110 ;Output   :	CF = 1  Partition not exist
;R110 ;		CF = 0  Partition exist
;R110 ;		DI = first parttion point
;R110 ;Note	  :
;R110 ;
;R110 ;[]========================================================================[]
;R110 Read_Ext_Partition	Proc	Near
;R110 
;R110 		push	cx
;R110 
;R110 		Call	Get_Start_Sector
;R110 
;R110 	;Read Extended Partition Sector
;R110 
;R110 		mov	ebx,edx
;R110 		mov	ah,20h			; Read command
;R110 		mov	al,1			; Sector Count
;R110 		mov	edi,EXT_PART_BUFFER
;R110 		call	HDD_Transfer	
;R110 
;R110 		pop	cx
;R110 
;R110 		ret
;R110 
;R110 Read_Ext_Partition	Endp
;R110 
;R110 Get_Start_Sector	Proc	Near
;R110 
;R110 	;Startint setcor :
;R110 	;  =  ( Sectors pre head * head pre cylinder * starting Cylinder )
;R110 	;  + ( Sectors pre head * Starting head )
;R110 	;  + ( Starting sector ) - 1 			;Zero base
;R110 
;R110 		mov	ah,es:[di+1]		; Starting cylinder
;R110 		and	ah,0c0h
;R110 		shr	ah,6
;R110 		mov	al,es:[di+2]
;R110 		mul	word ptr ds:[Cylinder_Sector]
;R110 		shl	edx,16
;R110 		mov	dx,ax
;R110 
;R110 		xor	eax,eax
;R110 		mov	al,es:[di]		; Starting head
;R110 		mul	byte ptr ds:[Head_Sector]
;R110 		add	edx,eax
;R110 
;R110 		xor	eax,eax
;R110 		mov	al,es:[di+1]		; Starting sector
;R110 		and	al,3Fh
;R110 		dec	al
;R110 		add	edx,eax			; Logical starting sector
;R110 
;R110 		ret
;R110 
;R110 Get_Start_Sector	Endp
;R110 
;R110 ;[]========================================================================[]
;R110 ;Procedure:	Ck_FAT_File_Exist
;R110 ;
;R110 ;Function :	Routine to check file (sus2disk.awa) exist or not
;R110 ;
;R110 ;Input	  :	ES:[DI]  DISK BOOT SECTOR
;R110 ;
;R110 ;Output   :	CF = 1  file not exist
;R110 ;		CF = 0  file exist
;R110 ;		EDX = file size
;R110 ;Note	  :
;R110 ;
;R110 ;[]========================================================================[]
;R110 
;R110 FAT_TYPE_STR	db	'FAT12   ',FAT_12bit
;R110 FAT_TYPE_LEN	EQU	$ - FAT_TYPE_STR
;R110 		db	'FAT16   ',FAT_16bit
;R110 ;;;;		db	'FAT32   ',FAT_32bit
;R110 		db	'FAT     ',FAT_16bit
;R110 FAT_TYPE_END:
;R110 FAT32_TYPE_STR:						;R99
;R110 		db	'FAT32   ',FAT_32bit		;R99
;R110 
;R110 FAT_FILE_NAME	db	'SAVE2DSKBIN'	
;R110 FAT_FILE_LEN	EQU	$ - FAT_FILE_NAME
;R110 
;R110 		ALIGN	4
;R110 Ck_FAT_File_Exist	Proc	Near
;R110 
;R110 		push	cx
;R110 
;R110 		Call	Get_Start_Sector
;R110 
;R110 	;Read Disk Boot Sector
;R110 
;R110 		push	di
;R110 
;R110 		mov	ebx,edx
;R110 		mov	ah,20h			; Read command
;R110 		mov	al,1			; Sector Count
;R110 		mov	edi,BOOT_BUFFER
;R110 		call	HDD_Transfer		
;R110 
;R110 		cmp	word ptr es:[di+1feh],0AA55h	
;R110 		je	short @F			
;R110 		stc					
;R110 		jmp	end_Fine			
;R110 @@:							
;R110 	;Strating Data area :
;R110 	;	=  ( Boot Disk sector + FAT sectors + Root dir ectors )
;R110 
;R110 ;R99		inc	ebx
;R110 
;R110 	; Calculator sector pre cluster
;R110 
;R110 		mov	al,byte ptr es:[di+0Dh]		; Sectors Pre Cluster
;R110 		mov	ds:[Cluster_Sector],al
;R110 
;R110 	; Check FAT type
;R110 
;R110 		push	ds
;R110 		push	di
;R110 ;R99 - start
;R110 	;; check FAT32 string first
;R110 
;R110 		add	di,52h			;Point to File-system ID
;R110 		
;R110 		push	cs
;R110 		pop	ds
;R110 		mov	si,offset FAT32_TYPE_STR
;R110 		push	si
;R110 		mov	cx,FAT_TYPE_LEN - 1
;R110 		repz	cmpsb
;R110 		pop	si
;R110 		jz	short @F
;R110 
;R110 	;; If not FAT32 system , check FAT16 or FAT12
;R110 		pop	di
;R110 		push	di
;R110 ;R99 - end
;R110 		add	di,36h			;Point to File-system ID
;R110 
;R110 		push	cs
;R110 		pop	ds
;R110 		mov	si,offset FAT_TYPE_STR
;R110 _Next:
;R110 		push	si
;R110 		push	di
;R110 		mov	cx,FAT_TYPE_LEN - 1
;R110 		repz	cmpsb
;R110 		pop	di
;R110 		pop	si
;R110 		jz	short @F
;R110 
;R110 		cmp	si,((offset FAT_TYPE_END) - FAT_TYPE_LEN)
;R110 ;R75		jae	short @F
;R110 ;R75 - start
;R110 		jb	short Next_FAT_TYPE
;R110 
;R110 		pop	di
;R110 		pop	ds
;R110 		stc
;R110 		jmp	end_Fine			
;R110 Next_FAT_TYPE:
;R110 ;R75 - end
;R110 
;R110 		add	si,FAT_TYPE_LEN
;R110 		jmp	short _Next
;R110 @@:
;R110 		add	si,FAT_TYPE_LEN - 1
;R110 		lodsb				;Get FAT size
;R110 		pop	di
;R110 		pop	ds
;R110 		mov	ds:[FAT_TYPE],al
;R110 		cmp	al,FAT_32BIT		;R99
;R110 		je	Check_FAT32_File	;R99
;R110 
;R110 		inc	ebx			;R99
;R110 	; Calculator FAT area sectors
;R110 
;R110 		mov	ax,word ptr es:[di+16h]	; Sector per FAT
;R110 		mov	cl,byte ptr es:[di+10h]	; FAT copies
;R110 		xor	ch,ch
;R110 		mul	cx
;R110 		shl	edx,16
;R110 		mov	dx,ax			; Total secotrs of FAT
;R110 		add	ebx,edx
;R110 
;R110 	; Calculator Root dir area sectors
;R110 
;R110 		xor	eax,eax
;R110 		mov	ax,word ptr es:[di+11h]	; Root directory entries
;R110 		mov	cx,20h			; Directory entries size
;R110 		mul	cx
;R110 		mov	cx,512
;R110 		div	cx			; Total secotrs of Root
;R110 		or	dx,dx
;R110 		jz	short @F
;R110 
;R110 		inc	al
;R110 @@:
;R110 		push	eax
;R110 		push	edi
;R110 		mov	cx,word ptr es:[di+11h]	; Root directory entries
;R110 
;R110 		mov	ah,20h			; Read command
;R110 		mov	edi,400h		; Write to 400h
;R110 		call	HDD_Transfer	
;R110 
;R110 		push	ds
;R110 		push	cs
;R110 		pop	ds
;R110 @@:
;R110 		push	cx
;R110 		push	di
;R110 		mov	cx,FAT_FILE_LEN		;file name lenght
;R110 		mov	si,offset FAT_FILE_NAME
;R110 		repz	cmpsb
;R110 		pop	di
;R110 		pop	cx
;R110 		jnz	short No_Find
;R110 
;R110 		mov	ax,es:[di+1Ah]		;starting cluster number
;R110 		mov	edx,es:[di+1Ch]		;File size
;R110 		clc
;R110 		jmp	short Find_It
;R110 No_Find:
;R110 		add	di,20h
;R110 		loop	short @B
;R110 		stc
;R110 find_it:
;R110 		pop	ds
;R110 		pop	edi
;R110 		pop	ecx
;R110 		jc	end_Fine
;R110 
;R110 		push	edx			
;R110 		add	ebx,ecx				; data area
;R110 		mov	ds:[ZV_HDD_Sector],ebx
;R110 
;R110 		sub	ax,2
;R110 		xor	bh,bh
;R110 		mov	bl,byte ptr ds:[Cluster_Sector]
;R110 		mul	bx
;R110 		xchg	dx,ax
;R110 		shl	eax,16
;R110 		mov	ax,dx
;R110 		add	ds:[ZV_HDD_Sector],eax
;R110 		pop	edx
;R110 
;R110 
;R110 		clc
;R110 end_Fine:
;R110 		pop	di
;R110 		pop	cx
;R110 
;R110 		ret
;R110 
;R110 Ck_FAT_File_Exist	Endp
;R110 
;R110 ;R99 - start
;R110 Check_FAT32_File	Proc	Near
;R110 
;R110 		mov	FAT32_SECTOR_FLAG[bp],ebx
;R110 	; Calculator FAT area sectors
;R110 
;R110 		xor	eax,eax	
;R110 		mov	ax,es:[di+0Eh]		; Reserved sector at begin
;R110 		add	ebx,eax
;R110 
;R110 		mov	eax,es:[di+24h]		; Sector per FAT
;R110 		xor	ecx,ecx
;R110 		mov	cl,byte ptr es:[di+10h]	; FAT copies
;R110 		mul	ecx
;R110 		add	ebx,eax			; Add Total secotrs of FAT
;R110 		mov	FAT32_ROOT_FLAG[bp],ebx
;R110 
;R110 Check_Next_Root_Cluster:
;R110 		mov	ah,20h			; Read command
;R110 		mov	al,ds:[Cluster_Sector]	; Read 1 cluster
;R110 		mov	edi,400h		; Write to 400h
;R110 		call	HDD_Transfer	
;R110 
;R110 		mov	cl,(512/20h)
;R110 		mul	cl
;R110 		mov	cx,ax
;R110 @@:
;R110 		push	ds
;R110 		push	cs
;R110 		pop	ds
;R110 		push	cx
;R110 		push	di
;R110 		mov	cx,FAT_FILE_LEN		;file name lenght
;R110 		mov	si,offset FAT_FILE_NAME
;R110 		repz	cmpsb
;R110 		pop	di
;R110 		pop	cx
;R110 		pop	ds
;R110 		jnz	short No_Find_FAT32
;R110 
;R110 		mov	ax,es:[di+14h]		;starting cluster number
;R110 		shl	eax,16
;R110 		mov	ax,es:[di+1Ah]		;starting cluster number
;R110 		mov	edx,es:[di+1Ch]		;File size
;R110 		clc
;R110 		jmp	short Find_FAT32_File
;R110 No_Find_FAT32:
;R110 		add	di,20h
;R110 		loop	short @B
;R110 
;R110 		Call	Skip_To_Next_Cluster
;R110 		jnc	short Check_Next_Root_Cluster
;R110 
;R110 Find_FAT32_File:
;R110 		jc	short End_FAT32_Fine
;R110 
;R110 		push	edx
;R110 		sub	eax,2
;R110 		xor	ecx,ecx
;R110 		mov	cl,byte ptr ds:[Cluster_Sector]
;R110 		mul	ecx
;R110 		add	eax,FAT32_ROOT_FLAG[bp]
;R110 		mov	ds:[ZV_HDD_Sector],eax
;R110 		pop	edx
;R110 
;R110 		clc
;R110 End_FAT32_Fine:
;R110 		pop	di
;R110 		pop	cx
;R110 
;R110 		ret
;R110 
;R110 Check_FAT32_File	Endp
;R110 
;R110 ;input : EDX = cluster Number
;R110 ;Ouput : CF  = 1    No next cluster
;R110 ;	 CF  = 0    Find next cluster
;R110 ;	     EDX = next cluster Number
;R110 ;	     EBX = next cluster sector number
;R110 Skip_To_Next_Cluster	Proc	Near
;R110 
;R110 		xor	eax,eax
;R110 		mov	ax,dx
;R110 		shr	edx,16
;R110 
;R110 		mov	bx,(512 / 4)
;R110 		div	bx
;R110 		mov	ebx,FAT32_SECTOR_FLAG[bp]
;R110 		add	ebx,eax
;R110 
;R110 		mov	ah,20h			; Read command
;R110 		mov	al,ds:[Cluster_Sector]	; Read 1 cluster
;R110 		mov	edi,400h		; Write to 400h
;R110 		call	HDD_Transfer
;R110 
;R110 		shr	edx,2
;R110 		add	edi,edx
;R110 	
;R110 		mov	edx,es:[edi]		; Get next cluster number
;R110 		cmp	edx,0FFFFFF8h		; Linker end ?
;R110 		jae	short @f		; Yes
;R110 
;R110 		sub	edx,2			;Frist Cluster
;R110 		mov	eax,edx
;R110 		push	edx
;R110 		xor	ecx,ecx
;R110 		mov	cl,ds:[Cluster_Sector]
;R110 		mul	ecx
;R110 		pop	edx
;R110 		
;R110 		mov	ebx,FAT32_ROOT_FLAG[bp]
;R110 		add	ebx,eax
;R110 		
;R110 		clc
;R110 		ret
;R110 @@:
;R110 		stc
;R110 		ret
;R110 Skip_To_Next_Cluster	Endp
;R110 ;R99 - end
;R110 ;[]========================================================================[]
;R110 ;Procedure:	Read_Partition
;R110 ;
;R110 ;Function :	Routine to read partition sector
;R110 ;
;R110 ;Input	  :	none
;R110 ;
;R110 ;Output   :	ES:[DI]  Partition sector
;R110 ;
;R110 ;Note	  :
;R110 ;
;R110 ;[]========================================================================[]
;R110 Read_Partition	Proc	Near
;R110 
;R110 		xor	ebx,ebx
;R110 		mov	ax,04000h
;R110 		mov	es,ax
;R110 		mov	ah,20h			; Read command
;R110 		mov	al,1			; Sector Count
;R110 		mov	edi,PART_BUFFER
;R110 		call	HDD_Transfer	
;R110 
;R110 		ret
;R110 Read_Partition	Endp
;R110 
;R110 ;[]========================================================================[]
;R110 ;Procedure:	Ck_SUS_Partition
;R110 ;
;R110 ;Function :	Routine to check 0V-suspend is use partition or not
;R110 ;
;R110 ;Input	  :	None
;R110 ;
;R110 ;Output   :	CF = 1 partition not exist
;R110 ;		CF = 0 partition exist
;R110 ;Note	  :
;R110 ;
;R110 ;[]========================================================================[]
;R110 RESERVED_TYPE	EQU	0A0h			
;R110 RESERVED_TYPE1	EQU	084h			;R106
;R110 Ck_SUS_Partition	Proc	Near
;R110 
;R110 	; Get the Min. 0V partition size.
;R110 
;R110 		mov	cx,512			; 512 byte / sector.
;R110 		mul	cx
;R110 		mov	cx,1024
;R110 		div	cx
;R110 		or	dx,dx
;R110 		jz	short @F
;R110 		xor	dx,dx
;R110 		inc	ax
;R110 	@@:
;R110 		mov	cx,ax			; ??KB / cylinder.
;R110 ;R73		mov	ax,bx
;R110 ;R73		xor	dx,dx
;R110 		push	ebx			;R73
;R110 		pop	ax			;R73
;R110 		pop	dx			;R73
;R110 		div	cx			; Get cylinders for reserved.
;R110 		or	dx,dx
;R110 		jz	short @F
;R110 		inc	ax
;R110 	@@:
;R110 
;R110 		push	es
;R110 		push	si
;R110 		push	ax
;R110 ;R73		push	bx	
;R110 		push	ebx			;R73
;R110 
;R110 	; Read partition table
;R110 
;R110 		Call	Read_Partition
;R110 
;R110 		cmp	word ptr es:[di+1feh],0AA55h
;R110 		je	short @F
;R110 ;R73		pop	bx
;R110 		pop	ebx			;R73
;R110 		pop	ax
;R110 		pop	si
;R110 		jmp	No_Reserve_HDD
;R110 @@:
;R110 
;R110 		xor	edx,edx
;R110 
;R110 		add	di,01efh		; 4st partition type
;R110 		cmp	byte ptr es:[di+3h],RESERVED_TYPE
;R110 ;R106		jne	short No_Find_Partition
;R110 		je	short @f				;R106
;R110 		cmp	byte ptr es:[di+3h],RESERVED_TYPE1	;R106
;R110 		jne	short No_Find_Partition			;R106
;R110 @@:								;R106
;R110 		mov	edx,dword ptr es:[di+0bh]
;R110 No_Find_Partition:
;R110 ;R73		pop	bx
;R110 		pop	ebx			;R73
;R110 		pop	cx
;R110 		pop	si
;R110 
;R110 ;R73		xor	eax,eax
;R110 
;R110 ;R73		mov	ax,bx
;R110 		mov	eax,ebx			;R73
;R110 		shl	eax,1			; system request space
;R110 		add	eax,1			; 1 ID sector
;R110 
;R110 		cmp	edx,eax			; Is reserved space enough ?
;R110 		jb	short No_Reserve_HDD	; No
;R110 
;R110 		mov	ah,es:[di+1]		; Starting cylinder
;R110 		and	ah,0c0h
;R110 		shr	ah,6
;R110 		mov	al,es:[di+2]
;R110 		mul	word ptr ds:[Cylinder_Sector]
;R110 		shl	edx,16
;R110 		mov	dx,ax
;R110 
;R110 	; Initial start sector number of Zero-Volt partition
;R110 
;R110 		mov	dword ptr ds:[ZV_HDD_Sector],edx
;R110 
;R110 End_Reserve_HDD:
;R110 		pop	es
;R110 		clc
;R110 		ret
;R110 
;R110 No_Reserve_HDD:
;R110 		pop	es
;R110 		stc
;R110 		ret
;R110 
;R110 Ck_SUS_Partition	Endp
;R110 
;R110 ;[]========================================================================[]
;R110 ;Procedure:	Show_PM_Config
;R110 ;
;R110 ;Function :	To show the message that 0V-Partition is reserved or not
;R110 ;		before booting.
;R110 ;
;R110 ;Input	  :	None
;R110 ;
;R110 ;Output   :	None
;R110 ;
;R110 ;[]========================================================================[]
;R110 		PUBLIC	Show_PM_Config
;R110 Show_PM_Config	PROC	NEAR
;R110 
;R110 		push	ds
;R110 		call	F000_Get_PM_RAM_Seg	
;R110 		mov	ds,ax
;R110 		cmp	dword ptr ds:[ZV_HDD_Sector],0
;R110 		je	short @F
;R110 
;R110 		mov	si,offset Reserve_ZV_File_Str
;R110 ;R99		cmp	byte ptr ds:[FAT_TYPE],0
;R110 ;R99		jne	short Use_FAT_File
;R110 ;R99 - start
;R110 		cmp	byte ptr ds:[FAT_TYPE],FAT_16BIT
;R110 		je	short Use_FAT_File
;R110 
;R110 		mov	si,offset Reserve_ZV_FAT32_Str
;R110 		cmp	byte ptr ds:[FAT_TYPE],FAT_32BIT
;R110 		je	short Use_FAT_File
;R110 ;R99 - end
;R110 		mov	si,offset Reserve_ZV_HDD_Str
;R110 Use_FAT_File:
;R110 
;R110 		push	cs
;R110 		pop	ds
;R110 		mov	byte ptr CURSOR_X[bp],0
;R110 		call	F000_Display_String	
;R110 		inc	byte ptr CURSOR_Y[bp]
;R110 
;R110 ifdef	No_0V_SPACE_WARNING
;R110 		pop	ds
;R110 		ret
;R110 	@@:
;R110 		mov	si,offset Suspend_Option_Item
;R110 		call	F000_Getitem_Value
;R110 		cmp	al,1
;R110 		jne	short @F
;R110 
;R110 		push	cs
;R110 		pop	ds
;R110 		mov	si,offset NO_RESERVE_Str
;R110 		mov	byte ptr CURSOR_X[bp],0
;R110 		CALL	F000_Display_String
;R110 		inc	byte ptr CURSOR_Y[bp]
;R110 
;R110 ifndef	No_0V_SPACE_NO_BEEP			;R104
;R110 ifndef	ZV_CHECK_BEEPS				;R109
;R110 		mov	cx,05h
;R110 else	;ZV_CHECK_BEEPS				;R109
;R110 		mov	cx,ZV_CHECK_BEEPS	;R109
;R110 endif	;ZV_CHECK_BEEPS				;R109
;R110 	WARNING_B:
;R110 		PUSH	cx
;R110 		mov	bl,5
;R110 		F000_call	SND_SPKR
;R110 		iodelay
;R110 		iodelay
;R110 		POP	cx
;R110 		loop	short WARNING_B
;R110 		xor	ecx,ecx
;R110 		loop	short $
;R110 endif	;No_0V_SPACE_NO_BEEP			;R104
;R110 endif	;No_0V_SPACE_WARNING
;R110 
;R110 	@@:
;R110 		pop	ds
;R110 		ret
;R110 Show_PM_Config	ENDP
;R110 
;R110 Reserve_ZV_File_Str:						
;R110 ;R99		db	'0V-Suspend FAT file reserved.',0	
;R110 		db	'0V-Suspend FAT16 file reserved.',0	;R99
;R110 Reserve_ZV_FAT32_Str:						;R99
;R110 		db	'0V-Suspend FAT32 file reserved.',0	;R99
;R110 Reserve_ZV_HDD_Str:
;R110 		db	'0V-Suspend partition reserved.',0
;R110 Require_ZV_HDD_Str:
;R110 		db	'Reserve partition for 0V-Suspend ? (Y/N) ',0
;R110 Skip_Resume_Str:
;R110		db	'0V-Suspend partition checksum error, Skip resume !',0
;R110 
;R110 
;R110 ifdef	No_0V_SPACE_WARNING
;R110 NO_RESERVE_Str:
;R110 		db	'Warning !! Can not find 0V-Suspend space or not enough, funtion will fail !!',0
;R110 endif	;No_0V_SPACE_WARNING
;R110 
endif	;Notebook_Power_Management

		Public	F000_Open_PM_RAM		
F000_Open_PM_RAM:
		F000_call	Open_PM_RAM
		ret
		Public	F000_Get_PM_RAM_Seg		
F000_Get_PM_RAM_Seg:
		F000_call	Get_PM_RAM_Seg
		ret
		Public	F000_Close_PM_RAM		
F000_Close_PM_RAM:
		F000_call	Close_PM_RAM
		ret

ifndef	NEW_SUPERVGA_KERNEL				

ifdef	LCD_CRT_OPTION		
	ifdef	CHIP_65545
		CHIP_655XX	EQU	1
	endif	;CHIP_65545
		Public	Set_SimulScan
Set_SimulScan	Proc	Near

ifdef	CHIP_655XX
		mov	ax,5F51h
		mov	bl,2			;SimulSCAN
		int	10h			;set display type
endif	;CHIP_655XX
ifdef	CL_GD754X
		mov	al,2			;SimulSCAN
		mov	ah,12h
		mov	bl,92h
		int	10h			;set display type
endif	;CL_GD754X
		ret
Set_SimulScan	Endp

		Public	Switch_Display
Switch_Display	Proc	Near

		pusha
		push	ds
		push	es

		Call	F000_Open_PM_RAM
		Call	F000_Get_PM_RAM_Seg
		mov	ds,ax
		ASSUME	DS:PM_RAM

		mov	si,offset Disp_Mode_Item
		call	F000_GetItem_Value

ifdef	CHIP_655XX

		push	ax
		mov	byte ptr PM_RAM:Display_Mode,2
		F000_Call	Disable_CRT
		pop	ax
ifndef	NO_CRT_AUTO_DETECT		
ifdef	LCD_ONLY			       
		mov	al,1		       
else	;LCD_ONLY			       
		cmp	al,3
		jne	short Follow_Setup

		mov	ax,5F55h		
		mov	bx,0001h		; Monitor Detect
		mov	cx,1000h
		xor	dx,dx
		int	10h

		mov	al,bl
		mov	bl,01h			;Output to LCD
		cmp	al,02h			;No monitor?
		je	short @F		;Yes
ifdef	AUTO_USE_DUAL_SCAN			
		mov	bl,02h			
else	;AUTO_USE_DUAL_SCAN			
		mov	bl,00h			;Output to CRT
endif	;AUTO_USE_DUAL_SCAN			
@@:
		jmp	short @F	
Follow_Setup:

endif	;LCD_ONLY				
endif	;NO_CRT_AUTO_DETECT			
		mov	bl,al
		cmp	al,1
		je	short @F
		xor	bl,02h
@@:
		mov	PM_RAM:Display_Mode,bl
		mov	ax,5F51h
		int	10h			;set display type

		F000_Call	Enable_CRT

endif	;CHIP_655XX
ifdef	CL_GD754X

		push	ax
		mov	byte ptr PM_RAM:Display_Mode,2
		F000_Call	Disable_CRT
		pop	ax

		cmp	al,3
		jne	short Follow_Setup

		mov	ax,12A1h		
		mov	bl,0A1h			;read Monitor ID/Type
		int	10h

		mov	al,0			;Output to LCD
		cmp	bh,0Fh			;No monitor?
		je	short @F		;Yes
ifdef	AUTO_USE_DUAL_SCAN			
		mov	al,2			
else	;AUTO_USE_DUAL_SCAN			
		mov	al,1			;Output to CRT
endif	;AUTO_USE_DUAL_SCAN			
@@:
		jmp	short @F		
Follow_Setup:

		sub	al,1
		jnc	short @F
		mov	al,2
@@:
		mov	PM_RAM:Display_Mode,al
		mov	ah,12h
		mov	bl,92h
		int	10h			;set display type

		F000_Call	Enable_CRT

endif	;CL_GD754X
End_Switch:					
		Call	F000_Close_PM_RAM

		pop	es
		pop	ds
		popa

		ret

Switch_Display	Endp
endif	;LCD_CRT_OPTION		

endif	;NEW_SUPERVGA_KERNEL				

;R115 - starts
ifndef	VSA_VGA						;R115A
Prepare_Variable_For_HDD_Timer	Proc	Near

		push	ds
		push	es

		push	SEG G_RAM
		pop	es
		push	SEG APM_HDD_Drive_Port
		pop	ds

		F000_call HDD_Standby_Offset
		call	F000_GetItem_Value
		mov	di, offset APM_HDD_TIMER_VALUE
		mov	ds:[di], al

		mov	si, offset G_RAM:HDD_Drive_Port
		mov	di, offset APM_HDD_Drive_Port
		mov	al, es:[si]
		mov	ds:[di], al

		mov	di, offset APM_HDD_EXIST_Flag
		mov	al, HDD_EXIST_Flag[bp]
		mov	ds:[di], al

		pop	es
		pop	ds

		ret

Prepare_Variable_For_HDD_Timer	Endp
endif	;VSA_VGA					;R115A
;R115 - ends

ENDIF	;PM_SUPPORT

;R115 ;[]------------------------------------------[]
;R115 ;Function :	Set the IDE HDD Standby Timer
;R115 ;
;R115 ;Input    :	AL = number of minutes,
;R115 ;		e.g. AL=1 --> 1 Min
;R115 ;
;R115 ;Output   :	None
;R115 ;
;R115 ;Destroy  :	FLAGS
;R115 ;[]------------------------------------------[]
;R115 Set_HDD_Standby_Timer	Proc	Near
;R115 
;R115 		push	cx
;R115 		push	dx
;R115 		push	bx
;R115 		push	ds
;R115 		mov	bx,G_RAM
;R115 		mov	ds,bx
;R115 		assume	ds:G_RAM
;R115 		xor	bl,bl
;R115 
;R115 		mov	cl,12			;1 unit is 5 second
;R115 		mul	cl			;one minute is 12 units
;R115 		mov	ch,al
;R115 Set_4_IDE_Loop:
;R115 		cmp	HDD_EXIST_Flag[bp],bl
;R115 		jbe	short No_Else_HDD
;R115 		mov	dx,1F2h			;sector count register
;R115 		mov	cl,bl
;R115 		shl	cl,1
;R115 		mov	bh,byte ptr HDD_Drive_Port
;R115 		shr	bh,cl
;R115 		test	bh,2			;Is primary channel?
;R115 		jz	short @F		;Yes,jump
;R115 		sub	dl,80h
;R115 @@:
;R115 		out	dx,al			;set the seconds
;R115 		iodelay
;R115 
;R115 		add	dl,4
;R115 		mov	al,0a0h
;R115 		test	bh,1			;Is master drive?
;R115 		jz	short @F		;Yes,jump
;R115 		mov	al,0b0h			;set salve drive
;R115 @@:
;R115 Set_timer_loop:
;R115 		out	dx,al
;R115 		iodelay
;R115 		inc	dl
;R115 
;R115 		mov	al,0e3h
;R115 		out	dx,al
;R115 		iodelay
;R115 		push	cx
;R115 		xor	cx,cx
;R115 @@:
;R115 		in	al,dx
;R115 		newiodelay
;R115 		test	al,80h
;R115 		jz	short @F
;R115 		loop	@B
;R115 @@:
;R115 		pop	cx
;R115 		in	al,dx
;R115 		iodelay
;R115 		test	al,1
;R115 		jz	short @F
;R115 		push	ax
;R115 		push	dx
;R115 		mov	dl,bl
;R115 		add	dl,80h
;R115 		xor	ah,ah
;R115 		int	13h
;R115 		pop	dx
;R115 		pop	ax
;R115 @@:
;R115 		inc	bl
;R115 
;R115 		mov	al,ch
;R115 		jmp	short Set_4_IDE_Loop
;R115 No_Else_HDD:
;R115 		pop	ds
;R115 		pop	bx
;R115 		pop	dx
;R115 		pop	cx
;R115 No_HDD_Item:
;R115 		ret
;R115 Set_HDD_Standby_Timer	EndP

if	DESKTOP_Power_Management	EQ	2	;for notebook
ifndef	No_HotKey_Set_PM

		public	PM_Save_USER_Define
PM_Save_USER_Define	proc	near
		push	si
		push	di
		push	bx
		push	cx
		push	dx
		push	es
		push	ds
		push	0F000h
		pop	ds
		push	word ptr USE_ITEMSTAT_BUF[bp]
		mov	byte ptr USE_ITEMSTAT_BUF[bp],1

		xor	cx,cx
		mov	si,offset PM_Auto_Table
		mov	cl,byte ptr DS:[si]
		mov	bx,(4 shl 1)
		dec	bx
		mov	di,DS:[si+bx]
		xor	bx,bx
	loopA:
		mov	dx,DS:[di+bx].RomReg
		push	cx
		push	bx
		push	ax
		push	si
		push	di

		xor	cx,cx
		mov	si,offset PM_FEATURE_START
search_menu_loopB:
		test	word ptr DS:[si].ItemStat,AUTOPROG
		jz	short Not_AUTOITEM
		cmp	word ptr DS:[si].CtReg,dx
		jne	short Not_AUTOITEM

		push	dx
		push	cx
		push	si
		push	di
		xor	di,di
		mov	ax,DS:[SI].CtRegMask
		mov	cx,-1			;Init shift value
	Next_Bit_ROL:
		inc	cx
		ror	ax,1
		jnc	short Next_Bit_ROL
		push	cx
		mov	bx,si
		F000_call	read_Item_Value
		mov	ax,dx
		pop	cx
		shl	ax,cl
		pop	di
		pop	si
		pop	cx
		pop	dx

		or	cx,ax
	Not_AUTOITEM:
		add	si,ITEM_SIZE
		cmp	si,offset PM_Feature_END
		jne	short search_menu_loopB
	loopB_END:
		pop	di
		pop	si
		pop	ax
		pop	bx
		mov	DS:[di+bx].RomValue,cx
		add	bx,ROMITEM_SIZE
		pop	cx
		loop	short loopA

		pop	word ptr USE_ITEMSTAT_BUF[bp]
		pop	ds
		pop	es
		pop	dx
		pop	cx
		pop	bx
		pop	di
		pop	si

		ret
PM_Save_USER_Define	endp

;[]=========================================================================[]
;Procedure Name: Get_PMITEM_Value
;Input : SI = Item offset
;	 BX = Power saving method 0=disable,1=Min save,2=Max save,3=user define
;				  
;Output: AX = item value set
;[]=========================================================================[]
Get_PMITEM_Value	proc	near
		push	bx
		push	cx
		push	dx
		push	di
		push	ds
		push	0F000h
		pop	ds
		mov	dx,DS:[si].CtReg
		mov	ax,DS:[si].CtRegMask
		push	ax
		mov	cx,-1			;Init shift value
Next_shift:
		inc	cx
		ror	ax,1
		jnc	short Next_shift
		pop	ax
		mov	di,offset PM_Auto_Table
		inc	bx
		shl	bx,1
		dec	bx
		mov	di,DS:[di+bx]
		xor	bx,bx
		sub	bx,ROMITEM_SIZE
	@@:
		add	bx,ROMITEM_SIZE
		cmp	dx,DS:[di+bx].RomReg
		jne	short @B
		mov	dx,DS:[di+bx].RomValue
		and	ax,dx
		shr	ax,cl

		pop	ds
		pop	di
		pop	dx
		pop	cx
		pop	bx
		ret
Get_PMITEM_Value	ENDP

endif	;No_HotKey_Set_PM
endif	;DESKTOP_Power_Management	EQ	2

;R112 start
ifdef	VSA_VGA
ifdef	S2D_SUPPORT
;[]========================================================================[]
;Procedure:	Reserve_ZV_HDD
;
;Function :	Routine to check 0V partition and reserve cylinders for
;		0V partition
;
;Input	  :	None
;
;Output   :	None
;
;Note	  :
;
;	The following is 0V suspend partition save location brief..
;
;	Sector 0	  : For ID sector.
;
;				Byte 0 - 23  : Chipset Name & Part No.(24 Bytes)
;					AA55AA55 = Skip reserve 0V partition.
;
;				Byte 24 - 25 : Suspend checksum.(2 Bytes)
;
;				Byte 26 - 29 : ID for ZVHDD.EXE.(4 Bytes)
;					AA55AA55 = 0V partition exist.
;
;				Byte 30 - 31 : Current HDD total cylinder.
;
;	Sector 1 - 64	  : For Save SMBASE. (32 KB)
;
;	Sector 65 - 2112  : For Save BASE Mmemory. (1024 KB)
;		            (640 KB DRAM & C0000 - FFFFF Shadow RAM )
;			    (Usually, we do not care A0000 - BFFFF shadow)
;
;	Sector 2113 - 6208: For Save VIDEO Mmemory. (2048KB)
;
;	Sector 6209 - Max : For Save EXT Mmemory.
;
;[]========================================================================[]
		PUBLIC	Reserve_ZV_HDD
Reserve_ZV_HDD	PROC	NEAR
		pushad
		push	ds
		push	es

		cli

		call	Get_EXT_Memory
		shl	ecx,6				; 1K block
		mov	ebx,ecx				;
		add	ebx,1024+4096			; Add base memory and video memory

		call	F000_Get_PM_RAM_Seg
		mov	ds,ax
		call	F000_Open_PM_RAM

		mov	ax,G_RAM
		mov	es,ax

		cmp	byte ptr HDD_EXIST_Flag[bp],0
		je	short End_Reserve_HDD1
;R74 start
		mov	cl,es:HDD_Drive_Port
		and	cl,3
		mov	ah,es:HDD_MODE_FLAG
		shr	ah,cl
		shr	ah,cl
		and	ah,3
		shl	ah,2
		or	ah,cl
		or	ds:[ZV_HDD_Scheme],ah
;R74 end
		mov	si,word ptr es:[DR0VECTOR]	; Get HDD table pointer.
		mov	ax,word ptr es:[DR0VECTOR+2]
		mov	es,ax

		mov	cl,es:[si+2]		; Max. Head   / cylinder.
		mov	al,es:[si+0eh]		; Max. Sector / head.

		mov	ds:[Head_Sector],al	; Init Sectors per head

		mul	cl

		mov	ds:[Cylinder_Sector],ax	; Init Sectors per Cylinder

		Call	Ck_SUS_Partition
		jnc	short End_Reserve_HDD1
		Call	Ck_SUS_FAT_File
End_Reserve_HDD1:

		call	F000_Close_PM_RAM

	; Clear temp memory

		mov	ax,04000h
		mov	es,ax
		xor	eax,eax
		xor	di,di
		mov	cx,2000h			;clear 32K
		cld
		rep	stosd

		pop	es
		pop	ds
		popad

		RET
Reserve_ZV_HDD	ENDP

;[]========================================================================[]
;Procedure:	Ck_SUS_FAT_File
;
;Function :	Routine to check 0v-suspend is use FAT file or not
;
;Input	  :	None
;
;Output   :	CF = 1  not use FAT file
;		CF = 0  use FAT file
;Note	  :
;
;[]========================================================================[]
PART_BUFFER	EQU	000h
EXT_PART_BUFFER	EQU	200h
BOOT_BUFFER	EQU	400h
EXT_PARTITION	EQU	05h

		ALIGN	4
Ck_SUS_FAT_File	Proc	Near

		push	es
		push	si
		push	ax
;R73		push	bx
		push	ebx			;R73

	; Read partition table

		Call	Read_Partition
		cmp	word ptr es:[di+1feh],0AA55h
		jne	short Bad_File

		add	di,01BFh		; Starting sector/head/Cylinder
		mov	cx,4
Find_FAT_part:
		Call	Ck_FAT_Partition_Exist
		jc	short End_Check		;Not FAT system

		push	di

		cmp	al,EXT_PARTITION
		jne	short _P11

		Call	Read_Ext_Partition
		cmp	word ptr es:[di+1feh],0AA55h
		je	short check_file
		pop	di
		jmp	short End_Check
Check_File:
		add	di,1bfh			; Starting sector/head/Cylinder
_P11:
		Call	Ck_FAT_File_Exist
		pop	di
		jnc	short FAT_File_Exist	;Get FAT File
End_Check:
		add	di,16
		loop	short Find_FAT_part

		jmp	short Bad_File
FAT_File_Exist:

;R73		xor	eax,eax

;R73		pop	ax
;R73		push	ax
		pop	eax			;R73
		push	eax			;R73


;R73		shl	eax,10			; system request space
		shl	eax,1			;R73 1K = 2 sectors
		add	eax,1
		shl	eax,9			;R73A 1 sector = 512 Bytes

		cmp	edx,eax			; Is reserved space enough ?
		jb	short bad_File		; No

		clc
_C22:
;R73		pop	bx
		pop	ebx			;R73
		pop	ax
		pop	si
		pop	es
		ret
Bad_File:
	; Clear start sector number of Zero-Volt partition

		mov	dword ptr ds:[ZV_HDD_Sector],0
		stc
		jmp	short _C22


Ck_SUS_FAT_File	Endp

;[]========================================================================[]
;Procedure:	Ck_FAT_Partition_Exist
;
;Function :	Routine to check FAT system exist or not
;
;Input	  :	ES:[DI+3] = Partition Type (byte)
;			= 00h	unknown
;			= 01h	DOS with 12-bit FAT
;			= 04h	DOS with 16-bit FAT
;			= 05h	extended DOS partition
;			= 06h	32-bit FAT (OS/2 FAT)
;			= 07h	OS/2 HPFS
;			= DBh	concurrent DOS
;			= 0Ah   MultiBoot Maganer
;			= 0Bh   Windows95 FAT32			;R99
;			= 17h   Windows NT NTFS
;			= 16h   Windows95 (Windows4.0) FAT
;
;Output   :	CF = 1  Not FAT system
;		CF = 0  FAT system
;		AL =    Parttion Type
;Note	  :
;
;[]========================================================================[]
		ALIGN	4
Ck_FAT_Partition_Exist	Proc	Near

		mov	si,offset Part_Tbl
	@@:
		lods	byte ptr cs:[si]
		cmp	al,0FFh
		je	short @F

		cmp	es:[di+3],al
		jne	short @B

		clc
		ret
	@@:
		stc
		ret
Ck_FAT_Partition_Exist	Endp

Part_Tbl:
		db	001h	;DOS with 12-bit FAT
		db	004h	;DOS with 16-bit FAT
		db	005h	;extended DOS partition
		db	006h	;32-bit FAT (OS/2 FAT)
		db	00Bh	;32-bit FAT (Windows95 FAT32)	;R99
		db	00Ch	;32-bit FAT (Windows95 FAT32)	;R26A
		db	016h    ;Windows95 (Windows4.0) FAT
		db	0FFh

;[]========================================================================[]
;Procedure:	Read_Ext_Partition
;
;Function :	Routine to read extended partition sector
;
;Input	  :	ES:[DI]  Extended Partition sector
;
;Output   :	CF = 1  Partition not exist
;		CF = 0  Partition exist
;		DI = first parttion point
;Note	  :
;
;[]========================================================================[]
Read_Ext_Partition	Proc	Near

		push	cx

		Call	Get_Start_Sector

	;Read Extended Partition Sector

		mov	ebx,edx
		mov	ah,20h			; Read command
		mov	al,1			; Sector Count
		mov	edi,EXT_PART_BUFFER
		call	HDD_Transfer

		pop	cx

		ret

Read_Ext_Partition	Endp

Get_Start_Sector	Proc	Near

	;Startint setcor :
	;  =  ( Sectors pre head * head pre cylinder * starting Cylinder )
	;  + ( Sectors pre head * Starting head )
	;  + ( Starting sector ) - 1 			;Zero base

		mov	ah,es:[di+1]		; Starting cylinder
		and	ah,0c0h
		shr	ah,6
		mov	al,es:[di+2]
		mul	word ptr ds:[Cylinder_Sector]
		shl	edx,16
		mov	dx,ax

		xor	eax,eax
		mov	al,es:[di]		; Starting head
		mul	byte ptr ds:[Head_Sector]
		add	edx,eax

		xor	eax,eax
		mov	al,es:[di+1]		; Starting sector
		and	al,3Fh
		dec	al
		add	edx,eax			; Logical starting sector

		ret

Get_Start_Sector	Endp

;[]========================================================================[]
;Procedure:	Ck_FAT_File_Exist
;
;Function :	Routine to check file (sus2disk.awa) exist or not
;
;Input	  :	ES:[DI]  DISK BOOT SECTOR
;
;Output   :	CF = 1  file not exist
;		CF = 0  file exist
;		EDX = file size
;Note	  :
;
;[]========================================================================[]

FAT_TYPE_STR	db	'FAT12   ',FAT_12bit
FAT_TYPE_LEN	EQU	$ - FAT_TYPE_STR
		db	'FAT16   ',FAT_16bit
;;;;		db	'FAT32   ',FAT_32bit
		db	'FAT     ',FAT_16bit
FAT_TYPE_END:
FAT32_TYPE_STR:						;R99
		db	'FAT32   ',FAT_32bit		;R99

FAT_FILE_NAME	db	'SAVE2DSKBIN'
FAT_FILE_LEN	EQU	$ - FAT_FILE_NAME

		ALIGN	4
Ck_FAT_File_Exist	Proc	Near

		push	cx

		Call	Get_Start_Sector

	;Read Disk Boot Sector

		push	di

		mov	ebx,edx
		mov	ah,20h			; Read command
		mov	al,1			; Sector Count
		mov	edi,BOOT_BUFFER
		call	HDD_Transfer

		cmp	word ptr es:[di+1feh],0AA55h
		je	short @F
		stc
		jmp	end_Fine
@@:
	;Strating Data area :
	;	=  ( Boot Disk sector + FAT sectors + Root dir ectors )

;R99		inc	ebx

	; Calculator sector pre cluster

		mov	al,byte ptr es:[di+0Dh]		; Sectors Pre Cluster
		mov	ds:[Cluster_Sector],al

	; Check FAT type

		push	ds
		push	di
;R99 - start
	;; check FAT32 string first

		add	di,52h			;Point to File-system ID

		push	cs
		pop	ds
		mov	si,offset FAT32_TYPE_STR
		push	si
		mov	cx,FAT_TYPE_LEN - 1
		repz	cmpsb
		pop	si
		jz	short @F

	;; If not FAT32 system , check FAT16 or FAT12
		pop	di
		push	di
;R99 - end
		add	di,36h			;Point to File-system ID

		push	cs
		pop	ds
		mov	si,offset FAT_TYPE_STR
_Next:
		push	si
		push	di
		mov	cx,FAT_TYPE_LEN - 1
		repz	cmpsb
		pop	di
		pop	si
		jz	short @F

		cmp	si,((offset FAT_TYPE_END) - FAT_TYPE_LEN)
;R75		jae	short @F
;R75 - start
		jb	short Next_FAT_TYPE

		pop	di
		pop	ds
		stc
		jmp	end_Fine
Next_FAT_TYPE:
;R75 - end

		add	si,FAT_TYPE_LEN
		jmp	short _Next
@@:
		add	si,FAT_TYPE_LEN - 1
		lodsb				;Get FAT size
		pop	di
		pop	ds
		mov	ds:[FAT_TYPE],al
		cmp	al,FAT_32BIT		;R99
		je	Check_FAT32_File	;R99

		inc	ebx			;R99
	; Calculator FAT area sectors

		mov	ax,word ptr es:[di+16h]	; Sector per FAT
		mov	cl,byte ptr es:[di+10h]	; FAT copies
		xor	ch,ch
		mul	cx
		shl	edx,16
		mov	dx,ax			; Total secotrs of FAT
		add	ebx,edx

	; Calculator Root dir area sectors

		xor	eax,eax
		mov	ax,word ptr es:[di+11h]	; Root directory entries
		mov	cx,20h			; Directory entries size
		mul	cx
		mov	cx,512
		div	cx			; Total secotrs of Root
		or	dx,dx
		jz	short @F

		inc	al
@@:
		push	eax
		push	edi
		mov	cx,word ptr es:[di+11h]	; Root directory entries

		mov	ah,20h			; Read command
		mov	edi,400h		; Write to 400h
		call	HDD_Transfer

		push	ds
		push	cs
		pop	ds
@@:
		push	cx
		push	di
		mov	cx,FAT_FILE_LEN		;file name lenght
		mov	si,offset FAT_FILE_NAME
		repz	cmpsb
		pop	di
		pop	cx
		jnz	short No_Find

		mov	ax,es:[di+1Ah]		;starting cluster number
		mov	edx,es:[di+1Ch]		;File size
		clc
		jmp	short Find_It
No_Find:
		add	di,20h
		loop	short @B
		stc
find_it:
		pop	ds
		pop	edi
		pop	ecx
		jc	end_Fine

		push	edx
		add	ebx,ecx				; data area
		mov	ds:[ZV_HDD_Sector],ebx

		sub	ax,2
		xor	bh,bh
		mov	bl,byte ptr ds:[Cluster_Sector]
		mul	bx
		xchg	dx,ax
		shl	eax,16
		mov	ax,dx
		add	ds:[ZV_HDD_Sector],eax
		pop	edx


		clc
end_Fine:
		pop	di
		pop	cx

		ret

Ck_FAT_File_Exist	Endp

;R99 - start
Check_FAT32_File	Proc	Near

		mov	FAT32_SECTOR_FLAG[bp],ebx
	; Calculator FAT area sectors

		xor	eax,eax
		mov	ax,es:[di+0Eh]		; Reserved sector at begin
		add	ebx,eax

		mov	eax,es:[di+24h]		; Sector per FAT
		xor	ecx,ecx
		mov	cl,byte ptr es:[di+10h]	; FAT copies
		mul	ecx
		add	ebx,eax			; Add Total secotrs of FAT
		mov	FAT32_ROOT_FLAG[bp],ebx

Check_Next_Root_Cluster:
		mov	ah,20h			; Read command
		mov	al,ds:[Cluster_Sector]	; Read 1 cluster
		mov	edi,400h		; Write to 400h
		call	HDD_Transfer

		mov	cl,(512/20h)
		mul	cl
		mov	cx,ax
@@:
		push	ds
		push	cs
		pop	ds
		push	cx
		push	di
		mov	cx,FAT_FILE_LEN		;file name lenght
		mov	si,offset FAT_FILE_NAME
		repz	cmpsb
		pop	di
		pop	cx
		pop	ds
		jnz	short No_Find_FAT32

		mov	ax,es:[di+14h]		;starting cluster number
		shl	eax,16
		mov	ax,es:[di+1Ah]		;starting cluster number
		mov	edx,es:[di+1Ch]		;File size
		clc
		jmp	short Find_FAT32_File
No_Find_FAT32:
		add	di,20h
		loop	short @B

		Call	Skip_To_Next_Cluster
		jnc	short Check_Next_Root_Cluster

Find_FAT32_File:
		jc	short End_FAT32_Fine

		push	edx
		sub	eax,2
		xor	ecx,ecx
		mov	cl,byte ptr ds:[Cluster_Sector]
		mul	ecx
		add	eax,FAT32_ROOT_FLAG[bp]
		mov	ds:[ZV_HDD_Sector],eax
		pop	edx

		clc
End_FAT32_Fine:
		pop	di
		pop	cx

		ret

Check_FAT32_File	Endp

;input : EDX = cluster Number
;Ouput : CF  = 1    No next cluster
;	 CF  = 0    Find next cluster
;	     EDX = next cluster Number
;	     EBX = next cluster sector number
Skip_To_Next_Cluster	Proc	Near

		xor	eax,eax
		mov	ax,dx
		shr	edx,16

		mov	bx,(512 / 4)
		div	bx
		mov	ebx,FAT32_SECTOR_FLAG[bp]
		add	ebx,eax

		mov	ah,20h			; Read command
		mov	al,ds:[Cluster_Sector]	; Read 1 cluster
		mov	edi,400h		; Write to 400h
		call	HDD_Transfer

		shr	edx,2
		add	edi,edx

		mov	edx,es:[edi]		; Get next cluster number
		cmp	edx,0FFFFFF8h		; Linker end ?
		jae	short @f		; Yes

		sub	edx,2			;Frist Cluster
		mov	eax,edx
		push	edx
		xor	ecx,ecx
		mov	cl,ds:[Cluster_Sector]
		mul	ecx
		pop	edx

		mov	ebx,FAT32_ROOT_FLAG[bp]
		add	ebx,eax

		clc
		ret
@@:
		stc
		ret
Skip_To_Next_Cluster	Endp
;R99 - end
;[]========================================================================[]
;Procedure:	Read_Partition
;
;Function :	Routine to read partition sector
;
;Input	  :	none
;
;Output   :	ES:[DI]  Partition sector
;
;Note	  :
;
;[]========================================================================[]
Read_Partition	Proc	Near

		xor	ebx,ebx
		mov	ax,04000h
		mov	es,ax
		mov	ah,20h			; Read command
		mov	al,1			; Sector Count
		mov	edi,PART_BUFFER
		call	HDD_Transfer

		ret
Read_Partition	Endp

;[]========================================================================[]
;Procedure:	Ck_SUS_Partition
;
;Function :	Routine to check 0V-suspend is use partition or not
;
;Input	  :	None
;
;Output   :	CF = 1 partition not exist
;		CF = 0 partition exist
;Note	  :
;
;[]========================================================================[]
RESERVED_TYPE	EQU	0A0h
Ck_SUS_Partition	Proc	Near

	; Get the Min. 0V partition size.

		mov	cx,512			; 512 byte / sector.
		mul	cx
		mov	cx,1024
		div	cx
		or	dx,dx
		jz	short @F
		xor	dx,dx
		inc	ax
	@@:
		mov	cx,ax			; ??KB / cylinder.
		push	ebx			;
		pop	ax			;
		pop	dx			;
		div	cx			; Get cylinders for reserved.
		or	dx,dx
		jz	short @F
		inc	ax
	@@:

		push	es
		push	si
		push	ax
		push	ebx			;R73

	; Read partition table

		Call	Read_Partition

		cmp	word ptr es:[di+1feh],0AA55h
		je	short @F
		pop	ebx			;R73
		pop	ax
		pop	si
		jmp	No_Reserve_HDD
@@:

		xor	edx,edx

		add	di,01efh		; 4st partition type
		cmp	byte ptr es:[di+3h],RESERVED_TYPE
		jne	short No_Find_Partition

		mov	edx,dword ptr es:[di+0bh]
No_Find_Partition:
		pop	ebx			;R73
		pop	cx
		pop	si

		mov	eax,ebx			;R73
		shl	eax,1			; system request space
		add	eax,1			; 1 ID sector

		cmp	edx,eax			; Is reserved space enough ?
		jb	short No_Reserve_HDD	; No

		mov	ah,es:[di+1]		; Starting cylinder
		and	ah,0c0h
		shr	ah,6
		mov	al,es:[di+2]
		mul	word ptr ds:[Cylinder_Sector]
		shl	edx,16
		mov	dx,ax

	; Initial start sector number of Zero-Volt partition

		mov	dword ptr ds:[ZV_HDD_Sector],edx

End_Reserve_HDD:
		pop	es
		clc
		ret

No_Reserve_HDD:
		pop	es
		stc
		ret

Ck_SUS_Partition	Endp

;[]========================================================================[]
;Procedure:	Get_EXT_Memory
;
;Function :	To return extended memory size.
;
;Input	  :	None
;
;Output   :	CX = Extended memory size (K Byte).
;
;[]========================================================================[]

Get_EXT_Memory	proc	near
		push	es
		mov	si,seg ExtMem128Mb
		mov	es,si
		mov	si,offset ExtMem128Mb
		mov	ecx,dword ptr es:[si+08h]
		shr	ecx,16				;64K block
		mov	word ptr PAGE_START[bp],cx	;
		pop	es
		ret
Get_EXT_Memory	endp

;[]===============================================================[]
;
; HDD_Transfer :
;
;	The routine does data transfer to/from HDD.
;
; Entry:
;	AH = 30h  write
;          = 20h  read
;	AL = sector count.
;       DS:SI = Address for writing.
;       ES:DI = Address for reading.
;       CX = cylinder number.
;       DH = Head number.
;       DL = starting sector number.
;
; Exit:
;	JNC = successful. JC = failed
;       ESI Or EDI updated pointer after the Write / Read operation.
;
; Note:
;
;[]==================================================================[]
Hdd_Register		EQU	03f6h	; Hdd register.
Hdd_Rdy			EQU	40h	; Drive ready bit.
Hdd_Busy		EQU	80h	; Drive busy bit.
Hdd_Drq			EQU	08h	; Drive DRQ bit.
Hdd_Seek_Cmd		EQU	70h	; Drive seek command.
Write_command		EQU	30h	; Hdd write multi-sector command.
Read_command		EQU	20h	; Hdd read multi-sector command.

		Public	HDD_Transfer
HDD_Transfer	proc	near

		pushad

		call	Get_HDD_Parm		; Get the Location parameter

		push	eax
		push	ecx
		push	dx
		push	bp

		mov	ebp,esp			; Get stack top.
Resend_HDD_Cmd:					;
		call	Test_CTLR_Busy

		mov	al,[bp+3]
		call	Get_HDD_Port_Base	;
		add	dl,6			;
		out	dx,al
		call	Test_CTLR_Busy		;
		call	Test_HDD_Rdy

; Feed the task file of HDD with relevent values.

		mov	al,[bp+8]
		call	Get_HDD_Port_Base	;
		add	dl,2			;
		out	dx,al

		mov	al,[bp+2]
		inc	dx			; Starting sector number.(1F3)
		out	dx,al

		mov	al,[bp+4]
		inc	dx			; Cylinder low.(1F4)
		out	dx,al

		mov	al,[bp+5]
		inc	dx			; Cylinder high.(1F5)
		out	dx,al

		inc	dx			; SDH reg.(1F6)
		mov	al,[bp+3]		;
		out	dx,al			;
		push	dx			;
		call	Test_CTLR_Busy		;
		call	Test_HDD_Rdy		;
		pop	dx			;

;Now we flash the command.

		mov	al,[bp+9]
		inc	dx			; Get command reg.(1F7)
		out	dx,al			; Flash the command.

		newiodelay
		call	Test_CTLR_Busy
		in	al,dx
		test	al,1
		jnz	short error_xfer

		mov	ah,3			;
		xor	cx,cx			;
	@@:
		NEWIODELAY			;
		NEWIODELAY			;
		in	al,dx
		test	al,HDD_DRQ

		jnz	short HDD_Cmd_OK
		loop	@B
		dec	ah
		jnz	short @B
		test	al,HDD_DRQ
		jz	short Resend_HDD_Cmd
HDD_Cmd_OK:

;Now we need to find out if it is read or write command.

		mov	al,[bp+9]
		cmp	al,Write_command
		jz	fill_buffer

;It is a read command so we need to read the buffer.

read_buffer:
		xor	ecx,ecx			; 32 bit type uses ecx.
		mov	cx,100h
		call	Get_HDD_Port_Base	;
		cld
		push	edi
		ALIGN	4
		db	67h			; Address size over-ride.
		rep 	insw
		pop	edi
		xor	eax,eax
		mov	ax,200h
		add	edi,eax
		add	dx,7
	@@:
		in	al,dx
		test	al,HDD_BUSY
		jnz	short @B
		in	al,dx
		test	al,HDD_DRQ
		jnz	read_buffer
		jmp	done_xfer

fill_buffer:
		xor	ecx,ecx
		mov	cx,100h
		call	Get_HDD_Port_Base	;
		cld
		push	esi
		ALIGN	4
		db	67h			; Address size over-ride.
		rep 	outsw
		pop	esi
		xor	eax, eax
		mov	ax, 200h
		add	esi, eax
		add	dx,7
	@@:
		in	al,dx
		test	al,HDD_BUSY
		jnz	short @B
		in	al,dx
		test	al,HDD_DRQ
		jnz	fill_buffer

done_xfer:
		jmp	short no_error_xfer

error_xfer:
		stc
;		POST_CODE	0edh
;		jmp	$
		pop	bp
		pop	dx
		pop	ecx
		pop	eax
		popad
		ret

no_error_xfer:
		call	Test_CTLR_Busy
		pop	bp
		pop	dx
		pop	ecx
		pop	eax
		popad
		ret
HDD_Transfer	endp

;===========================================================================
;FUNC:  TEST_HDD_RDY
;
;DESC:  Tests if the HDD controller is ready to accept commands.
;
;IN:    None
;
;OUT:   None
;===========================================================================
Test_CTLR_Busy:
		call	Get_HDD_Port_Base	;
		add	dl,7			;
	@@:
		in	al,dx			; Get Status value.
		test	al,HDD_BUSY
		jz	short @F
		mov	cx,40h
		call	Small_Delay
		jmp	short @B

	@@:
		ret

Test_HDD_Rdy	proc	near

		call	Get_HDD_Port_Base	;
		add	dl,7			;
	@@:
		in	al,dx			; Get Status value.
		test	al,HDD_RDY		; HDD_BUSY
		jnz	short @F
		mov	cx,40h
		call	Small_Delay
		jmp	short @B
	@@:

		ret
Test_HDD_Rdy	endp

;[]===============================================================[]
;
; Get_HDD_Parm
;
;	The routine to return HDD location parameter for R/W.
;
; Entry:
;	EBX = absolute sector number.
;
; Exit:
;       CX = cylinder number.
;       DH = Head number.
;       DL = starting sector number.
;
; Note:
;
;[]==================================================================[]
Get_HDD_Parm	Proc	Near

		push	ax
		push	ebx

		call	F000_Get_PM_RAM_Seg
		mov	fs,ax

		mov	dl,fs:[ZV_HDD_Scheme]
		shr	dl,2
		and	dl,3
		cmp	dl,1			;HDD is LBA mode?
		jne	short @F		;No,jump to Large or Normal mode

		mov	dl,bl
		mov	cl,bh
		shr	ebx,16
		mov	ch,bl
		mov	dh,bh
		and	dh,0fh
		or	dh,0E0H			; LBA SDH

		test	byte ptr fs:[ZV_HDD_Scheme],1	;check on master
		jz	short ZV_HDD_on_master		;Yes,jump
		or	dh,10h				;set to slave
ZV_HDD_on_master:


		jmp	short End_Get_HDD_Parm
@@:

		xor	ecx,ecx
		mov	ax,bx
		shr	ebx,16
		mov	dx,bx
		mov	cx,word ptr fs:[Cylinder_Sector]
		div	cx			; Get Cylinder
		mov	cx,ax
		mov	ax,dx
		mov	bl,byte ptr fs:[Head_Sector]
		div	bl
		mov	dl,ah
		inc	dl

		mov	bl,fs:[ZV_HDD_Scheme]	;R27A
		shr	bl,2			;R27A
		and	bl,3			;R27A
		cmp	bl,2			;R27A;HDD is large mode?
		jne	short @F		;No,jump to Large or Normal mode

;R117		shr	al,1			;R04 head/2
;R117		shl	cx,1			;R04 cylinder*2
;R117 - Start
		mov	bl,ds:[Logical_Heads]	;get logical head number
		mov	bh,ds:[Hdd_Head]	;get real head number
Process_Head_Loop:
		cmp	bl,bh			;if logical below phicial head
		jbe	short Process_Head_Over	;yes , process over
		shl	cx,1			;otherwise cylinder*2
		shr	bl,1			;Hdd logical head/2
		jmp	short Process_Head_Loop	;do it again
Process_Head_Over:
		movzx	ax,al			;head number
		div	bh			;devide real head number
		movzx	bx,al			;
		add	cx,bx			;add it to cilinder number
		mov	al,ah			;real to access head number
@@:
;R117 - end
@@:						;R04
		and	al,0fh
		or	al, 0A0h		; sector size = 512 bytes

		test	byte ptr fs:[ZV_HDD_Scheme],1	;check on master
		jz	short ZV_HDD_on_master0		;Yes,jump
		or	al,10h				;set to slave
ZV_HDD_on_master0:

		mov	dh,al

End_Get_HDD_Parm:

		pop	ebx
		pop	ax
		ret
Get_HDD_Parm	endp

Get_HDD_Port_Base:
		push	ax
		call	F000_Get_PM_RAM_Seg
		mov	fs,ax
		mov	dx,1f0h
		test	byte ptr fs:[ZV_HDD_Scheme],2	;check on primary?
		jz	short @F
		sub	dl,80h
@@:
		pop	ax
		ret

;[]===============================================================[]
;Procedure:	Small_Delay
;Function :	Delay loop
;Input    :	CX = delay loop count.
;Output   :	None
;Preserve :	ALL
;[]===============================================================[]
Small_Delay	Proc	Near
		push	cx
	@@:
		NEWIODELAY
		loop	short @B
		pop	cx
		ret
Small_Delay	Endp

endif	;S2D_SUPPORT
endif	;VSA_VGA
;R112 end

ifdef	SMBIOS_INTERFACE
;[]========================================================================[]
; Move_SMB_ID_TBL:
; Input	: None
; Output: None
; Note	: Should build table in E-segment and must include under label(public)
;	  "SMB_DEVID_TABLE" and define dword of "SMB_DEVID_TBL_LENTH" at the end 
;[]========================================================================[]
Move_SMB_ID_TBL	proc	near
		push	ds
		push	es
		pushad

		F000_call	F000_Shadow_W

		push	0E000h
		push	0F000h
		pop	ES
		pop	DS
		extrn	SMB_DEVID_TBL_LENTH:near
		mov	cx, word ptr DS:[SMB_DEVID_TBL_LENTH]
		mov	di,offset SMB_DEVICE_TABLE	
		mov	si,offset SMB_DEVID_TABLE
	;;;; check your table length prevent detroy code
		cmp	cx, SMB_NO_OF_DEVICE
		je	short lenth_accord
	;;;; if hang here means your SMB_DEVID_TABLE wrong
		jmp	short $
lenth_accord:
	;;;; Move table
		lodsb
		stosb
		loop	short lenth_accord

		F000_call	F000_Shadow_R

		popad
		pop	es
		pop	ds

		ret
Move_SMB_ID_TBL	ENDP
endif	;SMBIOS_INTERFACE

ECODE		ENDS
		END
