;
;	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.
;
;	[]===========================================================[]
;

		PAGE	60,132
		TITLE	PNPPOST  -- Plug and Play POST
;----------------------------------------------------------------------------
;Rev	Date	 Name	Description
;----------------------------------------------------------------------------
;R21	03/22/99 PAL	Add ESS1869 onboard PNP sound chip Disable function
;R20	03/01/99 RCH	Change the year of copyright from 1998 to 1999
;R19	12/16/98 RCH	Added "NO_ISA_BUS" switch support to eliminate DMA
;			setup items
;R18	11/16/98 RAY	call fPROC_Reserve_Irq_For_PciBootDev(Far) instead of
;			calling Reserve_Irq_For_PciBootDev(Near)
;R17A	11/10/98 KEN	Fixed bug that the AMIDIAG report error while running
;			"Plug-n-Play Test".
;R17	11/03/98 PHI	Changed the method to get device node number with
;			fixed number to avoid that the win95/98 report "new
;			device found" according to un-related device node
;			changing.So we need to get total device node number
;			,not only enable device node number.
;
;R16	08/20/98 KEN	1. Add declaration of "NO_ISA_PNP" to unsupport ISA/PNP
;			   cards for the system doesn't contain ISA bus.
;			2. Supplement declaration of "ESCD_SUPPORT".
;----	08/19/98 KEN	No codes' modification for this revision actually,
;			just group routines for future implementation of
;			new declaration of "NO_ISA_PNP" and supplement of
;			declaration of "ESCD_SUPPORT".
;			Old files are backup as PNP0819.ZIP.
;R15	08/07/98 RCH	Added a switch to disable PnP copyright message
;			display
;R14	07/02/98 RCH	Added Midi IRQ assignment control for CMI8330 audio
;			chip.
;R13	05/25/98 KEN	Added PNP_IRQ_MAP record for the reference of the "AUTO"
;			feature of super I/O serial ports.
;R12	05/04/98 KEN	Always assign resources for PnP/IDE, SCSI devices
;			recognized with the compatiable device ID of the
;			logical device, regardless the PNP_OS setting. To
;			Solve that the IDE/ESDI device of ESS1868 is showed
;			error in device management of Win95, if the PNP_OS item
;			of BIOS SETUP is selected as "Yes" and the IRQ12 is
;			occupied by PS/2 mouse.
;R11	03/18/98 DNL	To let "Award_PnP_Msg" become public
;R10	01/13/98 KEN	Verify that the CSN is assigned successfully while
;			doing ISA/PNP isolation to patch that the system is
;			hang-up at "PnP_Early_Init" when plugged with the
;			Intel EtherExpress card got from Hyosung. (The card
;			seems to be damaged.)
;R09	01/06/98 RCH	Added optional feature with IRQ selectable for each
;			PCI slots if define "PCI_IRQ_SELECTABLE"
;R08	12/31/96 RCH	Change the year of copyright from 1997 to 1998
;R07	10/08/97 KVN	Remove CPINSTAL.ASM to XGROUP from EGROUP to reduce
;			compressed size for 2M BIOS code overflow (i.e. system
;			BIOS compressed code cover to decompress code)
;R06	09/10/97 RCH	Win 95 can not handle resource properly if user
;			select "Yes" for "PnP OS" under specific add-in cards
;			comination. Add a switch to force resource assignment
;			to prevent resource conflict problem and the setup
;			item still exist but no function.
;R05	08/08/97 KEN	Later PnP/ISA initialization to shorten the time in
;			POST_11s.
;R04	05/20/97 RAY	Somebody do not want the BIOS to touch game port since
;			it may cause their board to hang when some special add
;			on card is added. So add switch: No_Touch_Game_Port
;R03	04/14/97 RCH	Let UMB_AREA_SETUP also can be used for old PnP setup
;R02	03/06/97 KEN	Fixed coding mistake for PNPPOST(R65),
;			the SPECIAL_IO_MAP contains incorrect default data,
;			and caused the 376h, 3F6h always are occupied. This
;			cause the REALTEK(Avance Logic) sound card can not
;			work with on-chip IDE port for CDROM.
;R01	01/07/96 RCH	Change the year of copyright from 1996 to 1997
;R00	11/15/96 RAY	Initial Revision:
;
;			Move codes to from PNPPOST.ASM
;			This file will be linked to address at E0000-E7FFF
;			to save E8000-EFFFF area.

ifdef	MASM611
.MODEL	SMALL, BASIC
OPTION	PROC: PRIVATE
endif	;MASM611

.386P

.XLIST
;[]========================================================================[]
;
;	Include file definition
;
;[]========================================================================[]

		INCLUDE BIOS.CFG
ifdef	NEW_PNP_SETUP
CLEAR_ESCD_OPTION	EQU	1
endif	;NEW_PNP_SETUP
		INCLUDE BTROMSEG.EQU			;R07
		INCLUDE COMMON.EQU
		INCLUDE COMMON.MAC
		INCLUDE CMOS.EQU
		INCLUDE PNP.EQU
IF	BUS_TYPE EQ EISA_BUS
		INCLUDE EISA.EQU
ENDIF;	BUS_TYPE EQ EISA_BUS

;[]========================================================================[]
;
;	External label definition
;
;[]========================================================================[]

ifdef	PNP_BIOS
;R21 -start
ifdef	PROC_SPECIAL_ISAPNP
		extrn	Ct_Check_Special_IsaPnp:near	;PNPCHIP.ASM
		extrn	Ct_Proc_Special_IsaPnp:near	;PNPCHIP.ASM
endif	;PROC_SPECIAL_ISAPNP
;R21 -end

		extrn	xcall_proc:near 	;R07
		extrn	F000_GetItem_Value:near
ifndef	NO_ISA_PNP					;R16
ifdef	PNP_OS_SELECTABLE
		extrn	OS_Setup_Item:near
endif;	PNP_OS_SELECTABLE
endif	;NO_ISA_PNP					;R16

;R14 - start
ifdef	MIDI_IRQ_CMOS
		extrn	MidiIrq_Item:near
endif;	MIDI_IRQ_CMOS
;R14 - end

		EXTRN	Ct_PNP_Early_Init:near	;PNPCHIP.ASM
		EXTRN	Ct_ReAlloc_Resource:near;PNPCHIP.ASM
		EXTRN	Ct_Record_Resource:near ;PNPCHIP.ASM

		EXTRN	Ct_Get_Resource_Map:near;PNPCHIP.ASM
		EXTRN	Ct_Set_Resource_Map:near;PNPCHIP.ASM

		EXTRN	DEF_IRQ_MAP:word
		EXTRN	DEF_DMA_MAP:byte
		EXTRN	DEF_IO_MAP:byte
		EXTRN	DEF_IO_MAP_L:abs
		EXTRN	Get_CMOS:near		;ATORGS.ASM
		EXTRN	Set_CMOS:near		;ATORGS.ASM
		EXTRN	Get_OptionROM_Map:near	;ATORGS.ASM
		EXTRN	Wait_Refresh:near	;ATORGS.ASM
		EXTRN	R_MOD_CK:near		;ATBASE.ASM
ifdef	ESCD_SUPPORT

		EXTRN	DEFAULT_ESCD:byte	;PNPCHIP.ASM
		EXTRN	DEFAULT_ESCD_L:abs	;PNPCHIP.ASM
		EXTRN	PNP_BIOS_Real:far	;PNPBIOS.ASM
ifdef	ESCD_M2
		extrn	Write_ESCD_Shadow:near
endif	;ESCD_M2
endif	;ESCD_SUPPORT
		EXTRN	PNP_RD:word		;PNPKERNL.ASM
		EXTRN	LAST_CSN:byte		;PNPKERNL.ASM
		EXTRN	NODES_INDEX:word	;PNPBIOS.ASM
		EXTRN	NODES_PROC:word 	;PNPBIOS.ASM

		EXTRN	TOTAL_NODES:byte	;PNPKERNL.ASM
		EXTRN	LARGEST_SIZE:word	;PNPKERNL.ASM
		EXTRN	Ct_Buffer_Request:near	;PNPCHIP.ASM
		EXTRN	Ct_Save_Shadow:near	;PNPCHIP.ASM
		EXTRN	Ct_Restore_Shadow:near	;PNPCHIP.ASM
		EXTRN	Ct_Shadow_Write:near	;PNPCHIP.ASM
		EXTRN	Ct_Set_Shadow:near	;PNPCHIP.ASM
ifdef	PCI_BUS
;R18		extrn	Reserve_Irq_For_PciBootDev:near
		extrn	fPROC_Reserve_Irq_For_PciBootDev:far	;R18
		EXTRN	PCI_IDE_EXIST:abs	;PCIPOST.ASM
		EXTRN	PCI_IRQ_MAP:abs 	;PCIPOST.ASM
		EXTRN	AGet_CfgSpace_Byte:near ;PCI1A.ASM
		EXTRN	AGet_CfgSpace_Word:near ;PCI1A.ASM
		EXTRN	AGet_CfgSpace_Dword:near ;PCI1A.ASM
		EXTRN	ASet_CfgSpace_Dword:near ;PCI1A.ASM
		extrn	CURRENT_BUS_NO:ABS
		extrn	TOTAL_BUS_NO:ABS

		EXTRN	Ct_Pci_Escd:near	;PNPCHIP.ASM
endif	;PCI_BUS
		extrn	Display_String:near	;SETUP.ASM
		extrn	F000_Display_String:Near
		extrn	Display_CS_String:Near
ifdef	IRQ12_CHIPSET_QUALIFY
		EXTRN	Ct_Irq12_Chk:near
endif;	IRQ12_CHIPSET_QUALIFY
ifdef	ESCD_SUPPORT				;R16
ifdef	CLEAR_ESCD_OPTION
		extrn	Reset_Escd_Item:near
		extrn	F000_GetItem_Value:near
		extrn	Write_Item_Value:near
endif	;CLEAR_ESCD_OPTION
endif	;ESCD_SUPPORT				;R16
ifdef	NEW_PNP_SETUP

		extrn	PnP_Control_Item:near	;PNPFEAT.ASM

		extrn	IrqItem_Table:near	;PNPFEAT.ASM
 ifndef	NO_ISA_BUS					;R19
		extrn	DmaItem_Table:near	;PNPFEAT.ASM
 endif;	NO_ISA_BUS					;R19
		extrn	ESCD_IRQ:abs		;PCIPOST.ASM
		extrn	ESCD_DMA:abs		;PCIPOST.ASM
endif	;NEW_PNP_SETUP				;R03
ifdef	UMB_AREA_SETUP
		extrn	UMB_BASE_ITEM:Near
		extrn	UMB_LEN_ITEM:Near
endif	;UMB_AREA_SETUP
;R03endif	;NEW_PNP_SETUP
		extrn	Aux_Addrs:word		;ATORGS.ASM
		extrn	Aux_Prn_Addrs:word	;ATORGS.ASM
		extrn	Test_COMM:near		;CPINSTAL.ASM
		extrn	Test_LPT:near		;CPINSTAL.ASM
		extrn	NO_OF_NODE_TBL:ABS
		extrn	Special_PNP_Audio_Init:near	;AUDIO.ASM

		extrn	Record_IO_Map:Near
		extrn	F000_CT_BUFFER_REQUEST:Near
		extrn	F000_CT_SET_SHADOW:Near
		extrn	GET_TAG_NAME:Near
		extrn	INIT_CFGDATA:Near
		extrn	RECORD_CFGDATA:Near
		extrn	RECORD_DMA_MAP:Near
		extrn	RECORD_IRQ_MAP:Near
		extrn	TAG_CODE:Near
		extrn	TAG_CODE_L:ABS
ifndef	NO_ISA_PNP					;R16
		extrn	ASSIGN_CSN:Near
		extrn	CLEAR_PNPREG:Near
		extrn	DELAY_1MS:Near
		extrn	FIND_LOGICDEV:Near
		extrn	FORCE_SLEEP:Near
		extrn	GET_RESOURCE_BLOCK:Near
		extrn	GET_SERIALID:Near
		extrn	INITIATION_KEY:Near
		extrn	ISOLATION:Near
		extrn	PROG_PNPDEV:Near
		extrn	RELEASE_IO_MAP:Near
		extrn	RELEASE_IRQ_MAP:Near
		extrn	RELEASE_MEM_MAP:Near
		extrn	RESET_DEVICES:Near
		extrn	SET_PNP_REG:Near
		extrn	SET_WAKE_CSN:Near
		extrn	WAIT_FOR_KEY:Near
		extrn	Proc_sIrqFormat:Near
		extrn	Proc_sDmaFormat:Near
		extrn	Proc_sIoPort:Near
		extrn	Proc_sIoPortFixed:Near
		extrn	Proc_lMem24:Near
		extrn	Proc_lMem32:Near
		extrn	Proc_lMemFixed:Near
		extrn	QUERY_MEM_MAP:near
		extrn	QUERY_IO_MAP:near
		extrn	QUERY_IRQ_MAP:near
		extrn	QUERY_DMA_MAP:near
ifdef	ESCD_SUPPORT					;R16
		extrn	CHECK_DISABLE:Near
		extrn	COPY_ESCDFUNC:Near
		extrn	CREATE_PNPECDFF:Near
		extrn	FIND_PNPESCD:Near
		extrn	PROC_PNPESCD:Near
		extrn	VERIFY_CFGDATA:Near
endif	;ESCD_SUPPORT					;R16
endif	;NO_ISA_PNP					;R16
ifdef	ESCD_SUPPORT					;R16
		extrn	CREATE_ESCDBRDMAP:Near
		extrn	CREATE_MBESCD:Near
		extrn	DECODE_BRDESCD:Near
		extrn	DECODE_ESCD:Near
		extrn	ESCDFUNCHEAD:Byte
		extrn	ESCDFUNCHEAD_L:ABS
		extrn	POST_SET_ESCD:Near
		extrn	REMOVE_ESCDBRD:Near
		extrn	RESET_ESCDBRD:Near
		extrn	XLAT_CFGDATA_ESCD:Near
		extrn	XLAT_ESCD_CFGDATA:Near
		extrn	EscdBrdHead:near
		extrn	EscdBrdHead_L:ABS
else	;ESCD_SUPPORT					;R16
		extrn	Decode_MbNode:near		;R16
endif	;ESCD_SUPPORT					;R16

		extrn	F000_call_proc:near
		extrn	F000_VECT:near
		extrn	RET_E_SEG:near
		extrn	F000_Wait_Refresh:near
		extrn	F000_Get_Cmos:near

endif	;PNP_BIOS

;[]========================================================================[]
;
;	Low memory init (1st 64k)
;
;[]========================================================================[]

G_RAM		SEGMENT USE16 AT 0

		ORG	04H*4
		INCLUDE SEG_0.INC

		ORG	400H
		INCLUDE G_RAM.INC

		ORG	2000h
		INCLUDE PNPDATA.INC

IF BUS_TYPE EQ EISA_BUS
		ORG	4000H
TEMP_ESCD	db	4096 dup (?)

ADDRSIZE	STRUC
RecAddr 	dw	?
RecSize 	dw	?
ADDRSIZE	ENDS

		ORG	5000H
ADDR_ARRAY	db	(256 * (SIZE ADDRSIZE)) dup (?)

endif; BUS_TYPE EQ EISA_BUS

		ORG	7C00H
BOOT		LABEL	FAR

G_RAM		ENDS

.LIST

DGROUP		GROUP	FCODE
FCODE		SEGMENT PUBLIC 'CODE'
FCODE		ENDS

EGROUP		GROUP	ECODE
ECODE		SEGMENT USE16 DWORD PUBLIC 'ECODE'
		ASSUME	CS:EGROUP,DS:G_RAM

IFDEF	PNP_BIOS

;************************************************************************
;*									*
;*		GENERAL PNP BIOS MODULE 				*
;*									*
;************************************************************************

;[]========================================================================[]
;Procedure:	PNP_Early_Init
;Function :	1. Reset all PnP Device.
;		2. Issue Initiation Key.
;		3. Serial isolate and assign a CSN for each PnP Card.
;		4. Force all Logical Devices to inactivate.
;		5. All PnP Device enter Sleep mode.
;Input	  :	None
;Output   :	None
;[]========================================================================[]
		public	PNP_Early_Init
		ALIGN	4
PNP_Early_Init	proc	near

		pushf
		pusha
		push	ds
		push	es

ifndef	NO_ISA_PNP					;R16
		F000_call	Ct_PNP_Early_Init	;OEM initialization

		call	Special_PNP_Audio_Init

		mov	ax, G_RAM
		mov	ds, ax
		mov	es, ax
		ASSUME	ds:G_RAM

		cli

; Reset all PnP devices

		call	Wait_For_Key
		call	Delay_1ms

; Issue the initiation key

		call	Initiation_Key

		call	Reset_Devices
		call	Delay_1ms
		call	Initiation_Key

; Get non-conflicted READ_DATA port

		mov	si, offset EGROUP:RDDATA_PORT
@@:

		lods	word ptr cs:[si]
		or	ax, ax
		jz	short @f
		mov	dx, ax
		call	Isolation
		jnc	short Cont_Isolate
		jmp	short @b
@@:

; No PnP device found or READ_DATA port conflicted

		xor	al, al			; for CSN
		jmp	short Set_Last_CSN
Isolate_Fail:					;R10
		dec	al			;R10
		jmp	short Set_Last_CSN	;R10
Cont_Isolate:

; Store READ_DATA port address value

; Isolate each PnP device and assign a CSN for it
;	AL = CSN
;	DX = READ_DATA port address

		xor	al, al			; for CSN
@@:
		inc	al
;R21; - start
ifdef	PROC_SPECIAL_ISAPNP
		pusha
		push	ds
		push	es
		F000_call 	Ct_Check_Special_IsaPnp
		pop	es
		pop	ds
		popa
		jnc	short Not_Special_IsaPnp

		pusha
		push	ds
		push	es
		mov	al, MAX_CSN+1
		call	Assign_CSN
		F000_call 	Ct_Proc_Special_IsaPnp
		pop	es
		pop	ds
		popa

		dec	al
		jmp	short Isolate_Next_IsaPnp
Not_Special_IsaPnp:
endif	;PROC_SPECIAL_ISAPNP
;R21 - end

		call	Assign_CSN
		jc	short Isolate_Fail	;R10

Isolate_Next_IsaPnp:				;R21

		call	Isolation
		jnc	short @b		; isolate next PnP card

; Store LAST_CSN assigned

Set_Last_CSN:
		cmp	al, MAX_CSN
		jbe	short @f
		mov	al, MAX_CSN
@@:
		mov	ds:TEMP_LAST_CSN, al
		mov	ds:TEMP_PNP_RD, dx

; Inactivate all logical devices

		cmp	byte ptr ds:TEMP_LAST_CSN, 0
		je	short PnP_Early_Init_Exit

		mov	dx, ds:TEMP_PNP_RD	;RD_DATA port address
		mov	byte ptr ds:CSN_CNT, 1	;CSN start

Inactive_PnpCard_Loop:
		mov	byte ptr ds:LOGIC_DEV_CNT, 0	;logical device count

Inactive_PnpDev_Loop:
		mov	al, ds:CSN_CNT
		cmp	al, ds:TEMP_LAST_CSN
		ja	short Inactive_PnpCard_Exit

		mov	ah, ds:LOGIC_DEV_CNT
		call	Find_LogicDev
		jc	short Inactive_Next_PnpCard

		mov	al, LOGIC_DEV		;select logical device
		call	Set_PnP_Reg
		call	Clear_PnpReg
		mov	al, ACT_REG		;activate register
		xor	ah, ah			;inactive
		call	Set_PnP_Reg

		inc	byte ptr ds:LOGIC_DEV_CNT
		jmp	short Inactive_PnpDev_Loop

Inactive_Next_PnpCard:
		inc	byte ptr ds:CSN_CNT
		jmp	short Inactive_PnpCard_Loop

Inactive_PnpCard_Exit:

		call	Force_Sleep		;all PnP enter sleep state

PNP_Early_Init_Exit:
		mov	ax, ds:TEMP_PNP_RD	;R05
		mov	dx, 1			;R05
		call	Record_IO_Map		;R05
		mov	ax, PNP_ADDR		;R05
		call	Record_IO_Map		;R05
		mov	ax, PNP_WR		;R05
		call	Record_IO_Map		;R05
endif	;NO_ISA_PNP					;R16

 ifdef	PCI_IRQ_SELECTABLE			;R09
		extrn	fBuild_FixedIrqTbl:far	;R09
		call	fBuild_FixedIrqTbl	;R09
 endif; PCI_IRQ_SELECTABLE			;R09

		pop	es
		pop	ds
		popa
		popf
		ret
PNP_Early_Init	endp

;[]========================================================================[]
;Procedure:	PNP_System_Resource
;Function :	1. Get ESCD.
;		2. Create default SYSTEM_MAP.
;		3. Decode/Record ISA ESCD resources.
;		4. Record I/O port for PNP operation.
;Input	  :	None
;Output   :	None
;[]========================================================================[]
		public	PNP_System_Resource
		ALIGN	4
PNP_System_Resource	proc	near
		pusha
		push	ds
		push	es
		mov	ax, G_RAM
		mov	ds, ax
		mov	es, ax

		mov	byte ptr ds:PNP_FLAG, 0

;R14 - start
 ifdef	MIDI_IRQ_CMOS
		mov	si, offset MidiIrq_Item 	;MIDI setup item
		call	F000_GetItem_Value		;read CMOS setting
		or	al, al
		jz	short NoMidiIrq
		or	byte ptr ds:PNP_FLAG, 80H	;assign IRQ for Midi
	NoMidiIrq:
 endif; MIDI_IRQ_CMOS
;R14 - end

ifndef	NO_ISA_PNP					;R16
 ifndef FORCE_NON_PNP_OS				;R06
	ifdef	PNP_OS_SELECTABLE
		mov	si, offset OS_Setup_Item
		call	F000_GetItem_Value
		or	al, al
		jz	short @f
		or	byte ptr ds:PNP_FLAG, OS_ENABLE
	@@:
	endif	;PNP_OS_SELECTABLE
 endif; FORCE_NON_PNP_OS				;R06
endif	;NO_ISA_PNP					;R16

		mov	al, 0FFh
		mov	cx, IO_MAP_L
		mov	di, offset IO_MAP
		rep	stosb
		mov	SPECIAL_IO_MAP, al		;R02

		mov	eax, 0FFFFFFFFh
		mov	ds:PNPROM_MAP, eax
		mov	ds:PNP_IRQ_MAP, ax	;R13

		push	es
		mov	ax, 0F000h
		mov	es, ax
		mov	ax, es:DEF_IRQ_MAP
		mov	ds:IRQ_MAP, ax
		mov	al, es:DEF_DMA_MAP
		mov	ds:DMA_MAP, al

		mov	cx, DEF_IO_MAP_L
		mov	si, offset DEF_IO_MAP
@@:
		jcxz	short @f
		lods	word ptr es:[si]	;base address
		mov	dx, ax
		xor	ax, ax
		lods	byte ptr es:[si]	;length
		xchg	ax, dx
		call	Record_IO_Map
		loop	short @b
@@:
		pop	es
ifdef	PCI_BUS
		mov	edx, 0FFFFFF00h
		mov	dword ptr ds:UMB_MAP, edx
else	;PCI_BUS
		call	Get_OptionROM_Map
		not	dx
		shr	dx, 2			;just check C8 to DF
		mov	ebx, 0FFFFFF00h
		mov	cx, 6
		mov	eax, 0FFFFF0FFh
Mask_OptionROM:
		shr	dl, 1
		jc	short @f
		and	ebx, eax
@@:
		rol	eax, 4
		loop	short Mask_OptionROM
		mov	dword ptr ds:UMB_MAP, ebx
endif	;PCI_BUS

ifdef	ESCD_SUPPORT
; Parse ESCD information

		push	ds
		push	es
		mov	di, G_RAM
		mov	es, di
		mov	di, 0F000h		;for FLASH_SUPPORT
		mov	ds, di

ifdef	CLEAR_ESCD_OPTION
;R14 - start
 ifdef	MIDI_IRQ_CMOS
	;Clear ESCD if user change CMOS value for IRQ control
	;The programmer must define a backup CMOS for BIOS to identify
	;the CMOS change. The backup CMOS - "MIDI_IRQ_BIT_BACKUP" should
	;be in same CMOS location with MIDI_IRQ_BIT.
		mov	al, MIDI_IRQ_CMOS[bp]	;get CMOS value
		and	al, MIDI_IRQ_BIT + MIDI_IRQ_BIT_BACKUP
		jz	short @F
		cmp	al, MIDI_IRQ_BIT + MIDI_IRQ_BIT_BACKUP
		jne	short ForceEscdClear
 endif; MIDI_IRQ_CMOS
;R14 - end

		mov	si, offset Reset_Escd_Item

		call	F000_GetItem_Value
		or	al, al			;clear ESCD enabled ?
		jz	short @f		;no

	ForceEscdClear: 			;R14
		xor	dx, dx			;yes, write CMOS back
		mov	bx, offset Reset_Escd_Item;for next boot
		F000_CALL	Write_Item_Value
		mov	di, offset ESCD_BUFFER
		mov	si, offset DEFAULT_ESCD
		mov	cx, DEFAULT_ESCD_L
		rep	movsb
		call	Post_Set_Escd
		jmp	short Set_Default_Escd
@@:
endif	;CLEAR_ESCD_OPTION

		mov	di, offset ESCD_BUFFER
		mov	cx, 1000h

ifdef	ORION_ESCD_PATCH
;Copy ESCD buffer from temporary memory(0:4000H) due to system hang
;while reading ESCD for ORION chipset
		push	ds
		push	di
		mov	ax,0400H		;tempory segment
		mov	ds,ax
		xor	si,si
		rep	movsb
		pop	di
		pop	ds

		cmp	dword ptr es:[di+2], 'GFCA'     ;ESCD signature
		je	short @F
		stc					;load default ESCD

else;	ORION_ESCD_PATCH

		call	Post_Get_Escd
endif;	ORION_ESCD_PATCH

		jnc	short @f

Set_Default_Escd:
		or	byte ptr es:PNP_FLAG, BAD_ESCD

		mov	di, offset ESCD_BUFFER
		mov	si, offset DEFAULT_ESCD
		mov	cx, DEFAULT_ESCD_L
		rep	movsb
@@:
		push	es
		pop	ds
		mov	si, offset ESCD_BUFFER
		cmp	dword ptr ds:[si+2], "GFCA"
		jne	short @f
		call	Decode_ESCD
@@:
		pop	es
		pop	ds
endif	;ESCD_SUPPORT

ifdef	NEW_PNP_SETUP

		mov	ax, ds:IRQ_MAP
		mov	word ptr ESCD_IRQ[bp], ax

		mov	al, ds:DMA_MAP
		mov	byte ptr ESCD_DMA[bp], al

		push	ds
		pop	es
		push	ds

		mov	ax, 0F000h
		mov	ds, ax

		mov	si, offset PnP_Control_Item
		call	F000_GetItem_Value

		or	al, al				;auto ?

		jz	No_Manual_Control		;yes

		mov	bx, offset IrqItem_Table
IrqItem_Loop:
		mov	si, ds:[bx]
		cmp	si, -1				;last item ?
		je	short IrqItem_End		;yes, quit

		call	F000_GetItem_Value
		or	al, al				;IRQ for legacy ?
		jz	short @f

		mov	ax, 0FFFEh			;yes
		mov	cl, ds:[bx+2]
		rol	ax, cl

		and	es:IRQ_MAP, ax
@@:
		add	bx, 3
		jmp	short IrqItem_Loop
IrqItem_End:

 ifndef	NO_ISA_BUS					;R19
		mov	bx, offset DmaItem_Table
DmaItem_Loop:
		mov	si, ds:[bx]
		cmp	si, -1
		je	short DmaItem_End
		call	F000_GetItem_Value
		or	al, al
		jz	short @f
		mov	al, 0FEh
		mov	cl, ds:[bx+2]
		rol	al, cl

		and	es:DMA_MAP, al
@@:
		add	bx, 3
		jmp	short DmaItem_Loop
DmaItem_End:
 endif;	NO_ISA_BUS					;R19

ifdef	UMB_AREA_SETUP

		call	GetUmb_Info		;get UMB info. from CMOS setup;R03

;R03	;-----------------------------------------------------
;R03	;trying to exclude UMB area according to CMOS setup
;R03	;-----------------------------------------------------
;R03
;R03	;retrieve Used UMB base address
;R03
;R03		mov	si, offset UMB_BASE_ITEM	;0=N/A
;R03		call	F000_GetItem_Value		;1=C800
;R03							;2=CC00
;R03							;3=D000
;R03							;4=D400
;R03							;5=D800
;R03							;6=DC00
;R03		or	al, al				;any used area ?
;R03		jz	short No_Manual_UMB		;no, skip follows
;R03
;R03		mov	ebx, 0FFFFFEFFh 		;starting from C8
;R03		dec	al
;R03		shl	al, 2
;R03		mov	cl, al
;R03		rol	ebx, cl
;R03
;R03	;retrieve Used UMB length
;R03
;R03		mov	si, offset UMB_LEN_ITEM 	;0=8k length
;R03		call	F000_GetItem_Value		;1=16k length
;R03							;2=32k length
;R03							;3=64k length
;R03		mov	cl, al
;R03		inc	cl
;R03		mov	al, 1
;R03		shl	al, cl
;R03		mov	edx, ebx
;R03		dec	al
;R03	@@:
;R03		or	al, al
;R03		jz	short @F
;R03		rol	edx, 1
;R03		jnc	short @F
;R03		and	ebx, edx
;R03		dec	al
;R03		jmp	short @B
;R03	@@:
;R03		and	dword ptr es:UMB_MAP, ebx
;R03
;R03	No_Manual_UMB:
endif	;UMB_AREA_SETUP

No_Manual_Control:
		pop	ds

;R03 - start
else;	;NEW_PNP_SETUP
 ifdef	UMB_AREA_SETUP
		push	ds		;get resource buffer's segment
		pop	es

		call	GetUmb_Info	;get UMB info. from CMOS setup;R03
 endif; UMB_AREA_SETUP
;R03 - end

endif	;NEW_PNP_SETUP

; Record PNP_RD port

;R05		mov	ax, ds:TEMP_PNP_RD
;R05		mov	dx, 1
;R05
;R05		call	Record_IO_Map
;R05		mov	ax, PNP_ADDR
;R05
;R05		call	Record_IO_Map
;R05		mov	ax, PNP_WR
;R05
;R05		call	Record_IO_Map

ifdef	PCI_BUS

		mov	ax, ds:IRQ_MAP
		mov	word ptr PCI_IRQ_MAP[bp], ax
endif	;PCI_BUS

ifdef	ESCD_SUPPORT					;R16
		mov	si, offset ESCD_BUFFER
		call	Create_EscdBrdMap
endif	;ESCD_SUPPORT					;R16

		pop	es
		pop	ds
		popa
		ret
PNP_System_Resource	endp

;R03 - start
ifdef	UMB_AREA_SETUP
;Input : ES:UMB_MAP = segment of resource buffer
;Output: content of ES:UMB_MAP
GetUmb_Info	proc	near

		push	ds
	;-----------------------------------------------------
	;trying to exclude UMB area according to CMOS setup
	;-----------------------------------------------------

	;retrieve Used UMB base address

		mov	si, offset UMB_BASE_ITEM	;0=N/A
		call	F000_GetItem_Value		;1=C800
							;2=CC00
							;3=D000
							;4=D400
							;5=D800
							;6=DC00
		or	al, al				;any used area ?
		jz	short No_Manual_UMB		;no, skip follows

		mov	ebx, 0FFFFFEFFh 		;starting from C8
		dec	al
		shl	al, 2
		mov	cl, al
		rol	ebx, cl

	;retrieve Used UMB length

		mov	si, offset UMB_LEN_ITEM 	;0=8k length
		call	F000_GetItem_Value		;1=16k length
							;2=32k length
							;3=64k length
		mov	cl, al
		inc	cl
		mov	al, 1
		shl	al, cl
		mov	edx, ebx
		dec	al
	@@:
		or	al, al
		jz	short @F
		rol	edx, 1
		jnc	short @F
		and	ebx, edx
		dec	al
		jmp	short @B
	@@:
		and	dword ptr es:UMB_MAP, ebx

	No_Manual_UMB:
		pop	ds
		ret
GetUmb_Info	endp
endif	;UMB_AREA_SETUP
;R03 - end

;[]========================================================================[]
;Procedure:	PNP_Video_Init
;Function :
;Input	  :	None
;Output   :	CF = 1	no PnP video card found
;		CF = 0	PnP video card found
;[]========================================================================[]
		public	PNP_Video_Init
		ALIGN	4
PNP_Video_Init	proc	near
		stc
		ret
PNP_Video_Init	endp

;[]========================================================================[]
;Procedure:	PNP_SuperIO_Init
;Function :	Assign system resources for AT compatible PNP cards.
;Input	  :	none
;Output   :	none
;[]========================================================================[]

		public	PNP_SuperIO_Init
PNP_SuperIO_Init	proc	near

		pusha
		push	ds
		push	es

		mov	ax, G_RAM
		mov	ds, ax
		mov	es, ax

		call	Check_At_Device

		call	Create_Resource_Map

		call	Proc_Post_Node

ifdef	ESCD_SUPPORT					;R16
		call	Create_MbEscd
		mov	si, offset CurrentEscd
		call	Decode_BrdEscd
else	;ESCD_SUPPORT					;R16
		call	Decode_MbNode			;R16
endif	;ESCD_SUPPORT					;R16

; Clear PnpRomMap

		mov	cx, PnpRomMap_L
		xor	al, al
		mov	di, offset PnpRomMap
		rep	stosb

; Let OEM to update system resource map

		F000_call	Ct_ReAlloc_Resource

ifdef	PCI_BUS
;R18		call	Reserve_Irq_For_PciBootDev
		call	fPROC_Reserve_Irq_For_PciBootDev	;R18
endif;	PCI_BUS

ifndef	NO_ISA_PNP					;R16
; Sort CSN initailizing priority

		call	Sort_CSN

; Clear initailization flag

		xor	ax, ax
		mov	ds:INIT_FLAG, ax
		mov	ds:ERROR_FLAG, ax

; Fixed configuration loop

		movzx	cx, byte ptr ds:TEMP_LAST_CSN
		or	cx, cx
		jz	Init_SuperIO_Exit

		mov	dx, ds:TEMP_PNP_RD	;RD_DATA port address
		mov	si, offset CSN_PRIORITY

ifdef	ESCD_SUPPORT					;R16
Fix_Config_Loop:
		lodsb
		mov	ds:CSN_CNT, al
		push	cx
		push	si
		call	Find_PnpEscd
		jc	short Fix_Config_Next

		call	Proc_PnpCard

Fix_Config_Next:
		pop	si
		pop	cx
		cmp	word ptr ds:ERROR_FLAG, 0
		jne	short Release_All_Cards
		loop	short Fix_Config_Loop

		cmp	word ptr ds:INIT_FLAG, 0
		je	short Auto_Config

; New PNP card configuration loop

		movzx	cx, byte ptr ds:TEMP_LAST_CSN
		mov	si, offset CSN_PRIORITY
New_Config_Loop:
		lodsb
		mov	ds:CSN_CNT, al
		push	cx
		push	si
		mov	cl, ds:CSN_CNT
		mov	ax, 1
		shl	ax, cl
		test	ds:INIT_FLAG, ax
		jnz	short New_Config_Next

		call	Proc_PnpCard

New_Config_Next:
		pop	si
		pop	cx
		cmp	word ptr ds:ERROR_FLAG, 0
		jne	short Release_All_Cards
		loop	short New_Config_Loop
		jmp	short Init_SuperIO_Exit

; Release all initiated PNP card resource loop

Release_All_Cards:
		mov	cx, 15
		mov	byte ptr ds:CSN_CNT, 1

Release_Cards_Loop:
		push	cx

		mov	cl, ds:CSN_CNT
		mov	ax, 1
		shl	ax, cl
		test	ds:INIT_FLAG, ax
		jz	short Release_Cards_Next

		call	Find_PnpEscd
		jc	short Release_Cards_Next

		xor	al, al				;function no.
Release_OneCard_Loop:
		push	si
		call	Find_EscdFunc
		jc	short Release_OneCard_Exit

		mov	di, offset CfgBuffer
		call	Xlat_Escd_CfgData
		call	Release_CfgData
		pop	si
		inc	al
		jmp	short Release_OneCard_Loop

Release_OneCard_Exit:
		pop	si

		mov	al, ds:[si].bSlotNum
		mov	di, offset NewEscdBrdMap
		call	Reset_EscdBrd
		mov	di, offset EscdBrdMap
		call	Reset_EscdBrd

		mov	bx, offset ESCD_BUFFER
		call	Remove_EscdBrd

Release_Cards_Next:
		pop	cx
		inc	byte ptr ds:CSN_CNT
		loop	short Release_Cards_Loop
endif	;ESCD_SUPPORT					;R16

; Auto configuration loop

Auto_Config:
		movzx	cx, byte ptr ds:TEMP_LAST_CSN
		mov	si, offset CSN_PRIORITY

Auto_Config_Loop:
		lodsb
		mov	ds:CSN_CNT, al
		push	cx
		push	si

		call	Proc_PnpCard

Auto_Config_Next:
		pop	si
		pop	cx
		loop	short Auto_Config_Loop

Init_SuperIO_Exit:
endif	;NO_ISA_PNP					;R16

		F000_call	Ct_Record_Resource

		pop	es
		pop	ds
		popa

		ret
PNP_SuperIO_Init	endp

;[]========================================================================[]
;Procedure:	Check_AT_Device
;Function :	Check/Record AT compatible device.
;Input	  :	None
;Output   :	None
;[]========================================================================[]

		ALIGN	4
Check_At_Device proc	near
		push	es
		mov	ax, 0F000h
		mov	es, ax

; Check standard serial port
; just record I/O port, since IRQ unknown

		mov	cx, 4
		mov	si, offset Aux_Addrs
Check_Comm_Loop:
		lods	word ptr es:[si]
		mov	dx, ax
ifdef CPINSTAL_IN_XGROUP		;R07
		Xcall	Test_COMM	;R07
else ;CPINSTAL_IN_XGROUP		;R07
		call	Test_COMM
endif ;CPINSTAL_IN_XGROUP		;R07
		jnz	short Check_Next_Comm
		mov	ax, dx
		dec	ax
		dec	ax
		mov	dx, 8
		call	Record_IO_Map
Check_Next_Comm:
		loop	short Check_Comm_Loop

; Check standard parallel port
; just record I/O port, since IRQ, DMA unknown

		mov	cx, 3
		mov	si,offset Aux_Prn_Addrs
Check_Lpt_Loop:
		lods	word ptr es:[si]
		mov	dx, ax
ifdef CPINSTAL_IN_XGROUP		;R07
		Xcall	Test_LPT	;R07
else ;CPINSTAL_IN_XGROUP		;R07
		call	Test_LPT
endif ;CPINSTAL_IN_XGROUP		;R07
		jnz	short Check_Next_Lpt
		mov	ax, dx
		mov	dx, 4			;length 4 for 3BC
		cmp	ax, 3BCh
		je	short @f
		add	dx, dx			;length 8 for others
@@:
		call	Record_IO_Map
Check_Next_Lpt:
		loop	short Check_Lpt_Loop

; Check game port

ifndef	No_Touch_Game_Port				;R04
		mov	dx, 201h
		in	al, dx
		test	al, 0Fh
		jnz	short @f
endif	;No_Touch_Game_Port				;R04
		mov	ax, dx
		mov	dx, 1
		call	Record_IO_Map
@@:

; Check floppy diskette controller
; and record I/O port 3F0-3F7, IRQ6, DMA2

		mov	cx, 3
		mov	si, offset EGROUP:Disk_Table
Check_Disk_Loop:
		push	si
		lods	word ptr cs:[si]
		mov	dx, ax

		mov	al,0ah
		out	dx, al
		not	al
		NEWIODELAY
		in	al, dx

		cmp	al,0ah
		jnz	short @f

		mov	al,05h
		out	dx, al
		not	al
		NEWIODELAY
		in	al, dx

		cmp	al,05h
		jne	short @F
		dec	dx
		dec	dx
		mov	ax, dx

		cmp	ax, 1F0h
		jne	short Check_Ide2
		push	ax
		mov	ax, 3F6h
		mov	dx, 1
		call	Record_IO_Map
		pop	ax
		jmp	short Check_Ide_Exit
Check_Ide2:
		cmp	ax, 170h
		jne	short Check_Ide_Exit
		push	ax
		mov	ax, 376h
		mov	dx, 1
		call	Record_IO_Map
		pop	ax
Check_Ide_Exit:

		mov	dx, 8
		call	Record_IO_Map
		lods	byte ptr cs:[si]
		call	Record_IRQ_Map
		lods	byte ptr cs:[si]
		call	Record_DMA_Map
@@:

		pop	si
		add	si, 4
		loop	short Check_Disk_Loop

		pop	es
		ret
Check_At_Device endp

Disk_Table	label	byte
		dw	3F2h, 0206h		;IRQ6, DMA2
		dw	1F2h, 040Eh		;IRQ14, DMA4(dummy)
		dw	172h, 040Fh		;IRQ15, DMA4(dummy)

;[]========================================================================[]
;Procedure:	Proc_Post_Node
;Function :	Call POST process routine of system device nodes.
;Input	  :	None
;Output   :	None
;[]========================================================================[]

		public	Proc_Post_Node
		ALIGN	4
Proc_Post_Node	proc	near
		pushad
		push	ds
		push	es
		pushf
		cli

		xor	eax,eax

		call	F000_Ct_Buffer_Request
		shl	eax,1
		sub	esp, eax		;reduce stack for saving status

		mov	eax, esp
		push	ebp			;save EBP value
		mov	ebp, eax		;status buffer index

		F000_call	Ct_Save_Shadow		;save shadow status

; Process special system device nodes

		F000_call	Ct_Shadow_Write

		pop	eax
		push	ebp			;save for Ct_Restore_Shadow
		mov	ebp, eax		;restore EBP value

		assume	ds:NOTHING
		mov	ax, 0F000h
		mov	ds, ax
		mov	ax, 0F000h
		mov	es, ax

; Process special post procedure

		xor	bx, bx

		mov	cx, NO_OF_NODE_TBL
Proc_Special_Loop:
		push	cx
		xor	dl, dl			;node number in index table
		mov	si, ds:NODES_INDEX[bx]
		lodsb
		movzx	cx, al
		jcxz	short Proc_Next_Table
Proc_Special_Loop1:
		push	si

		test	byte ptr ds:[si], 08	;special post process ?
		jz	short Proc_Next_Node

		mov	di, si			;point to node index
		mov	si, ds:NODES_PROC[bx]
Search_Proc_Loop:
		cmp	byte ptr ds:[si], 0FFh	;end NODE_PROC table ?
		je	short Proc_Next_Node	;yes, no corresponding proc

		cmp	dl, ds:[si]		;node number match ?
		je	short @f
		add	si, 7			;NODE_PROC structure length
		jmp	short Search_Proc_Loop

@@:
		pusha
		mov	di, ds:[di+1]		;point to description block

; ES(DS):DI = point to resource description block

		mov	si, ds:[si+5]		;special post procedure
		F000_call	si
		popa

; ES(DS):DI = point to node attribute flag in index table

		mov	al, ds:[di]		;original attribute flag
		jnc	short @f
		or	al, 80h 		;disable attribute

		call	F000_Ct_Set_Shadow
		jmp	short Proc_Next_Node
@@:
		and	al, not 80h		;enable attribute

		call	F000_Ct_Set_Shadow

Proc_Next_Node:
		pop	si
		inc	dl			;inc node num in index table
		add	si, 3			;NODE_INDEX structure length
		loop	short Proc_Special_Loop1

Proc_Next_Table:
		pop	cx
		add	bx, 2			;next NODES_INDEX
		loop	short Proc_Special_Loop

; Calculate total system device nodes and largest node size

		xor	dx, dx			;largest node
		xor	ax, ax			;total nodes
		xor	bx, bx

		mov	cx, NO_OF_NODE_TBL
Calc_Nodes_Loop:
		push	cx
		mov	si, ds:NODES_INDEX[bx]
		xor	cx, cx
		mov	cl, ds:[si]
		jcxz	short Next_Nodes_Table
		inc	si
Calc_Nodes_Loop1:
;R17		test	byte ptr ds:[si], 80h
;R17		jnz	short Calc_Next_Node
		test	byte ptr ds:[si], 80h	;R17A
		jnz	short Calc_Next_Node	;R17A
		inc	al			;increment total nodes
		mov	di, ds:[si+1]
		cmp	dx, ds:[di]
		jae	short Calc_Next_Node
		mov	dx, ds:[di]
Calc_Next_Node:
		add	si, 3
		loop	short Calc_Nodes_Loop1
Next_Nodes_Table:
		pop	cx
		add	bx, 2
		loop	short Calc_Nodes_Loop

; AL = total nodes
; DX = largest node size

		push	ax

		mov	ax, 0F000h
		mov	es, ax
		mov	ax, G_RAM
		mov	ds, ax
		assume	ds:G_RAM

		pop	ax
		mov	di, offset TOTAL_NODES

		call	F000_Ct_Set_Shadow

		mov	di, offset LARGEST_SIZE
		mov	al, dl

		call	F000_Ct_Set_Shadow
		mov	di, offset LARGEST_SIZE+1
		mov	al, dh

		call	F000_Ct_Set_Shadow

ifndef	NO_ISA_PNP					;R16
; Set PNP_RD and LAST_CSN

		mov	al, byte ptr ds:TEMP_PNP_RD
		mov	di, offset PNP_RD

		call	F000_Ct_Set_Shadow
		mov	al, byte ptr ds:TEMP_PNP_RD+1
		mov	di, offset PNP_RD+1

		call	F000_Ct_Set_Shadow
		mov	al, ds:TEMP_LAST_CSN
		mov	di, offset LAST_CSN

		call	F000_Ct_Set_Shadow
endif	;NO_ISA_PNP					;R16

		pop	ebp			;restore for Ct_Restore_Shadow

		F000_call	Ct_Restore_Shadow	;restore shadow status

		xor	eax, eax

		call	F000_Ct_Buffer_Request
		shl	eax,1
		add	esp,eax

		popf
		pop	es
		pop	ds
		popad
		ret
Proc_Post_Node	endp

;[]========================================================================[]
;Procedure:	Create_Resource_Map
;Function :	Create standard PC/AT system resource usaged map
;Input	  :	DS, ES = G_RAM
;Output   :	None
;[]========================================================================[]
		ALIGN	4
Create_Resource_Map	proc	near

; Check COMM port resource usage

; Exclude IRQ enabled by any things

; Get extended memory usage

		xor	edx, edx
		mov	al, EXT_MEMORY

		call	F000_Get_Cmos
		mov	dl, al
		mov	al, EXT_MEMORY+1

		call	F000_Get_Cmos
		mov	dh, al
		add	dx, 1024		;add convenient memory size
		test	dx, 07FFh		;check 2MB boundary
		jz	short @f
		add	dx, 0800h		;next 2MB boundary
@@:
		and	dx, 0F800h		;force in 2MB boundary
		shl	edx, 10

		mov	ds:EXTMEM_BASE, edx

ifdef	IRQ12_CHIPSET_QUALIFY
	;if PS2 mouse installed, exclude IRQ12
		F000_CALL Ct_Irq12_Chk		;IRQ 12 available ?
		jc	short Irq12_Used
endif;	IRQ12_CHIPSET_QUALIFY

	;if PS2 mouse installed, exclude IRQ12
		test	byte ptr ds:Hardware,00000100b		;PS/2 spec.
		jz	short @F
Irq12_Used:

		and	byte ptr ds:IRQ_MAP+1,11101111b
	@@:

ifdef	PCI_BUS
		test	byte ptr PCI_IDE_EXIST[bp], 03
		jz	short @f
		call	Record_1st_Ide
		test	byte ptr PCI_IDE_EXIST[bp], 01
		jz	short @f
		call	Record_2nd_Ide
@@:
endif	;PCI_BUS

		mov	ax, 110h
		mov	dx, 10h
		call	Record_IO_Map

		ret
Create_Resource_Map	endp

		ALIGN	4
		public	Record_1st_Ide
Record_1st_Ide	proc	near
		push	ax
		push	dx
		mov	ax, 1F0h
		mov	dx, 8
		call	Record_IO_Map
		mov	ax, 3F6h
		mov	dx, 1
		call	Record_IO_Map
		mov	al, 14
		call	Record_IRQ_Map
		pop	dx
		pop	ax
		ret
Record_1st_Ide	endp

		ALIGN	4
		public	Record_2nd_Ide
Record_2nd_Ide	proc	near
		push	ax
		push	dx
		mov	ax, 170h
		mov	dx, 8
		call	Record_IO_Map
		mov	ax, 376h
		mov	dx, 1
		call	Record_IO_Map
		mov	al, 15
		call	Record_IRQ_Map
		pop	dx
		pop	ax
		ret
Record_2nd_Ide	endp

;[]========================================================================[]
;Procedure:	PNP_Disp_Logo
;Function :
;Input	  :	None
;Output   :	None
;Registers:
;Note	  :
;[]========================================================================[]

ifndef	NO_PNP_MSG_DISPLAY				;R15
		Public	Award_PnP_Msg			;R11
Award_PnP_Msg	db	0Bh
		db	"Award Plug and Play BIOS Extension v1.0A", 0Bh
		db	"Copyright (C) 1999, Award Software, Inc.", 0;R01;R08;R20
endif;	NO_PNP_MSG_DISPLAY				;R15

		public	PNP_Disp_Logo
		ALIGN	4
PNP_Disp_Logo	proc	near
ifndef	NO_PNP_MSG_DISPLAY				;R15
		push	si
		mov	si, offset EGROUP:Award_PnP_Msg
		call	Display_CS_String
		pop	si
endif;	NO_PNP_MSG_DISPLAY				;R15
		ret
PNP_Disp_Logo	endp

ifndef	NO_ISA_PNP					;R16
;************************************************************************
;*									*
;*		PROCESS ISA/PNP MODULE					*
;*									*
;************************************************************************

RDDATA_PORT	label	word
		dw	020Bh
		dw	020Fh
		dw	0213h
		dw	0217h
		dw	021Bh
		dw	021Fh

		dw	0263h
		dw	0283h
		dw	02A3h
		dw	02C3h
		dw	02E3h

		dw	0323h
		dw	0343h
		dw	0363h
		dw	0383h
		dw	03A3h
		dw	03E3h
		dw	0

;[]========================================================================[]
;Procedure:	Proc_PnpCard
;Function :	Process one PNP card, include resources assignment and
;		ESCD process.
;Input	  :	DS:CSN_CNT
;Output   :	None
;[]========================================================================[]

		ALIGN	4
Proc_PnpCard	proc	near

		pusha

ifdef	ESCD_SUPPORT					;R16
		mov	cl, ds:CSN_CNT
		mov	ax, 1
		shl	ax, cl
		or	ds:INIT_FLAG, ax

		call	Create_PnpEscd_Head
endif	;ESCD_SUPPORT					;R16

		mov	byte ptr ds:LOGIC_DEV_CNT, 0	;logical device count

Init_PnpDev_Loop:
		mov	al, ds:CSN_CNT
		mov	ah, ds:LOGIC_DEV_CNT
		call	Find_LogicDev
		jc	Init_PnpCard_End

 ifndef FORCE_NON_PNP_OS				;R06
	ifdef	PNP_OS_SELECTABLE
		test	byte ptr ds:[si+4], 01		;power up active flag
		jnz	short @f
		test	byte ptr ds:PNP_FLAG, OS_ENABLE
;R12		jnz	Init_PnpDev_Disable
;R12 - start
		jz	short @f

		call	Find_BootDev			;find compatible dev id
							;for boot device
ifdef	ESCD_SUPPORT					;R16
		jc	Init_PnpDev_Disable		;skip if not boot dev
else	;ESCD_SUPPORT					;R16
		jc	short Init_Next_PnpDev		;R16
endif	;ESCD_SUPPORT					;R16

		mov	al, ds:CSN_CNT
		mov	ah, ds:LOGIC_DEV_CNT
		call	Find_LogicDev			;re-point to logic dev
							;resource data
;R12 - end
	@@:
	endif	;PNP_OS_SELECTABLE
 endif; FORCE_NON_PNP_OS				;R06

ifdef	ESCD_SUPPORT					;R16
		mov	di, offset CfgBuffer
		call	Init_CfgData

		call	Find_PnpEscd
		jc	short No_Fix_Config

; SI = point to PNP ESCD record

		mov	al, ds:LOGIC_DEV_CNT
		call	Check_Disable

		jc	Init_PnpDev_Disable

		call	Find_EscdFunc
		jc	short No_Fix_Config

; SI = point to PNP ESCD Function record

		call	Xlat_Escd_CfgData
		jz	short No_Fix_Config

; Find corresponding resource information

		mov	byte ptr ds:CHOICE_CNT, 0	;resouce choice count
Find_Resource_Loop:
		push	di
		mov	di, offset CHOICE_BUFFER
		mov	al, byte ptr ds:CHOICE_CNT
		call	Find_Choice
		pop	di
		jc	short No_Fix_Config

		call	Verify_CfgData
		jnc	short Find_Resource_End

		inc	byte ptr ds:CHOICE_CNT

		mov	al, ds:CSN_CNT
		mov	ah, ds:LOGIC_DEV_CNT
		push	si
		call	Find_LogicDev
		pop	si
		jnc	short Find_Resource_Loop
		jmp	Init_PnpDev_Fail

Find_Resource_End:

		call	Query_CfgData
		jc	short No_Fix_Config

		call	Record_CfgData

		call	Copy_EscdFunc
		mov	ax, ds:[si].wFuncSize
		add	ax, 2
		add	ds:CurrentEscd.wBrdSize, ax

		mov	ah, ds:LOGIC_DEV_CNT
		mov	al, LOGIC_DEV
		call	Set_PnP_Reg

		call	Prog_PnpDev

		mov	ah, 01
		mov	al, ACT_REG
		call	Set_PnP_Reg

		jmp	Init_Next_PnpDev

No_Fix_Config:

		mov	al, ds:CSN_CNT
		mov	ah, ds:LOGIC_DEV_CNT
		call	Find_LogicDev
		jc	short Init_PnpDev_Fail
endif	;ESCD_SUPPORT					;R16

		mov	byte ptr ds:CHOICE_CNT, 0	;resouce choice count

PnpDev_Choice_Loop:
		mov	di, offset CHOICE_BUFFER
		mov	al, byte ptr ds:CHOICE_CNT
		call	Find_Choice
ifdef	ESCD_SUPPORT					;R16
		jc	short Init_PnpDev_Fail
else	;ESCD_SUPPORT					;R16
		jc	short Init_Next_PnpDev		;R16
endif	;ESCD_SUPPORT					;R16

		mov	di, offset CfgBuffer
		call	Init_CfgData

		mov	si, offset CHOICE_BUFFER
@@:
		call	Get_Tag_Name

		cmp	ah, sEndTag		;end resource information
		je	short One_PnpDev_End

		call	Parse_Tag
		jc	short @f

		add	si, cx
		jmp	short @b

@@:
		call	Release_CfgData

		mov	al, ds:CSN_CNT
		mov	ah, ds:LOGIC_DEV_CNT
		call	Find_LogicDev
ifdef	ESCD_SUPPORT					;R16
		jc	short Init_PnpDev_Fail
else	;ESCD_SUPPORT					;R16
		jc	short Init_Next_PnpDev		;R16
endif	;ESCD_SUPPORT					;R16

		inc	byte ptr ds:CHOICE_CNT
		jmp	short PnpDev_Choice_Loop

; Program logical device with CfgBuffer

One_PnpDev_End:

; Select current logical device

		mov	ah, ds:LOGIC_DEV_CNT
		mov	al, LOGIC_DEV
		call	Set_PnP_Reg

; Program configuration registers

		call	Prog_PnpDev

; Activate current logical device

		mov	ah, 01
		mov	al, ACT_REG
		call	Set_PnP_Reg

ifdef	ESCD_SUPPORT					;R16
		mov	bx, ds:CurrentEscdPoint
		mov	di, bx
		mov	si, offset EGROUP:EscdFuncHead
		mov	cx, EscdFuncHead_L
		push	ds
		push	cs
		pop	ds
		rep	movsb
		pop	ds
		mov	si, offset CfgBuffer
		call	Xlat_CfgData_Escd
		jmp	short @f

Init_PnpDev_Fail:
		mov	cl, ds:CSN_CNT
		mov	ax, 1
		shl	ax, cl
		or	ds:ERROR_FLAG, ax
Init_PnpDev_Disable:
		mov	bx, ds:CurrentEscdPoint
		mov	di, bx
		mov	si, offset EGROUP:EscdFuncHead
		mov	cx, EscdFuncHead_L
		push	ds
		push	cs
		pop	ds
		rep	movsb
		pop	ds
@@:
		or	byte ptr es:[bx].bFuncInfo, FUNC_DISABLE
		mov	ds:CurrentEscdPoint, di
		mov	ax, ds:[bx].wFuncSize
		add	ax, 2
		add	ds:CurrentEscd.wBrdSize, ax
endif	;ESCD_SUPPORT					;R16

Init_Next_PnpDev:
		inc	byte ptr ds:LOGIC_DEV_CNT
		jmp	Init_PnpDev_Loop

Init_PnpCard_End:
ifdef	ESCD_SUPPORT					;R16
		call	Create_PnpEcdFF
		call	Proc_PnpEscd
endif	;ESCD_SUPPORT					;R16
Proc_PnpCard_Exit:
		call	Force_Sleep
		popa
		ret

Proc_PnpCard	endp

;R12 - start
ifndef	FORCE_NON_PNP_OS
ifdef	PNP_OS_SELECTABLE
;[]========================================================================[]
;Procedure:	Find_BootDev
;Function :	Find boot device according to Compatible Device ID
;Input: 	DX = READ_DATA port address
;		DS, ES = G_RAM
;		DS:SI = Logical Device ID string
;Output:	CF = 0 boot device found
;		CF = 1 not boot device
;Note:		The card's resource data has to be point to current logical
;		device.
;[]========================================================================[]

		ALIGN	4
Find_BootDev	proc	near
		pusha
		jmp	short Comp_BootDev_ID		;cmp logic dev ID first
Find_BootDev_Loop:
		call	Get_Resource_Block
		jc	short Find_BootDev_Fail
		cmp	ah, sLogicDevId 		;next logic dev?
		je	short Find_BootDev_Fail
		cmp	ah, sEndTag			;end resource data?
		je	short Find_BootDev_Fail
		cmp	ah, sCompDevId
		jne	short Find_BootDev_Loop

Comp_BootDev_ID:
		mov	di, offset BootDev_ID
		mov	cx, BootDev_L
Comp_BootDev_Loop:
		push	cx
		push	di
		push	es
		push	cs
		pop	es
		mov	cx, 3
		repe	cmpsb
		pop	es
		pop	di
		pop	cx
		je	short Find_BootDev_Success
		add	di, 3
		loop	short Comp_BootDev_Loop
		jmp	short Find_BootDev_Loop

Find_BootDev_Success:
		popa
		clc					;boot device
		ret

Find_BootDev_Fail:
		popa
		stc					;not boot device
		ret
Find_BootDev	endp

BootDev_ID	label	byte
		db	41h, 0D0h, 06h		;IDE
		db	41h, 0D0h, 0A0h 	;SCSI
BootDev_L	equ	($ - offset BootDev_ID)/3
endif	;PNP_OS_SELECTABLE
endif	;FORCE_NON_PNP_OS
;R12 - end

;[]========================================================================[]
;Procedure:	Find_Choice
;Function :	Find/Create one choice resouce information for current device
;Input: 	DS(ES):DI = point to buffer
;		AL = Choice Number
;Output:	CF = 0 successful
;		CF = 1 fail
;[]========================================================================[]

		ALIGN	4
Find_Choice	proc	near
		push	ax
		push	bx
		push	cx
		push	dx
		push	si
		push	di
		mov	bl, al
		neg	bl			;choice count
Find_Choice_Loop:
		call	Get_Resource_Block
		jc	short Find_Choice_Fail
		cmp	ah, sLogicDevId
		je	short Find_Choice_Success
		cmp	ah, sEndTag
		je	short Find_Choice_Success
		cmp	ah, sStartDf
		je	short Find_Choice_Proc_Df
		call	Move_Item
		jmp	short Find_Choice_Loop

Find_Choice_Proc_Df:
		or	bl, bl
		jz	short Find_Choice_Df_Loop
Find_Choice_Next_Df:
		call	Get_Resource_Block
		jc	short Find_Choice_Fail
		cmp	ah, sEndTag
		je	short Find_Choice_Fail
		cmp	ah, sEndDf
		je	short Find_Choice_Fail
		cmp	ah, sStartDf
		jne	short Find_Choice_Next_Df
		inc	bl
		jmp	short Find_Choice_Proc_Df

Find_Choice_Df_Loop:
		call	Get_Resource_Block
		jc	short Find_Choice_Fail
		cmp	ah, sEndTag
		je	short Find_Choice_Success
		cmp	ah, sEndDf
		je	short Find_Choice_Loop
		cmp	ah, sStartDf
		je	short Find_Choice_Clear_Df
		call	Move_Item
		jmp	short Find_Choice_Df_Loop

Find_Choice_Clear_Df:
		call	Get_Resource_Block
		jc	short Find_Choice_Fail
		cmp	ah, sEndTag
		je	short Find_Choice_Success
		cmp	ah, sEndDf
		je	short Find_Choice_Loop
		jmp	short Find_Choice_Clear_Df

Find_Choice_Success:
		or	bl, bl
		jnz	short Find_Choice_Fail
		mov	ax, 0079h		;end tag
		stosw
		pop	si
		push	si
		call	Sort_Item
		clc
		jmp	short Find_Choice_Exit

Find_Choice_Fail:
		stc

Find_Choice_Exit:
		pop	di
		pop	si
		pop	dx
		pop	cx
		pop	bx
		pop	ax
		ret
Find_Choice	endp

;[]========================================================================[]
;Procedure:	Move_Item
;Function :	Move one temperary resouce buffer to global resource buffer
;Input: 	DS(ES):SI = source
;		DS(ES):DI = destination
;Output:	none
;[]========================================================================[]

		ALIGN	4
Move_Item	proc	near
		push	ax
		push	cx
		push	di
		push	es
		push	cs
		pop	es
		mov	al, ah
		mov	di, offset EGROUP:TAG_CODE
		mov	cx, TAG_CODE_L
		repne	scasb
		pop	es
		pop	di
		pop	cx
		pop	ax
		jne	short Move_Item_Exit
		stosb
		test	al, 80h
		jz	short @f
		mov	ax, cx
		stosw
@@:
		rep	movsb
Move_Item_Exit:
		ret
Move_Item	endp

;[]========================================================================[]
;Procedure:	Sort_Item
;Function :	Sort a global resource buffer with item process priority
;Input: 	DS(ES):SI = buffer start address
;		DS(ES):DI = buffer end address
;Output:	none
;[]========================================================================[]

Sort_Table	label	byte
		db	3,81h,85h,86h	;lMem24/lMem32/lMemFixed
		db	2,47h,4Bh	;sIoPort/sIoPortFixed
		db	2,22h,23h	;sIrqFormat
		db	1,2Ah		;sDmaFormat

; si = start address
; di = end address

		ALIGN	4
Sort_Item	proc	near
		push	si
		push	di

		mov	dx, di				;buffer end
		mov	bx, offset EGROUP:Sort_Table
		mov	cx, 4				;group number
		mov	di, si				;start address

; di = buffer pointer

Sort_Group_Loop:
		push	cx
		mov	si, di			;remainder scanning pointer
Sort_Item_Loop:
		push	si			;scanning pointer

		lodsb
		cmp	al, 79h 		;end item
		je	short Sort_Next_Group

		push	ax			;item name
		test	al, 80h
		jz	short Sort_sItem
		lodsw
		mov	cx, ax
		add	cx, 3
		jmp	short Sort_Item_Cont
Sort_sItem:
		movzx	cx, al
		and	cl, 07
		inc	cx
Sort_Item_Cont:
		pop	ax			;item name

; ax = item name
; cx = item length
; si = scanning pointer
; di = remainder pointer
; bx = group pointer
; dx = point to buffer end

		push	es
		push	di
		push	cx
		movzx	cx, byte ptr cs:[bx]	;group item number
		push	cs
		pop	es
		mov	di, bx
		inc	di			;point to group item value
		repne	scasb
		pop	cx
		pop	di
		pop	es

		pop	si

		jne	short Sort_Next_Item

		cmp	di, si			;no swapping needed, if remainder
		je	short @f		;pointer equal to current item pointer

		call	Swap_Buffer

@@:
		add	di, cx			;remainder pointer

Sort_Next_Item:
		add	si, cx			;scanning pointer
		jmp	short Sort_Item_Loop

Sort_Next_Group:
		pop	si
		movzx	ax, byte ptr cs:[bx]
		add	bx, ax			;next group
		inc	bx
		pop	cx
		loop	short Sort_Group_Loop

		pop	di
		pop	si
		ret
Sort_Item	endp

;[]========================================================================[]
;Procedure:	Swap_Buffer
;Function :	Swap one selected resource item block to privious position
;Input: 	DS(ES):SI = point to selected resource item block
;		DS(ES):DI = point to last stored address
;		DS(ES):DX = point to buffer end
;		CX = item block length
;Output:	none
;[]========================================================================[]

		ALIGN	4
Swap_Buffer	proc	near
		push	cx
		push	si
		push	di
		mov	di, dx
		rep	movsb			;move to buffer end
		pop	di
		pop	si
		pop	cx

		push	cx
		push	si
		push	di
		mov	ax, di
		mov	di, si
		add	di, cx
		mov	cx, si
		sub	cx, ax
		dec	si
		dec	di
		std
		rep	movsb
		cld
		pop	di
		pop	si
		pop	cx

		push	cx
		push	si
		push	di
		mov	si, dx
		rep	movsb
		pop	di
		pop	si
		pop	cx
		ret
Swap_Buffer	endp

;[]========================================================================[]
;Procedure:	Sort_CSN
;Function :	Sort PNP cards initializing sequence with device type priority
;Input	  :	none
;Output   :	none
;[]========================================================================[]

		ALIGN	4
Sort_CSN	proc	near
		pusha

		movzx	cx, byte ptr ds:TEMP_LAST_CSN
		or	cx, cx
		jz	Sort_CSN_Exit

		mov	dx, ds:TEMP_PNP_RD		;RD_DATA port address
		mov	di, offset STR_BUFFER		;temporary usage

		push	cx
		push	di
		mov	al, Priority_Table_L		;lowest priority
		rep	stosb
		pop	di
		pop	cx

		mov	byte ptr ds:CSN_CNT, 1		;CSN start

Chk_Priority_Loop1:
		push	cx

		mov	al, ds:CSN_CNT
		call	Set_Wake_CSN
		call	Get_SerialId
		jc	short Chk_Priority_Next
Chk_Priority_Loop2:
		call	Get_Resource_Block
		jc	short Chk_Priority_Next
		cmp	ah, sEndTag
		je	short Chk_Priority_Next

		cmp	ah, sLogicDevId
		je	short @f
		cmp	ah, sCompDevId
		jne	short Chk_Priority_Loop2

@@:
		push	es
		push	di
		push	cx

		push	cs
		pop	es

		mov	cx, Priority_Table_L
		mov	di, offset EGROUP:Priority_Table
		xor	al, al				;highest priority
@@:
		push	cx
		push	si
		push	di
		mov	cx, 3
		repe	cmpsb
		pop	di
		pop	si
		pop	cx
		je	short @f
		inc	al
		add	di, 3
		loop	short @b
		pop	cx
		pop	di
		pop	es
		jmp	short Chk_Priority_Loop2
@@:
		pop	cx
		pop	di
		pop	es
		cmp	al, ds:[di]
		jae	short @f
		mov	ds:[di], al
@@:
		jmp	short Chk_Priority_Loop2

Chk_Priority_Next:
		pop	cx
		call	Force_Sleep
		inc	di
		inc	byte ptr ds:CSN_CNT		;next CSN
		loop	short Chk_Priority_Loop1

		mov	di, offset CSN_PRIORITY
		mov	cx, Priority_Table_L+1
		xor	ah, ah				;highest priority
Sort_CSN_Loop1:
		push	cx

		movzx	cx, byte ptr ds:TEMP_LAST_CSN
		mov	si, offset STR_BUFFER
		mov	al, 1				;CSN
Sort_CSN_Loop2:
		cmp	ah, ds:[si]
		jne	short @f
		stosb
@@:
		inc	al
		inc	si
		loop	short Sort_CSN_Loop2

		pop	cx
		inc	ah
		loop	short Sort_CSN_Loop1

Sort_CSN_Exit:
		popa
		ret
Sort_CSN	endp

Priority_Table	label	byte
		db	41h, 0D0h, 06h		;IDE
		db	41h, 0D0h, 07h		;Floppy
		db	41h, 0D0h, 04h		;LPT
		db	41h, 0D0h, 05h		;COM

		db	41h, 0D0h, 0B0h 	;Sound
		db	41h, 0D0h, 0A0h 	;SCSI
Priority_Table_L	equ	($ - offset Priority_Table)/3

TAG_PROC	label	word
		dw	offset EGROUP:Proc_sIrqFormat
		dw	offset EGROUP:Proc_sDmaFormat
		dw	offset EGROUP:Proc_sIoPort
		dw	offset EGROUP:Proc_sIoPortFixed
		dw	offset EGROUP:Proc_lMem24
		dw	offset EGROUP:Proc_lMem32
		dw	offset EGROUP:Proc_lMemFixed

	ALIGN	4
Parse_Tag	proc	near
		pushad
		mov	bx, offset EGROUP:TAG_CODE
		mov	dx, offset EGROUP:TAG_PROC
		mov	cx, TAG_CODE_L
@@:
		cmp	cs:[bx], ah
		je	short @f
		inc	bx
		inc	dx
		inc	dx
		loop	short @b
		jmp	short Parse_Tag_Success
@@:
		mov	bx, dx
		call	word ptr cs:[bx]
		jc	short Parse_Tag_Fail
Parse_Tag_Exit:
		popad
		ret
Parse_Tag_Success:
		clc
		jmp	short Parse_Tag_Exit
Parse_Tag_Fail:
		stc
		jmp	short Parse_Tag_Exit
Parse_Tag	endp

;[]========================================================================[]
;Procedure:	Release_CfgData
;Function :	Release resouces with specified CFGDATA
;Input	  :	ES(DS):DI = point to CFGDATA structure
;Output   :	None
;[]========================================================================[]

		ALIGN	4
Release_CfgData proc	near
		pushad

; Release memory 24 configuration data

		xor	cx, cx
Release_Mem24:
		mov	cl, ds:[di].Mem24CfgCount
		jcxz	short Release_Mem32
		xor	ax, ax
Release_Mem24_Loop:
		push	ax
		push	cx
		mov	bl, (SIZE MEMCFGDATA)
		mul	bl
		mov	bx, ax
		mov	eax, ds:[bx+di].Mem24Cfg.MemBase
		mov	edx, ds:[bx+di].Mem24Cfg.MemLength
		call	Release_Mem_Map
		pop	cx
		pop	ax
		inc	al
		loop	short Release_Mem24_Loop

; Release memory 32 configuration data

Release_Mem32:
		mov	cl, ds:[di].Mem32CfgCount
		jcxz	short Release_IO
		xor	ax, ax
Release_Mem32_Loop:
		push	ax
		push	cx
		mov	bl, (SIZE MEMCFGDATA)
		mul	bl
		mov	bx, ax
		mov	eax, ds:[bx+di].Mem32Cfg.MemBase
		mov	edx, ds:[bx+di].Mem32Cfg.MemLength
		call	Release_Mem_Map
		pop	cx
		pop	ax
		inc	al
		loop	short Release_Mem32_Loop

; Release I/O port configuration data

Release_IO:
		mov	cl, ds:[di].IoCfgCount
		jcxz	short Release_IRQ
		xor	ax, ax
Release_IO_Loop:
		push	ax
		push	cx
		mov	bl, (SIZE IOCFGDATA)
		mul	bl
		mov	bx, ax
		xor	dx, dx
		mov	ax, ds:[bx+di].IoCfg.IoBase
		mov	dl, ds:[bx+di].IoCfg.IoLength
		call	Release_IO_Map
		pop	cx
		pop	ax
		inc	al
		loop	short Release_IO_Loop

; Release IRQ configuration data

Release_IRQ:
		mov	cl, ds:[di].IrqCfgCount
		jcxz	short Release_DMA
		xor	ax, ax
Release_IRQ_Loop:
		push	ax
		push	cx
		mov	bl, (SIZE IRQCFGDATA)
		mul	bl
		mov	bx, ax
		mov	al, ds:[bx+di].IrqCfg.IrqNum
		call	Release_IRQ_Map
		pop	cx
		pop	ax
		inc	al
		loop	short Release_IRQ_Loop

; Release DMA configuration data

Release_DMA:
		mov	cl, ds:[di].DmaCfgCount
		jcxz	short Release_System_Map_Exit
		xor	ax, ax
Release_DMA_Loop:
		push	ax
		push	cx
		mov	bl, (SIZE DMACFGDATA)
		mul	bl
		mov	bx, ax
		mov	al, ds:[bx+di].DmaCfg.DmaNum
		call	Release_DMA_Map
		pop	cx
		pop	ax
		inc	al
		loop	short Release_DMA_Loop

; All configuration data released

Release_System_Map_Exit:
		popad
		ret

Release_CfgData endp

;[]========================================================================[]
;Procedure:	Release_DMA_Map
;Function :	Release DMA resource
;Input	  :	DS = G_RAM
;		AL = DMA chanel
;Output   :	None
;[]========================================================================[]

		ALIGN	4
Release_DMA_Map proc	near
		push	ax
		push	cx
		mov	cl, al
		and	cl, 07h
		mov	al, 01
		rol	al, cl

		or	ds:DMA_MAP, al
		pop	cx
		pop	ax
		ret
Release_DMA_Map endp

ifdef	ESCD_SUPPORT					;R16
;************************************************************************
;*									*
;*		PROCESS ISA/PNP RELATED TO ESCD MODULE			*
;*									*
;************************************************************************

;[]========================================================================[]
;Procedure:	Query_CfgData
;Function :	Query resouces with specified CFGDATA
;Input	  :	ES(DS):DI = point to CFGDATA structure
;Output   :	CF = 0 successful
;		CF = 1 fail
;[]========================================================================[]

		ALIGN	4
Query_CfgData	proc	near
		pushad

; Query memory 24 configuration data

		xor	cx, cx
Query_Mem24:
		mov	cl, ds:[di].Mem24CfgCount
		jcxz	short Query_Mem32
		xor	ax, ax
Query_Mem24_Loop:
		push	ax
		push	cx
		mov	bl, (SIZE MEMCFGDATA)
		mul	bl
		mov	bx, ax
		mov	eax, ds:[bx+di].Mem24Cfg.MemBase
		mov	edx, ds:[bx+di].Mem24Cfg.MemLength
		call	Query_Mem_Map
		pop	cx
		pop	ax
		jc	Query_CfgData_Fail
		inc	al
		loop	short Query_Mem24_Loop

; Query memory 32 configuration data

Query_Mem32:
		mov	cl, ds:[di].Mem32CfgCount
		jcxz	short Query_IO
		xor	ax, ax
Query_Mem32_Loop:
		push	ax
		push	cx
		mov	bl, (SIZE MEMCFGDATA)
		mul	bl
		mov	bx, ax
		mov	eax, ds:[bx+di].Mem32Cfg.MemBase
		mov	edx, ds:[bx+di].Mem32Cfg.MemLength
		call	Query_Mem_Map
		pop	cx
		pop	ax
		jc	short Query_CfgData_Fail
		inc	al
		loop	short Query_Mem32_Loop

; Query I/O port configuration data

Query_IO:
		mov	cl, ds:[di].IoCfgCount
		jcxz	short Query_IRQ
		xor	ax, ax
Query_IO_Loop:
		push	ax
		push	cx
		mov	bl, (SIZE IOCFGDATA)
		mul	bl
		mov	bx, ax
		xor	dx, dx
		mov	ax, ds:[bx+di].IoCfg.IoBase
		mov	dl, ds:[bx+di].IoCfg.IoLength
		call	Query_IO_Map
		pop	cx
		pop	ax
		jc	short Query_CfgData_Fail
		inc	al
		loop	short Query_IO_Loop

; Query IRQ configuration data

Query_IRQ:
		mov	cl, ds:[di].IrqCfgCount
		jcxz	short Query_DMA
		xor	ax, ax
Query_IRQ_Loop:
		push	ax
		push	cx
		mov	bl, (SIZE IRQCFGDATA)
		mul	bl
		mov	bx, ax
		mov	cl, ds:[bx+di].IrqCfg.IrqNum
		mov	ax, 01
		shl	ax, cl
		call	Query_IRQ_Map
		pop	cx
		pop	ax
		jc	short Query_CfgData_Fail
		inc	al
		loop	short Query_IRQ_Loop

; Query DMA configuration data

Query_DMA:
		mov	cl, ds:[di].DmaCfgCount
		jcxz	short Query_CfgData_Exit
		xor	ax, ax
Query_DMA_Loop:
		push	ax
		push	cx
		mov	bl, (SIZE DMACFGDATA)
		mul	bl
		mov	bx, ax
		mov	cl, ds:[bx+di].DmaCfg.DmaNum
		mov	al, 01
		shl	al, cl
		call	Query_DMA_Map
		pop	cx
		pop	ax
		jc	short Query_CfgData_Fail
		inc	al
		loop	short Query_DMA_Loop

Query_CfgData_Exit:
		popad
		clc
		ret
Query_CfgData_Fail:
		popad
		stc
		ret
Query_CfgData	endp

;[]========================================================================[]
;Procedure:	Find_EscdFunc
;Function :	Find function block in ESCD
;Input	  :	DS:SI = point to ESCD board record
;		AL = function number
;Output   :	CF = 0 function block found
;			SI = point to ESCD function block
;		CF = 1 function block not found
;[]========================================================================[]

		ALIGN	4
Find_EscdFunc	proc	near
		push	ax
		xor	ah, ah
		add	si, 12			;ESCD board header length
Find_EscdFunc_Loop:
		cmp	al, ah
		jne	short @f
		pop	ax
		clc
		ret
@@:
		cmp	word ptr ds:[si], 0		;board end
		je	short Find_EscdFunc_Exit
		cmp	byte ptr ds:[si+4], 0C0h	;free form data
		jne	short @f
		cmp	dword ptr ds:[si+6], 'GFCA'     ;ECD free form sign
		je	short Find_EscdFunc_Exit
@@:
		add	si, ds:[si]			;function length
		add	si, 2				;exclusive length word
		inc	ah
		jmp	short Find_EscdFunc_Loop
Find_EscdFunc_Exit:
		pop	ax
		stc
		ret
Find_EscdFunc	endp

;[]========================================================================[]
;Procedure:	Create_PnpEscd_Head
;Function :	Create ISA/PNP card ESCD head to CurrentEscd
;Input	  :	CSN_CNT
;Output   :	CurrentEscdPoint
;[]========================================================================[]

		ALIGN	4
Create_PnpEscd_Head	proc	near
		push	ds
		push	cs
		pop	ds
		mov	di, offset CurrentEscd
		mov	si, offset EGROUP:EscdBrdHead
		mov	cx, EscdBrdHead_L
		rep	movsb
		pop	ds
		mov	ds:CurrentEscdPoint, di
		mov	al, ds:CSN_CNT
		mov	ah, 9
		mul	ah
		mov	si, offset SERIAL_ID
		add	si, ax
		mov	di, offset CurrentEscd.wCompBrdID
		mov	cx, 4
		rep	movsb
		ret
Create_PnpEscd_Head	endp
endif	;ESCD_SUPPORT					;R16
endif	;NO_ISA_PNP					;R16

ifdef	ESCD_SUPPORT					;R16
;************************************************************************
;*									*
;*		PROCESS ESCD MODULE					*
;*									*
;************************************************************************

;[]========================================================================[]
;Procedure:	POST_Get_Escd
;Function :	Get ESCD in POST
;Input	  :	none
;Output   :	AX = return code
;[]========================================================================[]

		ALIGN	4
POST_Get_Escd	proc	near
		push	0F000h			;BiosSelector
		push	0F000h			;EscdSelector
		push	0			;EscdBufSeg
		push	offset ESCD_BUFFER	;EscdBufOff
		push	0042h			;Get ESCD
		FAR_CALL	<offset PNP_BIOS_Real>, 0F000h
		add	sp, 10
		or	ax, ax
		jnz	short @f
		clc
		ret
@@:
		stc
		ret
POST_Get_Escd	endp

endif	;ESCD_SUPPORT					;R16
ENDIF	;PNP_BIOS

ECODE		ENDS
		END
