Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Inc/Variables.inc
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Inc/Variables.inc	(revision 491)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Inc/Variables.inc	(revision 497)
@@ -29,4 +29,6 @@
 NUMBER_OF_EEPROM_TYPES				EQU		5
 MAX_EEPROM_SIZE_IN_BYTES			EQU		65536
+IDE_PORT_TO_START_DETECTION			EQU	00h		; Must be zero (not actual port)
+FIRST_MEMORY_SEGMENT_ADDRESS		EQU	0C000h
 
 
Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/AutoConfigure.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/AutoConfigure.asm	(revision 497)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/AutoConfigure.asm	(revision 497)
@@ -0,0 +1,178 @@
+; Project name	:	XTIDE Universal BIOS Configurator v2
+; Description	:	Functions to automatically configure XTIDE
+;					Universal BIOS for current system.
+
+;
+; XTIDE Universal BIOS and Associated Tools
+; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2012 by XTIDE Universal BIOS Team.
+;
+; This program is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+; GNU General Public License for more details.
+; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+;
+
+; Section containing code
+SECTION .text
+
+
+;--------------------------------------------------------------------
+; AutoConfigure_ForThisSystem
+; MENUITEM activation function (.fnActivate)
+;	Parameters:
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		All, except segments
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+AutoConfigure_ForThisSystem:
+	push	es
+	push	ds
+
+	call	Buffers_GetFileBufferToESDI		; ROMVARS now in ES:DI
+	push	es
+	pop		ds								; ROMVARS now in DS:DI
+	call	ResetIdevarsToDefaultValues
+	call	DetectIdePortsAndDevices
+	call	StoreAndDisplayNumberOfControllers
+
+	pop		ds
+	pop		es
+	ret
+
+
+;--------------------------------------------------------------------
+; ResetIdevarsToDefaultValues
+;	Parameters:
+;		DS:DI:	Ptr to ROMVARS
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, CX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+ResetIdevarsToDefaultValues:
+	push	di
+	add		di, BYTE ROMVARS.ideVarsBegin
+	mov		cx, ROMVARS.ideVarsEnd - ROMVARS.ideVarsBegin
+	call	Memory_ZeroESDIwithSizeInCX	; Never clears ROMVARS.ideVarsSerialAuto
+	pop		di
+
+	; Set default values (other than zero)
+	mov		ax, DISABLE_WRITE_CACHE | (TRANSLATEMODE_AUTO<<TRANSLATEMODE_FIELD_POSITION) | FLG_DRVPARAMS_BLOCKMODE
+	mov		[di+ROMVARS.ideVars0+IDEVARS.drvParamsMaster+DRVPARAMS.wFlags], ax
+	mov		[di+ROMVARS.ideVars1+IDEVARS.drvParamsMaster+DRVPARAMS.wFlags], ax
+	mov		[di+ROMVARS.ideVars2+IDEVARS.drvParamsMaster+DRVPARAMS.wFlags], ax
+	mov		[di+ROMVARS.ideVars3+IDEVARS.drvParamsMaster+DRVPARAMS.wFlags], ax
+	ret
+
+
+;--------------------------------------------------------------------
+; DetectIdePortsAndDevices
+;	Parameters:
+;		DS:DI:	Ptr to ROMVARS
+;	Returns:
+;		CX:		Number of controllers detected
+;	Corrupts registers:
+;		AX, BX, DX, SI
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+DetectIdePortsAndDevices:
+	xor		cx, cx							; Number of devices found
+	xor		dx, dx							; IDE_PORT_TO_START_DETECTION
+	lea		si, [di+ROMVARS.ideVarsBegin]	; DS:SI points to first IDEVARS
+
+.DetectFromNextPort:
+	call	IdeAutodetect_IncrementDXtoNextIdeBasePort
+	jz		SHORT .AllPortsAlreadyDetected
+	push	cx
+	call	IdeAutodetect_DetectIdeDeviceFromPortDX
+	pop		cx
+	jc		SHORT .DetectFromNextPort
+
+	; Device found from port DX, Device Type returned in AL
+	inc		cx	; Increment number of controllers found
+	call	GetControlBlockPortToBXfromDeviceTypeInALandBasePortInDX
+	mov		[si+IDEVARS.wBasePort], dx
+	mov		[si+IDEVARS.wControlBlockPort], bx
+	mov		[si+IDEVARS.bDevice], al
+
+	; Point to next IDEVARS
+	cmp		si, ROMVARS.ideVars3
+	jae		SHORT .AllPortsAlreadyDetected
+	add		si, IDEVARS_size
+	jmp		SHORT .DetectFromNextPort
+.AllPortsAlreadyDetected:
+	ret
+
+
+;--------------------------------------------------------------------
+; GetControlBlockPortToBXfromDeviceTypeInALandBasePortInDX
+;	Parameters:
+;		AL:		Device Type
+;		DX:		Base port
+;	Returns:
+;		BX:		Control Block Port
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+GetControlBlockPortToBXfromDeviceTypeInALandBasePortInDX:
+	mov		bx, dx
+	cmp		al, DEVICE_8BIT_XTIDE_REV1
+	jae		SHORT .NonStandardControlBlockPortLocation
+
+	; Standard IDE Devices
+	add		bx, STANDARD_CONTROL_BLOCK_OFFSET
+	ret
+
+.NonStandardControlBlockPortLocation:
+	cmp		al, DEVICE_8BIT_JRIDE_ISA
+	je		SHORT .JrIdeIsaDoesNotNeedControlBlockAddress
+
+	; 8-bit Devices
+	add		bx, BYTE XTIDE_CONTROL_BLOCK_OFFSET	; XT-CF also
+.JrIdeIsaDoesNotNeedControlBlockAddress:
+	ret
+
+
+;--------------------------------------------------------------------
+; StoreAndDisplayNumberOfControllers
+;	Parameters:
+;		CX:		Number of controllers detected
+;		DS:DI:	Ptr to ROMVARS
+;		SS:BP:	Ptr to MENU
+;	Returns:
+;		Nothing
+;	Corrupts registers:
+;		AX, BX, DX, DI, SI, DS, ES
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+StoreAndDisplayNumberOfControllers:
+	mov		ax, 1
+	MAX_U	al, cl						; Cannot store zero
+	test	BYTE [di+ROMVARS.wFlags], FLG_ROMVARS_FULLMODE
+	jnz		SHORT .FullModeSoNoNeedToLimit
+	MIN_U	al, MAX_LITE_MODE_CONTROLLERS
+.FullModeSoNoNeedToLimit:
+
+	; Store number of IDE Controllers. This will also modify
+	; menu and set unsaved changes flag.
+	push	cs
+	pop		ds
+	mov		si, g_MenuitemConfigurationIdeControllers
+	call	Menuitem_StoreValueFromAXtoMenuitemInDSSI
+
+	; Display results (should be changed to proper string formatting)
+	add		cl, '0'
+	mov		[cs:g_bControllersDetected], cl
+	mov		dx, g_szDlgAutoConfigure
+	jmp		Dialogs_DisplayNotificationFromCSDX
Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/IdeAutodetect.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/IdeAutodetect.asm	(revision 497)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/IdeAutodetect.asm	(revision 497)
@@ -0,0 +1,226 @@
+; Project name	:	XTIDE Universal BIOS Configurator v2
+; Description	:	Functions to detect ports and devices.
+
+;
+; XTIDE Universal BIOS and Associated Tools
+; Copyright (C) 2009-2010 by Tomi Tilli, 2011-2012 by XTIDE Universal BIOS Team.
+;
+; This program is free software; you can redistribute it and/or modify
+; it under the terms of the GNU General Public License as published by
+; the Free Software Foundation; either version 2 of the License, or
+; (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+; GNU General Public License for more details.
+; Visit http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+;
+
+; Section containing code
+SECTION .text
+
+;--------------------------------------------------------------------
+; IdeAutodetect_DetectIdeDeviceFromPortDX
+;	Parameters:
+;		DX:		IDE Base Port
+;		DS:DI:	Ptr to ROMVARS
+;	Returns:
+;		AL:		Device Type
+;		CF:		Clear if IDE Device found
+;				Set if IDE Device not found
+;	Corrupts registers:
+;		AH, BX, CX
+;--------------------------------------------------------------------
+IdeAutodetect_DetectIdeDeviceFromPortDX:
+	cmp		dx, FIRST_MEMORY_SEGMENT_ADDRESS
+	jb		SHORT .DetectPortMappedDevices
+
+	; Try to detect JR-IDE/ISA (only if MODULE_8BIT_IDE_ADVANCED is present)
+	test	WORD [di+ROMVARS.wFlags], FLG_ROMVARS_MODULE_8BIT_IDE_ADVANCED
+	jz		SHORT .SkipRestOfDetection
+
+	push	ds
+	mov		ds, dx
+	cli							; Disable Interrupts
+	mov		ah, [JRIDE_COMMAND_BLOCK_REGISTER_WINDOW_OFFSET + STATUS_REGISTER_in]
+	mov		al, [JRIDE_CONTROL_BLOCK_REGISTER_WINDOW_OFFSET + ALTERNATE_STATUS_REGISTER_in]
+	sti							; Enable Interrupts
+	pop		ds
+	call	CompareIdeStatusRegistersFromALandAH
+	mov		al, DEVICE_8BIT_JRIDE_ISA
+	ret
+.DetectPortMappedDevices:
+
+
+	; Try to detect Standard 16- and 32-bit IDE Devices
+	mov		bh, DEVICE_16BIT_ATA		; Assume 16-bit ISA slot for AT builds
+	call	Buffers_IsXTbuildLoaded
+	eCMOVE	bh, DEVICE_8BIT_ATA			; Assume 8-bit ISA slot for XT builds
+	mov		bl, STATUS_REGISTER_in
+	mov		cx, STANDARD_CONTROL_BLOCK_OFFSET + ALTERNATE_STATUS_REGISTER_in
+	call	DetectIdeDeviceFromPortDXwithStatusRegOffsetsInBLandCX
+	mov		al, bh
+	jnc		SHORT .IdeDeviceFound
+
+
+	; Detect 8-bit devices only if MODULE_8BIT_IDE is available
+	test	BYTE [di+ROMVARS.wFlags], FLG_ROMVARS_MODULE_8BIT_IDE
+	jz		SHORT .SkipRestOfDetection
+
+	; Try to detect XT-CF
+	mov		bl, STATUS_REGISTER_in << 1
+	mov		cx, (XTIDE_CONTROL_BLOCK_OFFSET + ALTERNATE_STATUS_REGISTER_in) << 1
+	call	DetectIdeDeviceFromPortDXwithStatusRegOffsetsInBLandCX
+	mov		al, DEVICE_8BIT_XTCF_PIO8
+	jnc		SHORT .IdeDeviceFound
+
+	; Try to detect 8-bit XT-IDE rev 1
+	shr		cx, 1
+	call	DetectIdeDeviceFromPortDXwithStatusRegOffsetsInBLandCX
+	mov		al, DEVICE_8BIT_XTIDE_REV1
+	jnc		SHORT .IdeDeviceFound
+
+	; Try to detect 8-bit XT-IDE rev 2 or modded rev 1
+	; This doesn't actually work since Status Register and Alternative
+	; Status Register swap place!!!
+	mov		bl, 1110b	; STATUS_REGISTER_in with A0 and A3 swapped
+	mov		cl, 0111b
+	call	DetectIdeDeviceFromPortDXwithStatusRegOffsetsInBLandCX
+	mov		al, DEVICE_8BIT_XTIDE_REV2
+.IdeDeviceFound:
+	ret
+.SkipRestOfDetection:
+	stc
+	ret
+
+
+;--------------------------------------------------------------------
+; DetectIdeDeviceFromPortDXwithStatusRegOffsetsInBLandCX
+;	Parameters:
+;		BL:		Offset to IDE Status Register
+;		CX:		Offset to Alternative Status Register
+;		DX:		IDE Base Port
+;	Returns:
+;		CF:		Clear if IDE Device found
+;				Set if IDE Device not found
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+DetectIdeDeviceFromPortDXwithStatusRegOffsetsInBLandCX:
+	; Read Status and Alternative Status Registers
+	push	cx
+	push	dx
+
+	add		cx, dx				; CX = Address to Alternative Status Register
+	add		dl, bl				; DX = Address to Status Register
+	cli							; Disable Interrupts
+	in		al, dx				; Read Status Register
+	mov		ah, al
+	mov		dx, cx
+	in		al, dx				; Read Alternative Status Register
+	sti							; Enable Interrupts
+
+	pop		dx
+	pop		cx
+	; Fall to CompareIdeStatusRegistersFromALandAH
+
+
+;--------------------------------------------------------------------
+; CompareIdeStatusRegistersFromALandAH
+;	Parameters:
+;		AL:		Possible IDE Status Register contents
+;		AH:		Possible IDE Alternative Status Register contents
+;	Returns:
+;		CF:		Clear if valid Status Register Contents
+;				Set if not possible IDE Status Registers
+;	Corrupts registers:
+;		Nothing
+;--------------------------------------------------------------------
+CompareIdeStatusRegistersFromALandAH:
+	; Status Register now in AH and Alternative Status Register in AL.
+	; They must be the same if base port was in use by IDE device.
+	cmp		al, ah
+	jne		SHORT .InvalidStatusRegister
+
+	; Bytes were the same but it is possible they were both FFh, for 
+	; example. We must make sure bit are what is expected from valid
+	; IDE Status Register.
+	test	al, FLG_STATUS_BSY | FLG_STATUS_DF | FLG_STATUS_DRQ | FLG_STATUS_ERR
+	jnz		SHORT .InvalidStatusRegister	; Busy or Errors cannot be set
+	test	al, FLG_STATUS_DRDY
+	jz		SHORT .InvalidStatusRegister	; Device needs to be ready
+	ret										; Return with CF cleared
+
+.InvalidStatusRegister:
+AllPortsAlreadyDetected:
+	stc
+	ret
+
+
+;--------------------------------------------------------------------
+; IdeAutodetect_IncrementDXtoNextIdeBasePort
+;	Parameters:
+;		DX:		Previous IDE Base Port
+;	Returns:
+;		DX:		Next IDE Base Port
+;		ZF:		Set if no more Base Ports (DX was last base port on entry)
+;				Clear if new base port returned in DX
+;	Corrupts registers:
+;		AX
+;--------------------------------------------------------------------
+ALIGN JUMP_ALIGN
+IdeAutodetect_IncrementDXtoNextIdeBasePort:
+	cmp		dx, [cs:.wLastIdePort]
+	je		SHORT .AllPortsAlreadyDetected
+
+	push	si
+	mov		si, .rgwIdeBasePorts
+.CompareNextIdeBasePort:
+	cmp		[cs:si], dx
+	lea		si, [si+2]	; Increment SI and preserve FLAGS
+	jne		SHORT .CompareNextIdeBasePort
+
+	mov		dx, [cs:si]			; Get next port
+	test	dx, dx				; Clear ZF
+	pop		si
+.AllPortsAlreadyDetected:
+	ret
+
+
+	; All ports used in autodetection. Ports can be in any order.
+ALIGN WORD_ALIGN
+.rgwIdeBasePorts:
+	dw		IDE_PORT_TO_START_DETECTION		; Must be first
+	; JR-IDE/ISA (Memory Segment Addresses)
+	dw		0C000h
+	dw		0C400h
+	dw		0C800h
+	dw		0CC00h
+	dw		0D000h
+	dw		0D400h
+	dw		0D800h
+	dw		0DC00h
+	; 8-bit Devices
+	dw		200h
+	dw		220h
+	dw		240h
+	dw		260h
+	dw		280h
+	dw		2A0h
+	dw		2C0h
+	dw		2E0h
+	dw		300h
+	dw		320h
+	dw		340h
+	dw		360h
+	dw		380h
+	dw		3A0h
+	dw		3C0h
+	dw		3E0h
+	; Standard IDE
+	dw		DEVICE_ATA_PRIMARY_PORT
+	dw		DEVICE_ATA_SECONDARY_PORT
+	dw		DEVICE_ATA_TERTIARY_PORT
+.wLastIdePort:
+	dw		DEVICE_ATA_QUATERNARY_PORT
Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Main.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Main.asm	(revision 491)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Main.asm	(revision 497)
@@ -25,4 +25,5 @@
 %include "AssemblyLibrary.inc"	; Assembly Library. Must be included first!
 %include "Romvars.inc"			; XTIDE Universal BIOS variables
+%include "IdeRegisters.inc"		; Needed for port and device autodetection
 %include "JRIDE_ISA.inc"		; For JR-IDE/ISA default segment
 %include "XTCF.inc"				; For XT-CF modes
@@ -47,4 +48,5 @@
 
 ; Include sources for this program
+%include "AutoConfigure.asm"
 %include "BiosFile.asm"
 %include "Buffers.asm"
@@ -52,4 +54,5 @@
 %include "EEPROM.asm"
 %include "Flash.asm"
+%include "IdeAutodetect.asm"
 %include "MenuEvents.asm"
 %include "Menuitem.asm"
Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menupages/ConfigurationMenu.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menupages/ConfigurationMenu.asm	(revision 491)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Menupages/ConfigurationMenu.asm	(revision 497)
@@ -26,5 +26,5 @@
 	at	MENUPAGE.fnEnter,			dw	ConfigurationMenu_EnterMenuOrModifyItemVisibility
 	at	MENUPAGE.fnBack,			dw	MainMenu_EnterMenuOrModifyItemVisibility
-	at	MENUPAGE.wMenuitems,		dw	10
+	at	MENUPAGE.wMenuitems,		dw	11
 iend
 
@@ -87,4 +87,14 @@
 	at	MENUITEM.bFlags,			db	FLG_MENUITEM_VISIBLE
 	at	MENUITEM.bType,				db	TYPE_MENUITEM_PAGENEXT
+iend
+
+g_MenuitemAutoConfigure:
+istruc MENUITEM
+	at	MENUITEM.fnActivate,		dw	AutoConfigure_ForThisSystem
+	at	MENUITEM.szName,			dw	g_szItemAutoConfigure
+	at	MENUITEM.szQuickInfo,		dw	g_szNfoAutoConfigure
+	at	MENUITEM.szHelp,			dw	g_szNfoAutoConfigure
+	at	MENUITEM.bFlags,			db	FLG_MENUITEM_VISIBLE | FLG_MENUITEM_MODIFY_MENU
+	at	MENUITEM.bType,				db	TYPE_MENUITEM_ACTION
 iend
 
Index: trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Strings.asm
===================================================================
--- trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Strings.asm	(revision 491)
+++ trunk/XTIDE_Universal_BIOS_Configurator_v2/Src/Strings.asm	(revision 497)
@@ -106,4 +106,5 @@
 g_szItemCfgIde4:		db	"Quaternary IDE Controller",NULL
 g_szItemCfgBootMenu:	db	"Boot settings",NULL
+g_szItemAutoConfigure:	db	"Auto Configure",NULL
 g_szItemCfgFullMode:	db	"Full operating mode",NULL
 g_szItemCfgStealSize:	db	"kiB to steal from RAM",NULL
@@ -111,4 +112,7 @@
 g_szItemCfgIdleTimeout:	db	"Power Management",NULL
 
+g_szDlgAutoConfigure:	db	"Found " 
+g_bControllersDetected:	db	'x'				; Value stored directly here
+						db	" controllers.",NULL
 g_szDlgCfgFullMode:		db	"Enable full operating mode?",NULL
 g_szDlgCfgStealSize:	db	"How many kiB of base memory to steal for XTIDE Universal BIOS variables (1...255)?",NULL
@@ -118,4 +122,5 @@
 g_szNfoCfgIde:			db	"IDE controller and drive configuration.",NULL
 g_szNfoCfgBootMenu:		db	"Boot configuration.",NULL
+g_szNfoAutoConfigure:	db	"Automatically Configure XTIDE Universal BIOS for this system.",NULL
 g_szNfoCfgFullMode:		db	"Full mode supports multiple controllers and has more features.",NULL
 g_szNfoCfgStealSize:	db	"How many kiB's to steal from Conventional memory for XTIDE Universal BIOS variables.",NULL
