;	[]===========================================================[]
;
;	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
;---------------------------------------------------------------------------
;R90	04/07/99 KVN	Fixed coding mistake that will cause setup wrong HDD
;			parameter table.This case occur on cylinders of HDD
;			nearly equte to 25230 (e.g. FUJITSUI-MPD3130AT)
;R86B	03/24/99 KVN	set flag of show warning message of 80 conductor cable
;			into stack buffer instead of ZF.That to avoid verify
;			wrong value for CHIPPOST.ASM if not be modified
;R89	03/22/99 KVN	Fixed HDD LED of M/B turn on a long time after reset
;			IDE controller.Now we send a NOP command for each
;			ATAPI device after reset IDE that can solve this problem.
;R86A	03/15/99 KVN	Return ZF for kernel code to decide show warning of
;			80 conductor cable
;R88	03/09/99 KVN	Added 2 switches for support customer request.First is
;			'Dont_support_UltraDMA_For_all_CDROM',this definition
;			can skip IDE ultra DMA be enabled when device is CDROM.
;			Secondary definition is 'Dont_support_UltraDMA_For',
;			this will skip IDE ultra DMA enable too.But only the
;			model number match with this definition.For example :
;			(Dont_support_UltraDMA_For	equ	<'Maxtor'>).
;R84A	03/09/99 KVN	Added second method to determine IDE 80 conductor cable
;			be connected or not.This function should add definition
;			"Determine_IDE_80_Cable_by_Drive" in BIOS.CFG
;R29A	03/08/99 KVN	Cancel R29 of no longer used code
;R87	03/04/99 KVN	Set IDE DMA capable status exactly for each drive.That
;			can use DMA driver (i.e. service pack 4) in NT.
;R86	03/01/99 KVN	Added a warning message for ultra DMA 66 device was
;			connected and not installed 80 conductor then show warning.
;R85	12/31/98 KVN	Fixed identify ultra DMA mode not correctly for Pioneer
;			DVD-ROM (Model : Pioneer DVD-ROM ATAPIModel DVD-103S)
;R84	12/10/98 KVN	Added a subprocedure in chippost for check whether
;			ultra DMA-66 interface contected or not.
;R83	12/03/98 KVN	Fixed HDD formated by PHOENIX BIOS then boot fail from
;			AWARD.The HDD model is cylinders value over 8192 and
;			heads number is 16.In this case Phoenix BIOS will
;			change HDD of heads number to 15 and re-calculate for
;			cylinders (new Cyls = Cyls*Heads / (Heads-1))
;R82	12/02/98 KVN	Support IDE DMA transfer function
;R81 	12/01/98 MIL    Fixed "No_Post_Auto_IDE_Detect" define cause compiler
;			fail.
;R80A	11/24/98 KVN	Fixed coding mistake by R80 that will cause system hang
;			on POST 42
;R80	11/23/98 KVN	Fixed ultra DMA mode stack be destroyed when BIOS define
;			E000_IDE_Special_Do and HDD type in setup set USER.
;R79	11/13/98 RAY	Support switch: MULTI_LANGUAGE_SUPPORT so that this file
;			becomes common for 4.5 & 4.6
;R78	10/28/98 KVN	Fixed WD HDD support ultra mode 4 have some problem in
;			current chipset.That is chipset only support mode 2
;			and our BIOS will depand on HDD mode to program.In this
;			case the chipset will be program to mode 2 and HDD be
;			mode 4.That cause WD hdd crashed.Now we support a
;			definition to limit maxium ultra DMA mode that called
;			"UltraDMA_MaxMode".If you don't define then BIOS default
;			maxium mode is 2.
;R77	10/22/98 KVN	Set LBA mode to LARGE parameter.That can access large
;			mode of hdd to use LBA command.If HDD is new then default
;			LBA parameter is used.You can use LARGE parameter in new
;			HDD just define "Always_Use_Large_Para" in BIOS.CFG
;R45c	10/22/98 BAR	Wait more time for HDD smart command.
;			Fixed WD WDC AC38400L can't Detect SMART Funcation.
;R76	10/20/98 KVN	Fixed CDROM test hang in QAPLUSFE v5.50
;			Test method is list below:
;			   1. made a bootable floppy diskette with LGIDECD.SYS
;			      CDROM driver and load qaplus program by LOAD.COM
;			      utility
;			   2. connect CDROM on secondary channel
;			   3. boot from floppy and auto run qaplus (by load utility)
;			      and system will hang on analysis CDROM
;R74A 	10/20/98 GAR	Fix bug. If define No_Support_4_IDE, it still search
;			4 hard disk.
;R75	10/07/98 BAR	Added define "Set_DMA_Capable_Status" to set DMA
;			Capable status
;R74	10/02/98 BAR	Fixed define support " No_Support_4_IDE "
;			compile error.
;R73	09/29/98 RAY	Instead of using F000_call for "check_if_lba_mode"
;			& "check_if_large_mode", call the corresponding
;			far routine.
;R72	09/11/98 RIC	Add "Have_CDROM_PIOMode_Item" define.
;R52A	09/09/98 RIC	Don't change the show message of UltraDMA Mode for
;			E000_IDE_Special_Do
;R71	08/24/98 BAR	Added report IDE has changed.
;			Added define "Show_IDE_Changed_Message"
;R70	08/19/98 RIC	Add "Disable_Ultra_DMA33_When_SAMSUNG_WU32543A" define
;			for customer special request.
;R69	08/11/98 KVN	Added "request sense command" to exactly report ATAPI
;			access status.That will dont delay or loop for some
;			boot fail CDROM
;R68	08/07/97 BAR	Added detect SONY  CDROM "CD-ROM CDU711 " model
;			try boot more times.
;R63B	07/30/98 KVN	Added a switch to set IOMEGA ZIP to floppy or removable
;			mode by jumper of ZIP drive.If you want control floppy
;			mode by jumper then define "ZIP_Floppy_Depand_on_Jumper"
;			in BIOS.CFG
;R67	07/24/98 KVN	Added a new switch to skip ATAPI detect if type is none
;R66	06/05/98 KVN	Reserved one cylinder for some test program (test.exe
;			by AST).Some test program diagnostic HDD R/W to examined
;			state of HDD but it use over maximun cylinder (report
;			by function 8 of int 13h) to test HDD.That we will
;			report error.Define "Reserved_1_Cyl_for_test" in BIOS.CFG
;			to fix this problem
;R65	06/04/98 KVN	Don't Set ultra DMA mode to Acer 632A CDROM (firmware
;			revision is 322P) for customer(MicroStar) issue
;R51B	05/12/98 KVN	Fixed R51 coding mistake that will cause ZIP show none
;			in system config table
;R58B	04/23/98 KVN	Fixed [SAMSUNG WA32163A] HDD hang at POST_66S
;R63A	04/16/98 RAY	Fix linking error for unresolved externals if CD_ROM
;			is not defined
;R64	04/21/98 BAR	Can't be enabled CDROM DMA mode in Windows 95.The CDROM
;			vendor is Acer and model is 'ATAPI CD-ROM DRIVE 32X MAXIMUM'
;			Test motherboard is DFI LX (part no is 2a69jd49).
;			If you enable CDROM DMA mode in Win95 but it will auto
;			be disabled on next time boot
;R63	04/16/98 KVN	IOMEGA release new ZIP drive support both original
;			ZIP mode and floppy emluation mode. BIOS need to
;			program the new drive to Floppy mode, otherwise
;			it can be booted as drive A when new firmware is
;			used.
;R62	04/01/98 RCH	Added NO_HDD_RESET_IF_NO_HDD to skip HDD reset for
;			the system have no FDD & HDD to speed up POST
;R61	03/13/98 RAY	Add Quiet_POST_SUPPORT
;R60	02/26/98 KVN	Added "IDE_DETECT_RESET" definition before Identify
;			IDE device to fixed SR200S CDROM detect fail if press
;			warmboot during detect it (2A5IJS39)
;R58A	02/25/98 KVN	Fixed IBM-DTCA-23240 HDD boot fail by R58
;R59	02/11/98 KVN	Fixed coding mistake that will cause HDD report error
;			if HDD fail > 2 (e.g. master and slave of primary)
;R58	02/11/98 KVN	Reduce HDD initialize procedure for POST quickly
;R57	02/09/98 KVN	Fixed some HDD (e.g. QUANTUM FIREBALL ST3.2A) detect
;			model be null string during POST for power on somtimes
;R56B	12/31/97 KGN	Pitch defin CDROM_UJDA110 can't use NT cdrom boot
;R56A	12/29/97 BAR	Boot from CDROM "UJDA110" ,no disk present wait long time
;			Reason:
;			  Reading time any longer other device.
;			Solution:
;			  Added define "CDROM_UJDA110" to reduce try times.
;
;R56	12/15/97 BAR	added detect pioneer 24x cdrom try more times.
;			"Pioneer CD-ROM ATAPI Model DR-A24X  0102"
;			move detect code to xgroup
;R55	12/08/97 KVN	Fixed show LS120 to CDROM in system config table
;			if standard floppy set type both A and B
;R43A	11/26/97 BAR	Fixed CD-ROM CDU571 can't boot.
;R54	11/25/97 KVN	Fixed Fujitsu MO (Model = M2541BE02) detected to HDD
;			on 2A5UQC29 BIOS that cause POST wait at 42h and show
;			correspond HDD failure
;R53	11/17/97 KVN	Remove check combo-card code to fixed floppy B drive
;			still accessable even drive B type is NONE
;R35B	11/11/97 KVN	Report physical cylinders for INT41 table.The reason
;			is some test program (from Quantum) request it must be
;			physically.
;R52	10/30/97 RIC	Add "E000_IDE_Special_Do" define.
;R51A	10/29/97 KVN	Fixed R51 coding mistake that will cause connected
;			CDROM but show ZIP in system config table when
;			correspond IDE setup CMOS type is NONE
;R51	10/23/97 KVN	Show all IDE device on system config table if define
;			support LS120/ZIP/CDROM in BIOS.CFG
;R37F	10/22/97 KVN	Added "Dont_Use_IDE_Word_6061_in_Size" switch for
;			special customer to force use tradition CHS size
;R50	10/21/97 BAR	Fixed Windows NT can't access floppy disk during setup
;			if system only connecting SCSI HD without IDE HD.
;			i.e. install SCSI driver from floppy in Windows NT
;			setup processing
;R49	10/17/97 RIC	Add "Disable_Ultra_DMA33_When_WD_HardDisk" define.
;R47A	10/09/97 BAR	Added Ultra DMA Flag  of hardware specific option
;R48	10/08/97 RIC	Add "ONCHIP_2ND_ALWAYS_DISABLE" define.
;R47	10/07/97 BAR	Added Fixed Disk Parameter Table Extension(FDPTE)
;			INT13X function 48h
;R37E	09/17/97 BAR	Fix (R37) HDD Identify word 60-61 to exactly detect size
;			for fix [Maxtor 7546AT] can't detected.
;			Because [Maxtor 7546AT] word 60-61 location is mistake
;			Don't check Identify word 60,61 if over 0ff00000h(136.9GB)
;			    example: (HDD model=Maxtor 7546AT)
;			    Identify word 60,61 is 51aa0010h  over 0ff00000h
;R37D	09/17/97 KVN	Fix R37C coding mistake will cause DI register be destroy
;			then always not fix heads number to compatible old BIOS
;			So,We can't boot HDD by old BIOS (before 04/24/97) formatted
;R46	09/08/97 RCH	Change display message from "Detecting HDD" to
;			"Detecting IDE" due to not only supporing HDD but
;			also CD-ROM and other ATAPI devices(ZIP or LS120)
;R45B	09/04/97 BAR	Fixed Segate ST32132A can't Execute Enable/Disable
;			Attribute Autosave Subcommand
;R45a	09/04/97 BAR	Move clear HDD_SMART_Flag to HD_INSTALL
;R45	08/21/97 BAR	Added Support S.M.A.R.T. Function
;R44	08/15/97 KVN	Force release IRQ 15 if define "No_Support_4_IDE" in BIOS.CFG
;R43	08/08/97 BAR	Fixed CD-ROM CDU511 can't boot
;R37C	08/06/97 KVN	Fix HDD Display size wrong in system config table if
;			Partition table is invalid
;R42	07/23/97 BAR	When master is Maxtor 82100A4 and slave is 71626A
;			send ATAPI Identify command 82100A4 Error_bit no set
;R41	07/23/97 KVN	Clear any garbage data before send Identify command
;			to IDE device to fixed CD-316E CDROM detect fail if
;			warmboot while detect it
;R18A	07/23/97 KVN	Always set CDROM Ultra DMA 33 mode to CDROM if support.
;			That fix BTC CDROM(BCD 16X) cause system hang at Win95
;			OSR2 boot stage.
;R40	07/22/97 BAR	Fix when HDD is slave drive delay 3 second power-up
;
;R37B	06/24/97 KVN	Fix HDD Identify word 60,61 and word 0,3,6 problem list
;			below :
;			  if use word 0(cylinders),word 3(heads) and word 6(sectors)
;			  to translate CHS -> LBA not equate word 60,61 translated
;			  then format it in DOS or Win95 use old BIOS.It cant
;			  boot or fdisk in new BIOS.
;			    example: (HDD model=FUJITSU M1624TAU)
;				1. use old BIOS(detect HDD CHS from word 0,3,6)
;				   then translate it to LBA heads is 64
;				   (physical clys=0FFCh, heads=10h, sectors=3Fh)
;				2. use new BIOS(detect HDD CHS from word 60,61 translated)
;				   then translate it to LBA heads is 128
;				   (physical total sectors=43A5B0h)
;				So,if you format it in DOS or Win95 by ex1 then
;				You cant boot or fdisk in ex2
;R39	06/10/97 KVN	Fix CDROM can't boot if connected it behind LS120 or Zip
;R38A	05/07/97 KVN	Fix HDD mode detect error.if HDD formated to LBA mode
;			and heads is 255 then BIOS auto detect to LARGE
;R38	05/02/97 KVN	Support HDD access of Phoenix method
;R37A	05/01/97 KVN	Don't get HDD ID word 60,61 to recalculate CHS if not
;			ATA device that will cause system hang at POST_66S when
;			system plug LS120 drive and insert 120MB diskette
;R37	04/24/97 KVN	Support HDD identify word 60-61 to exactly detect size
;			for fix [QUANTUM TX12000A] detect size to wrong
;			(physical is 12GB then detect to 8GB)
;R36	04/23/97 KVN	If support CDROM only detect and display CDROM device,
;			same as LS120 and IOMEGA device
;R35A	04/21/97 KVN	Fix R35 coding mistake that will cause system hang at
;			POST 0Eh if set HDD mode is LBA and none correspond
;			HDD drive be connected
;R35	04/09/97 KVN	Recalculate physical cylinders size for int 13 extent
;			function-48h return parameter to match function-08h to
;			fixed DOS6.22 fdisk.exe size not match with WIN95 OS-R2
;R33C	02/17/97 KVN	Fixed CDROM can't boot if connected LS120
;R34	02/01/97 KVN	Support IOMEGA ZIP-100 drive active
;R33B	01/24/97 KVN	Support LS120 drive active on drive A if set floppy
;			disk on drive B
;R33A	01/24/97 KVN	Fixed R33 coding mistake
;R33	01/22/97 KVN	Support dual LS120 drive active
;R32	01/13/97 KVN	Fixed [QUANTUM FIREBALL_TM2110A] HDD sometimes detect
;			error (show model is null string) while power on
;R31	12/24/96 KVN	Fixed determine LS-120 drive to cautious.Otherwise
;			determine wrong on detect Seagate ST31081A HDD then
;			LS-120 exist that will cause Win95 plus version (MSWIN4.0)
;			system hang and display "initial IOs error" while run
;			first time after setup
;R30A	11/11/96 KVN	Added "Ultra_DMA33_support" control by item of IOfeat
;R30	11/07/96 KVN	Added "Ultra_DMA33_support" definition for Ultra DMA33
;			function support
;R29	11/06/96 KVN	Fixed some PCMCIA ROM card emulate boot to C error
;R28	11/01/96 KVN	Added LS-120 support
;R27	10/21/96 KVN	Fixed SONY CDROM (MODEL NO. : CDU76E) during Triones
;			driver V3.22 initial then system hang on TRITON II and
;			CPU run at 200 MHz
;R26A	10/11/96 KVN	Fixed coding mistake that cause IDE HDD F can't boot
;R26	10/04/96 KVN	Added boot HDD selectable function
;R25A	09/25/96 KVN	Fixed R25 code mistake that will cause [Symbios Logic
;			SDMS PCI SCSI V4.0] hang in initial ROM
;R25	09/23/96 KVN	Fixed NT 4.0 no emulation CD install to SCSI HDD fail
;R24	09/21/96 KVN	Fixed slave HDD access error when primary master connect
;			[WDC AC31200F] and slave is [WDC AC2850F] work in
;			Triton II mother board and bus clock is 60MHz or higher
;R22A	09/02/96 KVN	Fixed CDROM can't boot if HDD type is none
;R23	09/02/96 KVN	Move "Reset_INT13" subroutine to E8POST.ASM to fix
;			system hang when define CD_ROM and E000-E800 be cleared
;			before POST_97S
;R22	08/07/96 KVN	Remove AUTO_CDROM_DETECT to early execute to fixed
;			JETWAY-VX Main Board (2A59GJ19) Sec-Slave IDE connect
;			Conner 1620MB-CFS1621A HDD then hang at POST_66S
;R17B	06/27/96 KVN	Fixed Acer-C645A CDROM detect none
;R21	06/24/96 KVN	Fixed hook acer CDROM driver (file name is ACERCD.SYS)
;			will spend long time if none IDE HDD and CDROM drive
;			connect at primary channel then from SCSI boot
;R10C	06/21/96 KVN	Fixed [Acer model:CD-747E] CD-ROM can't found in dos
;			driver when HDD type is set AUTO
;R20	06/14/96 KVN	Fixed HDD sometimes detect error(e.g. [Maxtor 7540 AV]
;			HDD connect master and type is set none else set AUTO
;			then will detect it at slave)
;R05A	06/14/96 KVN	if won't AUTO detect CDROM then define "NO_CDROM_AUTO_DETECT"
;			in BIOS.CFG even HDD type set AUTO.Once define "CD_ROM"
;			in BIOS.CFG,BIOS will always detect CDROM
;R19	06/12/96 KVN	Fixed system hang at MSCDEX.EXE if system none HDD only
;			plug SCSI and MITSUMI CDROM drive then hook mitsumi
;			driver in config.sys and autoexec.bat. Because PM_INIT
;			send HDD standby command to CDROM
;R17A	06/12/96 KVN	Change wait error bit time became 1 sec. for safety
;R18	06/11/96 KVN	Fixed SAMSUMG(SCR-830) always read first CD disk bug
;			(i.e. if change another CD disk then still read previous
;			CD disk data)
;R17	06/11/96 KVN	Change wait error bit time for 0.5 sec to fixed master
;			and slave both connect QUANTUM-FIREBALL1280A on GIGAByte
;			Intel Triton-VX mother board then slave HDD detect none
;R10B	06/10/96 KVN	Fixed SAMSUNG(SCR-830) CDROM detect error when drive set
;			slave then detect become master and slave both exist
;R16	06/01/96 KVN	Fixed HDD auto detect error if HDD enter power down mode
;			(i.e. when HDD is power down mode then warmboot)
;R15	05/29/96 KVN	Fixed show HDD or CDROM mode value wrong if not define NEW_IDE_MODE_3.
;			so always store mode value to stack for system config display
;R10A	05/29/96 KVN	Fixed Creative CDROM (model-CD820E.1v0788200) can't be
;			detected after call Reset_HDD_controller.so change POST
;			auto detect method to detect CDROM first,if fail then
;			call Reset_HDD_controller and detect HDD
;R14	05/27/96 KVN	Fix skip key invalid during [AUTO_IDE_DETECT]
;R13A	05/23/96 KVN	Fix [SAMSUNG SHD-30560A] HDD initial error because add
;			R13 code
;R13	05/21/96 KVN	Fix scale floating in landmark with Triton VX.
;R12	05/21/96 TNY	Fix coding error.
;R11	05/20/96 TNY	Add IDE_HDD_DELAY_SUPPORT definition for QDI.
;R10	05/15/96 KVN	Fixed HDD WD93044-A 40MB can't auto detect during POST
;R07C	05/10/96 KVN	Wait IDE busy for short time if detect CDROM
;R07B	05/10/96 KVN	Don't detect CDROM again if HDD type is AUTO
;R09	05/10/96 KVN	Display exact HDD fail drive
;R08	05/10/96 KVN	Fixed CDROM boot will hang when none CDROM drive
;R07A	05/09/96 KVN	Fixed some HDD return status error then detect became
;			CDROM (e.g. Conner-CFA540A, QUANTUM LPS170A)
;R07	05/09/96 KVN	Added Display CDROM model function.If HDD type is AUTO
;			then show it at original HDD display model position else
;			show found CDROM message and model at new line
;R06	05/08/96 KVN	Fixed CDROM detect method for some chipset detect spent
;			much time
;R05	05/08/96 RCH	Routine "AUTO_CDROM_DETECT" cause SONY 4x CD-ROM fail
;			so define a switch to skip it.
;R03A	05/07/95 KVN	System can not boot if define CD_ROM and only SCSI HDD
;			installed with a ATAPI CD-ROM connected at IDE port.
;			This section code must be remove E8POST.ASM(R307)
;R04	05/06/95 KVN	Fixed [Maxtor 7345 AT] detect exist both Master and Slave
;			in fact only connect one this drive on Master
;R03	05/06/95 RCH	System can not boot if define CD_ROM and only SCSI HDD
;			installed with a ATAPI CD-ROM connected at IDE port.
;			Note : It's a temporary solution , need to be verified
;			       for CD-ROM bootability
;R02	05/02/96 KVN	Fixed musted to clear [CDROM_Exist_Flag] value before
;			Auto_IDE_Detect function otherwise HDD will detect none
;R01	05/02/96 RCH	Fixed compiling error for short branch jump
;R00	05/01/96 KVN	Initial Revision for support any drive boot

		PAGE	56,132
		TITLE	HDINSTAL
.386P

.XLIST
		INCLUDE BIOS.CFG

		INCLUDE COMMON.EQU

		INCLUDE POST.EXT
		INCLUDE AHDSK.EXT
		INCLUDE	ATORGS.EXT

		INCLUDE	HDISK.EQU
		INCLUDE POST.EQU
		INCLUDE 8259.EQU

		INCLUDE COMMON.MAC

		INCLUDE	ATBASE.EXT

;R05A start
ifndef	IOMEGA_ZIP_Support		;R34
ifndef	CD_ROM
ifndef	LS120_SUPPORT	;R28
ifdef	NO_CDROM_AUTO_DETECT
NO_CDROM_DETECT	EQU	1
endif	;NO_CDROM_AUTO_DETECT
endif	;LS120_SUPPORT	;R28
endif	;CD_ROM
endif	;IOMEGA_ZIP_Support		;R34
;R05A end

ifndef No_Post_Auto_IDE_Detect
Post_Auto_IDE_Detect	equ	1
endif ;No_Post_Auto_IDE_Detect
ifndef No_Post_Auto_Set_IDE_Mode
Post_Auto_Set_IDE_Mode	equ	1
endif ;No_Post_Auto_Set_IDE_Mode
ifndef	No_Support_4_IDE
Support_4_IDE		EQU	1
endif	;No_Support_4_IDE

IDE_LBA_MODE_SUPPORT	EQU	1
HDD_TEMP_RAM_SEG	equ	8000h
Drive_delay_time	equ	120

;R84 start
ifdef UltraDMA_MaxMode
  if UltraDMA_MaxMode GT 2
;R86Bifndef	Determine_IDE_80_Cable_by_Drive		;R84A
		extrn	Ct_IDE_Interface_Status:near
;R86Bendif	;Determine_IDE_80_Cable_by_Drive	;R84A
  endif ;UltraDMA_MaxMode
endif ;UltraDMA_MaxMode
;R84 end
		extrn	AGet_CfgSpace_Word:near	;R87

ifdef	IDE_32BIT_BY_SETUP
		extrn	IDE_transfer_item:near
endif;	IDE_32BIT_BY_SETUP

;R11 - start
ifdef	IDE_HDD_DELAY_SUPPORT
		extrn	Hdd_Delay_Item:near
endif;	IDE_HDD_DELAY_SUPPORT
;R11 - end

;R82 start
ifdef	IDE_DMA_Transfer
		extrn	IDE_DMA_Item:near
		extrn	IDE_DMA_Flag:byte
		extrn	IDE_DMA_BMIBA:word
		extrn	Ct_Get_BMIBA:near
		extrn	Ct_Get_OnboardIDE_Status:near
endif	;IDE_DMA_Transfer
;R82 end

		extrn	F000_Vcrlf:near
		extrn	NUM_OF_IDE_ITEM:ABS
		extrn	HDD_TYPE_DIFF:ABS
		extrn	Get_HDD_CMOS_Info:near
		extrn	HDDC_ITEM:near
		extrn	HDDD_ITEM:near
	ifdef	Support_4_IDE
		extrn	HDDE_ITEM:near
		extrn	HDDF_ITEM:near
	endif	;Support_4_IDE
		extrn	F000_GetItem_Value:near
		extrn	IdeBlock_Item:near
		extrn	Ct_Check_System_Shadow:near
;R73		extrn	Chk_If_LARGE_Mode:near
;R73		extrn	Chk_If_LBA_Mode:near
		extrn	fPROC_Chk_If_LARGE_Mode:Far		;R73
		extrn	fPROC_Chk_If_LBA_Mode:Far		;R73
		extrn	Type_To_DrvParm:near
		extrn	Type_To_DrvParm_End:near
		extrn	GetItem_Cmos:near
		extrn	Read_Item_Value:near
		extrn	Write_Item_Value:near
ifdef Post_Auto_Set_IDE_Mode
		extrn	F000_Do_F000_Shadow:near
endif ;Post_Auto_Set_IDE_Mode
ifdef Post_Auto_IDE_Detect
		extrn	Do_F000_Shadow:near
		extrn	F000_DISPLAY_STRING:near
		extrn	Display_Char:near
endif ;Post_Auto_IDE_Detect
		extrn	F000_DISPLAY_STRING:near		;R81
ifdef	IDE_MODE_3_SUPPORT
		extrn	Ct_Set_IDE_Timing:near
		extrn	Ide_mode_3_Item:near
endif	;IDE_MODE_3_SUPPORT
ifdef	NEW_IDE_MODE_3
		extrn	Ct_Set_IDE_Timing:near
endif	;NEW_IDE_MODE_3

ifdef	IDE_TIME_OUT_SETUP
		extrn	IdeTime_Out_Item:near
endif;	IDE_TIME_OUT_SETUP

ifdef	AUTO_CFG_IO
		extrn	GetItem_Value:near
		extrn	AUTO_IO_Item:near
		extrn	IO_CHIP_FUNC_DISABLE:near
ifndef	IDE_ALWAYS_DISABLE
		extrn	AUTO_CFG_IO_IDE:near
endif;	IDE_ALWAYS_DISABLE
endif;	AUTO_CFG_IO
                extrn   Shadow_Dr:near
ifdef	IDE_Special_Do
		extrn	Ct_IDE_Special_Do:near
endif	;IDE_Special_Do
;R52 - starts
ifdef	E000_IDE_Special_Do
		extrn	E000_Ct_IDE_Special_Do:near
endif	;E000_IDE_Special_Do
;R52 - ends
		extrn	RET_E_SEG:near
		extrn	F000_VECT:near
		extrn	F000_call_proc:near
ifdef	Support_CDROM_IORDY
		extrn	Enable_chipset_IORDY:near
endif	;Support_CDROM_IORDY
		extrn	Reset_INT13:near			;R23
		extrn	F000_Shadow_W:near	;R25
		extrn	F000_Shadow_R:near	;R25
		extrn	IDE_Drive_Max_Num:byte	;R25
		extrn	Int13_original_address:dword		;R25A
		extrn	IDE_drive_Type:word	;R89
;R30A start
ifdef	Ultra_DMA33_support
		extrn	IdeA_Sdma_Item:near
		extrn	IdeB_Sdma_Item:near
ifndef  ONCHIP_2ND_ALWAYS_DISABLE		;R48
	ifdef	Support_4_IDE			;R74
		extrn	IdeC_Sdma_Item:near
		extrn	IdeD_Sdma_Item:near
	endif;	Support_4_IDE		   	;R74
endif;  ONCHIP_2ND_ALWAYS_DISABLE		;R48
endif	;Ultra_DMA33_support
;R30A end
ifdef	HDD_SMART_Support			;R45
		extrn	HDD_SMART_Item:near	;R45
endif;	HDD_SMART_Support			;R45
;R47 - start
		extrn	FDPTE_Drive0:near
		extrn	FDPTE_Drive1:near
		extrn	FDPTE_Drive2:near
		extrn	FDPTE_Drive3:near
;R47 - end
		extrn	DSK_VECT:near			;R50
;R56 -Start
;R69		extrn	CDROM_Boot_Delay:near
;R69		extrn	CDROM_Boot_loop:near
		extrn	Write_F000_shadow_Byte:near
		extrn	Write_F000_shadow_Word:near
		extrn	Write_F000_shadow_DWord:near
		extrn	post_call_proc:near
;R56 - end

ifdef	Quiet_POST_Support					;R61
		extrn	Ck_Quiet_Post:near			;R61
endif	;Quiet_POST_Support					;R61

;R79 - starts
ifdef	MULTI_LANGUAGE_SUPPORT
		DECLARE_MULTI_LANGUAGE		;macro to declare externals
		extrn	fProc_Disp_Language:far
		extrn	fProc_Get_Language_Type:far
		extrn	Full_Screen_E_Show:Near
		extrn	Full_Screen_M_Show:Near
endif	;MULTI_LANGUAGE_SUPPORT
;R79 - ends

;;;ifdef	ATAPI_COMMAND_SUPPORT			;R63A
if	ATAPI_COMMAND_SUPPORT	eq	1	;;;
		extrn	std_atapi:near		;R63
		extrn	IoMegaZip_Flag:near	;R63
endif	;ATAPI_COMMAND_SUPPORT			;R63A

ifdef	Have_CDROM_PIOMode_Item				;R72 - starts
		extrn	CDROM_PIOMode_Item:Near
endif;	Have_CDROM_PIOMode_Item				;R72 - ends
;R75 - start
ifdef	Set_DMA_Capable_Status
		extrn	Set_DMA_Capable:Near
endif;	Set_DMA_Capable_Status
;R75 - end

.LIST

SEG_0		SEGMENT	USE16 AT 1
		INCLUDE	SEG_0.INC
SEG_0		ENDS

G_RAM		SEGMENT	USE16 AT 40H
		INCLUDE	G_RAM.INC
G_RAM		ENDS

DGROUP		GROUP	FCODE
FCODE           SEGMENT PARA PUBLIC 'CODE'
                ASSUME  CS:DGROUP
FCODE           ENDS

EGROUP		GROUP	ECODE
ECODE		SEGMENT	USE16 PARA PUBLIC 'ECODE'
		ASSUME	CS:EGROUP,DS:G_RAM,ES:EGROUP

;R30A start
ifdef	Ultra_DMA33_support
Sdma_Item_Off:
		dw	offset DGROUP:IdeA_Sdma_Item
		dw	offset DGROUP:IdeB_Sdma_Item
ifndef  ONCHIP_2ND_ALWAYS_DISABLE		;R48
	ifdef	Support_4_IDE			;R74
		dw	offset DGROUP:IdeC_Sdma_Item
		dw	offset DGROUP:IdeD_Sdma_Item
	endif;	Support_4_IDE		   	;R74
endif;  ONCHIP_2ND_ALWAYS_DISABLE		;R48
endif	;Ultra_DMA33_support
;R30A end

ifdef Post_Auto_IDE_Detect
;R79 Post_Detect_Msg:
DEFINE_MSG	Post_Detect_Msg					;R79
		db	V_NORMAL,NEWLINE
		ADDX	<,2>
		db	'Detecting IDE Primary Master  ... [Press '	;R46
;R46		db	'Detecting HDD Primary Master  ... [Press '
		db	V_HILITE,'F4'
		db	V_NORMAL,' to skip] '
		db	0

Clear_Detect_Msg:
		db	V_NORMAL
		SUBX	<,19>
		db	'                  '
		SUBX	<,18>
		db	0

;R79 Detect_Skip_Msg:
DEFINE_MSG	Detect_Skip_Msg			;R79
		db	'Skip '
		db	0

;R79 Detect_Fail_Msg:
DEFINE_MSG	Detect_Fail_Msg			;R79
		db	'None '
		db	0

;R79 D_Drive_Msg:
DEFINE_MSG	D_Drive_Msg					;R79
		SUBX	<,24+15>
		db	'Primary Slave   '
		ADDX	<,22>
		db	' '
		db	0

ifdef	Support_4_IDE
;R79 E_Drive_Msg:
DEFINE_MSG	E_Drive_Msg					;R79
		SUBX	<,24+15>
		db	'Secondary Master'
		ADDX	<,22>
		db	' '
		db	0

;R79 F_Drive_Msg:
DEFINE_MSG	F_Drive_Msg					;R79
		SUBX	<,24+15>
		db	'Secondary Slave '
		ADDX	<,22>
		db	' '
		db	0
endif	;Support_4_IDE
endif ;Post_Auto_IDE_Detect
;R07 start
Found_CDROM_Str:
		db	V_NORMAL,NEWLINE
		db	'Found CDROM : '
		db	0
;R07 end
;R28 start
ifdef	LS120_SUPPORT
Found_ATAPI_Str:
		db	V_NORMAL,NEWLINE
;R36		db	'Found LS-120 Device : '
		db	'Found ATAPI Device : '			;R36
		db	0
endif	;LS120_SUPPORT
;R28 end

		PUBLIC	HD_INSTALL
HD_INSTALL	PROC	NEAR
		push	ds
		push	es
		push	gs
;R82 start
		mov	eax,0ffffffffh
		mov	HDD_0_UltraDMA[bp],eax
		mov	IDE_0_DMA_MODE[bp],eax
;R82 end
		xor	eax,eax				;R45A
;R15 ifdef	NEW_IDE_MODE_3
;clear stack values
;R45A		xor	eax,eax
		mov	HDD_0_MODE[bp],eax
;R47 - start
		mov	byte ptr IDE_PARM_Flag[bp],al	;R86
		mov	byte ptr HDD_SMART_FLAG[bp],al	;clear flag
		mov	IDE_0_Specific_FLAG[bp],eax
		mov	IDE_EXist_FLAG[bp],al
;R82		mov	IDE_0_DMA_MODE[bp],eax
;R47 - end
;R15 endif	;NEW_IDE_MODE_3
;R47;R45A start
;R47ifdef	HDD_SMART_Support
;R47		mov	byte ptr HDD_SMART_FLAG[bp],al	;clear flag
;R47endif;	HDD_SMART_Support
;R47;R45A end

;R82		mov	dword ptr HDD_0_UltraDMA[bp],0ffffffffh	;R30

ifndef	NO_HDD_LOW_LEVEL_FORMAT
		and	byte ptr FIXED_ERROR[bp], 01h	; reset to no errors
else;	NO_HDD_LOW_LEVEL_FORMAT
;RBAR		mov	byte ptr FIXED_ERROR[bp], 0	; reset to no errors
		mov	byte ptr FIXED_ERROR[bp], al	; reset to no errors;RBAR
endif;	NO_HDD_LOW_LEVEL_FORMAT

		push	0f000h
		pop	gs
		assume	gs:dgroup

		mov	ax,G_RAM
		mov	ds,ax
		ASSUME	DS:G_RAM		; ds = G_RAM

;R11 - start
ifdef	IDE_HDD_DELAY_SUPPORT
		push	ds

ifndef	No_Support_4_IDE						;R12
		cmp	byte ptr CMOS_HDDE[bp],0	;Is AUTO?	;R12
		je	short Delay_Sure				;R12
		cmp	byte ptr CMOS_HDDF[bp],0	;Is AUTO?	;R12
		je	short Delay_Sure				;R12
endif;	No_Support_4_IDE						;R12

		cmp	byte ptr FIXED_TYPE[bp],0	;C & D existed ?
		je	short No_Hdd_Delay

		cmp	word ptr ds:USER_REBOOT, CTRL_ALT_DEL
		je	short No_Hdd_Delay

Delay_Sure:								;R12

		mov	si,offset Hdd_Delay_Item
		call	F000_GetItem_Value
		or	al,al
		jz	short No_Hdd_Delay

		cmp	al,15
		ja	short No_Hdd_Delay

		xor	edx,edx

@@:
		add	edx,0f4240h		;1 second to wait
		dec	al
		jnz	short @B

		mov	ecx,edx
		shr	ecx,16

		mov	ah,86h
		int	15h

No_Hdd_Delay:
		pop	ds

endif;	IDE_HDD_DELAY_SUPPORT
;R11 - end

		mov	ax,SEG_0
		mov	es,ax
		ASSUME	ES:SEG_0

		lea	ax,DSK_VECT			;R50
		mov	word ptr seg_0:int40,ax		;R50 ;fill int40 vector

;R09		mov	byte ptr POST_HDD_Err_Flag[bp],0

;------------ Check IDE block mode enable/disabled ------------
		and	byte ptr POST_FLAG,not IDE_Block_Mode
		mov	si,offset IdeBlock_Item
		call	F000_GetItem_Value
		or	al,al		    	;block mode enabled?
		jz	short Block_Mode_Disable
		or	byte ptr POST_FLAG,IDE_Block_Mode
Block_Mode_Disable:
;--------------------------------------------------------------

ifdef	IDE_MODE_3_SUPPORT
;------------ Check IDE block mode enable/disabled ------------
		and	byte ptr IDE_PARM_Flag[bp],not Mode_3_Support
		mov	si,offset Ide_mode_3_Item
		call	F000_GetItem_Value
		or	al,al		    	;mode3 item enabled?
		jz	short Mode3_No_Support
		or	byte ptr IDE_PARM_Flag[bp],Mode_3_Support
Mode3_No_Support:
;--------------------------------------------------------------
endif	;IDE_MODE_3_SUPPORT

;R10A		call	Reset_HDD_controller	;R10
;R53;	look for hard/floppy combo card
;R53
;R53		mov	dx,1f6h
;R53		mov	al,0a0h
;R53		out	dx,al
;R53		newiodelay
;R53		mov	al,0ffh
;R53		in	al,dx
;R53		cmp	al,0a0h
;R53		jne	short hd_combodone
;R53
;R53		mov	dx,DISK_STAT_PORT	; SEE IF COMBO CARD IS 'BUSY'
;R53		xor	bh,bh
;R53		in	al,dx
;R53		newiodelay
;R53		test	al,20h
;R53		jnz	short Check_Combo
;R53		test	al,0d0h
;R53		jz	short Check_Combo
;R53		mov	bh,gs:[Wait_HDU_Ctlr_Busy_Hi]
;R53Check_Combo:
;R53		mov	cx,gs:[Wait_HDU_Ctlr_Busy_Lo]
;R53		mov	ax,0c040h
;R53		call	F000_Wait_For_Port
;R53
;R53		or	ah,ah			; did we timeout?
;R53		jz	short hdc_not_busy	; jump if not
;R53
;R53		test	al,0ch			; if busy but no data request or
;R53		jz	short combo_present	; ecc bit then it is there
;R53
;R53		jmp	short hd_combodone
;R53
;R53hdc_not_busy:
;R53		mov	al,05h			; write to sector cnt register
;R53		mov	ah,al			; to see if it's there
;R53		mov	dx,DISK_SECTOR_CNT_PORT
;R53		out	dx,al
;R53		IODELAY
;R53		in	al,dx
;R53
;R53		cmp	al,ah		      	; any response?
;R53		je	short Ck_Again
;R53		jmp	short hd_combodone	; no, no combo present...
;R53Ck_Again:
;R53		mov	al,11h			; try again to be sure
;R53		mov	ah,al			; ah = saved value
;R53		out	dx,al
;R53		IODELAY
;R53		in	al,dx
;R53
;R53		cmp	al,ah			; any response?
;R53		jne	short hd_combodone	; no, no combo...
;R53
;R53;
;R53;	Hard Disk Controller is present
;R53;
;R53
;R53COMBO_PRESENT:
;R53		or	Most_Recent_Rate,1
;R53
;R53		test	Hardware,1
;R53		jz	short hd_combodone
;R53
;R53		test	DCapability,0f0h	; if upper half non-zero,
;R53		jz	short hd_combodone	; then no second drive
;R53
;R53		or	Hardware,40h		; we have 2 drives.
;R53;
;R53;	Based on what CMOS tells us, we are going to attempt
;R53;	to install the interrupt vectors for the two fixed disks.
;R53;
;R53;
;R53;	Install Fixed Disk Vectors, Drive 0
;R53;
;R53
;R53hd_combodone:
;
;	Install Fixed Disk Vectors, Drive 1
;
		mov	byte ptr NumHDSKS,0	; set none HARD DISK
		and	byte ptr Post_Temp_Byte[bp],0f0h
		mov	byte ptr HDD_Drive_Port,0	;channel 0, master

 		mov	al,FIXED_TYPE[bp]	; get hard drive types
		shr	al,4
		or	al,al
		jz	short Check_Drive1
ifdef Post_Auto_IDE_Detect
		cmp	al,15			; if type 15 then need type
		jne	short Drive0_Not_Auto
		cmp	byte ptr EXT_FIXED_0[bp],47
		jne	short Drive0_Not_Auto
		cmp	byte ptr CURSOR_Y[bp],6
		jae	short @F
		mov	byte ptr CURSOR_Y[bp],6
@@:
		mov	bx,offset HDDC_ITEM
		shr	esi,16
		or	byte ptr Post_Temp_Byte[bp],DriveC_AUTO
		call	Post_Auto_Detect
;R07		jnc	short Drive0_Not_Auto
;R07 start
		jc	short PM_Error
		test	byte ptr CDROM_Exist_Flag[bp],PM_CDROM
		jz	short Drive0_Not_Auto
PM_Error:
;R07 end
 		or	byte ptr FIXED_TYPE[bp],0f0h
		mov	byte ptr EXT_FIXED_0[bp],47
		jmp	short Check_Drive1
Drive0_Not_Auto:
endif ;Post_Auto_IDE_Detect
		inc	byte ptr NumHDSKS	; SET FOR 1 HARD DISK
Check_Drive1:
;
;	Install Fixed Disk Vectors, Drive 1
;

 		mov	al,FIXED_TYPE[bp]	; get hard drive types
		and	al,0fh
		jnz	short @F
ifdef	NO_SUPPORT_DRVE1_EMPTY
		cmp	byte ptr NumHDSKS,0
		jne	short no_sec_dsk
else	;NO_SUPPORT_DRVE1_EMPTY					
		jmp	Check_Drive2
endif	;NO_SUPPORT_DRVE1_EMPTY
@@:

ifdef Post_Auto_IDE_Detect
		cmp	al,15			; if type 15 then need type
		jne	short Drive1_Not_Auto
		cmp	byte ptr EXT_FIXED_1[bp],47
		jne	short Drive1_Not_Auto
		mov	bx,offset HDDD_ITEM
		lea	si,D_Drive_Msg
		shl	esi,16
		or	byte ptr Post_Temp_Byte[bp],DriveD_AUTO
		call	Post_Auto_Detect
;R07		jnc	short Drive1_Not_Auto
;R07 start
		jc	short PS_Error
		test	byte ptr CDROM_Exist_Flag[bp],PS_CDROM
		jz	short Drive1_Not_Auto
PS_Error:
;R07 end
 		or	byte ptr FIXED_TYPE[bp],0fh
		mov	byte ptr EXT_FIXED_1[bp],47
ifdef	NO_SUPPORT_DRVE1_EMPTY
		jmp	short no_sec_dsk
else	;NO_SUPPORT_DRVE1_EMPTY
		jmp	short Check_Drive2
endif	;NO_SUPPORT_DRVE1_EMPTY
Drive1_Not_Auto:
endif ;Post_Auto_IDE_Detect
		mov	cl,NUMHDSKS
		shl	cl,1
		mov	al,1		;channel 0 and slave
		shl	al,cl
		or	byte ptr HDD_Drive_Port,al
		inc	byte ptr NUMHDSKS
Check_Drive2:
ifdef	Support_4_IDE
		cmp	byte ptr CMOS_HDDE[bp],0
		je	short Check_Drive3
ifdef Post_Auto_IDE_Detect
		cmp	byte ptr CMOS_HDDE[bp],47
		jne	short Drive2_Not_Auto
		mov	bx,offset HDDE_ITEM
		lea	si,E_Drive_Msg
		shl	esi,16
		or	byte ptr Post_Temp_Byte[bp],DriveE_AUTO
		call	Post_Auto_Detect
;R07		jnc	short Drive2_Not_Auto
;R07 start
		jc	short SM_Error
		test	byte ptr CDROM_Exist_Flag[bp],SM_CDROM
		jz	short Drive2_Not_Auto
SM_Error:
;R07 end
		mov	byte ptr CMOS_HDDE[bp],47
		jmp	short Check_Drive3
Drive2_Not_Auto:
endif ;Post_Auto_IDE_Detect
		mov	cl,NUMHDSKS
		shl	cl,1
		mov	al,2		;channel 1 and master
		shl	al,cl
		or	byte ptr HDD_Drive_Port,al
		inc	byte ptr NUMHDSKS
Check_Drive3:
		cmp	byte ptr CMOS_HDDF[bp],0
		je	short no_sec_dsk
ifdef Post_Auto_IDE_Detect
		cmp	byte ptr CMOS_HDDF[bp],47
		jne	short Drive3_Not_Auto
		mov	bx,offset HDDF_ITEM
		lea	si,F_Drive_Msg
		shl	esi,16
		or	byte ptr Post_Temp_Byte[bp],DriveF_AUTO
		call	Post_Auto_Detect
;R07		jnc	short Drive3_Not_Auto
;R07 start
		jc	short SS_Error
		test	byte ptr CDROM_Exist_Flag[bp],SS_CDROM
		jz	short Drive3_Not_Auto
SS_Error:
;R07 end
		mov	byte ptr CMOS_HDDF[bp],47
		jmp	short no_sec_dsk
Drive3_Not_Auto:
endif ;Post_Auto_IDE_Detect
		mov	cl,NUMHDSKS
		shl	cl,1
		mov	al,3		;channel 1 and slave
		shl	al,cl
		or	byte ptr HDD_Drive_Port,al
		inc	byte ptr NUMHDSKS
endif	;Support_4_IDE

;
;	Here we try and enable the hard disk interrupts
;

no_sec_dsk:
		call	Show_80_Cable_Msg	;R86
;R80A - start
ifdef	IDE_Special_Do				;kevin
;store original HDD mode for system config display correctly
		push	word ptr HDD_0_MODE[bp]	;kevin
		push	word ptr HDD_2_MODE[bp]	;kevin
endif	;IDE_Special_Do				;kevin
;R52 - starts
ifdef	E000_IDE_Special_Do
;store original HDD mode for system config display correctly
		push	word ptr HDD_0_UltraDMA[bp]		;R52A
		push	word ptr HDD_2_UltraDMA[bp]		;R52A
		push	word ptr HDD_0_MODE[bp]
		push	word ptr HDD_2_MODE[bp]
endif	;E000_IDE_Special_Do
;R52 - ends
;R80A - ends
;R89 start
		mov	ax,IDE_device_item[bp]		;get IDE drive of type
		lea	si,IDE_drive_Type		;store to shadow for runtime code (AHDSK)
		call	Write_F000_shadow_Word
;R89 end
		call	Write_IDE_Drive_Max_Num		;R25
;R21 start
		mov	ax,offset dgroup:int_hdisk
		mov	word ptr seg_0:hd_int,ax
		mov	word ptr seg_0:hd_int+2,0f000h
;R76 start
	ifdef	Support_4_IDE
		mov	ax,offset dgroup:int_hdisk1
		mov	word ptr seg_0:int77,ax		;IRQ15 offset
		mov	word ptr seg_0:int77+2,0f000h	;IRQ15 segment
	endif	;Support_4_IDE
;R76 end
;R21 end
;R22A start
ifndef	NO_CDROM_DETECT
ifndef	NO_CDROM_DETECT_IF_NONE			;R67
		call	AUTO_CDROM_detect
endif	;NO_CDROM_DETECT_IF_NONE		;R67
endif	;NO_CDROM_DETECT
ifdef	CD_ROM
		mov	G_RAM:[CDROM_EMUL_HEAD],0
		test	byte ptr CDROM_Exist_Flag[bp],0fh
		jz	short None_CDROM
;R28 start
;R39 ifdef	LS120_SUPPORT
;R39 		mov	cl,byte ptr G_RAM:[ATAPI_Byte]
;R39 		mov	ch,cl
;R39 		and	cl,3
;R39 endif	;LS120_SUPPORT
;R28 end
		mov	al,CDROM_Exist_Flag[bp]
		xor	ah,ah
@@:
;R28 start
;R39 ifdef	LS120_SUPPORT
		mov	cl,byte ptr G_RAM:[ATAPI_Byte]	;R39
		mov	ch,cl				;R39
		and	cl,3				;R39
		test	ch,4
		jz	short None_ARMD
		cmp	cl,ah
		je	short Scan_next_available_CDROM
;R33 start
		test	ch,30h			;R33C have 2 LS120/ZIP100 drive?
		jz	short None_ARMD		;R33C
		shr	ch,4			;check floptical drive 1
		and	ch,3
		cmp	ch,ah
		je	short Scan_next_available_CDROM
;R33 end
None_ARMD:
;R39 endif	;LS120_SUPPORT
;R28 end
		shr	al,1
		jc	short @F
		shl	al,1			;R33C
Scan_next_available_CDROM:			;R28
		shr	al,1			;R33C
		inc	ah
		cmp	ah,4			;R28
		jae	short None_CDROM	;R28
		jmp	short @B
@@:
		mov	G_RAM:[CDROM_EMUL_HEAD],ah
		add	byte ptr G_RAM:[CDROM_EMUL_HEAD],8	;Default Emulate Drive C
None_CDROM:
endif	;CD_ROM
;R22A end
		cmp	byte ptr NumHDSKS,0
		je	hd_install_ret
		call	Fill_Drv_Vector
		call	Reset_INT13

		cli
ifdef IDE_LBA_MODE_SUPPORT
		mov	byte ptr HDD_MODE_FLAG,0
		call	Get_HDD_Access_mode
		xor	esi,esi
		call	Set_HDD_Access_mode
endif ;IDE_LBA_MODE_SUPPORT
;R45A;R45 start
;R45Aifdef	HDD_SMART_Support
;R45A		mov	byte ptr HDD_SMART_FLAG[bp],0h	;clear flag
;R45Aendif;	HDD_SMART_Support
;R45A;R45 end
ifdef Post_Auto_IDE_Detect
		push	ds
		push	es
		pusha
                lea	si,Shadow_Dr
		call	F000_Do_F000_Shadow
		mov	esi,edi
		call	Set_HDD_Access_mode
		popa
		pop	es
		pop	ds
endif ;Post_Auto_IDE_Detect
		sti
		test	byte ptr Post_Temp_Byte[bp],DriveC_AUTO
		jz	short @F
		mov	byte ptr EXT_FIXED_0[bp],47
@@:
		test	byte ptr Post_Temp_Byte[bp],DriveD_AUTO
		jz	short @F
		mov	byte ptr EXT_FIXED_1[bp],47
@@:
		test	byte ptr Post_Temp_Byte[bp],DriveE_AUTO
		jz	short @F
		mov	byte ptr CMOS_HDDE[bp],47
@@:
		test	byte ptr Post_Temp_Byte[bp],DriveF_AUTO
		jz	short @F
		mov	byte ptr CMOS_HDDF[bp],47
@@:
;R22 start
;R22Aifndef	NO_CDROM_DETECT
;R22A		call	AUTO_CDROM_detect
;R22Aendif	;NO_CDROM_DETECT
;R22 end
		cli
		in	al,b8259+1		;enable hrd disk int

	ifdef	Support_4_IDE
		ifdef	No_Support_4_IDE		;R44
			and	al,0BFH			;R44
		else	;No_Support_4_IDE		;R44
			and	al,03FH
		endif	;No_Support_4_IDE		;R44
	else	;Support_4_IDE
		and	al,0BFH
	endif	;Support_4_IDE

		IODELAY

		out	B8259+1,al
		IODELAY

		in	al,A8259+1
		and	al,0FBH
		IODELAY

		out	A8259+1,al
		sti

;R58B start
ifndef	NO_Hard_disk_Diagnostic
		mov	dx,80h			; HD CONTROLER DIAGNOSTIC
		mov	ax,1400h
		mov	cx,3
@@:
		int	13h
		jnc	short l14		; no errors...
		loop	@B

		or	byte ptr FIXED_ERROR[bp],FIXED_DIAG_ERROR
		mov	byte ptr NumHDSKS,0
		jmp	hd_install_ret
endif;	Hard_Disk_Diagnostic

; 	Try to reset fixed disk

l14:
;R58B end

;R58ifndef	NO_Hard_disk_Diagnostic
;R58		mov	dx,80h			; HD CONTROLER DIAGNOSTIC
;R58		mov	ax,1400h
;R58		mov	cx,3
;R58@@:
;R58		int	13h
;R58		jnc	short l14		; no errors...
;R58		loop	@B
;R58
;R58;R09		mov	al,FIXED_DIAG_ERROR	; INT 13H, FUNCTION 14H. Diagnostics error...
;R58;R09		mov	POST_HDD_Err_Flag[bp],al
;R58		or	byte ptr FIXED_ERROR[bp],FIXED_DIAG_ERROR	;R09
;R58		mov	byte ptr NumHDSKS,0
;R58		jmp	hd_install_ret
;R58endif;	Hard_Disk_Diagnostic
;R58
;R58; 	Try to reset fixed disk
;R58
;R58l14:
;R58		xor	ax,ax			; reset hdisk
;R58		mov	dx,80h
;R58		push	dx
;R58		int	13h
;R58		pop	dx
;R58		jnc	short l16		; ok
;R58
;R58;
;R58;	Report bad fixed disk
;R58;
;R58
;R58l15:
;R58;R09		mov	byte ptr POST_HDD_Err_Flag[bp],UNABLE_FIXED_RESET
;R58
;R58;
;R58;	Wait for fixed disk to power up
;R58;
;R58
		mov	dl,80h			;R58
;R58A start
		xor	ah,ah			; reset hdisk
		int	13h
;R58A end
l16:
;R58		cli				; SET TIMER TO 0 FOR TIME OUT
;R58		xor	ax,ax
;R58		mov	word ptr LOW_8254_CNT,ax
;R58		mov	word ptr HI_8254_CNT,ax
;R58		sti

l16_lp1:
		mov	ax,0900h		; initialize using drive parameters
;R58		push	dx
		int	13h
;R58		pop	dx
;R58		jc	short l16_lp_err1	; report error
		jnc	short l16_lp_1		;R58

;R58		mov	ax,1100h		; recalibrate hard drive
;R58		push	dx
;R58		int	13h
;R58		pop	dx
;R58		jc	short l16_lp_err2
;R58
;R58		mov	ax,0401h		; VERIFY SECTORS
;R58		mov	cx,1
;R58		push	dx
;R58		int	13h
;R58		pop	dx
;R58		jnc	short l16_lp_1		; no error
;R58
;R58		cmp	ah,10h
;R58		je	short l16_lp_1
;R58
;R58		cmp	ah,11h
;R58		je	short l16_lp_1
;R58
;R58		cmp	ah,0ah
;R58		je	short l16_lp_1
;R58
;R58l16_lp_err3:
;R58;R09		mov	al,SECTOR_VERIFY_ERROR	; INT 13H, FUNCTION 04H
;R58;R09		jmp	short l16_lp_err
;R58
;R58l16_lp_err2:
;R58;R09		mov	al,UNABLE_RECALIBRATE	; INT 13H, FUNCTION 11H
;R58;R09		jmp	short l16_lp_err
;R58
;R58l16_lp_err1:
;R58;R09		mov	al,UNABLE_FIXED_INIT	; INT 13H, FUNCTION 09H
;R58
;R58l16_lp_err:
		mov	cl,dl
		sub	cl,80h
;R09 start
		mov	ah,byte ptr HDD_Drive_Port
		shr	ah,cl
		shr	ah,cl
		and	ah,3
		xchg	ah,cl
		mov	al,80h
		shr	al,cl
		or	byte ptr FIXED_ERROR[bp],al
		xchg	ah,cl
;R09 end
		inc	cl
		shl	cl,1
		xor	ah,ah
@@:
		stc
		rcl	ah,1
;R59		loop	@B
		dec	cl			;R59
		jnz	short @B		;R59
		mov	cl,byte ptr HDD_Drive_Port
		not	ah
		and	cl,ah
		shr	cl,2
		not	ah
		shr	ah,2
		and	byte ptr HDD_Drive_Port,ah
		or	byte ptr HDD_Drive_Port,cl
;R09		cmp	byte ptr POST_HDD_Err_Flag[bp],0
;R09		jne	short @F
;R09		mov	byte ptr POST_HDD_Err_Flag[bp],al
;R09@@:
		dec	dl
		dec	byte ptr NumHDSKS
		call	Fill_Drv_Vector
		jmp	Next_HDD_Drive
;R58		cli
;R58		cmp	word ptr LOW_8254_CNT,1092	; has a minute elapsed?
;R58		sti
;R58		jb	l16_lp1
;R58		jmp	hd_install_ret

;
;	Try again except with the second hard drive, if present
;


l16_lp_1:
ifdef	HDD_SMART_Support
		call	HDD_Smart_Detect	;R45
endif;	HDD_SMART_Support
		mov	ax,201h
		mov	bx,HDD_TEMP_RAM_SEG+20h
		mov	es,bx
		xor	bx,bx
		mov	cx,1
		xor	dh,dh
		int	13h
;R58ifndef Post_Auto_Set_IDE_Mode
;R58ifdef	IDE_MODE_3_SUPPORT
;R58		test	byte ptr IDE_PARM_Flag[bp],Mode_3_Support
;R58		jnz	short detect_IDE
;R58endif	;IDE_MODE_3_SUPPORT
;R58ifdef	NEW_IDE_MODE_3						
;R58		jmp	short detect_IDE;always detect HDD	
;R58endif;	NEW_IDE_MODE_3						
;R58		test	byte ptr POST_FLAG,IDE_Block_Mode	
;R58		jz	short Next_HDD_Drive
;R58detect_IDE:
;R58endif ;Post_Auto_Set_IDE_Mode
		push	ss
		pop	es
		mov	di,bp
		add	di,IDE_PARM 			;make es:di point to 16 bytes buffer
		push	dx
		mov	cl,dl
		sub	cl,80h
		shl	cl,1
		mov	dl,byte ptr HDD_Drive_Port
		shr	dl,cl
		and	dl,3
		add	dl,80h
		mov	word ptr IDE_Detect_Skip_Key[bp],0
		call	Auto_Ide_Detect			;perform IDE auto-detection
;R80 start
;R80A		pop	ax			;restore original DX to AX
;R80Aifdef	IDE_Special_Do
;R80A;store original HDD mode for system config display correctly
;R80A		push	word ptr HDD_0_MODE[bp]
;R80A		push	word ptr HDD_2_MODE[bp]
;R80Aendif	;IDE_Special_Do
;R80A
;R80Aifdef	E000_IDE_Special_Do
;R80A;store original HDD mode for system config display correctly
;R80A		push	word ptr HDD_0_UltraDMA[bp]
;R80A		push	word ptr HDD_2_UltraDMA[bp]
;R80A		push	word ptr HDD_0_MODE[bp]
;R80A		push	word ptr HDD_2_MODE[bp]
;R80Aendif	;E000_IDE_Special_Do
;R80A		push	ax			;store original DX from AX
;R80 end
ifdef	IDE_Special_Do
		push	ds
		push	dx
		pushf
		mov	si,HDD_TEMP_RAM_SEG
		mov	ds,si
		mov	si,27*2
		F000_call	Ct_IDE_Special_Do
		popf
		pop	dx
		pop	ds
endif	;IDE_Special_Do
;R52 - starts
ifdef	E000_IDE_Special_Do
		push	ds
		push	dx
		pushf
		mov	si,HDD_TEMP_RAM_SEG
		mov	ds,si
		mov	si,27*2
		call	E000_Ct_IDE_Special_Do
		popf
		pop	dx
		pop	ds
endif	;E000_IDE_Special_Do
;R52 - ends
		mov	al,es:[di.HEADS]		
		dec	al				
		mov	ah,dl				
		pop	dx

ifdef Post_Auto_Set_IDE_Mode
;-------------- Auto detect IDE access and set -----------------
		mov	bx,HDD_TEMP_RAM_SEG+20h
		mov	es,bx				
		xor	bx,bx				
		push	dx
		jc	Some_error
		mov	di,bx			;save BX to DI
		mov	bl,ah
		sub	bl,80h
		xor	bl,1
		shl	bl,1
		xor	bh,bh
		lea	si,HDD_Type_Tbl
		mov	bx,cs:[si+bx]
		F000_call Read_Item_Value
		cmp	dl,46
		jb	Some_error
		add	bx,HDD_TYPE_DIFF-ITEM_SIZE
		mov	cl,ah				
		sub	cl,80h				
		shl	cl,1				
		add	cl,8				
		shr	edi,cl				
		mov	dx,di				
		shl	edi,cl				
		and	dh,3				

		cmp	word ptr es:[di+1feh],0aa55h
		jne	short New_HDD
		mov	si,di
		add	si,1c3h
		mov	cx,4
@@:
		cmp	byte ptr es:[si],0		;partition heads = 0?
		jne	short @F			;No,jump
		add	si,10h
		loop	@B
		jmp	short New_HDD
@@:
		mov	cx,es:[si]			;get partition heads and sectors
		and	ch,3fh				;CL = heads,CH = sectors

		cmp	cl,16
		jae	short Not_Normal
		cmp	cl,al
		je	short Set_Normal
		jmp	short Set_Large
Not_Normal:
		or	ch,ch				;partition sectors = 0?
		jz	short New_HDD
		cmp	ch,63
		jne	short Set_Large
;R38 start
		or	cl,cl
		jz	short New_HDD
		mov	dl,cl
		cmp	dl,255				; heads = 256
		je	short Skip_Large		; Yes,dont check large
		inc	dl
		cmp	dl,255				;R38A heads = 255
		je	short Skip_Large		;R38A Yes,dont check large
		test	dl,0fh				; test head is 16 times?
		jnz	short Set_Large			; Not,jump to set large mode
		shr	dl,4
@@:
		jc	short @F
		shr	dl,1
		jmp	short @B
@@:
		or	dl,dl
		jnz	short Set_Large
;R38 end
Skip_Large:						;R38A
		mov	dl,1				;force LBA mode
		test	edx,2000000h
		jnz	short Set_HDD_Mode
Set_Large:
		mov	dl,2				;force large mode
		jmp	short Set_HDD_Mode
Set_normal:
		xor	dl,dl				;force normal mode
		jmp	short Set_HDD_Mode
New_HDD:
		cmp	dh,3				;Is auto set?
		je	short Is_auto_type
		mov	dl,dh				;R77
		cmp	dh,1				;Setup is LBA mode?
;R77		jne	short Restore_original		;No,jump
		jne	short Set_HDD_Mode		;R77
Is_auto_type:
ifndef	Always_Use_Large_Para				;R77
		mov	dl,1
		test	edx,2000000h			;HDD support LBA mode?
;R77		jnz	short Set_HDD_Cmos_Mode
		jnz	short Set_HDD_Mode		;R77
endif	;Always_Use_Large_Para				;R77
		xor	dl,dl				;Force Normal mode
;R38 start
		cmp	word ptr ss:[di.Cyls],1024	;cylinder over 1024?
		jbe	short Set_HDD_Mode		;No,skip
		mov	dl,2				;force large mode
;R38 end
Set_HDD_Mode:
		cmp	dh,3				;Is auto set?
;R77		je	short Set_HDD_Cmos_Mode		;Yes,jump
;R77		cmp	dh,1
;R77		jne	short Restore_original		;No,jump
;R77		test	edx,2000000h			;HDD support LBA mode?
;R77		jnz	short Restore_original		;No,jump
;R77		xor	dh,dh				;Force CHS mode
;R77 start
		jne	short Restore_original
		mov	dh,dl
		cmp	dh,2				;large mode?
		jne	short Restore_original
		test	edx,2000000h			;HDD support LBA mode?
		jz	short Restore_original		;No,jump
		mov	dh,1				;set to LBA mode
;R77 end
Restore_original:
;R77		mov	dl,dh
		xchg	dl,dh				;R77
Set_HDD_Cmos_Mode:
;R37B start
		push	ax				;save AX
		push	dx				;save DX
		or	dl,dl				;Is Normal mode?
		jz	short Heads_Dont_modify		;Yes,dont modify
		cmp	word ptr es:[di+1feh],0aa55h	;R37D Check partition is invalid?
		jne	short Heads_Dont_modify		;R37D Yes,dont modify
		push	cx				;save CX (CL=part heads)
		xor	ah,1				;Change for match HDD_Type_Tbl
		shl	ah,1				;x2 for get offset
		movzx	di,ah				;set to DI base reg.
		add	di,offset cs:HDD_Type_Tbl	;get correct HDD type table
		mov	bx,cs:[di]			;get offset
		call	F000_Get_HDD_CMOS_Info
		pop	ax
;R37D		cmp	word ptr es:[di+1feh],0aa55h	;R37C Check partition is invalid?
;R37D		jne	short Heads_Dont_modify		;R37C Yes,dont modify
		or	al,al				;R37C Check partition heads is invalid?
		jz	short Heads_Dont_modify		;R37C Yes,dont modify
		inc	al				;inc partition heads to match physical
		xor	cl,cl				;loop count
		mov	dl,[bp+di+2]			;get physical heads
@@:
		cmp	al,dl				;Is match?
		je	short @F			;Yes,jump to modulate cyl.
		shl	dl,1				;physical heads x 2
		inc	cl				;counter
		cmp	cl,8				;overflow?
		jb	short @B			;No,continue
;R83 start
		cmp	al,0ffh				;max heads
		je	short Heads_Dont_modify		;Yes,skip
;----- Physical heads not match with logical
		movzx	cx,byte ptr [bp+di+2]		;get physical heads
		cmp	cl,10h				;physical heads = 10h?
		jne	short Heads_Dont_modify		;No,skip
		mov	ax,[bp+di]			;get physical cylinders
		cmp	ax,8192
		jbe	short Heads_Dont_modify
		mul	cx				;get total track
		dec	cl				;new heads = 0fh
		div	cx				;get new cylinders
		mov	[bp+di],ax			;set new cylinders to table
		mov	byte ptr [bp+di+2],cl		;set new heads to table
;R83 end
		jmp	short Heads_Dont_modify		;Illegal value
@@:
		mov	dx,[bp+di]			;get physical cylinders
		shr	dx,cl				;tran to LBA
		cmp	dx,1024				;over 1024?
		jb	short Heads_Dont_modify		;No,skip
		mov	dx,1024				;limit max cylinders
		shl	dx,cl				;fix to useful cyls.
		mov	word ptr [bp+di],dx		;set actual cylinders
Heads_Dont_modify:
		pop	dx				;restore DX
		pop	ax				;restore AX
;R37B end
;R77		xor	dh,dh
		mov	cl,ah
		sub	cl,80h
		shl	cl,1
		add	cl,16
		shl	edx,cl
		or	esi,edx
Some_error:
		pop	dx
;---------------------------------------------------------------
endif ;Post_Auto_Set_IDE_Mode

Next_HDD_Drive:
		inc	dl			; set for next drive
		mov	al,NumHDSKS
		add	al,80h
		cmp	dl,al
		jae	short hd_install_ret
		jmp	l16

hd_install_ret:
;R26 start
ifdef HDD_Boot_Selectable
;--- Modify HDD DRV0-DRV3 parameter if boot sequence within [D,A] to [F,A] ---
;--- to correspond AHDSK.ASM function call
		mov	al,BootSel
		xor	ah,ah
ifdef CD_ROM
		cmp	al,4
		jb	short @F
		cmp	al,6
;R26A		jae	short @F
		ja	short @F	;R26A
		mov	ah,al
		sub	ah,3
@@:
else ;CD_ROM
		cmp	al,2
		jb	short @F
		cmp	al,4
;R26A		jae	short @F
		ja	short @F	;R26A
		mov	ah,al
		sub	ah,1
@@:
endif ;CD_ROM
	or	ah,ah
	jz	short Dont_change_Boot_HDD
	cmp	ah,NUMHDSKS
	jae	short Dont_change_Boot_HDD
	mov	cl,ah
	shl	cl,1
	mov	al,HDD_Drive_Port
	mov	ah,0fch
	rol	ah,cl
	and	ah,0fch
	and	HDD_Drive_Port,ah
	mov	ah,al
	shr	ah,cl
	and	ah,3
	movzx	si,ah
	and	al,3
	movzx	di,al
	shl	al,cl
	or	al,ah
	or	HDD_Drive_Port,al

	shl	si,4
	shl	di,4
	add	si,offset DGROUP:DRV0
	add	di,offset DGROUP:DRV0
	cli
	F000_call	F000_Shadow_W		;enable F000 shadow writeable
	mov	cx,4
@@:
	mov	eax,gs:[si]
	xchg	gs:[di],eax
	mov	gs:[si],eax
	loop	@B
	F000_call	F000_Shadow_R
	sti
Dont_change_Boot_HDD:
;----------------------------------------------------------------------------
endif ;HDD_Boot_Selectable
;R26 end
		mov	al,ds:NUMHDSKS			;R19
		mov	HDD_EXIST_Flag[bp],al		;R19
		call	Write_IDE_Drive_Max_Num		;R25
;R05A ifndef	NO_CDROM_AUTO_DETECT			;R05
;R22 ifndef	NO_CDROM_DETECT					;R05A
;R22 		call	AUTO_CDROM_detect
;R22 endif	;NO_CDROM_DETECT				;R05A
;R05A endif;	NO_CDROM_AUTO_DETECT			;R05
ifdef	Post_Auto_IDE_Detect
		call	F000_Vcrlf		;set next line
endif;  Post_Auto_IDE_Detect
;R09		cmp	byte ptr POST_HDD_Err_Flag[bp],0
;R09		je	short @F
;------------------------ Hard disk error ----------------------------------
;R09		mov	al,POST_HDD_Err_Flag[bp]
;R09		or	byte ptr FIXED_ERROR[bp],al
		or	byte ptr CMOS_STATUS[bp], FIXED_STATUS+EQUIP_STATUS
;---------------------------------------------------------------------------
;R09@@:
ifdef Post_Auto_Set_IDE_Mode
		cmp	byte ptr NUMHDSKS,0
		jne	short @F
;----- Mask IRQ 14,15 if no hard drive installed
		cli
		in	al,B8259+1
		NEWIODELAY
		or	al,0C0H			;mask IRQ 14 & 15
		out	B8259+1,al
		sti
		jmp	short Hdd_Exit
@@:
		cli
		mov	eax,esi
		shr	eax,16
		mov	byte ptr HDD_MODE_FLAG,al
		shr	esi,8				;R77
		call	Set_HDD_Access_mode
                lea	si,Shadow_Dr
		call	F000_Do_F000_Shadow
		mov	esi,edi
		call	Set_HDD_Access_mode
		sti

endif ;Post_Auto_Set_IDE_Mode
ifdef	NEW_IDE_MODE_3					
		;byte ptr HDD_0_MODE[bp] = drive C mode 0-mode 0, 1-mode1 ,etc
		;byte ptr HDD_1_MODE[bp] = drive D mode
		;byte ptr HDD_2_MODE[bp] = drive E mode
		;byte ptr HDD_3_MODE[bp] = drive F mode
		F000_Call	Ct_Set_IDE_Timing	
		call	Set_PIO_Mode
		call	Set_IDE_DMA_Capable	;R87
endif;	NEW_IDE_MODE_3

Hdd_Exit:
		call	Fill_FDPTE	;Fill Fixed Disk parmeter Table ;R47

ifndef	NO_HDD_LOW_LEVEL_FORMAT
		and	byte ptr FIXED_ERROR[bp], 0feh	; clear flag
endif;	NO_HDD_LOW_LEVEL_FORMAT

;R13A		call	Reset_HDD_controller		;R13
;R27;R13A start
;R27		mov	dx,1f6h				;assume primary channel
;R27		mov	ah,CDROM_Exist_Flag[bp]
;R27		mov	cl,PM_CDROM
;R27		test	ah,PM_CDROM+PS_CDROM
;R27		jnz	short Select_Drive
;R27		sub	dl,80h				;assume secondary channel
;R27		mov	cl,SM_CDROM
;R27		test	ah,SM_CDROM+SS_CDROM
;R27		jz	short No_CDROM_Exist
;R27Select_Drive:
;R27		mov	al,0a0h				;assume master drive
;R27		test	ah,cl
;R27		jnz	short Out_data
;R27		mov	al,0b0h				;set slave drive
;R27Out_data:
;R27		out	dx,al
;R27No_CDROM_Exist:
;R27;R13A end

;R62 - start
ifdef	NO_HDD_RESET_IF_NO_HDD
		cmp	byte ptr NumHDSKS,0	;no HDD installed ?
		je	short SkipHddReset	;yes, skip reset
endif;	NO_HDD_RESET_IF_NO_HDD
;R62 - end

		xor	ah,ah
		mov	dl,80h
		int	13h

SkipHddReset:					;R62

;R29A;R29 start
;R29A		mov	ah,8
;R29A		int	13h
;R29A		mov	IDE_HDD0_CYL_SEC[bp],cx
;R29A		mov	IDE_HDD0_HEAD[bp],dh
;R29A;R29 end
ifdef	IDE_Special_Do				;kevin
		pop	ax			;kevin
		pop	bx			;kevin
		test	byte ptr Post_Temp_Byte[bp],DriveC_AUTO	;R80A
		jz	short @F				;R80A
		cmp	bl,HDD_0_MODE[bp]	;kevin
		jb	short @F		;kevin
		mov	HDD_0_MODE[bp],bl	;kevin
@@:						;kevin
		test	byte ptr Post_Temp_Byte[bp],DriveD_AUTO	;R80A
		jz	short @F				;R80A
		cmp	bh,HDD_1_MODE[bp]	;kevin
		jb	short @F		;kevin
		mov	HDD_1_MODE[bp],bh	;kevin
@@:						;kevin
		test	byte ptr Post_Temp_Byte[bp],DriveE_AUTO	;R80A
		jz	short @F				;R80A
		cmp	al,HDD_2_MODE[bp]	;kevin
		jb	short @F		;kevin
		mov	HDD_2_MODE[bp],al	;kevin
@@:						;kevin
		test	byte ptr Post_Temp_Byte[bp],DriveF_AUTO	;R80A
		jz	short @F				;R80A
		cmp	ah,HDD_3_MODE[bp]	;kevin
		jb	short @F		;kevin
		mov	HDD_3_MODE[bp],ah	;kevin
@@:						;kevin
endif	;IDE_Special_Do				;kevin
;R52 - starts
ifdef	E000_IDE_Special_Do
		pop	ax			
		pop	bx			
		pop	cx		;R80A HDD_2_UltraDMA[bp]
		pop	dx		;R80A HDD_0_UltraDMA[bp]
		test	byte ptr Post_Temp_Byte[bp],DriveC_AUTO	;R80A
		jz	short @F				;R80A
		mov	HDD_0_UltraDMA[bp],dl			;R80A
		cmp	bl,HDD_0_MODE[bp]	
		jb	short @F		
		mov	HDD_0_MODE[bp],bl	
@@:						
		test	byte ptr Post_Temp_Byte[bp],DriveD_AUTO	;R80A
		jz	short @F				;R80A
		mov	HDD_1_UltraDMA[bp],dh			;R80A
		cmp	bh,HDD_1_MODE[bp]	
		jb	short @F		
		mov	HDD_1_MODE[bp],bh	
@@:						
		test	byte ptr Post_Temp_Byte[bp],DriveE_AUTO	;R80A
		jz	short @F				;R80A
		mov	HDD_2_UltraDMA[bp],cl			;R80A
		cmp	al,HDD_2_MODE[bp]	
		jb	short @F		
		mov	HDD_2_MODE[bp],al	
@@:						
		test	byte ptr Post_Temp_Byte[bp],DriveF_AUTO	;R80A
		jz	short @F				;R80A
		mov	HDD_3_UltraDMA[bp],ch			;R80A
		cmp	ah,HDD_3_MODE[bp]	
		jb	short @F		
		mov	HDD_3_MODE[bp],ah	
@@:						
;R80A		pop	word ptr HDD_2_UltraDMA[bp]		;R52A
;R80A		pop	word ptr HDD_0_UltraDMA[bp]		;R52A
endif	;E000_IDE_Special_Do			
;R52 - ends

		pop	gs
		pop	es
		pop	ds
		ret
HD_INSTALL	ENDP

;R87 start
Set_IDE_DMA_Capable	proc	Near
		pusha

		xor	bh,bh			;bus 0
		xor	ch,ch			;start device 0,function 0
SIDC_Loop:
		mov	cl,0ah			;offset 0Ah (class code)
		F000_call	AGet_CfgSpace_Word
		cmp	ax,0ffffh		;invalid?
		je	short Next_Device	;Yes,skip

		cmp	ax,101h			;IDE device?
		jne	short Next_Device	;Yes,skip

		mov	cl,20h			;offset 20h (DMA base port)
		F000_call	AGet_CfgSpace_Word
		and	ax,0fff0h		;isolate useful bits
		jz	short Next_Device	;invalid then skip

		mov	dx,ax			;DX = base port
		and	dx,0fff0h		;isolate useful bits
		add	dl,2			;set to status register of primary
		in	al,dx			;get original data
		and	al,not 60h		;assume not support DMA
		xor	ah,ah			;indicate primary master
		call	Set_Indepand_DMA_Capable;Set flag for AL
		mov	ah,1			;indicate primary slave
		call	Set_Indepand_DMA_Capable;Set flag for AL
		out	dx,al			;send to port

		add	dl,8			;set to status register of secondary
		in	al,dx			;get original data
		and	al,not 60h		;assume not support DMA
		mov	ah,2			;indicate secondary master
		call	Set_Indepand_DMA_Capable;Set flag for AL
		mov	ah,3			;indicate secondary slave
		call	Set_Indepand_DMA_Capable;Set flag for AL
		out	dx,al			;send to port
Next_Device:
		inc	ch			;next device and function
		jnz	short SIDC_Loop		;not exceed then continue

		popa
		ret
Set_IDE_DMA_Capable	endp

;[]=======================================================[]
;Input	: AH = drive no (0=primary master, 1=primary slave ...)
;[]=======================================================[]
Set_Indepand_DMA_Capable:
		push	si
		movzx	si,ah
		cmp	byte ptr HDD_0_UltraDMA[bp][si],0ffh	;DMA support?
		jne	short Set_Capable			;Yes,go to set flag
		cmp	byte ptr IDE_0_DMA_MODE[bp][si],0ffh	;DMA support?
		je	short SIDC_Ret				;No,go to ret
Set_Capable:
		test	ah,1			;check master/slave
		mov	ah,20h			;assume master
		jz	short @F		;master then skip
		mov	ah,40h			;Is slave
@@:
		or	al,ah			;set correspond flag for drive
SIDC_Ret:
		pop	si
		ret
;R87 end

F000_Get_HDD_CMOS_Info:
		F000_call	Get_HDD_CMOS_Info
		ret
F000_Wait_For_Port:			
		F000_call	Wait_For_Port
		ret

;[]=======================================================[]
;Output	: EDI high word is access mode
;[]=======================================================[]
Get_HDD_Access_mode:
		push	ds
		push	0f000h
		pop	ds
		lea	si,Type_To_DrvParm
@@:
		mov	bx,ds:[si]
		add	bx,HDD_TYPE_DIFF-ITEM_SIZE
		push	si
		F000_call	Read_Item_Value
		pop	si
		mov	di,dx
		ror	edi,2
		add	si,5
		cmp	si,offset Type_To_DrvParm_End
		jne	short @B
ifdef	Support_4_IDE
		ror	edi,8
else	;Support_4_IDE
		ror	edi,12
endif	;Support_4_IDE
		pop	ds
		ret
;R45 strat
;[]=======================================================[]
;		HDD_SMART_Detect
;Input	:	dl=80,81,82,83
;Output	:	HDD_smart_flag
;[]=======================================================[]
ifdef	HDD_SMART_Support
HDD_SMART_Detect:
		pusha
		call	Get_HDD_Drive_Port	;Get real port
		push	dx			;save drive number
		call	Get_HDD_Master_Slave	;Master => al=DRIVE_0
						;Slave  => al=DRIVE_1
		call	Get_HDD_Channel		;Primary   si=00h
						;Secondary si=80h
		call	Set_HDD_SDH_reg		;Set device master or slave
		jc	short HDD_smart_Err	;error
						;must enable first to test Capability
	      	mov	al,0d8h			;Enable S.M.A.R.T.
	      	call	Smart_Subcommand
		jc	short HDD_smart_Err	;error

		push	si			;save channel No.
		mov	si,offset HDD_SMART_Item
		call	F000_GetItem_Value	;Get CMOS Item Value
		pop	si			;get channel No.

		mov	dx,TF_SECTCOUNT		;1f2h/172h
		sub	dx,si
		or	al,al			;test capability en/disable?
		push	ax			;Save CMOS Itemvalue
		mov	al,0f1h			;enable autosave attribute
		jz	short @F
		xor	al,al			;Disable autosave attribute
@@:
		out	dx,al			;write to sector count
	      	mov	al,0d2h			;En/disable  auotsave
	      	call	Smart_Subcommand
		pop	ax			;Get CMOS Itemvalue
;R45B		jc	short HDD_smart_Err	;error

		or	al,al			;test capability en/disable?
		jnz	short @F		
		push	ax			;save CMOS value
	      	mov	al,0d9h			;Disable S.M.A.R.T.
	      	call	Smart_Subcommand
		pop	ax			;get CMOS value
	      	jc	short HDD_smart_Err	;error	;R45B
@@:
;R45B	      	jc	short HDD_smart_Err	;error
		or	al,al			;test capability en/disable?
		mov	al,02h			;Capability & Disable
		jz	short @F
		mov	al,03h			;Capability & Enable 
@@:
		pop	cx			;Get HDD Drive number
		sub	cl,80h
		shl	cl,1
		shl	al,cl			;shift to real location
		or	byte ptr HDD_SMART_FLAG[bp],al	;setting flag
		popa
		ret
HDD_Smart_Err:
		mov	al,01
		jmp	short @B
		       
;R47;[]=======================================================[]
;R47;			Get_HDD_Drive_Port
;R47;
;R47;Input:	 dl = drive number 80,81,..	
;R47;
;R47;	HDD_Drive_port 	 bit1,3,5,7 ==>	0 = channel-0
;R47;			           	1 = channel-1
;R47;	        	 bit0,2,4,6 ==>	0 = master
;R47;		        	 	1 = slave					
;R47;[]=======================================================[]
;R47Get_HDD_Drive_Port:
;R47		mov	cl,dl
;R47		sub	cl,80h
;R47		shl	cl,1
;R47		mov	dl,byte ptr HDD_Drive_Port
;R47		shr	dl,cl
;R47		and	dl,3
;R47		add	dl,80h
;R47		ret
;[]=======================================================[]
;		Get_HDD_Command_Port
;Input ==>  dl=80,81,..	
;	    si= 0h  primary
;	      = 80h secondary			
;Output==>  dx=	primary	      =	1f7h
;		secondary     =	177h
;[]=======================================================[]
Get_HDD_Command_Port:
		mov	dx,TF_STATUS
		sub	dx,si
		ret	
;[]=======================================================[]
;			Get_HDD_Master_Slave
;Input:	dl=80,81,..
;Output:al=DRIVE_0=>master
;	   DRIVE_1=>slave
;
;[]=======================================================[]
Get_HDD_Master_Slave:
		mov	al,DRIVE_0		;assume master drive(AL=0A0h)
		test	dl,01h			;Is detect master drive?
		jz	short @F		;No,jump
		mov	al,DRIVE_1		;set is slave drive(AL=0B0h)
@@:
		ret
;R47;[]=======================================================[]
;R47;			Get_HDD_Channel
;R47;Input:	dl=80,81,..
;R47;Output:si=0  channel_0
;R47;	   1  channel_1
;R47;
;R47;[]=======================================================[]
;R47Get_HDD_Channel:
;R47		xor	si,si		;assume primary channel(si=0h)
;R47		cmp	dl,81h		;Is secondary channel?
;R47		jbe	short @F	;No,jump
;R47		mov	si,80h		;set is secondary channel (si=080h)
;R47@@:
;R47		ret
;R47
;[]=======================================================[]
;			Set_HDD_SDH_reg
;
;Input:	 al = Drive_0 = master  
;	      Drive_1 = slave
;	 Si =   0     =primary
;	    =   1     =secondary	
;Output: 
;
;[]=======================================================[]
Set_HDD_SDH_reg:
;R45C		call	wait_hdd_busy
		mov	cx,33333/4	 	;R45C   .25 second time out
		xor	bh,bh 			;R45C
		call	wait_hdd_busy_1		;R45C
		mov	dx,TF_DRV_HD
		sub 	dx,si			;SDH Register
		out 	dx,al			;set port value
		ret
;[]===============================================[]
;	Wait_HDD_Busy
;Wait HD_status bit7 is low		
;[]===============================================[]
Wait_hdd_busy:
		mov	cx,08b09h	 ;R45C	; 5 second time out
		mov	bh,2		 ;R45C
Wait_hdd_busy_1:			 ;R45C
		push	ax
		mov	dx,TF_STATUS
		sub	dx,si			;dx=1X7h
;R45C		xor	bh,bh
;R45C		mov	cx,33333/4		; 0.25 second time out
		mov	ax,8000h		; check for bit 7 = 0
		call	F000_Wait_For_Port	; wait for not busy
	       	or	ah,ah			;set zero flag => time?
		jz	short @F
		stc
@@:				
		pop	ax
		ret
;[]=============================================================[]
;		Get_smart_status
;To read Attribute Values (Subcommand D0h) 512 bytes
;[]=============================================================[]
;Get_smart_status:
;		mov	ax,808h			;wait DRQ
;		mov	dx, TF_STATUS
;		sub	dx,si
;		mov	bh,10h
;		call	wait_for_port1
;		jc	short Get_Smart_Status_ret
;
;		mov	cx,172h/2		;read offset 170h S.M.A.R.T. 
;						;capability
;		sub	dl,7			;HDD data port 1f0h/170h
;@@:
;		in	ax,dx			;get drive information
;		loop	@B			
;		push	ax			;save capability byte
;		mov	cx,100h-(172h/2)	;continue to read data
;@@:
;		in	ax,dx
;		loop	@B
;		pop	ax     
;		clc
;Get_Smart_Status_ret:
;		ret
;[]=======================================================[]
;	Smart_Subcommand   (HDD SMART Command)		
;Input :  SI =   0     =primary
;	     =   1     =secondary	
;	  Al = Subcommand
;The host must write key values into Cylinder high Registers(4Fh,C2h)
;Output:  Carry =1 ==> Command Fail
;[]=======================================================[]
Smart_Subcommand:
		call	wait_hdd_busy
 		jc	short Smart_Subcommand_r
		mov	dx,TF_FEATURE		;dx=feature register port
		sub	dx,si			;dx=171h/1f1h
		out	dx,al			;out subcommand
		newiodelay
		add	dl,3			;dx=Cylinder Low port
		mov	al,04fh			
		out	dx,al			;write key value
		newiodelay
		inc	dl			;dx=Cylinder High
		mov	al,0c2h
		out	dx,al			;write key value

		call	wait_hdd_busy		;waitting ready
 		jc	short Smart_Subcommand_r
		mov	al,0b0h			
		out	dx,al			;Execute S.M.A.R.T. command

		call	wait_hdd_busy
		jc	short Smart_Subcommand_r
		call	Get_HDD_command_port
		in	al,dx
		test	al,01
		jz	short Smart_Subcommand_r 
		stc					;Set error flag
Smart_Subcommand_r:
		ret
endif    ;	HDD_SMART_Support
;R45 end
;R47 start
;[]=======================================================[]
;			Get_HDD_Drive_Port
;
;Input:	 dl = drive number 80,81,..	
;
;	HDD_Drive_port 	 bit1,3,5,7 ==>	0 = channel-0
;			           	1 = channel-1
;	        	 bit0,2,4,6 ==>	0 = master
;		        	 	1 = slave					
;[]=======================================================[]
Get_HDD_Drive_Port:
		mov	cl,dl
		sub	cl,80h
		shl	cl,1
		mov	dl,byte ptr HDD_Drive_Port
		shr	dl,cl
		and	dl,3
		add	dl,80h
		ret

;[]=======================================================[]
;			Get_HDD_Channel
;Input:	dl=80,81,..
;Output:si=0  channel_0
;	   1  channel_1
;
;[]=======================================================[]
Get_HDD_Channel:
		xor	si,si		;assume primary channel(si=0h)
		cmp	dl,81h		;Is secondary channel?
		jbe	short @F	;No,jump
		mov	si,80h		;set is secondary channel (si=080h)
@@:
		ret

;[]=======================================================[]
;	FILL  FDPTE(Fixed Disk Parameter Table Extension)
;[]=======================================================[]
Fill_FDPTE:
		pusha
		push	ds
		push	es
	F000_call	F000_Shadow_W	;enable F000 shadow writeable
		mov	ax,seg DGROUP
		mov	es,ax			;es=0f000h
		mov	ax,G_RAM
		mov	ds,ax			;ds=40h
		mov	dl,80h
		mov	al,IDE_Exist_FLag[bp]
@@:
		sar 	al,1			;check IDE drive Exist
		jnc	NO_IDE_Exist		;No,skip
		call	Fill_FDPTE_loop
NO_IDE_Exist:
		inc	dl			;for next drive
		cmp	dl,84h			;check is 4th drive
		jb	short @B		;No,skip
	F000_call	F000_Shadow_R		;disable F000 shadow writeable
		pop	es
		pop	ds
		popa
		ret

;-----------------------------------------
Fill_FDPTE_loop:
		pusha
		call	Get_HDD_Channel		;return Primary   si=00h
						;       Secondary si=80h
		xor	dh,dh			;
		sub	dl,80h			;dl = drive number
		mov	di,dx			;di = drive offset
		xor	bx,bx			;clear index point
;------- I/O port base address ------ 		;Byte 0,1 
		mov	ax,TF_DATA		;Get I/O port base address
		sub	ax,si
		call	Set_FDPTE_word		;Stroe I/O port base address
;------- Control port address ------ 		;Byte 2,3 
		mov 	ax,TF_DIG_OUT		;Get Control port address
		sub	ax,si
		call	Set_FDPTE_word		;Store Control port address
;------- Head Prefix ------ 			;Byte 4 
			;Bit 0-3 Reserved,must be 0
		    	;Bit 4   Master/Slave Bit (0=Master)
		    	;Bit 5	 Reserved,must be 1
		    	;Bit 6   LBA Enable(1=Enable)
		    	;Bit 7	 Reserved,must be 1
		mov	al,ds:HDD_MODE_FLAG	
		mov	cl,dl
		shr	al,cl
		shr	al,cl
		and	al,03h			;Get real port data 
		push	ax
		jz	short @F
		cmp	al,03h			;LBA or Large to set CHSenabl
		jae	short @F
		or	byte ptr IDE_0_Specific_Flag[bp+di],CHSenabl	;
@@:
		cmp	al,1			;HDD_Mode_Flag
		mov	al,0a0h			;Disable LBA 	
		jne	short @F
		mov	al,0e0h			;Enable LBA 	
@@:			   
		test	dl,01h			;Is detect master drive?
		jz	Short @F
		or	al,00010000b		;Set Slave Drive
@@:
		call	Set_FDPTE_byte
;------- Internal Use Only ------ 		;Byte 5
		pop	ax
		push	ax
		cmp	al,02h			;Lagre Mode
		jne	short Not_Lagre_Mode	
		xor	cl,cl			;
		push	si			;Save Channel number
	      	movzx	si,dl
		shl	si,4
		add	si,offset dgroup:DRV0	;get HDD Physical Cylinders
		mov	ax,es:[si+9]			
		pop	si
@@:
		cmp	ax,1024			;Cylinder >1024
		jb	short @F
   		shr	ax,1			;ax=ax/2
		inc	cl			;Large mode counter
		jmp	short @B
@@:
		mov	al,cl		   
		call	Set_FDPTE_byte
		dec	bx
Not_Lagre_Mode:
		
	       	inc	bx			;Jump offset 5 (Internal Use Only)
;------- IRQ information------ 				;Byte 6
		; channel_0=14
		; channel_1=15
		mov	al,14			;ax=IRQ number
		or	si,si			;test channel 0 or 1
		jz	short @F
		inc	ax		    
@@:						;FDPT_channel_0:
		call	Set_FDPTE_byte		;Store IRQ
;------ Sector count ------  			;Byte 7
		push	bx
		movzx	bx,dl
		mov	al,byte ptr ds:SECTOR_PER_BLOCK_0[bx]
		pop	bx
		or	al,al			;check block mode
		jz	short @F		;No,skip
		or	byte ptr IDE_0_Specific_Flag[bp+di],BlockPIO		
					;set block PIO flag
@@:
		call	Set_FDPTE_byte		;store sector count
;------ DMA information ------			;Byte 8
		mov	al,byte ptr IDE_0_DMA_Mode[bp+di]	;get DMA type
;R82 start
		cmp	al,0ffh					;DMA not support?
		jne	short @F				;No,skip
		xor	al,al					;set = 0
@@:
;R82 end
		shl	al,4					;DMA channel no use
		call	Set_Fdpte_byte
;------ PIO Mode ------       			;Byte 9
		mov	al,byte ptr HDD_0_MODE[bp+di]		;Get PIO mode 
		or	al,al					;check is Mode 0
		jz	short @F				;Yes,skip
		or	byte ptr IDE_0_Specific_Flag[bp+di],FastPIO	;Set Fast PIO Flag
@@:
		call	Set_FDPTE_byte
;------ Hardware Specific Option Flags ------ 	;Byte 10,11
		movzx	ax,byte ptr IDE_0_Specific_Flag[bp+di]
		pop	cx			;get HDD_mode
		cmp	cl,01			;Is LBA
		jne	short @F		;No,skip
		or	ah,00000010b		;Set translation type
@@:
		test	al,80h			;test Interrupt DRQ
		jz	short @F		;No,skip
		or	ah,00000001b		;Set ATAPI Interrupt DRQ
@@:
;R47A -start
		cmp	byte ptr HDD_0_UltraDMA[bp+di],0ffh	
			;check configured for Ultra DMA
		je	short	@F		;No,skip
		or	ah,04h			;Hardware Specific flag bit-11
@@:
;R47A - end
		and	al,not 80h		;Clear 32bit transfer
		call	Set_FDPTE_word
;------ Reserved ------ 			;Byte 12,13
		inc	bx			;index +2
		inc	bx
;------ Revision level of this extension ------ ;Byte 14
		mov	al,11h
		call	Set_FDPTE_byte
;------ Checksum,2's complement of the sum of bytes 0-14 ------ ;Byte 15
	;32-bit transfer mode test in e8post.asm   
	; Checksum fill in e8post.asm   
		popa
		ret 
Set_FDPTE_word:
		pusha
		call	Get_FDPTE_addr
		mov	word ptr DGROUP:[si+bx],ax    	;save word data to FDPTE
		popa
		inc	bx				;index=index+2
		inc	bx
		ret
Set_FDPTE_byte:
		pusha
		call	Get_FDPTE_addr			
		mov	byte ptr DGROUP:[si+bx],al	;save byte data to FDPTE
		popa
		inc	bx				;index++
		ret
Get_FDPTE_addr:
		xor	dh,dh
		shl	dl,4				;Table size is 16 bytes
		mov	si,offset DGROUP:FDPTE_Drive0	;get BASE address
		add	si,dx				;get FDPT address	
		ret
;R47 end
;[]=======================================================[]
;Input	: ESI high word is access mode
;[]=======================================================[]
Set_HDD_Access_mode:
		shr	esi,16
		mov	cx,si
		push	ds
		push	0f000h
		pop	ds
		lea	si,Type_To_DrvParm
@@:
		mov	bx,ds:[si]
		add	bx,HDD_TYPE_DIFF-ITEM_SIZE
		mov	dx,cx
		and	dx,3
		F000_call	Write_Item_Value
		shr	cx,2
		add	si,5
		cmp	si,offset Type_To_DrvParm_End
		jne	short @B
		pop	ds
		ret

ifdef Post_Auto_IDE_Detect
;R40 start
Post_Auto_Detect_Delay:
		pusha	

	    	cmp	bx,offset HDDC_ITEM		;Auto detect is HD_C 
		je	short No_Delay_For_Slave	;HD_C do'nt need delay

ifdef	Support_4_IDE
		cmp	bx,offset HDDE_ITEM		;Auto detect is HD_E
		je	short No_Delay_For_Slave	;HD_E do'nt need delay

		cmp	bx,offset HDDD_ITEM
		je	short @F
	
		mov	al,byte ptr EXT_FIXED_1		;compare HD_D is Auto detect
		F000_call	Get_CMOS
		cmp	al,47				;if HD_D is already delay 
		je	short No_Delay_For_Slave	;so HD_F do'nt need to delay
		
		cmp	byte ptr CMOS_HDDE[bp],48	;HD_E is spend some time
	     	je	short No_Delay_For_Slave	;to detect HD ;

@@:
endif;	Support_4_IDE

		cmp    	byte ptr EXT_FIXED_0[bp],48	;HD_C is spend some time
		je	short No_Delay_For_Slave	;to detect HD 
		
Delay_Slave:
		xor	bx,bx
		mov	cx,41666			;Delay 1.25 secondnd
;R57		F000_call	Wait_Refresh
		call	F000_Wait_Refresh		;R57

No_Delay_For_Slave:
		popa	
		ret
;R40 end

;[]=======================================================[]
Detect_Skip_Key	EQU	K_F4
;Input : esi - high word = message to display
;		low word = no use
;[]=======================================================[]
Post_Auto_Detect:
		push	ds
							;SI = HDD type loc.
							;DI = HDD params loc.
		call	F000_Get_HDD_CMOS_Info

;R79 - start
ifdef	MULTI_LANGUAGE_SUPPORT
		inc	byte ptr HDD_COUNT[bp]		
		mov	byte ptr STR_COUNT[bp],0	
		mov	word ptr POST_MSG_SEG[bp], Seg Post_Detect_Msg		;debug
		mov	word ptr POST_MSG_OFF[bp], Offset Post_Detect_Msg	;debug
endif	;MULTI_LANGUAGE_SUPPORT
;R79 - end

		push	si

ifdef	Quiet_POST_Support					;R61
		call	Ck_Quiet_Post				;R61
		jnc	short @F				;R61
endif	;Quiet_POST_Support					;R61

		push	cs
		pop	ds
		lea	si,Post_Detect_Msg
	ifdef	MULTI_LANGUAGE_SUPPORT				;R79
		Call	Full_Screen_M_Show			;R79
	else	;MULTI_LANGUAGE_SUPPORT				;R79
		call	F000_DISPLAY_STRING
	endif	;MULTI_LANGUAGE_SUPPORT				;R79
		shr	esi,16
		or	si,si
		jz	short @F
	ifdef	MULTI_LANGUAGE_SUPPORT				;R79
		Call	Full_Screen_M_Show			;R79
	else	;MULTI_LANGUAGE_SUPPORT				;R79
		call	F000_DISPLAY_STRING
	endif	;MULTI_LANGUAGE_SUPPORT				;R79
@@:

		pop	si
	     	call 	Post_Auto_Detect_Delay			;R40
		mov	word ptr IDE_Detect_Skip_Key[bp],Detect_Skip_Key	;Skip key is 'F4'
		call	Auto_IDE_Detect_X
		pushf
		push	ax
		lea	si,Clear_Detect_Msg
	ifdef	MULTI_LANGUAGE_SUPPORT				;R79
		Call	Full_Screen_E_Show			;R79
	else	;MULTI_LANGUAGE_SUPPORT				;R79
		call	F000_DISPLAY_STRING
	endif	;MULTI_LANGUAGE_SUPPORT				;R79
		pop	ax
		popf
		jnc	short @F
		lea	si,Detect_Fail_Msg
		cmp	ax,Detect_Skip_Key
		jne	short Not_Esc_Key
		lea	si,Detect_Skip_Msg
Not_Esc_Key:
ifdef	Quiet_POST_Support					;R61
		call	Ck_Quiet_Post				;R61
		jnc	short LMNJA				;R61
endif	;Quiet_POST_Support					;R61
	ifdef	MULTI_LANGUAGE_SUPPORT				;R79
		Call	Full_Screen_M_Show			;R79
	else	;MULTI_LANGUAGE_SUPPORT				;R79
		call	F000_DISPLAY_STRING
	endif	;MULTI_LANGUAGE_SUPPORT				;R79
	LMNJA:							;R61
		pop	ds
		stc
		ret
@@:
		mov	si,HDD_TEMP_RAM_SEG
		mov	ds,si
		mov	si,27*2
		push	word ptr [si+40]
		push	si
;Skip blank characters to display
		add	si,40

ifdef	Quiet_POST_Support					;R61
		call	Ck_Quiet_Post				;R61
		jnc	short @F				;R61
endif	;Quiet_POST_Support					;R61
Blank_It:
		mov	byte ptr [si],0		;mark end of string
		dec	si 			;previous character
		cmp	byte ptr [si],' '	;space ?
		je	short Blank_It
		
		pop	si			
		push	si			
	ifdef	MULTI_LANGUAGE_SUPPORT				;R79
		Call	Full_Screen_E_Show			;R79
	else	;MULTI_LANGUAGE_SUPPORT				;R79
		call	F000_DISPLAY_STRING
	endif	;MULTI_LANGUAGE_SUPPORT				;R79
	@@:							;R61
		pop	si
		pop	word ptr [si+40]
		pop	ds
		clc
		ret
endif ;Post_Auto_IDE_Detect

ifdef IDE_LBA_MODE_SUPPORT
;[]==============================================================[]
;
;Tran_CHS_LBA:
;
;	Translate physical CHS to logical LBA.
;
;Saves:	NONE
;
;Entry:	bx = CHS cylinders
;	al = CHS sector
;	ah = CHS head
;
;Exit:	bx = LBA cylinders
;	al = LBA sector
;	ah = LBA head
;
;[]==============================================================[]

		public	Tran_CHS_LBA
Tran_CHS_LBA	PROC	NEAR
		push	cx
		push	dx

ifdef Reserved_1_Cyl_for_test			;R66
		dec	bx			;R66
endif ;Reserved_1_Cyl_for_test			;R66
		mul	ah
		mul	bx
		shl	edx,16
		mov	dx,ax

		cmp	edx,1024*32*63		;528MB < X <=1056.9MB
		ja	short @F		;above then jump next
		mov	bh,32
		mov	cx,32*63
		jmp	short Set_Cylinder
@@:
		cmp	edx,1024*64*63		;1056.9MB < X <=2113.9MB
		ja	short @F		;above then jump next
		mov	bh,64
		mov	cx,64*63
		jmp	short Set_Cylinder
@@:
		cmp	edx,1024*128*63		;2113.9MB < X <=4227.8MB
		ja	short @F		;above then jump next
		mov	bh,128
		mov	cx,128*63
		jmp	short Set_Cylinder
@@:						;4227.8MB < X <=8422.6MB
		mov	bh,255
		mov	cx,255*63
Set_Cylinder:
		mov	ax,dx
		shr	edx,16
		div	cx
		xchg	ax,bx
		mov	al,63			;sectors
		or	bx,bx
		jnz	short @F
		xor	ax,ax
@@:

		pop	dx
		pop	cx
		ret
Tran_CHS_LBA	ENDP

		Public	Tran_CHS_LARGE
Tran_CHS_LARGE	Proc	Near
ifdef Reserved_1_Cyl_for_test			;R66
		dec	bx			;R66
endif ;Reserved_1_Cyl_for_test			;R66
@@:						;R66
		shr	bx,1
		shl	ah,1
;R38 start
		test	ah,80h
		jnz	short @F
		cmp	bx,1024
;R66		ja	short Tran_CHS_LARGE
		ja	short @B		;R66
@@:
;R38 end
;R83 start
		cmp	bx,1024
		jbe	short Cyl_Below_1024
		movzx	cx,byte ptr [bp+si+2]	;physical heads
		cmp	cl,10h
		jne	short Cyl_Below_1024
		mov	ax,[bp+si]		;physical cylinders
		mul	cx
		dec	cl
		div	cx
		mov	bx,ax			;BX = new cylinders
		mov	[bp+si],ax
		mov	ah,0fh			;AH = new heads
		mov	[bp+si+2],ah
		jmp	short Tran_CHS_LARGE
Cyl_Below_1024:
;R83 end
		ret
Tran_CHS_LARGE	Endp

endif ;IDE_LBA_MODE_SUPPORT

;[]===================================================================[]
;Input	:	ES = F000h
;		DI = offset for HDD parameters to copy into
;		AX = 0 HDD type 48 for user type of HDD C
;		     1 HDD type 49 for user type of HDD D
;		     2 HDD type 50 for user type of HDD E
;		     3 HDD type 51 for user type of HDD F
;[]===================================================================[]
HDD_Type_Tbl:
		dw	offset HDDD_ITEM
		dw	offset HDDC_ITEM
	ifdef	Support_4_IDE
		dw	offset HDDF_ITEM
		dw	offset HDDE_ITEM
	endif	;Support_4_IDE

		public	Set_HDD_parm
Set_HDD_parm	PROC	NEAR
		push	di
		mov	di,offset cs:HDD_Type_Tbl	;128k
		shl	ax,1
		add	di,ax
		mov	bx,cs:[di]
		call	F000_Get_HDD_CMOS_Info
		mov	si,di	;SI = CMOS stack location
		pop	di
		cld
ifdef	IDE_LBA_MODE_SUPPORT
;R90		mov	bx,[bp+si+0]		;cylinder
		mov	ah,[bp+si+2]		;head
;R73		F000_call	Chk_If_LBA_Mode
		call	far ptr fPROC_Chk_If_LBA_Mode		;R73
		je	short @F
;R73		F000_call	Chk_If_LARGE_Mode
		call	far ptr fPROC_Chk_If_LARGE_Mode		;R73
		jne	short Not_support_LBA	;no, goto CHS
Set_Large_Parm:					;R83
		mov	bx,[bp+si+0]		;R90 cylinder
		call	Tran_CHS_LARGE
		mov	al,[bp+si+7]		;physical sectors
                mov	cx,[bp+si+3]		;set precomp
		jmp	short Set_LBA_parm
@@:
;R83 start
		cmp	ah,0fh			;physical heads is 15?
		jne	short Not_Doubt		;No,skip
		mov	cx,[bp+si+5]		;get landing cylinders
		inc	cx			;set to physical cyls
;R90		cmp	bx,cx			;phy = land?
		cmp	[bp+si+0],cx		;R90 phy = land?
		je	short Not_Doubt		;Yes,set LBA
		dec	cx
		mov	[bp+si+5],cx		;set new landing cylinders
		jmp	short Set_Large_Parm
Not_Doubt:
;R83 end
		mov	bx,[bp+si+0]		;R90 cylinder
		mov	al,[bp+si+7]		;sector
		call	Tran_CHS_LBA
		xor	cx,cx			;set precomp = 0 for LBA
Set_LBA_parm:
		push	di
		xchg	ax,bx			;logical cylinders
;R35B		push	ax			;R35
		stosw
		mov	al,bh			;logical heads
		stosb
		mov	al,0a0h			;LBA signature
		stosb
		mov	al,[bp+si+7]		;physical sectors
		stosb
		mov	ax,cx			;set precomp
		stosw
 		xor	al,al
		stosb				;reserve byte

		cmp	byte ptr [bp+si+2],8	;>8 heads?
		jbe	short @F 		;no, mark as 0
		mov	al,8			;yes, mark as 8
@@:
		stosb				;HEAD < 8 --> bit 3 = 0
						;HEAD > 8 --> bit 3 = 1
		mov	ax,[bp+si]		;R35B physical cylinders
;R35		mov	ax,[bp+si]		;physical cylinders
;R35 start
;R35B		mov	al,bl
;R35B		mul	bh
;R35B		pop	cx
;R35B		dec	cx
;R35B		mul	cx
;R35B		or	dx,dx			;R35A
;R35B		jnz	@F			;R35A
;R35B		or	ax,ax			;R35A
;R35B		jz	short HDD_Size_Not_None	;R35A
;R35B@@:						;R35A
;R35B		push	ax
;R35B		mov	ax,[bp+si+2]		;physical heads
;R35B		mul	byte ptr [bp+si+7]	;physical sectors
;R35B		mov	cx,ax
;R35B		pop	ax
;R35B		div	cx
;R35BHDD_Size_Not_None:				;R35A
;R35 end
		stosw
		mov	ax,[bp+si+2]		;physical heads
		stosb
		mov	ax,[bp+si+5]		;landing zone
		stosw
		mov	al,bl			;logical sectors
		stosb
		pop	di
		xor	al,al
;calculate checksum
		mov	cx,15
@@:
		add	al,es:[di]
		inc	di
		loop	@B
		xor	al,0ffh
		inc	al
		stosb			;Checksum
		jmp	short Set_HDD_parm_Ret
Not_support_LBA:
endif	;IDE_LBA_MODE_SUPPORT
		mov	ax,[bp+si]		;get cylinders
		stosw
                mov	ax,[bp+si+2]		;get heads
                stosb
		xor	ax,ax
		stosw				;unused
                mov	ax,[bp+si+3]		;get precomp
           	stosw
		xor	al,al
		stosb				;unused
		cmp	byte ptr [bp+si+2],8	;>8 heads?
		jbe	short hdi_1 		;no, mark as 0
		mov	al,8			;yes, mark as 8
hdi_1:
		stosb
		xor	ax,ax
		stosw
		stosb				;unused
                mov	ax,[bp+si+5]		;get landing zone
           	stosw
		mov	al,[bp+si+7]		;get sectors
                stosb
                xor	al,al
                stosb				;unused
Set_HDD_parm_Ret:
		ret
Set_HDD_parm	ENDP

;[]==================================================================[]
;
; Procedure Name: AUTO_IDE_DETECT
;
;
; Saves:
; Input:
;
;	DL: = 80H FOR DISK 0
;	    = 81H FOR DISK 1
;		:
;		:
;
;	ES:DI  -> 16 BYTES BUFFER FOR DISK PARAMETERS
;
; Output:
;
;	CARRY SET IF ERROR
;	CARRY CLEAR IF SUCCESS
; 	ES:DI  -> 16 BYTES BUFFER
;	AH     = ERROR CODE
;	DX     = Identify Drive word 49 (for LBA mode)
;
; [Note]:
;
;
;
; Author: William Chang
; Date: May 1, 1991
;
; Name	| Date		| Description
; -----------------------------------------------------------------
; WC	| 05/01/91	| Initial version
;[]==================================================================[]

		PUBLIC	AUTO_IDE_DETECT
AUTO_IDE_DETECT	PROC	NEAR

		push	ds			; save registers
		push	es
		push	di
		push	si
		push	bx
		push	cx
		push	CDROM_Exist_Flag[bp]	;R07A
		push	dx

IFDEF	IDE_DETECT_RESET
;R60		call	far ptr Reset_Recal_Hd	; reset controller and recal drive
		call	Reset_HDD_controller	;R60
ENDIF	;IDE_DETECT_RESET

		mov	si,G_RAM
		mov	ds,si
		xor	si,si

ifdef	Support_4_IDE
		cmp	dl,81h			;Is secondary channel?
		jbe	short @F		;No,jump
		mov	si,80h			;modulate port to 17Xh
@@:
endif	;Support_4_IDE
		mov	dx,TF_STATUS
		sub	dx,si			;dx=1X7h
		xor	cx,cx
@@:
		in	al,dx					
		newiodelay
		test	al,80h			;Test controller busy?
		jz	short @F		;No,jump
		loop	@B			;Go on check...
@@:
		cmp	byte ptr IDE_Detect_Counter[bp],0
		ja	short @F
		mov	byte ptr IDE_Detect_Counter[bp],Drive_delay_time
		cmp	word ptr ds:USER_REBOOT, CTRL_ALT_DEL
		jne	short @F
		mov	byte ptr IDE_Detect_Counter[bp],1
@@:
		mov	ah,al			;Store status(port 1X7h) value
		pop	dx
		push	dx
		mov	al,DRIVE_0		;assume master drive(AL=0A0h)
		test	dl,01h			;Is detect master drive?
		jz	short @F		;No,jump
		mov	al,DRIVE_1		;set is slave drive(AL=0B0h)
@@:
		mov	dx,TF_DRV_HD		;DX = 1X6h
		sub	dx,si
		out 	dx,al			;set port value
		newiodelay
;R07C start
		xor	ch,ch
ifndef	NO_CDROM_DETECT				;R05A
		cmp	word ptr IDE_Detect_Skip_Key[bp],K_ESC1
		je	short @F
		pop	cx			;get will detect drive number
		push	cx
		mov	ch,1
		sub	cl,80h
		shl	ch,cl
@@:
endif	;NO_CDROM_DETECT			;R05A
		test	byte ptr CDROM_Exist_Flag[bp],ch	;Is CDROM?
		jz	short @F
;R10A		mov	ah,al
		mov	ah,al					;R10B
ifdef CDROM_detect_short_time
		mov	bl,2
else ;CDROM_detect_short_time
		mov	bl,15
endif ;CDROM_detect_short_time
		jmp	short Check_next
@@:
;R07C end
		test	ah,80h			;check previous status is busy?
;R07C		jnz	short @F		;Yes,jump
		jnz	short PreStatus_Busy	;Yes,jump
		mov	ah,al			;No,then check this port is
		in	al,dx			;available?

;-------------------------------------------------------------
		cmp	al,0ffh
		jne	short Set_OK
;R07C		mov	bl,10
		mov	bl,20			;R07C
Check_next:
		inc	dl
		push	ax
		call	chk_esc_key		;R14
		jnc	short Not_skip_key	;R14
		pop	bx			;R14
		jmp	exit_with_error		;R14
Not_skip_key:					;R14
		xor	bh,bh
		push	cx			;R07C
;R07C		mov	cx,33333/2		;0.5 second time out
		mov	cx,33333/8		;R07C 0.125 second time out
		mov	ax,8000h
		call	F000_Wait_For_Port
		pop	cx			;R07C
		dec	dl
		or	ah,ah
		pop	ax
		mov	al,ah
		out	dx,al
		newiodelay
		in	al,dx
		jz	short Set_OK
		dec	bl
		jnz	short Check_next
Set_OK:
;-------------------------------------------------------------

		cmp	al,ah
		jne	exit_with_error		;Not available then skip
;R07C @@:
PreStatus_Busy:					;R07C
		mov	dx,TF_STATUS
		sub	dx,si
		in	al,dx			;get status value
		newiodelay
		test	al,20h			;check have connected drive?
		jnz	exit_with_error		;None drive then skip...
;R07 start
;R07C		xor	ch,ch
;R07C		cmp	word ptr IDE_Detect_Skip_Key[bp],K_ESC1
;R07C		je	short Resend_Identify_Cmd
;R07C		pop	cx			;get will detect drive number
;R07C		push	cx
;R07C		mov	ch,1
;R07C		sub	cl,80h
;R07C		shl	ch,cl
		mov	cl,1					;R10A
		test	byte ptr CDROM_Exist_Flag[bp],ch	;R10A
		jnz	short Resend_Identify_Cmd		;R10A
		or	byte ptr CDROM_Exist_Flag[bp],ch	;R10A
		xor	cl,cl					;R10A
Resend_Identify_Cmd:
;R07 end
		mov	dx,TF_STATUS	;R10A
		sub	dx,si		;R10A
		mov	ax,8000h		; check for bit 7 = 0
		xor	bh,bh
		call	Wait_for_Port1		; wait for not busy
		jc	exit_with_error		; and get to common error exit
;R41 start
		push	cx
		xor	cx,cx			;64k counter
@@:
		in	al,dx			;get status
		newiodelay
		test	al,8			;any remain data
		jz	short @F		;no,skip
		sub	dl,7			;set to data port
		in	ax,dx			;read garbage data
		add	dl,7			;set to status port
		loop	@B			;next loop
@@:
		pop	cx
;R41 end
;R32 start
		test	byte ptr CDROM_Exist_Flag[bp],ch	;Is CDROM?
		jnz	short @F		;Yes,skip drive ready check
;R57 start
		push	cx
		xor	bx,bx
		mov	cx,33333/320		;1/320 second time out
		call	F000_Wait_Refresh
		pop	cx
;R57 end
		mov	ax,5050h
		mov	bh,10h
		call	wait_for_port1
@@:
;R32 end
;R20 start
		pop	dx
		push	dx
		mov	al,DRIVE_0		;assume master drive(AL=0A0h)
		test	dl,01h			;Is detect master drive?
		jz	short @F		;No,jump
		mov	al,DRIVE_1		;set is slave drive(AL=0B0h)
@@:
		mov	dx,TF_DRV_HD		;DX = 1X6h
		sub	dx,si
		out 	dx,al			;set port value
		newiodelay
;R20 end
; Identify drive
		mov	al,COMMAND_ID_DRIVE	; set for IDENTIFY DRIVE
;R07		pop	cx			;get will detect drive number
;R07		push	cx
;R07		mov	ch,1
;R07		sub	cl,80h
;R07		shl	ch,cl
		test	byte ptr CDROM_Exist_Flag[bp],ch	;Is CDROM?
		jz	short @F		;No,jump
		mov	al,ATAPI_Identify_Cmd	;Set CDROM identify command
@@:
		mov	dx,TF_COMMAND		; get to command register
		sub	dx,si
		out	dx,al			;send command
		newiodelay

		mov	dx, TF_STATUS		;R16
		sub	dx,si			;R16
;R04		mov	ax,8000h		;check controller idle?
;R16		mov	ax,0f050h		;R04
;R06 start
		test	byte ptr CDROM_Exist_Flag[bp],ch	;Is CDROM?
;R16		jz	short @F		;No,jump
;R16		mov	ax,8000h		;check controller idle?
;R16 start
		jnz	short @F		;Yes,skip drive ready check
		mov	ax,5050h
		mov	bh,10h
		call	wait_for_port1
		jc	short detect_other_cmd
;R16 end
@@:
;R06 end
;R16		mov	dx, TF_STATUS
;R16		sub	dx,si
;R06		mov	bh,20h
;R16		mov	bh,10h			;R06
		mov	ax,8000h		;R16
		xor	bh,bh			;R16
		call	wait_for_port1
;R07		jc	exit_with_error		;If busy then get to common error and exit
		jc	short @F		;R07
;R17 start
		mov	ax,101h			;check status error bit
;R17A		mov	bh,8			;wait for 0.5 second
;R17B		mov	bh,10h			;R17A wait for 1 second
		mov	bh,8			;R17B wait for 0.5 second
		call	wait_for_port1		;check it
		jc	short Send_Cmd_OK	;no error then jump
;R17 end
;R17		in	al,dx
;R17		newiodelay
;R17		test	al,1			;Check command have any error?
;R07		jnz	exit_with_error		;Yes,skip it
;R07 start
;R17		jz	short Send_Cmd_OK
@@:
detect_other_cmd:				;R16
;R10C start
		pop	dx
		push	dx
		test	dl,1				;Is master drive?
		jnz	short @F
;--------------------- reset HDD controller ------------------------
		mov	dx,DISK_STAT_PORTB
		sub	dx,si
		mov	al,04			; assert reset
		out	dx,al
		newiodelay

		push	cx
		mov	cx,21h
		align	4
		loop	short $
		pop	cx

		xor	al,al			; deassert reset
		out	dx,al
		newiodelay
;----------------------------------------------------------------
@@:
;R10C end
		or	ch,ch
		jz	exit_with_error
;R10A		test	byte ptr CDROM_Exist_Flag[bp],ch
		test	cl,1					;R10A
;R07A		jz	short @F
;R07A		not	ch
;R07A		and	byte ptr CDROM_Exist_Flag[bp],ch
;R07A		jmp	exit_with_error
;R07A@@:
		jnz	exit_with_error				;R07A
;R10A		or	byte ptr CDROM_Exist_Flag[bp],ch
;R10A start
		xor	cl,1
		mov	dl,ch
		not	dl
		and	byte ptr CDROM_Exist_Flag[bp],dl
;R10C		pop	dx
;R10C		push	dx
;R10C		test	dl,1				;Is master drive?
;R10C		jnz	short Resend_Identify_Cmd	;No,skip reset controller
;R10C;--------------------- reset HDD controller ------------------------
;R10C		mov	dx,DISK_STAT_PORTB
;R10C		sub	dx,si
;R10C		mov	al,04			; assert reset
;R10C		out	dx,al
;R10C		newiodelay
;R10C
;R10C		push	cx
;R10C		mov	cx,21h
;R10C		align	4
;R10C		loop	short $
;R10C		pop	cx
;R10C
;R10C		xor	al,al			; deassert reset
;R10C		out	dx,al
;R10C		newiodelay
;R10C;----------------------------------------------------------------
;R10A end
;R16		jmp	short Resend_Identify_Cmd
		jmp	Resend_Identify_Cmd	;R16
Send_Cmd_OK:
;R07 end
;R51 start
		mov	bx,1				;indicate HDD (ATA device)
;R51A		test	cl,1				;check is ATA or ATAPI?
;R51A		jnz	short @F			;Is ATA then jump
		test	byte ptr CDROM_Exist_Flag[bp],ch;R51A check is ATA or ATAPI?
		jz	short @F			;R51A Is ATA then jump
		mov	bx,2				;indicate CDROM (ATAPI device)
@@:
		pop	cx
		push	cx				;get drive number (80h,81h...)
		and	cl,3				;isolate useable bits
		shl	cl,2				;set shift count
		shl	bx,cl				;shift to corespond with IDE_device_item[bp] byte
		or	IDE_device_item[bp],bx		;store to stack
;R51 end
		mov	ax,808h			;wait DRQ
		mov	dx, TF_STATUS
		sub	dx,si
		mov	bh,10h
		call	wait_for_port1
;R42		jc	exit_with_error
		jc	short detect_other_cmd	;R42

		push	es			;prepare to get information
		push	di
		mov	di,HDD_TEMP_RAM_SEG
		mov	es,di
		xor	di,di
		push	di
		mov	cx,100h
		mov	dx,1f0h
		sub	dx,si
		cld
@@:
		insw				;get drive information
		loop	@B
		sub	di,200h-27*2
		mov	cx,20
@@:
		mov	ax,es:[di]
		xchg	al,ah
		mov	es:[di],ax
		add	di,2
		loop	@B
		pop	di
		pop	si
		pop	ds
		add	dx,7			;discard any garbage data
		xor	cx,cx
@@:
		in	al,dx
		test	al,8
		jz	short @F
		loop	@B
@@:
;R47 -start
		pop	cx				;
       		push	cx				;get drive number
		call	Set_IDE_SPecific		
;R47 -end

		mov	ax,WORD PTR ES:[DI+0]		;word 0 = General configuration
		cmp	ax,-1				;signature information
		je	exit_with_error
		mov	WORD PTR DS:[SI.MANUFACTURER],ax
		mov	ax,WORD PTR ES:[DI+1*2]		;word 1 = cylinders
;R37 start
		mov	dh,BYTE PTR ES:[DI+3*2]		;word 3 = heads
		mov	dl,BYTE PTR ES:[DI+6*2]		;word 6 = sectors
		test	byte ptr es:[di+1],80h		;R37A Is ATA device?
		jnz	short @F			;R37A No,skip
		test	byte ptr ES:[DI+49*2+1],2	;check word 49(LBA) to
		jz	short @F		;confirm word 60-61 is valid?
		cmp	dword ptr ES:[DI+60*2],0
		je	short @F
		cmp	dword ptr ES:[DI+60*2],0ffffffffh
		je	short @F
;R37E start
		cmp	word ptr ES:[DI+61*2],0ff0h	
		ja	short @F	  
;check total number of Addressable sectors >ff00000h(136.9GB)
;R37E end
;R37F start
ifdef Dont_Use_IDE_Word_6061_in_Size
		cmp	word ptr ES:[DI+61*2],0fbh	;word 61 = physical sectors high dword
		jb	short @F			; > 8.4GB (0FB0400H sectors)?
endif ;Dont_Use_IDE_Word_6061_in_Size
;R37F end
		push	dx
		mov	al,dh
		mul	dl
		mov	cx,ax
		mov	ax,ES:[DI+60*2]			;word 60 = physical sectors low dword
		mov	dx,ES:[DI+61*2]			;word 61 = physical sectors high dword
		div	cx
		pop	dx
@@:
;R37 end
		mov	WORD PTR DS:[SI.CYLS],ax
;R37		mov	al,BYTE PTR ES:[DI+3*2]		;word 3 = heads
;R37		cmp	al,16
		cmp	dh,16				;R37
		ja	Exit_With_Error
;R37		mov	BYTE PTR DS:[SI.HEADS],al
;R37		mov	al,BYTE PTR ES:[DI+6*2]		;word 6 = sectors
;R37		mov	BYTE PTR DS:[SI.SECTORS],al
		mov	BYTE PTR DS:[SI.HEADS],dh	;R37 store heads
		mov	BYTE PTR DS:[SI.SECTORS],dl	;R37 store sectors

		mov	al,BYTE PTR ES:[DI+47*2]	;word 47 = multiple buffer size

		mov	dx,G_RAM
		mov	ds,dx
		pop	dx
		push	dx
		push	si
		mov	si,offset SECTOR_PER_BLOCK_0
		cmp	dl,80h				;is drive 0 ?
		je	short @F
		mov	si,offset SECTOR_PER_BLOCK_1

	ifdef	Support_4_IDE
		cmp	dl,81h				;is drive 1 ?
		je	short @F
		mov	si,offset SECTOR_PER_BLOCK_2
		cmp	dl,82h				;is drive 2 ?
		je	short @F
		mov	si,offset SECTOR_PER_BLOCK_3
	endif	;Support_4_IDE
	@@:
		mov	[si],al
		pop	si

get_block_over:
;R28 start
ifndef	NO_CDROM_DETECT
;R33CMD_DRQ_TYPE	EQU	01100000b
;R33		mov	al,es:[di]
;R33		and	al,CMD_DRQ_TYPE
;R33		jne	short @F
;R33		pop	cx
;R33		push	cx
;R33		sub	cl,80h
;R33		mov	al,10h
;R33		shl	al,cl
;R33		or	byte ptr ds:[ATAPI_Byte],al
;R33@@:
;R34ifdef	LS120_SUPPORT
;R31		mov	al,es:[di+1]
;R31		and	al,1fh
;R31		jnz	short Not_floptical_Drive
;R56		call	CDROM_Special_Check			;R43
;R69		far_call  <offset CDROM_Special_Check>, 06000h	;R56 XGROUP

		mov	ax,es:[di]				;R31
		and	ah,0dfh					;R31
		cmp	ah,80h					;R31
;R33		jne	short Not_floptical_Drive		;R31
		jne	Not_floptical_Drive			;;R33
;R54 start
;;		je	short Maybe_Floptical
;;		test	al,80h
;;		jnz	exit_with_error
;;Maybe_Floptical:
;R54 end
		test	al,80h					;R31
;R33		jz	short Not_floptical_Drive		;R31
		jz	Not_floptical_Drive			;R33
;--------------------------------------------------------------------
;----- Found Floptical drive
;R36 start
ifndef	LS120_SUPPORT
ifndef	IOMEGA_ZIP_Support
		jmp	exit_with_error
endif	;IOMEGA_ZIP_Support
endif	;LS120_SUPPORT
;R36 end
;R55		test	byte ptr FLOPPY_TYPE[bp],0f0h	;R33B check drive A exist?
;R55		jz	short Assign_ARMD		;R33B
;R55		test	byte ptr FLOPPY_TYPE[bp],0fh	;check drive B exist?
;R33		jnz	short Not_floptical_Drive	;Yes,ignore ARMD drive
;R55		jnz	Not_floptical_Drive		;R33
Assign_ARMD:						;R33B
;R34 start
ifdef	IOMEGA_ZIP_Support
		test	al,20h
		pop	ax
		push	ax
;R63		jz	short Not_IOMEGA_ZIP
		jz	Not_IOMEGA_ZIP			;R63
;R51 start
		mov	cl,al				;get drive number (80h,81h...)
		and	cl,3				;isolate useable bits
		shl	cl,2				;set shift count
		mov	bx,0fff0h			;R51B
		rol	bx,cl				;R51B shift to corespond with IDE_device_item[bp] byte
		and	IDE_device_item[bp],bx		;R51B mask bits
		mov	bx,4				;indicate ZIP-100 (ref. bsetup.inc)
		shl	bx,cl				;shift to corespond with IDE_device_item[bp] byte
		or	IDE_device_item[bp],bx		;store to stack
;R51 end
;R63 start
		push	ax				;store Ax value
		test	byte ptr es:[di+50*2],00000010b	;test word 50 bit 1
		jz	short SMCC_Error		;not support floppy mode
;R63B start
ifdef ZIP_Floppy_Depand_on_Jumper
		push	ds
		push	cs
		pop	ds			;Source string segment
		add	di,27*2+34		;ZIP Floppy string offset
		lea     si,ZIP_Floppy_Str
		mov     cx,ZIP_Floppy_Str_Len
		rep     cmpsb			;compare it
		pop	ds
		jne	short SMCC_Error	;Not equate then skip compare
		jmp	short Set_ZIP_Floppy_Flag
ZIP_Floppy_Str:		db	'Floppy'
ZIP_Floppy_Str_Len	equ	$-offset ZIP_Floppy_Str
Set_ZIP_Floppy_Flag:
else ;ZIP_Floppy_Depand_on_Jumper
;R63B end
		push	word ptr ds:[ATAPI_byte]	;store ATAPI_byte of G_RAM
		mov	cl,al				;get drive number
		and	cl,3				;isolate bits
		or	cl,44h				;set drive exist and ZIP flag
		mov	byte ptr ds:[ATAPI_byte],cl	;set to ATAPI_byte for call std_atapi
		xor	dl,dl				;drive letter
		mov	ah,0feh				;set MISC function
		mov	cx,'PO'				;signature
		mov	bx,'ST'				;signature
		F000_call	std_atapi		;call function
		pop	word ptr ds:[ATAPI_byte]	;restore ATAPI_byte
		jc	short SMCC_Error
endif ;ZIP_Floppy_Depand_on_Jumper			;R63B

		pop	ax				;get drive number
		push	ax
		mov	cl,al
		and	cl,3				;isolate bits
		mov	al,1				;assume drive 0
		shl	al,cl				;shift to correspond bit
		lea	si,DGROUP:IoMegaZip_Flag	;var shadow offset
		or	al,gs:[si]			;or original value
		Post_func_call	Write_F000_shadow_byte	;write to F000 shadow
SMCC_Error:
		pop	ax
;R63 end
		test	byte ptr ds:[ATAPI_byte],4	;have any ATAPI drive exist?
		jz	short Init_IOMEGA_ZIP		;No,jump init ATAPI_Byte
		test	byte ptr FLOPPY_TYPE[bp],0fh	;check drive B exist?
		jnz	Not_floptical_Drive		;Yes,skip
		test	byte ptr ds:[ATAPI_byte],8	;check have ZIP emul to B
		jnz	Not_floptical_Drive		;Yes,skip
		sub	al,80h				;get IDE scheme
		shl	al,4				;shift to ATAPI drive 1 area
		or	al,80h				;indicate ATAPI drive 1 is ZIP-100
		or	byte ptr ds:[ATAPI_byte],al	;Set to ATAPI_byte
		add	HARDWARE,40h			;increase 40:HARDWARE floppy drive number
		jmp	Not_floptical_Drive
Init_IOMEGA_ZIP:
		sub	al,80h				;get IDE scheme
		or	al,44h				;indicate ATAPI drive 0 exist and set to ZIP-100
		test	byte ptr FLOPPY_TYPE[bp],0f0h	;check drive A exist?
		jz	short @F			;No,jump and set to be drive A
		test	byte ptr FLOPPY_TYPE[bp],0fh	;R55 check drive B exist?
		jnz	Not_floptical_Drive		;R55 Yes,skip
		or	al,8				;set ATAPI drive 0 is B
		add	HARDWARE,40h			;increase 40:HARDWARE floppy drive number
@@:
		or	byte ptr ds:[ATAPI_byte],al	;Set to ATAPI_byte
		or	HARDWARE,1			;Set 40:HARDWARE floppy drive is available
		jmp	Not_floptical_Drive
Not_IOMEGA_ZIP:
;R36 start
else	;IOMEGA_ZIP_Support
		test	al,20h
		jnz	exit_with_error
;R36 end
endif	;IOMEGA_ZIP_Support
ifdef	LS120_SUPPORT
;R34 end
		pop	ax
		push	ax
;R51 start
		mov	cl,al				;get drive number (80h,81h...)
		and	cl,3				;isolate useable bits
		shl	cl,2				;set shift count
		mov	bx,0fff0h			;R51B
		rol	bx,cl				;R51B shift to corespond with IDE_device_item[bp] byte
		and	IDE_device_item[bp],bx		;R51B mask bits
		mov	bx,3				;indicate LS120 (ref. bsetup.inc)
		shl	bx,cl				;shift to corespond with IDE_device_item[bp] byte
		or	IDE_device_item[bp],bx		;store to stack
;R51 end
		sub	al,80h
;R55 start
		test	byte ptr FLOPPY_TYPE[bp],0f0h	;check drive A exist?
		jz	short @F			;No,Set flag for LS120
		test	byte ptr FLOPPY_TYPE[bp],0fh	;check drive B exist?
		jnz	Not_floptical_Drive		;Yes,skip
@@:
;R55 end
;R33 start
		lea	si,Floptical0_EMUL_CYL_SEC
		test	byte ptr ds:[ATAPI_Byte],4
		jz	short ARMD_Not_Exist
		lea	si,Floptical1_EMUL_CYL_SEC
		and	byte ptr ds:[ATAPI_Byte],0cfh
		shl	al,4
		or	byte ptr ds:[ATAPI_Byte],al
		jmp	short Set_ARMD_Scheme_OK
ARMD_Not_Exist:
;R33 end
;R33A		or	al,4		;indicate 120MB floptical exist
;R33A		and	byte ptr ds:[ATAPI_Byte],0f8h	;set drive scheme
		and	byte ptr ds:[ATAPI_Byte],0fch	;R33A
		or	byte ptr ds:[ATAPI_Byte],al
Set_ARMD_Scheme_OK:					;R33

		or	HARDWARE,1
;R34		and	HARDWARE,3fh
		cmp	byte ptr es:[di+4*2],0	;have any media in drive?
		jne	short Set_Media_Para	;None any media
;R33		mov	ds:[Floptical_EMUL_CYL_SEC],0c3e0h
;R33		mov	ds:[Floptical_EMUL_HEAD],8
		mov	word ptr ds:[si],0c3e0h		;R33
		mov	byte ptr ds:[si+2],8		;R33
		jmp	short Set_Para_OK
Set_Media_Para:
		mov	ax,es:[di+1*2]		;cylinders(word 1)
		xchg	al,ah
		shl	al,6
		or	al,es:[di+6*2]		;sectors per track(word 6)
;R33		mov	ds:[Floptical_EMUL_CYL_SEC],ax
		mov	word ptr ds:[si],ax		;R33
		mov	al,es:[di+3*2]		;heads(word 3)
;R33		mov	byte ptr ds:[Floptical_EMUL_HEAD],al
		mov	byte ptr ds:[si+2],al		;R33
Set_Para_OK:
;R33 start
		test	byte ptr ds:[ATAPI_Byte],4
		jz	short @F
		test	byte ptr ds:[ATAPI_Byte],8
		jnz	short Not_floptical_Drive
		add	HARDWARE,40h
;R34		or	byte ptr ds:[ATAPI_Byte],40h
		jmp	short Not_floptical_Drive
@@:
;R33 end
		test	byte ptr FLOPPY_TYPE[bp],0f0h	;check drive A exist?
		jnz	short @F			;Yes,assign ARMD is B
		and	byte ptr ds:[ATAPI_Byte],0f7h
		test	byte ptr FLOPPY_TYPE[bp],0fh	;R33B check drive A exist?
		jz	short Set_ARMD_Drive_Exist	;R33B
		add	HARDWARE,40h			;R33B
;R33A		jmp	short Not_floptical_Drive
		jmp	short Set_ARMD_Drive_Exist	;R33A
@@:
		add	HARDWARE,40h
		or	byte ptr ds:[ATAPI_Byte],8
Set_ARMD_Drive_Exist:					;R33A
		or	byte ptr ds:[ATAPI_Byte],4	;R33A indicate 120MB floptical exist

;R36 start
else	;LS120_SUPPORT
		test	al,20h
		jz	exit_with_error
;R36 end
endif	;LS120_SUPPORT					;R34
Not_floptical_Drive:
;R34endif	;LS120_SUPPORT
endif	;NO_CDROM_DETECT
;R28 end
ifdef	IDE_MODE_3_SUPPORT
		mov	bx,ES:[DI+53*2]
		test	bl,00000010b		;Words 64-70 are valid?
		jz	short Mode_0_1_2	;No
		
		mov	bx,ES:[DI+64*2]		;Get Advanced PIO mode 3-N
		test	bl,11111111b		;Any mode?
		jz	short Mode_0_1_2	;No
		
		mov	bh,3			;From mode 3
		mov	cx,2			;Test mode 3,4
Test_Mode:
		test	bl,01h			;Get mode?
		jnz	short Set_IDE_Timing	;Yes
		shr	bl,1
		inc	bh			;Next mode
		loop	short Test_Mode

Mode_0_1_2:

		mov	bx,ES:[DI+51*2]		;Get data transfer timing mode
		and	bh,03h

Set_IDE_Timing:

		pop	dx			;Get drive number
		push	dx			;Save Value
 		F000_Call Ct_Set_IDE_Timing
endif	;IDE_MODE_3_SUPPORT

;R15 ifdef	NEW_IDE_MODE_3
ifdef	SET_MODE2_FOR_MAXTOR_7240AV
		mov	ah,2	;set mode 2

		cmp	es:[di+3ch],34322037H		;maxtor 7240AV
		jne	short Not_Maxtor_7240AV
		cmp	es:[di+40h],41563020H		;maxtor 7240AV
		je	short Below_Mode3
Not_Maxtor_7240AV:
endif;	SET_MODE2_FOR_MAXTOR_7240AV

		mov	ah,ES:[DI+51*2+1]		;get mode below 2
		test	byte ptr ES:[DI+53*2],02H	;advance PIO support ?
		jz	short Below_Mode3		;no,

		;it may be mode 3 or 4
		mov	al,ES:[DI+64*2]
		or	al,al				;mode 3 and above ?
		jz	short Below_Mode3

		mov	ah,2				;assume mode 
@@:
		inc	ah
		shr	al,1
		or	al,al
		jnz	short @B
Below_Mode3:

		mov	al,dl				;get drive number
		and	al,03H				;valid bits
		movzx	si,al
		add	si,HDD_0_MODE
;Set mode 0 if PIO mode large than 5
		cmp	ah,05H				;mode 5
		jbe	short @F
		xor	ah,ah				;set mode 0
@@:
		mov	byte ptr [bp+si],ah

;R15 endif	;NEW_IDE_MODE_3

;R30 start
ifdef	Ultra_DMA33_support
		mov	al,dl				;get drive number
		and	al,03H				;valid bits
;R30A start
		push	ax
		shl	al,1
		movzx	si,al
		add	si,offset cs:Sdma_Item_Off
		mov	si,cs:[si]
		call	F000_GetItem_Value
		mov	cl,al
		pop	ax
		movzx	si,al
		add	si,HDD_0_UltraDMA
		mov	ah,0ffh
;R88 start
ifdef Dont_support_UltraDMA_For_all_CDROM
		push	cx
		mov	cx,IDE_device_item[bp]	;get device type
		test	al,2			;channel 2?
		jz	short @F
		mov	cl,ch			;get channel 2 device to CL
@@:
		test	al,1			;slave?
		jz	short @F		;No,jump
		shr	cl,4			;load slave type
@@:
		and	cl,0fh			;isolate useful bits
		cmp	cl,2			;Is CDROM device?
		pop	cx
		je	short Ultra_DMA_Exit	;Yes,skip
endif ;Dont_support_UltraDMA_For_all_CDROM
;R88 end
;R65 start
;R88 ifdef No_UltraDMA_for_AcerCDROM
;R88 		jmp	short Scan_AcerCDROM
;R88 AcerCDROM_Model:	db	'ATAPI CD-ROM DRIVE 32X MAXIMUM'
;R88 AcerCDROM_Model_Len	equ	$-offset AcerCDROM_Model
;R88 AcerCDROM_Rev:	db	'23P2'
;R88 AcerCDROM_Rev_Len	equ	$-offset AcerCDROM_Rev

;R88 start
ifdef No_UltraDMA_for_AcerCDROM
Dont_support_UltraDMA_For	equ	'ATAPI CD-ROM DRIVE 32X MAXIMUM'
Dont_support_UltraDMA_Rev	equ	'23P2'
endif ;No_UltraDMA_for_AcerCDROM

ifdef Dont_support_UltraDMA_For
		jmp	short Scan_AcerCDROM
AcerCDROM_Model:	db	Dont_support_UltraDMA_For
AcerCDROM_Model_Len	equ	$-offset AcerCDROM_Model
ifdef Dont_support_UltraDMA_Rev
AcerCDROM_Rev:		db	Dont_support_UltraDMA_Rev
AcerCDROM_Rev_Len	equ	$-offset AcerCDROM_Rev
endif ;Dont_support_UltraDMA_Rev
;R88 end
Scan_AcerCDROM:
		push	ds
		push	si
		push	cx
		push	di

		push	cs
		pop	ds			;Source string segment
		add	di,27*2			;Model string offset
		lea     si,AcerCDROM_Model
		mov     cx,AcerCDROM_Model_Len
		rep     cmpsb			;compare it
		jne	short Not_AcerCDROM	;Not equate then skip compare
ifdef Dont_support_UltraDMA_Rev			;R88
		pop	di
		push	di
		add	di,23*2			;Revision string offset
		lea     si,AcerCDROM_Rev
		mov     cx,AcerCDROM_Rev_Len
		rep     cmpsb
endif ;Dont_support_UltraDMA_Rev		;R88
Not_AcerCDROM:
		pop	di
		pop	cx
		pop	si
		pop	ds
		je	short Ultra_DMA_Exit	;Revision string is '323P' then skip set Ultra DMA
;R88 endif ;No_UltraDMA_for_AcerCDROM
endif ;Dont_support_UltraDMA_For		;R88
;R65 end
		or	cl,cl
		jz	short Ultra_DMA_Exit
;R30A end
;R30A		movzx	si,al
;R30A		add	si,HDD_0_UltraDMA
;R30A		mov	ah,0ffh
ifdef	Disable_Ultra_DMA33_When_WD_HardDisk		;R49 - starts
		cmp	Word ptr ES:[DI+10*2], 05744h	;"WD"=5744h
		jz	short Ultra_DMA_Exit
endif;	Disable_Ultra_DMA33_When_WD_HardDisk		;R49 - ends
ifdef	Disable_Ultra_DMA33_When_SAMSUNG_WU32543A	;R70 - starts
		cmp	Word ptr ES:[DI+27*2], 04153h	;"SA"=5341h
		jnz	short Not_SAMSUNG_WU32543A
		cmp	Word ptr ES:[DI+28*2], 0534Dh	;"MS"=4D53h
		jnz	short Not_SAMSUNG_WU32543A
		cmp	Word ptr ES:[DI+29*2], 04E55h	;"UN"=554Eh
		jnz	short Not_SAMSUNG_WU32543A
		cmp	Word ptr ES:[DI+30*2], 02047h	;"G "=4720h
		jnz	short Not_SAMSUNG_WU32543A
		cmp	Word ptr ES:[DI+31*2], 05557h	;"WU"=5755h
		jnz	short Not_SAMSUNG_WU32543A
		cmp	Word ptr ES:[DI+32*2], 03233h	;"32"=3332h
		jnz	short Not_SAMSUNG_WU32543A
		cmp	Word ptr ES:[DI+33*2], 03435h	;"54"=3534h
		jnz	short Not_SAMSUNG_WU32543A
		cmp	Word ptr ES:[DI+34*2], 04133h	;"3A"=3341h
		jnz	short Not_SAMSUNG_WU32543A
		jmp	short Ultra_DMA_Exit
Not_SAMSUNG_WU32543A:
endif;	Disable_Ultra_DMA33_When_SAMSUNG_WU32543A	;R70 - ends

		test	byte ptr ES:[DI+53*2],4		;test word 88 is valid?
		jz	short Ultra_DMA_Exit
		mov	al,ES:[DI+88*2]			;Get Ultra DMA mode value
;R85		test	al,1				;test supported?
		or	al,al				;R85;test supported?
		jz	short Ultra_DMA_Exit		;Not support then skip

	;Calculate maximum UltraDMA mode supported by hard drive into AH
	; Word 88 [0] = 1 UltraDMA mode 0 supported
	;	  [1] = 1 UltraDMA mode 1 supported
	;	  [2] = 1 UltraDMA mode 2 supported
	;	  ....etc
	; Value of AH = 0 Maximum UltraDMA is mode 0
	;		1 Maximum UltraDMA is mode 1
	;		2 Maximum UltraDMA is mode 2
	;	     0FFH No UltraDMA mode is support
		xor	cl,cl			;start from bit 0
Ultra_DMA_Loop:
		shr	al,1		   	;bit set ?
		jnc	short @F		;no, check next bit
		mov	ah,cl			;get maximum UltraDMA mode
@@:
		inc	cl			;next bit to check
		cmp	cl,8			;total 8 bits
		jb	short Ultra_DMA_Loop
Ultra_DMA_Exit:
;R78 start
		cmp	ah,0ffh			;HDD not support ultra DMA mode 
		je	short @F		;Yes,skip

ifdef UltraDMA_MaxMode
;R84 start
if UltraDMA_MaxMode GT 2
;R86B;R84A start
;R86Bifdef	Determine_IDE_80_Cable_by_Drive
;R86B;The word 93(bit 13) of Identify drive parameters to
;R86B;indicate 80 condoctor cable whether connected.
;R86B		test	byte ptr ES:[DI+93*2+1],00100000b	;test word 93 bit 13
;R86Belse	;Determine_IDE_80_Cable_by_Drive
;R86B;R84A end
		pop	dx			;Get drive number
		push	dx			;Save Value
		and	dl,3			;isolate useful bits
		call	Ct_IDE_Interface_Status
;R86Bendif	;Determine_IDE_80_Cable_by_Drive	;R84A
endif ;UltraDMA_MaxMode
;R84 end
		mov	al,UltraDMA_MaxMode	;Max. UltraDMA mode support
;R84 start
if UltraDMA_MaxMode GT 2
;R84A start
ifdef	Determine_IDE_80_Cable_by_Drive
;R86B start
;The word 93(bit 13) of Identify drive parameters to
;indicate 80 condoctor cable whether connected.
		test	byte ptr ES:[DI+93*2+1],00100000b	;test word 93 bit 13
;R86B end
		jnz	short New_Interface	;skip if connected new interface
else	;Determine_IDE_80_Cable_by_Drive
;R84A end
		jnc	short New_Interface	;skip if connected new interface
endif	;Determine_IDE_80_Cable_by_Drive	;R84A
;R86 start
;R86B		call	Ct_IDE_Interface_Status		;R86A
		test	byte ptr IDE_PARM_Flag[bp],IDE_UDMA66_Warn_Msg	;R86B
		jz	short Dont_Set_80_Cable_Flag	;R86A
		cmp	ah,2			;<= ultra DMA 33?
		jbe	short Dont_Set_80_Cable_Flag
		pop	dx			;get ultra dma flag and drive no.
		push	dx			;balence stack
		mov	dh,IDE_CH1_80_Cable	;channel 1 flag
		test	dl,2			;test channel
		jz	short Is_Sec_Ch		;jump if secondary channel
		mov	dh,IDE_CH2_80_Cable	;channel 2 flag
Is_Sec_Ch:
		or	IDE_PARM_Flag[bp],dh	;set flag
Dont_Set_80_Cable_Flag:
;R86 end
		mov	al,2			;otherwise set to ultra-33
New_Interface:
endif ;UltraDMA_MaxMode
;R84 end
else ;UltraDMA_MaxMode				;by chipset
		mov	al,2			;default mode 2
endif ;UltraDMA_MaxMode
		cmp	ah,al			;HDD ultra DMA mode over chipset supported
		jbe	short @F		;No,skip
		mov	ah,al			;Yes,limitation by chipset
@@:
;R78 end
		mov	byte ptr [bp+si],ah	;save current UltraDMA mode
						;in buffer
endif	;Ultra_DMA33_support
;R30 end
		mov	dx,ES:[DI+49*2]

		shl	edx,16
		clc
		jmp	short exit_ok
exit_with_error:
;R89		stc
		pop	dx				;R07A
;R89 start
		mov	cl,dl				;get drive number (80h,81h...)
		and	cl,3				;isolate useable bits
		shl	cl,2				;set shift count
		mov	bx,0fff0h			;R51B
		rol	bx,cl				;R51B shift to corespond with IDE_device_item[bp] byte
		and	IDE_device_item[bp],bx		;R51B mask bits
;R89 end
		pop	CDROM_Exist_Flag[bp]		;R07A
		stc					;R89
		jmp	short @F			;R07A
exit_ok:
		pop	dx
		pop	cx				;R07A
@@:							;R07A
		pop	cx
		pop	bx
		pop	si
		pop	di
		pop	es
		pop	ds
		ret
AUTO_IDE_DETECT	ENDP

;R86 start
;[]==================================================================[]
; Procedure Name: Show_80_Cable_Msg
;
;[]==================================================================[]
Primary_CH_Msg:	db	NewLine
		db	'Primary'
IDE_80_Pin_Msg:	db	' IDE channel no 80 conductor cable installed',0
		db	0

Second_CH_Msg:	db	NewLine
		db	'Secondary'
		STRSHOW	<,,,offset IDE_80_Pin_Msg>
		db	0

Show_80_Cable_Msg:
		push	ds

		push	cs
		pop	ds			;set DS = segment of string
		test	byte ptr IDE_PARM_Flag[bp],IDE_CH1_80_Cable
		jz	short @F
		lea	si,Primary_CH_Msg
		call	F000_DISPLAY_STRING
@@:
		test	byte ptr IDE_PARM_Flag[bp],IDE_CH2_80_Cable
		jz	short @F
		lea	si,Second_CH_Msg
		call	F000_DISPLAY_STRING
@@:
		pop	ds
		ret
;R86 end

;R47 -start
Set_IDE_SPecific:
		pusha
		and	cl,03h				;cl is drive number
		movzx	si,cl				;si is offset
		mov	ah,01
		shl	ah,cl				;get IDE Position
		or	IDE_exist_Flag[bp],ah		;set IDE Exist flag		
		mov	ax,WORD PTR ES:[DI+0]		;word 0 = General configuration
		test	ah,80h				;test ATAPI bit
		jz	short @F			;No,skip
		or	byte ptr IDE_0_Specific_FLAG[bp+si],ATAPIDev
		test	al,80h				;test REmovable media
@@:
		jz	short @F		
		or	byte ptr IDE_0_Specific_FLAG[bp+si],RemoveablMedia
@@:
		test	al,40h				;test DRQ
		jnz	short @F			
		test	al,20h				;test DRQ
		jz	short @F
		or	byte ptr IDE_0_Specific_FLAG[bp+si],ATAPI_DRQ
@@:		
		mov	ax,WORD PTR ES:[DI+49*2]	;word 49 = Capability
		test	ah,02				;test LBA Support
		jz	short @F			;No,skip
		or	byte ptr IDE_0_Specific_FLAG[bp+si],LBAenabl
@@:		
		test	ah,01				;test DMA Support
		jz	short NO_Support_DMA		;No,skip
		or	byte ptr IDE_0_Specific_FLAG[bp+si],DMAenabl
		mov	ax,ES:[DI+63*2]			;word 63 = DMA Mode

		mov	ah,02				;mode 2
		test	al,04h
		jnz	short @F
		dec	ah				;mode 1
		test	al,02h
		jz	short NO_Support_DMA		;mode 0
@@:
		mov	IDE_0_DMA_Mode[bp+si],ah	;save DMA mode
NO_Support_DMA:
		popa
		ret
;R47 -  end

;R56 ;R43 start
;R56 ;[]======================================================================[]
;R56 ;	Check CD_ROM Model 
;R56 ;		     CDU511 (SONY X16) 
;R56 ;  yes => Special_CDROM_Bit = 1
;R56 ;[]======================================================================[]
;R56 Special_CDROM_Drive	db	'CD-ROM CDU511                           ' 
;R56 Special_CDROM_Drive1	db	'CD-ROM CDU571                           '  ;Ryyy
;R56 Special_CDROM_Len	equ	40
;R56 
;R56 CDROM_Special_Check:	
;R56 		pusha	
;R56 		push	ds
;R56 		push	es
;R56 ;R43A		mov	di,27*2
;R56 	   	push	cs
;R56 		pop	ds
;R56 ;R43A	Found_Loop:
;R56 ;R43A			lea	si,Special_CDROM_Drive
;R56 ;R43A			mov	cx,Special_CDROM_Len
;R56 ;R43A			rep	cmpsb
;R56 ;R43A			jz	short Found_It
;R56 ;R43A			cmp	di,27*2+Special_CDROM_Len
;R56 ;R43A			jbe	short Found_Loop
;R56 ;R43A - start
;R56 		mov	di,27*2
;R56 		lea	si,Special_CDROM_Drive
;R56 		call	Compare_Serial_Number 	;compare SONY 'CDU511'
;R56 		je	short Found_It
;R56 
;R56 		mov	di,27*2
;R56 		lea	si,Special_CDROM_Drive1
;R56 		call	Compare_Serial_Number	;compare SONY 'CDU571'
;R56 		je	short Found_It
;R56 ;R43A - end
;R56 		jmp	short Not_CDU511
;R56 Found_It:
;R56 		mov	ax,G_RAm
;R56 		mov	ds,ax
;R56 		assume	ds:G_RAM
;R56 
;R56 		mov	al,Special_CDROM_Bit			;Set bit=1
;R56 		or	G_RAM:[CDROM_ALLOCATE],al
;R56 Not_CDU511:
;R56 		pop	es
;R56 		pop	ds
;R56 		popa	
;R56 		ret
;R56 ;R43A - start
;R56 Compare_Serial_Number:
;R56 		mov	cx,Special_CDROM_Len
;R56 		cld		
;R56 		repe	cmpsb
;R56 		ret
;R56 ;R43A - end
;R56 		
;R56 ;R43 end
;[]==================================================================[]
;input	:	DX = HDD type item offset
;		SI = HDD type loc.
;		DI = HDD params loc.
;output	:	AX = 11bh is to be press ESC key
;		     else another key or not press
;[]==================================================================[]
		Public	Auto_IDE_Detect_X
Auto_IDE_Detect_X	Proc	Near

; auto-detect C IDE drive parameters, then save it as TYPE 49

		push	es				; save regs
		pusha

		push	di
		push	si

;-----------------------------------------------------------

		mov	di,dx
		mov	dh,0F0h				;DH to update CMOS12
		mov	dl,80h				;detect drive C
		mov	word ptr IDE_MFGR[bp],0		;assume no IDE detected
		cmp	di,offset HDDC_ITEM
		je	short @F

		mov	word ptr IDE_MFGR[bp+2],0	;assume no IDE detected
		shr	dh,4
		inc	dl				;detect drive D

ifdef	Support_4_IDE
		cmp	di,offset HDDD_ITEM
		je	short @F
		inc	dl				;detect drive E
		xor	dh,dh				;DH to update CMOS12
		cmp	di,offset HDDE_ITEM
		je	short @F
		inc	dl				;detect drive F
endif	;Support_4_IDE

	@@:
;-----------------------------------------------------------------

		push	ss
		pop	es
		mov	di,bp
		add	di,IDE_PARM 			;make es:di point to 16 bytes buffer

		push	dx
		call	Auto_IDE_Detect			;perform IDE auto-detection
		pop	dx

		jnc	short IDE_Drive_Exist
Skip_Detect:
;-----------------------------------------------------------------
;-----------------------------------------------------------------
ifdef Show_IDE_Changed_Message				;R71
		call	Set_ATAPI_Drive			;R71
endif ;Show_IDE_Changed_Message				;R71

		pop	si				;HDD type loc -> SI
		pop	di				;PARAMS loc. -> DI

		not	dh
		and	byte ptr FIXED_TYPE[bp],dh

		xor	dx,dx
		mov	byte ptr [bp+si],dl		;TYPE
		mov	word ptr [bp+di+0],dx		;CYLINDER
		mov	word ptr [bp+di+2],dx		;HEADS
		mov	word ptr [bp+di+3],dx		;PRECOMP
		mov	byte ptr [bp+di+5],dl		;LANDING
		mov	byte ptr [bp+di+7],dl		;SECTORS

		shl	eax,16
		stc
		jmp	short adc_exit

;-----------------------------------------------------------------
IDE_Drive_Exist:

		or	byte ptr FIXED_TYPE[bp],dh

		pop	si				;HDD type loc. -> SI
		mov	byte ptr [bp+si],48		
							; type to 46, SETUP
							; will update it to a
							; apropriate value

		mov	ax,word ptr es:[di].MANUFACTURER
		or	ax,ax				;check IDE MANUFACTURER code 0 returned
		jnz	short adc_1	      		;skip if not
		dec	ax				;else use 0FFFFh for IDE MANUFACTURER code of 0
adc_1:
		pop	si				;PARAMS loc. -> SI
		mov	word ptr IDE_MFGR[bp],ax

		mov	ax,word ptr es:[di].CYLS	;set cylinder
		mov	word ptr [bp+si+0],ax
		dec	ax				;set landing zone as cyls-1
		mov	word ptr [bp+si+5],ax
		mov	word ptr [bp+si+3],-1		;set no precomp
		mov	al,byte ptr es:[di].HEADS 	;set head
		mov	byte ptr [bp+si+2],al
		mov	al,byte ptr es:[di].SECTORS	;set sector
		mov	byte ptr [bp+si+7],al
		clc					

adc_exit:
		popa					; restore regs
		pop	es
		pushf
		shr	edx,16
		shr	eax,16
		popf
		ret

Auto_IDE_Detect_X	ENDP

;R71 - start
ifdef Show_IDE_Changed_Message
Set_ATAPI_Drive	Proc	Near
		pusha
		push	ds
		and	dx,0fh			;get drive number 
		mov	cx,dx
		mov	al,CDROM_Exist_Flag[bp]	;ATAPI drive flag
		shr	al,cl			;get right bit
		test	al,01			;ATAPI device ?
		jz	short	Is_ATA_Device	;no

		mov	di,HDD_TEMP_RAM_SEG
		mov	ds,di			;data get by Identify command
	;Build checksum for Word 27 to 67
		mov	di,27*2
		xor	ax,ax
		mov	cx,40			;total 40 words 
	@@:
		add	ax,word ptr [di]	;add word data
		inc	di			;next word
		loop	short @B

		mov	byte ptr [bp+si+2],al  	;set checksum low byte to CMOS(head)
		mov	al,ah
		mov	byte ptr [bp+si+7],al  	;set checksum high byte to CMOS(sector)

		clc
		pop	ds
		popa
		ret
Is_ATA_Device:
		stc
		pop	ds
		popa
		ret
Set_ATAPI_Drive	ENDP
endif; Show_IDE_Changed_Message	
;R71 - end

IFDEF	IDE_DETECT_RESET
WAIT_HD_NOT_BUSY PROC	NEAR

		mov	dx,DISK_STAT_PORT	; SEE IF COMBO CARD IS 'BUSY'
		mov	ax,8000h				; wait for top bit to equal zero.
		mov	bh,DGROUP:[Wait_HDU_Ctlr_Busy_Hi]
		mov	cx,DGROUP:[Wait_HDU_Ctlr_Busy_Lo]
		call	F000_Wait_For_Port
		ret

WAIT_HD_NOT_BUSY ENDP
RESET_HD_CONTROLLER PROC NEAR

		pusha

		mov	dx,DISK_STAT_PORTB
		mov	al,04				; assert reset
		newiodelay
		out	dx,al

		xor	bx,bx

ifdef	NO_WAIT_REFRESH_DELAY
		mov	cx,8000h
Io_Wait:
		NEWIODELAY
		loop	short Io_Wait
else;	NO_WAIT_REFRESH_DELAY

		mov	cx,3000				; 90 msec
;R57		F000_call 	Wait_Refresh
		call	F000_Wait_Refresh		;R57
endif;	NO_WAIT_REFRESH_DELAY

		mov	al,0 				; deassert reset
		out	dx,al
		newiodelay

		xor	bx,bx
		mov	cx,256				; wait for 6.7 milliseconds
;R57		F000_call 	Wait_Refresh
		call	F000_Wait_Refresh		;R57

		popa					; restore regs
		ret

RESET_HD_CONTROLLER ENDP

		PUBLIC	RESET_RECAL_HD
RESET_RECAL_HD	PROC	FAR

		pusha
		push	es

		mov	dx,1f2h			; trigger any PM trap
		in	al,dx			;  that may be set
		call	Reset_Hd_Controller

		xor	bx,bx
		mov	cx,3000			; 90 msec.
;R57		F000_call 	Wait_Refresh
		call	F000_Wait_Refresh		;R57
		mov	dx,1f7h
		mov	al,10h			; recal command
		out	dx,al			; issue command
		xor	bx,bx
		mov	cx,3000			; 90 msec.
;R57		F000_call 	Wait_Refresh
		call	F000_Wait_Refresh		;R57

		pop	es
		popa
		ret
RESET_RECAL_HD	ENDP
ENDIF	;IDE_DETECT_RESET

;[]==========================================================[]
;Name	:	Wait_For_Port1
;
;Function :	Wait for a pattern from port DX within a given
;		time period
;
;Input	:	AH = Mask for isolation bits.
;		AL = pattern to look for.
;		DX = Port to test for
;		BH = wait time (unit = 1/18.2 second, 0 is 256 units = 14 seconds)
;
;Output	:	AH =  0   if got pattern.
;	    	      80h if timeout.
;		AL = Last read of port.
;		DX preserved
;		BX preserved.
;
;Note	:	1. if ESC is pressed, the wait loop will
;		   immediately ends!
;
;		2. Maximum BH is 0(=256)
;[]==========================================================[]
Auto_Detect_Time	EQU	252
Wait_For_Port1	Proc	Near
		push	ds
		push	bx
		push	cx			;R07
		sti

		mov	cx,G_RAM
		mov	ds,cx

		xchg	bx,ax		;bx = pattern, ah = no. of 2 sec

ifdef	IDE_TIME_OUT_SETUP
		push	si
;Get time out value for IDE auto-detection and put it into temporary location
		mov	si,offset IdeTime_Out_Item
		call	F000_GetItem_Value
		inc	al					
		shl	al,1					
		mov	cl,20					
		mul	cl					
		pop	si					
		mov	MOTOR_OFF_WAIT,al			
else;	IDE_TIME_OUT_SETUP					
		mov	MOTOR_OFF_WAIT,Auto_Detect_Time
		or	ah,ah
		jz	short @F
		mov	MOTOR_OFF_WAIT,ah
@@:
endif;	IDE_TIME_OUT_SETUP
		push	word ptr [MOTOR_OFF_WAIT]

		xor	ah,ah
	Next_:
		in	al,dx
		newiodelay
		cmp	al,0ffh
		je	short @F
		push	ax
		and	al,bh
		cmp	al,bl
		pop	ax
		clc
		je	short Got_Pattern

		call	chk_esc_key
		jc	short Got_Pattern
		align	4					
		newiodelay					
		cmp	MOTOR_OFF_WAIT,0
		jne	short Next_
@@:
		stc						;Time_Over
Got_Pattern:
		pop	bx
		pushf
		cmp	byte ptr IDE_Detect_Counter[bp],1
		jbe	short @F
		sub	bl,motor_off_wait
		sub	byte ptr IDE_Detect_Counter[bp],bl
		inc	byte ptr IDE_Detect_Counter[bp]
		jnc	short @F
		mov	byte ptr IDE_Detect_Counter[bp],1
@@:
		popf
		pop	cx			;R07
		pop	bx
		pop	ds
		ret

Wait_For_Port1	Endp

;[]==========================================================[]
;Name	  :	Chk_ESC_Key
;Function :	if ESC pressed, set time out
;				i.e. G_RAM:[MOTOR_OFF_WAIT]=0
;Input	  :	DS = G_RAM
;Output	  :	None
;[]==========================================================[]
Chk_ESC_Key:
		mov	ah,01h
		int	16h
		jz	short @F

		mov	ah,10h			; get the key
		int	16h
		cmp	ax,IDE_Detect_Skip_Key[bp]
		jne	short @F
		stc
		ret
@@:
		clc
		ret

ifdef	AUTO_CFG_IO
;[]==================================================================[]
;Name	  :	AUTO_CFG_IDE_PORT
;Function :	Detect any IDE port for add onboard IDE port on dummy space
;
;Input	  :	None
;Output	  :	None
;[]==================================================================[]
ifndef	IDE_ALWAYS_DISABLE
Primary_IDE_data_port	equ	1f2h
Secondary_IDE_data_port	equ	172h
endif;	IDE_ALWAYS_DISABLE

		public	AUTO_CFG_IDE_PORT
AUTO_CFG_IDE_PORT	proc	near

		pusha
ifndef	IDE_ALWAYS_DISABLE
;; Disable onboard IDE port
		mov	si,offset AUTO_IO_Item
		call	F000_GetItem_Value
		test	al,al
		jz	AUTO_CFG_IDE_PORT_EXIT		; JMP If not AUTO
		xor	al,al
		F000_call IO_CHIP_FUNC_DISABLE

		xor	bl,bl
		mov	dx,Primary_IDE_data_port
		mov	ax,5A5Ah
		out	dx,al
		IODELAY
		IODELAY
		in	al,dx
		IODELAY
		cmp	al,ah
		jne	short detect_sec_port
		or	bl,1
detect_sec_port:
		mov	dx,Primary_IDE_data_port
		mov	ax,5A5Ah
		out	dx,al
		IODELAY
		IODELAY
		in	al,dx
		IODELAY
		cmp	al,ah
		pop	dx
		jne	short @f
		or	bl,2
@@:
		F000_call AUTO_CFG_IO_IDE
AUTO_CFG_IDE_PORT_EXIT:

else;	IDE_ALWAYS_DISABLE
;; Disable OnBorad IDE port
		xor	al,al
		F000_call IO_CHIP_FUNC_DISABLE
endif;	IDE_ALWAYS_DISABLE

		popa
		ret
AUTO_CFG_IDE_PORT	endp
endif;	AUTO_CFG_IO

ifdef	NEW_IDE_MODE_3					
;[]==================================================================[]
;Set PIO mode for mode 3 and above
;Note : this routine should be called , otherwise WD2540 mode 3 can not boot
;Input :	;byte ptr HDD_0_MODE[bp] = drive C mode 0-mode 0, 1-mode1 ,etc
;		;byte ptr HDD_1_MODE[bp] = drive D mode
;		;byte ptr HDD_2_MODE[bp] = drive E mode
;		;byte ptr HDD_3_MODE[bp] = drive F mode
;Output : none
;[]==================================================================[]
Set_PIO_Mode	proc	near

                pusha

		xor	si,si			;start from drive 0
Next_Pio_Mode:
;R18 start
;R18A		mov	cx,si
;R18A		mov	al,1
;R18A		shl	al,cl
;R18A		test	byte ptr CDROM_Exist_Flag[bp],al
;R30		jnz	short Not_Mode3_Above
;R18A		jnz	Not_Mode3_Above			;R30
;R18 end
              
;R18A	        cmp     byte ptr HDD_0_MODE[bp+si],3
;R18A		jb	short Not_Mode3_Above

		xor	cx,cx			;R64 ;time-out loop
		mov	dx,1f7h
                cmp     si, 1			;drive 0 & 1 ?
                jbe     short @F
                mov     dl,77h			;for drive 2 & 3

;R64		xor	cx,cx			;time-out loop
		align	4	;R24
@@:        
		in      al, dx
                newiodelay
		test    al, 80h
		jz	short Ready
		loop	short @B		;time out ?
;R64		jmp     short Not_Mode3_Above
Ready:

		dec	dx				;dx = 1f6h or 176h
							;select drive
                mov     al,0a0h				;for drive 0 & 2
                test    si, 1
                jz      short @F
                mov     al, 0b0h			;for drive 1 & 3
		align	4	;R24
@@:
                out     dx,al

;R24 start
                newiodelay
		inc	dl
;R64		xor	cx,cx			;time-out loop
;R64		align	4
;R64@@:        
;R64		in      al, dx
;R64		newiodelay
;R64		test    al, 80h
;R64		jz	short @F
;R64		loop	short @B		;time out ?
;R64		jmp     short Not_Mode3_Above
;R64@@:
;R64            sub     dx,6
;R64	 - start
		xor	bh,bh
		mov	cx,33333/2		; 0.5 second time out
		mov	ax,8000h		; check for bit 7 = 0
		call	F000_Wait_For_Port	; wait for not busy
	       	or	ah,ah			;set zero flag => time?
;R82		jnz     short Not_Mode3_Above
		jnz     Not_Mode3_Above		;R82
                sub     dl,6
;R64	 - end
;R24 end
;R24                sub     dx, 5
                mov     al,03h			;Set transfer mode
                out     dx,al
                newiodelay	;R24

                inc     dx
;R18A start
		mov	cx,si
		mov	al,1
		shl	al,cl
ifdef	Have_CDROM_PIOMode_Item				;R72 - starts
		pushad
		mov	si, offset CDROM_PIOMode_Item
		call	F000_Getitem_Value
		or	al,al
		popad
		jz	short Set_CDROM_PIOMode_
endif;	Have_CDROM_PIOMode_Item				;R72 - ends
		test	byte ptr CDROM_Exist_Flag[bp],al
		jnz	short Not_PIO_Mode3_Above
	Set_CDROM_PIOMode_:				;R72
	        cmp     byte ptr HDD_0_MODE[bp+si],3
		jb	short Not_PIO_Mode3_Above
;R18A end
                mov     al, 08h			;PIO mode
                add     al, HDD_0_MODE[bp+si]   ;set mode
                out     dx, al			;set PIO mode, mode 0 = 1000B
                newiodelay	;R24		;		    1 = 1001B
						;		    2 = 1010B
						;		    3 = 1011B	
						;		    4 = 1100B	
;R64            add     dx,5
                add     dl,5		;R64
                mov     al,0efh		 	;set feature command
                out     dx,al
;R24 start
                newiodelay
	;Wait for drive receiving command
		xor	cx,cx
@@:
		newiodelay
		newiodelay
		loop	@B
		sub	dl,5			;R18A
Not_PIO_Mode3_Above:				;R18A
;R24 end
		xor	bl,bl			;R82 assume none DMA mode
;R30 start
ifdef	Ultra_DMA33_support
                mov	al,HDD_0_UltraDMA[bp+si]	;set ultra DMA
		cmp	al,0ffh				;not support?
;R82		je	short Not_Mode3_Above		;Yes,jump next drive
		je	short No_IDE_UDMA_MODE		;R82 Yes,jump next drive
;R18A		sub	dl,5
                or	al,40h				;Ultra DMA mode 0=40H
                out     dx,al				;	   mode	1=41H
                newiodelay				;	   mode	2=42H

                add     dl,5
                mov     al,0efh				;set feature command
                out     dx,al
                newiodelay

	;Wait for drive receiving command
		xor	cx,cx
@@:
		newiodelay
		newiodelay
		loop	@B
		or	bl,1				;R82 set DMA mode flag
No_IDE_UDMA_MODE:					;R82
;R82;R75 - start
;R82ifdef	Set_DMA_Capable_Status
;R82		call	Set_DMA_Capable
;R82endif;	Set_DMA_Capable_Status
;R82;R75 - end
endif	;Ultra_DMA33_support
;R30 end
;R82 start
ifdef	IDE_DMA_Transfer
                mov	al,IDE_0_DMA_MODE[bp+si]	;set ultra DMA
		cmp	al,0ffh				;No DMA support
		je	short No_IDE_DMA_MODE
                or	al,20h				;enable multi-word DMA
                out     dx,al				;send to sector counter
                newiodelay

                add     dl,5				;dx=1X7h
                mov     al,0efh				;set feature command
                out     dx,al				;send out
                newiodelay
		xor	cx,cx
@@:
		newiodelay
		newiodelay
		loop	@B
;; support word DMA ---		or	bl,1				;set DMA mode flag
No_IDE_DMA_MODE:
		or	bl,bl				;have any DMA support?
		jz	short No_DMA_Support		;No,skip
		push	si

		mov	cx,si				;save drive no. to CL
		call	Ct_Get_OnboardIDE_Status
		jz	short Set_DMA_flag_end		;Yes,skip
		mov	si,offset IDE_DMA_Item
		call	F000_GetItem_Value
		or	al,al				;Disable?
		jz	short Set_DMA_flag_end		;Yes,skip
		mov	si,offset DGROUP:IDE_DMA_Flag	;get offset
		mov	al,fs:[si]			;get original flag value
		mov	ch,1				;set drive 0 flag
		shl	ch,cl				;shift to correspond bit
		or	al,ch				;set to correct value
		call	Write_F000_shadow_byte		;write to F000 shadow

		call	Ct_Get_BMIBA			;get Bus Master Interface Base Address
		mov	si,offset DGROUP:IDE_DMA_BMIBA	;get offset
		call	Write_F000_shadow_word		;write to F000 shadow
Set_DMA_flag_end:
		pop	si
endif	;IDE_DMA_Transfer
ifdef	Set_DMA_Capable_Status
		call	Set_DMA_Capable
endif;	Set_DMA_Capable_Status
No_DMA_Support:
;R82 end
Not_Mode3_Above:
		inc	si			;next drive
;R74A - start
ifdef	No_Support_4_IDE
		cmp	si,2
else	;No_Support_4_IDE
		cmp	si,4
endif	;No_Support_4_IDE
;R74A - end
;R74A		cmp	si,4
;R30		jb	short Next_Pio_Mode
		jb	Next_Pio_Mode			;R30

                popa

		ret

Set_PIO_Mode	endp
endif;	NEW_IDE_MODE_3					

;[]==================================================================[]
;
; Procedure Name: AUTO_CDROM_DETECT
;
;
; Input:
;	DS = G_RAM
;
; Output:
;
;	IF ERROR	: CARRY SET
;		G_RAM:[CDROM_ALLOCATE] = 0 - None CDROM
;
;	IF SUCCESS	: CARRY CLEAR
;		G_RAM:[CDROM_ALLOCATE]
;				bit 0-1 = 0 - CDROM at Primary Master
;					  1 - CDROM at Primary Slave
;					  2 - CDROM at Secondany Master
;					  3 - CDROM at Secondany Slave
;				bit 2-3 = 0 - None CDROM
;					  1 - Emulate A drive
;					  2 - Emulate C drive
;
; [Note]:
;
;[]==================================================================[]

		PUBLIC	AUTO_CDROM_DETECT
AUTO_CDROM_DETECT	PROC	NEAR
		push	es
		mov	dx,G_RAM
		mov	ds,dx
		assume	ds:G_RAM

		mov	byte ptr G_RAM:[CDROM_EMUL_HEAD],0	;Assume Drive 0
;R02		mov	byte ptr CDROM_Exist_Flag[bp],0
;R07		or	byte ptr CDROM_Exist_Flag[bp],0fh	;R06
		mov	word ptr IDE_Detect_Skip_Key[bp],0	;R07
CDROM_detect_loop:
;R07 start
		mov	cl,G_RAM:[CDROM_EMUL_HEAD]
		mov	al,1
		shl	al,cl
;R07B		test	byte ptr CDROM_Exist_Flag[bp],al
		test	byte ptr Post_Temp_Byte[bp],al		;R07B
		jnz	short Next_Drive
		mov	ch,cl
		xor	cl,cl
@@:
		cmp	cl,G_RAM:[NumHDSKS]
		jae	short @F
		mov	ah,G_RAM:[HDD_Drive_Port]
		shr	ah,cl
		shr	ah,cl
		and	ah,3
		cmp	ah,ch				;Exist HDD drive?
		je	short Next_Drive		;Yes,Skip CDROM detect
		inc	cl
		jmp	short @B
@@:
		or	byte ptr CDROM_Exist_Flag[bp],al
;R07 end
		jmp	short ADC_OK				;R06
;R06		mov	dx,1f7h			;select Primary channel
;R06ifdef	Support_4_IDE
;R06		cmp	byte ptr G_RAM:[CDROM_EMUL_HEAD],2
;R06		jb	short Is_Primary
;R06		sub	dl,80h
;R06Is_Primary:
;R06endif	;Support_4_IDE
;R06		xor	cx,cx
;R06@@:
;R06		in	al,dx
;R06		newiodelay
;R06		test	al,80h
;R06		jz	short @F
;R06		loop	@B
;R06@@:
;R06		dec	dl
;R06		mov	al,DRIVE_0		; 0a0h for drive 0, 0b0h for drive 1
;R06		test	byte ptr G_RAM:[CDROM_EMUL_HEAD],1
;R06		jz	short @F
;R06		mov	al,DRIVE_1
;R06@@:
;R06		out 	dx,al			; output to drive controller
;R06		newiodelay
;R06;----- clear return value before reset CDROM -----
;R06	xor	al,al
;R06	dec	dl
;R06	out	dx,al				;Out 1X5h = 0
;R06	dec	dl
;R06	out	dx,al				;Out 1X4h = 0
;R06	add	dl,3				;make DX = 1X7h
;R06;-------------------------------------------------
;R06
;R06		in	al,dx
;R06		newiodelay
;R06		test	al,20h			;write fault?
;R06		jnz	short Next_Drive
;R06		mov	di,3			;Resend Reset Command count
;R06Resend_RST_CMD:
;R06		mov	ax,8000h		; check for bit 7 = 0
;R06		xor	bh,bh
;R06		call	Wait_for_Port1		; wait for not busy
;R06		jc	short Next_Drive
;R06
;R06		mov	al,ATAPI_Soft_Reset	;ATAPI soft reset
;R06		out	dx,al
;R06		newiodelay
;R06
;R06		mov	ax,8000h		; check for bit 7 = 0
;R06		xor	bh,bh
;R06		call	Wait_for_Port1		; wait for not busy
;R06		jc	short Next_Drive
;R06
;R06		in	al,dx
;R06		sub	dl,2			;DX = 1X5h
;R06		test	al,1
;R06		jnz	short Next_Drive
;R06		xor	cx,cx
;R06@@:
;R06		in	al,dx
;R06		newiodelay
;R06		cmp	al,0ebh
;R06		je	short @F
;R06		loop	@B
;R06		dec	di
;R06		jz	short Next_Drive
;R06		add	dx,2
;R06		jmp	short Resend_RST_CMD
;R06@@:
;R06
;R06		dec	dl			;DX = 1X4h
;R06		in	al,dx
;R06		newiodelay
;R06		cmp	al,14h
;R06		je	short ADC_OK
Next_Drive:
ifdef	Support_4_IDE
		cmp	byte ptr G_RAM:[CDROM_EMUL_HEAD],3
else	;Support_4_IDE
		cmp	byte ptr G_RAM:[CDROM_EMUL_HEAD],1
endif	;Support_4_IDE
;R01		jae	short ADC_Ret
		jae	ADC_Ret				;R01
		inc	byte ptr G_RAM:[CDROM_EMUL_HEAD]
		jmp	CDROM_detect_loop
ADC_OK:
;R06		mov	cl,G_RAM:[CDROM_EMUL_HEAD]
;R06		mov	al,1
;R06		shl	al,cl
;R06		or	byte ptr CDROM_Exist_Flag[bp],al
;R06		xor	cx,cx
;R06@@:
;R06		newiodelay
;R06		loop	@B
		mov	dl,G_RAM:[CDROM_EMUL_HEAD]
;R06		mov	G_RAM:[CDROM_ALLOCATE],dl
;R06		mov	byte ptr G_RAM:[CDROM_EMUL_HEAD],0	;Default Emulate Drive C
		and	dl,3
		add	dl,80h
		push	ss
		pop	es
		mov	di,bp
		add	di,IDE_PARM 			;make es:di point to 16 bytes buffer
		mov	word ptr IDE_Detect_Skip_Key[bp],0
		call	Auto_IDE_Detect
;R06		mov	al,G_RAM:[CDROM_ALLOCATE]
;R06		mov	G_RAM:[CDROM_EMUL_HEAD],al
;R06		mov	byte ptr G_RAM:[CDROM_ALLOCATE],0
;R06		jc	short Next_Drive
		jc	short CDROM_Detect_Err	;R06
		mov	ax,HDD_TEMP_RAM_SEG
		mov	es,ax
ifdef	Support_CDROM_IORDY
IORDY_Support	EQU	00001000b
		test	byte ptr es:[49*2+1],IORDY_Support
		jz	short @F
		mov	al,G_RAM:[CDROM_EMUL_HEAD]
		and	al,3
		F000_call	Enable_chipset_IORDY
@@:
endif	;Support_CDROM_IORDY
		mov	ax,es:[0]

Protocol_Type	EQU	1100000000000000b
Device_Type	EQU	0001111100000000b
CMD_PKT_Size	EQU	0000000000000011b
ATAPI_Type	EQU	1000000000000000b
CDROM_Type	EQU	0000010100000000b
CPS_12_Byte	EQU	0000000000000000b

;R28		and	ax,(Protocol_Type+Device_Type+CMD_PKT_Size)
;R28		cmp	ax,(ATAPI_Type+CDROM_Type+CPS_12_Byte)
		and	ax,(Protocol_Type+CMD_PKT_Size)	;R28
		cmp	ax,(ATAPI_Type+CPS_12_Byte)	;R28
;R07		je	short Next_Drive
;R07 start
		jne	short CDROM_Detect_Err
		push	ds
		push	cs
		pop	ds
		lea	si,Found_CDROM_Str
;R28 start
ifdef	LS120_SUPPORT
		mov	ax,es:[0]
		and	ax,Device_Type
		cmp	ax,CDROM_Type
		je	short @F
		lea	si,Found_ATAPI_Str
@@:
endif	;LS120_SUPPORT
;R28 end
ifdef	Quiet_POST_Support					;R61
		call	Ck_Quiet_Post				;R61
		jnc	short _JAAddd				;R61
endif	;Quiet_POST_Support					;R61
		call	F000_DISPLAY_STRING
	_JAAddd:						;R61
		push	es
		pop	ds
		mov	si,27*2
		push	word ptr [si+40]
		push	si
;Skip blank characters to display
		add	si,40
@@:
		mov	byte ptr [si],0		;mark end of string
		dec	si 			;previous character
		cmp	byte ptr [si],' '	;space ?
		je	short @B
		
		pop	si			
		push	si			
ifdef	Quiet_POST_Support					;R61
		call	Ck_Quiet_Post				;R61
		jnc	short _JwAddd				;R61
endif	;Quiet_POST_Support					;R61
		call	F000_DISPLAY_STRING
	_JwAddd:						;R61
		pop	si
		pop	word ptr [si+40]
		pop	ds
		jmp	Next_Drive
;R07 end
CDROM_Detect_Err:					;R06
		mov	cl,G_RAM:[CDROM_EMUL_HEAD]
		mov	al,0feh
;R06		shl	al,cl
		rol	al,cl				;R06
		and	byte ptr CDROM_Exist_Flag[bp],al
;R01		jmp	short Next_Drive
		jmp	Next_Drive				;R01
ADC_Ret:
;R22A		stc
;R22A		mov	G_RAM:[CDROM_EMUL_HEAD],0	;R08
;R22A		test	byte ptr CDROM_Exist_Flag[bp],0fh
;R22A		jz	short No_any_CDROM
;R22A		mov	al,CDROM_Exist_Flag[bp]
;R22A		xor	ah,ah
;R22A@@:
;R22A		shr	al,1
;R22A		jc	short @F
;R22A		inc	ah
;R22A		jmp	short @B
;R22A@@:
;R22A		mov	G_RAM:[CDROM_EMUL_HEAD],ah
;R22A		add	byte ptr G_RAM:[CDROM_EMUL_HEAD],8	;Default Emulate Drive C
ifdef	CD_ROM
;R03		cmp	byte ptr NumHDSKS,0
;R03		jne	short @F
;R03		call	Reset_INT13
;R03@@:
endif	;CD_ROM
		clc
No_any_CDROM:
		pop	es
		ret
AUTO_CDROM_DETECT	ENDP

;R23		public	Reset_INT13
;R23Reset_INT13:
;R23		mov	ax,seg_0
;R23		mov	es,ax
;R23		assume	es:seg_0
;R23		cli
;R23		mov	ax,word ptr seg_0:int13
;R23		cmp	ax,offset dgroup:hrdskio	
;R23		je	short Already_Reset_Int13	
;R23		mov	word ptr seg_0:int40,ax
;R23		mov	ax,word ptr seg_0:int13+2
;R23		mov	word ptr seg_0:int40+2,ax
;R23
;R23;R21		mov	ax,offset dgroup:int_hdisk
;R23;R21		mov	word ptr seg_0:hd_int,ax
;R23;R21		mov	word ptr seg_0:hd_int+2,0f000h
;R23
;R23		mov	ax,offset dgroup:hrdskio
;R23		mov	word ptr seg_0:int13,ax
;R23		mov	word ptr seg_0:int13+2,0f000h
;R23	ifdef	Support_4_IDE
;R23		cmp	byte ptr CMOS_HDDE[bp],0
;R23		je	short @F
;R23		mov	bx,offset HDDE_ITEM
;R23		call	F000_Get_HDD_CMOS_Info
;R23		cmp	word ptr [bp+di+0],0		;CYLINDER
;R23		je	short @F
;R23		mov	ax,offset dgroup:int_hdisk1
;R23		mov	word ptr seg_0:int77,ax		;IRQ15 offset
;R23		mov	word ptr seg_0:int77+2,0f000h	;IRQ15 segment
;R23@@:
;R23	endif	;Support_4_IDE
;R23Already_Reset_Int13:					
;R23		sti
;R23		ret

;[]==================================================================[]
;	Reset HDD controller all channel
;[]==================================================================[]
		public	Reset_HDD_controller
Reset_HDD_controller:
; assert reset signal to hard disk (solve DTC EISA ESDI problem)
		pusha
		mov	dx,DISK_STAT_PORTB
		mov	al,04				; assert reset
		out	dx,al
		newiodelay
ifdef	Support_4_IDE
		sub	dx,80h
		out	dx,al
		newiodelay
endif	;Support_4_IDE

		mov	cx,21h
		align	4
		loop	short $

		xor	al,al			; deassert reset
		out	dx,al
		newiodelay
ifdef	Support_4_IDE
		add	dx,80h
		out	dx,al
		newiodelay
endif	;Support_4_IDE
		popa
		ret

;[]==================================================================[]
;	Fill INT41h and INT46h vector address
;[]==================================================================[]
Fill_Drv_Vector:
		xor	cl,cl
Fill_DrvVector_Loop:
		cmp	byte ptr NumHDSKS,cl
		jbe	short FD_end
		mov	ax,0f000h
		shl	eax,16
		lea	ax,DGROUP:DRV0
		mov	bl,byte ptr HDD_Drive_Port
		shr	bl,cl
		shr	bl,cl
		and	bx,3
		shl	bx,4
		add	ax,bx
		lea	bx,seg_0:Dr0Vector
		or	cl,cl
		jz	short @F
		lea	bx,seg_0:Dr1Vector
@@:
		mov	seg_0:[bx],eax
		inc	cl
		cmp	cl,2
		jb	short Fill_DrvVector_Loop
FD_end:
		ret

;R25 start
Write_IDE_Drive_Max_Num:
		cli						;R26
		F000_call	F000_Shadow_W		;enable F000 shadow writeable
		mov	al,ds:NUMHDSKS
		add	al,80h
		mov	gs:[IDE_Drive_Max_Num],al
		lea	bx,dgroup:Int13_original_address+2	;R25A
		mov	word ptr gs:[bx],0ffffh			;R25A
		F000_call	F000_Shadow_R
		sti						;R26
		ret
;R25 end
;R57 start
F000_Wait_Refresh:
		F000_call	Wait_Refresh
		ret
;R57 end
ECODE		ENDS
;R69;R56 - start
;R69
;R69XGROUP		GROUP	XCODE
;R69XCODE		SEGMENT USE16 PARA PUBLIC 'XCODE'
;R69		ASSUME	CS:XGROUP,ES:XGROUP
;R69
;R69;[]======================================================================[]
;R69;	Check CD_ROM Model 
;R69;		     CDU511 (SONY X16) 
;R69;  yes => Special_CDROM_Bit = 1
;R69;[]======================================================================[]
;R69
;R69;R68 Special_CDROM_Drive	db	'CD-ROM CDU511                           ' 
;R69;R68 Special_CDROM_Drive1	db	'CD-ROM CDU571                           ' 
;R69;R68 Special_CDROM_Drive2	db	'Pioneer CD-ROM ATAPI Model DR-A24X  0102'
;R69;R68 ;R56A - start
;R69;R68 ifdef CDROM_UJDA110							
;R69;R68 Special_CDROM_Drive3	db	'UJDA110                                 '
;R69;R68 endif; CDROM_UJDA110
;R69;R68 ;R56A - end
;R69
;R69;R68 - start
;R69Special_CDROM_Drive_TAB:
;R69			dw	0a005h		;retry loop = a000h ,delay 5 unit
;R69			db	'CD-ROM CDU511                           ' 
;R69
;R69			dw	0a005h		;retry loop = a000h ,delay 5 unit
;R69			db	'CD-ROM CDU571                           ' 
;R69
;R69			dw	02000h		;retry loop = 2000h ,delay 0 unit
;R69			db	'Pioneer CD-ROM ATAPI Model DR-A24X  0102'
;R69ifdef CDROM_UJDA110		
;R69			dw	0101h		;retry loop = 100h ,delay 1 unit
;R69			db	'UJDA110                                 '
;R69endif; CDROM_UJDA110
;R69			dw	03000h		;retry loop = 3000h ,delay 0 unit
;R69			db	'CD-ROM CDU711                           '
;R69
;R69			dw	0h		;End of Table
;R69;R68 - end
;R69
;R69Special_CDROM_Len	equ	40
;R69
;R69CDROM_Special_Check	proc	far
;R69		pusha	
;R69		push	ds
;R69		push	es
;R69	   	push	cs
;R69		pop	ds
;R69 		mov	di,27*2
;R69;R68 - start
;R69		lea	si,Special_CDROM_Drive_TAB
;R69Special_CDROM_Loop:
;R69		mov	ax,[si]			;delay time & retry loop	
;R69		or	ax,ax			;end of Table
;R69		jz	short Not_Special_CDROM
;R69		add 	si,2			;index to serinal number
;R69		push	di			;save identfiy offset
;R69		call	Compare_Serial_Number	;compare serinal number
;R69		pop	di
;R69		je	short Found_It
;R69		jmp	short Special_CDROM_Loop
;R69;R68 - end
;R69;R68 		mov	ax,0a005h		;delay 1 unit,loop=a000h
;R69;R68 		lea	si,Special_CDROM_Drive
;R69;R68 		call	Compare_Serial_Number 	;compare SONY 'CDU511'
;R69;R68 		je	short Found_It
;R69;R68 
;R69;R68 		mov	di,27*2
;R69;R68 		mov	ax,0a005h		;delay 1 unit,loop=a000h
;R69;R68 		lea	si,Special_CDROM_Drive1
;R69;R68 		call	Compare_Serial_Number	;compare SONY 'CDU571'
;R69;R68		je	short Found_It
;R69;R68
;R69;R68		mov	di,27*2
;R69;R68		mov	ax,2000h		;no delay ,loop=2000h
;R69;R68		lea	si,Special_CDROM_Drive2
;R69;R68		call	Compare_Serial_Number	;compare Pioneer 'DR-A24X'
;R69;R68		je	short Found_It
;R69;R68
;R69;R68;R56A - start
;R69;R68ifdef CDROM_UJDA110
;R69;R68		mov	di,27*2
;R69;R68;R56B		mov	ax,0100h		;no delay ,loop=100h
;R69;R68		mov	ax,0101h		;R56B no delay ,loop=100h
;R69;R68		lea	si,Special_CDROM_Drive3
;R69;R68		call	Compare_Serial_Number	;compare 'UJDA110'
;R69;R68		je	short Found_It
;R69;R68endif; CDROM_UJDA110
;R69;R68;R56A - end
;R69;R68		jmp	short Not_Special_CDROM
;R69
;R69Found_It:
;R69
;R69		lea	si,DGROUP:CDROM_Boot_Delay
;R69	Post_func_call	Write_F000_shadow_word		;write to shadow
;R69
;R69Not_Special_CDROM:
;R69		pop	es
;R69		pop	ds
;R69		popa 
;R69		retf
;R69CDROM_Special_Check	endp
;R69
;R69Compare_Serial_Number:
;R69		mov	cx,Special_CDROM_Len
;R69		cld		
;R69		repe	cmpsb
;R69		ret
;R69
;R69XCODE		ENDS
;R69;R56 - end

		END
